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

FREE TheDoorKnocker : 1.4.3 1.4.3

Нет прав для скачивания
C#:
using System;
using Newtonsoft.Json;
using Oxide.Core;
using System.Collections.Generic;
using System.Linq;
//using Oxide.Game.Rust.Cui;
using UnityEngine;
using Random = Oxide.Core.Random;


// For changelog
/*
 * Added support to initialize player data when they are added to a group that contains TDK permissions
 * Added support for server owners to change the velocity of each rocket type the player can fire
 */



namespace Oxide.Plugins
{
    [Info("The Door Knocker", "Cannabis", "1.4.3")]
    [Description("Allows players to shoot more than 1 rocket at a time")]
    internal class TheDoorKnocker : RustPlugin
    {
        #region Declarations

        //private readonly string limitperm = "thedoorknocker.amount.";
        private readonly string useperm = "thedoorknocker.use";
        SavedData data;
        //SavedData dataCache;

        #endregion

        #region Oxide Hooks

        void Init()
        {
            foreach (var kvp in config.maxRocketPermission)
            {
                permission.RegisterPermission(kvp.Key, this);
            }

            permission.RegisterPermission(useperm, this);
            lang.RegisterMessages(_messages, this);
            cmd.AddChatCommand(config.rocketamtcmd, this, nameof(CmdHandleRockets));
            //cmd.AddChatCommand(config.rocketCuiCmd, this, nameof(CUI_CmdOpenSettings));
            data = SavedData.Load();
            //dataCache = data;
            if (config.cleanOldData)
            {
                timer.Once(5f, () =>
                {
                    foreach (var userID in data.playerData.Keys.ToList())
                    {
                        DateTime lastDisconnectTime = data.playerData[userID].lastSeen;
                        TimeSpan timeDifference = DateTime.UtcNow - lastDisconnectTime;
                        double daysSinceLastSeen = timeDifference.TotalDays;
                        if (!(daysSinceLastSeen >= config.daysSinceLastSeenToClean)) continue;
                        data.playerData.Remove(userID);
                        data.Save();
                    }
                });

            }
        }

        void OnPlayerConnected(BasePlayer player)
        {
            if (!permission.UserHasPermission(player.UserIDString, useperm) || data.playerData.ContainsKey(player.userID)) return;

            data.playerData.Add(player.userID, new TheDoorKnockerData()
            {
                lastSeen = DateTime.Now,
                playerPreferences = new TheDoorKnockerPlayerPreferences()
                {
                    basicRocket = true,
                    fireRocket = false,
                    hvRocket = true,
                    smokeRocket = false
                },
                playerRockets = config.defaultPlayerData.amount,
                rocketsEnabled = config.defaultPlayerData.enabled
            });
            data.Save();
        }

        void OnUserPermissionGranted(string id, string permName)
        {
            bool a = config.maxRocketPermission.ContainsKey(permName);
            ulong userID;
            if ((permName != useperm && !a) || !ulong.TryParse(id, out userID)) return;
            if (data.playerData.ContainsKey(userID)) return;
            data.playerData.Add(userID, new TheDoorKnockerData()
            {
                lastSeen = DateTime.Now,
                playerRockets = config.defaultPlayerData.amount,
                rocketsEnabled = config.defaultPlayerData.enabled,
                playerPreferences = new TheDoorKnockerPlayerPreferences()
                {
                    basicRocket = true,
                    fireRocket = false,
                    hvRocket = true,
                    smokeRocket = false
                }
            });
            data.Save();
        }

        void OnNewSave(string filename)
        {
            if (!config.wipeOnWipe) return;
            data = new SavedData();
            data.Save();
        }

        void OnPlayerDisconnected(BasePlayer player, string reason)
        {
            if (!data.playerData.ContainsKey(player.userID)) return;
            data.playerData[player.userID].lastSeen = DateTime.Now;
            data.Save();
        }

