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

FREE CupboardLimiter : 1.7.6 1.7.6

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Linq;
using System.Reflection;
using System.Collections.Generic;
using Oxide.Core.Plugins;
using Oxide.Core.Libraries;
using Newtonsoft.Json;
using Oxide.Core.Libraries.Covalence;
using UnityEngine;

#region Changelogs and ToDo
/**********************************************************************
 * 
 * v1.1.0   :   Started to Maintain (Krungh Crow)
 *          :   Fixed RPC error
 *          :   Added permissions
 *          :   Language File Updated
 *          :   Debug warning added (read.cs file)
 *          :   Rewrite of config handling
 *          :   Coding Optimisations
 * v1.2.0   :   Added discord notification for exceeding limit
 *          :   Added Remaining tc chat notification after 1st placement
 * V1.2.1   :   Fix for remaining tc limit chatmessage
 * v1.2.2   :   Performance Update
 * v1.2.3   :   Possible fix for NRE at startup
 * v1.3.0   :   Maintain (Spiikesan): Rework done.Performance increased and bugs fixed.* v1.3.1   :   Lang messages are now version dependant (CANCELLED)
 * v1.4.0   :   Add command 'clinspect' to retrieve users TCs informations
 * v1.5.0   :   "Limit reached" message is now working.*          :   Chat prefix and icon is customizable.*          :   Dynamic limits and permissions.* v1.6.0   :   Add team-based limits.* v1.6.1   :   Refactoring team-based limits
 * V1.6.2   :   Command "tc" now use the player instead of the argument if there is no argument.**********************************************************************/
#endregion

namespace Oxide.Plugins
{
    [Info("Cupboard Limiter", "Spiikesan", "1.7.6")]
    [Description("Simplified version for cupboard limits")]

    public class CupboardLimiter : RustPlugin
    {
        #region Variables

        bool debug = false;

        const string Vip_Perm = "cupboardlimiter.vip";
        const string Bypass_Perm = "cupboardlimiter.bypass";
        const string Admin_Perm = "cupboardlimiter.admin";
        const string Other_Perm = "cupboardlimiter.limit_";
        const string CommandList_Perm = "cupboardlimiter.commandList";

        const string Message_MaxLimitDefault = "MaxLimitDefault";
        const string Message_MaxLimitVip = "MaxLimitVip";
        const string Message_MaxLimit = "MaxLimit";
        const string Message_Remaining = "Remaining";
        const string Message_NoPermission = "NoPermission";
        const string Message_Inspect = "cInspect";
        const string Message_InspectOwn = "cInspectOwn";
        const string Message_InspectNotFound = "cInspectNotFound";
        const string Message_InspectUsage = "cInspectUsage";
        const string Message_TeamOvercount = "TeamOvercount";
        const string Message_TeamOvercountTarget = "TeamOvercountTarget";
        const string Message_Error = "Error";


        Dictionary<ulong, List<BuildingPrivlidge>> TCIDs = new Dictionary<ulong, List<BuildingPrivlidge>>();
        private int TCCount(BasePlayer player)
        {
            //bypass command : ignore TC from player with bypass ?
            List<BuildingPrivlidge> tcs;
            int count = 0;

            if (configData.Limits.GlobalTeamLimit && player.Team != null && player.Team.members.Count > 1)
            {
                foreach (var pl in player.Team.members)
                {
                    if (TCIDs.TryGetValue(pl, out tcs))
                    {
                        count += tcs.Count;
                    }
                }
                // Counting pending invites to avoid bypass
                foreach (var pl in player.Team.invites.Except(player.Team.members))
                {
                    if (TCIDs.TryGetValue(pl, out tcs))
                    {
                        count += tcs.Count;
                    }
                }
            }
            else
            {
                if (TCIDs.TryGetValue(player.userID, out tcs))
                {
                    count = tcs.Count;
                }
            }
            return count;
        }

        private void TCAdd(ulong playerId, BuildingPrivlidge tcId)
        {
            List<BuildingPrivlidge> tcs;
            if (TCIDs.TryGetValue(playerId, out tcs))
            {
                if (!tcs.Contains(tcId))
                    tcs.Add(tcId);
            }
            else
            {
                tcs = new List<BuildingPrivlidge>();
                tcs.Add(tcId);
                TCIDs.Add(playerId, tcs);
            }
        }

