First terrain commit
This commit is contained in:
parent
e02a02eb5f
commit
8f06a025f0
322
net/terrain.json
322
net/terrain.json
@ -33,6 +33,14 @@
|
||||
"name" : "worldMaxY",
|
||||
"type" : "FIXED_INT"
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
"name" : "value",
|
||||
"type" : "FIXED_FLOAT"
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
"name" : "worldX",
|
||||
"type" : "FIXED_INT"
|
||||
@ -45,26 +53,8 @@
|
||||
"name" : "worldZ",
|
||||
"type" : "FIXED_INT"
|
||||
},
|
||||
{
|
||||
"name" : "value",
|
||||
"type" : "FIXED_FLOAT"
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
"name" : "locationX",
|
||||
"type" : "FIXED_INT"
|
||||
},
|
||||
{
|
||||
"name" : "locationY",
|
||||
"type" : "FIXED_INT"
|
||||
},
|
||||
{
|
||||
"name" : "locationZ",
|
||||
"type" : "FIXED_INT"
|
||||
},
|
||||
|
||||
|
||||
|
||||
{
|
||||
@ -82,215 +72,18 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
"name" : "macroValue00",
|
||||
"type" : "FIXED_FLOAT"
|
||||
},
|
||||
{
|
||||
"name" : "macroValue01",
|
||||
"type" : "FIXED_FLOAT"
|
||||
},
|
||||
{
|
||||
"name" : "macroValue02",
|
||||
"type" : "FIXED_FLOAT"
|
||||
},
|
||||
{
|
||||
"name" : "macroValue03",
|
||||
"type" : "FIXED_FLOAT"
|
||||
},
|
||||
{
|
||||
"name" : "macroValue04",
|
||||
"type" : "FIXED_FLOAT"
|
||||
},
|
||||
{
|
||||
"name" : "macroValue10",
|
||||
"type" : "FIXED_FLOAT"
|
||||
},
|
||||
{
|
||||
"name" : "macroValue11",
|
||||
"type" : "FIXED_FLOAT"
|
||||
},
|
||||
{
|
||||
"name" : "macroValue12",
|
||||
"type" : "FIXED_FLOAT"
|
||||
},
|
||||
{
|
||||
"name" : "macroValue13",
|
||||
"type" : "FIXED_FLOAT"
|
||||
},
|
||||
{
|
||||
"name" : "macroValue14",
|
||||
"type" : "FIXED_FLOAT"
|
||||
},
|
||||
{
|
||||
"name" : "macroValue20",
|
||||
"type" : "FIXED_FLOAT"
|
||||
},
|
||||
{
|
||||
"name" : "macroValue21",
|
||||
"type" : "FIXED_FLOAT"
|
||||
},
|
||||
{
|
||||
"name" : "macroValue22",
|
||||
"type" : "FIXED_FLOAT"
|
||||
},
|
||||
{
|
||||
"name" : "macroValue23",
|
||||
"type" : "FIXED_FLOAT"
|
||||
},
|
||||
{
|
||||
"name" : "macroValue24",
|
||||
"type" : "FIXED_FLOAT"
|
||||
},
|
||||
{
|
||||
"name" : "macroValue30",
|
||||
"type" : "FIXED_FLOAT"
|
||||
},
|
||||
{
|
||||
"name" : "macroValue31",
|
||||
"type" : "FIXED_FLOAT"
|
||||
},
|
||||
{
|
||||
"name" : "macroValue32",
|
||||
"type" : "FIXED_FLOAT"
|
||||
},
|
||||
{
|
||||
"name" : "macroValue33",
|
||||
"type" : "FIXED_FLOAT"
|
||||
},
|
||||
{
|
||||
"name" : "macroValue34",
|
||||
"type" : "FIXED_FLOAT"
|
||||
},
|
||||
{
|
||||
"name" : "macroValue40",
|
||||
"type" : "FIXED_FLOAT"
|
||||
},
|
||||
{
|
||||
"name" : "macroValue41",
|
||||
"type" : "FIXED_FLOAT"
|
||||
},
|
||||
{
|
||||
"name" : "macroValue42",
|
||||
"type" : "FIXED_FLOAT"
|
||||
},
|
||||
{
|
||||
"name" : "macroValue43",
|
||||
"type" : "FIXED_FLOAT"
|
||||
},
|
||||
{
|
||||
"name" : "macroValue44",
|
||||
"type" : "FIXED_FLOAT"
|
||||
},
|
||||
|
||||
|
||||
|
||||
{
|
||||
"name" : "randomizerValue00",
|
||||
"type" : "FIXED_LONG"
|
||||
},
|
||||
{
|
||||
"name" : "randomizerValue01",
|
||||
"type" : "FIXED_LONG"
|
||||
},
|
||||
{
|
||||
"name" : "randomizerValue02",
|
||||
"type" : "FIXED_LONG"
|
||||
},
|
||||
{
|
||||
"name" : "randomizerValue03",
|
||||
"type" : "FIXED_LONG"
|
||||
},
|
||||
{
|
||||
"name" : "randomizerValue04",
|
||||
"type" : "FIXED_LONG"
|
||||
},
|
||||
{
|
||||
"name" : "randomizerValue10",
|
||||
"type" : "FIXED_LONG"
|
||||
},
|
||||
{
|
||||
"name" : "randomizerValue11",
|
||||
"type" : "FIXED_LONG"
|
||||
},
|
||||
{
|
||||
"name" : "randomizerValue12",
|
||||
"type" : "FIXED_LONG"
|
||||
},
|
||||
{
|
||||
"name" : "randomizerValue13",
|
||||
"type" : "FIXED_LONG"
|
||||
},
|
||||
{
|
||||
"name" : "randomizerValue14",
|
||||
"type" : "FIXED_LONG"
|
||||
},
|
||||
{
|
||||
"name" : "randomizerValue20",
|
||||
"type" : "FIXED_LONG"
|
||||
},
|
||||
{
|
||||
"name" : "randomizerValue21",
|
||||
"type" : "FIXED_LONG"
|
||||
},
|
||||
{
|
||||
"name" : "randomizerValue22",
|
||||
"type" : "FIXED_LONG"
|
||||
},
|
||||
{
|
||||
"name" : "randomizerValue23",
|
||||
"type" : "FIXED_LONG"
|
||||
},
|
||||
{
|
||||
"name" : "randomizerValue24",
|
||||
"type" : "FIXED_LONG"
|
||||
},
|
||||
{
|
||||
"name" : "randomizerValue30",
|
||||
"type" : "FIXED_LONG"
|
||||
},
|
||||
{
|
||||
"name" : "randomizerValue31",
|
||||
"type" : "FIXED_LONG"
|
||||
},
|
||||
{
|
||||
"name" : "randomizerValue32",
|
||||
"type" : "FIXED_LONG"
|
||||
},
|
||||
{
|
||||
"name" : "randomizerValue33",
|
||||
"type" : "FIXED_LONG"
|
||||
},
|
||||
{
|
||||
"name" : "randomizerValue34",
|
||||
"type" : "FIXED_LONG"
|
||||
},
|
||||
{
|
||||
"name" : "randomizerValue40",
|
||||
"type" : "FIXED_LONG"
|
||||
},
|
||||
{
|
||||
"name" : "randomizerValue41",
|
||||
"type" : "FIXED_LONG"
|
||||
},
|
||||
{
|
||||
"name" : "randomizerValue42",
|
||||
"type" : "FIXED_LONG"
|
||||
},
|
||||
{
|
||||
"name" : "randomizerValue43",
|
||||
"type" : "FIXED_LONG"
|
||||
},
|
||||
{
|
||||
"name" : "randomizerValue44",
|
||||
"type" : "FIXED_LONG"
|
||||
},
|
||||
{
|
||||
"name" : "chunkData",
|
||||
"type" : "BYTE_ARRAY"
|
||||
},
|
||||
|
||||
{
|
||||
"name" : "terrainWeight",
|
||||
"type" : "FIXED_FLOAT"
|
||||
},
|
||||
{
|
||||
"name" : "terrainValue",
|
||||
"type" : "FIXED_INT"
|
||||
}
|
||||
],
|
||||
"messageTypes" : [
|
||||
@ -319,87 +112,10 @@
|
||||
},
|
||||
{
|
||||
"messageName" : "Update",
|
||||
"data" : [
|
||||
"locationX",
|
||||
"locationY",
|
||||
"locationZ"
|
||||
]
|
||||
},
|
||||
{
|
||||
"messageName" : "chunkLoadStart",
|
||||
"data" : [
|
||||
"worldX",
|
||||
"worldY",
|
||||
"value"
|
||||
]
|
||||
},
|
||||
{
|
||||
"messageName" : "MacroValue",
|
||||
"data" : [
|
||||
"worldX",
|
||||
"worldY",
|
||||
"macroValue00",
|
||||
"macroValue01",
|
||||
"macroValue02",
|
||||
"macroValue03",
|
||||
"macroValue04",
|
||||
"macroValue10",
|
||||
"macroValue11",
|
||||
"macroValue12",
|
||||
"macroValue13",
|
||||
"macroValue14",
|
||||
"macroValue20",
|
||||
"macroValue21",
|
||||
"macroValue22",
|
||||
"macroValue23",
|
||||
"macroValue24",
|
||||
"macroValue30",
|
||||
"macroValue31",
|
||||
"macroValue32",
|
||||
"macroValue33",
|
||||
"macroValue34",
|
||||
"macroValue40",
|
||||
"macroValue41",
|
||||
"macroValue42",
|
||||
"macroValue43",
|
||||
"macroValue44",
|
||||
"randomizerValue00",
|
||||
"randomizerValue01",
|
||||
"randomizerValue02",
|
||||
"randomizerValue03",
|
||||
"randomizerValue04",
|
||||
"randomizerValue10",
|
||||
"randomizerValue11",
|
||||
"randomizerValue12",
|
||||
"randomizerValue13",
|
||||
"randomizerValue14",
|
||||
"randomizerValue20",
|
||||
"randomizerValue21",
|
||||
"randomizerValue22",
|
||||
"randomizerValue23",
|
||||
"randomizerValue24",
|
||||
"randomizerValue30",
|
||||
"randomizerValue31",
|
||||
"randomizerValue32",
|
||||
"randomizerValue33",
|
||||
"randomizerValue34",
|
||||
"randomizerValue40",
|
||||
"randomizerValue41",
|
||||
"randomizerValue42",
|
||||
"randomizerValue43",
|
||||
"randomizerValue44"
|
||||
]
|
||||
},
|
||||
{
|
||||
"messageName" : "heightMapModification",
|
||||
"data" : [
|
||||
"value",
|
||||
"worldX",
|
||||
"worldY",
|
||||
"worldZ",
|
||||
"locationX",
|
||||
"locationY",
|
||||
"locationZ"
|
||||
"worldZ"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
9
pom.xml
9
pom.xml
@ -143,6 +143,15 @@
|
||||
<version>0.1</version>
|
||||
</dependency>
|
||||
|
||||
<!--Ode4J-->
|
||||
<!--License: Dual LGPL 2.1 OR BSD 3-clause-->
|
||||
<!--https://github.com/tzaeschke/ode4j-->
|
||||
<dependency>
|
||||
<groupId>org.ode4j</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>0.5.0</version>
|
||||
</dependency>
|
||||
|
||||
<!--SQLITE-JDBC-->
|
||||
<!--License: Apache-->
|
||||
<!-- https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc -->
|
||||
|
||||
@ -43,9 +43,9 @@ public class ClientEntityCullingManager {
|
||||
public void clearOutOfBoundsEntities(){
|
||||
if(Globals.commonWorldData != null && Globals.playerEntity != null && Globals.clientPlayerData != null){
|
||||
Vector3d playerCharacterPos = EntityUtils.getPosition(Globals.playerEntity);
|
||||
int playerCharacterWorldX = Globals.commonWorldData.convertRealToWorld(playerCharacterPos.x);
|
||||
int playerCharacterWorldY = Globals.commonWorldData.convertRealToWorld(playerCharacterPos.y);
|
||||
int playerCharacterWorldZ = Globals.commonWorldData.convertRealToWorld(playerCharacterPos.z);
|
||||
int playerCharacterWorldX = Globals.clientWorldData.convertRealToWorld(playerCharacterPos.x);
|
||||
int playerCharacterWorldY = Globals.clientWorldData.convertRealToWorld(playerCharacterPos.y);
|
||||
int playerCharacterWorldZ = Globals.clientWorldData.convertRealToWorld(playerCharacterPos.z);
|
||||
if(
|
||||
playerCharacterWorldX != Globals.clientPlayerData.getWorldPos().x||
|
||||
playerCharacterWorldY != Globals.clientPlayerData.getWorldPos().y ||
|
||||
@ -59,22 +59,14 @@ public class ClientEntityCullingManager {
|
||||
//common world data is initialized with the collision data
|
||||
//if this is null then the engine hasn't fully started up yet
|
||||
if(position != null){
|
||||
int worldX = Globals.commonWorldData.convertRealToWorld(position.x);
|
||||
int worldY = Globals.commonWorldData.convertRealToWorld(position.z);
|
||||
if(!Globals.drawCellManager.coordsInPhysicsSpace(worldX, worldY)){
|
||||
//if we're running the server we need to just hide the entity
|
||||
//otherwise delete it
|
||||
if(Globals.RUN_SERVER && Globals.RUN_CLIENT){
|
||||
recursiveHide(entity);
|
||||
} else {
|
||||
scene.recursiveDeregister(entity);
|
||||
}
|
||||
int worldX = Globals.clientWorldData.convertRealToWorld(position.x);
|
||||
int worldZ = Globals.clientWorldData.convertRealToWorld(position.z);
|
||||
if(!Globals.drawCellManager.coordsInPhysicsSpace(worldX, worldZ)){
|
||||
//we need to just hide the entity
|
||||
recursiveHide(entity);
|
||||
} else {
|
||||
//if the entity is within range, we're running server,
|
||||
//and it's not set to visible, make it visible
|
||||
if(Globals.RUN_SERVER && Globals.RUN_CLIENT){
|
||||
recursiveShow(entity);
|
||||
}
|
||||
//if the entity is within range and it's not set to visible, make it visible
|
||||
recursiveShow(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
package electrosphere.client.foliagemanager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
@ -42,6 +44,15 @@ public class ClientFoliageManager {
|
||||
//Used to prevent concurrent usage of grassEntities set
|
||||
boolean ready = false;
|
||||
|
||||
//The list of voxel type ids that should have grass generated on top of them
|
||||
static final List<Integer> grassGeneratingVoxelIds = new ArrayList<Integer>();
|
||||
|
||||
//FoliageCells that are active and have foliage that is being drawn
|
||||
Set<FoliageCell> activeCells = new HashSet<FoliageCell>();
|
||||
//The maximum distance a cell can be away from the player before being destroyed
|
||||
static final float CELL_DISTANCE_MAX = 25f;
|
||||
//The maximum number of foliage cells
|
||||
static final int CELL_COUNT_MAX = 100;
|
||||
|
||||
|
||||
|
||||
@ -59,6 +70,9 @@ public class ClientFoliageManager {
|
||||
};
|
||||
modelMatrixAttribute = new ShaderAttribute(attributeIndices);
|
||||
attributes.put(modelMatrixAttribute,HomogenousBufferTypes.MAT4F);
|
||||
|
||||
//set grass generating voxel ids
|
||||
grassGeneratingVoxelIds.add(2);
|
||||
}
|
||||
|
||||
//shader paths
|
||||
@ -119,14 +133,6 @@ public class ClientFoliageManager {
|
||||
grassPosition.set(getNewPosition(playerPosition));
|
||||
grassRotation.set(getNewRotation());
|
||||
}
|
||||
//update uniforms
|
||||
// instancedActor.setUniform("position", grassPosition);
|
||||
// instancedActor.setUniform("rotation", new Vector4d(
|
||||
// grassRotation.x,
|
||||
// grassRotation.y,
|
||||
// grassRotation.z,
|
||||
// grassRotation.w));
|
||||
// instancedActor.setUniform("scale", new Vector3d(EntityUtils.getScale(grassEntity)));
|
||||
|
||||
modelMatrix = modelMatrix.identity();
|
||||
Vector3f cameraModifiedPosition = new Vector3f((float)grassPosition.x,(float)grassPosition.y,(float)grassPosition.z).sub(cameraCenter);
|
||||
@ -137,7 +143,7 @@ public class ClientFoliageManager {
|
||||
instancedActor.setAttribute(modelMatrixAttribute, modelMatrix);
|
||||
|
||||
//draw
|
||||
instancedActor.draw(Globals.renderingEngine.getRenderPipelineState());
|
||||
// instancedActor.draw(Globals.renderingEngine.getRenderPipelineState());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -166,13 +172,6 @@ public class ClientFoliageManager {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Makes an already created entity a drawable, instanced entity (client only) by backing it with an InstancedActor
|
||||
* @param entity The entity
|
||||
@ -188,6 +187,19 @@ public class ClientFoliageManager {
|
||||
Globals.clientScene.registerEntityToTag(entity, EntityTags.DRAW_INSTANCED);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Evaluate all foliage cells to see if any should be deconstructed and any new ones should be created
|
||||
*/
|
||||
protected void evaluateFoliageCells(){
|
||||
Vector3d playerPosition = EntityUtils.getPosition(Globals.playerEntity);
|
||||
for(FoliageCell activeCell : activeCells){
|
||||
//if cell is outside of range of player, disable cell
|
||||
if(activeCell.position.distance(playerPosition) > CELL_DISTANCE_MAX){
|
||||
//TODO: destroy cell
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
package electrosphere.client.foliagemanager;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.joml.Vector3d;
|
||||
|
||||
import electrosphere.entity.Entity;
|
||||
|
||||
/**
|
||||
* Contains a set of foliage entities and groups them together.
|
||||
*/
|
||||
public class FoliageCell {
|
||||
//position of the foliage cell
|
||||
Vector3d position;
|
||||
//constituent entities
|
||||
Set<Entity> containedEntities;
|
||||
|
||||
}
|
||||
@ -3,7 +3,6 @@ package electrosphere.client.scene;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.Scene;
|
||||
import electrosphere.game.collision.CollisionEngine;
|
||||
|
||||
@ -1,11 +1,5 @@
|
||||
package electrosphere.client.scene;
|
||||
|
||||
import electrosphere.game.server.world.*;
|
||||
import electrosphere.server.datacell.ServerDataCell;
|
||||
import electrosphere.server.terrain.manager.ServerTerrainManager;
|
||||
|
||||
import java.util.List;
|
||||
import org.joml.Vector2f;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
/**
|
||||
@ -44,7 +38,13 @@ public class ClientWorldData {
|
||||
int worldDiscreteSize;
|
||||
|
||||
|
||||
public ClientWorldData(Vector3f worldMinPoint, Vector3f worldMaxPoint, int dynamicInterpolationRatio, float randomDampener, int worldDiscreteSize) {
|
||||
public ClientWorldData(
|
||||
Vector3f worldMinPoint,
|
||||
Vector3f worldMaxPoint,
|
||||
int dynamicInterpolationRatio,
|
||||
float randomDampener,
|
||||
int worldDiscreteSize
|
||||
) {
|
||||
this.worldMinPoint = worldMinPoint;
|
||||
this.worldMaxPoint = worldMaxPoint;
|
||||
this.dynamicInterpolationRatio = dynamicInterpolationRatio;
|
||||
@ -84,4 +84,12 @@ public class ClientWorldData {
|
||||
return chunk * dynamicInterpolationRatio;
|
||||
}
|
||||
|
||||
public int convertRealToWorld(double real){
|
||||
return convertRealToChunkSpace(real);
|
||||
}
|
||||
|
||||
public double convertWorldToReal(int world){
|
||||
return convertChunkToRealSpace(world);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -3,10 +3,8 @@ package electrosphere.client.sim;
|
||||
import electrosphere.client.terrain.manager.ClientTerrainManager;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.EntityUtils;
|
||||
import electrosphere.entity.types.camera.CameraEntityUtils;
|
||||
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -45,7 +43,6 @@ public class ClientFunctions {
|
||||
public static void loadTerrain(){
|
||||
if(Globals.clientTerrainManager != null){
|
||||
Globals.clientTerrainManager.handleMessages();
|
||||
Globals.clientTerrainManager.ejectLoadedChunks();
|
||||
updateCellManager();
|
||||
}
|
||||
}
|
||||
@ -59,7 +56,7 @@ public class ClientFunctions {
|
||||
newPlayerCharacterPosition = EntityUtils.getPosition(Globals.playerEntity);
|
||||
}
|
||||
//Cell manager do your things
|
||||
Globals.drawCellManager.calculateDeltas(oldPlayerCharacterPosition, newPlayerCharacterPosition);
|
||||
Globals.drawCellManager.calculateDeltas(newPlayerCharacterPosition);
|
||||
Globals.drawCellManager.update();
|
||||
}
|
||||
}
|
||||
|
||||
52
src/main/java/electrosphere/client/terrain/cache/ChunkData.java
vendored
Normal file
52
src/main/java/electrosphere/client/terrain/cache/ChunkData.java
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
package electrosphere.client.terrain.cache;
|
||||
|
||||
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
||||
|
||||
/**
|
||||
* A container of data about a chunk of terrain
|
||||
*/
|
||||
public class ChunkData {
|
||||
|
||||
//The size of a chunk
|
||||
public static final int CHUNK_SIZE = ServerTerrainChunk.CHUNK_DIMENSION;
|
||||
|
||||
//What type of terrain is in this voxel, eg stone vs dirt vs grass, etc
|
||||
int[][][] voxelType;
|
||||
//How much of that terrain type is in this voxel
|
||||
float[][][] voxelWeight;
|
||||
|
||||
|
||||
/**
|
||||
* Gets the voxel type array in this container
|
||||
* @return The voxel type array
|
||||
*/
|
||||
public int[][][] getVoxelType(){
|
||||
return voxelType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the voxel type array in this container
|
||||
* @param voxelType The voxel type array
|
||||
*/
|
||||
public void setVoxelType(int[][][] voxelType){
|
||||
this.voxelType = voxelType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the voxel weight array in this container
|
||||
* @return The voxel weight array
|
||||
*/
|
||||
public float[][][] getVoxelWeight(){
|
||||
return voxelWeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the voxel weight array in this container
|
||||
* @param voxelWeight The voxel weight array
|
||||
*/
|
||||
public void setVoxelWeight(float[][][] voxelWeight){
|
||||
this.voxelWeight = voxelWeight;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -1,48 +0,0 @@
|
||||
package electrosphere.client.terrain.cache;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
*/
|
||||
public class ChunkModification {
|
||||
int worldX;
|
||||
int worldY;
|
||||
int locationX;
|
||||
int locationY;
|
||||
float value;
|
||||
|
||||
public ChunkModification(int worldX, int worldY, int locationX, int locationY, float value) {
|
||||
this.worldX = worldX;
|
||||
this.worldY = worldY;
|
||||
this.locationX = locationX;
|
||||
this.locationY = locationY;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getWorldX() {
|
||||
return worldX;
|
||||
}
|
||||
|
||||
public int getLocationX() {
|
||||
return locationX;
|
||||
}
|
||||
|
||||
public int getLocationY() {
|
||||
return locationY;
|
||||
}
|
||||
|
||||
public float getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public int getWorldY() {
|
||||
return worldY;
|
||||
}
|
||||
|
||||
public float[][] applyModification(float[][] heightmap){
|
||||
heightmap[locationX][locationY] = value;
|
||||
return heightmap;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -1,73 +1,40 @@
|
||||
package electrosphere.client.terrain.cache;
|
||||
|
||||
import electrosphere.client.scene.ClientWorldData;
|
||||
import electrosphere.game.terrain.processing.TerrainInterpolator;
|
||||
import electrosphere.server.terrain.models.TerrainModel;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
|
||||
/**
|
||||
* Acts as a cache in front of terrain model to streamline receiving chunks
|
||||
*/
|
||||
public class ClientTerrainCache {
|
||||
|
||||
/*
|
||||
Acts as a cache in front of terrain model to streamline receiving heightmaps
|
||||
on both client and server
|
||||
*/
|
||||
|
||||
|
||||
|
||||
ClientWorldData clientWorldData;
|
||||
|
||||
|
||||
//cache capacity
|
||||
int cacheSize;
|
||||
Map<String,float[][]> cacheMap = new ConcurrentHashMap<String,float[][]> ();
|
||||
//the map of chunk key -> chunk data
|
||||
Map<String,ChunkData> cacheMap = new ConcurrentHashMap<String,ChunkData>();
|
||||
//the list of keys in the cache
|
||||
List<String> cacheList = new CopyOnWriteArrayList<String>();
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param cacheSize The capacity of the cache
|
||||
*/
|
||||
public ClientTerrainCache(int cacheSize){
|
||||
this.cacheSize = cacheSize;
|
||||
}
|
||||
|
||||
// TerrainChunkValues getChunkValuesAtPoint(int x, int y){
|
||||
// if(terrainModel != null){
|
||||
// return new TerrainChunkValues(
|
||||
// terrainModel.getMacroValuesAtPosition(x, y),
|
||||
// terrainModel.getRandomizerValuesAtPosition(x, y)
|
||||
// );
|
||||
// } else {
|
||||
// return new TerrainChunkValues(
|
||||
// new float[3][3],
|
||||
// new long[3][3]
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
//USED TO ADD macro values
|
||||
public void addChunkValuesToCache(int x, int y, float[][] macroValues, long[][] randomizer){
|
||||
// TerrainChunkValues chunk = new TerrainChunkValues(macroValues, randomizer);
|
||||
assert clientWorldData != null;
|
||||
|
||||
float[][] heightmap = TerrainInterpolator.getBicubicInterpolatedChunk(
|
||||
macroValues,
|
||||
randomizer,
|
||||
clientWorldData.getDynamicInterpolationRatio(),
|
||||
clientWorldData.getRandomDampener()
|
||||
);
|
||||
|
||||
cacheMap.put(getKey(x,y),heightmap);
|
||||
while(cacheList.size() > cacheSize){
|
||||
String currentChunk = cacheList.remove(0);
|
||||
cacheMap.remove(currentChunk);
|
||||
}
|
||||
}
|
||||
|
||||
public void addFloatsToCache(int x, int y, float[][] values){
|
||||
cacheMap.put(getKey(x,y),values);
|
||||
/**
|
||||
* Adds a chunk data to the terrain cache
|
||||
* @param worldX The x world position
|
||||
* @param worldY The y world position
|
||||
* @param worldZ The z world position
|
||||
* @param chunkData The chunk data to add at the specified positions
|
||||
*/
|
||||
public void addChunkDataToCache(int worldX, int worldY, int worldZ, ChunkData chunkData){
|
||||
cacheMap.put(getKey(worldX,worldY,worldZ),chunkData);
|
||||
while(cacheList.size() > cacheSize){
|
||||
String currentChunk = cacheList.remove(0);
|
||||
cacheMap.remove(currentChunk);
|
||||
@ -75,29 +42,41 @@ public class ClientTerrainCache {
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String getKey(int x, int y){
|
||||
return x + "-" + y;
|
||||
/**
|
||||
* Generates a key for the cache based on the position provided
|
||||
* @param worldX The x world position
|
||||
* @param worldY The y world position
|
||||
* @param worldZ The z world position
|
||||
* @return The cache key
|
||||
*/
|
||||
public String getKey(int worldX, int worldY, int worldZ){
|
||||
return worldX + "_" + worldY + "_" + worldZ;
|
||||
}
|
||||
|
||||
|
||||
public boolean containsHeightmapAtChunkPoint(int x, int y){
|
||||
return cacheMap.containsKey(getKey(x,y));
|
||||
/**
|
||||
* Checks whether the cache contains chunk data at a given world point
|
||||
* @param worldX The x world position
|
||||
* @param worldY The y world position
|
||||
* @param worldZ The z world position
|
||||
* @return True if the cache contains chunk data at the specified point, false otherwise
|
||||
*/
|
||||
public boolean containsChunkDataAtWorldPoint(int worldX, int worldY, int worldZ){
|
||||
return cacheMap.containsKey(getKey(worldX,worldY,worldZ));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//ALL RETRIEVE
|
||||
public float[][] getHeightmapAtChunkPoint(int x, int y){
|
||||
return cacheMap.get(getKey(x,y));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public void setClientWorldData(ClientWorldData clientWorldData){
|
||||
this.clientWorldData = clientWorldData;
|
||||
/**
|
||||
* Gets chunk data at the given world point
|
||||
* @param worldX The x world position
|
||||
* @param worldY The y world position
|
||||
* @param worldZ The z world position
|
||||
* @return The chunk data if it exists, null otherwise
|
||||
*/
|
||||
public ChunkData getSubChunkDataAtPoint(int worldX, int worldY, int worldZ){
|
||||
return cacheMap.get(getKey(worldX,worldY,worldZ));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,83 +0,0 @@
|
||||
package electrosphere.client.terrain.cache;
|
||||
|
||||
import electrosphere.client.scene.ClientWorldData;
|
||||
import electrosphere.game.terrain.processing.TerrainInterpolator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
*/
|
||||
public class LoadingChunk {
|
||||
|
||||
int worldX, worldY;
|
||||
int totalNumMessages;
|
||||
int numReceivedMessages = 0;
|
||||
|
||||
ClientWorldData clientWorldData;
|
||||
|
||||
float[][] macroValues;
|
||||
long[][] randomizer;
|
||||
List<ChunkModification> modification = new ArrayList<ChunkModification>();
|
||||
|
||||
public LoadingChunk(int worldX, int worldY, int numMessages, ClientWorldData clientWorldData){
|
||||
this.worldX = worldX;
|
||||
this.worldY = worldY;
|
||||
this.totalNumMessages = numMessages;
|
||||
this.clientWorldData = clientWorldData;
|
||||
}
|
||||
|
||||
public void addMacroValues(float[][] macroValues){
|
||||
this.macroValues = macroValues;
|
||||
}
|
||||
|
||||
public void addRandomizer(long[][] randomizer){
|
||||
this.randomizer = randomizer;
|
||||
}
|
||||
|
||||
public void addModification(int worldX, int worldY, int locationX, int locationY, float value){
|
||||
// System.out.println("Client add modification");
|
||||
ChunkModification newModification = new ChunkModification(worldX, worldY, locationX, locationY, value);
|
||||
modification.add(newModification);
|
||||
}
|
||||
|
||||
public void incrementMessageCount(){
|
||||
numReceivedMessages++;
|
||||
}
|
||||
|
||||
public boolean isComplete(){
|
||||
return numReceivedMessages >= totalNumMessages && macroValues != null && randomizer != null;
|
||||
}
|
||||
|
||||
public float[][] exportFloats(){
|
||||
float[][] heightmap = TerrainInterpolator.getBicubicInterpolatedChunk(
|
||||
macroValues,
|
||||
randomizer,
|
||||
clientWorldData.getDynamicInterpolationRatio(),
|
||||
clientWorldData.getRandomDampener()
|
||||
);
|
||||
if(modification != null){
|
||||
for(ChunkModification modification : modification){
|
||||
// System.out.println("Apply modification");
|
||||
heightmap = modification.applyModification(heightmap);
|
||||
}
|
||||
}
|
||||
return heightmap;
|
||||
}
|
||||
|
||||
public int getWorldX() {
|
||||
return worldX;
|
||||
}
|
||||
|
||||
public int getWorldY() {
|
||||
return worldY;
|
||||
}
|
||||
|
||||
public ClientWorldData getClientWorldData(){
|
||||
return this.clientWorldData;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -1,50 +0,0 @@
|
||||
package electrosphere.client.terrain.cache;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
*/
|
||||
public class LoadingChunkCache {
|
||||
Map<String,LoadingChunk> cacheMap = new ConcurrentHashMap<String,LoadingChunk>();
|
||||
List<String> cacheList = new CopyOnWriteArrayList<String>();
|
||||
|
||||
|
||||
public LoadingChunkCache(){
|
||||
}
|
||||
|
||||
|
||||
//USED TO ADD macro values
|
||||
public void addLoadingChunkToCache(LoadingChunk chunk){
|
||||
cacheMap.put(getKey(chunk.worldX, chunk.worldY),chunk);
|
||||
}
|
||||
|
||||
public LoadingChunk fetch(String key){
|
||||
return cacheMap.get(key);
|
||||
}
|
||||
|
||||
|
||||
public String getKey(int worldX, int worldY){
|
||||
return worldX + "-" + worldY;
|
||||
}
|
||||
|
||||
public boolean containsKey(String key){
|
||||
return cacheMap.containsKey(key);
|
||||
}
|
||||
|
||||
public Collection<LoadingChunk> getChunks(){
|
||||
return cacheMap.values();
|
||||
}
|
||||
|
||||
public void remove(LoadingChunk chunk){
|
||||
cacheMap.remove(getKey(chunk.worldX,chunk.worldY));
|
||||
cacheList.remove(getKey(chunk.worldX,chunk.worldY));
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,27 +0,0 @@
|
||||
package electrosphere.client.terrain.cells;
|
||||
|
||||
import electrosphere.entity.Entity;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
*/
|
||||
public class ClientDataCell {
|
||||
List<Entity> entities = new LinkedList<Entity>();
|
||||
|
||||
|
||||
public ClientDataCell(){
|
||||
|
||||
}
|
||||
|
||||
public void addEntity(Entity e){
|
||||
entities.add(e);
|
||||
}
|
||||
|
||||
public void removeEntity(Entity e){
|
||||
entities.remove(e);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,12 +1,16 @@
|
||||
package electrosphere.client.terrain.cells;
|
||||
|
||||
import electrosphere.client.terrain.cache.ChunkData;
|
||||
import electrosphere.client.terrain.manager.ClientTerrainManager;
|
||||
import electrosphere.collision.dispatch.CollisionObject;
|
||||
import electrosphere.dynamics.RigidBody;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.ClientEntityUtils;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.EntityCreationUtils;
|
||||
import electrosphere.entity.EntityDataStrings;
|
||||
import electrosphere.entity.EntityUtils;
|
||||
import electrosphere.entity.types.terrain.TerrainChunk;
|
||||
import electrosphere.game.collision.PhysicsUtils;
|
||||
import electrosphere.game.collision.collidable.Collidable;
|
||||
import electrosphere.game.terrain.processing.TerrainInterpolator;
|
||||
@ -24,20 +28,19 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector3i;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author satellite
|
||||
*/
|
||||
public class DrawCell {
|
||||
int cellX;
|
||||
int cellY;
|
||||
//the position of the draw cell in world coordinates
|
||||
Vector3i worldPos;
|
||||
|
||||
float[][] heightmap;
|
||||
float[][] texturemap;
|
||||
|
||||
int dynamicInterpolationRatio;
|
||||
ChunkData data;
|
||||
|
||||
Entity modelEntity;
|
||||
|
||||
@ -64,31 +67,17 @@ public class DrawCell {
|
||||
|
||||
|
||||
/**
|
||||
* Catches for this function: drawArray's dimensions need to be equal to drawWidth and 1 greater than cellWidth
|
||||
* because the model creation code for terrain heightmaps sucks :D
|
||||
* 06/03/2021
|
||||
*
|
||||
*
|
||||
* ITS NOT EVEN UP TO DATE!
|
||||
* 06/13/2021
|
||||
*
|
||||
* //@param drawArray
|
||||
* Constructs a drawcell object
|
||||
*/
|
||||
public static DrawCell generateTerrainCell(
|
||||
int cellX,
|
||||
int cellY,
|
||||
float[][] heightmap,
|
||||
float[][] texturemap,
|
||||
int dynamicInterpolationRatio,
|
||||
Vector3i worldPos,
|
||||
ChunkData data,
|
||||
ShaderProgram program
|
||||
){
|
||||
DrawCell rVal = new DrawCell();
|
||||
rVal.cellX = cellX;
|
||||
rVal.cellY = cellY;
|
||||
rVal.worldPos = worldPos;
|
||||
rVal.program = program;
|
||||
rVal.dynamicInterpolationRatio = dynamicInterpolationRatio;
|
||||
rVal.heightmap = heightmap;
|
||||
rVal.texturemap = texturemap;
|
||||
rVal.data = data;
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -96,52 +85,63 @@ public class DrawCell {
|
||||
* Generates a drawable entity based on this chunk
|
||||
* @param stride The stride between indices used to generate "sparse" meshes
|
||||
*/
|
||||
public void generateDrawableEntity(int stride){
|
||||
public void generateDrawableEntity(){
|
||||
if(modelEntity != null){
|
||||
Globals.clientScene.deregisterEntity(modelEntity);
|
||||
}
|
||||
Model terrainModel = RenderUtils.createMinimizedTerrainModelPrecomputedShader(heightmap, texturemap, program, stride);
|
||||
Mesh terrainMesh = terrainModel.meshes.get(0);
|
||||
List<Texture> textureList = new LinkedList<Texture>();
|
||||
textureList.add(groundTextureOne);
|
||||
textureList.add(groundTextureTwo);
|
||||
textureList.add(groundTextureThree);
|
||||
textureList.add(groundTextureFour);
|
||||
List<String> uniformList = new LinkedList<String>();
|
||||
uniformList.add("groundTextures[0]");
|
||||
uniformList.add("groundTextures[1]");
|
||||
uniformList.add("groundTextures[2]");
|
||||
uniformList.add("groundTextures[3]");
|
||||
String terrainModelPath = Globals.assetManager.registerModel(terrainModel);
|
||||
modelEntity = EntityCreationUtils.createClientSpatialEntity();
|
||||
EntityCreationUtils.makeEntityDrawable(modelEntity, terrainModelPath);
|
||||
EntityUtils.getActor(modelEntity).addTextureMask(new ActorTextureMask("terrain",textureList,uniformList));
|
||||
modelEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
|
||||
modelEntity.putData(EntityDataStrings.DRAW_CAST_SHADOW, true);
|
||||
LoggerInterface.loggerRenderer.INFO("New cell @ " + cellX * dynamicInterpolationRatio + "," + cellY * dynamicInterpolationRatio);
|
||||
EntityUtils.getPosition(modelEntity).set(new Vector3f(cellX * dynamicInterpolationRatio, 0.0f, cellY * dynamicInterpolationRatio));
|
||||
modelEntity = TerrainChunk.clientCreateTerrainChunkEntity(data.getVoxelWeight(), data.getVoxelType());
|
||||
// TerrainChunk.createTerrainChunkEntity();
|
||||
// Model terrainModel = RenderUtils.createMinimizedTerrainModelPrecomputedShader(heightmap, texturemap, program, stride);
|
||||
// Mesh terrainMesh = terrainModel.meshes.get(0);
|
||||
// List<Texture> textureList = new LinkedList<Texture>();
|
||||
// textureList.add(groundTextureOne);
|
||||
// textureList.add(groundTextureTwo);
|
||||
// textureList.add(groundTextureThree);
|
||||
// textureList.add(groundTextureFour);
|
||||
// List<String> uniformList = new LinkedList<String>();
|
||||
// uniformList.add("groundTextures[0]");
|
||||
// uniformList.add("groundTextures[1]");
|
||||
// uniformList.add("groundTextures[2]");
|
||||
// uniformList.add("groundTextures[3]");
|
||||
// String terrainModelPath = Globals.assetManager.registerModel(terrainModel);
|
||||
// modelEntity = EntityCreationUtils.createClientSpatialEntity();
|
||||
// EntityCreationUtils.makeEntityDrawable(modelEntity, terrainModelPath);
|
||||
// EntityUtils.getActor(modelEntity).addTextureMask(new ActorTextureMask("terrain",textureList,uniformList));
|
||||
// modelEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
|
||||
// modelEntity.putData(EntityDataStrings.DRAW_CAST_SHADOW, true);
|
||||
// LoggerInterface.loggerRenderer.INFO("New cell @ " + cellX * dynamicInterpolationRatio + "," + cellY * dynamicInterpolationRatio);
|
||||
// EntityUtils.getPosition(modelEntity).set(getRealPos());
|
||||
ClientEntityUtils.initiallyPositionEntity(modelEntity, getRealPos());
|
||||
}
|
||||
|
||||
public void retireCell(){
|
||||
EntityUtils.cleanUpEntity(modelEntity);
|
||||
}
|
||||
|
||||
public void generatePhysics(){
|
||||
//if we're in no-graphics mode, need to generate the entity
|
||||
if(modelEntity == null){
|
||||
modelEntity = EntityCreationUtils.createClientSpatialEntity();
|
||||
modelEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
|
||||
EntityUtils.getPosition(modelEntity).set(new Vector3f(cellX * dynamicInterpolationRatio, 0.0f, cellY * dynamicInterpolationRatio));
|
||||
}
|
||||
//then actually perform the attach
|
||||
physicsObject = PhysicsUtils.attachTerrainRigidBody(modelEntity,heightmap,false);
|
||||
Globals.clientSceneWrapper.getCollisionEngine().registerPhysicsEntity(modelEntity);
|
||||
// System.out.println("generate physics");
|
||||
|
||||
protected Vector3d getRealPos(){
|
||||
return new Vector3d(
|
||||
worldPos.x * ChunkData.CHUNK_SIZE,
|
||||
worldPos.y * ChunkData.CHUNK_SIZE,
|
||||
worldPos.z * ChunkData.CHUNK_SIZE
|
||||
);
|
||||
}
|
||||
|
||||
public void destroyPhysics(){
|
||||
Globals.clientSceneWrapper.getCollisionEngine().deregisterCollidableEntity(modelEntity);
|
||||
Globals.clientSceneWrapper.getCollisionEngine().deregisterRigidBody((RigidBody)physicsObject);
|
||||
}
|
||||
// public void generatePhysics(){
|
||||
// //if we're in no-graphics mode, need to generate the entity
|
||||
// if(modelEntity == null){
|
||||
// modelEntity = EntityCreationUtils.createClientSpatialEntity();
|
||||
// modelEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
|
||||
// EntityUtils.getPosition(modelEntity).set(new Vector3f(cellX * dynamicInterpolationRatio, 0.0f, cellY * dynamicInterpolationRatio));
|
||||
// }
|
||||
// //then actually perform the attach
|
||||
// physicsObject = PhysicsUtils.attachTerrainRigidBody(modelEntity,heightmap,false);
|
||||
// Globals.clientSceneWrapper.getCollisionEngine().registerPhysicsEntity(modelEntity);
|
||||
// // System.out.println("generate physics");
|
||||
// }
|
||||
|
||||
// public void destroyPhysics(){
|
||||
// Globals.clientSceneWrapper.getCollisionEngine().deregisterCollidableEntity(modelEntity);
|
||||
// Globals.clientSceneWrapper.getCollisionEngine().deregisterRigidBody((RigidBody)physicsObject);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@ -1,20 +1,25 @@
|
||||
package electrosphere.client.terrain.cells;
|
||||
|
||||
import electrosphere.client.scene.ClientWorldData;
|
||||
import electrosphere.client.terrain.cache.ChunkData;
|
||||
import electrosphere.client.terrain.manager.ClientTerrainManager;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.EntityUtils;
|
||||
import electrosphere.game.terrain.processing.TerrainInterpolator;
|
||||
import electrosphere.game.collision.CommonWorldData;
|
||||
import electrosphere.net.parser.net.message.TerrainMessage;
|
||||
import electrosphere.renderer.ShaderProgram;
|
||||
import electrosphere.server.terrain.manager.ServerTerrainManager;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.joml.Vector2i;
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector3i;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -26,41 +31,40 @@ public class DrawCellManager {
|
||||
//the center of this cell manager's array in cell space
|
||||
int cellX;
|
||||
int cellY;
|
||||
int cellZ;
|
||||
|
||||
|
||||
//the dimensions of the world that this cell manager can handles
|
||||
int cellWidth;
|
||||
int cellHeight;
|
||||
|
||||
//the width of a minicell in this manager
|
||||
int miniCellWidth;
|
||||
|
||||
//all currently displaying mini cells
|
||||
DrawCell[][] cells;
|
||||
boolean[][] valid;
|
||||
boolean[][] drawable;
|
||||
boolean[][] updateable;
|
||||
boolean[][] hasRequested;
|
||||
boolean[][] needsPhysics;
|
||||
boolean[][] hasPhysics;
|
||||
Set<DrawCell> cells;
|
||||
Map<String,DrawCell> keyCellMap = new HashMap<String,DrawCell>();
|
||||
Set<String> hasNotRequested;
|
||||
Set<String> hasRequested;
|
||||
Set<String> drawable;
|
||||
Set<String> undrawable;
|
||||
Set<String> updateable;
|
||||
|
||||
|
||||
ShaderProgram program;
|
||||
|
||||
|
||||
|
||||
int drawRadius = 5;
|
||||
// int drawRadius = 5;
|
||||
int drawStepdownInterval = 3;
|
||||
int drawStepdownValue = 25;
|
||||
|
||||
double drawRadius = 200;
|
||||
|
||||
int physicsRadius = 3;
|
||||
|
||||
int worldBoundDiscreteMin = 0;
|
||||
int worldBoundDiscreteMax = 0;
|
||||
|
||||
//metadata about the game world
|
||||
CommonWorldData commonWorldData;
|
||||
|
||||
|
||||
//client terrain manager
|
||||
// ClientTerrainManager clientTerrainManager;
|
||||
|
||||
@ -80,600 +84,273 @@ public class DrawCellManager {
|
||||
* @param discreteX The initial discrete position X coordinate
|
||||
* @param discreteY The initial discrete position Y coordinate
|
||||
*/
|
||||
public DrawCellManager(CommonWorldData commonWorldData, ClientTerrainManager clientTerrainManager, int discreteX, int discreteY){
|
||||
this.commonWorldData = commonWorldData;
|
||||
worldBoundDiscreteMax = (int)(commonWorldData.getWorldBoundMin().x / commonWorldData.getDynamicInterpolationRatio() * 1.0f);
|
||||
// this.clientTerrainManager = clientTerrainManager;
|
||||
cells = new DrawCell[drawRadius * 2 + 1][drawRadius * 2 + 1];
|
||||
valid = new boolean[drawRadius * 2 + 1][drawRadius * 2 + 1];
|
||||
drawable = new boolean[drawRadius * 2 + 1][drawRadius * 2 + 1];
|
||||
updateable = new boolean[drawRadius * 2 + 1][drawRadius * 2 + 1];
|
||||
hasRequested = new boolean[drawRadius * 2 + 1][drawRadius * 2 + 1];
|
||||
needsPhysics = new boolean[physicsRadius * 2 + 1][physicsRadius * 2 + 1];
|
||||
hasPhysics = new boolean[physicsRadius * 2 + 1][physicsRadius * 2 + 1];
|
||||
for(int x = 0; x < drawRadius * 2 + 1; x++){
|
||||
for(int y = 0; y < drawRadius * 2 + 1; y++){
|
||||
valid[x][y] = false;
|
||||
drawable[x][y] = false;
|
||||
updateable[x][y] = false;
|
||||
hasRequested[x][y] = false;
|
||||
}
|
||||
}
|
||||
for(int x = 0; x < physicsRadius * 2 + 1; x++){
|
||||
for(int y = 0; y < physicsRadius * 2 + 1; y++){
|
||||
needsPhysics[x][y] = true;
|
||||
hasPhysics[x][y] = false;
|
||||
}
|
||||
}
|
||||
public DrawCellManager(ClientTerrainManager clientTerrainManager, int discreteX, int discreteY, int discreteZ){
|
||||
worldBoundDiscreteMax = (int)(Globals.clientWorldData.getWorldBoundMin().x / Globals.clientWorldData.getDynamicInterpolationRatio() * 1.0f);
|
||||
cells = new HashSet<DrawCell>();
|
||||
hasNotRequested = new HashSet<String>();
|
||||
drawable = new HashSet<String>();
|
||||
undrawable = new HashSet<String>();
|
||||
updateable = new HashSet<String>();
|
||||
hasRequested = new HashSet<String>();
|
||||
|
||||
cellX = discreteX;
|
||||
cellY = discreteY;
|
||||
cellZ = discreteZ;
|
||||
|
||||
program = Globals.terrainShaderProgram;
|
||||
|
||||
drawRadius = Globals.userSettings.getGraphicsPerformanceLODChunkRadius();
|
||||
// drawRadius = Globals.userSettings.getGraphicsPerformanceLODChunkRadius();
|
||||
drawStepdownInterval = Globals.userSettings.getGameplayPhysicsCellRadius();
|
||||
physicsRadius = Globals.userSettings.getGameplayPhysicsCellRadius();
|
||||
|
||||
invalidateAllCells();
|
||||
|
||||
update = true;
|
||||
}
|
||||
|
||||
DrawCellManager(){
|
||||
|
||||
}
|
||||
|
||||
public int getCellX(){
|
||||
return cellX;
|
||||
}
|
||||
|
||||
public int getCellY(){
|
||||
return cellY;
|
||||
}
|
||||
|
||||
public void setCellX(int x){
|
||||
cellX = x;
|
||||
}
|
||||
|
||||
public void setCellY(int y){
|
||||
cellY = y;
|
||||
}
|
||||
|
||||
public void setCell(Vector2i cellPos){
|
||||
public void setCell(Vector3i cellPos){
|
||||
cellX = cellPos.x;
|
||||
cellY = cellPos.y;
|
||||
cellZ = cellPos.z;
|
||||
}
|
||||
|
||||
void updateInvalidCell(){
|
||||
int targetX = 0;
|
||||
int targetY = 0;
|
||||
boolean found = false;
|
||||
for(int x = 0; x < drawRadius * 2 + 1; x++){
|
||||
targetX = x;
|
||||
for(int y = 0; y < drawRadius * 2 + 1; y++){
|
||||
targetY = y;
|
||||
if(!valid[x][y]){
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(found){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(found){
|
||||
int currentCellX = cellX - drawRadius + targetX;
|
||||
int currentCellY = cellY - drawRadius + targetY;
|
||||
|
||||
void updateUnrequestedCell(){
|
||||
if(hasNotRequested.size() > 0){
|
||||
String targetKey = hasNotRequested.iterator().next();
|
||||
hasNotRequested.remove(targetKey);
|
||||
Vector3i worldPos = getVectorFromKey(targetKey);
|
||||
// Vector3i vector = getVectorFromKey(targetKey);
|
||||
// int currentCellX = cellX - drawRadius + vector.x;
|
||||
// int currentCellY = cellY - drawRadius + vector.y;
|
||||
// int currentCellZ = cellZ - drawRadius + vector.z;
|
||||
|
||||
if(
|
||||
currentCellX >= 0 &&
|
||||
currentCellX < commonWorldData.getWorldDiscreteSize() &&
|
||||
currentCellY >= 0 &&
|
||||
currentCellY < commonWorldData.getWorldDiscreteSize()
|
||||
){
|
||||
if(containsHeightmapAtDiscretePoint(currentCellX, currentCellY)){
|
||||
cells[targetX][targetY] = DrawCell.generateTerrainCell(
|
||||
currentCellX,
|
||||
currentCellY,
|
||||
getHeightmapAtPoint(currentCellX, currentCellY),
|
||||
getTextureMapAtPoint(currentCellX, currentCellY),
|
||||
commonWorldData.getDynamicInterpolationRatio(),
|
||||
program
|
||||
);
|
||||
valid[targetX][targetY] = true;
|
||||
drawable[targetX][targetY] = false;
|
||||
updateable[targetX][targetY] = false;
|
||||
hasRequested[targetX][targetY] = false;
|
||||
hasPhysics[targetX][targetY] = false;
|
||||
needsPhysics[targetX][targetY] = true;
|
||||
// if(Math.abs(physicsRadius + 1 - targetX) < physicsRadius && Math.abs(physicsRadius + 1 - targetY) < physicsRadius){
|
||||
// needsPhysics[targetX][targetY] = true;
|
||||
// }
|
||||
} else {
|
||||
if(hasRequested[targetX][targetY] == false){
|
||||
//client should request macro values from server
|
||||
Globals.clientConnection.queueOutgoingMessage(TerrainMessage.constructRequestChunkMessage(currentCellX, currentCellY));
|
||||
hasRequested[targetX][targetY] = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
valid[targetX][targetY] = true;
|
||||
drawable[targetX][targetY] = false;
|
||||
updateable[targetX][targetY] = false;
|
||||
hasRequested[targetX][targetY] = false;
|
||||
hasPhysics[targetX][targetY] = false;
|
||||
needsPhysics[targetX][targetY] = true;
|
||||
worldPos.x >= 0 &&
|
||||
worldPos.x < Globals.clientWorldData.getWorldDiscreteSize() &&
|
||||
worldPos.y >= 0 &&
|
||||
worldPos.y < Globals.clientWorldData.getWorldDiscreteSize() &&
|
||||
worldPos.z >= 0 &&
|
||||
worldPos.z < Globals.clientWorldData.getWorldDiscreteSize()
|
||||
){
|
||||
// if(!hasRequested.contains(targetKey)){
|
||||
//client should request chunk data from server
|
||||
Globals.clientConnection.queueOutgoingMessage(TerrainMessage.constructRequestChunkDataMessage(
|
||||
worldPos.x,
|
||||
worldPos.y,
|
||||
worldPos.z
|
||||
));
|
||||
undrawable.add(targetKey);
|
||||
hasRequested.add(targetKey);
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes one of the undrawable cells drawable
|
||||
*/
|
||||
void makeCellDrawable(){
|
||||
int targetX = 0;
|
||||
int targetY = 0;
|
||||
boolean found = false;
|
||||
for(int x = 0; x < drawRadius * 2 + 1; x++){
|
||||
targetX = x;
|
||||
for(int y = 0; y < drawRadius * 2 + 1; y++){
|
||||
targetY = y;
|
||||
if(valid[x][y] && !drawable[x][y]){
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(found){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(found){
|
||||
int currentCellX = cellX - drawRadius + targetX;
|
||||
int currentCellY = cellY - drawRadius + targetY;
|
||||
if(undrawable.size() > 0){
|
||||
String targetKey = undrawable.iterator().next();
|
||||
Vector3i worldPos = getVectorFromKey(targetKey);
|
||||
if(
|
||||
currentCellX >= 0 &&
|
||||
currentCellX < commonWorldData.getWorldDiscreteSize() &&
|
||||
currentCellY >= 0 &&
|
||||
currentCellY < commonWorldData.getWorldDiscreteSize()
|
||||
){
|
||||
//physics radius calculation
|
||||
// if(Math.abs(physicsRadius + 1 - targetX) < physicsRadius && Math.abs(physicsRadius + 1 - targetY) < physicsRadius){
|
||||
// needsPhysics[targetX][targetY] = true;
|
||||
// }
|
||||
//calculation for stride
|
||||
int dist = (int)Math.sqrt((targetX - drawRadius)*(targetX - drawRadius) + (targetY - drawRadius) * (targetY - drawRadius));//Math.abs(targetX - drawRadius) * Math.abs(targetY - drawRadius);
|
||||
int stride = Math.min(commonWorldData.getDynamicInterpolationRatio()/2, Math.max(1, dist / drawStepdownInterval * drawStepdownValue));
|
||||
while(commonWorldData.getDynamicInterpolationRatio() % stride != 0){
|
||||
stride = stride + 1;
|
||||
worldPos.x >= 0 &&
|
||||
worldPos.x < Globals.clientWorldData.getWorldDiscreteSize() &&
|
||||
worldPos.y >= 0 &&
|
||||
worldPos.y < Globals.clientWorldData.getWorldDiscreteSize() &&
|
||||
worldPos.z >= 0 &&
|
||||
worldPos.z < Globals.clientWorldData.getWorldDiscreteSize()
|
||||
){
|
||||
if(containsChunkDataAtWorldPoint(worldPos.x, worldPos.y, worldPos.z)){
|
||||
DrawCell cell = DrawCell.generateTerrainCell(
|
||||
worldPos,
|
||||
Globals.clientTerrainManager.getChunkDataAtWorldPoint(worldPos.x, worldPos.y, worldPos.z),
|
||||
program
|
||||
);
|
||||
cells.add(cell);
|
||||
keyCellMap.put(targetKey,cell);
|
||||
// undrawable.add(targetKey);
|
||||
undrawable.remove(targetKey);
|
||||
drawable.add(targetKey);
|
||||
//make drawable entity
|
||||
keyCellMap.get(targetKey).generateDrawableEntity();
|
||||
}
|
||||
//make drawable entity
|
||||
cells[targetX][targetY].generateDrawableEntity(stride);
|
||||
}
|
||||
drawable[targetX][targetY] = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a cell that can be updated
|
||||
*/
|
||||
void updateCellModel(){
|
||||
int targetX = 0;
|
||||
int targetY = 0;
|
||||
boolean found = false;
|
||||
for(int x = 0; x < drawRadius * 2 + 1; x++){
|
||||
targetX = x;
|
||||
for(int y = 0; y < drawRadius * 2 + 1; y++){
|
||||
targetY = y;
|
||||
if(updateable[x][y]){
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(found){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(found){
|
||||
int currentCellX = cellX - drawRadius + targetX;
|
||||
int currentCellY = cellY - drawRadius + targetY;
|
||||
if(updateable.size() > 0){
|
||||
String targetKey = updateable.iterator().next();
|
||||
updateable.remove(targetKey);
|
||||
Vector3i worldPos = getVectorFromKey(targetKey);
|
||||
if(
|
||||
currentCellX >= 0 &&
|
||||
currentCellX < commonWorldData.getWorldDiscreteSize() &&
|
||||
currentCellY >= 0 &&
|
||||
currentCellY < commonWorldData.getWorldDiscreteSize()
|
||||
worldPos.x >= 0 &&
|
||||
worldPos.x < Globals.clientWorldData.getWorldDiscreteSize() &&
|
||||
worldPos.y >= 0 &&
|
||||
worldPos.y < Globals.clientWorldData.getWorldDiscreteSize() &&
|
||||
worldPos.z >= 0 &&
|
||||
worldPos.z < Globals.clientWorldData.getWorldDiscreteSize()
|
||||
){
|
||||
// if(Math.abs(drawRadius + 1 - targetX) < physicsRadius && Math.abs(drawRadius + 1 - targetY) < physicsRadius){
|
||||
// needsPhysics[targetX][targetY] = true;
|
||||
// }
|
||||
int dist = (int)Math.sqrt((targetX - drawRadius)*(targetX - drawRadius) + (targetY - drawRadius) * (targetY - drawRadius)); //Math.abs(targetX - drawRadius) * Math.abs(targetY - drawRadius);
|
||||
int stride = Math.min(commonWorldData.getDynamicInterpolationRatio()/2, Math.max(1, dist / drawStepdownInterval * drawStepdownValue));
|
||||
while(commonWorldData.getDynamicInterpolationRatio() % stride != 0){
|
||||
stride = stride + 1;
|
||||
}
|
||||
cells[targetX][targetY].generateDrawableEntity(stride);
|
||||
// int dist = (int)Math.sqrt((targetX - drawRadius)*(targetX - drawRadius) + (targetY - drawRadius) * (targetY - drawRadius)); //Math.abs(targetX - drawRadius) * Math.abs(targetY - drawRadius);
|
||||
// int stride = Math.min(commonWorldData.getDynamicInterpolationRatio()/2, Math.max(1, dist / drawStepdownInterval * drawStepdownValue));
|
||||
// while(commonWorldData.getDynamicInterpolationRatio() % stride != 0){
|
||||
// stride = stride + 1;
|
||||
// }
|
||||
keyCellMap.get(targetKey).generateDrawableEntity();
|
||||
}
|
||||
updateable[targetX][targetY] = false;
|
||||
drawable[targetX][targetY] = true;
|
||||
drawable.add(targetKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean containsInvalidCell(){
|
||||
// if(DRAW_CELL_MANAGER_FLAG_UPDATE_DYNAMIC_TERRAIN){
|
||||
for(int x = 0;x < drawRadius * 2 + 1; x++){
|
||||
for(int y = 0; y < drawRadius * 2 + 1; y++){
|
||||
if(!valid[x][y]){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// } else if(DRAW_CELL_MANAGER_FLAG_GENERATE_ARENA){
|
||||
// return cells[0][0] == null || cells[1][0] == null || cells[0][1] == null | cells[1][1] == null;
|
||||
// }
|
||||
return false;
|
||||
public boolean containsUnrequestedCell(){
|
||||
return hasNotRequested.size() > 0;
|
||||
}
|
||||
|
||||
public boolean containsUndrawableCell(){
|
||||
for(int x = 0;x < drawRadius * 2 + 1; x++){
|
||||
for(int y = 0; y < drawRadius * 2 + 1; y++){
|
||||
if(!drawable[x][y] && this.generateDrawables){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return undrawable.size() > 0;
|
||||
}
|
||||
|
||||
public boolean containsUpdateableCell(){
|
||||
for(int x = 0;x < drawRadius * 2 + 1; x++){
|
||||
for(int y = 0; y < drawRadius * 2 + 1; y++){
|
||||
if(updateable[x][y] && this.generateDrawables){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean containsPhysicsNeedingCell(){
|
||||
for(int x = 0; x < physicsRadius * 2 + 1; x++){
|
||||
for(int y = 0; y < physicsRadius * 2 + 1; y++){
|
||||
if(needsPhysics[x][y]){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void addPhysicsToCell(){
|
||||
int targetX = 0;
|
||||
int targetY = 0;
|
||||
boolean found = false;
|
||||
for(int x = 0; x < physicsRadius * 2 + 1; x++){
|
||||
targetX = x;
|
||||
for(int y = 0; y < physicsRadius * 2 + 1; y++){
|
||||
targetY = y;
|
||||
// System.out.println(x + " <=>w " + y);
|
||||
if(needsPhysics[x][y]){
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(found){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(found){
|
||||
int currentCellX = cellX - physicsRadius + targetX;
|
||||
int currentCellY = cellY - physicsRadius + targetY;
|
||||
if(
|
||||
currentCellX >= 0 &&
|
||||
currentCellX < commonWorldData.getWorldDiscreteSize() &&
|
||||
currentCellY >= 0 &&
|
||||
currentCellY < commonWorldData.getWorldDiscreteSize()
|
||||
){
|
||||
// if(Math.abs(drawRadius + 1 - targetX) < physicsRadius && Math.abs(drawRadius + 1 - targetY) < physicsRadius){
|
||||
// needsPhysics[targetX][targetY] = true;
|
||||
// }
|
||||
// int dist = (int)Math.sqrt((targetX - drawRadius)*(targetX - drawRadius) + (targetY - drawRadius) * (targetY - drawRadius)); //Math.abs(targetX - drawRadius) * Math.abs(targetY - drawRadius);
|
||||
// int stride = Math.min(clientWorldData.getDynamicInterpolationRatio()/2, Math.max(1, dist / drawStepdownInterval * drawStepdownValue));
|
||||
// while(clientWorldData.getDynamicInterpolationRatio() % stride != 0){
|
||||
// stride = stride + 1;
|
||||
// }
|
||||
// if(cells[targetX][targetY + drawRadius] != null){
|
||||
// System.out.println(targetX + " - " + targetY);
|
||||
cells[targetX + drawRadius - physicsRadius][targetY + drawRadius - physicsRadius].generatePhysics();
|
||||
// } else {
|
||||
// System.out.println("Current cell is null: " + currentCellX + " - " + currentCellY);
|
||||
// }
|
||||
}
|
||||
needsPhysics[targetX][targetY] = false;
|
||||
hasPhysics[targetX][targetY] = true;
|
||||
}
|
||||
return updateable.size() > 0;
|
||||
}
|
||||
|
||||
|
||||
public void shiftChunksNegX(){
|
||||
//retire old graphics
|
||||
for(int y = 0; y < drawRadius * 2 + 1; y++){
|
||||
if(cells[drawRadius * 2][y] != null){
|
||||
cells[drawRadius * 2][y].retireCell();
|
||||
}
|
||||
}
|
||||
//shift draw array
|
||||
for(int x = drawRadius * 2; x > 0; x--){
|
||||
for(int y = 0; y < drawRadius * 2 + 1; y++){
|
||||
cells[x][y] = cells[x-1][y];
|
||||
updateable[x][y] = true;
|
||||
hasRequested[x][y] = hasRequested[x-1][y];
|
||||
}
|
||||
}
|
||||
//invalidate edge of draw array
|
||||
for(int y = 0; y < drawRadius * 2 + 1; y++){
|
||||
valid[0][y] = false;
|
||||
hasRequested[0][y] = false;
|
||||
}
|
||||
//retire physics of cells
|
||||
for(int x = 0; x < physicsRadius * 2 + 1; x++){
|
||||
if(hasPhysics[x][physicsRadius * 2]){
|
||||
if(cells[x + drawRadius - physicsRadius][physicsRadius * 2 + drawRadius - physicsRadius] != null){
|
||||
cells[x + drawRadius - physicsRadius][physicsRadius * 2 + drawRadius - physicsRadius].destroyPhysics();
|
||||
}
|
||||
}
|
||||
}
|
||||
//shift physics array
|
||||
for(int x = physicsRadius * 2; x > 0; x--){
|
||||
for(int y = 0; y < physicsRadius * 2 + 1; y++){
|
||||
needsPhysics[x][y] = needsPhysics[x-1][y];
|
||||
hasPhysics[x][y] = hasPhysics[x-1][y];
|
||||
}
|
||||
}
|
||||
//invalidate edge of physics array
|
||||
for(int y = 0; y < physicsRadius * 2 + 1; y++){
|
||||
needsPhysics[0][y] = true;
|
||||
hasPhysics[0][y] = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void shiftChunksPosX(){
|
||||
//retire old graphics
|
||||
for(int y = 0; y < drawRadius * 2 + 1; y++){
|
||||
if(cells[0][y] != null){
|
||||
cells[0][y].retireCell();
|
||||
}
|
||||
}
|
||||
//shift draw array
|
||||
for(int x = 0; x < drawRadius * 2; x++){
|
||||
for(int y = 0; y < drawRadius * 2 + 1; y++){
|
||||
cells[x][y] = cells[x+1][y];
|
||||
updateable[x][y] = true;
|
||||
hasRequested[x][y] = hasRequested[x+1][y];
|
||||
}
|
||||
}
|
||||
//invalidate edge of draw array
|
||||
for(int y = 0; y < drawRadius * 2 + 1; y++){
|
||||
valid[drawRadius * 2][y] = false;
|
||||
hasRequested[drawRadius * 2][y] = false;
|
||||
}
|
||||
//retire physics of cells
|
||||
for(int x = 0; x < physicsRadius * 2 + 1; x++){
|
||||
if(hasPhysics[x][physicsRadius * 2]){
|
||||
if(cells[x + drawRadius - physicsRadius][physicsRadius * 2 + drawRadius - physicsRadius] != null){
|
||||
cells[x + drawRadius - physicsRadius][physicsRadius * 2 + drawRadius - physicsRadius].destroyPhysics();
|
||||
}
|
||||
}
|
||||
}
|
||||
//shift physics array
|
||||
for(int x = 0; x < physicsRadius * 2; x++){
|
||||
for(int y = 0; y < physicsRadius * 2 + 1; y++){
|
||||
needsPhysics[x][y] = needsPhysics[x+1][y];
|
||||
hasPhysics[x][y] = hasPhysics[x+1][y];
|
||||
}
|
||||
}
|
||||
//invalidate edge of physics array
|
||||
for(int y = 0; y < physicsRadius * 2 + 1; y++){
|
||||
needsPhysics[physicsRadius * 2][y] = true;
|
||||
hasPhysics[physicsRadius * 2][y] = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void shiftChunksNegY(){
|
||||
//retire cells
|
||||
for(int x = 0; x < drawRadius * 2 + 1; x++){
|
||||
if(cells[x][drawRadius * 2] != null){
|
||||
cells[x][drawRadius * 2].retireCell();
|
||||
}
|
||||
}
|
||||
//shift draw array
|
||||
for(int x = 0; x < drawRadius * 2 + 1; x++){
|
||||
for(int y = drawRadius * 2; y > 0; y--){
|
||||
cells[x][y] = cells[x][y-1];
|
||||
updateable[x][y] = true;
|
||||
hasRequested[x][y] = hasRequested[x][y-1];
|
||||
}
|
||||
}
|
||||
//invalidate edge of draw array
|
||||
for(int x = 0; x < drawRadius * 2 + 1; x++){
|
||||
valid[x][0] = false;
|
||||
hasRequested[x][0] = false;
|
||||
}
|
||||
//retire physics of cells
|
||||
for(int x = 0; x < physicsRadius * 2 + 1; x++){
|
||||
if(hasPhysics[x][physicsRadius * 2]){
|
||||
if(cells[x + drawRadius - physicsRadius][physicsRadius * 2 + drawRadius - physicsRadius] != null){
|
||||
cells[x + drawRadius - physicsRadius][physicsRadius * 2 + drawRadius - physicsRadius].destroyPhysics();
|
||||
}
|
||||
}
|
||||
}
|
||||
//shift physics array
|
||||
for(int x = 0; x < physicsRadius * 2 + 1; x++){
|
||||
for(int y = physicsRadius * 2; y > 0; y--){
|
||||
needsPhysics[x][y] = needsPhysics[x][y-1];
|
||||
hasPhysics[x][y] = hasPhysics[x][y-1];
|
||||
}
|
||||
}
|
||||
//invalidate edge of physics array
|
||||
for(int x = 0; x < physicsRadius * 2 + 1; x++){
|
||||
needsPhysics[x][0] = true;
|
||||
hasPhysics[x][0] = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void shiftChunksPosY(){
|
||||
//retire old graphics
|
||||
for(int x = 0; x < drawRadius * 2 + 1; x++){
|
||||
if(cells[x][0] != null){
|
||||
cells[x][0].retireCell();
|
||||
}
|
||||
}
|
||||
//shift draw array
|
||||
for(int x = 0; x < drawRadius * 2 + 1; x++){
|
||||
for(int y = 0; y < drawRadius * 2; y++){
|
||||
cells[x][y] = cells[x][y+1];
|
||||
updateable[x][y] = true;
|
||||
hasRequested[x][y] = hasRequested[x][y+1];
|
||||
}
|
||||
}
|
||||
//invalidate edge of draw array
|
||||
for(int x = 0; x < drawRadius * 2 + 1; x++){
|
||||
valid[x][drawRadius * 2] = false;
|
||||
hasRequested[x][drawRadius * 2] = false;
|
||||
}
|
||||
//retire physics of cells
|
||||
for(int x = 0; x < physicsRadius * 2 + 1; x++){
|
||||
if(hasPhysics[x][0]){
|
||||
if(cells[x + drawRadius - physicsRadius][0 + drawRadius - physicsRadius] != null){
|
||||
cells[x + drawRadius - physicsRadius][0 + drawRadius - physicsRadius].destroyPhysics();
|
||||
}
|
||||
}
|
||||
}
|
||||
//shift physics array
|
||||
for(int x = 0; x < physicsRadius * 2 + 1; x++){
|
||||
for(int y = 0; y < physicsRadius * 2; y++){
|
||||
needsPhysics[x][y] = needsPhysics[x][y+1];
|
||||
hasPhysics[x][y] = hasPhysics[x][y+1];
|
||||
}
|
||||
}
|
||||
//invalidate edge of physics array
|
||||
for(int x = 0; x < physicsRadius * 2 + 1; x++){
|
||||
needsPhysics[x][physicsRadius * 2] = true;
|
||||
hasPhysics[x][physicsRadius * 2] = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public int transformRealSpaceToCellSpace(double input){
|
||||
return (int)(input / commonWorldData.getDynamicInterpolationRatio());
|
||||
return (int)(input / Globals.clientWorldData.getDynamicInterpolationRatio());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clears the valid set and adds all keys to invalid set
|
||||
*/
|
||||
public void invalidateAllCells(){
|
||||
for(int x = 0; x < drawRadius * 2 + 1; x++){
|
||||
for(int y = 0; y < drawRadius * 2 + 1; y++){
|
||||
valid[x][y] = false;
|
||||
drawable.clear();
|
||||
hasNotRequested.clear();
|
||||
clearOutOfBoundsCells();
|
||||
queueNewCells();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates whether the position of the player has changed and if so, invalidates and cleans up cells accordingly
|
||||
* @param position The position of the player entity on current frame
|
||||
*/
|
||||
public void calculateDeltas(Vector3d position){
|
||||
//check if any not requested cells no longer need to be requested
|
||||
clearOutOfBoundsCells();
|
||||
//check if any cells should be added
|
||||
queueNewCells();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all cells outside of draw radius
|
||||
*/
|
||||
private void clearOutOfBoundsCells(){
|
||||
Set<DrawCell> cellsToRemove = new HashSet<DrawCell>();
|
||||
for(DrawCell cell : cells){
|
||||
Vector3d realPos = cell.getRealPos();
|
||||
if(Globals.playerEntity != null && EntityUtils.getPosition(Globals.playerEntity).distance(realPos) > drawRadius){
|
||||
cellsToRemove.add(cell);
|
||||
}
|
||||
}
|
||||
for(DrawCell cell : cellsToRemove){
|
||||
cells.remove(cell);
|
||||
String key = getCellKey(cell.worldPos.x, cell.worldPos.y, cell.worldPos.z);
|
||||
hasNotRequested.remove(key);
|
||||
drawable.remove(key);
|
||||
undrawable.remove(key);
|
||||
updateable.remove(key);
|
||||
keyCellMap.remove(key);
|
||||
hasRequested.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Queues new cells that are in bounds but not currently accounted for
|
||||
*/
|
||||
private void queueNewCells(){
|
||||
if(Globals.playerEntity != null && Globals.clientWorldData != null){
|
||||
Vector3d playerPos = EntityUtils.getPosition(Globals.playerEntity);
|
||||
for(int x = -(int)drawRadius; x < drawRadius; x = x + ChunkData.CHUNK_SIZE){
|
||||
for(int y = -(int)drawRadius; y < drawRadius; y = y + ChunkData.CHUNK_SIZE){
|
||||
for(int z = -(int)drawRadius; z < drawRadius; z = z + ChunkData.CHUNK_SIZE){
|
||||
Vector3d newPos = new Vector3d(playerPos.x + x, playerPos.y + y, playerPos.z + z);
|
||||
Vector3i worldPos = new Vector3i(
|
||||
Globals.clientWorldData.convertRealToChunkSpace(newPos.x),
|
||||
Globals.clientWorldData.convertRealToChunkSpace(newPos.y),
|
||||
Globals.clientWorldData.convertRealToChunkSpace(newPos.z)
|
||||
);
|
||||
Vector3d chunkRealSpace = new Vector3d(
|
||||
Globals.clientWorldData.convertChunkToRealSpace(worldPos.x),
|
||||
Globals.clientWorldData.convertChunkToRealSpace(worldPos.y),
|
||||
Globals.clientWorldData.convertChunkToRealSpace(worldPos.z)
|
||||
);
|
||||
if(
|
||||
playerPos.distance(chunkRealSpace) < drawRadius &&
|
||||
worldPos.x >= 0 &&
|
||||
worldPos.x < Globals.clientWorldData.getWorldDiscreteSize() &&
|
||||
worldPos.y >= 0 &&
|
||||
worldPos.y < Globals.clientWorldData.getWorldDiscreteSize() &&
|
||||
worldPos.z >= 0 &&
|
||||
worldPos.z < Globals.clientWorldData.getWorldDiscreteSize()
|
||||
){
|
||||
String key = getCellKey(
|
||||
Globals.clientWorldData.convertRealToChunkSpace(chunkRealSpace.x),
|
||||
Globals.clientWorldData.convertRealToChunkSpace(chunkRealSpace.y),
|
||||
Globals.clientWorldData.convertRealToChunkSpace(chunkRealSpace.z)
|
||||
);
|
||||
if(!keyCellMap.containsKey(key) && !hasNotRequested.contains(key) && !undrawable.contains(key) && !drawable.contains(key) &&
|
||||
!hasRequested.contains(key)){
|
||||
hasNotRequested.add(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void calculateDeltas(Vector3d oldPosition, Vector3d newPosition){
|
||||
// if(DRAW_CELL_MANAGER_FLAG_UPDATE_DYNAMIC_TERRAIN){
|
||||
if(transformRealSpaceToCellSpace(newPosition.x()) < transformRealSpaceToCellSpace(oldPosition.x())){
|
||||
shiftChunksNegX();
|
||||
setCellX(transformRealSpaceToCellSpace(newPosition.x()));
|
||||
setCellY(transformRealSpaceToCellSpace(newPosition.z()));
|
||||
} else if(transformRealSpaceToCellSpace(newPosition.x()) > transformRealSpaceToCellSpace(oldPosition.x())){
|
||||
shiftChunksPosX();
|
||||
setCellX(transformRealSpaceToCellSpace(newPosition.x()));
|
||||
setCellY(transformRealSpaceToCellSpace(newPosition.z()));
|
||||
}
|
||||
|
||||
if(transformRealSpaceToCellSpace(newPosition.z()) < transformRealSpaceToCellSpace(oldPosition.z())){
|
||||
shiftChunksNegY();
|
||||
setCellX(transformRealSpaceToCellSpace(newPosition.x()));
|
||||
setCellY(transformRealSpaceToCellSpace(newPosition.z()));
|
||||
} else if(transformRealSpaceToCellSpace(newPosition.z()) > transformRealSpaceToCellSpace(oldPosition.z())){
|
||||
shiftChunksPosY();
|
||||
setCellX(transformRealSpaceToCellSpace(newPosition.x()));
|
||||
setCellY(transformRealSpaceToCellSpace(newPosition.z()));
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates cells that need updating in this manager
|
||||
*/
|
||||
public void update(){
|
||||
if(update){
|
||||
// if(DRAW_CELL_MANAGER_FLAG_UPDATE_DYNAMIC_TERRAIN){
|
||||
if(containsInvalidCell()){
|
||||
updateInvalidCell();
|
||||
if(containsUnrequestedCell() && !containsUndrawableCell()){
|
||||
updateUnrequestedCell();
|
||||
} else if(containsUndrawableCell()){
|
||||
makeCellDrawable();
|
||||
} else if(containsUpdateableCell()){
|
||||
updateCellModel();
|
||||
} else if(containsPhysicsNeedingCell()){
|
||||
addPhysicsToCell();
|
||||
}
|
||||
}
|
||||
// } else if(DRAW_CELL_MANAGER_FLAG_GENERATE_ARENA){
|
||||
// if(cells[0][0] == null){
|
||||
// int arenaChunkWidth = 100;
|
||||
// cells[0][0] = new DrawCell(
|
||||
// new float[arenaChunkWidth + 1][arenaChunkWidth + 1],
|
||||
// arenaChunkWidth + 1,
|
||||
// 0,
|
||||
// 0,
|
||||
// arenaChunkWidth,
|
||||
// program
|
||||
// );
|
||||
// cells[0][0].generateDrawableEntity(1);
|
||||
// } else if(cells[0][1] == null){
|
||||
// int arenaChunkWidth = 100;
|
||||
// cells[0][1] = new DrawCell(
|
||||
// new float[arenaChunkWidth + 1][arenaChunkWidth + 1],
|
||||
// arenaChunkWidth + 1,
|
||||
// 0,
|
||||
// 1,
|
||||
// arenaChunkWidth,
|
||||
// program
|
||||
// );
|
||||
// cells[0][1].generateDrawableEntity(1);
|
||||
// } else if(cells[1][0] == null){
|
||||
// int arenaChunkWidth = 100;
|
||||
// cells[1][0] = new DrawCell(
|
||||
// new float[arenaChunkWidth + 1][arenaChunkWidth + 1],
|
||||
// arenaChunkWidth + 1,
|
||||
// 1,
|
||||
// 0,
|
||||
// arenaChunkWidth,
|
||||
// program
|
||||
// );
|
||||
// cells[1][0].generateDrawableEntity(1);
|
||||
// } else if(cells[1][1] == null){
|
||||
// int arenaChunkWidth = 100;
|
||||
// cells[1][1] = new DrawCell(
|
||||
// new float[arenaChunkWidth + 1][arenaChunkWidth + 1],
|
||||
// arenaChunkWidth + 1,
|
||||
// 1,
|
||||
// 1,
|
||||
// arenaChunkWidth,
|
||||
// program
|
||||
// );
|
||||
// cells[1][1].generateDrawableEntity(1);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
// public float getElevationAtRealPoint(float realPointX, float realPointY){
|
||||
//// if(DRAW_CELL_MANAGER_FLAG_UPDATE_DYNAMIC_TERRAIN){
|
||||
// return terrainManager.getHeightAtPosition(realPointX, realPointY);
|
||||
//// }
|
||||
//// if(DRAW_CELL_MANAGER_FLAG_GENERATE_ARENA){
|
||||
//// return 0;
|
||||
//// }
|
||||
//// return 0;
|
||||
// }
|
||||
|
||||
|
||||
public boolean canValidateCell(){
|
||||
boolean rVal = false;
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits a cell key into its constituent coordinates in array format.
|
||||
* @param cellKey The cell key to split
|
||||
* @return The coordinates in array format
|
||||
*/
|
||||
// private int[] splitKeyToCoordinates(String cellKey){
|
||||
// int[] rVal = new int[3];
|
||||
// String[] components = cellKey.split("_");
|
||||
// for(int i = 0; i < 3; i++){
|
||||
// rVal[i] = Integer.parseInt(components[i]);
|
||||
// }
|
||||
// return rVal;
|
||||
// }
|
||||
|
||||
public boolean coordsInPhysicsSpace(int worldX, int worldY){
|
||||
return worldX <= cellX + physicsRadius && worldX >= cellX - physicsRadius && worldY <= cellY + physicsRadius && worldY >= cellY - physicsRadius;
|
||||
@ -683,38 +360,44 @@ public class DrawCellManager {
|
||||
this.generateDrawables = generate;
|
||||
}
|
||||
|
||||
boolean containsHeightmapAtDiscretePoint(int currentCellX, int currentCellY){
|
||||
boolean containsChunkDataAtWorldPoint(int worldX, int worldY, int worldZ){
|
||||
if(Globals.clientTerrainManager != null){
|
||||
return Globals.clientTerrainManager.containsHeightmapAtDiscretePoint(currentCellX, currentCellY);
|
||||
return Globals.clientTerrainManager.containsChunkDataAtWorldPoint(worldX,worldY,worldZ);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
float[][] getHeightmapAtPoint(int currentCellX, int currentCellY){
|
||||
if(Globals.clientTerrainManager != null){
|
||||
return Globals.clientTerrainManager.getHeightmapAtPoint(currentCellX, currentCellY);
|
||||
}
|
||||
return Globals.serverTerrainManager.getChunk(currentCellX, currentCellY).getHeightMap();
|
||||
/**
|
||||
* Gets the chunk data at a given point
|
||||
* @param worldX The world position x component of the cell
|
||||
* @param worldY The world position y component of the cell
|
||||
* @param worldZ The world position z component of the cell
|
||||
* @return The chunk data at the specified points
|
||||
*/
|
||||
ChunkData getChunkDataAtPoint(int worldX, int worldY, int worldZ){
|
||||
return Globals.clientTerrainManager.getChunkDataAtWorldPoint(worldX,worldY,worldZ);
|
||||
}
|
||||
|
||||
float[][] getTextureMapAtPoint(int currentCellX, int currentCellY){
|
||||
if(Globals.clientTerrainManager != null){
|
||||
return Globals.clientTerrainManager.getTextureMapAtPoint(currentCellX,currentCellY);
|
||||
} else {
|
||||
//hacky fix to +2 to this, I think the interpolation ratio was different for server/client data
|
||||
//now that we're merging/ambiguous within this class, it's out of bounds-ing unless I +2
|
||||
//TODO: investigate
|
||||
float[][] rVal = new float[commonWorldData.getDynamicInterpolationRatio() + 2][commonWorldData.getDynamicInterpolationRatio() + 2];
|
||||
rVal[1][1] = 1;
|
||||
rVal[2][1] = 1;
|
||||
rVal[3][1] = 1;
|
||||
rVal[4][1] = 1;
|
||||
rVal[5][1] = 1;
|
||||
rVal[5][2] = 1;
|
||||
rVal[6][1] = 1;
|
||||
rVal[6][2] = 1;
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a unique key for the cell
|
||||
* @param worldX The world position x component of the cell
|
||||
* @param worldY The world position y component of the cell
|
||||
* @param worldZ The world position z component of the cell
|
||||
* @return The key
|
||||
*/
|
||||
private String getCellKey(int worldX, int worldY, int worldZ){
|
||||
return worldX + "_" + worldY + "_" + worldZ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a vector3i from the cell key
|
||||
* @param key The cell key
|
||||
* @return The vector3i containing the components of the cell key
|
||||
*/
|
||||
private Vector3i getVectorFromKey(String key){
|
||||
String[] keyComponents = key.split("_");
|
||||
return new Vector3i(Integer.parseInt(keyComponents[0]),Integer.parseInt(keyComponents[1]),Integer.parseInt(keyComponents[2]));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,27 +1,34 @@
|
||||
package electrosphere.client.terrain.manager;
|
||||
|
||||
import electrosphere.client.scene.ClientWorldData;
|
||||
import electrosphere.client.terrain.cache.ChunkData;
|
||||
import electrosphere.client.terrain.cache.ClientTerrainCache;
|
||||
import electrosphere.client.terrain.cache.LoadingChunk;
|
||||
import electrosphere.client.terrain.cache.LoadingChunkCache;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.types.terrain.TerrainChunkData;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.net.parser.net.message.TerrainMessage;
|
||||
import electrosphere.renderer.Model;
|
||||
import electrosphere.renderer.meshgen.TerrainChunkModelGeneration;
|
||||
import electrosphere.server.terrain.manager.ServerTerrainManager;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
/**
|
||||
* Manages terrain storage and access on the client
|
||||
*/
|
||||
public class ClientTerrainManager {
|
||||
|
||||
//queues messages from server
|
||||
List<TerrainMessage> messageQueue = new CopyOnWriteArrayList<TerrainMessage>();
|
||||
|
||||
//The interpolation ratio of terrain
|
||||
public static final int INTERPOLATION_RATIO = ServerTerrainManager.SERVER_TERRAIN_MANAGER_INTERPOLATION_RATIO;
|
||||
|
||||
//caches chunks from server
|
||||
static final int CACHE_SIZE = 50;
|
||||
@ -29,18 +36,17 @@ public class ClientTerrainManager {
|
||||
//used for caching the macro values
|
||||
ClientTerrainCache terrainCache;
|
||||
|
||||
//used for caching loading chunks that are still streaming over the net
|
||||
LoadingChunkCache loadingChunkCache;
|
||||
|
||||
|
||||
//The world data for the client
|
||||
ClientWorldData clientWorldData;
|
||||
|
||||
//The queue of terrain chunk data to be buffered to gpu
|
||||
static List<TerrainChunkGenQueueItem> terrainChunkGenerationQueue = new CopyOnWriteArrayList<TerrainChunkGenQueueItem>();
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public ClientTerrainManager(){
|
||||
terrainCache = new ClientTerrainCache(CACHE_SIZE);
|
||||
loadingChunkCache = new LoadingChunkCache();
|
||||
}
|
||||
|
||||
|
||||
@ -49,89 +55,35 @@ public class ClientTerrainManager {
|
||||
for(TerrainMessage message : messageQueue){
|
||||
messageQueue.remove(message);
|
||||
switch(message.getMessageSubtype()){
|
||||
case MACROVALUE:
|
||||
// terrainCache.addChunkValuesToCache(message.getlocationX(), message.getlocationY(), macroValues, randomizer);
|
||||
if(loadingChunkCache.containsKey(loadingChunkCache.getKey(message.getworldX(), message.getworldY()))){
|
||||
float[][] macroValues = new float[5][5];
|
||||
long[][] randomizer = new long[5][5];
|
||||
//macro values
|
||||
macroValues[0][0] = message.getmacroValue00();
|
||||
macroValues[0][1] = message.getmacroValue01();
|
||||
macroValues[0][2] = message.getmacroValue02();
|
||||
macroValues[0][3] = message.getmacroValue03();
|
||||
macroValues[0][4] = message.getmacroValue04();
|
||||
macroValues[1][0] = message.getmacroValue10();
|
||||
macroValues[1][1] = message.getmacroValue11();
|
||||
macroValues[1][2] = message.getmacroValue12();
|
||||
macroValues[1][3] = message.getmacroValue13();
|
||||
macroValues[1][4] = message.getmacroValue14();
|
||||
macroValues[2][0] = message.getmacroValue20();
|
||||
macroValues[2][1] = message.getmacroValue21();
|
||||
macroValues[2][2] = message.getmacroValue22();
|
||||
macroValues[2][3] = message.getmacroValue23();
|
||||
macroValues[2][4] = message.getmacroValue24();
|
||||
macroValues[3][0] = message.getmacroValue30();
|
||||
macroValues[3][1] = message.getmacroValue31();
|
||||
macroValues[3][2] = message.getmacroValue32();
|
||||
macroValues[3][3] = message.getmacroValue33();
|
||||
macroValues[3][4] = message.getmacroValue34();
|
||||
macroValues[4][0] = message.getmacroValue40();
|
||||
macroValues[4][1] = message.getmacroValue41();
|
||||
macroValues[4][2] = message.getmacroValue42();
|
||||
macroValues[4][3] = message.getmacroValue43();
|
||||
macroValues[4][4] = message.getmacroValue44();
|
||||
//randomizer
|
||||
randomizer[0][0] = message.getrandomizerValue00();
|
||||
randomizer[0][1] = message.getrandomizerValue01();
|
||||
randomizer[0][2] = message.getrandomizerValue02();
|
||||
randomizer[0][3] = message.getrandomizerValue03();
|
||||
randomizer[0][4] = message.getrandomizerValue04();
|
||||
randomizer[1][0] = message.getrandomizerValue10();
|
||||
randomizer[1][1] = message.getrandomizerValue11();
|
||||
randomizer[1][2] = message.getrandomizerValue12();
|
||||
randomizer[1][3] = message.getrandomizerValue13();
|
||||
randomizer[1][4] = message.getrandomizerValue14();
|
||||
randomizer[2][0] = message.getrandomizerValue20();
|
||||
randomizer[2][1] = message.getrandomizerValue21();
|
||||
randomizer[2][2] = message.getrandomizerValue22();
|
||||
randomizer[2][3] = message.getrandomizerValue23();
|
||||
randomizer[2][4] = message.getrandomizerValue24();
|
||||
randomizer[3][0] = message.getrandomizerValue30();
|
||||
randomizer[3][1] = message.getrandomizerValue31();
|
||||
randomizer[3][2] = message.getrandomizerValue32();
|
||||
randomizer[3][3] = message.getrandomizerValue33();
|
||||
randomizer[3][4] = message.getrandomizerValue34();
|
||||
randomizer[4][0] = message.getrandomizerValue40();
|
||||
randomizer[4][1] = message.getrandomizerValue41();
|
||||
randomizer[4][2] = message.getrandomizerValue42();
|
||||
randomizer[4][3] = message.getrandomizerValue43();
|
||||
randomizer[4][4] = message.getrandomizerValue44();
|
||||
LoadingChunk inProgressChunk = loadingChunkCache.fetch(loadingChunkCache.getKey(message.getworldX(), message.getworldY()));
|
||||
inProgressChunk.addMacroValues(macroValues);
|
||||
inProgressChunk.addRandomizer(randomizer);
|
||||
inProgressChunk.incrementMessageCount();
|
||||
} else {
|
||||
bouncedMessages.add(message);
|
||||
case SENDCHUNKDATA: {
|
||||
int[][][] values = new int[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE];
|
||||
float[][][] weights = new float[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE];
|
||||
ByteBuffer buffer = ByteBuffer.wrap(message.getchunkData());
|
||||
FloatBuffer floatBuffer = buffer.asFloatBuffer();
|
||||
for(int x = 0; x < ChunkData.CHUNK_SIZE; x++){
|
||||
for(int y = 0; y < ChunkData.CHUNK_SIZE; y++){
|
||||
for(int z = 0; z < ChunkData.CHUNK_SIZE; z++){
|
||||
weights[x][y][z] = floatBuffer.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CHUNKLOADSTART:
|
||||
if(clientWorldData != null){
|
||||
LoadingChunk newChunk = new LoadingChunk(message.getworldX(),message.getworldY(),(int)message.getvalue(),clientWorldData);
|
||||
loadingChunkCache.addLoadingChunkToCache(newChunk);
|
||||
newChunk.incrementMessageCount();
|
||||
} else {
|
||||
bouncedMessages.add(message);
|
||||
IntBuffer intView = buffer.asIntBuffer();
|
||||
intView.position(floatBuffer.position());
|
||||
for(int x = 0; x < ChunkData.CHUNK_SIZE; x++){
|
||||
for(int y = 0; y < ChunkData.CHUNK_SIZE; y++){
|
||||
for(int z = 0; z < ChunkData.CHUNK_SIZE; z++){
|
||||
values[x][y][z] = intView.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case HEIGHTMAPMODIFICATION:
|
||||
if(loadingChunkCache.containsKey(loadingChunkCache.getKey(message.getworldX(), message.getworldY()))){
|
||||
LoadingChunk inProgressChunk = loadingChunkCache.fetch(loadingChunkCache.getKey(message.getworldX(), message.getworldY()));
|
||||
inProgressChunk.addModification(message.getworldX(), message.getworldZ(), message.getlocationX(), message.getlocationZ(), message.getvalue());
|
||||
inProgressChunk.incrementMessageCount();
|
||||
} else {
|
||||
bouncedMessages.add(message);
|
||||
}
|
||||
break;
|
||||
ChunkData data = new ChunkData();
|
||||
data.setVoxelType(values);
|
||||
data.setVoxelWeight(weights);
|
||||
terrainCache.addChunkDataToCache(
|
||||
message.getworldX(), message.getworldY(), message.getworldZ(),
|
||||
data
|
||||
);
|
||||
} break;
|
||||
default:
|
||||
LoggerInterface.loggerEngine.WARNING("ClientTerrainManager: unhandled network message of type" + message.getMessageSubtype());
|
||||
break;
|
||||
@ -146,88 +98,30 @@ public class ClientTerrainManager {
|
||||
messageQueue.add(message);
|
||||
}
|
||||
|
||||
public boolean containsHeightmapAtDiscretePoint(int x, int y){
|
||||
return terrainCache.containsHeightmapAtChunkPoint(x, y);
|
||||
public boolean containsChunkDataAtWorldPoint(int worldX, int worldY, int worldZ){
|
||||
return terrainCache.containsChunkDataAtWorldPoint(worldX, worldY, worldZ);
|
||||
}
|
||||
|
||||
public boolean containsHeightmapAtRealPoint(double x, double z){
|
||||
public boolean containsChunkDataAtRealPoint(double x, double y, double z){
|
||||
assert clientWorldData != null;
|
||||
return terrainCache.containsHeightmapAtChunkPoint(clientWorldData.convertRealToChunkSpace(x), clientWorldData.convertRealToChunkSpace(z));
|
||||
return terrainCache.containsChunkDataAtWorldPoint(
|
||||
clientWorldData.convertRealToChunkSpace(x),
|
||||
clientWorldData.convertRealToChunkSpace(y),
|
||||
clientWorldData.convertRealToChunkSpace(z)
|
||||
);
|
||||
}
|
||||
|
||||
public float[][] getHeightmapAtPoint(int x, int y){
|
||||
return terrainCache.getHeightmapAtChunkPoint(x, y);
|
||||
public ChunkData getChunkDataAtWorldPoint(int worldX, int worldY, int worldZ){
|
||||
return terrainCache.getSubChunkDataAtPoint(worldX, worldY, worldZ);
|
||||
}
|
||||
|
||||
|
||||
public double getHeightAtPosition(double x, double y){
|
||||
assert clientWorldData != null;
|
||||
//get chunk coordinate space of input x,y
|
||||
int chunkX = (int)Math.floor(x / clientWorldData.getDynamicInterpolationRatio());
|
||||
int chunkY = (int)Math.floor(y / clientWorldData.getDynamicInterpolationRatio());
|
||||
//get local coordinate space of input x,y
|
||||
double localX = x - chunkX * clientWorldData.getDynamicInterpolationRatio();
|
||||
double localY = y - chunkY * clientWorldData.getDynamicInterpolationRatio();
|
||||
//get chunk elevation map
|
||||
float[][] chunkElevationMap = getHeightmapAtPoint(chunkX,chunkY);
|
||||
//floored variants of local values
|
||||
int localXf = (int)Math.floor(localX);
|
||||
int localYf = (int)Math.floor(localY);
|
||||
|
||||
/*
|
||||
Average some inner value.
|
||||
|
||||
01 11
|
||||
0.3 0.4 0.5
|
||||
0.1 0.2 0.3
|
||||
00 10
|
||||
*/
|
||||
//interp elevation from map
|
||||
float elevation00 = chunkElevationMap[(int)localX+0][(int)localY+0];
|
||||
float elevation10 = chunkElevationMap[(int)localX+1][(int)localY+0];
|
||||
float elevation01 = chunkElevationMap[(int)localX+0][(int)localY+1];
|
||||
float elevation11 = chunkElevationMap[(int)localX+1][(int)localY+1];
|
||||
|
||||
double rVal =
|
||||
(1-(localX-localXf))*(1-(localY-localYf)) * elevation00 +
|
||||
( (localX-localXf))*(1-(localY-localYf)) * elevation10 +
|
||||
(1-(localX-localXf))*( (localY-localYf)) * elevation01 +
|
||||
( (localX-localXf))*( (localY-localYf)) * elevation11
|
||||
;
|
||||
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public float[][] getTextureMapAtPoint(int x, int y){
|
||||
assert clientWorldData != null;
|
||||
float[][] rVal = new float[clientWorldData.getDynamicInterpolationRatio()][clientWorldData.getDynamicInterpolationRatio()];
|
||||
rVal[1][1] = 1;
|
||||
rVal[2][1] = 1;
|
||||
rVal[3][1] = 1;
|
||||
rVal[4][1] = 1;
|
||||
rVal[5][1] = 1;
|
||||
rVal[5][2] = 1;
|
||||
rVal[6][1] = 1;
|
||||
rVal[6][2] = 1;
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public void ejectLoadedChunks(){
|
||||
if(clientWorldData != null){
|
||||
List<LoadingChunk> chunksToEject = new LinkedList<LoadingChunk>();
|
||||
for(LoadingChunk chunk : loadingChunkCache.getChunks()){
|
||||
if(chunk.isComplete() && chunk.getClientWorldData() != null){
|
||||
float[][] heightMap = chunk.exportFloats();
|
||||
terrainCache.addFloatsToCache(chunk.getWorldX(), chunk.getWorldY(), heightMap);
|
||||
chunksToEject.add(chunk);
|
||||
}
|
||||
}
|
||||
for(LoadingChunk loadedChunk : chunksToEject){
|
||||
loadingChunkCache.remove(loadedChunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Queues a terrain chunk to be pushed to GPU based on chunk data
|
||||
* @param data The chunk data (triangles, normals, etc)
|
||||
* @return The model path that is promised to eventually reflect the terrain model when it makes it to gpu
|
||||
*/
|
||||
public static String queueTerrainGridGeneration(TerrainChunkData data){
|
||||
String promisedHash = "";
|
||||
UUID newUUID = UUID.randomUUID();
|
||||
@ -237,6 +131,9 @@ public class ClientTerrainManager {
|
||||
return promisedHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes all terrain data in queue to the gpu and registers the resulting models
|
||||
*/
|
||||
public static void generateTerrainChunkGeometry(){
|
||||
for(TerrainChunkGenQueueItem queueItem : terrainChunkGenerationQueue){
|
||||
Model terrainModel = TerrainChunkModelGeneration.generateTerrainModel(queueItem.getData());
|
||||
@ -244,14 +141,5 @@ public class ClientTerrainManager {
|
||||
}
|
||||
terrainChunkGenerationQueue.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the client world data that this terrain manager references
|
||||
* @param clientWorldData The client world data
|
||||
*/
|
||||
public void setClientWorldData(ClientWorldData clientWorldData){
|
||||
this.clientWorldData = clientWorldData;
|
||||
this.terrainCache.setClientWorldData(clientWorldData);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -31,7 +31,7 @@ import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.Scene;
|
||||
import electrosphere.entity.types.hitbox.HitboxManager;
|
||||
import electrosphere.game.collision.CollisionEngine;
|
||||
import electrosphere.game.collision.CommonWorldData;
|
||||
import electrosphere.game.collision.CollisionWorldData;
|
||||
import electrosphere.game.config.UserSettings;
|
||||
import electrosphere.game.server.structure.virtual.StructureManager;
|
||||
import electrosphere.game.server.world.MacroData;
|
||||
@ -64,7 +64,6 @@ import electrosphere.server.ai.AIManager;
|
||||
import electrosphere.server.datacell.EntityDataCellMapper;
|
||||
import electrosphere.server.datacell.GriddedDataCellManager;
|
||||
import electrosphere.server.datacell.RealmManager;
|
||||
import electrosphere.server.datacell.physics.DataCellPhysicsManager;
|
||||
import electrosphere.server.db.DatabaseController;
|
||||
import electrosphere.server.pathfinding.NavMeshManager;
|
||||
import electrosphere.server.simulation.MacroSimulation;
|
||||
@ -157,7 +156,6 @@ public class Globals {
|
||||
public static ServerWorldData serverWorldData;
|
||||
public static RealmManager realmManager;
|
||||
public static EntityDataCellMapper entityDataCellMapper;
|
||||
public static DataCellPhysicsManager dataCellPhysicsManager;
|
||||
|
||||
//
|
||||
//Player manager
|
||||
@ -299,7 +297,7 @@ public class Globals {
|
||||
public static int openInventoriesCount = 0;
|
||||
|
||||
//collision world data
|
||||
public static CommonWorldData commonWorldData;
|
||||
public static CollisionWorldData commonWorldData;
|
||||
|
||||
//structure manager
|
||||
public static StructureManager structureManager;
|
||||
|
||||
@ -36,8 +36,6 @@ public class ArenaLoading {
|
||||
LoadingUtils.initAuthenticationManager();
|
||||
//initialize the server thread (server only)
|
||||
LoadingUtils.initServerThread();
|
||||
//collision engine
|
||||
LoadingUtils.initCommonWorldData(Globals.RUN_SERVER);
|
||||
//init gridded datacell manager
|
||||
LoadingUtils.initGriddedRealm();
|
||||
//initialize the "virtual" objects simulation
|
||||
|
||||
@ -75,10 +75,6 @@ public class ClientLoading {
|
||||
loadingWindow.setVisible(true);
|
||||
//disable menu input
|
||||
Globals.controlHandler.setHandlerState(ControlHandler.ControlsState.NO_INPUT);
|
||||
//collision engine
|
||||
if(!Globals.RUN_SERVER){
|
||||
LoadingUtils.initCommonWorldData(Globals.RUN_SERVER);
|
||||
}
|
||||
//initialize the "real" objects simulation
|
||||
initClientSimulation();
|
||||
//initialize the cell manager (client)
|
||||
@ -212,14 +208,20 @@ public class ClientLoading {
|
||||
}
|
||||
|
||||
static void initDrawCellManager(){
|
||||
while(Globals.clientWorldData == null){
|
||||
try {
|
||||
TimeUnit.MILLISECONDS.sleep(10);
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
}
|
||||
//initialize draw cell manager
|
||||
Globals.drawCellManager = new DrawCellManager(Globals.commonWorldData, Globals.clientTerrainManager, 0, 0);
|
||||
Globals.drawCellManager = new DrawCellManager(Globals.clientTerrainManager, 0, 0, 0);
|
||||
//set our draw cell manager to actually generate drawable chunks
|
||||
Globals.drawCellManager.setGenerateDrawables(true);
|
||||
//Alerts the client simulation that it should start loading terrain
|
||||
Globals.clientSimulation.setLoadingTerrain(true);
|
||||
//wait for all the terrain data to arrive
|
||||
while(Globals.drawCellManager.containsInvalidCell()){
|
||||
while(Globals.drawCellManager.containsUnrequestedCell()){
|
||||
// Globals.drawCellManager.updateInvalidCell();
|
||||
try {
|
||||
TimeUnit.MILLISECONDS.sleep(10);
|
||||
@ -237,12 +239,12 @@ public class ClientLoading {
|
||||
// System.out.println("undrawable");
|
||||
}
|
||||
|
||||
while(Globals.drawCellManager.containsPhysicsNeedingCell()){
|
||||
try {
|
||||
TimeUnit.MILLISECONDS.sleep(10);
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
}
|
||||
// while(Globals.drawCellManager.containsPhysicsNeedingCell()){
|
||||
// try {
|
||||
// TimeUnit.MILLISECONDS.sleep(10);
|
||||
// } catch (InterruptedException ex) {
|
||||
// }
|
||||
// }
|
||||
// System.out.println("Draw Cell Manager ready");
|
||||
}
|
||||
|
||||
|
||||
@ -29,7 +29,7 @@ public class DebugSPWorldLoading {
|
||||
WindowUtils.replaceMainMenuContents(MenuGenerators.createEmptyMainMenu());
|
||||
loadingWindow.setVisible(true);
|
||||
|
||||
Globals.serverTerrainManager = new ServerTerrainManager(2000,50,100,0.0f,0);
|
||||
Globals.serverTerrainManager = new ServerTerrainManager(2000,50,ServerTerrainManager.SERVER_TERRAIN_MANAGER_INTERPOLATION_RATIO,0.0f,0);
|
||||
if(!SaveUtils.getSaves().contains("random_sp_world")){
|
||||
//
|
||||
//the juicy server GENERATION part
|
||||
@ -63,8 +63,6 @@ public class DebugSPWorldLoading {
|
||||
LoadingUtils.initLocalConnection();
|
||||
//initialize the "real" objects simulation
|
||||
LoadingUtils.initMicroSimulation();
|
||||
//collision engine
|
||||
LoadingUtils.initCommonWorldData(Globals.RUN_SERVER);
|
||||
//init game specific stuff (ie different skybox colors)
|
||||
LoadingUtils.initGameGraphicalEntities();
|
||||
//set simulations to ready if they exist
|
||||
|
||||
@ -20,7 +20,7 @@ import electrosphere.entity.ServerEntityUtils;
|
||||
import electrosphere.entity.state.movement.ApplyRotationTree;
|
||||
import electrosphere.entity.types.creature.CreatureTemplate;
|
||||
import electrosphere.entity.types.creature.CreatureUtils;
|
||||
import electrosphere.game.collision.CommonWorldData;
|
||||
import electrosphere.game.collision.CollisionWorldData;
|
||||
import electrosphere.game.data.creature.type.CreatureType;
|
||||
import electrosphere.game.data.creature.type.visualattribute.VisualAttribute;
|
||||
import electrosphere.game.server.town.Town;
|
||||
@ -54,7 +54,7 @@ public class LoadingUtils {
|
||||
Actually initialize the terrain manager
|
||||
*/
|
||||
float randomDampener = 0.0f; //0.25f;
|
||||
Globals.serverTerrainManager = new ServerTerrainManager(2000,50,100,randomDampener,0);
|
||||
Globals.serverTerrainManager = new ServerTerrainManager(2000,50,ServerTerrainManager.SERVER_TERRAIN_MANAGER_INTERPOLATION_RATIO,randomDampener,0);
|
||||
if(Globals.RUN_SERVER){
|
||||
if(Globals.userSettings.gameplayGenerateWorld()){
|
||||
Globals.serverTerrainManager.generate();
|
||||
@ -108,32 +108,32 @@ public class LoadingUtils {
|
||||
Globals.serverWorldData = ServerWorldData.createGameWorld(Globals.serverTerrainManager);
|
||||
}
|
||||
|
||||
static void initCommonWorldData(boolean FLAG_INIT_SERVER){
|
||||
if(Globals.commonWorldData == null){
|
||||
if(FLAG_INIT_SERVER){
|
||||
Globals.commonWorldData = new CommonWorldData(Globals.serverWorldData, Globals.serverTerrainManager);
|
||||
if(Globals.macroSimulation != null){
|
||||
Town startTown = Globals.macroData.getTowns().get(0);
|
||||
Vector2i firstPos = startTown.getPositions().get(0);
|
||||
// double startX = firstPos.x * Globals.serverTerrainManager.getChunkWidth();
|
||||
// double startZ = firstPos.y * Globals.serverTerrainManager.getChunkWidth();
|
||||
double startX = Globals.commonWorldData.convertWorldToReal(firstPos.x);
|
||||
double startZ = Globals.commonWorldData.convertWorldToReal(firstPos.y);
|
||||
Globals.spawnPoint.set((float)startX,(float)Globals.commonWorldData.getElevationAtPoint(new Vector3d(startX,0,startZ)),(float)startZ);
|
||||
}
|
||||
} else {
|
||||
//basically wait for the client to receive the world metadata
|
||||
while(!Globals.clientConnection.getClientProtocol().hasReceivedWorld()){
|
||||
try {
|
||||
TimeUnit.MILLISECONDS.sleep(5);
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
}
|
||||
//then create common world data
|
||||
Globals.commonWorldData = new CommonWorldData(Globals.clientWorldData, Globals.clientTerrainManager);
|
||||
}
|
||||
}
|
||||
}
|
||||
// static void initCommonWorldData(boolean FLAG_INIT_SERVER){
|
||||
// if(Globals.commonWorldData == null){
|
||||
// if(FLAG_INIT_SERVER){
|
||||
// Globals.commonWorldData = new CommonWorldData(Globals.serverWorldData, Globals.serverTerrainManager);
|
||||
// if(Globals.macroSimulation != null){
|
||||
// Town startTown = Globals.macroData.getTowns().get(0);
|
||||
// Vector2i firstPos = startTown.getPositions().get(0);
|
||||
// // double startX = firstPos.x * Globals.serverTerrainManager.getChunkWidth();
|
||||
// // double startZ = firstPos.y * Globals.serverTerrainManager.getChunkWidth();
|
||||
// double startX = Globals.commonWorldData.convertWorldToReal(firstPos.x);
|
||||
// double startZ = Globals.commonWorldData.convertWorldToReal(firstPos.y);
|
||||
// Globals.spawnPoint.set((float)startX,(float)Globals.commonWorldData.getElevationAtPoint(new Vector3d(startX,0,startZ)),(float)startZ);
|
||||
// }
|
||||
// } else {
|
||||
// //basically wait for the client to receive the world metadata
|
||||
// while(!Globals.clientConnection.getClientProtocol().hasReceivedWorld()){
|
||||
// try {
|
||||
// TimeUnit.MILLISECONDS.sleep(5);
|
||||
// } catch (InterruptedException ex) {
|
||||
// }
|
||||
// }
|
||||
// //then create common world data
|
||||
// Globals.commonWorldData = new CommonWorldData(Globals.clientWorldData, Globals.clientTerrainManager);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
@ -15,7 +15,7 @@ public class ServerLoading {
|
||||
// }
|
||||
|
||||
//TODO: Globals.serverTerrainManager = new ServerTerrainManager(2000,50,100,randomDampener,0);
|
||||
Globals.serverTerrainManager = new ServerTerrainManager(2000,50,100,0.0f,0);
|
||||
Globals.serverTerrainManager = new ServerTerrainManager(2000,50,ServerTerrainManager.SERVER_TERRAIN_MANAGER_INTERPOLATION_RATIO,0.0f,0);
|
||||
SaveUtils.loadSave(Globals.currentSaveName);
|
||||
// LoadingUtils.initTerrainDataCellManager();
|
||||
//TODO: set spawnpoint
|
||||
@ -32,8 +32,6 @@ public class ServerLoading {
|
||||
LoadingUtils.initMacroSimulation();
|
||||
//initialize the "real" objects simulation
|
||||
LoadingUtils.initMicroSimulation();
|
||||
//collision engine
|
||||
LoadingUtils.initCommonWorldData(Globals.RUN_SERVER);
|
||||
//init game specific stuff (ie different skybox colors)
|
||||
LoadingUtils.initGameGraphicalEntities();
|
||||
//set simulations to ready if they exist
|
||||
|
||||
@ -103,4 +103,20 @@ public class EntityCreationUtils {
|
||||
Globals.clientScene.registerEntityToTag(entity, EntityTags.DRAWABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* MAkes an already created entity a drawable entity (client only) by backing it with an Actor
|
||||
* @param entity The entity
|
||||
* @param modelPath The model path for the model to back the actor
|
||||
*/
|
||||
public static void makeEntityDrawablePreexistingModel(Entity entity, String modelPath){
|
||||
entity.putData(EntityDataStrings.DATA_STRING_ACTOR, ActorUtils.createActorOfLoadingModel(modelPath));
|
||||
entity.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
||||
entity.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaternionf().identity());
|
||||
entity.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
|
||||
entity.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
||||
entity.putData(EntityDataStrings.DRAW_SOLID_PASS, true);
|
||||
Globals.clientScene.registerEntity(entity);
|
||||
Globals.clientScene.registerEntityToTag(entity, EntityTags.DRAWABLE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -136,6 +136,11 @@ public class EntityUtils {
|
||||
if(Globals.realmManager != null){
|
||||
Realm realm = Globals.realmManager.getEntityRealm(e);
|
||||
if(realm != null){
|
||||
//get data cell
|
||||
ServerDataCell dataCell = realm.getEntityDataCellMapper().getEntityDataCell(e);
|
||||
if(dataCell != null){
|
||||
dataCell.getScene().deregisterEntity(e);
|
||||
}
|
||||
realm.getEntityDataCellMapper().ejectEntity(e);
|
||||
}
|
||||
Globals.realmManager.removeEntity(e);
|
||||
|
||||
@ -44,9 +44,9 @@ public class ServerEntityUtils {
|
||||
public static void repositionEntity(Entity entity, Vector3d position){
|
||||
Realm realm = Globals.realmManager.getEntityRealm(entity);
|
||||
//if server, get current server data cell
|
||||
if(Globals.RUN_SERVER){
|
||||
ServerDataCell oldDataCell = realm.getDataCellManager().getDataCellAtPoint(EntityUtils.getPosition(entity));
|
||||
ServerDataCell newDataCell = realm.getDataCellManager().getDataCellAtPoint(position);
|
||||
ServerDataCell oldDataCell = realm.getDataCellManager().getDataCellAtPoint(EntityUtils.getPosition(entity));
|
||||
ServerDataCell newDataCell = realm.getDataCellManager().getDataCellAtPoint(position);
|
||||
if(oldDataCell != newDataCell){
|
||||
if(newDataCell != null){
|
||||
ServerDataCell.moveEntityFromCellToCell(entity, oldDataCell, newDataCell);
|
||||
ServerBehaviorTreeUtils.updateCell(entity, oldDataCell);
|
||||
@ -58,13 +58,13 @@ public class ServerEntityUtils {
|
||||
ServerBehaviorTreeUtils.updateCell(entity, oldDataCell);
|
||||
}
|
||||
}
|
||||
// //if the server is also a client, update the drawcell manager to know to pull new chunks
|
||||
// if(Globals.RUN_CLIENT){
|
||||
// Globals.drawCellManager.invalidateAllCells();
|
||||
// Globals.drawCellManager.setCellX(Globals.clientPlayerData.getWorldPos().x);
|
||||
// Globals.drawCellManager.setCellY(Globals.clientPlayerData.getWorldPos().z);
|
||||
// }
|
||||
}
|
||||
// //if the server is also a client, update the drawcell manager to know to pull new chunks
|
||||
// if(Globals.RUN_CLIENT){
|
||||
// Globals.drawCellManager.invalidateAllCells();
|
||||
// Globals.drawCellManager.setCellX(Globals.clientPlayerData.getWorldPos().x);
|
||||
// Globals.drawCellManager.setCellY(Globals.clientPlayerData.getWorldPos().z);
|
||||
// }
|
||||
//reposition entity
|
||||
CollisionObjUtils.positionCharacter(entity, Globals.spawnPoint);
|
||||
}
|
||||
|
||||
@ -71,7 +71,7 @@ public class ServerCollidableTree implements BehaviorTree {
|
||||
Vector3d impulseForce = new Vector3d(impulse.getDirection()).mul(impulse.getForce());
|
||||
if(impulse.type.matches(Collidable.TYPE_TERRAIN)){
|
||||
hitTerrain = true;
|
||||
// System.out.println("Impulse force: " + impulseForce);
|
||||
// System.out.println("Impulse force: " + impulseForce);
|
||||
// System.out.println("Position: " + position);
|
||||
}
|
||||
if(impulse.type.matches(Collidable.TYPE_ITEM)){
|
||||
|
||||
@ -12,11 +12,8 @@ import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.EntityUtils;
|
||||
import electrosphere.entity.state.BehaviorTree;
|
||||
import electrosphere.entity.state.collidable.ClientCollidableTree;
|
||||
import electrosphere.entity.state.collidable.Impulse;
|
||||
import electrosphere.entity.state.collidable.ServerCollidableTree;
|
||||
import electrosphere.entity.state.movement.FallTree;
|
||||
import electrosphere.entity.state.movement.JumpTree;
|
||||
import electrosphere.entity.state.movement.ServerFallTree;
|
||||
import electrosphere.entity.state.movement.ServerJumpTree;
|
||||
import electrosphere.game.collision.collidable.Collidable;
|
||||
@ -212,6 +209,7 @@ public class ServerGravityTree implements BehaviorTree {
|
||||
boolean rVal = false;
|
||||
for(Impulse impulse : collidable.getImpulses()){
|
||||
if(impulse.getType().equals(Collidable.TYPE_TERRAIN)){
|
||||
System.out.println(rVal);
|
||||
rVal = true;
|
||||
break;
|
||||
} else if(
|
||||
|
||||
@ -496,6 +496,7 @@ public class CreatureUtils {
|
||||
*/
|
||||
public static Entity serverSpawnBasicCreature(Realm realm, Vector3d position, String type, CreatureTemplate template){
|
||||
CreatureType rawType = Globals.gameConfigCurrent.getCreatureTypeLoader().getCreature(type);
|
||||
System.out.println("Creature");
|
||||
Entity rVal = EntityCreationUtils.createServerEntity(realm, position);
|
||||
EntityCreationUtils.makeEntityPoseable(rVal, rawType.getModelPath());
|
||||
|
||||
|
||||
@ -285,46 +285,49 @@ public class HitboxUtils {
|
||||
Entity generatorParent = (Entity)generatorHitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
|
||||
|
||||
Realm generatorRealm = Globals.realmManager.getEntityRealm(generatorParent);
|
||||
HitboxManager realmHitboxManager = generatorRealm.getHitboxManager();
|
||||
if(generatorRealm != null){
|
||||
HitboxManager realmHitboxManager = generatorRealm.getHitboxManager();
|
||||
|
||||
for(Entity receiverHitbox : realmHitboxManager.getAllHitboxes()){
|
||||
|
||||
Entity receiverParent = (Entity)receiverHitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
|
||||
|
||||
HitboxData generatorData = getHitboxData(generatorHitbox);
|
||||
HitboxData receiverData = getHitboxData(receiverHitbox);
|
||||
|
||||
//check projectile filters
|
||||
List<Entity> generatorFilter = generatorData.getEntityFilter();
|
||||
if(generatorFilter != null && generatorFilter.contains(receiverParent)){
|
||||
continue;
|
||||
}
|
||||
|
||||
List<Entity> receiverFilter = receiverData.getEntityFilter();
|
||||
if(receiverFilter != null && receiverFilter.contains(generatorParent)){
|
||||
continue;
|
||||
}
|
||||
|
||||
//if there is a collision
|
||||
//and the collision isn't against itself
|
||||
//and both hitboxes are active
|
||||
if(
|
||||
receiverParent != generatorParent &&
|
||||
generatorRealm.getCollisionEngine().collisionSphereCheck(generatorHitbox, generatorData, receiverHitbox, receiverData) &&
|
||||
generatorData.isActive() &&
|
||||
receiverData.isActive()){
|
||||
//if two spheres collide, grab their hitbox types (eg hurt, hit, fire, etc)
|
||||
String generatorType = generatorData.getType();
|
||||
String receiverType = receiverData.getType();
|
||||
for(Entity receiverHitbox : realmHitboxManager.getAllHitboxes()){
|
||||
|
||||
if(generatorType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT) && receiverType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT)){
|
||||
serverDamageHitboxColision(generatorHitbox, receiverHitbox);
|
||||
Entity receiverParent = (Entity)receiverHitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
|
||||
|
||||
HitboxData generatorData = getHitboxData(generatorHitbox);
|
||||
HitboxData receiverData = getHitboxData(receiverHitbox);
|
||||
|
||||
//check projectile filters
|
||||
List<Entity> generatorFilter = generatorData.getEntityFilter();
|
||||
if(generatorFilter != null && generatorFilter.contains(receiverParent)){
|
||||
continue;
|
||||
}
|
||||
|
||||
List<Entity> receiverFilter = receiverData.getEntityFilter();
|
||||
if(receiverFilter != null && receiverFilter.contains(generatorParent)){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(generatorType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT) && receiverType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT)){
|
||||
serverDamageHitboxColision(receiverHitbox, generatorHitbox);
|
||||
//if there is a collision
|
||||
//and the collision isn't against itself
|
||||
//and both hitboxes are active
|
||||
if(
|
||||
receiverParent != generatorParent &&
|
||||
generatorRealm.getCollisionEngine().collisionSphereCheck(generatorHitbox, generatorData, receiverHitbox, receiverData) &&
|
||||
generatorData.isActive() &&
|
||||
receiverData.isActive()){
|
||||
//if two spheres collide, grab their hitbox types (eg hurt, hit, fire, etc)
|
||||
String generatorType = generatorData.getType();
|
||||
String receiverType = receiverData.getType();
|
||||
|
||||
if(generatorType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT) && receiverType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT)){
|
||||
serverDamageHitboxColision(generatorHitbox, receiverHitbox);
|
||||
}
|
||||
|
||||
if(generatorType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT) && receiverType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT)){
|
||||
serverDamageHitboxColision(receiverHitbox, generatorHitbox);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,171 +1,68 @@
|
||||
package electrosphere.entity.types.terrain;
|
||||
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import electrosphere.client.terrain.manager.ClientTerrainManager;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.EntityCreationUtils;
|
||||
import electrosphere.entity.EntityDataStrings;
|
||||
import electrosphere.entity.EntityUtils;
|
||||
import electrosphere.entity.ServerEntityUtils;
|
||||
import electrosphere.game.collision.PhysicsUtils;
|
||||
import electrosphere.renderer.Model;
|
||||
import electrosphere.renderer.meshgen.TerrainChunkModelGeneration;
|
||||
import electrosphere.server.datacell.Realm;
|
||||
|
||||
/**
|
||||
* Utilities for creating terrain chunk entities
|
||||
*/
|
||||
public class TerrainChunk {
|
||||
|
||||
|
||||
public static Entity createTerrainChunkEntity(){
|
||||
|
||||
float[][][] terrainGrid = new float[][][]{
|
||||
//plane 1
|
||||
{
|
||||
//row 1
|
||||
{1.0f,1.0f,-1.0f,-1.0f,-1.0f,},
|
||||
//row 2
|
||||
{-1.0f,1.0f,-1.0f,-1.0f,-1.0f,},
|
||||
//row 3
|
||||
{-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,},
|
||||
//row 4
|
||||
{-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,},
|
||||
//row 5
|
||||
{-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,},
|
||||
},
|
||||
//plane 2
|
||||
{
|
||||
//row 1
|
||||
{-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,},
|
||||
//row 2
|
||||
{-1.0f,0.3f,0.6f,0.3f,-1.0f,},
|
||||
//row 3
|
||||
{-1.0f,0.6f,1.0f,0.6f,-1.0f,},
|
||||
//row 4
|
||||
{-1.0f,0.3f,0.6f,0.3f,-1.0f,},
|
||||
//row 5
|
||||
{-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,},
|
||||
},
|
||||
//plane 3
|
||||
{
|
||||
//row 1
|
||||
{-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,},
|
||||
//row 2
|
||||
{-1.0f,0.7f,1.0f,0.7f,-1.0f,},
|
||||
//row 3
|
||||
{-1.0f,1.0f,1.0f,1.0f,-1.0f,},
|
||||
//row 4
|
||||
{-1.0f,0.7f,1.0f,0.7f,-1.0f,},
|
||||
//row 5
|
||||
{-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,},
|
||||
},
|
||||
//plane 4
|
||||
{
|
||||
//row 1
|
||||
{-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,},
|
||||
//row 2
|
||||
{-1.0f,0.3f,0.6f,0.3f,-1.0f,},
|
||||
//row 3
|
||||
{-1.0f,0.6f,1.0f,0.6f,-1.0f,},
|
||||
//row 4
|
||||
{-1.0f,0.3f,0.6f,0.3f,-1.0f,},
|
||||
//row 5
|
||||
{-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,},
|
||||
},
|
||||
//plane 5
|
||||
{
|
||||
//row 1
|
||||
{-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,},
|
||||
//row 2
|
||||
{-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,},
|
||||
//row 3
|
||||
{-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,},
|
||||
//row 4
|
||||
{-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,},
|
||||
//row 5
|
||||
{-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,},
|
||||
},
|
||||
};
|
||||
|
||||
int[][][] textureGrid = new int[][][]{
|
||||
//plane 1
|
||||
{
|
||||
//row 1
|
||||
{0, 0, 0, 0, 0},
|
||||
//row 2
|
||||
{0, 0, 0, 0, 0},
|
||||
//row 3
|
||||
{0, 0, 0, 0, 0},
|
||||
//row 4
|
||||
{0, 0, 0, 0, 0},
|
||||
//row 5
|
||||
{0, 0, 0, 0, 0},
|
||||
},
|
||||
//plane 2
|
||||
{
|
||||
//row 1
|
||||
{0, 0, 0, 0, 0},
|
||||
//row 2
|
||||
{0, 0, 0, 0, 0},
|
||||
//row 3
|
||||
{0, 0, 0, 0, 0},
|
||||
//row 4
|
||||
{0, 0, 0, 0, 0},
|
||||
//row 5
|
||||
{0, 0, 0, 0, 0},
|
||||
},
|
||||
//plane 3
|
||||
{
|
||||
//row 1
|
||||
{0, 0, 0, 0, 0},
|
||||
//row 2
|
||||
{0, 0, 0, 0, 0},
|
||||
//row 3
|
||||
{0, 0, 0, 0, 0},
|
||||
//row 4
|
||||
{0, 0, 0, 0, 0},
|
||||
//row 5
|
||||
{0, 0, 0, 0, 0},
|
||||
},
|
||||
//plane 4
|
||||
{
|
||||
//row 1
|
||||
{0, 0, 0, 0, 0},
|
||||
//row 2
|
||||
{0, 0, 0, 0, 0},
|
||||
//row 3
|
||||
{0, 0, 0, 0, 0},
|
||||
//row 4
|
||||
{0, 0, 0, 0, 0},
|
||||
//row 5
|
||||
{0, 0, 0, 0, 0},
|
||||
},
|
||||
//plane 5
|
||||
{
|
||||
//row 1
|
||||
{0, 0, 0, 0, 0},
|
||||
//row 2
|
||||
{0, 0, 0, 0, 0},
|
||||
//row 3
|
||||
{0, 0, 0, 0, 0},
|
||||
//row 4
|
||||
{0, 0, 0, 0, 0},
|
||||
//row 5
|
||||
{0, 0, 0, 0, 0},
|
||||
},
|
||||
};
|
||||
/**
|
||||
* Creates a client terrain chunk based on weights and values provided
|
||||
* @param weights The terrain weights
|
||||
* @param values The values (block types)
|
||||
* @return The terrain chunk entity
|
||||
*/
|
||||
public static Entity clientCreateTerrainChunkEntity(float[][][] weights, int[][][] values){
|
||||
|
||||
TerrainChunkData data = TerrainChunkModelGeneration.generateTerrainChunkData(terrainGrid, textureGrid);
|
||||
TerrainChunkData data = TerrainChunkModelGeneration.generateTerrainChunkData(weights, values);
|
||||
String modelPath = ClientTerrainManager.queueTerrainGridGeneration(data);
|
||||
|
||||
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
|
||||
EntityCreationUtils.makeEntityDrawable(rVal, modelPath);
|
||||
// Entity rVal = EntityUtils.spawnDrawableEntityWithPreexistingModel(modelPath);
|
||||
PhysicsUtils.clientAttachTerrainChunkRigidBody(rVal, data);
|
||||
EntityCreationUtils.makeEntityDrawablePreexistingModel(rVal, modelPath);
|
||||
if(data.vertices.size() > 0){
|
||||
PhysicsUtils.clientAttachTerrainChunkRigidBody(rVal, data);
|
||||
}
|
||||
|
||||
rVal.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
|
||||
rVal.putData(EntityDataStrings.DRAW_CAST_SHADOW, true);
|
||||
|
||||
ServerEntityUtils.repositionEntity(rVal, new Vector3d(1,-1,1));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a terrain chunk entity on the server
|
||||
* @param realm The realm
|
||||
* @param position The position of the chunk
|
||||
* @param weights The weights for the terrain chunk
|
||||
* @param values The values of each voxel in the chunk
|
||||
* @return The terrain entity
|
||||
*/
|
||||
public static Entity serverCreateTerrainChunkEntity(Realm realm, Vector3d position, float[][][] weights, int[][][] values){
|
||||
|
||||
TerrainChunkData data = TerrainChunkModelGeneration.generateTerrainChunkData(weights, values);
|
||||
|
||||
Entity rVal = EntityCreationUtils.createServerEntity(realm, position);
|
||||
if(data.vertices.size() > 0){
|
||||
PhysicsUtils.serverAttachTerrainChunkRigidBody(rVal, data);
|
||||
rVal.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
|
||||
ServerEntityUtils.initiallyPositionEntity(realm, rVal, position);
|
||||
// physicsObject = PhysicsUtils.attachTerrainRigidBody(physicsEntity,heightmap,true);
|
||||
// Realm realm = Globals.realmManager.getEntityRealm(physicsEntity);
|
||||
// realm.getCollisionEngine().registerPhysicsEntity(physicsEntity);
|
||||
|
||||
}
|
||||
|
||||
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package electrosphere.game.collision;
|
||||
|
||||
import electrosphere.collision.dispatch.CollisionWorld.ClosestConvexResultCallback;
|
||||
import electrosphere.collision.dispatch.CollisionWorld.ConvexResultCallback;
|
||||
import electrosphere.collision.dispatch.CollisionWorld.LocalConvexResult;
|
||||
import electrosphere.collision.broadphase.BroadphaseInterface;
|
||||
import electrosphere.collision.broadphase.BroadphasePair;
|
||||
@ -38,10 +39,13 @@ import org.joml.Vector3f;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
* TODO: https://stackoverflow.com/questions/32445679/3d-java-collision-detection-with-jbullet
|
||||
*/
|
||||
public class CollisionEngine {
|
||||
|
||||
//world data that the collision engine leverages for position correction and the like
|
||||
CollisionWorldData collisionWorldData;
|
||||
|
||||
DiscreteDynamicsWorld world;
|
||||
SequentialImpulseConstraintSolver solver;
|
||||
BroadphaseInterface broadphase;
|
||||
@ -211,16 +215,16 @@ public class CollisionEngine {
|
||||
* @param positionToCheck the position that it wants to move to
|
||||
* @return true if it can occupy that position, false otherwise
|
||||
*/
|
||||
public boolean checkCanOccupyPosition(CommonWorldData w, Entity e, Vector3d positionToCheck){
|
||||
public boolean checkCanOccupyPosition(CollisionWorldData w, Entity e, Vector3d positionToCheck){
|
||||
boolean rVal = true;
|
||||
//
|
||||
// check world bounds
|
||||
//
|
||||
if(
|
||||
positionToCheck.x < w.getWorldBoundMin().x ||
|
||||
positionToCheck.z < w.getWorldBoundMin().z ||
|
||||
positionToCheck.x > w.getWorldBoundMax().x ||
|
||||
positionToCheck.z > w.getWorldBoundMax().z
|
||||
positionToCheck.x < collisionWorldData.getWorldBoundMin().x ||
|
||||
positionToCheck.z < collisionWorldData.getWorldBoundMin().z ||
|
||||
positionToCheck.x > collisionWorldData.getWorldBoundMax().x ||
|
||||
positionToCheck.z > collisionWorldData.getWorldBoundMax().z
|
||||
){
|
||||
return false;
|
||||
}
|
||||
@ -246,7 +250,7 @@ public class CollisionEngine {
|
||||
* @return the position the engine recommends it move to instead (this is
|
||||
* guaranteed to be a valid position)
|
||||
*/
|
||||
public Vector3d suggestMovementPosition(CommonWorldData w, Entity e, Vector3d positionToCheck){
|
||||
public Vector3d suggestMovementPosition(CollisionWorldData w, Entity e, Vector3d positionToCheck){
|
||||
Vector3d suggestedPosition = new Vector3d(positionToCheck);
|
||||
//
|
||||
// adjust for minimum height (Terrain)
|
||||
@ -258,17 +262,17 @@ public class CollisionEngine {
|
||||
//
|
||||
// adjust for world bounds
|
||||
//
|
||||
if(suggestedPosition.x < w.getWorldBoundMin().x){
|
||||
suggestedPosition.x = w.getWorldBoundMin().x;
|
||||
if(suggestedPosition.x < collisionWorldData.getWorldBoundMin().x){
|
||||
suggestedPosition.x = collisionWorldData.getWorldBoundMin().x;
|
||||
}
|
||||
if(suggestedPosition.z < w.getWorldBoundMin().z){
|
||||
suggestedPosition.z = w.getWorldBoundMin().z;
|
||||
if(suggestedPosition.z < collisionWorldData.getWorldBoundMin().z){
|
||||
suggestedPosition.z = collisionWorldData.getWorldBoundMin().z;
|
||||
}
|
||||
if(suggestedPosition.x > w.getWorldBoundMax().x){
|
||||
suggestedPosition.x = w.getWorldBoundMax().x;
|
||||
if(suggestedPosition.x > collisionWorldData.getWorldBoundMax().x){
|
||||
suggestedPosition.x = collisionWorldData.getWorldBoundMax().x;
|
||||
}
|
||||
if(suggestedPosition.z > w.getWorldBoundMax().z){
|
||||
suggestedPosition.z = w.getWorldBoundMax().z;
|
||||
if(suggestedPosition.z > collisionWorldData.getWorldBoundMax().z){
|
||||
suggestedPosition.z = collisionWorldData.getWorldBoundMax().z;
|
||||
}
|
||||
return suggestedPosition;
|
||||
}
|
||||
@ -282,6 +286,13 @@ public class CollisionEngine {
|
||||
return collisionEntities;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the collision world data
|
||||
* @param collisionWorldData The collision world data
|
||||
*/
|
||||
public void setCollisionWorldData(CollisionWorldData collisionWorldData){
|
||||
this.collisionWorldData = collisionWorldData;
|
||||
}
|
||||
|
||||
|
||||
public boolean collisionSphereCheck(Entity hitbox1, HitboxData hitbox1data, Entity hitbox2, HitboxData hitbox2data){
|
||||
@ -384,17 +395,6 @@ public class CollisionEngine {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// private static class SpecificConvexResultCallback extends ConvexResultCallback {
|
||||
//
|
||||
// @Override
|
||||
// public float addSingleResult(LocalConvexResult convexResult, boolean bln) {
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
private static class ClosestConvexResultCallbackImpl extends ClosestConvexResultCallback {
|
||||
|
||||
CollisionObject me;
|
||||
|
||||
@ -8,7 +8,7 @@ import electrosphere.server.terrain.manager.ServerTerrainManager;
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
public class CommonWorldData {
|
||||
public class CollisionWorldData {
|
||||
|
||||
|
||||
|
||||
@ -20,17 +20,12 @@ public class CommonWorldData {
|
||||
ServerWorldData serverWorldData;
|
||||
ServerTerrainManager serverTerrainManager;
|
||||
|
||||
|
||||
|
||||
public CommonWorldData(ClientWorldData clientWorldData, ClientTerrainManager clientTerrainManager){
|
||||
this.clientWorldData = clientWorldData;
|
||||
this.clientTerrainManager = clientTerrainManager;
|
||||
}
|
||||
|
||||
|
||||
public CommonWorldData(ServerWorldData serverWorldData, ServerTerrainManager serverTerrainManager){
|
||||
public CollisionWorldData(ServerWorldData serverWorldData){
|
||||
this.serverWorldData = serverWorldData;
|
||||
this.serverTerrainManager = serverTerrainManager;
|
||||
}
|
||||
|
||||
public CollisionWorldData(ClientWorldData clientWorldData){
|
||||
this.clientWorldData = clientWorldData;
|
||||
}
|
||||
|
||||
|
||||
@ -44,17 +39,17 @@ public class CommonWorldData {
|
||||
* @param position
|
||||
* @return
|
||||
*/
|
||||
public double getElevationAtPoint(Vector3d position){
|
||||
if(clientWorldData != null){
|
||||
if(clientTerrainManager.containsHeightmapAtRealPoint(position.x, position.z)){
|
||||
return clientTerrainManager.getHeightAtPosition(position.x, position.z);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return serverTerrainManager.getHeightAtPosition(position.x, position.z);
|
||||
}
|
||||
}
|
||||
// public double getElevationAtPoint(Vector3d position){
|
||||
// if(clientWorldData != null){
|
||||
// if(clientTerrainManager.containsHeightmapAtRealPoint(position.x, position.z)){
|
||||
// return clientTerrainManager.getHeightAtPosition(position.x, position.z);
|
||||
// } else {
|
||||
// return 0;
|
||||
// }
|
||||
// } else {
|
||||
// return serverTerrainManager.getHeightAtPosition(position.x, position.z);
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
public Vector3f getWorldBoundMin(){
|
||||
@ -15,6 +15,7 @@ import electrosphere.server.datacell.Realm;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.EntityDataStrings;
|
||||
import electrosphere.entity.EntityUtils;
|
||||
import electrosphere.entity.ServerEntityUtils;
|
||||
import electrosphere.entity.types.terrain.TerrainChunkData;
|
||||
import electrosphere.game.collision.collidable.Collidable;
|
||||
|
||||
@ -380,7 +381,6 @@ public class PhysicsUtils {
|
||||
|
||||
Realm terrainRealm = Globals.realmManager.getEntityRealm(terrain);
|
||||
terrainRealm.getCollisionEngine().registerCollisionObject(terrainRigidBody, new Collidable(terrain,Collidable.TYPE_TERRAIN));
|
||||
|
||||
// terrainRigidBody.getAabb(aabbMin, aabbMax);
|
||||
//
|
||||
// System.out.println("aabbMin: " + aabbMin + " aabbMax: " + aabbMax);
|
||||
@ -598,6 +598,18 @@ public class PhysicsUtils {
|
||||
|
||||
return transform;
|
||||
}
|
||||
|
||||
public static electrosphere.linearmath.Transform jomlVecToTransform(Vector3d vector){
|
||||
electrosphere.linearmath.Transform transform = new electrosphere.linearmath.Transform();
|
||||
|
||||
javax.vecmath.Matrix4f transformMatrix = new javax.vecmath.Matrix4f();
|
||||
transformMatrix.setIdentity();
|
||||
|
||||
transformMatrix.setTranslation(new javax.vecmath.Vector3f((float)vector.x, (float)vector.y, (float)vector.z));
|
||||
transform.set(transformMatrix);
|
||||
|
||||
return transform;
|
||||
}
|
||||
|
||||
public static void setRigidBodyTransform(Vector3f position, Quaternionf rotation, CollisionObject body){
|
||||
electrosphere.linearmath.Transform transform = new electrosphere.linearmath.Transform();
|
||||
|
||||
@ -20,28 +20,28 @@ import org.joml.Vector3f;
|
||||
public class VirtualStructureUtils {
|
||||
|
||||
|
||||
public static Structure placeStructureAtPoint(float posX, float posY, String type){
|
||||
public static Structure placeStructureAtPoint(float posX, float posY, float posZ, String type){
|
||||
int worldX = Globals.serverWorldData.convertRealToChunkSpace(posX);
|
||||
int worldY = Globals.serverWorldData.convertRealToChunkSpace(posY);
|
||||
Structure rVal = new Structure(worldX,worldY,posX,posY,type);
|
||||
Globals.macroData.addStructure(rVal);
|
||||
|
||||
double centerHeight = Globals.serverTerrainManager.getHeightAtPosition(posX, posY);
|
||||
StructureType currentTypeObject = Globals.gameConfigCurrent.getStructureTypeMap().getType(type);
|
||||
float radius = currentTypeObject.getRadius();
|
||||
for(int x = -(int)radius; x < radius; x++){
|
||||
for(int y = -(int)radius; y < radius; y++){
|
||||
int newWorldX = Globals.serverWorldData.convertRealToChunkSpace(posX + x);
|
||||
int newWorldY = Globals.serverWorldData.convertRealToChunkSpace(posY + y);
|
||||
double newLocationX = Globals.serverWorldData.getRelativeLocation(posX + x, newWorldX);
|
||||
double newLocationY = Globals.serverWorldData.getRelativeLocation(posY + y, newWorldY);
|
||||
// System.out.println("Set height: " + centerHeight);
|
||||
// System.out.println("Deform in chunk: " + newWorldX + "," + newWorldY);
|
||||
Globals.serverTerrainManager.deformTerrainAtLocationToValue(newWorldX, newWorldY, (int)(newLocationX), (int)(newLocationY), (float)centerHeight);
|
||||
}
|
||||
}
|
||||
// double centerHeight = Globals.serverTerrainManager.getHeightAtPosition(posX, posY, posZ);
|
||||
// StructureType currentTypeObject = Globals.gameConfigCurrent.getStructureTypeMap().getType(type);
|
||||
// float radius = currentTypeObject.getRadius();
|
||||
// for(int x = -(int)radius; x < radius; x++){
|
||||
// for(int y = -(int)radius; y < radius; y++){
|
||||
// int newWorldX = Globals.serverWorldData.convertRealToChunkSpace(posX + x);
|
||||
// int newWorldY = Globals.serverWorldData.convertRealToChunkSpace(posY + y);
|
||||
// double newLocationX = Globals.serverWorldData.getRelativeLocation(posX + x, newWorldX);
|
||||
// double newLocationY = Globals.serverWorldData.getRelativeLocation(posY + y, newWorldY);
|
||||
// // System.out.println("Set height: " + centerHeight);
|
||||
// // System.out.println("Deform in chunk: " + newWorldX + "," + newWorldY);
|
||||
// Globals.serverTerrainManager.deformTerrainAtLocationToValue(newWorldX, newWorldY, (int)(newLocationX), (int)(newLocationY), (float)centerHeight);
|
||||
// }
|
||||
// }
|
||||
Realm realm = Globals.realmManager.getRealms().iterator().next();
|
||||
StructureUtils.serverSpawnBasicStructure(type, realm, new Vector3d(posX,(float)centerHeight + 2.4f,posY), new Quaternionf());
|
||||
// StructureUtils.serverSpawnBasicStructure(type, realm, new Vector3d(posX,(float)centerHeight + 2.4f,posY), new Quaternionf());
|
||||
return rVal;
|
||||
}
|
||||
|
||||
|
||||
@ -36,29 +36,29 @@ public class Town {
|
||||
public static Vector2i findValidTownLocation(){
|
||||
for(int x = 0; x < Globals.serverTerrainManager.getWorldDiscreteSize(); x++){
|
||||
for(int y = 0; y < Globals.serverTerrainManager.getWorldDiscreteSize(); y++){
|
||||
ServerTerrainChunk chunk = Globals.serverTerrainManager.getChunk(x, y);
|
||||
float[][] macroValues = chunk.getMacroValues();
|
||||
float sum = 0;
|
||||
int count = 0;
|
||||
for(int i = 0; i < 5; i++){
|
||||
for(int j = 0; j < 5; j++){
|
||||
sum = sum + macroValues[i][j];
|
||||
count++;
|
||||
}
|
||||
}
|
||||
float average = sum / (float)count;
|
||||
if(average > 1000){
|
||||
float diffSum = 0;
|
||||
for(int i = 0; i < 5; i++){
|
||||
for(int j = 0; j < 5; j++){
|
||||
diffSum = diffSum + (float)Math.abs(average - macroValues[i][j]);
|
||||
}
|
||||
}
|
||||
float averageDiff = diffSum / (float)count;
|
||||
if(averageDiff < avgDiffThreshold){
|
||||
return new Vector2i(x,y);
|
||||
}
|
||||
}
|
||||
// ServerTerrainChunk chunk = Globals.serverTerrainManager.getChunk(x, y);
|
||||
// float[][] macroValues = chunk.getMacroValues();
|
||||
// float sum = 0;
|
||||
// int count = 0;
|
||||
// for(int i = 0; i < 5; i++){
|
||||
// for(int j = 0; j < 5; j++){
|
||||
// sum = sum + macroValues[i][j];
|
||||
// count++;
|
||||
// }
|
||||
// }
|
||||
// float average = sum / (float)count;
|
||||
// if(average > 1000){
|
||||
// float diffSum = 0;
|
||||
// for(int i = 0; i < 5; i++){
|
||||
// for(int j = 0; j < 5; j++){
|
||||
// diffSum = diffSum + (float)Math.abs(average - macroValues[i][j]);
|
||||
// }
|
||||
// }
|
||||
// float averageDiff = diffSum / (float)count;
|
||||
// if(averageDiff < avgDiffThreshold){
|
||||
// return new Vector2i(x,y);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
@ -21,7 +21,7 @@ public class LoggerInterface {
|
||||
|
||||
public static void initLoggers(){
|
||||
loggerStartup = new Logger(LogLevel.WARNING);
|
||||
loggerNetworking = new Logger(LogLevel.DEBUG);
|
||||
loggerNetworking = new Logger(LogLevel.WARNING);
|
||||
loggerFileIO = new Logger(LogLevel.WARNING);
|
||||
loggerGameLogic = new Logger(LogLevel.WARNING);
|
||||
loggerRenderer = new Logger(LogLevel.WARNING);
|
||||
|
||||
@ -5,7 +5,11 @@ import javax.vecmath.Vector3d;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import electrosphere.client.scene.ClientWorldData;
|
||||
import electrosphere.client.terrain.cache.ChunkData;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.types.terrain.TerrainChunk;
|
||||
import electrosphere.entity.types.terrain.TerrainChunkData;
|
||||
import electrosphere.game.collision.CollisionWorldData;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.net.parser.net.message.TerrainMessage;
|
||||
|
||||
@ -17,24 +21,18 @@ public class TerrainProtocol {
|
||||
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(),0,message.getworldMaxY()),
|
||||
message.getdynamicInterpolationRatio(),
|
||||
new Vector3f(message.getworldMaxX(),3,message.getworldMaxY()),
|
||||
ChunkData.CHUNK_SIZE,
|
||||
message.getrandomDampener(),
|
||||
message.getworldSizeDiscrete()
|
||||
);
|
||||
Globals.clientTerrainManager.setClientWorldData(Globals.clientWorldData);
|
||||
Globals.clientSceneWrapper.getCollisionEngine().setCollisionWorldData(new CollisionWorldData(Globals.clientWorldData));
|
||||
Globals.clientConnection.getClientProtocol().setHasReceivedWorld(true);
|
||||
break;
|
||||
case MACROVALUE:
|
||||
Globals.clientTerrainManager.attachTerrainMessage(message);
|
||||
break;
|
||||
case SPAWNPOSITION:
|
||||
Globals.spawnPoint.set(message.getrealLocationX(),0.25,message.getrealLocationZ());
|
||||
break;
|
||||
case CHUNKLOADSTART:
|
||||
Globals.clientTerrainManager.attachTerrainMessage(message);
|
||||
break;
|
||||
case HEIGHTMAPMODIFICATION:
|
||||
case SENDCHUNKDATA:
|
||||
Globals.clientTerrainManager.attachTerrainMessage(message);
|
||||
break;
|
||||
default:
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package electrosphere.net.parser.net.message;
|
||||
|
||||
import electrosphere.net.parser.util.ByteStreamUtils;
|
||||
import electrosphere.net.parser.net.raw.CircularByteBuffer;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
@ -42,29 +43,28 @@ public class AuthMessage extends NetworkMessage {
|
||||
this.pass = pass;
|
||||
}
|
||||
|
||||
static void stripPacketHeader(List<Byte> byteStream){
|
||||
byteStream.remove(0);
|
||||
byteStream.remove(0);
|
||||
static void stripPacketHeader(CircularByteBuffer byteBuffer){
|
||||
byteBuffer.read(2);
|
||||
}
|
||||
|
||||
public static boolean canParseMessage(List<Byte> byteStream, byte secondByte){
|
||||
public static boolean canParseMessage(CircularByteBuffer byteBuffer, byte secondByte){
|
||||
switch(secondByte){
|
||||
case TypeBytes.AUTH_MESSAGE_TYPE_AUTHREQUEST:
|
||||
if(byteStream.size() >= TypeBytes.AUTH_MESSAGE_TYPE_AUTHREQUEST_SIZE){
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.AUTH_MESSAGE_TYPE_AUTHREQUEST_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case TypeBytes.AUTH_MESSAGE_TYPE_AUTHDETAILS:
|
||||
return AuthMessage.canParseAuthDetailsMessage(byteStream);
|
||||
return AuthMessage.canParseAuthDetailsMessage(byteBuffer);
|
||||
case TypeBytes.AUTH_MESSAGE_TYPE_AUTHSUCCESS:
|
||||
if(byteStream.size() >= TypeBytes.AUTH_MESSAGE_TYPE_AUTHSUCCESS_SIZE){
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.AUTH_MESSAGE_TYPE_AUTHSUCCESS_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case TypeBytes.AUTH_MESSAGE_TYPE_AUTHFAILURE:
|
||||
if(byteStream.size() >= TypeBytes.AUTH_MESSAGE_TYPE_AUTHFAILURE_SIZE){
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.AUTH_MESSAGE_TYPE_AUTHFAILURE_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@ -73,9 +73,9 @@ public class AuthMessage extends NetworkMessage {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static AuthMessage parseAuthRequestMessage(List<Byte> byteStream){
|
||||
public static AuthMessage parseAuthRequestMessage(CircularByteBuffer byteBuffer){
|
||||
AuthMessage rVal = new AuthMessage(AuthMessageType.AUTHREQUEST);
|
||||
stripPacketHeader(byteStream);
|
||||
stripPacketHeader(byteBuffer);
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -85,17 +85,17 @@ public class AuthMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static boolean canParseAuthDetailsMessage(List<Byte> byteStream){
|
||||
int currentStreamLength = byteStream.size();
|
||||
public static boolean canParseAuthDetailsMessage(CircularByteBuffer byteBuffer){
|
||||
int currentStreamLength = byteBuffer.getRemaining();
|
||||
List<Byte> temporaryByteQueue = new LinkedList();
|
||||
int userSize = 0;
|
||||
if(currentStreamLength < 6){
|
||||
return false;
|
||||
} else {
|
||||
temporaryByteQueue.add(byteStream.get(2 + 0));
|
||||
temporaryByteQueue.add(byteStream.get(2 + 1));
|
||||
temporaryByteQueue.add(byteStream.get(2 + 2));
|
||||
temporaryByteQueue.add(byteStream.get(2 + 3));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 0));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 1));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 2));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 3));
|
||||
userSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
|
||||
}
|
||||
if(currentStreamLength < 6 + userSize){
|
||||
@ -105,10 +105,10 @@ public class AuthMessage extends NetworkMessage {
|
||||
if(currentStreamLength < 10){
|
||||
return false;
|
||||
} else {
|
||||
temporaryByteQueue.add(byteStream.get(6 + userSize + 0));
|
||||
temporaryByteQueue.add(byteStream.get(6 + userSize + 1));
|
||||
temporaryByteQueue.add(byteStream.get(6 + userSize + 2));
|
||||
temporaryByteQueue.add(byteStream.get(6 + userSize + 3));
|
||||
temporaryByteQueue.add(byteBuffer.peek(6 + userSize + 0));
|
||||
temporaryByteQueue.add(byteBuffer.peek(6 + userSize + 1));
|
||||
temporaryByteQueue.add(byteBuffer.peek(6 + userSize + 2));
|
||||
temporaryByteQueue.add(byteBuffer.peek(6 + userSize + 3));
|
||||
passSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
|
||||
}
|
||||
if(currentStreamLength < 10 + userSize + passSize){
|
||||
@ -117,11 +117,11 @@ public class AuthMessage extends NetworkMessage {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static AuthMessage parseAuthDetailsMessage(List<Byte> byteStream){
|
||||
public static AuthMessage parseAuthDetailsMessage(CircularByteBuffer byteBuffer){
|
||||
AuthMessage rVal = new AuthMessage(AuthMessageType.AUTHDETAILS);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setuser(ByteStreamUtils.popStringFromByteQueue(byteStream));
|
||||
rVal.setpass(ByteStreamUtils.popStringFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setuser(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
|
||||
rVal.setpass(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -133,9 +133,9 @@ public class AuthMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static AuthMessage parseAuthSuccessMessage(List<Byte> byteStream){
|
||||
public static AuthMessage parseAuthSuccessMessage(CircularByteBuffer byteBuffer){
|
||||
AuthMessage rVal = new AuthMessage(AuthMessageType.AUTHSUCCESS);
|
||||
stripPacketHeader(byteStream);
|
||||
stripPacketHeader(byteBuffer);
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -145,9 +145,9 @@ public class AuthMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static AuthMessage parseAuthFailureMessage(List<Byte> byteStream){
|
||||
public static AuthMessage parseAuthFailureMessage(CircularByteBuffer byteBuffer){
|
||||
AuthMessage rVal = new AuthMessage(AuthMessageType.AUTHFAILURE);
|
||||
stripPacketHeader(byteStream);
|
||||
stripPacketHeader(byteBuffer);
|
||||
return rVal;
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package electrosphere.net.parser.net.message;
|
||||
|
||||
import electrosphere.net.parser.util.ByteStreamUtils;
|
||||
import electrosphere.net.parser.net.raw.CircularByteBuffer;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
@ -36,50 +37,49 @@ public class CharacterMessage extends NetworkMessage {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
static void stripPacketHeader(List<Byte> byteStream){
|
||||
byteStream.remove(0);
|
||||
byteStream.remove(0);
|
||||
static void stripPacketHeader(CircularByteBuffer byteBuffer){
|
||||
byteBuffer.read(2);
|
||||
}
|
||||
|
||||
public static boolean canParseMessage(List<Byte> byteStream, byte secondByte){
|
||||
public static boolean canParseMessage(CircularByteBuffer byteBuffer, byte secondByte){
|
||||
switch(secondByte){
|
||||
case TypeBytes.CHARACTER_MESSAGE_TYPE_REQUESTCHARACTERLIST:
|
||||
if(byteStream.size() >= TypeBytes.CHARACTER_MESSAGE_TYPE_REQUESTCHARACTERLIST_SIZE){
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.CHARACTER_MESSAGE_TYPE_REQUESTCHARACTERLIST_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case TypeBytes.CHARACTER_MESSAGE_TYPE_RESPONSECHARACTERLIST:
|
||||
return CharacterMessage.canParseResponseCharacterListMessage(byteStream);
|
||||
return CharacterMessage.canParseResponseCharacterListMessage(byteBuffer);
|
||||
case TypeBytes.CHARACTER_MESSAGE_TYPE_REQUESTCREATECHARACTER:
|
||||
return CharacterMessage.canParseRequestCreateCharacterMessage(byteStream);
|
||||
return CharacterMessage.canParseRequestCreateCharacterMessage(byteBuffer);
|
||||
case TypeBytes.CHARACTER_MESSAGE_TYPE_RESPONSECREATECHARACTERSUCCESS:
|
||||
if(byteStream.size() >= TypeBytes.CHARACTER_MESSAGE_TYPE_RESPONSECREATECHARACTERSUCCESS_SIZE){
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.CHARACTER_MESSAGE_TYPE_RESPONSECREATECHARACTERSUCCESS_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case TypeBytes.CHARACTER_MESSAGE_TYPE_RESPONSECREATECHARACTERFAILURE:
|
||||
if(byteStream.size() >= TypeBytes.CHARACTER_MESSAGE_TYPE_RESPONSECREATECHARACTERFAILURE_SIZE){
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.CHARACTER_MESSAGE_TYPE_RESPONSECREATECHARACTERFAILURE_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case TypeBytes.CHARACTER_MESSAGE_TYPE_REQUESTSPAWNCHARACTER:
|
||||
if(byteStream.size() >= TypeBytes.CHARACTER_MESSAGE_TYPE_REQUESTSPAWNCHARACTER_SIZE){
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.CHARACTER_MESSAGE_TYPE_REQUESTSPAWNCHARACTER_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case TypeBytes.CHARACTER_MESSAGE_TYPE_RESPONSESPAWNCHARACTER:
|
||||
return CharacterMessage.canParseResponseSpawnCharacterMessage(byteStream);
|
||||
return CharacterMessage.canParseResponseSpawnCharacterMessage(byteBuffer);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static CharacterMessage parseRequestCharacterListMessage(List<Byte> byteStream){
|
||||
public static CharacterMessage parseRequestCharacterListMessage(CircularByteBuffer byteBuffer){
|
||||
CharacterMessage rVal = new CharacterMessage(CharacterMessageType.REQUESTCHARACTERLIST);
|
||||
stripPacketHeader(byteStream);
|
||||
stripPacketHeader(byteBuffer);
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -89,17 +89,17 @@ public class CharacterMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static boolean canParseResponseCharacterListMessage(List<Byte> byteStream){
|
||||
int currentStreamLength = byteStream.size();
|
||||
public static boolean canParseResponseCharacterListMessage(CircularByteBuffer byteBuffer){
|
||||
int currentStreamLength = byteBuffer.getRemaining();
|
||||
List<Byte> temporaryByteQueue = new LinkedList();
|
||||
int dataSize = 0;
|
||||
if(currentStreamLength < 6){
|
||||
return false;
|
||||
} else {
|
||||
temporaryByteQueue.add(byteStream.get(2 + 0));
|
||||
temporaryByteQueue.add(byteStream.get(2 + 1));
|
||||
temporaryByteQueue.add(byteStream.get(2 + 2));
|
||||
temporaryByteQueue.add(byteStream.get(2 + 3));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 0));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 1));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 2));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 3));
|
||||
dataSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
|
||||
}
|
||||
if(currentStreamLength < 6 + dataSize){
|
||||
@ -108,10 +108,10 @@ public class CharacterMessage extends NetworkMessage {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static CharacterMessage parseResponseCharacterListMessage(List<Byte> byteStream){
|
||||
public static CharacterMessage parseResponseCharacterListMessage(CircularByteBuffer byteBuffer){
|
||||
CharacterMessage rVal = new CharacterMessage(CharacterMessageType.RESPONSECHARACTERLIST);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -122,17 +122,17 @@ public class CharacterMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static boolean canParseRequestCreateCharacterMessage(List<Byte> byteStream){
|
||||
int currentStreamLength = byteStream.size();
|
||||
public static boolean canParseRequestCreateCharacterMessage(CircularByteBuffer byteBuffer){
|
||||
int currentStreamLength = byteBuffer.getRemaining();
|
||||
List<Byte> temporaryByteQueue = new LinkedList();
|
||||
int dataSize = 0;
|
||||
if(currentStreamLength < 6){
|
||||
return false;
|
||||
} else {
|
||||
temporaryByteQueue.add(byteStream.get(2 + 0));
|
||||
temporaryByteQueue.add(byteStream.get(2 + 1));
|
||||
temporaryByteQueue.add(byteStream.get(2 + 2));
|
||||
temporaryByteQueue.add(byteStream.get(2 + 3));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 0));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 1));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 2));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 3));
|
||||
dataSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
|
||||
}
|
||||
if(currentStreamLength < 6 + dataSize){
|
||||
@ -141,10 +141,10 @@ public class CharacterMessage extends NetworkMessage {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static CharacterMessage parseRequestCreateCharacterMessage(List<Byte> byteStream){
|
||||
public static CharacterMessage parseRequestCreateCharacterMessage(CircularByteBuffer byteBuffer){
|
||||
CharacterMessage rVal = new CharacterMessage(CharacterMessageType.REQUESTCREATECHARACTER);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -155,9 +155,9 @@ public class CharacterMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static CharacterMessage parseResponseCreateCharacterSuccessMessage(List<Byte> byteStream){
|
||||
public static CharacterMessage parseResponseCreateCharacterSuccessMessage(CircularByteBuffer byteBuffer){
|
||||
CharacterMessage rVal = new CharacterMessage(CharacterMessageType.RESPONSECREATECHARACTERSUCCESS);
|
||||
stripPacketHeader(byteStream);
|
||||
stripPacketHeader(byteBuffer);
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -167,9 +167,9 @@ public class CharacterMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static CharacterMessage parseResponseCreateCharacterFailureMessage(List<Byte> byteStream){
|
||||
public static CharacterMessage parseResponseCreateCharacterFailureMessage(CircularByteBuffer byteBuffer){
|
||||
CharacterMessage rVal = new CharacterMessage(CharacterMessageType.RESPONSECREATECHARACTERFAILURE);
|
||||
stripPacketHeader(byteStream);
|
||||
stripPacketHeader(byteBuffer);
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -179,9 +179,9 @@ public class CharacterMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static CharacterMessage parseRequestSpawnCharacterMessage(List<Byte> byteStream){
|
||||
public static CharacterMessage parseRequestSpawnCharacterMessage(CircularByteBuffer byteBuffer){
|
||||
CharacterMessage rVal = new CharacterMessage(CharacterMessageType.REQUESTSPAWNCHARACTER);
|
||||
stripPacketHeader(byteStream);
|
||||
stripPacketHeader(byteBuffer);
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -191,17 +191,17 @@ public class CharacterMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static boolean canParseResponseSpawnCharacterMessage(List<Byte> byteStream){
|
||||
int currentStreamLength = byteStream.size();
|
||||
public static boolean canParseResponseSpawnCharacterMessage(CircularByteBuffer byteBuffer){
|
||||
int currentStreamLength = byteBuffer.getRemaining();
|
||||
List<Byte> temporaryByteQueue = new LinkedList();
|
||||
int dataSize = 0;
|
||||
if(currentStreamLength < 6){
|
||||
return false;
|
||||
} else {
|
||||
temporaryByteQueue.add(byteStream.get(2 + 0));
|
||||
temporaryByteQueue.add(byteStream.get(2 + 1));
|
||||
temporaryByteQueue.add(byteStream.get(2 + 2));
|
||||
temporaryByteQueue.add(byteStream.get(2 + 3));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 0));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 1));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 2));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 3));
|
||||
dataSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
|
||||
}
|
||||
if(currentStreamLength < 6 + dataSize){
|
||||
@ -210,10 +210,10 @@ public class CharacterMessage extends NetworkMessage {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static CharacterMessage parseResponseSpawnCharacterMessage(List<Byte> byteStream){
|
||||
public static CharacterMessage parseResponseSpawnCharacterMessage(CircularByteBuffer byteBuffer){
|
||||
CharacterMessage rVal = new CharacterMessage(CharacterMessageType.RESPONSESPAWNCHARACTER);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package electrosphere.net.parser.net.message;
|
||||
|
||||
import electrosphere.net.parser.util.ByteStreamUtils;
|
||||
import electrosphere.net.parser.net.raw.CircularByteBuffer;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
@ -272,107 +273,106 @@ public class EntityMessage extends NetworkMessage {
|
||||
this.propertyValueString = propertyValueString;
|
||||
}
|
||||
|
||||
static void stripPacketHeader(List<Byte> byteStream){
|
||||
byteStream.remove(0);
|
||||
byteStream.remove(0);
|
||||
static void stripPacketHeader(CircularByteBuffer byteBuffer){
|
||||
byteBuffer.read(2);
|
||||
}
|
||||
|
||||
public static boolean canParseMessage(List<Byte> byteStream, byte secondByte){
|
||||
public static boolean canParseMessage(CircularByteBuffer byteBuffer, byte secondByte){
|
||||
switch(secondByte){
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_CREATE:
|
||||
return EntityMessage.canParseCreateMessage(byteStream);
|
||||
return EntityMessage.canParseCreateMessage(byteBuffer);
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SPAWNCREATURE:
|
||||
return EntityMessage.canParseSpawnCreatureMessage(byteStream);
|
||||
return EntityMessage.canParseSpawnCreatureMessage(byteBuffer);
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SPAWNITEM:
|
||||
return EntityMessage.canParseSpawnItemMessage(byteStream);
|
||||
return EntityMessage.canParseSpawnItemMessage(byteBuffer);
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETPOSITION:
|
||||
if(byteStream.size() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETPOSITION_SIZE){
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETPOSITION_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETFACING:
|
||||
if(byteStream.size() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETFACING_SIZE){
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETFACING_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_MOVEUPDATE:
|
||||
if(byteStream.size() >= TypeBytes.ENTITY_MESSAGE_TYPE_MOVEUPDATE_SIZE){
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_MOVEUPDATE_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_ATTACKUPDATE:
|
||||
if(byteStream.size() >= TypeBytes.ENTITY_MESSAGE_TYPE_ATTACKUPDATE_SIZE){
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_ATTACKUPDATE_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_MOVE:
|
||||
if(byteStream.size() >= TypeBytes.ENTITY_MESSAGE_TYPE_MOVE_SIZE){
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_MOVE_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_KILL:
|
||||
if(byteStream.size() >= TypeBytes.ENTITY_MESSAGE_TYPE_KILL_SIZE){
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_KILL_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_DESTROY:
|
||||
if(byteStream.size() >= TypeBytes.ENTITY_MESSAGE_TYPE_DESTROY_SIZE){
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_DESTROY_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETBEHAVIORTREE:
|
||||
if(byteStream.size() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETBEHAVIORTREE_SIZE){
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETBEHAVIORTREE_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETPROPERTY:
|
||||
if(byteStream.size() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETPROPERTY_SIZE){
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETPROPERTY_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYINT:
|
||||
if(byteStream.size() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYINT_SIZE){
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYINT_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYFLOAT:
|
||||
if(byteStream.size() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYFLOAT_SIZE){
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYFLOAT_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYDOUBLE:
|
||||
if(byteStream.size() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYDOUBLE_SIZE){
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYDOUBLE_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYSTRING:
|
||||
return EntityMessage.canParsesetBTreePropertyStringMessage(byteStream);
|
||||
return EntityMessage.canParsesetBTreePropertyStringMessage(byteBuffer);
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYENUM:
|
||||
if(byteStream.size() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYENUM_SIZE){
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYENUM_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_ATTACHENTITYTOENTITY:
|
||||
return EntityMessage.canParseattachEntityToEntityMessage(byteStream);
|
||||
return EntityMessage.canParseattachEntityToEntityMessage(byteBuffer);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean canParseCreateMessage(List<Byte> byteStream){
|
||||
int currentStreamLength = byteStream.size();
|
||||
public static boolean canParseCreateMessage(CircularByteBuffer byteBuffer){
|
||||
int currentStreamLength = byteBuffer.getRemaining();
|
||||
List<Byte> temporaryByteQueue = new LinkedList();
|
||||
if(currentStreamLength < 6){
|
||||
return false;
|
||||
@ -384,10 +384,10 @@ public class EntityMessage extends NetworkMessage {
|
||||
if(currentStreamLength < 14){
|
||||
return false;
|
||||
} else {
|
||||
temporaryByteQueue.add(byteStream.get(10 + 0));
|
||||
temporaryByteQueue.add(byteStream.get(10 + 1));
|
||||
temporaryByteQueue.add(byteStream.get(10 + 2));
|
||||
temporaryByteQueue.add(byteStream.get(10 + 3));
|
||||
temporaryByteQueue.add(byteBuffer.peek(10 + 0));
|
||||
temporaryByteQueue.add(byteBuffer.peek(10 + 1));
|
||||
temporaryByteQueue.add(byteBuffer.peek(10 + 2));
|
||||
temporaryByteQueue.add(byteBuffer.peek(10 + 3));
|
||||
entitySubtypeSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
|
||||
}
|
||||
if(currentStreamLength < 14 + entitySubtypeSize){
|
||||
@ -405,15 +405,15 @@ public class EntityMessage extends NetworkMessage {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static EntityMessage parseCreateMessage(List<Byte> byteStream){
|
||||
public static EntityMessage parseCreateMessage(CircularByteBuffer byteBuffer){
|
||||
EntityMessage rVal = new EntityMessage(EntityMessageType.CREATE);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.setentityCategory(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.setentitySubtype(ByteStreamUtils.popStringFromByteQueue(byteStream));
|
||||
rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setentityCategory(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setentitySubtype(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
|
||||
rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -429,8 +429,8 @@ public class EntityMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static boolean canParseSpawnCreatureMessage(List<Byte> byteStream){
|
||||
int currentStreamLength = byteStream.size();
|
||||
public static boolean canParseSpawnCreatureMessage(CircularByteBuffer byteBuffer){
|
||||
int currentStreamLength = byteBuffer.getRemaining();
|
||||
List<Byte> temporaryByteQueue = new LinkedList();
|
||||
if(currentStreamLength < 6){
|
||||
return false;
|
||||
@ -439,10 +439,10 @@ public class EntityMessage extends NetworkMessage {
|
||||
if(currentStreamLength < 10){
|
||||
return false;
|
||||
} else {
|
||||
temporaryByteQueue.add(byteStream.get(6 + 0));
|
||||
temporaryByteQueue.add(byteStream.get(6 + 1));
|
||||
temporaryByteQueue.add(byteStream.get(6 + 2));
|
||||
temporaryByteQueue.add(byteStream.get(6 + 3));
|
||||
temporaryByteQueue.add(byteBuffer.peek(6 + 0));
|
||||
temporaryByteQueue.add(byteBuffer.peek(6 + 1));
|
||||
temporaryByteQueue.add(byteBuffer.peek(6 + 2));
|
||||
temporaryByteQueue.add(byteBuffer.peek(6 + 3));
|
||||
creatureTemplateSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
|
||||
}
|
||||
if(currentStreamLength < 10 + creatureTemplateSize){
|
||||
@ -460,14 +460,14 @@ public class EntityMessage extends NetworkMessage {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static EntityMessage parseSpawnCreatureMessage(List<Byte> byteStream){
|
||||
public static EntityMessage parseSpawnCreatureMessage(CircularByteBuffer byteBuffer){
|
||||
EntityMessage rVal = new EntityMessage(EntityMessageType.SPAWNCREATURE);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.setcreatureTemplate(ByteStreamUtils.popStringFromByteQueue(byteStream));
|
||||
rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setcreatureTemplate(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
|
||||
rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -482,8 +482,8 @@ public class EntityMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static boolean canParseSpawnItemMessage(List<Byte> byteStream){
|
||||
int currentStreamLength = byteStream.size();
|
||||
public static boolean canParseSpawnItemMessage(CircularByteBuffer byteBuffer){
|
||||
int currentStreamLength = byteBuffer.getRemaining();
|
||||
List<Byte> temporaryByteQueue = new LinkedList();
|
||||
if(currentStreamLength < 6){
|
||||
return false;
|
||||
@ -492,10 +492,10 @@ public class EntityMessage extends NetworkMessage {
|
||||
if(currentStreamLength < 10){
|
||||
return false;
|
||||
} else {
|
||||
temporaryByteQueue.add(byteStream.get(6 + 0));
|
||||
temporaryByteQueue.add(byteStream.get(6 + 1));
|
||||
temporaryByteQueue.add(byteStream.get(6 + 2));
|
||||
temporaryByteQueue.add(byteStream.get(6 + 3));
|
||||
temporaryByteQueue.add(byteBuffer.peek(6 + 0));
|
||||
temporaryByteQueue.add(byteBuffer.peek(6 + 1));
|
||||
temporaryByteQueue.add(byteBuffer.peek(6 + 2));
|
||||
temporaryByteQueue.add(byteBuffer.peek(6 + 3));
|
||||
creatureTemplateSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
|
||||
}
|
||||
if(currentStreamLength < 10 + creatureTemplateSize){
|
||||
@ -513,14 +513,14 @@ public class EntityMessage extends NetworkMessage {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static EntityMessage parseSpawnItemMessage(List<Byte> byteStream){
|
||||
public static EntityMessage parseSpawnItemMessage(CircularByteBuffer byteBuffer){
|
||||
EntityMessage rVal = new EntityMessage(EntityMessageType.SPAWNITEM);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.setcreatureTemplate(ByteStreamUtils.popStringFromByteQueue(byteStream));
|
||||
rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setcreatureTemplate(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
|
||||
rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -535,14 +535,14 @@ public class EntityMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static EntityMessage parseSetPositionMessage(List<Byte> byteStream){
|
||||
public static EntityMessage parseSetPositionMessage(CircularByteBuffer byteBuffer){
|
||||
EntityMessage rVal = new EntityMessage(EntityMessageType.SETPOSITION);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteStream));
|
||||
rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
||||
rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -557,14 +557,14 @@ public class EntityMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static EntityMessage parsesetFacingMessage(List<Byte> byteStream){
|
||||
public static EntityMessage parsesetFacingMessage(CircularByteBuffer byteBuffer){
|
||||
EntityMessage rVal = new EntityMessage(EntityMessageType.SETFACING);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteStream));
|
||||
rVal.setrotationX(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
rVal.setrotationY(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
rVal.setrotationZ(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
||||
rVal.setrotationX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
rVal.setrotationY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
rVal.setrotationZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -579,20 +579,20 @@ public class EntityMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static EntityMessage parsemoveUpdateMessage(List<Byte> byteStream){
|
||||
public static EntityMessage parsemoveUpdateMessage(CircularByteBuffer byteBuffer){
|
||||
EntityMessage rVal = new EntityMessage(EntityMessageType.MOVEUPDATE);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteStream));
|
||||
rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
rVal.setrotationX(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
rVal.setrotationY(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
rVal.setrotationZ(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
rVal.setrotationW(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
rVal.setvelocity(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
rVal.settreeState(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
||||
rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
rVal.setrotationX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
rVal.setrotationY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
rVal.setrotationZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
rVal.setrotationW(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
rVal.setvelocity(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
rVal.settreeState(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -613,19 +613,19 @@ public class EntityMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static EntityMessage parseattackUpdateMessage(List<Byte> byteStream){
|
||||
public static EntityMessage parseattackUpdateMessage(CircularByteBuffer byteBuffer){
|
||||
EntityMessage rVal = new EntityMessage(EntityMessageType.ATTACKUPDATE);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteStream));
|
||||
rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
rVal.setrotationX(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
rVal.setrotationY(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
rVal.setrotationZ(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
rVal.setvelocity(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
rVal.settreeState(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
||||
rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
rVal.setrotationX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
rVal.setrotationY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
rVal.setrotationZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
rVal.setvelocity(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
rVal.settreeState(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -645,14 +645,14 @@ public class EntityMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static EntityMessage parseMoveMessage(List<Byte> byteStream){
|
||||
public static EntityMessage parseMoveMessage(CircularByteBuffer byteBuffer){
|
||||
EntityMessage rVal = new EntityMessage(EntityMessageType.MOVE);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteStream));
|
||||
rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
||||
rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -667,11 +667,11 @@ public class EntityMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static EntityMessage parseKillMessage(List<Byte> byteStream){
|
||||
public static EntityMessage parseKillMessage(CircularByteBuffer byteBuffer){
|
||||
EntityMessage rVal = new EntityMessage(EntityMessageType.KILL);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteStream));
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -683,10 +683,10 @@ public class EntityMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static EntityMessage parseDestroyMessage(List<Byte> byteStream){
|
||||
public static EntityMessage parseDestroyMessage(CircularByteBuffer byteBuffer){
|
||||
EntityMessage rVal = new EntityMessage(EntityMessageType.DESTROY);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -697,13 +697,13 @@ public class EntityMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static EntityMessage parseSetBehaviorTreeMessage(List<Byte> byteStream){
|
||||
public static EntityMessage parseSetBehaviorTreeMessage(CircularByteBuffer byteBuffer){
|
||||
EntityMessage rVal = new EntityMessage(EntityMessageType.SETBEHAVIORTREE);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteStream));
|
||||
rVal.settreeType(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.settreeStatus(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
||||
rVal.settreeType(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.settreeStatus(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -717,13 +717,13 @@ public class EntityMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static EntityMessage parsesetPropertyMessage(List<Byte> byteStream){
|
||||
public static EntityMessage parsesetPropertyMessage(CircularByteBuffer byteBuffer){
|
||||
EntityMessage rVal = new EntityMessage(EntityMessageType.SETPROPERTY);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteStream));
|
||||
rVal.setpropertyType(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.setpropertyValue(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
||||
rVal.setpropertyType(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setpropertyValue(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -737,14 +737,14 @@ public class EntityMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static EntityMessage parsesetBTreePropertyIntMessage(List<Byte> byteStream){
|
||||
public static EntityMessage parsesetBTreePropertyIntMessage(CircularByteBuffer byteBuffer){
|
||||
EntityMessage rVal = new EntityMessage(EntityMessageType.SETBTREEPROPERTYINT);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteStream));
|
||||
rVal.setbTreeID(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.setpropertyID(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.setpropertyValueInt(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
||||
rVal.setbTreeID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setpropertyID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setpropertyValueInt(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -759,14 +759,14 @@ public class EntityMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static EntityMessage parsesetBTreePropertyFloatMessage(List<Byte> byteStream){
|
||||
public static EntityMessage parsesetBTreePropertyFloatMessage(CircularByteBuffer byteBuffer){
|
||||
EntityMessage rVal = new EntityMessage(EntityMessageType.SETBTREEPROPERTYFLOAT);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteStream));
|
||||
rVal.setbTreeID(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.setpropertyID(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.setpropertyValueFloat(ByteStreamUtils.popFloatFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
||||
rVal.setbTreeID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setpropertyID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setpropertyValueFloat(ByteStreamUtils.popFloatFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -781,14 +781,14 @@ public class EntityMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static EntityMessage parsesetBTreePropertyDoubleMessage(List<Byte> byteStream){
|
||||
public static EntityMessage parsesetBTreePropertyDoubleMessage(CircularByteBuffer byteBuffer){
|
||||
EntityMessage rVal = new EntityMessage(EntityMessageType.SETBTREEPROPERTYDOUBLE);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteStream));
|
||||
rVal.setbTreeID(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.setpropertyID(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.setpropertyValueDouble(ByteStreamUtils.popDoubleFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
||||
rVal.setbTreeID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setpropertyID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setpropertyValueDouble(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -803,8 +803,8 @@ public class EntityMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static boolean canParsesetBTreePropertyStringMessage(List<Byte> byteStream){
|
||||
int currentStreamLength = byteStream.size();
|
||||
public static boolean canParsesetBTreePropertyStringMessage(CircularByteBuffer byteBuffer){
|
||||
int currentStreamLength = byteBuffer.getRemaining();
|
||||
List<Byte> temporaryByteQueue = new LinkedList();
|
||||
if(currentStreamLength < 6){
|
||||
return false;
|
||||
@ -822,10 +822,10 @@ public class EntityMessage extends NetworkMessage {
|
||||
if(currentStreamLength < 26){
|
||||
return false;
|
||||
} else {
|
||||
temporaryByteQueue.add(byteStream.get(22 + 0));
|
||||
temporaryByteQueue.add(byteStream.get(22 + 1));
|
||||
temporaryByteQueue.add(byteStream.get(22 + 2));
|
||||
temporaryByteQueue.add(byteStream.get(22 + 3));
|
||||
temporaryByteQueue.add(byteBuffer.peek(22 + 0));
|
||||
temporaryByteQueue.add(byteBuffer.peek(22 + 1));
|
||||
temporaryByteQueue.add(byteBuffer.peek(22 + 2));
|
||||
temporaryByteQueue.add(byteBuffer.peek(22 + 3));
|
||||
propertyValueStringSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
|
||||
}
|
||||
if(currentStreamLength < 26 + propertyValueStringSize){
|
||||
@ -834,14 +834,14 @@ public class EntityMessage extends NetworkMessage {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static EntityMessage parsesetBTreePropertyStringMessage(List<Byte> byteStream){
|
||||
public static EntityMessage parsesetBTreePropertyStringMessage(CircularByteBuffer byteBuffer){
|
||||
EntityMessage rVal = new EntityMessage(EntityMessageType.SETBTREEPROPERTYSTRING);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteStream));
|
||||
rVal.setbTreeID(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.setpropertyID(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.setpropertyValueString(ByteStreamUtils.popStringFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
||||
rVal.setbTreeID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setpropertyID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setpropertyValueString(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -856,14 +856,14 @@ public class EntityMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static EntityMessage parsesetBTreePropertyEnumMessage(List<Byte> byteStream){
|
||||
public static EntityMessage parsesetBTreePropertyEnumMessage(CircularByteBuffer byteBuffer){
|
||||
EntityMessage rVal = new EntityMessage(EntityMessageType.SETBTREEPROPERTYENUM);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteStream));
|
||||
rVal.setbTreeID(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.setpropertyID(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.setpropertyValueInt(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
||||
rVal.setbTreeID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setpropertyID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setpropertyValueInt(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -878,8 +878,8 @@ public class EntityMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static boolean canParseattachEntityToEntityMessage(List<Byte> byteStream){
|
||||
int currentStreamLength = byteStream.size();
|
||||
public static boolean canParseattachEntityToEntityMessage(CircularByteBuffer byteBuffer){
|
||||
int currentStreamLength = byteBuffer.getRemaining();
|
||||
List<Byte> temporaryByteQueue = new LinkedList();
|
||||
if(currentStreamLength < 6){
|
||||
return false;
|
||||
@ -888,10 +888,10 @@ public class EntityMessage extends NetworkMessage {
|
||||
if(currentStreamLength < 10){
|
||||
return false;
|
||||
} else {
|
||||
temporaryByteQueue.add(byteStream.get(6 + 0));
|
||||
temporaryByteQueue.add(byteStream.get(6 + 1));
|
||||
temporaryByteQueue.add(byteStream.get(6 + 2));
|
||||
temporaryByteQueue.add(byteStream.get(6 + 3));
|
||||
temporaryByteQueue.add(byteBuffer.peek(6 + 0));
|
||||
temporaryByteQueue.add(byteBuffer.peek(6 + 1));
|
||||
temporaryByteQueue.add(byteBuffer.peek(6 + 2));
|
||||
temporaryByteQueue.add(byteBuffer.peek(6 + 3));
|
||||
boneSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
|
||||
}
|
||||
if(currentStreamLength < 10 + boneSize){
|
||||
@ -903,12 +903,12 @@ public class EntityMessage extends NetworkMessage {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static EntityMessage parseattachEntityToEntityMessage(List<Byte> byteStream){
|
||||
public static EntityMessage parseattachEntityToEntityMessage(CircularByteBuffer byteBuffer){
|
||||
EntityMessage rVal = new EntityMessage(EntityMessageType.ATTACHENTITYTOENTITY);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.setbone(ByteStreamUtils.popStringFromByteQueue(byteStream));
|
||||
rVal.settargetID(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setbone(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
|
||||
rVal.settargetID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package electrosphere.net.parser.net.message;
|
||||
|
||||
import electrosphere.net.parser.util.ByteStreamUtils;
|
||||
import electrosphere.net.parser.net.raw.CircularByteBuffer;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
@ -72,37 +73,36 @@ public class InventoryMessage extends NetworkMessage {
|
||||
this.containerType = containerType;
|
||||
}
|
||||
|
||||
static void stripPacketHeader(List<Byte> byteStream){
|
||||
byteStream.remove(0);
|
||||
byteStream.remove(0);
|
||||
static void stripPacketHeader(CircularByteBuffer byteBuffer){
|
||||
byteBuffer.read(2);
|
||||
}
|
||||
|
||||
public static boolean canParseMessage(List<Byte> byteStream, byte secondByte){
|
||||
public static boolean canParseMessage(CircularByteBuffer byteBuffer, byte secondByte){
|
||||
switch(secondByte){
|
||||
case TypeBytes.INVENTORY_MESSAGE_TYPE_ADDITEMTOINVENTORY:
|
||||
return InventoryMessage.canParseaddItemToInventoryMessage(byteStream);
|
||||
return InventoryMessage.canParseaddItemToInventoryMessage(byteBuffer);
|
||||
case TypeBytes.INVENTORY_MESSAGE_TYPE_REMOVEITEMFROMINVENTORY:
|
||||
if(byteStream.size() >= TypeBytes.INVENTORY_MESSAGE_TYPE_REMOVEITEMFROMINVENTORY_SIZE){
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.INVENTORY_MESSAGE_TYPE_REMOVEITEMFROMINVENTORY_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTEQUIPITEM:
|
||||
return InventoryMessage.canParseclientRequestEquipItemMessage(byteStream);
|
||||
return InventoryMessage.canParseclientRequestEquipItemMessage(byteBuffer);
|
||||
case TypeBytes.INVENTORY_MESSAGE_TYPE_SERVERCOMMANDMOVEITEMCONTAINER:
|
||||
return InventoryMessage.canParseserverCommandMoveItemContainerMessage(byteStream);
|
||||
return InventoryMessage.canParseserverCommandMoveItemContainerMessage(byteBuffer);
|
||||
case TypeBytes.INVENTORY_MESSAGE_TYPE_SERVERCOMMANDEQUIPITEM:
|
||||
return InventoryMessage.canParseserverCommandEquipItemMessage(byteStream);
|
||||
return InventoryMessage.canParseserverCommandEquipItemMessage(byteBuffer);
|
||||
case TypeBytes.INVENTORY_MESSAGE_TYPE_SERVERCOMMANDUNEQUIPITEM:
|
||||
return InventoryMessage.canParseserverCommandUnequipItemMessage(byteStream);
|
||||
return InventoryMessage.canParseserverCommandUnequipItemMessage(byteBuffer);
|
||||
case TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTUNEQUIPITEM:
|
||||
return InventoryMessage.canParseclientRequestUnequipItemMessage(byteStream);
|
||||
return InventoryMessage.canParseclientRequestUnequipItemMessage(byteBuffer);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean canParseaddItemToInventoryMessage(List<Byte> byteStream){
|
||||
int currentStreamLength = byteStream.size();
|
||||
public static boolean canParseaddItemToInventoryMessage(CircularByteBuffer byteBuffer){
|
||||
int currentStreamLength = byteBuffer.getRemaining();
|
||||
List<Byte> temporaryByteQueue = new LinkedList();
|
||||
if(currentStreamLength < 6){
|
||||
return false;
|
||||
@ -111,10 +111,10 @@ public class InventoryMessage extends NetworkMessage {
|
||||
if(currentStreamLength < 10){
|
||||
return false;
|
||||
} else {
|
||||
temporaryByteQueue.add(byteStream.get(6 + 0));
|
||||
temporaryByteQueue.add(byteStream.get(6 + 1));
|
||||
temporaryByteQueue.add(byteStream.get(6 + 2));
|
||||
temporaryByteQueue.add(byteStream.get(6 + 3));
|
||||
temporaryByteQueue.add(byteBuffer.peek(6 + 0));
|
||||
temporaryByteQueue.add(byteBuffer.peek(6 + 1));
|
||||
temporaryByteQueue.add(byteBuffer.peek(6 + 2));
|
||||
temporaryByteQueue.add(byteBuffer.peek(6 + 3));
|
||||
itemTemplateSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
|
||||
}
|
||||
if(currentStreamLength < 10 + itemTemplateSize){
|
||||
@ -123,11 +123,11 @@ public class InventoryMessage extends NetworkMessage {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static InventoryMessage parseaddItemToInventoryMessage(List<Byte> byteStream){
|
||||
public static InventoryMessage parseaddItemToInventoryMessage(CircularByteBuffer byteBuffer){
|
||||
InventoryMessage rVal = new InventoryMessage(InventoryMessageType.ADDITEMTOINVENTORY);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.setitemTemplate(ByteStreamUtils.popStringFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setitemTemplate(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -139,10 +139,10 @@ public class InventoryMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static InventoryMessage parseremoveItemFromInventoryMessage(List<Byte> byteStream){
|
||||
public static InventoryMessage parseremoveItemFromInventoryMessage(CircularByteBuffer byteBuffer){
|
||||
InventoryMessage rVal = new InventoryMessage(InventoryMessageType.REMOVEITEMFROMINVENTORY);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -153,17 +153,17 @@ public class InventoryMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static boolean canParseclientRequestEquipItemMessage(List<Byte> byteStream){
|
||||
int currentStreamLength = byteStream.size();
|
||||
public static boolean canParseclientRequestEquipItemMessage(CircularByteBuffer byteBuffer){
|
||||
int currentStreamLength = byteBuffer.getRemaining();
|
||||
List<Byte> temporaryByteQueue = new LinkedList();
|
||||
int equipPointIdSize = 0;
|
||||
if(currentStreamLength < 6){
|
||||
return false;
|
||||
} else {
|
||||
temporaryByteQueue.add(byteStream.get(2 + 0));
|
||||
temporaryByteQueue.add(byteStream.get(2 + 1));
|
||||
temporaryByteQueue.add(byteStream.get(2 + 2));
|
||||
temporaryByteQueue.add(byteStream.get(2 + 3));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 0));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 1));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 2));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 3));
|
||||
equipPointIdSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
|
||||
}
|
||||
if(currentStreamLength < 6 + equipPointIdSize){
|
||||
@ -175,11 +175,11 @@ public class InventoryMessage extends NetworkMessage {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static InventoryMessage parseclientRequestEquipItemMessage(List<Byte> byteStream){
|
||||
public static InventoryMessage parseclientRequestEquipItemMessage(CircularByteBuffer byteBuffer){
|
||||
InventoryMessage rVal = new InventoryMessage(InventoryMessageType.CLIENTREQUESTEQUIPITEM);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setequipPointId(ByteStreamUtils.popStringFromByteQueue(byteStream));
|
||||
rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setequipPointId(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
|
||||
rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -191,8 +191,8 @@ public class InventoryMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static boolean canParseserverCommandMoveItemContainerMessage(List<Byte> byteStream){
|
||||
int currentStreamLength = byteStream.size();
|
||||
public static boolean canParseserverCommandMoveItemContainerMessage(CircularByteBuffer byteBuffer){
|
||||
int currentStreamLength = byteBuffer.getRemaining();
|
||||
List<Byte> temporaryByteQueue = new LinkedList();
|
||||
if(currentStreamLength < 6){
|
||||
return false;
|
||||
@ -204,10 +204,10 @@ public class InventoryMessage extends NetworkMessage {
|
||||
if(currentStreamLength < 14){
|
||||
return false;
|
||||
} else {
|
||||
temporaryByteQueue.add(byteStream.get(10 + 0));
|
||||
temporaryByteQueue.add(byteStream.get(10 + 1));
|
||||
temporaryByteQueue.add(byteStream.get(10 + 2));
|
||||
temporaryByteQueue.add(byteStream.get(10 + 3));
|
||||
temporaryByteQueue.add(byteBuffer.peek(10 + 0));
|
||||
temporaryByteQueue.add(byteBuffer.peek(10 + 1));
|
||||
temporaryByteQueue.add(byteBuffer.peek(10 + 2));
|
||||
temporaryByteQueue.add(byteBuffer.peek(10 + 3));
|
||||
equipPointIdSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
|
||||
}
|
||||
if(currentStreamLength < 14 + equipPointIdSize){
|
||||
@ -216,12 +216,12 @@ public class InventoryMessage extends NetworkMessage {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static InventoryMessage parseserverCommandMoveItemContainerMessage(List<Byte> byteStream){
|
||||
public static InventoryMessage parseserverCommandMoveItemContainerMessage(CircularByteBuffer byteBuffer){
|
||||
InventoryMessage rVal = new InventoryMessage(InventoryMessageType.SERVERCOMMANDMOVEITEMCONTAINER);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.setcontainerType(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.setequipPointId(ByteStreamUtils.popStringFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setcontainerType(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setequipPointId(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -234,8 +234,8 @@ public class InventoryMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static boolean canParseserverCommandEquipItemMessage(List<Byte> byteStream){
|
||||
int currentStreamLength = byteStream.size();
|
||||
public static boolean canParseserverCommandEquipItemMessage(CircularByteBuffer byteBuffer){
|
||||
int currentStreamLength = byteBuffer.getRemaining();
|
||||
List<Byte> temporaryByteQueue = new LinkedList();
|
||||
if(currentStreamLength < 6){
|
||||
return false;
|
||||
@ -244,10 +244,10 @@ public class InventoryMessage extends NetworkMessage {
|
||||
if(currentStreamLength < 10){
|
||||
return false;
|
||||
} else {
|
||||
temporaryByteQueue.add(byteStream.get(6 + 0));
|
||||
temporaryByteQueue.add(byteStream.get(6 + 1));
|
||||
temporaryByteQueue.add(byteStream.get(6 + 2));
|
||||
temporaryByteQueue.add(byteStream.get(6 + 3));
|
||||
temporaryByteQueue.add(byteBuffer.peek(6 + 0));
|
||||
temporaryByteQueue.add(byteBuffer.peek(6 + 1));
|
||||
temporaryByteQueue.add(byteBuffer.peek(6 + 2));
|
||||
temporaryByteQueue.add(byteBuffer.peek(6 + 3));
|
||||
equipPointIdSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
|
||||
}
|
||||
if(currentStreamLength < 10 + equipPointIdSize){
|
||||
@ -260,10 +260,10 @@ public class InventoryMessage extends NetworkMessage {
|
||||
if(currentStreamLength < 18){
|
||||
return false;
|
||||
} else {
|
||||
temporaryByteQueue.add(byteStream.get(14 + equipPointIdSize + 0));
|
||||
temporaryByteQueue.add(byteStream.get(14 + equipPointIdSize + 1));
|
||||
temporaryByteQueue.add(byteStream.get(14 + equipPointIdSize + 2));
|
||||
temporaryByteQueue.add(byteStream.get(14 + equipPointIdSize + 3));
|
||||
temporaryByteQueue.add(byteBuffer.peek(14 + equipPointIdSize + 0));
|
||||
temporaryByteQueue.add(byteBuffer.peek(14 + equipPointIdSize + 1));
|
||||
temporaryByteQueue.add(byteBuffer.peek(14 + equipPointIdSize + 2));
|
||||
temporaryByteQueue.add(byteBuffer.peek(14 + equipPointIdSize + 3));
|
||||
itemTemplateSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
|
||||
}
|
||||
if(currentStreamLength < 18 + equipPointIdSize + itemTemplateSize){
|
||||
@ -272,13 +272,13 @@ public class InventoryMessage extends NetworkMessage {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static InventoryMessage parseserverCommandEquipItemMessage(List<Byte> byteStream){
|
||||
public static InventoryMessage parseserverCommandEquipItemMessage(CircularByteBuffer byteBuffer){
|
||||
InventoryMessage rVal = new InventoryMessage(InventoryMessageType.SERVERCOMMANDEQUIPITEM);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setequipperId(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.setequipPointId(ByteStreamUtils.popStringFromByteQueue(byteStream));
|
||||
rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.setitemTemplate(ByteStreamUtils.popStringFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setequipperId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setequipPointId(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
|
||||
rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setitemTemplate(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -292,8 +292,8 @@ public class InventoryMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static boolean canParseserverCommandUnequipItemMessage(List<Byte> byteStream){
|
||||
int currentStreamLength = byteStream.size();
|
||||
public static boolean canParseserverCommandUnequipItemMessage(CircularByteBuffer byteBuffer){
|
||||
int currentStreamLength = byteBuffer.getRemaining();
|
||||
List<Byte> temporaryByteQueue = new LinkedList();
|
||||
if(currentStreamLength < 6){
|
||||
return false;
|
||||
@ -302,10 +302,10 @@ public class InventoryMessage extends NetworkMessage {
|
||||
if(currentStreamLength < 10){
|
||||
return false;
|
||||
} else {
|
||||
temporaryByteQueue.add(byteStream.get(6 + 0));
|
||||
temporaryByteQueue.add(byteStream.get(6 + 1));
|
||||
temporaryByteQueue.add(byteStream.get(6 + 2));
|
||||
temporaryByteQueue.add(byteStream.get(6 + 3));
|
||||
temporaryByteQueue.add(byteBuffer.peek(6 + 0));
|
||||
temporaryByteQueue.add(byteBuffer.peek(6 + 1));
|
||||
temporaryByteQueue.add(byteBuffer.peek(6 + 2));
|
||||
temporaryByteQueue.add(byteBuffer.peek(6 + 3));
|
||||
equipPointIdSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
|
||||
}
|
||||
if(currentStreamLength < 10 + equipPointIdSize){
|
||||
@ -314,11 +314,11 @@ public class InventoryMessage extends NetworkMessage {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static InventoryMessage parseserverCommandUnequipItemMessage(List<Byte> byteStream){
|
||||
public static InventoryMessage parseserverCommandUnequipItemMessage(CircularByteBuffer byteBuffer){
|
||||
InventoryMessage rVal = new InventoryMessage(InventoryMessageType.SERVERCOMMANDUNEQUIPITEM);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setequipperId(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.setequipPointId(ByteStreamUtils.popStringFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setequipperId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setequipPointId(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -330,17 +330,17 @@ public class InventoryMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static boolean canParseclientRequestUnequipItemMessage(List<Byte> byteStream){
|
||||
int currentStreamLength = byteStream.size();
|
||||
public static boolean canParseclientRequestUnequipItemMessage(CircularByteBuffer byteBuffer){
|
||||
int currentStreamLength = byteBuffer.getRemaining();
|
||||
List<Byte> temporaryByteQueue = new LinkedList();
|
||||
int equipPointIdSize = 0;
|
||||
if(currentStreamLength < 6){
|
||||
return false;
|
||||
} else {
|
||||
temporaryByteQueue.add(byteStream.get(2 + 0));
|
||||
temporaryByteQueue.add(byteStream.get(2 + 1));
|
||||
temporaryByteQueue.add(byteStream.get(2 + 2));
|
||||
temporaryByteQueue.add(byteStream.get(2 + 3));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 0));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 1));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 2));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 3));
|
||||
equipPointIdSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
|
||||
}
|
||||
if(currentStreamLength < 6 + equipPointIdSize){
|
||||
@ -349,10 +349,10 @@ public class InventoryMessage extends NetworkMessage {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static InventoryMessage parseclientRequestUnequipItemMessage(List<Byte> byteStream){
|
||||
public static InventoryMessage parseclientRequestUnequipItemMessage(CircularByteBuffer byteBuffer){
|
||||
InventoryMessage rVal = new InventoryMessage(InventoryMessageType.CLIENTREQUESTUNEQUIPITEM);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setequipPointId(ByteStreamUtils.popStringFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setequipPointId(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package electrosphere.net.parser.net.message;
|
||||
|
||||
import electrosphere.net.parser.util.ByteStreamUtils;
|
||||
import electrosphere.net.parser.net.raw.CircularByteBuffer;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
@ -35,40 +36,39 @@ public class LoreMessage extends NetworkMessage {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
static void stripPacketHeader(List<Byte> byteStream){
|
||||
byteStream.remove(0);
|
||||
byteStream.remove(0);
|
||||
static void stripPacketHeader(CircularByteBuffer byteBuffer){
|
||||
byteBuffer.read(2);
|
||||
}
|
||||
|
||||
public static boolean canParseMessage(List<Byte> byteStream, byte secondByte){
|
||||
public static boolean canParseMessage(CircularByteBuffer byteBuffer, byte secondByte){
|
||||
switch(secondByte){
|
||||
case TypeBytes.LORE_MESSAGE_TYPE_REQUESTRACES:
|
||||
if(byteStream.size() >= TypeBytes.LORE_MESSAGE_TYPE_REQUESTRACES_SIZE){
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.LORE_MESSAGE_TYPE_REQUESTRACES_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case TypeBytes.LORE_MESSAGE_TYPE_RESPONSERACES:
|
||||
return LoreMessage.canParseResponseRacesMessage(byteStream);
|
||||
return LoreMessage.canParseResponseRacesMessage(byteBuffer);
|
||||
case TypeBytes.LORE_MESSAGE_TYPE_REQUESTRACEDATA:
|
||||
if(byteStream.size() >= TypeBytes.LORE_MESSAGE_TYPE_REQUESTRACEDATA_SIZE){
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.LORE_MESSAGE_TYPE_REQUESTRACEDATA_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case TypeBytes.LORE_MESSAGE_TYPE_RESPONSERACEDATA:
|
||||
return LoreMessage.canParseResponseRaceDataMessage(byteStream);
|
||||
return LoreMessage.canParseResponseRaceDataMessage(byteBuffer);
|
||||
case TypeBytes.LORE_MESSAGE_TYPE_REQUESTDATA:
|
||||
return LoreMessage.canParseRequestDataMessage(byteStream);
|
||||
return LoreMessage.canParseRequestDataMessage(byteBuffer);
|
||||
case TypeBytes.LORE_MESSAGE_TYPE_RESPONSEDATA:
|
||||
return LoreMessage.canParseResponseDataMessage(byteStream);
|
||||
return LoreMessage.canParseResponseDataMessage(byteBuffer);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static LoreMessage parseRequestRacesMessage(List<Byte> byteStream){
|
||||
public static LoreMessage parseRequestRacesMessage(CircularByteBuffer byteBuffer){
|
||||
LoreMessage rVal = new LoreMessage(LoreMessageType.REQUESTRACES);
|
||||
stripPacketHeader(byteStream);
|
||||
stripPacketHeader(byteBuffer);
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -78,17 +78,17 @@ public class LoreMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static boolean canParseResponseRacesMessage(List<Byte> byteStream){
|
||||
int currentStreamLength = byteStream.size();
|
||||
public static boolean canParseResponseRacesMessage(CircularByteBuffer byteBuffer){
|
||||
int currentStreamLength = byteBuffer.getRemaining();
|
||||
List<Byte> temporaryByteQueue = new LinkedList();
|
||||
int dataSize = 0;
|
||||
if(currentStreamLength < 6){
|
||||
return false;
|
||||
} else {
|
||||
temporaryByteQueue.add(byteStream.get(2 + 0));
|
||||
temporaryByteQueue.add(byteStream.get(2 + 1));
|
||||
temporaryByteQueue.add(byteStream.get(2 + 2));
|
||||
temporaryByteQueue.add(byteStream.get(2 + 3));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 0));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 1));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 2));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 3));
|
||||
dataSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
|
||||
}
|
||||
if(currentStreamLength < 6 + dataSize){
|
||||
@ -97,10 +97,10 @@ public class LoreMessage extends NetworkMessage {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static LoreMessage parseResponseRacesMessage(List<Byte> byteStream){
|
||||
public static LoreMessage parseResponseRacesMessage(CircularByteBuffer byteBuffer){
|
||||
LoreMessage rVal = new LoreMessage(LoreMessageType.RESPONSERACES);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -111,9 +111,9 @@ public class LoreMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static LoreMessage parseRequestRaceDataMessage(List<Byte> byteStream){
|
||||
public static LoreMessage parseRequestRaceDataMessage(CircularByteBuffer byteBuffer){
|
||||
LoreMessage rVal = new LoreMessage(LoreMessageType.REQUESTRACEDATA);
|
||||
stripPacketHeader(byteStream);
|
||||
stripPacketHeader(byteBuffer);
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -123,17 +123,17 @@ public class LoreMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static boolean canParseResponseRaceDataMessage(List<Byte> byteStream){
|
||||
int currentStreamLength = byteStream.size();
|
||||
public static boolean canParseResponseRaceDataMessage(CircularByteBuffer byteBuffer){
|
||||
int currentStreamLength = byteBuffer.getRemaining();
|
||||
List<Byte> temporaryByteQueue = new LinkedList();
|
||||
int dataSize = 0;
|
||||
if(currentStreamLength < 6){
|
||||
return false;
|
||||
} else {
|
||||
temporaryByteQueue.add(byteStream.get(2 + 0));
|
||||
temporaryByteQueue.add(byteStream.get(2 + 1));
|
||||
temporaryByteQueue.add(byteStream.get(2 + 2));
|
||||
temporaryByteQueue.add(byteStream.get(2 + 3));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 0));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 1));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 2));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 3));
|
||||
dataSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
|
||||
}
|
||||
if(currentStreamLength < 6 + dataSize){
|
||||
@ -142,10 +142,10 @@ public class LoreMessage extends NetworkMessage {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static LoreMessage parseResponseRaceDataMessage(List<Byte> byteStream){
|
||||
public static LoreMessage parseResponseRaceDataMessage(CircularByteBuffer byteBuffer){
|
||||
LoreMessage rVal = new LoreMessage(LoreMessageType.RESPONSERACEDATA);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -156,17 +156,17 @@ public class LoreMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static boolean canParseRequestDataMessage(List<Byte> byteStream){
|
||||
int currentStreamLength = byteStream.size();
|
||||
public static boolean canParseRequestDataMessage(CircularByteBuffer byteBuffer){
|
||||
int currentStreamLength = byteBuffer.getRemaining();
|
||||
List<Byte> temporaryByteQueue = new LinkedList();
|
||||
int dataSize = 0;
|
||||
if(currentStreamLength < 6){
|
||||
return false;
|
||||
} else {
|
||||
temporaryByteQueue.add(byteStream.get(2 + 0));
|
||||
temporaryByteQueue.add(byteStream.get(2 + 1));
|
||||
temporaryByteQueue.add(byteStream.get(2 + 2));
|
||||
temporaryByteQueue.add(byteStream.get(2 + 3));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 0));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 1));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 2));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 3));
|
||||
dataSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
|
||||
}
|
||||
if(currentStreamLength < 6 + dataSize){
|
||||
@ -175,10 +175,10 @@ public class LoreMessage extends NetworkMessage {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static LoreMessage parseRequestDataMessage(List<Byte> byteStream){
|
||||
public static LoreMessage parseRequestDataMessage(CircularByteBuffer byteBuffer){
|
||||
LoreMessage rVal = new LoreMessage(LoreMessageType.REQUESTDATA);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -189,17 +189,17 @@ public class LoreMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static boolean canParseResponseDataMessage(List<Byte> byteStream){
|
||||
int currentStreamLength = byteStream.size();
|
||||
public static boolean canParseResponseDataMessage(CircularByteBuffer byteBuffer){
|
||||
int currentStreamLength = byteBuffer.getRemaining();
|
||||
List<Byte> temporaryByteQueue = new LinkedList();
|
||||
int dataSize = 0;
|
||||
if(currentStreamLength < 6){
|
||||
return false;
|
||||
} else {
|
||||
temporaryByteQueue.add(byteStream.get(2 + 0));
|
||||
temporaryByteQueue.add(byteStream.get(2 + 1));
|
||||
temporaryByteQueue.add(byteStream.get(2 + 2));
|
||||
temporaryByteQueue.add(byteStream.get(2 + 3));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 0));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 1));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 2));
|
||||
temporaryByteQueue.add(byteBuffer.peek(2 + 3));
|
||||
dataSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
|
||||
}
|
||||
if(currentStreamLength < 6 + dataSize){
|
||||
@ -208,10 +208,10 @@ public class LoreMessage extends NetworkMessage {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static LoreMessage parseResponseDataMessage(List<Byte> byteStream){
|
||||
public static LoreMessage parseResponseDataMessage(CircularByteBuffer byteBuffer){
|
||||
LoreMessage rVal = new LoreMessage(LoreMessageType.RESPONSEDATA);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package electrosphere.net.parser.net.message;
|
||||
|
||||
import electrosphere.net.parser.util.ByteStreamUtils;
|
||||
import electrosphere.net.parser.net.raw.CircularByteBuffer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class NetworkMessage {
|
||||
@ -28,329 +30,314 @@ INVENTORY_MESSAGE,
|
||||
return rawBytes;
|
||||
}
|
||||
|
||||
public static NetworkMessage parseBytestreamForMessage(List<Byte> byteStream){
|
||||
public static NetworkMessage parseBytestreamForMessage(CircularByteBuffer byteBuffer){
|
||||
NetworkMessage rVal = null;
|
||||
byte firstByte;
|
||||
byte secondByte;
|
||||
if(byteStream.size() > 1){
|
||||
firstByte = byteStream.get(0);
|
||||
if(byteBuffer.getRemaining() > 1){
|
||||
firstByte = byteBuffer.peek();
|
||||
switch(firstByte){
|
||||
case TypeBytes.MESSAGE_TYPE_ENTITY:
|
||||
secondByte = byteStream.get(1);
|
||||
secondByte = byteBuffer.peek(1);
|
||||
switch(secondByte){
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_CREATE:
|
||||
if(EntityMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = EntityMessage.parseCreateMessage(byteStream);
|
||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = EntityMessage.parseCreateMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SPAWNCREATURE:
|
||||
if(EntityMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = EntityMessage.parseSpawnCreatureMessage(byteStream);
|
||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = EntityMessage.parseSpawnCreatureMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SPAWNITEM:
|
||||
if(EntityMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = EntityMessage.parseSpawnItemMessage(byteStream);
|
||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = EntityMessage.parseSpawnItemMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETPOSITION:
|
||||
if(EntityMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = EntityMessage.parseSetPositionMessage(byteStream);
|
||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = EntityMessage.parseSetPositionMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETFACING:
|
||||
if(EntityMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = EntityMessage.parsesetFacingMessage(byteStream);
|
||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = EntityMessage.parsesetFacingMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_MOVEUPDATE:
|
||||
if(EntityMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = EntityMessage.parsemoveUpdateMessage(byteStream);
|
||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = EntityMessage.parsemoveUpdateMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_ATTACKUPDATE:
|
||||
if(EntityMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = EntityMessage.parseattackUpdateMessage(byteStream);
|
||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = EntityMessage.parseattackUpdateMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_MOVE:
|
||||
if(EntityMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = EntityMessage.parseMoveMessage(byteStream);
|
||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = EntityMessage.parseMoveMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_KILL:
|
||||
if(EntityMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = EntityMessage.parseKillMessage(byteStream);
|
||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = EntityMessage.parseKillMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_DESTROY:
|
||||
if(EntityMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = EntityMessage.parseDestroyMessage(byteStream);
|
||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = EntityMessage.parseDestroyMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETBEHAVIORTREE:
|
||||
if(EntityMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = EntityMessage.parseSetBehaviorTreeMessage(byteStream);
|
||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = EntityMessage.parseSetBehaviorTreeMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETPROPERTY:
|
||||
if(EntityMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = EntityMessage.parsesetPropertyMessage(byteStream);
|
||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = EntityMessage.parsesetPropertyMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYINT:
|
||||
if(EntityMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = EntityMessage.parsesetBTreePropertyIntMessage(byteStream);
|
||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = EntityMessage.parsesetBTreePropertyIntMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYFLOAT:
|
||||
if(EntityMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = EntityMessage.parsesetBTreePropertyFloatMessage(byteStream);
|
||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = EntityMessage.parsesetBTreePropertyFloatMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYDOUBLE:
|
||||
if(EntityMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = EntityMessage.parsesetBTreePropertyDoubleMessage(byteStream);
|
||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = EntityMessage.parsesetBTreePropertyDoubleMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYSTRING:
|
||||
if(EntityMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = EntityMessage.parsesetBTreePropertyStringMessage(byteStream);
|
||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = EntityMessage.parsesetBTreePropertyStringMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYENUM:
|
||||
if(EntityMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = EntityMessage.parsesetBTreePropertyEnumMessage(byteStream);
|
||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = EntityMessage.parsesetBTreePropertyEnumMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.ENTITY_MESSAGE_TYPE_ATTACHENTITYTOENTITY:
|
||||
if(EntityMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = EntityMessage.parseattachEntityToEntityMessage(byteStream);
|
||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = EntityMessage.parseattachEntityToEntityMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TypeBytes.MESSAGE_TYPE_LORE:
|
||||
secondByte = byteStream.get(1);
|
||||
secondByte = byteBuffer.peek(1);
|
||||
switch(secondByte){
|
||||
case TypeBytes.LORE_MESSAGE_TYPE_REQUESTRACES:
|
||||
if(LoreMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = LoreMessage.parseRequestRacesMessage(byteStream);
|
||||
if(LoreMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = LoreMessage.parseRequestRacesMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.LORE_MESSAGE_TYPE_RESPONSERACES:
|
||||
if(LoreMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = LoreMessage.parseResponseRacesMessage(byteStream);
|
||||
if(LoreMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = LoreMessage.parseResponseRacesMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.LORE_MESSAGE_TYPE_REQUESTRACEDATA:
|
||||
if(LoreMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = LoreMessage.parseRequestRaceDataMessage(byteStream);
|
||||
if(LoreMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = LoreMessage.parseRequestRaceDataMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.LORE_MESSAGE_TYPE_RESPONSERACEDATA:
|
||||
if(LoreMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = LoreMessage.parseResponseRaceDataMessage(byteStream);
|
||||
if(LoreMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = LoreMessage.parseResponseRaceDataMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.LORE_MESSAGE_TYPE_REQUESTDATA:
|
||||
if(LoreMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = LoreMessage.parseRequestDataMessage(byteStream);
|
||||
if(LoreMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = LoreMessage.parseRequestDataMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.LORE_MESSAGE_TYPE_RESPONSEDATA:
|
||||
if(LoreMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = LoreMessage.parseResponseDataMessage(byteStream);
|
||||
if(LoreMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = LoreMessage.parseResponseDataMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TypeBytes.MESSAGE_TYPE_PLAYER:
|
||||
secondByte = byteStream.get(1);
|
||||
secondByte = byteBuffer.peek(1);
|
||||
switch(secondByte){
|
||||
case TypeBytes.PLAYER_MESSAGE_TYPE_SET_ID:
|
||||
if(PlayerMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = PlayerMessage.parseSet_IDMessage(byteStream);
|
||||
if(PlayerMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = PlayerMessage.parseSet_IDMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.PLAYER_MESSAGE_TYPE_SETINITIALDISCRETEPOSITION:
|
||||
if(PlayerMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = PlayerMessage.parseSetInitialDiscretePositionMessage(byteStream);
|
||||
if(PlayerMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = PlayerMessage.parseSetInitialDiscretePositionMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TypeBytes.MESSAGE_TYPE_TERRAIN:
|
||||
secondByte = byteStream.get(1);
|
||||
secondByte = byteBuffer.peek(1);
|
||||
switch(secondByte){
|
||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTMETADATA:
|
||||
if(TerrainMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = TerrainMessage.parseRequestMetadataMessage(byteStream);
|
||||
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = TerrainMessage.parseRequestMetadataMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_RESPONSEMETADATA:
|
||||
if(TerrainMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = TerrainMessage.parseResponseMetadataMessage(byteStream);
|
||||
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = TerrainMessage.parseResponseMetadataMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTCHUNK:
|
||||
if(TerrainMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = TerrainMessage.parseRequestChunkMessage(byteStream);
|
||||
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = TerrainMessage.parseRequestChunkMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_UPDATE:
|
||||
if(TerrainMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = TerrainMessage.parseUpdateMessage(byteStream);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_CHUNKLOADSTART:
|
||||
if(TerrainMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = TerrainMessage.parsechunkLoadStartMessage(byteStream);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_MACROVALUE:
|
||||
if(TerrainMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = TerrainMessage.parseMacroValueMessage(byteStream);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_HEIGHTMAPMODIFICATION:
|
||||
if(TerrainMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = TerrainMessage.parseheightMapModificationMessage(byteStream);
|
||||
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = TerrainMessage.parseUpdateMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_SPAWNPOSITION:
|
||||
if(TerrainMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = TerrainMessage.parseSpawnPositionMessage(byteStream);
|
||||
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = TerrainMessage.parseSpawnPositionMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTCHUNKDATA:
|
||||
if(TerrainMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = TerrainMessage.parseRequestChunkDataMessage(byteStream);
|
||||
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = TerrainMessage.parseRequestChunkDataMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_SENDCHUNKDATA:
|
||||
if(TerrainMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = TerrainMessage.parsesendChunkDataMessage(byteStream);
|
||||
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = TerrainMessage.parsesendChunkDataMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TypeBytes.MESSAGE_TYPE_SERVER:
|
||||
secondByte = byteStream.get(1);
|
||||
secondByte = byteBuffer.peek(1);
|
||||
switch(secondByte){
|
||||
case TypeBytes.SERVER_MESSAGE_TYPE_PING:
|
||||
if(ServerMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = ServerMessage.parsePingMessage(byteStream);
|
||||
if(ServerMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = ServerMessage.parsePingMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.SERVER_MESSAGE_TYPE_PONG:
|
||||
if(ServerMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = ServerMessage.parsePongMessage(byteStream);
|
||||
if(ServerMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = ServerMessage.parsePongMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TypeBytes.MESSAGE_TYPE_AUTH:
|
||||
secondByte = byteStream.get(1);
|
||||
secondByte = byteBuffer.peek(1);
|
||||
switch(secondByte){
|
||||
case TypeBytes.AUTH_MESSAGE_TYPE_AUTHREQUEST:
|
||||
if(AuthMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = AuthMessage.parseAuthRequestMessage(byteStream);
|
||||
if(AuthMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = AuthMessage.parseAuthRequestMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.AUTH_MESSAGE_TYPE_AUTHDETAILS:
|
||||
if(AuthMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = AuthMessage.parseAuthDetailsMessage(byteStream);
|
||||
if(AuthMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = AuthMessage.parseAuthDetailsMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.AUTH_MESSAGE_TYPE_AUTHSUCCESS:
|
||||
if(AuthMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = AuthMessage.parseAuthSuccessMessage(byteStream);
|
||||
if(AuthMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = AuthMessage.parseAuthSuccessMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.AUTH_MESSAGE_TYPE_AUTHFAILURE:
|
||||
if(AuthMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = AuthMessage.parseAuthFailureMessage(byteStream);
|
||||
if(AuthMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = AuthMessage.parseAuthFailureMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TypeBytes.MESSAGE_TYPE_CHARACTER:
|
||||
secondByte = byteStream.get(1);
|
||||
secondByte = byteBuffer.peek(1);
|
||||
switch(secondByte){
|
||||
case TypeBytes.CHARACTER_MESSAGE_TYPE_REQUESTCHARACTERLIST:
|
||||
if(CharacterMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = CharacterMessage.parseRequestCharacterListMessage(byteStream);
|
||||
if(CharacterMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = CharacterMessage.parseRequestCharacterListMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.CHARACTER_MESSAGE_TYPE_RESPONSECHARACTERLIST:
|
||||
if(CharacterMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = CharacterMessage.parseResponseCharacterListMessage(byteStream);
|
||||
if(CharacterMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = CharacterMessage.parseResponseCharacterListMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.CHARACTER_MESSAGE_TYPE_REQUESTCREATECHARACTER:
|
||||
if(CharacterMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = CharacterMessage.parseRequestCreateCharacterMessage(byteStream);
|
||||
if(CharacterMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = CharacterMessage.parseRequestCreateCharacterMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.CHARACTER_MESSAGE_TYPE_RESPONSECREATECHARACTERSUCCESS:
|
||||
if(CharacterMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = CharacterMessage.parseResponseCreateCharacterSuccessMessage(byteStream);
|
||||
if(CharacterMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = CharacterMessage.parseResponseCreateCharacterSuccessMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.CHARACTER_MESSAGE_TYPE_RESPONSECREATECHARACTERFAILURE:
|
||||
if(CharacterMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = CharacterMessage.parseResponseCreateCharacterFailureMessage(byteStream);
|
||||
if(CharacterMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = CharacterMessage.parseResponseCreateCharacterFailureMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.CHARACTER_MESSAGE_TYPE_REQUESTSPAWNCHARACTER:
|
||||
if(CharacterMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = CharacterMessage.parseRequestSpawnCharacterMessage(byteStream);
|
||||
if(CharacterMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = CharacterMessage.parseRequestSpawnCharacterMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.CHARACTER_MESSAGE_TYPE_RESPONSESPAWNCHARACTER:
|
||||
if(CharacterMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = CharacterMessage.parseResponseSpawnCharacterMessage(byteStream);
|
||||
if(CharacterMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = CharacterMessage.parseResponseSpawnCharacterMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TypeBytes.MESSAGE_TYPE_INVENTORY:
|
||||
secondByte = byteStream.get(1);
|
||||
secondByte = byteBuffer.peek(1);
|
||||
switch(secondByte){
|
||||
case TypeBytes.INVENTORY_MESSAGE_TYPE_ADDITEMTOINVENTORY:
|
||||
if(InventoryMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = InventoryMessage.parseaddItemToInventoryMessage(byteStream);
|
||||
if(InventoryMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = InventoryMessage.parseaddItemToInventoryMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.INVENTORY_MESSAGE_TYPE_REMOVEITEMFROMINVENTORY:
|
||||
if(InventoryMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = InventoryMessage.parseremoveItemFromInventoryMessage(byteStream);
|
||||
if(InventoryMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = InventoryMessage.parseremoveItemFromInventoryMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTEQUIPITEM:
|
||||
if(InventoryMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = InventoryMessage.parseclientRequestEquipItemMessage(byteStream);
|
||||
if(InventoryMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = InventoryMessage.parseclientRequestEquipItemMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.INVENTORY_MESSAGE_TYPE_SERVERCOMMANDMOVEITEMCONTAINER:
|
||||
if(InventoryMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = InventoryMessage.parseserverCommandMoveItemContainerMessage(byteStream);
|
||||
if(InventoryMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = InventoryMessage.parseserverCommandMoveItemContainerMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.INVENTORY_MESSAGE_TYPE_SERVERCOMMANDEQUIPITEM:
|
||||
if(InventoryMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = InventoryMessage.parseserverCommandEquipItemMessage(byteStream);
|
||||
if(InventoryMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = InventoryMessage.parseserverCommandEquipItemMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.INVENTORY_MESSAGE_TYPE_SERVERCOMMANDUNEQUIPITEM:
|
||||
if(InventoryMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = InventoryMessage.parseserverCommandUnequipItemMessage(byteStream);
|
||||
if(InventoryMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = InventoryMessage.parseserverCommandUnequipItemMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTUNEQUIPITEM:
|
||||
if(InventoryMessage.canParseMessage(byteStream,secondByte)){
|
||||
rVal = InventoryMessage.parseclientRequestUnequipItemMessage(byteStream);
|
||||
if(InventoryMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = InventoryMessage.parseclientRequestUnequipItemMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package electrosphere.net.parser.net.message;
|
||||
|
||||
import electrosphere.net.parser.util.ByteStreamUtils;
|
||||
import electrosphere.net.parser.net.raw.CircularByteBuffer;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
@ -58,21 +59,20 @@ public class PlayerMessage extends NetworkMessage {
|
||||
this.initialDiscretePositionZ = initialDiscretePositionZ;
|
||||
}
|
||||
|
||||
static void stripPacketHeader(List<Byte> byteStream){
|
||||
byteStream.remove(0);
|
||||
byteStream.remove(0);
|
||||
static void stripPacketHeader(CircularByteBuffer byteBuffer){
|
||||
byteBuffer.read(2);
|
||||
}
|
||||
|
||||
public static boolean canParseMessage(List<Byte> byteStream, byte secondByte){
|
||||
public static boolean canParseMessage(CircularByteBuffer byteBuffer, byte secondByte){
|
||||
switch(secondByte){
|
||||
case TypeBytes.PLAYER_MESSAGE_TYPE_SET_ID:
|
||||
if(byteStream.size() >= TypeBytes.PLAYER_MESSAGE_TYPE_SET_ID_SIZE){
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.PLAYER_MESSAGE_TYPE_SET_ID_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case TypeBytes.PLAYER_MESSAGE_TYPE_SETINITIALDISCRETEPOSITION:
|
||||
if(byteStream.size() >= TypeBytes.PLAYER_MESSAGE_TYPE_SETINITIALDISCRETEPOSITION_SIZE){
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.PLAYER_MESSAGE_TYPE_SETINITIALDISCRETEPOSITION_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@ -81,10 +81,10 @@ public class PlayerMessage extends NetworkMessage {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static PlayerMessage parseSet_IDMessage(List<Byte> byteStream){
|
||||
public static PlayerMessage parseSet_IDMessage(CircularByteBuffer byteBuffer){
|
||||
PlayerMessage rVal = new PlayerMessage(PlayerMessageType.SET_ID);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setplayerID(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setplayerID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -95,12 +95,12 @@ public class PlayerMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static PlayerMessage parseSetInitialDiscretePositionMessage(List<Byte> byteStream){
|
||||
public static PlayerMessage parseSetInitialDiscretePositionMessage(CircularByteBuffer byteBuffer){
|
||||
PlayerMessage rVal = new PlayerMessage(PlayerMessageType.SETINITIALDISCRETEPOSITION);
|
||||
stripPacketHeader(byteStream);
|
||||
rVal.setinitialDiscretePositionX(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.setinitialDiscretePositionY(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
rVal.setinitialDiscretePositionZ(ByteStreamUtils.popIntFromByteQueue(byteStream));
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setinitialDiscretePositionX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setinitialDiscretePositionY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setinitialDiscretePositionZ(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package electrosphere.net.parser.net.message;
|
||||
|
||||
import electrosphere.net.parser.util.ByteStreamUtils;
|
||||
import electrosphere.net.parser.net.raw.CircularByteBuffer;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
@ -22,21 +23,20 @@ public class ServerMessage extends NetworkMessage {
|
||||
return this.messageType;
|
||||
}
|
||||
|
||||
static void stripPacketHeader(List<Byte> byteStream){
|
||||
byteStream.remove(0);
|
||||
byteStream.remove(0);
|
||||
static void stripPacketHeader(CircularByteBuffer byteBuffer){
|
||||
byteBuffer.read(2);
|
||||
}
|
||||
|
||||
public static boolean canParseMessage(List<Byte> byteStream, byte secondByte){
|
||||
public static boolean canParseMessage(CircularByteBuffer byteBuffer, byte secondByte){
|
||||
switch(secondByte){
|
||||
case TypeBytes.SERVER_MESSAGE_TYPE_PING:
|
||||
if(byteStream.size() >= TypeBytes.SERVER_MESSAGE_TYPE_PING_SIZE){
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.SERVER_MESSAGE_TYPE_PING_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case TypeBytes.SERVER_MESSAGE_TYPE_PONG:
|
||||
if(byteStream.size() >= TypeBytes.SERVER_MESSAGE_TYPE_PONG_SIZE){
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.SERVER_MESSAGE_TYPE_PONG_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@ -45,9 +45,9 @@ public class ServerMessage extends NetworkMessage {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static ServerMessage parsePingMessage(List<Byte> byteStream){
|
||||
public static ServerMessage parsePingMessage(CircularByteBuffer byteBuffer){
|
||||
ServerMessage rVal = new ServerMessage(ServerMessageType.PING);
|
||||
stripPacketHeader(byteStream);
|
||||
stripPacketHeader(byteBuffer);
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -57,9 +57,9 @@ public class ServerMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static ServerMessage parsePongMessage(List<Byte> byteStream){
|
||||
public static ServerMessage parsePongMessage(CircularByteBuffer byteBuffer){
|
||||
ServerMessage rVal = new ServerMessage(ServerMessageType.PONG);
|
||||
stripPacketHeader(byteStream);
|
||||
stripPacketHeader(byteBuffer);
|
||||
return rVal;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -81,12 +81,9 @@ Message categories
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_RESPONSEMETADATA = 1;
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_REQUESTCHUNK = 2;
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_UPDATE = 3;
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_CHUNKLOADSTART = 4;
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_MACROVALUE = 5;
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_HEIGHTMAPMODIFICATION = 6;
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_SPAWNPOSITION = 7;
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_REQUESTCHUNKDATA = 8;
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_SENDCHUNKDATA = 9;
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_SPAWNPOSITION = 4;
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_REQUESTCHUNKDATA = 5;
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_SENDCHUNKDATA = 6;
|
||||
/*
|
||||
Terrain packet sizes
|
||||
*/
|
||||
@ -94,9 +91,6 @@ Message categories
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_RESPONSEMETADATA_SIZE = 30;
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_REQUESTCHUNK_SIZE = 10;
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_UPDATE_SIZE = 14;
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_CHUNKLOADSTART_SIZE = 14;
|
||||
public static final short TERRAIN_MESSAGE_TYPE_MACROVALUE_SIZE = 310;
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_HEIGHTMAPMODIFICATION_SIZE = 30;
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_SPAWNPOSITION_SIZE = 26;
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_REQUESTCHUNKDATA_SIZE = 14;
|
||||
/*
|
||||
|
||||
@ -0,0 +1,120 @@
|
||||
package electrosphere.net.parser.net.raw;
|
||||
|
||||
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
/**
|
||||
* A circular byte buffer optimized for high throughput (relative to a list) and peaking at early elements of the current position.
|
||||
*/
|
||||
public class CircularByteBuffer {
|
||||
|
||||
//The array backing this circular byte buffer
|
||||
byte[] backingArray;
|
||||
//the current read position of the buffer in the backing array
|
||||
int position;
|
||||
//the remaining bytes to read before the read position equals the write position
|
||||
int remaining;
|
||||
//the capacity of the backing array
|
||||
int capacity;
|
||||
//Lock to make the structure threadsafe
|
||||
Semaphore lock = new Semaphore(1);
|
||||
|
||||
/**
|
||||
* Constructs a CircularByteBuffer
|
||||
* @param capacity The capacity of the backing array in bytes
|
||||
*/
|
||||
public CircularByteBuffer(int capacity){
|
||||
backingArray = new byte[capacity];
|
||||
position = 0;
|
||||
remaining = 0;
|
||||
this.capacity = capacity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an array of bytes to the circular buffer
|
||||
* @param bytes The bytes
|
||||
* @param len The number of bytes to pull from the array bytes
|
||||
*/
|
||||
public void add(byte[] bytes, int len){
|
||||
lock.acquireUninterruptibly();
|
||||
// System.out.println("Add start");
|
||||
int writePosition = (position + remaining) % capacity;
|
||||
//amount possible to write before wrapping
|
||||
int writeBeforeWrap = capacity - writePosition;
|
||||
//only run wrapping logic if necessary
|
||||
if(len > writeBeforeWrap){
|
||||
System.arraycopy(bytes, 0, backingArray, writePosition, writeBeforeWrap);
|
||||
System.arraycopy(bytes, writeBeforeWrap, backingArray, 0, len - writeBeforeWrap);
|
||||
} else {
|
||||
System.arraycopy(bytes, 0, backingArray, writePosition, len);
|
||||
}
|
||||
remaining = remaining + len;
|
||||
lock.release();
|
||||
}
|
||||
|
||||
/**
|
||||
* Peeks at the next element in the buffer
|
||||
* @return The value of the byte next in the buffer
|
||||
*/
|
||||
public byte peek(){
|
||||
byte rVal = peek(0);
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Peeks at an element @param offset elements further along the buffer from the current position
|
||||
* @param offset The offset, in bytes, to look forward in the buffer
|
||||
* @return The value of the byte at the current position + @param offset
|
||||
*/
|
||||
public byte peek(int offset){
|
||||
lock.acquireUninterruptibly();
|
||||
byte rVal = backingArray[(position + offset) % capacity];
|
||||
lock.release();
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the remaining number of bytes in the buffer
|
||||
* @return The remaining number of bytes
|
||||
*/
|
||||
public int getRemaining(){
|
||||
lock.acquireUninterruptibly();
|
||||
int rVal = remaining;
|
||||
lock.release();
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the capacity of the buffer
|
||||
* @return The capacity
|
||||
*/
|
||||
public int getCapacity(){
|
||||
lock.acquireUninterruptibly();
|
||||
int rVal = capacity;
|
||||
lock.release();
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a given number of bytes from the buffer
|
||||
* @param len The number of bytes to read
|
||||
* @return The bytes in an array
|
||||
*/
|
||||
public byte[] read(int len){
|
||||
lock.acquireUninterruptibly();
|
||||
byte[] rVal = new byte[len];
|
||||
//amount possible to read before loop
|
||||
int toReadBeforeLoop = capacity - position;
|
||||
if(len > capacity - position){
|
||||
System.arraycopy(backingArray, position, rVal, 0, toReadBeforeLoop);
|
||||
System.arraycopy(backingArray, 0, rVal, toReadBeforeLoop, len - toReadBeforeLoop);
|
||||
} else {
|
||||
System.arraycopy(backingArray, position, rVal, 0, len);
|
||||
}
|
||||
position = (position + len) % capacity;
|
||||
remaining = remaining - len;
|
||||
lock.release();
|
||||
return rVal;
|
||||
}
|
||||
|
||||
}
|
||||
@ -15,7 +15,7 @@ public class NetworkParser {
|
||||
CopyOnWriteArrayList<NetworkMessage> incomingMessageQueue = new CopyOnWriteArrayList<NetworkMessage>();
|
||||
CopyOnWriteArrayList<NetworkMessage> outgoingMessageQueue = new CopyOnWriteArrayList<NetworkMessage>();
|
||||
|
||||
CopyOnWriteArrayList<Byte> incomingByteQueue = new CopyOnWriteArrayList<Byte>();
|
||||
CircularByteBuffer incomingByteBuffer = new CircularByteBuffer(64 * 1024 * 124);
|
||||
CopyOnWriteArrayList<Byte> outgoingByteQueue = new CopyOnWriteArrayList<Byte>();
|
||||
|
||||
|
||||
@ -29,24 +29,24 @@ public class NetworkParser {
|
||||
|
||||
}
|
||||
|
||||
static final int READ_BUFFER_SIZE = 64 * 1024 * 1024;
|
||||
byte[] readBuffer = new byte[READ_BUFFER_SIZE];
|
||||
public void readMessagesIn(){
|
||||
try {
|
||||
//read in bytes
|
||||
int nextValue = 0;
|
||||
int bytesRead = 0;
|
||||
byte currentByte = -1;
|
||||
while(incomingStream.available() > 0){
|
||||
nextValue = incomingStream.read();
|
||||
if(nextValue != -1){
|
||||
currentByte = (byte)nextValue;
|
||||
incomingByteQueue.add(currentByte);
|
||||
// System.out.println(currentByte);
|
||||
// nextValue = incomingStream.read();
|
||||
bytesRead = incomingStream.read(readBuffer, 0, READ_BUFFER_SIZE);
|
||||
if(bytesRead > 0){
|
||||
incomingByteBuffer.add(readBuffer, bytesRead);
|
||||
}
|
||||
//add bytes to some kind of queue
|
||||
}
|
||||
//parse byte queue for messages
|
||||
//for each message, append to clientIncomingMessageQueue
|
||||
NetworkMessage newMessage;
|
||||
while((newMessage = NetworkMessage.parseBytestreamForMessage(incomingByteQueue))!=null){
|
||||
while((newMessage = NetworkMessage.parseBytestreamForMessage(incomingByteBuffer))!=null){
|
||||
incomingMessageQueue.add(newMessage);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package electrosphere.net.parser.util;
|
||||
|
||||
import electrosphere.net.parser.net.raw.CircularByteBuffer;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Semaphore;
|
||||
@ -107,6 +109,96 @@ public class ByteStreamUtils {
|
||||
bufferLock.release();
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static int popIntFromByteQueue(CircularByteBuffer byteBuffer){
|
||||
int rVal = -1;
|
||||
bufferLock.acquireUninterruptibly();
|
||||
integerCompactor.clear();
|
||||
integerCompactor.position(0);
|
||||
integerCompactor.limit(4);
|
||||
integerCompactor.put(0,byteBuffer.peek(0));
|
||||
integerCompactor.put(1,byteBuffer.peek(1));
|
||||
integerCompactor.put(2,byteBuffer.peek(2));
|
||||
integerCompactor.put(3,byteBuffer.peek(3));
|
||||
byteBuffer.read(4);
|
||||
integerCompactor.position(0);
|
||||
integerCompactor.limit(4);
|
||||
rVal = integerCompactor.getInt();
|
||||
bufferLock.release();
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static float popFloatFromByteQueue(CircularByteBuffer byteBuffer){
|
||||
float rVal = -1;
|
||||
bufferLock.acquireUninterruptibly();
|
||||
integerCompactor.clear();
|
||||
integerCompactor.position(0);
|
||||
integerCompactor.limit(4);
|
||||
integerCompactor.put(0,byteBuffer.read(1));
|
||||
integerCompactor.put(1,byteBuffer.read(1));
|
||||
integerCompactor.put(2,byteBuffer.read(1));
|
||||
integerCompactor.put(3,byteBuffer.read(1));
|
||||
integerCompactor.position(0);
|
||||
integerCompactor.limit(4);
|
||||
rVal = integerCompactor.getFloat();
|
||||
bufferLock.release();
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static long popLongFromByteQueue(CircularByteBuffer byteBuffer){
|
||||
long rVal = -1;
|
||||
bufferLock.acquireUninterruptibly();
|
||||
integerCompactor.clear();
|
||||
integerCompactor.position(0);
|
||||
integerCompactor.limit(8);
|
||||
integerCompactor.put(0,byteBuffer.read(1));
|
||||
integerCompactor.put(1,byteBuffer.read(1));
|
||||
integerCompactor.put(2,byteBuffer.read(1));
|
||||
integerCompactor.put(3,byteBuffer.read(1));
|
||||
integerCompactor.put(4,byteBuffer.read(1));
|
||||
integerCompactor.put(5,byteBuffer.read(1));
|
||||
integerCompactor.put(6,byteBuffer.read(1));
|
||||
integerCompactor.put(7,byteBuffer.read(1));
|
||||
integerCompactor.position(0);
|
||||
integerCompactor.limit(8);
|
||||
rVal = integerCompactor.getLong();
|
||||
bufferLock.release();
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static String popStringFromByteQueue(CircularByteBuffer byteBuffer){
|
||||
int length = popIntFromByteQueue(byteBuffer);
|
||||
byte[] stringBytes = byteBuffer.read(length);
|
||||
String rVal = new String(stringBytes);
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static byte[] popByteArrayFromByteQueue(CircularByteBuffer byteBuffer){
|
||||
int length = popIntFromByteQueue(byteBuffer);
|
||||
byte[] bytes = byteBuffer.read(length);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static double popDoubleFromByteQueue(CircularByteBuffer byteBuffer){
|
||||
double rVal = -1;
|
||||
bufferLock.acquireUninterruptibly();
|
||||
integerCompactor.clear();
|
||||
integerCompactor.position(0);
|
||||
integerCompactor.limit(8);
|
||||
integerCompactor.put(0,byteBuffer.read(1));
|
||||
integerCompactor.put(1,byteBuffer.read(1));
|
||||
integerCompactor.put(2,byteBuffer.read(1));
|
||||
integerCompactor.put(3,byteBuffer.read(1));
|
||||
integerCompactor.put(4,byteBuffer.read(1));
|
||||
integerCompactor.put(5,byteBuffer.read(1));
|
||||
integerCompactor.put(6,byteBuffer.read(1));
|
||||
integerCompactor.put(7,byteBuffer.read(1));
|
||||
integerCompactor.position(0);
|
||||
integerCompactor.limit(8);
|
||||
rVal = integerCompactor.getDouble();
|
||||
bufferLock.release();
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static byte[] serializeIntToBytes(int i){
|
||||
byte[] rVal = new byte[4];
|
||||
|
||||
@ -1,5 +1,10 @@
|
||||
package electrosphere.net.server.protocol;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
|
||||
import electrosphere.client.terrain.cache.ChunkData;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.net.parser.net.message.TerrainMessage;
|
||||
import electrosphere.net.server.Server;
|
||||
@ -12,25 +17,27 @@ public class TerrainProtocol {
|
||||
protected static void handleTerrainMessage(ServerConnectionHandler connectionHandler, TerrainMessage message){
|
||||
switch(message.getMessageSubtype()){
|
||||
case REQUESTCHUNK:
|
||||
sendWorldChunk(connectionHandler, message.getworldX(), message.getworldY());
|
||||
// sendWorldChunk(connectionHandler, message.getworldX(), message.getworldY());
|
||||
break;
|
||||
case REQUESTMETADATA:
|
||||
sendWorldMetadata(connectionHandler);
|
||||
break;
|
||||
|
||||
case REQUESTCHUNKDATA:
|
||||
sendWorldSubChunk(connectionHandler,
|
||||
message.getworldX(), message.getworldY(), message.getworldZ()
|
||||
);
|
||||
break;
|
||||
//all ignored message types
|
||||
case CHUNKLOADSTART:
|
||||
case HEIGHTMAPMODIFICATION:
|
||||
case MACROVALUE:
|
||||
case RESPONSEMETADATA:
|
||||
case SPAWNPOSITION:
|
||||
case UPDATE:
|
||||
case SENDCHUNKDATA:
|
||||
//silently ignore
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void sendWorldChunk(ServerConnectionHandler connectionHandler, int worldX, int worldY){
|
||||
static void sendWorldSubChunk(ServerConnectionHandler connectionHandler, int worldX, int worldY, int worldZ){
|
||||
/*
|
||||
int locationX,
|
||||
int locationY,
|
||||
@ -56,92 +63,117 @@ public class TerrainProtocol {
|
||||
|
||||
// System.out.println("Received request for chunk " + message.getworldX() + " " + message.getworldY());
|
||||
|
||||
ServerTerrainChunk chunk = Globals.serverTerrainManager.getChunk(worldX, worldY);
|
||||
ServerTerrainChunk chunk = Globals.serverTerrainManager.getChunk(worldX, worldY, worldZ);
|
||||
|
||||
float[][] macroValues = chunk.getMacroValues();//Globals.serverTerrainManager.getRad5MacroValues(message.getworldX(), message.getworldY());
|
||||
// float[][] macroValues = chunk.getMacroValues();//Globals.serverTerrainManager.getRad5MacroValues(message.getworldX(), message.getworldY());
|
||||
|
||||
long[][] randomizer = chunk.getRandomizer();//Globals.serverTerrainManager.getRandomizer(message.getworldX(), message.getworldY());
|
||||
// long[][] randomizer = chunk.getRandomizer();//Globals.serverTerrainManager.getRandomizer(message.getworldX(), message.getworldY());
|
||||
|
||||
int numMessages = 2 + chunk.getModifications().size();
|
||||
ByteBuffer buffer = ByteBuffer.allocate(ServerTerrainChunk.CHUNK_DIMENSION*ServerTerrainChunk.CHUNK_DIMENSION*ServerTerrainChunk.CHUNK_DIMENSION*(4+4));
|
||||
FloatBuffer floatView = buffer.asFloatBuffer();
|
||||
|
||||
connectionHandler.addMessagetoOutgoingQueue(
|
||||
TerrainMessage.constructchunkLoadStartMessage(worldX, worldY, numMessages)
|
||||
);
|
||||
|
||||
connectionHandler.addMessagetoOutgoingQueue(
|
||||
TerrainMessage.constructMacroValueMessage(
|
||||
worldX,
|
||||
worldY,
|
||||
|
||||
|
||||
macroValues[0][0],
|
||||
macroValues[0][1],
|
||||
macroValues[0][2],
|
||||
macroValues[0][3],
|
||||
macroValues[0][4],
|
||||
macroValues[1][0],
|
||||
macroValues[1][1],
|
||||
macroValues[1][2],
|
||||
macroValues[1][3],
|
||||
macroValues[1][4],
|
||||
macroValues[2][0],
|
||||
macroValues[2][1],
|
||||
macroValues[2][2],
|
||||
macroValues[2][3],
|
||||
macroValues[2][4],
|
||||
macroValues[3][0],
|
||||
macroValues[3][1],
|
||||
macroValues[3][2],
|
||||
macroValues[3][3],
|
||||
macroValues[3][4],
|
||||
macroValues[4][0],
|
||||
macroValues[4][1],
|
||||
macroValues[4][2],
|
||||
macroValues[4][3],
|
||||
macroValues[4][4],
|
||||
|
||||
|
||||
randomizer[0][0],
|
||||
randomizer[0][1],
|
||||
randomizer[0][2],
|
||||
randomizer[0][3],
|
||||
randomizer[0][4],
|
||||
randomizer[1][0],
|
||||
randomizer[1][1],
|
||||
randomizer[1][2],
|
||||
randomizer[1][3],
|
||||
randomizer[1][4],
|
||||
randomizer[2][0],
|
||||
randomizer[2][1],
|
||||
randomizer[2][2],
|
||||
randomizer[2][3],
|
||||
randomizer[2][4],
|
||||
randomizer[3][0],
|
||||
randomizer[3][1],
|
||||
randomizer[3][2],
|
||||
randomizer[3][3],
|
||||
randomizer[3][4],
|
||||
randomizer[4][0],
|
||||
randomizer[4][1],
|
||||
randomizer[4][2],
|
||||
randomizer[4][3],
|
||||
randomizer[4][4]
|
||||
)
|
||||
);
|
||||
|
||||
for(TerrainModification modification : chunk.getModifications()){
|
||||
connectionHandler.addMessagetoOutgoingQueue(
|
||||
TerrainMessage.constructheightMapModificationMessage(
|
||||
modification.getValue(),
|
||||
modification.getWorldX(),
|
||||
0,
|
||||
modification.getWorldY(),
|
||||
modification.getLocationX(),
|
||||
0,
|
||||
modification.getLocationY()
|
||||
)
|
||||
);
|
||||
for(int x = 0; x < ServerTerrainChunk.CHUNK_DIMENSION; x++){
|
||||
for(int y = 0; y < ServerTerrainChunk.CHUNK_DIMENSION; y++){
|
||||
for(int z = 0; z < ServerTerrainChunk.CHUNK_DIMENSION; z++){
|
||||
floatView.put(chunk.getWeights()[x][y][z]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IntBuffer intView = buffer.asIntBuffer();
|
||||
intView.position(floatView.position());
|
||||
|
||||
for(int x = 0; x < ServerTerrainChunk.CHUNK_DIMENSION; x++){
|
||||
for(int y = 0; y < ServerTerrainChunk.CHUNK_DIMENSION; y++){
|
||||
for(int z = 0; z < ServerTerrainChunk.CHUNK_DIMENSION; z++){
|
||||
intView.put(chunk.getValues()[x][y][z]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
connectionHandler.addMessagetoOutgoingQueue(TerrainMessage.constructsendChunkDataMessage(worldX, worldY, worldZ, buffer.array()));
|
||||
|
||||
// int numMessages = 2 + chunk.getModifications().size();
|
||||
|
||||
// connectionHandler.addMessagetoOutgoingQueue(
|
||||
// TerrainMessage.constructchunkLoadStartMessage(worldX, worldY, numMessages)
|
||||
// );
|
||||
|
||||
// connectionHandler.addMessagetoOutgoingQueue(
|
||||
// TerrainMessage.constructMacroValueMessage(
|
||||
// worldX,
|
||||
// worldY,
|
||||
|
||||
|
||||
// macroValues[0][0],
|
||||
// macroValues[0][1],
|
||||
// macroValues[0][2],
|
||||
// macroValues[0][3],
|
||||
// macroValues[0][4],
|
||||
// macroValues[1][0],
|
||||
// macroValues[1][1],
|
||||
// macroValues[1][2],
|
||||
// macroValues[1][3],
|
||||
// macroValues[1][4],
|
||||
// macroValues[2][0],
|
||||
// macroValues[2][1],
|
||||
// macroValues[2][2],
|
||||
// macroValues[2][3],
|
||||
// macroValues[2][4],
|
||||
// macroValues[3][0],
|
||||
// macroValues[3][1],
|
||||
// macroValues[3][2],
|
||||
// macroValues[3][3],
|
||||
// macroValues[3][4],
|
||||
// macroValues[4][0],
|
||||
// macroValues[4][1],
|
||||
// macroValues[4][2],
|
||||
// macroValues[4][3],
|
||||
// macroValues[4][4],
|
||||
|
||||
|
||||
// randomizer[0][0],
|
||||
// randomizer[0][1],
|
||||
// randomizer[0][2],
|
||||
// randomizer[0][3],
|
||||
// randomizer[0][4],
|
||||
// randomizer[1][0],
|
||||
// randomizer[1][1],
|
||||
// randomizer[1][2],
|
||||
// randomizer[1][3],
|
||||
// randomizer[1][4],
|
||||
// randomizer[2][0],
|
||||
// randomizer[2][1],
|
||||
// randomizer[2][2],
|
||||
// randomizer[2][3],
|
||||
// randomizer[2][4],
|
||||
// randomizer[3][0],
|
||||
// randomizer[3][1],
|
||||
// randomizer[3][2],
|
||||
// randomizer[3][3],
|
||||
// randomizer[3][4],
|
||||
// randomizer[4][0],
|
||||
// randomizer[4][1],
|
||||
// randomizer[4][2],
|
||||
// randomizer[4][3],
|
||||
// randomizer[4][4]
|
||||
// )
|
||||
// );
|
||||
|
||||
// for(TerrainModification modification : chunk.getModifications()){
|
||||
// connectionHandler.addMessagetoOutgoingQueue(
|
||||
// TerrainMessage.constructheightMapModificationMessage(
|
||||
// modification.getValue(),
|
||||
// modification.getWorldX(),
|
||||
// 0,
|
||||
// modification.getWorldY(),
|
||||
// modification.getLocationX(),
|
||||
// 0,
|
||||
// modification.getLocationY()
|
||||
// )
|
||||
// );
|
||||
// }
|
||||
}
|
||||
|
||||
static void sendWorldMetadata(ServerConnectionHandler connectionHandler){
|
||||
|
||||
@ -1,15 +1,8 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package electrosphere.renderer;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.renderer.texture.Texture;
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.assimp.AIMaterial;
|
||||
import org.lwjgl.assimp.AIMaterialProperty;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
|
||||
import static org.lwjgl.opengl.GL11.glBindTexture;
|
||||
import static org.lwjgl.opengl.GL13.GL_TEXTURE0;
|
||||
@ -27,6 +20,8 @@ public class Material {
|
||||
String specular;
|
||||
boolean hasTransparency = false;
|
||||
|
||||
//Sets whether this material should get its texture pointers from the assetManager by looking up diffuse and specular paths
|
||||
//or whether it should have a manually set texturePointer and not look up while binding
|
||||
boolean usesFetch = true;
|
||||
|
||||
int texturePointer;
|
||||
@ -70,8 +65,11 @@ public class Material {
|
||||
usesFetch = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the material
|
||||
*/
|
||||
public void apply_material(){
|
||||
//basically a switch for the case where we want to manually set texture pointer
|
||||
//Controls whether the texturePointer should be resolved by looking up the diffuse in asset manager or using the texture pointer already set in this material
|
||||
if(usesFetch){
|
||||
Texture diffuseTexture = Globals.assetManager.fetchTexture(diffuse);
|
||||
if(diffuseTexture != null){
|
||||
|
||||
@ -132,40 +132,41 @@ public class InstanceData {
|
||||
*/
|
||||
protected void fillBuffers(){
|
||||
int i = 0;
|
||||
//reset all buffers
|
||||
//for some reason the limit is not being set correctly. This explicitly forces it for each buffer
|
||||
for(ShaderAttribute attribute : attributeIndices){
|
||||
switch(attributeGlBufferMap.get(attribute).getType()){
|
||||
case VEC3F: {
|
||||
FloatBuffer buffer = ((FloatBuffer)attributeCpuBufferMap.get(attribute));
|
||||
buffer.position(0);
|
||||
buffer.limit(buffer.capacity());
|
||||
} break;
|
||||
case VEC3D: {
|
||||
DoubleBuffer buffer = ((DoubleBuffer)attributeCpuBufferMap.get(attribute));
|
||||
buffer.position(0);
|
||||
buffer.limit(buffer.capacity());
|
||||
} break;
|
||||
case VEC4F: {
|
||||
FloatBuffer buffer = ((FloatBuffer)attributeCpuBufferMap.get(attribute));
|
||||
buffer.position(0);
|
||||
buffer.limit(buffer.capacity());
|
||||
} break;
|
||||
case VEC4D: {
|
||||
DoubleBuffer buffer = ((DoubleBuffer)attributeCpuBufferMap.get(attribute));
|
||||
buffer.position(0);
|
||||
buffer.limit(buffer.capacity());
|
||||
} break;
|
||||
case MAT4F: {
|
||||
FloatBuffer buffer = ((FloatBuffer)attributeCpuBufferMap.get(attribute));
|
||||
buffer.position(0);
|
||||
buffer.limit(buffer.capacity());
|
||||
// System.out.println(buffer.position() + " " + buffer.limit());
|
||||
} break;
|
||||
case DOUBLE: {
|
||||
DoubleBuffer buffer = ((DoubleBuffer)attributeCpuBufferMap.get(attribute));
|
||||
buffer.position(0);
|
||||
buffer.limit(buffer.capacity());
|
||||
} break;
|
||||
case FLOAT: {
|
||||
FloatBuffer buffer = ((FloatBuffer)attributeCpuBufferMap.get(attribute));
|
||||
buffer.position(0);
|
||||
buffer.limit(buffer.capacity());
|
||||
} break;
|
||||
case INT: {
|
||||
IntBuffer buffer = ((IntBuffer)attributeCpuBufferMap.get(attribute));
|
||||
buffer.position(0);
|
||||
buffer.limit(buffer.capacity());
|
||||
} break;
|
||||
}
|
||||
}
|
||||
@ -308,6 +309,46 @@ public class InstanceData {
|
||||
}
|
||||
}
|
||||
|
||||
protected void flip(){
|
||||
//reset all buffers
|
||||
for(ShaderAttribute attribute : attributeIndices){
|
||||
switch(attributeGlBufferMap.get(attribute).getType()){
|
||||
case VEC3F: {
|
||||
FloatBuffer buffer = ((FloatBuffer)attributeCpuBufferMap.get(attribute));
|
||||
buffer.flip();
|
||||
} break;
|
||||
case VEC3D: {
|
||||
DoubleBuffer buffer = ((DoubleBuffer)attributeCpuBufferMap.get(attribute));
|
||||
buffer.flip();
|
||||
} break;
|
||||
case VEC4F: {
|
||||
FloatBuffer buffer = ((FloatBuffer)attributeCpuBufferMap.get(attribute));
|
||||
buffer.flip();
|
||||
} break;
|
||||
case VEC4D: {
|
||||
DoubleBuffer buffer = ((DoubleBuffer)attributeCpuBufferMap.get(attribute));
|
||||
buffer.flip();
|
||||
} break;
|
||||
case MAT4F: {
|
||||
FloatBuffer buffer = ((FloatBuffer)attributeCpuBufferMap.get(attribute));
|
||||
buffer.flip();
|
||||
} break;
|
||||
case DOUBLE: {
|
||||
DoubleBuffer buffer = ((DoubleBuffer)attributeCpuBufferMap.get(attribute));
|
||||
buffer.flip();
|
||||
} break;
|
||||
case FLOAT: {
|
||||
FloatBuffer buffer = ((FloatBuffer)attributeCpuBufferMap.get(attribute));
|
||||
buffer.flip();
|
||||
} break;
|
||||
case INT: {
|
||||
IntBuffer buffer = ((IntBuffer)attributeCpuBufferMap.get(attribute));
|
||||
buffer.flip();
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a map of all attributes to the buffers of data for that attribute
|
||||
* @return The data buffers
|
||||
|
||||
@ -85,6 +85,8 @@ public class InstanceManager {
|
||||
model.draw(renderPipelineState);
|
||||
}
|
||||
|
||||
data.flip();
|
||||
|
||||
//clear queue
|
||||
data.clearDrawQueue();
|
||||
}
|
||||
|
||||
@ -790,6 +790,7 @@ public class TerrainChunkModelGeneration {
|
||||
Material groundMat = new Material();
|
||||
groundMat.set_diffuse("/Textures/Ground/Dirt1.png");
|
||||
groundMat.set_specular("/Textures/Ground/Dirt1.png");
|
||||
Globals.assetManager.addTexturePathtoQueue("/Textures/Ground/Dirt1.png");
|
||||
m.setMaterial(groundMat);
|
||||
|
||||
m.setShader(TerrainChunkModelGeneration.terrainChunkShaderProgram);
|
||||
@ -802,7 +803,7 @@ public class TerrainChunkModelGeneration {
|
||||
|
||||
//TODO: more optimal key creation
|
||||
private static String getVertKeyFromPoints(float x, float y, float z){
|
||||
return x + "-" + y + "-" + z;
|
||||
return x + "_" + y + "_" + z;
|
||||
}
|
||||
|
||||
private static int getVertIndex(Vector3f vert, Map<String,Integer> vertMap, List<Vector3f> verts){
|
||||
|
||||
@ -64,7 +64,7 @@ public class MillAbout extends AI {
|
||||
rand.nextFloat() - 0.5,
|
||||
rand.nextFloat() - 0.5
|
||||
).normalize().mul(millTargetMaxDist);
|
||||
moveVector.y = Globals.commonWorldData.getElevationAtPoint(new Vector3d(position).add(moveVector));
|
||||
moveVector.y = position.y; //Globals.commonWorldData.getElevationAtPoint(new Vector3d(position).add(moveVector));
|
||||
|
||||
//TODO: search in navmeshmanager to make sure navigable, otherwise generate new pos
|
||||
// }
|
||||
|
||||
@ -29,18 +29,18 @@ public class SeekTown extends AI {
|
||||
|
||||
@Override
|
||||
public void simulate() {
|
||||
if(target == null){
|
||||
if(Globals.macroData.getTowns().size() > 0){
|
||||
target = Globals.macroData.getTowns().get(0);
|
||||
targetPos = new Vector3d(
|
||||
Globals.commonWorldData.convertWorldToReal(target.getPositions().get(0).x),
|
||||
0,
|
||||
Globals.commonWorldData.convertWorldToReal(target.getPositions().get(0).y)
|
||||
);
|
||||
targetPos.y = Globals.commonWorldData.getElevationAtPoint(targetPos);
|
||||
System.out.println("Target pos: " + targetPos);
|
||||
}
|
||||
}
|
||||
// if(target == null){
|
||||
// if(Globals.macroData.getTowns().size() > 0){
|
||||
// target = Globals.macroData.getTowns().get(0);
|
||||
// targetPos = new Vector3d(
|
||||
// Globals.commonWorldData.convertWorldToReal(target.getPositions().get(0).x),
|
||||
// 0,
|
||||
// Globals.commonWorldData.convertWorldToReal(target.getPositions().get(0).y)
|
||||
// );
|
||||
// targetPos.y = Globals.commonWorldData.getElevationAtPoint(targetPos);
|
||||
// System.out.println("Target pos: " + targetPos);
|
||||
// }
|
||||
// }
|
||||
moveToTarget();
|
||||
}
|
||||
|
||||
|
||||
@ -24,14 +24,14 @@ public class EnvironmentGenerator {
|
||||
Random rand = new Random(randomizer);
|
||||
int targetNum = (int)(rand.nextFloat() * 10) + 10;
|
||||
for(int i = 0; i < targetNum; i++){
|
||||
Entity newTree = FoliageUtils.spawnBasicFoliage("FallOak1");
|
||||
cell.getScene().registerEntity(newTree);
|
||||
double posX = worldPos.x * Globals.serverWorldData.getDynamicInterpolationRatio() + (float)(rand.nextFloat() * Globals.serverWorldData.getDynamicInterpolationRatio());
|
||||
double posZ = worldPos.z * Globals.serverWorldData.getDynamicInterpolationRatio() + (float)(rand.nextFloat() * Globals.serverWorldData.getDynamicInterpolationRatio());
|
||||
double posY = Globals.serverTerrainManager.getHeightAtPosition(posX, posZ);
|
||||
// System.out.println("Spawning tree at: " + posX + "," + posY + "," + posZ);
|
||||
// CollisionObjUtils.positionCharacter(newTree, new Vector3f(posX,posY,posZ));
|
||||
EntityUtils.getPosition(newTree).set(posX,posY,posZ);
|
||||
// Entity newTree = FoliageUtils.spawnBasicFoliage("FallOak1");
|
||||
// cell.getScene().registerEntity(newTree);
|
||||
// double posX = worldPos.x * Globals.serverWorldData.getDynamicInterpolationRatio() + (float)(rand.nextFloat() * Globals.serverWorldData.getDynamicInterpolationRatio());
|
||||
// double posZ = worldPos.z * Globals.serverWorldData.getDynamicInterpolationRatio() + (float)(rand.nextFloat() * Globals.serverWorldData.getDynamicInterpolationRatio());
|
||||
// double posY = Globals.serverTerrainManager.getHeightAtPosition(posX, posZ);
|
||||
// // System.out.println("Spawning tree at: " + posX + "," + posY + "," + posZ);
|
||||
// // CollisionObjUtils.positionCharacter(newTree, new Vector3f(posX,posY,posZ));
|
||||
// EntityUtils.getPosition(newTree).set(posX,posY,posZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,7 +15,14 @@ public class ServerContentManager {
|
||||
//else create from scratch
|
||||
EnvironmentGenerator.generatePlains(cell, worldPos, Globals.serverTerrainManager.getRandomizerAtPoint(worldPos.x, worldPos.z));
|
||||
}
|
||||
cell.setNavMesh(NavMeshUtils.createMeshFromChunk(Globals.serverTerrainManager.getChunk(worldPos.x, worldPos.z),Globals.navMeshManager.getBlockerCache().getBlocker(worldPos.x, worldPos.z)));
|
||||
cell.setNavMesh(
|
||||
NavMeshUtils.createMeshFromChunk(Globals.serverTerrainManager.getChunk(
|
||||
worldPos.x,
|
||||
worldPos.y,
|
||||
worldPos.z
|
||||
),
|
||||
Globals.navMeshManager.getBlockerCache().getBlocker(worldPos.x, worldPos.z))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
package electrosphere.server.datacell;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3i;
|
||||
@ -16,29 +19,40 @@ import electrosphere.game.server.world.ServerWorldData;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.net.server.player.Player;
|
||||
import electrosphere.server.datacell.interfaces.DataCellManager;
|
||||
import electrosphere.server.datacell.physics.PhysicsDataCell;
|
||||
import electrosphere.server.terrain.manager.ServerTerrainManager;
|
||||
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
||||
|
||||
/**
|
||||
* Implementation of DataCellManager that lays out cells in a logical grid (array). Useful for eg 3d terrain gridded world.
|
||||
*/
|
||||
public class GriddedDataCellManager implements DataCellManager {
|
||||
//these are going to be the natural ground grid of data cells, but we're going to have more than this
|
||||
ServerDataCell[][][] groundDataCells;
|
||||
Map<String,ServerDataCell> groundDataCells = new HashMap<String,ServerDataCell>();
|
||||
//loaded cells
|
||||
Semaphore loadedCellsLock = new Semaphore(1);
|
||||
Set<ServerDataCell> loadedCells;
|
||||
int discreteWorldSize;
|
||||
//parent realm
|
||||
Realm parent;
|
||||
//Manager for terrain for this particular cell manager
|
||||
ServerTerrainManager serverTerrainManager;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param parent The gridded data cell manager's parent realm
|
||||
*/
|
||||
public GriddedDataCellManager(Realm parent) {
|
||||
public GriddedDataCellManager(Realm parent, ServerTerrainManager serverTerrainManager) {
|
||||
this.parent = parent;
|
||||
this.serverTerrainManager = serverTerrainManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the gridded data cell manager
|
||||
* @param data The server world data to back the manager with
|
||||
*/
|
||||
public void init(ServerWorldData data){
|
||||
discreteWorldSize = data.getWorldSizeDiscrete();
|
||||
groundDataCells = new ServerDataCell[discreteWorldSize][discreteWorldSize][discreteWorldSize];
|
||||
loadedCells = new HashSet<ServerDataCell>();
|
||||
}
|
||||
|
||||
@ -57,17 +71,24 @@ public class GriddedDataCellManager implements DataCellManager {
|
||||
y >= 0 && y < discreteWorldSize &&
|
||||
z >= 0 && z < discreteWorldSize
|
||||
){
|
||||
LoggerInterface.loggerEngine.DEBUG("TerrainDataCellManager: Add player to " + x + " " + y);
|
||||
if(groundDataCells[x][y][z] != null){
|
||||
groundDataCells[x][y][z].addPlayer(player);
|
||||
Vector3i targetPos = new Vector3i(x,y,z);
|
||||
LoggerInterface.loggerEngine.DEBUG("GriddedDataCellManager: Add player to " + x + " " + y + " " + z);
|
||||
if(groundDataCells.get(getServerDataCellKey(targetPos)) != null){
|
||||
groundDataCells.get(getServerDataCellKey(targetPos)).addPlayer(player);
|
||||
} else {
|
||||
LoggerInterface.loggerEngine.DEBUG("Creating new cell @ " + x + " " + y + " " + z);
|
||||
//create data cell
|
||||
groundDataCells[x][y][z] = ServerDataCell.createServerDataCell(new Scene());
|
||||
loadedCells.add(groundDataCells[x][y][z]);
|
||||
createServerDataCell(targetPos);
|
||||
///generates physics for the cell in a dedicated thread then finally registers
|
||||
runPhysicsGenerationThread(targetPos);
|
||||
//add to loaded cells
|
||||
loadedCellsLock.acquireUninterruptibly();
|
||||
loadedCells.add(groundDataCells.get(getServerDataCellKey(targetPos)));
|
||||
loadedCellsLock.release();
|
||||
//generate/handle content for new server data cell
|
||||
|
||||
//add player
|
||||
groundDataCells[x][y][z].addPlayer(player);
|
||||
groundDataCells.get(getServerDataCellKey(targetPos)).addPlayer(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -103,10 +124,11 @@ public class GriddedDataCellManager implements DataCellManager {
|
||||
z > newPosition.z + playerSimulationRadius
|
||||
)
|
||||
){
|
||||
if(groundDataCells[x][y][z] != null){
|
||||
if(groundDataCells[x][y][z].containsPlayer(player)){
|
||||
Vector3i targetPos = new Vector3i(x,y,z);
|
||||
if(groundDataCells.get(getServerDataCellKey(targetPos)) != null){
|
||||
if(groundDataCells.get(getServerDataCellKey(targetPos)).containsPlayer(player)){
|
||||
// removals++;
|
||||
groundDataCells[x][y][z].removePlayer(player);
|
||||
groundDataCells.get(getServerDataCellKey(targetPos)).removePlayer(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -129,14 +151,21 @@ public class GriddedDataCellManager implements DataCellManager {
|
||||
z > oldPosition.z + playerSimulationRadius
|
||||
)
|
||||
){
|
||||
Vector3i targetPos = new Vector3i(x,y,z);
|
||||
// System.out.println("Add player to " + x + " " + y);
|
||||
if(groundDataCells[x][y][z] != null){
|
||||
groundDataCells[x][y][z].addPlayer(player);
|
||||
if(groundDataCells.get(getServerDataCellKey(targetPos)) != null){
|
||||
groundDataCells.get(getServerDataCellKey(targetPos)).addPlayer(player);
|
||||
} else {
|
||||
//create data cell
|
||||
groundDataCells[x][y][z] = parent.createNewCell();
|
||||
createServerDataCell(targetPos);
|
||||
//generates physics for the cell in a dedicated thread then finally registers
|
||||
runPhysicsGenerationThread(targetPos);
|
||||
//add to loaded cells
|
||||
loadedCellsLock.acquireUninterruptibly();
|
||||
loadedCells.add(groundDataCells.get(getServerDataCellKey(targetPos)));
|
||||
loadedCellsLock.release();
|
||||
//add player
|
||||
groundDataCells[x][y][z].addPlayer(player);
|
||||
groundDataCells.get(getServerDataCellKey(targetPos)).addPlayer(player);
|
||||
}
|
||||
// additions++;
|
||||
} else {
|
||||
@ -148,6 +177,15 @@ public class GriddedDataCellManager implements DataCellManager {
|
||||
}
|
||||
// System.out.println("removals: " + removals + "\tadditions: " + additions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates physics entities when new data cell being created
|
||||
*/
|
||||
private void createTerrainPhysicsEntities(Vector3i worldPos){
|
||||
ServerTerrainChunk subChunk = serverTerrainManager.getChunk(worldPos.x, worldPos.y, worldPos.z);
|
||||
PhysicsDataCell cell = PhysicsDataCell.createPhysicsCell(parent, worldPos, subChunk);
|
||||
cell.generatePhysics();
|
||||
}
|
||||
|
||||
/**
|
||||
* For every player, looks at their entity and determines what data cell they should be considered inside of
|
||||
@ -181,15 +219,16 @@ public class GriddedDataCellManager implements DataCellManager {
|
||||
int worldX = Globals.serverWorldData.convertRealToChunkSpace(point.x);
|
||||
int worldY = Globals.serverWorldData.convertRealToChunkSpace(point.y);
|
||||
int worldZ = Globals.serverWorldData.convertRealToChunkSpace(point.z);
|
||||
Vector3i worldPos = new Vector3i(worldX,worldY,worldZ);
|
||||
if(
|
||||
//in bounds of array
|
||||
worldX >= 0 && worldX < groundDataCells.length &&
|
||||
worldY >= 0 && worldY < groundDataCells[0].length &&
|
||||
worldZ >= 0 && worldZ < groundDataCells[0][0].length &&
|
||||
worldX >= 0 && worldX < discreteWorldSize &&
|
||||
worldY >= 0 && worldY < discreteWorldSize &&
|
||||
worldZ >= 0 && worldZ < discreteWorldSize &&
|
||||
//isn't null
|
||||
groundDataCells[worldX][worldY][worldZ] != null
|
||||
groundDataCells.get(getServerDataCellKey(worldPos)) != null
|
||||
){
|
||||
rVal = groundDataCells[worldX][worldY][worldZ];
|
||||
rVal = groundDataCells.get(getServerDataCellKey(worldPos));
|
||||
}
|
||||
return rVal;
|
||||
}
|
||||
@ -203,18 +242,25 @@ public class GriddedDataCellManager implements DataCellManager {
|
||||
int worldX = Globals.serverWorldData.convertRealToChunkSpace(point.x);
|
||||
int worldY = Globals.serverWorldData.convertRealToChunkSpace(point.y);
|
||||
int worldZ = Globals.serverWorldData.convertRealToChunkSpace(point.z);
|
||||
Vector3i worldPos = new Vector3i(worldX,worldY,worldZ);
|
||||
if(
|
||||
//in bounds of array
|
||||
worldX >= 0 && worldX < groundDataCells.length &&
|
||||
worldY >= 0 && worldY < groundDataCells[0].length &&
|
||||
worldZ >= 0 && worldZ < groundDataCells[0][0].length &&
|
||||
worldX >= 0 && worldX < discreteWorldSize &&
|
||||
worldY >= 0 && worldY < discreteWorldSize &&
|
||||
worldZ >= 0 && worldZ < discreteWorldSize &&
|
||||
//isn't null
|
||||
groundDataCells[worldX][worldY][worldZ] == null
|
||||
groundDataCells.get(getServerDataCellKey(worldPos)) == null
|
||||
){
|
||||
groundDataCells[worldX][worldY][worldZ] = ServerDataCell.createServerDataCell(new Scene());
|
||||
loadedCells.add(groundDataCells[worldX][worldY][worldZ]);
|
||||
//create data cell
|
||||
createServerDataCell(worldPos);
|
||||
//generates physics for the cell in a dedicated thread then finally registers
|
||||
runPhysicsGenerationThread(worldPos);
|
||||
//add to loaded cells
|
||||
loadedCellsLock.acquireUninterruptibly();
|
||||
loadedCells.add(groundDataCells.get(getServerDataCellKey(worldPos)));
|
||||
loadedCellsLock.release();
|
||||
}
|
||||
return groundDataCells[worldX][worldY][worldZ];
|
||||
return groundDataCells.get(getServerDataCellKey(worldPos));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -225,13 +271,13 @@ public class GriddedDataCellManager implements DataCellManager {
|
||||
public ServerDataCell getCellAtWorldPosition(Vector3i position){
|
||||
if(
|
||||
//in bounds of array
|
||||
position.x >= 0 && position.x < groundDataCells.length &&
|
||||
position.y >= 0 && position.y < groundDataCells[0].length &&
|
||||
position.z >= 0 && position.z < groundDataCells[0][0].length &&
|
||||
position.x >= 0 && position.x < discreteWorldSize &&
|
||||
position.y >= 0 && position.y < discreteWorldSize &&
|
||||
position.z >= 0 && position.z < discreteWorldSize &&
|
||||
//isn't null
|
||||
groundDataCells[position.x][position.y][position.z] != null
|
||||
groundDataCells.get(getServerDataCellKey(position)) != null
|
||||
){
|
||||
return groundDataCells[position.x][position.y][position.z];
|
||||
return groundDataCells.get(getServerDataCellKey(position));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -241,9 +287,59 @@ public class GriddedDataCellManager implements DataCellManager {
|
||||
* Calls the simulate function on all loaded cells
|
||||
*/
|
||||
public void simulate(){
|
||||
loadedCellsLock.acquireUninterruptibly();
|
||||
for(ServerDataCell cell : loadedCells){
|
||||
Globals.microSimulation.simulate(cell, parent.getHitboxManager());
|
||||
}
|
||||
loadedCellsLock.release();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the server terrain manager for this realm if it exists
|
||||
* @return The server terrain manager if it exists, null otherwise
|
||||
*/
|
||||
public ServerTerrainManager getServerTerrainManager(){
|
||||
return serverTerrainManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs code to generate physics entities and register cell in a dedicated thread.
|
||||
* Because cell hasn't been registered yet, no simulation is performed until the physics is created.
|
||||
* @param worldPos
|
||||
*/
|
||||
private void runPhysicsGenerationThread(Vector3i worldPos){
|
||||
Thread thread = new Thread(new Runnable(){
|
||||
@Override
|
||||
public void run() {
|
||||
//create physics entities
|
||||
createTerrainPhysicsEntities(worldPos);
|
||||
//set ready
|
||||
groundDataCells.get(getServerDataCellKey(worldPos)).setReady(true);
|
||||
}
|
||||
});
|
||||
groundDataCells.get(getServerDataCellKey(worldPos)).setReady(false);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the key in the groundDataCells map for the data cell at the provided world pos
|
||||
* @param worldPos The position in world coordinates of the server data cell
|
||||
* @return The server data cell if it exists, otherwise null
|
||||
*/
|
||||
private String getServerDataCellKey(Vector3i worldPos){
|
||||
return worldPos.x + "_" + worldPos.y + "_" + worldPos.z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a server data cell with the internal datastructure for tracking them
|
||||
* @param key The key to register the cell at
|
||||
* @param cell The cell itself
|
||||
*/
|
||||
private ServerDataCell createServerDataCell(Vector3i worldPos){
|
||||
ServerDataCell rVal = parent.createNewCell();
|
||||
groundDataCells.put(getServerDataCellKey(worldPos),rVal);
|
||||
return rVal;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -7,13 +7,14 @@ import electrosphere.entity.EntityUtils;
|
||||
import electrosphere.entity.Scene;
|
||||
import electrosphere.entity.types.hitbox.HitboxManager;
|
||||
import electrosphere.game.collision.CollisionEngine;
|
||||
import electrosphere.game.collision.CommonWorldData;
|
||||
import electrosphere.game.collision.CollisionWorldData;
|
||||
import electrosphere.game.server.world.ServerWorldData;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.net.parser.net.message.NetworkMessage;
|
||||
import electrosphere.net.server.Server;
|
||||
import electrosphere.net.server.player.Player;
|
||||
import electrosphere.server.datacell.interfaces.DataCellManager;
|
||||
import electrosphere.server.terrain.manager.ServerTerrainManager;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
@ -30,9 +31,6 @@ public class Realm {
|
||||
//this is the cell that all players loading into the game (via connection startup, death, etc) reside in
|
||||
ServerDataCell loadingCell = new ServerDataCell(new Scene());
|
||||
|
||||
//resolver for location -> data cell within this realm
|
||||
// DataCellLocationResolver dataCellLocationResolver;
|
||||
|
||||
//resolver for entity -> data cell within this realm
|
||||
EntityDataCellMapper entityDataCellMapper;
|
||||
|
||||
|
||||
@ -4,10 +4,14 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.types.hitbox.HitboxManager;
|
||||
import electrosphere.game.collision.CollisionEngine;
|
||||
import electrosphere.game.collision.CollisionWorldData;
|
||||
import electrosphere.game.server.world.ServerWorldData;
|
||||
|
||||
/**
|
||||
@ -16,9 +20,9 @@ import electrosphere.game.server.world.ServerWorldData;
|
||||
public class RealmManager {
|
||||
|
||||
//All realms in this manager
|
||||
Set<Realm> realms = new HashSet<Realm>();
|
||||
Set<Realm> realms = new CopyOnWriteArraySet<Realm>();
|
||||
//Map of entities to the realm the entity is in
|
||||
Map<Entity,Realm> entityToRealmMap = new HashMap<Entity,Realm>();
|
||||
Map<Entity,Realm> entityToRealmMap = new ConcurrentHashMap<Entity,Realm>();
|
||||
|
||||
|
||||
/**
|
||||
@ -42,9 +46,13 @@ public class RealmManager {
|
||||
* @return The realm
|
||||
*/
|
||||
public Realm createGriddedRealm(ServerWorldData serverWorldData){
|
||||
Realm realm = new Realm(new CollisionEngine(), new HitboxManager());
|
||||
//create collision engine
|
||||
CollisionEngine collisionEngine = new CollisionEngine();
|
||||
collisionEngine.setCollisionWorldData(new CollisionWorldData(serverWorldData));
|
||||
//create realm
|
||||
Realm realm = new Realm(collisionEngine, new HitboxManager());
|
||||
//create function classes
|
||||
GriddedDataCellManager griddedDataCellManager = new GriddedDataCellManager(realm);
|
||||
GriddedDataCellManager griddedDataCellManager = new GriddedDataCellManager(realm,Globals.serverTerrainManager);
|
||||
EntityDataCellMapper entityDataCellMapper = new EntityDataCellMapper();
|
||||
//init gridded manager
|
||||
griddedDataCellManager.init(serverWorldData);
|
||||
|
||||
@ -31,7 +31,8 @@ public class ServerDataCell {
|
||||
List<Player> activePlayers = new LinkedList<Player>();
|
||||
NavMesh navMesh;
|
||||
Scene scene;
|
||||
|
||||
//controls whether the server data cell simulates its entities or not
|
||||
boolean ready = false;
|
||||
|
||||
/**
|
||||
* Constructs a datacell based on a virtual cell. Should be used when a player
|
||||
@ -222,5 +223,21 @@ public class ServerDataCell {
|
||||
public void setNavMesh(NavMesh navMesh){
|
||||
this.navMesh = navMesh;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the simulation ready status of the server data cell
|
||||
* @return True if ready, false otherwise
|
||||
*/
|
||||
public boolean isReady(){
|
||||
return ready;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the simulation ready status of the server data cell
|
||||
* @param ready True if ready, false otherwise
|
||||
*/
|
||||
public void setReady(boolean ready){
|
||||
this.ready = ready;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,6 @@
|
||||
package electrosphere.server.datacell.physics;
|
||||
|
||||
import electrosphere.client.terrain.cache.ChunkData;
|
||||
import electrosphere.collision.dispatch.CollisionObject;
|
||||
import electrosphere.dynamics.RigidBody;
|
||||
import electrosphere.engine.Globals;
|
||||
@ -7,6 +8,8 @@ import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.EntityCreationUtils;
|
||||
import electrosphere.entity.EntityDataStrings;
|
||||
import electrosphere.entity.EntityUtils;
|
||||
import electrosphere.entity.ServerEntityUtils;
|
||||
import electrosphere.entity.types.terrain.TerrainChunk;
|
||||
import electrosphere.game.collision.PhysicsUtils;
|
||||
import electrosphere.game.collision.collidable.Collidable;
|
||||
import electrosphere.game.terrain.processing.TerrainInterpolator;
|
||||
@ -19,30 +22,33 @@ import electrosphere.renderer.ShaderProgram;
|
||||
import electrosphere.renderer.actor.ActorTextureMask;
|
||||
import electrosphere.renderer.texture.Texture;
|
||||
import electrosphere.server.datacell.Realm;
|
||||
import electrosphere.server.terrain.manager.ServerTerrainManager;
|
||||
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
||||
import electrosphere.util.Utilities;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector3i;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author satellite
|
||||
*/
|
||||
public class PhysicsDataCell {
|
||||
int cellX;
|
||||
int cellZ;
|
||||
|
||||
Vector3i worldPos;
|
||||
|
||||
float[][] heightmap;
|
||||
float[][] texturemap;
|
||||
|
||||
int dynamicInterpolationRatio;
|
||||
ServerTerrainChunk chunkData;
|
||||
|
||||
Entity physicsEntity;
|
||||
|
||||
CollisionObject physicsObject;
|
||||
|
||||
Realm realm;
|
||||
|
||||
|
||||
PhysicsDataCell(){
|
||||
@ -50,18 +56,15 @@ public class PhysicsDataCell {
|
||||
}
|
||||
|
||||
|
||||
public static PhysicsDataCell generateTerrainCell(
|
||||
int cellX,
|
||||
int cellZ,
|
||||
float[][] heightmap,
|
||||
float[][] texturemap,
|
||||
int dynamicInterpolationRatio
|
||||
public static PhysicsDataCell createPhysicsCell(
|
||||
Realm realm,
|
||||
Vector3i worldPos,
|
||||
ServerTerrainChunk chunkData
|
||||
){
|
||||
PhysicsDataCell rVal = new PhysicsDataCell();
|
||||
rVal.cellX = cellX;
|
||||
rVal.cellZ = cellZ;
|
||||
rVal.dynamicInterpolationRatio = dynamicInterpolationRatio;
|
||||
rVal.heightmap = heightmap;
|
||||
rVal.realm = realm;
|
||||
rVal.worldPos = worldPos;
|
||||
rVal.chunkData = chunkData;
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -72,17 +75,25 @@ public class PhysicsDataCell {
|
||||
EntityUtils.cleanUpEntity(physicsEntity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the physics entity for this chunk
|
||||
*/
|
||||
public void generatePhysics(){
|
||||
//if the entity hasn't already been created for some reason, need to create it
|
||||
if(physicsEntity == null){
|
||||
physicsEntity = EntityCreationUtils.createClientSpatialEntity();
|
||||
Vector3d position = new Vector3d(
|
||||
worldPos.x * ServerTerrainChunk.CHUNK_DIMENSION,
|
||||
worldPos.y * ServerTerrainChunk.CHUNK_DIMENSION,
|
||||
worldPos.z * ServerTerrainChunk.CHUNK_DIMENSION
|
||||
);
|
||||
physicsEntity = TerrainChunk.serverCreateTerrainChunkEntity(realm, position, chunkData.getWeights(), chunkData.getValues());
|
||||
physicsEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
|
||||
EntityUtils.getPosition(physicsEntity).set(new Vector3f(cellX * dynamicInterpolationRatio, 0.0f, cellZ * dynamicInterpolationRatio));
|
||||
ServerEntityUtils.repositionEntity(physicsEntity, position);
|
||||
}
|
||||
//then actually perform the attach
|
||||
physicsObject = PhysicsUtils.attachTerrainRigidBody(physicsEntity,heightmap,true);
|
||||
Realm realm = Globals.realmManager.getEntityRealm(physicsEntity);
|
||||
realm.getCollisionEngine().registerPhysicsEntity(physicsEntity);
|
||||
// //then actually perform the attach
|
||||
// physicsObject = PhysicsUtils.attachTerrainRigidBody(physicsEntity,heightmap,true);
|
||||
// Realm realm = Globals.realmManager.getEntityRealm(physicsEntity);
|
||||
// realm.getCollisionEngine().registerPhysicsEntity(physicsEntity);
|
||||
}
|
||||
|
||||
public void destroyPhysics(){
|
||||
|
||||
@ -23,7 +23,7 @@ public class NavMeshUtils {
|
||||
static float NAVMESH_PHASE_TWO_DISPARITY_TOLERANCE = 0.5f;
|
||||
public static NavMesh createMeshFromChunk(ServerTerrainChunk chunk, NavBlocker navBlocker){
|
||||
NavMesh rVal = Globals.navMeshManager.createNavMesh();
|
||||
float[][] heightMap = chunk.getHeightMap();
|
||||
float[][] heightMap = chunk.getWeights()[0];
|
||||
boolean[][] navMeshGeneratorMask = navBlocker.getHeightfieldBlocker();
|
||||
List<FirstPhaseBox> firstPassBoxes = new LinkedList<FirstPhaseBox>();
|
||||
int numInCurrent = 0;
|
||||
|
||||
@ -22,7 +22,7 @@ public class NavTerrainBlockerCache {
|
||||
|
||||
|
||||
public String getKey(int x, int y){
|
||||
return x + "-" + y;
|
||||
return x + "_" + y;
|
||||
}
|
||||
|
||||
public NavBlocker getBlocker(int x, int y){
|
||||
|
||||
@ -106,7 +106,7 @@ public class SaveUtils {
|
||||
}
|
||||
|
||||
public static boolean loadTerrainAndCreateWorldData(String currentSaveName){
|
||||
Globals.serverTerrainManager = new ServerTerrainManager(2000,50,100,0.0f,0);
|
||||
Globals.serverTerrainManager = new ServerTerrainManager(2000,50,ServerTerrainManager.SERVER_TERRAIN_MANAGER_INTERPOLATION_RATIO,0.0f,0);
|
||||
SaveUtils.loadTerrainAndDB(currentSaveName);
|
||||
Globals.serverWorldData = ServerWorldData.createGameWorld(Globals.serverTerrainManager);
|
||||
Globals.realmManager.createGriddedRealm(Globals.serverWorldData);
|
||||
|
||||
@ -105,9 +105,9 @@ public class MacroSimulation {
|
||||
}
|
||||
}
|
||||
if(placementPos != null){
|
||||
Structure placedStructure = VirtualStructureUtils.placeStructureAtPoint(placementPos.x, placementPos.y, buildingTypeToPlace);
|
||||
CharacterUtils.addShelter(chara, placedStructure);
|
||||
VirtualStructureUtils.addResident(placedStructure, chara);
|
||||
// Structure placedStructure = VirtualStructureUtils.placeStructureAtPoint(placementPos.x, placementPos.y, buildingTypeToPlace);
|
||||
// CharacterUtils.addShelter(chara, placedStructure);
|
||||
// VirtualStructureUtils.addResident(placedStructure, chara);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,62 +47,64 @@ public class MicroSimulation {
|
||||
}
|
||||
|
||||
public void simulate(ServerDataCell dataCell, HitboxManager hitboxManager){
|
||||
//update dynamic entity positions calculated by bullet
|
||||
// Globals.collisionEngine.updateDynamicObjectTransforms();
|
||||
//list dynamic object positions
|
||||
// Globals.collisionEngine.listBodyPositions();
|
||||
//simulate ai
|
||||
Globals.aiManager.simulate();
|
||||
//update actor animations
|
||||
for(Entity currentEntity : dataCell.getScene().getEntitiesWithTag(EntityTags.DRAWABLE)){
|
||||
//fetch actor
|
||||
Actor currentActor = EntityUtils.getActor(currentEntity);
|
||||
//increment animations
|
||||
if(currentActor.isPlayingAnimation()){
|
||||
currentActor.incrementAnimationTime(Main.deltaFrames / Main.targetFrameRate);
|
||||
if(dataCell.isReady()){
|
||||
//update dynamic entity positions calculated by bullet
|
||||
// Globals.collisionEngine.updateDynamicObjectTransforms();
|
||||
//list dynamic object positions
|
||||
// Globals.collisionEngine.listBodyPositions();
|
||||
//simulate ai
|
||||
Globals.aiManager.simulate();
|
||||
//update actor animations
|
||||
for(Entity currentEntity : dataCell.getScene().getEntitiesWithTag(EntityTags.DRAWABLE)){
|
||||
//fetch actor
|
||||
Actor currentActor = EntityUtils.getActor(currentEntity);
|
||||
//increment animations
|
||||
if(currentActor.isPlayingAnimation()){
|
||||
currentActor.incrementAnimationTime(Main.deltaFrames / Main.targetFrameRate);
|
||||
}
|
||||
}
|
||||
}
|
||||
//make items play idle animation
|
||||
for(Entity item : dataCell.getScene().getEntitiesWithTag(EntityTags.ITEM)){
|
||||
ItemUtils.updateItemActorAnimation(item);
|
||||
}
|
||||
//particle state updates
|
||||
for(Entity particle : dataCell.getScene().getEntitiesWithTag(EntityTags.PARTICLE)){
|
||||
// ParticleTree tree = ParticleUtils.getParticleTree(particle);
|
||||
// tree.simulate(Main.deltaFrames);
|
||||
ParticleUtils.makeParticleBillboardFaceCamera(particle);
|
||||
}
|
||||
//update attached entity positions
|
||||
AttachUtils.serverUpdateAttachedEntityPositions(dataCell);
|
||||
//update hitbox positions
|
||||
for(Entity currentHitbox : hitboxManager.getAllHitboxes()){
|
||||
HitboxUtils.serverUpdatePosition(currentHitbox);
|
||||
}
|
||||
//collide hitboxes
|
||||
for(Entity currentHitbox : hitboxManager.getAllHitboxes()){
|
||||
if(isReady){
|
||||
HitboxUtils.serverCollideEntities(currentHitbox);
|
||||
//make items play idle animation
|
||||
for(Entity item : dataCell.getScene().getEntitiesWithTag(EntityTags.ITEM)){
|
||||
ItemUtils.updateItemActorAnimation(item);
|
||||
}
|
||||
//particle state updates
|
||||
for(Entity particle : dataCell.getScene().getEntitiesWithTag(EntityTags.PARTICLE)){
|
||||
// ParticleTree tree = ParticleUtils.getParticleTree(particle);
|
||||
// tree.simulate(Main.deltaFrames);
|
||||
ParticleUtils.makeParticleBillboardFaceCamera(particle);
|
||||
}
|
||||
//update attached entity positions
|
||||
AttachUtils.serverUpdateAttachedEntityPositions(dataCell);
|
||||
//update hitbox positions
|
||||
for(Entity currentHitbox : hitboxManager.getAllHitboxes()){
|
||||
HitboxUtils.serverUpdatePosition(currentHitbox);
|
||||
}
|
||||
//collide hitboxes
|
||||
for(Entity currentHitbox : hitboxManager.getAllHitboxes()){
|
||||
if(isReady){
|
||||
HitboxUtils.serverCollideEntities(currentHitbox);
|
||||
}
|
||||
}
|
||||
//tally collidables and offset position accordingly
|
||||
// for(Entity currentCollidable : Globals.entityManager.getEntitiesWithTag(EntityTags.COLLIDABLE)){
|
||||
// CollidableTree tree = CollidableTree.getCollidableTree(currentCollidable);
|
||||
// tree.simulate(Main.deltaFrames);
|
||||
// }
|
||||
//targeting crosshair
|
||||
if(Globals.RUN_CLIENT){
|
||||
Crosshair.checkTargetable();
|
||||
Crosshair.updateTargetCrosshairPosition();
|
||||
}
|
||||
//simulate behavior trees
|
||||
dataCell.getScene().simulateBehaviorTrees(Main.deltaFrames);
|
||||
//sum collidable impulses
|
||||
for(Entity collidable : dataCell.getScene().getEntitiesWithTag(EntityTags.COLLIDABLE)){
|
||||
ServerCollidableTree.getServerCollidableTree(collidable).simulate(Main.deltaFrames);
|
||||
}
|
||||
//delete all client side entities that aren't in visible chunks
|
||||
if(Globals.clientEntityCullingManager != null){
|
||||
Globals.clientEntityCullingManager.clearOutOfBoundsEntities();
|
||||
}
|
||||
}
|
||||
//tally collidables and offset position accordingly
|
||||
// for(Entity currentCollidable : Globals.entityManager.getEntitiesWithTag(EntityTags.COLLIDABLE)){
|
||||
// CollidableTree tree = CollidableTree.getCollidableTree(currentCollidable);
|
||||
// tree.simulate(Main.deltaFrames);
|
||||
// }
|
||||
//targeting crosshair
|
||||
if(Globals.RUN_CLIENT){
|
||||
Crosshair.checkTargetable();
|
||||
Crosshair.updateTargetCrosshairPosition();
|
||||
}
|
||||
//simulate behavior trees
|
||||
dataCell.getScene().simulateBehaviorTrees(Main.deltaFrames);
|
||||
//sum collidable impulses
|
||||
for(Entity collidable : dataCell.getScene().getEntitiesWithTag(EntityTags.COLLIDABLE)){
|
||||
ServerCollidableTree.getServerCollidableTree(collidable).simulate(Main.deltaFrames);
|
||||
}
|
||||
//delete all client side entities that aren't in visible chunks
|
||||
if(Globals.clientEntityCullingManager != null){
|
||||
Globals.clientEntityCullingManager.clearOutOfBoundsEntities();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -6,29 +6,58 @@ import java.util.List;
|
||||
import electrosphere.server.terrain.models.TerrainModification;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
* Is a single subchunk of terrain on the server
|
||||
*/
|
||||
public class ServerTerrainChunk {
|
||||
int worldX, worldY;
|
||||
List<TerrainModification> modifications = new LinkedList<TerrainModification>();
|
||||
float[][] heightMap;
|
||||
float[][] macroValues;
|
||||
long[][] randomizer;
|
||||
|
||||
public ServerTerrainChunk(int worldX, int worldY, float[][] heightMap, float[][] macroValues, long[][] randomizer) {
|
||||
//all chunks are 16x16x16
|
||||
public static final int CHUNK_DIMENSION = 16;
|
||||
|
||||
int worldX, worldY, worldZ;
|
||||
List<TerrainModification> modifications = new LinkedList<TerrainModification>();
|
||||
float[][][] weights;
|
||||
int[][][] values;
|
||||
|
||||
public ServerTerrainChunk(int worldX, int worldY, int worldZ, float[][][] weights, int[][][] values) {
|
||||
this.worldX = worldX;
|
||||
this.worldY = worldY;
|
||||
this.heightMap = heightMap;
|
||||
this.macroValues = macroValues;
|
||||
this.randomizer = randomizer;
|
||||
this.worldZ = worldZ;
|
||||
this.weights = weights;
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
public static ServerTerrainChunk getArenaChunk(int width, int x, int y){
|
||||
float[][] macroValues = new float[5][5];
|
||||
long[][] randomizer = new long[5][5];
|
||||
float[][] heightmap = new float[width + 1][width + 1];
|
||||
ServerTerrainChunk rVal = new ServerTerrainChunk(x, y, heightmap, macroValues, randomizer);
|
||||
public static ServerTerrainChunk getArenaChunk(int worldX, int worldY, int worldZ){
|
||||
float[][][] weights = new float[CHUNK_DIMENSION][CHUNK_DIMENSION][CHUNK_DIMENSION];
|
||||
int[][][] values = new int[CHUNK_DIMENSION][CHUNK_DIMENSION][CHUNK_DIMENSION];
|
||||
for(int inc = 0; inc < CHUNK_DIMENSION; inc++){
|
||||
for(int weightX = 0; weightX < CHUNK_DIMENSION; weightX++){
|
||||
for(int weightZ = 0; weightZ < CHUNK_DIMENSION; weightZ++){
|
||||
weights[weightX][inc][weightZ] = -1;
|
||||
values[weightX][inc][weightZ] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(worldY < 1){
|
||||
for(int weightX = 0; weightX < CHUNK_DIMENSION; weightX++){
|
||||
for(int weightZ = 0; weightZ < CHUNK_DIMENSION; weightZ++){
|
||||
weights[weightX][0][weightZ] = 0.1f;
|
||||
values[weightX][0][weightZ] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
// for(int weightX = 0; weightX < SUB_CHUNK_DIMENSION; weightX++){
|
||||
// for(int weightZ = 0; weightZ < SUB_CHUNK_DIMENSION; weightZ++){
|
||||
// weights[weightX][SUB_CHUNK_DIMENSION-1][weightZ] = 1;
|
||||
// values[weightX][SUB_CHUNK_DIMENSION-1][weightZ] = 1;
|
||||
// }
|
||||
// }
|
||||
// for(int weightX = 0; weightX < SUB_CHUNK_DIMENSION; weightX++){
|
||||
// for(int weightZ = 0; weightZ < SUB_CHUNK_DIMENSION; weightZ++){
|
||||
// weights[SUB_CHUNK_DIMENSION-1][weightX][weightZ] = 1;
|
||||
// values[SUB_CHUNK_DIMENSION-1][weightX][weightZ] = 1;
|
||||
// }
|
||||
// }
|
||||
ServerTerrainChunk rVal = new ServerTerrainChunk(worldX, worldY, worldZ, weights, values);
|
||||
// rVal.addModification(new TerrainModification(x, y, 3, 3, 5));
|
||||
return rVal;
|
||||
}
|
||||
@ -41,24 +70,26 @@ public class ServerTerrainChunk {
|
||||
return worldY;
|
||||
}
|
||||
|
||||
public int getWorldZ() {
|
||||
return worldZ;
|
||||
}
|
||||
|
||||
public List<TerrainModification> getModifications() {
|
||||
return modifications;
|
||||
}
|
||||
|
||||
public float[][] getHeightMap() {
|
||||
return heightMap;
|
||||
public float[][][] getWeights() {
|
||||
return weights;
|
||||
}
|
||||
|
||||
public float[][] getMacroValues() {
|
||||
return macroValues;
|
||||
public int[][][] getValues() {
|
||||
return values;
|
||||
}
|
||||
|
||||
public long[][] getRandomizer() {
|
||||
return randomizer;
|
||||
}
|
||||
|
||||
public void addModification(TerrainModification modification){
|
||||
modifications.add(modification);
|
||||
values[modification.getVoxelPos().x][modification.getVoxelPos().y][modification.getVoxelPos().z] = modification.getValue();
|
||||
weights[modification.getVoxelPos().x][modification.getVoxelPos().y][modification.getVoxelPos().z] = modification.getWeight();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -14,15 +14,21 @@ import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import org.joml.Vector3i;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author satellite
|
||||
* Provides an interface for the server to query information about terrain
|
||||
*/
|
||||
public class ServerTerrainManager {
|
||||
|
||||
//the interpolation width of a server terrain manager is hard coded at the moment to make sure it's divisible by the sub chunk calculations
|
||||
public static final int SERVER_TERRAIN_MANAGER_INTERPOLATION_RATIO = 128;
|
||||
|
||||
//The size of the world in discrete units * must be multiple of 200
|
||||
int worldSizeDiscrete;
|
||||
@ -42,9 +48,14 @@ public class ServerTerrainManager {
|
||||
//Basic idea is we associate string that contains chunk x&y with elevation
|
||||
//While we incur a penalty with converting ints -> string, think this will
|
||||
//offset regenerating the array every time we want a new one
|
||||
int cacheSize = 50;
|
||||
Map<String, ServerTerrainChunk> elevationMapCache;
|
||||
List<String> elevationMapCacheContents;
|
||||
int cacheSize = 500;
|
||||
Map<String, ServerTerrainChunk> chunkCache;
|
||||
List<String> chunkCacheContents;
|
||||
|
||||
//cache for the bicubic interpolated chunks
|
||||
//don't need to interpolate each time a new chunk is created
|
||||
//This should eventually be removed as terrain generation becomes more complicated than a heightmap
|
||||
Map<String, float[][]> heightmapCache = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
|
||||
@ -52,8 +63,8 @@ public class ServerTerrainManager {
|
||||
this.worldSizeDiscrete = worldSizeDiscrete;
|
||||
this.verticalInterpolationRatio = verticalInterpolationRatio;
|
||||
this.dynamicInterpolationRatio = dynamicInterpolationRatio;
|
||||
this.elevationMapCache = new HashMap<String, ServerTerrainChunk>();
|
||||
this.elevationMapCacheContents = new ArrayList<String>();
|
||||
this.chunkCache = new ConcurrentHashMap<String, ServerTerrainChunk>();
|
||||
this.chunkCacheContents = new CopyOnWriteArrayList<String>();
|
||||
this.interpolationRandomDampener = interpolationRandomDampener;
|
||||
this.seed = seed;
|
||||
}
|
||||
@ -66,9 +77,9 @@ public class ServerTerrainManager {
|
||||
ServerTerrainManager rVal = new ServerTerrainManager();
|
||||
rVal.worldSizeDiscrete = 2;
|
||||
rVal.verticalInterpolationRatio = 0;
|
||||
rVal.dynamicInterpolationRatio = 100;
|
||||
rVal.elevationMapCache = new HashMap<String, ServerTerrainChunk>();
|
||||
rVal.elevationMapCacheContents = new ArrayList<String>();
|
||||
rVal.dynamicInterpolationRatio = SERVER_TERRAIN_MANAGER_INTERPOLATION_RATIO;
|
||||
rVal.chunkCache = new ConcurrentHashMap<String, ServerTerrainChunk>();
|
||||
rVal.chunkCacheContents = new CopyOnWriteArrayList<String>();
|
||||
rVal.interpolationRandomDampener = 0.0f;
|
||||
return rVal;
|
||||
}
|
||||
@ -139,41 +150,44 @@ public class ServerTerrainManager {
|
||||
// }
|
||||
// }
|
||||
|
||||
public double getHeightAtPosition(double x, double y){
|
||||
public double getHeightAtPosition(double x, double y, double z){
|
||||
//get chunk coordinate space of input x,y
|
||||
int chunkX = (int)Math.floor(x / dynamicInterpolationRatio);
|
||||
int chunkY = (int)Math.floor(y / dynamicInterpolationRatio);
|
||||
//get local coordinate space of input x,y
|
||||
double localX = x - chunkX * dynamicInterpolationRatio;
|
||||
double localY = y - chunkY * dynamicInterpolationRatio;
|
||||
//get chunk elevation map
|
||||
float[][] chunkElevationMap = getChunk(chunkX,chunkY).heightMap;
|
||||
//floored variants of local values
|
||||
int localXf = (int)Math.floor(localX);
|
||||
int localYf = (int)Math.floor(localY);
|
||||
// int chunkX = (int)Math.floor(x / dynamicInterpolationRatio);
|
||||
// int chunkY = (int)Math.floor(y / dynamicInterpolationRatio);
|
||||
// int chunkZ = (int)Math.floor(z / dynamicInterpolationRatio);
|
||||
// //get local coordinate space of input x,y
|
||||
// double localX = x - chunkX * dynamicInterpolationRatio;
|
||||
// double localY = y - chunkY * dynamicInterpolationRatio;
|
||||
// double localZ = z - chunkZ * dynamicInterpolationRatio;
|
||||
// //get chunk elevation map
|
||||
// float[][] chunkElevationMap = getChunk(chunkX,chunkY,chunkZ).heightMap;
|
||||
// //floored variants of local values
|
||||
// int localXf = (int)Math.floor(localX);
|
||||
// int localYf = (int)Math.floor(localY);
|
||||
// int localZf = (int)Math.floor(localZ);
|
||||
|
||||
/*
|
||||
Average some inner value.
|
||||
// /*
|
||||
// Average some inner value.
|
||||
|
||||
01 11
|
||||
0.3 0.4 0.5
|
||||
0.1 0.2 0.3
|
||||
00 10
|
||||
*/
|
||||
//interp elevation from map
|
||||
float elevation00 = chunkElevationMap[(int)localX+0][(int)localY+0];
|
||||
float elevation10 = chunkElevationMap[(int)localX+1][(int)localY+0];
|
||||
float elevation01 = chunkElevationMap[(int)localX+0][(int)localY+1];
|
||||
float elevation11 = chunkElevationMap[(int)localX+1][(int)localY+1];
|
||||
// 01 11
|
||||
// 0.3 0.4 0.5
|
||||
// 0.1 0.2 0.3
|
||||
// 00 10
|
||||
// */
|
||||
// //interp elevation from map
|
||||
// float elevation00 = chunkElevationMap[(int)localX+0][(int)localY+0];
|
||||
// float elevation10 = chunkElevationMap[(int)localX+1][(int)localY+0];
|
||||
// float elevation01 = chunkElevationMap[(int)localX+0][(int)localY+1];
|
||||
// float elevation11 = chunkElevationMap[(int)localX+1][(int)localY+1];
|
||||
|
||||
double rVal =
|
||||
(1-(localX-localXf))*(1-(localY-localYf)) * elevation00 +
|
||||
( (localX-localXf))*(1-(localY-localYf)) * elevation10 +
|
||||
(1-(localX-localXf))*( (localY-localYf)) * elevation01 +
|
||||
( (localX-localXf))*( (localY-localYf)) * elevation11
|
||||
;
|
||||
// double rVal =
|
||||
// (1-(localX-localXf))*(1-(localY-localYf)) * elevation00 +
|
||||
// ( (localX-localXf))*(1-(localY-localYf)) * elevation10 +
|
||||
// (1-(localX-localXf))*( (localY-localYf)) * elevation01 +
|
||||
// ( (localX-localXf))*( (localY-localYf)) * elevation11
|
||||
// ;
|
||||
|
||||
return rVal;
|
||||
return y;
|
||||
}
|
||||
|
||||
public int getChunkWidth(){
|
||||
@ -250,82 +264,100 @@ public class ServerTerrainManager {
|
||||
return model;
|
||||
}
|
||||
|
||||
public String getKey(int x, int y){
|
||||
return x + "-" + y;
|
||||
public String getKey(int worldX, int worldY, int worldZ){
|
||||
return worldX + "_" + worldY + "_" + worldZ;
|
||||
}
|
||||
|
||||
public ServerTerrainChunk getChunk(int x, int y){
|
||||
public ServerTerrainChunk getChunk(int worldX, int worldY, int worldZ){
|
||||
if(model != null){
|
||||
//THIS FIRES IF THERE IS A MAIN GAME WORLD RUNNING
|
||||
String key = getKey(x,y);
|
||||
String key = getKey(worldX,worldY,worldZ);
|
||||
ServerTerrainChunk returnedChunk;
|
||||
if(elevationMapCache.containsKey(key)){
|
||||
elevationMapCacheContents.remove(key);
|
||||
elevationMapCacheContents.add(0, key);
|
||||
returnedChunk = elevationMapCache.get(key);
|
||||
if(chunkCache.containsKey(key)){
|
||||
chunkCacheContents.remove(key);
|
||||
chunkCacheContents.add(0, key);
|
||||
returnedChunk = chunkCache.get(key);
|
||||
return returnedChunk;
|
||||
} else {
|
||||
float[][] macroValues = model.getRad5MacroValuesAtPosition(x, y);
|
||||
long[][] randomizer = model.getRad5RandomizerValuesAtPosition(x, y);
|
||||
float[][] heightmap = TerrainInterpolator.getBicubicInterpolatedChunk(
|
||||
macroValues,
|
||||
randomizer,
|
||||
model.getDynamicInterpolationRatio(),
|
||||
model.getRandomDampener()
|
||||
);
|
||||
ModificationList modificationList = model.getModifications(x, y);
|
||||
if(modificationList != null){
|
||||
for(TerrainModification modification : modificationList.getModifications()){
|
||||
heightmap = modification.applyToHeightfield(heightmap);
|
||||
float[][] heightmap = getHeightmap(worldX, worldZ);
|
||||
float[][][] weights = new float[ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION];
|
||||
int[][][] values = new int[ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION];
|
||||
for(int weightX = 0; weightX < ServerTerrainChunk.CHUNK_DIMENSION; weightX++){
|
||||
for(int weightY = 0; weightY < ServerTerrainChunk.CHUNK_DIMENSION; weightY++){
|
||||
for(int weightZ = 0; weightZ < ServerTerrainChunk.CHUNK_DIMENSION; weightZ++){
|
||||
if(weightY < heightmap[ServerTerrainChunk.CHUNK_DIMENSION * worldX + weightX][ServerTerrainChunk.CHUNK_DIMENSION * worldZ + weightZ]){
|
||||
weights[weightX][weightY][weightZ] = 1;
|
||||
values[weightX][weightY][weightZ] = 1;
|
||||
} else {
|
||||
weights[weightX][weightY][weightZ] = -1;
|
||||
values[weightX][weightY][weightZ] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(elevationMapCacheContents.size() > cacheSize){
|
||||
String oldChunk = elevationMapCacheContents.remove(elevationMapCacheContents.size() - 1);
|
||||
elevationMapCache.remove(oldChunk);
|
||||
// ModificationList modificationList = model.getModifications(x, y);
|
||||
// if(modificationList != null){
|
||||
// for(TerrainModification modification : modificationList.getModifications()){
|
||||
// heightmap = modification.applyToHeightfield(heightmap);
|
||||
// }
|
||||
// }
|
||||
if(chunkCacheContents.size() > cacheSize){
|
||||
String oldChunk = chunkCacheContents.remove(chunkCacheContents.size() - 1);
|
||||
chunkCache.remove(oldChunk);
|
||||
}
|
||||
returnedChunk = new ServerTerrainChunk(x, y, heightmap, macroValues, randomizer);
|
||||
elevationMapCache.put(key, returnedChunk);
|
||||
elevationMapCacheContents.add(key);
|
||||
returnedChunk = new ServerTerrainChunk(worldX, worldY, worldZ, weights, values);
|
||||
chunkCache.put(key, returnedChunk);
|
||||
chunkCacheContents.add(key);
|
||||
return returnedChunk;
|
||||
}
|
||||
} else {
|
||||
//THIS FIRES IF THERE IS AN ARENA WORLD RUNNING
|
||||
String key = getKey(x,y);
|
||||
String key = getKey(worldX, worldY, worldZ);
|
||||
ServerTerrainChunk returnedChunk;
|
||||
if(elevationMapCache.containsKey(key)){
|
||||
elevationMapCacheContents.remove(key);
|
||||
elevationMapCacheContents.add(0, key);
|
||||
returnedChunk = elevationMapCache.get(key);
|
||||
if(chunkCache.containsKey(key)){
|
||||
chunkCacheContents.remove("" + key);
|
||||
chunkCacheContents.add(0, key);
|
||||
returnedChunk = chunkCache.get(key);
|
||||
return returnedChunk;
|
||||
} else {
|
||||
returnedChunk = ServerTerrainChunk.getArenaChunk(dynamicInterpolationRatio + 1, x, y);
|
||||
elevationMapCache.put(key, returnedChunk);
|
||||
elevationMapCacheContents.add(key);
|
||||
returnedChunk = ServerTerrainChunk.getArenaChunk(worldX, worldY, worldZ);
|
||||
chunkCache.put(key, returnedChunk);
|
||||
chunkCacheContents.add(key);
|
||||
return returnedChunk;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void deformTerrainAtLocationToValue(int worldX, int worldY, int locationX, int locationY, float value){
|
||||
System.out.println("Add modification at " + worldX + "," + worldY + " subloc " + locationX + "," + locationY);
|
||||
TerrainModification modification = new TerrainModification(worldX,worldY,locationX,locationY,value);
|
||||
model.addModification(modification);
|
||||
String key = getKey(worldX,worldY);
|
||||
if(elevationMapCache.containsKey(key)){
|
||||
ServerTerrainChunk chunk = elevationMapCache.get(key);
|
||||
chunk.addModification(modification);
|
||||
chunk.heightMap = modification.applyToHeightfield(chunk.heightMap);
|
||||
|
||||
private float[][] getHeightmap(int worldX, int worldZ){
|
||||
String key = worldX + "_" + worldZ;
|
||||
if(heightmapCache.containsKey(key)){
|
||||
return heightmapCache.get(key);
|
||||
} else {
|
||||
float[][] macroValues = model.getRad5MacroValuesAtPosition(worldX, worldZ);
|
||||
long[][] randomizer = model.getRad5RandomizerValuesAtPosition(worldX, worldZ);
|
||||
float[][] heightmap = TerrainInterpolator.getBicubicInterpolatedChunk(
|
||||
macroValues,
|
||||
randomizer,
|
||||
model.getDynamicInterpolationRatio(),
|
||||
model.getRandomDampener()
|
||||
);
|
||||
heightmapCache.put(key,heightmap);
|
||||
return heightmap;
|
||||
}
|
||||
if(locationX == 0){
|
||||
if(locationY == 0){
|
||||
deformTerrainAtLocationToValue(worldX - 1, worldY - 1, Globals.serverTerrainManager.dynamicInterpolationRatio, Globals.serverTerrainManager.dynamicInterpolationRatio, value);
|
||||
deformTerrainAtLocationToValue(worldX - 1, worldY, Globals.serverTerrainManager.dynamicInterpolationRatio, locationY, value);
|
||||
deformTerrainAtLocationToValue(worldX, worldY - 1, locationX, Globals.serverTerrainManager.dynamicInterpolationRatio, value);
|
||||
} else {
|
||||
deformTerrainAtLocationToValue(worldX - 1, worldY, Globals.serverTerrainManager.dynamicInterpolationRatio, locationY, value);
|
||||
}
|
||||
} else if(locationY == 0){
|
||||
deformTerrainAtLocationToValue(worldX, worldY - 1, locationX, Globals.serverTerrainManager.dynamicInterpolationRatio, value);
|
||||
}
|
||||
|
||||
public void deformTerrainAtLocationToValue(
|
||||
Vector3i worldPos,
|
||||
Vector3i subChunkPos,
|
||||
Vector3i voxelPos,
|
||||
float weight, int value){
|
||||
System.out.println("Add modification at " + worldPos.x + "," + worldPos.z + " subloc " + voxelPos.x + "," + voxelPos.z);
|
||||
TerrainModification modification = new TerrainModification(worldPos,subChunkPos,voxelPos,weight,value);
|
||||
model.addModification(modification);
|
||||
String key = getKey(worldPos.x,worldPos.y,worldPos.z);
|
||||
if(chunkCache.containsKey(key)){
|
||||
ServerTerrainChunk chunk = chunkCache.get(key);
|
||||
chunk.addModification(modification);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -372,12 +372,12 @@ public class TerrainModel {
|
||||
return realOceanThreshold;
|
||||
}
|
||||
|
||||
public String getModificationKey(int x, int y){
|
||||
return x + "-" + y;
|
||||
public String getModificationKey(int x, int y, int z){
|
||||
return x + "_" + y + "_" + z;
|
||||
}
|
||||
|
||||
public void addModification(TerrainModification modification){
|
||||
String key = getModificationKey(modification.worldX,modification.worldY);
|
||||
String key = getModificationKey(modification.getWorldPos().x,modification.getWorldPos().y,modification.getWorldPos().z);
|
||||
ModificationList list;
|
||||
if(!modifications.containsKey(key)){
|
||||
list = new ModificationList();
|
||||
@ -388,13 +388,13 @@ public class TerrainModel {
|
||||
list.addModification(modification);
|
||||
}
|
||||
|
||||
public boolean containsModificationsAtCoord(int worldX, int worldY){
|
||||
return modifications.containsKey(getModificationKey(worldX, worldY));
|
||||
public boolean containsModificationsAtCoord(int worldX, int worldY, int worldZ){
|
||||
return modifications.containsKey(getModificationKey(worldX, worldY, worldZ));
|
||||
}
|
||||
|
||||
public ModificationList getModifications(int worldX, int worldY){
|
||||
public ModificationList getModifications(int worldX, int worldY, int worldZ){
|
||||
// System.out.println("Got modifications at " + worldX + " " + worldY);
|
||||
return modifications.get(getModificationKey(worldX, worldY));
|
||||
return modifications.get(getModificationKey(worldX, worldY, worldZ));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,48 +1,47 @@
|
||||
package electrosphere.server.terrain.models;
|
||||
|
||||
import org.joml.Vector3i;
|
||||
|
||||
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
*/
|
||||
public class TerrainModification {
|
||||
int worldX;
|
||||
int worldY;
|
||||
int locationX;
|
||||
int locationY;
|
||||
float value;
|
||||
Vector3i worldPos;
|
||||
Vector3i subChunkPos;
|
||||
Vector3i voxelPos;
|
||||
float weight;
|
||||
int value;
|
||||
|
||||
public TerrainModification(int worldX, int worldY, int locationX, int locationY, float value) {
|
||||
this.worldX = worldX;
|
||||
this.worldY = worldY;
|
||||
this.locationX = locationX;
|
||||
this.locationY = locationY;
|
||||
public TerrainModification(Vector3i worldPos, Vector3i subChunkPos, Vector3i voxelPos, float weight, int value) {
|
||||
this.worldPos = worldPos;
|
||||
this.subChunkPos = subChunkPos;
|
||||
this.voxelPos = voxelPos;
|
||||
this.weight = weight;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getWorldX() {
|
||||
return worldX;
|
||||
public Vector3i getWorldPos() {
|
||||
return worldPos;
|
||||
}
|
||||
|
||||
public int getWorldY() {
|
||||
return worldY;
|
||||
public Vector3i getSubChunkPos() {
|
||||
return subChunkPos;
|
||||
}
|
||||
|
||||
public int getLocationX() {
|
||||
return locationX;
|
||||
public Vector3i getVoxelPos() {
|
||||
return voxelPos;
|
||||
}
|
||||
|
||||
public int getLocationY() {
|
||||
return locationY;
|
||||
public float getWeight(){
|
||||
return weight;
|
||||
}
|
||||
|
||||
public float getValue() {
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public float[][] applyToHeightfield(float[][] heightfield){
|
||||
heightfield[locationX][locationY] = value;
|
||||
return heightfield;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user