Files
CustomNPC-Plus/src/main/java/kamkeel/npcs/network/LargeAbstractPacket.java
T

104 lines
3.7 KiB
Java
Raw Normal View History

2025-01-29 13:20:04 -05:00
package kamkeel.npcs.network;
2025-01-29 15:04:19 -05:00
2025-01-28 18:14:18 -05:00
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import net.minecraft.entity.player.EntityPlayer;
2025-01-29 15:04:19 -05:00
import org.lwjgl.Sys;
2025-01-28 18:14:18 -05:00
import java.io.IOException;
import java.util.Map;
2025-01-28 18:25:30 -05:00
import java.util.UUID;
2025-01-29 15:04:19 -05:00
import java.util.concurrent.ConcurrentHashMap;
2025-01-28 18:14:18 -05:00
public abstract class LargeAbstractPacket extends AbstractPacket {
2025-01-29 15:04:19 -05:00
private static final Map<UUID, PacketStorage> packetChunks = new ConcurrentHashMap<>();
private static final int CHUNK_SIZE = 5000;
2025-01-28 18:14:18 -05:00
@Override
public void sendData(ByteBuf out) throws IOException {
2025-01-29 15:04:19 -05:00
byte[] data = getData();
int totalSize = data.length;
UUID packetId = UUID.randomUUID();
// Break the data into chunks of CHUNK_SIZE bytes each
for (int offset = 0; offset < totalSize; offset += CHUNK_SIZE) {
int chunkSize = Math.min(CHUNK_SIZE, totalSize - offset);
// Write a header for each chunk
2025-01-28 18:25:30 -05:00
out.writeLong(packetId.getMostSignificantBits());
out.writeLong(packetId.getLeastSignificantBits());
2025-01-28 18:14:18 -05:00
out.writeInt(totalSize);
2025-01-29 15:04:19 -05:00
out.writeInt(offset);
out.writeInt((totalSize + CHUNK_SIZE - 1) / CHUNK_SIZE); // totalChunks
// Write the chunk bytes
out.writeBytes(data, offset, chunkSize);
2025-01-28 18:14:18 -05:00
}
}
@Override
public void receiveData(ByteBuf in, EntityPlayer player) throws IOException {
2025-01-28 18:25:30 -05:00
long mostSigBits = in.readLong();
long leastSigBits = in.readLong();
UUID packetId = new UUID(mostSigBits, leastSigBits);
2025-01-29 15:04:19 -05:00
2025-01-28 18:14:18 -05:00
int totalSize = in.readInt();
int offset = in.readInt();
2025-01-29 15:04:19 -05:00
int totalChunks = in.readInt(); // Currently unused aside from potential debugging/verification
int chunkSize = Math.min(CHUNK_SIZE, totalSize - offset);
// Basic validation to ensure the chunk won't overwrite out of bounds
if (chunkSize <= 0 || offset < 0 || (offset + chunkSize) > totalSize) {
throw new IndexOutOfBoundsException("Invalid chunk size/offset: chunkSize="
+ chunkSize + ", offset=" + offset + ", totalSize=" + totalSize);
}
// Read the exact chunk data
ByteBuf chunk = in.readBytes(chunkSize);
2025-01-28 18:14:18 -05:00
2025-01-29 15:04:19 -05:00
// Store the received chunk in a PacketStorage
PacketStorage storage = packetChunks.computeIfAbsent(packetId,
k -> new PacketStorage(Unpooled.buffer(totalSize), 0, totalSize));
2025-01-28 18:14:18 -05:00
2025-01-29 15:04:19 -05:00
// Write this chunk into the buffer at the correct offset
storage.data.setBytes(offset, chunk);
storage.receivedSoFar += chunkSize;
// If we've received all bytes, finalize
if (storage.receivedSoFar >= totalSize) {
// Remove from the map to clean up
2025-01-28 18:14:18 -05:00
packetChunks.remove(packetId);
2025-01-29 15:04:19 -05:00
// We now have the complete data in storage.data
// Copy (or slice) the exact bytes, then handle them
ByteBuf completeData = storage.data.copy(0, totalSize);
// Clean up and handle
storage.data.release();
handleCompleteData(completeData, player);
completeData.release();
2025-01-29 13:28:14 -05:00
}
2025-01-29 15:04:19 -05:00
chunk.release();
2025-01-29 13:28:14 -05:00
}
2025-01-29 15:04:19 -05:00
protected abstract byte[] getData() throws IOException;
protected abstract void handleCompleteData(ByteBuf data, EntityPlayer player) throws IOException;
/**
* Simple storage class to keep track of partial data and how many bytes we've received so far.
*/
private static class PacketStorage {
final ByteBuf data;
int receivedSoFar;
final int totalSize;
2025-01-28 18:25:30 -05:00
2025-01-29 15:04:19 -05:00
PacketStorage(ByteBuf data, int receivedSoFar, int totalSize) {
this.data = data;
this.receivedSoFar = receivedSoFar;
this.totalSize = totalSize;
}
}
2025-01-28 18:14:18 -05:00
}