synchronization full flow initial implementation
This commit is contained in:
parent
b7d993ddbb
commit
e924511883
55
net/synchronization.json
Normal file
55
net/synchronization.json
Normal file
@ -0,0 +1,55 @@
|
||||
{
|
||||
"outputPath" : "./src/main/java/electrosphere/net/parser/",
|
||||
"packageName" : "electrosphere.net.parser",
|
||||
"categories":[
|
||||
|
||||
{
|
||||
"categoryName" : "Synchronization",
|
||||
"data" : [
|
||||
{
|
||||
"name" : "entityId",
|
||||
"type" : "FIXED_INT"
|
||||
},
|
||||
{
|
||||
"name" : "bTreeId",
|
||||
"type" : "FIXED_INT"
|
||||
},
|
||||
{
|
||||
"name" : "fieldId",
|
||||
"type" : "FIXED_INT"
|
||||
},
|
||||
{
|
||||
"name" : "bTreeValue",
|
||||
"type" : "FIXED_INT"
|
||||
}
|
||||
],
|
||||
"messageTypes" : [
|
||||
{
|
||||
"messageName" : "UpdateClientState",
|
||||
"data" : [
|
||||
"entityId",
|
||||
"bTreeId",
|
||||
"fieldId",
|
||||
"bTreeValue"
|
||||
]
|
||||
},
|
||||
{
|
||||
"messageName" : "AttachTree",
|
||||
"data" : [
|
||||
"entityId",
|
||||
"bTreeId"
|
||||
]
|
||||
},
|
||||
{
|
||||
"messageName" : "DetatchTree",
|
||||
"data" : [
|
||||
"entityId",
|
||||
"bTreeId"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
}
|
||||
@ -20,6 +20,8 @@ public class ClientFunctions {
|
||||
if(Globals.playerEntity != null){
|
||||
oldPlayerCharacterPosition = new Vector3d(EntityUtils.getPosition(Globals.playerEntity));
|
||||
}
|
||||
//process all server synchronization messages
|
||||
Globals.clientSynchronizationManager.processMessages();
|
||||
}
|
||||
|
||||
public static void runClientFunctions(){
|
||||
|
||||
@ -43,6 +43,7 @@ import electrosphere.net.monitor.NetMonitor;
|
||||
import electrosphere.net.server.Server;
|
||||
import electrosphere.net.server.player.Player;
|
||||
import electrosphere.net.server.player.PlayerManager;
|
||||
import electrosphere.net.synchronization.ClientSynchronizationManager;
|
||||
import electrosphere.net.synchronization.EntityValueTrackingService;
|
||||
import electrosphere.renderer.Material;
|
||||
import electrosphere.renderer.RenderUtils;
|
||||
@ -268,6 +269,7 @@ public class Globals {
|
||||
public static ClientSceneWrapper clientSceneWrapper;
|
||||
public static ClientEntityCullingManager clientEntityCullingManager;
|
||||
public static ClientSimulation clientSimulation;
|
||||
public static ClientSynchronizationManager clientSynchronizationManager;
|
||||
|
||||
//instanced actor manager
|
||||
public static InstanceManager clientInstanceManager = new InstanceManager();
|
||||
@ -406,6 +408,8 @@ public class Globals {
|
||||
if(Globals.userSettings.getNetRunNetMonitor()){
|
||||
netMonitor = new NetMonitor();
|
||||
}
|
||||
//client synchronization manager
|
||||
clientSynchronizationManager = new ClientSynchronizationManager();
|
||||
}
|
||||
|
||||
public static void initDefaultAudioResources(){
|
||||
|
||||
@ -219,7 +219,8 @@ public class EntityDataStrings {
|
||||
/*
|
||||
idle behavior tree
|
||||
*/
|
||||
public static final String IDLE_TREE = "idleTree";
|
||||
public static final String TREE_IDLE = "treeIdle";
|
||||
public static final String TREE_SERVERIDLE = "treeServerIdle";
|
||||
|
||||
/*
|
||||
particle behavior tree
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
package electrosphere.entity.state.idle;
|
||||
|
||||
|
||||
import electrosphere.net.synchronization.BehaviorTreeIdEnums;
|
||||
|
||||
import electrosphere.entity.state.BehaviorTree;
|
||||
import electrosphere.entity.state.attack.AttackTree;
|
||||
import electrosphere.entity.state.attack.AttackTree.AttackTreeState;
|
||||
@ -38,9 +41,6 @@ public class IdleTree implements BehaviorTree {
|
||||
@SyncedField
|
||||
IdleTreeState state;
|
||||
|
||||
@SyncedField
|
||||
int test;
|
||||
|
||||
Entity parent;
|
||||
|
||||
CopyOnWriteArrayList<EntityMessage> networkMessageQueue = new CopyOnWriteArrayList<EntityMessage>();
|
||||
@ -50,7 +50,7 @@ public class IdleTree implements BehaviorTree {
|
||||
int maxFrame = 60;
|
||||
|
||||
public IdleTree(Entity e){
|
||||
state = IdleTreeState.IDLE;
|
||||
state = IdleTreeState.NOT_IDLE;
|
||||
parent = e;
|
||||
}
|
||||
|
||||
@ -58,12 +58,11 @@ public class IdleTree implements BehaviorTree {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void start(){
|
||||
//TODO: check if can start moving
|
||||
state = IdleTreeState.IDLE;
|
||||
frameCurrent = 0;
|
||||
public void setState(IdleTreeState state){
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
|
||||
public void interrupt(){
|
||||
state = IdleTreeState.NOT_IDLE;
|
||||
}
|
||||
@ -85,38 +84,38 @@ public class IdleTree implements BehaviorTree {
|
||||
}
|
||||
|
||||
//parse attached network messages
|
||||
for(EntityMessage message : networkMessageQueue){
|
||||
networkMessageQueue.remove(message);
|
||||
// System.out.println("MOVE to " + message.getX() + " " + message.getY() + " " + message.getZ());
|
||||
switch(message.getMessageSubtype()){
|
||||
case ATTACKUPDATE:
|
||||
switch(message.gettreeState()){
|
||||
case 0:
|
||||
state = IdleTreeState.IDLE;
|
||||
break;
|
||||
case 1:
|
||||
state = IdleTreeState.NOT_IDLE;
|
||||
break;
|
||||
}
|
||||
EntityUtils.getPosition(parent).set(message.getpositionX(),message.getpositionY(),message.getpositionZ());
|
||||
CreatureUtils.setFacingVector(parent, new Vector3d(message.getrotationX(),message.getrotationY(),message.getrotationZ()));
|
||||
break;
|
||||
case ATTACHENTITYTOENTITY:
|
||||
case CREATE:
|
||||
case DESTROY:
|
||||
case MOVE:
|
||||
case MOVEUPDATE:
|
||||
case SETBEHAVIORTREE:
|
||||
case SETFACING:
|
||||
case SETPOSITION:
|
||||
case SETPROPERTY:
|
||||
case SPAWNCREATURE:
|
||||
case SPAWNITEM:
|
||||
case KILL:
|
||||
//silently ignore
|
||||
break;
|
||||
}
|
||||
}
|
||||
// for(EntityMessage message : networkMessageQueue){
|
||||
// networkMessageQueue.remove(message);
|
||||
// // System.out.println("MOVE to " + message.getX() + " " + message.getY() + " " + message.getZ());
|
||||
// switch(message.getMessageSubtype()){
|
||||
// case ATTACKUPDATE:
|
||||
// switch(message.gettreeState()){
|
||||
// case 0:
|
||||
// state = IdleTreeState.IDLE;
|
||||
// break;
|
||||
// case 1:
|
||||
// state = IdleTreeState.NOT_IDLE;
|
||||
// break;
|
||||
// }
|
||||
// EntityUtils.getPosition(parent).set(message.getpositionX(),message.getpositionY(),message.getpositionZ());
|
||||
// CreatureUtils.setFacingVector(parent, new Vector3d(message.getrotationX(),message.getrotationY(),message.getrotationZ()));
|
||||
// break;
|
||||
// case ATTACHENTITYTOENTITY:
|
||||
// case CREATE:
|
||||
// case DESTROY:
|
||||
// case MOVE:
|
||||
// case MOVEUPDATE:
|
||||
// case SETBEHAVIORTREE:
|
||||
// case SETFACING:
|
||||
// case SETPOSITION:
|
||||
// case SETPROPERTY:
|
||||
// case SPAWNCREATURE:
|
||||
// case SPAWNITEM:
|
||||
// case KILL:
|
||||
// //silently ignore
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
boolean isIdle;
|
||||
|
||||
@ -133,32 +132,32 @@ public class IdleTree implements BehaviorTree {
|
||||
entityActor.incrementAnimationTime(0.0001);
|
||||
}
|
||||
}
|
||||
isIdle = true;
|
||||
if(!movementTreeIsIdle){
|
||||
isIdle = false;
|
||||
}
|
||||
if(hasAttackTree){
|
||||
if(attackTree.getState() != AttackTreeState.IDLE){
|
||||
isIdle = false;
|
||||
}
|
||||
}
|
||||
if(!isIdle){
|
||||
state = IdleTreeState.NOT_IDLE;
|
||||
}
|
||||
// isIdle = true;
|
||||
// if(!movementTreeIsIdle){
|
||||
// isIdle = false;
|
||||
// }
|
||||
// if(hasAttackTree){
|
||||
// if(attackTree.getState() != AttackTreeState.IDLE){
|
||||
// isIdle = false;
|
||||
// }
|
||||
// }
|
||||
// if(!isIdle){
|
||||
// state = IdleTreeState.NOT_IDLE;
|
||||
// }
|
||||
break;
|
||||
case NOT_IDLE:
|
||||
isIdle = true;
|
||||
if(!movementTreeIsIdle){
|
||||
isIdle = false;
|
||||
}
|
||||
if(hasAttackTree){
|
||||
if(attackTree.getState() != AttackTreeState.IDLE){
|
||||
isIdle = false;
|
||||
}
|
||||
}
|
||||
if(isIdle){
|
||||
state = IdleTreeState.IDLE;
|
||||
}
|
||||
// isIdle = true;
|
||||
// if(!movementTreeIsIdle){
|
||||
// isIdle = false;
|
||||
// }
|
||||
// if(hasAttackTree){
|
||||
// if(attackTree.getState() != AttackTreeState.IDLE){
|
||||
// isIdle = false;
|
||||
// }
|
||||
// }
|
||||
// if(isIdle){
|
||||
// state = IdleTreeState.IDLE;
|
||||
// }
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -183,4 +182,82 @@ public class IdleTree implements BehaviorTree {
|
||||
networkMessageQueue.add(networkMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> Automatically generated </p>
|
||||
* <p>
|
||||
* Detatches this tree from the entity.
|
||||
* </p>
|
||||
* @param entity The entity to detach to
|
||||
* @param tree The behavior tree to detach
|
||||
*/
|
||||
public static void detachTree(Entity entity, BehaviorTree tree){
|
||||
Globals.entityValueTrackingService.detatchTreeFromEntity(entity, BehaviorTreeIdEnums.BTREE_IDLE_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> (initially) Automatically generated </p>
|
||||
* <p> More parameters can be safely added to this method</p>
|
||||
* <p>
|
||||
* Attaches this tree to the entity.
|
||||
* </p>
|
||||
* @param entity The entity to attach to
|
||||
* @param tree The behavior tree to attach
|
||||
*/
|
||||
public static IdleTree attachTree(Entity parent){
|
||||
IdleTree rVal = new IdleTree(parent);
|
||||
//put manual code here (setting params, etc)
|
||||
|
||||
|
||||
//!!WARNING!! from here below should not be touched
|
||||
//This was generated automatically to properly alert various systems that the btree exists and should be tracked
|
||||
parent.putData(EntityDataStrings.TREE_IDLE, rVal);
|
||||
Globals.entityValueTrackingService.attachTreeToEntity(parent, BehaviorTreeIdEnums.BTREE_IDLE_ID);
|
||||
return rVal;
|
||||
}
|
||||
/**
|
||||
* <p> Automatically generated </p>
|
||||
* <p>
|
||||
* Converts this enum type to an equivalent short value
|
||||
* </p>
|
||||
* @param enumVal The enum value
|
||||
* @return The short value
|
||||
*/
|
||||
public static short getIdleTreeStateEnumAsShort(IdleTreeState enumVal){
|
||||
switch(enumVal){
|
||||
case IDLE:
|
||||
return 0;
|
||||
case NOT_IDLE:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <p> Automatically generated </p>
|
||||
* <p>
|
||||
* Converts a short to the equivalent enum value
|
||||
* </p>
|
||||
* @param shortVal The short value
|
||||
* @return The enum value
|
||||
*/
|
||||
public static IdleTreeState getIdleTreeStateShortAsEnum(short shortVal){
|
||||
switch(shortVal){
|
||||
case 0:
|
||||
return IdleTreeState.IDLE;
|
||||
case 1:
|
||||
return IdleTreeState.NOT_IDLE;
|
||||
default:
|
||||
return IdleTreeState.IDLE;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <p>
|
||||
* Gets the IdleTree of the entity
|
||||
* </p>
|
||||
* @param entity the entity
|
||||
* @return The IdleTree
|
||||
*/
|
||||
public static IdleTree getIdleTree(Entity entity){
|
||||
return (IdleTree)entity.getData(EntityDataStrings.TREE_IDLE);
|
||||
}
|
||||
}
|
||||
@ -10,26 +10,26 @@ import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.EntityDataStrings;
|
||||
import electrosphere.entity.EntityUtils;
|
||||
import electrosphere.engine.Main;
|
||||
import electrosphere.entity.state.movement.ServerGroundMovementTree.MovementTreeState;
|
||||
import electrosphere.entity.types.creature.CreatureUtils;
|
||||
import electrosphere.net.parser.net.message.EntityMessage;
|
||||
import electrosphere.net.parser.net.message.SynchronizationMessage;
|
||||
import electrosphere.net.synchronization.BehaviorTreeIdEnums;
|
||||
import electrosphere.net.synchronization.annotation.SyncedField;
|
||||
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
|
||||
import electrosphere.renderer.actor.Actor;
|
||||
import electrosphere.renderer.anim.Animation;
|
||||
import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
||||
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import org.joml.Vector3d;
|
||||
|
||||
|
||||
@SynchronizedBehaviorTree(name = "serverIdle", isServer = true)
|
||||
@SynchronizedBehaviorTree(name = "serverIdle", isServer = true, correspondingTree = "idle")
|
||||
/**
|
||||
* Tree for playing an idle animation when an entity isn't doing anything
|
||||
*/
|
||||
public class ServerIdleTree {
|
||||
public class ServerIdleTree implements BehaviorTree {
|
||||
|
||||
@SyncedField
|
||||
IdleTreeState state;
|
||||
@ -47,9 +47,15 @@ public class ServerIdleTree {
|
||||
parent = e;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> Automatically generated </p>
|
||||
* <p>
|
||||
* Gets state.
|
||||
* </p>
|
||||
*/
|
||||
public IdleTreeState getState(){
|
||||
return state;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public void start(){
|
||||
//TODO: check if can start moving
|
||||
@ -66,6 +72,7 @@ public class ServerIdleTree {
|
||||
}
|
||||
|
||||
public void simulate(float deltaTime){
|
||||
System.out.println("simulate server chunk");
|
||||
Actor entityActor = EntityUtils.getActor(parent);
|
||||
|
||||
boolean movementTreeIsIdle = movementTreeIsIdle();
|
||||
@ -76,40 +83,6 @@ public class ServerIdleTree {
|
||||
attackTree = CreatureUtils.serverGetAttackTree(parent);
|
||||
}
|
||||
|
||||
//parse attached network messages
|
||||
for(EntityMessage message : networkMessageQueue){
|
||||
networkMessageQueue.remove(message);
|
||||
// System.out.println("MOVE to " + message.getX() + " " + message.getY() + " " + message.getZ());
|
||||
switch(message.getMessageSubtype()){
|
||||
case ATTACKUPDATE:
|
||||
switch(message.gettreeState()){
|
||||
case 0:
|
||||
state = IdleTreeState.IDLE;
|
||||
break;
|
||||
case 1:
|
||||
state = IdleTreeState.NOT_IDLE;
|
||||
break;
|
||||
}
|
||||
EntityUtils.getPosition(parent).set(message.getpositionX(),message.getpositionY(),message.getpositionZ());
|
||||
CreatureUtils.setFacingVector(parent, new Vector3d(message.getrotationX(),message.getrotationY(),message.getrotationZ()));
|
||||
break;
|
||||
case ATTACHENTITYTOENTITY:
|
||||
case CREATE:
|
||||
case DESTROY:
|
||||
case MOVE:
|
||||
case MOVEUPDATE:
|
||||
case SETBEHAVIORTREE:
|
||||
case SETFACING:
|
||||
case SETPOSITION:
|
||||
case SETPROPERTY:
|
||||
case SPAWNCREATURE:
|
||||
case SPAWNITEM:
|
||||
case KILL:
|
||||
//silently ignore
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
boolean isIdle;
|
||||
|
||||
//state machine
|
||||
@ -135,7 +108,7 @@ public class ServerIdleTree {
|
||||
}
|
||||
}
|
||||
if(!isIdle){
|
||||
state = IdleTreeState.NOT_IDLE;
|
||||
this.setState(IdleTreeState.NOT_IDLE);
|
||||
}
|
||||
break;
|
||||
case NOT_IDLE:
|
||||
@ -149,7 +122,7 @@ public class ServerIdleTree {
|
||||
}
|
||||
}
|
||||
if(isIdle){
|
||||
state = IdleTreeState.IDLE;
|
||||
this.setState(IdleTreeState.IDLE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -176,15 +149,25 @@ public class ServerIdleTree {
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> Automatically generated </p>
|
||||
* <p> (initially) Automatically generated </p>
|
||||
* <p> More parameters can be safely added to this method</p>
|
||||
* <p>
|
||||
* Attaches this tree to the entity.
|
||||
* </p>
|
||||
* @param entity The entity to attach to
|
||||
* @param tree The behavior tree to attach
|
||||
*/
|
||||
public static void attachTree(Entity entity, BehaviorTree tree){
|
||||
Globals.entityValueTrackingService.attachTreeToEntity(entity, BehaviorTreeIdEnums.BTREE_SERVERIDLE_ID);
|
||||
public static ServerIdleTree attachTree(Entity parent){
|
||||
ServerIdleTree rVal = new ServerIdleTree(parent);
|
||||
//put manual code here (setting params, etc)
|
||||
|
||||
|
||||
//!!WARNING!! from here below should not be touched
|
||||
//This was generated automatically to properly alert various systems that the btree exists and should be tracked
|
||||
ServerBehaviorTreeUtils.attachBTreeToEntity(parent, rVal);
|
||||
parent.putData(EntityDataStrings.TREE_SERVERIDLE, rVal);
|
||||
Globals.entityValueTrackingService.attachTreeToEntity(parent, BehaviorTreeIdEnums.BTREE_SERVERIDLE_ID);
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -199,4 +182,27 @@ public class ServerIdleTree {
|
||||
Globals.entityValueTrackingService.detatchTreeFromEntity(entity, BehaviorTreeIdEnums.BTREE_SERVERIDLE_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> Automatically generated </p>
|
||||
* <p>
|
||||
* Sets state and handles the synchronization logic for it.
|
||||
* </p>
|
||||
* @param state The value to set state to.
|
||||
*/
|
||||
public void setState(IdleTreeState state){
|
||||
this.state = state;
|
||||
int value = IdleTree.getIdleTreeStateEnumAsShort(state);
|
||||
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(SynchronizationMessage.constructUpdateClientStateMessage(parent.getId(), 1, 1, value));
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Gets the ServerIdleTree of the entity
|
||||
* </p>
|
||||
* @param entity the entity
|
||||
* @return The ServerIdleTree
|
||||
*/
|
||||
public static ServerIdleTree getServerIdleTree(Entity entity){
|
||||
return (ServerIdleTree)entity.getData(EntityDataStrings.TREE_SERVERIDLE);
|
||||
}
|
||||
}
|
||||
@ -28,6 +28,7 @@ import electrosphere.entity.state.equip.EquipState;
|
||||
import electrosphere.entity.state.gravity.ClientGravityTree;
|
||||
import electrosphere.entity.state.gravity.ServerGravityTree;
|
||||
import electrosphere.entity.state.idle.IdleTree;
|
||||
import electrosphere.entity.state.idle.ServerIdleTree;
|
||||
import electrosphere.entity.state.inventory.InventoryState;
|
||||
import electrosphere.entity.state.inventory.InventoryUtils;
|
||||
import electrosphere.entity.state.inventory.RelationalInventoryState;
|
||||
@ -370,7 +371,7 @@ public class CreatureUtils {
|
||||
Globals.clientScene.registerEntityToTag(rVal, EntityTags.LIFE_STATE);
|
||||
//idle tree & generic stuff all creatures have
|
||||
IdleTree idleTree = new IdleTree(rVal);
|
||||
rVal.putData(EntityDataStrings.IDLE_TREE, idleTree);
|
||||
rVal.putData(EntityDataStrings.TREE_IDLE, idleTree);
|
||||
Globals.clientScene.registerBehaviorTree(idleTree);
|
||||
Globals.clientScene.registerEntityToTag(rVal, EntityTags.CREATURE);
|
||||
rVal.putData(EntityDataStrings.DATA_STRING_CREATURE_IS_CREATURE, true);
|
||||
@ -669,9 +670,8 @@ public class CreatureUtils {
|
||||
rVal.putData(EntityDataStrings.LIFE_STATE, new LifeState(rVal, rawType.getHealthSystem()));
|
||||
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.LIFE_STATE);
|
||||
//idle tree & generic stuff all creatures have
|
||||
IdleTree idleTree = new IdleTree(rVal);
|
||||
rVal.putData(EntityDataStrings.IDLE_TREE, idleTree);
|
||||
ServerBehaviorTreeUtils.attachBTreeToEntity(rVal, idleTree);
|
||||
ServerIdleTree.attachTree(rVal);
|
||||
|
||||
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.CREATURE);
|
||||
rVal.putData(EntityDataStrings.DATA_STRING_CREATURE_IS_CREATURE, true);
|
||||
rVal.putData(EntityDataStrings.DATA_STRING_CREATURE_TYPE, type);
|
||||
@ -790,7 +790,7 @@ public class CreatureUtils {
|
||||
}
|
||||
|
||||
public static IdleTree getIdleTree(Entity e){
|
||||
return (IdleTree)e.getData(EntityDataStrings.IDLE_TREE);
|
||||
return (IdleTree)e.getData(EntityDataStrings.TREE_IDLE);
|
||||
}
|
||||
|
||||
public static SprintTree clientGetSprintTree(Entity e){
|
||||
|
||||
@ -115,7 +115,7 @@ public class ObjectUtils {
|
||||
// rVal.putData(EntityDataStrings.LIFE_STATE, new LifeState(rVal, rawType.getHealthSystem()));
|
||||
// Globals.entityManager.registerLifeStateEntity(rVal);
|
||||
//idle tree & generic stuff all objects have
|
||||
rVal.putData(EntityDataStrings.IDLE_TREE, new IdleTree(rVal));
|
||||
rVal.putData(EntityDataStrings.TREE_IDLE, new IdleTree(rVal));
|
||||
rVal.putData(EntityDataStrings.DRAW_CAST_SHADOW, true);
|
||||
return rVal;
|
||||
}
|
||||
@ -212,7 +212,7 @@ public class ObjectUtils {
|
||||
// rVal.putData(EntityDataStrings.LIFE_STATE, new LifeState(rVal, rawType.getHealthSystem()));
|
||||
// Globals.entityManager.registerLifeStateEntity(rVal);
|
||||
//idle tree & generic stuff all objects have
|
||||
rVal.putData(EntityDataStrings.IDLE_TREE, new IdleTree(rVal));
|
||||
rVal.putData(EntityDataStrings.TREE_IDLE, new IdleTree(rVal));
|
||||
rVal.putData(EntityDataStrings.DRAW_CAST_SHADOW, true);
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ import electrosphere.net.parser.net.message.LoreMessage;
|
||||
import electrosphere.net.parser.net.message.NetworkMessage;
|
||||
import electrosphere.net.parser.net.message.PlayerMessage;
|
||||
import electrosphere.net.parser.net.message.ServerMessage;
|
||||
import electrosphere.net.parser.net.message.SynchronizationMessage;
|
||||
import electrosphere.net.parser.net.message.TerrainMessage;
|
||||
import org.joml.Vector2f;
|
||||
import org.joml.Vector3f;
|
||||
@ -53,6 +54,9 @@ public class ClientProtocol {
|
||||
case INVENTORY_MESSAGE:
|
||||
InventoryProtocol.handleInventoryMessage((InventoryMessage)message);
|
||||
break;
|
||||
case SYNCHRONIZATION_MESSAGE:
|
||||
SynchronizationProtocol.handleSynchronizationMessage((SynchronizationMessage)message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
package electrosphere.net.client.protocol;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.net.parser.net.message.SynchronizationMessage;
|
||||
|
||||
public class SynchronizationProtocol {
|
||||
|
||||
protected static void handleSynchronizationMessage(SynchronizationMessage message){
|
||||
switch(message.getMessageSubtype()){
|
||||
case UPDATECLIENTSTATE:
|
||||
case ATTACHTREE:
|
||||
case DETATCHTREE:
|
||||
Globals.clientSynchronizationManager.pushMessage(message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -16,6 +16,7 @@ SERVER_MESSAGE,
|
||||
AUTH_MESSAGE,
|
||||
CHARACTER_MESSAGE,
|
||||
INVENTORY_MESSAGE,
|
||||
SYNCHRONIZATION_MESSAGE,
|
||||
}
|
||||
|
||||
MessageType type;
|
||||
@ -352,6 +353,26 @@ INVENTORY_MESSAGE,
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TypeBytes.MESSAGE_TYPE_SYNCHRONIZATION:
|
||||
secondByte = byteBuffer.peek(1);
|
||||
switch(secondByte){
|
||||
case TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_UPDATECLIENTSTATE:
|
||||
if(SynchronizationMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = SynchronizationMessage.parseUpdateClientStateMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_ATTACHTREE:
|
||||
if(SynchronizationMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = SynchronizationMessage.parseAttachTreeMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_DETATCHTREE:
|
||||
if(SynchronizationMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = SynchronizationMessage.parseDetatchTreeMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rVal;
|
||||
|
||||
@ -0,0 +1,205 @@
|
||||
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;
|
||||
|
||||
public class SynchronizationMessage extends NetworkMessage {
|
||||
|
||||
public enum SynchronizationMessageType {
|
||||
UPDATECLIENTSTATE,
|
||||
ATTACHTREE,
|
||||
DETATCHTREE,
|
||||
}
|
||||
|
||||
SynchronizationMessageType messageType;
|
||||
int entityId;
|
||||
int bTreeId;
|
||||
int fieldId;
|
||||
int bTreeValue;
|
||||
|
||||
SynchronizationMessage(SynchronizationMessageType messageType){
|
||||
this.type = MessageType.SYNCHRONIZATION_MESSAGE;
|
||||
this.messageType = messageType;
|
||||
}
|
||||
|
||||
public SynchronizationMessageType getMessageSubtype(){
|
||||
return this.messageType;
|
||||
}
|
||||
|
||||
public int getentityId() {
|
||||
return entityId;
|
||||
}
|
||||
|
||||
public void setentityId(int entityId) {
|
||||
this.entityId = entityId;
|
||||
}
|
||||
|
||||
public int getbTreeId() {
|
||||
return bTreeId;
|
||||
}
|
||||
|
||||
public void setbTreeId(int bTreeId) {
|
||||
this.bTreeId = bTreeId;
|
||||
}
|
||||
|
||||
public int getfieldId() {
|
||||
return fieldId;
|
||||
}
|
||||
|
||||
public void setfieldId(int fieldId) {
|
||||
this.fieldId = fieldId;
|
||||
}
|
||||
|
||||
public int getbTreeValue() {
|
||||
return bTreeValue;
|
||||
}
|
||||
|
||||
public void setbTreeValue(int bTreeValue) {
|
||||
this.bTreeValue = bTreeValue;
|
||||
}
|
||||
|
||||
static void stripPacketHeader(CircularByteBuffer byteBuffer){
|
||||
byteBuffer.read(2);
|
||||
}
|
||||
|
||||
public static boolean canParseMessage(CircularByteBuffer byteBuffer, byte secondByte){
|
||||
switch(secondByte){
|
||||
case TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_UPDATECLIENTSTATE:
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_UPDATECLIENTSTATE_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_ATTACHTREE:
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_ATTACHTREE_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_DETATCHTREE:
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_DETATCHTREE_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static SynchronizationMessage parseUpdateClientStateMessage(CircularByteBuffer byteBuffer){
|
||||
SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.UPDATECLIENTSTATE);
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setbTreeId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setfieldId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setbTreeValue(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static SynchronizationMessage constructUpdateClientStateMessage(int entityId,int bTreeId,int fieldId,int bTreeValue){
|
||||
SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.UPDATECLIENTSTATE);
|
||||
rVal.setentityId(entityId);
|
||||
rVal.setbTreeId(bTreeId);
|
||||
rVal.setfieldId(fieldId);
|
||||
rVal.setbTreeValue(bTreeValue);
|
||||
rVal.serialize();
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static SynchronizationMessage parseAttachTreeMessage(CircularByteBuffer byteBuffer){
|
||||
SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.ATTACHTREE);
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setbTreeId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static SynchronizationMessage constructAttachTreeMessage(int entityId,int bTreeId){
|
||||
SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.ATTACHTREE);
|
||||
rVal.setentityId(entityId);
|
||||
rVal.setbTreeId(bTreeId);
|
||||
rVal.serialize();
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static SynchronizationMessage parseDetatchTreeMessage(CircularByteBuffer byteBuffer){
|
||||
SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.DETATCHTREE);
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setbTreeId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static SynchronizationMessage constructDetatchTreeMessage(int entityId,int bTreeId){
|
||||
SynchronizationMessage rVal = new SynchronizationMessage(SynchronizationMessageType.DETATCHTREE);
|
||||
rVal.setentityId(entityId);
|
||||
rVal.setbTreeId(bTreeId);
|
||||
rVal.serialize();
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
void serialize(){
|
||||
byte[] intValues = new byte[8];
|
||||
byte[] stringBytes;
|
||||
switch(this.messageType){
|
||||
case UPDATECLIENTSTATE:
|
||||
rawBytes = new byte[2+4+4+4+4];
|
||||
//message header
|
||||
rawBytes[0] = TypeBytes.MESSAGE_TYPE_SYNCHRONIZATION;
|
||||
//entity messaage header
|
||||
rawBytes[1] = TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_UPDATECLIENTSTATE;
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(entityId);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[2+i] = intValues[i];
|
||||
}
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(bTreeId);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[6+i] = intValues[i];
|
||||
}
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(fieldId);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[10+i] = intValues[i];
|
||||
}
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(bTreeValue);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[14+i] = intValues[i];
|
||||
}
|
||||
break;
|
||||
case ATTACHTREE:
|
||||
rawBytes = new byte[2+4+4];
|
||||
//message header
|
||||
rawBytes[0] = TypeBytes.MESSAGE_TYPE_SYNCHRONIZATION;
|
||||
//entity messaage header
|
||||
rawBytes[1] = TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_ATTACHTREE;
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(entityId);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[2+i] = intValues[i];
|
||||
}
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(bTreeId);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[6+i] = intValues[i];
|
||||
}
|
||||
break;
|
||||
case DETATCHTREE:
|
||||
rawBytes = new byte[2+4+4];
|
||||
//message header
|
||||
rawBytes[0] = TypeBytes.MESSAGE_TYPE_SYNCHRONIZATION;
|
||||
//entity messaage header
|
||||
rawBytes[1] = TypeBytes.SYNCHRONIZATION_MESSAGE_TYPE_DETATCHTREE;
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(entityId);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[2+i] = intValues[i];
|
||||
}
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(bTreeId);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[6+i] = intValues[i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
serialized = true;
|
||||
}
|
||||
|
||||
}
|
||||
@ -13,6 +13,7 @@ Message categories
|
||||
public static final byte MESSAGE_TYPE_AUTH = 5;
|
||||
public static final byte MESSAGE_TYPE_CHARACTER = 6;
|
||||
public static final byte MESSAGE_TYPE_INVENTORY = 7;
|
||||
public static final byte MESSAGE_TYPE_SYNCHRONIZATION = 8;
|
||||
/*
|
||||
Entity subcategories
|
||||
*/
|
||||
@ -151,5 +152,17 @@ Message categories
|
||||
Inventory packet sizes
|
||||
*/
|
||||
public static final byte INVENTORY_MESSAGE_TYPE_REMOVEITEMFROMINVENTORY_SIZE = 6;
|
||||
/*
|
||||
Synchronization subcategories
|
||||
*/
|
||||
public static final byte SYNCHRONIZATION_MESSAGE_TYPE_UPDATECLIENTSTATE = 0;
|
||||
public static final byte SYNCHRONIZATION_MESSAGE_TYPE_ATTACHTREE = 1;
|
||||
public static final byte SYNCHRONIZATION_MESSAGE_TYPE_DETATCHTREE = 2;
|
||||
/*
|
||||
Synchronization packet sizes
|
||||
*/
|
||||
public static final byte SYNCHRONIZATION_MESSAGE_TYPE_UPDATECLIENTSTATE_SIZE = 18;
|
||||
public static final byte SYNCHRONIZATION_MESSAGE_TYPE_ATTACHTREE_SIZE = 10;
|
||||
public static final byte SYNCHRONIZATION_MESSAGE_TYPE_DETATCHTREE_SIZE = 10;
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
package electrosphere.net.parser.net.raw;
|
||||
|
||||
import electrosphere.net.parser.net.message.NetworkMessage;
|
||||
package electrosphere.net.parser.net.raw;
|
||||
|
||||
import electrosphere.net.parser.net.message.NetworkMessage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
@ -15,7 +15,7 @@ public class NetworkParser {
|
||||
CopyOnWriteArrayList<NetworkMessage> incomingMessageQueue = new CopyOnWriteArrayList<NetworkMessage>();
|
||||
CopyOnWriteArrayList<NetworkMessage> outgoingMessageQueue = new CopyOnWriteArrayList<NetworkMessage>();
|
||||
|
||||
CircularByteBuffer incomingByteBuffer = new CircularByteBuffer(64 * 1024 * 1024);
|
||||
CircularByteBuffer incomingByteBuffer = new CircularByteBuffer(64 * 1024 * 124);
|
||||
CopyOnWriteArrayList<Byte> outgoingByteQueue = new CopyOnWriteArrayList<Byte>();
|
||||
|
||||
|
||||
|
||||
@ -1,8 +1,85 @@
|
||||
package electrosphere.net.synchronization;
|
||||
|
||||
|
||||
import electrosphere.entity.state.idle.ServerIdleTree;
|
||||
|
||||
import electrosphere.entity.state.idle.IdleTree;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.net.parser.net.message.SynchronizationMessage;
|
||||
|
||||
/**
|
||||
* Takes in raw behavior tree packets from server and pushes their values into respective behavior trees in entities
|
||||
*/
|
||||
public class ClientSynchronizationManager {
|
||||
|
||||
//The list of messages to loop through
|
||||
List<SynchronizationMessage> messages = new CopyOnWriteArrayList<SynchronizationMessage>();
|
||||
|
||||
/**
|
||||
* Pushes a message into the queue to be processed
|
||||
* @param message The message
|
||||
*/
|
||||
public void pushMessage(SynchronizationMessage message){
|
||||
this.messages.add(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes all messages in the queue and then clears the queue
|
||||
*/
|
||||
public void processMessages(){
|
||||
List<SynchronizationMessage> messagesToClear = new LinkedList<SynchronizationMessage>();
|
||||
for(SynchronizationMessage message : messages){
|
||||
messagesToClear.add(message);
|
||||
switch(message.getMessageSubtype()){
|
||||
case UPDATECLIENTSTATE:{
|
||||
int bTreeId = message.getbTreeId();
|
||||
int entityId = message.getentityId();
|
||||
Entity targetEntity = Globals.clientSceneWrapper.getEntityFromServerId(entityId);
|
||||
updateEntityState(targetEntity,bTreeId,message);
|
||||
} break;
|
||||
case ATTACHTREE:{
|
||||
int bTreeId = message.getbTreeId();
|
||||
int bTreeValue = message.getbTreeValue();
|
||||
int entityId = message.getentityId();
|
||||
} break;
|
||||
case DETATCHTREE:{
|
||||
int bTreeId = message.getbTreeId();
|
||||
int entityId = message.getentityId();
|
||||
} break;
|
||||
}
|
||||
}
|
||||
for(SynchronizationMessage message : messagesToClear){
|
||||
messages.remove(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> Automatically generated </p>
|
||||
* <p>
|
||||
* Updates the state of a given behavior tree on a given entity
|
||||
* </p>
|
||||
* @param entity The entity
|
||||
* @param bTreeId The id of the behavior tree
|
||||
* @param message The raw synchronization message holding the update data
|
||||
*/
|
||||
private void updateEntityState(Entity entity, int bTreeId, SynchronizationMessage message){
|
||||
switch(bTreeId){
|
||||
case BehaviorTreeIdEnums.BTREE_SERVERIDLE_ID: {
|
||||
switch(message.getfieldId()){
|
||||
case 1:{
|
||||
IdleTree tree = IdleTree.getIdleTree(entity);
|
||||
tree.setState(IdleTree.getIdleTreeStateShortAsEnum((short)message.getbTreeValue()));
|
||||
} break;
|
||||
}
|
||||
} break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,30 +0,0 @@
|
||||
package electrosphere.net.synchronization;
|
||||
|
||||
import electrosphere.entity.state.idle.IdleTree.IdleTreeState;
|
||||
|
||||
public class TypeTranslator {
|
||||
|
||||
|
||||
public static short getIdleStateEnumAsShort(IdleTreeState enumVal){
|
||||
switch(enumVal){
|
||||
case IDLE:
|
||||
return 0;
|
||||
case NOT_IDLE:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static IdleTreeState getIdleStateShortAsEnum(short rawValue){
|
||||
switch(rawValue){
|
||||
case 0:
|
||||
return IdleTreeState.IDLE;
|
||||
case 1:
|
||||
return IdleTreeState.NOT_IDLE;
|
||||
default:
|
||||
return IdleTreeState.IDLE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -13,7 +13,8 @@
|
||||
"./net/world.json",
|
||||
"./net/server.json",
|
||||
"./net/character.json",
|
||||
"./net/inventory.json"
|
||||
"./net/inventory.json",
|
||||
"./net/synchronization.json"
|
||||
]
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user