Skip to content

Commit

Permalink
Fixed concurrency issues, datapacked targets are now checked
Browse files Browse the repository at this point in the history
  • Loading branch information
bibi-reden committed Aug 9, 2024
1 parent af68a6e commit 5d4d6d7
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 15 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
- Implemented a feature that reads data-packs and applies attribute modifications to the world based on order.
- More documentation on this feature will come as the mod stabilizes.
- For now, if you want to be aware of how to format your data-pack(s), look towards the source code of the next builds of PlayerEX/WizardEX.

## Changes 🌽
- Changed how configs and modded entries are applied.
- Your config will appear sparse on startup, but when you go to a world (in an integrated server), it will show the extra modifications provided by loaded packs and mods.
- You can overwrite these, and they will appear in your actual config. Your config will **overwrite** any data-pack or modded pack.
- The UI will be overhauled to better assist in knowing what is supplied by datapacks/mods, but that will be in the later future.
- Deprecated the `DefaultAttributeRegistry` to keep previous versions functional, but it will be removed before release.
- Deprecated the `DefaultAttributeRegistry` to keep previous versions functional, but it will be removed before release.
- Being able to override specific mods and being able to customize your data-packs will come in the future. For now, if you want to override something, use your config as it is the main source of truth.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import net.minecraft.util.Identifier
/**
* Used to manage config data, and contains an [AttributeContainerHandler] to build related [EntityTypeData].
*/
class AttributeConfigManager(private var data: Data = Data(), val handler: AttributeContainerHandler = AttributeContainerHandler()) {
class AttributeConfigManager(var data: Data = Data(), val handler: AttributeContainerHandler = AttributeContainerHandler()) {
var updateFlag: Int = 0

var defaults: DefaultAttributesReloadListener.Cache = DefaultAttributesReloadListener.Cache()
Expand Down Expand Up @@ -163,10 +163,10 @@ class AttributeConfigManager(private var data: Data = Data(), val handler: Attri
}

private fun insertOverrides(overrides: Map<Identifier, AttributeOverride>, entityAttributeData: MutableMap<Identifier, EntityAttributeData>) {
overrides.forEach { (id, override) ->
for ((id, override) in overrides) {
if (!Registries.ATTRIBUTE.containsId(id)) {
DataAttributes.LOGGER.warn("Attribute [$id] that was targeted for override is not registered. This has been skipped.")
return@forEach
continue
}
val attribute = Registries.ATTRIBUTE[id]!! as IEntityAttribute
if (override.max.isNaN()) {
Expand All @@ -180,11 +180,10 @@ class AttributeConfigManager(private var data: Data = Data(), val handler: Attri
}

private fun insertFunctions(store: Map<Identifier, List<AttributeFunction>>, data: MutableMap<Identifier, EntityAttributeData>) {
store.forEach { (id, functions) ->
for ((id, functions) in store) {
if (!Registries.ATTRIBUTE.containsId(id)) {
DataAttributes.LOGGER.warn("Function parent [$id] that was defined in config is not registered. This has been skipped.")
}
else {
} else {
val dat = data[id] ?: EntityAttributeData()
dat.putFunctions(functions)
data[id] = dat
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@ object ConfigMerger {
fun mergeFunctions(values: Map<Identifier, List<AttributeFunction>>): Map<Identifier, List<AttributeFunction>> {
val entries = values.toMutableMap()
for ((primaryId, primaryFunctions) in DataAttributes.FUNCTIONS_CONFIG.functions.data) {
val secondaryEntry = entries[primaryId]?.toMutableList()
if (secondaryEntry == null) {
val entriesMap = entries[primaryId]
if (entriesMap == null) {
entries[primaryId] = primaryFunctions
}
else {
val secondaryEntry = entriesMap.toMutableList()
primaryFunctions.forEach { primaryFunction ->
var replaced = false
secondaryEntry.forEachIndexed { index, entry ->
entriesMap.forEachIndexed { index, entry ->
if (entry.id == primaryFunction.id) {
secondaryEntry.removeAt(index)
secondaryEntry.add(index, primaryFunction)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromStream
import net.fabricmc.fabric.api.resource.SimpleResourceReloadListener
import net.minecraft.registry.Registries
import net.minecraft.resource.ResourceManager
import net.minecraft.util.Identifier
import net.minecraft.util.profiler.Profiler
Expand All @@ -29,11 +30,11 @@ class DefaultAttributesReloadListener : SimpleResourceReloadListener<DefaultAttr
var data: Cache = Cache()

@Serializable
data class Overrides(val entries: LinkedHashMap<Identifier, AttributeOverride> = LinkedHashMap())
data class Overrides(var entries: LinkedHashMap<Identifier, AttributeOverride> = LinkedHashMap())
@Serializable
data class Functions(val entries: LinkedHashMap<Identifier, List<AttributeFunction>> = LinkedHashMap())
data class Functions(var entries: LinkedHashMap<Identifier, List<AttributeFunction>> = LinkedHashMap())
@Serializable
data class EntityTypes(val entries: LinkedHashMap<Identifier, LinkedHashMap<Identifier, Double>> = LinkedHashMap())
data class EntityTypes(var entries: LinkedHashMap<Identifier, LinkedHashMap<Identifier, Double>> = LinkedHashMap())

@Serializable
data class Cache(val overrides: Overrides = Overrides(), val functions: Functions = Functions(), val types: EntityTypes = EntityTypes())
Expand All @@ -54,6 +55,23 @@ class DefaultAttributesReloadListener : SimpleResourceReloadListener<DefaultAttr
readFunctions(manager, cache)
readEntityTypes(manager, cache)

// Filtering before applying the cache.
cache.overrides.entries = LinkedHashMap(cache.overrides.entries.filter { (id, _) -> Registries.ATTRIBUTE.containsId(id) })
cache.functions.entries.forEach { (id, functions) ->
if (!Registries.ATTRIBUTE.containsId(id)) {
cache.functions.entries.remove(id)
return@forEach
}
cache.functions.entries[id] = functions.filter { f -> Registries.ATTRIBUTE.containsId(f.id) }
}
cache.types.entries.forEach { (id, data) ->
if (!Registries.ENTITY_TYPE.containsId(id)) {
cache.types.entries.remove(id)
return@forEach
}
cache.types.entries[id] = LinkedHashMap(data.filter { (id2) -> Registries.ATTRIBUTE.containsId(id2) })
}

cache
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class AttributeFunctionsProvider(val option: Option<AttributeFunctionConfig>) :
onChange = {
it.toDoubleOrNull()?.let { v ->
val popped = this.backing.remove(topID)?.toMutableList() ?: mutableListOf()
if (popped.isEmpty()) {
if (popped.size - 1 < index) {
popped.add(function.copy(value = v))
}
else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class AttributeOverrideProvider(val option: Option<Map<Identifier, AttributeOver
min_fallback = attribute.`data_attributes$min_fallback`(),
max_fallback = attribute.`data_attributes$max_fallback`()
)
this.backing[id] = override
this.backing.replace(id, override)
}

val isOverrideInvalid = isAttributeUnregistered(id)
Expand Down

0 comments on commit 5d4d6d7

Please sign in to comment.