예제 #1
0
        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));
        }
예제 #2
0
        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());
        }
예제 #4
0
        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]);
            }
        }
예제 #5
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;
            }
        }
예제 #7
0
        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];
        }
예제 #8
0
        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);
        }
예제 #9
0
        // 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
        }
예제 #10
0
        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]);
            }
        }
예제 #11
0
        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;
        }
예제 #12
0
        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);
        }
예제 #13
0
파일: Saver.cs 프로젝트: zrisher/ARMS
        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
        }
예제 #15
0
        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;
            }
        }
예제 #16
0
        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;
        }
예제 #17
0
        /// <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);
        }
예제 #18
0
파일: Saver.cs 프로젝트: zrisher/ARMS
        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);
                }
            }
        }