        void OnUserPermissionRevoked(string id, string permName)
        {
            BasePlayer player = BasePlayer.FindByID(ulong.Parse(id));
            if (player == null) return;
            if (permName == useperm)
            {
                if (!data.playerData.ContainsKey(player.userID)) return;
                data.playerData.Remove(player.userID);
                data.Save();
            };
            foreach (var kvp in config.maxRocketPermission)
            {
                if (permName != kvp.Key || !permission.UserHasPermission(id, useperm)) continue;
                data.playerData[player.userID].playerRockets = config.defaultPlayerData.amount;
                data.Save();
            }
        }
        void OnUserGroupAdded(string playerId, string groupName)
        {
            string[] permissions = permission.GetGroupPermissions(groupName);
            BasePlayer player = BasePlayer.FindByID(ulong.Parse(playerId));
            if (player == null) return;
            if (permissions.Contains(useperm) && !data.playerData.ContainsKey(player.userID))
            {
                data.playerData.Add(player.userID, new TheDoorKnockerData()
                {
                    lastSeen = DateTime.Now,
                    playerPreferences = new TheDoorKnockerPlayerPreferences()
                    {
                        basicRocket = true,
                        fireRocket = false,
                        hvRocket = true,
                        smokeRocket = false
                    },
                    playerRockets = config.defaultPlayerData.amount,
                    rocketsEnabled = config.defaultPlayerData.enabled
                });
                data.Save();
                
            }

        }


        void OnRocketLaunched(BasePlayer player, BaseEntity entity)
        {
            if (!permission.UserHasPermission(player.UserIDString, useperm) || data.playerData[player.userID].rocketsEnabled == false) return;
            int rockettype;
            BaseProjectile.Magazine rocketMagazine = player.GetHeldEntity()?.GetComponent<BaseProjectile>()?.primaryMagazine;
            Item heldItem = player.GetActiveItem();
            int rocketsSent = data.playerData[player.userID].playerRockets;
            if (rocketsSent > GetMaxRockets(player)) rocketsSent = GetMaxRockets(player);
            switch (rocketMagazine?.ammoType.shortname)
            {
                case "ammo.rocket.basic":
                    if (config.blockTypes.Contains("basic") || data.playerData[player.userID].playerPreferences.basicRocket == false) return;
                    rockettype = 1;
                    break;
                case "ammo.rocket.hv":
                    if (config.blockTypes.Contains("hv") || data.playerData[player.userID].playerPreferences.hvRocket == false) return;
                    rockettype = 2;
                    break;
                case "ammo.rocket.fire":
                    if (config.blockTypes.Contains("fire") || data.playerData[player.userID].playerPreferences.fireRocket == false) return;
                    rockettype = 3;
                    break;
                case "ammo.rocket.smoke":
                    if (config.blockTypes.Contains("smoke") || data.playerData[player.userID].playerPreferences.smokeRocket == false) return;
                    rockettype = 4;
                    break;
                default:
                    if (data.playerData[player.userID].playerPreferences.basicRocket == false) return;
                    rockettype = 1;
                    break;
            }

            if (rocketMagazine != null && heldItem.info.shortname == "rocket.launcher" && rocketsSent > 0)
            {
                SpawnRockets(player, rocketsSent, rockettype);
            }
        }

        void Unload()
        {
            data.Save();
        }


        #endregion

        #region Commands

