PageRenderTime 24ms CodeModel.GetById 8ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 1ms

/src/network/Lobby.java

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