Иконка ресурса

FREE LootConfig : 1.0.0 1.0.0

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
// Reference: Oxide.Ext.Rust
// Reference: Newtonsoft.Json

using System.Collections.Generic;
using System.Linq;

using Rust;

using System;
using System.IO;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

using UnityEngine;

using JSONObject = JSON.Object;
using JSONArray = JSON.Array;
using JSONValue = JSON.Value;
using JSONValueType = JSON.ValueType;

namespace Oxide.Plugins
{
    [Info("LootConfig", "Nogrod", "1.0.0")]
    class LootConfig : RustPlugin
    {
        private readonly Regex _findLoot = new Regex("loot|crate|supply_drop", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        private string _configpath = "";

        void Loaded()
        {
            _configpath = Manager.ConfigPath + string.Format("\\{0}.json", Name);
        }

        new void LoadDefaultConfig()
        {
        }

        private static JSONObject ToJsonObject(object obj)
        {
            return JSONObject.Parse(ToJsonString(obj));
        }

        private static string ToJsonString(object obj)
        {
            return JsonConvert.SerializeObject(obj, new JsonSerializerSettings
            {
                ContractResolver = new DynamicContractResolver(),
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                Converters = new List<JsonConverter> { new Newtonsoft.Json.Converters.StringEnumConverter() }
            });
        }

        private bool CreateDefaultConfig()
        {
            Config.Clear();
            Config["Version"] = Protocol.network;
            var containers = Resources.FindObjectsOfTypeAll<LootContainer>();
            foreach (var lootContainer in containers)
            {
                if (Config[lootContainer.lootDefinition.name.Substring(10)] != null) continue;
                var obj = ToJsonObject(lootContainer);
                StripLoot(obj.GetObject("lootDefinition"), obj, "lootDefinition");
                Config[lootContainer.lootDefinition.name.Substring(10)] = JsonObjectToObject(obj);
            }
            try
            {
                Config.Save(_configpath);
            }
            catch (Exception e)
            {
                LocalPuts(e.Message);
                return false;
            }
            LocalPuts("Created new config");
            return LoadConfig();
        }

        private bool LoadConfig()
        {
            try
            {
                Config.Load(_configpath);
            }
            catch (FileNotFoundException)
            {
                return CreateDefaultConfig();
            }
            catch (Exception e)
            {
                LocalPuts(e.Message);
                return false;
            }
            return true;
        }

        private void CheckConfig()
        {
            if (Config["Version"] != null && (int)Config["Version"] == Protocol.network) return;
            LocalPuts("Incorrect config version(" + Config["Version"] + ") move to.old");
            if (Config["Version"] != null) Config.Save(string.Format("{0}.old", _configpath));
            CreateDefaultConfig();
        }

        private void UpdateLoot()
        {
            var containers = Resources.FindObjectsOfTypeAll<LootContainer>();
            var done = new HashSet<LootSpawn>();
            // Cleanup old instances
            var loot = Resources.FindObjectsOfTypeAll<LootSpawn>();
            foreach (var lootContainer in containers)
            {
                done.Add(lootContainer.lootDefinition);
            }
            foreach (var lootSpawn in loot)
            {
                if (!done.Contains(lootSpawn))
                {
                    UnityEngine.Object.Destroy(lootSpawn);
                }
            }
            done.Clear();
            // Cleanup done
            foreach (var lootContainer in containers)
            {
                var obj = ObjectToJsonObject(Config[lootContainer.lootDefinition.name.Substring(10)]).Obj;
                lootContainer.maxDefinitionsToSpawn = obj.GetInt("maxDefinitionsToSpawn", 0);
                lootContainer.minSecondsBetweenRefresh = obj.GetFloat("minSecondsBetweenRefresh", 3600);
                lootContainer.maxSecondsBetweenRefresh = obj.GetFloat("maxSecondsBetweenRefresh", 7200);
                lootContainer.destroyOnEmpty = obj.GetBoolean("destroyOnEmpty", true);
                if (!done.Contains(lootContainer.lootDefinition))
                {
                    UpdateLootSpawn(lootContainer.lootDefinition, obj, "lootDefinition");
                    done.Add(lootContainer.lootDefinition);
                }
            }
        }

        private void UpdateLootSpawn(LootSpawn lootSpawn, JSONObject obj, string path)
        {
            var value = obj.GetValue(path);
            if (value != null && value.Type == JSONValueType.Array && value.Array.Length > 0)
            {
                lootSpawn.items = new ItemAmount[0];
                lootSpawn.blueprints = new ItemAmount[0];
                lootSpawn.subSpawn = new LootSpawn.Entry[value.Array.Length];
                for (var i = 0; i < lootSpawn.subSpawn.Length; i++)
                {
                    lootSpawn.subSpawn[i] = new LootSpawn.Entry { category = ScriptableObject.CreateInstance<LootSpawn>(), weight = value.Array[i].Obj.GetInt("weight", 0) };
                    UpdateLootSpawn(lootSpawn.subSpawn[i].category, value.Array[i].Obj, "category");
                }
                return;
            }
            var itemsValue = obj.GetValue("items");
            if (itemsValue != null && itemsValue.Type == JSONValueType.Array && itemsValue.Array.Length > 0)
            {
                var items = itemsValue.Array;
                lootSpawn.items = new ItemAmount[items.Length];
                for (var i = 0; i < items.Length; i++)
                {
                    var def = ItemManager.FindItemDefinition(items[i].Obj.GetString("item", "unnamed"));
                    //TODO null check
                    lootSpawn.items[i] = new ItemAmount(def, items[i].Obj.GetFloat("amount", 0));
                }
            }
            var blueprintsValue = obj.GetValue("blueprints");
            if (blueprintsValue != null && blueprintsValue.Type == JSONValueType.Array && blueprintsValue.Array.Length > 0)
            {
                var blueprints = blueprintsValue.Array;
                lootSpawn.blueprints = new ItemAmount[blueprints.Length];
                for (var i = 0; i < blueprints.Length; i++)
                {
                    var def = ItemManager.FindItemDefinition(blueprints[i].Obj.GetString("item", "unnamed"));
                    //TODO null check
                    lootSpawn.blueprints[i] = new ItemAmount(def, blueprints[i].Obj.GetFloat("amount", 0));
                }
            }
        }

        void OnServerInitialized()
        {
            if (!LoadConfig())
                return;
            var prefabs = GameManifest.Get().pooledStrings.ToList().ConvertAll(p => p.str).Where(p => _findLoot.IsMatch("loot|crate|supply_drop")).ToArray();
            foreach (var source in prefabs)
            {
                GameManager.server.FindPrefab(source);
            }
            CheckConfig();
            UpdateLoot();
        }

        private void StripLoot(JSONObject obj, JSONObject parent = null, string path = null)
        {
            var value = obj.GetValue("subSpawn");
            if (value != null && value.Type == JSONValueType.Array && value.Array.Length > 0)
            {
                if (parent != null)
                {
                    parent[path] = obj.GetArray("subSpawn");
                }
                obj.Remove("items");
                obj.Remove("blueprints");
                StripSubCategoryLoot(obj.GetArray("subSpawn"));
                return;
            }
            obj.Remove("subSpawn");
            var items = obj.GetValue("items");
            if (items != null && items.Type == JSONValueType.Array)
            {
                foreach (var item in items.Array)
                {
                    StripEntry(item.Obj);
                }
            }
            var bps = obj.GetValue("blueprints");
            if (bps != null && bps.Type == JSONValueType.Array)
            {
                foreach (var bp in bps.Array)
                {
                    StripEntry(bp.Obj);
                }
            }
            if (parent != null && path != null && path.Equals("category"))
            {
                parent["items"] = items;
                parent["blueprints"] = bps;
                parent.Remove("category");
            }
        }

        private static void StripEntry(JSONObject obj)
        {
            obj["item"] = obj.GetObject("itemDef").GetString("shortname", "unnamed");
            obj.Remove("itemDef");
            obj.Remove("itemid");
        }

        private void StripSubCategoryLoot(JSONArray arr)
        {
            //float sum = arr.Sum(x => x.Obj.GetFloat("weight", 0)), curSum = sum;
            foreach (var entry in arr)
            {
                StripLoot(entry.Obj.GetObject("category"), entry.Obj, "category");
                //curSum -= entry.Obj.GetFloat("weight", 0);
                //entry.Obj["percent"] = Math.Round((sum - curSum)/(sum/100f), 2);
            }
        }

        private JSONValue ObjectToJsonObject(object obj)
        {
            if (obj == null)
            {
                return new JSONValue(JSONValueType.Null);
            }
            if (obj is string)
            {
                return new JSONValue((string)obj);
            }
            if (obj is double)
            {
                return new JSONValue((double)obj);
            }
            if (obj is int)
            {
                return new JSONValue((int)obj);
            }
            if (obj is bool)
            {
                return new JSONValue((bool)obj);
            }
            var dict = obj as Dictionary<string, object>;
            if (dict != null)
            {
                var newObj = new JSONObject();
                foreach (var prop in dict)
                {
                    newObj.Add(prop.Key, ObjectToJsonObject(prop.Value));
                }
                return newObj;
            }
            var list = obj as List<object>;
            if (list != null)
            {
                var arr = new JSONArray();
                foreach (var o in list)
                {
                    arr.Add(ObjectToJsonObject(o));
                }
                return arr;
            }
            LocalPuts("Unknown: " + obj.GetType().FullName + " Value: " + obj);
            return new JSONValue(JSONValueType.Null);
        }

        private object JsonObjectToObject(JSONValue obj)
        {
            switch (obj.Type)
            {
                case JSONValueType.String:
                    return obj.Str;
                case JSONValueType.Number:
                    return obj.Number;
                case JSONValueType.Boolean:
                    return obj.Boolean;
                case JSONValueType.Null:
                    return null;
                case JSONValueType.Array:
                    return obj.Array.Select(v => JsonObjectToObject(v.Obj)).ToList();
                case JSONValueType.Object:
                    var dict = new Dictionary<string, object>();
                    foreach (var prop in obj.Obj)
                    {
                        dict[prop.Key] = JsonObjectToObject(prop.Value);
                    }
                    return dict;
                default:
                    LocalPuts("Missing type: " + obj.Type);
                    break;
            }
            return null;
        }

        private void LocalPuts(string msg)
        {
            Puts("{0}: {1}", Title, msg);
        }

        [ConsoleCommand("loot.reload")]
        void cmdConsoleReload(ConsoleSystem.Arg arg)
        {
            if (!LoadConfig())
                return;
            CheckConfig();
            UpdateLoot();
            LocalPuts("Loot config reloaded.");
        }

        class DynamicContractResolver : DefaultContractResolver
        {
            private static bool IsAllowed(JsonProperty property)
            {
                return property.PropertyType.IsPrimitive||
                        property.PropertyType == typeof(ItemAmount[]) ||
                        property.PropertyType == typeof(ItemDefinition) ||
                        property.PropertyType == typeof(String) ||
                        property.PropertyType == typeof(LootSpawn) ||
                        property.PropertyType == typeof(LootSpawn.Entry[]);
            }

            protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
            {
                var properties = base.CreateProperties(type, memberSerialization);
                return properties.Where(p => (p.DeclaringType == type || p.DeclaringType == typeof(LootContainer)) && IsAllowed(p)).ToList();
            }
        }
    }
}

Автор
15FPS
Скачиваний
0
Просмотры
1
Первый выпуск
Обновление
Оценка
0.00 звёзд 0 оценок
Сверху