        private void CmdHandleRockets(BasePlayer player, string command, string[] args)
        {
            // Checks if the player is null (isn't there) or if the player doesn't have permission
            if (player == null || !permission.UserHasPermission(player.UserIDString, useperm))
            {
                // If they don't have permission they will be alerted and nothing further will happen.
                PrintToChat(player, string.Format(lang.GetMessage("NoPermission", this, player.UserIDString)));
                return;
            }
            // If there are no args or if there's too many arguments let the player know
            if (args.Length == 0 || args.Length > 2)
            {
                PrintToChat(player, lang.GetMessage("NoArgs", this, player.UserIDString));
                return;
            }
            // Get the max rockets available to the player
            int maxRockets = GetMaxRockets(player);
            // Check if they do not have a permission to allow extra rockets and alert the player
            if (maxRockets == 0)
            {
                PrintToChat(player, lang.GetMessage("InvalidRockets", this, player.UserIDString));
                return;
            }
            // Try to parse the first argument as an int and continue through with changing rocket amount
            int amount;
            if (int.TryParse(args[0], out amount))
            {
                // Check if the player is trying to set rocket amount higher than they have permission for
                if (amount > maxRockets)
                {
                    PrintToChat(player, string.Format(lang.GetMessage("TooMany", this, player.UserIDString), maxRockets));
                    return;
                }

                if (amount == 0)
                {
                    PrintToChat(player, lang.GetMessage("NoZero", this, player.UserIDString));
                    return;
                }

                // Update player rockets in data for persistent storage.
                data.UpdateAmount(player.userID, amount);
                PrintToChat(player, string.Format(lang.GetMessage("ChangeRockets", this, player.UserIDString), amount));
                return;
            }
            // Try to parse the first argument as a boolean and continue through with enabling/disabling extra rockets being sent
            bool enabled;
            if (bool.TryParse(args[0], out enabled))
            {
                // Update whether or not the player has TDK enabled
                data.UpdateEnabled(player.userID, enabled);
                // Catch whether they turned on or off TDK and let them know of the change
                switch (enabled)
                {
                    case true:
                        PrintToChat(player, lang.GetMessage("TurnedOn", this, player.UserIDString));
                        return;
                    case false:
                        PrintToChat(player, lang.GetMessage("TurnedOff", this, player.UserIDString));
                        return;
                }
            }

            if (args[0].ToLower() == "toggle")
            {
                switch (args[1].ToLower())
                {
                    case "basic":
                        if (config.blockTypes.Contains(args[1]))
                        {
                            PrintToChat(player, string.Format(lang.GetMessage("TypeDisabledTryToggle", this, player.UserIDString), "basic"));
                            break;
                        }
                        data.playerData[player.userID].playerPreferences.basicRocket = !data.playerData[player.userID].playerPreferences.basicRocket;

                        switch (data.playerData[player.userID].playerPreferences.basicRocket)
                        {
                            case true:
                                PrintToChat(player, string.Format(lang.GetMessage("TypeToggled", this, player.UserIDString), "enabled", "basic"));
                                break;
                            default:
                                PrintToChat(player, string.Format(lang.GetMessage("TypeToggled", this, player.UserIDString), "disabled", "basic"));
                                break;
                        }

                        data.Save();
                        break;
                    case "hv":
                        if (config.blockTypes.Contains(args[1]))
                        {
                            PrintToChat(player, string.Format(lang.GetMessage("TypeDisabledTryToggle", this, player.UserIDString), "hv"));
                            break;
                        }
                        data.playerData[player.userID].playerPreferences.hvRocket = !data.playerData[player.userID].playerPreferences.hvRocket;
                        switch (data.playerData[player.userID].playerPreferences.hvRocket)
                        {
                            case true:
                                PrintToChat(player, string.Format(lang.GetMessage("TypeToggled", this, player.UserIDString), "enabled", "hv"));
                                break;
                            default:
                                PrintToChat(player, string.Format(lang.GetMessage("TypeToggled", this, player.UserIDString), "disabled", "hv"));
                                break;
                        }
                        data.Save();
                        break;
                    case "fire":
                        if (config.blockTypes.Contains(args[1]))
                        {
                            PrintToChat(player, string.Format(lang.GetMessage("TypeDisabledTryToggle", this, player.UserIDString), "incendiary"));
                            break;
                        }
                        data.playerData[player.userID].playerPreferences.fireRocket = !data.playerData[player.userID].playerPreferences.fireRocket;
                        switch (data.playerData[player.userID].playerPreferences.fireRocket)
                        {
                            case true:
                                PrintToChat(player, string.Format(lang.GetMessage("TypeToggled", this, player.UserIDString), "enabled", "incendiary"));
                                break;
                            default:
                                PrintToChat(player, string.Format(lang.GetMessage("TypeToggled", this, player.UserIDString), "disabled", "incendiary"));
                                break;
                        }
                        data.Save();
                        break;
                    case "smoke":
                        if (config.blockTypes.Contains(args[1]))
                        {
                            PrintToChat(player, string.Format(lang.GetMessage("TypeDisabledTryToggle", this, player.UserIDString), "smoke"));
                            break;
                        }
                        data.playerData[player.userID].playerPreferences.smokeRocket = !data.playerData[player.userID].playerPreferences.smokeRocket;
                        switch (data.playerData[player.userID].playerPreferences.smokeRocket)
                        {
                            case true:
                                PrintToChat(player, string.Format(lang.GetMessage("TypeToggled", this, player.UserIDString), "enabled", "smoke"));
                                break;
                            default:
                                PrintToChat(player, string.Format(lang.GetMessage("TypeToggled", this, player.UserIDString), "disabled", "smoke"));
                                break;
                        }
                        data.Save();
                        break;
                    default:
                        PrintToChat(player, lang.GetMessage("InvalidTypeToggle", this, player.UserIDString));
                        break;
                }
            }
        }


