private void HandleMessages() { GameMessage message; foreach (KeyValuePair<int, MessageStack<GameMessage>> kvp in _messageStacks) { while (kvp.Value.Pop(out message)) { if (message == null) { } else { if (message.DataType == GameState.DataTypeEntityQuery) { //_infoStack.Push(String.Format("Entity {0} queried, sending info", message.index)); if (entities.Keys.Contains<int>(message.index)) { _infoStack.Push(String.Format("Received query for entity {0}:{1}", message.index, entities[message.index].GetType().ToString())); messages[kvp.Key].Add(entities[message.index].GetSpawnMessage()); } else { _infoStack.Push(String.Format("Received query for entity {0}, does not exist, sending despawn message", message.index)); messages[kvp.Key].Add(GameState.DespawnMessage(message.index)); } } else if (message.DataType == GameState.DataTypeRequest) { switch (message.index) { case GameState.IndexInitialisePlayerShip: InitialisePlayerShip(kvp.Key); _infoStack.Push(String.Format("Initialisation request from client {0}, ship index {1}", kvp.Key, playerInfo[kvp.Key].EntityID)); break; case GameState.IndexRespawnShip: if (ships.Keys.Contains<int>(kvp.Key)) { ships.Remove(kvp.Key); } PlayerShip ship = new PlayerShip(); int clientShipIndex = AddEntity(ship); ship.Place(new Vector2(rand.Next(Game1.width - 100) + 50, Game1.height - 50.0f)); ship.color = shipColors[kvp.Key % 16]; ships.Add(kvp.Key, ship); playerInfo[kvp.Key].EntityID = clientShipIndex; InitialisePlayerShip(kvp.Key); break; } } else if (message.DataType == GameState.DataTypeReassignID) { if (!entities.Keys.Contains<int>(message.index)) return; int newIndex = BitConverter.ToInt32(message.Message, 0); _infoStack.Push(String.Format("Reassigning object {0}:{1} to ID {2}", entities[message.index].GetType().ToString(), message.index, newIndex)); if (!ReassignID(message.index, newIndex)) { int nextIndex = GetNextID(); messages[kvp.Key].Add(ReassignIndexMessage(newIndex, nextIndex)); ReassignID(newIndex, nextIndex); } } else { //_infoStack.Push(String.Format("Entity {0} Update Received, DataType {1}", message.index, message.DataType)); if (message.DataType == GameState.DataTypeSpawnEntity) { _infoStack.Push(String.Format("Spawning entity. index: {0}, typeID: {1}", message.index, BitConverter.ToInt32(message.Message, 16))); if (message.index > idCounter) idCounter = message.index + 1; if (entities.Keys.Contains<int>(message.index)) { int nextID = GetNextID(); messages[kvp.Key].Add(ReassignIndexMessage(message.index, nextID)); message.index = nextID; Spawn(message); } else { HandleEntityUpdates(message, true); } } else { if (message.Message != null) HandleEntityUpdates(message, true); } } } } } }
public void ClientConnect(int clientNumber, GameMessage message) { try { playerInfo.Add(clientNumber, new PlayerInfo(clientNumber)); _messageStacks.Add(clientNumber, new MessageStack<GameMessage>(500)); messages.Add(clientNumber, new List<GameMessage>()); _infoStack.Push(String.Format("Client {0} connected from address {1}", clientNumber, _server.Connections[clientNumber].Socket.RemoteEndPoint)); PlayerShip ship = new PlayerShip(); int clientShipIndex = AddEntity(ship); ship.Place(new Vector2(rand.Next(Game1.width - 100) + 50.0f, Game1.height - 50.0f)); ship.color = shipColors[clientNumber % 16]; ships.Add(clientNumber, ship); foreach (IEntity entity in entities.Values) { if (entity != ship) { messages[clientNumber].Add(entity.GetSpawnMessage()); } } foreach (KeyValuePair<int, List<GameMessage>> kvp in messages) { kvp.Value.Add(ship.GetSpawnMessage()); } GameMessage initMessage = new GameMessage(); initMessage.DataType = GameState.DataTypeMetaInfo; initMessage.index = GameState.IndexInitialisePlayerShip; byte[] arr = new byte[7]; BitConverter.GetBytes(clientShipIndex).CopyTo(arr, 0); arr[4] = shipColors[clientNumber % 16].R; arr[5] = shipColors[clientNumber % 16].G; arr[6] = shipColors[clientNumber % 16].B; initMessage.SetMessage(arr); messages[clientNumber].Add(initMessage); playerInfo[clientNumber].EntityID = clientShipIndex; lastMessage.Add(clientNumber, lastTime); } catch (Exception e) { _errorStack.Push(e.Message); } }