Example #1
0
            /// <summary>
            /// Checks for and processes any new commands coming in from the client.
            /// </summary>
            public void ReceiveClientCommands(EntityArray entityArray)
            {
                IncomingMessage incomingMessage;

                while ((incomingMessage = this.clientNetworkConnection.GetNextIncomingMessage()) != null)
                {
                    int numberOfCommands = ClientUpdateSerializer <TCommandData> .Deserialize(incomingMessage, this.deserializedClientCommandHistory, out int newlatestFrameTickAcknowledgedByClient);

                    if (this.LatestFrameTickAcknowledgedByClient < newlatestFrameTickAcknowledgedByClient)
                    {
                        this.LatestFrameTickAcknowledgedByClient = newlatestFrameTickAcknowledgedByClient;
                    }

                    for (int i = 0; i < numberOfCommands; i++)
                    {
                        ClientCommand <TCommandData> clientCommand = this.deserializedClientCommandHistory[i];

                        // Make sure we don't process a command we've already received and processed in a previous tick
                        if (!clientCommand.HasData || clientCommand.ClientFrameTick <= this.LatestClientTickReceived)
                        {
                            continue;
                        }

                        this.parentServer.executeClientCommand(this, clientCommand);

                        if (this.LatestClientTickReceived < clientCommand.ClientFrameTick)
                        {
                            this.LatestClientTickReceived = clientCommand.ClientFrameTick;
                        }
                    }
                }
            }
Example #2
0
        /// <summary>
        /// Updates the client state by processing server snapshots, updating rendered frame (with interpolation and prediction), and sending commands to the server.
        /// </summary>
        public void Update(TCommandData commandData)
        {
            Log <LogGameClient> .StartNew();

            if (this.LatestServerTickReceived >= 0)
            {
                // Only tick the client if we started getting data from the server (i.e. fully connected)
                this.FrameTick++;
            }

            this.receiveServerUpdates();

            if (this.HasRenderingStarted)
            {
                // Once we are rendering we can start taking user commands and sending them to the server
                // Take the latest command and add it to the command history buffer (overwriting an old command)
                ClientCommand <TCommandData> newClientCommand = this.clientCommandHistory.Dequeue();
                newClientCommand.Update(this.FrameTick, this.RenderedSnapshot.ServerFrameTick, this.InterpolationStartSnapshot.ServerFrameTick, this.InterpolationEndSnapshot.ServerFrameTick, this.ShouldInterpolate, this.CommandingEntityID, commandData);
                this.clientCommandHistory.Enqueue(newClientCommand);

                if (this.FrameTick % this.NetworkSendRate == 0)
                {
                    ClientUpdateSerializer <TCommandData> .Send(this.serverNetworkConnection, this.clientCommandHistory, this.LatestServerTickReceived, this.LatestFrameTickAcknowledgedByServer);
                }
            }

            this.updateRenderedSnapshot();

            this.updatePrediction();

            if (this.HasRenderingStarted)
            {
                this.SystemArray.ClientUpdate(this.RenderedSnapshot.EntityArray, this.GetCommandingEntity());
            }
        }
Example #3
0
 /// <summary>
 /// Executes a given client command on behalf of the given client.
 /// </summary>
 private void executeClientCommand(ClientProxy client, ClientCommand <TCommandData> clientCommand)
 {
     // Make sure we have an entity to command, that the client thinks its commanding that same entity, and that the entity actually exists
     if (client.CommandingEntityID != -1 && clientCommand.CommandingEntityID == client.CommandingEntityID && this.EntityArray.TryGetEntity(client.CommandingEntityID, out Entity commandingEntity))
     {
         EntitySnapshot lagCompensationSnapshot = this.getEntitySnapshotForServerFrameTick(clientCommand.RenderedTick);
         this.SystemArray.ProcessClientCommand(this.EntityArray, commandingEntity, clientCommand.CommandData, lagCompensationSnapshot?.EntityArray);
     }
 }