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

FREE SwitchGuard : 1.3.0 1.3.0

Нет прав для скачивания
C#:
using System;
using System.Collections.Generic;
using HarmonyLib;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Plugins;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("SwitchGuard", "romzar.games", "1.3.0")]
    [Description("Prevents unauthorized players from toggling Industrial Conveyors and Fluid Switches")]
    public class SwitchGuard : RustPlugin
    {
        #region Constants

        private const string PERM_BYPASS = "switchguard.bypass";
        private const string PERM_ADMIN = "switchguard.admin";

        #endregion

        #region Plugin References

        [PluginReference] private Plugin Friends, Clans;

        #endregion

        #region Static Instance

        private static SwitchGuard _instance;

        #endregion

        #region Configuration

        private PluginConfig _config;

        private class PluginConfig
        {
            [JsonProperty("Admin can always toggle (server.IsAdmin bypass)")]
            public bool AdminCanToggle { get; set; } = false;

            [JsonProperty("Use Friends API")]
            public bool UseFriendsAPI { get; set; } = true;

            [JsonProperty("Use Clans API")]
            public bool UseClansAPI { get; set; } = true;

            [JsonProperty("Use Rust Teams")]
            public bool UseTeams { get; set; } = true;

            [JsonProperty("Use TC Authorization")]
            public bool UseTCAuth { get; set; } = true;

            [JsonProperty("Protect Industrial Conveyors")]
            public bool ProtectConveyors { get; set; } = true;

            [JsonProperty("Protect Fluid Switches")]
            public bool ProtectFluidSwitches { get; set; } = true;

            [JsonProperty("Message cooldown (seconds)")]
            public float MessageCooldown { get; set; } = 3.0f;
        }

        protected override void LoadDefaultConfig()
        {
            _config = new PluginConfig();
            SaveConfig();
        }

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                _config = Config.ReadObject<PluginConfig>() ?? new PluginConfig();
            }
            catch (Exception ex)
            {
                PrintError($"Failed to load config: {ex.Message}");
                _config = new PluginConfig();
            }
            SaveConfig();
        }

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

        #endregion

        #region State

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

        #endregion

        #region Localization

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["NotAuthorized"] = "You are not authorized to toggle this device.",
                ["NoPermission"] = "You do not have permission to use this."
            }, this, "en");

            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["NotAuthorized"] = "Voce nao tem autorizacao para ligar/desligar este dispositivo.",
                ["NoPermission"] = "Voce nao tem permissao para usar isso."
            }, this, "pt-BR");

            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["NotAuthorized"] = "No tienes autorizacion para activar/desactivar este dispositivo.",
                ["NoPermission"] = "No tienes permiso para usar esto."
            }, this, "es-ES");
        }

        private string Lang(string key, BasePlayer player = null)
        {
            return lang.GetMessage(key, this, player?.UserIDString);
        }

        #endregion

        #region Lifecycle

        private void Init()
        {
            _instance = this;

            permission.RegisterPermission(PERM_BYPASS, this);
            permission.RegisterPermission(PERM_ADMIN, this);
        }

        private void Unload()
        {
            _instance = null;
            _messageCooldowns.Clear();
        }

        private void OnPlayerDisconnected(BasePlayer player, string reason)
        {
            if (player == null) return;
            _messageCooldowns.Remove((ulong)player.userID);
        }

        #endregion

        #region Harmony Patches

        [AutoPatch]
        [HarmonyPatch(typeof(IndustrialConveyor), "SvSwitch")]
        public static class Patch_ConveyorSvSwitch
        {
            public static bool Prefix(IndustrialConveyor __instance, BaseEntity.RPCMessage msg)
            {
                if (_instance == null || !_instance._config.ProtectConveyors) return true;
                if (__instance == null || __instance.IsDestroyed) return true;

                var player = msg.player;
                if (player == null) return true;

                return _instance.CanToggleEntity(player, __instance);
            }
        }

        [AutoPatch]
        [HarmonyPatch(typeof(ElectricSwitch), "RPC_Switch")]
        public static class Patch_FluidSwitchRpcSwitch
        {
            public static bool Prefix(ElectricSwitch __instance, BaseEntity.RPCMessage msg)
            {
                if (_instance == null || !_instance._config.ProtectFluidSwitches) return true;
                if (!(__instance is FluidSwitch)) return true;
                if (__instance.IsDestroyed) return true;

                var player = msg.player;
                if (player == null) return true;

                return _instance.CanToggleEntity(player, __instance);
            }
        }

        #endregion

        #region Authorization Logic

        private bool CanToggleEntity(BasePlayer player, BaseEntity entity)
        {
            if (player == null || entity == null || entity.IsDestroyed) return true;

            ulong playerId = (ulong)player.userID;
            string playerIdString = player.UserIDString;

            if (permission.UserHasPermission(playerIdString, PERM_BYPASS))
                return true;

            if (permission.UserHasPermission(playerIdString, PERM_ADMIN))
                return true;

            if (_config.AdminCanToggle && player.IsAdmin)
                return true;

            ulong ownerId = entity.OwnerID;
            if (ownerId == 0UL) return true;
            if (playerId == ownerId) return true;

            if (_config.UseTCAuth && IsAuthedOnTC(player, entity))
                return true;

            if (_config.UseClansAPI && IsClanMemberOrAlly(ownerId, playerId))
                return true;

            if (_config.UseFriendsAPI && IsFriend(ownerId, playerId))
                return true;

            if (_config.UseTeams && IsTeammate(ownerId, playerId))
                return true;

            SendCooldownMessage(player, "NotAuthorized");
            return false;
        }

        #endregion

        #region Friend/Clan/Team Checks

        private bool IsAuthedOnTC(BasePlayer player, BaseEntity entity)
        {
            if (player == null || entity == null) return false;

            var priv = player.GetBuildingPrivilege(entity.WorldSpaceBounds());
            if (priv == null) return false;

            return priv.IsAuthed(player);
        }

        private bool IsClanMemberOrAlly(ulong ownerId, ulong playerId)
        {
            if (Clans == null) return false;

            try
            {
                var result = Clans.Call("IsMemberOrAlly", ownerId.ToString(), playerId.ToString());
                if (result is bool b) return b;
            }
            catch (Exception ex)
            {
                PrintWarning($"Clans API error: {ex.Message}");
            }

            return false;
        }

        private bool IsFriend(ulong ownerId, ulong playerId)
        {
            if (Friends == null) return false;

            try
            {
                var result = Friends.Call("AreFriends", ownerId, playerId);
                if (result is bool b) return b;
            }
            catch (Exception ex)
            {
                PrintWarning($"Friends API error: {ex.Message}");
            }

            return false;
        }

        private bool IsTeammate(ulong ownerId, ulong playerId)
        {
            var rm = RelationshipManager.ServerInstance;
            if (rm == null) return false;

            if (!rm.playerToTeam.TryGetValue(playerId, out var team))
                return false;

            return team.members.Contains(ownerId);
        }

        #endregion

        #region Helpers

        private void SendCooldownMessage(BasePlayer player, string langKey)
        {
            if (player == null || !player.IsConnected) return;

            ulong playerId = (ulong)player.userID;
            float now = Time.realtimeSinceStartup;

            if (_messageCooldowns.TryGetValue(playerId, out float lastTime))
            {
                if (now - lastTime < _config.MessageCooldown)
                    return;
            }

            _messageCooldowns[playerId] = now;
            SendReply(player, Lang(langKey, player));
        }

        #endregion
    }
}

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