Пример #1
0
    private void UpdateClientInFastForward()
    {
        uint clientId = (uint)ECSManager.Instance.NetworkManager.LocalClientId;
        var  inputs   = ComponentsManager.Instance.GetComponent <UserInputComponent>(clientId);

        if (inputs.fastForwardInputsMessages.Count > 0)
        {
            var shape = ComponentsManager.Instance.GetComponent <ShapeComponent>(clientId);
            shape.speed = Vector2.zero;

            // Pop input
            ReplicationMessage currentInput = inputs.fastForwardInputsMessages[0];
            inputs.fastForwardInputsMessages.RemoveAt(0);

            // Apply input
            Utils.GetUserInput(ref currentInput, ref shape, false);
            ComponentsManager.Instance.SetComponent <ShapeComponent>(clientId, shape);
            ComponentsManager.Instance.SetComponent <UserInputComponent>(clientId, inputs);

            // Update history
            ComponentsManager.Instance.ForEach <ShapeComponent, UserInputComponent>((entityID, entityShape, entityUserInput) =>
            {
                int historicalInputIndex = entityUserInput.inputHistory.FindIndex(x => x.timeCreated == currentInput.timeCreated);
                if (historicalInputIndex >= 0)
                {
                    ReplicationMessage msg = entityUserInput.inputHistory[historicalInputIndex];
                    msg.pos = currentInput.pos;
                    ComponentsManager.Instance.SetComponent <UserInputComponent>(entityID, entityUserInput);
                }
            });
        }
    }
    private void HandleReplicationMessage(ulong clientId, Stream stream)
    {
        ReplicationMessage replicationMessage = new ReplicationMessage();

        using (PooledBitReader reader = PooledBitReader.Get(stream))
        {
            replicationMessage.messageID   = reader.ReadInt32();
            replicationMessage.timeCreated = reader.ReadInt32();
            replicationMessage.frameNumber = reader.ReadInt32();
            replicationMessage.entityId    = reader.ReadUInt32();
            replicationMessage.shape       = (Config.Shape)reader.ReadInt16();
            replicationMessage.pos         = reader.ReadVector2();
            replicationMessage.speed       = reader.ReadVector2();
            replicationMessage.size        = (float)reader.ReadDouble();
            ComponentsManager.Instance.SetComponent <ReplicationMessage>(replicationMessage.entityId, replicationMessage);
            if (!ComponentsManager.Instance.EntityContains <EntityComponent>(replicationMessage.entityId))
            {
                bool spawnFound = ComponentsManager.Instance.TryGetComponent(new EntityComponent(0), out SpawnInfo spawnInfo);

                if (!spawnFound)
                {
                    spawnInfo = new SpawnInfo(false);
                }
                spawnInfo.replicatedEntitiesToSpawn.Add(replicationMessage);
                ComponentsManager.Instance.SetComponent <SpawnInfo>(new EntityComponent(0), spawnInfo);
            }
        }
    }
Пример #3
0
        private ReplicationMessage GetCountersDataSinceEtag(long etag, out long lastEtagSent)
        {
            var message = new ReplicationMessage {
                ServerId = storage.ServerId, SendingServerName = storage.CounterStorageUrl
            };

            using (var reader = storage.CreateReader())
            {
                message.Counters = reader.GetCountersSinceEtag(etag + 1).Take(1024).ToList();             //TODO: Capped this...how to get remaining values?
                lastEtagSent     = message.Counters.Count > 0 ? message.Counters.Max(x => x.Etag) : etag; // change this once changed this function do a reall paging
            }

            return(message);
        }
Пример #4
0
        private ReplicationMessage GetCountersDataSinceEtag(long etag, out long lastEtagSent, int take = 1024)
        {
            var message = new ReplicationMessage {
                ServerId = storage.ServerId, SendingServerName = storage.CounterStorageUrl
            };

            using (var reader = storage.CreateReader())
            {
                message.Counters = reader.GetCountersSinceEtag(etag + 1, take: take).ToList();
                lastEtagSent     = message.Counters.Count > 0 ? message.Counters.Max(x => x.Etag) : etag; // change this once changed this function do a reall paging
            }

            return(message);
        }
