From 1006145eead1e3a734436a3aad7219a23c0e2a4f Mon Sep 17 00:00:00 2001 From: austin Date: Sun, 19 Jan 2025 17:28:35 -0500 Subject: [PATCH] single-chunk levels from level creation menu --- .../net/server/protocol/TerrainProtocol.java | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/src/main/java/electrosphere/net/server/protocol/TerrainProtocol.java b/src/main/java/electrosphere/net/server/protocol/TerrainProtocol.java index 7c69c235..5583d81f 100644 --- a/src/main/java/electrosphere/net/server/protocol/TerrainProtocol.java +++ b/src/main/java/electrosphere/net/server/protocol/TerrainProtocol.java @@ -167,6 +167,18 @@ public class TerrainProtocol implements ServerProtocolTemplate { ServerWorldData serverWorldData = realm.getServerWorldData(); + //special handling for a world of size 1 + if( + serverWorldData.getWorldBoundMax().x == ServerTerrainChunk.CHUNK_DIMENSION && + serverWorldData.getWorldBoundMax().y == ServerTerrainChunk.CHUNK_DIMENSION && + serverWorldData.getWorldBoundMax().z == ServerTerrainChunk.CHUNK_DIMENSION + ){ + TerrainProtocol.sendWorldSubChunkAsyncStridedSingleChunk(connectionHandler, worldX, worldY, worldZ, stride); + Globals.profiler.endCpuSample(); + return; + } + + //normal multi-chunk world error checking if(worldX + Math.pow(2,stride) * ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE >= serverWorldData.getWorldBoundMax().x){ throw new Error("Requested invalid position! " + worldX); } @@ -226,6 +238,73 @@ public class TerrainProtocol implements ServerProtocolTemplate { Globals.profiler.endCpuSample(); } + + /** + * Sends a subchunk to the client + * @param connectionHandler The connection handler + * @param worldX the world x + * @param worldY the world y + * @param worldZ the world z + * @param stride The stride of the data + */ + static void sendWorldSubChunkAsyncStridedSingleChunk(ServerConnectionHandler connectionHandler, int worldX, int worldY, int worldZ, int stride){ + Globals.profiler.beginAggregateCpuSample("TerrainProtocol(server).sendWorldSubChunk"); + + // System.out.println("Received request for chunk " + message.getworldX() + " " + message.getworldY()); + Realm realm = Globals.playerManager.getPlayerRealm(connectionHandler.getPlayer()); + if(realm.getServerWorldData().getServerTerrainManager() == null){ + return; + } + + Consumer onLoad = (ServerTerrainChunk chunk) -> { + //The length along each access of the chunk data. Typically, should be at least 17. + //Because CHUNK_SIZE is 16, 17 adds the necessary extra value. Each chunk needs the value of the immediately following position to generate + //chunk data that connects seamlessly to the next chunk. + int xWidth = chunk.getWeights().length; + int yWidth = chunk.getWeights()[0].length; + int zWidth = chunk.getWeights()[0][0].length; + + byte[] toSend = null; + + if(chunk.getHomogenousValue() == ChunkData.NOT_HOMOGENOUS){ + ByteBuffer buffer = ByteBuffer.allocate(xWidth*yWidth*zWidth*(4+4)); + FloatBuffer floatView = buffer.asFloatBuffer(); + + for(int x = 0; x < xWidth; x++){ + for(int z = 0; z < zWidth; z++){ + for(int y = 0; y < yWidth; y++){ + floatView.put(chunk.getWeights()[x][y][z]); + } + } + } + + IntBuffer intView = buffer.asIntBuffer(); + intView.position(floatView.position()); + + for(int x = 0; x < xWidth; x++){ + for(int z = 0; z < zWidth; z++){ + for(int y = 0; y < yWidth; y++){ + intView.put(chunk.getValues()[x][y][z]); + } + } + } + toSend = buffer.array(); + } else { + toSend = new byte[]{ 0 }; + } + + + // System.out.println("(Server) Send terrain at " + worldX + " " + worldY + " " + worldZ); + LoggerInterface.loggerNetworking.DEBUG("(Server) Send terrain at " + worldX + " " + worldY + " " + worldZ); + connectionHandler.addMessagetoOutgoingQueue(TerrainMessage.constructSendReducedChunkDataMessage(chunk.getWorldX(), chunk.getWorldY(), chunk.getWorldZ(), stride, chunk.getHomogenousValue(), toSend)); + }; + + //request chunk + realm.getServerWorldData().getServerTerrainManager().getChunkAsync(worldX, worldY, worldZ, stride, onLoad); + + Globals.profiler.endCpuSample(); + } + /** * Sends a subchunk to the client * @param connectionHandler The connection handler