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

FREE SleeperGuard : 1.1.2 1.1.2

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

namespace Oxide.Plugins
{
    [Info("Sleeper Guard", "Wulf/lukespragg/Arainrr", "1.1.2")]
    [Description("Protects sleeping players from being hurt, killed, or looted")]
    public class SleeperGuard : RustPlugin
    {
        #region Fields

        [PluginReference] private readonly Plugin Friends, Clans;

        private const string permCanLoot = "sleeperguard.canloot";
        private const string permCanDamage = "sleeperguard.candamage";
        private const string permNPCIgnore = "sleeperguard.npcignore";
        private const string permNoTimeLimit = "sleeperguard.notimelimit";
        private const string permNoLootDelay = "sleeperguard.nolootdelay";
        private const string permNoDamageDelay = "sleeperguard.nodamagedelay";
        private const string permLootProtection = "sleeperguard.lootprotection";
        private const string permDamageProtection = "sleeperguard.damageprotection";

        private readonly Dictionary<ulong, float> noticeTimes = new Dictionary<ulong, float>();

        //Reduce boxing
        private static readonly object True = true, False = false, Null = null;

        #endregion Fields

        #region Oxide Hooks

        private void Init()
        {
            LoadData();
            permission.RegisterPermission(permCanLoot, this);
            permission.RegisterPermission(permCanDamage, this);
            permission.RegisterPermission(permNPCIgnore, this);
            permission.RegisterPermission(permNoTimeLimit, this);
            permission.RegisterPermission(permNoLootDelay, this);
            permission.RegisterPermission(permNoDamageDelay, this);
            permission.RegisterPermission(permLootProtection, this);
            permission.RegisterPermission(permDamageProtection, this);
            if (!configData.ignoreSleeper)
            {
                Unsubscribe(nameof(OnNpcTarget));
                Unsubscribe(nameof(CanBradleyApcTarget));
            }
        }

        private void OnServerInitialized()
        {
            if (storedData.lastSavedTimestamp > 0)
            {
                double unloadedPluginTime = TimeEx.currentTimestamp - storedData.lastSavedTimestamp;
                foreach (var entry in storedData.sleeperDatas)
                    entry.Value.ignoredTime += unloadedPluginTime;
            }
            foreach (var sleeper in BasePlayer.sleepingPlayerList)
                OnPlayerSleep(sleeper);
        }

        private void OnServerSave() => timer.Once(UnityEngine.Random.Range(0f, 60f), SaveData);

        private void Unload() => SaveData();

        private object OnNpcTarget(BaseEntity npc, BasePlayer player) => CanIgnoreSleeper(player) ? True : Null;

        private object CanBradleyApcTarget(BradleyAPC apc, BasePlayer player) => CanIgnoreSleeper(player) ? False : Null;

        private object OnEntityTakeDamage(BasePlayer target, HitInfo info)
        {
            if (target == null || !target.userID.IsSteamId()) return Null;
            if (target.IsSleeping())
            {
                BasePlayer attacker = info?.InitiatorPlayer;
                if (attacker != null && permission.UserHasPermission(attacker.UserIDString, permCanDamage)) return Null;
                if (permission.UserHasPermission(target.UserIDString, permDamageProtection))
                {
                    double timeleft;
                    if (CanGuardPlayer(target, false, out timeleft))
                    {
                        if (configData.notifyPlayer && attacker != null && CanNotice(attacker))
                        {
                            Print(attacker, Lang("NoDamage", attacker.UserIDString, timeleft.ToString("0.0")));
                        }
                        NullifyDamage(ref info);
                        return True;
                    }
                }
            }
            return Null;
        }

        private object CanLootPlayer(BasePlayer target, BasePlayer looter)
        {
            if (target == null || looter == null || !target.IsSleeping()) return Null;
            if (permission.UserHasPermission(looter.UserIDString, permCanLoot)) return Null;
            if (permission.UserHasPermission(target.UserIDString, permLootProtection))
            {
                double timeleft;
                if (CanGuardPlayer(target, true, out timeleft) && !AreFriends(target.userID, looter.userID))
                {
                    if (configData.notifyPlayer && CanNotice(looter))
                    {
                        Print(looter, Lang("NoLoot", looter.UserIDString, timeleft.ToString("0.0")));
                    }
                    return False;
                }
            }
            return Null;
        }

        private void OnPlayerSleep(BasePlayer player)
        {
            if (!storedData.sleeperDatas.ContainsKey(player.userID))
            {
                storedData.sleeperDatas.Add(player.userID, new StoredData.TimeData());
            }
        }

        private void OnPlayerSleepEnded(BasePlayer player)
        {
            storedData.sleeperDatas.Remove(player.userID);
        }

