Added instanced player messaging. Correct Player Joining/Leaving bugs.

pull/2/head
Joshua Sigona 4 years ago
parent f7cf09ce4b
commit c028e94d2c
  1. 1
      .gitattributes
  2. 27
      assets/Materials/Generated/model2-Hair001_baked_006.j3m
  3. 23
      assets/Materials/Generated/model2-Hair001_baked_2391.j3m
  4. 9
      assets/Materials/PinkHair.j3m
  5. BIN
      assets/Models/Oto.mesh.j3o
  6. 3
      assets/Models/model5/model5.j3o
  7. 3
      assets/Models/model5/model5.j3odata
  8. BIN
      assets/Models/test ava/test ava.j3o
  9. BIN
      assets/Scenes/TestLevel.j3o
  10. 3
      assets/Scenes/TestLevel2.j3o
  11. 3
      assets/Scenes/TestLevel2.j3odata
  12. BIN
      build/classes/mygame/Main.class
  13. 2
      nbproject/private/private.xml
  14. 4
      nbproject/project.properties
  15. 8
      src/mygame/Main.java
  16. 42
      src/mygame/appstate/RunLevel.java
  17. 10
      src/mygame/control/PlayableCharacter.java
  18. 1
      src/mygame/server/Instance.java
  19. 47
      src/mygame/server/ServerMain.java

1
.gitattributes vendored

@ -0,0 +1 @@
*.j3o filter=lfs diff=lfs merge=lfs -text

@ -0,0 +1,27 @@
Material MyMaterial : Common/MatDefs/Light/PBRLighting.j3md {
MaterialParameters {
Glossiness : 1.0
EmissivePower : 3.0
BaseColor : 1.0 1.0 1.0 1.0
ParallaxHeight : 0.05
Metallic : 0.0
BackfaceShadows : false
Roughness : 0.0
NormalType : -1.0
Emissive : 0.0 0.0 0.0 1.0
EmissiveIntensity : 2.0
BaseColorMap : Texture2D[name=image6.png, image=Image[size=1024x256, format=ABGR8, id=323]]:returned null key
Specular : 1.0 1.0 1.0 1.0
}
AdditionalRenderState {
PointSprite On
FaceCull Off
AlphaTestFalloff 0.0
DepthWrite On
ColorWrite On
PolyOffset 0.0 0.0
DepthTest On
Blend Off
Wireframe Off
}
}

@ -0,0 +1,23 @@
Material MyMaterial : Common/MatDefs/Light/Lighting.j3md {
MaterialParameters {
Diffuse : 0.64000005 0.64000005 0.64000005 1.0
UseMaterialColors : true
ParallaxHeight : 0.05
Ambient : 1.0 1.0 1.0 1.0
BackfaceShadows : false
DiffuseMap : Texture2D[name=Atlas_40637.png, image=Image[size=8192x4096, format=RGBA8, id=481]]:returned null key
Specular : 0.4 0.4 0.4 1.0
Shininess : 128.0
}
AdditionalRenderState {
PointSprite On
FaceCull Back
AlphaTestFalloff 0.0
DepthWrite On
ColorWrite On
PolyOffset 0.0 0.0
DepthTest On
Blend Off
Wireframe Off
}
}

@ -0,0 +1,9 @@
Material PinkHair : Common/MatDefs/Light/Lighting.j3md {
MaterialParameters {
Diffuse : 1.0 0.2 1.0 1.0
VertexLighting : false
UseMaterialColors : true
}
AdditionalRenderState {
}
}

Binary file not shown.

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:176f45a93d4e1074dd77f53868dba0a1b05dbbd858a4f2a2b67311ec13308331
size 120792010

@ -0,0 +1,3 @@
#
#Sun Jun 28 15:49:26 KST 2020
ORIGINAL_PATH=Models/model5/model5.gltf

Binary file not shown.

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7a1e76295163b1d07e43a734e54c4e8ea440ebb6af63240eb015a095311d6765
size 155133

@ -0,0 +1,3 @@
#
#Wed Jun 17 10:55:55 KST 2020
ORIGINAL_PATH=Scenes/TestLevel.j3o

Binary file not shown.

