Exemple #1
0
		/// <summary>
		/// Sends the specified string to all clients, excluding the one specified in exclude, using the specified MemoryStream.
		/// </summary>
		/// <param name="data">The MemoryStream containing data to send</param>
		/// <param name="exclude">Null if all clients should get this data</param>
		private void propogate(MemoryStream stream, TcpClient exclude)
		{
			foreach (Player p in clientList.Values) {
				if (p.client != exclude)
					CSCommon.sendData(p.client, stream);
			}
		}
Exemple #2
0
		private void sendCriticalMessage() {
			if (String.IsNullOrEmpty(serverMessage))
				return;
			lock (serverMessage) {
				foreach (Player p in clientList.Values)
					CSCommon.sendData(p.client, CSCommon.buildCMDString(CSCommon.cmd_chat, (byte)MessageType.critical, serverMessage));
				serverMessage = "";
			}
		}
Exemple #3
0
		/// <summary>
		/// Creates a bot.
		/// </summary>
		/// <param name="creator">The tag of the player that will hold the bot's data initially.</param>
		/// <param name="objectType">The type of the bot.</param>
		private void createBot(String creator, ObjectType objectType) {
			String id = getBotID();
			String botName = "Bot " + id;
			String botId = "B-" + id;
			CSCommon.sendData(clientList[creator].client, CSCommon.buildCMDString(CSCommon.cmd_createBot, botId, botName, (byte)objectType));
			//Other players will just see another spawn.
			propogate(CSCommon.buildCMDString(CSCommon.cmd_distributeServerTag, botId, botName, (byte)objectType, (short)0), clientList[creator].client);
			if (objectType == ObjectType.aircraft)
				sendMessage(botName + " has been created.", null);
			bots.Add(new BotInfo(creator, botId, botName, objectType));
			bots.Sort();
		}
Exemple #4
0
		/// <summary>
		/// Pushes the bot to a new player, in the event the previous host was disconnected. The bots list will always be modified after this method runs. Call this method after removing the player.
		/// </summary>
		/// <param name="index">The position in bots to remove.</param>
		private void pushBot(int index) {
			String botID = bots[index].id;
			String botName = bots[index].name;
			ObjectType objectType = bots[index].objectType;
			if (clientList.Count == 0) {
				bots[index].creator = null;
				return;
			}

			String[] ids = clientList.Keys.ToArray();
			Random r = new Random();
			String pid = null; //ID of new host player for bot
			CSCommon.sendData(clientList[pid = ids[r.Next(0, ids.Length)]].client,
				CSCommon.buildCMDString(CSCommon.cmd_createBot, botID, botName, (byte)objectType));
			bots[index].creator = pid;
		}
Exemple #5
0
		/// <summary>
		/// Sends a private message.
		/// </summary>
		/// <param name="target">The recipient of the message</param>
		/// <param name="message">The message to send</param>
		private void sendPrivateChatMessage(String target, String message) {
			Player p = getPlayerByID(target);
			if (p != null)
				CSCommon.sendData(p.client, CSCommon.buildCMDString(CSCommon.cmd_chat, (byte)MessageType.privateMessage, message));
		}
Exemple #6
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
		}
Exemple #7
0
		/// <summary>
		/// This method will add a new player to this game.
		/// </summary>
		/// <param name="tag">The server tag of the player being added</param>
		/// <param name="p">The Player object representing the connection.</param>
		private bool add(String tag, Player p) {
			try {
				//pauseProcessing();
				output("Adding player " + tag + "...");
				lock (lockObject) {
					if (clientList.Count == 0 && type != GameType.freeForAll) //This is first player being added, so this is the host.
						p.host = true;
					//Create local player.
					if (p.entryMode != 1) {
						int maxWeight = 0;
						CSCommon.sendData(p.client, CSCommon.buildCMDString(CSCommon.cmd_position, next++, (short)0));
						CSCommon.sendData(p.client,
						  CSCommon.buildCMDString(CSCommon.cmd_requestCreate, p.name, maxWeight));

						//Give this player's info to all players.
						output("Propogating connection...", true);
						if (type != GameType.teamDeath) {
							propogate(CSCommon.buildCMDString(CSCommon.cmd_distributeServerTag, tag, p.name, (byte)ObjectType.aircraft, (short)0),
							 p.client);
						} else { //if team death
							propogate(CSCommon.buildCMDString(CSCommon.cmd_distributeServerTag, tag, p.name, (byte)ObjectType.aircraft, (int)p.team, (short)0),
					  p.client);
						}
					} //if entryMode != 1

					//Give this player info about all other players.
					output("Sending info about other clients to this client...", true);
					foreach (Player player in clientList.Values) {
						if (player.entryMode == 1)  //spectator
							continue;
						if (type != GameType.teamDeath) {
							CSCommon.sendData(p.client, CSCommon.buildCMDString(CSCommon.cmd_distributeServerTag, player.tag, player.name, (byte)ObjectType.aircraft, (short)0));
						} else { //if team death
							CSCommon.sendData(p.client, CSCommon.buildCMDString(CSCommon.cmd_distributeServerTag, player.tag, player.name, (byte)ObjectType.aircraft,
								(int)player.team, (short)0));
						}
					} //foreach connected player

					foreach (BotInfo info in bots) {
						if (info.creator == null) {
							info.creator = tag;
							CSCommon.sendData(p.client, CSCommon.buildCMDString(CSCommon.cmd_createBot, info.id, info.name, (byte)info.objectType));
							CSCommon.sendData(p.client, new MemoryStream(info.data));
							output("Created bot " + info.id, true);
						} else
							CSCommon.sendData(p.client, CSCommon.buildCMDString(CSCommon.cmd_distributeServerTag, info.id, info.name, (byte)info.objectType,
								(short)0));
					}
					if (type == GameType.freeForAll) {
						output("FFA, Starting local player...", true);
						CSCommon.sendData(p.client, CSCommon.buildCMDString(CSCommon.cmd_startGame));
					} //if FFA
					clientList[tag] = p;
					if (type == GameType.teamDeath)
						incrementTeam(tag, p.team);

					String entMessage = ".";
					if (type == GameType.teamDeath)
						entMessage = " for the " + p.team + " team";
					sendMessage(clientList[tag].name +
						String.Format(" has joined this game{0}",
						(p.entryMode == 1) ? " as a spectator" : entMessage),
					   p.client);
				} //lock
				if (type != GameType.freeForAll && !canEvaluateGameEnd
					&& (type == GameType.teamDeath && getNumberOfTeams() >= 2 || type != GameType.teamDeath))
					canEvaluateGameEnd = true;
				//resumeProcessing();
				return true;
			} catch (Exception e) {
				output(e.Message + Environment.NewLine + e.StackTrace);
			}
			return false;
		}