diff --git a/build.gradle b/build.gradle index b165df33..af070dbe 100644 --- a/build.gradle +++ b/build.gradle @@ -75,6 +75,8 @@ allprojects { mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" modCompileOnly "net.fabricmc:fabric-loader:${project.loader_version}" modLocalRuntime "net.fabricmc:fabric-loader:${project.loader_version}" + + annotationProcessor("io.github.llamalad7:mixinextras-fabric:${mixin_extras_version}") } loom { diff --git a/gradle.properties b/gradle.properties index e0ef017e..4dd6e952 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,10 +12,11 @@ fabric_version=0.83.0+1.20.1 maven_group = eu.pb4 -mod_version = 0.5.14 +mod_version = 0.5.15 minecraft_version_supported = ">=1.20-" packet_tweaker_version = 0.4.0+1.19.4 +mixin_extras_version = 0.2.0-rc.1 is_stable = true diff --git a/polymer-autohost/build.gradle b/polymer-autohost/build.gradle index 2ad2b883..56274043 100644 --- a/polymer-autohost/build.gradle +++ b/polymer-autohost/build.gradle @@ -39,7 +39,6 @@ dependencies { localRuntime (project(path: ':polymer-virtual-entity', configuration: 'namedElements')) modLocalRuntime("xyz.nucleoid:server-translations-api:2.0.0-beta.2+1.19.4-pre2") - project(":polymer-core").afterEvaluate { testmodImplementation project(":polymer-core").sourceSets.testmod.output } diff --git a/polymer-common/build.gradle b/polymer-common/build.gradle index 1ccab332..79e1bdaa 100644 --- a/polymer-common/build.gradle +++ b/polymer-common/build.gradle @@ -11,7 +11,7 @@ dependencies { modApi include("xyz.nucleoid:packet-tweaker:${packet_tweaker_version}") { transitive(false) } - modApi(include(annotationProcessor("com.llamalad7.mixinextras:mixinextras-fabric:0.2.0-beta.9"))) + modApi(include(annotationProcessor("io.github.llamalad7:mixinextras-fabric:${mixin_extras_version}"))) modCompileOnly "xyz.nucleoid:disguiselib-fabric:1.2.2" modCompileOnly "org.geysermc.floodgate:api:2.2.0-SNAPSHOT" } diff --git a/polymer-common/src/main/java/eu/pb4/polymer/common/api/PolymerCommonUtils.java b/polymer-common/src/main/java/eu/pb4/polymer/common/api/PolymerCommonUtils.java index 14218d88..523e0536 100644 --- a/polymer-common/src/main/java/eu/pb4/polymer/common/api/PolymerCommonUtils.java +++ b/polymer-common/src/main/java/eu/pb4/polymer/common/api/PolymerCommonUtils.java @@ -172,6 +172,14 @@ public static boolean hasResourcePack(@Nullable ServerPlayerEntity player) { || (CommonImpl.IS_CLIENT && ClientUtils.isResourcePackLoaded()); } + public static boolean isServerBound() { + if (CommonImpl.IS_CLIENT) { + return ClientUtils.isSingleplayer(); + } + + return true; + } + public interface ResourcePackChangeCallback { void onResourcePackChange(ServerPlayNetworkHandler handler, boolean oldStatus, boolean newStatus); } diff --git a/polymer-common/src/main/java/eu/pb4/polymer/common/impl/CommonImpl.java b/polymer-common/src/main/java/eu/pb4/polymer/common/impl/CommonImpl.java index 66a80f26..92023daa 100644 --- a/polymer-common/src/main/java/eu/pb4/polymer/common/impl/CommonImpl.java +++ b/polymer-common/src/main/java/eu/pb4/polymer/common/impl/CommonImpl.java @@ -58,6 +58,13 @@ public static void addContributor(Person person) { static { new CompatStatus(); + if (CompatStatus.FORGE_CONNECTOR) { + LOGGER.warn("=================================================================================="); + LOGGER.warn("Polymer (" + VERSION + ") support for Connector/Forge is highly experimental!"); + LOGGER.warn("Things might not work correctly if at all, so you are on your own!"); + LOGGER.warn("================================================================================="); + } + var config = loadConfig("common", CommonConfig.class); CORE_COMMAND_MINIMAL_OP = config.coreCommandOperatorLevel; DEVELOPER_MODE = config.enableDevTools || DEV_ENV; diff --git a/polymer-common/src/main/java/eu/pb4/polymer/common/impl/CompatStatus.java b/polymer-common/src/main/java/eu/pb4/polymer/common/impl/CompatStatus.java index a1c5a93a..eebd7077 100644 --- a/polymer-common/src/main/java/eu/pb4/polymer/common/impl/CompatStatus.java +++ b/polymer-common/src/main/java/eu/pb4/polymer/common/impl/CompatStatus.java @@ -30,6 +30,8 @@ public final class CompatStatus { public static final boolean QUILT_ITEM_GROUP = LOADER.isModLoaded("quilt_item_group"); public static final boolean QUILT_REGISTRY = LOADER.isModLoaded("quilt_registry"); + public static final boolean FORGE_CONNECTOR = LOADER.isModLoaded("connectormod"); + public static final boolean POLYMC = LOADER.isModLoaded("polymc"); public static final boolean LITHIUM = LOADER.isModLoaded("lithium"); public static final boolean DISGUISELIB = LOADER.isModLoaded("disguiselib"); diff --git a/polymer-core/build.gradle b/polymer-core/build.gradle index 3348fdaa..942f0126 100644 --- a/polymer-core/build.gradle +++ b/polymer-core/build.gradle @@ -59,7 +59,7 @@ dependencies { modCompileOnly "mcp.mobius.waila:wthit:fabric-5.1.3" //modCompileOnly "me.shedaniel:RoughlyEnoughItems-api-fabric:9.1.530" - modCompileOnly /*modLocalRuntime*/ ("me.shedaniel:RoughlyEnoughItems-fabric:10.0.592") + modCompileOnly /*modLocalRuntime*/ ("me.shedaniel:RoughlyEnoughItems-fabric:12.0.645") modCompileOnly /*modLocalRuntime*/("dev.emi:emi-fabric:1.0.19+1.20.1") //modCompileOnlyApi modLocalRuntime("mezz.jei:jei-1.19-common:11.0.0.206") diff --git a/polymer-core/src/main/java/eu/pb4/polymer/core/api/item/PolymerItemUtils.java b/polymer-core/src/main/java/eu/pb4/polymer/core/api/item/PolymerItemUtils.java index a72ac2d2..f4f5b114 100644 --- a/polymer-core/src/main/java/eu/pb4/polymer/core/api/item/PolymerItemUtils.java +++ b/polymer-core/src/main/java/eu/pb4/polymer/core/api/item/PolymerItemUtils.java @@ -334,7 +334,7 @@ public static ItemStack createItemStack(ItemStack itemStack, TooltipContext tool NbtList lore = new NbtList(); if (itemStack.getNbt() != null) { - out.getNbt().put(PolymerItemUtils.REAL_TAG, itemStack.getNbt()); + out.getNbt().put(PolymerItemUtils.REAL_TAG, removeStackMarker(itemStack.getNbt())); assert out.getNbt() != null; cmd = cmd == -1 && itemStack.getNbt().contains("CustomModelData") ? itemStack.getNbt().getInt("CustomModelData") : cmd; @@ -512,6 +512,24 @@ public static ItemStack createItemStack(ItemStack itemStack, TooltipContext tool }); } + private static NbtElement removeStackMarker(NbtElement nbt) { + if (nbt instanceof NbtCompound compound) { + var out = new NbtCompound(); + for (var entry : compound.getKeys()) { + out.put(entry, removeStackMarker(compound.get(entry))); + } + return out; + } else if (nbt instanceof NbtList list) { + var out = new NbtList(); + for (var entry : list) { + out.add(removeStackMarker(entry)); + } + return out; + } + + return nbt; + } + /** * This method is minimal wrapper around {@link PolymerItem#getPolymerItem(ItemStack, ServerPlayerEntity)} to make sure * It gets replaced if it represents other PolymerItem diff --git a/polymer-core/src/main/java/eu/pb4/polymer/core/impl/PolymerImplUtils.java b/polymer-core/src/main/java/eu/pb4/polymer/core/impl/PolymerImplUtils.java index 3ab95241..90a437cb 100644 --- a/polymer-core/src/main/java/eu/pb4/polymer/core/impl/PolymerImplUtils.java +++ b/polymer-core/src/main/java/eu/pb4/polymer/core/impl/PolymerImplUtils.java @@ -268,6 +268,6 @@ public static ItemStack convertStack(ItemStack representation, ServerPlayerEntit } public static ItemStack convertStack(ItemStack representation, ServerPlayerEntity player, TooltipContext context) { - return ServerTranslationUtils.parseFor(player.networkHandler, PolyMcUtils.toVanilla(PolymerItemUtils.getPolymerItemStack(representation, context, player), player)); + return ServerTranslationUtils.parseFor(player.networkHandler, PolyMcUtils.toVanilla(PolymerItemUtils.getPolymerItemStack(representation, context, player), player)); } } diff --git a/polymer-core/src/main/java/eu/pb4/polymer/core/impl/client/InternalClientRegistry.java b/polymer-core/src/main/java/eu/pb4/polymer/core/impl/client/InternalClientRegistry.java index 25b4b968..add3a18a 100644 --- a/polymer-core/src/main/java/eu/pb4/polymer/core/impl/client/InternalClientRegistry.java +++ b/polymer-core/src/main/java/eu/pb4/polymer/core/impl/client/InternalClientRegistry.java @@ -303,7 +303,7 @@ public static void tick() { regInfo.append(", "); } - regInfo.append("BS: " + InternalClientRegistry.BLOCK_STATES.mapSize()); + regInfo.append("BS: ").append(InternalClientRegistry.BLOCK_STATES.mapSize()); debugRegistryInfo = regInfo.toString(); @@ -330,7 +330,7 @@ public static void clear() { try { ((ClientItemGroupExtension) group).polymer$clearStacks(); } catch (Throwable e) { - e.printStackTrace(); + PolymerImpl.LOGGER.warn("Can't clear stacks of ItemGroup!", e); } } } @@ -339,7 +339,7 @@ public static void clear() { ItemGroupsAccessor.callUpdateEntries(ItemGroupsAccessor.getDisplayContext()); } } catch (Throwable e) { - e.printStackTrace(); + PolymerImpl.LOGGER.warn("Can't update entries of ItemGroups!", e); } }); PolymerClientUtils.ON_CLEAR.invoke(EventRunners.RUN); @@ -352,17 +352,7 @@ public static void clearTabs(Predicate removePredicate) ITEM_GROUPS.removeIf(removePredicate); CreativeInventoryScreenAccessor.setSelectedTab(ItemGroups.getDefaultTab()); - if (CompatStatus.FABRIC_ITEM_GROUP) { - try { - /*ItemGroupHelper.sortedGroups = validated.stream().sorted((a, b) -> { - if (a.isSpecial() && !b.isSpecial()) return 1; - if (!a.isSpecial() && b.isSpecial()) return -1; - return 0; - }).toList();*/ - } catch (Throwable e) { - - } - + if (CompatStatus.FABRIC_ITEM_GROUP && !CompatStatus.FORGE_CONNECTOR) { try { var f1 = CreativeInventoryScreen.class.getDeclaredField("fabric_currentPage"); f1.setAccessible(true); @@ -388,7 +378,18 @@ public static void clearTabs(Predicate removePredicate) PolymerImpl.LOGGER.error("Failed to change item group page (QUILT)!", e); } } + } + if (CompatStatus.FORGE_CONNECTOR) { + try { + var f1 = Class.forName("net.minecraftforge.common.CreativeModeTabRegistry").getDeclaredField("SORTED_TABS"); + f1.setAccessible(true); + ((List) f1.get(null)).removeIf((x) -> x instanceof InternalClientItemGroup ig && removePredicate.test(ig)); + } catch (Throwable e) { + if (PolymerImpl.LOG_MORE_ERRORS) { + PolymerImpl.LOGGER.error("Failed to change item group page (FORGE)!", e); + } + } } int count = Registries.ITEM_GROUP.size() - 4; @@ -408,11 +409,11 @@ public static void clearTabs(Predicate removePredicate) private static void setItemGroupPage(ItemGroup group, int page) { ((ClientItemGroupExtension) group).polymerCore$setPage(page); - if (CompatStatus.FABRIC_ITEM_GROUP) { + if (CompatStatus.FABRIC_ITEM_GROUP && !CompatStatus.FORGE_CONNECTOR) { try { ((net.fabricmc.fabric.impl.itemgroup.FabricItemGroup) group).setPage(page); } catch (Throwable e) { - e.printStackTrace(); + PolymerImpl.LOGGER.warn("Couldn't set page of ItemGroup (FABRIC)", e); } } } @@ -432,6 +433,19 @@ public static void createItemGroup(Identifier id, Text name, ItemStack icon) { var group = new InternalClientItemGroup(row, c, id, name, icon); ITEM_GROUPS.set(id, group); + + if (CompatStatus.FORGE_CONNECTOR) { + try { + var f1 = Class.forName("net.minecraftforge.common.CreativeModeTabRegistry").getDeclaredField("SORTED_TABS"); + f1.setAccessible(true); + ((List) f1.get(null)).add(group); + } catch (Throwable e) { + if (PolymerImpl.LOG_MORE_ERRORS) { + PolymerImpl.LOGGER.error("Failed to change item group page (FORGE)!", e); + } + } + } + setItemGroupPage(group, page); } catch(Throwable e) { diff --git a/polymer-core/src/main/java/eu/pb4/polymer/core/impl/client/networking/PolymerClientProtocolHandler.java b/polymer-core/src/main/java/eu/pb4/polymer/core/impl/client/networking/PolymerClientProtocolHandler.java index f749837b..54537e98 100644 --- a/polymer-core/src/main/java/eu/pb4/polymer/core/impl/client/networking/PolymerClientProtocolHandler.java +++ b/polymer-core/src/main/java/eu/pb4/polymer/core/impl/client/networking/PolymerClientProtocolHandler.java @@ -81,7 +81,7 @@ public static void register() { )); })); registerPacketHandler(ServerPackets.SYNC_BLOCKSTATE, (handler, version, buf) -> handleGenericSync(handler, version, buf, PolymerBlockStateEntry::read, - (entry) -> InternalClientRegistry.BLOCK_STATES.set(new ClientPolymerBlock.State(entry.states(), InternalClientRegistry.BLOCKS.get(entry.blockId()), blockStateOrNull(entry.states(), InternalClientRegistry.BLOCKS.get(entry.blockId()))), entry.numId()))); + (entry) -> InternalClientRegistry.BLOCK_STATES.set(new ClientPolymerBlock.State(entry.properties(), InternalClientRegistry.BLOCKS.get(entry.blockId()), blockStateOrNull(entry.properties(), InternalClientRegistry.BLOCKS.get(entry.blockId()))), entry.numId()))); registerPacketHandler(ServerPackets.SYNC_ENTITY, (handler, version, buf) -> handleGenericSync(handler, version, buf, PolymerEntityEntry::read, (entry) -> InternalClientRegistry.ENTITY_TYPES.set(entry.identifier(), entry.rawId(), new ClientPolymerEntityType(entry.identifier(), entry.name(), Registries.ENTITY_TYPE.get(entry.identifier()))))); diff --git a/polymer-core/src/main/java/eu/pb4/polymer/core/impl/compat/polymc/PolyMcUtils.java b/polymer-core/src/main/java/eu/pb4/polymer/core/impl/compat/polymc/PolyMcUtils.java index a25f9212..1cffb049 100644 --- a/polymer-core/src/main/java/eu/pb4/polymer/core/impl/compat/polymc/PolyMcUtils.java +++ b/polymer-core/src/main/java/eu/pb4/polymer/core/impl/compat/polymc/PolyMcUtils.java @@ -21,11 +21,12 @@ public static BlockState toVanilla(BlockState state, ServerPlayerEntity player) } public static ItemStack toVanilla(ItemStack stack, ServerPlayerEntity player) { - if (CompatStatus.POLYMC) { + if (CompatStatus.POLYMC && !stack.isEmpty()) { var out = PolyMapProvider.getPolyMap(player).getClientItem(stack, player, ItemLocation.INVENTORY); - if (!ItemStack.canCombine(stack, out) && !stack.isEmpty()) { + if (!ItemStack.canCombine(stack, out)) { out = out.copy(); out.setSubNbt("PolyMcOriginal", stack.writeNbt(new NbtCompound())); + return out; } } diff --git a/polymer-core/src/main/java/eu/pb4/polymer/core/impl/interfaces/ItemStackAwareNbtCompound.java b/polymer-core/src/main/java/eu/pb4/polymer/core/impl/interfaces/ItemStackAwareNbtCompound.java index 2fac1602..8a70b516 100644 --- a/polymer-core/src/main/java/eu/pb4/polymer/core/impl/interfaces/ItemStackAwareNbtCompound.java +++ b/polymer-core/src/main/java/eu/pb4/polymer/core/impl/interfaces/ItemStackAwareNbtCompound.java @@ -1,7 +1,13 @@ package eu.pb4.polymer.core.impl.interfaces; -import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NbtByte; +import net.minecraft.nbt.NbtElement; public interface ItemStackAwareNbtCompound { + String MARKER_KEY = "$$polymer:itemstack"; + NbtElement MARKER_VALUE = NbtByte.of((byte) 1); default void polymerCore$setItemStack(boolean bool) {}; + default boolean polymerCore$getItemStack() { + return false; + }; } diff --git a/polymer-core/src/main/java/eu/pb4/polymer/core/impl/interfaces/PolymerIdList.java b/polymer-core/src/main/java/eu/pb4/polymer/core/impl/interfaces/PolymerIdList.java index 7fc35466..a101f927 100644 --- a/polymer-core/src/main/java/eu/pb4/polymer/core/impl/interfaces/PolymerIdList.java +++ b/polymer-core/src/main/java/eu/pb4/polymer/core/impl/interfaces/PolymerIdList.java @@ -14,8 +14,9 @@ public interface PolymerIdList { int polymer$getOffset(); void polymer$clear(); - int polymer$getVanillaBitCount(); + int polymer$getNonPolymerBitCount(); void polymer$setReorderLock(boolean value); boolean polymer$getReorderLock(); + int polymer$getVanillaBitCount(); } diff --git a/polymer-core/src/main/java/eu/pb4/polymer/core/impl/networking/PolymerServerProtocol.java b/polymer-core/src/main/java/eu/pb4/polymer/core/impl/networking/PolymerServerProtocol.java index e0ff57cc..522a7252 100644 --- a/polymer-core/src/main/java/eu/pb4/polymer/core/impl/networking/PolymerServerProtocol.java +++ b/polymer-core/src/main/java/eu/pb4/polymer/core/impl/networking/PolymerServerProtocol.java @@ -54,19 +54,19 @@ public static void sendBlockUpdate(ServerPlayNetworkHandler player, BlockPos pos } - public static void sendMultiBlockUpdate(ServerPlayNetworkHandler player, ChunkSectionPos chunkPos, short[] positions, BlockState[] blockSTATE_IDS) { + public static void sendMultiBlockUpdate(ServerPlayNetworkHandler player, ChunkSectionPos chunkPos, short[] positions, BlockState[] blockStates) { var version = PolymerServerNetworking.getSupportedVersion(player, ServerPackets.WORLD_CHUNK_SECTION_UPDATE); if (version > -1) { var list = new LongArrayList(); - for (int i = 0; i < blockSTATE_IDS.length; i++) { - if (PolymerImplUtils.POLYMER_STATES.contains(blockSTATE_IDS[i])) { - list.add(((long) Block.STATE_IDS.getRawId(blockSTATE_IDS[i])) << 12 | positions[i]); + for (int i = 0; i < blockStates.length; i++) { + if (PolymerImplUtils.POLYMER_STATES.contains(blockStates[i])) { + list.add(((long) Block.STATE_IDS.getRawId(blockStates[i])) << 12 | positions[i]); } } - if (list.size() != 0) { + if (!list.isEmpty()) { var buf = buf(version); buf.writeChunkSectionPos(chunkPos); buf.writeVarInt(list.size()); diff --git a/polymer-core/src/main/java/eu/pb4/polymer/core/impl/networking/packets/PolymerBlockStateEntry.java b/polymer-core/src/main/java/eu/pb4/polymer/core/impl/networking/packets/PolymerBlockStateEntry.java index a9027216..04f23a58 100644 --- a/polymer-core/src/main/java/eu/pb4/polymer/core/impl/networking/packets/PolymerBlockStateEntry.java +++ b/polymer-core/src/main/java/eu/pb4/polymer/core/impl/networking/packets/PolymerBlockStateEntry.java @@ -13,13 +13,13 @@ import java.util.Map; @ApiStatus.Internal -public record PolymerBlockStateEntry(Map states, int numId, int blockId) implements BufferWritable { +public record PolymerBlockStateEntry(Map properties, int numId, int blockId) implements BufferWritable { public static final IdentityHashMap CACHE = new IdentityHashMap<>(); public void write(PacketByteBuf buf, int version, ServerPlayNetworkHandler handler) { buf.writeVarInt(numId); buf.writeVarInt(blockId); - buf.writeMap(states, PacketByteBuf::writeString, PacketByteBuf::writeString); + buf.writeMap(properties, PacketByteBuf::writeString, PacketByteBuf::writeString); } public static PolymerBlockStateEntry of(BlockState state, ServerPlayNetworkHandler player, int version) { diff --git a/polymer-core/src/main/java/eu/pb4/polymer/core/mixin/block/packet/PalettedContainerDataMixin.java b/polymer-core/src/main/java/eu/pb4/polymer/core/mixin/block/packet/PalettedContainerDataMixin.java index 525ec5a2..54d24bbc 100644 --- a/polymer-core/src/main/java/eu/pb4/polymer/core/mixin/block/packet/PalettedContainerDataMixin.java +++ b/polymer-core/src/main/java/eu/pb4/polymer/core/mixin/block/packet/PalettedContainerDataMixin.java @@ -1,8 +1,10 @@ package eu.pb4.polymer.core.mixin.block.packet; +import com.llamalad7.mixinextras.injector.ModifyReceiver; import eu.pb4.polymer.core.api.block.PolymerBlockUtils; import eu.pb4.polymer.core.api.utils.PolymerUtils; import eu.pb4.polymer.core.impl.ClientMetadataKeys; +import eu.pb4.polymer.core.impl.PolymerImpl; import eu.pb4.polymer.core.impl.interfaces.PolymerIdList; import eu.pb4.polymer.networking.api.PolymerServerNetworking; import net.minecraft.block.Block; @@ -12,46 +14,46 @@ import net.minecraft.util.collection.PaletteStorage; import net.minecraft.world.chunk.IdListPalette; import net.minecraft.world.chunk.Palette; +import net.minecraft.world.chunk.PalettedContainer; 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 org.spongepowered.asm.mixin.injection.Redirect; -@Mixin(targets = "net/minecraft/world/chunk/PalettedContainer$Data") -public class PalettedContainerDataMixin { - @Shadow @Final private Palette palette; +@Mixin(PalettedContainer.Data.class) +public abstract class PalettedContainerDataMixin { + @Shadow public abstract Palette palette(); - @Shadow @Final private PaletteStorage storage; - - @ModifyArg(method = "writePacket", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/PacketByteBuf;writeLongArray([J)Lnet/minecraft/network/PacketByteBuf;"), require = 0) - private long[] polymer$replaceData(long[] initialReturn) { - if (this.palette instanceof IdListPalette && this.palette.get(0) instanceof BlockState) { - var palette = (IdListPalette) this.palette; + @ModifyReceiver(method = "writePacket", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/collection/PaletteStorage;getData()[J"), require = 0) + private PaletteStorage polymer$replaceData(PaletteStorage storage) { + var palette = this.palette(); + if (palette instanceof IdListPalette && palette.get(0) instanceof BlockState) { var player = PolymerUtils.getPlayerContext(); if (player == null) { - return initialReturn; + return storage; } int bits; var playerBitCount = PolymerServerNetworking.getMetadata(player.networkHandler, ClientMetadataKeys.BLOCKSTATE_BITS, NbtInt.TYPE); if (playerBitCount == null) { - bits = ((PolymerIdList) Block.STATE_IDS).polymer$getVanillaBitCount(); + bits = PolymerImpl.SYNC_MODDED_ENTRIES_POLYMC + ? ((PolymerIdList) Block.STATE_IDS).polymer$getVanillaBitCount() + : ((PolymerIdList) Block.STATE_IDS).polymer$getNonPolymerBitCount(); } else { bits = playerBitCount.intValue(); } - final var instance = new PackedIntegerArray(this.storage.getElementBits(), this.storage.getSize(), initialReturn); - final int size = instance.getSize(); + final int size = storage.getSize(); var data = new PackedIntegerArray(bits, size); + var stateMap = Block.STATE_IDS; + for (int i = 0; i < size; i++) { - data.set(i, palette.index(PolymerBlockUtils.getPolymerBlockState(palette.get(instance.get(i)), player))); + data.set(i, stateMap.getRawId(PolymerBlockUtils.getPolymerBlockState(stateMap.get(storage.get(i)), player))); } - return data.getData(); + return data; } - return initialReturn; + return storage; } } diff --git a/polymer-core/src/main/java/eu/pb4/polymer/core/mixin/client/compat/emi_EmiScreenManager.java b/polymer-core/src/main/java/eu/pb4/polymer/core/mixin/client/compat/emi_EmiScreenManager.java new file mode 100644 index 00000000..0709653c --- /dev/null +++ b/polymer-core/src/main/java/eu/pb4/polymer/core/mixin/client/compat/emi_EmiScreenManager.java @@ -0,0 +1,41 @@ +package eu.pb4.polymer.core.mixin.client.compat; + +import com.llamalad7.mixinextras.sugar.Local; +import dev.emi.emi.api.stack.EmiStack; +import dev.emi.emi.screen.EmiScreenManager; +import eu.pb4.polymer.core.api.item.PolymerItemUtils; +import eu.pb4.polymer.core.impl.client.compat.CompatUtils; +import net.minecraft.client.MinecraftClient; +import net.minecraft.item.ItemStack; +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.CallbackInfoReturnable; + +@Mixin(EmiScreenManager.class) +public class emi_EmiScreenManager { + @Shadow private static MinecraftClient client; + + @Inject(method = "give", at = @At(value = "INVOKE", target = "Lnet/minecraft/registry/Registry;getId(Ljava/lang/Object;)Lnet/minecraft/util/Identifier;"), require = 0, cancellable = true) + private static void polymerCore$replaceWithServerItem(EmiStack eStack, int amount, int mode, CallbackInfoReturnable cir, @Local(ordinal = 0) ItemStack stack) { + try { + if (CompatUtils.isServerSide(stack)) { + var id = PolymerItemUtils.getServerIdentifier(stack); + var nbt = CompatUtils.getBackingNbt(stack); + String command = "give @s " + id; + if (nbt != null) { + var nbtString = nbt.toString(); + if (nbtString.length() + command.length() + 3 < 256) { + command += nbtString; + } + } + command += " " + amount; + client.player.networkHandler.sendChatCommand(command); + cir.setReturnValue(true); + } + } catch (Throwable e) { + e.printStackTrace(); + } + } +} diff --git a/polymer-core/src/main/java/eu/pb4/polymer/core/mixin/item/ItemStackMixin.java b/polymer-core/src/main/java/eu/pb4/polymer/core/mixin/item/ItemStackMixin.java index 6eb8a634..e24f6745 100644 --- a/polymer-core/src/main/java/eu/pb4/polymer/core/mixin/item/ItemStackMixin.java +++ b/polymer-core/src/main/java/eu/pb4/polymer/core/mixin/item/ItemStackMixin.java @@ -1,5 +1,8 @@ package eu.pb4.polymer.core.mixin.item; +import com.llamalad7.mixinextras.injector.ModifyReturnValue; +import com.llamalad7.mixinextras.sugar.Local; +import eu.pb4.polymer.common.api.PolymerCommonUtils; import eu.pb4.polymer.core.api.item.PolymerItemUtils; import eu.pb4.polymer.core.api.utils.PolymerUtils; import eu.pb4.polymer.core.impl.PolymerImpl; @@ -17,7 +20,6 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; @@ -25,6 +27,16 @@ @Mixin(ItemStack.class) public class ItemStackMixin { + + /*@ModifyReturnValue(method = "fromNbt(Lnet/minecraft/nbt/NbtCompound;)Lnet/minecraft/item/ItemStack;", at = @At("RETURN")) + private static ItemStack polymerCore$swapToRealStack(ItemStack stack, @Local NbtCompound nbt) { + if (nbt.contains(ItemStackAwareNbtCompound.MARKER_KEY) && PolymerCommonUtils.isServerBound()) { + return PolymerItemUtils.getRealItemStack(stack); + } + + return stack; + }*/ + @Inject(method = "writeNbt", at = @At("TAIL")) private void polymerCore$magicPerPlayerNbt(NbtCompound nbt, CallbackInfoReturnable cir) { if (PolymerImpl.ITEMSTACK_NBT_HACK) { diff --git a/polymer-core/src/main/java/eu/pb4/polymer/core/mixin/item/NbtCompoundMixin.java b/polymer-core/src/main/java/eu/pb4/polymer/core/mixin/item/NbtCompoundMixin.java index 96f33c16..06c8d93c 100644 --- a/polymer-core/src/main/java/eu/pb4/polymer/core/mixin/item/NbtCompoundMixin.java +++ b/polymer-core/src/main/java/eu/pb4/polymer/core/mixin/item/NbtCompoundMixin.java @@ -1,17 +1,20 @@ package eu.pb4.polymer.core.mixin.item; -import com.llamalad7.mixinextras.sugar.Local; +import com.llamalad7.mixinextras.injector.WrapWithCondition; import com.llamalad7.mixinextras.sugar.Share; import com.llamalad7.mixinextras.sugar.ref.LocalRef; import eu.pb4.polymer.common.api.PolymerCommonUtils; import eu.pb4.polymer.core.api.item.PolymerItemUtils; import eu.pb4.polymer.core.impl.interfaces.ItemStackAwareNbtCompound; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NbtByte; import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtElement; import net.minecraft.nbt.NbtString; import net.minecraft.registry.Registries; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -20,10 +23,15 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.io.DataOutput; +import java.io.IOException; +import java.util.Map; -@SuppressWarnings("InvalidInjectorMethodSignature") @Mixin(NbtCompound.class) -public class NbtCompoundMixin implements ItemStackAwareNbtCompound { +public abstract class NbtCompoundMixin implements ItemStackAwareNbtCompound { + @Shadow + private static void write(String key, NbtElement element, DataOutput output) throws IOException { + } + @Unique private boolean polymerCore$stack; @@ -32,6 +40,10 @@ public class NbtCompoundMixin implements ItemStackAwareNbtCompound { this.polymerCore$stack = value; } + @Override + public boolean polymerCore$getItemStack() { + return this.polymerCore$stack; + } @Inject(method = "write(Ljava/io/DataOutput;)V", at = @At("HEAD")) private void polymerCore$storePlayerContextedItemStack(DataOutput output, CallbackInfo ci, @Share("polymerCore:stack") LocalRef polymerStack) { @@ -44,20 +56,32 @@ public class NbtCompoundMixin implements ItemStackAwareNbtCompound { } } - @ModifyArg(method = "write(Ljava/io/DataOutput;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/nbt/NbtCompound;write(Ljava/lang/String;Lnet/minecraft/nbt/NbtElement;Ljava/io/DataOutput;)V")) - private NbtElement polymerCore$swapNbt(NbtElement nbtElement, @Local(ordinal = 0) String key, @Share("polymerCore:stack") LocalRef polymerStack) { + @WrapWithCondition( + method = "write(Ljava/io/DataOutput;)V", + at = @At(value = "INVOKE", target = "Lnet/minecraft/nbt/NbtCompound;write(Ljava/lang/String;Lnet/minecraft/nbt/NbtElement;Ljava/io/DataOutput;)V") + ) + private boolean polymerCore$ignoreIdAndTag(String key, NbtElement element, DataOutput output, @Share("polymerCore:stack") LocalRef polymerStack) { if (this.polymerCore$stack && PolymerCommonUtils.isNetworkingThread()) { var stack = polymerStack.get(); if (stack != null) { - if (key.equals("id") && nbtElement.getType() == NbtElement.STRING_TYPE) { - return NbtString.of(Registries.ITEM.getId(stack.getItem()).toString()); - } else if (key.equals("tag") && nbtElement.getType() == NbtElement.COMPOUND_TYPE) { - return stack.getOrCreateNbt(); - } + return !key.equals("id") && !key.equals("tag"); } } - return nbtElement; + return true; + } + @Inject(method = "write(Ljava/io/DataOutput;)V", at = @At(value = "INVOKE", target = "Ljava/io/DataOutput;writeByte(I)V", ordinal = 0)) + private void polymerCore$writeNbtIfMissing(DataOutput output, CallbackInfo ci, @Share("polymerCore:stack") LocalRef polymerStack) throws IOException { + if (this.polymerCore$stack && PolymerCommonUtils.isNetworkingThread()) { + var stack = polymerStack.get(); + if (stack != null) { + write(MARKER_KEY, MARKER_VALUE, output); + write("id", NbtString.of(Registries.ITEM.getId(stack.getItem()).toString()), output); + if (stack.hasNbt()) { + write("tag", stack.getNbt(), output); + } + } + } } @Inject(method = "copy()Lnet/minecraft/nbt/NbtCompound;", at = @At("RETURN")) diff --git a/polymer-core/src/main/java/eu/pb4/polymer/core/mixin/other/IdListMixin.java b/polymer-core/src/main/java/eu/pb4/polymer/core/mixin/other/IdListMixin.java index 5320eafa..801c1f02 100644 --- a/polymer-core/src/main/java/eu/pb4/polymer/core/mixin/other/IdListMixin.java +++ b/polymer-core/src/main/java/eu/pb4/polymer/core/mixin/other/IdListMixin.java @@ -30,7 +30,12 @@ public abstract class IdListMixin implements PolymerIdList { @Shadow @Final private Object2IntMap idMap; + @Unique + private int polymer$nonPolymerBitCount; + @Unique private int polymer$vanillaBitCount; + @Unique + private int polymer$vanillaEntryCount; @Shadow public abstract void add(T value); @@ -52,9 +57,9 @@ public abstract class IdListMixin implements PolymerIdList { @Unique private boolean polymer$reorderLock = false; @Unique - private Predicate polymer$checker; + private Predicate polymer$polymerEntryChecker; @Unique - private Predicate polymer$checkerList; + private Predicate polymer$serverEntryChecker; @Unique private boolean polymer$isPolymerAware; @Unique @@ -68,10 +73,12 @@ public abstract class IdListMixin implements PolymerIdList { return; } - var isPolymerObj = this.polymer$checker.test(value); + var isPolymerObj = this.polymer$polymerEntryChecker.test(value); - if (isPolymerObj || this.polymer$checkerList.test(value)) { + if (isPolymerObj || this.polymer$serverEntryChecker.test(value)) { this.polymer$states.add(value); + } else { + this.polymer$vanillaEntryCount++; } if (isPolymerObj) { @@ -117,7 +124,8 @@ public abstract class IdListMixin implements PolymerIdList { } } } - this.polymer$vanillaBitCount = MathHelper.ceilLog2(this.list.size() - this.polymer$states.size()); + this.polymer$nonPolymerBitCount = MathHelper.ceilLog2(this.list.size() - this.polymer$states.size()); + this.polymer$vanillaEntryCount = MathHelper.ceilLog2(this.polymer$vanillaEntryCount); } } @@ -156,10 +164,15 @@ public abstract class IdListMixin implements PolymerIdList { this.polymer$locked = false; this.polymer$lazyList.forEach(this::add); this.polymer$lazyList.clear(); - this.polymer$vanillaBitCount = MathHelper.ceilLog2(this.list.size() - this.polymer$states.size()); + this.polymer$nonPolymerBitCount = MathHelper.ceilLog2(this.list.size() - this.polymer$states.size()); } } + @Override + public int polymer$getNonPolymerBitCount() { + return this.polymer$nonPolymerBitCount; + } + @Override public int polymer$getVanillaBitCount() { return this.polymer$vanillaBitCount; @@ -167,8 +180,8 @@ public abstract class IdListMixin implements PolymerIdList { @Override public void polymer$setChecker(Predicate polymerChecker, Predicate serverChecker, Function namer) { - this.polymer$checker = polymerChecker; - this.polymer$checkerList = serverChecker; + this.polymer$polymerEntryChecker = polymerChecker; + this.polymer$serverEntryChecker = serverChecker; this.polymer$isPolymerAware = polymerChecker != null; this.polymer$nameCreator = namer; } @@ -198,6 +211,7 @@ public abstract class IdListMixin implements PolymerIdList { this.nextId = 0; this.idMap.clear(); this.list.clear(); + this.polymer$vanillaEntryCount = 0; this.polymer$lazyList.clear(); this.polymer$states.clear(); this.polymer$offset = Integer.MAX_VALUE; diff --git a/polymer-core/src/main/resources/polymer-core.mixins.json b/polymer-core/src/main/resources/polymer-core.mixins.json index 62c1ccc7..3ac9086c 100644 --- a/polymer-core/src/main/resources/polymer-core.mixins.json +++ b/polymer-core/src/main/resources/polymer-core.mixins.json @@ -26,6 +26,7 @@ "block.packet.WorldEventS2CPacketMixin", "block.storage.ChunkSectionMixin", "block.storage.WorldChunkMixin", + "client.compat.emi_EmiScreenManager", "command.ArgumentNodeMixin", "command.CommandManagerMixin", "compat.lithium_BlockPaletteMixin", diff --git a/polymer-core/src/testmod/java/eu/pb4/polymertest/TestMod.java b/polymer-core/src/testmod/java/eu/pb4/polymertest/TestMod.java index 06df600e..5762cb11 100644 --- a/polymer-core/src/testmod/java/eu/pb4/polymertest/TestMod.java +++ b/polymer-core/src/testmod/java/eu/pb4/polymertest/TestMod.java @@ -472,6 +472,7 @@ public void onInitialize() { s.getPlayerManager().getPlayerList().forEach(x -> { var i = x.getMainHandStack(); if (i.isOf(Items.EGG)) { + x.setPose(EntityPose.SLEEPING); x.networkHandler.sendPacket(new EntityTrackerUpdateS2CPacket(x.getId(), List.of(DataTracker.SerializedEntry.of(EntityTrackedData.POSE, EntityPose.SLEEPING)))); } else if (i.isOf(Items.CREEPER_HEAD)) { var l = new ArrayList>(); diff --git a/polymer-core/src/testmod/java/eu/pb4/polymertest/mixin/PlayerEntityMixin.java b/polymer-core/src/testmod/java/eu/pb4/polymertest/mixin/PlayerEntityMixin.java index 88851b7a..dcf68c5e 100644 --- a/polymer-core/src/testmod/java/eu/pb4/polymertest/mixin/PlayerEntityMixin.java +++ b/polymer-core/src/testmod/java/eu/pb4/polymertest/mixin/PlayerEntityMixin.java @@ -16,6 +16,4 @@ public abstract class PlayerEntityMixin extends LivingEntity { protected PlayerEntityMixin(EntityType entityType, World world) { super(entityType, world); } - - } diff --git a/polymer-networking/src/main/java/eu/pb4/polymer/networking/api/EarlyPlayNetworkHandler.java b/polymer-networking/src/main/java/eu/pb4/polymer/networking/api/EarlyPlayNetworkHandler.java index 15e2a235..b9463c91 100644 --- a/polymer-networking/src/main/java/eu/pb4/polymer/networking/api/EarlyPlayNetworkHandler.java +++ b/polymer-networking/src/main/java/eu/pb4/polymer/networking/api/EarlyPlayNetworkHandler.java @@ -13,6 +13,7 @@ import net.minecraft.network.packet.c2s.play.*; import net.minecraft.network.packet.s2c.play.*; import net.minecraft.server.MinecraftServer; +import net.minecraft.server.network.ServerLoginNetworkHandler; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; import net.minecraft.util.Identifier; @@ -452,4 +453,8 @@ public interface Context { public final @Nullable ServerPlayerEntity getPlayerForPacketTweaker() { return this.getPlayer(); } + + protected final ServerLoginNetworkHandler getLoginNetworkHandler() { + return this.context.loginHandler(); + } } diff --git a/polymer-networking/src/main/java/eu/pb4/polymer/networking/impl/EarlyConnectionMagic.java b/polymer-networking/src/main/java/eu/pb4/polymer/networking/impl/EarlyConnectionMagic.java index 51d9db47..355c12a7 100644 --- a/polymer-networking/src/main/java/eu/pb4/polymer/networking/impl/EarlyConnectionMagic.java +++ b/polymer-networking/src/main/java/eu/pb4/polymer/networking/impl/EarlyConnectionMagic.java @@ -4,6 +4,7 @@ import net.minecraft.network.ClientConnection; import net.minecraft.network.packet.c2s.play.CustomPayloadC2SPacket; import net.minecraft.server.MinecraftServer; +import net.minecraft.server.network.ServerLoginNetworkHandler; import net.minecraft.server.network.ServerPlayerEntity; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; @@ -17,10 +18,10 @@ public class EarlyConnectionMagic { private static final List> CONSTRUCTORS = new ArrayList<>(); - public static void handle(ServerPlayerEntity player, MinecraftServer server, ClientConnection connection, Consumer finish) { + public static void handle(ServerPlayerEntity player, ServerLoginNetworkHandler loginHandler, MinecraftServer server, ClientConnection connection, Consumer finish) { var iterator = new ArrayList<>(CONSTRUCTORS).iterator(); - var context = new ContextImpl(server, player, connection, new ArrayList<>(), (c) -> { + var context = new ContextImpl(server, player, connection, loginHandler, new ArrayList<>(), (c) -> { while (iterator.hasNext()) { var handler = iterator.next().apply(c); if (handler != null) { @@ -48,7 +49,9 @@ public record ContextImpl( MinecraftServer server, ServerPlayerEntity player, ClientConnection connection, + ServerLoginNetworkHandler loginHandler, List storedPackets, Consumer continueRunning - ) implements EarlyPlayNetworkHandler.Context {} + ) implements EarlyPlayNetworkHandler.Context { + } } diff --git a/polymer-networking/src/main/java/eu/pb4/polymer/networking/impl/client/ClientPacketRegistry.java b/polymer-networking/src/main/java/eu/pb4/polymer/networking/impl/client/ClientPacketRegistry.java index 9ba7a144..4ea81fd0 100644 --- a/polymer-networking/src/main/java/eu/pb4/polymer/networking/impl/client/ClientPacketRegistry.java +++ b/polymer-networking/src/main/java/eu/pb4/polymer/networking/impl/client/ClientPacketRegistry.java @@ -126,9 +126,7 @@ private static void sendMetadata(ClientPlayNetworkHandler handler) { public static void handleDisable(ClientPlayNetworkHandler handler, int version, PacketByteBuf buf) { if (version > -1) { - MinecraftClient.getInstance().execute(() -> { - clear(); - }); + clear(); } } diff --git a/polymer-networking/src/main/java/eu/pb4/polymer/networking/mixin/ServerLoginNetworkHandlerMixin.java b/polymer-networking/src/main/java/eu/pb4/polymer/networking/mixin/ServerLoginNetworkHandlerMixin.java index 0ac4706b..23a188e7 100644 --- a/polymer-networking/src/main/java/eu/pb4/polymer/networking/mixin/ServerLoginNetworkHandlerMixin.java +++ b/polymer-networking/src/main/java/eu/pb4/polymer/networking/mixin/ServerLoginNetworkHandlerMixin.java @@ -35,7 +35,7 @@ public abstract class ServerLoginNetworkHandlerMixin { @Inject(method = "addToServer", at = @At("HEAD"), cancellable = true) private void polymerNet$prePlayHandshakeHackfest(ServerPlayerEntity player, CallbackInfo ci) { if (!this.polymerNet$passPlayer) { - EarlyConnectionMagic.handle(player, server, connection, (context) -> { + EarlyConnectionMagic.handle(player, (ServerLoginNetworkHandler) (Object) this, server, connection, (context) -> { if (!this.polymerNet$passPlayer) { this.polymerNet$passPlayer = true; ((ExtClientConnection) this.connection).polymerNet$ignorePacketsUntilChange(context.storedPackets()::add); diff --git a/polymer-reg-sync-manipulator/src/main/java/eu/pb4/polymer/rsm/impl/CompatStatus.java b/polymer-reg-sync-manipulator/src/main/java/eu/pb4/polymer/rsm/impl/CompatStatus.java index d262cb99..3f62651e 100644 --- a/polymer-reg-sync-manipulator/src/main/java/eu/pb4/polymer/rsm/impl/CompatStatus.java +++ b/polymer-reg-sync-manipulator/src/main/java/eu/pb4/polymer/rsm/impl/CompatStatus.java @@ -8,6 +8,7 @@ public final class CompatStatus { private static final FabricLoader LOADER = FabricLoader.getInstance(); public static final boolean FABRIC_SYNC = LOADER.isModLoaded("fabric-registry-sync-v0"); - public static final boolean QUILT_REGISTRY = LOADER.isModLoaded("quilt_registry"); + + public static final boolean FORGE_CONNECTOR = LOADER.isModLoaded("connectormod"); } diff --git a/polymer-reg-sync-manipulator/src/main/java/eu/pb4/polymer/rsm/impl/forge/ForgeRegistryUtils.java b/polymer-reg-sync-manipulator/src/main/java/eu/pb4/polymer/rsm/impl/forge/ForgeRegistryUtils.java new file mode 100644 index 00000000..1b4acfe0 --- /dev/null +++ b/polymer-reg-sync-manipulator/src/main/java/eu/pb4/polymer/rsm/impl/forge/ForgeRegistryUtils.java @@ -0,0 +1,45 @@ +package eu.pb4.polymer.rsm.impl.forge; + +import eu.pb4.polymer.rsm.api.RegistrySyncUtils; +import net.minecraft.registry.Registries; +import net.minecraft.util.Identifier; + +import java.lang.reflect.Field; +import java.util.List; +import java.util.Map; + +@SuppressWarnings("unchecked") +public class ForgeRegistryUtils { + private static final Field IDS_FIELD; + + static { + try { + IDS_FIELD = Class.forName("net.minecraftforge.registries.ForgeRegistry$Snapshot").getField("ids"); + } catch (Throwable e) { + throw new RuntimeException(e); + } + } + + + public static Object clearPolymerEntries(Object o) { + var entry = (Map.Entry) o; + var registry = Registries.REGISTRIES.get(entry.getKey()); + if (registry == null) { + return o; + } + try { + var map = (Map) IDS_FIELD.get(entry.getValue()); + + for (var id : List.copyOf(map.keySet())) { + if (RegistrySyncUtils.isServerEntry(registry, id)) { + map.remove(id); + } + } + + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + + return o; + } +} diff --git a/polymer-reg-sync-manipulator/src/main/java/eu/pb4/polymer/rsm/mixin/PolymerMixinConfigPlugin.java b/polymer-reg-sync-manipulator/src/main/java/eu/pb4/polymer/rsm/mixin/PolymerMixinConfigPlugin.java new file mode 100644 index 00000000..e9edd970 --- /dev/null +++ b/polymer-reg-sync-manipulator/src/main/java/eu/pb4/polymer/rsm/mixin/PolymerMixinConfigPlugin.java @@ -0,0 +1,54 @@ +package eu.pb4.polymer.rsm.mixin; + +import eu.pb4.polymer.rsm.impl.CompatStatus; +import org.objectweb.asm.tree.ClassNode; +import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; +import org.spongepowered.asm.mixin.extensibility.IMixinInfo; + +import java.util.List; +import java.util.Set; + +public class PolymerMixinConfigPlugin implements IMixinConfigPlugin { + private static final String PACKAGE_ROOT = "eu.pb4.polymer.rsm.mixin."; + + @Override + public void onLoad(String mixinPackage) { + } + + @Override + public String getRefMapperConfig() { + return null; + } + + @Override + public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { + var name = mixinClassName.substring(PACKAGE_ROOT.length()); + + if (name.startsWith("fabric")) { + return CompatStatus.FABRIC_SYNC; + } else if (name.startsWith("forge")) { + return CompatStatus.FORGE_CONNECTOR; + } + return true; + } + + @Override + public void acceptTargets(Set myTargets, Set otherTargets) { + + } + + @Override + public List getMixins() { + return null; + } + + @Override + public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { + + } + + @Override + public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { + + } +} diff --git a/polymer-reg-sync-manipulator/src/main/java/eu/pb4/polymer/rsm/mixin/SimpleRegistryMixin.java b/polymer-reg-sync-manipulator/src/main/java/eu/pb4/polymer/rsm/mixin/SimpleRegistryMixin.java index 44e50246..130bc313 100644 --- a/polymer-reg-sync-manipulator/src/main/java/eu/pb4/polymer/rsm/mixin/SimpleRegistryMixin.java +++ b/polymer-reg-sync-manipulator/src/main/java/eu/pb4/polymer/rsm/mixin/SimpleRegistryMixin.java @@ -21,7 +21,8 @@ @Mixin(value = SimpleRegistry.class) public abstract class SimpleRegistryMixin implements RegistrySyncExtension, MutableRegistry { - private Object2BooleanMap polymer_registry_sync$entryStatus = new Object2BooleanOpenHashMap<>(); + @Unique + private final Object2BooleanMap polymer_registry_sync$entryStatus = new Object2BooleanOpenHashMap<>(); @Shadow public abstract Set getIds(); diff --git a/polymer-reg-sync-manipulator/src/main/java/eu/pb4/polymer/rsm/mixin/forge/forge_RegistryManager.java b/polymer-reg-sync-manipulator/src/main/java/eu/pb4/polymer/rsm/mixin/forge/forge_RegistryManager.java new file mode 100644 index 00000000..e94868cf --- /dev/null +++ b/polymer-reg-sync-manipulator/src/main/java/eu/pb4/polymer/rsm/mixin/forge/forge_RegistryManager.java @@ -0,0 +1,24 @@ +package eu.pb4.polymer.rsm.mixin.forge; + +import eu.pb4.polymer.rsm.impl.forge.ForgeRegistryUtils; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Pseudo; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import java.util.List; +import java.util.function.Function; +import java.util.stream.Stream; + +@SuppressWarnings("UnresolvedMixinReference") +@Pseudo +@Mixin(targets = "net/minecraftforge/registries/RegistryManager", remap = false) +public class forge_RegistryManager { + @Redirect(method = "generateRegistryPackets(Z)Ljava/util/List;", + at = @At(value = "INVOKE", target = "Ljava/util/stream/Stream;map(Ljava/util/function/Function;)Ljava/util/stream/Stream;") + ) + + private static Stream polymerRegSync$removePolymerEntries(Stream stream, Function function) { + return stream.map(ForgeRegistryUtils::clearPolymerEntries).map(function); + } +} diff --git a/polymer-reg-sync-manipulator/src/main/resources/polymer-rsm.mixins.json b/polymer-reg-sync-manipulator/src/main/resources/polymer-rsm.mixins.json index 37e8aa23..0a3684b5 100644 --- a/polymer-reg-sync-manipulator/src/main/resources/polymer-rsm.mixins.json +++ b/polymer-reg-sync-manipulator/src/main/resources/polymer-rsm.mixins.json @@ -2,10 +2,12 @@ "required": true, "minVersion": "0.8", "package": "eu.pb4.polymer.rsm.mixin", + "plugin": "eu.pb4.polymer.rsm.mixin.PolymerMixinConfigPlugin", "compatibilityLevel": "JAVA_17", "mixins": [ "SimpleRegistryMixin", - "fabric.fabricSync_RegistrySyncManagerMixin" + "fabric.fabricSync_RegistrySyncManagerMixin", + "forge.forge_RegistryManager" ], "injectors": { "defaultRequire": 0 diff --git a/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/impl/VirtualEntityMod.java b/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/impl/VirtualEntityMod.java new file mode 100644 index 00000000..97a4f698 --- /dev/null +++ b/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/impl/VirtualEntityMod.java @@ -0,0 +1,43 @@ +package eu.pb4.polymer.virtualentity.impl; + +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import eu.pb4.polymer.common.api.PolymerCommonUtils; +import eu.pb4.polymer.common.impl.CommonImplUtils; +import eu.pb4.polymer.common.impl.CompatStatus; +import eu.pb4.polymer.virtualentity.api.attachment.BlockBoundAttachment; +import net.fabricmc.api.ModInitializer; +import net.minecraft.command.CommandRegistryAccess; +import net.minecraft.command.argument.BlockPosArgumentType; +import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.text.Text; +import org.jetbrains.annotations.ApiStatus; + +import static net.minecraft.server.command.CommandManager.argument; +import static net.minecraft.server.command.CommandManager.literal; + + +@ApiStatus.Internal +public class VirtualEntityMod implements ModInitializer { + @Override + public void onInitialize() { + CommonImplUtils.registerDevCommands(this::commands); + } + + private void commands(LiteralArgumentBuilder builder, CommandRegistryAccess commandRegistryAccess) { + builder.then(literal("ve_blockbound").then(argument("pos", BlockPosArgumentType.blockPos()).executes((ctx) -> { + var b = BlockBoundAttachment.get(ctx.getSource().getWorld(), BlockPosArgumentType.getBlockPos(ctx, "pos")); + + if (b == null) { + ctx.getSource().sendFeedback(() -> Text.literal("No block bound!"), false); + } else { + ctx.getSource().sendFeedback(() -> Text.literal("Found: " + b.holder()), false); + for (var e : b.holder().getElements()) { + ctx.getSource().sendFeedback(() -> Text.literal("- " + e), false); + } + } + + + return b != null ? b.holder().getElements().size() : -1; + }))); + } +} diff --git a/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/mixin/block/WorldChunkMixin.java b/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/mixin/block/WorldChunkMixin.java index 65d88e7f..64920ecd 100644 --- a/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/mixin/block/WorldChunkMixin.java +++ b/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/mixin/block/WorldChunkMixin.java @@ -99,10 +99,9 @@ public WorldChunkMixin(ChunkPos pos, UpgradeData upgradeData, HeightLimitView he } } - @Inject(method = "setBlockState", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/BlockState;hasBlockEntity()Z", ordinal = 1), locals = LocalCapture.CAPTURE_FAILSOFT) + @Inject(method = "setBlockState", at = @At(value = "FIELD", target = "Lnet/minecraft/world/World;isClient:Z", ordinal = 1, shift = At.Shift.BEFORE), locals = LocalCapture.CAPTURE_FAILSOFT) private void polymerVE$addNew(BlockPos pos, BlockState state, boolean moved, CallbackInfoReturnable cir, int i, ChunkSection section, boolean bool, int j, int k, int l, BlockState oldBlockState) { - if (oldBlockState.getBlock() != state.getBlock() && state.getBlock() instanceof BlockWithElementHolder blockWithElementHolder && this.world instanceof ServerWorld serverWorld) { var holder = blockWithElementHolder.createElementHolder(serverWorld, pos, state); if (holder != null) { diff --git a/polymer-virtual-entity/src/main/resources/fabric.mod.json b/polymer-virtual-entity/src/main/resources/fabric.mod.json index f9b3c0ac..c50ad745 100644 --- a/polymer-virtual-entity/src/main/resources/fabric.mod.json +++ b/polymer-virtual-entity/src/main/resources/fabric.mod.json @@ -17,6 +17,7 @@ "icon": "assets/icon.png", "environment": "*", "entrypoints": { + "main": ["eu.pb4.polymer.virtualentity.impl.VirtualEntityMod"] }, "accessWidener": "polymer-virtual-entity.accesswidener", "mixins": [