/// <summary> /// Send a message to all clients connected to a particular game. /// </summary> /// <param name="game">GameRep to pull clients from</param> /// <param name="s">String to broadcast</param> private void BroadcastToGame(GameRep game, String s) { lock (clients) { lock (outputbox) { OutputToForm("\tBroadcasting to game " + game.id.ToString() + ":\r\n\t"); OutputToForm(s); } foreach (TcpClient client in game.GetClientList()) { this.WriteLine(client, s); } } }
/// <summary> /// Disambiguate a recieved command and perform desired operation. /// </summary> /// <param name="cmd">The command string to process</param> /// <returns>The response to be sent back to the client</returns> private String InterpretCommand(String cmd, TcpClient sender) { lock (outputbox) { this.OutputToForm(GetIPAddressOf(sender) + "\r\n$ " + cmd); String[] args = cmd.Trim().Split(' '); String op = args[0]; if (op.Equals(CMD_FETCH)) { this.PurgeDeadGames(); int active_count = 0; foreach (GameRep game in games) { active_count += game.started ? 0 : 1; } if (active_count == 0) { this.OutputToForm("Responded with RESPONSE_FAIL"); return(RESPONSE_FAIL); } String ToSend = ""; foreach (GameRep game in games) { if (!game.started) { ToSend += (game.ToString() + ";"); } } this.OutputToForm("Responded with:"); this.OutputToForm("RESPONSE_SUCCESS " + ToSend); return(RESPONSE_SUCCESS + " " + ToSend); } else if (op.Equals(CMD_GET_GAME_NAME_BY_ID)) { int id; try { id = Int32.Parse(args[1]); } catch (Exception) { OutputToForm("Syntax error: cannot parse game id"); return(RESPONSE_SYNTAX_ERROR); } lock (games) { OutputToForm("Locked resources: Searching for game: " + id.ToString()); foreach (GameRep game in games) { if (game.id == id) { OutputToForm("Found game: " + game.name); return(RESPONSE_SUCCESS + " " + game.name); } } OutputToForm("Failed to find game: " + id.ToString()); return(RESPONSE_FAIL); } } else if (op.Equals(CMD_GET_GAME_POP_BY_ID)) { int id; try { id = Int32.Parse(args[1]); } catch (Exception) { OutputToForm("Syntax error: cannot parse game id"); return(RESPONSE_SYNTAX_ERROR); } lock (games) { OutputToForm("Locked resources: Searching for population of game: " + id.ToString()); foreach (GameRep game in games) { if (game.id == id) { OutputToForm("Found game: " + game.name + ", pop: " + game.population.ToString()); return(RESPONSE_SUCCESS + " " + game.population.ToString()); } } OutputToForm("Failed to find game: " + id.ToString()); return(RESPONSE_FAIL); } } else if (op.Equals(CMD_HOST_NEW_GAME)) { String new_game_name; int key; try { new_game_name = args[1]; key = Int32.Parse(args[2]); } catch (Exception) { OutputToForm("Syntax Error: Failed to parse name and key"); return(RESPONSE_SYNTAX_ERROR); } lock (games) { OutputToForm("Resources Locked: Checking for game: " + new_game_name); foreach (GameRep game in games) { if (game.name.Equals(new_game_name) || game.name.Trim().Equals("")) { OutputToForm("Found duplicate game, Responding with RESPONSE_FAIL"); return(RESPONSE_FAIL); } } OutputToForm("Constructing New Game: " + new_game_name + " with key: " + key.ToString()); GameRep newGame = new GameRep(new_game_name, key); newGame.SetHost(sender); games.Add(newGame); return(RESPONSE_SUCCESS + " " + newGame.id.ToString()); } } else if (op.Equals(CMD_JOIN_GAME_BY_ID)) { int id, key; try { id = Int32.Parse(args[1]); key = Int32.Parse(args[2]); } catch { OutputToForm("Syntax Error: Failed to parse id"); return(RESPONSE_SYNTAX_ERROR); } lock (games) { OutputToForm("Resources Locked: Searching for game: " + id.ToString()); foreach (GameRep game in games) { if (game.id == id && !game.started) { OutputToForm("Found requested game, linking"); game.AddClient(key, sender); this.WriteLine(game.GetHost(), UPDATE_PLAYER_JOINED); return(RESPONSE_SUCCESS + " " + game.population.ToString()); } } } OutputToForm("Could not find requested game, responding with RESPONSE_FAIL"); return(RESPONSE_FAIL); } else if (op.Equals(NOTIFY_CARD_DRAW)) { int id, key; String cardrep; try { id = Int32.Parse(args[1]); key = Int32.Parse(args[2]); cardrep = args[3]; } catch { OutputToForm("Syntax Error: Failed to parse command"); return(RESPONSE_SYNTAX_ERROR); } foreach (GameRep game in games) { if (game.id == id) { int?player_index = game.GetIndexOfClient(sender); if (player_index == null) { OutputToForm("Failed to find player " + key.ToString()); return(RESPONSE_FAIL); } else { BroadcastToGame(game, UPDATE_PLAYER_DRAW + " " + player_index.ToString() + " " + cardrep); return(RESPONSE_SUCCESS); } } } OutputToForm("Failed to find game " + id.ToString()); return(RESPONSE_FAIL); } else if (op.Equals(NOTIFY_DEALER_DRAW)) { int id; String cardString; try { id = Int32.Parse(args[1]); cardString = args[2]; } catch { OutputToForm("Syntax Error: Failed to parse command"); return(RESPONSE_SYNTAX_ERROR); } foreach (GameRep game in games) { if (game.id == id) { BroadcastToGame(game, UPDATE_DEALER_DRAW + " " + cardString); return(RESPONSE_SUCCESS); } } return(RESPONSE_FAIL); } else if (op.Equals(NOTIFY_DEALER_SETUP_FINISH)) { int id; try { id = Int32.Parse(args[1]); } catch { OutputToForm("Syntax Error: Failed to parse command"); return(RESPONSE_SYNTAX_ERROR); } foreach (GameRep game in games) { if (game.id == id) { game.turn_index = 0; this.WriteLine(game.GetClientList()[game.turn_index], UPDATE_YOUR_TURN); return(RESPONSE_SUCCESS); } } return(RESPONSE_FAIL); } else if (op.Equals(NOTIFY_DEALER_STAND)) { int id; try { id = Int32.Parse(args[1]); } catch { OutputToForm("Syntax Error: Failed to parse command"); return(RESPONSE_SYNTAX_ERROR); } foreach (GameRep game in games) { if (game.id == id) { this.BroadcastToGame(game, UPDATE_DEALER_STAND); return(RESPONSE_SUCCESS); } } return(RESPONSE_FAIL); } else if (op.Equals(NOTIFY_INIT)) { int id; try { id = Int32.Parse(args[1]); } catch { OutputToForm("Syntax Error: Failed to parse command"); return(RESPONSE_SYNTAX_ERROR); } foreach (GameRep game in games) { if (game.id == id) { game.waiting--; if (game.waiting == 0) { this.WriteLine(game.GetClientList()[0], UPDATE_YOUR_SETUP); } return(RESPONSE_SUCCESS); } } return(RESPONSE_FAIL); } else if (op.Equals(NOTIFY_SETUP_FINISH)) { int id; try { id = Int32.Parse(args[1]); } catch { OutputToForm("Syntax Error: Failed to parse command"); return(RESPONSE_SYNTAX_ERROR); } foreach (GameRep game in games) { if (game.id == id) { int?player_index = game.GetIndexOfClient(sender); if (player_index == null) { OutputToForm("Failed to find player at " + sender.Client.RemoteEndPoint.ToString()); return(RESPONSE_FAIL); } else { game.turn_index++; OutputToForm("Passing setup turn to player index: " + game.turn_index.ToString()); try { this.WriteLine(game.GetClientList()[game.turn_index], UPDATE_YOUR_SETUP); } catch { this.WriteLine(game.GetClientList()[0], UPDATE_DEALER_SETUP); } return(RESPONSE_SUCCESS); } } } OutputToForm("Failed to find game: " + id.ToString()); return(RESPONSE_FAIL); } else if (op.Equals(NOTIFY_STAND)) { int id, key; try { id = Int32.Parse(args[1]); key = Int32.Parse(args[2]); } catch { OutputToForm("Syntax Error: Failed to parse command"); return(RESPONSE_SYNTAX_ERROR); } foreach (GameRep game in games) { if (game.id == id) { OutputToForm("Found game: " + id + ": checking turn"); int?player_index = game.GetIndexOfClient(sender); if (player_index == null) { OutputToForm("Failed to find player " + key.ToString()); return(RESPONSE_FAIL); } else { BroadcastToGame(game, UPDATE_PLAYER_STAND + " " + player_index.ToString()); game.turn_index++; try { this.WriteLine(game.GetClientList()[game.turn_index], UPDATE_YOUR_TURN); OutputToForm("Passing turn to player: " + game.turn_index); } catch { OutputToForm("Passing turn to dealer"); this.WriteLine(sender, UPDATE_DEALER_TURN); } return(RESPONSE_SUCCESS); } } } OutputToForm("Failed to find game " + id.ToString()); return(RESPONSE_FAIL); } else if (op.Equals(CMD_REMOVE_GAME_BY_ID)) { int id, key; try { id = Int32.Parse(args[1]); key = Int32.Parse(args[2]); } catch (Exception) { OutputToForm("Syntax Error: Failed to parse id and key"); return(RESPONSE_SYNTAX_ERROR); } lock (games) { OutputToForm("Locked Resources: Searching for game: " + id.ToString()); for (int i = 0; i < games.Count; i++) { GameRep game = (GameRep)games[i]; if (game.id == id && game.key == key) { OutputToForm("Found game: " + id.ToString() + ", removing..."); games.RemoveAt(i); this.BroadcastToGame(game, UPDATE_GAME_CONNECTION_BROKEN); return(RESPONSE_SUCCESS); } } } OutputToForm("Failed to remove game: Game " + id.ToString() + " doesn't exist or key does not match"); return(RESPONSE_FAIL); } else if (op.Equals(CMD_REMOVE_PLAYER_FROM_GAME)) { int id, key; try { id = Int32.Parse(args[1]); key = Int32.Parse(args[2]); } catch (Exception) { OutputToForm("Syntax Error: Failed to parse id and key"); return(RESPONSE_SYNTAX_ERROR); } lock (games) { OutputToForm("Locked Resources: Searching for game: " + id); foreach (GameRep game in games) { if (game.id == id) { OutputToForm("Found game " + id); if (game.ContainsClientByKey(key)) { OutputToForm("Removing client with key: " + key); int?index = game.RemoveClient(game.client_dict[key]); this.BroadcastToGame(game, UPDATE_PLAYER_CONNECTION_BROKEN + " " + index.ToString()); return(RESPONSE_SUCCESS); } else { OutputToForm("Client" + key + " not found in game dict"); return(RESPONSE_FAIL); } } } OutputToForm("Failed to find game, responded with RESPONSE_FAIL"); return(RESPONSE_FAIL); } } else if (op.Equals(CMD_START_GAME_BY_ID)) { int id, key; try { id = Int32.Parse(args[1]); key = Int32.Parse(args[2]); } catch (Exception) { OutputToForm("Syntax Error: Failed to parse id and key"); return(RESPONSE_SYNTAX_ERROR); } lock (games) { OutputToForm("Resource Locked: Searching for game: " + id.ToString()); GameRep gameToStart = null; foreach (GameRep game in games) { if (game.id.Equals(id)) { game.started = true; game.waiting = game.population; OutputToForm("Updating clients with player index"); foreach (TcpClient cli in game.GetClientList()) { if (cli != sender) { this.WriteLine(cli, UPDATE_GAME_HAS_STARTED + " " + game.GetIndexOfClient(cli)); } } return(UPDATE_GAME_HAS_STARTED + " " + game.GetIndexOfClient(sender).ToString()); } } return(RESPONSE_FAIL); } } else { OutputToForm("Unrecognized command, responding with RESPONSE_UNRECOGNIZED_CMD"); return(RESPONSE_UNRECOGNIZED_CMD); } } }