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

FREE CustomGatherRates : 1.0.0 1.0.0

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
/*
 * Copyright (C) 2024 Game4Freak.io
 * This mod is provided under the Game4Freak EULA.* Full legal terms can be found at https://game4freak.io/eula/
 */

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("Custom Gather Rates", "VisEntities", "1.0.0")]
    [Description("Change how much players get when gathering resources.")]
    public class CustomGatherRates : RustPlugin
    {
        #region Fields

        private static CustomGatherRates _plugin;
        private static Configuration _config;
        private readonly Dictionary<MiningQuarry, BasePlayer> _quarryStarters = new Dictionary<MiningQuarry, BasePlayer>();
        private readonly Dictionary<ExcavatorArm, BasePlayer> _excavatorStarters = new Dictionary<ExcavatorArm, BasePlayer>();

        #endregion Fields

        #region Configuration

        private class Configuration
        {
            [JsonProperty("Version")]
            public string Version { get; set; }

            [JsonProperty("Show Rates Chat Command")]
            public string ShowRatesChatCommand { get; set; }

            [JsonProperty("Global Rates")]
            public Dictionary<string, Dictionary<string, float>> GlobalRates { get; set; }

            [JsonProperty("Permission Profiles")]
            public List<PermissionRateConfig> PermissionProfiles { get; set; }
        }

        private class PermissionRateConfig
        {
            [JsonProperty("Permission Suffix")]
            public string PermissionSuffix { get; set; }

            [JsonIgnore]
            public string FullPermission { get; set; }

            [JsonProperty("Rates")]
            public Dictionary<string, Dictionary<string, float>> Rates { get; set; }
        }

        protected override void LoadConfig()
        {
            base.LoadConfig();
            _config = Config.ReadObject<Configuration>();

            if (string.Compare(_config.Version, Version.ToString()) < 0)
                UpdateConfig();

            SaveConfig();
        }

        protected override void LoadDefaultConfig()
        {
            _config = GetDefaultConfig();
        }

        protected override void SaveConfig()
        {
            Config.WriteObject(_config, true);
        }

        private void UpdateConfig()
        {
            PrintWarning("Config changes detected! Updating...");

            Configuration defaultConfig = GetDefaultConfig();

            if (string.Compare(_config.Version, "1.0.0") < 0)
                _config = defaultConfig;

            PrintWarning("Config update complete! Updated from version " + _config.Version + " to " + Version.ToString());
            _config.Version = Version.ToString();
        }

        private Configuration GetDefaultConfig()
        {
            return new Configuration
            {
                Version = Version.ToString(),
                ShowRatesChatCommand = "gather",
                GlobalRates = CreateEmptyRateDictionary(),
                PermissionProfiles = new List<PermissionRateConfig>
                {
                    new PermissionRateConfig
                    {
                        PermissionSuffix = "vip",
                        Rates = new Dictionary<string, Dictionary<string, float>>
                        {
                            ["Dispenser"] = new Dictionary<string, float>
                            {
                                ["*"] = 1.5f,
                                ["wood"] = 2.0f
                            },
                            ["Pickup"] = new Dictionary<string, float>
                            {
                                ["*"] = 1.75f
                            },
                            ["Growable"] = new Dictionary<string, float>
                            {
                                ["*"] = 1.25f
                            },
                            ["Quarry"]    = new Dictionary<string, float> { ["*"] = 1.0f },
                            ["Excavator"] = new Dictionary<string, float> { ["*"] = 1.0f }
                        }
                    }
                }
            };
        }

        private Dictionary<string, Dictionary<string, float>> CreateEmptyRateDictionary()
        {
            string[] buckets = { "Dispenser", "Growable", "Pickup", "Quarry", "Excavator" };
            var dict = new Dictionary<string, Dictionary<string, float>>(buckets.Length);
            foreach (string key in buckets)
                dict[key] = new Dictionary<string, float> { { "*", 1f } };
            return dict;
        }

        #endregion Configuration

        #region Oxide Hooks

        private void Init()
        {
            _plugin = this;
            PermissionUtil.RegisterPermissions(_config.PermissionProfiles);
            cmd.AddChatCommand(_config.ShowRatesChatCommand, this, nameof(cmdShowRates));
        }

        private void Unload()
        {
            _quarryStarters.Clear();
            _excavatorStarters.Clear();

            _config = null;
            _plugin = null;
        }

        private void OnDispenserGather(ResourceDispenser dispenser, BaseEntity entity, Item item)
        {
            if (dispenser == null || entity == null || item == null)
                return;

            BasePlayer player = entity as BasePlayer;
            if (player == null)
                return;

            float multiplier = GetGatherMultiplier(player, "Dispenser", item.info.shortname);
            ApplyMultiplier(item, multiplier);
        }

        private void OnDispenserBonus(ResourceDispenser dispenser, BaseEntity entity, Item item)
        {
            if (dispenser == null || entity == null || item == null)
                return;

            OnDispenserGather(dispenser, entity, item);
        }

        private void OnGrowableGathered(GrowableEntity growable, Item item, BasePlayer player)
        {
            if (growable == null || item == null || player == null)
                return;

            float multiplier = GetGatherMultiplier(player, "Growable", item.info.shortname);
            ApplyMultiplier(item, multiplier);
        }

        private object CanTakeCutting(BasePlayer player, GrowableEntity plant)
        {
            if (player == null || plant == null || !plant.CanClone())
                return null;

            int amount = plant.Properties.BaseCloneCount + plant.Genes.GetGeneTypeCount(GrowableGenetics.GeneType.Yield) / 2;
            if (amount <= 0)
                return null;

            float multiplier = GetGatherMultiplier(player, "Growable", plant.Properties.CloneItem.shortname);
            amount = Mathf.Max(1, Mathf.CeilToInt(amount * multiplier));

            Item clone = ItemManager.Create(plant.Properties.CloneItem, amount, 0UL, true);
            clone.SetItemOwnership(player, ItemOwnershipPhrases.Cloned);
            GrowableGeneEncoding.EncodeGenesToItem(plant, clone);

            player.GiveItem(clone, BaseEntity.GiveItemReason.ResourceHarvested);

            if (plant.Properties.pickEffect.isValid)
                Effect.server.Run(plant.Properties.pickEffect.resourcePath, plant.transform.position, Vector3.up);

            plant.TellPlanter();
            plant.Die(null);

            return false;
        }

        private void OnCollectiblePickup(CollectibleEntity collectible, BasePlayer player)
        {
            if (collectible.itemList == null || player == null)
                return;

            for (int i = 0; i < collectible.itemList.Length; i++)
            {
                ItemAmount amt = collectible.itemList[i];
                if (amt == null || amt.itemDef == null)
                    continue;

                float multiplier = GetGatherMultiplier(player, "Pickup", amt.itemDef.shortname);
                ApplyMultiplier(amt, multiplier);
            }
        }

        private void OnQuarryGather(MiningQuarry quarry, Item item)
        {
            if (quarry == null || item == null)
                return;

            _quarryStarters.TryGetValue(quarry, out var starter);

            float multiplier = GetGatherMultiplier(starter, "Quarry", item.info.shortname);
            ApplyMultiplier(item, multiplier);
        }

        private void OnExcavatorGather(ExcavatorArm excavator, Item item)
        {
            if (excavator == null || item == null)
                return;

            _excavatorStarters.TryGetValue(excavator, out var starter);

            float multiplier = GetGatherMultiplier(starter, "Excavator", item.info.shortname);
            ApplyMultiplier(item, multiplier);
        }

        private void OnQuarryToggled(MiningQuarry quarry, BasePlayer player)
        {
            if (quarry == null || player == null)
                return;

            if (quarry.IsEngineOn())
                _quarryStarters[quarry] = player;
            else
                _quarryStarters.Remove(quarry);
        }

        private void OnExcavatorResourceSet(ExcavatorArm arm, string resourceCode, BasePlayer player)
        {
            if (arm != null && player != null)
                _excavatorStarters[arm] = player;
        }

        private void OnExcavatorMiningToggled(ExcavatorArm arm)
        {
            if (arm != null && !arm.IsMining())
                _excavatorStarters.Remove(arm);
        }

        private void OnEntityKill(BaseNetworkable entity)
        {
            if (entity is MiningQuarry quarry)
            {
                _quarryStarters.Remove(quarry);
            }
            else if (entity is ExcavatorArm arm)
            {
                _excavatorStarters.Remove(arm);
            }
        }

        #endregion Oxide Hooks

        #region Multiplier Helpers

        private void ApplyMultiplier(Item item, float multiplier)
        {
            if (multiplier <= 0f || Math.Abs(multiplier - 1f) < float.Epsilon)
                return;

            item.amount = Mathf.Max(1, (int)Mathf.Ceil(item.amount * multiplier));
        }

        private void ApplyMultiplier(ItemAmount amount, float multiplier)
        {
            if (multiplier <= 0f || Math.Abs(multiplier - 1f) < float.Epsilon)
                return;

            amount.amount = Mathf.Max(1f, Mathf.Ceil(amount.amount * multiplier));
        }

        private void AdjustDispenserRemainder(ResourceDispenser dispenser, Item item, int originalAmount, float multiplier)
        {
            if (multiplier <= 1f || dispenser == null || dispenser.containedItems == null)
                return;

            int delta = item.amount - originalAmount;
            if (delta <= 0) return;

            foreach (ItemAmount entry in dispenser.containedItems)
            {
                if (entry == null) continue;
                if (entry.itemDef == null) continue;
                if (entry.itemDef.shortname != item.info.shortname)
                    continue;

                entry.amount += delta;
                break;
            }
        }

        private float GetGatherMultiplier(BasePlayer gatherer, string gatherCategory, string itemShortName)
        {
            foreach (PermissionRateConfig permProfile in _config.PermissionProfiles)
            {
                if (!PermissionUtil.HasPermission(gatherer, permProfile.FullPermission))
                    continue;

                if (!permProfile.Rates.TryGetValue(gatherCategory, out var ratesByItem))
                    continue;

                if (ratesByItem.TryGetValue(itemShortName, out float multiplier))
                    return multiplier;

                if (ratesByItem.TryGetValue("*", out multiplier))
                    return multiplier;
            }

            if (_config.GlobalRates.TryGetValue(gatherCategory, out var globalRatesByItem))
            {
                if (globalRatesByItem.TryGetValue(itemShortName, out float multiplier))
                    return multiplier;

                if (globalRatesByItem.TryGetValue("*", out multiplier))
                    return multiplier;
            }

            return 1f;
        }

        #endregion Multiplier Helpers

        #region Permissions

        private static class PermissionUtil
        {
            public const string ADMIN = "customgatherrates.admin";
            private static readonly List<string> _permissions = new List<string>
            {
                ADMIN,
            };

            public static string ConstructPermission(string suffix, bool addToList = true)
            {
                string perm = string.Join(".", nameof(CustomGatherRates), suffix).ToLower();

                if (addToList && !_permissions.Contains(perm))
                    _permissions.Add(perm);

                return perm;
            }

            public static void AddPermission(string permission)
            {
                if (!_permissions.Contains(permission))
                    _permissions.Add(permission);
            }

            public static void RegisterPermissions(IEnumerable<PermissionRateConfig> dynamicPermissions = null)
            {
                foreach (string perm in _permissions)
                    _plugin.permission.RegisterPermission(perm, _plugin);

                if (dynamicPermissions == null)
                    return;

                foreach (var dynamicPerm in dynamicPermissions)
                {
                    if (dynamicPerm == null || string.IsNullOrEmpty(dynamicPerm.PermissionSuffix))
                        continue;

                    if (string.IsNullOrEmpty(dynamicPerm.FullPermission))
                        dynamicPerm.FullPermission = ConstructPermission(dynamicPerm.PermissionSuffix);

                    AddPermission(dynamicPerm.FullPermission);
                    _plugin.permission.RegisterPermission(dynamicPerm.FullPermission, _plugin);
                }
            }

            public static bool HasPermission(BasePlayer player, string permission)
            {
                return player != null && _plugin.permission.UserHasPermission(player.UserIDString, permission);
            }
        }

        #endregion Permissions

        #region Commands
        
        private void cmdShowRates(BasePlayer player, string command, string[] args)
        {
            List<string> lines = new List<string>
            {
                GetMessage(player, Lang.Info_Header_YourRates)
            };

            foreach (var categoryPair in _config.GlobalRates)
            {
                float multiplier = GetGatherMultiplier(player, categoryPair.Key, "*");
                if (Math.Abs(multiplier - 1f) > float.Epsilon)
                    lines.Add(string.Format(GetMessage(player, Lang.Info_Line_Rate), categoryPair.Key, multiplier));
            }

            if (lines.Count == 1)
                lines.Add(GetMessage(player, Lang.Info_NoRateOverrides));

            foreach (string line in lines)
                MessagePlayer(player, line);
        }

        [ConsoleCommand("gather.rate")]
        private void cmdSetRate(ConsoleSystem.Arg conArgs)
        {
            BasePlayer caller = conArgs.Player();
            bool fromServerConsole = caller == null;
            string[] arguments = conArgs.Args;

            if (!fromServerConsole && !PermissionUtil.HasPermission(caller, PermissionUtil.ADMIN))
            {
                MessagePlayer(caller, Lang.Error_NoPermission);
                return;
            }

            if (!conArgs.HasArgs(4))
            {
                string msg = GetMessage(null, Lang.Error_InvalidArguments);
                if (fromServerConsole)
                    Puts(msg);
                else
                    MessagePlayer(caller, msg);
                return;
            }

            string modeToken = arguments[0].ToLowerInvariant();
            bool globalMode = modeToken == "global";
            bool permMode = modeToken == "perm";

            if (!globalMode && !permMode)
            {
                string msg = GetMessage(null, Lang.Error_InvalidFirstArgument);
                if (fromServerConsole)
                    Puts(msg);
                else
                    MessagePlayer(caller, msg);
                return;
            }

            int argIndex = 1;
            PermissionRateConfig permProfile = null;

            if (permMode)
            {
                string suffix = arguments[argIndex++];
                permProfile = _config.PermissionProfiles.Find(p =>
                    p.PermissionSuffix.Equals(suffix, StringComparison.OrdinalIgnoreCase));

                if (permProfile == null)
                {
                    permProfile = new PermissionRateConfig
                    {
                        PermissionSuffix = suffix,
                        FullPermission = PermissionUtil.ConstructPermission(suffix),
                        Rates = CreateEmptyRateDictionary()
                    };
                    _config.PermissionProfiles.Add(permProfile);
                    PermissionUtil.AddPermission(permProfile.FullPermission);
                    PermissionUtil.RegisterPermissions(_config.PermissionProfiles);
                }
            }

            string gatherCategory = arguments[argIndex++];
            if (!_config.GlobalRates.ContainsKey(gatherCategory))
            {
                string msg = GetMessage(null, Lang.Error_InvalidGatherCategory);
                if (fromServerConsole)
                    Puts(msg);
                else
                    MessagePlayer(caller, msg);
                return;
            }

            string resourceKey = arguments[argIndex++];
            string multiplierToken = arguments[argIndex];

            if (!float.TryParse(multiplierToken, out float multiplier) || multiplier <= 0f)
            {
                string msg = GetMessage(null, Lang.Error_InvalidMultiplier);
                if (fromServerConsole)
                    Puts(msg);
                else
                    MessagePlayer(caller, msg);
                return;
            }

            Dictionary<string, Dictionary<string, float>> rateTable;
            if (globalMode)
                rateTable = _config.GlobalRates;
            else
                rateTable = permProfile.Rates;

            rateTable[gatherCategory][resourceKey] = multiplier;
            SaveConfig();

            string success = GetMessage(null, Lang.Info_RateSet,
                                        gatherCategory, resourceKey, multiplier);
            if (fromServerConsole)
                Puts(success);
            else
                MessagePlayer(caller, success);
        }
        
        #endregion Commands

        #region Localization

        private class Lang
        {
            public const string Error_NoPermission = "Error.NoPermission";
            public const string Error_InvalidArguments = "Error.InvalidArguments";
            public const string Error_InvalidFirstArgument = "Error.InvalidFirstArgument";
            public const string Error_InvalidPermissionName = "Error.InvalidPermissionName";
            public const string Error_InvalidGatherCategory = "Error.InvalidGatherCategory";
            public const string Error_InvalidMultiplier = "Error.InvalidMultiplier";
            public const string Error_EntryDoesNotExist = "Error.EntryDoesNotExist";
            public const string Info_Header_YourRates = "Info.Header.YourRates";
            public const string Info_Line_Rate = "Info.Line.Rate";
            public const string Info_NoRateOverrides = "Info.NoRateOverrides";
            public const string Info_RateSet = "Info.RateSet";
        }

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                [Lang.Error_NoPermission] = "You do not have permission to use this command.",
                [Lang.Error_InvalidArguments] = "Invalid arguments supplied.",
                [Lang.Error_InvalidFirstArgument] = "First argument must be 'global' or 'perm'.",
                [Lang.Error_InvalidPermissionName] = "Permission name is not valid.",
                [Lang.Error_InvalidGatherCategory] = "Gather category is not recognised.",
                [Lang.Error_InvalidMultiplier] = "Multiplier must be a number greater than 0.",
                [Lang.Error_EntryDoesNotExist] = "There is no existing rate entry to remove.",

                [Lang.Info_Header_YourRates] = "Your gather multipliers:",
                [Lang.Info_Line_Rate] = "{0}: x{1}",
                [Lang.Info_NoRateOverrides] = "All rates are default (x1).",
                [Lang.Info_RateSet] = "Set {0} / {1} to x{2}.",
            }, this, "en");
        }

        private static string GetMessage(BasePlayer player, string messageKey, params object[] args)
        {
            string userId;
            if (player != null)
                userId = player.UserIDString;
            else
                userId = null;

            string message = _plugin.lang.GetMessage(messageKey, _plugin, userId);

            if (args.Length > 0)
                message = string.Format(message, args);

            return message;
        }

        public static void MessagePlayer(BasePlayer player, string messageKey, params object[] args)
        {
            string message = GetMessage(player, messageKey, args);

            if (!string.IsNullOrWhiteSpace(message))
                _plugin.SendReply(player, message);
        }

        #endregion Localization
    }
}

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