Пример #5
0
 public void SendReplicationMessage(ReplicationMessage msg)
 {
     using (PooledBitStream stream = PooledBitStream.Get())
     {
         using (PooledBitWriter writer = PooledBitWriter.Get(stream))
         {
             writer.WriteInt32(msg.messageID);
             writer.WriteInt32(msg.timeCreated);
             writer.WriteUInt32(msg.entityId);
             writer.WriteInt16((byte)msg.shape);
             writer.WriteVector2(msg.pos);
             writer.WriteVector2(msg.speed);
             writer.WriteDouble(msg.size);
             CustomMessagingManager.SendNamedMessage("Replication", null, stream, "customChannel");
         }
     }
 }
    public static void UpdateSystemServer()
    {
        // creates messages from current state

        ComponentsManager.Instance.ForEach <ShapeComponent>((entityID, shapeComponent) => {
            ReplicationMessage msg = new ReplicationMessage()
            {
                messageID   = 0,
                timeCreated = Utils.SystemTime,
                entityId    = entityID.id,
                shape       = shapeComponent.shape,
                pos         = shapeComponent.pos,
                speed       = shapeComponent.speed,
                size        = shapeComponent.size
            };
            ComponentsManager.Instance.SetComponent <ReplicationMessage>(entityID, msg);
        });
    }
Пример #7
0
    // if 'readFromInput == true': Reads the inputs from user keyboard and populates 'msg' and 'shapeComponent' accordingly
    // else: Reads the inputs inside 'msg' and populates 'shapeComponent' accordingly
    public static bool GetUserInput(ref ReplicationMessage msg, ref ShapeComponent shapeComponent, bool readFromInput)
    {
        int  SPEED         = 4;
        bool inputDetected = false;

        shapeComponent.speed = Vector2.zero;
        if ((!readFromInput && msg.inputA == 1) || (readFromInput && Input.GetKey(KeyCode.A)))
        {
            if (readFromInput)
            {
                msg.inputA = 1;
            }
            shapeComponent.speed = Vector2.left * SPEED;
            inputDetected        = true;
        }
        else if ((!readFromInput && msg.inputW == 1) || (readFromInput && Input.GetKey(KeyCode.W)))
        {
            if (readFromInput)
            {
                msg.inputW = 1;
            }
            shapeComponent.speed = Vector2.up * SPEED;
            inputDetected        = true;
        }
        else if ((!readFromInput && msg.inputS == 1) || (readFromInput && Input.GetKey(KeyCode.S)))
        {
            if (readFromInput)
            {
                msg.inputS = 1;
            }
            shapeComponent.speed = Vector2.down * SPEED;
            inputDetected        = true;
        }
        else if ((!readFromInput && msg.inputD == 1) || (readFromInput && Input.GetKey(KeyCode.D)))
        {
            if (readFromInput)
            {
                msg.inputD = 1;
            }
            shapeComponent.speed = Vector2.right * SPEED;
            inputDetected        = true;
        }
        return(inputDetected);
    }
Пример #8
0
    // In charge of sending all messages pending sending
    public void UpdateSystem()
    {
        if (ECSManager.Instance.RunningFastForward)
        {
            return;
        }

        bool messagingInfoFound = ComponentsManager.Instance.TryGetComponent(new EntityComponent(0), out MessagingInfo messagingInfo);

        if (!messagingInfoFound)
        {
            messagingInfo = new MessagingInfo()
            {
                currentMessageId = 0
            };
        }

        if (ECSManager.Instance.NetworkManager.isServer)
        {
            ComponentsManager.Instance.ForEach <ReplicationMessage>((entityID, msg) =>
            {
                msg.messageID = messagingInfo.currentMessageId++;
                ECSManager.Instance.NetworkManager.SendReplicationMessage(msg);
                msg.handled = true;
                ComponentsManager.Instance.SetComponent <ReplicationMessage>(entityID, msg);
            });
        }

        if (ECSManager.Instance.NetworkManager.isClient)
        {
            uint clientId = (uint)ECSManager.Instance.NetworkManager.LocalClientId;
            if (ComponentsManager.Instance.TryGetComponent(clientId, out UserInputComponent userInput))
            {
                for (int i = 0; i < userInput.pendingInputsMessages.Count; i++)
                {
                    ReplicationMessage msg = userInput.pendingInputsMessages[i];
                    ECSManager.Instance.NetworkManager.SendReplicationMessageToServer(msg);
                }
                userInput.pendingInputsMessages.Clear();
            }
        }

        ComponentsManager.Instance.SetComponent <MessagingInfo>(new EntityComponent(0), messagingInfo);
    }