        #endregion

        #region CUI
        //TODO Get a CUI design for a nice and easy way for players to configure their own settings and move away from chat commands.
        /*public void CUI_CmdOpenSettings(BasePlayer player)
        {

        }

        [ConsoleCommand("thedoorknocker.cui.toggle")]
        public void CUI_CmdButtonToggle(ConsoleSystem.Arg args, string command, string[] arg)
        {
            BasePlayer player = args.Player();
            if (player == null) return;
            CUI_CmdOpenSettings(player);
        }
        [ConsoleCommand("thedoorknocker.cui.closesettings")]
        public void CUI_CmdSettingsClose(BasePlayer player)
        {
            CuiHelper.DestroyUi(player, "placeholder");
        }*/

        #endregion

        #region Helpers

        private int GetMaxRockets(BasePlayer player)
        {
            int max = config.defaultPlayerData.amount;

            foreach (var kvp in config.maxRocketPermission)
            {
                if (permission.UserHasPermission(player.UserIDString, kvp.Key))
                {
                    max = Mathf.Max(max, kvp.Value);
                }
            }

            return max > 0 ? max : 0;
        }

        /*
           assets/prefabs/ammo/rocket/ammo_rocket_basic.item.prefab
           assets/prefabs/ammo/rocket/ammo_rocket_fire.item.prefab
           assets/prefabs/ammo/rocket/ammo_rocket_hv.item.prefab
           assets/prefabs/ammo/rocket/ammo_rocket_smoke.item.prefab
         */


        private void SpawnRockets(BasePlayer player, int amount, int type)
        {
            Item item = player.GetActiveItem();
            string rocketprefab;
            int rocketid;
            int velocity;
            switch (type)
            {
                case 1:
                    rocketprefab = "assets/prefabs/ammo/rocket/rocket_basic.prefab";
                    rocketid = -742865266;
                    velocity = config.rocketSpeeds.basicVelocity;
                    break;
                case 2:
                    rocketprefab = "assets/prefabs/ammo/rocket/rocket_hv.prefab";
                    rocketid = -1841918730;
                    velocity = config.rocketSpeeds.hvVelocity;
                    break;
                case 3:
                    rocketprefab = "assets/prefabs/ammo/rocket/rocket_fire.prefab";
                    rocketid = 1638322904;
                    velocity = config.rocketSpeeds.fireVelocity;
                    break;
                case 4:
                    rocketprefab = "assets/prefabs/ammo/rocket/rocket_smoke.prefab";
                    rocketid = -17123659;
                    velocity = config.rocketSpeeds.smokeVelocity;
                    break;
                default:
                    rocketprefab = "assets/prefabs/ammo/rocket/rocket_basic.prefab";
                    rocketid = -742865266;
                    velocity = config.rocketSpeeds.basicVelocity;
                    break;
            }

            for (int i = 1; i <= amount; i++)
            {
                int rocketsInInventory = player.inventory.GetAmount(rocketid);
                if (rocketsInInventory < 1 || item.info.shortname != "rocket.launcher" || item.condition <= 0) return;
                if (config.takeDurability)
                {
                    item.LoseCondition(config.durabilityAmount);
                }
                Vector3 aimDirection = Quaternion.Euler(player.serverInput.current.aimAngles) * Vector3.forward;
                aimDirection = Quaternion.Euler(Random.Range(-config.aimCone, config.aimCone), Random.Range(-config.aimCone, config.aimCone), 0) * aimDirection;
                TimedExplosive rocket = GameManager.server.CreateEntity(rocketprefab, player.eyes.position + player.eyes.HeadForward(), player.transform.rotation) as TimedExplosive;
                if (rocket != null) rocket.creatorEntity = player;
                ServerProjectile rocketProjectile = rocket?.GetComponent<ServerProjectile>();
                rocketProjectile?.InitializeVelocity(aimDirection * velocity);
                rocket?.Spawn();
                player.inventory.Take(null, rocketid, 1);

            }

            
        }

