Skip to content

Commit

Permalink
Fix campfires not showing polymer items, make resource pack merge lan…
Browse files Browse the repository at this point in the history
…guage files and mcmeta together
  • Loading branch information
Patbox committed Aug 14, 2024
1 parent e5e815a commit 35f357c
Show file tree
Hide file tree
Showing 31 changed files with 501 additions and 140 deletions.
8 changes: 4 additions & 4 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ org.gradle.jvmargs=-Xmx4G
# Fabric Properties
# check these on https://fabricmc.net/use

minecraft_version=1.21
yarn_mappings=1.21+build.1
minecraft_version=1.21.1
yarn_mappings=1.21.1+build.1
loader_version=0.15.11

# Fabric API
fabric_version=0.100.0+1.21
fabric_version=0.102.1+1.21.1

maven_group = eu.pb4

mod_version = 0.9.9
mod_version = 0.9.10

minecraft_version_supported = ">=1.20.5-"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ 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 FORGE_CONNECTOR = LOADER.isModLoaded("connector");


public static final boolean POLYMC = LOADER.isModLoaded("polymc");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
import eu.pb4.polymer.common.api.events.SimpleEvent;
import eu.pb4.polymer.common.impl.CommonImplUtils;
import eu.pb4.polymer.core.api.item.PolymerItem;
import eu.pb4.polymer.core.api.item.PolymerItemUtils;
import eu.pb4.polymer.core.api.other.PolymerComponent;
import eu.pb4.polymer.core.impl.PolymerImplUtils;
import eu.pb4.polymer.core.impl.TransformingComponent;
import eu.pb4.polymer.core.impl.compat.polymc.PolyMcUtils;
import eu.pb4.polymer.core.impl.interfaces.BlockStateExtra;
import eu.pb4.polymer.core.mixin.block.BlockEntityUpdateS2CPacketAccessor;
Expand All @@ -12,7 +16,12 @@
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.component.ComponentMap;
import net.minecraft.component.ComponentType;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement;
import net.minecraft.nbt.NbtOps;
import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket;
import net.minecraft.registry.Registries;
import net.minecraft.server.network.ServerPlayerEntity;
Expand All @@ -21,37 +30,32 @@
import net.minecraft.util.math.ChunkSectionPos;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import xyz.nucleoid.packettweaker.PacketContext;

import java.util.Arrays;
import java.util.Set;
import java.util.function.BiPredicate;
import java.util.function.Predicate;