@ -5,8 +5,10 @@
<group> <group>
<file>file:/E:/GameProjects/Rabi-Bounce-Bounce-R/src/mygame/Main.java</file> <file>file:/E:/GameProjects/Rabi-Bounce-Bounce-R/src/mygame/Main.java</file>
<file>file:/E:/GameProjects/Rabi-Bounce-Bounce-R/src/mygame/appstate/RunLevel.java</file> <file>file:/E:/GameProjects/Rabi-Bounce-Bounce-R/src/mygame/appstate/RunLevel.java</file>
<file>file:/E:/GameProjects/Rabi-Bounce-Bounce-R/src/mygame/control/PhysicsControl.java</file>
<file>file:/E:/GameProjects/Rabi-Bounce-Bounce-R/src/mygame/control/PlayableCharacter.java</file> <file>file:/E:/GameProjects/Rabi-Bounce-Bounce-R/src/mygame/control/PlayableCharacter.java</file>
<file>file:/E:/GameProjects/Rabi-Bounce-Bounce-R/src/mygame/server/ServerMain.java</file> <file>file:/E:/GameProjects/Rabi-Bounce-Bounce-R/src/mygame/server/ServerMain.java</file>
<file>file:/E:/GameProjects/Rabi-Bounce-Bounce-R/src/mygame/server/Instance.java</file>
<file>file:/E:/GameProjects/Rabi-Bounce-Bounce-R/src/mygame/control/NetworkPlayableCharacter.java</file> <file>file:/E:/GameProjects/Rabi-Bounce-Bounce-R/src/mygame/control/NetworkPlayableCharacter.java</file>
</group> </group>
</open-files> </open-files>

@ -51,8 +51,8 @@ javac.deprecation=false
javac.external.vm=false javac.external.vm=false
javac.processorpath=\ javac.processorpath=\
${javac.classpath} ${javac.classpath}
javac.source=1.7 javac.source=1.8
javac.target=1.7 javac.target=1.8
javac.test.classpath=\ javac.test.classpath=\
${javac.classpath}:\ ${javac.classpath}:\
${build.classes.dir} ${build.classes.dir}

@ -23,6 +23,7 @@ import mygame.server.ServerMain;
import mygame.server.ServerMain.EntityMessage; import mygame.server.ServerMain.EntityMessage;
import mygame.server.ServerMain.JoinMessage; import mygame.server.ServerMain.JoinMessage;
import mygame.server.ServerMain.PlayerActionMessage; import mygame.server.ServerMain.PlayerActionMessage;
import mygame.server.ServerMain.PlayerLeaveMessage;
import mygame.server.ServerMain.PlayerPositionMessage; import mygame.server.ServerMain.PlayerPositionMessage;
import mygame.server.ServerMain.ServerMessage; import mygame.server.ServerMain.ServerMessage;
import mygame.server.ServerMain.SyncLevelMessage; import mygame.server.ServerMain.SyncLevelMessage;
@ -44,6 +45,7 @@ public class Main extends SimpleApplication implements ClientStateListener{
client.addMessageListener(new ClientListener(), JoinMessage.class); client.addMessageListener(new ClientListener(), JoinMessage.class);
//client.addMessageListener(new ClientListener(), PlayerJoinMessage.class); //client.addMessageListener(new ClientListener(), PlayerJoinMessage.class);
client.addMessageListener(new ClientListener(), PlayerActionMessage.class); client.addMessageListener(new ClientListener(), PlayerActionMessage.class);
client.addMessageListener(new ClientListener(), PlayerLeaveMessage.class);
client.addClientStateListener(this); client.addClientStateListener(this);
client.start(); client.start();
@ -68,8 +70,9 @@ public class Main extends SimpleApplication implements ClientStateListener{
public void simpleInitApp() { public void simpleInitApp() {
flyCam.setEnabled(false); flyCam.setEnabled(false);
//flyCam.setMoveSpeed(50); //flyCam.setMoveSpeed(50);
level = new RunLevel("TestLevel"); level = new RunLevel("TestLevel2");
stateManager.attach(level); stateManager.attach(level);
//stateManager.detach(level);
} }
@Override @Override
@ -110,6 +113,9 @@ public class Main extends SimpleApplication implements ClientStateListener{
} else } else
if (message instanceof JoinMessage) { if (message instanceof JoinMessage) {
level.getPlayerJoinMessage((JoinMessage)message); level.getPlayerJoinMessage((JoinMessage)message);
} else
if (message instanceof PlayerLeaveMessage) {
level.getPlayerLeaveMessage((PlayerLeaveMessage)message);
} }
} }
} }

