/// <summary> /// Send setup messages to the newly connected client. /// Tell the client they are in the lobby, /// who is in the lobby, /// and what tables are up. /// Finally, start the listening thread for the client. /// </summary> /// <param name="client"></param> public void sendConnectionMsg(GameClient client) { /** We should be locked from start listening */ //if the client is not in the client data structure yet, add it. if (!clients.Contains(client.getUserName())) { clients.Add(client.getUserName(), client); } //first join the lobby. client.joinLobby(); //get everyone else in the lobby. string lobbyList = ""; foreach (object o in clients.Values) { GameClient gc = (GameClient)o; if (gc.inLobby()) { lobbyList += gc.getUserName() + " "; } } client.sendMessage(Message.WHO_IN_LOBBY + " " + lobbyList); //get all the tables. string tids = ""; foreach (int i in tables.Keys) { tids += i.ToString() + " "; } client.sendMessage(Message.TBL_LIST + " " + tids.Trim()); //tell everyone this client joined the lobby. this.alertJoinLobby(client); //finally, start the listening thread for the game client to hear incoming requests. client.Start(); }
private void addObserver(GameClient c, string tableId) { //if (c.isLoggedIn()) { int tid; try { tid = int.Parse(tableId); } catch (Exception) { c.sendMessage(Message.BAD_MESSAGE); return; } if (tables.ContainsKey(tid)) { GameTable t = tables[tid]; //c.leaveLobby(); //alertLeaveLobby(c); c.observeTable(tid); //give the player the latest update about the table its about to observe. sayWhoOnTbl(c, tid); t.addObserver(c); } else { c.sendMessage(Message.TBL_NOT_EXIST); } //} c.sendMessage(Message.LOGIN_FAIL); }
/**part 4 methods * These require the support of the DBConnection class * **/ private void registerClient(GameClient c, string pwd) { if (Program.CUR_PHASE == Program.Phase.FULL) { if (DBConnection.addUser(c.getUserName(), pwd) > 0) { c.sendMessage(Message.REGISTER_OK); } else { c.sendMessage(Message.ALREADY_REGISTERED); } } }
private void loginClient(GameClient c, string pwd) { if (Program.CUR_PHASE == Program.Phase.FULL) { if (DBConnection.login(c.getUserName(), pwd)) { c.setLogin(); c.sendMessage(Message.LOGIN_OK); } else { c.sendMessage(Message.LOGIN_FAIL); } } }
/// <summary> /// Removes a player from the table /// </summary> /// <param name="c">the player instance to remove</param> public void nowLeaving(GameClient c) { if (black != null && black.Equals(c)) { black = null; if (red != null) { red.sendMessage(Message.OPP_LEFT_TABLE.ToString()); } seatsOpen++; } else if (red != null && red.Equals(c)) { red = null; if (black != null) { black.sendMessage(Message.OPP_LEFT_TABLE.ToString()); } seatsOpen++; } if (curGame != null) { //if a game was instanciated, tell the game a player quit. //This will make the game close properly. curGame.tsPlayerLeft(c); } }
private void updateProfile(GameClient c, string profile) { if (Program.CUR_PHASE == Program.Phase.FULL) { if (c.isLoggedIn()) { if (DBConnection.updateProfile(c.getUserName(), profile) > 0) { c.sendMessage(Message.PROFILE_UPDATED); } } else { c.sendMessage(Message.LOGIN_FAIL); } } }
private void getProfile(GameClient c, string user) { if (Program.CUR_PHASE == Program.Phase.FULL) { if (c.isLoggedIn()) { string[] profile = DBConnection.getProfile(user); if (profile != null) { c.sendMessage(Message.USER_PROFILE.ToString() + " " + profile[0] + " " + profile[1] + " " + profile[2] + " " + profile[3]); } } else { c.sendMessage(Message.LOGIN_FAIL); } } }
//observers.. public void addObserver(GameClient c) { if(!observers.ContainsKey(c.getUserName())){ this.observers.Add(c.getUserName(), c); } if (curGame != null) { c.sendMessage(Message.BOARD_STATE + " " +this.tid.ToString()+" "+ curGame.getBoardState()); } }
//observers.. public void addObserver(GameClient c) { if (!observers.ContainsKey(c.getUserName())) { this.observers.Add(c.getUserName(), c); } if (curGame != null) { c.sendMessage(Message.BOARD_STATE + " " + this.tid.ToString() + " " + curGame.getBoardState()); } }
public void clientReady(GameClient c) { if (curGame != null) { curGame.tsAlertReady(c); } else { c.sendMessage(Message.GAME_NOT_CREATED); } }
private void sayWhoOnTbl(GameClient client, int tid) { GameTable tbl; try { tbl = tables[tid]; } catch (Exception) { client.sendMessage(Message.TBL_NOT_EXIST); return; } if (tbl != null) { //the clients <2> <3> are on table with tid <1>. <2> is black. <3> is red. If either is -1, the seat is open. GameClient[] players = tbl.getPlayers(); //red = 0, black = 1. string rp = players[0] == null ? "-1" : players[0].getUserName(); string bp = players[1] == null ? "-1" : players[1].getUserName(); client.sendMessage(Message.WHO_ON_TBL.ToString() + " " + tbl.getTid() + " " + bp + " " + rp); } }
private void sendMsg(string fromUser, string toUser, string msg) { foreach (object o in clients.Values) { GameClient gc = (GameClient)o; if (gc.getUserName().Equals(toUser)) { gc.sendMessage(Message.MSG + " " + fromUser + " 1 " + msg); return; } } }
//verify the client can join the table - see if tid has open seat private void joinTable(GameClient c, int tid) { if (c.isLoggedIn()) { if (tables.Count > 0) { foreach (int i in tables.Keys) { if (i == tid) { GameTable t = tables[i]; if (t.joinTable(c)) { putOnTable(c, tid); if (!t.hasOpenSeat()) { t.createGame(); } } else { //we couldnt join the table. It must be full. c.sendMessage(Message.TBL_FULL.ToString()); } return; } } //else we iterated over all the tables, and couldnt find the id. c.sendMessage(Message.TBL_NOT_EXIST.ToString()); } else { c.sendMessage(Message.TBL_NOT_EXIST.ToString()); } } else { c.sendMessage(Message.LOGIN_FAIL); } }
private void stopObserving(GameClient c, string tableId, bool disconnecting) { int tid; try { tid = int.Parse(tableId); } catch (Exception) { c.sendMessage(Message.BAD_MESSAGE); return; } if (tables.ContainsKey(tid)) { GameTable t = tables[tid]; t.removeObserver(c); c.stopObserving(tid); //c.joinLobby(); //if (!disconnecting) // alertJoinLobby(c); } else { c.sendMessage(Message.TBL_NOT_EXIST); } }
/** * All clients will be constantly updated about the status of the lobby, regardless of whether they are in * the game or not. */ ///<summary> ejects the game client passed from its table.</summary> private void leaveTable(GameClient c) { //find the table they are in and tell them the client is leaving. foreach (GameTable tbl in tables.Values) { GameClient[] players = tbl.getPlayers(); if ((players[0] != null && c.getUserName().Equals(players[0].getUserName())) || (players[1] != null && c.getUserName().Equals(players[1].getUserName()))) { putOffTable(c, tbl, false); return; } } //else cant find the player in any table. c.sendMessage(Message.TBL_NOT_EXIST); }
/// <summary> /// Tells the game a client is ready. If both are ready, this /// method also starts the game and tells black to move. /// </summary> /// <param name="c">The GameClient instance that is ready</param> public void tsAlertReady(GameClient c) { if (red.Equals(c)) { redRdy = true; } if (black.Equals(c)) { blackRdy = true; } if (redRdy && blackRdy) { resetBoard(); //reset the board red.sendMessage(Message.COLOR_RED); red.sendMessage(Message.GAME_START.ToString()); black.sendMessage(Message.COLOR_BLACK); black.sendMessage(Message.GAME_START.ToString()); black.sendMessage(Message.YOUR_TURN.ToString()); } }
private void broadcastMsg(string fromUser, string msg) { foreach (object o in clients.Values) { GameClient gc = (GameClient)o; if (gc.inLobby()) { if (gc.isConnected()) { gc.sendMessage(Message.MSG + " " + fromUser + " 0 " + msg); } else { dcList.Add(gc); } } } clearClosedClients(); }
public void alertLeaveLobby(GameClient c) { //we have to be locked from an above method foreach (object o in clients.Values) { GameClient gc = (GameClient)o; if (!gc.Equals(c)) { if (gc.isConnected()) { gc.sendMessage(Message.NOW_LEFT_LOBBY + " " + c.getUserName()); } else { dcList.Add(gc); } } } clearClosedClients(); }
private void createTable(GameClient client) { if (client.isLoggedIn()) { Random r = new Random(); while (true) { int tid = r.Next(1001, 5000); bool exists = false; if (tables.Count == 0) { tables.Add(tid, new GameTable(tid)); alertNewTable(tid); joinTable(client, tid); return; } else { foreach (int i in tables.Keys) { if (i == tid) { exists = true; break; } } if (!exists) { tables.Add(tid, new GameTable(tid)); alertNewTable(tid); joinTable(client, tid); return; } } } } else { client.sendMessage(Message.LOGIN_FAIL); } }
/// <summary> /// Broadcast to everyone a new table was created. /// </summary> /// <param name="tid"></param> public void alertNewTable(int tid) { //we have to be locked from an above method if (tables.ContainsKey(tid)) { //tell everyone a new table was created. foreach (object o in clients.Values) { GameClient gc = (GameClient)o; if (gc.isConnected()) { gc.sendMessage(Message.NEW_TBL + " " + tid.ToString()); } else { dcList.Add(gc); } } clearClosedClients(); } }
//a game client sent a move. We need to send this move to the chceckers game instance. private void sendMove(GameClient c, string from, string to) { try { int x = int.Parse(from.Substring(0, 1)); x = int.Parse(from.Substring(2, 1)); x = int.Parse(to.Substring(0, 1)); x = int.Parse(to.Substring(2, 1)); } catch (Exception) { c.sendMessage(Message.BAD_MESSAGE); return; } foreach (GameTable tbl in tables.Values) { GameClient[] players = tbl.getPlayers(); if ((players[0] != null && c.getUserName().Equals(players[0].getUserName())) || (players[1] != null && c.getUserName().Equals(players[1].getUserName()))) { tbl.sendMove(c, from, to); return; } } }
private void stopObserving(GameClient c, string tableId, bool disconnecting) { int tid; try { tid = int.Parse(tableId); } catch (Exception) { c.sendMessage(Message.BAD_MESSAGE); return; } if (tables.ContainsKey(tid)) { GameTable t = tables[tid]; t.removeObserver(c); c.stopObserving(tid); //c.joinLobby(); //if (!disconnecting) // alertJoinLobby(c); } else c.sendMessage(Message.TBL_NOT_EXIST); }
private void addObserver(GameClient c, string tableId) { //if (c.isLoggedIn()) { int tid; try { tid = int.Parse(tableId); } catch (Exception) { c.sendMessage(Message.BAD_MESSAGE); return; } if (tables.ContainsKey(tid)) { GameTable t = tables[tid]; //c.leaveLobby(); //alertLeaveLobby(c); c.observeTable(tid); //give the player the latest update about the table its about to observe. sayWhoOnTbl(c, tid); t.addObserver(c); } else c.sendMessage(Message.TBL_NOT_EXIST); //} c.sendMessage(Message.LOGIN_FAIL); }
/** * All clients will be constantly updated about the status of the lobby, regardless of whether they are in * the game or not. */ ///<summary> ejects the game client passed from its table.</summary> private void leaveTable(GameClient c) { //find the table they are in and tell them the client is leaving. foreach (GameTable tbl in tables.Values) { GameClient[] players = tbl.getPlayers(); if ((players[0]!=null && c.getUserName().Equals(players[0].getUserName())) || (players[1]!=null && c.getUserName().Equals(players[1].getUserName()))) { putOffTable(c, tbl, false); return; } } //else cant find the player in any table. c.sendMessage(Message.TBL_NOT_EXIST); }
/// <summary> /// Process a message receieved from a game client. /// </summary> /// <param name="client">The GameClient instance that sent the message</param> /// <param name="msg">The TCP message code</param> /// <param name="args">A list of the arguments for the message</param> public void processMessage(GameClient client, int msg, List <string> args) { string text = ""; lock (this) { try { switch (msg) { case Message.MSG_ALL: //client sends message <1> to everyone in lobby if (client.inLobby()) { //when we broadcast a message, each word is in the args. foreach (string s in args) { text += s + " "; } } broadcastMsg(client.getUserName(), text); break; case Message.MSG_C: //client sends message <3> to client <1>. for (int i = 1; i < args.Count; i++) { text += args[i] + " "; } sendMsg(client.getUserName(), args[0], text); break; case Message.MAKE_TBL: //client wants to make and sit at a table if (client.inLobby()) { createTable(client); } else { client.sendMessage(Message.NOT_IN_LOBBY.ToString()); } break; case Message.JOIN_TBL: //client wants to join table id <1> if (!client.inLobby()) { client.sendMessage(Message.NOT_IN_LOBBY.ToString()); } else { int p1 = -1; try { p1 = int.Parse(args[0]); } catch (Exception) { client.sendMessage(Message.BAD_MESSAGE.ToString()); return; } joinTable(client, p1); } break; case Message.READY: //client is ready for game to start sendReady(client); break; case Message.MOVE: //client moves from <1> to <2> sendMove(client, args[0].Substring(0, 1) + "," + args[0].Substring(2, 1), args[1].Substring(0, 1) + "," + args[1].Substring(2, 1)); break; case Message.LEAVE_TBL: //client leaves the table if (!client.inLobby()) { leaveTable(client); } else { client.sendMessage(Message.ERR_IN_LOBBY.ToString()); } break; case Message.ASK_TBL_STATUS: //client is asking for the status of table <1> int tid = -1; try { tid = int.Parse(args[0]); } catch (Exception) { client.sendMessage(Message.BAD_MESSAGE.ToString()); return; } sayWhoOnTbl(client, tid); break; /** part 4 new messages **/ case Message.OBSERVE_TBL: // if (client.inLobby()) addObserver(client, args[0]); //else client.sendMessage(Message.NOT_IN_LOBBY); break; case Message.STOP_OBSERVING: if (client.isObserving()) { stopObserving(client, args[0], false); } else { client.sendMessage(Message.NOT_OBSERVING); } break; case Message.REGISTER: registerClient(client, args[0]); break; case Message.LOGIN: loginClient(client, args[0]); break; case Message.UPDATE_PROFILE: text = ""; foreach (string s in args) { text += s + " "; } updateProfile(client, text); break; case Message.GET_PROFILE: getProfile(client, args[0]); break; case Message.QUIT: //client leaves the server alertPlayerDisconnected(client); break; } } catch (Exception) { //the message, or some parameter was bad. client.sendMessage(Message.BAD_MESSAGE); } } }
//verify the client can join the table - see if tid has open seat private void joinTable(GameClient c, int tid) { if (c.isLoggedIn()) { if (tables.Count > 0) { foreach (int i in tables.Keys) { if (i == tid) { GameTable t = tables[i]; if (t.joinTable(c)) { putOnTable(c, tid); if (!t.hasOpenSeat()) { t.createGame(); } } else { //we couldnt join the table. It must be full. c.sendMessage(Message.TBL_FULL.ToString()); } return; } } //else we iterated over all the tables, and couldnt find the id. c.sendMessage(Message.TBL_NOT_EXIST.ToString()); } else c.sendMessage(Message.TBL_NOT_EXIST.ToString()); } else c.sendMessage(Message.LOGIN_FAIL); }
//a game client sent a move. We need to send this move to the chceckers game instance. private void sendMove(GameClient c, string from, string to) { try { int x = int.Parse(from.Substring(0, 1)); x = int.Parse(from.Substring(2, 1)); x = int.Parse(to.Substring(0, 1)); x = int.Parse(to.Substring(2, 1)); } catch (Exception) { c.sendMessage(Message.BAD_MESSAGE); return; } foreach (GameTable tbl in tables.Values) { GameClient[] players = tbl.getPlayers(); if ((players[0]!=null && c.getUserName().Equals(players[0].getUserName())) || (players[1]!=null && c.getUserName().Equals(players[1].getUserName()))) { tbl.sendMove(c, from, to); return; } } }
/// <summary> /// Process a message receieved from a game client. /// </summary> /// <param name="client">The GameClient instance that sent the message</param> /// <param name="msg">The TCP message code</param> /// <param name="args">A list of the arguments for the message</param> public void processMessage(GameClient client, int msg, List<string> args) { string text = ""; lock (this) { try { switch (msg) { case Message.MSG_ALL: //client sends message <1> to everyone in lobby if (client.inLobby()) //when we broadcast a message, each word is in the args. foreach (string s in args) text += s + " "; broadcastMsg(client.getUserName(), text); break; case Message.MSG_C: //client sends message <3> to client <1>. for (int i = 1; i < args.Count; i++) text += args[i] + " "; sendMsg(client.getUserName(), args[0], text); break; case Message.MAKE_TBL: //client wants to make and sit at a table if (client.inLobby()) createTable(client); else client.sendMessage(Message.NOT_IN_LOBBY.ToString()); break; case Message.JOIN_TBL: //client wants to join table id <1> if (!client.inLobby()) client.sendMessage(Message.NOT_IN_LOBBY.ToString()); else { int p1 = -1; try { p1 = int.Parse(args[0]); } catch (Exception) { client.sendMessage(Message.BAD_MESSAGE.ToString()); return; } joinTable(client, p1); } break; case Message.READY: //client is ready for game to start sendReady(client); break; case Message.MOVE: //client moves from <1> to <2> sendMove(client, args[0].Substring(0, 1) + "," + args[0].Substring(2, 1), args[1].Substring(0,1) + "," + args[1].Substring(2, 1)); break; case Message.LEAVE_TBL: //client leaves the table if (!client.inLobby()) leaveTable(client); else client.sendMessage(Message.ERR_IN_LOBBY.ToString()); break; case Message.ASK_TBL_STATUS: //client is asking for the status of table <1> int tid = -1; try { tid = int.Parse(args[0]); } catch (Exception) { client.sendMessage(Message.BAD_MESSAGE.ToString()); return; } sayWhoOnTbl(client, tid); break; /** part 4 new messages **/ case Message.OBSERVE_TBL: // if (client.inLobby()) addObserver(client, args[0]); //else client.sendMessage(Message.NOT_IN_LOBBY); break; case Message.STOP_OBSERVING: if(client.isObserving()) stopObserving(client, args[0], false); else client.sendMessage(Message.NOT_OBSERVING); break; /* case Message.REGISTER: registerClient(client, args[0]); break; case Message.LOGIN: loginClient(client, args[0]); break; case Message.UPDATE_PROFILE: text = ""; foreach (string s in args) text += s + " "; updateProfile(client, text); break; case Message.GET_PROFILE: getProfile(client, args[0]); break;*/ case Message.QUIT: //client leaves the server alertPlayerDisconnected(client); break; } } catch (Exception) { //the message, or some parameter was bad. client.sendMessage(Message.BAD_MESSAGE); } } }
/// <summary> /// Sends the move to the checkers game, where it is validated /// and committed. The players are directly notified by the /// game the results. /// </summary> /// <param name="c">The client making the move</param> /// <param name="from">from position "i,j"</param> /// <param name="to">to position "i,j"</param> public void tsMakeMove(GameClient c, string from, string to) { if (gameStarted()) { if (curTurn == side.black && black.Equals(c) || curTurn == side.red && red.Equals(c)) { if (moveLegal(from, to)) { applyMove(from, to); //tell opponent what the move was if (curTurn == side.black) { red.sendMessage(Message.OPP_MOVE + " " + from + " " + to); } else { black.sendMessage(Message.OPP_MOVE + " " + from + " " + to); } //send the new board state red.sendMessage(Message.BOARD_STATE + " " + this.table.getTid() + " " + encodeState()); black.sendMessage(Message.BOARD_STATE + " " + this.table.getTid() + " " + encodeState()); table.updateObservers(encodeState()); //now check if game is over if (!isGameOver()) { //tell the other player it is their turn if (curTurn == side.black) { red.sendMessage(Message.YOUR_TURN.ToString()); curTurn = side.red; } else { black.sendMessage(Message.YOUR_TURN.ToString()); curTurn = side.black; } } else //else the game is over. { side winner = checkWinner(); if (winner == side.black) { setWinner(black); } else if (winner == side.red) { setWinner(red); } else { //something happened, the game is over, but we couldnt find a winner... //todo... } //make both players not ready. redRdy = false; blackRdy = false; //finally, tell the table the game is over. table.alertGameEnd(); } } //else the move is not legal. else { c.sendMessage(Message.ILLEGAL); } } //else its not this players turn. else { c.sendMessage(Message.NOT_YOUR_TURN); } } //else the game hasnt started yet: some players are not ready. else { c.sendMessage(Message.PLAYERS_NOT_READY); } }
private void createTable(GameClient client) { if (client.isLoggedIn()) { Random r = new Random(); while (true) { int tid = r.Next(1001, 5000); bool exists = false; if (tables.Count == 0) { tables.Add(tid, new GameTable(tid)); alertNewTable(tid); joinTable(client, tid); return; } else { foreach (int i in tables.Keys) { if (i == tid) { exists = true; break; } } if (!exists) { tables.Add(tid, new GameTable(tid)); alertNewTable(tid); joinTable(client, tid); return; } } } } else client.sendMessage(Message.LOGIN_FAIL); }
public void clientReady(GameClient c) { if (curGame != null) { curGame.tsAlertReady(c); } else c.sendMessage(Message.GAME_NOT_CREATED); }
private void sayWhoOnTbl(GameClient client, int tid ) { GameTable tbl; try { tbl = tables[tid]; } catch (Exception) { client.sendMessage(Message.TBL_NOT_EXIST); return; } if (tbl != null) { //the clients <2> <3> are on table with tid <1>. <2> is black. <3> is red. If either is -1, the seat is open. GameClient[] players = tbl.getPlayers(); //red = 0, black = 1. string rp = players[0] == null ? "-1" : players[0].getUserName(); string bp = players[1] == null ? "-1" : players[1].getUserName(); client.sendMessage(Message.WHO_ON_TBL.ToString() + " " + tbl.getTid() + " " + bp + " " + rp); } }