private Message GetNextMessageInCombinedMessage(Message message) { var type = (PacketType)message.Data[combinedMessageStartIndex]; var size = packetSizeLookup[type]; // Dynamic size packet? if (size == 0) { if (type == PacketType.EntityEvents) { // The byte at (combinedMessageStartIndex + 1) represents the length of all events, then we add + 2 for the header to get the total packet size size = message.Data[combinedMessageStartIndex + 1] + 2; } else { throw new NotImplementedException("Implement this type!"); } } var result = new Message { ClientId = message.ClientId, Type = MessageType.Data, Data = new byte[size] }; Array.Copy(message.Data, combinedMessageStartIndex, result.Data, 0, size); combinedMessageStartIndex += size; return result; }
private void ReceivedClientSpatial(Message message) { if (GetEntitySpatialCompleted != null) { var args = new ClientSpatialEventArgs(); // Read the message client.Reader.ReadNewMessage(message); client.Reader.ReadByte(); // Find out how many clients that are included in the message byte clients = client.Reader.ReadByte(); // Initialize and retrieve all client spatial data args.Entity = new EntitySpatial[clients]; for (byte i = 0; i < clients; i++) { var data = new EntitySpatial(); data.Id = client.Reader.ReadUInt16(); data.TimeStamp = client.Reader.ReadTimeStamp(); data.Position = messageHelper.ReadVector3(client.Reader); data.Velocity = messageHelper.ReadVector3(client.Reader); data.Angle = messageHelper.ReadVector3(client.Reader); args.Entity[i] = data; } GetEntitySpatialCompleted(this, args); } }
private void ReceivedEntityEvents(Message message) { var clientId = connectionIds[message.ClientId]; if (!entityHelper.Entities.ContainsKey(clientId)) { return; } // Header server.Reader.ReadNewMessage(message); server.Reader.ReadByte(); // Events int events = server.Reader.ReadByte() / 5; for (int i = 0; i < events; i++) { var entityEvent = new EntityEvent(); entityEvent.TimeStamp = server.Reader.ReadTimeStamp(); entityEvent.Type = (EntityEventType)server.Reader.ReadByte(); entityHelper.AddEvent(clientId, entityEvent); } }
private void ReceivedCombinedMessage(Message message) { var clientId = connectionIds[message.ClientId]; if (!entityHelper.Entities.ContainsKey(clientId)) { return; } combinedMessageStartIndex = 1; while (HasMoreMessagesInCombinedMessage(message)) { server.Messages.Add(GetNextMessageInCombinedMessage(message)); } }
private void ReceivedEntityEvents(Message message) { if (GetEntityEventsCompleted != null) { //System.Diagnostics.Debug.WriteLine(""); //System.Diagnostics.Debug.WriteLine(string.Format("[X] Client received events in message: {0}", messageHelper.BytesToString(message.Data))); var args = new ClientEventsEventArgs(); // Read the message client.Reader.ReadNewMessage(message); client.Reader.ReadByte(); // Get the number of entities in this message ushort entities = client.Reader.ReadUInt16(); //System.Diagnostics.Debug.WriteLine(string.Format("[X] Number of entities: {0}", entities)); for (ushort i = 0; i < entities; i++) { // Get the id of the current entity ushort entityId = client.Reader.ReadUInt16(); // Get the number of events for the current entity byte events = client.Reader.ReadByte(); //System.Diagnostics.Debug.WriteLine(string.Format("[X] ClientId: {0}, Events: {1}", entityId, events)); for (byte j = 0; j < events; j++) { var entityEvent = new EntityEvent(); entityEvent.Id = entityId; entityEvent.TimeStamp = client.Reader.ReadTimeStamp(); entityEvent.Type = (EntityEventType)client.Reader.ReadByte(); args.Events.Add(entityEvent); System.Diagnostics.Debug.WriteLine(string.Format("[X] Client received event: ClientId: {0}, TimeStamp: {1}, Type: {2}", entityEvent.Id, entityEvent.TimeStamp, entityEvent.Type)); } } GetEntityEventsCompleted(this, args); } }
private void ReceivedClientStatus(Message message) { // Read the message client.Reader.ReadNewMessage(message); client.Reader.ReadByte(); ushort clientId = client.Reader.ReadUInt16(); bool connected = client.Reader.ReadBool(); // Add a global message for this event var notificationMessage = new NetworkMessage() { ClientId = clientId, Type = connected ? NetworkMessageType.Connected : NetworkMessageType.Disconnected, Text = string.Format("Player {0} {1}", clientId, connected ? "connected" : "disconnected") }; messageHandler.AddMessage(MessageHandlerType.GameClient, notificationMessage); UpdateServerEntities(clientId, EntityType.Client, connected); }
private void UpdateConnectionsDictionary(NetConnectionStatus status) { if (status == NetConnectionStatus.Connected) { var senderId = messageIn.SenderConnection.RemoteUniqueIdentifier; if (connections.ContainsKey(senderId)) { connections.Remove(senderId); } connections.Add(senderId, messageIn.SenderConnection); // Store the event as a message var message = new Message { ClientId = messageIn.SenderConnection.RemoteUniqueIdentifier, Type = MessageType.Connect, RemoteTimeOffset = messageIn.SenderConnection.RemoteTimeOffset }; Messages.Add(message); Logger.Log<LidgrenServer>(LogLevel.Info, string.Format("Client {0} connected from IP {1}", senderId, messageIn.SenderEndpoint.Address)); } else if (status == NetConnectionStatus.Disconnected) { var senderId = messageIn.SenderConnection.RemoteUniqueIdentifier; if (connections.ContainsKey(senderId)) { connections.Remove(senderId); } // Store the event as a message var message = new Message { ClientId = messageIn.SenderConnection.RemoteUniqueIdentifier, Type = MessageType.Disconnect }; Messages.Add(message); Logger.Log<LidgrenServer>(LogLevel.Info, string.Format("Client {0} disconnected with IP {1}", senderId, messageIn.SenderEndpoint.Address)); } }
private void HandleDataMessage() { var message = new Message(); message.ClientId = messageIn.SenderConnection.RemoteUniqueIdentifier; message.RemoteTimeOffset = messageIn.SenderConnection.RemoteTimeOffset; message.Data = new byte[messageIn.LengthBytes]; messageIn.ReadBytes(message.Data, 0, messageIn.LengthBytes); Messages.Add(message); //Logger.Log<LidgrenServer>(LogLevel.Debug, "Received Data: {0} bytes", message.Data.Length); }
private void ReceivedGameSettings(Message message) { if (GetGameSettingsCompleted != null) { var args = new GameSettingsEventArgs(); // Read the message client.Reader.ReadNewMessage(message); client.Reader.ReadByte(); args.ClientId = client.Reader.ReadUInt16(); args.Seed = client.Reader.ReadInt32(); // Assign the client id ClientId = args.ClientId; // World gravity (skip for now) client.Reader.ReadFloat(); client.Reader.ReadFloat(); client.Reader.ReadFloat(); byte totalClients = client.Reader.ReadByte(); for (int i = 0; i < totalClients; i++) { ushort currentClientId = client.Reader.ReadUInt16(); UpdateServerEntities(currentClientId, EntityType.Client, true); } GetGameSettingsCompleted(this, args); } }
private bool HasMoreMessagesInCombinedMessage(Message message) { return (combinedMessageStartIndex < message.Data.Length); }
private void ReceivedGameSettingsRequest(Message message) { SendGameSettings(message); }
private void ReceivedEntitySpatial(Message message) { var clientId = connectionIds[message.ClientId]; if (!entityHelper.Entities.ContainsKey(clientId)) { return; } server.Reader.ReadNewMessage(message); server.Reader.ReadByte(); var spatial = new EntitySpatial(); spatial.Id = clientId; spatial.TimeStamp = server.Reader.ReadTimeStamp(); spatial.Position = messageHelper.ReadVector3(server.Reader); spatial.Velocity = messageHelper.ReadVector3(server.Reader); spatial.Angle = messageHelper.ReadVector3(server.Reader); entityHelper.AddSpatial(clientId, spatial); }
private void ProcessMessage(GameTime gameTime, Message message) { if (message.Type == MessageType.Data) { // Skip clients that doesnt exist if (!connectionIds.ContainsKey(message.ClientId)) { return; } // Reset the client timeout counter every time data has been received var clientId = connectionIds[message.ClientId]; entityHelper.UpdateTimeout(gameTime, clientId); switch ((PacketType)message.Data[0]) { case PacketType.Combined: ReceivedCombinedMessage(message); break; case PacketType.GameSettings: ReceivedGameSettingsRequest(message); break; case PacketType.EntitySpatial: ReceivedEntitySpatial(message); break; case PacketType.EntityEvents: ReceivedEntityEvents(message); break; } // TODO: Temp Debug if ((PacketType)message.Data[0] != PacketType.EntitySpatial) { Logger.Log<GameServer>(LogLevel.Debug, "Received Data: {0} ({1} bytes)", messageHelper.BytesToString(message.Data), message.Data.Length); } } else { var status = new EntityStatusArgs { Type = EntityType.Client, ServerId = message.ClientId }; if (message.Type == MessageType.Connect) { status.StatusType = EntityStatusType.Connected; status.Id = CreateShortClientId(message.ClientId); entityHelper.Entities.Add(status.Id, CreateConnectedClient(status.Id, message)); Logger.Log<GameServer>(LogLevel.Debug, "Client with id {0} connected with remote time offset: {1}", status.Id, message.RemoteTimeOffset); } else { status.StatusType = EntityStatusType.Disconnected; status.Id = connectionIds[message.ClientId]; entityHelper.Entities.Remove(status.Id); connectionIds.Remove(message.ClientId); Logger.Log<GameServer>(LogLevel.Debug, "Client with id {0} disconnected", status.Id); } BroadcastClientStatusChanged(status); } }
private ServerEntity CreateConnectedClient(ushort id, Message message) { var entityInfo = new ServerEntity(id, message.ClientId); entityInfo.RemoteTimeOffset = message.RemoteTimeOffset; return entityInfo; }
private void CheckTimeouts(GameTime gameTime) { var clientsToRemove = new List<ushort>(); var clients = entityHelper.GetEntitiesOfType(EntityType.Client); foreach (var client in clients) { if (gameTime.TotalGameTime.Seconds - client.Timeout >= 20) { var message = new Message(); message.ClientId = client.ServerId; message.Type = MessageType.Disconnect; server.Messages.Add(message); clientsToRemove.Add(client.Id); Logger.Log<LidgrenServer>(LogLevel.Debug, "Log: Client: {0} disconnected due to timeout.", client.Id.ToString()); } } for (int i = 0; i < clientsToRemove.Count; i++) { entityHelper.Entities.Remove(clientsToRemove[i]); } }