public void CachingLookupCaseInsensitiveNoCacheMissingKeys() { StringComparer comparer = StringComparer.OrdinalIgnoreCase; int[] numbers = RandomNumbers(435, 19874); var dict = new Dictionary <string, ImmutableArray <int> >(comparer); foreach (string k in Keys(numbers, false, comparer)) { dict.Add(k, Values(k, numbers, false)); } var look1 = CreateLookup(numbers, true); var look2 = new CachingDictionary <string, int>(s => dict.ContainsKey(s) ? dict[s] : ImmutableArray.Create <int>(), (c) => Keys(numbers, true, comparer: c), comparer); CompareLookups1(look1, look2, Keys(numbers, true, comparer)); look1 = CreateLookup(numbers, true); look2 = new CachingDictionary <string, int>(s => dict.ContainsKey(s) ? dict[s] : ImmutableArray.Create <int>(), (c) => Keys(numbers, true, comparer: c), comparer); CompareLookups2(look1, look2, Keys(numbers, true, comparer)); CompareLookups1(look1, look2, Keys(numbers, true, comparer)); look1 = CreateLookup(numbers, true); look2 = new CachingDictionary <string, int>(s => dict.ContainsKey(s) ? dict[s] : ImmutableArray.Create <int>(), (c) => Keys(numbers, true, comparer: c), comparer); CompareLookups2(look2, look1, Keys(numbers, true, comparer)); CompareLookups1(look1, look2, Keys(numbers, true, comparer)); }
public void CachingLookupCorrectResults() { StringComparer comparer = StringComparer.Ordinal; int[] numbers = RandomNumbers(200, 11234); var dict = new Dictionary <string, ImmutableArray <int> >(comparer); foreach (string k in Keys(numbers, false, comparer)) { dict.Add(k, Values(k, numbers, false)); } var look1 = CreateLookup(numbers, false); var look2 = new CachingDictionary <string, int>( s => dict.ContainsKey(s) ? dict[s] : ImmutableArray.Create <int>(), (c) => Keys(numbers, false, comparer: c), comparer); CompareLookups1(look1, look2, Keys(numbers, false, comparer)); look1 = CreateLookup(numbers, false); look2 = new CachingDictionary <string, int>( s => dict.ContainsKey(s) ? dict[s] : ImmutableArray.Create <int>(), (c) => Keys(numbers, false, comparer: c), comparer); CompareLookups2(look1, look2, Keys(numbers, false, comparer)); CompareLookups1(look1, look2, Keys(numbers, false, comparer)); look1 = CreateLookup(numbers, false); look2 = new CachingDictionary <string, int>( s => dict.ContainsKey(s) ? dict[s] : ImmutableArray.Create <int>(), (c) => Keys(numbers, false, comparer: c), comparer); CompareLookups2(look2, look1, Keys(numbers, false, comparer)); CompareLookups1(look1, look2, Keys(numbers, false, comparer)); }
public void TestCachingDictionaryClear() { Random random = new Random(); CachingDictionary <int, Guid> cache = new CachingDictionary <int, Guid>(); // Build cache in parallel Parallel.For( 0, CacheSize, i => cache.AddOrUpdate(i, Guid.NewGuid(), DateTime.Now.AddMilliseconds(random.Next(1000, 60000)))); Parallel.Invoke( () => { int count = 0; // ReSharper disable LoopCanBeConvertedToQuery foreach (Guid guid in cache.Values) { // ReSharper restore LoopCanBeConvertedToQuery count++; } Trace.WriteLine(string.Format("Count was {0}", count)); }, cache.Clear); Trace.WriteLine(cache.ToString()); }
public void FullyPopulateRace_01() { CachingDictionary <int, FullyPopulateRaceHelper> lookup = null; FullyPopulateRaceHelper item = null; int itemAccessCount = 0; lookup = new CachingDictionary <int, FullyPopulateRaceHelper>(getElementsOfKey, getKeys, EqualityComparer <int> .Default); _ = lookup.Count; Assert.NotNull(item); Assert.Same(item, getItem()); ImmutableArray <FullyPopulateRaceHelper> getElementsOfKey(int id) { itemAccessCount++; if (item is null && itemAccessCount == 1) { item = getItem(); } return(ImmutableArray.Create <FullyPopulateRaceHelper>(new FullyPopulateRaceHelper())); } HashSet <int> getKeys(IEqualityComparer <int> comparer) { return(new HashSet <int>(new[] { 1 }, comparer)); } FullyPopulateRaceHelper getItem() { return(lookup[1][0]); } }
public void AddExtension(IMyToolbarExtension newExtension) { if (m_extensions == null) { m_extensions = new CachingDictionary <Type, IMyToolbarExtension>(); } m_extensions.Add(newExtension.GetType(), newExtension); newExtension.AddedToToolbar(this); }
public override void LoadData() { base.LoadData(); m_pirateAntennas = new CachingDictionary <long, PirateAntennaInfo>(); m_definitionsByAntennaName = new Dictionary <string, MyPirateAntennaDefinition>(); m_droneInfos = new CachingDictionary <long, DroneInfo>(); foreach (var antennaDefinition in MyDefinitionManager.Static.GetPirateAntennaDefinitions()) { m_definitionsByAntennaName[antennaDefinition.Name] = antennaDefinition; } }
public void CallExactlyOncePerKey() { StringComparer comparer = StringComparer.OrdinalIgnoreCase; int[] numbers = RandomNumbers(435, 19874); var dict = new Dictionary <string, ImmutableArray <int> >(comparer); foreach (string k in Keys(numbers, false, comparer)) { dict.Add(k, Values(k, numbers, false)); } HashSet <string> lookedUp = new HashSet <string>(comparer); bool askedForKeys = false; var look1 = new CachingDictionary <string, int>( s => { Assert.False(lookedUp.Contains(s)); lookedUp.Add(s); return(dict.ContainsKey(s) ? dict[s] : ImmutableArray.Create <int>()); }, (c) => { Assert.False(askedForKeys); askedForKeys = true; return(Keys(numbers, true, comparer: c)); }, comparer ); string key1 = GetKey(numbers[0], false); string key2 = GetKey(numbers[1], false); string key3 = GetKey(numbers[2], false); ImmutableArray <int> retval; retval = look1[key1]; retval = look1[key2]; retval = look1[key3]; retval = look1[key1]; retval = look1[key2]; retval = look1[key3]; retval = look1[key1]; retval = look1[key2]; retval = look1[key3]; retval = look1[key1]; retval = look1[key2]; retval = look1[key3]; }
private void CompareLookups2(CachingDictionary <string, int> look1, ILookup <string, int> look2, HashSet <string> keys) { foreach (string k in look1.Keys) { CheckEqualEnumerable(look1[k], look2[k]); } foreach (string k in look2.Select(g => g.Key)) { CheckEqualEnumerable(look1[k], look2[k]); } Assert.Equal(look1.Count, look2.Count); }
// Constructor. Use static Create method to create instances. private MergedNamespaceSymbol(NamespaceExtent extent, NamespaceSymbol containingNamespace, ImmutableArray <NamespaceSymbol> namespacesToMerge, string nameOpt) { this.extent = extent; this.namespacesToMerge = namespacesToMerge; this.containingNamespace = containingNamespace; this.cachedLookup = new CachingDictionary <string, Symbol>(SlowGetChildrenOfName, SlowGetChildNames, EqualityComparer <string> .Default); this.nameOpt = nameOpt; #if DEBUG // We shouldn't merged namespaces that are already merged. foreach (NamespaceSymbol ns in namespacesToMerge) { Debug.Assert(ns.ConstituentNamespaces.Length == 1); } #endif }
private void CompareLookups1(ILookup <string, int> look1, CachingDictionary <string, int> look2, HashSet <string> keys) { foreach (string k in keys) { Assert.Equal(look1.Contains(k), look2.Contains(k)); CheckEqualEnumerable(look1[k], look2[k]); } foreach (string k in new string[] { "goo", "bar", "banana", "flibber" }) { Assert.False(look1.Contains(k)); Assert.False(look2.Contains(k)); Assert.Empty(look1[k]); Assert.Empty(look2[k]); } }
protected override void UnloadData() { base.UnloadData(); m_piratesIdentityId = 0; m_definitionsByAntennaName = null; foreach (var entry in m_droneInfos) { MyEntity entity; MyEntities.TryGetEntityById(entry.Key, out entity); if (entity != null) { UnregisterDrone(entity, immediate: false); } } m_droneInfos.Clear(); m_droneInfos = null; m_pirateAntennas = null; }
public static MySessionComponentBase FindModSessionComponent(string modName, string modScriptsFolder, string typeName) { string assemblyName = $"{modName}_{modScriptsFolder}, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"; CachingDictionary <Type, MySessionComponentBase> sessionComponents = (CachingDictionary <Type, MySessionComponentBase>) typeof(MySession).GetField("m_sessionComponents", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(MySession.Static); if (sessionComponents == null) { Logger.AlwaysLog("Failed to get m_sessionComponents", Logger.severity.ERROR); return(null); } // Type.GetType(string typeName) with the fully qualified name doesn't seem to work, maybe it's something to do with CodeDOM // there can be more than one assembly with the right name foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies().Where(x => x.FullName == assemblyName)) { Type componentType = assembly.GetType(typeName); if (componentType == null) { Logger.DebugLog($"Failed to get type from assembly. Assembly: {assemblyName}, Type: {typeName}", Logger.severity.TRACE); continue; } MySessionComponentBase component; if (!sessionComponents.TryGetValue(componentType, out component)) { Logger.DebugLog($"Failed to get MySessionComponentBase. Assembly: {assemblyName}, Type: {typeName}", Logger.severity.TRACE); continue; } return(component); } return(null); }
private void LoadSaveData(Builder_ArmsData data) { if (data == null) { Logger.DebugLog("No data to load"); return; } #pragma warning disable 612, 618 if (Comparer <Version> .Default.Compare(data.ArmsVersion, default(Version)) == 0) { Logger.DebugLog("Old version: " + data.ModVersion); data.ArmsVersion = new Version(data.ModVersion); } #pragma warning restore 612, 618 Logger.AlwaysLog("Save version: " + data.ArmsVersion, Rynchodon.Logger.severity.INFO); // relay Dictionary <Message.Builder_Message, Message> messages = MyAPIGateway.Multiplayer.IsServer ? new Dictionary <Message.Builder_Message, Message>() : null; SerializableGameTime.Adjust = new TimeSpan(data.SaveTime); foreach (RelayStorage.Builder_NetworkStorage bns in data.AntennaStorage) { RelayNode node; if (!Registrar.TryGetValue(bns.PrimaryNode, out node)) { Logger.AlwaysLog("Failed to get node for: " + bns.PrimaryNode, Rynchodon.Logger.severity.WARNING); continue; } RelayStorage store = node.Storage; if (store == null) // probably always true { node.ForceCreateStorage(); store = node.Storage; if (store == null) { Logger.AlwaysLog("failed to create storage for " + node.DebugName, Rynchodon.Logger.severity.ERROR); continue; } } foreach (LastSeen.Builder_LastSeen bls in bns.LastSeenList) { LastSeen ls = new LastSeen(bls); if (ls.IsValid) { store.Receive(ls); } else { Logger.AlwaysLog("failed to create a valid last seen from builder for " + bls.EntityId, Rynchodon.Logger.severity.WARNING); if (m_failedLastSeen == null) { m_failedLastSeen = new CachingDictionary <long, CachingList <LastSeen.Builder_LastSeen> >(); UpdateManager.Register(100, RetryLastSeen); } CachingList <LastSeen.Builder_LastSeen> list; if (!m_failedLastSeen.TryGetValue(bns.PrimaryNode, out list)) { list = new CachingList <LastSeen.Builder_LastSeen>(); m_failedLastSeen.Add(bns.PrimaryNode, list, true); } list.Add(bls); list.ApplyAdditions(); } } Logger.DebugLog("added " + bns.LastSeenList.Length + " last seen to " + store.PrimaryNode.DebugName, Rynchodon.Logger.severity.DEBUG); // messages in the save file belong on the server if (messages == null) { continue; } foreach (Message.Builder_Message bm in bns.MessageList) { Message msg; if (!messages.TryGetValue(bm, out msg)) { msg = new Message(bm); messages.Add(bm, msg); } else { Logger.DebugLog("found linked message", Rynchodon.Logger.severity.TRACE); } if (msg.IsValid) { store.Receive(msg); } else { Logger.AlwaysLog("failed to create a valid message from builder for " + bm.DestCubeBlock + "/" + bm.SourceCubeBlock, Rynchodon.Logger.severity.WARNING); } } Logger.DebugLog("added " + bns.MessageList.Length + " message to " + store.PrimaryNode.DebugName, Rynchodon.Logger.severity.DEBUG); } // past this point, only synchronized data if (!MyAPIGateway.Multiplayer.IsServer) { data = null; return; } // system disruption foreach (Disruption.Builder_Disruption bd in data.SystemDisruption) { Disruption disrupt; switch (bd.Type) { case "AirVentDepressurize": disrupt = new AirVentDepressurize(); break; case "CryoChamberMurder": disrupt = new CryoChamberMurder(); break; case "DisableTurret": disrupt = new DisableTurret(); break; case "DoorLock": disrupt = new DoorLock(); break; case "EMP": disrupt = new EMP(); break; case "GravityReverse": disrupt = new GravityReverse(); break; case "JumpDriveDrain": disrupt = new JumpDriveDrain(); break; case "MedicalRoom": disrupt = new MedicalRoom(); break; case "TraitorTurret": disrupt = new TraitorTurret(); break; default: Logger.AlwaysLog("Unknown disruption: " + bd.Type, Rynchodon.Logger.severity.WARNING); continue; } disrupt.Start(bd); } // autopilot if (data.Autopilot != null) { foreach (ShipAutopilot.Builder_Autopilot ba in data.Autopilot) { ShipAutopilot autopilot; if (Registrar.TryGetValue(ba.AutopilotBlock, out autopilot)) { autopilot.ResumeFromSave(ba); } else { Logger.AlwaysLog("failed to find autopilot block " + ba.AutopilotBlock, Rynchodon.Logger.severity.WARNING); } } } // programmable block if (data.ProgrammableBlock != null) { foreach (ProgrammableBlock.Builder_ProgrammableBlock bpa in data.ProgrammableBlock) { ProgrammableBlock pb; if (Registrar.TryGetValue(bpa.BlockId, out pb)) { pb.ResumeFromSave(bpa); } else { Logger.AlwaysLog("failed to find programmable block " + bpa.BlockId, Rynchodon.Logger.severity.WARNING); } } } // text panel if (data.TextPanel != null) { foreach (TextPanel.Builder_TextPanel btp in data.TextPanel) { TextPanel panel; if (Registrar.TryGetValue(btp.BlockId, out panel)) { panel.ResumeFromSave(btp); } else { Logger.AlwaysLog("failed to find text panel " + btp.BlockId, Rynchodon.Logger.severity.WARNING); } } } // weapon if (data.Weapon != null) { foreach (WeaponTargeting.Builder_WeaponTargeting bwt in data.Weapon) { WeaponTargeting targeting; if (WeaponTargeting.TryGetWeaponTargeting(bwt.WeaponId, out targeting)) { targeting.ResumeFromSave(bwt); } else { Logger.AlwaysLog("failed to find weapon " + bwt.WeaponId, Rynchodon.Logger.severity.WARNING); } } } // entity values if (data.EntityValues != null) { UpgradeEntityValue.Load(data.EntityValues); } // sync if (data.Sync != null) { ASync.SetBuilder(data.Sync); } data = null; }
// Constructor. Use static Create method to create instances. private MergedNamespaceSymbol(NamespaceExtent extent, NamespaceSymbol containingNamespace, ImmutableArray<NamespaceSymbol> namespacesToMerge, string nameOpt) { this.extent = extent; this.namespacesToMerge = namespacesToMerge; this.containingNamespace = containingNamespace; this.cachedLookup = new CachingDictionary<string, Symbol>(SlowGetChildrenOfName, SlowGetChildNames, EqualityComparer<string>.Default); this.nameOpt = nameOpt; #if DEBUG // We shouldn't merged namespaces that are already merged. foreach (NamespaceSymbol ns in namespacesToMerge) { Debug.Assert(ns.ConstituentNamespaces.Length == 1); } #endif }
public override void LoadData() { base.LoadData(); m_pirateAntennas = new CachingDictionary<long, PirateAntennaInfo>(); m_definitionsByAntennaName = new Dictionary<string, MyPirateAntennaDefinition>(); m_droneInfos = new CachingDictionary<long, DroneInfo>(); foreach (var antennaDefinition in MyDefinitionManager.Static.GetPirateAntennaDefinitions()) { m_definitionsByAntennaName[antennaDefinition.Name] = antennaDefinition; } }
protected override void UnloadData() { base.UnloadData(); m_piratesIdentityId = 0; m_definitionsByAntennaName = null; foreach (var entry in m_droneInfos) { MyEntity entity; MyEntities.TryGetEntityById(entry.Key, out entity); if (entity != null) { UnregisterDrone(entity, immediate: false); } } m_droneInfos.Clear(); m_droneInfos = null; m_pirateAntennas = null; }
/// <summary> /// Gets a session snapshot customized for an individual player. Removes data that player does not need, /// which improves download times, and fixes some exploits. /// </summary> /// <param name="steamId"></param> /// <returns></returns> private static MyObjectBuilder_Checkpoint GetClientCheckpoint(ulong steamId) { Log.Info($"Saving checkpoint..."); var cpid = new MyObjectBuilder_Checkpoint.PlayerId(); cpid.ClientId = steamId; var ppid = new MyPlayer.PlayerId(steamId); if (_checkpoint == null) { _checkpoint = MyObjectBuilderSerializer.CreateNewObject <MyObjectBuilder_Checkpoint>(); _cameraSettings = new List <CameraControllerSettings>(); var settings = MyObjectBuilderSerializer.Clone(MySession.Static.Settings) as MyObjectBuilder_SessionSettings; bGps = MyObjectBuilderSerializer.CreateNewObject <MyObjectBuilder_Gps>(); bGps.Entries = new List <MyObjectBuilder_Gps.Entry>(); settings.ScenarioEditMode |= MySession.Static.PersistentEditMode; _checkpoint.SessionName = MySession.Static.Name; _checkpoint.Description = MySession.Static.Description; _checkpoint.PromotedUsers = new SerializableDictionary <ulong, MyPromoteLevel>(MySession.Static.PromotedUsers); _checkpoint.CreativeTools = new HashSet <ulong>(); _checkpoint.Settings = settings; //We're replacing the call to MySession.GetWorld, so Torch can't inject the torch mod. Do it here instead _checkpoint.Mods = MySession.Static.Mods.ToList(); _checkpoint.Mods.AddRange(SessionManager.OverrideMods); _checkpoint.Scenario = MySession.Static.Scenario.Id; _checkpoint.WorldBoundaries = MySession.Static.WorldBoundaries; _checkpoint.PreviousEnvironmentHostility = MySession.Static.PreviousEnvironmentHostility; _checkpoint.RequiresDX = MySession.Static.RequiresDX; _checkpoint.CustomSkybox = MySession.Static.CustomSkybox; _checkpoint.GameDefinition = MySession.Static.GameDefinition.Id; _checkpoint.Gps = new SerializableDictionary <long, MyObjectBuilder_Gps>(); _checkpoint.RespawnCooldowns = new List <MyObjectBuilder_Checkpoint.RespawnCooldownItem>(); _checkpoint.ControlledEntities = new SerializableDictionary <long, MyObjectBuilder_Checkpoint.PlayerId>(); _checkpoint.ChatHistory = new List <MyObjectBuilder_ChatHistory>(); _checkpoint.FactionChatHistory = new List <MyObjectBuilder_FactionChatHistory>(); _checkpoint.AppVersion = MyFinalBuildConstants.APP_VERSION; _checkpoint.SessionComponents = new List <MyObjectBuilder_SessionComponent>(); _checkpoint.AllPlayersData = new SerializableDictionary <MyObjectBuilder_Checkpoint.PlayerId, MyObjectBuilder_Player>(); _checkpoint.AllPlayersColors = new SerializableDictionary <MyObjectBuilder_Checkpoint.PlayerId, List <Vector3> >(); _checkpoint.Identities = new List <MyObjectBuilder_Identity>(); _checkpoint.Clients = new List <MyObjectBuilder_Client>(); _checkpoint.NonPlayerIdentities = new List <long>(); _checkpoint.CharacterToolbar = null; } _checkpoint.CreativeTools.Clear(); //Pool.DeallocateCollection(_checkpoint.Gps.Dictionary.Values); _checkpoint.Gps.Dictionary.Clear(); //Pool.DeallocateAndClear(bGps.Entries); bGps.Entries.Clear(); //Pool.DeallocateAndClear(_checkpoint.RespawnCooldowns); _checkpoint.RespawnCooldowns.Clear(); Pool.DeallocateAndClear(_checkpoint.ChatHistory); _checkpoint.ControlledEntities.Dictionary.Clear(); Pool.DeallocateAndClear(_checkpoint.FactionChatHistory); _checkpoint.SessionComponents.Clear(); Pool.DeallocateCollection(_checkpoint.AllPlayersData.Dictionary.Values); _checkpoint.AllPlayersData.Dictionary.Clear(); _checkpoint.AllPlayersColors.Dictionary.Clear(); Pool.DeallocateAndClear(_checkpoint.Identities); Pool.DeallocateAndClear(_checkpoint.Clients); _checkpoint.NonPlayerIdentities.Clear(); Pool.DeallocateAndClear(_cameraSettings); if (MySession.Static.CreativeToolsEnabled(steamId)) { _checkpoint.CreativeTools.Add(steamId); } //checkpoint.Briefing = Briefing; //checkpoint.BriefingVideo = BriefingVideo; _checkpoint.LastSaveTime = DateTime.Now; _checkpoint.WorkshopId = MySession.Static.WorkshopId; _checkpoint.ElapsedGameTime = MySession.Static.ElapsedGameTime.Ticks; _checkpoint.InGameTime = MySession.Static.InGameTime; //checkpoint.CharacterToolbar = MyToolbarComponent.CharacterToolbar.GetObjectBuilder(); //TODO _checkpoint.CustomLoadingScreenImage = MySession.Static.CustomLoadingScreenImage; _checkpoint.CustomLoadingScreenText = EssentialsPlugin.Instance.Config.LoadingText ?? MySession.Static.CustomLoadingScreenText; _checkpoint.SessionComponentDisabled = MySession.Static.SessionComponentDisabled; _checkpoint.SessionComponentEnabled = MySession.Static.SessionComponentEnabled; // checkpoint.PlayerToolbars = Toolbars.GetSerDictionary(); //Sync.Players.SavePlayers(_checkpoint); ConcurrentDictionary <MyPlayer.PlayerId, MyPlayer> m_players = Players_Getter(MySession.Static.Players); ConcurrentDictionary <MyPlayer.PlayerId, long> m_playerIdentityIds = PlayerIdentities_Getter(MySession.Static.Players); foreach (MyPlayer p in m_players.Values) { var id = new MyObjectBuilder_Checkpoint.PlayerId { ClientId = p.Id.SteamId, SerialId = p.Id.SerialId }; var playerOb = Pool.AllocateOrCreate <MyObjectBuilder_Player>(); playerOb.DisplayName = p.DisplayName; playerOb.IdentityId = p.Identity.IdentityId; playerOb.Connected = true; playerOb.ForceRealPlayer = p.IsRealPlayer; if (playerOb.BuildColorSlots == null) { playerOb.BuildColorSlots = new List <Vector3>(); } else { playerOb.BuildColorSlots.Clear(); } foreach (Vector3 color in p.BuildColorSlots) { playerOb.BuildColorSlots.Add(color); } _checkpoint.AllPlayersData.Dictionary.Add(id, playerOb); } foreach (KeyValuePair <MyPlayer.PlayerId, long> identityPair in m_playerIdentityIds) { if (m_players.ContainsKey(identityPair.Key)) { continue; } var id = new MyObjectBuilder_Checkpoint.PlayerId { ClientId = identityPair.Key.SteamId, SerialId = identityPair.Key.SerialId }; MyIdentity identity = MySession.Static.Players.TryGetIdentity(identityPair.Value); var playerOb = Pool.AllocateOrCreate <MyObjectBuilder_Player>(); playerOb.DisplayName = identity?.DisplayName; playerOb.IdentityId = identityPair.Value; playerOb.Connected = false; if (MyCubeBuilder.AllPlayersColors != null) { MyCubeBuilder.AllPlayersColors.TryGetValue(identityPair.Key, out playerOb.BuildColorSlots); } _checkpoint.AllPlayersData.Dictionary.Add(id, playerOb); } if (MyCubeBuilder.AllPlayersColors != null) { foreach (KeyValuePair <MyPlayer.PlayerId, List <Vector3> > colorPair in MyCubeBuilder.AllPlayersColors) { //TODO: check if the player exists in m_allIdentities if (m_players.ContainsKey(colorPair.Key) || m_playerIdentityIds.ContainsKey(colorPair.Key)) { continue; } var id = new MyObjectBuilder_Checkpoint.PlayerId { ClientId = colorPair.Key.SteamId, SerialId = colorPair.Key.SerialId }; _checkpoint.AllPlayersColors.Dictionary.Add(id, colorPair.Value); } } _checkpoint.AllPlayersData.Dictionary.TryGetValue(cpid, out MyObjectBuilder_Player player); if (player != null) { //Toolbars.SaveToolbars(checkpoint); MyToolbar toolbar = MySession.Static.Toolbars.TryGetPlayerToolbar(ppid); if (toolbar != null) { player.Toolbar = toolbar.GetObjectBuilder(); } else if (EssentialsPlugin.Instance.Config.EnableToolbarOverride) { player.Toolbar = EssentialsPlugin.Instance.Config.DefaultToolbar; _checkpoint.CharacterToolbar = EssentialsPlugin.Instance.Config.DefaultToolbar; } //MySession.Static.Cameras.SaveCameraCollection(checkpoint); player.EntityCameraData = _cameraSettings; Dictionary <MyPlayer.PlayerId, Dictionary <long, MyEntityCameraSettings> > d = EntityCameraSettings; if (d.TryGetValue(ppid, out Dictionary <long, MyEntityCameraSettings> camera)) { foreach (KeyValuePair <long, MyEntityCameraSettings> cameraSetting in camera) { var set = Pool.AllocateOrCreate <CameraControllerSettings>(); set.Distance = cameraSetting.Value.Distance; set.IsFirstPerson = cameraSetting.Value.IsFirstPerson; set.HeadAngle = cameraSetting.Value.HeadAngle; set.EntityId = cameraSetting.Key; player.EntityCameraData.Add(set); } } //Gpss.SaveGpss(checkpoint); foreach (IMyGps igps in MyAPIGateway.Session.GPS.GetGpsList(player.IdentityId)) { var gps = igps as MyGps; if (!gps.IsLocal) { if (gps.EntityId == 0 || MyEntities.GetEntityById(gps.EntityId) != null) { var builder = new MyObjectBuilder_Gps.Entry { name = gps.Name, description = gps.Description, coords = gps.Coords, isFinal = gps.DiscardAt == null, showOnHud = gps.ShowOnHud, alwaysVisible = gps.AlwaysVisible, color = gps.GPSColor, entityId = gps.EntityId, DisplayName = gps.DisplayName }; bGps.Entries.Add(builder); } } } _checkpoint.Gps.Dictionary.Add(player.IdentityId, bGps); } //bunch of allocations in here, but can't replace the logic easily because private types _checkpoint.Factions = MySession.Static.Factions.GetObjectBuilder(); //ok for now, clients need to know about dead identities. Might filter out those that own no blocks. //amount of data per ID is low, and admins usually clean them, so meh //_checkpoint.Identities = Sync.Players.SaveIdentities(); foreach (MyIdentity identity in MySession.Static.Players.GetAllIdentities()) { if (MySession.Static.Players.TryGetPlayerId(identity.IdentityId, out MyPlayer.PlayerId id)) { MyPlayer p = MySession.Static.Players.GetPlayerById(id); if (p != null) { identity.LastLogoutTime = DateTime.Now; } } var objectBuilder = Pool.AllocateOrCreate <MyObjectBuilder_Identity>(); objectBuilder.IdentityId = identity.IdentityId; objectBuilder.DisplayName = identity.DisplayName; objectBuilder.CharacterEntityId = identity.Character?.EntityId ?? 0; objectBuilder.Model = identity.Model; objectBuilder.ColorMask = identity.ColorMask; objectBuilder.BlockLimitModifier = identity.BlockLimits.BlockLimitModifier; objectBuilder.LastLoginTime = identity.LastLoginTime; objectBuilder.LastLogoutTime = identity.LastLogoutTime; objectBuilder.SavedCharacters = identity.SavedCharacters; objectBuilder.RespawnShips = identity.RespawnShips; objectBuilder.LastDeathPosition = identity.LastDeathPosition; _checkpoint.Identities.Add(objectBuilder); } Sync.Players.RespawnComponent.SaveToCheckpoint(_checkpoint); //count for these is low, and the store is internal, so removing unnecessary entries is cheaper than reflection (probably?) _checkpoint.RespawnCooldowns.RemoveAll(i => i.PlayerSteamId != steamId); //checkpoint.ControlledEntities = Sync.Players.SerializeControlledEntities(); foreach (KeyValuePair <long, MyPlayer.PlayerId> entry in MySession.Static.Players.ControlledEntities) { if (entry.Value.SteamId == steamId) { _checkpoint.ControlledEntities.Dictionary.Add(entry.Key, cpid); } } //checkpoint.SpectatorPosition = new MyPositionAndOrientation(ref spectatorMatrix); //checkpoint.SpectatorIsLightOn = MySpectatorCameraController.Static.IsLightOn; //checkpoint.SpectatorCameraMovement = MySpectator.Static.SpectatorCameraMovement; //checkpoint.SpectatorDistance = (float)MyThirdPersonSpectator.Static.GetViewerDistance(); //checkpoint.CameraController = cameraControllerEnum; //if (cameraControllerEnum == MyCameraControllerEnum.Entity) // checkpoint.CameraEntity = ((MyEntity)CameraController).EntityId; //if (ControlledEntity != null) //{ // checkpoint.ControlledObject = ControlledEntity.Entity.EntityId; // if (ControlledEntity is MyCharacter) // { // Debug.Assert(LocalCharacter == null || !(LocalCharacter.IsUsing is MyCockpit), "Character in cockpit cannot be controlled entity"); // } //} //else _checkpoint.ControlledObject = -1; //SaveChatHistory(checkpoint); /* * if (player != null && MySession.Static.ChatHistory.TryGetValue(player.IdentityId, out MyChatHistory playerChat)) * { * var builder = Pool.AllocateOrCreate<MyObjectBuilder_ChatHistory>(); * builder.IdentityId = playerChat.IdentityId; * if (builder.PlayerChatHistory != null) * Pool.DeallocateAndClear(builder.PlayerChatHistory); * else * builder.PlayerChatHistory = new List<MyObjectBuilder_PlayerChatHistory>(); * foreach (MyPlayerChatHistory chat in playerChat.PlayerChatHistory.Values) * { * var cb = Pool.AllocateOrCreate<MyObjectBuilder_PlayerChatHistory>(); * if (cb.Chat != null) * Pool.DeallocateAndClear(cb.Chat); * else * cb.Chat = new List<MyObjectBuilder_PlayerChatItem>(); * cb.IdentityId = chat.IdentityId; * foreach (MyPlayerChatItem m in chat.Chat) * { * var mb = Pool.AllocateOrCreate<MyObjectBuilder_PlayerChatItem>(); * mb.Text = m.Text; * mb.IdentityIdUniqueNumber = MyEntityIdentifier.GetIdUniqueNumber(m.IdentityId); * mb.TimestampMs = (long)m.Timestamp.TotalMilliseconds; * mb.Sent = m.Sent; * cb.Chat.Add(mb); * } * builder.PlayerChatHistory.Add(cb); * } * * if (builder.GlobalChatHistory == null) * builder.GlobalChatHistory = Pool.AllocateOrCreate<MyObjectBuilder_GlobalChatHistory>(); * if (builder.GlobalChatHistory.Chat != null) * Pool.DeallocateAndClear(builder.GlobalChatHistory.Chat); * else * builder.GlobalChatHistory.Chat = new List<MyObjectBuilder_GlobalChatItem>(); * * foreach (MyGlobalChatItem g in playerChat.GlobalChatHistory.Chat) * { * var gb = Pool.AllocateOrCreate<MyObjectBuilder_GlobalChatItem>(); * gb.Text = g.Text; * gb.Font = g.AuthorFont; * if (g.IdentityId == 0) * { * gb.IdentityIdUniqueNumber = 0; * gb.Author = g.Author; * } * else * { * gb.IdentityIdUniqueNumber = MyEntityIdentifier.GetIdUniqueNumber(g.IdentityId); * gb.Author = string.Empty; * } * builder.GlobalChatHistory.Chat.Add(gb); * } * * _checkpoint.ChatHistory.Add(builder); * } * * if (player != null) * { * IMyFaction pfac = MySession.Static.Factions.TryGetPlayerFaction(player.IdentityId); * if (pfac != null) * { * foreach (MyFactionChatHistory history in MySession.Static.FactionChatHistory) * { * if (history.FactionId1 == pfac.FactionId || history.FactionId2 == pfac.FactionId) * { * var builder = Pool.AllocateOrCreate<MyObjectBuilder_FactionChatHistory>(); * if (builder.Chat != null) * Pool.DeallocateAndClear(builder.Chat); * else * builder.Chat = new List<MyObjectBuilder_FactionChatItem>(); * * builder.FactionId1 = history.FactionId1; * builder.FactionId2 = history.FactionId2; * * foreach (MyFactionChatItem fc in history.Chat) * { * if (fc.PlayersToSendTo != null && fc.PlayersToSendTo.Count > 0) * { * var fb = Pool.AllocateOrCreate<MyObjectBuilder_FactionChatItem>(); * fb.Text = fc.Text; * fb.IdentityIdUniqueNumber = MyEntityIdentifier.GetIdUniqueNumber(fc.IdentityId); * fb.TimestampMs = (long)fc.Timestamp.TotalMilliseconds; * if (fb.PlayersToSendToUniqueNumber != null) * fb.PlayersToSendToUniqueNumber.Clear(); * else * fb.PlayersToSendToUniqueNumber = new List<long>(); * if (fb.IsAlreadySentTo != null) * fb.IsAlreadySentTo.Clear(); * else * fb.IsAlreadySentTo = new List<bool>(); * foreach (KeyValuePair<long, bool> pair in fc.PlayersToSendTo) * { * fb.PlayersToSendToUniqueNumber.Add(MyEntityIdentifier.GetIdUniqueNumber(pair.Key)); * fb.IsAlreadySentTo.Add(pair.Value); * } * builder.Chat.Add(fb); * } * } * } * } * } * } */ //_checkpoint.Clients = SaveMembers_Imp(MySession.Static, false); if (MyMultiplayer.Static.Members.Count() > 1) { foreach (ulong member in MyMultiplayer.Static.Members) { var ob = Pool.AllocateOrCreate <MyObjectBuilder_Client>(); ob.SteamId = member; ob.Name = MyMultiplayer.Static.GetMemberName(member); ob.IsAdmin = MySession.Static.IsUserAdmin(member); _checkpoint.Clients.Add(ob); } } //_checkpoint.NonPlayerIdentities = Sync.Players.SaveNpcIdentities(); foreach (long npc in MySession.Static.Players.GetNPCIdentities()) { _checkpoint.NonPlayerIdentities.Add(npc); } //SaveSessionComponentObjectBuilders(checkpoint); CachingDictionary <Type, MySessionComponentBase> compDic = SessionComponents_Getter(MySession.Static); foreach (KeyValuePair <Type, MySessionComponentBase> entry in compDic) { //literally dozens of MB of duplicated garbage. Ignore all of it. //TODO: Keen fixed the duplication but this shouldn't exist at all. Rexxar has a plan //if (entry.Value is MyProceduralWorldGenerator) // continue; MyObjectBuilder_SessionComponent ob = entry.Value.GetObjectBuilder(); if (ob != null) { _checkpoint.SessionComponents.Add(ob); } } _checkpoint.ScriptManagerData = MySession.Static.ScriptManager.GetObjectBuilder(); //skipped on DS //GatherVicinityInformation(checkpoint); //if (OnSavingCheckpoint != null) // OnSavingCheckpoint(checkpoint); Log.Info("Done."); return(_checkpoint); }
private void RetryLastSeen() { foreach (KeyValuePair <long, CachingList <LastSeen.Builder_LastSeen> > storageLastSeen in m_failedLastSeen) { RelayNode node; if (Registrar.TryGetValue(storageLastSeen.Key, out node)) { RelayStorage store = node.Storage; foreach (LastSeen.Builder_LastSeen builder in storageLastSeen.Value) { if (MyAPIGateway.Entities.EntityExists(builder.EntityId)) { LastSeen ls = new LastSeen(builder); if (ls.IsValid) { Logger.DebugLog("Successfully created a LastSeen. Primary node: " + storageLastSeen.Key + ", entity: " + ls.Entity.nameWithId()); storageLastSeen.Value.Remove(builder); } else { Logger.AlwaysLog("Unknown failure with last seen", Rynchodon.Logger.severity.ERROR); } } else { Logger.DebugLog("Not yet available: " + builder.EntityId); } } storageLastSeen.Value.ApplyRemovals(); if (storageLastSeen.Value.Count == 0) { Logger.DebugLog("Finished with: " + storageLastSeen.Key, Rynchodon.Logger.severity.DEBUG); m_failedLastSeen.Remove(storageLastSeen.Key); } else { Logger.DebugLog("For " + storageLastSeen.Key + ", " + storageLastSeen.Value.Count + " builders remain"); } } else { Logger.DebugLog("Failed to get node for " + storageLastSeen.Key, Rynchodon.Logger.severity.WARNING); } } m_failedLastSeen.ApplyRemovals(); if (m_failedLastSeen.Count() == 0) { Logger.DebugLog("All LastSeen have been successfully added", Rynchodon.Logger.severity.INFO); m_failedLastSeen = null; UpdateManager.Unregister(100, RetryLastSeen); } else { Logger.DebugLog(m_failedLastSeen.Count() + " primary nodes still have last seen to be added"); if (Globals.UpdateCount >= 3600) { foreach (KeyValuePair <long, CachingList <LastSeen.Builder_LastSeen> > storageLastSeen in m_failedLastSeen) { foreach (LastSeen.Builder_LastSeen builder in storageLastSeen.Value) { Logger.AlwaysLog("Failed to add last seen to world. Primary node: " + storageLastSeen.Key + ", entity ID: " + builder.EntityId, Rynchodon.Logger.severity.WARNING); } } m_failedLastSeen = null; UpdateManager.Unregister(100, RetryLastSeen); } } }