        #endregion Oxide Hooks

        #region Methods

        private bool CanGuardPlayer(BasePlayer sleeper, bool isLoot, out double timeleft)
        {
            StoredData.TimeData timeData;
            if (!storedData.sleeperDatas.TryGetValue(sleeper.userID, out timeData))
            {
                timeleft = 0;
                return false;
            }
            if (permission.UserHasPermission(sleeper.UserIDString, permNoTimeLimit))
            {
                timeleft = -1;
                return true;
            }
            double secondsSleeping = timeData.SecondsSleeping;
            if (isLoot)
            {
                if (configData.lootDelay <= 0 || secondsSleeping >= configData.lootDelay || permission.UserHasPermission(sleeper.UserIDString, permNoLootDelay))
                {
                    if (configData.lootGuardTime <= 0)
                    {
                        timeleft = -1;
                        return true;
                    }
                    timeleft = configData.lootGuardTime - secondsSleeping;
                    if (timeleft > 0)
                    {
                        return true;
                    }
                }
            }
            else
            {
                if (configData.damageDelay <= 0 || secondsSleeping >= configData.damageDelay || permission.UserHasPermission(sleeper.UserIDString, permNoDamageDelay))
                {
                    if (configData.damageGuardTime <= 0)
                    {
                        timeleft = -1;
                        return true;
                    }
                    timeleft = configData.damageGuardTime - secondsSleeping;
                    if (timeleft > 0)
                    {
                        return true;
                    }
                }
            }
            timeleft = 0;
            return false;
        }

        private bool CanIgnoreSleeper(BasePlayer player)
        {
            if (player == null || !player.userID.IsSteamId() || !player.IsSleeping()) return false;
            if (!permission.UserHasPermission(player.UserIDString, permNPCIgnore)) return false;
            double timeleft;
            return permission.UserHasPermission(player.UserIDString, permDamageProtection) && CanGuardPlayer(player, false, out timeleft);
        }

        private bool CanNotice(BasePlayer player)
        {
            float lastTime;
            if (!noticeTimes.TryGetValue(player.userID, out lastTime))
            {
                noticeTimes.Add(player.userID, Time.realtimeSinceStartup);
                return true;
            }
            if (Time.realtimeSinceStartup - lastTime >= configData.notifyInterval)
            {
                noticeTimes[player.userID] = Time.realtimeSinceStartup;
                return true;
            }
            return false;
        }

        #region AreFriends

        private bool AreFriends(ulong playerID, ulong friendID)
        {
            if (!playerID.IsSteamId()) return false;
            if (playerID == friendID) return true;
            if (configData.useTeams && SameTeam(playerID, friendID)) return true;
            if (configData.useFriends && HasFriend(playerID, friendID)) return true;
            if (configData.useClans && SameClan(playerID, friendID)) return true;
            return false;
        }

        private static bool SameTeam(ulong playerID, ulong friendID)
        {
            if (!RelationshipManager.TeamsEnabled()) return false;
            var playerTeam = RelationshipManager.ServerInstance.FindPlayersTeam(playerID);
            if (playerTeam == null) return false;
            var friendTeam = RelationshipManager.ServerInstance.FindPlayersTeam(friendID);
            if (friendTeam == null) return false;
            return playerTeam == friendTeam;
        }

        private bool HasFriend(ulong playerID, ulong friendID)
        {
            if (Friends == null) return false;
            return (bool)Friends.Call("HasFriend", playerID, friendID);
        }

        private bool SameClan(ulong playerID, ulong friendID)
        {
            if (Clans == null) return false;
            //Clans
            var isMember = Clans.Call("IsClanMember", playerID.ToString(), friendID.ToString());
            if (isMember != null) return (bool)isMember;
            //Rust:IO Clans
            var playerClan = Clans.Call("GetClanOf", playerID);
            if (playerClan == null) return false;
            var friendClan = Clans.Call("GetClanOf", friendID);
            if (friendClan == null) return false;
            return (string)playerClan == (string)friendClan;
        }

        #endregion AreFriends

        #endregion Methods

        #region Helpers

        private static void NullifyDamage(ref HitInfo info)
        {
            info.damageTypes = new DamageTypeList();
            info.HitMaterial = 0;
            info.PointStart = Vector3.zero;
        }

        #endregion Helpers

        #region ConfigurationFile

        private ConfigData configData;

        public class ConfigData
        {
            [JsonProperty(PropertyName = "Use Teams (Used For Loot)")]
            public bool useTeams = false;

            [JsonProperty(PropertyName = "Use Clans (Used For Loot)")]
            public bool useClans = true;

