package vooga.rts.networking.server;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import util.logger.HandlerTxt;
import vooga.rts.networking.NetworkBundle;
/**
* Object responsible for creating an instance of a game, and establishing
* connections between clients and the game.
*
* @author srwareham
* @author David Winegar
*
*/
public class MatchmakerServer extends AbstractThreadContainer {
private Map<String, GameContainer> myGameContainers = new HashMap<String, GameContainer>();
private ConnectionServer myConnectionServer = new ConnectionServer(this);
/**
* Initializes overall server hierarchy.
*/
public MatchmakerServer () {
getLogger().addHandler(new HandlerTxt(getClass().getSimpleName()).getHandler());
getLogger().log(Level.INFO, NetworkBundle.getString("ServerStarted"));
}
/**
* Starts the ConnectionServer so that this server can start accepting connections.
*/
public void startAcceptingConnections () {
myConnectionServer.start();
}
@Override
public void joinGameContainer (ConnectionThread thread, String gameName) {
GameContainer container;
if (myGameContainers.containsKey(gameName)) {
container = myGameContainers.get(gameName);
getLogger().log(Level.INFO,
NetworkBundle.getString("GameContainerJoined") +
gameName);
}
else {
container = createGameContainer(gameName);
getLogger().log(Level.INFO, NetworkBundle.getString("NewGameContainer") +
gameName);
}
container.addConnection(thread);
removeConnection(thread);
}
/**
* If there is a GameContainer subclass associated with the game name, it looks for it in the
* configuration file and tries to instantiate that instead. If not, uses a normal
* GameContainer.
*/
private GameContainer createGameContainer (String gameName) {
GameContainer container;
if (NetworkBundle.containsConfigurationItem(gameName)) {
String className = NetworkBundle.getConfigurationItem(gameName);
try {
Constructor<?> constructor = Class.forName(className).getConstructor(String.class);
container = (GameContainer) constructor.newInstance(gameName);
}
catch (InstantiationException e) {
container = logAndCreateContainer(gameName);
}
catch (IllegalAccessException e) {
container = logAndCreateContainer(gameName);
}
catch (ClassNotFoundException e) {
container = logAndCreateContainer(gameName);
}
catch (IllegalArgumentException e) {
container = logAndCreateContainer(gameName);
}
catch (InvocationTargetException e) {
container = logAndCreateContainer(gameName);
}
catch (NoSuchMethodException e) {
container = logAndCreateContainer(gameName);
}
catch (SecurityException e) {
container = logAndCreateContainer(gameName);
}
}
else {
container = new GameContainer(gameName);
}
myGameContainers.put(gameName, container);
return container;
}
private GameContainer logAndCreateContainer (String gameName) {
getLogger().log(Level.SEVERE, NetworkBundle.getString("GameContainerCreationFailed"));
return new GameContainer(gameName);
}
}