예제 #1
0
		private static async void Handshake(Connection connection)
		{
			string line = await connection.reader.ReadLineAsync();
			string[] tokens = line.Split(' ');
			if (tokens[0] == "Bomberman")
			{
				string response;
				lock(clientsPlaying){
					response = "ACK " + clientsPlaying.Count;
					connection.position = GameLogic.GetStartPosition(clientsPlaying.Count.ToString());
					clientsPlaying.Add(connection);
					clientsAll.Add(connection);
					connection.playerNumber = clientsPlaying.Count;
				}
				Send(response, connection);
				if (tokens[1] == true.ToString()) // client need updates
				{
					lock (clientUpdate) clientUpdate.Add(connection);
					SendPlayground(connection);
				}
				if (tokens[2] == false.ToString()) // client is AI
				{
					lock (clientAI) clientAI.Add(connection);
					SendAll("Update " + connection.playerNumber + " AI");
				}
				else // client is user
				{
					lock (clientPlayers) clientPlayers.Add(connection);
					SendAll("Update " + connection.playerNumber + " Alive");
				}
				if (clientsPlaying.Count == 4) SendInitUpdate();
				StartListening(connection);
			}
		}
예제 #2
0
		private static void AcceptTcpClient(IAsyncResult ar)
		{
			try
			{
				allDone.Set();
				TcpListener listener = (TcpListener)ar.AsyncState;
				TcpClient client = listener.EndAcceptTcpClient(ar);
				Connection connection = new Connection(client);
				Handshake(connection);
			}
			catch (ObjectDisposedException) // server has been stopped
			{
				return;
			}
		}
예제 #3
0
		private static void Clean(Connection connection)
		{
			try
			{
				clientsPlaying.Remove(connection);
				clientAI.Remove(connection);
			}
			catch (ArgumentOutOfRangeException) // Called in middle of stopping server
			{
				return;
			} 
			for (int i = 0; i < futureMoves.Count; i++)
			{
				FutureMove tmp = futureMoves.Dequeue();
				if (tmp.connection != connection) futureMoves.Enqueue(tmp);
			}
			Program.playground.board[connection.position.X][connection.position.Y] = Square.Empty;
			GameLogic.changes.Add(new Change(new Point(connection.position.X, connection.position.Y), Square.Empty));
			lock (futureMoves)
			{
				if (futureMoves.Count == clientsPlaying.Count * 2) ProcessMoves();
			}
		}
예제 #4
0
		private static void Send(string msg, Connection connection)
		{
			try
			{
				connection.writer.WriteLine(msg);
			}
			catch (System.IO.IOException) // client disconected
			{
				clientUpdate.Remove(connection);
				Clean(connection);
				SendUpdate("Update " + connection.playerNumber + " Disconected");
				connection.client.Close();
				lock (futureMoves)
				{
					if (futureMoves.Count == clientsPlaying.Count * 2) ProcessMoves();
				}
				return;
			}
			catch (ObjectDisposedException) // Called in middle of stopping server
			{
				return;
			}
		}
예제 #5
0
		private static void AddMoves(string[] moves, Connection connection)
		{
			if (!clientsPlaying.Contains(connection)) return; // check if sender is regular client
			lock (futureMoves)
			{
				if (futureMoves.Count == 0)
				{
					for (int i = 0; i < clientAI.Count; i++)
					{
						Send("SendMoves", clientAI[i]);
					}
				}
				Movement movement = (Movement)int.Parse(moves[1]);
				futureMoves.Enqueue(new FutureMove(movement, connection));
				movement = (Movement)int.Parse(moves[2]);
				futureMoves.Enqueue(new FutureMove(movement, connection));
				lock (futureMoves)
				{
					if (futureMoves.Count == clientsPlaying.Count * 2) ProcessMoves();
				}
			}
		}
예제 #6
0
		private static void ProcessCommand(string command, Connection connection)
		{
			string[] tokens = command.Split(' ');
			switch (tokens[0])
			{
				case "Move":
					AddMoves(tokens, connection);
					break;
				default:
					break;
			}
		}
예제 #7
0
		private static async void StartListening(Connection connection)
		{
			string line;
			try
			{
				while (connection.client.Connected)
				{
					line = await connection.reader.ReadLineAsync();
					ProcessCommand(line, connection);
				}
			}
			catch (System.IO.IOException) // connection with client has been lost
			{
				clientUpdate.Remove(connection);
				Clean(connection);
				SendUpdate("Update " + connection.playerNumber + " Disconected");
				connection.client.Close();
				lock (futureMoves)
				{
					if (futureMoves.Count == clientsPlaying.Count * 2) ProcessMoves();
				}
			}
			catch (NullReferenceException) // client quit game
			{
				clientUpdate.Remove(connection);
				Clean(connection);
				SendUpdate("Update " + connection.playerNumber + " Quit");
				connection.client.Close();
			}
		}
예제 #8
0
		/// <summary>
		/// Send to coresponding client to connection changes on playground
		/// </summary>
		/// <param name="connection">Receiver connection</param>
		private static void SendChanges(Connection connection)
		{
			StringBuilder message = new StringBuilder("Change " + GameLogic.changes.Count + " ");
			for (int i = 0; i < GameLogic.changes.Count; i++)
			{
				Change change = GameLogic.changes[i];
				message.Append(change.coordinate.X + " " + change.coordinate.Y + " " + (int)change.square + " ");
			}
			Send(message.ToString(), connection);
		}
예제 #9
0
		/// <summary>
		/// Send to coresponding client to connection whole playground
		/// </summary>
		/// <param name="connection">Receiver connection</param>
		private static void SendPlayground(Connection connection)
		{
			StringBuilder message = new StringBuilder("Playground " + Playground.playgroundSize + " ");
			for (int i = 0; i < Playground.playgroundSize; i++)
			{
				for (int j = 0; j < Playground.playgroundSize; j++)
				{
					message.Append((int)Program.playground.board[i][j] + " ");
				}
			}
			string data = message.ToString();
			Send(data, connection);
		}