package clueless.controller.server;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.LinkedList;
import java.util.UUID;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import clueless.controller.GameController;
import clueless.events.ClientJoinedEvent;
import clueless.model.Game;
import clueless.model.Player;
import clueless.messaging.Message;
import clueless.messaging.SelectPlayer;
/**
* Class for the Clueless game server.
*
* @author T
*/
public class CluelessServer extends Thread {
private boolean keepRunning = true;
private ServerSocket serverSocket = null;
private GameController controller;
private int numPlayers;
/** A list of all the Clueless player clients that have connected. */
private LinkedList<CluelessClientThread> cluelessClients = null;
/**
* Public constructor.
* @param portNum - the Port number to use for communications
*/
public CluelessServer(GameController controller, int portNum, int numPlayers){
this.controller = controller;
this.numPlayers = numPlayers;
cluelessClients = new LinkedList<CluelessClientThread>();
try{
serverSocket = new ServerSocket(portNum);
}catch(IOException err){
System.err.println("Error creating server socket: "+err.getMessage());
keepRunning = false;
}
this.setName("Server Thread");
}
@Override
public void run(){
/** Keep looking for clients, and when you get one, spin off a new thread.
* Stop when Socket is closed or numPlayers is reached
*/
while(keepRunning && !serverSocket.isClosed()){
Socket clientSocket;
try {
System.out.println("Waiting for next client");
clientSocket = serverSocket.accept(); // blocks until it gets a client
System.out.println("Heard Client: " + clientSocket);
CluelessClientThread client = new CluelessClientThread(controller, clientSocket, getNumClients());
client.setName("Client" + cluelessClients.size());
cluelessClients.add(client);
//TODO: Add CluelessClientThread reference to Player model?
controller.fireClientJoinedEvent(new ClientJoinedEvent(this, client));
System.out.println("Added Client: " + client);
System.out.println(cluelessClients.size() + " Client(s) Connected");
client.start();
if (cluelessClients.size() == numPlayers) break;
} catch (IOException e) {
System.err.println("Error obtaining Clueless client: "+e.getMessage());
e.printStackTrace();
}
}
}
/**
* Sends the given message to the indicated client.
* @param client - the client to receive the server message
* @param message - the message to send
*/
public void send(Player player, Message message){
CluelessClientThread client = getClientThread(player);
client.send(message);
}
/**
* Sends the given message to all clients for this game.
* @param message - the message to send
*/
public void sendAll(Message message){
for(CluelessClientThread client : cluelessClients){
client.send(message);
}
}
/**
* Shuts down all sending and receiving and closes the socket.
*/
public void disconnect(){
keepRunning = false;
for(CluelessClientThread player : cluelessClients){
player.disconnect();
}
try {
serverSocket.close();
} catch (IOException e) {
System.err.println("Error closing Clueless server.");
e.printStackTrace();
}
}
/**
* Used to specify a particular client to transmit to
* @param i = client number, assigned on connection
* @return the thread
*/
public CluelessClientThread getClientThread(int i){
CluelessClientThread thread = null;
if ((i >= 0) && (i < cluelessClients.size())){
thread = cluelessClients.get(i);
}
return thread;
}
/**
* Returns client thread via Player reference
* @param player - Player associated with client thread in reference
* @return client thread
*/
public CluelessClientThread getClientThread(Player player)
{
CluelessClientThread thread = null;
for(CluelessClientThread client : cluelessClients)
{
if(client.getPlayer().getUUID().equals(player.getUUID()))
thread = client;
}
return thread;
}
public int getNumClients(){
return cluelessClients.size();
}
}