package complexion.client; import java.io.IOException; import java.net.InetAddress; import java.util.HashMap; import java.util.Map; import complexion.common.Utils; import com.esotericsoftware.kryonet.Connection; import com.esotericsoftware.kryonet.Listener; import complexion.network.message.AtomDelta; import complexion.network.message.CreateDialog; import complexion.network.message.DialogSync; import complexion.network.message.LoginAccepted; import complexion.network.message.LoginRequest; import complexion.network.message.RegisterClasses; /** * This class is responsible for managing network connections. * It will mostly be responsible for accepting and creating new * connections. */ public class ServerConnection extends Listener { /** * Create a new ServerConnection, which will automatically * connect to the specified host. * @param port The port to host the server on. * @throws IOException */ public ServerConnection(Client client, InetAddress address, int port) throws IOException { // Remember the client this.client = client; // Start the connection and connect to the server connection = new com.esotericsoftware.kryonet.Client(8192,3072); connection.addListener(this); connection.start(); connection.connect(5000, address, port); // Setup message classes for transfer. RegisterClasses.registerClasses(connection.getKryo()); } /** * Try to log into the server with the specified account name and password * @param password An MD5(or otherwise) hashed password * @return true on success, false otherwise */ public boolean login(String account_name, String password) { connection.sendTCP(new LoginRequest(account_name, password)); // Wait for an answer. If none arrives, return false. long start = System.currentTimeMillis(); while(!loggedIn) { long waitedFor = System.currentTimeMillis()-start; if(waitedFor > 5000) // timeout { return false; } Utils.sleep(1); } return true; } /** * Handle the incoming message. * * Note that this will be running in a separate thread. Thus, all operations * performed from this function(and its descendends) must either operate on local * values, or operate on threadsafe calls. * * Anything interacting with game-world data must be done by writing * requests into a thread-safe structure, and having the master controller * poll this structure. */ @Override public void received(Connection connection, Object object) { if(object instanceof LoginAccepted) { this.loggedIn = true; LoginAccepted data = (LoginAccepted) object; client.setTick(data.tick); connection.sendTCP(new LoginAccepted()); } else { this.client.serverMessages.add(object); } } public void send(Object data) { if(!connection.isConnected()) return; connection.sendTCP(data); } /// Private var to check whether we're logged in. private boolean loggedIn = false; /// Client this connection is running under. private Client client; /// TCP connection we're using. private com.esotericsoftware.kryonet.Client connection; }