        private void TCDel(ulong playerId, BuildingPrivlidge tcId)
        {
            List<BuildingPrivlidge> tcs;
            if (TCIDs.TryGetValue(playerId, out tcs))
            {
                tcs.Remove(tcId);
            }
        }

        #endregion

        #region Configuration

        void Init()
        {
            if (!LoadConfigVariables())
            {
                Puts("Config file issue detected.Please delete file, or check syntax and fix.");
                return;
            }
            permission.RegisterPermission(Vip_Perm, this);
            permission.RegisterPermission(Bypass_Perm, this);
            permission.RegisterPermission(Admin_Perm, this);
            permission.RegisterPermission(CommandList_Perm, this);

            for (int i = 0; i < configData.Limits.OtherLimits.Count; i++)
            {
                permission.RegisterPermission(Other_Perm + (i + 1), this);
            }

            if (debug) Puts($"Debug is activated check CupboardLimiter.cs file if not intended");
        }

        private ConfigData configData;

        class ConfigData
        {
            [JsonProperty(PropertyName = "Max amount of TC(s) to place")]
            public Settings Limits = new Settings();
            [JsonProperty(PropertyName = "Discord Notification")]
            public SettingsDiscord Discord = new SettingsDiscord();
            [JsonProperty(PropertyName = "Chat Settings")]
            public SettingsChat Chat = new SettingsChat();
        }

        class Settings
        {
            [JsonProperty(PropertyName = "Limit Default")]
            public int DefaultLimit = 1;
            [JsonProperty(PropertyName = "Limit Vip")]
            public int VipLimit = 3;
            [JsonProperty(PropertyName = "Limit Others")]
            public List<int> OtherLimits = new List<int>();
            [JsonProperty(PropertyName = "Limit Others Can Downgrade Default")]
            public bool OtherLimitsOverDefault = false;
            [JsonProperty(PropertyName = "Global Team Limit")]
            public bool GlobalTeamLimit = true;
            [JsonProperty(PropertyName = "Limits In Team")]
            public Dictionary<int, int> TeamLimits = new Dictionary<int, int>();
        }

        class SettingsDiscord
        {
            [JsonProperty(PropertyName = "Discord Webhook URL")]
            public string DiscordWebhookAddress = string.Empty;
        }

        class SettingsChat
        {
            [JsonProperty(PropertyName = "Prefix")]
            public string Prefix = "[Cupboard Limiter] :";
            [JsonProperty(PropertyName = "Icon's SteamId")]
            public ulong SteamIdIcon = 76561198049668039;

        }

        private bool LoadConfigVariables()
        {
            try
            {
                configData = Config.ReadObject<ConfigData>();
                foreach (var data in configData.Limits.TeamLimits)
                {
                    if (data.Key <= 1)
                    {
                        Puts($"Config Warning : Team count {data.Key} is below the limit of 2 players.");
                    }
                    else if (data.Key > RelationshipManager.maxTeamSize)
                    {
                        Puts($"Config Warning : Team count {data.Key} is over the max team limit of {RelationshipManager.maxTeamSize} players.");
                    }
                }
            }
            catch (Exception ex)
            {
                PrintError("An error occured dugin ConfigData load: " + ex.ToString());
                return false;
            }
            SaveConf();
            return true;
        }

        protected override void LoadDefaultConfig()
        {
            Puts("Fresh install detected Creating a new config file.");
            configData = new ConfigData();
            SaveConf();
        }

        void SaveConf() => Config.WriteObject(configData, true);
        #endregion

