From c8e1855da667fa25a7ff751c8275938feed23a70 Mon Sep 17 00:00:00 2001 From: Kam Date: Thu, 28 Mar 2024 18:16:17 -0400 Subject: [PATCH] Fix Player Quest Data being too Large --- .../java/noppes/npcs/NoppesUtilServer.java | 24 +++++++++++- .../noppes/npcs/ScriptPlayerEventHandler.java | 2 +- src/main/java/noppes/npcs/Server.java | 6 +++ .../java/noppes/npcs/client/NoppesUtil.java | 37 +++++++++++++++++++ .../npcs/client/PacketHandlerClient.java | 13 +++++-- .../npcs/constants/EnumPacketClient.java | 3 +- .../npcs/controllers/SyncController.java | 20 +++++----- .../npcs/controllers/data/PlayerData.java | 6 +++ 8 files changed, 95 insertions(+), 16 deletions(-) diff --git a/src/main/java/noppes/npcs/NoppesUtilServer.java b/src/main/java/noppes/npcs/NoppesUtilServer.java index f027b4f15..792c04ff3 100644 --- a/src/main/java/noppes/npcs/NoppesUtilServer.java +++ b/src/main/java/noppes/npcs/NoppesUtilServer.java @@ -13,6 +13,7 @@ import net.minecraft.entity.projectile.EntityThrowable; import net.minecraft.init.Blocks; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.server.MinecraftServer; import net.minecraft.tileentity.MobSpawnerBaseLogic; @@ -844,8 +845,29 @@ public class NoppesUtilServer { return entity; } } + public static void sendPlayerDataCompound(EntityPlayerMP player, NBTTagCompound compound, boolean sync) { + try { + byte[] bytes = CompressedStreamTools.compress(compound); - public static boolean isOp(EntityPlayer player) { + // Split byte array into chunks and send each chunk + int chunkSize = 16000; + int totalChunks = (int) Math.ceil((double) bytes.length / chunkSize); + for (int i = 0; i < totalChunks; i++) { + int start = i * chunkSize; + int length = Math.min(bytes.length - start, chunkSize); + byte[] chunk = new byte[length]; + System.arraycopy(bytes, start, chunk, 0, length); + Server.sendData(player, EnumPacketClient.LARGE_NBT_PART, (Object) chunk); + } + // Send end packet + Server.sendData(player, EnumPacketClient.SYNC_PLAYER, sync); + } catch (IOException e) { + e.printStackTrace(); + } + } + + + public static boolean isOp(EntityPlayer player) { return MinecraftServer.getServer().getConfigurationManager().func_152596_g(player.getGameProfile()); } diff --git a/src/main/java/noppes/npcs/ScriptPlayerEventHandler.java b/src/main/java/noppes/npcs/ScriptPlayerEventHandler.java index 8d1dbaf6f..189c70dd7 100644 --- a/src/main/java/noppes/npcs/ScriptPlayerEventHandler.java +++ b/src/main/java/noppes/npcs/ScriptPlayerEventHandler.java @@ -61,7 +61,7 @@ public class ScriptPlayerEventHandler { PlayerData playerData = PlayerDataController.Instance.getPlayerData(player); if(playerData.updateClient) { - Server.sendData((EntityPlayerMP)player, EnumPacketClient.SYNC_END, SyncType.PLAYER_DATA, playerData.getSyncNBT()); + NoppesUtilServer.sendPlayerDataCompound((EntityPlayerMP)player, playerData.getSyncNBT(), true); // VisibilityController.instance.onUpdate((EntityPlayerMP) player); playerData.updateClient = false; } diff --git a/src/main/java/noppes/npcs/Server.java b/src/main/java/noppes/npcs/Server.java index ea7bbd697..a6ef411b2 100644 --- a/src/main/java/noppes/npcs/Server.java +++ b/src/main/java/noppes/npcs/Server.java @@ -95,6 +95,12 @@ public class Server { buffer.writeLong((Long) ob); else if(ob instanceof Double) buffer.writeDouble((Double) ob); + else if (ob instanceof byte[]) { + // Write byte array length followed by bytes + byte[] byteArray = (byte[]) ob; + buffer.writeShort((short) byteArray.length); + buffer.writeBytes(byteArray); + } else if(ob instanceof NBTTagCompound) writeNBT(buffer, (NBTTagCompound) ob); } diff --git a/src/main/java/noppes/npcs/client/NoppesUtil.java b/src/main/java/noppes/npcs/client/NoppesUtil.java index 3a9eb87dd..70628c2f1 100644 --- a/src/main/java/noppes/npcs/client/NoppesUtil.java +++ b/src/main/java/noppes/npcs/client/NoppesUtil.java @@ -6,6 +6,8 @@ import net.minecraft.client.audio.PositionedSoundRecord; import net.minecraft.client.gui.GuiScreen; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.nbt.CompressedStreamTools; +import net.minecraft.nbt.NBTSizeTracker; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.tileentity.TileEntity; @@ -30,6 +32,7 @@ import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.scripted.ScriptParticle; import org.lwjgl.Sys; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.net.URI; @@ -326,4 +329,38 @@ public class NoppesUtil { public static void isGUIOpen(boolean isGUIOpen) { Client.sendData(EnumPacketServer.IsGuiOpen, isGUIOpen); } + + + private static byte[] accumulatedData = new byte[0]; + public static void handleLargeData(byte[] chunk) { + // Append the chunk to the accumulated data + accumulatedData = concatByteArrays(accumulatedData, chunk); + } + + public static void handlePlayerDataEnd(boolean sync) { + NBTTagCompound compound; + try { + compound = CompressedStreamTools.func_152457_a(accumulatedData, new NBTSizeTracker(2097152L)); + if(sync){ + ClientCacheHandler.playerData.setSyncNBT(compound); + } + else { + ClientCacheHandler.playerData.setNBT(compound); + } + } catch (IOException e) { + e.printStackTrace(); + return; + } finally { + // Reset the accumulated data after processing + accumulatedData = new byte[0]; + } + } + + // Utility method to concatenate two byte arrays + private static byte[] concatByteArrays(byte[] a, byte[] b) { + byte[] result = new byte[a.length + b.length]; + System.arraycopy(a, 0, result, 0, a.length); + System.arraycopy(b, 0, result, a.length, b.length); + return result; + } } diff --git a/src/main/java/noppes/npcs/client/PacketHandlerClient.java b/src/main/java/noppes/npcs/client/PacketHandlerClient.java index a1a48a560..e54be94f9 100644 --- a/src/main/java/noppes/npcs/client/PacketHandlerClient.java +++ b/src/main/java/noppes/npcs/client/PacketHandlerClient.java @@ -112,15 +112,20 @@ public class PacketHandlerClient extends PacketHandlerServer{ RecipeController.Instance.anvilRecipes = RecipeController.syncRecipes; RecipeController.syncRecipes = new HashMap(); } + else if(type == EnumPacketClient.LARGE_NBT_PART){ + byte[] chunk = new byte[buffer.readShort()]; + buffer.readBytes(chunk); + NoppesUtil.handleLargeData(chunk); + } + else if(type == EnumPacketClient.SYNC_PLAYER){ + boolean sync = buffer.readBoolean(); + NoppesUtil.handlePlayerDataEnd(sync); + } else if(type == EnumPacketClient.SYNC_ADD || type == EnumPacketClient.SYNC_END){ int synctype = buffer.readInt(); NBTTagCompound compound = Server.readNBT(buffer); SyncController.clientSync(synctype, compound, type == EnumPacketClient.SYNC_END); - - if(synctype == SyncType.PLAYER_DATA){ - ClientCacheHandler.playerData.setNBT(compound); - } } else if(type == EnumPacketClient.SYNC_UPDATE){ int synctype = buffer.readInt(); diff --git a/src/main/java/noppes/npcs/constants/EnumPacketClient.java b/src/main/java/noppes/npcs/constants/EnumPacketClient.java index d1b269bbc..68a48b3e8 100644 --- a/src/main/java/noppes/npcs/constants/EnumPacketClient.java +++ b/src/main/java/noppes/npcs/constants/EnumPacketClient.java @@ -55,6 +55,7 @@ public enum EnumPacketClient { STOP_SOUNDS, SYNC_WEAPON, MARK_DATA, - SYNC_ADD, SYNC_END, SYNC_UPDATE, SYNC_REMOVE, + SYNC_ADD, SYNC_END, SYNC_UPDATE, SYNC_REMOVE, SYNC_PLAYER, + LARGE_NBT_PART, LARGE_NBT_END, PARTY_DATA } diff --git a/src/main/java/noppes/npcs/controllers/SyncController.java b/src/main/java/noppes/npcs/controllers/SyncController.java index e47ebbcbe..564e3e42a 100644 --- a/src/main/java/noppes/npcs/controllers/SyncController.java +++ b/src/main/java/noppes/npcs/controllers/SyncController.java @@ -4,6 +4,7 @@ import io.netty.buffer.ByteBuf; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; +import noppes.npcs.NoppesUtilServer; import noppes.npcs.Server; import noppes.npcs.constants.EnumPacketClient; import noppes.npcs.constants.SyncType; @@ -23,7 +24,7 @@ public class SyncController { NBTTagCompound factioNBT = new NBTTagCompound(); faction.writeNBT(factioNBT); list.appendTag(factioNBT); - if(list.tagCount() > 20){ + if(list.tagCount() > 10){ compound = new NBTTagCompound(); compound.setTag("Data", list); Server.sendData(player, EnumPacketClient.SYNC_ADD, SyncType.FACTION, compound); @@ -43,7 +44,7 @@ public class SyncController { for(int questID : category.quests.keySet()){ Quest quest = category.quests.get(questID); questList.appendTag(quest.writeToNBT(new NBTTagCompound())); - if(questList.tagCount() > 50){ + if(questList.tagCount() > 40){ questCompound = new NBTTagCompound(); questCompound.setTag("Data", questList); questCompound.setTag("CatNBT", category.writeSmallNBT(new NBTTagCompound())); @@ -67,7 +68,7 @@ public class SyncController { for(int dialogID : category.dialogs.keySet()){ Dialog dialog = category.dialogs.get(dialogID); dialogList.appendTag(dialog.writeToNBT(new NBTTagCompound())); - if(dialogList.tagCount() > 50){ + if(dialogList.tagCount() > 40){ dialogCompound = new NBTTagCompound(); dialogCompound.setTag("Data", dialogList); dialogCompound.setTag("CatNBT", category.writeSmallNBT(new NBTTagCompound())); @@ -84,8 +85,9 @@ public class SyncController { //////////////////////////////////////////////////////////////////////////////// PlayerData data = PlayerData.get(player); - if(data != null) - Server.sendData(player, EnumPacketClient.SYNC_END, SyncType.PLAYER_DATA, data.getNBT()); + if(data != null){ + NoppesUtilServer.sendPlayerDataCompound(player, data.getNBT(), false); + } } public static void syncAllDialogs() { @@ -95,7 +97,7 @@ public class SyncController { for(int dialogID : category.dialogs.keySet()){ Dialog dialog = category.dialogs.get(dialogID); dialogList.appendTag(dialog.writeToNBT(new NBTTagCompound())); - if(dialogList.tagCount() > 50){ + if(dialogList.tagCount() > 40){ dialogCompound = new NBTTagCompound(); dialogCompound.setTag("Data", dialogList); dialogCompound.setTag("CatNBT", category.writeSmallNBT(new NBTTagCompound())); @@ -118,7 +120,7 @@ public class SyncController { for(int questID : category.quests.keySet()){ Quest quest = category.quests.get(questID); questList.appendTag(quest.writeToNBT(new NBTTagCompound())); - if(questList.tagCount() > 50){ + if(questList.tagCount() > 40){ questCompound = new NBTTagCompound(); questCompound.setTag("Data", questList); questCompound.setTag("CatNBT", category.writeSmallNBT(new NBTTagCompound())); @@ -140,7 +142,7 @@ public class SyncController { for(int questID : questCategory.quests.keySet()){ Quest quest = questCategory.quests.get(questID); questList.appendTag(quest.writeToNBT(new NBTTagCompound())); - if(questList.tagCount() > 50){ + if(questList.tagCount() > 40){ questCompound = new NBTTagCompound(); questCompound.setTag("Data", questList); questCompound.setTag("CatNBT", questCategory.writeSmallNBT(new NBTTagCompound())); @@ -160,7 +162,7 @@ public class SyncController { for(int questID : dialogCategory.dialogs.keySet()){ Dialog dialog = dialogCategory.dialogs.get(questID); dialogList.appendTag(dialog.writeToNBT(new NBTTagCompound())); - if(dialogList.tagCount() > 50){ + if(dialogList.tagCount() > 40){ dialogCompound = new NBTTagCompound(); dialogCompound.setTag("Data", dialogList); dialogCompound.setTag("CatNBT", dialogCategory.writeSmallNBT(new NBTTagCompound())); diff --git a/src/main/java/noppes/npcs/controllers/data/PlayerData.java b/src/main/java/noppes/npcs/controllers/data/PlayerData.java index f370375bc..d7b3133b3 100644 --- a/src/main/java/noppes/npcs/controllers/data/PlayerData.java +++ b/src/main/java/noppes/npcs/controllers/data/PlayerData.java @@ -156,6 +156,12 @@ public class PlayerData implements IExtendedEntityProperties, IPlayerData { return compound; } + public void setSyncNBT(NBTTagCompound data){ + dialogData.loadNBTData(data); + questData.loadNBTData(data); + factionData.loadNBTData(data); + } + @Override public void init(Entity entity, World world) {