Пример #9
0
    private void HandleServerReplicationMessage(ulong clientId, Stream stream)
    {
        ReplicationMessage msg = new ReplicationMessage();

        using (PooledBitReader reader = PooledBitReader.Get(stream))
        {
            msg.messageID   = reader.ReadInt32();
            msg.timeCreated = reader.ReadInt32();
            msg.entityId    = reader.ReadUInt32();
            msg.shape       = (Config.Shape)reader.ReadInt16();
            msg.pos         = reader.ReadVector2();
            msg.speed       = reader.ReadVector2();
            msg.size        = (float)reader.ReadDouble();
            msg.inputA      = reader.ReadUInt32();
            msg.inputW      = reader.ReadUInt32();
            msg.inputS      = reader.ReadUInt32();
            msg.inputD      = reader.ReadUInt32();
            var userInputComponent = ComponentsManager.Instance.GetComponent <UserInputComponent>(msg.entityId);
            userInputComponent.pendingInputsMessages.Add(msg);
            ComponentsManager.Instance.SetComponent <UserInputComponent>(msg.entityId, userInputComponent);
        }
    }
Пример #10
0
    private static int ClientIsUpToDateWithServer(MessageBuffer msgBuffer, int maxOffset)
    {
        // Compute buffer time and network lag
        int   bufferTime = msgBuffer.buffer[msgBuffer.buffer.Count - 1].timeCreated;
        float networkLag = Utils.SystemTime - bufferTime + Time.deltaTime;

        bool upToDateWithServer = true;
        int  oldInputIndex      = -1;

        for (int i = 0; i < msgBuffer.buffer.Count; i++)
        {
            ReplicationMessage msg = msgBuffer.buffer[i];
            var userInput          = ComponentsManager.Instance.GetComponent <UserInputComponent>(msg.entityId);

            oldInputIndex = userInput.inputHistory.FindIndex(x => x.timeCreated >= (bufferTime - networkLag));
            if (oldInputIndex >= 0)
            {
                float offset = (userInput.inputHistory[oldInputIndex].pos - msg.pos).magnitude;
                upToDateWithServer = upToDateWithServer && offset <= maxOffset;
            }
        }
        return(upToDateWithServer? -1: oldInputIndex);
    }
Пример #11
0
    void UpdateServerSystem()
    {
        ComponentsManager.Instance.ForEach <UserInputComponent>((entityID, userInput) =>
        {
            bool shapeSpawned = ComponentsManager.Instance.TryGetComponent(entityID, out ShapeComponent shapeComp);
            bool isPlayer     = ComponentsManager.Instance.EntityContains <PlayerComponent>(entityID);
            if (shapeSpawned && isPlayer)
            {
                for (int i = 0; i < userInput.pendingInputsMessages.Count; i++)
                {
                    ShapeComponent shapeComponent = ComponentsManager.Instance.GetComponent <ShapeComponent>(entityID);

                    // Get the user input coming from the client
                    ReplicationMessage msg = userInput.pendingInputsMessages[i];
                    Utils.GetUserInput(ref msg, ref shapeComponent, false);

                    ComponentsManager.Instance.SetComponent <ShapeComponent>(entityID, shapeComponent);

                    // Prepare fast forward:
                    // Set a replication message to let the world know that this entity is concerned by fast forward
                    userInput.fastForwardInputsMessages = new List <ReplicationMessage> {
                        new ReplicationMessage()
                    };
                    ComponentsManager.Instance.SetComponent <UserInputComponent>(entityID, userInput);

                    ECSManager.Instance.FastForward(1);

                    // Reset speed to 0
                    ShapeComponent newShapeComponent = ComponentsManager.Instance.GetComponent <ShapeComponent>(entityID);
                    newShapeComponent.speed          = Vector2.zero;
                    ComponentsManager.Instance.SetComponent <ShapeComponent>(entityID, newShapeComponent);
                }
                userInput.pendingInputsMessages.Clear();
                ComponentsManager.Instance.SetComponent <UserInputComponent>(entityID, userInput);
            }
        });
    }
Пример #12
0
 private TcpPackage WrapDataChunkBulk(ReplicationMessage.DataChunkBulk msg)
 {
     var dto = new ReplicationMessageDto.DataChunkBulk(msg.MasterId.ToByteArray(),
                                                       msg.SubscriptionId.ToByteArray(),
                                                       msg.ChunkStartNumber,
                                                       msg.ChunkEndNumber,
                                                       msg.SubscriptionPosition,
                                                       msg.DataBytes,
                                                       msg.CompleteChunk);
     return new TcpPackage(TcpCommand.DataChunkBulk, Guid.NewGuid(), dto.Serialize());
 }
