示例#1
0
        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;
        }
示例#2
0
        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);
            }
        }
示例#3
0
        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);
            }
        }
示例#4
0
        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));
            }
        }
示例#5
0
        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);
            }
        }
示例#6
0
        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);
        }
示例#7
0
        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));
            }
        }
示例#8
0
        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);
        }
示例#9
0
        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);
            }
        }
示例#10
0
 private bool HasMoreMessagesInCombinedMessage(Message message)
 {
     return (combinedMessageStartIndex < message.Data.Length);
 }
示例#11
0
 private void ReceivedGameSettingsRequest(Message message)
 {
     SendGameSettings(message);
 }
示例#12
0
        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);
        }
示例#13
0
        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);
            }
        }
示例#14
0
 private ServerEntity CreateConnectedClient(ushort id, Message message)
 {
     var entityInfo = new ServerEntity(id, message.ClientId);
     entityInfo.RemoteTimeOffset = message.RemoteTimeOffset;
     return entityInfo;
 }
示例#15
0
        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]);
            }
        }