diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/inventory/gui/GuiLaserRelayItemWhitelist.java b/src/main/java/de/ellpeck/actuallyadditions/mod/inventory/gui/GuiLaserRelayItemWhitelist.java index 19d73b25e..f43b405e2 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/inventory/gui/GuiLaserRelayItemWhitelist.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/inventory/gui/GuiLaserRelayItemWhitelist.java @@ -12,16 +12,14 @@ package de.ellpeck.actuallyadditions.mod.inventory.gui; import com.mojang.blaze3d.systems.RenderSystem; import de.ellpeck.actuallyadditions.mod.inventory.ContainerLaserRelayItemWhitelist; -import de.ellpeck.actuallyadditions.mod.network.packet.PacketClientToServer; -import de.ellpeck.actuallyadditions.mod.network.PacketHandler; import de.ellpeck.actuallyadditions.mod.network.PacketHelperClient; +import de.ellpeck.actuallyadditions.mod.network.packet.ButtonToContainerPacket; import de.ellpeck.actuallyadditions.mod.tile.TileEntityLaserRelayItemAdvanced; import de.ellpeck.actuallyadditions.mod.util.AssetUtil; import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; -import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.FormattedCharSequence; @@ -84,11 +82,8 @@ public class GuiLaserRelayItemWhitelist extends AAScreen { private static final ResourceLocation RES_LOC = AssetUtil.getGuiLocation("gui_ranged_collector"); @@ -73,14 +70,8 @@ public class GuiRangedCollector extends AAScreen { } public void buttonClicked(int id) { - CompoundTag data = new CompoundTag(); - data.putInt("ButtonID", id); - data.putInt("PlayerID", Minecraft.getInstance().player.getId()); - data.putString("WorldID", Minecraft.getInstance().level.dimension().location().toString()); - data.putInt("X", this.collector.getBlockPos().getX()); - data.putInt("Y", this.collector.getBlockPos().getY()); - data.putInt("Z", this.collector.getBlockPos().getZ()); - PacketDistributor.sendToServer(new PacketClientToServer(data, PacketHandler.GUI_BUTTON_TO_TILE_HANDLER)); + PacketDistributor.sendToServer(new ButtonToTilePacket(collector.getLevel().dimension().location(), + this.collector.getBlockPos(), Minecraft.getInstance().player.getId(), id)); } } diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/inventory/gui/ItemTagScreen.java b/src/main/java/de/ellpeck/actuallyadditions/mod/inventory/gui/ItemTagScreen.java index 82d00175c..c63795d21 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/inventory/gui/ItemTagScreen.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/inventory/gui/ItemTagScreen.java @@ -1,16 +1,13 @@ package de.ellpeck.actuallyadditions.mod.inventory.gui; import de.ellpeck.actuallyadditions.mod.inventory.ItemTagContainer; -import de.ellpeck.actuallyadditions.mod.network.packet.PacketClientToServer; -import de.ellpeck.actuallyadditions.mod.network.PacketHandler; -import net.minecraft.client.Minecraft; +import de.ellpeck.actuallyadditions.mod.network.packet.ButtonToContainerPacket; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.EditBox; import net.minecraft.client.gui.components.StringWidget; import net.minecraft.core.HolderSet; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; -import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.TagKey; @@ -81,12 +78,13 @@ public class ItemTagScreen extends AAScreen { this.minecraft.player.closeContainer(); } if (pKeyCode == GLFW.GLFW_KEY_ENTER && validTag) { - CompoundTag data = new CompoundTag(); - data.putInt("ButtonID", 0); - data.putInt("PlayerID", Minecraft.getInstance().player.getId()); - data.putString("WorldID", Minecraft.getInstance().level.dimension().location().toString()); - data.putString("Tag", tagBox.getValue()); - PacketDistributor.sendToServer(new PacketClientToServer(data, PacketHandler.GUI_BUTTON_TO_CONTAINER_HANDLER)); +// data.putString("Tag", tagBox.getValue()); TODO: This value was never used by the old packet (GUI_BUTTON_TO_CONTAINER_HANDLER) + PacketDistributor.sendToServer(new ButtonToContainerPacket( + minecraft.level.dimension().location(), + minecraft.player.getId(), + 0 + )); + this.minecraft.player.closeContainer(); } diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/inventory/gui/SackGui.java b/src/main/java/de/ellpeck/actuallyadditions/mod/inventory/gui/SackGui.java index 81fe76093..0e36660bc 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/inventory/gui/SackGui.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/inventory/gui/SackGui.java @@ -12,14 +12,12 @@ package de.ellpeck.actuallyadditions.mod.inventory.gui; import com.mojang.blaze3d.systems.RenderSystem; import de.ellpeck.actuallyadditions.mod.inventory.SackContainer; -import de.ellpeck.actuallyadditions.mod.network.packet.PacketClientToServer; -import de.ellpeck.actuallyadditions.mod.network.PacketHandler; +import de.ellpeck.actuallyadditions.mod.network.packet.ButtonToContainerPacket; import de.ellpeck.actuallyadditions.mod.util.AssetUtil; import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; -import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.player.Inventory; @@ -65,11 +63,11 @@ public class SackGui extends AAScreen { } public void buttonClicked(int id) { - CompoundTag data = new CompoundTag(); - data.putInt("ButtonID", id); - data.putInt("PlayerID", Minecraft.getInstance().player.getId()); - data.putString("WorldID", Minecraft.getInstance().level.dimension().location().toString()); - PacketDistributor.sendToServer(new PacketClientToServer(data, PacketHandler.GUI_BUTTON_TO_CONTAINER_HANDLER)); + PacketDistributor.sendToServer(new ButtonToContainerPacket( + Minecraft.getInstance().level.dimension().location(), + Minecraft.getInstance().player.getId(), + id + )); } @Override diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/inventory/gui/VoidSackGui.java b/src/main/java/de/ellpeck/actuallyadditions/mod/inventory/gui/VoidSackGui.java index 54c091f57..3ea212784 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/inventory/gui/VoidSackGui.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/inventory/gui/VoidSackGui.java @@ -12,14 +12,11 @@ package de.ellpeck.actuallyadditions.mod.inventory.gui; import com.mojang.blaze3d.systems.RenderSystem; import de.ellpeck.actuallyadditions.mod.inventory.VoidSackContainer; -import de.ellpeck.actuallyadditions.mod.network.packet.PacketClientToServer; -import de.ellpeck.actuallyadditions.mod.network.PacketHandler; +import de.ellpeck.actuallyadditions.mod.network.packet.ButtonToContainerPacket; import de.ellpeck.actuallyadditions.mod.util.AssetUtil; import net.minecraft.ChatFormatting; -import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; -import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.player.Inventory; @@ -65,11 +62,11 @@ public class VoidSackGui extends AAScreen { } public void buttonClicked(int id) { - CompoundTag data = new CompoundTag(); - data.putInt("ButtonID", id); - data.putInt("PlayerID", Minecraft.getInstance().player.getId()); - data.putString("WorldID", Minecraft.getInstance().level.dimension().location().toString()); - PacketDistributor.sendToServer(new PacketClientToServer(data, PacketHandler.GUI_BUTTON_TO_CONTAINER_HANDLER)); + PacketDistributor.sendToServer(new ButtonToContainerPacket( + minecraft.level.dimension().location(), + minecraft.player.getId(), + id + )); } @Override diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/network/IDataHandler.java b/src/main/java/de/ellpeck/actuallyadditions/mod/network/IDataHandler.java deleted file mode 100644 index 1530d5c74..000000000 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/network/IDataHandler.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * This file ("IDataHandler.java") is part of the Actually Additions mod for Minecraft. - * It is created and owned by Ellpeck and distributed - * under the Actually Additions License to be found at - * http://ellpeck.de/actaddlicense - * View the source code at https://github.com/Ellpeck/ActuallyAdditions - * - * © 2015-2017 Ellpeck - */ - -package de.ellpeck.actuallyadditions.mod.network; - -import net.minecraft.nbt.CompoundTag; -import net.neoforged.neoforge.network.handling.IPayloadContext; - -public interface IDataHandler { - - void handleData(CompoundTag compound, IPayloadContext context); - -} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/network/PacketHandler.java b/src/main/java/de/ellpeck/actuallyadditions/mod/network/PacketHandler.java index 85144ece1..56720c113 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/network/PacketHandler.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/network/PacketHandler.java @@ -11,159 +11,36 @@ package de.ellpeck.actuallyadditions.mod.network; import de.ellpeck.actuallyadditions.mod.ActuallyAdditions; -import de.ellpeck.actuallyadditions.mod.data.PlayerData; -import de.ellpeck.actuallyadditions.mod.data.WorldData; -import de.ellpeck.actuallyadditions.mod.network.gui.IButtonReactor; -import de.ellpeck.actuallyadditions.mod.network.gui.INumberReactor; -import de.ellpeck.actuallyadditions.mod.network.gui.IStringReactor; -import de.ellpeck.actuallyadditions.mod.network.packet.PacketClientToServer; -import de.ellpeck.actuallyadditions.mod.network.packet.PacketServerToClient; -import net.minecraft.core.BlockPos; -import net.minecraft.core.registries.Registries; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.protocol.PacketFlow; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.inventory.AbstractContainerMenu; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.entity.BlockEntity; +import de.ellpeck.actuallyadditions.mod.network.handler.ClientPayloadHandler; +import de.ellpeck.actuallyadditions.mod.network.handler.ServerPayloadHandler; +import de.ellpeck.actuallyadditions.mod.network.packet.ButtonToContainerPacket; +import de.ellpeck.actuallyadditions.mod.network.packet.ButtonToTilePacket; +import de.ellpeck.actuallyadditions.mod.network.packet.NumberToTilePacket; +import de.ellpeck.actuallyadditions.mod.network.packet.SpawnLaserPacket; +import de.ellpeck.actuallyadditions.mod.network.packet.SpawnLaserParticlePacket; +import de.ellpeck.actuallyadditions.mod.network.packet.StringToTilePacket; +import de.ellpeck.actuallyadditions.mod.network.packet.SyncPlayerPacket; +import de.ellpeck.actuallyadditions.mod.network.packet.TileUpdatePacket; import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent; -import net.neoforged.neoforge.network.handling.IPayloadContext; +import net.neoforged.neoforge.network.handling.DirectionalPayloadHandler; import net.neoforged.neoforge.network.registration.PayloadRegistrar; -import java.util.ArrayList; -import java.util.List; - public final class PacketHandler { - public static final List DATA_HANDLERS = new ArrayList<>(); - public static final IDataHandler LASER_HANDLER = new IDataHandler() { - @Override - public void handleData(CompoundTag compound, IPayloadContext context) { - if(context.flow() == PacketFlow.CLIENTBOUND) { - PacketHelperClient.handleLaser(compound, context); - } - } - }; - public static final IDataHandler TILE_ENTITY_HANDLER = new IDataHandler() { - @Override - public void handleData(CompoundTag compound, IPayloadContext context) { - if(context.flow() == PacketFlow.CLIENTBOUND) { - PacketHelperClient.handleTileUpdate(compound, context); - } - } - }; - public static final IDataHandler LASER_PARTICLE_HANDLER = new IDataHandler() { - @Override - public void handleData(CompoundTag compound, IPayloadContext context) { - if(context.flow() == PacketFlow.CLIENTBOUND) { - PacketHelperClient.handleLaserParticle(compound, context); - } - } - }; - public static final IDataHandler GUI_BUTTON_TO_TILE_HANDLER = (compound, context) -> { - if (context.player() != null) { - Player player = context.player(); - Level level = player.getServer().getLevel(ResourceKey.create(Registries.DIMENSION, ResourceLocation.tryParse(compound.getString("WorldID")))); - BlockEntity tile = level.getBlockEntity(new BlockPos(compound.getInt("X"), compound.getInt("Y"), compound.getInt("Z"))); - - if (tile instanceof IButtonReactor reactor) { - Entity entity = level.getEntity(compound.getInt("PlayerID")); - if (entity instanceof Player) { - reactor.onButtonPressed(compound.getInt("ButtonID"), (Player) entity); - } - } - } - }; - public static final IDataHandler GUI_BUTTON_TO_CONTAINER_HANDLER = (compound, context) -> { - if (context.player() != null) { - Player player = context.player(); - Level level = player.getServer().getLevel(ResourceKey.create(Registries.DIMENSION, ResourceLocation.tryParse(compound.getString("WorldID")))); - Entity entity = level.getEntity(compound.getInt("PlayerID")); - if (entity instanceof Player p) { - AbstractContainerMenu container = p.containerMenu; - if (container instanceof IButtonReactor reactor) { - reactor.onButtonPressed(compound.getInt("ButtonID"), (Player) entity); - } - } - } - }; - public static final IDataHandler GUI_NUMBER_TO_TILE_HANDLER = (compound, context) -> { - if (context.player() != null) { - Player player = context.player(); - Level level = player.getServer().getLevel(ResourceKey.create(Registries.DIMENSION, ResourceLocation.tryParse(compound.getString("WorldID")))); - BlockEntity tile = level.getBlockEntity(new BlockPos(compound.getInt("X"), compound.getInt("Y"), compound.getInt("Z"))); - - if (tile instanceof INumberReactor reactor) { - reactor.onNumberReceived(compound.getDouble("Number"), compound.getInt("NumberID"), (Player) level.getEntity(compound.getInt("PlayerID"))); - } - } - }; - public static final IDataHandler GUI_STRING_TO_TILE_HANDLER = (compound, context) -> { - if (context.player() != null) { - Player player = context.player(); - Level level = player.getServer().getLevel(ResourceKey.create(Registries.DIMENSION, ResourceLocation.tryParse(compound.getString("WorldID")))); - BlockEntity tile = level.getBlockEntity(new BlockPos(compound.getInt("X"), compound.getInt("Y"), compound.getInt("Z"))); - - if (tile instanceof IStringReactor reactor) { - reactor.onTextReceived(compound.getString("Text"), compound.getInt("TextID"), (Player) level.getEntity(compound.getInt("PlayerID"))); - } - } - }; - public static final IDataHandler SYNC_PLAYER_DATA = new IDataHandler() { - @Override - public void handleData(CompoundTag compound, IPayloadContext context) { - if(context.flow() == PacketFlow.CLIENTBOUND) { - PacketHelperClient.handlePlayerUpdate(compound, context); - } - } - }; - public static final IDataHandler PLAYER_DATA_TO_SERVER = (compound, context) -> { - if (context.player() != null) { - Level level = context.player().getServer().getLevel(ResourceKey.create(Registries.DIMENSION, ResourceLocation.tryParse(compound.getString("World")))); - Player player = level.getServer().getPlayerList().getPlayer(compound.getUUID("UUID")); - if (player != null) { - PlayerData.PlayerSave data = PlayerData.getDataFromPlayer(player); - - int type = compound.getInt("Type"); - if (type == 0) { - data.loadBookmarks(compound.getList("Bookmarks", 8)); - } else if (type == 1) { - data.didBookTutorial = compound.getBoolean("DidBookTutorial"); - } else if (type == 2) { - data.loadTrials(compound.getList("Trials", 8)); - - if (compound.getBoolean("Achievement")) { - //TheAchievements.COMPLETE_TRIALS.get(player); - } - } - WorldData.get(level).setDirty(); - - if (compound.getBoolean("Log")) { - ActuallyAdditions.LOGGER.info("Receiving changed Player Data for player {}.", player.getName()); - } - } else { - ActuallyAdditions.LOGGER.error("Tried to receive Player Data for UUID {}, but he doesn't seem to be present!", compound.getUUID("UUID")); - } - } - }; public static void register(final RegisterPayloadHandlersEvent event) { final PayloadRegistrar registrar = event.registrar(ActuallyAdditions.MODID); - registrar.playToClient(PacketServerToClient.ID, PacketServerToClient.CODEC, PacketServerToClient::handle); - registrar.playToServer(PacketClientToServer.ID, PacketClientToServer.CODEC, PacketClientToServer::handle); + registrar.playToClient(SpawnLaserPacket.ID, SpawnLaserPacket.CODEC, ClientPayloadHandler.getInstance()::handleSpawnLaser); + registrar.playToClient(SpawnLaserParticlePacket.ID, SpawnLaserParticlePacket.CODEC, ClientPayloadHandler.getInstance()::handleSpawnLaserParticle); + registrar.playToClient(TileUpdatePacket.ID, TileUpdatePacket.CODEC, ClientPayloadHandler.getInstance()::handleTileUpdate); - DATA_HANDLERS.add(LASER_HANDLER); - DATA_HANDLERS.add(TILE_ENTITY_HANDLER); - DATA_HANDLERS.add(GUI_BUTTON_TO_TILE_HANDLER); - DATA_HANDLERS.add(GUI_STRING_TO_TILE_HANDLER); - DATA_HANDLERS.add(GUI_NUMBER_TO_TILE_HANDLER); - DATA_HANDLERS.add(SYNC_PLAYER_DATA); - DATA_HANDLERS.add(GUI_BUTTON_TO_CONTAINER_HANDLER); - DATA_HANDLERS.add(LASER_PARTICLE_HANDLER); - DATA_HANDLERS.add(PLAYER_DATA_TO_SERVER); + registrar.playToServer(ButtonToTilePacket.ID, ButtonToTilePacket.CODEC, ServerPayloadHandler.getInstance()::handleButtonToTile); + registrar.playToServer(StringToTilePacket.ID, StringToTilePacket.CODEC, ServerPayloadHandler.getInstance()::handleStringToTile); + registrar.playToServer(NumberToTilePacket.ID, NumberToTilePacket.CODEC, ServerPayloadHandler.getInstance()::handleNumberToTile); + registrar.playToServer(ButtonToContainerPacket.ID, ButtonToContainerPacket.CODEC, ServerPayloadHandler.getInstance()::handleButtonToContainer); + + registrar.playBidirectional(SyncPlayerPacket.ID, SyncPlayerPacket.CODEC, + new DirectionalPayloadHandler<>(ClientPayloadHandler.getInstance()::handleSyncPlayer, ServerPayloadHandler.getInstance()::handleSyncPlayer)); } } diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/network/PacketHelperClient.java b/src/main/java/de/ellpeck/actuallyadditions/mod/network/PacketHelperClient.java index 6b31b1931..b6a64f2ca 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/network/PacketHelperClient.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/network/PacketHelperClient.java @@ -12,79 +12,24 @@ package de.ellpeck.actuallyadditions.mod.network; import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; import de.ellpeck.actuallyadditions.api.booklet.IBookletChapter; -import de.ellpeck.actuallyadditions.mod.ActuallyAdditions; import de.ellpeck.actuallyadditions.mod.data.PlayerData; import de.ellpeck.actuallyadditions.mod.data.PlayerData.PlayerSave; -import de.ellpeck.actuallyadditions.mod.network.packet.PacketClientToServer; -import de.ellpeck.actuallyadditions.mod.particle.ParticleLaserItem; -import de.ellpeck.actuallyadditions.mod.tile.TileEntityBase; -import de.ellpeck.actuallyadditions.mod.util.AssetUtil; +import de.ellpeck.actuallyadditions.mod.network.packet.ButtonToTilePacket; +import de.ellpeck.actuallyadditions.mod.network.packet.NumberToTilePacket; +import de.ellpeck.actuallyadditions.mod.network.packet.SyncPlayerPacket; import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; import net.neoforged.neoforge.network.PacketDistributor; -import net.neoforged.neoforge.network.handling.IPayloadContext; public final class PacketHelperClient { - public static void handleLaser(CompoundTag compound, IPayloadContext context) { - AssetUtil.spawnLaserWithTimeClient(compound.getDouble("StartX"), compound.getDouble("StartY"), compound.getDouble("StartZ"), compound.getDouble("EndX"), compound.getDouble("EndY"), compound.getDouble("EndZ"), compound.getInt("Color"), compound.getInt("MaxAge"), compound.getDouble("RotationTime"), compound.getFloat("Size"), compound.getFloat("Alpha")); - } - - public static void handleTileUpdate(CompoundTag compound, IPayloadContext context) { - Level world = Minecraft.getInstance().level; - if (world != null) { - BlockEntity tile = world.getBlockEntity(new BlockPos(compound.getInt("X"), compound.getInt("Y"), compound.getInt("Z"))); - if (tile instanceof TileEntityBase tileBase) { - tileBase.readSyncableNBT(compound.getCompound("Data"), world.registryAccess(), TileEntityBase.NBTType.SYNC); - } - } - } - - public static void handleLaserParticle(CompoundTag compound, IPayloadContext context) { - Minecraft mc = Minecraft.getInstance(); - ItemStack stack = ItemStack.parseOptional(context.player().registryAccess(), compound); - - double inX = compound.getDouble("InX") + 0.5; - double inY = compound.getDouble("InY") + 0.78; - double inZ = compound.getDouble("InZ") + 0.5; - - double outX = compound.getDouble("OutX") + 0.5; - double outY = compound.getDouble("OutY") + 0.525; - double outZ = compound.getDouble("OutZ") + 0.5; - - mc.level.addParticle(ParticleLaserItem.Factory.createData(stack, inX, inY, inZ), - outX, outY, outZ, 0, 0.025, 0); - } - - public static void handlePlayerUpdate(CompoundTag compound, IPayloadContext context) { - CompoundTag dataTag = compound.getCompound("Data"); - Player player = context.player(); //ActuallyAdditions.PROXY.getCurrentPlayer(); - - if (player != null) { - PlayerData.getDataFromPlayer(player).readFromNBT(dataTag, false); - - if (compound.getBoolean("Log")) { - ActuallyAdditions.LOGGER.info("Receiving (new or changed) Player Data for player {}.", player.getName()); - } - } else { - ActuallyAdditions.LOGGER.error("Tried to receive Player Data for the current player, but he doesn't seem to be present!"); - } - } public static void sendButtonPacket(BlockEntity tile, int buttonId) { - CompoundTag compound = new CompoundTag(); BlockPos pos = tile.getBlockPos(); - compound.putInt("X", pos.getX()); - compound.putInt("Y", pos.getY()); - compound.putInt("Z", pos.getZ()); - compound.putString("WorldID", tile.getLevel().dimension().location().toString()); - compound.putInt("PlayerID", Minecraft.getInstance().player.getId()); - compound.putInt("ButtonID", buttonId); - PacketDistributor.sendToServer(new PacketClientToServer(compound, PacketHandler.GUI_BUTTON_TO_TILE_HANDLER)); + PacketDistributor.sendToServer(new ButtonToTilePacket(tile.getLevel().dimension().location(), + pos, Minecraft.getInstance().player.getId(), buttonId)); } public static void sendPlayerDataToServer(boolean log, int type) { @@ -118,20 +63,14 @@ public final class PacketHelperClient { } } - PacketDistributor.sendToServer(new PacketClientToServer(compound, PacketHandler.PLAYER_DATA_TO_SERVER)); + PacketDistributor.sendToServer(new SyncPlayerPacket(compound)); } } public static void sendNumberPacket(BlockEntity tile, double number, int id) { - CompoundTag compound = new CompoundTag(); - compound.putInt("X", tile.getBlockPos().getX()); - compound.putInt("Y", tile.getBlockPos().getY()); - compound.putInt("Z", tile.getBlockPos().getZ()); - compound.putString("WorldID", tile.getLevel().dimension().location().toString()); - compound.putInt("PlayerID", Minecraft.getInstance().player.getId()); - compound.putInt("NumberID", id); - compound.putDouble("Number", number); - PacketDistributor.sendToServer(new PacketClientToServer(compound, PacketHandler.GUI_NUMBER_TO_TILE_HANDLER)); + PacketDistributor.sendToServer(new NumberToTilePacket( + tile.getLevel().dimension().location(), tile.getBlockPos(), Minecraft.getInstance().player.getId(), number, id + )); } } diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/network/PacketHelperServer.java b/src/main/java/de/ellpeck/actuallyadditions/mod/network/PacketHelperServer.java index 97952b426..19d0ce6af 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/network/PacketHelperServer.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/network/PacketHelperServer.java @@ -12,10 +12,13 @@ package de.ellpeck.actuallyadditions.mod.network; import de.ellpeck.actuallyadditions.mod.ActuallyAdditions; import de.ellpeck.actuallyadditions.mod.data.PlayerData; -import de.ellpeck.actuallyadditions.mod.network.packet.PacketServerToClient; +import de.ellpeck.actuallyadditions.mod.network.packet.SpawnLaserPacket; +import de.ellpeck.actuallyadditions.mod.network.packet.SyncPlayerPacket; import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Player; +import net.neoforged.neoforge.network.PacketDistributor; /** * A helper class for sending packets from the server to the client. @@ -32,7 +35,17 @@ public final class PacketHelperServer { ActuallyAdditions.LOGGER.info("Sending data {}", data); if (player instanceof ServerPlayer serverPlayer) { - serverPlayer.connection.send(new PacketServerToClient(compound, PacketHandler.SYNC_PLAYER_DATA)); + serverPlayer.connection.send(new SyncPlayerPacket(data)); + } + } + + public static void spawnLaserWithTimeServer(ServerLevel world, double startX, double startY, double startZ, double endX, double endY, double endZ, int color, int maxAge, double rotationTime, float size, float alpha) { + if (!world.isClientSide) { + PacketDistributor.sendToPlayersNear(world, null, startX, startY, startZ, 96, new SpawnLaserPacket( + startX, startY, startZ, + endX, endY, endZ, + color, maxAge, rotationTime, size, alpha + )); } } } diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/network/handler/ClientPayloadHandler.java b/src/main/java/de/ellpeck/actuallyadditions/mod/network/handler/ClientPayloadHandler.java new file mode 100644 index 000000000..6d4e26b92 --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/network/handler/ClientPayloadHandler.java @@ -0,0 +1,119 @@ +package de.ellpeck.actuallyadditions.mod.network.handler; + +import de.ellpeck.actuallyadditions.mod.ActuallyAdditions; +import de.ellpeck.actuallyadditions.mod.data.PlayerData; +import de.ellpeck.actuallyadditions.mod.network.packet.SpawnLaserPacket; +import de.ellpeck.actuallyadditions.mod.network.packet.SpawnLaserParticlePacket; +import de.ellpeck.actuallyadditions.mod.network.packet.SyncPlayerPacket; +import de.ellpeck.actuallyadditions.mod.network.packet.TileUpdatePacket; +import de.ellpeck.actuallyadditions.mod.particle.ParticleLaserItem; +import de.ellpeck.actuallyadditions.mod.tile.TileEntityBase; +import de.ellpeck.actuallyadditions.mod.util.AssetUtil; +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.neoforged.neoforge.network.handling.IPayloadContext; + +public class ClientPayloadHandler { + private static final ClientPayloadHandler INSTANCE = new ClientPayloadHandler(); + + public static ClientPayloadHandler getInstance() { + return INSTANCE; + } + + public void handleSpawnLaser(final SpawnLaserPacket packet, final IPayloadContext context) { + context.enqueueWork(() -> { + if (context.flow().isClientbound()) { + AssetUtil.spawnLaserWithTimeClient( + packet.startX(), packet.startY(), packet.startZ(), + packet.endX(), packet.endY(), packet.endZ(), + packet.color(), packet.maxAge(), packet.rotationTime(), + packet.size(), packet.alpha() + ); + } + }) + .exceptionally(e -> { + // Handle exception + context.disconnect(Component.translatable("actuallyadditions.networking.spawn_laser.failed", e.getMessage())); + return null; + }); + } + + public void handleSpawnLaserParticle(final SpawnLaserParticlePacket packet, final IPayloadContext context) { + context.enqueueWork(() -> { + if (context.flow().isClientbound()) { + Player player = context.player(); + if (player != null) { + ItemStack stack = packet.stack(); + + BlockPos in = packet.in(); + double inX = in.getX() + 0.5; + double inY = in.getY() + 0.78; + double inZ = in.getZ() + 0.5; + + BlockPos out = packet.out(); + double outX = out.getX() + 0.5; + double outY = out.getY() + 0.525; + double outZ = out.getZ() + 0.5; + + player.level().addParticle(ParticleLaserItem.Factory.createData(stack, inX, inY, inZ), + outX, outY, outZ, 0, 0.025, 0); + } + } + }) + .exceptionally(e -> { + // Handle exception + context.disconnect(Component.translatable("actuallyadditions.networking.spawn_laser_particle.failed", e.getMessage())); + return null; + }); + } + + public void handleTileUpdate(final TileUpdatePacket packet, final IPayloadContext context) { + context.enqueueWork(() -> { + if (context.flow().isClientbound()) { + Player player = context.player(); + if (player != null) { + BlockEntity tile = player.level().getBlockEntity(packet.pos()); + if (tile instanceof TileEntityBase tileBase) { + tileBase.readSyncableNBT(packet.data(), player.registryAccess(), TileEntityBase.NBTType.SYNC); + } + } + } + }) + .exceptionally(e -> { + // Handle exception + context.disconnect(Component.translatable("actuallyadditions.networking.tile_update.failed", e.getMessage())); + return null; + }); + } + + public void handleSyncPlayer(final SyncPlayerPacket packet, final IPayloadContext context) { + context.enqueueWork(() -> { + if (context.flow().isClientbound()) { + Player player = context.player(); //ActuallyAdditions.PROXY.getCurrentPlayer(); + CompoundTag tag = packet.tag(); + CompoundTag dataTag = tag.getCompound("Data"); + + if (player != null) { + PlayerData.getDataFromPlayer(player).readFromNBT(dataTag, false); + + if (tag.getBoolean("Log")) { + ActuallyAdditions.LOGGER.info("Receiving (new or changed) Player Data for player {}.", player.getName()); + } + } else { + ActuallyAdditions.LOGGER.error("Tried to receive Player Data for the current player, but he doesn't seem to be present!"); + } + } + }) + .exceptionally(e -> { + // Handle exception + context.disconnect(Component.translatable("actuallyadditions.networking.sync_player_client.failed", e.getMessage())); + return null; + }); + } + + +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/network/handler/ServerPayloadHandler.java b/src/main/java/de/ellpeck/actuallyadditions/mod/network/handler/ServerPayloadHandler.java new file mode 100644 index 000000000..6670efcfc --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/network/handler/ServerPayloadHandler.java @@ -0,0 +1,152 @@ +package de.ellpeck.actuallyadditions.mod.network.handler; + +import de.ellpeck.actuallyadditions.mod.ActuallyAdditions; +import de.ellpeck.actuallyadditions.mod.data.PlayerData; +import de.ellpeck.actuallyadditions.mod.data.WorldData; +import de.ellpeck.actuallyadditions.mod.network.gui.IButtonReactor; +import de.ellpeck.actuallyadditions.mod.network.gui.INumberReactor; +import de.ellpeck.actuallyadditions.mod.network.gui.IStringReactor; +import de.ellpeck.actuallyadditions.mod.network.packet.ButtonToContainerPacket; +import de.ellpeck.actuallyadditions.mod.network.packet.ButtonToTilePacket; +import de.ellpeck.actuallyadditions.mod.network.packet.NumberToTilePacket; +import de.ellpeck.actuallyadditions.mod.network.packet.StringToTilePacket; +import de.ellpeck.actuallyadditions.mod.network.packet.SyncPlayerPacket; +import net.minecraft.core.registries.Registries; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.neoforged.neoforge.network.handling.IPayloadContext; + +public class ServerPayloadHandler { + public static final ServerPayloadHandler INSTANCE = new ServerPayloadHandler(); + + public static ServerPayloadHandler getInstance() { + return INSTANCE; + } + + public void handleButtonToTile(final ButtonToTilePacket packet, final IPayloadContext context) { + context.enqueueWork(() -> { + if (context.player() != null) { + Player player = context.player(); + Level level = player.getServer().getLevel(ResourceKey.create(Registries.DIMENSION, packet.dimension())); + BlockEntity tile = level.getBlockEntity(packet.pos()); + + if (tile instanceof IButtonReactor reactor) { + Entity entity = level.getEntity(packet.playerId()); + if (entity instanceof Player) { + reactor.onButtonPressed(packet.buttonId(), (Player) entity); + } + } + } + }) + .exceptionally(e -> { + // Handle exception + context.disconnect(Component.translatable("actuallyadditions.networking.button_to_tile.failed", e.getMessage())); + return null; + }); + } + + public void handleStringToTile(final StringToTilePacket packet, final IPayloadContext context) { + context.enqueueWork(() -> { + if (context.player() != null) { + Player player = context.player(); + Level level = player.getServer().getLevel(ResourceKey.create(Registries.DIMENSION, packet.dimension())); + BlockEntity tile = level.getBlockEntity(packet.pos()); + + if (tile instanceof IStringReactor reactor) { + reactor.onTextReceived(packet.text(), packet.textId(), (Player) level.getEntity(packet.playerId())); + } + } + }) + .exceptionally(e -> { + // Handle exception + context.disconnect(Component.translatable("actuallyadditions.networking.string_to_tile.failed", e.getMessage())); + return null; + }); + } + + public void handleNumberToTile(final NumberToTilePacket packet, final IPayloadContext context) { + context.enqueueWork(() -> { + if (context.player() != null) { + Player player = context.player(); + Level level = player.getServer().getLevel(ResourceKey.create(Registries.DIMENSION, packet.dimension())); + BlockEntity tile = level.getBlockEntity(packet.pos()); + + if (tile instanceof INumberReactor reactor) { + reactor.onNumberReceived(packet.number(), packet.numberId(), (Player) level.getEntity(packet.playerId())); + } + } + }) + .exceptionally(e -> { + // Handle exception + context.disconnect(Component.translatable("actuallyadditions.networking.number_to_tile.failed", e.getMessage())); + return null; + }); + } + + public void handleButtonToContainer(final ButtonToContainerPacket packet, final IPayloadContext context) { + context.enqueueWork(() -> { + if (context.player() != null) { + Player player = context.player(); + Level level = player.getServer().getLevel(ResourceKey.create(Registries.DIMENSION, packet.dimension())); + Entity entity = level.getEntity(packet.playerId()); + if (entity instanceof Player p) { + AbstractContainerMenu container = p.containerMenu; + if (container instanceof IButtonReactor reactor) { + reactor.onButtonPressed(packet.buttonId(), (Player) entity); + } + } + } + }) + .exceptionally(e -> { + // Handle exception + context.disconnect(Component.translatable("actuallyadditions.networking.button_to_container.failed", e.getMessage())); + return null; + }); + } + + public void handleSyncPlayer(final SyncPlayerPacket packet, final IPayloadContext context) { + context.enqueueWork(() -> { + if (context.player() != null) { + CompoundTag tag = packet.tag(); + Level level = context.player().getServer().getLevel(ResourceKey.create(Registries.DIMENSION, + ResourceLocation.tryParse(tag.getString("World")))); + Player player = level.getServer().getPlayerList().getPlayer(tag.getUUID("UUID")); + if (player != null) { + PlayerData.PlayerSave data = PlayerData.getDataFromPlayer(player); + + int type = tag.getInt("Type"); + if (type == 0) { + data.loadBookmarks(tag.getList("Bookmarks", 8)); + } else if (type == 1) { + data.didBookTutorial = tag.getBoolean("DidBookTutorial"); + } else if (type == 2) { + data.loadTrials(tag.getList("Trials", 8)); + + if (tag.getBoolean("Achievement")) { + //TheAchievements.COMPLETE_TRIALS.get(player); + } + } + WorldData.get(level).setDirty(); + + if (tag.getBoolean("Log")) { + ActuallyAdditions.LOGGER.info("Receiving changed Player Data for player {}.", player.getName()); + } + } else { + ActuallyAdditions.LOGGER.error("Tried to receive Player Data for UUID {}, but he doesn't seem to be present!", tag.getUUID("UUID")); + } + } + }) + .exceptionally(e -> { + // Handle exception + context.disconnect(Component.translatable("actuallyadditions.networking.sync_player.failed", e.getMessage())); + return null; + }); + } +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/network/packet/ButtonToContainerPacket.java b/src/main/java/de/ellpeck/actuallyadditions/mod/network/packet/ButtonToContainerPacket.java new file mode 100644 index 000000000..96c2918bc --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/network/packet/ButtonToContainerPacket.java @@ -0,0 +1,34 @@ +package de.ellpeck.actuallyadditions.mod.network.packet; + +import de.ellpeck.actuallyadditions.mod.ActuallyAdditions; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; + +public record ButtonToContainerPacket(ResourceLocation dimension, int playerId, int buttonId) implements CustomPacketPayload { + public static final StreamCodec CODEC = CustomPacketPayload.codec( + ButtonToContainerPacket::write, + ButtonToContainerPacket::new); + public static final Type ID = new Type<>(ResourceLocation.fromNamespaceAndPath(ActuallyAdditions.MODID, "button_to_container")); + + + public ButtonToContainerPacket(FriendlyByteBuf buf) { + this( + ResourceLocation.STREAM_CODEC.decode(buf), + buf.readInt(), + buf.readInt() + ); + } + + public void write(FriendlyByteBuf buf) { + ResourceLocation.STREAM_CODEC.encode(buf, dimension); + buf.writeInt(playerId); + buf.writeInt(buttonId); + } + + @Override + public Type type() { + return ID; + } +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/network/packet/ButtonToTilePacket.java b/src/main/java/de/ellpeck/actuallyadditions/mod/network/packet/ButtonToTilePacket.java new file mode 100644 index 000000000..f18e86fa0 --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/network/packet/ButtonToTilePacket.java @@ -0,0 +1,38 @@ +package de.ellpeck.actuallyadditions.mod.network.packet; + +import de.ellpeck.actuallyadditions.mod.ActuallyAdditions; +import net.minecraft.core.BlockPos; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; + +public record ButtonToTilePacket(ResourceLocation dimension, BlockPos pos, int playerId, + int buttonId) implements CustomPacketPayload { + public static final StreamCodec CODEC = CustomPacketPayload.codec( + ButtonToTilePacket::write, + ButtonToTilePacket::new); + public static final Type ID = new Type<>(ResourceLocation.fromNamespaceAndPath(ActuallyAdditions.MODID, "button_to_tile")); + + + public ButtonToTilePacket(FriendlyByteBuf buf) { + this( + ResourceLocation.STREAM_CODEC.decode(buf), + BlockPos.STREAM_CODEC.decode(buf), + buf.readInt(), + buf.readInt() + ); + } + + public void write(FriendlyByteBuf buf) { + ResourceLocation.STREAM_CODEC.encode(buf, dimension); + BlockPos.STREAM_CODEC.encode(buf, pos); + buf.writeInt(playerId); + buf.writeInt(buttonId); + } + + @Override + public Type type() { + return ID; + } +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/network/packet/NumberToTilePacket.java b/src/main/java/de/ellpeck/actuallyadditions/mod/network/packet/NumberToTilePacket.java new file mode 100644 index 000000000..c5de31ba0 --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/network/packet/NumberToTilePacket.java @@ -0,0 +1,40 @@ +package de.ellpeck.actuallyadditions.mod.network.packet; + +import de.ellpeck.actuallyadditions.mod.ActuallyAdditions; +import net.minecraft.core.BlockPos; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; + +public record NumberToTilePacket(ResourceLocation dimension, BlockPos pos, int playerId, + double number, int numberId) implements CustomPacketPayload { + public static final StreamCodec CODEC = CustomPacketPayload.codec( + NumberToTilePacket::write, + NumberToTilePacket::new); + public static final Type ID = new Type<>(ResourceLocation.fromNamespaceAndPath(ActuallyAdditions.MODID, "number_to_tile")); + + + public NumberToTilePacket(FriendlyByteBuf buf) { + this( + ResourceLocation.STREAM_CODEC.decode(buf), + BlockPos.STREAM_CODEC.decode(buf), + buf.readInt(), + buf.readDouble(), + buf.readInt() + ); + } + + public void write(FriendlyByteBuf buf) { + ResourceLocation.STREAM_CODEC.encode(buf, dimension); + BlockPos.STREAM_CODEC.encode(buf, pos); + buf.writeInt(playerId); + buf.writeDouble(number); + buf.writeInt(numberId); + } + + @Override + public Type type() { + return ID; + } +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/network/packet/PacketClientToServer.java b/src/main/java/de/ellpeck/actuallyadditions/mod/network/packet/PacketClientToServer.java deleted file mode 100644 index 48ac430e2..000000000 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/network/packet/PacketClientToServer.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file ("PacketClientToServer.java") is part of the Actually Additions mod for Minecraft. - * It is created and owned by Ellpeck and distributed - * under the Actually Additions License to be found at - * http://ellpeck.de/actaddlicense - * View the source code at https://github.com/Ellpeck/ActuallyAdditions - * - * © 2015-2017 Ellpeck - */ - -package de.ellpeck.actuallyadditions.mod.network.packet; - -import de.ellpeck.actuallyadditions.mod.ActuallyAdditions; -import de.ellpeck.actuallyadditions.mod.network.IDataHandler; -import de.ellpeck.actuallyadditions.mod.network.PacketHandler; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.network.codec.StreamCodec; -import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.neoforged.neoforge.network.handling.IPayloadContext; -import org.apache.commons.lang3.tuple.Pair; - -public record PacketClientToServer(CompoundTag data, IDataHandler handler) implements CustomPacketPayload { - public static final StreamCodec CODEC = CustomPacketPayload.codec( - PacketClientToServer::write, - PacketClientToServer::new); - public static final Type ID = new Type<>(ActuallyAdditions.modLoc("client_to_server")); - - public PacketClientToServer(Pair data) { - this(data.getLeft(), data.getRight()); - } - - public PacketClientToServer(final FriendlyByteBuf buffer) { - this(fromBytes(buffer)); - } - - public static Pair fromBytes(FriendlyByteBuf buffer) { - try { - CompoundTag data = buffer.readNbt(); - - int handlerId = buffer.readInt(); - if (handlerId >= 0 && handlerId < PacketHandler.DATA_HANDLERS.size()) { - return Pair.of(data, PacketHandler.DATA_HANDLERS.get(handlerId)); - } - } catch (Exception e) { - ActuallyAdditions.LOGGER.error("Something went wrong trying to receive a server packet!", e); - } - return Pair.of(null, null); - } - - public void write(FriendlyByteBuf buf) { - buf.writeNbt(data); - buf.writeInt(PacketHandler.DATA_HANDLERS.indexOf(handler)); - } - - public static void handle(final PacketClientToServer message, final IPayloadContext context) { - context.enqueueWork( - () -> { - if (message.data != null && message.handler != null) { - message.handler.handleData(message.data, context); - } - } - ); - } - - @Override - public Type type() { - return ID; - } -} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/network/packet/PacketServerToClient.java b/src/main/java/de/ellpeck/actuallyadditions/mod/network/packet/PacketServerToClient.java deleted file mode 100644 index e4245432a..000000000 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/network/packet/PacketServerToClient.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file ("PacketServerToClient.java") is part of the Actually Additions mod for Minecraft. - * It is created and owned by Ellpeck and distributed - * under the Actually Additions License to be found at - * http://ellpeck.de/actaddlicense - * View the source code at https://github.com/Ellpeck/ActuallyAdditions - * - * © 2015-2017 Ellpeck - */ - -package de.ellpeck.actuallyadditions.mod.network.packet; - -import de.ellpeck.actuallyadditions.mod.ActuallyAdditions; -import de.ellpeck.actuallyadditions.mod.network.IDataHandler; -import de.ellpeck.actuallyadditions.mod.network.PacketHandler; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.network.codec.StreamCodec; -import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.neoforged.neoforge.network.handling.IPayloadContext; -import org.apache.commons.lang3.tuple.Pair; - - -public record PacketServerToClient(CompoundTag data, IDataHandler handler) implements CustomPacketPayload { - public static final StreamCodec CODEC = CustomPacketPayload.codec( - PacketServerToClient::write, - PacketServerToClient::new); - public static final Type ID = new Type<>(ActuallyAdditions.modLoc("server_to_client")); - - public PacketServerToClient(Pair data) { - this(data.getLeft(), data.getRight()); - } - - public PacketServerToClient(final FriendlyByteBuf buffer) { - this(fromBytes(buffer)); - } - - public static Pair fromBytes(FriendlyByteBuf buffer) { - try { - CompoundTag data = buffer.readNbt(); - - int handlerId = buffer.readInt(); - if (handlerId >= 0 && handlerId < PacketHandler.DATA_HANDLERS.size()) { - return Pair.of(data, PacketHandler.DATA_HANDLERS.get(handlerId)); - } - } catch (Exception e) { - ActuallyAdditions.LOGGER.error("Something went wrong trying to receive a client packet!", e); - } - return Pair.of(null, null); - } - - public void write(FriendlyByteBuf buf) { - buf.writeNbt(data); - buf.writeInt(PacketHandler.DATA_HANDLERS.indexOf(handler)); - } - @Override - public Type type() { - return ID; - } - - public static void handle(final PacketServerToClient message, final IPayloadContext context) { - context.enqueueWork( - () -> { - if (message.data != null && message.handler != null) { - message.handler.handleData(message.data, context); - } - } - ); - } -} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/network/packet/SpawnLaserPacket.java b/src/main/java/de/ellpeck/actuallyadditions/mod/network/packet/SpawnLaserPacket.java new file mode 100644 index 000000000..8cbac00c9 --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/network/packet/SpawnLaserPacket.java @@ -0,0 +1,55 @@ +package de.ellpeck.actuallyadditions.mod.network.packet; + +import de.ellpeck.actuallyadditions.mod.ActuallyAdditions; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; + +public record SpawnLaserPacket(double startX, double startY, double startZ, + double endX, double endY, double endZ, + int color, int maxAge, double rotationTime, float size, + float alpha) implements CustomPacketPayload { + public static final StreamCodec CODEC = CustomPacketPayload.codec( + SpawnLaserPacket::write, + SpawnLaserPacket::new); + public static final Type ID = new Type<>(ResourceLocation.fromNamespaceAndPath(ActuallyAdditions.MODID, "spawn_laser")); + + + public SpawnLaserPacket(FriendlyByteBuf buf) { + this( + buf.readDouble(), + buf.readDouble(), + buf.readDouble(), + buf.readDouble(), + buf.readDouble(), + buf.readDouble(), + buf.readInt(), + buf.readInt(), + buf.readDouble(), + buf.readFloat(), + buf.readFloat() + ); + } + + public void write(FriendlyByteBuf buf) { + buf.writeDouble(startX); + buf.writeDouble(startY); + buf.writeDouble(startZ); + buf.writeDouble(endX); + buf.writeDouble(endY); + buf.writeDouble(endZ); + buf.writeInt(color); + buf.writeInt(maxAge); + buf.writeDouble(rotationTime); + buf.writeFloat(size); + buf.writeFloat(alpha); + } + + @Override + public Type type() { + return ID; + } + + +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/network/packet/SpawnLaserParticlePacket.java b/src/main/java/de/ellpeck/actuallyadditions/mod/network/packet/SpawnLaserParticlePacket.java new file mode 100644 index 000000000..05ac0c946 --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/network/packet/SpawnLaserParticlePacket.java @@ -0,0 +1,38 @@ +package de.ellpeck.actuallyadditions.mod.network.packet; + +import de.ellpeck.actuallyadditions.mod.ActuallyAdditions; +import net.minecraft.core.BlockPos; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; + +public record SpawnLaserParticlePacket(ItemStack stack, BlockPos in, BlockPos out) implements CustomPacketPayload { + public static final StreamCodec CODEC = CustomPacketPayload.codec( + SpawnLaserParticlePacket::write, + SpawnLaserParticlePacket::new); + public static final Type ID = new Type<>(ResourceLocation.fromNamespaceAndPath(ActuallyAdditions.MODID, "spawn_laser_particle")); + + + public SpawnLaserParticlePacket(RegistryFriendlyByteBuf buf) { + this( + ItemStack.STREAM_CODEC.decode(buf), + BlockPos.STREAM_CODEC.decode(buf), + BlockPos.STREAM_CODEC.decode(buf) + ); + } + + public void write(RegistryFriendlyByteBuf buf) { + ItemStack.STREAM_CODEC.encode(buf, stack); + BlockPos.STREAM_CODEC.encode(buf, in); + BlockPos.STREAM_CODEC.encode(buf, out); + } + + @Override + public Type type() { + return ID; + } + + +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/network/packet/StringToTilePacket.java b/src/main/java/de/ellpeck/actuallyadditions/mod/network/packet/StringToTilePacket.java new file mode 100644 index 000000000..4df3ba041 --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/network/packet/StringToTilePacket.java @@ -0,0 +1,40 @@ +package de.ellpeck.actuallyadditions.mod.network.packet; + +import de.ellpeck.actuallyadditions.mod.ActuallyAdditions; +import net.minecraft.core.BlockPos; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; + +public record StringToTilePacket(ResourceLocation dimension, BlockPos pos, int playerId, + String text, int textId) implements CustomPacketPayload { + public static final StreamCodec CODEC = CustomPacketPayload.codec( + StringToTilePacket::write, + StringToTilePacket::new); + public static final Type ID = new Type<>(ResourceLocation.fromNamespaceAndPath(ActuallyAdditions.MODID, "string_to_tile")); + + + public StringToTilePacket(FriendlyByteBuf buf) { + this( + ResourceLocation.STREAM_CODEC.decode(buf), + BlockPos.STREAM_CODEC.decode(buf), + buf.readInt(), + buf.readUtf(), + buf.readInt() + ); + } + + public void write(FriendlyByteBuf buf) { + ResourceLocation.STREAM_CODEC.encode(buf, dimension); + BlockPos.STREAM_CODEC.encode(buf, pos); + buf.writeInt(playerId); + buf.writeUtf(text); + buf.writeInt(textId); + } + + @Override + public Type type() { + return ID; + } +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/network/packet/SyncPlayerPacket.java b/src/main/java/de/ellpeck/actuallyadditions/mod/network/packet/SyncPlayerPacket.java new file mode 100644 index 000000000..0fa44d6b3 --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/network/packet/SyncPlayerPacket.java @@ -0,0 +1,28 @@ +package de.ellpeck.actuallyadditions.mod.network.packet; + +import de.ellpeck.actuallyadditions.mod.ActuallyAdditions; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; + +public record SyncPlayerPacket(CompoundTag tag) implements CustomPacketPayload { + public static final StreamCodec CODEC = CustomPacketPayload.codec( + SyncPlayerPacket::write, + SyncPlayerPacket::new); + public static final Type ID = new Type<>(ResourceLocation.fromNamespaceAndPath(ActuallyAdditions.MODID, "sync_player")); + + + public SyncPlayerPacket(FriendlyByteBuf buf) { + this(buf.readNbt()); + } + public void write(FriendlyByteBuf buf) { + buf.writeNbt(tag); + } + + @Override + public Type type() { + return ID; + } +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/network/packet/TileUpdatePacket.java b/src/main/java/de/ellpeck/actuallyadditions/mod/network/packet/TileUpdatePacket.java new file mode 100644 index 000000000..5c50e5c39 --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/network/packet/TileUpdatePacket.java @@ -0,0 +1,36 @@ +package de.ellpeck.actuallyadditions.mod.network.packet; + +import de.ellpeck.actuallyadditions.mod.ActuallyAdditions; +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; + +public record TileUpdatePacket(BlockPos pos, CompoundTag data) implements CustomPacketPayload { + public static final StreamCodec CODEC = CustomPacketPayload.codec( + TileUpdatePacket::write, + TileUpdatePacket::new); + public static final Type ID = new Type<>(ResourceLocation.fromNamespaceAndPath(ActuallyAdditions.MODID, "tile_update")); + + + public TileUpdatePacket(FriendlyByteBuf buf) { + this( + buf.readBlockPos(), + buf.readNbt() + ); + } + + public void write(FriendlyByteBuf buf) { + buf.writeBlockPos(pos); + buf.writeNbt(data); + } + + @Override + public Type type() { + return ID; + } + + +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityAtomicReconstructor.java b/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityAtomicReconstructor.java index 10ab8b1a2..68a6b4fe9 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityAtomicReconstructor.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityAtomicReconstructor.java @@ -17,7 +17,7 @@ import de.ellpeck.actuallyadditions.api.lens.Lens; import de.ellpeck.actuallyadditions.mod.AASounds; import de.ellpeck.actuallyadditions.mod.blocks.ActuallyBlocks; import de.ellpeck.actuallyadditions.mod.config.CommonConfig; -import de.ellpeck.actuallyadditions.mod.util.AssetUtil; +import de.ellpeck.actuallyadditions.mod.network.PacketHelperServer; import de.ellpeck.actuallyadditions.mod.util.ItemStackHandlerAA.IAcceptor; import de.ellpeck.actuallyadditions.mod.util.WorldUtil; import net.minecraft.core.BlockPos; @@ -53,7 +53,7 @@ public class TileEntityAtomicReconstructor extends TileEntityInventoryBase imple public static void shootLaser(IAtomicReconstructor tile, ServerLevel world, double startX, double startY, double startZ, double endX, double endY, double endZ, Lens currentLens) { world.playSound(null, startX, startY, startZ, AASounds.RECONSTRUCTOR.get(), SoundSource.BLOCKS, 0.35F, 1.0F); - AssetUtil.spawnLaserWithTimeServer(world, startX, startY, startZ, endX, endY, endZ, currentLens.getColor(), 25, 0, 0.2F, 0.8F); + PacketHelperServer.spawnLaserWithTimeServer(world, startX, startY, startZ, endX, endY, endZ, currentLens.getColor(), 25, 0, 0.2F, 0.8F); } @Override diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityItemInterface.java b/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityItemInterface.java index aab270930..81456858c 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityItemInterface.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityItemInterface.java @@ -12,14 +12,12 @@ package de.ellpeck.actuallyadditions.mod.tile; import de.ellpeck.actuallyadditions.api.laser.Network; import de.ellpeck.actuallyadditions.mod.blocks.ActuallyBlocks; -import de.ellpeck.actuallyadditions.mod.network.PacketHandler; -import de.ellpeck.actuallyadditions.mod.network.packet.PacketServerToClient; +import de.ellpeck.actuallyadditions.mod.network.packet.SpawnLaserParticlePacket; import de.ellpeck.actuallyadditions.mod.util.StackUtil; import de.ellpeck.actuallyadditions.mod.util.WorldUtil; import de.ellpeck.actuallyadditions.mod.util.compat.SlotlessableItemHandlerWrapper; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; -import net.minecraft.nbt.CompoundTag; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; @@ -162,22 +160,11 @@ public class TileEntityItemInterface extends TileEntityBase { public void doItemParticle(ItemStack stack, BlockPos input, BlockPos output) { if (!this.level.isClientSide) { - CompoundTag compound = new CompoundTag(); - stack.save(this.level.registryAccess(), compound); - - compound.putDouble("InX", input.getX()); - compound.putDouble("InY", input.getY()); - compound.putDouble("InZ", input.getZ()); - - compound.putDouble("OutX", output.getX()); - compound.putDouble("OutY", output.getY()); - compound.putDouble("OutZ", output.getZ()); - int rangeSq = 16 * 16; for (Player player : this.level.players()) { - if (player instanceof ServerPlayer) { + if (player instanceof ServerPlayer serverPlayer) { if (player.distanceToSqr(input.getX(), input.getY(), input.getZ()) <= rangeSq || player.distanceToSqr(output.getX(), output.getY(), output.getZ()) <= rangeSq) { - ((ServerPlayer) player).connection.send(new PacketServerToClient(compound, PacketHandler.LASER_PARTICLE_HANDLER)); + serverPlayer.connection.send(new SpawnLaserParticlePacket(stack, input, output)); } } } diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityLeafGenerator.java b/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityLeafGenerator.java index e9cdc4ca9..07871b089 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityLeafGenerator.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityLeafGenerator.java @@ -12,7 +12,7 @@ package de.ellpeck.actuallyadditions.mod.tile; import de.ellpeck.actuallyadditions.mod.blocks.ActuallyBlocks; import de.ellpeck.actuallyadditions.mod.config.CommonConfig; -import de.ellpeck.actuallyadditions.mod.util.AssetUtil; +import de.ellpeck.actuallyadditions.mod.network.PacketHelperServer; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.HolderLookup; @@ -89,7 +89,7 @@ public class TileEntityLeafGenerator extends TileEntityBase implements ISharingE tile.storage.receiveEnergyInternal(energyProduced, false); - AssetUtil.spawnLaserWithTimeServer((ServerLevel) level, pos.getX(), pos.getY(), pos.getZ(), theCoord.getX(), theCoord.getY(), theCoord.getZ(), 0x3EA34A, 25, 0, 0.075F, 0.8F); + PacketHelperServer.spawnLaserWithTimeServer((ServerLevel) level, pos.getX(), pos.getY(), pos.getZ(), theCoord.getX(), theCoord.getY(), theCoord.getZ(), 0x3EA34A, 25, 0, 0.075F, 0.8F); } } } else { diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityVerticalDigger.java b/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityVerticalDigger.java index 4248d72e7..ae92ba1e7 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityVerticalDigger.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/tile/TileEntityVerticalDigger.java @@ -13,8 +13,8 @@ package de.ellpeck.actuallyadditions.mod.tile; import de.ellpeck.actuallyadditions.mod.blocks.ActuallyBlocks; import de.ellpeck.actuallyadditions.mod.config.CommonConfig; import de.ellpeck.actuallyadditions.mod.inventory.ContainerMiner; +import de.ellpeck.actuallyadditions.mod.network.PacketHelperServer; import de.ellpeck.actuallyadditions.mod.network.gui.IButtonReactor; -import de.ellpeck.actuallyadditions.mod.util.AssetUtil; import de.ellpeck.actuallyadditions.mod.util.ItemStackHandlerAA.IAcceptor; import de.ellpeck.actuallyadditions.mod.util.StackUtil; import de.ellpeck.actuallyadditions.mod.util.WorldUtil; @@ -197,7 +197,7 @@ public class TileEntityVerticalDigger extends TileEntityInventoryBase implements } private void shootParticles(int endX, int endY, int endZ) { - AssetUtil.spawnLaserWithTimeServer((ServerLevel) this.level, this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ(), endX, endY, endZ, 0x429602, 10, 120, 0.1F, 0.8F); + PacketHelperServer.spawnLaserWithTimeServer((ServerLevel) this.level, this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ(), endX, endY, endZ, 0x429602, 10, 120, 0.1F, 0.8F); } private boolean isBlacklisted(Block block) { diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/util/AssetUtil.java b/src/main/java/de/ellpeck/actuallyadditions/mod/util/AssetUtil.java index 67bd26d9b..555853cd7 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/util/AssetUtil.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/util/AssetUtil.java @@ -16,8 +16,6 @@ import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.math.Axis; import de.ellpeck.actuallyadditions.mod.ActuallyAdditions; import de.ellpeck.actuallyadditions.mod.blocks.render.RenderTypes; -import de.ellpeck.actuallyadditions.mod.network.PacketHandler; -import de.ellpeck.actuallyadditions.mod.network.packet.PacketServerToClient; import de.ellpeck.actuallyadditions.mod.particle.ParticleBeam; import net.minecraft.client.Camera; import net.minecraft.client.Minecraft; @@ -33,9 +31,7 @@ import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.core.BlockPos; import net.minecraft.core.NonNullList; -import net.minecraft.nbt.CompoundTag; import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.level.ServerLevel; import net.minecraft.util.FastColor; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; @@ -47,7 +43,6 @@ import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; import net.neoforged.neoforge.client.ClientHooks; -import net.neoforged.neoforge.network.PacketDistributor; import org.joml.Matrix4f; public final class AssetUtil { @@ -216,24 +211,6 @@ public final class AssetUtil { // GlStateManager._popMatrix(); // } - public static void spawnLaserWithTimeServer(ServerLevel world, double startX, double startY, double startZ, double endX, double endY, double endZ, int color, int maxAge, double rotationTime, float size, float alpha) { - if (!world.isClientSide) { - CompoundTag data = new CompoundTag(); - data.putDouble("StartX", startX); - data.putDouble("StartY", startY); - data.putDouble("StartZ", startZ); - data.putDouble("EndX", endX); - data.putDouble("EndY", endY); - data.putDouble("EndZ", endZ); - data.putInt("Color", color); - data.putDouble("RotationTime", rotationTime); - data.putFloat("Size", size); - data.putInt("MaxAge", maxAge); - data.putFloat("Alpha", alpha); - PacketDistributor.sendToPlayersNear(world, null, startX, startY, startZ, 96, new PacketServerToClient(data, PacketHandler.LASER_HANDLER)); - } - } - public static void spawnLaserWithTimeClient(double startX, double startY, double startZ, double endX, double endY, double endZ, int color, int maxAge, double rotationTime, float size, float alpha) { Minecraft mc = Minecraft.getInstance(); diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/util/VanillaPacketDispatcher.java b/src/main/java/de/ellpeck/actuallyadditions/mod/util/VanillaPacketDispatcher.java index 64940333f..33a348e32 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/util/VanillaPacketDispatcher.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/util/VanillaPacketDispatcher.java @@ -10,6 +10,9 @@ public final class VanillaPacketDispatcher { //Don't call from the client. public static void dispatchTEToNearbyPlayers(BlockEntity blockEntity) { + if (blockEntity.getLevel().isClientSide) { + throw new IllegalArgumentException("Tried to dispatch a TileEntity packet on the client side! This is not allowed!"); + } ServerLevel serverLevel = (ServerLevel) blockEntity.getLevel(); LevelChunk chunk = serverLevel.getChunk(blockEntity.getBlockPos().getX() >> 4, blockEntity.getBlockPos().getZ() >> 4); diff --git a/src/main/resources/assets/actuallyadditions/lang/en_us.json b/src/main/resources/assets/actuallyadditions/lang/en_us.json index c80bef640..ce74a8050 100644 --- a/src/main/resources/assets/actuallyadditions/lang/en_us.json +++ b/src/main/resources/assets/actuallyadditions/lang/en_us.json @@ -976,6 +976,16 @@ "booklet.actuallyadditions.chapter.trialsIntro": "Intro to Trials", "booklet.actuallyadditions.chapter.trialsIntro.text.1": "Trials are a set of fun and interesting challenges that you can use to get inspiration on what to build next. Once you complete a Trial, you can press the button in the bottom right to mark the trial as completed, turning its name in the list green. Since there is no way to check if a trial is actually completed, Trials are meant as personal goals. To visit the Trials page, you can click the bookmark in the top right corner of the manual GUI.", "booklet.actuallyadditions.chapter.trialsIntro.text.2": "Note that Trials are designed in a way that they should be completed with the concepts of Minecraft and Actually Additions alone.", + "_comment": "Networking", + "actuallyadditions.networking.spawn_laser.failed": "Failed to spawn laser: %s", + "actuallyadditions.networking.spawn_laser_particle.failed": "Failed to spawn laser particle: %s", + "actuallyadditions.networking.tile_update.failed": "Failed to update tile entity: %s", + "actuallyadditions.networking.sync_player_client.failed": "Failed to sync player data from client to server: %s", + "actuallyadditions.networking.sync_player.failed": "Failed to sync player data from server to client: %s", + "actuallyadditions.networking.button_to_tile.failed": "Failed to send button press to tile entity: %s", + "actuallyadditions.networking.string_to_tile.failed": "Failed to send string to tile entity: %s", + "actuallyadditions.networking.number_to_tile.failed": "Failed to send number to tile entity: %s", + "actuallyadditions.networking.button_to_container.failed": "Failed to send button press to container: %s", "_comment": "JEI", "jei.actuallyadditions.coffee.special": "Special Feature", "jei.actuallyadditions.coffee.maxAmount": "Max Amount",