Exemplo n.º 1
0
		/// <summary>
		/// gets data from the TCPClient passed and does a command based on the given data. This command could result in information being passed to other TCPClient objects, for instance if we've recieved information about an aircraft's state that needs to be propogated.
		/// </summary>
		/// <param name="tag">The GUID of the player to perform commands on</param>
		/// <param name="client">The player's TcpClient object</param>
		private void performCMDRCV(String tag, TcpClient client) {
			if (!CSCommon.isLiveConnection(client))
				return;
			MemoryStream stream = CSCommon.getData(client);
			if (stream == null)
				return;

			BinaryReader rcvData = new BinaryReader(stream);
			//rcvData is the list of serverCommands.
			sbyte c = 0;
			long start = 0L;
			byte command = 0;
			try {
				while (rcvData.BaseStream.Length > rcvData.BaseStream.Position) {
					start = rcvData.BaseStream.Position;
					c = rcvData.ReadSByte();
					if (c > 4)
						return;
					if (c == 1) {
						command = rcvData.ReadByte();

						switch (command) {
							case CSCommon.cmd_test:
								int testAmount = recordWin("6SRKJ695G", "ABCDEFGHI");
								CSCommon.sendData(client, CSCommon.buildCMDString(CSCommon.cmd_newval, testAmount));
								break;

							case CSCommon.cmd_createBot:
								//The player who creates the bot will spawn a thread to control them.
								createBot(tag, ObjectType.aircraft);
								break;

							case CSCommon.cmd_removeBot:
								String rBotId = removeBot(0);
								if (rBotId == null)
									break;
								sendMessage(rBotId + " has been dropped from the server", null);
								propogate(CSCommon.buildCMDString(CSCommon.cmd_forceDisconnect, rBotId), null);
								break;

							case CSCommon.cmd_whois:
								using (BinaryWriter whoWriter = new BinaryWriter(new MemoryStream())) {
									whoWriter.Write((short)clientList.Count);
									foreach (Player p in clientList.Values) {
										whoWriter.Write(p.tag);
										whoWriter.Write(p.name + ((p.admin) ? " (GM)" : ""));
									}
									CSCommon.sendResponse(client, whoWriter);
								} //using
								break;

							case CSCommon.cmd_requestStartGame:
								if (type == GameType.oneOnOne && clientList.Count == 2)
									gameStarted = true;
								if (type == GameType.teamDeath) {
									if (getNumberOfTeams() >= 2)
										gameStarted = true;
								} //if team death
								CSCommon.sendResponse(client, gameStarted);
								if (gameStarted) {
									propogate(CSCommon.buildCMDString(CSCommon.cmd_startGame), client);
								}
								break;

							case CSCommon.cmd_updatePoints:
								Player winner = getPlayerByID(rcvData.ReadString());
								if (winner == null) //winner logged off; kill doesn't count!
									break;
								//The client sending this command is the loser.
								int amount = recordWin(winner.tag, tag);
								CSCommon.sendData(winner.client, CSCommon.buildCMDString(CSCommon.cmd_newval, amount));
								break;

							case CSCommon.cmd_startGame:
								//Send cmd_startGame to all clients so they can
								//signal start locally.
								propogate(CSCommon.buildCMDString(CSCommon.cmd_startGame), client);
								break;

							case CSCommon.cmd_chat:
								bool isPrivate = rcvData.ReadBoolean();
								String chatMsg = null;
								if (isPrivate) {
									String recipient = rcvData.ReadString();
									chatMsg = clientList[tag].name + " (private): " + rcvData.ReadString();
									sendPrivateChatMessage(recipient, chatMsg);
								} else {
									chatMsg = rcvData.ReadString();
									sendChatMessage(tag, chatMsg, MessageType.normal);
								}
								break;

							case CSCommon.cmd_serverMessage:
								sendMessage(rcvData.ReadString(), client);
								break;

							case CSCommon.cmd_disconnectMe:
								String name = clientList[tag].name;
								removeFromGame(tag, true, DisconnectMethod.midGame);
								sendMessage(name + " has left the game.", null);
								return; //no need to process things further.

							case CSCommon.cmd_deleteFromGame: //silent exit
								removeFromGame(tag, true, DisconnectMethod.gameEnded); //delete will only be sent on successful game end
								return; //no need to process data further.
						} //switch
					} //if explicit command
					else {
						byte[] buffer = new byte[rcvData.ReadInt32()];
						string id = rcvData.ReadString();
						bool updateBot = false;
						int botIndex = 0;
						if (c == 3) {
							if ((botIndex = getBot(id)) > -1) {
								rcvData.ReadInt16(); //passed numArgs
								while (rcvData.ReadSByte() != 1) ;
								if (rcvData.ReadInt32() > 0)
									updateBot = true;
								else
									removeBot(botIndex);
							} //if bot exists
						} //if this is a bot update
						rcvData.BaseStream.Position = start;
						rcvData.BaseStream.Read(buffer, 0, buffer.Length);
						if (updateBot)
							bots[botIndex].data = buffer;
						propogate(buffer, client);
					} //if something else besides cmd_command.
				} //foreach serverCommand
			} catch (Exception e) {
				output("Error while reading data from " + tag + ". Char = " + c + Environment.NewLine + "Last command: " + command + Environment.NewLine + "Stack trace: " + e.Message + e.StackTrace);
			} //catch
		}