From 151bcb52a2db217626fd97f79b9ba1d7be8b4d3d Mon Sep 17 00:00:00 2001 From: CleverNucleus Date: Sun, 30 Apr 2023 21:22:33 +0100 Subject: [PATCH 1/8] Modrinth has issues accepting javadocs. --- .github/workflows/build-and-deploy.yml | 12 +++++------- build.gradle | 1 + 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-and-deploy.yml b/.github/workflows/build-and-deploy.yml index 06446209..c6b041ec 100644 --- a/.github/workflows/build-and-deploy.yml +++ b/.github/workflows/build-and-deploy.yml @@ -54,19 +54,17 @@ jobs: if: github.ref == 'refs/heads/${{ env.BRANCH_PREFIX }}/main' uses: Kir-Antipov/mc-publish@v3.2 with: - #curseforge-id: 514734 - #curseforge-token: ${{ secrets.CURSEFORGE_TOKEN }} - #curseforge-dependencies: | - # fabric-api | depends | * - #curseforge-files-secondary: build/libs/*-@(sources\|javadoc).jar + curseforge-id: 514734 + curseforge-token: ${{ secrets.CURSEFORGE_TOKEN }} + curseforge-dependencies: | + fabric-api | depends | * + curseforge-files-secondary: build/libs/*-@(sources\|javadoc).jar modrinth-id: wFyCClLQ modrinth-token: "${{ secrets.MODRINTH_TOKEN }}" modrinth-dependencies: | fabric-api | depends | * # Modrinth has issues accepting javadocs right now - modrinth-files-primary: build/libs/!(*-@(sources)).jar - modrinth-files-secondary: build/libs/*-sources.jar github-tag: "${{ steps.mod_version.outputs.mod_version }}" github-token: ${{ secrets.REPOSITORY_TOKEN }} diff --git a/build.gradle b/build.gradle index 235db6e9..f77e93e7 100644 --- a/build.gradle +++ b/build.gradle @@ -47,6 +47,7 @@ task javadocJar(type: Jar) { archiveClassifier = "javadoc" } +// Modrinth has issues accepting javadocs right now // build.dependsOn javadocJar java { From ba0858cc97a5753e3517fbe13134dbcfc7f25a0a Mon Sep 17 00:00:00 2001 From: CleverNucleus Date: Sun, 28 May 2023 11:42:16 +0100 Subject: [PATCH 2/8] Fixed crash/freeze when Lithium + REI are present. --- .../mixin/AttributeContainerMixin.java | 27 +++++++++++++++++ .../mixin/EntityTrackerEntryMixin.java | 30 +++++++++++++++++++ .../mutable/MutableAttributeContainer.java | 2 ++ src/main/resources/dataattributes.mixins.json | 1 + 4 files changed, 60 insertions(+) create mode 100644 src/main/java/com/github/clevernucleus/dataattributes/mixin/EntityTrackerEntryMixin.java diff --git a/src/main/java/com/github/clevernucleus/dataattributes/mixin/AttributeContainerMixin.java b/src/main/java/com/github/clevernucleus/dataattributes/mixin/AttributeContainerMixin.java index be0576b9..9374112c 100644 --- a/src/main/java/com/github/clevernucleus/dataattributes/mixin/AttributeContainerMixin.java +++ b/src/main/java/com/github/clevernucleus/dataattributes/mixin/AttributeContainerMixin.java @@ -3,6 +3,8 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -34,6 +36,9 @@ abstract class AttributeContainerMixin implements MutableAttributeContainer { @Unique private Map data_custom = new HashMap(); + @Unique + private Map data_tracked = new HashMap(); + @Unique private LivingEntity data_livingEntity; @@ -44,6 +49,23 @@ abstract class AttributeContainerMixin implements MutableAttributeContainer { @Shadow private void updateTrackedStatus(EntityAttributeInstance instance) {} + @Inject(method = "updateTrackedStatus", at = @At("HEAD"), cancellable = true) + private void data_updateTrackedStatus(EntityAttributeInstance instance, CallbackInfo ci) { + Identifier identifier = ((MutableAttributeInstance)instance).getId(); + + if(identifier != null) { + this.data_tracked.put(identifier, instance); + } + + ci.cancel(); + } + + @Inject(method = "getTracked", at = @At("Head"), cancellable = true) + private void data_getTracked(CallbackInfoReturnable> cir) { + Set tracked = this.data_tracked.values().stream().collect(Collectors.toSet()); + cir.setReturnValue(tracked); + } + @Redirect(method = "getAttributesToSend", at = @At(value = "INVOKE", target = "Ljava/util/Map;values()Ljava/util/Collection;")) private Collection data_getAttributesToSend(Map instances) { return this.data_custom.values(); @@ -159,4 +181,9 @@ public void refresh() { ((MutableAttributeInstance)instance).refresh(); } } + + @Override + public void clearTracked() { + this.data_tracked.clear(); + } } diff --git a/src/main/java/com/github/clevernucleus/dataattributes/mixin/EntityTrackerEntryMixin.java b/src/main/java/com/github/clevernucleus/dataattributes/mixin/EntityTrackerEntryMixin.java new file mode 100644 index 00000000..12b5f75b --- /dev/null +++ b/src/main/java/com/github/clevernucleus/dataattributes/mixin/EntityTrackerEntryMixin.java @@ -0,0 +1,30 @@ +package com.github.clevernucleus.dataattributes.mixin; + +import java.util.Set; + +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import com.github.clevernucleus.dataattributes.mutable.MutableAttributeContainer; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.attribute.EntityAttributeInstance; +import net.minecraft.server.network.EntityTrackerEntry; + +@Mixin(EntityTrackerEntry.class) +abstract class EntityTrackerEntryMixin { + + @Final + @Shadow + private Entity entity; + + @Redirect(method = "syncEntityData",at = @At(value = "INVOKE", target = "Ljava/util/Set;clear()V")) + private void data_syncEntityData(Set set) { + MutableAttributeContainer container = (MutableAttributeContainer)((LivingEntity)this.entity).getAttributes(); + container.clearTracked(); + } +} diff --git a/src/main/java/com/github/clevernucleus/dataattributes/mutable/MutableAttributeContainer.java b/src/main/java/com/github/clevernucleus/dataattributes/mutable/MutableAttributeContainer.java index 17b1f487..557b215e 100644 --- a/src/main/java/com/github/clevernucleus/dataattributes/mutable/MutableAttributeContainer.java +++ b/src/main/java/com/github/clevernucleus/dataattributes/mutable/MutableAttributeContainer.java @@ -14,4 +14,6 @@ public interface MutableAttributeContainer { void setLivingEntity(final LivingEntity livingEntity); void refresh(); + + void clearTracked(); } diff --git a/src/main/resources/dataattributes.mixins.json b/src/main/resources/dataattributes.mixins.json index a0021f57..b2ccc085 100644 --- a/src/main/resources/dataattributes.mixins.json +++ b/src/main/resources/dataattributes.mixins.json @@ -22,6 +22,7 @@ "PlayerRespawnS2CPacketMixin", "PlayerManagerMixin", "ReloadCommandMixin", + "EntityTrackerEntryMixin", "item.ItemMixin", "item.SwordItemMixin", "item.ArmorItemMixin", From cf308b2266d14e9220c6d3d44a5cc1f8288868dd Mon Sep 17 00:00:00 2001 From: CleverNucleus Date: Sun, 28 May 2023 11:44:37 +0100 Subject: [PATCH 3/8] Increment version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 3a82b9d3..1a31c4e2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ minecraft_version=1.19.2 yarn_mappings=1.19.2+build.28 loader_version=0.14.18 -mod_version=1.4.4+1.19.2 +mod_version=1.4.5+1.19.2 maven_group=com.github.clevernucleus archives_base_name=dataattributes From 278c211dff47340c13b44b73f4e607113d35456a Mon Sep 17 00:00:00 2001 From: CleverNucleus Date: Sun, 28 May 2023 20:18:07 +0100 Subject: [PATCH 4/8] Reverted data compression for packets - redundent system since this is a feature by default. --- .../dataattributes/DataAttributes.java | 10 +- .../dataattributes/DataAttributesClient.java | 21 +- .../impl/AttributeContainerHandler.java | 90 ++++++++ .../dataattributes/impl/AttributeManager.java | 218 ++++-------------- .../mixin/ReloadCommandMixin.java | 6 +- 5 files changed, 159 insertions(+), 186 deletions(-) create mode 100644 src/main/java/com/github/clevernucleus/dataattributes/impl/AttributeContainerHandler.java diff --git a/src/main/java/com/github/clevernucleus/dataattributes/DataAttributes.java b/src/main/java/com/github/clevernucleus/dataattributes/DataAttributes.java index e04d828a..205e827c 100644 --- a/src/main/java/com/github/clevernucleus/dataattributes/DataAttributes.java +++ b/src/main/java/com/github/clevernucleus/dataattributes/DataAttributes.java @@ -24,6 +24,7 @@ import net.minecraft.entity.attribute.EntityAttribute; import net.minecraft.entity.attribute.EntityAttributeModifier; import net.minecraft.entity.attribute.EntityAttributes; +import net.minecraft.nbt.NbtCompound; import net.minecraft.network.PacketByteBuf; import net.minecraft.resource.ResourceType; import net.minecraft.server.MinecraftServer; @@ -40,14 +41,13 @@ public class DataAttributes implements ModInitializer { private static void loginQueryStart(ServerLoginNetworkHandler handler, MinecraftServer server, PacketSender sender, ServerLoginNetworking.LoginSynchronizer synchronizer) { PacketByteBuf buf = PacketByteBufs.create(); - buf.writeByteArray(DataAttributes.MANAGER.getEntityAttributeData()); - buf.writeByteArray(DataAttributes.MANAGER.getEntityTypeData()); + NbtCompound tag = new NbtCompound(); + DataAttributes.MANAGER.toNbt(tag); + buf.writeNbt(tag); sender.sendPacket(HANDSHAKE, buf); } - private static void loginQueryResponse(MinecraftServer server, ServerLoginNetworkHandler handler, boolean understood, PacketByteBuf buf, LoginSynchronizer synchronizer, PacketSender responseSender) { - // Does doing nothing here make us compatible with Velocity plugin? - } + private static void loginQueryResponse(MinecraftServer server, ServerLoginNetworkHandler handler, boolean understood, PacketByteBuf buf, LoginSynchronizer synchronizer, PacketSender responseSender) {} private static void refreshAttributes(final Entity entity) { if(!(entity instanceof LivingEntity)) return; diff --git a/src/main/java/com/github/clevernucleus/dataattributes/DataAttributesClient.java b/src/main/java/com/github/clevernucleus/dataattributes/DataAttributesClient.java index f971c360..3bfa6f6f 100644 --- a/src/main/java/com/github/clevernucleus/dataattributes/DataAttributesClient.java +++ b/src/main/java/com/github/clevernucleus/dataattributes/DataAttributesClient.java @@ -16,31 +16,32 @@ import net.minecraft.client.network.ClientLoginNetworkHandler; import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.client.world.ClientWorld; +import net.minecraft.nbt.NbtCompound; import net.minecraft.network.PacketByteBuf; public class DataAttributesClient implements ClientModInitializer { private static CompletableFuture loginQueryReceived(MinecraftClient client, ClientLoginNetworkHandler handler, PacketByteBuf buf, Consumer>> listenerAdder) { - final byte[] entityAttributeData = buf.readByteArray(); - final byte[] entityTypeData = buf.readByteArray(); + NbtCompound tag = buf.readNbt(); client.execute(() -> { - DataAttributes.MANAGER.setEntityAttributeData(entityAttributeData); - DataAttributes.MANAGER.setEntityTypeData(entityTypeData); - DataAttributes.MANAGER.apply(); + if(tag != null) { + DataAttributes.MANAGER.fromNbt(tag); + DataAttributes.MANAGER.apply(); + } }); return CompletableFuture.completedFuture(PacketByteBufs.empty()); } private static void updateReceived(MinecraftClient client, ClientPlayNetworkHandler handler, PacketByteBuf buf, PacketSender responseSender) { - final byte[] entityAttributeData = buf.readByteArray(); - final byte[] entityTypeData = buf.readByteArray(); + NbtCompound tag = buf.readNbt(); final int updateFlag = buf.readInt(); client.execute(() -> { - DataAttributes.MANAGER.setEntityAttributeData(entityAttributeData); - DataAttributes.MANAGER.setEntityTypeData(entityTypeData); - DataAttributes.MANAGER.apply(); + if(tag != null) { + DataAttributes.MANAGER.fromNbt(tag); + DataAttributes.MANAGER.apply(); + } ClientWorld world = client.world; diff --git a/src/main/java/com/github/clevernucleus/dataattributes/impl/AttributeContainerHandler.java b/src/main/java/com/github/clevernucleus/dataattributes/impl/AttributeContainerHandler.java new file mode 100644 index 00000000..21edd3a3 --- /dev/null +++ b/src/main/java/com/github/clevernucleus/dataattributes/impl/AttributeContainerHandler.java @@ -0,0 +1,90 @@ +package com.github.clevernucleus.dataattributes.impl; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; + +import com.github.clevernucleus.dataattributes.impl.AttributeManager.Tuple; +import com.github.clevernucleus.dataattributes.mutable.MutableAttributeContainer; +import com.github.clevernucleus.dataattributes.mutable.MutableDefaultAttributeContainer; +import com.google.common.collect.ImmutableMap; + +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.attribute.AttributeContainer; +import net.minecraft.entity.attribute.DefaultAttributeContainer; +import net.minecraft.entity.attribute.DefaultAttributeRegistry; +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.Registry; + +public final class AttributeContainerHandler { + private Map> implicitContainers; + private Map, DefaultAttributeContainer> explicitContainers; + + protected AttributeContainerHandler() { + this.implicitContainers = ImmutableMap.of(); + this.explicitContainers = ImmutableMap.of(); + } + + protected AttributeContainer getContainer(final EntityType entityType, final LivingEntity livingEntity) { + DefaultAttributeContainer.Builder builder = DefaultAttributeContainer.builder(); + ((MutableDefaultAttributeContainer)DefaultAttributeRegistry.get(entityType)).copy(builder); + + for(int i = 0; i < this.implicitContainers.size(); i++) { + Tuple tuple = this.implicitContainers.get(i); + Class type = tuple.livingEntity(); + + if(type.isInstance(livingEntity)) { + ((MutableDefaultAttributeContainer)tuple.value()).copy(builder); + } + } + + if(this.explicitContainers.containsKey(entityType)) { + ((MutableDefaultAttributeContainer)this.explicitContainers.get(entityType)).copy(builder); + } + + AttributeContainer container = new AttributeContainer(builder.build()); + ((MutableAttributeContainer)container).setLivingEntity(livingEntity); + + return container; + } + + @SuppressWarnings("unchecked") + protected void buildContainers(final Map entityTypeDataIn, Map> entityTypeInstances) { + Collection entityTypes = Registry.ENTITY_TYPE.getIds().stream().filter(id -> DefaultAttributeRegistry.hasDefinitionFor(Registry.ENTITY_TYPE.get(id))).collect(Collectors.toSet()); + ImmutableMap.Builder> implicitContainers = ImmutableMap.builder(); + ImmutableMap.Builder, DefaultAttributeContainer> explicitContainers = ImmutableMap.builder(); + Map> orderedEntityTypes = new HashMap<>(); + + for(Identifier identifier : entityTypeDataIn.keySet()) { + if(entityTypeInstances.containsKey(identifier)) { + Tuple tuple = entityTypeInstances.get(identifier); + orderedEntityTypes.put(tuple.value(), new Tuple(tuple.livingEntity(), identifier)); + } + if(!entityTypes.contains(identifier)) continue; + EntityType entityType = (EntityType)Registry.ENTITY_TYPE.get(identifier); + DefaultAttributeContainer.Builder builder = DefaultAttributeContainer.builder(); + EntityTypeData entityTypeData = entityTypeDataIn.get(identifier); + entityTypeData.build(builder, DefaultAttributeRegistry.get(entityType)); + explicitContainers.put(entityType, builder.build()); + } + + final int size = orderedEntityTypes.size(); + final int max = orderedEntityTypes.keySet().stream().mapToInt(Integer::intValue).max().orElse(0); + + for(Map.Entry> entry : orderedEntityTypes.entrySet()) { + Tuple tuple = entry.getValue(); + Identifier identifier = tuple.value(); + final int hierarchy = entry.getKey(); + final int index = Math.round((float)size * (float)hierarchy / (float)max) - 1; + DefaultAttributeContainer.Builder builder = DefaultAttributeContainer.builder(); + EntityTypeData entityTypeData = entityTypeDataIn.get(identifier); + entityTypeData.build(builder, null); + implicitContainers.put(index, new Tuple(tuple.livingEntity(), builder.build())); + } + + this.implicitContainers = implicitContainers.build(); + this.explicitContainers = explicitContainers.build(); + } +} diff --git a/src/main/java/com/github/clevernucleus/dataattributes/impl/AttributeManager.java b/src/main/java/com/github/clevernucleus/dataattributes/impl/AttributeManager.java index 6714118b..afe91c43 100644 --- a/src/main/java/com/github/clevernucleus/dataattributes/impl/AttributeManager.java +++ b/src/main/java/com/github/clevernucleus/dataattributes/impl/AttributeManager.java @@ -3,17 +3,10 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.Reader; -import java.io.UnsupportedEncodingException; -import java.util.Arrays; -import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; -import java.util.stream.Collectors; -import java.util.zip.DataFormatException; -import java.util.zip.Deflater; -import java.util.zip.Inflater; import org.slf4j.Logger; @@ -24,21 +17,16 @@ import com.github.clevernucleus.dataattributes.json.EntityTypesJson; import com.github.clevernucleus.dataattributes.json.FunctionsJson; import com.github.clevernucleus.dataattributes.json.PropertiesJson; -import com.github.clevernucleus.dataattributes.mutable.MutableAttributeContainer; -import com.github.clevernucleus.dataattributes.mutable.MutableDefaultAttributeContainer; import com.github.clevernucleus.dataattributes.mutable.MutableEntityAttribute; import com.google.common.collect.ImmutableMap; import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.logging.LogUtils; import net.fabricmc.fabric.api.resource.SimpleResourceReloadListener; import net.minecraft.entity.EntityType; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.attribute.AttributeContainer; -import net.minecraft.entity.attribute.DefaultAttributeContainer; -import net.minecraft.entity.attribute.DefaultAttributeRegistry; import net.minecraft.entity.attribute.EntityAttribute; import net.minecraft.entity.mob.HostileEntity; import net.minecraft.entity.mob.MobEntity; @@ -46,8 +34,6 @@ import net.minecraft.entity.passive.AnimalEntity; import net.minecraft.entity.passive.PassiveEntity; import net.minecraft.nbt.NbtCompound; -import net.minecraft.nbt.StringNbtReader; -import net.minecraft.nbt.visitor.StringNbtWriter; import net.minecraft.resource.Resource; import net.minecraft.resource.ResourceManager; import net.minecraft.util.Identifier; @@ -61,16 +47,14 @@ public final class AttributeManager implements SimpleResourceReloadListener, Integer>> ENTITY_TYPE_INSTANCES = new HashMap<>(); + private static final Map> ENTITY_TYPE_INSTANCES = new HashMap<>(); private Map entityAttributeData = ImmutableMap.of(); private Map entityTypeData = ImmutableMap.of(); - private Map, DefaultAttributeContainer>> implicitContainers = ImmutableMap.of(); - private Map, DefaultAttributeContainer> explicitContainers = ImmutableMap.of(); - private byte[] entityAttributeBytes, entityTypeBytes; + private AttributeContainerHandler handler = new AttributeContainerHandler(); - private static record Pair(F fruit, S stalk) {} - protected record Wrapper(Map entityAttributeData, Map entityTypeData) {} + protected static final record Tuple(Class livingEntity, T value) {} + protected static final record Wrapper(Map entityAttributeData, Map entityTypeData) {} public AttributeManager() {} @@ -260,124 +244,56 @@ private static void loadEntityTypes(ResourceManager manager, Map byte[] generateCurrentData(final Map data) { - StringNbtWriter writer = new StringNbtWriter(); - NbtCompound tag = new NbtCompound(); - - data.forEach((key, value) -> { + public void toNbt(NbtCompound tag) { + NbtCompound entityAttributeNbt = new NbtCompound(); + NbtCompound entityTypeNbt = new NbtCompound(); + + this.entityAttributeData.forEach((key, val) -> { NbtCompound entry = new NbtCompound(); - value.writeToNbt(entry); - tag.put(key.toString(), entry); + val.writeToNbt(entry); + entityAttributeNbt.put(key.toString(), entry); }); - - String snbt = writer.apply(tag); - byte[] bytes; - - try { - bytes = snbt.getBytes("UTF-8"); - } catch(UnsupportedEncodingException e) { - bytes = new byte[] {(byte)0}; - } - - Deflater deflater = new Deflater(); - deflater.setInput(bytes); - deflater.finish(); - - byte[] compressed = new byte[Short.MAX_VALUE]; - int size = deflater.deflate(compressed); - deflater.end(); - - return Arrays.copyOf(compressed, size); - } - - private NbtCompound readFromData(byte[] bytesIn) { - Inflater inflater = new Inflater(); - inflater.setInput(bytesIn); - - byte[] cache = new byte[Short.MAX_VALUE]; - int size; - - try { - size = inflater.inflate(cache); - } catch (DataFormatException e) { - size = 1; - } - - inflater.end(); - byte[] uncompressed = Arrays.copyOf(cache, size); - String snbt = new String(uncompressed); - NbtCompound nbt; - - try { - nbt = StringNbtReader.parse(snbt); - } catch (CommandSyntaxException e) { - nbt = new NbtCompound(); - } - - return nbt; - } - - public void setEntityAttributeData(byte[] bytesIn) { - NbtCompound tag = this.readFromData(bytesIn); - ImmutableMap.Builder builder = ImmutableMap.builder(); - tag.getKeys().forEach(key -> { - NbtCompound entry = tag.getCompound(key); - EntityAttributeData entityAttributeData = new EntityAttributeData(); - entityAttributeData.readFromNbt(entry); - builder.put(new Identifier(key), entityAttributeData); - }); - - this.entityAttributeData = builder.build(); - } - - public void setEntityTypeData(byte[] bytesIn) { - NbtCompound tag = this.readFromData(bytesIn); - ImmutableMap.Builder builder = ImmutableMap.builder(); - tag.getKeys().forEach(key -> { - NbtCompound entry = tag.getCompound(key); - EntityTypeData entityTypeData = new EntityTypeData(); - entityTypeData.readFromNbt(entry); - builder.put(new Identifier(key), entityTypeData); + this.entityTypeData.forEach((key, val) -> { + NbtCompound entry = new NbtCompound(); + val.writeToNbt(entry); + entityTypeNbt.put(key.toString(), entry); }); - - this.entityTypeData = builder.build(); - } - - public byte[] getEntityAttributeData() { - if(this.entityAttributeBytes == null) return new byte[] {(byte)0}; - return this.entityAttributeBytes; - } - - public byte[] getEntityTypeData() { - if(this.entityTypeBytes == null) return new byte[] {(byte)0}; - return this.entityTypeBytes; + + tag.put("Attributes", entityAttributeNbt); + tag.put("EntityTypes", entityTypeNbt); } - public AttributeContainer getContainer(final EntityType entityType, final LivingEntity entity) { - DefaultAttributeContainer.Builder builder = DefaultAttributeContainer.builder(); - ((MutableDefaultAttributeContainer)DefaultAttributeRegistry.get(entityType)).copy(builder); - - for(int i = 0; i < this.implicitContainers.size(); i++) { - Pair, DefaultAttributeContainer> entityTypeContainer = this.implicitContainers.get(i); - Class type = entityTypeContainer.fruit(); - - if(type.isInstance(entity)) { - ((MutableDefaultAttributeContainer)entityTypeContainer.stalk()).copy(builder); - } + public void fromNbt(NbtCompound tag) { + if(tag.contains("Attributes")) { + ImmutableMap.Builder builder = ImmutableMap.builder(); + NbtCompound nbtCompound = tag.getCompound("Attributes"); + nbtCompound.getKeys().forEach(key -> { + NbtCompound entry = nbtCompound.getCompound(key); + EntityAttributeData entityAttributeData = new EntityAttributeData(); + entityAttributeData.readFromNbt(entry); + builder.put(new Identifier(key), entityAttributeData); + }); + this.entityAttributeData = builder.build(); } - if(this.explicitContainers.containsKey(entityType)) { - ((MutableDefaultAttributeContainer)this.explicitContainers.get(entityType)).copy(builder); + if(tag.contains("EntityTypes")) { + ImmutableMap.Builder builder = ImmutableMap.builder(); + NbtCompound nbtCompound = tag.getCompound("EntityTypes"); + nbtCompound.getKeys().forEach(key -> { + NbtCompound entry = nbtCompound.getCompound(key); + EntityTypeData entityTypeData = new EntityTypeData(); + entityTypeData.readFromNbt(entry); + builder.put(new Identifier(key), entityTypeData); + }); + this.entityTypeData = builder.build(); } + } - AttributeContainer attributeContainer = new AttributeContainer(builder.build()); - ((MutableAttributeContainer)attributeContainer).setLivingEntity(entity); - - return attributeContainer; + public AttributeContainer getContainer(final EntityType entityType, final LivingEntity livingEntity) { + return this.handler.getContainer(entityType, livingEntity); } - @SuppressWarnings("unchecked") public void apply() { MutableRegistryImpl.unregister(Registry.ATTRIBUTE); @@ -403,41 +319,7 @@ public void apply() { entityAttributeData.copy(entityAttribute); } - Collection entityTypes = Registry.ENTITY_TYPE.getIds().stream().filter(id -> DefaultAttributeRegistry.hasDefinitionFor(Registry.ENTITY_TYPE.get(id))).collect(Collectors.toSet()); - ImmutableMap.Builder, DefaultAttributeContainer> explicitContainers = ImmutableMap.builder(); - ImmutableMap.Builder, DefaultAttributeContainer>> implicitContainers = ImmutableMap.builder(); - Map, Identifier>> orderedEntityTypeHierarchy = new HashMap<>(); - - for(Identifier identifier : this.entityTypeData.keySet()) { - if(ENTITY_TYPE_INSTANCES.containsKey(identifier)) { - Pair, Integer> value = ENTITY_TYPE_INSTANCES.get(identifier); - orderedEntityTypeHierarchy.put(value.stalk(), new Pair, Identifier>(value.fruit(), identifier)); - } - if(!entityTypes.contains(identifier)) continue; - - EntityType entityType = (EntityType)Registry.ENTITY_TYPE.get(identifier); - DefaultAttributeContainer.Builder builder = DefaultAttributeContainer.builder(); - EntityTypeData entityTypeData = this.entityTypeData.get(identifier); - entityTypeData.build(builder, DefaultAttributeRegistry.get(entityType)); - explicitContainers.put(entityType, builder.build()); - } - - final int size = orderedEntityTypeHierarchy.size(); - final int max = orderedEntityTypeHierarchy.keySet().stream().mapToInt(Integer::intValue).max().orElse(0); - - for(Map.Entry, Identifier>> entry : orderedEntityTypeHierarchy.entrySet()) { - Pair, Identifier> entityTypeHierarchy = entry.getValue(); - Identifier identifier = entityTypeHierarchy.stalk(); - final int hierarchy = entry.getKey(); - final int index = Math.round((float)size * (float)hierarchy / (float)max) - 1; - DefaultAttributeContainer.Builder builder = DefaultAttributeContainer.builder(); - EntityTypeData entityTypeData = this.entityTypeData.get(identifier); - entityTypeData.build(builder, null); - implicitContainers.put(index, new Pair, DefaultAttributeContainer>(entityTypeHierarchy.fruit(), builder.build())); - } - - this.implicitContainers = implicitContainers.build(); - this.explicitContainers = explicitContainers.build(); + this.handler.buildContainers(this.entityTypeData, ENTITY_TYPE_INSTANCES); AttributesReloadedEvent.EVENT.invoker().onCompletedReload(); } @@ -463,12 +345,10 @@ public CompletableFuture apply(AttributeManager.Wrapper data, ResourceMana ImmutableMap.Builder entityAttributeData = ImmutableMap.builder(); data.entityAttributeData.forEach(entityAttributeData::put); this.entityAttributeData = entityAttributeData.build(); - this.entityAttributeBytes = this.generateCurrentData(this.entityAttributeData); ImmutableMap.Builder entityTypeData = ImmutableMap.builder(); data.entityTypeData.forEach(entityTypeData::put); this.entityTypeData = entityTypeData.build(); - this.entityTypeBytes = this.generateCurrentData(this.entityTypeData); this.apply(); }, executor); @@ -480,11 +360,11 @@ public Identifier getFabricId() { } static { - ENTITY_TYPE_INSTANCES.put(new Identifier(DataAttributesAPI.MODID, DataAttributesAPI.ENTITY_INSTANCE_LIVING_ENTITY), new Pair, Integer>(LivingEntity.class, 0)); - ENTITY_TYPE_INSTANCES.put(new Identifier(DataAttributesAPI.MODID, DataAttributesAPI.ENTITY_INSTANCE_MOB_ENTITY), new Pair, Integer>(MobEntity.class, 1)); - ENTITY_TYPE_INSTANCES.put(new Identifier(DataAttributesAPI.MODID, DataAttributesAPI.ENTITY_INSTANCE_PATH_AWARE_ENTITY), new Pair, Integer>(PathAwareEntity.class, 2)); - ENTITY_TYPE_INSTANCES.put(new Identifier(DataAttributesAPI.MODID, DataAttributesAPI.ENTITY_INSTANCE_HOSTILE_ENTITY), new Pair, Integer>(HostileEntity.class, 3)); - ENTITY_TYPE_INSTANCES.put(new Identifier(DataAttributesAPI.MODID, DataAttributesAPI.ENTITY_INSTANCE_PASSIVE_ENTITY), new Pair, Integer>(PassiveEntity.class, 4)); - ENTITY_TYPE_INSTANCES.put(new Identifier(DataAttributesAPI.MODID, DataAttributesAPI.ENTITY_INSTANCE_ANIMAL_ENTITY), new Pair, Integer>(AnimalEntity.class, 5)); + ENTITY_TYPE_INSTANCES.put(new Identifier(DataAttributesAPI.MODID, DataAttributesAPI.ENTITY_INSTANCE_LIVING_ENTITY), new Tuple(LivingEntity.class, 0)); + ENTITY_TYPE_INSTANCES.put(new Identifier(DataAttributesAPI.MODID, DataAttributesAPI.ENTITY_INSTANCE_MOB_ENTITY), new Tuple(MobEntity.class, 1)); + ENTITY_TYPE_INSTANCES.put(new Identifier(DataAttributesAPI.MODID, DataAttributesAPI.ENTITY_INSTANCE_PATH_AWARE_ENTITY), new Tuple(PathAwareEntity.class, 2)); + ENTITY_TYPE_INSTANCES.put(new Identifier(DataAttributesAPI.MODID, DataAttributesAPI.ENTITY_INSTANCE_HOSTILE_ENTITY), new Tuple(HostileEntity.class, 3)); + ENTITY_TYPE_INSTANCES.put(new Identifier(DataAttributesAPI.MODID, DataAttributesAPI.ENTITY_INSTANCE_PASSIVE_ENTITY), new Tuple(PassiveEntity.class, 4)); + ENTITY_TYPE_INSTANCES.put(new Identifier(DataAttributesAPI.MODID, DataAttributesAPI.ENTITY_INSTANCE_ANIMAL_ENTITY), new Tuple(AnimalEntity.class, 5)); } } diff --git a/src/main/java/com/github/clevernucleus/dataattributes/mixin/ReloadCommandMixin.java b/src/main/java/com/github/clevernucleus/dataattributes/mixin/ReloadCommandMixin.java index 1c9a14e1..13d06a99 100644 --- a/src/main/java/com/github/clevernucleus/dataattributes/mixin/ReloadCommandMixin.java +++ b/src/main/java/com/github/clevernucleus/dataattributes/mixin/ReloadCommandMixin.java @@ -14,6 +14,7 @@ import net.fabricmc.fabric.api.networking.v1.PacketByteBufs; import net.fabricmc.fabric.api.networking.v1.PlayerLookup; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; +import net.minecraft.nbt.NbtCompound; import net.minecraft.network.PacketByteBuf; import net.minecraft.server.MinecraftServer; import net.minecraft.server.command.ReloadCommand; @@ -40,8 +41,9 @@ private static void data_tryReloadDataPacks(Collection dataPacks, Server mutableUpdateFlag.setUpdateFlag(updateFlag2); PacketByteBuf buf = PacketByteBufs.create(); - buf.writeByteArray(DataAttributes.MANAGER.getEntityAttributeData()); - buf.writeByteArray(DataAttributes.MANAGER.getEntityTypeData()); + NbtCompound tag = new NbtCompound(); + DataAttributes.MANAGER.toNbt(tag); + buf.writeNbt(tag); buf.writeInt(mutableUpdateFlag.getUpdateFlag()); PlayerLookup.all(server).forEach(player -> ServerPlayNetworking.send(player, DataAttributes.RELOAD, buf)); } From e49db5dbada1cb75a8d00b16519af591c511e377 Mon Sep 17 00:00:00 2001 From: CleverNucleus Date: Sat, 3 Jun 2023 11:50:42 +0100 Subject: [PATCH 5/8] Updated CHANGELOG. --- CHANGELOG.md | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cd7e73e..366ce687 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,25 +1,17 @@ ### Changelog -+Added hierarchy entity types that can be used to apply attributes to all entities that are an instance of an entity class. Currently supported types are as follows: +This is primarily a bug-fixing and optimisation update. -| **Identifier** | **Class Type** | -| -------------- | -------------- | -| `dataattributes:living_entity` | `LivingEntity` | -| `dataattributes:mob_entity` | `MobEntity` | -| `dataattributes:path_aware_entity` | `PathAwareEntity` | -| `dataattributes:hostile_entity` | `HostileEntity` | -| `dataattributes:passive_entity` | `PassiveEntity` | -| `dataattributes:animal_entity` | `AnimalEntity` | +*Changed the way `/reload` works to refresh attributes: -These have a hierarchy of: + - No longer saves the `updateFlag` to the level's nbt data. + - No longer injects the `updateFlag` into vanilla packets. + - Instead, we only use the `updateFlag` in runtime - not saving it at all, anywhere. -``` -LivingEntity - ┗ MobEntity - ┗ PathAwareEntity - ┣ HostileEntity - ┗ PassiveEntity - ┗ AnimalEntity -``` +*Fixed [#80](https://github.com/CleverNucleus/data-attributes/issues/80): attribute tracking is handled differently now. -This feature is useful for when you want to modify the attributes of many different mobs, but do not know every mob's `EntityType` identifier. \ No newline at end of file +*Likely fixed an incompatibility between Data Attributes and ReplayMod: we no longer mess around with world properties at all. + +**May* have fixed long-standing issues [24](https://github.com/CleverNucleus/data-attributes/issues/24) and [10](https://github.com/CleverNucleus/data-attributes/issues/10): almost all networking has been removed - now we only send/receive two custom packets in the whole mod: on game join and when `/reload` is executed. + +*Various performance improvements. \ No newline at end of file From a25ba2ddafa2c533a2d7e56aecddd77af41d84d5 Mon Sep 17 00:00:00 2001 From: CleverNucleus Date: Sat, 3 Jun 2023 11:51:24 +0100 Subject: [PATCH 6/8] Removed use of world properties. --- .../mixin/LevelPropertiesMixin.java | 50 ------------------- .../mixin/MutableWorldPropertiesMixin.java | 10 ---- .../UnmodifiableLevelPropertiesMixin.java | 27 ---------- .../client/ClientWorldPropertiesMixin.java | 25 ---------- 4 files changed, 112 deletions(-) delete mode 100644 src/main/java/com/github/clevernucleus/dataattributes/mixin/LevelPropertiesMixin.java delete mode 100644 src/main/java/com/github/clevernucleus/dataattributes/mixin/MutableWorldPropertiesMixin.java delete mode 100644 src/main/java/com/github/clevernucleus/dataattributes/mixin/UnmodifiableLevelPropertiesMixin.java delete mode 100644 src/main/java/com/github/clevernucleus/dataattributes/mixin/client/ClientWorldPropertiesMixin.java diff --git a/src/main/java/com/github/clevernucleus/dataattributes/mixin/LevelPropertiesMixin.java b/src/main/java/com/github/clevernucleus/dataattributes/mixin/LevelPropertiesMixin.java deleted file mode 100644 index ebdd8285..00000000 --- a/src/main/java/com/github/clevernucleus/dataattributes/mixin/LevelPropertiesMixin.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.github.clevernucleus.dataattributes.mixin; - -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import com.github.clevernucleus.dataattributes.mutable.MutableIntFlag; -import com.mojang.datafixers.DataFixer; -import com.mojang.serialization.Dynamic; -import com.mojang.serialization.Lifecycle; - -import net.minecraft.nbt.NbtCompound; -import net.minecraft.nbt.NbtElement; -import net.minecraft.util.registry.DynamicRegistryManager; -import net.minecraft.world.gen.GeneratorOptions; -import net.minecraft.world.level.LevelInfo; -import net.minecraft.world.level.LevelProperties; -import net.minecraft.world.level.storage.SaveVersionInfo; - -@Mixin(LevelProperties.class) -abstract class LevelPropertiesMixin implements MutableWorldPropertiesMixin { - - @Unique - private int data_updateFlag; - - @Inject(method = "updateProperties", at = @At("HEAD")) - private void data_updateProperties(DynamicRegistryManager registryManager, NbtCompound levelNbt, @Nullable NbtCompound playerNbt, CallbackInfo ci) { - levelNbt.putInt("AttributeUpdateFlag", this.data_updateFlag); - } - - @Inject(method = "readProperties", at = @At("RETURN")) - private static void data_readProperties(Dynamic dynamic2, DataFixer dataFixer, int dataVersion, @Nullable NbtCompound playerData, LevelInfo levelInfo, SaveVersionInfo saveVersionInfo, GeneratorOptions generatorOptions, Lifecycle lifecycle, CallbackInfoReturnable ci) { - LevelProperties levelProperties = ci.getReturnValue(); - ((MutableIntFlag)levelProperties).setUpdateFlag(dynamic2.get("AttributeUpdateFlag").asInt(0)); - } - - @Override - public void setUpdateFlag(int flag) { - this.data_updateFlag = flag; - } - - @Override - public int getUpdateFlag() { - return this.data_updateFlag; - } -} diff --git a/src/main/java/com/github/clevernucleus/dataattributes/mixin/MutableWorldPropertiesMixin.java b/src/main/java/com/github/clevernucleus/dataattributes/mixin/MutableWorldPropertiesMixin.java deleted file mode 100644 index db524d4c..00000000 --- a/src/main/java/com/github/clevernucleus/dataattributes/mixin/MutableWorldPropertiesMixin.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.github.clevernucleus.dataattributes.mixin; - -import org.spongepowered.asm.mixin.Mixin; - -import com.github.clevernucleus.dataattributes.mutable.MutableIntFlag; - -import net.minecraft.world.MutableWorldProperties; - -@Mixin(MutableWorldProperties.class) -public interface MutableWorldPropertiesMixin extends MutableIntFlag {} diff --git a/src/main/java/com/github/clevernucleus/dataattributes/mixin/UnmodifiableLevelPropertiesMixin.java b/src/main/java/com/github/clevernucleus/dataattributes/mixin/UnmodifiableLevelPropertiesMixin.java deleted file mode 100644 index 23608257..00000000 --- a/src/main/java/com/github/clevernucleus/dataattributes/mixin/UnmodifiableLevelPropertiesMixin.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.github.clevernucleus.dataattributes.mixin; - -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import com.github.clevernucleus.dataattributes.mutable.MutableIntFlag; - -import net.minecraft.world.level.ServerWorldProperties; -import net.minecraft.world.level.UnmodifiableLevelProperties; - -@Mixin(UnmodifiableLevelProperties.class) -abstract class UnmodifiableLevelPropertiesMixin implements MutableWorldPropertiesMixin { - - @Final - @Shadow - private ServerWorldProperties worldProperties; - - @Override - public void setUpdateFlag(int flag) {} - - @Override - public int getUpdateFlag() { - if(!(this.worldProperties instanceof MutableIntFlag)) return 0; - return ((MutableIntFlag)this.worldProperties).getUpdateFlag(); - } -} diff --git a/src/main/java/com/github/clevernucleus/dataattributes/mixin/client/ClientWorldPropertiesMixin.java b/src/main/java/com/github/clevernucleus/dataattributes/mixin/client/ClientWorldPropertiesMixin.java deleted file mode 100644 index c88ff953..00000000 --- a/src/main/java/com/github/clevernucleus/dataattributes/mixin/client/ClientWorldPropertiesMixin.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.github.clevernucleus.dataattributes.mixin.client; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; - -import com.github.clevernucleus.dataattributes.mixin.MutableWorldPropertiesMixin; - -import net.minecraft.client.world.ClientWorld; - -@Mixin(ClientWorld.Properties.class) -abstract class ClientWorldPropertiesMixin implements MutableWorldPropertiesMixin { - - @Unique - private int data_updateFlag; - - @Override - public void setUpdateFlag(int flag) { - this.data_updateFlag = flag; - } - - @Override - public int getUpdateFlag() { - return this.data_updateFlag; - } -} From 27ca39e43a6ab65651afc1a89a77e47bd8a74c1b Mon Sep 17 00:00:00 2001 From: CleverNucleus Date: Sat, 3 Jun 2023 11:51:53 +0100 Subject: [PATCH 7/8] Removed mixin into vanilla packets --- .../mixin/GameJoinS2CPacketMixin.java | 39 -------------- .../mixin/PlayerManagerMixin.java | 53 ------------------- .../mixin/PlayerRespawnS2CPacketMixin.java | 39 -------------- .../mixin/ServerPlayerEntityMixin.java | 46 ---------------- .../client/ClientPlayNetworkHandlerMixin.java | 41 -------------- .../mutable/MutableIntFlag.java | 6 --- src/main/resources/dataattributes.mixins.json | 10 +--- 7 files changed, 1 insertion(+), 233 deletions(-) delete mode 100644 src/main/java/com/github/clevernucleus/dataattributes/mixin/GameJoinS2CPacketMixin.java delete mode 100644 src/main/java/com/github/clevernucleus/dataattributes/mixin/PlayerManagerMixin.java delete mode 100644 src/main/java/com/github/clevernucleus/dataattributes/mixin/PlayerRespawnS2CPacketMixin.java delete mode 100644 src/main/java/com/github/clevernucleus/dataattributes/mixin/ServerPlayerEntityMixin.java delete mode 100644 src/main/java/com/github/clevernucleus/dataattributes/mixin/client/ClientPlayNetworkHandlerMixin.java delete mode 100644 src/main/java/com/github/clevernucleus/dataattributes/mutable/MutableIntFlag.java diff --git a/src/main/java/com/github/clevernucleus/dataattributes/mixin/GameJoinS2CPacketMixin.java b/src/main/java/com/github/clevernucleus/dataattributes/mixin/GameJoinS2CPacketMixin.java deleted file mode 100644 index 5d2ec171..00000000 --- a/src/main/java/com/github/clevernucleus/dataattributes/mixin/GameJoinS2CPacketMixin.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.github.clevernucleus.dataattributes.mixin; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import com.github.clevernucleus.dataattributes.mutable.MutableIntFlag; - -import net.minecraft.network.PacketByteBuf; -import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket; - -@Mixin(GameJoinS2CPacket.class) -abstract class GameJoinS2CPacketMixin implements MutableIntFlag { - - @Unique - private int updateFlag; - - @Inject(method = "", at = @At("TAIL")) - private void data_init(PacketByteBuf buf, CallbackInfo ci) { - this.updateFlag = buf.readInt(); - } - - @Inject(method = "write", at = @At("TAIL")) - private void data_write(PacketByteBuf buf, CallbackInfo ci) { - buf.writeInt(this.updateFlag); - } - - @Override - public void setUpdateFlag(int flag) { - this.updateFlag = flag; - } - - @Override - public int getUpdateFlag() { - return this.updateFlag; - } -} diff --git a/src/main/java/com/github/clevernucleus/dataattributes/mixin/PlayerManagerMixin.java b/src/main/java/com/github/clevernucleus/dataattributes/mixin/PlayerManagerMixin.java deleted file mode 100644 index a170d943..00000000 --- a/src/main/java/com/github/clevernucleus/dataattributes/mixin/PlayerManagerMixin.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.github.clevernucleus.dataattributes.mixin; - -import java.util.List; - -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyArg; - -import com.github.clevernucleus.dataattributes.mutable.MutableIntFlag; - -import net.minecraft.network.Packet; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.PlayerManager; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.world.WorldProperties; - -@Mixin(PlayerManager.class) -abstract class PlayerManagerMixin { - - @Final - @Shadow - private MinecraftServer server; - - @Final - @Shadow - List players; - - @ModifyArg(method = "onPlayerConnect", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerPlayNetworkHandler;sendPacket(Lnet/minecraft/network/Packet;)V", ordinal = 0)) - private Packet data_onPlayerConnect(Packet arg) { - WorldProperties worldProperties = this.server.getOverworld().getLevelProperties(); - - if(arg instanceof MutableIntFlag && worldProperties instanceof MutableIntFlag) { - int updateFlag = ((MutableIntFlag)worldProperties).getUpdateFlag(); - ((MutableIntFlag)arg).setUpdateFlag(updateFlag); - } - - return arg; - } - - @ModifyArg(method = "respawnPlayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerPlayNetworkHandler;sendPacket(Lnet/minecraft/network/Packet;)V", ordinal = 1)) - private Packet data_respawnPlayer(Packet arg) { - WorldProperties worldProperties = this.server.getOverworld().getLevelProperties(); - - if(arg instanceof MutableIntFlag && worldProperties instanceof MutableIntFlag) { - int updateFlag = ((MutableIntFlag)worldProperties).getUpdateFlag(); - ((MutableIntFlag)arg).setUpdateFlag(updateFlag); - } - - return arg; - } -} diff --git a/src/main/java/com/github/clevernucleus/dataattributes/mixin/PlayerRespawnS2CPacketMixin.java b/src/main/java/com/github/clevernucleus/dataattributes/mixin/PlayerRespawnS2CPacketMixin.java deleted file mode 100644 index 3da2996c..00000000 --- a/src/main/java/com/github/clevernucleus/dataattributes/mixin/PlayerRespawnS2CPacketMixin.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.github.clevernucleus.dataattributes.mixin; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import com.github.clevernucleus.dataattributes.mutable.MutableIntFlag; - -import net.minecraft.network.PacketByteBuf; -import net.minecraft.network.packet.s2c.play.PlayerRespawnS2CPacket; - -@Mixin(PlayerRespawnS2CPacket.class) -abstract class PlayerRespawnS2CPacketMixin implements MutableIntFlag { - - @Unique - private int updateFlag; - - @Inject(method = "(Lnet/minecraft/network/PacketByteBuf;)V", at = @At("TAIL")) - private void data_init(PacketByteBuf buf, CallbackInfo ci) { - this.updateFlag = buf.readInt(); - } - - @Inject(method = "write", at = @At("TAIL")) - private void data_write(PacketByteBuf buf, CallbackInfo ci) { - buf.writeInt(this.updateFlag); - } - - @Override - public void setUpdateFlag(int flag) { - this.updateFlag = flag; - } - - @Override - public int getUpdateFlag() { - return this.updateFlag; - } -} diff --git a/src/main/java/com/github/clevernucleus/dataattributes/mixin/ServerPlayerEntityMixin.java b/src/main/java/com/github/clevernucleus/dataattributes/mixin/ServerPlayerEntityMixin.java deleted file mode 100644 index 0947f205..00000000 --- a/src/main/java/com/github/clevernucleus/dataattributes/mixin/ServerPlayerEntityMixin.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.github.clevernucleus.dataattributes.mixin; - -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyArg; - -import com.github.clevernucleus.dataattributes.mutable.MutableIntFlag; - -import net.minecraft.network.Packet; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.world.WorldProperties; - -@Mixin(ServerPlayerEntity.class) -abstract class ServerPlayerEntityMixin { - - @Final - @Shadow - private MinecraftServer server; - - @ModifyArg(method = "moveToWorld", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerPlayNetworkHandler;sendPacket(Lnet/minecraft/network/Packet;)V", ordinal = 1)) - private Packet data_moveToWorld(Packet arg) { - WorldProperties worldProperties = this.server.getOverworld().getLevelProperties(); - - if(arg instanceof MutableIntFlag && worldProperties instanceof MutableIntFlag) { - int updateFlag = ((MutableIntFlag)worldProperties).getUpdateFlag(); - ((MutableIntFlag)arg).setUpdateFlag(updateFlag); - } - - return arg; - } - - @ModifyArg(method = "teleport", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerPlayNetworkHandler;sendPacket(Lnet/minecraft/network/Packet;)V", ordinal = 0)) - private Packet data_teleport(Packet arg) { - WorldProperties worldProperties = this.server.getOverworld().getLevelProperties(); - - if(arg instanceof MutableIntFlag && worldProperties instanceof MutableIntFlag) { - int updateFlag = ((MutableIntFlag)worldProperties).getUpdateFlag(); - ((MutableIntFlag)arg).setUpdateFlag(updateFlag); - } - - return arg; - } -} diff --git a/src/main/java/com/github/clevernucleus/dataattributes/mixin/client/ClientPlayNetworkHandlerMixin.java b/src/main/java/com/github/clevernucleus/dataattributes/mixin/client/ClientPlayNetworkHandlerMixin.java deleted file mode 100644 index 368ce51d..00000000 --- a/src/main/java/com/github/clevernucleus/dataattributes/mixin/client/ClientPlayNetworkHandlerMixin.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.github.clevernucleus.dataattributes.mixin.client; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import com.github.clevernucleus.dataattributes.mutable.MutableIntFlag; - -import net.minecraft.client.network.ClientPlayNetworkHandler; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket; -import net.minecraft.network.packet.s2c.play.PlayerRespawnS2CPacket; - -@Mixin(ClientPlayNetworkHandler.class) -abstract class ClientPlayNetworkHandlerMixin { - - @Shadow - private ClientWorld world; - - @Inject(method = "onGameJoin", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;joinWorld(Lnet/minecraft/client/world/ClientWorld;)V", shift = At.Shift.AFTER)) - private void data_onGameJoin(GameJoinS2CPacket packet, CallbackInfo ci) { - ClientWorld.Properties properties = this.world.getLevelProperties(); - - if(properties instanceof MutableIntFlag) { - int updateFlag = ((MutableIntFlag)(Object)packet).getUpdateFlag(); - ((MutableIntFlag)properties).setUpdateFlag(updateFlag); - } - } - - @Inject(method = "onPlayerRespawn", at = @At("TAIL")) - private void data_onPlayerRespawn(PlayerRespawnS2CPacket packet, CallbackInfo ci) { - ClientWorld.Properties properties = this.world.getLevelProperties(); - - if(properties instanceof MutableIntFlag) { - int updateFlag = ((MutableIntFlag)(Object)packet).getUpdateFlag(); - ((MutableIntFlag)properties).setUpdateFlag(updateFlag); - } - } -} diff --git a/src/main/java/com/github/clevernucleus/dataattributes/mutable/MutableIntFlag.java b/src/main/java/com/github/clevernucleus/dataattributes/mutable/MutableIntFlag.java deleted file mode 100644 index bc8b3926..00000000 --- a/src/main/java/com/github/clevernucleus/dataattributes/mutable/MutableIntFlag.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.github.clevernucleus.dataattributes.mutable; - -public interface MutableIntFlag { - default void setUpdateFlag(int flag) {} - default int getUpdateFlag() { return 0; } -} diff --git a/src/main/resources/dataattributes.mixins.json b/src/main/resources/dataattributes.mixins.json index b2ccc085..9c18ba71 100644 --- a/src/main/resources/dataattributes.mixins.json +++ b/src/main/resources/dataattributes.mixins.json @@ -14,13 +14,6 @@ "LivingEntityMixin", "PlayerEntityMixin", "MobEntityMixin", - "ServerPlayerEntityMixin", - "MutableWorldPropertiesMixin", - "LevelPropertiesMixin", - "UnmodifiableLevelPropertiesMixin", - "GameJoinS2CPacketMixin", - "PlayerRespawnS2CPacketMixin", - "PlayerManagerMixin", "ReloadCommandMixin", "EntityTrackerEntryMixin", "item.ItemMixin", @@ -30,8 +23,7 @@ "item.ItemStackMixin" ], "client": [ - "client.ClientWorldPropertiesMixin", - "client.ClientPlayNetworkHandlerMixin" + ], "injectors": { "defaultRequire": 1 From 7c14c5595734a5660fa8c674e2865a7b3231ac57 Mon Sep 17 00:00:00 2001 From: CleverNucleus Date: Sat, 3 Jun 2023 11:52:10 +0100 Subject: [PATCH 8/8] Bug fixes and various rewrites --- .../dataattributes/DataAttributes.java | 17 +---------- .../dataattributes/DataAttributesClient.java | 27 ++++------------- .../dataattributes/impl/AttributeManager.java | 15 ++++++++-- .../mixin/LivingEntityMixin.java | 14 +++------ .../mixin/ReloadCommandMixin.java | 29 ++++--------------- 5 files changed, 30 insertions(+), 72 deletions(-) diff --git a/src/main/java/com/github/clevernucleus/dataattributes/DataAttributes.java b/src/main/java/com/github/clevernucleus/dataattributes/DataAttributes.java index 205e827c..662d0b21 100644 --- a/src/main/java/com/github/clevernucleus/dataattributes/DataAttributes.java +++ b/src/main/java/com/github/clevernucleus/dataattributes/DataAttributes.java @@ -1,12 +1,9 @@ package com.github.clevernucleus.dataattributes; -import java.util.Arrays; - import org.jetbrains.annotations.Nullable; import com.github.clevernucleus.dataattributes.api.DataAttributesAPI; import com.github.clevernucleus.dataattributes.api.event.EntityAttributeModifiedEvents; -import com.github.clevernucleus.dataattributes.api.util.Maths; import com.github.clevernucleus.dataattributes.impl.AttributeManager; import com.github.clevernucleus.dataattributes.mutable.MutableAttributeContainer; @@ -18,7 +15,6 @@ import net.fabricmc.fabric.api.networking.v1.ServerLoginNetworking; import net.fabricmc.fabric.api.networking.v1.ServerLoginNetworking.LoginSynchronizer; import net.fabricmc.fabric.api.resource.ResourceManagerHelper; -import net.fabricmc.loader.api.FabricLoader; import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.attribute.EntityAttribute; @@ -35,9 +31,6 @@ public class DataAttributes implements ModInitializer { public static final Identifier HANDSHAKE = new Identifier(DataAttributesAPI.MODID, "handshake"); public static final Identifier RELOAD = new Identifier(DataAttributesAPI.MODID, "reload"); public static final AttributeManager MANAGER = new AttributeManager(); - protected static String version = ""; - protected static byte[] semVer; - private static final byte VER_SIZE = 3; private static void loginQueryStart(ServerLoginNetworkHandler handler, MinecraftServer server, PacketSender sender, ServerLoginNetworking.LoginSynchronizer synchronizer) { PacketByteBuf buf = PacketByteBufs.create(); @@ -49,7 +42,7 @@ private static void loginQueryStart(ServerLoginNetworkHandler handler, Minecraft private static void loginQueryResponse(MinecraftServer server, ServerLoginNetworkHandler handler, boolean understood, PacketByteBuf buf, LoginSynchronizer synchronizer, PacketSender responseSender) {} - private static void refreshAttributes(final Entity entity) { + public static void refreshAttributes(final Entity entity) { if(!(entity instanceof LivingEntity)) return; ((MutableAttributeContainer)((LivingEntity)entity).getAttributes()).refresh(); } @@ -67,14 +60,6 @@ private static void healthModified(final EntityAttribute attribute, final @Nulla @Override public void onInitialize() { - version = FabricLoader.getInstance().getModContainer(DataAttributesAPI.MODID).get().getMetadata().getVersion().getFriendlyString(); - String[] versionArray = Arrays.copyOf(version.split("\\."), VER_SIZE); - semVer = new byte[Math.max(versionArray.length, VER_SIZE)]; - - for(int i = 0; i < semVer.length; i++) { - semVer[i] = (byte)Maths.parse(versionArray[i]); - } - ResourceManagerHelper.get(ResourceType.SERVER_DATA).registerReloadListener(MANAGER); ServerLoginConnectionEvents.QUERY_START.register(DataAttributes::loginQueryStart); ServerLoginNetworking.registerGlobalReceiver(HANDSHAKE, DataAttributes::loginQueryResponse); diff --git a/src/main/java/com/github/clevernucleus/dataattributes/DataAttributesClient.java b/src/main/java/com/github/clevernucleus/dataattributes/DataAttributesClient.java index 3bfa6f6f..7541a56c 100644 --- a/src/main/java/com/github/clevernucleus/dataattributes/DataAttributesClient.java +++ b/src/main/java/com/github/clevernucleus/dataattributes/DataAttributesClient.java @@ -3,8 +3,6 @@ import java.util.concurrent.CompletableFuture; import java.util.function.Consumer; -import com.github.clevernucleus.dataattributes.mutable.MutableIntFlag; - import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; import net.fabricmc.api.ClientModInitializer; @@ -15,43 +13,30 @@ import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.ClientLoginNetworkHandler; import net.minecraft.client.network.ClientPlayNetworkHandler; -import net.minecraft.client.world.ClientWorld; import net.minecraft.nbt.NbtCompound; import net.minecraft.network.PacketByteBuf; public class DataAttributesClient implements ClientModInitializer { private static CompletableFuture loginQueryReceived(MinecraftClient client, ClientLoginNetworkHandler handler, PacketByteBuf buf, Consumer>> listenerAdder) { - NbtCompound tag = buf.readNbt(); - - client.execute(() -> { - if(tag != null) { - DataAttributes.MANAGER.fromNbt(tag); - DataAttributes.MANAGER.apply(); - } - }); - + onPacketReceived(client, buf); return CompletableFuture.completedFuture(PacketByteBufs.empty()); } private static void updateReceived(MinecraftClient client, ClientPlayNetworkHandler handler, PacketByteBuf buf, PacketSender responseSender) { + onPacketReceived(client, buf); + } + + private static void onPacketReceived(MinecraftClient client, PacketByteBuf buf) { NbtCompound tag = buf.readNbt(); - final int updateFlag = buf.readInt(); client.execute(() -> { if(tag != null) { DataAttributes.MANAGER.fromNbt(tag); DataAttributes.MANAGER.apply(); } - - ClientWorld world = client.world; - - if(world != null) { - ClientWorld.Properties properties = world.getLevelProperties(); - ((MutableIntFlag)properties).setUpdateFlag(updateFlag); - } }); } - + @Override public void onInitializeClient() { ClientLoginNetworking.registerGlobalReceiver(DataAttributes.HANDSHAKE, DataAttributesClient::loginQueryReceived); diff --git a/src/main/java/com/github/clevernucleus/dataattributes/impl/AttributeManager.java b/src/main/java/com/github/clevernucleus/dataattributes/impl/AttributeManager.java index afe91c43..66717136 100644 --- a/src/main/java/com/github/clevernucleus/dataattributes/impl/AttributeManager.java +++ b/src/main/java/com/github/clevernucleus/dataattributes/impl/AttributeManager.java @@ -52,12 +52,13 @@ public final class AttributeManager implements SimpleResourceReloadListener entityAttributeData = ImmutableMap.of(); private Map entityTypeData = ImmutableMap.of(); private AttributeContainerHandler handler = new AttributeContainerHandler(); - + private int updateFlag = 0; + protected static final record Tuple(Class livingEntity, T value) {} protected static final record Wrapper(Map entityAttributeData, Map entityTypeData) {} public AttributeManager() {} - + private static Map formatFunctions(Map functionsIn) { Map functions = new HashMap(); @@ -262,6 +263,7 @@ public void toNbt(NbtCompound tag) { tag.put("Attributes", entityAttributeNbt); tag.put("EntityTypes", entityTypeNbt); + tag.putInt("UpdateFlag", this.updateFlag); } public void fromNbt(NbtCompound tag) { @@ -288,6 +290,15 @@ public void fromNbt(NbtCompound tag) { }); this.entityTypeData = builder.build(); } + this.updateFlag = tag.getInt("UpdateFlag"); + } + + public void nextUpdateFlag() { + this.updateFlag++; + } + + public int getUpdateFlag() { + return this.updateFlag; } public AttributeContainer getContainer(final EntityType entityType, final LivingEntity livingEntity) { diff --git a/src/main/java/com/github/clevernucleus/dataattributes/mixin/LivingEntityMixin.java b/src/main/java/com/github/clevernucleus/dataattributes/mixin/LivingEntityMixin.java index 59d094fb..5ea4d8e6 100644 --- a/src/main/java/com/github/clevernucleus/dataattributes/mixin/LivingEntityMixin.java +++ b/src/main/java/com/github/clevernucleus/dataattributes/mixin/LivingEntityMixin.java @@ -9,13 +9,11 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.github.clevernucleus.dataattributes.DataAttributes; -import com.github.clevernucleus.dataattributes.mutable.MutableIntFlag; import net.minecraft.entity.EntityType; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.attribute.AttributeContainer; import net.minecraft.world.World; -import net.minecraft.world.WorldProperties; @Mixin(value = LivingEntity.class, priority = 999) abstract class LivingEntityMixin { @@ -27,24 +25,18 @@ abstract class LivingEntityMixin { @Unique private int data_updateFlag; - private int data_checkedUpdateFlag(World world) { - WorldProperties worldProperties = world.getLevelProperties(); - if(!(worldProperties instanceof MutableIntFlag)) return 0; - return ((MutableIntFlag)worldProperties).getUpdateFlag(); - } - @Inject(method = "", at = @At("TAIL")) private void data_init(EntityType entityType, World world, CallbackInfo ci) { LivingEntity livingEntity = (LivingEntity)(Object)this; this.attributes = DataAttributes.MANAGER.getContainer(entityType, livingEntity); - this.data_updateFlag = this.data_checkedUpdateFlag(world); + this.data_updateFlag = DataAttributes.MANAGER.getUpdateFlag(); livingEntity.setHealth(livingEntity.getMaxHealth()); } @Inject(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;tickActiveItemStack()V")) private void data_tick(CallbackInfo ci) { LivingEntity livingEntity = (LivingEntity)(Object)this; - final int updateFlag = this.data_checkedUpdateFlag(livingEntity.world); + final int updateFlag = DataAttributes.MANAGER.getUpdateFlag(); if(this.data_updateFlag != updateFlag) { AttributeContainer container = livingEntity.getAttributes(); @@ -54,6 +46,8 @@ private void data_tick(CallbackInfo ci) { container2.setFrom(container); this.attributes = container2; this.data_updateFlag = updateFlag; + + DataAttributes.refreshAttributes(livingEntity); } } } diff --git a/src/main/java/com/github/clevernucleus/dataattributes/mixin/ReloadCommandMixin.java b/src/main/java/com/github/clevernucleus/dataattributes/mixin/ReloadCommandMixin.java index 13d06a99..4a8757a2 100644 --- a/src/main/java/com/github/clevernucleus/dataattributes/mixin/ReloadCommandMixin.java +++ b/src/main/java/com/github/clevernucleus/dataattributes/mixin/ReloadCommandMixin.java @@ -1,7 +1,6 @@ package com.github.clevernucleus.dataattributes.mixin; import java.util.Collection; -import java.util.Random; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -9,7 +8,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.github.clevernucleus.dataattributes.DataAttributes; -import com.github.clevernucleus.dataattributes.mutable.MutableIntFlag; import net.fabricmc.fabric.api.networking.v1.PacketByteBufs; import net.fabricmc.fabric.api.networking.v1.PlayerLookup; @@ -19,7 +17,6 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.server.command.ReloadCommand; import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.world.level.ServerWorldProperties; @Mixin(ReloadCommand.class) abstract class ReloadCommandMixin { @@ -27,25 +24,11 @@ abstract class ReloadCommandMixin { @Inject(method = "tryReloadDataPacks", at = @At("TAIL")) private static void data_tryReloadDataPacks(Collection dataPacks, ServerCommandSource source, CallbackInfo ci) { MinecraftServer server = source.getServer(); - ServerWorldProperties serverWorldProperties = server.getSaveProperties().getMainWorldProperties(); - - if(serverWorldProperties instanceof MutableIntFlag) { - MutableIntFlag mutableUpdateFlag = (MutableIntFlag)serverWorldProperties; - final int updateFlag = mutableUpdateFlag.getUpdateFlag(); - int updateFlag2 = updateFlag; - - while(updateFlag2 == updateFlag) { - updateFlag2 = (new Random()).nextInt(); - } - - mutableUpdateFlag.setUpdateFlag(updateFlag2); - - PacketByteBuf buf = PacketByteBufs.create(); - NbtCompound tag = new NbtCompound(); - DataAttributes.MANAGER.toNbt(tag); - buf.writeNbt(tag); - buf.writeInt(mutableUpdateFlag.getUpdateFlag()); - PlayerLookup.all(server).forEach(player -> ServerPlayNetworking.send(player, DataAttributes.RELOAD, buf)); - } + PacketByteBuf buf = PacketByteBufs.create(); + NbtCompound tag = new NbtCompound(); + DataAttributes.MANAGER.nextUpdateFlag(); + DataAttributes.MANAGER.toNbt(tag); + buf.writeNbt(tag); + PlayerLookup.all(server).forEach(player -> ServerPlayNetworking.send(player, DataAttributes.RELOAD, buf)); } }