package electrosphere.net.client.protocol; import java.util.LinkedList; import java.util.List; import org.joml.Vector3f; import org.joml.Vector3i; import electrosphere.client.scene.ClientWorldData; import electrosphere.client.terrain.cache.ChunkData; import electrosphere.collision.CollisionWorldData; import electrosphere.engine.Globals; import electrosphere.logger.LoggerInterface; import electrosphere.net.parser.net.message.TerrainMessage; import electrosphere.net.template.ClientProtocolTemplate; /** * The client protocol for handling terrain messages */ public class TerrainProtocol implements ClientProtocolTemplate { @Override public TerrainMessage handleAsyncMessage(TerrainMessage message) { return message; } @Override public void handleSyncMessage(TerrainMessage message) { Globals.profiler.beginCpuSample("TerrainProtocol.handleTerrainMessage"); switch(message.getMessageSubtype()){ case RESPONSEMETADATA: Globals.clientWorldData = new ClientWorldData( //Vector3f worldMinPoint, Vector3f worldMaxPoint, int dynamicInterpolationRatio, float randomDampener, int worldDiscreteSize new Vector3f(message.getworldMinX(),0,message.getworldMinY()), new Vector3f(message.getworldMaxX(),32,message.getworldMaxY()), message.getrandomDampener(), message.getworldSizeDiscrete() ); Globals.clientSceneWrapper.getCollisionEngine().setCollisionWorldData(new CollisionWorldData(Globals.clientWorldData)); Globals.clientConnection.getMessageProtocol().setHasReceivedWorld(true); break; case SPAWNPOSITION: LoggerInterface.loggerNetworking.WARNING("Received spawnPosition packet on client. This is deprecated!"); break; case SENDCHUNKDATA: { LoggerInterface.loggerNetworking.DEBUG("(Client) Received terrain at " + message.getworldX() + " " + message.getworldY() + " " + message.getworldZ()); Globals.clientTerrainManager.attachTerrainMessage(message); } break; case SENDREDUCEDCHUNKDATA: { LoggerInterface.loggerNetworking.DEBUG("(Client) Received terrain at " + message.getworldX() + " " + message.getworldY() + " " + message.getworldZ() + " " + message.getchunkResolution()); Globals.clientTerrainManager.attachTerrainMessage(message); } break; case UPDATEVOXEL: { // //find what all drawcells might be updated by this voxel update Vector3i worldPos = new Vector3i(message.getworldX(), message.getworldY(), message.getworldZ()); List positionsToUpdate = new LinkedList(); positionsToUpdate.add(worldPos); if(message.getvoxelX() < 1){ positionsToUpdate.add(new Vector3i(worldPos).sub(1,0,0)); if(message.getvoxelY() < 1){ positionsToUpdate.add(new Vector3i(worldPos).sub(1,1,0)); if(message.getvoxelZ() < 1){ positionsToUpdate.add(new Vector3i(worldPos).sub(1,1,1)); } } else { if(message.getvoxelZ() < 1){ positionsToUpdate.add(new Vector3i(worldPos).sub(1,0,1)); } } } else { if(message.getvoxelY() < 1){ positionsToUpdate.add(new Vector3i(worldPos).sub(0,1,0)); if(message.getvoxelZ() < 1){ positionsToUpdate.add(new Vector3i(worldPos).sub(0,1,1)); } } else { if(message.getvoxelZ() < 1){ positionsToUpdate.add(new Vector3i(worldPos).sub(0,0,1)); } } } // //update the terrain cache if(Globals.clientTerrainManager.containsChunkDataAtWorldPoint(worldPos.x, worldPos.y, worldPos.z, ChunkData.NO_STRIDE)){ ChunkData data = Globals.clientTerrainManager.getChunkDataAtWorldPoint(worldPos.x, worldPos.y, worldPos.z, ChunkData.NO_STRIDE); if(data != null){ data.updatePosition( message.getvoxelX(), message.getvoxelY(), message.getvoxelZ(), message.getterrainWeight(), message.getterrainValue() ); } } // //mark all relevant drawcells as updateable for(Vector3i worldPosToUpdate : positionsToUpdate){ if(Globals.clientTerrainManager.containsChunkDataAtWorldPoint(worldPosToUpdate.x, worldPosToUpdate.y, worldPosToUpdate.z, ChunkData.NO_STRIDE)){ ChunkData data = Globals.clientTerrainManager.getChunkDataAtWorldPoint(worldPosToUpdate.x, worldPosToUpdate.y, worldPosToUpdate.z, ChunkData.NO_STRIDE); if(data != null){ Globals.clientDrawCellManager.markUpdateable(worldPosToUpdate.x, worldPosToUpdate.y, worldPosToUpdate.z); } } Globals.clientFoliageManager.evaluateChunk(worldPos); } } break; case SENDFLUIDDATA: { Globals.clientFluidManager.attachFluidMessage(message); } break; case UPDATEFLUIDDATA: { Globals.clientFluidManager.attachFluidMessage(message); } break; default: LoggerInterface.loggerNetworking.WARNING("Client networking: Unhandled message of type: " + message.getMessageSubtype()); break; } Globals.profiler.endCpuSample(); } }