        #endregion

        #region Configuration

        private static ConfigData config;

        private class ConfigData
        {
            [JsonProperty(PropertyName = "Permissions and allowed max rockets per permission")]
            public Dictionary<string, int> maxRocketPermission;

            [JsonProperty(PropertyName = "Chat based command (/{command} {bool | # | toggle [basic, hv, fire, smoke]}")]
            public string rocketamtcmd;

            /*[JsonProperty(PropertyName = "Command to bring up CUI")]
            public string rocketCuiCmd;*/

            [JsonProperty(PropertyName = "Rocket spread (Larger number means more spread lower number means less spread)")]
            public float aimCone;

            [JsonProperty(PropertyName = "Rocket types to block?")]
            public List<string> blockTypes;

            [JsonProperty(PropertyName = "Default player data")]
            public TheDoorKnockerDefaultPlayerData defaultPlayerData;

            [JsonProperty(PropertyName = "Clean up old player data?")]
            public bool cleanOldData;

            [JsonProperty(PropertyName = "How many days since last connection should data be erased?")]
            public double daysSinceLastSeenToClean;

            [JsonProperty(PropertyName = "Should TDK take durability per extra rocket?")]
            public bool takeDurability;

            [JsonProperty(PropertyName = "Amount of durability taken per 1 rocket")]
            public int durabilityAmount;

            /*
            [JsonProperty(PropertyName = "Enable toggle CUI button on screen?")]
            public bool showToggle;

            [JsonProperty(PropertyName = "Toggle button image URL")]
            public string toggleButtonImageURL;*/

            [JsonProperty(PropertyName = "Wipe data every map wipe?")]
            public bool wipeOnWipe;

            [JsonProperty(PropertyName = "Custom rocket speeds (For additional rockets fired)")]
            public TheDoorKnockerRocketSpeeds rocketSpeeds;
        }

        private ConfigData GetDefaultConfig()
        {
            return new ConfigData
            {
                maxRocketPermission = new Dictionary<string, int>()
                {
                    {"thedoorknocker.basic", 2},
                    {"thedoorknocker.vip", 3},
                    {"thedoorknocker.example", 69}
                },
                rocketamtcmd = "tdk",
                //rocketCuiCmd = "tdk.cui",
                blockTypes = new List<string>()
                {
                    "smoke",
                    "fire"
                },
                aimCone = 4.0f,
                cleanOldData = true,
                daysSinceLastSeenToClean = 7,
                takeDurability = false,
                durabilityAmount = 1,
                //showToggle = true,
                //toggleButtonImageURL = "https://cdn.rustbyte.dev/u/vh0v1j.webp",
                wipeOnWipe = true,
                defaultPlayerData = new TheDoorKnockerDefaultPlayerData()
                {
                    amount = 1,
                    enabled = true
                },
                rocketSpeeds = new TheDoorKnockerRocketSpeeds()
                {
                    basicVelocity = 22,
                    fireVelocity = 22,
                    hvVelocity = 44,
                    smokeVelocity = 22
                }
            };
        }