        #region LanguageAPI
        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                [Message_MaxLimitDefault] = "You have reached the Default maximum cupboard limit of {0}",
                [Message_MaxLimitVip] = "You have reached the Vip maximum cupboard limit of {0}",
                [Message_MaxLimit] = "You have reached the maximum cupboard limit of {0}",
                [Message_Remaining] = "Amount of TC's remaining = {0}",
                [Message_NoPermission] = "You don't have the permission.",
                [Message_Inspect] = "The user {0} have {1} TCs.",
                [Message_InspectOwn] = "You have {0} TC and {1} remaining.",
                [Message_InspectNotFound] = "Error: User not found",
                [Message_TeamOvercount] = "You cannot invite this player right now, he have {0} TC too many.",
                [Message_TeamOvercountTarget] = "You cannot be invited by this player right now, you have {0} TC too many.",
                [Message_InspectUsage] = "Usage: tc <partialNameOrId>...",
                [Message_Error] = "An unexpected error occured.",
            }, this, "en");

            lang.RegisterMessages(new Dictionary<string, string>
            {
                [Message_MaxLimitDefault] = "Vous avez atteint la limite par defaut de {0} pour les armoires a outils.",
                [Message_MaxLimitVip] = "Vous avez atteint la limite VIP de {0} pour les armoires a outils.",
                [Message_MaxLimit] = "Vous avez atteint la limite de {0} pour les armoires a outils.",
                [Message_Remaining] = "Il vous reste {0} armoires a outils a placer.",
                [Message_NoPermission] = "Vous n'avez pas la permission",
                [Message_Inspect] = "Le joueur {0} a {1} TCs.",
                [Message_InspectOwn] = "Vous avez {0} TC(s) et {1} restant a poser.",
                [Message_InspectNotFound] = "Erreur: Le joueur n'a pas ete trouve.",
                [Message_TeamOvercount] = "Vous ne pouvez pas inviter ce joueur actuellement, il a {0} armoires a outils en trop.",
                [Message_TeamOvercountTarget] = "Vous ne pouvez pas etre invite par ce joueur actuellement, vous avez {0} armoires a outils en trop.",
                [Message_InspectUsage] = "Usage: tc <pseudoPartielOuId>...",
                [Message_Error] = "Une erreur inattendue s'est produite.",
            }, this, "fr");
        }

        #endregion

        #region Hooks

        void OnServerInitialized()
        {
            if (!configData.Discord.DiscordWebhookAddress.Contains("discord.com/api/webhooks"))
            {
                Puts("Warning !!\n----------------------------------\nNo Webhook has been assigned yet !\n----------------------------------");
            }
            else if (configData.Discord.DiscordWebhookAddress.Contains("discord.com/api/webhooks"))
            {
                Puts($"Verified !!\n----------------------------------\nWebhook has been found :\n{configData.Discord.DiscordWebhookAddress}\n----------------------------------");
            }

            foreach (var entity in BaseNetworkable.serverEntities)
            {
                BuildingPrivlidge TC = entity as BuildingPrivlidge;
                if (TC != null && !TC.IsDestroyed && TC.OwnerID.IsSteamId())
                {
                    TCAdd(TC.OwnerID, TC);
                }
            }

            if (debug)
            {
                foreach (var userTc in TCIDs)
                {
                    try
                    {
                        Puts("User " + BasePlayer.allPlayerList.Single(pl => pl.userID == userTc.Key) + " has " + userTc.Value.Count + " TC : ");
                    }
                    catch
                    {
                        Puts("User " + userTc.Key + " has " + userTc.Value.Count + " TC : ");
                    }
                    foreach (var tc in userTc.Value)
                    {
                        Puts("   - " + tc);
                    }
                }
            }
        }

        void OnEntitySpawned(BaseEntity entity, UnityEngine.GameObject gameObject)
        {
            BuildingPrivlidge TC = entity as BuildingPrivlidge;

            if (TC != null && TC.OwnerID.IsSteamId())
            {
                TCAdd(TC.OwnerID, TC);

                if (debug) Puts($"a cupboard is spawning in world.It's ID is {TC.GetInstanceID()} and owner {TC.OwnerID}");

                BasePlayer player = BasePlayer.FindByID(TC.OwnerID);
                if (player == null) return;
                if (player.IsSleeping() || !player.IsConnected)
                {
                    if (debug) Puts($"sleep|offline check");
                    return;
                }

                // HOW MANY CHECK

                if (!permission.UserHasPermission(player.UserIDString, Bypass_Perm))
                {
                    int limit = GetTCLimit(player);
                    int count = TCCount(player);

                    if (debug) Puts($"{player}: cupboard count {count}");
                    // EXTRA CHECK IF PLAYER HAS ABNORMAL CUPBOARD COUNT
                    if (count - limit > 1) PrintWarning($"PLAYER {player.displayName} has {count - limit - 1} more cupboards over his limit of {limit} !");
                    // CANCEL IF LIMIT REACHED

                    if (count > limit)
                    {
                        NextTick(() =>
                        {
                            if (configData.Discord.DiscordWebhookAddress.Contains("discord.com/api/webhooks"))
                            {
                                try
                                {
                                    webrequest.Enqueue(configData.Discord.DiscordWebhookAddress, $"{{\"content\":\" {DateTime.Now.ToShortTimeString()} : **{player}** : Tried to place more TC's than the max of **{limit}**\"}}",
                                    Callback, this, RequestMethod.POST, new Dictionary<string, string> { ["Content-Type"] = "application/json" });
                                }
                                catch { }
                            }
                            RefundTC(TC, player);
                        });
                    }
                    else
                        ChatMessage(player, FormatMessage(Message_Remaining, player.UserIDString, limit - count));
                }
            }
            return;
        }

        void OnEntityKill(BaseEntity entity)
        {
            BuildingPrivlidge TC = entity as BuildingPrivlidge;

            if (TC is BuildingPrivlidge && TC.OwnerID.IsSteamId())
            {
                TCDel(TC.OwnerID, TC);
            }
        }

        object OnTeamInvite(BasePlayer inviter, BasePlayer target)
        {
            if (configData.Limits.GlobalTeamLimit)
            {
                int limit = GetTCLimit(inviter, true);
                int teamTC = TCCount(inviter);
                int targetTC = TCCount(target);

                if (teamTC + targetTC > limit)
                {
                    ChatMessage(inviter, FormatMessage(Message_TeamOvercount, inviter.UserIDString, (teamTC + targetTC) - limit));
                    ChatMessage(target, FormatMessage(Message_TeamOvercountTarget, target.UserIDString, (teamTC + targetTC) - limit));
                    inviter.Team.RejectInvite(target);
                    return false;
                }
            }
            return null;
        }

        #endregion

        #region Commands

        [ChatCommand("tc")]
        private void ChatCommand_Inspect(BasePlayer player, string command, string[] args)
        {

            ulong userID = player.userID;
            bool isOwn = true;
            string receiverId = player.UserIDString;
            if (args.Length >= 1)
            {
                isOwn = false;
                userID = 0;
                if (permission.UserHasPermission(player.UserIDString, CommandList_Perm))
                {
                    var user = covalence.Players.FindPlayer(args[0]);

                    if (user is IPlayer)
                    {
                        if (ulong.TryParse(user.Id, out userID))
                        {
                            player = user.Object as BasePlayer;
                        }
                    }
                    else
                    {
                        ChatMessage(player, FormatMessage(Message_InspectNotFound, player.UserIDString));
                    }
                }
                else
                {
                    ChatMessage(player, FormatMessage(Message_NoPermission, player.UserIDString));
                }
            }

            if (player != null && userID.IsSteamId())
            {
                ChatMessage(player, PlayerTcsString(player, receiverId, isOwn));
            }
            else
            {
                ChatMessage(player, FormatMessage(Message_Error, player.UserIDString));
            }
        }
        [ConsoleCommand("tc")]
        private void ServerCommand_Inspect(ConsoleSystem.Arg arg)
        {
            PrintToConsole("ServerCommand");
            if (!arg.IsServerside)
            {
                arg.ReplyWith("Unkown command.");
            }
            else if (arg.Args == null || arg.Args.Count() == 0)
            {
                arg.ReplyWith(FormatMessage(Message_InspectUsage, null));
            }
            else
            {
                string reply = "Query result:\n";
                foreach (string playerId in arg.Args)
                {
                    var user = covalence.Players.FindPlayer(playerId);
                    if (user != null)
                    {
                        BasePlayer player = user.Object as BasePlayer;
                        if (player != null)
                        {
                            reply += $"{PlayerTcsString(player, null, false)}\n";
                        }
                        else
                        {
                            reply += $"Player \"{playerId}\" cannot be got as BasePlayer\n";
                        }
                    }
                    else
                    {
                        reply += $"Player \"{playerId}\" not found\n";
                    }
                }
                arg.ReplyWith(reply);
            }
        }


        #endregion

        #region Helpers

        void RefundTC(BaseEntity tC, BasePlayer player)
        {
            if (debug) Puts($"cancelling cupboard ID {tC.GetInstanceID()} of player {player.UserIDString}");

            if (permission.UserHasPermission(player.UserIDString, Vip_Perm))
            {
                ChatMessage(player, FormatMessage(Message_MaxLimitVip, player.UserIDString, configData.Limits.VipLimit));
            }
            else
            {
                bool otherLimitPerm = false;
                for (int i = 0; i < configData.Limits.OtherLimits.Count; i++)
                {
                    if (permission.UserHasPermission(player.UserIDString, Other_Perm + (i + 1)))
                    {
                        otherLimitPerm = true;
                        break;
                    }
                }
                if (otherLimitPerm)
                {
                    ChatMessage(player, FormatMessage(Message_MaxLimit, player.UserIDString, configData.Limits.DefaultLimit));
                }
                else
                {
                    ChatMessage(player, FormatMessage(Message_MaxLimitDefault, player.UserIDString, configData.Limits.DefaultLimit));
                }
            }

            tC.KillMessage();
            var itemToGive = ItemManager.CreateByItemID(-97956382, 1);
            if (itemToGive != null) player.inventory.GiveItem(itemToGive);
        }

        public int GetTCLimit(BasePlayer player, bool isInvite = false)
        {
            int limit = configData.Limits.DefaultLimit;

            if (debug) Puts($"{player}: Default limit {limit}");

            if (configData.Limits.TeamLimits.Count > 0 && player.Team != null)
            {
                int tcount = player.Team.members.Count + (isInvite ? 1 : 0);

                if (tcount > 1)
                {
                    foreach (var tlim in configData.Limits.TeamLimits)
                    {
                        if (tlim.Key <= tcount)
                            limit = tlim.Value;
                        else
                            break;
                    }
                    if (debug) Puts($"{player}: Team limit {limit} for {tcount} players in the team");
                }
            }

            if (configData.Limits.OtherLimits.Count > 0)
            {
                int olimit = -1;
                for (int i = 0; i < configData.Limits.OtherLimits.Count; i++)
                {
                    if (permission.UserHasPermission(player.UserIDString, Other_Perm + (i + 1)))
                    {
                        if (configData.Limits.OtherLimits[i] > olimit)
                        {
                            olimit = configData.Limits.OtherLimits[i];
                        }
                    }
                }
                if (olimit > 0 && (olimit > limit || configData.Limits.OtherLimitsOverDefault))
                {
                    limit = olimit;
                }
                if (debug) Puts($"{player}: Other limit {olimit}");
            }

            if (permission.UserHasPermission(player.UserIDString, Vip_Perm))
            {
                limit = configData.Limits.VipLimit;
                if (debug) Puts($"{player}: VIP limit {limit}");
            }

            return limit;
        }

        public void Callback(int code, string response)
        {
        }

        public string FormatMessage(string messageId, string userId, params object[] parameters)
        {
            return string.Format(lang.GetMessage(messageId, this, userId), parameters);
        }

        private void ChatMessage(BasePlayer player, string message)
        {
            Player.Message(player, message, configData.Chat.Prefix, configData.Chat.SteamIdIcon);
        }

        private string PlayerTcsString(BasePlayer player, string receiverId, bool isOwn)
        {
            List<BuildingPrivlidge> tcs;
            if (!TCIDs.TryGetValue(player.userID, out tcs))
                tcs = new List<BuildingPrivlidge>();
            tcs = tcs.FindAll(tc => !tc.IsDestroyed);
            string msg = isOwn ? FormatMessage(Message_InspectOwn, receiverId, tcs.Count, GetTCLimit(player) - TCCount(player))
                               : FormatMessage(Message_Inspect, receiverId, player.displayName, tcs.Count);
            foreach (var TC in tcs)
            {
                msg += "\n - Pos: " + GetCoordinates(TC.ServerPosition);
            }
            return msg;
        }

        private string GetCoordinates(Vector3 position)
        {
            const float CELL_SIZE = 150f;
            Vector3 realPos = position - TerrainMeta.Transform.position; //Getting the real position in the "player map"
            realPos.z = TerrainMeta.Size.z - realPos.z; //Top is 0, we need to invert Z axis

            Vector3 error = new Vector3(-90f, 0f, -90f);
            Vector3 correction = new Vector3(
                error.x * (realPos.x / (TerrainMeta.Size.x + error.x)),
                0,
                error.z * (realPos.z / TerrainMeta.Size.z) - error.z
                );

            Vector3 cellPos = (realPos - correction) / CELL_SIZE;


            int letter = (int)cellPos.x;
            string c = string.Empty;
            if (letter >= 26)
            {
                c += (char)((letter / 26 - 1) + 'A');
                letter %= 26;
            }
            c += (char)(letter + 'A');

            c += ((int)cellPos.z).ToString();
            return c;
        }

        #endregion
    }
}

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