            [JsonProperty(PropertyName = "Use Friends (Used For Loot)")]
            public bool useFriends = true;

            [JsonProperty(PropertyName = "Damage delay (seconds) (0 to disable)")]
            public double damageDelay = 0;

            [JsonProperty(PropertyName = "Damage guard times (seconds) (0 to unlimit)")]
            public double damageGuardTime = 0;

            [JsonProperty(PropertyName = "Loot delay (seconds) (0 to disable)")]
            public double lootDelay = 0;

            [JsonProperty(PropertyName = "Loot guard times (seconds) (0 to unlimit)")]
            public double lootGuardTime = 0;

            [JsonProperty(PropertyName = "Notify player (true/false)")]
            public bool notifyPlayer = true;

            [JsonProperty(PropertyName = "Notification interval (seconds)")]
            public float notifyInterval = 5;

            [JsonProperty(PropertyName = "NPC ignores sleepers (Enabling it can cause server lag)")]
            public bool ignoreSleeper = false;

            [JsonProperty(PropertyName = "Chat Settings")]
            public ChatSettings chatS = new ChatSettings();

            public class ChatSettings
            {
                [JsonProperty(PropertyName = "Chat prefix")]
                public string prefix = "<color=#00FFFF>[SleeperGuard]</color>: ";

                [JsonProperty(PropertyName = "Chat steamID icon")]
                public ulong steamIDIcon = 0;
            }

            [JsonProperty(PropertyName = "Version")]
            public VersionNumber version;
        }

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                configData = Config.ReadObject<ConfigData>();
                if (configData == null)
                {
                    LoadDefaultConfig();
                }
                else
                {
                    UpdateConfigValues();
                }
            }
            catch
            {
                PrintError("The configuration file is corrupted");
                LoadDefaultConfig();
            }
            SaveConfig();
        }

        protected override void LoadDefaultConfig()
        {
            PrintWarning("Creating a new configuration file");
            configData = new ConfigData();
            configData.version = Version;
        }

        protected override void SaveConfig() => Config.WriteObject(configData);

        private void UpdateConfigValues()
        {
            if (configData.version < Version)
            {
                if (configData.version <= default(VersionNumber))
                {
                    string prefix, prefixColor;
                    if (GetConfigValue(out prefix, "Chat prefix") && GetConfigValue(out prefixColor, "Chat prefix color"))
                    {
                        configData.chatS.prefix = $"<color={prefixColor}>{prefix}</color>: ";
                    }
                }
                configData.version = Version;
            }
        }

        private bool GetConfigValue<T>(out T value, params string[] path)
        {
            var configValue = Config.Get(path);
            if (configValue == null)
            {
                value = default(T);
                return false;
            }
            value = Config.ConvertValue<T>(configValue);
            return true;
        }

        #endregion ConfigurationFile

        #region DataFile

        private StoredData storedData;

        private class StoredData
        {
            public double lastSavedTimestamp;
            public readonly Dictionary<ulong, TimeData> sleeperDatas = new Dictionary<ulong, TimeData>();

            public class TimeData
            {
                public double sleepStartTime;
                public double ignoredTime;
                [JsonIgnore] public double SecondsSleeping => TimeEx.currentTimestamp - sleepStartTime - ignoredTime;

                public TimeData()
                {
                    sleepStartTime = TimeEx.currentTimestamp;
                }
            }
        }

        private void LoadData()
        {
            try
            {
                storedData = Interface.Oxide.DataFileSystem.ReadObject<StoredData>(Name);
            }
            catch
            {
                ClearData();
            }
        }

        private void ClearData()
        {
            storedData = new StoredData();
            SaveData();
        }

        private void SaveData()
        {
            storedData.lastSavedTimestamp = TimeEx.currentTimestamp;
            Interface.Oxide.DataFileSystem.WriteObject(Name, storedData);
        }

        private void OnNewSave(string filename) => ClearData();

        #endregion DataFile

        #region LanguageFile

        private void Print(BasePlayer player, string message) => Player.Message(player, message, configData.chatS.prefix, configData.chatS.steamIDIcon);

        private string Lang(string key, string id = null, params object[] args) => string.Format(lang.GetMessage(key, this, id), args);

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["NoDamage"] = "You can't hurt this sleeping player.Protection time left: {0} seconds.",
                ["NoLoot"] = "You can't loot this sleeping player.Protection time left: {0} seconds.",
            }, this);
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["NoDamage"] = "您不能伤害这个睡眠玩家,剩余保护时间: {0} 秒",
                ["NoLoot"] = "您不能掠夺这个睡眠玩家,剩余保护时间: {0} 秒",
            }, this, "zh-CN");
        }

        #endregion LanguageFile
    }
}

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