private static void SpawnedDeployablesRemove(int id, JDeployable instance)
        {
            spawnedDeployables.Remove(id);

            Type type;

            if (!TryGetType(instance.ToString(), out type))
            {
                return;
            }

            if (spawnedDeployablesByType.ContainsKey(type))
            {
                spawnedDeployablesByType[type].Remove(instance);
            }

            JInfoAttribute info;

            if (!DeployableTypes.TryGetValue(type, out info))
            {
                return;
            }

            if (spawnedDeployablesByPlugin.ContainsKey(info.PluginInfo.Title))
            {
                spawnedDeployablesByPlugin[info.PluginInfo.Title].Remove(instance);
            }
        }
        public static void LoadJDeployables(string pluginname)
        {
            if (!DeployableTypesByPlugin.ContainsKey(pluginname))
            {
                return;
            }

            if (DataManager.data == null || DataManager.data.p == null)
            {
                DataManager.Load();
            }

            Dictionary <int, DeployableSaveData> pluginsavedata;

            if (!DataManager.data.p.TryGetValue(pluginname, out pluginsavedata))
            {
                return;
            }

            int totalloadcount = 0;
            Dictionary <JInfoAttribute, int> loadcount = new Dictionary <JInfoAttribute, int>();

            foreach (var de in pluginsavedata)
            {
                Type           deployabletype;
                JInfoAttribute info;
                if (TryGetType(de.Value.t, out deployabletype) && DeployableTypes.TryGetValue(deployabletype, out info))
                {
                    if (!loadcount.Keys.Contains(info))
                    {
                        loadcount.Add(info, 0);
                    }
                    if (LoadJDeployable(de.Key, de.Value))
                    {
                        loadcount[info]++;
                        totalloadcount++;
                    }
                    else
                    {
                        Interface.Oxide.LogWarning($"[JtechCore] Failed to Load JDeployable: [{pluginname}] {de.Value} {de.Key}");
                    }
                }
            }

            string top = $"--- {totalloadcount} JDeployable(s) from {pluginname} Loaded ---";

            Interface.Oxide.LogInfo($"[JtechCore] {top}");
            foreach (var count in loadcount)
            {
                Interface.Oxide.LogInfo($"[JtechCore] > {count.Value} {count.Key.Name}(s)");
            }
            Interface.Oxide.LogInfo($"[JtechCore] {new String('-', top.Length)}");
        }
        private static bool SaveJDeployable(int id, JDeployable d)
        {
            DeployableSaveData sd = new DeployableSaveData {
                t = d.ToString(),
                s = d.data
            };

            JInfoAttribute info = null;

            if (!DeployableTypes.TryGetValue(d.GetType(), out info))
            {
                return(false);
            }

            if (!DataManager.data.p.ContainsKey(info.PluginInfo.Title))
            {
                DataManager.data.p.Add(info.PluginInfo.Title, new Dictionary <int, DeployableSaveData>());
            }

            DataManager.data.p[info.PluginInfo.Title].Add(id, sd);

            return(true);
        }
        private static void SpawnedDeployablesAdd(int id, JDeployable instance, Type type)
        {
            spawnedDeployables.Add(id, instance);

            if (!spawnedDeployablesByType.ContainsKey(type))
            {
                spawnedDeployablesByType.Add(type, new List <JDeployable>());
            }
            spawnedDeployablesByType[type].Add(instance);

            JInfoAttribute info;

            if (!DeployableTypes.TryGetValue(type, out info))
            {
                return;
            }

            if (!spawnedDeployablesByPlugin.ContainsKey(info.PluginInfo.Title))
            {
                spawnedDeployablesByPlugin.Add(info.PluginInfo.Title, new List <JDeployable>());
            }
            spawnedDeployablesByPlugin[info.PluginInfo.Title].Add(instance);
        }
        public static void SaveJDeployables(string pluginname)
        {
            if (!DeployableTypesByPlugin.ContainsKey(pluginname))
            {
                return;
            }

            if (DataManager.data == null || DataManager.data.p == null)
            {
                DataManager.Load();
            }

            Dictionary <int, DeployableSaveData> pluginsavedata;

            if (DataManager.data.p.ContainsKey(pluginname))
            {
                if (!DataManager.data.p.TryGetValue(pluginname, out pluginsavedata))
                {
                    return;
                }
            }
            else
            {
                pluginsavedata = new Dictionary <int, DeployableSaveData>();
                DataManager.data.p.Add(pluginname, pluginsavedata);
            }

            pluginsavedata.Clear();

            int totalsavecount = 0;
            Dictionary <JInfoAttribute, int> savecount = new Dictionary <JInfoAttribute, int>();

            List <JDeployable> deps;

            if (!spawnedDeployablesByPlugin.TryGetValue(pluginname, out deps))
            {
                return;
            }

            foreach (var de in deps)
            {
                JInfoAttribute info;
                if (DeployableTypes.TryGetValue(de.GetType(), out info))
                {
                    if (!savecount.ContainsKey(info))
                    {
                        savecount.Add(info, 0);
                    }

                    if (SaveJDeployable(de.Id, de))
                    {
                        totalsavecount++;
                        savecount[info]++;
                    }
                    else
                    {
                        Interface.Oxide.LogWarning($"[JtechCore] Failed to Save JDeployable: [{pluginname}] {info.Name} {de.Id}");
                    }
                }
            }

            string top = $"--- {totalsavecount} JDeployable(s) from {pluginname} Saved ---";

            Interface.Oxide.LogInfo($"[JtechCore] {top}");
            foreach (var count in savecount)
            {
                if (count.Value > 0)
                {
                    Interface.Oxide.LogInfo($"[JtechCore] > {count.Value} {count.Key.Name}(s)");
                }
            }
            Interface.Oxide.LogInfo($"[JtechCore] {new String('-', top.Length)}");
        }