fix networking issues
This commit is contained in:
parent
c641512886
commit
ab5abb019f
@ -362,12 +362,6 @@ public class LoadingThread extends Thread {
|
||||
}
|
||||
|
||||
static void initClientTerrainManager(){
|
||||
while(!Globals.clientConnection.getClientProtocol().hasReceivedWorld()){
|
||||
try {
|
||||
TimeUnit.MILLISECONDS.sleep(5);
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
}
|
||||
Globals.clientTerrainManager = new ClientTerrainManager(Globals.clientWorldData);
|
||||
}
|
||||
|
||||
@ -393,6 +387,14 @@ public class LoadingThread extends Thread {
|
||||
Globals.spawnPoint.set((float)startX,(float)Globals.commonWorldData.getElevationAtPoint(new Vector3d(startX,0,startZ)),(float)startZ);
|
||||
}
|
||||
} else {
|
||||
//basically wait for the client to receive the world metadata
|
||||
while(!Globals.clientConnection.getClientProtocol().hasReceivedWorld()){
|
||||
try {
|
||||
TimeUnit.MILLISECONDS.sleep(5);
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
}
|
||||
//then create common world data
|
||||
Globals.commonWorldData = new CommonWorldData(Globals.clientWorldData, Globals.clientTerrainManager);
|
||||
}
|
||||
}
|
||||
@ -434,16 +436,16 @@ public class LoadingThread extends Thread {
|
||||
|
||||
|
||||
static void initDrawCellManager(){
|
||||
//if it hasn't already been initialized, create draw cell manager
|
||||
if(Globals.drawCellManager == null){
|
||||
Globals.drawCellManager = new DrawCellManager(
|
||||
Globals.commonWorldData,
|
||||
Globals.clientTerrainManager,
|
||||
Globals.clientPlayerData.getWorldPositionX(),
|
||||
Globals.clientPlayerData.getWorldPositionY()
|
||||
// Globals.terrainManager.getDynamicInterpolationRatio(),
|
||||
// Globals.terrainManager.getRandomDampener()
|
||||
);
|
||||
} else {
|
||||
}
|
||||
if(Globals.RUN_CLIENT == true) {
|
||||
//set our draw cell manager to actually generate drawable chunks
|
||||
Globals.drawCellManager.setGenerateDrawables(true);
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package electrosphere.menu;
|
||||
|
||||
import electrosphere.auth.AuthenticationManager;
|
||||
import electrosphere.controls.ControlHandler.ControlsState;
|
||||
import electrosphere.engine.LoadingThread;
|
||||
import electrosphere.entity.Entity;
|
||||
@ -353,16 +354,38 @@ public class MenuGenerators {
|
||||
portInput.setText(NetUtils.getPort() + "");
|
||||
rVal.addChild(portInput);
|
||||
|
||||
//label (address)
|
||||
Label usernameLabel = new Label(100,screenTop + 350,1.0f);
|
||||
usernameLabel.setText("Username");
|
||||
rVal.addChild(usernameLabel);
|
||||
|
||||
//text entry (address)
|
||||
TextInput usernameInput = new TextInput(100,screenTop + 425,1.0f);
|
||||
usernameInput.setText("");
|
||||
rVal.addChild(usernameInput);
|
||||
|
||||
//label (port)
|
||||
Label passwordLabel = new Label(100,screenTop + 500,1.0f);
|
||||
passwordLabel.setText("Password");
|
||||
rVal.addChild(passwordLabel);
|
||||
|
||||
//text entry (port)
|
||||
TextInput passwordInput = new TextInput(100,screenTop + 575,1.0f);
|
||||
passwordInput.setText("");
|
||||
rVal.addChild(passwordInput);
|
||||
|
||||
//button (connect)
|
||||
Button connectButton = new Button();
|
||||
Label connectLabel = new Label(100,screenTop + 350,1.0f);
|
||||
Label connectLabel = new Label(100,screenTop + 650,1.0f);
|
||||
connectLabel.setText("Connect");
|
||||
connectButton.addChild(connectLabel);
|
||||
rVal.addChild(connectButton);
|
||||
connectButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
|
||||
NetUtils.setAddress(addressInput.getText());
|
||||
NetUtils.setPort(Integer.parseInt(portInput.getText()));
|
||||
LoadingThread clientThread = new LoadingThread(LoadingThread.LOAD_MAIN_GAME);
|
||||
Globals.clientUsername = usernameInput.getText();
|
||||
Globals.clientPassword = AuthenticationManager.getHashedString(passwordInput.getText());
|
||||
LoadingThread clientThread = new LoadingThread(LoadingThread.LOAD_CHARACTER_SERVER);
|
||||
Globals.loadingThreadsList.add(clientThread);
|
||||
Globals.RUN_CLIENT = true;
|
||||
Globals.RUN_SERVER = false;
|
||||
@ -372,7 +395,7 @@ public class MenuGenerators {
|
||||
|
||||
//button (back)
|
||||
Button backButton = new Button();
|
||||
Label backLabel = new Label(100,screenTop + 425,1.0f);
|
||||
Label backLabel = new Label(100,screenTop + 725,1.0f);
|
||||
backLabel.setText("Back");
|
||||
backButton.addChild(backLabel);
|
||||
rVal.addChild(backButton);
|
||||
|
||||
@ -10,6 +10,7 @@ import electrosphere.net.client.protocol.ClientProtocol;
|
||||
import electrosphere.net.parser.net.message.EntityMessage;
|
||||
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.raw.NetworkParser;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -48,6 +49,11 @@ public class ClientNetworking implements Runnable{
|
||||
|
||||
static final int MAX_CONNECTION_ATTEMPTS = 10;
|
||||
|
||||
static final long SEND_PING_THRESHOLD = 3000;
|
||||
static final long PING_DISCONNECT_THRESHOLD = 20000;
|
||||
long lastPingTime = 0;
|
||||
long lastPongTime = 0;
|
||||
|
||||
public ClientNetworking(String address, int port){
|
||||
this.address = address;
|
||||
this.port = port;
|
||||
@ -112,6 +118,30 @@ public class ClientNetworking implements Runnable{
|
||||
parser.readMessagesIn();
|
||||
//outgoing messages
|
||||
parser.pushMessagesOut();
|
||||
//ping logic
|
||||
long currentTime = System.currentTimeMillis();
|
||||
//basically if we haven't sent a ping in a while, send one
|
||||
if(currentTime - lastPingTime > SEND_PING_THRESHOLD){
|
||||
queueOutgoingMessage(ServerMessage.constructPingMessage());
|
||||
lastPingTime = currentTime;
|
||||
if(lastPongTime == 0){
|
||||
lastPongTime = lastPingTime;
|
||||
}
|
||||
}
|
||||
if(lastPingTime - lastPongTime > PING_DISCONNECT_THRESHOLD){
|
||||
//disconnected from the server
|
||||
LoggerInterface.loggerNetworking.WARNING("Disconnected from server");
|
||||
//close socket
|
||||
if(socket.isConnected()){
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException e) {
|
||||
LoggerInterface.loggerNetworking.ERROR("Error closing socket", e);
|
||||
}
|
||||
}
|
||||
//TODO: kick us back to the main menu
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -137,4 +167,8 @@ public class ClientNetworking implements Runnable{
|
||||
return clientProtocol;
|
||||
}
|
||||
|
||||
public void markReceivedPongMessage(){
|
||||
lastPongTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -44,6 +44,10 @@ public class EntityProtocol {
|
||||
EntityUtils.setEntityID(newlySpawnedEntity, message.getentityID());
|
||||
break;
|
||||
case DESTROY:
|
||||
//only obey if we're not also the server
|
||||
if(!Globals.RUN_SERVER){
|
||||
Globals.entityManager.deregisterEntity(Globals.entityManager.getEntityFromId(message.getentityID()));
|
||||
}
|
||||
break;
|
||||
case MOVE:
|
||||
//literally just adding this to scope so I can use `` Entity target; `` again
|
||||
@ -84,6 +88,12 @@ public class EntityProtocol {
|
||||
case ATTACKUPDATE:
|
||||
CreatureUtils.attachEntityMessageToAttackTree(Globals.entityManager.getEntityFromId(message.getentityID()),message);
|
||||
break;
|
||||
case KILL:
|
||||
break;
|
||||
case SETPOSITION:
|
||||
break;
|
||||
case SETFACING:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -11,7 +11,8 @@ public class ServerProtocol {
|
||||
Globals.clientConnection.queueOutgoingMessage(ServerMessage.constructPongMessage());
|
||||
break;
|
||||
case PONG:
|
||||
//silently drop
|
||||
//let the networking loop know we received a pong message
|
||||
Globals.clientConnection.markReceivedPongMessage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,6 +18,7 @@ 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.raw.NetworkParser;
|
||||
import electrosphere.net.server.player.Player;
|
||||
import electrosphere.net.server.protocol.ServerProtocol;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -35,6 +36,8 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
/**
|
||||
@ -59,6 +62,15 @@ public class ServerConnectionHandler implements Runnable {
|
||||
|
||||
ServerProtocol serverProtocol;
|
||||
|
||||
//thresholds for determining when to send pings and when a client has disconnected
|
||||
static final long SEND_PING_THRESHOLD = 3000;
|
||||
static final long PING_DISCONNECT_THRESHOLD = 20000;
|
||||
//used to keep track of ping/pong messages with client
|
||||
long lastPingTime = 0;
|
||||
long lastPongTime = 0;
|
||||
//flag to disconnect due to pipe break
|
||||
boolean socketException = false;
|
||||
|
||||
public ServerConnectionHandler(Socket socket) {
|
||||
this.socket = socket;
|
||||
playerID = getNewPlayerID();
|
||||
@ -104,6 +116,45 @@ public class ServerConnectionHandler implements Runnable {
|
||||
|
||||
initialized = true;
|
||||
while(Main.isRunning()){
|
||||
//parse messages both incoming and outgoing
|
||||
try {
|
||||
parseMessages();
|
||||
} catch (SocketException 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());
|
||||
}
|
||||
//ping logic
|
||||
long currentTime = System.currentTimeMillis();
|
||||
//basically if we haven't sent a ping in a while, send one
|
||||
if(currentTime - lastPingTime > SEND_PING_THRESHOLD){
|
||||
addMessagetoOutgoingQueue(ServerMessage.constructPingMessage());
|
||||
lastPingTime = currentTime;
|
||||
if(lastPongTime == 0){
|
||||
lastPongTime = lastPingTime;
|
||||
}
|
||||
}
|
||||
//check if we meet disconnection criteria
|
||||
//has it been too long since the last ping?
|
||||
//have we had a socket exception?
|
||||
if(lastPingTime - lastPongTime > PING_DISCONNECT_THRESHOLD || this.socketException == true){
|
||||
//disconnected from the server
|
||||
LoggerInterface.loggerNetworking.WARNING("Client disconnected");
|
||||
//run disconnect routine
|
||||
disconnect();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Had to wrap the message parsing block in a function to throw a SocketException
|
||||
* without my linter freaking out
|
||||
* @throws SocketException
|
||||
*/
|
||||
void parseMessages() throws SocketException {
|
||||
//attempt poll incoming messages
|
||||
networkParser.readMessagesIn();
|
||||
//ponder incoming messages
|
||||
@ -120,7 +171,6 @@ public class ServerConnectionHandler implements Runnable {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setPlayerId(int id){
|
||||
playerID = id;
|
||||
@ -165,8 +215,6 @@ public class ServerConnectionHandler implements Runnable {
|
||||
networkParser.addOutgoingMessage(message);
|
||||
}
|
||||
break;
|
||||
case SPAWNCREATURE:
|
||||
break;
|
||||
default:
|
||||
networkParser.addOutgoingMessage(message);
|
||||
break;
|
||||
@ -186,4 +234,31 @@ public class ServerConnectionHandler implements Runnable {
|
||||
return this.currentCreatureTemplate;
|
||||
}
|
||||
|
||||
public void markReceivedPongMessage(){
|
||||
lastPongTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Routine to run when the client disconnects
|
||||
*/
|
||||
void disconnect(){
|
||||
//close socket
|
||||
if(socket.isConnected()){
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException e) {
|
||||
LoggerInterface.loggerNetworking.ERROR("Error closing socket", e);
|
||||
}
|
||||
}
|
||||
//figure out what player we are
|
||||
Player playerObject = Globals.playerManager.getPlayerFromId(getPlayerId());
|
||||
//get player entity & position
|
||||
Entity playerEntity = playerObject.getPlayerEntity();
|
||||
Vector3d position = EntityUtils.getPosition(playerEntity);
|
||||
//deregister entity
|
||||
Globals.entityManager.deregisterEntity(playerObject.getPlayerEntity());
|
||||
//tell all clients to destroy the entity
|
||||
Globals.dataCellManager.getDataCellAtPoint(position).broadcastNetworkMessage(EntityMessage.constructDestroyMessage(playerEntity.getId()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@ public class AuthProtocol {
|
||||
connectionHandler.addMessagetoOutgoingQueue(AuthMessage.constructAuthSuccessMessage());
|
||||
Player newPlayer = new Player(connectionHandler);
|
||||
Globals.playerManager.registerPlayer(newPlayer);
|
||||
if(connectionHandler.getIPAddress().contains("127.0.0.1")){
|
||||
if(connectionHandler.getIPAddress().contains("127.0.0.1") && Globals.RUN_CLIENT == true){
|
||||
Globals.clientPlayer = newPlayer;
|
||||
}
|
||||
connectionHandler.addMessagetoOutgoingQueue(PlayerMessage.constructSet_IDMessage(connectionHandler.getPlayerId()));
|
||||
|
||||
@ -29,7 +29,6 @@ import electrosphere.net.server.player.Player;
|
||||
public class ServerProtocol {
|
||||
|
||||
ServerConnectionHandler connectionHandler;
|
||||
int playerCharacterID;
|
||||
|
||||
public ServerProtocol(ServerConnectionHandler connectionHandler){
|
||||
this.connectionHandler = connectionHandler;
|
||||
@ -70,7 +69,7 @@ public class ServerProtocol {
|
||||
connectionHandler.addMessagetoOutgoingQueue(ServerMessage.constructPongMessage());
|
||||
break;
|
||||
case PONG:
|
||||
//silently drop
|
||||
connectionHandler.markReceivedPongMessage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user