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); } } }
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); }
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); }
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); }); }
// 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); }
// 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); }
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); } }
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); }
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); } }); }
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()); }
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); } }
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; }
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); } }
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; }
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()); }
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()); }
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; } }
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()); }
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; }