Skip to content

Commit

Permalink
Extend BlockWithElementHolder's api, add support for new Fabric APIs …
Browse files Browse the repository at this point in the history
…networking stuff
  • Loading branch information
Patbox committed Apr 15, 2023
1 parent 43f0fff commit 9f3fbc4
Show file tree
Hide file tree
Showing 16 changed files with 144 additions and 18 deletions.
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ yarn_mappings=1.19.4+build.1
loader_version=0.14.14

#Fabric api
fabric_version=0.74.2+1.19.4
fabric_version=0.77.0+1.19.4

maven_group = eu.pb4

mod_version = 0.4.5
mod_version = 0.4.6

minecraft_version_supported = ">=1.19.4-"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ public static boolean shouldApplyMixin(String source, String mixinClassName, boo
case "fabricSync" -> CompatStatus.FABRIC_SYNC;
case "fabricSH" -> CompatStatus.FABRIC_SCREEN_HANDLER;
case "fabricItemGroup" -> CompatStatus.FABRIC_ITEM_GROUP;
case "fabricNetworking" -> CompatStatus.FABRIC_NETWORKING;
case "polymc" -> CompatStatus.POLYMC;
case "wthit" -> CompatStatus.WTHIT;
case "rei" -> CompatStatus.REI;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public final class CompatStatus {
public static final boolean POLYMER_RESOURCE_PACKS = POLYMER_RESOURCE_PACK;

public static final boolean FABRIC_SYNC = LOADER.isModLoaded("fabric-registry-sync-v0");
public static final boolean FABRIC_NETWORKING = LOADER.isModLoaded("fabric-networking-api-v1");
public static final boolean FABRIC_FLUID_RENDERERING = LOADER.isModLoaded("fabric-rendering-fluids-v1");
public static final boolean FABRIC_ITEM_GROUP = LOADER.isModLoaded("fabric-item-group-api-v1");
public static final boolean FABRIC_SCREEN_HANDLER = LOADER.isModLoaded("fabric-screen-handler-api-v1");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package eu.pb4.polymer.core.mixin.compat.fabric;

import eu.pb4.polymer.common.impl.CommonImplUtils;
import net.fabricmc.fabric.api.networking.v1.FabricPacket;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.minecraft.server.network.ServerPlayerEntity;
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.Coerce;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Pseudo
@Mixin(ServerPlayNetworking.class)
public class fabricNetworking_ServerPlayNetworking {
@Inject(
method = "send(Lnet/minecraft/server/network/ServerPlayerEntity;Lnet/fabricmc/fabric/api/networking/v1/FabricPacket;)V",
at = @At(
value = "INVOKE",
target = "Lnet/fabricmc/fabric/api/networking/v1/FabricPacket;write(Lnet/minecraft/network/PacketByteBuf;)V",
shift = At.Shift.BEFORE
), require = 0
)
private static void polymerCore$addPlayerContext(ServerPlayerEntity player, @Coerce Object packet, CallbackInfo ci) {
CommonImplUtils.setPlayer(player);
}

@Inject(
method = "send(Lnet/minecraft/server/network/ServerPlayerEntity;Lnet/fabricmc/fabric/api/networking/v1/FabricPacket;)V",
at = @At(
value = "INVOKE",
target = "Lnet/fabricmc/fabric/api/networking/v1/FabricPacket;write(Lnet/minecraft/network/PacketByteBuf;)V",
shift = At.Shift.AFTER
), require = 0
)
private static void polymerCore$removePlayerContext(ServerPlayerEntity player, @Coerce Object packet, CallbackInfo ci) {
CommonImplUtils.setPlayer(null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,20 @@
import net.minecraft.screen.ScreenHandler;
import net.minecraft.server.network.ServerPlayerEntity;
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.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Pseudo
@Mixin(Networking.class)
public class fabricSH_NetworkingMixin {
@Inject(method = "sendOpenPacket", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/PacketByteBuf;<init>(Lio/netty/buffer/ByteBuf;)V"))
@Inject(method = "sendOpenPacket", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/PacketByteBuf;<init>(Lio/netty/buffer/ByteBuf;)V"), require = 0)
private static void polymer_setPlayer(ServerPlayerEntity player, ExtendedScreenHandlerFactory factory, ScreenHandler handler, int syncId, CallbackInfo ci) {
CommonImplUtils.setPlayer(player);
}

@Inject(method = "sendOpenPacket", at = @At("TAIL"))
@Inject(method = "sendOpenPacket", at = @At("TAIL"), require = 0)
private static void polymer_removePlayer(ServerPlayerEntity player, ExtendedScreenHandlerFactory factory, ScreenHandler handler, int syncId, CallbackInfo ci) {
CommonImplUtils.setPlayer(null);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,24 @@
import net.minecraft.util.collection.IdList;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Pseudo;
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;

@Pseudo
@Mixin(StateIdTracker.class)
public class fabricSync_StateIdTrackerMixin {
@Shadow @Final private IdList<?> stateList;

@Inject(method = "recalcStateMap", at = @At("HEAD"), remap = false)
@Inject(method = "recalcStateMap", at = @At("HEAD"), remap = false, require = 0)
private void polymer_clear(CallbackInfo ci) {
((PolymerIdList) this.stateList).polymer$setIgnoreCalls(true);
((PolymerIdList) this.stateList).polymer$clear();
}

@Inject(method = "recalcStateMap", at = @At("TAIL"), remap = false)
@Inject(method = "recalcStateMap", at = @At("TAIL"), remap = false, require = 0)
private void polymer_unignore(CallbackInfo ci) {
((PolymerIdList) this.stateList).polymer$setIgnoreCalls(false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.world.chunk.WorldChunk;
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.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
Expand All @@ -14,29 +15,30 @@

import java.util.function.Supplier;

@Pseudo
@Mixin(value = ChunkDataSyncManager.class)
public class ip_ChunkDataSyncManagerMixin {
@Inject(method = "sendChunkDataPacketNow", at = @At("HEAD"))
@Inject(method = "sendChunkDataPacketNow", at = @At("HEAD"), require = 0)
private void polymer_setPlayerNow(ServerPlayerEntity player, DimensionalChunkPos chunkPos, IEThreadedAnvilChunkStorage ieStorage, CallbackInfo ci) {
CommonImplUtils.setPlayer(player);
}

@Inject(method = "sendChunkDataPacketNow", at = @At("RETURN"))
@Inject(method = "sendChunkDataPacketNow", at = @At("RETURN"), require = 0)
private void polymer_resetPlayerNow1(ServerPlayerEntity player, DimensionalChunkPos chunkPos, IEThreadedAnvilChunkStorage ieStorage, CallbackInfo ci) {
CommonImplUtils.setPlayer(null);
}

@Redirect(method = "onChunkProvidedDeferred", at = @At(value = "INVOKE", target = "Lqouteall/q_misc_util/Helper;cached(Ljava/util/function/Supplier;)Ljava/util/function/Supplier;", ordinal = 0))
@Redirect(method = "onChunkProvidedDeferred", at = @At(value = "INVOKE", target = "Lqouteall/q_misc_util/Helper;cached(Ljava/util/function/Supplier;)Ljava/util/function/Supplier;", ordinal = 0), require = 0)
private Supplier<?> polymer_setPlayerLambda(Supplier<?> supplier, WorldChunk chunk) {
return supplier;
}

@Inject(method = "lambda$onChunkProvidedDeferred$1", at = @At("HEAD"))
@Inject(method = "lambda$onChunkProvidedDeferred$1", at = @At("HEAD"), require = 0)
private static void polymer_setPlayer(Supplier chunkDataPacketRedirected, IEThreadedAnvilChunkStorage ieStorage, WorldChunk chunk, ServerPlayerEntity player, CallbackInfo ci) {
CommonImplUtils.setPlayer(player);
}

@Inject(method = "lambda$onChunkProvidedDeferred$1", at = @At("TAIL"))
@Inject(method = "lambda$onChunkProvidedDeferred$1", at = @At("TAIL"), require = 0)
private static void polymer_resetPlayer(Supplier chunkDataPacketRedirected, IEThreadedAnvilChunkStorage ieStorage, WorldChunk chunk, ServerPlayerEntity player, CallbackInfo ci) {
CommonImplUtils.setPlayer(null);
}
Expand Down
1 change: 1 addition & 0 deletions polymer-core/src/main/resources/polymer-core.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"command.ArgumentNodeMixin",
"command.CommandManagerMixin",
"compat.lithium_BlockPaletteMixin",
"compat.fabric.fabricNetworking_ServerPlayNetworking",
"compat.fabric.fabricSync_StateIdTrackerMixin",
"compat.immersive_portals.ip_ChunkDataSyncManagerMixin",
"compat.polymc.polymc_BlockPolyGeneratorMixin",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,34 @@
package eu.pb4.polymer.virtualentity.api;

import net.minecraft.block.BlockState;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;

public interface BlockWithElementHolder {
ElementHolder createElementHolder(BlockPos pos, BlockState initialBlockState);
default ElementHolder createElementHolder(ServerWorld world, BlockPos pos, BlockState initialBlockState) {
return createElementHolder(pos, initialBlockState);
}

default Vec3d getElementHolderOffset(ServerWorld world, BlockPos pos, BlockState initialBlockState) {
return getElementHolderOffset();
}

default boolean tickElementHolder(ServerWorld world, BlockPos pos, BlockState initialBlockState) {
return tickElementHolder();
}

@Deprecated
default Vec3d getElementHolderOffset() {
return Vec3d.ZERO;
}

@Deprecated
default ElementHolder createElementHolder(BlockPos pos, BlockState initialBlockState) {
return null;
};

@Deprecated
default boolean tickElementHolder() {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ protected void onTick() {
}

protected void updatePosition() {
if (this.attachment == null) {
return;
}

var newPos = this.attachment.getPos();

if (!this.currentPos.equals(newPos)) {
Expand Down Expand Up @@ -223,4 +227,7 @@ public boolean equals(Object o) {
public int hashCode() {
return 31;
}

public void notifyUpdate(HolderAttachment.UpdateType updateType) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import org.jetbrains.annotations.Nullable;

public final class BlockBoundAttachment extends ChunkAttachment {
public static final UpdateType BLOCK_STATE_UPDATE = UpdateType.of("BlockState");

private final BlockPos blockPos;
private BlockState blockState;

Expand All @@ -36,6 +38,9 @@ public BlockPos getBlockPos() {
@ApiStatus.Internal
public void setBlockState(BlockState blockState) {
this.blockState = blockState;
if (this == this.holder().getAttachment()) {
this.holder().notifyUpdate(BLOCK_STATE_UPDATE);
}
}

public BlockState getBlockState() {
Expand All @@ -52,4 +57,9 @@ public static BlockBoundAttachment get(World world, BlockPos pos) {
public static BlockBoundAttachment get(WorldChunk chunk, BlockPos pos) {
return ((HolderAttachmentHolder) chunk).polymerVE$getPosHolder(pos);
}

@Nullable
public static BlockBoundAttachment get(ElementHolder holder) {
return holder.getAttachment() instanceof BlockBoundAttachment blockBoundAttachment ? blockBoundAttachment : null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ public EntityAttachment(ElementHolder holder, Entity entity, boolean autoTick) {
this.autoTick = autoTick;
}

public static EntityAttachment of(ElementHolder holder, Entity entity) {
return new EntityAttachment(holder, entity, false);
}

public static EntityAttachment ofTicking(ElementHolder holder, Entity entity) {
return new EntityAttachment(holder, entity, true);
}

@Override
public ElementHolder holder() {
return this.holder;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package eu.pb4.polymer.virtualentity.api.attachment;

import eu.pb4.polymer.virtualentity.api.ElementHolder;
import eu.pb4.polymer.virtualentity.impl.SimpleUpdateType;
import eu.pb4.polymer.virtualentity.impl.VoidUpdateType;
import net.minecraft.network.listener.ClientPlayPacketListener;
import net.minecraft.network.packet.Packet;
import net.minecraft.server.network.ServerPlayNetworkHandler;
Expand Down Expand Up @@ -47,4 +49,17 @@ default void tick() {
default boolean shouldTick() {
return true;
}


interface UpdateType {
UpdateType POSITION = UpdateType.of("BlockState");

static UpdateType of() {
return new VoidUpdateType();
}

static UpdateType of(String type) {
return new SimpleUpdateType(type);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package eu.pb4.polymer.virtualentity.impl;

import eu.pb4.polymer.virtualentity.api.attachment.HolderAttachment;

public record SimpleUpdateType(String value) implements HolderAttachment.UpdateType {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package eu.pb4.polymer.virtualentity.impl;

import eu.pb4.polymer.virtualentity.api.attachment.HolderAttachment;

public record VoidUpdateType() implements HolderAttachment.UpdateType {
@Override
public boolean equals(Object obj) {
return this == obj;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import net.minecraft.world.gen.chunk.BlendingData;
import net.minecraft.world.tick.ChunkTickScheduler;
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.Unique;
Expand All @@ -42,6 +43,7 @@ public WorldChunkMixin(ChunkPos pos, UpgradeData upgradeData, HeightLimitView he
@Shadow
public abstract World getWorld();

@Shadow @Final private World world;
@Unique
private final Collection<HolderAttachment> polymerVE$holders = new ArrayList<>();

Expand All @@ -53,7 +55,7 @@ public WorldChunkMixin(ChunkPos pos, UpgradeData upgradeData, HeightLimitView he
at = @At("TAIL")
)
private void polymer$polymerBlocksInit(World world, ChunkPos pos, UpgradeData upgradeData, ChunkTickScheduler blockTickScheduler, ChunkTickScheduler fluidTickScheduler, long inhabitedTime, ChunkSection[] sectionArrayInitializer, WorldChunk.EntityLoader entityLoader, BlendingData blendingData, CallbackInfo ci) {
if (world instanceof ServerWorld) {
if (world instanceof ServerWorld serverWorld) {
for (var section : this.getSectionArray()) {
if (section != null && !section.isEmpty()) {
var container = section.getBlockStateContainer();
Expand All @@ -67,9 +69,9 @@ public WorldChunkMixin(ChunkPos pos, UpgradeData upgradeData, HeightLimitView he
if (state.getBlock() instanceof BlockWithElementHolder blockWithElementHolder) {
var blockPos = pos.getBlockPos(x, section.getYOffset() + y, z);

var holder = blockWithElementHolder.createElementHolder(blockPos, state);
var holder = blockWithElementHolder.createElementHolder(serverWorld, blockPos, state);
if (holder != null) {
new BlockBoundAttachment(holder, (WorldChunk) (Object) this, state, blockPos, Vec3d.ofCenter(blockPos).add(blockWithElementHolder.getElementHolderOffset()), blockWithElementHolder.tickElementHolder());
new BlockBoundAttachment(holder, (WorldChunk) (Object) this, state, blockPos, Vec3d.ofCenter(blockPos).add(blockWithElementHolder.getElementHolderOffset(serverWorld, blockPos, state)), blockWithElementHolder.tickElementHolder(serverWorld, blockPos, state));
}
}
}
Expand Down Expand Up @@ -98,10 +100,11 @@ public WorldChunkMixin(ChunkPos pos, UpgradeData upgradeData, HeightLimitView he
@Inject(method = "setBlockState", at = @At(value = "FIELD", target = "Lnet/minecraft/world/chunk/WorldChunk;needsSaving:Z"), locals = LocalCapture.CAPTURE_FAILSOFT)
private void polymerVE$addNew(BlockPos pos, BlockState state, boolean moved, CallbackInfoReturnable<BlockState> 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) {
var holder = blockWithElementHolder.createElementHolder(pos, state);

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) {
new BlockBoundAttachment(holder, (WorldChunk) (Object) this, state, pos.toImmutable(), Vec3d.ofCenter(pos).add(blockWithElementHolder.getElementHolderOffset()), blockWithElementHolder.tickElementHolder());
new BlockBoundAttachment(holder, (WorldChunk) (Object) this, state, pos.toImmutable(), Vec3d.ofCenter(pos).add(blockWithElementHolder.getElementHolderOffset(serverWorld, pos, state)), blockWithElementHolder.tickElementHolder(serverWorld, pos, state));
}
}
};
Expand Down

0 comments on commit 9f3fbc4

Please sign in to comment.