This commit is contained in:
parent
8bf1c23704
commit
74167038f7
@ -1,3 +1,3 @@
|
|||||||
#maven.buildNumber.plugin properties file
|
#maven.buildNumber.plugin properties file
|
||||||
#Thu Aug 15 18:38:57 EDT 2024
|
#Fri Aug 16 07:57:34 EDT 2024
|
||||||
buildNumber=204
|
buildNumber=233
|
||||||
|
|||||||
9
docs/src/debug/BugLog.md
Normal file
9
docs/src/debug/BugLog.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
@page BugLog Bug Log
|
||||||
|
|
||||||
|
A log of bugs encountered
|
||||||
|
|
||||||
|
|
||||||
|
### 08-16-2024
|
||||||
|
- Starting a server with a local client didn't actually create the server socket/thread. This meant no other players could connect.
|
||||||
|
- On a client disconnection, the server connection was cleared by IP instead of by socket, so if two connections were from the same IP (ie localhost) it would disconnect the first one to connect.
|
||||||
|
|
||||||
@ -10,4 +10,8 @@ Arena was not loading because handling of edge-of-world chunks was not being han
|
|||||||
for a world of 2x2x2, when loading the chunk at (1,0,0) you need data for chunk (2,0,0)
|
for a world of 2x2x2, when loading the chunk at (1,0,0) you need data for chunk (2,0,0)
|
||||||
(2,0,0) is out of bounds of the world size, but the drawcellmanager would not mark the chunk data as present because it wasn't properly checking for bounds
|
(2,0,0) is out of bounds of the world size, but the drawcellmanager would not mark the chunk data as present because it wasn't properly checking for bounds
|
||||||
This was fixed by properly checking for bounds in drawcellmanager; however, it then started failing to fetch data for (2,0,0) and NPEing
|
This was fixed by properly checking for bounds in drawcellmanager; however, it then started failing to fetch data for (2,0,0) and NPEing
|
||||||
Fixed by guarding in the method that generates chunk data
|
Fixed by guarding in the method that generates chunk data
|
||||||
|
|
||||||
|
### 08-16-2024
|
||||||
|
Second client could not connect to server started with local player because the routine to start local server didn't actually start a socket
|
||||||
|
|
||||||
|
|||||||
@ -2,4 +2,5 @@
|
|||||||
|
|
||||||
|
|
||||||
[TOC]
|
[TOC]
|
||||||
|
- @subpage BugLog
|
||||||
- @subpage LoadingHalting
|
- @subpage LoadingHalting
|
||||||
@ -584,6 +584,10 @@ Play animations offset by network delay
|
|||||||
- Attack animation
|
- Attack animation
|
||||||
Fix viewmodel animation framerate
|
Fix viewmodel animation framerate
|
||||||
|
|
||||||
|
(08/16/2024)
|
||||||
|
Fix server not starting
|
||||||
|
Fix client disconnection causing wrong socket to be closed from server
|
||||||
|
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
|
|||||||
@ -72,7 +72,7 @@ public class LevelEditorLoading {
|
|||||||
//initialize the local connection
|
//initialize the local connection
|
||||||
Globals.clientUsername = "leveleditor";
|
Globals.clientUsername = "leveleditor";
|
||||||
Globals.clientPassword = AuthenticationManager.getHashedString("leveleditor");
|
Globals.clientPassword = AuthenticationManager.getHashedString("leveleditor");
|
||||||
ServerConnectionHandler serverPlayerConnection = LoadingUtils.initLocalConnection(false);
|
ServerConnectionHandler serverPlayerConnection = LoadingUtils.initLocalConnection(true);
|
||||||
//wait for player object creation
|
//wait for player object creation
|
||||||
while(Globals.playerManager.getPlayers().size() < 1){
|
while(Globals.playerManager.getPlayers().size() < 1){
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -85,10 +85,9 @@ public class ServerEntityUtils {
|
|||||||
* @param entity the entity to destroy
|
* @param entity the entity to destroy
|
||||||
*/
|
*/
|
||||||
public static void destroyEntity(Entity entity){
|
public static void destroyEntity(Entity entity){
|
||||||
//
|
if(entity == null){
|
||||||
//get info required to destroy
|
throw new IllegalArgumentException("Trying to destroy null!");
|
||||||
ServerDataCell cell = DataCellSearchUtils.getEntityDataCell(entity);
|
}
|
||||||
Realm realm = Globals.realmManager.getEntityRealm(entity);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
//destroy the child entities, too
|
//destroy the child entities, too
|
||||||
@ -100,22 +99,28 @@ public class ServerEntityUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
//cell specific logic
|
//get info required to destroy
|
||||||
if(cell != null){
|
Realm realm = Globals.realmManager.getEntityRealm(entity);
|
||||||
cell.broadcastNetworkMessage(EntityMessage.constructDestroyMessage(entity.getId()));
|
ServerDataCell cell = null;
|
||||||
cell.getScene().deregisterEntity(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
//realm specific logic
|
//realm specific logic
|
||||||
if(realm != null){
|
if(realm != null){
|
||||||
realm.getCollisionEngine().destroyPhysics(entity);
|
realm.getCollisionEngine().destroyPhysics(entity);
|
||||||
|
cell = DataCellSearchUtils.getEntityDataCell(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//cell specific logic
|
||||||
|
if(cell != null){
|
||||||
|
cell.broadcastNetworkMessage(EntityMessage.constructDestroyMessage(entity.getId()));
|
||||||
|
ServerBehaviorTreeUtils.deregisterEntity(entity);
|
||||||
|
cell.getScene().deregisterEntity(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
//detatch from all global tracking
|
//detatch from all global tracking
|
||||||
HitboxCollectionState.destroyHitboxState(entity);
|
HitboxCollectionState.destroyHitboxState(entity);
|
||||||
ServerBehaviorTreeUtils.deregisterEntity(entity);
|
|
||||||
Globals.realmManager.removeEntity(entity);
|
Globals.realmManager.removeEntity(entity);
|
||||||
EntityLookupUtils.removeEntity(entity);
|
EntityLookupUtils.removeEntity(entity);
|
||||||
Globals.aiManager.removeAI(entity);
|
Globals.aiManager.removeAI(entity);
|
||||||
|
|||||||
@ -146,6 +146,37 @@ public class ClientGroundMovementTree implements BehaviorTree {
|
|||||||
Vector3d position = EntityUtils.getPosition(parent);
|
Vector3d position = EntityUtils.getPosition(parent);
|
||||||
Quaterniond rotation = EntityUtils.getRotation(parent);
|
Quaterniond rotation = EntityUtils.getRotation(parent);
|
||||||
float velocity = CreatureUtils.getVelocity(parent);
|
float velocity = CreatureUtils.getVelocity(parent);
|
||||||
|
if(this.parent == Globals.playerEntity){
|
||||||
|
Globals.clientConnection.queueOutgoingMessage(
|
||||||
|
EntityMessage.constructmoveUpdateMessage(
|
||||||
|
Globals.clientSceneWrapper.mapClientToServerId(parent.getId()),
|
||||||
|
Globals.timekeeper.getNumberOfSimFramesElapsed(),
|
||||||
|
position.x,
|
||||||
|
position.y,
|
||||||
|
position.z,
|
||||||
|
rotation.x,
|
||||||
|
rotation.y,
|
||||||
|
rotation.z,
|
||||||
|
rotation.w,
|
||||||
|
velocity,
|
||||||
|
ClientGroundMovementTree.getMovementRelativeFacingEnumAsShort(facing),
|
||||||
|
0 //magic number corresponding to state startup
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests to the server that the movetree stop
|
||||||
|
*/
|
||||||
|
public void slowdown(){
|
||||||
|
state = MovementTreeState.SLOWDOWN;
|
||||||
|
//if we aren't the server, alert the server we intend to slow down
|
||||||
|
Vector3d position = EntityUtils.getPosition(parent);
|
||||||
|
Quaterniond rotation = EntityUtils.getRotation(parent);
|
||||||
|
float velocity = CreatureUtils.getVelocity(parent);
|
||||||
|
if(this.parent == Globals.playerEntity){
|
||||||
Globals.clientConnection.queueOutgoingMessage(
|
Globals.clientConnection.queueOutgoingMessage(
|
||||||
EntityMessage.constructmoveUpdateMessage(
|
EntityMessage.constructmoveUpdateMessage(
|
||||||
Globals.clientSceneWrapper.mapClientToServerId(parent.getId()),
|
Globals.clientSceneWrapper.mapClientToServerId(parent.getId()),
|
||||||
@ -159,39 +190,12 @@ public class ClientGroundMovementTree implements BehaviorTree {
|
|||||||
rotation.w,
|
rotation.w,
|
||||||
velocity,
|
velocity,
|
||||||
ClientGroundMovementTree.getMovementRelativeFacingEnumAsShort(facing),
|
ClientGroundMovementTree.getMovementRelativeFacingEnumAsShort(facing),
|
||||||
0 //magic number corresponding to state startup
|
2 //magic number corresponding to state slowdown
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Requests to the server that the movetree stop
|
|
||||||
*/
|
|
||||||
public void slowdown(){
|
|
||||||
state = MovementTreeState.SLOWDOWN;
|
|
||||||
//if we aren't the server, alert the server we intend to slow down
|
|
||||||
Vector3d position = EntityUtils.getPosition(parent);
|
|
||||||
Quaterniond rotation = EntityUtils.getRotation(parent);
|
|
||||||
float velocity = CreatureUtils.getVelocity(parent);
|
|
||||||
Globals.clientConnection.queueOutgoingMessage(
|
|
||||||
EntityMessage.constructmoveUpdateMessage(
|
|
||||||
Globals.clientSceneWrapper.mapClientToServerId(parent.getId()),
|
|
||||||
Globals.timekeeper.getNumberOfSimFramesElapsed(),
|
|
||||||
position.x,
|
|
||||||
position.y,
|
|
||||||
position.z,
|
|
||||||
rotation.x,
|
|
||||||
rotation.y,
|
|
||||||
rotation.z,
|
|
||||||
rotation.w,
|
|
||||||
velocity,
|
|
||||||
ClientGroundMovementTree.getMovementRelativeFacingEnumAsShort(facing),
|
|
||||||
2 //magic number corresponding to state slowdown
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void simulate(float deltaTime){
|
public void simulate(float deltaTime){
|
||||||
Actor entityActor = EntityUtils.getActor(parent);
|
Actor entityActor = EntityUtils.getActor(parent);
|
||||||
|
|||||||
@ -172,7 +172,11 @@ public class ClientNetworking implements Runnable {
|
|||||||
//attempt poll incoming messages
|
//attempt poll incoming messages
|
||||||
parser.readMessagesIn();
|
parser.readMessagesIn();
|
||||||
//outgoing messages
|
//outgoing messages
|
||||||
parser.pushMessagesOut();
|
try {
|
||||||
|
parser.pushMessagesOut();
|
||||||
|
} catch(IOException e){
|
||||||
|
LoggerInterface.loggerNetworking.ERROR(e);
|
||||||
|
}
|
||||||
//parses messages asynchronously
|
//parses messages asynchronously
|
||||||
this.parseMessagesAsynchronously();
|
this.parseMessagesAsynchronously();
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
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.NetworkMessage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
@ -55,15 +55,11 @@ public class NetworkParser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void pushMessagesOut(){
|
public void pushMessagesOut() throws IOException {
|
||||||
for(NetworkMessage message : outgoingMessageQueue){
|
for(NetworkMessage message : outgoingMessageQueue){
|
||||||
outgoingMessageQueue.remove(message);
|
outgoingMessageQueue.remove(message);
|
||||||
try {
|
|
||||||
// System.out.println("Write message of type " + message.getType());
|
// System.out.println("Write message of type " + message.getType());
|
||||||
outgoingStream.write(message.getRawBytes());
|
outgoingStream.write(message.getRawBytes());
|
||||||
} catch (IOException ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -106,6 +106,7 @@ public class MessageProtocol {
|
|||||||
if(result != null){
|
if(result != null){
|
||||||
this.synchronousMessageLock.acquireUninterruptibly();
|
this.synchronousMessageLock.acquireUninterruptibly();
|
||||||
this.synchronousMessageQueue.add(result);
|
this.synchronousMessageQueue.add(result);
|
||||||
|
LoggerInterface.loggerNetworking.DEBUG_LOOP("ADD SYNC MESSAGE [Sync queue size: " + this.synchronousMessageQueue.size() + "]");
|
||||||
this.synchronousMessageLock.release();
|
this.synchronousMessageLock.release();
|
||||||
}
|
}
|
||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
@ -114,6 +115,7 @@ public class MessageProtocol {
|
|||||||
public void handleSyncMessages(){
|
public void handleSyncMessages(){
|
||||||
Globals.profiler.beginAggregateCpuSample("MessageProtocol(client).handleSyncMessages");
|
Globals.profiler.beginAggregateCpuSample("MessageProtocol(client).handleSyncMessages");
|
||||||
this.synchronousMessageLock.acquireUninterruptibly();
|
this.synchronousMessageLock.acquireUninterruptibly();
|
||||||
|
LoggerInterface.loggerNetworking.DEBUG_LOOP("HANDLE SYNC MESSAGE [Sync queue size: " + this.synchronousMessageQueue.size() + "]");
|
||||||
for(NetworkMessage message : synchronousMessageQueue){
|
for(NetworkMessage message : synchronousMessageQueue){
|
||||||
switch(message.getType()){
|
switch(message.getType()){
|
||||||
case AUTH_MESSAGE:
|
case AUTH_MESSAGE:
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package electrosphere.net.server;
|
|||||||
|
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.engine.Main;
|
import electrosphere.engine.Main;
|
||||||
|
import electrosphere.entity.ServerEntityUtils;
|
||||||
import electrosphere.logger.LoggerInterface;
|
import electrosphere.logger.LoggerInterface;
|
||||||
import electrosphere.net.NetUtils;
|
import electrosphere.net.NetUtils;
|
||||||
import electrosphere.net.parser.net.message.NetworkMessage;
|
import electrosphere.net.parser.net.message.NetworkMessage;
|
||||||
@ -14,7 +15,11 @@ import java.net.ServerSocket;
|
|||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
import java.util.concurrent.Semaphore;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lowest level networking class for the server
|
* Lowest level networking class for the server
|
||||||
@ -27,10 +32,17 @@ public class Server implements Runnable{
|
|||||||
//the socket for the server
|
//the socket for the server
|
||||||
ServerSocket serverSocket;
|
ServerSocket serverSocket;
|
||||||
|
|
||||||
//the map of ip->connection handler
|
//Used to synchronize additions/subtractions to the connections stored by this server
|
||||||
Map<String,ServerConnectionHandler> clientMap = new HashMap<String,ServerConnectionHandler>();
|
Semaphore connectListLock = new Semaphore(1);
|
||||||
|
|
||||||
|
//map of socket->connection
|
||||||
|
Map<Socket,ServerConnectionHandler> socketConnectionMap = new HashMap<Socket,ServerConnectionHandler>();
|
||||||
|
|
||||||
|
//the list of active connections
|
||||||
|
List<ServerConnectionHandler> activeConnections = new LinkedList<ServerConnectionHandler>();
|
||||||
|
|
||||||
|
//The list of connections to clean up
|
||||||
|
List<ServerConnectionHandler> connectionsToCleanup = new CopyOnWriteArrayList<ServerConnectionHandler>();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,19 +72,20 @@ public class Server implements Runnable{
|
|||||||
}
|
}
|
||||||
} catch(BindException ex){
|
} catch(BindException ex){
|
||||||
LoggerInterface.loggerNetworking.ERROR("Failed to bind server socket!",ex);
|
LoggerInterface.loggerNetworking.ERROR("Failed to bind server socket!",ex);
|
||||||
ex.printStackTrace();
|
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
LoggerInterface.loggerNetworking.ERROR("Failed to start server socket!",ex);
|
LoggerInterface.loggerNetworking.ERROR("Failed to start server socket!",ex);
|
||||||
ex.printStackTrace();
|
|
||||||
LoggerInterface.loggerNetworking.ERROR("", ex);
|
|
||||||
}
|
}
|
||||||
while(Main.isRunning()){
|
while(Main.isRunning()){
|
||||||
Socket newSocket;
|
Socket newSocket;
|
||||||
try {
|
try {
|
||||||
newSocket = serverSocket.accept();
|
newSocket = serverSocket.accept();
|
||||||
|
connectListLock.acquireUninterruptibly();
|
||||||
ServerConnectionHandler newClient = new ServerConnectionHandler(newSocket);
|
ServerConnectionHandler newClient = new ServerConnectionHandler(newSocket);
|
||||||
clientMap.put(newSocket.getInetAddress().getHostAddress(), newClient);
|
// clientMap.put(newSocket.getInetAddress().getHostAddress(), newClient);
|
||||||
|
socketConnectionMap.put(newSocket, newClient);
|
||||||
|
activeConnections.add(newClient);
|
||||||
new Thread(newClient).start();
|
new Thread(newClient).start();
|
||||||
|
connectListLock.release();
|
||||||
} catch (SocketException ex){
|
} catch (SocketException ex){
|
||||||
LoggerInterface.loggerNetworking.ERROR("Socket closed!",ex);
|
LoggerInterface.loggerNetworking.ERROR("Socket closed!",ex);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
@ -85,9 +98,11 @@ public class Server implements Runnable{
|
|||||||
* Synchronously handles queued packets for each client connection
|
* Synchronously handles queued packets for each client connection
|
||||||
*/
|
*/
|
||||||
public void synchronousPacketHandling(){
|
public void synchronousPacketHandling(){
|
||||||
for(ServerConnectionHandler connectionHandler : this.clientMap.values()){
|
connectListLock.acquireUninterruptibly();
|
||||||
|
for(ServerConnectionHandler connectionHandler : activeConnections){
|
||||||
connectionHandler.handleSynchronousPacketQueue();
|
connectionHandler.handleSynchronousPacketQueue();
|
||||||
}
|
}
|
||||||
|
connectListLock.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -108,11 +123,13 @@ public class Server implements Runnable{
|
|||||||
* @param message The message to broadcast
|
* @param message The message to broadcast
|
||||||
*/
|
*/
|
||||||
public void broadcastMessage(NetworkMessage message){
|
public void broadcastMessage(NetworkMessage message){
|
||||||
for(ServerConnectionHandler client : clientMap.values()){
|
connectListLock.acquireUninterruptibly();
|
||||||
|
for(ServerConnectionHandler client : activeConnections){
|
||||||
if(Globals.clientPlayer == null || client.playerID != Globals.clientPlayer.getId()){
|
if(Globals.clientPlayer == null || client.playerID != Globals.clientPlayer.getId()){
|
||||||
client.addMessagetoOutgoingQueue(message);
|
client.addMessagetoOutgoingQueue(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
connectListLock.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -122,9 +139,37 @@ public class Server implements Runnable{
|
|||||||
* @return The connection object for the provided streams
|
* @return The connection object for the provided streams
|
||||||
*/
|
*/
|
||||||
public ServerConnectionHandler addLocalPlayer(InputStream serverInputStream, OutputStream serverOutputStream){
|
public ServerConnectionHandler addLocalPlayer(InputStream serverInputStream, OutputStream serverOutputStream){
|
||||||
|
connectListLock.acquireUninterruptibly();
|
||||||
ServerConnectionHandler newClient = new ServerConnectionHandler(serverInputStream,serverOutputStream);
|
ServerConnectionHandler newClient = new ServerConnectionHandler(serverInputStream,serverOutputStream);
|
||||||
clientMap.put("127.0.0.1", newClient);
|
activeConnections.add(newClient);
|
||||||
new Thread(newClient).start();
|
new Thread(newClient).start();
|
||||||
|
connectListLock.release();
|
||||||
return newClient;
|
return newClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a client to the queue of connections to cleanup
|
||||||
|
* @param serverConnectionHandler The connection
|
||||||
|
*/
|
||||||
|
public void addClientToCleanup(ServerConnectionHandler serverConnectionHandler){
|
||||||
|
this.connectListLock.acquireUninterruptibly();
|
||||||
|
this.connectionsToCleanup.add(serverConnectionHandler);
|
||||||
|
this.connectListLock.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleans up dead connections on the server
|
||||||
|
*/
|
||||||
|
public void cleanupDeadConnections(){
|
||||||
|
this.connectListLock.acquireUninterruptibly();
|
||||||
|
for(ServerConnectionHandler connection : this.connectionsToCleanup){
|
||||||
|
//tell all clients to destroy the entity
|
||||||
|
ServerEntityUtils.destroyEntity(connection.getPlayer().getPlayerEntity());
|
||||||
|
this.activeConnections.remove(connection);
|
||||||
|
if(connection.getSocket() != null){
|
||||||
|
this.socketConnectionMap.remove(connection.getSocket());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.connectListLock.release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,6 @@ package electrosphere.net.server;
|
|||||||
import electrosphere.entity.types.creature.CreatureTemplate;
|
import electrosphere.entity.types.creature.CreatureTemplate;
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.engine.Main;
|
import electrosphere.engine.Main;
|
||||||
import electrosphere.entity.ServerEntityUtils;
|
|
||||||
import electrosphere.logger.LoggerInterface;
|
import electrosphere.logger.LoggerInterface;
|
||||||
import electrosphere.net.parser.net.message.AuthMessage;
|
import electrosphere.net.parser.net.message.AuthMessage;
|
||||||
import electrosphere.net.parser.net.message.NetworkMessage;
|
import electrosphere.net.parser.net.message.NetworkMessage;
|
||||||
@ -61,6 +60,11 @@ public class ServerConnectionHandler implements Runnable {
|
|||||||
//the player's entity id
|
//the player's entity id
|
||||||
int playerEntityID;
|
int playerEntityID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tracks whether this connection is still communicating with the client
|
||||||
|
*/
|
||||||
|
boolean isConnected = true;
|
||||||
|
|
||||||
//the creature template associated with this player
|
//the creature template associated with this player
|
||||||
CreatureTemplate currentCreatureTemplate;
|
CreatureTemplate currentCreatureTemplate;
|
||||||
|
|
||||||
@ -189,7 +193,7 @@ public class ServerConnectionHandler implements Runnable {
|
|||||||
|
|
||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
while(Main.isRunning()){
|
while(Main.isRunning() && this.isConnected == true){
|
||||||
|
|
||||||
//
|
//
|
||||||
// Main Loop
|
// Main Loop
|
||||||
@ -203,6 +207,16 @@ public class ServerConnectionHandler implements Runnable {
|
|||||||
//TODO: fix, this doesn't actually catch the socket exception which is exceedingly obnoxious
|
//TODO: fix, this doesn't actually catch the socket exception which is exceedingly obnoxious
|
||||||
socketException = true;
|
socketException = true;
|
||||||
LoggerInterface.loggerNetworking.DEBUG(e.getLocalizedMessage());
|
LoggerInterface.loggerNetworking.DEBUG(e.getLocalizedMessage());
|
||||||
|
this.disconnect();
|
||||||
|
break;
|
||||||
|
} catch (IOException e){
|
||||||
|
//if we get a SocketException broken pipe (basically the client dc'd without telling us)
|
||||||
|
//set flag to disconnect client
|
||||||
|
//TODO: fix, this doesn't actually catch the socket exception which is exceedingly obnoxious
|
||||||
|
socketException = true;
|
||||||
|
LoggerInterface.loggerNetworking.DEBUG(e.getLocalizedMessage());
|
||||||
|
this.disconnect();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -233,6 +247,8 @@ public class ServerConnectionHandler implements Runnable {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LoggerInterface.loggerNetworking.WARNING("Server connection thread ended");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -240,7 +256,7 @@ public class ServerConnectionHandler implements Runnable {
|
|||||||
* without my linter freaking out
|
* without my linter freaking out
|
||||||
* @throws SocketException
|
* @throws SocketException
|
||||||
*/
|
*/
|
||||||
void parseMessages() throws SocketException {
|
void parseMessages() throws SocketException, IOException {
|
||||||
//
|
//
|
||||||
//Read in messages
|
//Read in messages
|
||||||
//
|
//
|
||||||
@ -333,6 +349,10 @@ public class ServerConnectionHandler implements Runnable {
|
|||||||
return Globals.playerManager.getPlayerFromId(playerID);
|
return Globals.playerManager.getPlayerFromId(playerID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the ip address of the connection
|
||||||
|
* @return The ip address
|
||||||
|
*/
|
||||||
public String getIPAddress(){
|
public String getIPAddress(){
|
||||||
if(local){
|
if(local){
|
||||||
return "127.0.0.1";
|
return "127.0.0.1";
|
||||||
@ -340,6 +360,14 @@ public class ServerConnectionHandler implements Runnable {
|
|||||||
return socket.getRemoteSocketAddress().toString();
|
return socket.getRemoteSocketAddress().toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the socket of the connection, if it is a socket based connection. Otherwise returns null.
|
||||||
|
* @return The socket if it exists, null otherwise
|
||||||
|
*/
|
||||||
|
public Socket getSocket(){
|
||||||
|
return this.socket;
|
||||||
|
}
|
||||||
|
|
||||||
public void addMessagetoOutgoingQueue(NetworkMessage message){
|
public void addMessagetoOutgoingQueue(NetworkMessage message){
|
||||||
networkParser.addOutgoingMessage(message);
|
networkParser.addOutgoingMessage(message);
|
||||||
@ -372,7 +400,7 @@ public class ServerConnectionHandler implements Runnable {
|
|||||||
/**
|
/**
|
||||||
* Routine to run when the client disconnects
|
* Routine to run when the client disconnects
|
||||||
*/
|
*/
|
||||||
void disconnect(){
|
private void disconnect(){
|
||||||
//close socket
|
//close socket
|
||||||
if(socket.isConnected()){
|
if(socket.isConnected()){
|
||||||
try {
|
try {
|
||||||
@ -381,10 +409,9 @@ public class ServerConnectionHandler implements Runnable {
|
|||||||
LoggerInterface.loggerNetworking.ERROR("Error closing socket", e);
|
LoggerInterface.loggerNetworking.ERROR("Error closing socket", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//figure out what player we are
|
this.isConnected = false;
|
||||||
Player playerObject = Globals.playerManager.getPlayerFromId(getPlayerId());
|
//add connection to server list of connections to cleanup
|
||||||
//tell all clients to destroy the entity
|
Globals.server.addClientToCleanup(this);
|
||||||
ServerEntityUtils.destroyEntity(playerObject.getPlayerEntity());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,6 +13,12 @@ public class MainServerFunctions {
|
|||||||
*/
|
*/
|
||||||
public static void simulate(){
|
public static void simulate(){
|
||||||
|
|
||||||
|
//
|
||||||
|
//Cleanup disconnected clients
|
||||||
|
if(Globals.server != null){
|
||||||
|
Globals.server.cleanupDeadConnections();
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
//Synchronous player message parsing\
|
//Synchronous player message parsing\
|
||||||
Globals.profiler.beginCpuSample("Server synchronous packet parsing");
|
Globals.profiler.beginCpuSample("Server synchronous packet parsing");
|
||||||
|
|||||||
@ -34,10 +34,11 @@ public class ServerBehaviorTreeUtils {
|
|||||||
public static void deregisterEntity(Entity entity){
|
public static void deregisterEntity(Entity entity){
|
||||||
Set<BehaviorTree> trees = entityBTreeMap.remove(entity);
|
Set<BehaviorTree> trees = entityBTreeMap.remove(entity);
|
||||||
ServerDataCell currentCell = DataCellSearchUtils.getEntityDataCell(entity);
|
ServerDataCell currentCell = DataCellSearchUtils.getEntityDataCell(entity);
|
||||||
for(BehaviorTree tree : trees){
|
if(trees != null){
|
||||||
currentCell.getScene().deregisterBehaviorTree(tree);
|
for(BehaviorTree tree : trees){
|
||||||
|
currentCell.getScene().deregisterBehaviorTree(tree);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
currentCell.getScene().deregisterEntity(entity);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user