Пример #13
0
    void UpdateClientSystem()
    {
        uint clientId    = (uint)ECSManager.Instance.NetworkManager.LocalClientId;
        int  currentTime = Utils.SystemTime;

        if (ComponentsManager.Instance.TryGetComponent(clientId, out ShapeComponent shapeComponent))
        {
            // Build a new message
            ReplicationMessage msg = new ReplicationMessage();
            msg.entityId    = clientId;
            msg.timeCreated = currentTime;
            msg.entityId    = clientId;
            msg.shape       = shapeComponent.shape;
            msg.pos         = shapeComponent.pos;
            msg.speed       = shapeComponent.speed;
            msg.inputA      = 0;
            msg.inputW      = 0;
            msg.inputS      = 0;
            msg.inputD      = 0;

            // Get user inputs
            bool inputDetected = Utils.GetUserInput(ref msg, ref shapeComponent, true);

            // Save the inputs if required
            if (ECSManager.Instance.Config.enableInputPrediction)
            {
                ComponentsManager.Instance.SetComponent <ShapeComponent>(clientId, shapeComponent);
            }


            ComponentsManager.Instance.ForEach <ShapeComponent, UserInputComponent>((entityID, entityShape, entityUserInput) =>
            {
                ReplicationMessage entityMsg = new ReplicationMessage();
                entityMsg.timeCreated        = currentTime;
                entityMsg.pos   = entityShape.pos;
                entityMsg.size  = entityShape.size;
                entityMsg.speed = entityShape.speed;
                entityMsg.shape = entityShape.shape;

                if (entityID == clientId && inputDetected)
                {
                    if (ECSManager.Instance.Config.enableInputPrediction)
                    {
                        entityMsg.inputA = msg.inputA;
                        entityMsg.inputW = msg.inputW;
                        entityMsg.inputS = msg.inputS;
                        entityMsg.inputD = msg.inputD;
                    }

                    // Put the new input message in the queue to server
                    entityUserInput.pendingInputsMessages.Add(msg);
                }

                // save in history
                entityUserInput.inputHistory.Add(entityMsg);

                ComponentsManager.Instance.SetComponent <UserInputComponent>(entityID, entityUserInput);
            });

            // Clear old messages
            ClearOldInputs(currentTime);
        }
    }
Пример #14
0
	    private ReplicationMessage GetCountersDataSinceEtag(long etag)
	    {
            var message = new ReplicationMessage { SendingServerName = storage.CounterStorageUrl };

            using (var reader = storage.CreateReader())
            {
                message.Counters = reader.GetCountersSinceEtag(etag + 1).Take(10240).ToList(); //TODO: Capped this...how to get remaining values?
            }

	        return message;
	    }
Пример #15
0
        private bool TryPerformReplicationToServer(RavenConnectionStringOptions connectionStringOptions, string counterStorageUrl, ReplicationMessage message, out string lastError)
        {
            try
            {
                var url = string.Format("{0}/replication", counterStorageUrl);
                lastError = string.Empty;
                var request = httpRavenRequestFactory.Create(url, HttpMethods.Post, connectionStringOptions);
                request.Write(RavenJObject.FromObject(message));
                request.ExecuteRequest();

                return(true);
            }
            catch (WebException e)
            {
                lastError = HandleReplicationDistributionWebException(e, counterStorageUrl);
                return(false);
            }
            catch (Exception e)
            {
                Log.ErrorException("Error occured replicating to: " + counterStorageUrl, e);
                lastError = e.Message;
                return(false);
            }
        }
Пример #16
0
        private bool PerformReplicationToServer(RavenConnectionStringOptions connectionStringOptions, string counterStorageUrl, ReplicationMessage message, out string lastError)
        {
            var destinationUrl = connectionStringOptions.Url;

            if (!TryPerformReplicationToServer(connectionStringOptions, counterStorageUrl, message, out lastError))
            {
                if (IsFirstFailure(destinationUrl))
                {
                    return(TryPerformReplicationToServer(connectionStringOptions, counterStorageUrl, message, out lastError));
                }
                return(false);
            }

            return(true);
        }
		private bool PerformReplicationToServer(RavenConnectionStringOptions connectionStringOptions, string counterStorageUrl, long etag, ReplicationMessage message, out string lastError)
		{
			var destinationUrl = connectionStringOptions.Url;

			if (!TryPerformReplicationToServer(connectionStringOptions, counterStorageUrl, message, out lastError))
			{
				if (IsFirstFailure(destinationUrl))
				{
					return TryPerformReplicationToServer(connectionStringOptions, counterStorageUrl, message, out lastError);
				}
				return false;
			}

			return true;
		}