@ -34,7 +34,9 @@ import mygame.control.PlayableCharacter;
import mygame.server.ServerMain.JoinMessage; import mygame.server.ServerMain.JoinMessage;
import mygame.server.ServerMain.SyncLevelMessage; import mygame.server.ServerMain.SyncLevelMessage;
import mygame.server.Entity; import mygame.server.Entity;
import mygame.server.ServerMain;
import mygame.server.ServerMain.PlayerActionMessage; import mygame.server.ServerMain.PlayerActionMessage;
import mygame.server.ServerMain.PlayerLeaveMessage;
public class RunLevel extends BaseAppState public class RunLevel extends BaseAppState
@ -50,10 +52,13 @@ public class RunLevel extends BaseAppState
private List<Integer> players = new ArrayList<>(); private List<Integer> players = new ArrayList<>();
private Vector3f[] player_locations; private Vector3f[] player_locations;
public static List<PlayerActionMessage> queuedPlayerActionMessages = new ArrayList<>(); public static List<PlayerActionMessage> queuedPlayerActionMessages = new ArrayList<>();
public static List<JoinMessage> queuedPlayerJoinMessages = new ArrayList<>();
public static List<PlayerLeaveMessage> queuedPlayerLeaveMessages = new ArrayList<>();
public static List<SyncLevelMessage> queuedSyncLevelMessages = new ArrayList<>(); public static List<SyncLevelMessage> queuedSyncLevelMessages = new ArrayList<>();
public static Node world; public static Node world;
Node entityNode; Node entityNode;
public static Node networkedPlayersNode; public static Node networkedPlayersNode;
float timer;
public RunLevel(String levelName) { public RunLevel(String levelName) {
//System.out.println("In here. Initialize"); //System.out.println("In here. Initialize");
@ -94,7 +99,7 @@ public class RunLevel extends BaseAppState
//DirectionalLight sceneLight = (DirectionalLight)world.getLocalLightList().get(0); //DirectionalLight sceneLight = (DirectionalLight)world.getLocalLightList().get(0);
Node player = (Node)assetManager.loadModel("Models/Oto/Oto.mesh.xml"); Node player = (Node)assetManager.loadModel("Models/Oto/Oto.mesh.xml");
Node playerNode = new Node(); Node playerNode = new Node("Player");
playerNode.attachChild(player); playerNode.attachChild(player);
playerNode.addControl(new PlayableCharacter()); playerNode.addControl(new PlayableCharacter());
@ -202,6 +207,8 @@ public class RunLevel extends BaseAppState
protected void cleanup(Application app) { protected void cleanup(Application app) {
//TODO: clean up what you initialized in the initialize method, //TODO: clean up what you initialized in the initialize method,
//e.g. remove all spatials from rootNode //e.g. remove all spatials from rootNode
//((Node)rootNode.getChild("Player")).removeControl(PlayableCharacter.class);
((Node)rootNode.getChild("Reflected Scene")).detachAllChildren();
} }
//onEnable()/onDisable() can be used for managing things that should //onEnable()/onDisable() can be used for managing things that should
@ -230,6 +237,30 @@ public class RunLevel extends BaseAppState
createPlayers(); createPlayers();
} }
queuedSyncLevelMessages.clear(); queuedSyncLevelMessages.clear();
for (JoinMessage msg : queuedPlayerJoinMessages) {
MakeNetworkPlayer(msg.getEntity().id,msg.getEntity().position);
players.add(msg.getEntity().id);
createPlayers();
System.out.println(msg);
}
queuedPlayerJoinMessages.clear();
for (PlayerLeaveMessage msg : queuedPlayerLeaveMessages) {
for (int i=0;i<networkedPlayersNode.getChildren().size();i++) {
Spatial s = networkedPlayersNode.getChildren().get(i);
if (s.getName().equalsIgnoreCase(Integer.toString(msg.getId()))) {
System.out.println("Removed "+s);
networkedPlayersNode.detachChild(s);
players.remove((Integer)msg.getId());
i--;
}
}
}
queuedPlayerLeaveMessages.clear();
/*timer+=tpf;
if (timer>5) {
main.getStateManager().detach(this);
this.setEnabled(false);
}*/
} }
@Override @Override
@ -259,9 +290,7 @@ public class RunLevel extends BaseAppState
public void getPlayerJoinMessage(JoinMessage playerJoinMessage) { public void getPlayerJoinMessage(JoinMessage playerJoinMessage) {
JoinMessage msg = playerJoinMessage; JoinMessage msg = playerJoinMessage;
MakeNetworkPlayer(msg.getEntity().id,msg.getEntity().position); queuedPlayerJoinMessages.add(msg);
players.add(msg.getEntity().id);
createPlayers();
} }
private void MakeNetworkPlayer(int id, Vector3f pos) { private void MakeNetworkPlayer(int id, Vector3f pos) {
@ -290,4 +319,9 @@ public class RunLevel extends BaseAppState
networkPlayer.setUserData("lastCamLeftDir", playerActionMessage.getCameraLeft()); networkPlayer.setUserData("lastCamLeftDir", playerActionMessage.getCameraLeft());
} }
public void getPlayerLeaveMessage(PlayerLeaveMessage playerLeaveMessage) {
PlayerLeaveMessage msg = playerLeaveMessage;
queuedPlayerLeaveMessages.add(msg);
}
} }