        protected override void LoadConfig()
        {
            base.LoadConfig();

            try
            {
                config = Config.ReadObject<ConfigData>();

                if (config == null)
                {
                    LoadDefaultConfig();
                }
            }
            catch
            {
                PrintError("Configuration file is corrupt! Unloading plugin...");
                Interface.Oxide.RootPluginManager.RemovePlugin(this);
                return;
            }

            SaveConfig();
        }

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

        protected override void SaveConfig()
        {
            Config.WriteObject(config);
        }


        public class TheDoorKnockerDefaultPlayerData
        {
            [JsonProperty(PropertyName = "Enable TDK by default?")]
            public bool enabled;
            [JsonProperty(PropertyName = "Amount of rockets sent by default")]
            public int amount;

        }

        public class TheDoorKnockerRocketSpeeds
        {
            [JsonProperty(PropertyName = "Basic rocket speed")]
            public int basicVelocity;
            [JsonProperty(PropertyName = "HV rocket speed")]
            public int hvVelocity;
            [JsonProperty(PropertyName = "Smoke rocket speed")]
            public int smokeVelocity;
            [JsonProperty(PropertyName = "Fire rocket speed")]
            public int fireVelocity;
        }




        #endregion

        #region Data Handling

        class SavedData
        {
            [JsonProperty("Player data")]
            public Dictionary<ulong, TheDoorKnockerData> playerData = new Dictionary<ulong, TheDoorKnockerData>();
            //instance.Name
            public static SavedData Load() =>
                Interface.Oxide.DataFileSystem.ReadObject<SavedData>("The Door Knocker\\TDK_playerData") ?? new SavedData();

            public void Save() =>
                Interface.Oxide.DataFileSystem.WriteObject<SavedData>("The Door Knocker\\TDK_playerData", this);

            public void UpdateAmount(ulong userId, int rocketAmount)
            {
                if (!playerData.ContainsKey(userId)) return;
                playerData[userId].playerRockets = rocketAmount;
                Save();

            }

            public void UpdateEnabled(ulong userId, bool enabled)
            {
                if (!playerData.ContainsKey(userId)) return;
                playerData[userId].rocketsEnabled = enabled;
                Save();
            }

        }

        public class TheDoorKnockerData
        {
            [JsonProperty(PropertyName = "# of rockets set")] 
            public int playerRockets;
            [JsonProperty(PropertyName = "Rockets enabled?")] 
            public bool rocketsEnabled;
            [JsonProperty(PropertyName = "Time last seen")] 
            public DateTime lastSeen;
            [JsonProperty(PropertyName = "Player preferences")]
            public TheDoorKnockerPlayerPreferences playerPreferences;
        }

        public class TheDoorKnockerPlayerPreferences
        {
            public bool basicRocket;
            public bool hvRocket;
            public bool fireRocket;
            public bool smokeRocket;
        }

        #endregion

        #region Language

        Dictionary<string, string> _messages = new Dictionary<string, string>()
        {
            { "NoPermission", "You lack <color=#FF0000>permission</color> to use this command." },
            { "TurnedOn", "You have <color=#00FBFF>enabled</color> more rockets per shot." },
            { "TurnedOff", "You have <color=#FF0000>disabled</color> more rockets per shot." },
            { "ChangeRockets", "Successfully changed rockets sent to <color=#0394fc>{0}</color>"},
            { "NoArgs", "Available arguments are <color=#03f8fc>true/false | # of rockets | toggle [basic/hv/fire/smoke]</color>"},
            { "InvalidRockets", "You lack permission to launch more than one rocket.\nIf you believe this is a mistake please contact your administrator."},
            { "TooMany", "You cannot choose more than {0} rockets."},
            { "NoAmount", "You do not have a configured amount of rockets set. Please set your rockets with /{0}"},
            { "NoZero", "Please disable TheDoorKnocker instead of setting your rockets sent to 0."},
            { "InvalidTypeToggle", "Type is unrecognized, valid types are: basic, hv, fire, smoke, homing"},
            { "TypeDisabledTryToggle", "You're unable to toggle {0} rockets as they are disabled."},
            { "TypeToggled", "You have {0} {1} rockets."}
        };

        #endregion

    }
}

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