Пример #18
0
 private TcpPackage WrapCloneAssignment(ReplicationMessage.CloneAssignment msg)
 {
     var dto = new ReplicationMessageDto.CloneAssignment(msg.MasterId.ToByteArray(), msg.SubscriptionId.ToByteArray());
     return new TcpPackage(TcpCommand.CloneAssignment, Guid.NewGuid(), dto.Serialize());
 }
Пример #19
0
 private TcpPackage WrapSubscribeReplica(ReplicationMessage.SubscribeReplica msg)
 {
     var epochs = msg.LastEpochs.Select(x => new ReplicationMessageDto.Epoch(x.EpochPosition, x.EpochNumber, x.EpochId.ToByteArray())).ToArray();
     var dto = new ReplicationMessageDto.SubscribeReplica(msg.LogPosition,
                                                          msg.ChunkId.ToByteArray(),
                                                          epochs,
                                                          msg.ReplicaEndPoint.Address.GetAddressBytes(),
                                                          msg.ReplicaEndPoint.Port,
                                                          msg.MasterId.ToByteArray(),
                                                          msg.SubscriptionId.ToByteArray(),
                                                          msg.IsPromotable);
     return new TcpPackage(TcpCommand.SubscribeReplica, Guid.NewGuid(), dto.Serialize());
 }
Пример #20
0
 private TcpPackage WrapReplicaSubscribed(ReplicationMessage.ReplicaSubscribed msg)
 {
     var dto = new ReplicationMessageDto.ReplicaSubscribed(msg.MasterId.ToByteArray(),
                                                           msg.SubscriptionId.ToByteArray(),
                                                           msg.SubscriptionPosition);
     return new TcpPackage(TcpCommand.ReplicaSubscribed, Guid.NewGuid(), dto.Serialize());
 }
		private bool TryPerformReplicationToServer(RavenConnectionStringOptions connectionStringOptions, string counterStorageUrl, ReplicationMessage message, out string lastError)
		{
			try
			{
				var url = string.Format("{0}/replication", counterStorageUrl);
				lastError = string.Empty;
				var request = httpRavenRequestFactory.Create(url, "POST", connectionStringOptions);
				request.Write(RavenJObject.FromObject(message));
				request.ExecuteRequest();
                
                return true;

			}
			catch (WebException e)
			{
				lastError = HandleReplicationDistributionWebException(e, counterStorageUrl);
				return false;
			}
			catch (Exception e)
			{
				Log.ErrorException("Error occured replicating to: " + counterStorageUrl, e);
				lastError = e.Message;
				return false;
			}
		}
Пример #22
0
 private TcpPackage WrapCreateChunk(ReplicationMessage.CreateChunk msg)
 {
     var dto = new ReplicationMessageDto.CreateChunk(msg.MasterId.ToByteArray(),
                                                     msg.SubscriptionId.ToByteArray(),
                                                     msg.ChunkHeader.AsByteArray(),
                                                     msg.FileSize,
                                                     msg.IsCompletedChunk);
     return new TcpPackage(TcpCommand.CreateChunk, Guid.NewGuid(), dto.Serialize());
 }
Пример #23
0
 private TcpPackage WrapAckLogPosition(ReplicationMessage.AckLogPosition msg)
 {
     var dto = new ReplicationMessageDto.ReplicaLogPositionAck(msg.SubscriptionId.ToByteArray(), msg.ReplicationLogPosition);
     return new TcpPackage(TcpCommand.ReplicaLogPositionAck, Guid.NewGuid(), dto.Serialize());
 }
	    private ReplicationMessage GetCountersDataSinceEtag(long etag, out long lastEtagSent)
	    {
            var message = new ReplicationMessage { SendingServerName = storage.CounterStorageUrl };

            using (var reader = storage.CreateReader())
            {
                message.Counters = reader.GetCountersSinceEtag(etag + 1).Take(10240).ToList(); //TODO: Capped this...how to get remaining values?
                lastEtagSent = message.Counters.Count > 0 ? message.Counters.Max(x=>x.Etag):etag; // change this once changed this function do a reall paging
            }

	        return message;
	    }