package WarTug;
import java.io.IOException;
import java.util.ArrayList;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryonet.Client;
import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.EndPoint;
import com.esotericsoftware.kryonet.Listener;
import com.esotericsoftware.kryonet.Server;
//TODO: Have the join game page call create setUpClientAndServer with a parameter that holds the host
public class Network {
static public final int port = 54555;
private WarTugServer server;
private Thread serverThread;
public Client client; //Receives the network connections
private boolean runningServer; //Does this Network instance have a serverThread
private UnitManager uManager;
public Network(UnitManager uMan) {
uManager = uMan;
}
public void setUpClientAndServer(boolean createServer, String host, WarTug game) {
if (createServer){
makeServer();
}
makeClient(host, game);
}
public void sendGardenToServer(Garden g) {
client.sendTCP(g);
}
private void makeServer(){
runningServer = true;
try{
server = new WarTugServer();
serverThread = new Thread(server);
serverThread.start();
} catch (IOException e) {
System.err.println("Error Starting Server...");
System.exit(-1);
}
}
private void makeClient(String host, WarTug game) {
final WarTug g = game;
client = new Client();
client.start();
// For consistency, the classes to be sent over the network are
// registered by the same method for both the client and server.
Network.register(client);
client.addListener(new Listener() { //Add listener to the client
public void connected (Connection connection) {
RegisterName registerName = new RegisterName();
registerName.name = g.name; //TODO: THis needs to know the name of the player
client.sendTCP(registerName);
}
public void received (Connection connection, Object object) {
if (object instanceof SimpleUnit) {
uManager.addUnit((SimpleUnit) object);
return;
}
if (object instanceof Garden) {
Garden gard = (Garden)object;
if (gard.playerNumber == 0 && gard.playerNumber != g.playerNum) {
g.garden0.buttons.updateGarden(gard);
} else if (gard.playerNumber != g.playerNum){
g.garden1.buttons.updateGarden(gard);
}
}
if (object instanceof Integer) {
if (object != null)
g.gardenUnlocksAvailable += ((Integer)object).intValue();
}
if (object instanceof EndGameStats) {
if (object != null) {
g.gameOver = true;
g.winner = ((EndGameStats)object).winningPlayer;
}
}
}
public void disconnected (Connection connection) {
//Here put code to stop client if it loses connection to server, maybe just set a variable
}
});
try {
client.connect(5000, host, Network.port); //Connect to the server
} catch (IOException e) { e.printStackTrace(); }
}
public void endNetworkConnection() {
//cleanup and end
client.close();
client.stop();
if (runningServer){
server.end = true;
try {
Thread.sleep(200); //Wait to ensure that the server has actually exited
} catch (InterruptedException e) { e.printStackTrace(); }
server.server.close();
server.server.stop();
try {
System.out.println("Waiting for server to quit...");
serverThread.join();
System.out.println("Server has quit!");
} catch (InterruptedException e) { e.printStackTrace(); }
runningServer = false;
}
}
// This registers objects that are going to be sent over the network.
static public void register (EndPoint endPoint) {
Kryo kryo = endPoint.getKryo();
kryo.register(ArrayList.class);
kryo.register(RegisterName.class);
kryo.register(SimpleUnit.class);
kryo.register(UnitType.class);
kryo.register(Garden.class);
kryo.register(int[].class);
kryo.register(GardenSpaceType.class);
kryo.register(GardenSpaceType[][].class);
kryo.register(UnitLion.class);
kryo.register(UnitGazelle.class);
kryo.register(UnitElephant.class);
kryo.register(UnitOstrich.class);
kryo.register(UnitTreeOfLife.class);
kryo.register(EndGameStats.class);
kryo.register(ClearRequest.class);
}
static public class RegisterName {
public String name;
}
public static void sendEndGameStats(Server s, int winningPlayer /*-1 if tie */) {
EndGameStats egs = new EndGameStats(winningPlayer);
s.sendToAllTCP(egs);
}
private static class EndGameStats {
public int winningPlayer;
public EndGameStats() {}
public EndGameStats(int winner) {
winningPlayer = winner;
}
//Other stats can be added here
}
//Allows for naming of connections by player name or by playerNumber
static public class WarTugConnection extends Connection {
public String name;
public int playerNum;
}
public void sendClearUnitsRequest() {
client.sendTCP(new ClearRequest());
}
public static class ClearRequest {
public ClearRequest() {}
}
}