/src/network/Lobby.java

http://inequity.googlecode.com/ · Java · 284 lines · 191 code · 38 blank · 55 comment · 10 complexity · 24d8a98bef755f4553d78f7bec69a22e MD5 · raw file

  1. package network;
  2. import elements.CompObj;
  3. import elements.Consts;
  4. import elements.LobbyNode;
  5. import java.io.IOException;
  6. import java.net.ServerSocket;
  7. import java.net.SocketException;
  8. import java.util.ArrayList;
  9. import java.util.concurrent.PriorityBlockingQueue;
  10. import java.util.logging.Level;
  11. import java.util.logging.Logger;
  12. import packets.ChatCmd;
  13. import packets.CleanLobbyReq;
  14. import packets.CommandRequest;
  15. import packets.InviteToGameCmd;
  16. import packets.LobbyJoinCmd;
  17. import packets.PlayerQuitCmd;
  18. import packets.Request;
  19. /**
  20. * Lobby engine for InEquity
  21. * @author Joel Garboden
  22. */
  23. public class Lobby
  24. {
  25. PriorityBlockingQueue<CommandRequest> lobbyQ;
  26. Server server;
  27. Thread connectionlistener;
  28. public ArrayList<LobbyNode> lobbyList;
  29. public Lobby lobbyAccessor;
  30. public ArrayList<Game> gameList;
  31. /**
  32. * Constructor
  33. * @param lobbyQ the queue to take requests from
  34. * @param server the server GUI, for logging
  35. * @param lobbyList client list
  36. */
  37. public Lobby(PriorityBlockingQueue<CommandRequest> lobbyQ, Server server, ArrayList<LobbyNode> lobbyList)
  38. {
  39. this.lobbyQ = lobbyQ;
  40. this.server = server;
  41. lobbyAccessor = this;
  42. this.lobbyList = lobbyList;
  43. gameList = new ArrayList<Game>(0);
  44. }
  45. /**
  46. * Broadcasts chat messages to all clients
  47. * @param playerName the origin of the message (System, playerName)
  48. * @param message the message to send
  49. */
  50. public void broadcastChat(String playerName, String message)
  51. {
  52. ChatCmd cmd = new ChatCmd(playerName, message);
  53. for(LobbyNode p: lobbyList)
  54. {
  55. p.send(cmd);
  56. }
  57. }
  58. /**
  59. * Accessor
  60. * @return the number of chatters
  61. */
  62. public int numChatters()
  63. {
  64. return lobbyList.size();
  65. }
  66. /**
  67. * Adds a NetQProxy for incoming connection
  68. * @param proxy proxy to be added
  69. * @return successful completion
  70. */
  71. public boolean addPlayer(NetQProxy proxy)
  72. {
  73. LobbyNode lobbyNode = new LobbyNode(proxy);
  74. lobbyList.add(lobbyNode);
  75. return true;
  76. }
  77. /**
  78. * Begins game mode
  79. * @param lobbyClients
  80. */
  81. public void startGameCmd(ArrayList<LobbyNode> lobbyClients)
  82. {
  83. if(gameList.size() >= Consts.GAME_SPAWN_LIMIT)
  84. {
  85. System.err.println(Consts.GAME_LIMIT_REACHED);
  86. broadcastChat(Consts.GM_NAME, Consts.GAME_LIMIT_REACHED);
  87. return;
  88. }
  89. boolean validPort = false;
  90. int gamePort = Consts.DEFAULT_PORT;
  91. System.err.println("Start game cmd is under development");
  92. cleanLobby();
  93. ServerSocket testSocket = null;
  94. while(!validPort)
  95. {
  96. try
  97. {
  98. testSocket = new ServerSocket(gamePort);
  99. validPort = true;
  100. System.out.println("");
  101. }
  102. catch(SocketException e)
  103. {
  104. ++gamePort;
  105. System.out.println("Socket:Port is now: " + gamePort);
  106. validPort = false;
  107. }
  108. catch(IOException e)
  109. {
  110. ++gamePort;
  111. System.out.println("IO:Port is now: " + gamePort);
  112. validPort = false;
  113. }
  114. }
  115. final ServerSocket gameSocket = testSocket;
  116. final PriorityBlockingQueue<CommandRequest> gameQ =
  117. new PriorityBlockingQueue<CommandRequest>
  118. (Consts.SERVER_QUEUE_SIZE, new CompObj());
  119. final Game newGame = new Game(gameQ);
  120. gameList.add(newGame);
  121. newGame.startListener();
  122. for(LobbyNode node: lobbyClients)
  123. {
  124. node.send(new InviteToGameCmd(Consts.DEFAULT_IP, gamePort));
  125. }
  126. Runnable rOut = new Runnable()
  127. {
  128. public void run()
  129. {
  130. while(true)
  131. {
  132. newGame.addPlayer(server.acceptClientConnection(gameSocket, gameQ));
  133. }
  134. }
  135. };
  136. Thread reconnector = new Thread(rOut);
  137. reconnector.start();
  138. }
  139. /**
  140. * Starts a LobbyListener to handle incoming packets
  141. */
  142. public void startListener()
  143. {
  144. new LobbyListener().start();
  145. }
  146. /**
  147. * Handles initialization of new clients joining
  148. * @param playerID ID of client
  149. * @param playerName name of joining client
  150. */
  151. public void playerJoinCmd(int playerID, String playerName)
  152. {
  153. if(playerName == null)
  154. {
  155. playerName = "Unknown";
  156. }
  157. LobbyJoinCmd joinCmd = new LobbyJoinCmd();
  158. lobbyList.get(playerID).setName(playerName);
  159. lobbyList.get(playerID).send(joinCmd);
  160. broadcastChat(Consts.GM_NAME, playerName + " " + Consts.JOIN_MSG);
  161. ChatCmd helloCmd = new ChatCmd(Consts.GM_NAME, Consts.WELCOME_MSG);
  162. lobbyList.get(playerID).send(helloCmd);
  163. }
  164. /**
  165. * Handles players quitting
  166. * @param playerName name of player who's quitting
  167. * @throws IndexOutOfBoundsException when player isn't found
  168. */
  169. public void playerQuitCmd(String playerName)
  170. {
  171. for (int i = 0; i < lobbyList.size(); ++i)
  172. {
  173. if (lobbyList.get(i).getName().equals(playerName))
  174. {
  175. lobbyList.get(i).setActive(false);
  176. PlayerQuitCmd cmd = new PlayerQuitCmd();
  177. lobbyList.get(i).send(cmd);
  178. broadcastChat(Consts.GM_NAME, lobbyList.get(i).getName()
  179. + " " + Consts.QUIT_MSG);
  180. lobbyQ.add(new CleanLobbyReq());
  181. return;
  182. }
  183. }
  184. server.postLogMsg("Player: " + playerName+ " not found!");
  185. }
  186. /**
  187. * Cleans inactive lobby members
  188. */
  189. public void cleanLobby()
  190. {
  191. for (int i = 0; i < lobbyList.size(); ++i)
  192. {
  193. if (!lobbyList.get(i).isActive())
  194. {
  195. lobbyList.remove(i);
  196. }
  197. }
  198. lobbyList.trimToSize();
  199. }
  200. /**
  201. * LobbyListener for handling incoming packets
  202. * @author Joel Garboden
  203. */
  204. public class LobbyListener extends Thread
  205. {
  206. boolean listen = true;
  207. /**
  208. * Attempts to halt the listening thread as quickly as possible
  209. */
  210. public void stopNow()
  211. {
  212. try
  213. {
  214. listen = false;
  215. this.finalize();
  216. this.interrupt();
  217. }
  218. catch (Throwable ex)
  219. {
  220. Logger.getLogger(LobbyListener.class.getName()).log(Level.SEVERE, "LobbyListener", ex);
  221. }
  222. }
  223. /**
  224. * Continually listens on incoming network stream and <br/>
  225. * drops packets to queue for processing
  226. */
  227. @Override
  228. public void run()
  229. {
  230. try
  231. {
  232. while (listen)
  233. {
  234. server.postLogMsg("Trying to take from lobbyQ");
  235. Request req = (Request) lobbyQ.take();
  236. server.postLogMsg("Received: " + req.toString());
  237. req.lobbyRequest(lobbyAccessor);
  238. }
  239. }
  240. catch (InterruptedException ex)
  241. {
  242. Logger.getLogger(LobbyListener.class.getName()).log(Level.SEVERE, null, ex);
  243. }
  244. }
  245. }
  246. }