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

FREE Stacks : 1.0.8 1.0.8

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
#region License (GPL v2)
/*
    Stacks.cs - Set stack sizes by item name, held, item, or category
    Copyright (c) 2021-2023 RFC1920 <desolationoutpostpve@gmail.com>

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; version 2
    of the License only.This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
    GNU General Public License for more details.You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.Optionally you can also view the license at <http://www.gnu.org/licenses/>.*/
#endregion
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Libraries.Covalence;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;

namespace Oxide.Plugins
{
    [Info("Stacks", "RFC1920", "1.0.8")]
    [Description("Manage stack sizes for items in Rust.")]
    internal class Stacks : RustPlugin
    {
        #region vars
        private SortedDictionary<string, SortedDictionary<string, int>> cat2items = new SortedDictionary<string, SortedDictionary<string, int>>();
        private SortedDictionary<string, string> name2cat = new SortedDictionary<string, string>();
        private DynamicConfigFile data, bdata;
        private ConfigData configData;
        private const string permAdmin = "stacks.admin";
        #endregion

        #region Message
        private string Lang(string key, string id = null, params object[] args) => string.Format(lang.GetMessage(key, this, id), args);
        private void Message(IPlayer player, string key, params object[] args) => player.Message(Lang(key, player.Id, args));
        #endregion

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["notauthorized"] = "You don't have permission to use this command.",
                ["current"] = "Current stack size for {0} is {1}",
                ["stackset"] = "Stack size for {0} is now {1}",
                ["notexist"] = "Item {0} does not exist.",
                ["helptext1"] = "Type /stack itemname OR hold an entity and type /stack.",
                ["helptext2"] = "Categories:\n{0}Type /stcat CATEGORY to list items in that category.",
                ["itemlist"] = "Items in {0}:\n{1}\n  To set the stack size for all items in this category, add the value to the end of this command, e.g./stcat traps 10\n  THIS IS NOT REVERSIBLE!",
                ["catstack"] = "The stack size for each item in category {0} was set to {1}.",
                ["invalid"] = "Invalid item {0} selected.",
                ["found"] = "Found {0} matching item(s)\n{1}",
                ["imported"] = "Imported {0} item(s)",
                ["exported"] = "Exported {0} item(s)",
                ["importfail"] = "Import failed :(",
                ["none"] = "None",
                ["invalidc"] = "Invalid category: {0}."
            }, this);
        }

        private void OnServerInitialized()
        {
            LoadConfigVariables();
            LoadData();
            UpdateItemList();

            permission.RegisterPermission(permAdmin, this);
            AddCovalenceCommand("stack", "CmdStackInfo");
            AddCovalenceCommand("stcat", "CmdStackCats");
            AddCovalenceCommand("stimport", "CmdStackImport");
            AddCovalenceCommand("stexport", "CmdStackExport");
        }

        private void Unload()
        {
            SaveData();
        }

        private string GetHeldItem(BasePlayer player)
        {
            if (player == null) return null;

            HeldEntity held = player.GetHeldEntity();

            return held.ShortPrefabName == "planner" ? held.GetOwnerItemDefinition().name : held.GetItem().info.name;
        }

        /// <summary>
        /// for SSC conversion
        /// </summary>
        private class Items
        {
            public Dictionary<string, int> itemlist = new Dictionary<string, int>();
        }

        private void CmdStackExport(IPlayer iplayer, string command, string[] args)
        {
            if (!iplayer.IsAdmin && !permission.UserHasPermission(iplayer.Id, permAdmin)) { Message(iplayer, "notauthorized"); return; }
            DynamicConfigFile ssc = Interface.Oxide.DataFileSystem.GetFile("StackSizeController");
            List<ItemDefinition> itemList = ItemManager.GetItemDefinitions();
            Dictionary<string, int> forSSC = new Dictionary<string, int>();
            int i = 0;

            foreach (KeyValuePair<string, SortedDictionary<string, int>> category in cat2items)
            {
                Puts($"Export working on category {category.Key}");
                foreach (KeyValuePair<string, int> item in category.Value)
                {
                    Puts($"  Item: {item.Key}");
                    string mykey = (from rv in itemList where rv.name.Equals(item.Key) select rv.displayName.english).FirstOrDefault();
                    if (mykey == null) continue;
                    if (!forSSC.ContainsKey(mykey) && !string.IsNullOrEmpty(mykey))
                    {
                        forSSC.Add(mykey, item.Value);
                        i++;
                    }
                }
            }
            Items sscItems = new Items()
            {
                itemlist = forSSC
            };
            ssc.WriteObject(sscItems);
            Message(iplayer, "exported", i.ToString());
        }

        private void CmdStackImport(IPlayer iplayer, string command, string[] args)
        {
            if (!iplayer.IsAdmin && !permission.UserHasPermission(iplayer.Id, permAdmin)) { Message(iplayer, "notauthorized"); return; }
            Puts("Opening data file for SSC");
            DynamicConfigFile ssc = Interface.Oxide.DataFileSystem.GetFile("StackSizeController");
            Items sscitems = ssc.ReadObject<Items>();
            Puts("Successfully read object");
            List<ItemDefinition> itemList = ItemManager.GetItemDefinitions();

            cat2items = new SortedDictionary<string, SortedDictionary<string, int>>();
            name2cat = new SortedDictionary<string, string>();
            ItemDefinition id = null;

            int i = 0;
            int stack = 0;
            foreach (KeyValuePair<string, int> item in sscitems.itemlist)
            {
                Puts($"Processing '{item.Key}' in SSC itemlist.");

                foreach (ItemDefinition idef in itemList)
                {
                    if (idef.displayName.english == item.Key)
                    {
                        id = idef;
                        stack = item.Value;
                        break;
                    }
                }
                if (id == null || stack == 0) continue;

                string nm = id.name;
                string cat = id.category.ToString().ToLower();

                Puts($"{item.Key} ({nm}): category {cat}, stack size {stack}");

                if (!cat2items.ContainsKey(cat))
                {
                    // Category missing, create it
                    cat2items.Add(cat, new SortedDictionary<string, int>());
                }

                cat2items[cat].Add(nm, stack);

                name2cat.Add(nm, cat);
                i++;
            }
            if (i > 0)
            {
                Message(iplayer, "imported", i.ToString());
                SaveData();
                LoadData();
            }
            else
            {
                Message(iplayer, "importfail");
            }
        }

        private void CmdStackCats(IPlayer iplayer, string command, string[] args)
        {
            if (!iplayer.IsAdmin && !permission.UserHasPermission(iplayer.Id, permAdmin)) { Message(iplayer, "notauthorized"); return; }

            string debug = string.Join(",", args); DoLog($"{debug}");
            if (args.Length == 0)
            {
                string cats = "\t" + string.Join("\n\t", cat2items.Keys.ToList()) + "\n";
                Message(iplayer, "helptext2", cats);
            }
            else if (args.Length == 1)
            {
                string items = null;
                string cat = args[0];
                if (!cat2items.ContainsKey(cat))
                {
                    Message(iplayer, "invalidc", cat);
                    return;
                }
                foreach (KeyValuePair<string, int> item in cat2items[cat])
                {
                    items += $"\t{item.Key}: {item.Value}\n";
                }
                Message(iplayer, "itemlist", cat, items);
            }
            else if (args.Length == 2)
            {
                string cat = args[0];
                if (!cat2items.ContainsKey(cat)) return;

                int stack;
                int.TryParse(args[1], out stack);
                bool success = false;

                if (stack > 0)
                {
                    success = true;
                    foreach (KeyValuePair<string, int> item in new SortedDictionary<string, int>(cat2items[cat]))
                    {
                        UpdateItem(item.Key, stack);
                    }
                }
                if (success) Message(iplayer, "catstack", cat, stack.ToString());
            }
        }

        private void CmdStackInfo(IPlayer iplayer, string command, string[] args)
        {
            if (!iplayer.IsAdmin && !permission.UserHasPermission(iplayer.Id, permAdmin)) { Message(iplayer, "notauthorized"); return; }
            BasePlayer player = iplayer.Object as BasePlayer;
            string debug = string.Join(",", args); DoLog($"{debug}");

            string itemName;
            int stack;
            if (args.Length == 0)
            {
                // Command alone, no args: get current stack size for held item
                DoLog("0: No item name set.Looking for held entity");
                itemName = GetHeldItem(player);

                if (itemName == null) { Message(iplayer, "helptext1"); return; }

                if (name2cat.ContainsKey(itemName))
                {
                    string cat = name2cat[itemName];
                    string stackinfo = cat2items[cat][itemName].ToString();
                    Message(iplayer, "current", itemName, stackinfo);
                }
                else
                {
                    Message(iplayer, "invalid");
                }
            }
            else if (args.Length == 1)
            {
                DoLog("1: No item name set.Looking for held entity.");
                int.TryParse(args[0], out stack);
                if (stack > 0)
                {
                    DoLog($"Will set stack size to {stack}");
                    itemName = GetHeldItem(player);
                    if (name2cat.ContainsKey(itemName))
                    {
                        string cat = name2cat[itemName];
                        UpdateItem(itemName, stack);
                        Message(iplayer, "stackset", itemName, stack.ToString());
                    }
                    else
                    {
                        Message(iplayer, "invalid");
                        return;
                    }
                }
                else
                {
                    DoLog("Item name set on command line: Get the current stack size for the named item.");
                    itemName = args[0];
                    if (itemName.Length < 5)
                    {
                        itemName += ".item";
                    }
                    else if (itemName.Substring(itemName.Length - 5) != ".item")
                    {
                        itemName += ".item";
                    }

                    if (name2cat.ContainsKey(itemName))
                    {
                        string cat = name2cat[itemName];
                        string stackinfo = cat2items[cat][itemName].ToString();
                        Message(iplayer, "current", itemName, stackinfo);
                    }
                    else
                    {
                        Message(iplayer, "invalid", itemName);
                        return;
                    }
                }
            }
            else if (args.Length == 2)
            {
                if (args[0] == "search")
                {
                    string res = "";
                    int i = 0;
                    foreach (string nm in name2cat.Keys)
                    {
                        if (nm.IndexOf(args[1], System.StringComparison.OrdinalIgnoreCase) >= 0)
                        {
                            i++;
                            string cat = name2cat[nm];
                            string stackinfo = cat2items[cat][nm].ToString();
                            res += $"\t[{name2cat[nm]}] {nm} ({stackinfo})\n";
                        }
                    }
                    Message(iplayer, "found", i.ToString(), res);
                    return;
                }
                DoLog("Item name AND stack size set on command line: Set the stack size for the named item.");

                itemName = args[0];
                if (itemName.Length < 5)
                {
                    itemName += ".item";
                }
                else if (itemName.Substring(itemName.Length - 5) != ".item")
                {
                    itemName += ".item";
                }

                if (name2cat.ContainsKey(itemName))
                {
                    int.TryParse(args[1], out stack);
                    DoLog($"Will set stack size to {stack}");
                    if (stack > 0)
                    {
                        UpdateItem(itemName, stack);
                        Message(iplayer, "stackset", itemName, stack.ToString());
                    }
                }
            }
        }

        private void LoadData()
        {
            DoLog("LoadData called");
            data = Interface.Oxide.DataFileSystem.GetFile(Name + "/stacking");
            cat2items = data.ReadObject<SortedDictionary<string, SortedDictionary<string, int>>>();

            foreach (KeyValuePair<string, SortedDictionary<string, int>> itemcats in cat2items)
            {
                foreach (KeyValuePair<string, int> items in itemcats.Value)
                {
                    IEnumerable<ItemDefinition> itemenum = ItemManager.GetItemDefinitions().Where(x => x.name.Equals(itemcats.Key));
                    ItemDefinition item = itemenum?.FirstOrDefault();
                    if (item != null)
                    {
                        DoLog($"Setting stack size for {item?.name} to {items.Value}");
                        item.stackable = items.Value;
                    }
                }
            }

            bdata = Interface.Oxide.DataFileSystem.GetFile(Name + "/name2cat");
            name2cat = bdata.ReadObject<SortedDictionary<string, string>>();
        }

        private void SaveData()
        {
            data.WriteObject(cat2items);
            bdata.WriteObject(name2cat);
        }

        private void DoLog(string message)
        {
            if (configData.Options.debug) Interface.Oxide.LogInfo(message);
        }

        private void UpdateItem(string itemName, int stack)
        {
            List<ItemDefinition> itemDefs = ItemManager.GetItemDefinitions();
            IEnumerable<ItemDefinition> itemDefIe = from rv in itemDefs where rv.name.Equals(itemName) select rv;

            ItemDefinition itemDef = itemDefIe.FirstOrDefault();
            DoLog($"Attempting to set stack size of {itemName} to {stack}");
            itemDef.stackable = stack;
            UpdateItemList(itemName, stack);
        }

        private void UpdateItemList(string itemNameToSet = null, int stack = 0)
        {
            DoLog("Update ItemList");
            if (itemNameToSet != null && stack > 0)
            {
                // Update one item
                string cat = name2cat[itemNameToSet];
                if (cat != null && !cat2items.ContainsKey(cat))
                {
                    // Category missing, create it
                    cat2items.Add(cat, new SortedDictionary<string, int>());
                }

                if (cat2items[cat].ContainsKey(itemNameToSet))
                {
                    cat2items[cat][itemNameToSet] = stack;
                    SaveData();
                }
                return;
            }

            SortedDictionary<string, SortedDictionary<string, int>> oldcat2items = cat2items;
            cat2items = new SortedDictionary<string, SortedDictionary<string, int>>();
            DoLog("Re-populating saved list");
            foreach (KeyValuePair<int, ItemDefinition> itemdef in ItemManager.itemDictionary)
            {
                string cat = itemdef.Value.category.ToString().ToLower();
                if (cat.Length == 0) continue;

                string itemName = itemdef.Value.name;
                int stackable = itemdef.Value.stackable;

                if (!cat2items.ContainsKey(cat))
                {
                    DoLog($"Adding category: {cat}");
                    cat2items.Add(cat, new SortedDictionary<string, int>());
                }

                if (oldcat2items.Count > 0)
                {
                    if (oldcat2items[cat].ContainsKey(itemName))
                    {
                        // Preserve previously set stacksize
                        int oldstack = oldcat2items[cat][itemName];
                        if (oldstack > 0 && !cat2items[cat].ContainsKey(itemName))
                        {
                            DoLog($"Setting stack size for {itemName} to previously set value {oldstack}");
                            cat2items[cat].Add(itemName, oldstack);
                            itemdef.Value.stackable = oldstack;
                        }
                    }
                }
                else if (!cat2items[cat].ContainsKey(itemName))
                {
                    DoLog($"Setting new stack size for {itemName} to default of {stackable}");
                    cat2items[cat].Add(itemName, stackable);
                    itemdef.Value.stackable = stackable;
                }

                if (!name2cat.ContainsKey(itemName)) name2cat.Add(itemName, cat);
            }
            SaveData();
        }

        #region config
        protected override void LoadDefaultConfig()
        {
            Puts("Creating new config file.");
            ConfigData config = new ConfigData
            {
                Options = new Options()
                {
                    debug = false,
                    maxStack = 100000
                },
                Version = Version
            };

            SaveConfig(config);
        }

        private void LoadConfigVariables()
        {
            configData = Config.ReadObject<ConfigData>();

            configData.Version = Version;
            SaveConfig(configData);
        }

        private void SaveConfig(ConfigData config)
        {
            Config.WriteObject(config, true);
        }

        public class ConfigData
        {
            public Options Options;
            public VersionNumber Version;
        }

        public class Options
        {
            [JsonProperty(PropertyName = "Enable debugging")]
            public bool debug;

            [JsonProperty(PropertyName = "Maximum allowable stack size")]
            public int maxStack;
        }
        #endregion
    }
}

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