netparser message pooling + multithread chunk io
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
This commit is contained in:
parent
deea49ba64
commit
c7dc9ef07d
26
docs/src/ideas/optimizationideas.md
Normal file
26
docs/src/ideas/optimizationideas.md
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
@page optimizationideas Optimization Ideas
|
||||||
|
|
||||||
|
Automatically transition between instanced actors and non-instanced actors for non-animated models
|
||||||
|
- Need to keep track of number of entities drawing a model, once that total passes a threshold convert them all to instanced actors
|
||||||
|
- name it something fun like "HybridActor" or "ShapeshiftActor"
|
||||||
|
|
||||||
|
Merge all kinematic bodies in a scene into one
|
||||||
|
- Need to keep track of individual entities' shapes after the merge
|
||||||
|
- When an individual entity dies, remove its shape from the main body
|
||||||
|
|
||||||
|
Second frustum full on shadow map pipeline
|
||||||
|
- only draw what is both in front of camera AND visible from sky (currently ignores sky's view)
|
||||||
|
|
||||||
|
Move hitbox position updates to behavior tree
|
||||||
|
- If an entity is not moving (ie a tree), don't have to update the hitbox's position
|
||||||
|
|
||||||
|
On client, only colide hitboxes closest to the player
|
||||||
|
- Currently collide all hitboxes and it's costly
|
||||||
|
|
||||||
|
Simplify collidable logic
|
||||||
|
- IE trees don't need to worry about gravity
|
||||||
|
|
||||||
|
In GriddedDataCellManager, skip ServerDataCells if they aren't doing anything interesting
|
||||||
|
|
||||||
|
In GriddedDataCellManager, run unload logic at the same time we're iterating through all cells to simulate the
|
||||||
|
|
||||||
@ -5,3 +5,4 @@
|
|||||||
- @subpage toolsindex
|
- @subpage toolsindex
|
||||||
- @subpage highleveldesignindex
|
- @subpage highleveldesignindex
|
||||||
- @subpage progress
|
- @subpage progress
|
||||||
|
- @subpage optimizationideas
|
||||||
|
|||||||
@ -1375,6 +1375,14 @@ Disable kinematic colliders on creation
|
|||||||
MainContentPipeline reduce allocations
|
MainContentPipeline reduce allocations
|
||||||
Move AI simulation to server level from chunk level
|
Move AI simulation to server level from chunk level
|
||||||
|
|
||||||
|
(03/29/2025)
|
||||||
|
Optimize ray casting near callback
|
||||||
|
Chunk file operation threadsafing
|
||||||
|
Multithread entity creation on server cell creation
|
||||||
|
Network message object pooling
|
||||||
|
Threadsafe EntityDataCellMapper
|
||||||
|
Code cleanup
|
||||||
|
Small ServerAttackTree fix (for when not holding an item)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -10,21 +10,35 @@ import electrosphere.renderer.texture.Texture;
|
|||||||
*/
|
*/
|
||||||
public class VoxelTextureAtlas {
|
public class VoxelTextureAtlas {
|
||||||
|
|
||||||
//A map of voxel id -> coordinates in the atlas texture for its texture
|
/**
|
||||||
|
* A map of voxel id -> coordinates in the atlas texture for its texture
|
||||||
|
*/
|
||||||
Map<Integer,Integer> typeCoordMap = new HashMap<Integer,Integer>();
|
Map<Integer,Integer> typeCoordMap = new HashMap<Integer,Integer>();
|
||||||
|
|
||||||
|
|
||||||
//the actual texture
|
/**
|
||||||
|
* The actual texture
|
||||||
|
*/
|
||||||
Texture specular;
|
Texture specular;
|
||||||
|
|
||||||
//the normal texture
|
/**
|
||||||
|
* The normal texture
|
||||||
|
*/
|
||||||
Texture normal;
|
Texture normal;
|
||||||
|
|
||||||
//the width in pixels of a single texture in the atlas
|
/**
|
||||||
|
* The width in pixels of a single texture in the atlas
|
||||||
|
*/
|
||||||
public static final int ATLAS_ELEMENT_DIM = 256;
|
public static final int ATLAS_ELEMENT_DIM = 256;
|
||||||
//the width in pixels of the whole atlas texture
|
|
||||||
|
/**
|
||||||
|
* The width in pixels of the whole atlas texture
|
||||||
|
*/
|
||||||
public static final int ATLAS_DIM = 8192;
|
public static final int ATLAS_DIM = 8192;
|
||||||
//number of textures per row in the atlas
|
|
||||||
|
/**
|
||||||
|
* Number of textures per row in the atlas
|
||||||
|
*/
|
||||||
public static final int ELEMENTS_PER_ROW = ATLAS_DIM / ATLAS_ELEMENT_DIM;
|
public static final int ELEMENTS_PER_ROW = ATLAS_DIM / ATLAS_ELEMENT_DIM;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,8 +1,5 @@
|
|||||||
package electrosphere.collision;
|
package electrosphere.collision;
|
||||||
|
|
||||||
import static org.ode4j.ode.OdeConstants.dContactBounce;
|
|
||||||
import static org.ode4j.ode.OdeConstants.dContactSoftCFM;
|
|
||||||
import static org.ode4j.ode.OdeConstants.dInfinity;
|
|
||||||
import static org.ode4j.ode.OdeHelper.areConnectedExcluding;
|
import static org.ode4j.ode.OdeHelper.areConnectedExcluding;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -28,7 +25,7 @@ public class RayCastCallback implements DNearCallback {
|
|||||||
/**
|
/**
|
||||||
* Maximum number of contacts allowed
|
* Maximum number of contacts allowed
|
||||||
*/
|
*/
|
||||||
static final int MAX_CONTACTS = 5;
|
static final int MAX_CONTACTS = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Really far away from the ray origin point
|
* Really far away from the ray origin point
|
||||||
@ -63,6 +60,7 @@ void RayCallback(void *Data, dGeomID Geometry1, dGeomID Geometry2) {
|
|||||||
public void call(Object data, DGeom o1, DGeom o2) {
|
public void call(Object data, DGeom o1, DGeom o2) {
|
||||||
// if (o1->body && o2->body) return;
|
// if (o1->body && o2->body) return;
|
||||||
RayCastCallbackData rayCastData = (RayCastCallbackData)data;
|
RayCastCallbackData rayCastData = (RayCastCallbackData)data;
|
||||||
|
|
||||||
//null out potentially previous results
|
//null out potentially previous results
|
||||||
// rayCastData.collisionPosition = null;
|
// rayCastData.collisionPosition = null;
|
||||||
// rayCastData.collidedEntity = null;
|
// rayCastData.collidedEntity = null;
|
||||||
@ -71,33 +69,25 @@ void RayCallback(void *Data, dGeomID Geometry1, dGeomID Geometry2) {
|
|||||||
DBody b2 = o2.getBody();
|
DBody b2 = o2.getBody();
|
||||||
if (b1!=null && b2!=null && areConnectedExcluding (b1,b2,DContactJoint.class)) return;
|
if (b1!=null && b2!=null && areConnectedExcluding (b1,b2,DContactJoint.class)) return;
|
||||||
|
|
||||||
//creates a buffer to store potential collisions
|
|
||||||
DContactBuffer contacts = new DContactBuffer(MAX_CONTACTS); // up to MAX_CONTACTS contacts per box-box
|
|
||||||
for (int i=0; i<MAX_CONTACTS; i++) {
|
|
||||||
DContact contact = contacts.get(i);
|
|
||||||
contact.surface.mode = dContactBounce | dContactSoftCFM;
|
|
||||||
contact.surface.mu = dInfinity;
|
|
||||||
contact.surface.mu2 = 0;
|
|
||||||
contact.surface.bounce = 0.1;
|
|
||||||
contact.surface.bounce_vel = 0.1;
|
|
||||||
contact.surface.soft_cfm = 0.01;
|
|
||||||
}
|
|
||||||
Collidable collidable1 = rayCastData.bodyEntityMap.get(b1);
|
Collidable collidable1 = rayCastData.bodyEntityMap.get(b1);
|
||||||
Collidable collidable2 = rayCastData.bodyEntityMap.get(b2);
|
Collidable collidable2 = rayCastData.bodyEntityMap.get(b2);
|
||||||
|
|
||||||
|
//don't self cast -- should work on both server and client
|
||||||
|
if(collidable1 != null && collidable1.getParent() == Globals.playerEntity){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(collidable2 != null && collidable2.getParent() == Globals.playerEntity){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Globals.profiler.beginAggregateCpuSample("RayCastCallback - try collisions");
|
||||||
if(
|
if(
|
||||||
(
|
rayCastData.collidableTypeMask == null ||
|
||||||
rayCastData.collidableTypeMask == null ||
|
(o1 instanceof DRay && rayCastData.collidableTypeMask.contains(collidable2.getType())) ||
|
||||||
(
|
(o2 instanceof DRay && rayCastData.collidableTypeMask.contains(collidable1.getType()))
|
||||||
rayCastData.collidableTypeMask != null &&
|
|
||||||
(
|
|
||||||
(o1 instanceof DRay && rayCastData.collidableTypeMask.contains(collidable2.getType())) ||
|
|
||||||
(o2 instanceof DRay && rayCastData.collidableTypeMask.contains(collidable1.getType()))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
) &&
|
|
||||||
(collidable1 == null || collidable1 != null && collidable1.getParent() != Globals.playerEntity) && //don't self cast -- should work on both server and client
|
|
||||||
(collidable2 == null || collidable2 != null && collidable2.getParent() != Globals.playerEntity) //don't self cast -- should work on both server and client
|
|
||||||
){
|
){
|
||||||
|
//creates a buffer to store potential collisions
|
||||||
|
DContactBuffer contacts = new DContactBuffer(MAX_CONTACTS); // up to MAX_CONTACTS contacts per box-box
|
||||||
//calculate collisions
|
//calculate collisions
|
||||||
int numc = OdeHelper.collide(o1,o2,MAX_CONTACTS,contacts.getGeomBuffer());
|
int numc = OdeHelper.collide(o1,o2,MAX_CONTACTS,contacts.getGeomBuffer());
|
||||||
//create DContacts based on each collision that occurs
|
//create DContacts based on each collision that occurs
|
||||||
@ -132,6 +122,7 @@ void RayCallback(void *Data, dGeomID Geometry1, dGeomID Geometry2) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Globals.profiler.endCpuSample();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -479,6 +479,9 @@ public class ServerAttackTree implements BehaviorTree {
|
|||||||
if(ServerToolbarState.getServerToolbarState(parent) != null){
|
if(ServerToolbarState.getServerToolbarState(parent) != null){
|
||||||
ServerToolbarState serverToolbarState = ServerToolbarState.getServerToolbarState(parent);
|
ServerToolbarState serverToolbarState = ServerToolbarState.getServerToolbarState(parent);
|
||||||
Entity item = serverToolbarState.getRealWorldItem();
|
Entity item = serverToolbarState.getRealWorldItem();
|
||||||
|
if(item == null){
|
||||||
|
return EntityDataStrings.ATTACK_MOVE_UNARMED;
|
||||||
|
}
|
||||||
if(ItemUtils.isWeapon(item)){
|
if(ItemUtils.isWeapon(item)){
|
||||||
currentWeapon = item;
|
currentWeapon = item;
|
||||||
switch(ItemUtils.getWeaponClass(item)){
|
switch(ItemUtils.getWeaponClass(item)){
|
||||||
|
|||||||
@ -28,11 +28,18 @@ public class AuthMessage extends NetworkMessage {
|
|||||||
* Constructor
|
* Constructor
|
||||||
* @param messageType The type of this message
|
* @param messageType The type of this message
|
||||||
*/
|
*/
|
||||||
AuthMessage(AuthMessageType messageType){
|
private AuthMessage(AuthMessageType messageType){
|
||||||
this.type = MessageType.AUTH_MESSAGE;
|
this.type = MessageType.AUTH_MESSAGE;
|
||||||
this.messageType = messageType;
|
this.messageType = messageType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
protected AuthMessage(){
|
||||||
|
this.type = MessageType.AUTH_MESSAGE;
|
||||||
|
}
|
||||||
|
|
||||||
public AuthMessageType getMessageSubtype(){
|
public AuthMessageType getMessageSubtype(){
|
||||||
return this.messageType;
|
return this.messageType;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,11 +31,18 @@ public class CharacterMessage extends NetworkMessage {
|
|||||||
* Constructor
|
* Constructor
|
||||||
* @param messageType The type of this message
|
* @param messageType The type of this message
|
||||||
*/
|
*/
|
||||||
CharacterMessage(CharacterMessageType messageType){
|
private CharacterMessage(CharacterMessageType messageType){
|
||||||
this.type = MessageType.CHARACTER_MESSAGE;
|
this.type = MessageType.CHARACTER_MESSAGE;
|
||||||
this.messageType = messageType;
|
this.messageType = messageType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
protected CharacterMessage(){
|
||||||
|
this.type = MessageType.CHARACTER_MESSAGE;
|
||||||
|
}
|
||||||
|
|
||||||
public CharacterMessageType getMessageSubtype(){
|
public CharacterMessageType getMessageSubtype(){
|
||||||
return this.messageType;
|
return this.messageType;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -35,11 +35,18 @@ public class CombatMessage extends NetworkMessage {
|
|||||||
* Constructor
|
* Constructor
|
||||||
* @param messageType The type of this message
|
* @param messageType The type of this message
|
||||||
*/
|
*/
|
||||||
CombatMessage(CombatMessageType messageType){
|
private CombatMessage(CombatMessageType messageType){
|
||||||
this.type = MessageType.COMBAT_MESSAGE;
|
this.type = MessageType.COMBAT_MESSAGE;
|
||||||
this.messageType = messageType;
|
this.messageType = messageType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
protected CombatMessage(){
|
||||||
|
this.type = MessageType.COMBAT_MESSAGE;
|
||||||
|
}
|
||||||
|
|
||||||
public CombatMessageType getMessageSubtype(){
|
public CombatMessageType getMessageSubtype(){
|
||||||
return this.messageType;
|
return this.messageType;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -66,11 +66,18 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
* Constructor
|
* Constructor
|
||||||
* @param messageType The type of this message
|
* @param messageType The type of this message
|
||||||
*/
|
*/
|
||||||
EntityMessage(EntityMessageType messageType){
|
private EntityMessage(EntityMessageType messageType){
|
||||||
this.type = MessageType.ENTITY_MESSAGE;
|
this.type = MessageType.ENTITY_MESSAGE;
|
||||||
this.messageType = messageType;
|
this.messageType = messageType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
protected EntityMessage(){
|
||||||
|
this.type = MessageType.ENTITY_MESSAGE;
|
||||||
|
}
|
||||||
|
|
||||||
public EntityMessageType getMessageSubtype(){
|
public EntityMessageType getMessageSubtype(){
|
||||||
return this.messageType;
|
return this.messageType;
|
||||||
}
|
}
|
||||||
@ -688,8 +695,9 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
/**
|
/**
|
||||||
* Parses a message of type Create
|
* Parses a message of type Create
|
||||||
*/
|
*/
|
||||||
public static EntityMessage parseCreateMessage(CircularByteBuffer byteBuffer){
|
public static EntityMessage parseCreateMessage(CircularByteBuffer byteBuffer, MessagePool pool){
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.CREATE);
|
EntityMessage rVal = (EntityMessage)pool.get(MessageType.ENTITY_MESSAGE);
|
||||||
|
rVal.messageType = EntityMessageType.CREATE;
|
||||||
stripPacketHeader(byteBuffer);
|
stripPacketHeader(byteBuffer);
|
||||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
rVal.setentityCategory(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setentityCategory(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
@ -728,8 +736,9 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
/**
|
/**
|
||||||
* Parses a message of type moveUpdate
|
* Parses a message of type moveUpdate
|
||||||
*/
|
*/
|
||||||
public static EntityMessage parsemoveUpdateMessage(CircularByteBuffer byteBuffer){
|
public static EntityMessage parsemoveUpdateMessage(CircularByteBuffer byteBuffer, MessagePool pool){
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.MOVEUPDATE);
|
EntityMessage rVal = (EntityMessage)pool.get(MessageType.ENTITY_MESSAGE);
|
||||||
|
rVal.messageType = EntityMessageType.MOVEUPDATE;
|
||||||
stripPacketHeader(byteBuffer);
|
stripPacketHeader(byteBuffer);
|
||||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
||||||
@ -770,8 +779,9 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
/**
|
/**
|
||||||
* Parses a message of type attackUpdate
|
* Parses a message of type attackUpdate
|
||||||
*/
|
*/
|
||||||
public static EntityMessage parseattackUpdateMessage(CircularByteBuffer byteBuffer){
|
public static EntityMessage parseattackUpdateMessage(CircularByteBuffer byteBuffer, MessagePool pool){
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.ATTACKUPDATE);
|
EntityMessage rVal = (EntityMessage)pool.get(MessageType.ENTITY_MESSAGE);
|
||||||
|
rVal.messageType = EntityMessageType.ATTACKUPDATE;
|
||||||
stripPacketHeader(byteBuffer);
|
stripPacketHeader(byteBuffer);
|
||||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
||||||
@ -808,8 +818,9 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
/**
|
/**
|
||||||
* Parses a message of type startAttack
|
* Parses a message of type startAttack
|
||||||
*/
|
*/
|
||||||
public static EntityMessage parsestartAttackMessage(CircularByteBuffer byteBuffer){
|
public static EntityMessage parsestartAttackMessage(CircularByteBuffer byteBuffer, MessagePool pool){
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.STARTATTACK);
|
EntityMessage rVal = (EntityMessage)pool.get(MessageType.ENTITY_MESSAGE);
|
||||||
|
rVal.messageType = EntityMessageType.STARTATTACK;
|
||||||
stripPacketHeader(byteBuffer);
|
stripPacketHeader(byteBuffer);
|
||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
@ -826,8 +837,9 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
/**
|
/**
|
||||||
* Parses a message of type Kill
|
* Parses a message of type Kill
|
||||||
*/
|
*/
|
||||||
public static EntityMessage parseKillMessage(CircularByteBuffer byteBuffer){
|
public static EntityMessage parseKillMessage(CircularByteBuffer byteBuffer, MessagePool pool){
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.KILL);
|
EntityMessage rVal = (EntityMessage)pool.get(MessageType.ENTITY_MESSAGE);
|
||||||
|
rVal.messageType = EntityMessageType.KILL;
|
||||||
stripPacketHeader(byteBuffer);
|
stripPacketHeader(byteBuffer);
|
||||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
||||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
@ -848,8 +860,9 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
/**
|
/**
|
||||||
* Parses a message of type Destroy
|
* Parses a message of type Destroy
|
||||||
*/
|
*/
|
||||||
public static EntityMessage parseDestroyMessage(CircularByteBuffer byteBuffer){
|
public static EntityMessage parseDestroyMessage(CircularByteBuffer byteBuffer, MessagePool pool){
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.DESTROY);
|
EntityMessage rVal = (EntityMessage)pool.get(MessageType.ENTITY_MESSAGE);
|
||||||
|
rVal.messageType = EntityMessageType.DESTROY;
|
||||||
stripPacketHeader(byteBuffer);
|
stripPacketHeader(byteBuffer);
|
||||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
return rVal;
|
return rVal;
|
||||||
@ -868,8 +881,9 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
/**
|
/**
|
||||||
* Parses a message of type setProperty
|
* Parses a message of type setProperty
|
||||||
*/
|
*/
|
||||||
public static EntityMessage parsesetPropertyMessage(CircularByteBuffer byteBuffer){
|
public static EntityMessage parsesetPropertyMessage(CircularByteBuffer byteBuffer, MessagePool pool){
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.SETPROPERTY);
|
EntityMessage rVal = (EntityMessage)pool.get(MessageType.ENTITY_MESSAGE);
|
||||||
|
rVal.messageType = EntityMessageType.SETPROPERTY;
|
||||||
stripPacketHeader(byteBuffer);
|
stripPacketHeader(byteBuffer);
|
||||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
||||||
@ -922,8 +936,9 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
/**
|
/**
|
||||||
* Parses a message of type attachEntityToEntity
|
* Parses a message of type attachEntityToEntity
|
||||||
*/
|
*/
|
||||||
public static EntityMessage parseattachEntityToEntityMessage(CircularByteBuffer byteBuffer){
|
public static EntityMessage parseattachEntityToEntityMessage(CircularByteBuffer byteBuffer, MessagePool pool){
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.ATTACHENTITYTOENTITY);
|
EntityMessage rVal = (EntityMessage)pool.get(MessageType.ENTITY_MESSAGE);
|
||||||
|
rVal.messageType = EntityMessageType.ATTACHENTITYTOENTITY;
|
||||||
stripPacketHeader(byteBuffer);
|
stripPacketHeader(byteBuffer);
|
||||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
rVal.setbone(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
|
rVal.setbone(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
|
||||||
@ -946,8 +961,9 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
/**
|
/**
|
||||||
* Parses a message of type updateEntityViewDir
|
* Parses a message of type updateEntityViewDir
|
||||||
*/
|
*/
|
||||||
public static EntityMessage parseupdateEntityViewDirMessage(CircularByteBuffer byteBuffer){
|
public static EntityMessage parseupdateEntityViewDirMessage(CircularByteBuffer byteBuffer, MessagePool pool){
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.UPDATEENTITYVIEWDIR);
|
EntityMessage rVal = (EntityMessage)pool.get(MessageType.ENTITY_MESSAGE);
|
||||||
|
rVal.messageType = EntityMessageType.UPDATEENTITYVIEWDIR;
|
||||||
stripPacketHeader(byteBuffer);
|
stripPacketHeader(byteBuffer);
|
||||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
||||||
@ -974,8 +990,9 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
/**
|
/**
|
||||||
* Parses a message of type syncPhysics
|
* Parses a message of type syncPhysics
|
||||||
*/
|
*/
|
||||||
public static EntityMessage parsesyncPhysicsMessage(CircularByteBuffer byteBuffer){
|
public static EntityMessage parsesyncPhysicsMessage(CircularByteBuffer byteBuffer, MessagePool pool){
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.SYNCPHYSICS);
|
EntityMessage rVal = (EntityMessage)pool.get(MessageType.ENTITY_MESSAGE);
|
||||||
|
rVal.messageType = EntityMessageType.SYNCPHYSICS;
|
||||||
stripPacketHeader(byteBuffer);
|
stripPacketHeader(byteBuffer);
|
||||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
||||||
|
|||||||
@ -47,11 +47,18 @@ public class InventoryMessage extends NetworkMessage {
|
|||||||
* Constructor
|
* Constructor
|
||||||
* @param messageType The type of this message
|
* @param messageType The type of this message
|
||||||
*/
|
*/
|
||||||
InventoryMessage(InventoryMessageType messageType){
|
private InventoryMessage(InventoryMessageType messageType){
|
||||||
this.type = MessageType.INVENTORY_MESSAGE;
|
this.type = MessageType.INVENTORY_MESSAGE;
|
||||||
this.messageType = messageType;
|
this.messageType = messageType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
protected InventoryMessage(){
|
||||||
|
this.type = MessageType.INVENTORY_MESSAGE;
|
||||||
|
}
|
||||||
|
|
||||||
public InventoryMessageType getMessageSubtype(){
|
public InventoryMessageType getMessageSubtype(){
|
||||||
return this.messageType;
|
return this.messageType;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,11 +25,18 @@ public class LoreMessage extends NetworkMessage {
|
|||||||
* Constructor
|
* Constructor
|
||||||
* @param messageType The type of this message
|
* @param messageType The type of this message
|
||||||
*/
|
*/
|
||||||
LoreMessage(LoreMessageType messageType){
|
private LoreMessage(LoreMessageType messageType){
|
||||||
this.type = MessageType.LORE_MESSAGE;
|
this.type = MessageType.LORE_MESSAGE;
|
||||||
this.messageType = messageType;
|
this.messageType = messageType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
protected LoreMessage(){
|
||||||
|
this.type = MessageType.LORE_MESSAGE;
|
||||||
|
}
|
||||||
|
|
||||||
public LoreMessageType getMessageSubtype(){
|
public LoreMessageType getMessageSubtype(){
|
||||||
return this.messageType;
|
return this.messageType;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,176 @@
|
|||||||
|
package electrosphere.net.parser.net.message;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
|
import electrosphere.net.parser.net.message.NetworkMessage.MessageType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pools message objects to reduce allocations
|
||||||
|
*/
|
||||||
|
public class MessagePool {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pools auth messages
|
||||||
|
*/
|
||||||
|
List<NetworkMessage> authMessagePool = new LinkedList<NetworkMessage>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pools character messages
|
||||||
|
*/
|
||||||
|
List<NetworkMessage> characterMessagePool = new LinkedList<NetworkMessage>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pools combat messages
|
||||||
|
*/
|
||||||
|
List<NetworkMessage> combatMessagePool = new LinkedList<NetworkMessage>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pools entity messages
|
||||||
|
*/
|
||||||
|
List<NetworkMessage> entityMessagePool = new LinkedList<NetworkMessage>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pools inventory messages
|
||||||
|
*/
|
||||||
|
List<NetworkMessage> inventoryMessagePool = new LinkedList<NetworkMessage>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pools lore messages
|
||||||
|
*/
|
||||||
|
List<NetworkMessage> loreMessagePool = new LinkedList<NetworkMessage>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pools player messages
|
||||||
|
*/
|
||||||
|
List<NetworkMessage> playerMessagePool = new LinkedList<NetworkMessage>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pools server messages
|
||||||
|
*/
|
||||||
|
List<NetworkMessage> serverMessagePool = new LinkedList<NetworkMessage>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pools synchronization messages
|
||||||
|
*/
|
||||||
|
List<NetworkMessage> synchronizationMessagePool = new LinkedList<NetworkMessage>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pools terrain messages
|
||||||
|
*/
|
||||||
|
List<NetworkMessage> terrainMessagePool = new LinkedList<NetworkMessage>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lock for thread-safeing operations
|
||||||
|
*/
|
||||||
|
ReentrantLock lock = new ReentrantLock();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a network message from the pool. Allocates if no free one is available
|
||||||
|
* @param type The type of the message
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public NetworkMessage get(MessageType type){
|
||||||
|
NetworkMessage rVal = null;
|
||||||
|
lock.lock();
|
||||||
|
if(type == MessageType.AUTH_MESSAGE){
|
||||||
|
if(authMessagePool.size() > 0){
|
||||||
|
rVal = authMessagePool.remove(0);
|
||||||
|
} else {
|
||||||
|
rVal = new AuthMessage();
|
||||||
|
}
|
||||||
|
} else if(type == MessageType.CHARACTER_MESSAGE){
|
||||||
|
if(characterMessagePool.size() > 0){
|
||||||
|
rVal = characterMessagePool.remove(0);
|
||||||
|
} else {
|
||||||
|
rVal = new CharacterMessage();
|
||||||
|
}
|
||||||
|
} else if(type == MessageType.COMBAT_MESSAGE){
|
||||||
|
if(combatMessagePool.size() > 0){
|
||||||
|
rVal = combatMessagePool.remove(0);
|
||||||
|
} else {
|
||||||
|
rVal = new CombatMessage();
|
||||||
|
}
|
||||||
|
} else if(type == MessageType.ENTITY_MESSAGE){
|
||||||
|
if(entityMessagePool.size() > 0){
|
||||||
|
rVal = entityMessagePool.remove(0);
|
||||||
|
} else {
|
||||||
|
rVal = new EntityMessage();
|
||||||
|
}
|
||||||
|
} else if(type == MessageType.INVENTORY_MESSAGE){
|
||||||
|
if(inventoryMessagePool.size() > 0){
|
||||||
|
rVal = inventoryMessagePool.remove(0);
|
||||||
|
} else {
|
||||||
|
rVal = new InventoryMessage();
|
||||||
|
}
|
||||||
|
} else if(type == MessageType.LORE_MESSAGE){
|
||||||
|
if(loreMessagePool.size() > 0){
|
||||||
|
rVal = loreMessagePool.remove(0);
|
||||||
|
} else {
|
||||||
|
rVal = new LoreMessage();
|
||||||
|
}
|
||||||
|
} else if(type == MessageType.PLAYER_MESSAGE){
|
||||||
|
if(playerMessagePool.size() > 0){
|
||||||
|
rVal = playerMessagePool.remove(0);
|
||||||
|
} else {
|
||||||
|
rVal = new PlayerMessage();
|
||||||
|
}
|
||||||
|
} else if(type == MessageType.SERVER_MESSAGE){
|
||||||
|
if(serverMessagePool.size() > 0){
|
||||||
|
rVal = serverMessagePool.remove(0);
|
||||||
|
} else {
|
||||||
|
rVal = new ServerMessage();
|
||||||
|
}
|
||||||
|
} else if(type == MessageType.SYNCHRONIZATION_MESSAGE){
|
||||||
|
if(synchronizationMessagePool.size() > 0){
|
||||||
|
rVal = synchronizationMessagePool.remove(0);
|
||||||
|
} else {
|
||||||
|
rVal = new SynchronizationMessage();
|
||||||
|
}
|
||||||
|
} else if(type == MessageType.TERRAIN_MESSAGE){
|
||||||
|
if(terrainMessagePool.size() > 0){
|
||||||
|
rVal = terrainMessagePool.remove(0);
|
||||||
|
} else {
|
||||||
|
rVal = new TerrainMessage();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Error("Unsupported message type! " + type);
|
||||||
|
}
|
||||||
|
lock.unlock();
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Releases a message back into the pool
|
||||||
|
* @param message The message
|
||||||
|
*/
|
||||||
|
public void release(NetworkMessage message){
|
||||||
|
lock.lock();
|
||||||
|
if(message instanceof AuthMessage){
|
||||||
|
authMessagePool.add(message);
|
||||||
|
} else if(message instanceof CharacterMessage){
|
||||||
|
characterMessagePool.add(message);
|
||||||
|
} else if(message instanceof CombatMessage){
|
||||||
|
combatMessagePool.add(message);
|
||||||
|
} else if(message instanceof EntityMessage){
|
||||||
|
entityMessagePool.add(message);
|
||||||
|
} else if(message instanceof InventoryMessage){
|
||||||
|
inventoryMessagePool.add(message);
|
||||||
|
} else if(message instanceof LoreMessage){
|
||||||
|
loreMessagePool.add(message);
|
||||||
|
} else if(message instanceof PlayerMessage){
|
||||||
|
playerMessagePool.add(message);
|
||||||
|
} else if(message instanceof ServerMessage){
|
||||||
|
serverMessagePool.add(message);
|
||||||
|
} else if(message instanceof SynchronizationMessage){
|
||||||
|
synchronizationMessagePool.add(message);
|
||||||
|
} else if(message instanceof TerrainMessage){
|
||||||
|
terrainMessagePool.add(message);
|
||||||
|
} else {
|
||||||
|
throw new Error("Unsupported message type! " + message.getClass());
|
||||||
|
}
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,16 +1,16 @@
|
|||||||
package electrosphere.net.parser.net.message;
|
package electrosphere.net.parser.net.message;
|
||||||
|
|
||||||
import io.github.studiorailgun.CircularByteBuffer;
|
import io.github.studiorailgun.CircularByteBuffer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A network message
|
* A network message
|
||||||
*/
|
*/
|
||||||
public abstract class NetworkMessage {
|
public abstract class NetworkMessage {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The different categories of network messages
|
* The different categories of network messages
|
||||||
*/
|
*/
|
||||||
public enum MessageType {
|
public enum MessageType {
|
||||||
ENTITY_MESSAGE,
|
ENTITY_MESSAGE,
|
||||||
LORE_MESSAGE,
|
LORE_MESSAGE,
|
||||||
PLAYER_MESSAGE,
|
PLAYER_MESSAGE,
|
||||||
@ -21,102 +21,103 @@ public abstract class NetworkMessage {
|
|||||||
INVENTORY_MESSAGE,
|
INVENTORY_MESSAGE,
|
||||||
SYNCHRONIZATION_MESSAGE,
|
SYNCHRONIZATION_MESSAGE,
|
||||||
COMBAT_MESSAGE,
|
COMBAT_MESSAGE,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of this message
|
* The type of this message
|
||||||
*/
|
*/
|
||||||
MessageType type;
|
MessageType type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tracks whether the message has been serialized to bytes or not
|
* Tracks whether the message has been serialized to bytes or not
|
||||||
*/
|
*/
|
||||||
boolean serialized;
|
boolean serialized;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The raw bytes contained in the message
|
* The raw bytes contained in the message
|
||||||
*/
|
*/
|
||||||
byte[] rawBytes;
|
byte[] rawBytes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the type of the message
|
* Gets the type of the message
|
||||||
* @return The type of the message
|
* @return The type of the message
|
||||||
*/
|
*/
|
||||||
public MessageType getType() {
|
public MessageType getType() {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the raw bytes of the message
|
* Gets the raw bytes of the message
|
||||||
* @return The raw bytes
|
* @return The raw bytes
|
||||||
*/
|
*/
|
||||||
public byte[] getRawBytes() {
|
public byte[] getRawBytes() {
|
||||||
return rawBytes;
|
return rawBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the byte stream for the next message
|
* Parses the byte stream for the next message
|
||||||
* @param byteBuffer The byte buffer
|
* @param byteBuffer The byte buffer
|
||||||
* @return The message if one is at the front of the byte stream, null otherwise
|
* @param pool The message pool
|
||||||
*/
|
* @return The message if one is at the front of the byte stream, null otherwise
|
||||||
public static NetworkMessage parseBytestreamForMessage(CircularByteBuffer byteBuffer){
|
*/
|
||||||
NetworkMessage rVal = null;
|
public static NetworkMessage parseBytestreamForMessage(CircularByteBuffer byteBuffer, MessagePool pool){
|
||||||
byte firstByte;
|
NetworkMessage rVal = null;
|
||||||
byte secondByte;
|
byte firstByte;
|
||||||
if(byteBuffer.getRemaining() > 1){
|
byte secondByte;
|
||||||
firstByte = byteBuffer.peek();
|
if(byteBuffer.getRemaining() > 1){
|
||||||
switch(firstByte){
|
firstByte = byteBuffer.peek();
|
||||||
|
switch(firstByte){
|
||||||
case TypeBytes.MESSAGE_TYPE_ENTITY:
|
case TypeBytes.MESSAGE_TYPE_ENTITY:
|
||||||
secondByte = byteBuffer.peek(1);
|
secondByte = byteBuffer.peek(1);
|
||||||
switch(secondByte){
|
switch(secondByte){
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_CREATE:
|
case TypeBytes.ENTITY_MESSAGE_TYPE_CREATE:
|
||||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = EntityMessage.parseCreateMessage(byteBuffer);
|
rVal = EntityMessage.parseCreateMessage(byteBuffer,pool);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_MOVEUPDATE:
|
case TypeBytes.ENTITY_MESSAGE_TYPE_MOVEUPDATE:
|
||||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = EntityMessage.parsemoveUpdateMessage(byteBuffer);
|
rVal = EntityMessage.parsemoveUpdateMessage(byteBuffer,pool);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_ATTACKUPDATE:
|
case TypeBytes.ENTITY_MESSAGE_TYPE_ATTACKUPDATE:
|
||||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = EntityMessage.parseattackUpdateMessage(byteBuffer);
|
rVal = EntityMessage.parseattackUpdateMessage(byteBuffer,pool);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_STARTATTACK:
|
case TypeBytes.ENTITY_MESSAGE_TYPE_STARTATTACK:
|
||||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = EntityMessage.parsestartAttackMessage(byteBuffer);
|
rVal = EntityMessage.parsestartAttackMessage(byteBuffer,pool);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_KILL:
|
case TypeBytes.ENTITY_MESSAGE_TYPE_KILL:
|
||||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = EntityMessage.parseKillMessage(byteBuffer);
|
rVal = EntityMessage.parseKillMessage(byteBuffer,pool);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_DESTROY:
|
case TypeBytes.ENTITY_MESSAGE_TYPE_DESTROY:
|
||||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = EntityMessage.parseDestroyMessage(byteBuffer);
|
rVal = EntityMessage.parseDestroyMessage(byteBuffer,pool);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETPROPERTY:
|
case TypeBytes.ENTITY_MESSAGE_TYPE_SETPROPERTY:
|
||||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = EntityMessage.parsesetPropertyMessage(byteBuffer);
|
rVal = EntityMessage.parsesetPropertyMessage(byteBuffer,pool);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_ATTACHENTITYTOENTITY:
|
case TypeBytes.ENTITY_MESSAGE_TYPE_ATTACHENTITYTOENTITY:
|
||||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = EntityMessage.parseattachEntityToEntityMessage(byteBuffer);
|
rVal = EntityMessage.parseattachEntityToEntityMessage(byteBuffer,pool);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_UPDATEENTITYVIEWDIR:
|
case TypeBytes.ENTITY_MESSAGE_TYPE_UPDATEENTITYVIEWDIR:
|
||||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = EntityMessage.parseupdateEntityViewDirMessage(byteBuffer);
|
rVal = EntityMessage.parseupdateEntityViewDirMessage(byteBuffer,pool);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SYNCPHYSICS:
|
case TypeBytes.ENTITY_MESSAGE_TYPE_SYNCPHYSICS:
|
||||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = EntityMessage.parsesyncPhysicsMessage(byteBuffer);
|
rVal = EntityMessage.parsesyncPhysicsMessage(byteBuffer,pool);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -156,82 +157,82 @@ public abstract class NetworkMessage {
|
|||||||
switch(secondByte){
|
switch(secondByte){
|
||||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTMETADATA:
|
case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTMETADATA:
|
||||||
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = TerrainMessage.parseRequestMetadataMessage(byteBuffer);
|
rVal = TerrainMessage.parseRequestMetadataMessage(byteBuffer,pool);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_RESPONSEMETADATA:
|
case TypeBytes.TERRAIN_MESSAGE_TYPE_RESPONSEMETADATA:
|
||||||
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = TerrainMessage.parseResponseMetadataMessage(byteBuffer);
|
rVal = TerrainMessage.parseResponseMetadataMessage(byteBuffer,pool);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTEDITVOXEL:
|
case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTEDITVOXEL:
|
||||||
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = TerrainMessage.parseRequestEditVoxelMessage(byteBuffer);
|
rVal = TerrainMessage.parseRequestEditVoxelMessage(byteBuffer,pool);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_UPDATEVOXEL:
|
case TypeBytes.TERRAIN_MESSAGE_TYPE_UPDATEVOXEL:
|
||||||
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = TerrainMessage.parseUpdateVoxelMessage(byteBuffer);
|
rVal = TerrainMessage.parseUpdateVoxelMessage(byteBuffer,pool);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTUSETERRAINPALETTE:
|
case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTUSETERRAINPALETTE:
|
||||||
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = TerrainMessage.parseRequestUseTerrainPaletteMessage(byteBuffer);
|
rVal = TerrainMessage.parseRequestUseTerrainPaletteMessage(byteBuffer,pool);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_SPAWNPOSITION:
|
case TypeBytes.TERRAIN_MESSAGE_TYPE_SPAWNPOSITION:
|
||||||
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = TerrainMessage.parseSpawnPositionMessage(byteBuffer);
|
rVal = TerrainMessage.parseSpawnPositionMessage(byteBuffer,pool);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTCHUNKDATA:
|
case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTCHUNKDATA:
|
||||||
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = TerrainMessage.parseRequestChunkDataMessage(byteBuffer);
|
rVal = TerrainMessage.parseRequestChunkDataMessage(byteBuffer,pool);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_SENDCHUNKDATA:
|
case TypeBytes.TERRAIN_MESSAGE_TYPE_SENDCHUNKDATA:
|
||||||
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = TerrainMessage.parsesendChunkDataMessage(byteBuffer);
|
rVal = TerrainMessage.parsesendChunkDataMessage(byteBuffer,pool);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTREDUCEDCHUNKDATA:
|
case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTREDUCEDCHUNKDATA:
|
||||||
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = TerrainMessage.parseRequestReducedChunkDataMessage(byteBuffer);
|
rVal = TerrainMessage.parseRequestReducedChunkDataMessage(byteBuffer,pool);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_SENDREDUCEDCHUNKDATA:
|
case TypeBytes.TERRAIN_MESSAGE_TYPE_SENDREDUCEDCHUNKDATA:
|
||||||
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = TerrainMessage.parseSendReducedChunkDataMessage(byteBuffer);
|
rVal = TerrainMessage.parseSendReducedChunkDataMessage(byteBuffer,pool);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTREDUCEDBLOCKDATA:
|
case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTREDUCEDBLOCKDATA:
|
||||||
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = TerrainMessage.parseRequestReducedBlockDataMessage(byteBuffer);
|
rVal = TerrainMessage.parseRequestReducedBlockDataMessage(byteBuffer,pool);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_SENDREDUCEDBLOCKDATA:
|
case TypeBytes.TERRAIN_MESSAGE_TYPE_SENDREDUCEDBLOCKDATA:
|
||||||
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = TerrainMessage.parseSendReducedBlockDataMessage(byteBuffer);
|
rVal = TerrainMessage.parseSendReducedBlockDataMessage(byteBuffer,pool);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_UPDATEBLOCK:
|
case TypeBytes.TERRAIN_MESSAGE_TYPE_UPDATEBLOCK:
|
||||||
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = TerrainMessage.parseUpdateBlockMessage(byteBuffer);
|
rVal = TerrainMessage.parseUpdateBlockMessage(byteBuffer,pool);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTFLUIDDATA:
|
case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTFLUIDDATA:
|
||||||
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = TerrainMessage.parseRequestFluidDataMessage(byteBuffer);
|
rVal = TerrainMessage.parseRequestFluidDataMessage(byteBuffer,pool);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_SENDFLUIDDATA:
|
case TypeBytes.TERRAIN_MESSAGE_TYPE_SENDFLUIDDATA:
|
||||||
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = TerrainMessage.parsesendFluidDataMessage(byteBuffer);
|
rVal = TerrainMessage.parsesendFluidDataMessage(byteBuffer,pool);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_UPDATEFLUIDDATA:
|
case TypeBytes.TERRAIN_MESSAGE_TYPE_UPDATEFLUIDDATA:
|
||||||
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = TerrainMessage.parseupdateFluidDataMessage(byteBuffer);
|
rVal = TerrainMessage.parseupdateFluidDataMessage(byteBuffer,pool);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -456,23 +457,23 @@ public abstract class NetworkMessage {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if this message is serialized or not
|
* Checks if this message is serialized or not
|
||||||
* @return true if it is serialized, false otherwise
|
* @return true if it is serialized, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean isSerialized(){
|
public boolean isSerialized(){
|
||||||
return serialized;
|
return serialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serializes the message
|
* Serializes the message
|
||||||
*/
|
*/
|
||||||
abstract void serialize();
|
abstract void serialize();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -25,11 +25,18 @@ public class PlayerMessage extends NetworkMessage {
|
|||||||
* Constructor
|
* Constructor
|
||||||
* @param messageType The type of this message
|
* @param messageType The type of this message
|
||||||
*/
|
*/
|
||||||
PlayerMessage(PlayerMessageType messageType){
|
private PlayerMessage(PlayerMessageType messageType){
|
||||||
this.type = MessageType.PLAYER_MESSAGE;
|
this.type = MessageType.PLAYER_MESSAGE;
|
||||||
this.messageType = messageType;
|
this.messageType = messageType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
protected PlayerMessage(){
|
||||||
|
this.type = MessageType.PLAYER_MESSAGE;
|
||||||
|
}
|
||||||
|
|
||||||
public PlayerMessageType getMessageSubtype(){
|
public PlayerMessageType getMessageSubtype(){
|
||||||
return this.messageType;
|
return this.messageType;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,11 +20,18 @@ public class ServerMessage extends NetworkMessage {
|
|||||||
* Constructor
|
* Constructor
|
||||||
* @param messageType The type of this message
|
* @param messageType The type of this message
|
||||||
*/
|
*/
|
||||||
ServerMessage(ServerMessageType messageType){
|
private ServerMessage(ServerMessageType messageType){
|
||||||
this.type = MessageType.SERVER_MESSAGE;
|
this.type = MessageType.SERVER_MESSAGE;
|
||||||
this.messageType = messageType;
|
this.messageType = messageType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
protected ServerMessage(){
|
||||||
|
this.type = MessageType.SERVER_MESSAGE;
|
||||||
|
}
|
||||||
|
|
||||||
public ServerMessageType getMessageSubtype(){
|
public ServerMessageType getMessageSubtype(){
|
||||||
return this.messageType;
|
return this.messageType;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,11 +42,18 @@ public class SynchronizationMessage extends NetworkMessage {
|
|||||||
* Constructor
|
* Constructor
|
||||||
* @param messageType The type of this message
|
* @param messageType The type of this message
|
||||||
*/
|
*/
|
||||||
SynchronizationMessage(SynchronizationMessageType messageType){
|
private SynchronizationMessage(SynchronizationMessageType messageType){
|
||||||
this.type = MessageType.SYNCHRONIZATION_MESSAGE;
|
this.type = MessageType.SYNCHRONIZATION_MESSAGE;
|
||||||
this.messageType = messageType;
|
this.messageType = messageType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
protected SynchronizationMessage(){
|
||||||
|
this.type = MessageType.SYNCHRONIZATION_MESSAGE;
|
||||||
|
}
|
||||||
|
|
||||||
public SynchronizationMessageType getMessageSubtype(){
|
public SynchronizationMessageType getMessageSubtype(){
|
||||||
return this.messageType;
|
return this.messageType;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -64,11 +64,18 @@ public class TerrainMessage extends NetworkMessage {
|
|||||||
* Constructor
|
* Constructor
|
||||||
* @param messageType The type of this message
|
* @param messageType The type of this message
|
||||||
*/
|
*/
|
||||||
TerrainMessage(TerrainMessageType messageType){
|
private TerrainMessage(TerrainMessageType messageType){
|
||||||
this.type = MessageType.TERRAIN_MESSAGE;
|
this.type = MessageType.TERRAIN_MESSAGE;
|
||||||
this.messageType = messageType;
|
this.messageType = messageType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
protected TerrainMessage(){
|
||||||
|
this.type = MessageType.TERRAIN_MESSAGE;
|
||||||
|
}
|
||||||
|
|
||||||
public TerrainMessageType getMessageSubtype(){
|
public TerrainMessageType getMessageSubtype(){
|
||||||
return this.messageType;
|
return this.messageType;
|
||||||
}
|
}
|
||||||
@ -536,8 +543,9 @@ public class TerrainMessage extends NetworkMessage {
|
|||||||
/**
|
/**
|
||||||
* Parses a message of type RequestMetadata
|
* Parses a message of type RequestMetadata
|
||||||
*/
|
*/
|
||||||
public static TerrainMessage parseRequestMetadataMessage(CircularByteBuffer byteBuffer){
|
public static TerrainMessage parseRequestMetadataMessage(CircularByteBuffer byteBuffer, MessagePool pool){
|
||||||
TerrainMessage rVal = new TerrainMessage(TerrainMessageType.REQUESTMETADATA);
|
TerrainMessage rVal = (TerrainMessage)pool.get(MessageType.TERRAIN_MESSAGE);
|
||||||
|
rVal.messageType = TerrainMessageType.REQUESTMETADATA;
|
||||||
stripPacketHeader(byteBuffer);
|
stripPacketHeader(byteBuffer);
|
||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
@ -554,8 +562,9 @@ public class TerrainMessage extends NetworkMessage {
|
|||||||
/**
|
/**
|
||||||
* Parses a message of type ResponseMetadata
|
* Parses a message of type ResponseMetadata
|
||||||
*/
|
*/
|
||||||
public static TerrainMessage parseResponseMetadataMessage(CircularByteBuffer byteBuffer){
|
public static TerrainMessage parseResponseMetadataMessage(CircularByteBuffer byteBuffer, MessagePool pool){
|
||||||
TerrainMessage rVal = new TerrainMessage(TerrainMessageType.RESPONSEMETADATA);
|
TerrainMessage rVal = (TerrainMessage)pool.get(MessageType.TERRAIN_MESSAGE);
|
||||||
|
rVal.messageType = TerrainMessageType.RESPONSEMETADATA;
|
||||||
stripPacketHeader(byteBuffer);
|
stripPacketHeader(byteBuffer);
|
||||||
rVal.setworldSizeDiscrete(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setworldSizeDiscrete(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
rVal.setworldMinX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setworldMinX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
@ -586,8 +595,9 @@ public class TerrainMessage extends NetworkMessage {
|
|||||||
/**
|
/**
|
||||||
* Parses a message of type RequestEditVoxel
|
* Parses a message of type RequestEditVoxel
|
||||||
*/
|
*/
|
||||||
public static TerrainMessage parseRequestEditVoxelMessage(CircularByteBuffer byteBuffer){
|
public static TerrainMessage parseRequestEditVoxelMessage(CircularByteBuffer byteBuffer, MessagePool pool){
|
||||||
TerrainMessage rVal = new TerrainMessage(TerrainMessageType.REQUESTEDITVOXEL);
|
TerrainMessage rVal = (TerrainMessage)pool.get(MessageType.TERRAIN_MESSAGE);
|
||||||
|
rVal.messageType = TerrainMessageType.REQUESTEDITVOXEL;
|
||||||
stripPacketHeader(byteBuffer);
|
stripPacketHeader(byteBuffer);
|
||||||
rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
@ -620,8 +630,9 @@ public class TerrainMessage extends NetworkMessage {
|
|||||||
/**
|
/**
|
||||||
* Parses a message of type UpdateVoxel
|
* Parses a message of type UpdateVoxel
|
||||||
*/
|
*/
|
||||||
public static TerrainMessage parseUpdateVoxelMessage(CircularByteBuffer byteBuffer){
|
public static TerrainMessage parseUpdateVoxelMessage(CircularByteBuffer byteBuffer, MessagePool pool){
|
||||||
TerrainMessage rVal = new TerrainMessage(TerrainMessageType.UPDATEVOXEL);
|
TerrainMessage rVal = (TerrainMessage)pool.get(MessageType.TERRAIN_MESSAGE);
|
||||||
|
rVal.messageType = TerrainMessageType.UPDATEVOXEL;
|
||||||
stripPacketHeader(byteBuffer);
|
stripPacketHeader(byteBuffer);
|
||||||
rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
@ -654,8 +665,9 @@ public class TerrainMessage extends NetworkMessage {
|
|||||||
/**
|
/**
|
||||||
* Parses a message of type RequestUseTerrainPalette
|
* Parses a message of type RequestUseTerrainPalette
|
||||||
*/
|
*/
|
||||||
public static TerrainMessage parseRequestUseTerrainPaletteMessage(CircularByteBuffer byteBuffer){
|
public static TerrainMessage parseRequestUseTerrainPaletteMessage(CircularByteBuffer byteBuffer, MessagePool pool){
|
||||||
TerrainMessage rVal = new TerrainMessage(TerrainMessageType.REQUESTUSETERRAINPALETTE);
|
TerrainMessage rVal = (TerrainMessage)pool.get(MessageType.TERRAIN_MESSAGE);
|
||||||
|
rVal.messageType = TerrainMessageType.REQUESTUSETERRAINPALETTE;
|
||||||
stripPacketHeader(byteBuffer);
|
stripPacketHeader(byteBuffer);
|
||||||
rVal.setrealLocationX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
rVal.setrealLocationX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||||
rVal.setrealLocationY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
rVal.setrealLocationY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||||
@ -684,8 +696,9 @@ public class TerrainMessage extends NetworkMessage {
|
|||||||
/**
|
/**
|
||||||
* Parses a message of type SpawnPosition
|
* Parses a message of type SpawnPosition
|
||||||
*/
|
*/
|
||||||
public static TerrainMessage parseSpawnPositionMessage(CircularByteBuffer byteBuffer){
|
public static TerrainMessage parseSpawnPositionMessage(CircularByteBuffer byteBuffer, MessagePool pool){
|
||||||
TerrainMessage rVal = new TerrainMessage(TerrainMessageType.SPAWNPOSITION);
|
TerrainMessage rVal = (TerrainMessage)pool.get(MessageType.TERRAIN_MESSAGE);
|
||||||
|
rVal.messageType = TerrainMessageType.SPAWNPOSITION;
|
||||||
stripPacketHeader(byteBuffer);
|
stripPacketHeader(byteBuffer);
|
||||||
rVal.setrealLocationX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
rVal.setrealLocationX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||||
rVal.setrealLocationY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
rVal.setrealLocationY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||||
@ -708,8 +721,9 @@ public class TerrainMessage extends NetworkMessage {
|
|||||||
/**
|
/**
|
||||||
* Parses a message of type RequestChunkData
|
* Parses a message of type RequestChunkData
|
||||||
*/
|
*/
|
||||||
public static TerrainMessage parseRequestChunkDataMessage(CircularByteBuffer byteBuffer){
|
public static TerrainMessage parseRequestChunkDataMessage(CircularByteBuffer byteBuffer, MessagePool pool){
|
||||||
TerrainMessage rVal = new TerrainMessage(TerrainMessageType.REQUESTCHUNKDATA);
|
TerrainMessage rVal = (TerrainMessage)pool.get(MessageType.TERRAIN_MESSAGE);
|
||||||
|
rVal.messageType = TerrainMessageType.REQUESTCHUNKDATA;
|
||||||
stripPacketHeader(byteBuffer);
|
stripPacketHeader(byteBuffer);
|
||||||
rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
@ -763,8 +777,9 @@ public class TerrainMessage extends NetworkMessage {
|
|||||||
/**
|
/**
|
||||||
* Parses a message of type sendChunkData
|
* Parses a message of type sendChunkData
|
||||||
*/
|
*/
|
||||||
public static TerrainMessage parsesendChunkDataMessage(CircularByteBuffer byteBuffer){
|
public static TerrainMessage parsesendChunkDataMessage(CircularByteBuffer byteBuffer, MessagePool pool){
|
||||||
TerrainMessage rVal = new TerrainMessage(TerrainMessageType.SENDCHUNKDATA);
|
TerrainMessage rVal = (TerrainMessage)pool.get(MessageType.TERRAIN_MESSAGE);
|
||||||
|
rVal.messageType = TerrainMessageType.SENDCHUNKDATA;
|
||||||
stripPacketHeader(byteBuffer);
|
stripPacketHeader(byteBuffer);
|
||||||
rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
@ -789,8 +804,9 @@ public class TerrainMessage extends NetworkMessage {
|
|||||||
/**
|
/**
|
||||||
* Parses a message of type RequestReducedChunkData
|
* Parses a message of type RequestReducedChunkData
|
||||||
*/
|
*/
|
||||||
public static TerrainMessage parseRequestReducedChunkDataMessage(CircularByteBuffer byteBuffer){
|
public static TerrainMessage parseRequestReducedChunkDataMessage(CircularByteBuffer byteBuffer, MessagePool pool){
|
||||||
TerrainMessage rVal = new TerrainMessage(TerrainMessageType.REQUESTREDUCEDCHUNKDATA);
|
TerrainMessage rVal = (TerrainMessage)pool.get(MessageType.TERRAIN_MESSAGE);
|
||||||
|
rVal.messageType = TerrainMessageType.REQUESTREDUCEDCHUNKDATA;
|
||||||
stripPacketHeader(byteBuffer);
|
stripPacketHeader(byteBuffer);
|
||||||
rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
@ -852,8 +868,9 @@ public class TerrainMessage extends NetworkMessage {
|
|||||||
/**
|
/**
|
||||||
* Parses a message of type SendReducedChunkData
|
* Parses a message of type SendReducedChunkData
|
||||||
*/
|
*/
|
||||||
public static TerrainMessage parseSendReducedChunkDataMessage(CircularByteBuffer byteBuffer){
|
public static TerrainMessage parseSendReducedChunkDataMessage(CircularByteBuffer byteBuffer, MessagePool pool){
|
||||||
TerrainMessage rVal = new TerrainMessage(TerrainMessageType.SENDREDUCEDCHUNKDATA);
|
TerrainMessage rVal = (TerrainMessage)pool.get(MessageType.TERRAIN_MESSAGE);
|
||||||
|
rVal.messageType = TerrainMessageType.SENDREDUCEDCHUNKDATA;
|
||||||
stripPacketHeader(byteBuffer);
|
stripPacketHeader(byteBuffer);
|
||||||
rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
@ -882,8 +899,9 @@ public class TerrainMessage extends NetworkMessage {
|
|||||||
/**
|
/**
|
||||||
* Parses a message of type RequestReducedBlockData
|
* Parses a message of type RequestReducedBlockData
|
||||||
*/
|
*/
|
||||||
public static TerrainMessage parseRequestReducedBlockDataMessage(CircularByteBuffer byteBuffer){
|
public static TerrainMessage parseRequestReducedBlockDataMessage(CircularByteBuffer byteBuffer, MessagePool pool){
|
||||||
TerrainMessage rVal = new TerrainMessage(TerrainMessageType.REQUESTREDUCEDBLOCKDATA);
|
TerrainMessage rVal = (TerrainMessage)pool.get(MessageType.TERRAIN_MESSAGE);
|
||||||
|
rVal.messageType = TerrainMessageType.REQUESTREDUCEDBLOCKDATA;
|
||||||
stripPacketHeader(byteBuffer);
|
stripPacketHeader(byteBuffer);
|
||||||
rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
@ -945,8 +963,9 @@ public class TerrainMessage extends NetworkMessage {
|
|||||||
/**
|
/**
|
||||||
* Parses a message of type SendReducedBlockData
|
* Parses a message of type SendReducedBlockData
|
||||||
*/
|
*/
|
||||||
public static TerrainMessage parseSendReducedBlockDataMessage(CircularByteBuffer byteBuffer){
|
public static TerrainMessage parseSendReducedBlockDataMessage(CircularByteBuffer byteBuffer, MessagePool pool){
|
||||||
TerrainMessage rVal = new TerrainMessage(TerrainMessageType.SENDREDUCEDBLOCKDATA);
|
TerrainMessage rVal = (TerrainMessage)pool.get(MessageType.TERRAIN_MESSAGE);
|
||||||
|
rVal.messageType = TerrainMessageType.SENDREDUCEDBLOCKDATA;
|
||||||
stripPacketHeader(byteBuffer);
|
stripPacketHeader(byteBuffer);
|
||||||
rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
@ -975,8 +994,9 @@ public class TerrainMessage extends NetworkMessage {
|
|||||||
/**
|
/**
|
||||||
* Parses a message of type UpdateBlock
|
* Parses a message of type UpdateBlock
|
||||||
*/
|
*/
|
||||||
public static TerrainMessage parseUpdateBlockMessage(CircularByteBuffer byteBuffer){
|
public static TerrainMessage parseUpdateBlockMessage(CircularByteBuffer byteBuffer, MessagePool pool){
|
||||||
TerrainMessage rVal = new TerrainMessage(TerrainMessageType.UPDATEBLOCK);
|
TerrainMessage rVal = (TerrainMessage)pool.get(MessageType.TERRAIN_MESSAGE);
|
||||||
|
rVal.messageType = TerrainMessageType.UPDATEBLOCK;
|
||||||
stripPacketHeader(byteBuffer);
|
stripPacketHeader(byteBuffer);
|
||||||
rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
@ -1009,8 +1029,9 @@ public class TerrainMessage extends NetworkMessage {
|
|||||||
/**
|
/**
|
||||||
* Parses a message of type RequestFluidData
|
* Parses a message of type RequestFluidData
|
||||||
*/
|
*/
|
||||||
public static TerrainMessage parseRequestFluidDataMessage(CircularByteBuffer byteBuffer){
|
public static TerrainMessage parseRequestFluidDataMessage(CircularByteBuffer byteBuffer, MessagePool pool){
|
||||||
TerrainMessage rVal = new TerrainMessage(TerrainMessageType.REQUESTFLUIDDATA);
|
TerrainMessage rVal = (TerrainMessage)pool.get(MessageType.TERRAIN_MESSAGE);
|
||||||
|
rVal.messageType = TerrainMessageType.REQUESTFLUIDDATA;
|
||||||
stripPacketHeader(byteBuffer);
|
stripPacketHeader(byteBuffer);
|
||||||
rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
@ -1064,8 +1085,9 @@ public class TerrainMessage extends NetworkMessage {
|
|||||||
/**
|
/**
|
||||||
* Parses a message of type sendFluidData
|
* Parses a message of type sendFluidData
|
||||||
*/
|
*/
|
||||||
public static TerrainMessage parsesendFluidDataMessage(CircularByteBuffer byteBuffer){
|
public static TerrainMessage parsesendFluidDataMessage(CircularByteBuffer byteBuffer, MessagePool pool){
|
||||||
TerrainMessage rVal = new TerrainMessage(TerrainMessageType.SENDFLUIDDATA);
|
TerrainMessage rVal = (TerrainMessage)pool.get(MessageType.TERRAIN_MESSAGE);
|
||||||
|
rVal.messageType = TerrainMessageType.SENDFLUIDDATA;
|
||||||
stripPacketHeader(byteBuffer);
|
stripPacketHeader(byteBuffer);
|
||||||
rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
@ -1121,8 +1143,9 @@ public class TerrainMessage extends NetworkMessage {
|
|||||||
/**
|
/**
|
||||||
* Parses a message of type updateFluidData
|
* Parses a message of type updateFluidData
|
||||||
*/
|
*/
|
||||||
public static TerrainMessage parseupdateFluidDataMessage(CircularByteBuffer byteBuffer){
|
public static TerrainMessage parseupdateFluidDataMessage(CircularByteBuffer byteBuffer, MessagePool pool){
|
||||||
TerrainMessage rVal = new TerrainMessage(TerrainMessageType.UPDATEFLUIDDATA);
|
TerrainMessage rVal = (TerrainMessage)pool.get(MessageType.TERRAIN_MESSAGE);
|
||||||
|
rVal.messageType = TerrainMessageType.UPDATEFLUIDDATA;
|
||||||
stripPacketHeader(byteBuffer);
|
stripPacketHeader(byteBuffer);
|
||||||
rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package electrosphere.net.parser.net.raw;
|
package electrosphere.net.parser.net.raw;
|
||||||
|
|
||||||
import electrosphere.net.parser.net.message.NetworkMessage;
|
import electrosphere.net.parser.net.message.MessagePool;
|
||||||
|
import electrosphere.net.parser.net.message.NetworkMessage;
|
||||||
import io.github.studiorailgun.CircularByteBuffer;
|
import io.github.studiorailgun.CircularByteBuffer;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@ -48,6 +49,11 @@ public class NetworkParser {
|
|||||||
*/
|
*/
|
||||||
CircularByteBuffer incomingByteBuffer = new CircularByteBuffer(CIRCULAR_BUFFER_SIZE);
|
CircularByteBuffer incomingByteBuffer = new CircularByteBuffer(CIRCULAR_BUFFER_SIZE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Message object pool
|
||||||
|
*/
|
||||||
|
MessagePool pool = new MessagePool();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The block array used to read blocks of bytes in
|
* The block array used to read blocks of bytes in
|
||||||
*/
|
*/
|
||||||
@ -91,7 +97,7 @@ public class NetworkParser {
|
|||||||
//parse byte queue for messages
|
//parse byte queue for messages
|
||||||
//for each message, append to clientIncomingMessageQueue
|
//for each message, append to clientIncomingMessageQueue
|
||||||
NetworkMessage newMessage;
|
NetworkMessage newMessage;
|
||||||
while((newMessage = NetworkMessage.parseBytestreamForMessage(incomingByteBuffer))!=null){
|
while((newMessage = NetworkMessage.parseBytestreamForMessage(incomingByteBuffer,this.pool))!=null){
|
||||||
incomingMessageQueue.add(newMessage);
|
incomingMessageQueue.add(newMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -104,6 +110,7 @@ public class NetworkParser {
|
|||||||
for(NetworkMessage message : outgoingMessageQueue){
|
for(NetworkMessage message : outgoingMessageQueue){
|
||||||
outgoingMessageQueue.remove(message);
|
outgoingMessageQueue.remove(message);
|
||||||
outgoingStream.write(message.getRawBytes());
|
outgoingStream.write(message.getRawBytes());
|
||||||
|
pool.release(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,5 +161,13 @@ public class NetworkParser {
|
|||||||
public long getNumberOfBytesRead(){
|
public long getNumberOfBytesRead(){
|
||||||
return totalBytesRead;
|
return totalBytesRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Releases a network message object back into the pool
|
||||||
|
* @param message The message
|
||||||
|
*/
|
||||||
|
public void release(NetworkMessage message){
|
||||||
|
this.pool.release(message);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -84,5 +84,16 @@ public class ServerContentManager {
|
|||||||
FileUtils.serializeObjectToFilePath(fullPath, serialization);
|
FileUtils.serializeObjectToFilePath(fullPath, serialization);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves a collection of serialized entities to disk
|
||||||
|
* @param locationKey The location key to save under
|
||||||
|
* @param serialization The collection of entities to save
|
||||||
|
*/
|
||||||
|
public void saveSerializationToDisk(Long locationKey, ContentSerialization serialization){
|
||||||
|
String dirPath = SaveUtils.deriveSaveDirectoryPath(Globals.currentSave.getName());
|
||||||
|
String fullPath = dirPath + "/content/" + locationKey + ".dat";
|
||||||
|
FileUtils.serializeObjectToFilePath(fullPath, serialization);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package electrosphere.server.datacell;
|
|||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
|
|
||||||
@ -10,19 +11,28 @@ import electrosphere.entity.Entity;
|
|||||||
*/
|
*/
|
||||||
public class EntityDataCellMapper {
|
public class EntityDataCellMapper {
|
||||||
|
|
||||||
// The map of entity -> server data cell
|
/**
|
||||||
|
* The map of entity -> server data cell
|
||||||
|
*/
|
||||||
Map<Entity,ServerDataCell> entityDataCellMap = new HashMap<Entity,ServerDataCell>();
|
Map<Entity,ServerDataCell> entityDataCellMap = new HashMap<Entity,ServerDataCell>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lock for thread safe-ing the mapper
|
||||||
|
*/
|
||||||
|
ReentrantLock lock = new ReentrantLock();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers an entity into the map. Should be called every time any entity is created on the server.
|
* Registers an entity into the map. Should be called every time any entity is created on the server.
|
||||||
* @param entity The entity that was just created
|
* @param entity The entity that was just created
|
||||||
* @param serverDataCell The server data cell to register this entity to
|
* @param serverDataCell The server data cell to register this entity to
|
||||||
*/
|
*/
|
||||||
public void registerEntity(Entity entity, ServerDataCell serverDataCell){
|
public void registerEntity(Entity entity, ServerDataCell serverDataCell){
|
||||||
|
lock.lock();
|
||||||
if(serverDataCell == null){
|
if(serverDataCell == null){
|
||||||
throw new Error("Mapping entity to null!");
|
throw new Error("Mapping entity to null!");
|
||||||
}
|
}
|
||||||
entityDataCellMap.put(entity, serverDataCell);
|
entityDataCellMap.put(entity, serverDataCell);
|
||||||
|
lock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -31,7 +41,10 @@ public class EntityDataCellMapper {
|
|||||||
* @return The server data cell that the entity is inside of
|
* @return The server data cell that the entity is inside of
|
||||||
*/
|
*/
|
||||||
public ServerDataCell getEntityDataCell(Entity entity){
|
public ServerDataCell getEntityDataCell(Entity entity){
|
||||||
return entityDataCellMap.get(entity);
|
lock.lock();
|
||||||
|
ServerDataCell rVal = entityDataCellMap.get(entity);
|
||||||
|
lock.unlock();
|
||||||
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,10 +53,12 @@ public class EntityDataCellMapper {
|
|||||||
* @param serverDataCell The new server data cell for the entity
|
* @param serverDataCell The new server data cell for the entity
|
||||||
*/
|
*/
|
||||||
public void updateEntityCell(Entity entity, ServerDataCell serverDataCell){
|
public void updateEntityCell(Entity entity, ServerDataCell serverDataCell){
|
||||||
|
lock.lock();
|
||||||
if(serverDataCell == null){
|
if(serverDataCell == null){
|
||||||
throw new Error("Passing null to cell mapper update! " + entity + " " + serverDataCell);
|
throw new Error("Passing null to cell mapper update! " + entity + " " + serverDataCell);
|
||||||
}
|
}
|
||||||
entityDataCellMap.put(entity, serverDataCell);
|
entityDataCellMap.put(entity, serverDataCell);
|
||||||
|
lock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -51,7 +66,9 @@ public class EntityDataCellMapper {
|
|||||||
* @param entity The entity to eject
|
* @param entity The entity to eject
|
||||||
*/
|
*/
|
||||||
public void ejectEntity(Entity entity){
|
public void ejectEntity(Entity entity){
|
||||||
|
lock.lock();
|
||||||
entityDataCellMap.remove(entity);
|
entityDataCellMap.remove(entity);
|
||||||
|
lock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package electrosphere.server.datacell.gridded;
|
|||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
@ -30,6 +31,62 @@ public class GriddedDataCellLoaderService {
|
|||||||
*/
|
*/
|
||||||
private static final Map<Long,Future<?>> queuedWorkLock = new HashMap<Long,Future<?>>();
|
private static final Map<Long,Future<?>> queuedWorkLock = new HashMap<Long,Future<?>>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map of a job to its corresponding work
|
||||||
|
*/
|
||||||
|
private static final Map<Long,Runnable> jobOperationMap = new HashMap<Long,Runnable>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queues an operation that requires a read or write of a location's file data.
|
||||||
|
* Guarantees that all operations will be run in order without losing any work.
|
||||||
|
* @param key The key for the cell
|
||||||
|
* @param operation The operation to perform
|
||||||
|
*/
|
||||||
|
protected static void queueLocationBasedOperation(long key, Runnable operation){
|
||||||
|
lock.lock();
|
||||||
|
//if there is a job queued and we couldn't cancel it, wait
|
||||||
|
Future<?> job = queuedWorkLock.get(key);
|
||||||
|
Runnable opCallback = () -> {
|
||||||
|
//work here
|
||||||
|
operation.run();
|
||||||
|
//let the service know we've finished this job
|
||||||
|
lock.lock();
|
||||||
|
queuedWorkLock.remove(key);
|
||||||
|
lock.unlock();
|
||||||
|
};
|
||||||
|
if(job != null){
|
||||||
|
if(!job.cancel(false)){
|
||||||
|
try {
|
||||||
|
Globals.profiler.beginCpuSample("Waiting for cell io job to finish");
|
||||||
|
job.get();
|
||||||
|
Globals.profiler.endCpuSample();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
LoggerInterface.loggerEngine.ERROR("Failed to wait for previous job for cell!", e);
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
LoggerInterface.loggerEngine.ERROR("Previous job for cell threw an error!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(job.isCancelled()){
|
||||||
|
Runnable oldOp = jobOperationMap.remove(key);
|
||||||
|
//queue job to run the old operation first, then the new one
|
||||||
|
opCallback = () -> {
|
||||||
|
oldOp.run();
|
||||||
|
//load here
|
||||||
|
operation.run();
|
||||||
|
//let the service know we've finished this job
|
||||||
|
lock.lock();
|
||||||
|
queuedWorkLock.remove(key);
|
||||||
|
lock.unlock();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//queue job to do the operation
|
||||||
|
Future<?> newJob = ioThreadService.submit(opCallback);
|
||||||
|
queuedWorkLock.put(key, newJob);
|
||||||
|
jobOperationMap.put(key,operation);
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads a cell
|
* Loads a cell
|
||||||
* @param key The key for the cell
|
* @param key The key for the cell
|
||||||
@ -48,7 +105,7 @@ public class GriddedDataCellLoaderService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//queue job to load the cell
|
//queue job to load the cell
|
||||||
ioThreadService.submit(() -> {
|
Future<?> newJob = ioThreadService.submit(() -> {
|
||||||
//load here
|
//load here
|
||||||
loadLogic.run();
|
loadLogic.run();
|
||||||
//let the service know we've finished this job
|
//let the service know we've finished this job
|
||||||
@ -56,6 +113,7 @@ public class GriddedDataCellLoaderService {
|
|||||||
queuedWorkLock.remove(key);
|
queuedWorkLock.remove(key);
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
});
|
});
|
||||||
|
queuedWorkLock.put(key, newJob);
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -32,6 +32,7 @@ import electrosphere.net.server.player.Player;
|
|||||||
import electrosphere.net.server.protocol.TerrainProtocol;
|
import electrosphere.net.server.protocol.TerrainProtocol;
|
||||||
import electrosphere.server.block.manager.ServerBlockManager;
|
import electrosphere.server.block.manager.ServerBlockManager;
|
||||||
import electrosphere.server.content.ServerContentManager;
|
import electrosphere.server.content.ServerContentManager;
|
||||||
|
import electrosphere.server.content.serialization.ContentSerialization;
|
||||||
import electrosphere.server.datacell.Realm;
|
import electrosphere.server.datacell.Realm;
|
||||||
import electrosphere.server.datacell.ServerDataCell;
|
import electrosphere.server.datacell.ServerDataCell;
|
||||||
import electrosphere.server.datacell.interfaces.DataCellManager;
|
import electrosphere.server.datacell.interfaces.DataCellManager;
|
||||||
@ -320,7 +321,9 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
//the server will not be able to synchronize it properly.
|
//the server will not be able to synchronize it properly.
|
||||||
ServerEntityUtils.initiallyPositionEntity(parent,blockEntity,realPos);
|
ServerEntityUtils.initiallyPositionEntity(parent,blockEntity,realPos);
|
||||||
ServerEntityUtils.initiallyPositionEntity(parent,terrainEntity,realPos);
|
ServerEntityUtils.initiallyPositionEntity(parent,terrainEntity,realPos);
|
||||||
PhysicsDataCell cell = PhysicsDataCell.createPhysicsCell(worldPos, terrainEntity, blockEntity, terrainChunk, blockChunkData);
|
PhysicsDataCell cell = PhysicsDataCell.createPhysicsCell(worldPos, terrainEntity, blockEntity);
|
||||||
|
cell.setTerrainChunk(terrainChunk);
|
||||||
|
cell.setBlockChunk(blockChunkData);
|
||||||
cell.generatePhysics();
|
cell.generatePhysics();
|
||||||
posPhysicsMap.put(key, cell);
|
posPhysicsMap.put(key, cell);
|
||||||
}
|
}
|
||||||
@ -449,11 +452,14 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
|
|
||||||
Vector3i worldPos = this.getCellWorldPosition(cell);
|
Vector3i worldPos = this.getCellWorldPosition(cell);
|
||||||
Long key = this.getServerDataCellKey(worldPos);
|
Long key = this.getServerDataCellKey(worldPos);
|
||||||
//offload all entities in cell to chunk file
|
//entities are serialized before tracking is removed. This makes sure that any side effects from calling destroyEntity (ie if it looks up the chunk that we're deleting)
|
||||||
//entities are saved before tracking is removed. This makes sure that any side effects from calling destroyEntity (ie if it looks up the chunk that we're deleting)
|
|
||||||
//don't trigger the chunk to be re-created
|
//don't trigger the chunk to be re-created
|
||||||
|
Globals.profiler.beginCpuSample("GriddedDataCellManager.unloadPlayerlessChunks - Serialize entities");
|
||||||
|
ContentSerialization serializedEntities = ContentSerialization.constructContentSerialization(cell.getScene().getEntityList());
|
||||||
|
Globals.profiler.endCpuSample();
|
||||||
|
|
||||||
|
|
||||||
Globals.profiler.beginCpuSample("GriddedDataCellManager.unloadPlayerlessChunks - Destroy entities");
|
Globals.profiler.beginCpuSample("GriddedDataCellManager.unloadPlayerlessChunks - Destroy entities");
|
||||||
serverContentManager.saveContentToDisk(key, cell.getScene().getEntityList());
|
|
||||||
for(Entity entity : cell.getScene().getEntityList()){
|
for(Entity entity : cell.getScene().getEntityList()){
|
||||||
ServerEntityUtils.destroyEntity(entity);
|
ServerEntityUtils.destroyEntity(entity);
|
||||||
}
|
}
|
||||||
@ -462,8 +468,11 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
//save terrain to disk
|
//save terrain to disk
|
||||||
//terrain is saved before tracking is removed. This makes sure that any side effects from calling savePositionToDisk (ie if it looks up the chunk that we're deleting)
|
//terrain is saved before tracking is removed. This makes sure that any side effects from calling savePositionToDisk (ie if it looks up the chunk that we're deleting)
|
||||||
//don't trigger the chunk to be re-created
|
//don't trigger the chunk to be re-created
|
||||||
Globals.profiler.beginCpuSample("GriddedDataCellManager.unloadPlayerlessChunks - Store terrain");
|
Globals.profiler.beginCpuSample("GriddedDataCellManager.unloadPlayerlessChunks - Store data");
|
||||||
serverTerrainManager.savePositionToDisk(worldPos);
|
GriddedDataCellLoaderService.queueLocationBasedOperation(key, () -> {
|
||||||
|
serverContentManager.saveSerializationToDisk(key, serializedEntities);
|
||||||
|
serverTerrainManager.savePositionToDisk(worldPos);
|
||||||
|
});
|
||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
|
|
||||||
//deregister from all tracking structures
|
//deregister from all tracking structures
|
||||||
@ -662,8 +671,6 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
worldPos.y * ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET,
|
worldPos.y * ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET,
|
||||||
worldPos.z * ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET
|
worldPos.z * ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET
|
||||||
);
|
);
|
||||||
BlockChunkData blockChunkData = realm.getServerWorldData().getServerBlockManager().getChunk(worldPos.x, worldPos.y, worldPos.z);
|
|
||||||
ServerTerrainChunk terrainChunk = realm.getServerWorldData().getServerTerrainManager().getChunk(worldPos.x, worldPos.y, worldPos.z);
|
|
||||||
ServerDataCell dataCell = groundDataCells.get(key);
|
ServerDataCell dataCell = groundDataCells.get(key);
|
||||||
|
|
||||||
//create entities
|
//create entities
|
||||||
@ -678,7 +685,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
ServerEntityUtils.initiallyPositionEntity(realm,blockEntity,realPos);
|
ServerEntityUtils.initiallyPositionEntity(realm,blockEntity,realPos);
|
||||||
ServerEntityUtils.initiallyPositionEntity(realm,terrainEntity,realPos);
|
ServerEntityUtils.initiallyPositionEntity(realm,terrainEntity,realPos);
|
||||||
|
|
||||||
PhysicsDataCell targetCell = PhysicsDataCell.createPhysicsCell(worldPos, terrainEntity, blockEntity, terrainChunk, blockChunkData);
|
PhysicsDataCell targetCell = PhysicsDataCell.createPhysicsCell(worldPos, terrainEntity, blockEntity);
|
||||||
if(cell == null){
|
if(cell == null){
|
||||||
posPhysicsMap.put(key, targetCell);
|
posPhysicsMap.put(key, targetCell);
|
||||||
} else {
|
} else {
|
||||||
@ -687,6 +694,10 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
generationService.submit(() -> {
|
generationService.submit(() -> {
|
||||||
|
BlockChunkData blockChunkData = realm.getServerWorldData().getServerBlockManager().getChunk(worldPos.x, worldPos.y, worldPos.z);
|
||||||
|
ServerTerrainChunk terrainChunk = realm.getServerWorldData().getServerTerrainManager().getChunk(worldPos.x, worldPos.y, worldPos.z);
|
||||||
|
targetCell.setTerrainChunk(terrainChunk);
|
||||||
|
targetCell.setBlockChunk(blockChunkData);
|
||||||
//create physics entities
|
//create physics entities
|
||||||
if(cell != null){
|
if(cell != null){
|
||||||
cell.retireCell();
|
cell.retireCell();
|
||||||
@ -725,10 +736,12 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
cellPositionMap.put(rVal,new Vector3i(worldPos));
|
cellPositionMap.put(rVal,new Vector3i(worldPos));
|
||||||
loadedCellsLock.unlock();
|
loadedCellsLock.unlock();
|
||||||
|
|
||||||
//generate content
|
|
||||||
serverContentManager.generateContentForDataCell(parent, worldPos, rVal, cellKey);
|
|
||||||
//generates physics for the cell in a dedicated thread then finally registers
|
|
||||||
Long key = this.getServerDataCellKey(worldPos);
|
Long key = this.getServerDataCellKey(worldPos);
|
||||||
|
//generate content
|
||||||
|
GriddedDataCellLoaderService.queueLocationBasedOperation(key, () -> {
|
||||||
|
serverContentManager.generateContentForDataCell(parent, worldPos, rVal, cellKey);
|
||||||
|
});
|
||||||
|
//generates physics for the cell in a dedicated thread then finally registers
|
||||||
PhysicsDataCell cell = posPhysicsMap.get(key);
|
PhysicsDataCell cell = posPhysicsMap.get(key);
|
||||||
GriddedDataCellManager.runPhysicsGenerationThread(worldPos,key,cell,this.posPhysicsMap,this.groundDataCells,this.parent);
|
GriddedDataCellManager.runPhysicsGenerationThread(worldPos,key,cell,this.posPhysicsMap,this.groundDataCells,this.parent);
|
||||||
|
|
||||||
|
|||||||
@ -48,17 +48,13 @@ public class PhysicsDataCell {
|
|||||||
public static PhysicsDataCell createPhysicsCell(
|
public static PhysicsDataCell createPhysicsCell(
|
||||||
Vector3i worldPos,
|
Vector3i worldPos,
|
||||||
Entity physicsEntity,
|
Entity physicsEntity,
|
||||||
Entity blockPhysicsEntity,
|
Entity blockPhysicsEntity
|
||||||
ServerTerrainChunk currentChunk,
|
|
||||||
BlockChunkData blockChunk
|
|
||||||
|
|
||||||
){
|
){
|
||||||
PhysicsDataCell rVal = new PhysicsDataCell();
|
PhysicsDataCell rVal = new PhysicsDataCell();
|
||||||
rVal.physicsEntity = physicsEntity;
|
rVal.physicsEntity = physicsEntity;
|
||||||
rVal.blockPhysicsEntity = blockPhysicsEntity;
|
rVal.blockPhysicsEntity = blockPhysicsEntity;
|
||||||
rVal.worldPos = worldPos;
|
rVal.worldPos = worldPos;
|
||||||
rVal.blockChunk = blockChunk;
|
|
||||||
rVal.terrainChunk = currentChunk;
|
|
||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,5 +227,23 @@ public class PhysicsDataCell {
|
|||||||
// types[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = 0;
|
// types[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = 0;
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the terrain chunk data for the physics cell
|
||||||
|
* @param terrainChunk The terrain chunk data
|
||||||
|
*/
|
||||||
|
public void setTerrainChunk(ServerTerrainChunk terrainChunk) {
|
||||||
|
this.terrainChunk = terrainChunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the block chunk data for the physics cell
|
||||||
|
* @param blockChunk The block chunk data
|
||||||
|
*/
|
||||||
|
public void setBlockChunk(BlockChunkData blockChunk) {
|
||||||
|
this.blockChunk = blockChunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user