@ -25,6 +25,7 @@ import com.jme3.scene.Spatial;
import com.jme3.scene.control.AbstractControl; import com.jme3.scene.control.AbstractControl;
import com.jme3.scene.control.Control; import com.jme3.scene.control.Control;
import java.io.IOException; import java.io.IOException;
import static mygame.Main.level;
import static mygame.Main.main; import static mygame.Main.main;
import mygame.server.ServerMain.PlayerActionMessage; import mygame.server.ServerMain.PlayerActionMessage;
import mygame.server.ServerMain.PlayerPositionMessage; import mygame.server.ServerMain.PlayerPositionMessage;
@ -60,6 +61,7 @@ public class PlayableCharacter extends AbstractControl implements Savable, Clone
@Override @Override
public void setSpatial(Spatial spatial) { public void setSpatial(Spatial spatial) {
super.setSpatial(spatial); super.setSpatial(spatial);
if (spatial!=null) {
//control = spatial.getControl(BetterCharacterControl.class); //control = spatial.getControl(BetterCharacterControl.class);
Node myNode = (Node)spatial; Node myNode = (Node)spatial;
@ -70,10 +72,12 @@ public class PlayableCharacter extends AbstractControl implements Savable, Clone
); );
myNode.addControl(physics); myNode.addControl(physics);
control = ((Node)spatial).getChild(0).getControl(AnimControl.class); control = (((Node)spatial).getChild(0)).getControl(AnimControl.class);
//System.out.println(control.getAnimationNames());
control.addListener(this); control.addListener(this);
channel = control.createChannel(); channel = control.createChannel();
channel.setAnim("stand"); channel.setAnim("stand");
channel.setLoopMode(LoopMode.Cycle);
/*channel_lowerbody = control.createChannel(); /*channel_lowerbody = control.createChannel();
channel_lowerbody.addBone("hip.right"); channel_lowerbody.addBone("hip.right");
channel_lowerbody.addBone("hip.left");*/ //There is no strafing animation channel_lowerbody.addBone("hip.left");*/ //There is no strafing animation
@ -88,6 +92,9 @@ public class PlayableCharacter extends AbstractControl implements Savable, Clone
main.getInputManager().addListener(this, "StrafeRight"); main.getInputManager().addListener(this, "StrafeRight");
main.getInputManager().addListener(this, "StrafeLeft"); main.getInputManager().addListener(this, "StrafeLeft");
main.getInputManager().addListener(this, "Jump"); main.getInputManager().addListener(this, "Jump");
} else {
main.getInputManager().removeListener(this);
}
} }
/** Implement your spatial's behaviour here. /** Implement your spatial's behaviour here.
@ -216,6 +223,7 @@ public class PlayableCharacter extends AbstractControl implements Savable, Clone
switch (name) { switch (name) {
case "Jump":{ case "Jump":{
if (isOnGround() || physics.airTime<=physics.walkOffTime) { if (isOnGround() || physics.airTime<=physics.walkOffTime) {
//System.out.println("Jump");
physics.jump(); physics.jump();
if (!(this instanceof NetworkPlayableCharacter)) { //Only send if this is the source client. if (!(this instanceof NetworkPlayableCharacter)) { //Only send if this is the source client.
PlayerActionMessage action = new PlayerActionMessage(name,"",main.client.getId(),spatial.getLocalTranslation(),spatial.getLocalRotation(),main.getCamera().getDirection(),main.getCamera().getLeft()); PlayerActionMessage action = new PlayerActionMessage(name,"",main.client.getId(),spatial.getLocalTranslation(),spatial.getLocalRotation(),main.getCamera().getDirection(),main.getCamera().getLeft());

@ -27,6 +27,7 @@ public class Instance {
protected HashMap<Integer,Vector3f> lastKnownPositions = new HashMap<>(); protected HashMap<Integer,Vector3f> lastKnownPositions = new HashMap<>();
protected List<Entity> entities = new ArrayList<>(); //Entity data specific to this instance. protected List<Entity> entities = new ArrayList<>(); //Entity data specific to this instance.
List<Integer> nullEntities = new ArrayList<>(); //A list of "null" entities. When adding new entities, these slots will be consumed first. List<Integer> nullEntities = new ArrayList<>(); //A list of "null" entities. When adding new entities, these slots will be consumed first.
public int INSTANCE_ID = -1;
Instance(String levelName) { Instance(String levelName) {
this.levelName = levelName; this.levelName = levelName;
} }

@ -34,6 +34,7 @@ public class ServerMain extends SimpleApplication{
int clientIDMax = 0; int clientIDMax = 0;
public static HashMap<String,Instance> instances = new HashMap<>(); public static HashMap<String,Instance> instances = new HashMap<>();
public static HashMap<Integer,Instance> players = new HashMap<>(); //The last instance location this player was seen in. public static HashMap<Integer,Instance> players = new HashMap<>(); //The last instance location this player was seen in.
public static int INSTANCE_UNIQUE_ID = 0;
ServerMain() { ServerMain() {
try { try {
@ -51,7 +52,9 @@ public class ServerMain extends SimpleApplication{
if (players.containsKey(conn.getId())) { if (players.containsKey(conn.getId())) {
Instance i = players.get(conn.getId()); Instance i = players.get(conn.getId());
i.removePlayer(conn); i.removePlayer(conn);
server.broadcast(Filters.in(i.clients),new PlayerLeaveMessage(i.levelName,conn.getId()));
} }
players.remove(conn.getId());
} }
}); });
@ -61,6 +64,7 @@ public class ServerMain extends SimpleApplication{
Serializer.registerClass(JoinMessage.class); Serializer.registerClass(JoinMessage.class);
Serializer.registerClass(SyncLevelMessage.class); Serializer.registerClass(SyncLevelMessage.class);
Serializer.registerClass(Entity.class); Serializer.registerClass(Entity.class);
Serializer.registerClass(PlayerLeaveMessage.class);
//Serializer.registerClass(PlayerJoinMessage.class); //Serializer.registerClass(PlayerJoinMessage.class);
Serializer.registerClass(PlayerActionMessage.class); Serializer.registerClass(PlayerActionMessage.class);
@ -71,6 +75,7 @@ public class ServerMain extends SimpleApplication{
server.addMessageListener(new ServerListener(), SyncLevelMessage.class); server.addMessageListener(new ServerListener(), SyncLevelMessage.class);
//server.addMessageListener(new ServerListener(), PlayerJoinMessage.class); //server.addMessageListener(new ServerListener(), PlayerJoinMessage.class);
server.addMessageListener(new ServerListener(), PlayerActionMessage.class); server.addMessageListener(new ServerListener(), PlayerActionMessage.class);
server.addMessageListener(new ServerListener(), PlayerLeaveMessage.class);
server.start(); server.start();
} catch (IOException ex) { } catch (IOException ex) {
@ -123,8 +128,11 @@ public class ServerMain extends SimpleApplication{
} else } else
if (message instanceof PlayerPositionMessage) { if (message instanceof PlayerPositionMessage) {
System.out.println("Position update for client "+source.getId()+". Broadcasting to others."); System.out.println("Position update for client "+source.getId()+". Broadcasting to others.");
server.broadcast(Filters.notEqualTo(source), message); if (players.containsKey(source.getId())) {
server.broadcast(Filters.in(source), new ServerMessage("Sent an update to other clients!")); Instance i = players.get(source.getId());
SendToAllButMe(i, source, message);
}
//server.broadcast(Filters.in(source), new ServerMessage("Sent an update to other clients!"));
} else } else
if (message instanceof JoinMessage) { if (message instanceof JoinMessage) {
JoinMessage msg = (JoinMessage)message; JoinMessage msg = (JoinMessage)message;
@ -139,6 +147,7 @@ public class ServerMain extends SimpleApplication{
instance = new Instance(msg.levelName); instance = new Instance(msg.levelName);
System.out.println("Instance "+msg.levelName+" does not exist. Creating... "+instance); System.out.println("Instance "+msg.levelName+" does not exist. Creating... "+instance);
CreateTestObj(instance); CreateTestObj(instance);
instance.INSTANCE_ID=INSTANCE_UNIQUE_ID++;
System.out.println(instance); System.out.println(instance);
instances.put(msg.levelName, instance); instances.put(msg.levelName, instance);
} }
@ -146,15 +155,15 @@ public class ServerMain extends SimpleApplication{
instance.addPlayer(source); instance.addPlayer(source);
SyncLevelMessage sync = new SyncLevelMessage(instance.getEntities(),instance.getPlayers(),instance.getPlayerPositions()); SyncLevelMessage sync = new SyncLevelMessage(instance.getEntities(),instance.getPlayers(),instance.getPlayerPositions());
server.broadcast(Filters.in(source),sync); server.broadcast(Filters.in(source),sync);
server.broadcast(Filters.notEqualTo(source),message); SendToAllButMe(instance, source, message);
} else } else
if (message instanceof PlayerActionMessage) { if (message instanceof PlayerActionMessage) {
System.out.println("Received player action message: "+message); System.out.println("Received player action message: "+message);
server.broadcast(Filters.notEqualTo(source), message);
PlayerActionMessage msg = (PlayerActionMessage)message; PlayerActionMessage msg = (PlayerActionMessage)message;
if (players.containsKey(source.getId())) { if (players.containsKey(source.getId())) {
Instance i = players.get(source.getId()); Instance i = players.get(source.getId());
i.updatePosition(source.getId(),msg.getPosition()); i.updatePosition(source.getId(),msg.getPosition());
SendToAllButMe(i, source, message);
} }
} /*else } /*else
if (message instanceof PlayerJoinMessage) { if (message instanceof PlayerJoinMessage) {
@ -162,6 +171,14 @@ public class ServerMain extends SimpleApplication{
server.broadcast(Filters.notEqualTo(source), message); server.broadcast(Filters.notEqualTo(source), message);
}*/ }*/
} }
private void SendToAllButMe(Instance i, HostedConnection source, Message message) {
for (HostedConnection conn : i.clients) {
if (conn!=source) {
server.broadcast(Filters.in(conn),message);
}
}
}
} }
public void CreateTestObj(Instance instance) { public void CreateTestObj(Instance instance) {
@ -248,6 +265,28 @@ public class ServerMain extends SimpleApplication{
} }
} }
@Serializable @Serializable
public static class PlayerLeaveMessage extends AbstractMessage {
String levelName;
int id;
public PlayerLeaveMessage() {
}
public PlayerLeaveMessage(String levelName, int id) {
this.levelName = levelName;
this.id=id;
}
@Override
public String toString() {
return "Client ID "+id+" left. In Instance "+levelName.toString();
}
public int getId() {
return id;
}
}
@Serializable
public static class SyncLevelMessage extends AbstractMessage { public static class SyncLevelMessage extends AbstractMessage {
Entity[] entities; Entity[] entities;
Integer[] clients; Integer[] clients;

Loading…
Cancel
Save