public final class PolymerBlockUtils {
private static final NbtCompound STATIC_COMPOUND = new NbtCompound();

private PolymerBlockUtils() {
}

public static final int NESTED_DEFAULT_DISTANCE = 32;

public static final Predicate<BlockState> IS_POLYMER_BLOCK_STATE_PREDICATE = state -> state.getBlock() instanceof PolymerBlock;

/**
* This event allows you to force server side mining for any block/item
*/
public static final BooleanEvent<MineEventListener> SERVER_SIDE_MINING_CHECK = new BooleanEvent<>();

public static final SimpleEvent<BreakingProgressListener> BREAKING_PROGRESS_UPDATE = new SimpleEvent<>();

/**
* This event allows you to force syncing of light updates between server and clinet
*/
public static final BooleanEvent<BiPredicate<ServerWorld, ChunkSectionPos>> SEND_LIGHT_UPDATE_PACKET = new BooleanEvent<>();
private static final NbtCompound STATIC_COMPOUND = new NbtCompound();
private static final Set<BlockEntityType<?>> BLOCK_ENTITY_TYPES = new ObjectOpenCustomHashSet<>(CommonImplUtils.IDENTITY_HASH);

private static boolean requireStrictBlockUpdates = false;

private PolymerBlockUtils() {
}

/**
* Marks BlockEntity type as server-side only
*
Expand Down Expand Up @@ -224,6 +228,70 @@ public static BlockState getServerSideBlockState(BlockState state, ServerPlayerE
return PolyMcUtils.toVanilla(getPolymerBlockState(state, player), player);
}

public static NbtCompound transformBlockEntityNbt(PacketContext context, BlockEntityType<?> type, NbtCompound original) {
if (original.isEmpty()) {
return original;
}
NbtCompound override = null;

var lookup = context.getRegistryWrapperLookup() != null ? context.getRegistryWrapperLookup() : PolymerImplUtils.FALLBACK_LOOKUP;

if (original.contains("Items", NbtElement.LIST_TYPE)) {
var list = original.getList("Items", NbtElement.COMPOUND_TYPE);
for (int i = 0; i < list.size(); i++) {
var nbt = list.getCompound(i);
var stack = ItemStack.fromNbtOrEmpty(lookup, nbt);
if (PolymerItemUtils.isPolymerServerItem(stack, context)) {
if (override == null) {
override = original.copy();
}
nbt = nbt.copy();
nbt.remove("id");
nbt.remove("components");
nbt.remove("count");
stack = PolymerItemUtils.getPolymerItemStack(stack, context);
override.getList("Items", NbtElement.COMPOUND_TYPE).set(i, stack.isEmpty() ? new NbtCompound() : stack.encode(lookup, nbt));
}
}
}

if (original.contains("components", NbtElement.COMPOUND_TYPE)) {
var ops = lookup.getOps(NbtOps.INSTANCE);

var comp = ComponentMap.CODEC.decode(ops, original.getCompound("components"));
if (comp.isSuccess()) {
var map = comp.getOrThrow().getFirst();
ComponentMap.Builder builder = null;

for (var component : map) {
if (component.value() instanceof TransformingComponent transformingComponent && transformingComponent.polymer$requireModification(context)) {
if (builder == null) {
builder = ComponentMap.builder();
builder.addAll(map);
}
//noinspection unchecked
builder.add((ComponentType<? super Object>) component.type(), transformingComponent.polymer$getTransformed(context));
} else if (!PolymerComponent.canSync(component.type(), component.value(), context)) {
if (builder == null) {
builder = ComponentMap.builder();
builder.addAll(map);
}
builder.add(component.type(), null);
}
}

if (builder != null) {
if (override == null) {
override = original.copy();
}
override.put("components", ComponentMap.CODEC.encodeStart(ops, builder.build()).result().orElse(new NbtCompound()));
}
}
}

return override != null ? override : original;
}

@FunctionalInterface
public interface MineEventListener {
boolean onBlockMine(BlockState state, BlockPos pos, ServerPlayerEntity player);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import eu.pb4.polymer.core.api.other.PolymerComponent;
import eu.pb4.polymer.core.api.utils.PolymerUtils;
import eu.pb4.polymer.core.impl.PolymerImpl;
import eu.pb4.polymer.core.impl.PolymerImplUtils;
import eu.pb4.polymer.core.impl.TransformingComponent;
import eu.pb4.polymer.core.impl.compat.polymc.PolyMcUtils;
import eu.pb4.polymer.resourcepack.api.PolymerResourcePackUtils;
Expand Down Expand Up @@ -125,6 +126,18 @@ public final class PolymerItemUtils {
private PolymerItemUtils() {
}

/**
* This method creates a client side ItemStack representation
*
* @param itemStack Server side ItemStack
* @param context Networking context
* @return Client side ItemStack
*/
public static ItemStack getPolymerItemStack(ItemStack itemStack, PacketContext context) {
return getPolymerItemStack(itemStack, context.getRegistryWrapperLookup() != null ? context.getRegistryWrapperLookup() : PolymerImplUtils.FALLBACK_LOOKUP,
context.getPlayer());
}

/**
* This method creates a client side ItemStack representation
*
Expand Down Expand Up @@ -282,6 +295,10 @@ public static boolean isPolymerServerItem(ItemStack itemStack) {
return isPolymerServerItem(itemStack, PolymerUtils.getPlayerContext());
}

public static boolean isPolymerServerItem(ItemStack itemStack, PacketContext context) {
return isPolymerServerItem(itemStack, context.getPlayer());
}

public static boolean isPolymerServerItem(ItemStack itemStack, @Nullable ServerPlayerEntity player) {
if (getPolymerIdentifier(itemStack) != null) {
return false;
Expand All @@ -305,7 +322,7 @@ public static boolean isPolymerServerItem(ItemStack itemStack, @Nullable ServerP
}

if (itemStack.contains(DataComponentTypes.ENCHANTMENTS) && itemStack.getOrDefault(DataComponentTypes.ATTRIBUTE_MODIFIERS, AttributeModifiersComponent.DEFAULT).showInTooltip()) {
for (var ench : itemStack.get(DataComponentTypes.ENCHANTMENTS).getEnchantments()) {
for (var ench : itemStack.getOrDefault(DataComponentTypes.ENCHANTMENTS, ItemEnchantmentsComponent.DEFAULT).getEnchantments()) {
var attributes = ench.value().getEffect(EnchantmentEffectComponentTypes.ATTRIBUTES);
if (attributes != null) {
for (var attr : attributes) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class PacketPatcher {

public static Packet<?> replace(ServerCommonNetworkHandler handler, Packet<?> packet) {
if (handler.getClass() == ServerPlayNetworkHandler.class) {
if (packet instanceof EntityEquipmentUpdateS2CPacket original && EntityAttachedPacket.get(original, original.getId()) instanceof PolymerEntity polymerEntity) {
if (packet instanceof EntityEquipmentUpdateS2CPacket original && EntityAttachedPacket.get(original, original.getEntityId()) instanceof PolymerEntity polymerEntity) {
return EntityAttachedPacket.setIfEmpty(
new EntityEquipmentUpdateS2CPacket(((Entity) polymerEntity).getId(), polymerEntity.getPolymerVisibleEquipment(original.getEquipmentList(), ((ServerPlayNetworkHandler) handler).getPlayer())),
(Entity) polymerEntity
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,43 @@
package eu.pb4.polymer.core.mixin.block;

import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.llamalad7.mixinextras.sugar.Local;
import eu.pb4.polymer.common.api.PolymerCommonUtils;
import eu.pb4.polymer.common.impl.CommonImplUtils;
import eu.pb4.polymer.core.api.utils.PolymerUtils;
import eu.pb4.polymer.core.impl.PolymerImplUtils;
import it.unimi.dsi.fastutil.longs.LongSet;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.s2c.play.ChunkDataS2CPacket;
import net.minecraft.server.network.ChunkDataSender;
import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.Unit;
import net.minecraft.world.chunk.WorldChunk;
import net.minecraft.world.chunk.light.LightingProvider;
import org.jetbrains.annotations.Nullable;
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.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import java.util.BitSet;

@Mixin(ChunkDataSender.class)
public class ChunkDataSenderMixin {
@Inject(method = "sendChunkData", at = @At("HEAD"), require = 0)
private static void polymer$catchPlayer(ServerPlayNetworkHandler handler, ServerWorld world, WorldChunk chunk, CallbackInfo ci) {
CommonImplUtils.setPlayer(handler.player);
}

@Inject(method = "sendChunkData", at = @At("TAIL"), require = 0)
private static void polymer$clearPlayer(ServerPlayNetworkHandler handler, ServerWorld world, WorldChunk chunk, CallbackInfo ci) {
CommonImplUtils.setPlayer(null);
@WrapOperation(method = "sendChunkData", at = @At(value = "NEW", target = "(Lnet/minecraft/world/chunk/WorldChunk;Lnet/minecraft/world/chunk/light/LightingProvider;Ljava/util/BitSet;Ljava/util/BitSet;)Lnet/minecraft/network/packet/s2c/play/ChunkDataS2CPacket;"), require = 0)
private static ChunkDataS2CPacket addContext(WorldChunk chunk, LightingProvider lightProvider, @Nullable BitSet skyBits, @Nullable BitSet blockBits, Operation<ChunkDataS2CPacket> call,
@Local(argsOnly = true) ServerPlayNetworkHandler handler) {
var storage = new ChunkDataS2CPacket[1];
PolymerCommonUtils.executeWithNetworkingLogic(handler, () -> storage[0] = call.call(chunk, lightProvider, skyBits, blockBits));
return storage[0];
}


@WrapWithCondition(method = "unload", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerPlayNetworkHandler;sendPacket(Lnet/minecraft/network/packet/Packet;)V"), require = 0)
private boolean skipChunkClearing(ServerPlayNetworkHandler instance, Packet packet) {
return PolymerImplUtils.IS_RELOADING_WORLD.get() == null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package eu.pb4.polymer.core.mixin.block.packet;

import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import eu.pb4.polymer.core.api.block.PolymerBlockUtils;
import eu.pb4.polymer.core.impl.networking.TransformingPacketCodec;
import eu.pb4.polymer.core.mixin.block.BlockEntityUpdateS2CPacketAccessor;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import xyz.nucleoid.packettweaker.PacketContext;

@Mixin(BlockEntityUpdateS2CPacket.class)
public class BlockEntityUpdateS2CPacketMixin {
@ModifyExpressionValue(method = "<clinit>", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/codec/PacketCodec;tuple(Lnet/minecraft/network/codec/PacketCodec;Ljava/util/function/Function;Lnet/minecraft/network/codec/PacketCodec;Ljava/util/function/Function;Lnet/minecraft/network/codec/PacketCodec;Ljava/util/function/Function;Lcom/mojang/datafixers/util/Function3;)Lnet/minecraft/network/codec/PacketCodec;"))
private static PacketCodec<RegistryByteBuf, BlockEntityUpdateS2CPacket> changeNbt(PacketCodec<RegistryByteBuf, BlockEntityUpdateS2CPacket> original) {
return TransformingPacketCodec.encodeOnly(original, (buf, packet) -> {
if (packet.getNbt() == null) {
return packet;
}
var nbt = PolymerBlockUtils.transformBlockEntityNbt(PacketContext.get(), packet.getBlockEntityType(), packet.getNbt());
if (packet.getNbt() == nbt) {
return packet;
}
return BlockEntityUpdateS2CPacketAccessor.createBlockEntityUpdateS2CPacket(packet.getPos(), packet.getBlockEntityType(), nbt);
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package eu.pb4.polymer.core.mixin.block.packet;

import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.llamalad7.mixinextras.sugar.Local;
import eu.pb4.polymer.core.api.block.PolymerBlockUtils;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.nbt.NbtCompound;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import xyz.nucleoid.packettweaker.PacketContext;

@Mixin(targets = "net/minecraft/network/packet/s2c/play/ChunkData$BlockEntityData")
public class ChunkDataBlockEntityDataMixin {
@ModifyExpressionValue(method = "of", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/entity/BlockEntity;toInitialChunkDataNbt(Lnet/minecraft/registry/RegistryWrapper$WrapperLookup;)Lnet/minecraft/nbt/NbtCompound;"))
private static NbtCompound changeNbt(NbtCompound original, @Local(argsOnly = true) BlockEntity blockEntity) {
return PolymerBlockUtils.transformBlockEntityNbt(PacketContext.get(), blockEntity.getType(), original);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package eu.pb4.polymer.core.mixin.block.packet;

import com.llamalad7.mixinextras.injector.WrapWithCondition;
import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
import com.llamalad7.mixinextras.sugar.Local;
import eu.pb4.polymer.common.api.PolymerCommonUtils;
import eu.pb4.polymer.core.api.block.PolymerBlockUtils;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ public class EntitySpawnS2CPacketMixin {

@Shadow @Final private EntityType<?> entityType;

@Shadow @Final private int id;
@Shadow @Final private int entityId;

@ModifyArg(method = "write", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/codec/PacketCodec;encode(Ljava/lang/Object;Ljava/lang/Object;)V"), index = 1)
private Object polymer$replaceWithPolymer(@Nullable Object value) {
if (EntityAttachedPacket.get(this, this.id) instanceof PolymerEntity polymerEntity && value == ((Entity) polymerEntity).getType()) {
if (EntityAttachedPacket.get(this, this.entityId) instanceof PolymerEntity polymerEntity && value == ((Entity) polymerEntity).getType()) {
return polymerEntity.getPolymerEntityType(PolymerUtils.getPlayerContext());
} else {
return value;
Expand Down
2 changes: 2 additions & 0 deletions polymer-core/src/main/resources/polymer-core.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@
"block.PalettedContainerAccessor",
"block.ServerChunkManagerMixin",
"block.ServerPlayerInteractionManagerMixin",
"block.packet.BlockEntityUpdateS2CPacketMixin",
"block.packet.BlockEventS2CPacketMixin",
"block.packet.BlockPaletteMixin",
"block.packet.BlockUpdateS2CPacketAccessor",
"block.packet.ChunkDataBlockEntityDataMixin",
"block.packet.ChunkDataMixin",
"block.packet.ChunkDataS2CPacketMixin",
"block.packet.ChunkDeltaUpdateS2CPacketAccessor",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,6 @@ protected boolean canBeReplacedWith(FluidState fluidState, BlockView blockView,
* Possibly related to the distance checks for flowing into nearby holes?
* Water returns 4. Lava returns 2 in the Overworld and 4 in the Nether.
*/
@Override
protected int getFlowSpeed(WorldView worldView) {
return 1;
}

/**
* Water returns 1. Lava returns 2 in the Overworld and 1 in the Nether.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import net.minecraft.state.StateManager;
import net.minecraft.state.property.Properties;
import net.minecraft.world.World;
import net.minecraft.world.WorldView;

public abstract class TestFluid extends BaseTestFluid {
@Override
Expand All @@ -24,6 +25,11 @@ public Item getBucketItem() {
return TestMod.FLUID_BUCKET;
}

@Override
protected int getMaxFlowDistance(WorldView world) {
return 8;
}

@Override
protected BlockState toBlockState(FluidState fluidState) {
return TestMod.FLUID_BLOCK.getDefaultState().with(Properties.LEVEL_15, getBlockStateLevel(fluidState));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"item.test.shulker_helmet": "Shulker Helmet"
}
Loading

0 comments on commit 35f357c

Please sign in to comment.