From 1b933e712a7005acb4c86c232843df2e29b073d4 Mon Sep 17 00:00:00 2001 From: "Josiah (Gaming32) Glosson" Date: Wed, 12 Jul 2023 11:41:27 -0500 Subject: [PATCH] Packet for updating block entities --- .../blockentities/CatapultBlockEntity.java | 32 ++++++++++++++++++- .../portalcubed/listeners/NbtSyncable.java | 9 ++++++ .../packet/PortalCubedServerPackets.java | 32 +++++++++++++++++++ .../assets/portalcubed/lang/en_us.json | 3 +- 4 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/fusionflux/portalcubed/listeners/NbtSyncable.java diff --git a/src/main/java/com/fusionflux/portalcubed/blocks/blockentities/CatapultBlockEntity.java b/src/main/java/com/fusionflux/portalcubed/blocks/blockentities/CatapultBlockEntity.java index 2ed50e5f..1d21b8e0 100644 --- a/src/main/java/com/fusionflux/portalcubed/blocks/blockentities/CatapultBlockEntity.java +++ b/src/main/java/com/fusionflux/portalcubed/blocks/blockentities/CatapultBlockEntity.java @@ -1,9 +1,12 @@ package com.fusionflux.portalcubed.blocks.blockentities; import com.fusionflux.portalcubed.blocks.PortalCubedBlocks; +import com.fusionflux.portalcubed.listeners.NbtSyncable; import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory; +import net.minecraft.commands.CommandRuntimeException; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.Tag; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.chat.Component; import net.minecraft.network.protocol.Packet; @@ -14,6 +17,7 @@ import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; @@ -21,7 +25,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class CatapultBlockEntity extends BlockEntity implements ExtendedScreenHandlerFactory { +public class CatapultBlockEntity extends BlockEntity implements ExtendedScreenHandlerFactory, NbtSyncable { private double destX; private double destY; private double destZ; @@ -54,6 +58,32 @@ protected void saveAdditional(CompoundTag nbt) { nbt.putDouble("Angle", angle); } + @Override + public void syncNbt(CompoundTag nbt, ServerPlayer player) throws CommandRuntimeException { + destX = getDouble(nbt, player, "DestX", destX); + destY = getDouble(nbt, player, "DestY", destY); + destZ = getDouble(nbt, player, "DestZ", destZ); + angle = getDouble(nbt, player, "Angle", angle); + updateListeners(); + } + + private static double getDouble(CompoundTag nbt, ServerPlayer player, String key, double defaultValue) throws CommandRuntimeException { + if (!nbt.contains(key, Tag.TAG_DOUBLE)) { + return defaultValue; + } + final double value = nbt.getDouble(key); + if (!Double.isFinite(value)) { + throw new CommandRuntimeException(Component.translatable("portalcubed.catapult.invalidDouble", value)); + } + return value; + } + + public void updateListeners() { + setChanged(); + assert level != null; + level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), Block.UPDATE_ALL); + } + @NotNull @Override public CompoundTag getUpdateTag() { diff --git a/src/main/java/com/fusionflux/portalcubed/listeners/NbtSyncable.java b/src/main/java/com/fusionflux/portalcubed/listeners/NbtSyncable.java new file mode 100644 index 00000000..d2d7ca56 --- /dev/null +++ b/src/main/java/com/fusionflux/portalcubed/listeners/NbtSyncable.java @@ -0,0 +1,9 @@ +package com.fusionflux.portalcubed.listeners; + +import net.minecraft.commands.CommandRuntimeException; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerPlayer; + +public interface NbtSyncable { + void syncNbt(CompoundTag nbt, ServerPlayer player) throws CommandRuntimeException; +} diff --git a/src/main/java/com/fusionflux/portalcubed/packet/PortalCubedServerPackets.java b/src/main/java/com/fusionflux/portalcubed/packet/PortalCubedServerPackets.java index 68816f3f..380ca155 100644 --- a/src/main/java/com/fusionflux/portalcubed/packet/PortalCubedServerPackets.java +++ b/src/main/java/com/fusionflux/portalcubed/packet/PortalCubedServerPackets.java @@ -10,13 +10,17 @@ import com.fusionflux.portalcubed.entity.CorePhysicsEntity; import com.fusionflux.portalcubed.entity.TurretEntity; import com.fusionflux.portalcubed.items.PortalCubedItems; +import com.fusionflux.portalcubed.listeners.NbtSyncable; import com.fusionflux.portalcubed.sound.PortalCubedSounds; import com.fusionflux.portalcubed.util.AdvancedEntityRaycast; import com.fusionflux.portalcubed.util.ClickHandlingItem; import com.fusionflux.portalcubed.util.PortalCubedComponents; import com.fusionflux.portalcubed.util.PortalDirectionUtils; +import net.minecraft.commands.CommandRuntimeException; import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; @@ -52,6 +56,7 @@ public class PortalCubedServerPackets { public static final ResourceLocation LEFT_CLICK = id("left_click"); public static final ResourceLocation RIGHT_CLICK = id("right_click"); public static final ResourceLocation SYNC_SHOOTER_ROT = id("sync_shooter_rot"); + public static final ResourceLocation NBT_SYNC = id("nbt_sync"); public static void onGrabKeyPressed(MinecraftServer server, ServerPlayer player, @SuppressWarnings("unused") ServerGamePacketListenerImpl handler, @SuppressWarnings("unused") FriendlyByteBuf buf, @SuppressWarnings("unused") PacketSender sender) { @@ -189,5 +194,32 @@ public static void registerPackets() { player.yHeadRotO = yRot; }); }); + ServerPlayNetworking.registerGlobalReceiver(NBT_SYNC, (server, player, handler, buf, responseSender) -> { + final BlockPos pos = buf.readBlockPos(); + final CompoundTag nbt = buf.readNbt(); + server.execute(() -> { + final Vec3 originPos = Vec3.atCenterOf(pos); + if (player.position().distanceToSqr(originPos) > 100) { + PortalCubed.LOGGER.warn( + "Player {} tried to update distant block entity ({})", + player, player.position().distanceTo(originPos) + ); + return; + } + if (player.level().getBlockState(pos) instanceof NbtSyncable syncable) { + try { + syncable.syncNbt(nbt, player); + } catch (CommandRuntimeException e) { + player.connection.disconnect(e.getComponent()); + PortalCubed.LOGGER.warn("Player {} sent invalid sync NBT: {}", player, e.getLocalizedMessage()); + } catch (Exception e) { + player.connection.disconnect(Component.translatable("disconnect.genericReason", e.getLocalizedMessage())); + PortalCubed.LOGGER.error("Error in handling nbt_sync", e); + } + } else { + PortalCubed.LOGGER.warn("{} failed to update non-existent block entity at {}", player, pos); + } + }); + }); } } diff --git a/src/main/resources/assets/portalcubed/lang/en_us.json b/src/main/resources/assets/portalcubed/lang/en_us.json index 186cd586..30e19ee3 100644 --- a/src/main/resources/assets/portalcubed/lang/en_us.json +++ b/src/main/resources/assets/portalcubed/lang/en_us.json @@ -494,5 +494,6 @@ "portalcubed.catapult.destX": "Destination X", "portalcubed.catapult.destY": "Destination Y", "portalcubed.catapult.destZ": "Destination Z", - "portalcubed.catapult.angle": "Launch Angle" + "portalcubed.catapult.angle": "Launch Angle", + "portalcubed.catapult.invalidDouble": "Invalid double: %s" } \ No newline at end of file