/// <summary> /// This method relays a message to the other clients in the same subspace. /// In case there are other players in OLDER subspaces it stores it in their queue for further processing /// </summary> public static void HandleVesselMessage(ClientStructure client, dynamic msg) { if (client.Subspace == -1) { return; } var vesselId = (Guid)msg.VesselId; var gameTime = (double)msg.GameTime; MessageQueuer.RelayMessageToSubspace <VesselSrvMsg>(client, msg); if (GeneralSettings.SettingsStore.ShowVesselsInThePast) { //Here we send this update to all the players in the FUTURE foreach (var subspace in WarpSystem.GetFutureSubspaces(client.Subspace)) { MessageQueuer.RelayMessageToSubspace <VesselSrvMsg>(client, msg, subspace); } } if (!VesselRelaySystem.ShouldStoreMessage(vesselId)) { return; } //In case the client is running in the future here we adjust the real sent time of the message msg.SentTime += WarpSystem.GetSubspaceTimeDifference(client.Subspace); foreach (var subspace in WarpSystem.GetPastSubspaces(client.Subspace)) { var vesselsAndQueues = OldSubspaceVesselMessages.GetOrAdd(subspace, new ConcurrentDictionary <Guid, ConcurrentQueue <VesselRelayItem> >()); var vesselQueue = vesselsAndQueues.GetOrAdd(vesselId, new ConcurrentQueue <VesselRelayItem>()); //This is the case when a user reverted (the message received has a game time LOWER than the last message received). //To handle this, we remove all the messages that we received UNTIL this revert. if (vesselQueue.LastOrDefault()?.GameTime > gameTime) { while (vesselQueue.TryPeek(out var peekValue) && peekValue.GameTime > gameTime) { vesselQueue.TryDequeue(out _); } } vesselQueue.Enqueue(new VesselRelayItem(subspace, vesselId, gameTime, msg)); } }
/// <summary> /// This method relays a message to the other clients in the same subspace. /// In case there are other players in OLDER subspaces it stores it in their queue for further processing /// </summary> public static void HandleVesselMessage(ClientStructure client, dynamic msg) { if (client.Subspace == -1) { return; } var vesselId = (Guid)msg.VesselId; var gameTime = (double)msg.GameTime; MessageQueuer.RelayMessageToSubspace <VesselSrvMsg>(client, msg); if (GeneralSettings.SettingsStore.ShowVesselsInThePast) { foreach (var subspace in WarpSystem.GetFutureSubspaces(client.Subspace)) { MessageQueuer.RelayMessageToSubspace <VesselSrvMsg>(client, msg, subspace); } } if (!VesselRelaySystem.ShouldStoreMessage(vesselId)) { return; } //The client is running in the future so here we adjust the real sent time of the message msg.SentTime += WarpSystem.GetSubspaceTimeDifference(client.Subspace); foreach (var subspace in WarpSystem.GetPastSubspaces(client.Subspace)) { //This is the case when a user reverted (the message received has a game time LOWER than the last message received). //To handle this, we remove all the messages that we received UNTIL this revert. if (DbCollection.Exists(x => x.VesselId == vesselId && x.GameTime > gameTime)) { DbCollection.Delete(x => x.VesselId == vesselId && x.GameTime > gameTime); DataBase.Shrink(); } DbCollection.Insert(new VesselRelayDbItem(subspace, vesselId, gameTime, msg)); } DbCollection.EnsureIndex(x => x.Id); DbCollection.EnsureIndex(x => x.SubspaceId); DbCollection.EnsureIndex(x => x.VesselId); DbCollection.EnsureIndex(x => x.GameTime); }