Commit 32828faa by Jonathan Thomas

Update player login message from server to be sent in chunks for 32000…

Update player login message from server to be sent in chunks for 32000 characters, to avoid the max String length errors. The client will reassemble all chunks and then load the JSON.
parent 0317dbdf
Pipeline #11959 passed with stage
in 22 seconds
......@@ -32,6 +32,7 @@ import java.util.stream.Collectors;
*/
public class ClickHandler {
private static boolean wasClicked = false;
static HashMap<Integer, String> receivedChunks = new HashMap<>();
public static void register() {
ClientTickEvents.END_CLIENT_TICK.register(client -> {
......@@ -76,16 +77,31 @@ public class ClickHandler {
// Client-side player login: get all chat data
ClientPlayNetworking.registerGlobalReceiver(ModInit.PACKET_S2C_LOGIN, (client, handler, buffer, responseSender) -> {
// Read the data from the server packet
int length = buffer.readInt();
String chatDataJSON = buffer.readString(length);
int sequenceNumber = buffer.readInt(); // Sequence number of the current packet
int totalPackets = buffer.readInt(); // Total number of packets for this data
String chunk = buffer.readString(); // Read the chunk from the current packet
// Update the chat data manager on the client-side
Gson GSON = new Gson();
client.execute(() -> { // Make sure to run on the client thread
// Parse JSON and override client chat data
Type type = new TypeToken<HashMap<String, ChatDataManager.EntityChatData>>(){}.getType();
ChatDataManager.getClientInstance().entityChatDataMap = GSON.fromJson(chatDataJSON, type);
// Store the received chunk
receivedChunks.put(sequenceNumber, chunk);
// Check if all chunks have been received
if (receivedChunks.size() == totalPackets) {
// Reconstruct the original chatDataJSON from chunks
StringBuilder chatDataJSONBuilder = new StringBuilder();
for (int i = 0; i < totalPackets; i++) {
chatDataJSONBuilder.append(receivedChunks.get(i));
}
String chatDataJSON = chatDataJSONBuilder.toString();
// Parse JSON and update client chat data
Gson GSON = new Gson();
Type type = new TypeToken<HashMap<String, ChatDataManager.EntityChatData>>(){}.getType();
ChatDataManager.getClientInstance().entityChatDataMap = GSON.fromJson(chatDataJSON, type);
// Clear receivedChunks for future use
receivedChunks.clear();
}
});
});
}
......
......@@ -142,19 +142,30 @@ public class ModInit implements ModInitializer {
});
});
// Send lite chat data JSON to new player (to populate client data)
// Data is sent in chunks, to prevent exceeding the 32767 limit per String.
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
ServerPlayerEntity player = handler.player;
LOGGER.info("Server send login message packet to player: " + player.getName().getString());
// Get chat data for logged in player (light version)
String chatDataJSON = ChatDataManager.getServerInstance().GetLightChatData();
int chunkSize = 32000; // Slightly below the limit to account for any additional data
// Write the light chat data
PacketByteBuf buffer = new PacketByteBuf(Unpooled.buffer());
buffer.writeInt(chatDataJSON.length());
buffer.writeString(chatDataJSON);
// Calculate the number of required packets to send the entire JSON string
int totalPackets = (int) Math.ceil(chatDataJSON.length() / (double) chunkSize);
ServerPlayNetworking.send(player, PACKET_S2C_LOGIN, buffer);
for (int i = 0; i < totalPackets; i++) {
int start = i * chunkSize;
int end = Math.min(start + chunkSize, chatDataJSON.length());
String chunk = chatDataJSON.substring(start, end);
PacketByteBuf buffer = new PacketByteBuf(Unpooled.buffer());
buffer.writeInt(i); // Packet sequence number
buffer.writeInt(totalPackets); // Total number of packets
buffer.writeString(chunk);
ServerPlayNetworking.send(player, PACKET_S2C_LOGIN, buffer);
}
});
ServerWorldEvents.LOAD.register((server, world) -> {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment