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

FREE Jail : 3.0.2 3.0.2

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System.Collections.Generic;
using System;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Core.Configuration;
using Oxide.Game.Rust.Cui;
using Newtonsoft.Json;
using UnityEngine;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
namespace Oxide.Plugins {
    [Info("Jail", "Reneb / k1lly0u", "3.0.2", ResourceId = 794)]
    class Jail : RustPlugin {
        [PluginReference]
        Plugin ZoneManager;
        [PluginReference]
        Plugin Spawns;
        [PluginReference]
        Plugin Kits;
        private bool Changed;
        private bool Started = false;
        JailDataStorage jailData;
        private DynamicConfigFile JailData;
        private Dictionary<ulong, int> jailTimerList = new Dictionary<ulong, int>();
        private List<string> prisonIDs = new List<string>();
        private static LayerMask GROUND_MASKS = LayerMask.GetMask("Terrain", "World", "Construction");
#region UI
        class UI {
            static public CuiElementContainer CreateElementContainer(string panelName, string color, string aMin, string aMax, bool useCursor) {
                var NewElement = new CuiElementContainer() {
                    {
                        new CuiPanel {
                            Image = {
                                Color = color
                            }
                            , RectTransform = {
                                AnchorMin = aMin, AnchorMax = aMax
                            }
                            , CursorEnabled = useCursor
                        }
                        , new CuiElement().Parent = "Overlay", panelName
                    }
                }
                ;
                return NewElement;
            }
            static public void CreateLabel(ref CuiElementContainer container, string panel, string color, string text, int size, string aMin, string aMax, TextAnchor align = TextAnchor.MiddleCenter) {
                container.Add(new CuiLabel {
                    Text = {
                        Color = color, FontSize = size, Align = align, Text = text
                    }
                    , RectTransform = {
                        AnchorMin = aMin, AnchorMax = aMax
                    }
                }
                , panel);
            }
        }
        private void CreateJailTimer(BasePlayer player) {
            if (player != null) {
                CuiHelper.DestroyUi(player, "jailTimer");
                if (jailData.Prisoners.ContainsKey(player.userID) && jailTimerList.ContainsKey(player.userID)) {
                    TimeSpan dateDifference = TimeSpan.FromSeconds(jailTimerList[player.userID]);
                    string clock = string.Format("{0:D2}:{1:D2}:{2:D2}", dateDifference.Hours, dateDifference.Minutes, dateDifference.Seconds);
                    if (jailData.Prisoners[player.userID].expireTime == -99999) clock = "~";
                    var container = UI.CreateElementContainer("jailTimer", "0.3 0.3 0.3 0.6", "0.42 0.965", "0.58 0.995", false);
                    UI.CreateLabel(ref container, "jailTimer", "", $"Remaining: {clock}", 18, "0 0", "1 1");
                    CuiHelper.AddUi(player, container);
                    jailTimerList[player.userID]--;
                    if (jailTimerList[player.userID] > 0) timer.Once(1, () => CreateJailTimer(player));
                    else timer.Once(2, () => CheckPlayerExpireTime(player));
                }
            }
        }
#endregion
#region Oxide Hooks
        void Loaded() {
            permission.RegisterPermission("jail.admin", this);
            lang.RegisterMessages(messages, this);
            JailData = Interface.Oxide.DataFileSystem.GetFile("jail_data");
            JailData.Settings.Converters = new JsonConverter[] {
                new StringEnumConverter(), new UnityVector3Converter(),
            }
            ;
        }
        void OnServerInitialized() {
            if (!CheckDependencies()) return;
            LoadData();
            LoadVariables();
            foreach(var player in BasePlayer.activePlayerList) CheckPlayer(player);
        }
        private bool CheckDependencies() {
            if (ZoneManager == null) {
                PrintWarning($"ZoneManager could not be found!");
                return false;
            }
            if (Spawns == null) {
                PrintWarning($"Spawns Database could not be found!");
                return false;
            }
            Started = true;
            return true;
        }
        protected override void LoadDefaultConfig() {
            Puts("Creating a new config file");
            Config.Clear();
            LoadVariables();
        }
        void Unload() {
            if (Started) {
                jailTimerList.Clear();
                foreach (var player in BasePlayer.activePlayerList) {
                    foreach(var jail in jailData.prisons) ZoneManager.Call("RemovePlayerFromZoneKeepinlist", jail.Value.zoneID, player);
                    CuiHelper.DestroyUi(player, "jailTimer");
                }
                SaveData();
            }
        }
        void OnPlayerInit(BasePlayer player) => CheckPlayer(player);
        void OnPlayerSleepEnded(BasePlayer player) => CheckPlayer(player);
        private void OnEntityTakeDamage(BaseCombatEntity entity, HitInfo hitinfo) {
            if (Started) {
                try {
                    if (entity is BasePlayer && hitinfo.Initiator is BasePlayer) {
                        var victim = entity.ToPlayer();
                        var attacker = hitinfo.Initiator.ToPlayer();
                        if (disableDamage) {
                            if (victim.userID != attacker.userID) if (jailData.Prisoners.ContainsKey(victim.userID) && jailData.Prisoners.ContainsKey(attacker.userID)) {
                                hitinfo.damageTypes.ScaleAll(0);
                                SendMsg(attacker, lang.GetMessage("ff", this, attacker.UserIDString));
                            }
                        }
                        else if (!jailData.Prisoners.ContainsKey(victim.userID) && jailData.Prisoners.ContainsKey(attacker.userID)) hitinfo.damageTypes.ScaleAll(0);
                        else if (jailData.Prisoners.ContainsKey(victim.userID) && !jailData.Prisoners.ContainsKey(attacker.userID)) hitinfo.damageTypes.ScaleAll(0);
                    }
                }
                catch (Exception ex) {
                }
            }
        }
        void OnPlayerRespawned(BasePlayer player) => CheckPlayer(player);
        void CheckPlayer(BasePlayer player) {
            if (Started) if (jailData.Prisoners.ContainsKey(player.userID)) CheckInmate(player);
        }
        void CheckInmate(BasePlayer player) {
            if (!CheckPlayerExpireTime(player)) {
                string prisonName = jailData.Prisoners[player.userID].prisonName;
                string zoneID = jailData.prisons[prisonName].zoneID;
                if (!isInZone(player, zoneID)) {
                    int cellNum = jailData.Prisoners[player.userID].cellNumber;
                    object cellPos = FindSpawnPoint(prisonName, cellNum);
                    if (cellPos == null) {
                        Puts("null cell pos");
                        return;
                    }
                    ZoneManager.Call("AddPlayerToZoneKeepinlist", zoneID, player);
                    TeleportPlayerPosition(player, (Vector3)cellPos);
                }
                if (!jailTimerList.ContainsKey(player.userID)) jailTimerList.Add(player.userID, (int)(jailData.Prisoners[player.userID].expireTime - GrabCurrentTime()));
                CreateJailTimer(player);
            }
        }
#endregion
#region Main Functions
        private object FindPlayer(string arg) {
            var foundPlayers = new List<BasePlayer>();
            ulong steamid;
            ulong.TryParse(arg, out steamid);
            string lowerarg = arg.ToLower();
            foreach (var p in BasePlayer.activePlayerList) {
                if (steamid != 0L) if (p.userID == steamid) {
                    foundPlayers.Clear();
                    foundPlayers.Add(p);
                    return foundPlayers[0];
                }
                string lowername = p.displayName.ToLower();
                if (lowername.Contains(lowerarg)) {
                    foundPlayers.Add(p);
                }
            }
            if (foundPlayers.Count == 0) return lang.GetMessage("noPlayers", this);
            if (foundPlayers.Count > 1) return lang.GetMessage("multiPlayers", this);
            return foundPlayers[0];
        }
        private BasePlayer FindPlayerByID(ulong steamid) {
            BasePlayer targetplayer = BasePlayer.FindByID(steamid);
            if (targetplayer != null) {
                return targetplayer;
            }
            targetplayer = BasePlayer.FindSleeping(steamid);
            if (targetplayer != null) {
                return targetplayer;
            }
            return null;
        }
        private void TPPlayer(BasePlayer player, Vector3 pos) {
            player.MovePosition(pos);
            player.ClientRPCPlayer(null, player, "ForcePositionTo", pos);
            player.SetPlayerFlag(BasePlayer.PlayerFlags.ReceivingSnapshot, true);
            player.UpdateNetworkGroup();
            player.SendNetworkUpdateImmediate(false);
            player.ClientRPCPlayer(null, player, "StartLoading", null, null, null, null, null);
            player.SendFullSnapshot();
        }
        private object CheckSpawns(string name) {
            object success = Spawns.Call("GetSpawnsCount", new object[] {
                name
            }
            );
            if (success is string) return null;
            return success;
        }
        private void AddJail(BasePlayer player, string[] args) {
            string name = args[1].ToLower();
            Prison data = new Prison();
            if (CheckSpawns(args[3]) != null) {
                object zoneid = ZoneManager.Call("CheckZoneID", args[2] );
                if (zoneid is string && (string)zoneid != "") {
                    data.zoneID = (string)zoneid;
                    object location = ZoneManager?.Call("GetZoneLocation", (string)zoneid );
                    if (location != null && location is Vector3) data.location = (Vector3)location;
                    else {
                        SendMsg(player, lang.GetMessage("invalidZPos", this, player.UserIDString));
                        return;
                    }
                    object radius = ZoneManager?.Call("GetZoneRadius", (string)zoneid );
                    if (radius != null && radius is float) data.zoneRadius = float.Parse(radius.ToString());
                    else {
                        SendMsg(player, lang.GetMessage("invalidZRad", this, player.UserIDString));
                        return;
                    }
                    data.spawnFile = args[3];
                    int cellCount = (int)CheckSpawns(args[3]);
                    for (int i = 0; i < cellCount; i++) data.freeCells.Add(i, false);
                }
                else {
                    SendMsg(player, lang.GetMessage("invalidZID", this, player.UserIDString) + args[2]);
                    return;
                }
                jailData.prisons.Add(args[1].ToLower(), data);
                SendMsg(player, lang.GetMessage("newJailAdd", this, player.UserIDString));
                SaveData();
                return;
            }
            SendMsg(player, lang.GetMessage("invalidSF", this, player.UserIDString) + args[3]);
        }
        private void RemoveJail(BasePlayer player, string arg) {
            if (jailData.prisons.ContainsKey(arg.ToLower())) {
                EraseJailZone(arg.ToLower());
                jailData.prisons.Remove(arg.ToLower());
                SendMsg(player, lang.GetMessage("remJail", this, player.UserIDString) + arg);
                SaveData();
            }
            else SendMsg(player, lang.GetMessage("noJail", this, player.UserIDString));
        }
        private void EraseJailZone(string zoneID) {
            ZoneManager.Call("EraseZone", zoneID);
            Puts("Jail Zone " + zoneID + " removed.");
        }
        private object SendPlayerToJail(BasePlayer player, string prisonName, int time) {
            object cellNum = FindEmptyCell(prisonName);
            if (cellNum != null) {
                string zoneID = jailData.prisons[prisonName].zoneID;
                object cellPos = FindSpawnPoint(prisonName, (int)cellNum);
                if (cellPos == null) return "noPos";
                jailData.prisons[prisonName].freeCells[(int)cellNum] = true;
                double jailTime = -99999;
                if (time != -99999) jailTime = time + GrabCurrentTime();
                Inmate inmate = new Inmate() {
                    initialPos = player.transform.position, prisonName = prisonName, cellNumber = (int)cellNum, expireTime = jailTime
                }
                ;
                jailData.Prisoners.Add(player.userID, inmate);
                SendMsg(player, lang.GetMessage("sentPrison", this, player.UserIDString));
                timer.Once(5, ()=> {
                    SaveInventory(player);
                    ZoneManager.Call("AddPlayerToZoneKeepinlist", zoneID, player);
                    player.inventory.Strip();
                    TeleportPlayerPosition(player, (Vector3)cellPos);
                    jailTimerList.Add(player.userID, time);
                    CreateJailTimer(player);
                    SendMsg(player, lang.GetMessage("checkTime", this, player.UserIDString));
                    if (giveKit) {
                        if (kitName == null || kitName == "") return;
                        Kits?.Call("GiveKit", player, kitName);
                    }
                }
                );
                SaveData();
                return true;
            }
            return "noCells";
        }
        private void FreeFromJail(BasePlayer player) {
            string prisonName = jailData.Prisoners[player.userID].prisonName;
            int cellNum = jailData.Prisoners[player.userID].cellNumber;
            string zoneID = jailData.prisons[prisonName].zoneID;
            CuiHelper.DestroyUi(player, "jailTimer");
            if (jailTimerList.ContainsKey(player.userID)) jailTimerList.Remove(player.userID);
            jailData.prisons[prisonName].freeCells[cellNum] = false;
            RestoreInventory(player);
            SendMsg(player, lang.GetMessage("relPrison", this, player.UserIDString));
            Vector3 freePos = CalculateFreePos(prisonName);
            if (useInitialSpawns) freePos = jailData.Prisoners[player.userID].initialPos;
            jailData.Prisoners.Remove(player.userID);
            ZoneManager.Call("RemovePlayerFromZoneKeepinlist", zoneID, player);
            TeleportPlayerPosition(player, freePos);
            SaveData();
        }
        private object FindSpawnPoint(string prisonName, int cellNumber) {
            object cellPos = Spawns?.Call("GetSpawn", new object[] {
                jailData.prisons[prisonName].spawnFile, cellNumber
            }
            );
            if (cellPos is string) {
                Puts((string)cellPos);
                return null;
            }
            return (Vector3)cellPos;
        }
        private Vector3 CalculateFreePos(string prisonName) {
            Vector3 zonePos = jailData.prisons[prisonName].location;
            float zoneRadius = jailData.prisons[prisonName].zoneRadius;
            Vector3 calcPos = zonePos + new Vector3(zoneRadius + 10, 0, 0);
            Vector3 finalPos = CalculateGroundPos(calcPos);
            return finalPos;
        }
        static Vector3 CalculateGroundPos(Vector3 sourcePos)  // credit Wulf & Nogrod
        {
            RaycastHit hitInfo;
            if (Physics.Raycast(sourcePos, Vector3.down, out hitInfo, GROUND_MASKS)) {
                sourcePos.y = hitInfo.point.y;
            }
            sourcePos.y = Mathf.Max(sourcePos.y, TerrainMeta.HeightMap.GetHeight(sourcePos));
            return sourcePos;
        }
        private bool CheckPlayerExpireTime(BasePlayer player) {
            if (!player.IsConnected()) return false;
            if (player.IsDead()) return false;
            double time = jailData.Prisoners[player.userID].expireTime;
            if (time == -99999) return false;
            double timeLeft = time - GrabCurrentTime();
            if (timeLeft <= 0) {
                jailTimerList.Remove(player.userID);
                FreeFromJail(player);
                return true;
            }
            return false;
        }
        void TeleportPlayerPosition(BasePlayer player, Vector3 destination) {
            player.MovePosition(destination);
            player.ClientRPCPlayer(null, player, "ForcePositionTo", destination);
            player.SetPlayerFlag(BasePlayer.PlayerFlags.ReceivingSnapshot, true);
            player.UpdateNetworkGroup();
            player.SendNetworkUpdateImmediate(false);
            player.ClientRPCPlayer(null, player, "StartLoading", null, null, null, null, null);
            player.SendFullSnapshot();
        }
        private string FindEmptyPrison() {
            List<string> emptyPrisons = new List<string>();
            int num = 0;
            foreach (var prison in jailData.prisons) {
                foreach (var cell in prison.Value.freeCells) if (cell.Value == false) num++;
                if (num > 0) return prison.Key;
            }
            return null;
        }
        private object FindEmptyCell(string prisonName) {
            int emptyCell = -1;
            foreach (var cell in jailData.prisons[prisonName].freeCells) {
                if (cell.Value == false) {
                    emptyCell = cell.Key;
                    break;
                }
            }
            if (emptyCell == -1) return null;
            return emptyCell;
        }
        static double GrabCurrentTime() => DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds;
        private void SendMsg(BasePlayer player, string msg) {
            SendReply(player, lang.GetMessage("title", this, player.UserIDString) + msgColor + msg + "</color>");
        }
        private bool IsPrisoner(BasePlayer player) {
            if (jailData.Prisoners.ContainsKey(player.userID)) return true;
            return false;
        }
#endregion
#region ZoneManager Hooks
        bool isInZone(BasePlayer player, string zoneID) {
            if (ZoneManager == null) return false;
            return (bool)ZoneManager.Call("isPlayerInZone", zoneID, player);
        }
        void OnEnterZone(string ZoneID, BasePlayer player) {
            if (Started) if (prisonIDs.Contains(ZoneID)) {
                if (hasPermission(player)) {
                    SendMsg(player, string.Format(lang.GetMessage("welcomeJail", this, player.UserIDString), player.displayName));
                    return;
                }
                else if (!jailData.Prisoners.ContainsKey(player.userID)) {
                    SendMsg(player, lang.GetMessage("keepOut", this, player.UserIDString));
                }
            }
        }
        void OnExitZone(string ZoneID, BasePlayer player) {
            if (Started) if (prisonIDs.Contains(ZoneID)) if (jailData.Prisoners.ContainsKey(player.userID)) {
                SendMsg(player, lang.GetMessage("keepIn", this, player.UserIDString));
            }
        }
#endregion
#region Permissions
        bool isAuth(BasePlayer player) {
            if (player.net.connection != null) if (player.net.connection.authLevel != 2) return false;
            return true;
        }
        bool hasPermission(BasePlayer player) {
            if (isAuth(player)) return true;
            else if (permission.UserHasPermission(player.userID.ToString(), "jail.admin")) return true;
            return false;
        }
#endregion
#region Chat/Console Commands
        [ChatCommand("jail")]
        private void cmdJail(BasePlayer player, string command, string[] args) {
            if (Started) if (jailData.Prisoners.ContainsKey(player.userID) && !hasPermission(player)) {
                double currentTime = GrabCurrentTime();
                double expTime = jailData.Prisoners[player.userID].expireTime;
                if (expTime == -99999) {
                    SendMsg(player, lang.GetMessage("noRelease", this, player.UserIDString));
                    return;
                }
                double timeLeft = expTime - currentTime;
                if (timeLeft > 0) {
                    string msg = lang.GetMessage("mins", this, player.UserIDString);
                    if (timeLeft <= 60) msg = lang.GetMessage("secs", this, player.UserIDString);
                    else timeLeft = timeLeft / 60;
                    SendMsg(player, string.Format(lang.GetMessage("remainJail", this, player.UserIDString), timeLeft, msg));
                    return;
                }
                FreeFromJail(player);
            }
            if (!hasPermission(player)) return;
            if (args == null || args.Length == 0) {
                SendMsg(player, lang.GetMessage("synSend1", this, player.UserIDString));
                SendMsg(player, lang.GetMessage("synFree", this, player.UserIDString));
                SendMsg(player, lang.GetMessage("synAdd", this, player.UserIDString));
                SendMsg(player, lang.GetMessage("synRem", this, player.UserIDString));
                SendMsg(player, lang.GetMessage("synList", this, player.UserIDString));
                SendMsg(player, lang.GetMessage("synPurge", this, player.UserIDString));
                SendMsg(player, lang.GetMessage("synZone", this, player.UserIDString));
                SendMsg(player, lang.GetMessage("synWipe", this, player.UserIDString));
                return;
            }
            if (!hasPermission(player)) return;
            switch (args[0].ToLower()) {
                case "send" : if (args.Length >= 2) {
                    object addPlayer = FindPlayer(args[1]);
                    if (addPlayer is string) {
                        SendMsg(player, (string)addPlayer);
                        return;
                    }
                    int time = -99999;
                    string prison = FindEmptyPrison();
                    if (args.Length >= 5) if (jailData.prisons.ContainsKey(args[4].ToLower())) prison = args[4].ToLower();
                    if (string.IsNullOrEmpty(prison)) {
                        SendMsg(player, lang.GetMessage("noPrisons", this, player.UserIDString));
                        return;
                    }
                    BasePlayer target = (BasePlayer)addPlayer;
                    if (jailData.Prisoners.ContainsKey(target.userID)) return;
                    if (args.Length >= 3) int.TryParse(args[2], out time);
                    object success = SendPlayerToJail(target, prison, time);
                    if (success is bool) {
                        if ((bool)success) {
                            SendMsg(player, string.Format(lang.GetMessage("sentTo", this, player.UserIDString), target.displayName, prison));
                            if (args.Length >= 4 && broadcastImprisonment) PrintToChat(string.Format(lang.GetMessage("sentToBroadcast", this, player.UserIDString), target.displayName, args[3]));
                        }
                    }
                    else if (success is string) {
                        if ((string)success == "noPos") SendMsg(player, string.Format(lang.GetMessage("noPos", this), prison));
                        else if ((string)success == "noCells") SendMsg(player, string.Format(lang.GetMessage("noCells", this), prison));
                        return;
                    }
                }
                else SendMsg(player, lang.GetMessage("synSend1", this, player.UserIDString));
                return;
                case "free" : if (args.Length == 2) {
                    object freePlayer = FindPlayer(args[1]);
                    if (freePlayer is string) {
                        SendMsg(player, (string)freePlayer);
                        return;
                    }
                    BasePlayer freetarget = (BasePlayer)freePlayer;
                    if (jailData.Prisoners.ContainsKey(freetarget.userID)) {
                        FreeFromJail(freetarget);
                        SendMsg(player, string.Format(lang.GetMessage("relFrom", this, player.UserIDString), freetarget.displayName));
                    }
                }
                else SendMsg(player, lang.GetMessage("synFree", this, player.UserIDString));
                return;
                case "add" : if (args.Length == 4) AddJail(player, args);
                else SendMsg(player, lang.GetMessage("synAdd", this, player.UserIDString));
                return;
                case "remove" : if (args.Length == 2) RemoveJail(player, args[1]);
                else SendMsg(player, lang.GetMessage("synRem", this, player.UserIDString));
                return;
                case "zone" : int radius = 30;
                if (args.Length >= 2) int.TryParse(args[1], out radius);
                string zoneID = "Jail" + (jailData.prisons.Count + 1);
                string[] zoneargs = new string[] {
                    "eject", "true", "radius", radius.ToString(), "sleepgod", "true", "undestr", "true", "nobuild", "true", "notp", "true", "nokits", "true", "nodeploy", "true", "nosuicide", "true"
                }
                ;
                ZoneManager?.Call("CreateOrUpdateZone", zoneID, zoneargs, player.transform.position);
                SendMsg(player, lang.GetMessage("createJail", this, player.UserIDString));
                SendMsg(player, string.Format(lang.GetMessage("jailID", this, player.UserIDString), zoneID));
                return;
                case "list" : foreach (var entry in jailData.prisons) SendReply(player, "Name: " + entry.Key + ", Location: " + entry.Value.location.ToString());
                return;
                case "purge" : List<ulong> RemoveList = new List<ulong>();
                List<BasePlayer> FreeList = new List<BasePlayer>();
                foreach(var entry in jailData.Prisoners) {
                    if (entry.Value.expireTime - GrabCurrentTime() < 0) {
                        BasePlayer target = FindPlayerByID(entry.Key);
                        if (target != null) FreeList.Add(target);
                        else RemoveList.Add(entry.Key);
                    }
                }
                foreach (var entry in RemoveList) jailData.Prisoners.Remove(entry);
                foreach (var entry in FreeList) FreeFromJail(entry);
                return;
                case "wipe" : foreach(var entry in jailData.prisons) EraseJailZone(entry.Key);
                foreach (var entry in jailData.Prisoners) {
                    BasePlayer inmate = FindPlayerByID(entry.Key);
                    if (inmate != null) FreeFromJail(inmate);
                }
                jailData.Prisoners.Clear();
                jailData.prisons.Clear();
                SaveData();
                return;
            }
        }
        [ConsoleCommand("jail.free")]
        private void ccmdJailFree(ConsoleSystem.Arg arg) {
            if (arg.connection != null) if (arg.connection.authLevel < 1) return;
            if (arg.Args.Length != 0) {
                object freePlayer = FindPlayer(arg.Args[0]);
                if (freePlayer is string) {
                    SendReply(arg, (string)freePlayer);
                    return;
                }
                BasePlayer freetarget = (BasePlayer)freePlayer;
                if (jailData.Prisoners.ContainsKey(freetarget.userID)) {
                    FreeFromJail(freetarget);
                    SendReply(arg, string.Format(lang.GetMessage("relFrom", this), freetarget.displayName));
                }
            }
            else SendReply(arg, lang.GetMessage("synFree", this));
        }
        [ConsoleCommand("jail.send")]
        private void ccmdjailSend(ConsoleSystem.Arg arg) {
            if (arg.connection != null) if (arg.connection.authLevel < 1) return;
            if (arg.Args.Length >= 1) {
                object addPlayer = FindPlayer(arg.Args[0]);
                if (addPlayer is string) {
                    SendReply(arg, (string)addPlayer);
                    return;
                }
                int time = -99999;
                string prison = FindEmptyPrison();
                if (arg.Args.Length >= 4) if (jailData.prisons.ContainsKey(arg.Args[3].ToLower())) prison = arg.Args[3].ToLower();
                if (string.IsNullOrEmpty(prison)) {
                    lang.GetMessage("noPrisons", this);
                    return;
                }
                BasePlayer target = (BasePlayer)addPlayer;
                if (jailData.Prisoners.ContainsKey(target.userID)) return;
                if (arg.Args.Length >= 2) int.TryParse(arg.Args[1], out time);
                object success = SendPlayerToJail(target, prison, time);
                if (success is bool) {
                    if ((bool)success) {
                        SendReply(arg, lang.GetMessage("sentTo", this), target.displayName, prison);
                        if (arg.Args.Length >= 3 && broadcastImprisonment) PrintToChat(string.Format(lang.GetMessage("sentToBroadcast", this), target.displayName, arg.Args[2]));
                    }
                }
                else if (success is string) {
                    if ((string)success == "noPos") SendReply(arg, string.Format(lang.GetMessage("noPos", this), prison));
                    else if ((string)success == "noCell") SendReply(arg, string.Format(lang.GetMessage("noCell", this), prison));
                    return;
                }
            }
            else SendReply(arg, lang.GetMessage("synSend1", this));
            return;
        }
#endregion
#region Config
        static bool useInitialSpawns = true;
        static bool disableDamage = false;
        static bool giveKit = true;
        static bool broadcastImprisonment = true;
        static string kitName = "default";
        static string msgColor = "<color=#d3d3d3>";
        private void LoadVariables() {
            LoadConfigVariables();
            SaveConfig();
        }
        private void LoadConfigVariables() {
            CheckCfg("Inmates - Release - Return to initial position when released", ref useInitialSpawns);
            CheckCfg("Inmates - Disable damage inside the Jail", ref disableDamage);
            CheckCfg("Inmates - Kits - Give kit to Inmates", ref giveKit);
            CheckCfg("Inmates - Kits - Kitname", ref kitName);
            CheckCfg("Messages - Message color", ref msgColor);
            CheckCfg("Messages - Broadcast imprisonment", ref broadcastImprisonment);
        }
        private void CheckCfg<T>(string Key, ref T var) {
            if (Config[Key] is T) var = (T)Config[Key];
            else Config[Key] = var;
        }
        private void CheckCfgFloat(string Key, ref float var) {
            if (Config[Key] != null) var = Convert.ToSingle(Config[Key]);
            else Config[Key] = var;
        }
        object GetConfig(string menu, string datavalue, object defaultValue) {
            var data = Config[menu] as Dictionary<string, object>;
            if (data == null) {
                data = new Dictionary<string, object>();
                Config[menu] = data;
                Changed = true;
            }
            object value;
            if (!data.TryGetValue(datavalue, out value)) {
                value = defaultValue;
                data[datavalue] = value;
                Changed = true;
            }
            return value;
        }
#endregion
#region Classes and Data
        class JailDataStorage {
            public Dictionary<ulong, Inmate> Prisoners = new Dictionary<ulong, Inmate>();
            public Dictionary<string, Prison> prisons = new Dictionary<string, Prison>();
        }
        void SaveData() {
            JailData.WriteObject(jailData);
        }
        void LoadData() {
            try {
                jailData = Interface.GetMod().DataFileSystem.ReadObject<JailDataStorage>("jail_data");
                foreach (var entry in jailData.prisons) prisonIDs.Add(entry.Value.zoneID);
            }
            catch {
                jailData = new JailDataStorage();
            }
        }
        class Inmate {
            public Vector3 initialPos;
            public string prisonName;
            public int cellNumber;
            public double expireTime;
            public List<InvItem> savedInventory = new List<InvItem>();
        }
        public class Prison {
            public string zoneID;
            public float zoneRadius;
            public string spawnFile;
            public Dictionary<int, bool> freeCells = new Dictionary<int, bool>();
            public Vector3 location;
        }
        class InvItem {
            public int itemid;
            public ulong skinid;
            public string container;
            public int amount;
            public bool weapon;
            public int ammo;
            public string ammotype;
            public List<int> mods;
            public float condition;
            public InvItem() {
            }
        }
        class JailTimer {
            public Timer time;
            public int timeLeft;
        }
        private class UnityVector3Converter : JsonConverter {
            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
                var vector = (Vector3)value;
                writer.WriteValue($"{vector.x} {vector.y} {vector.z}");
            }
            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
                if (reader.TokenType == JsonToken.String) {
                    var values = reader.Value.ToString().Trim().Split(' ');
                    return new Vector3(Convert.ToSingle(values[0]), Convert.ToSingle(values[1]), Convert.ToSingle(values[2]));
                }
                var o = JObject.Load(reader);
                return new Vector3(Convert.ToSingle(o["x"]), Convert.ToSingle(o["y"]), Convert.ToSingle(o["z"]));
            }
            public override bool CanConvert(Type objectType) {
                return objectType == typeof(Vector3);
            }
        }
        // borrowed from ZoneManager
#endregion
#region Inventory Saving and Restoration
        public void SaveInventory(BasePlayer player) {
            jailData.Prisoners[player.userID].savedInventory.Clear();
            List<InvItem> kititems = new List<InvItem>();
            foreach (Item item in player.inventory.containerWear.itemList) {
                if (item != null) {
                    var iteminfo = AddItemToSave(item, "wear");
                    kititems.Add(iteminfo);
                }
            }
            foreach (Item item in player.inventory.containerMain.itemList) {
                if (item != null) {
                    var iteminfo = AddItemToSave(item, "main");
                    kititems.Add(iteminfo);
                }
            }
            foreach (Item item in player.inventory.containerBelt.itemList) {
                if (item != null) {
                    var iteminfo = AddItemToSave(item, "belt");
                    kititems.Add(iteminfo);
                }
            }
            jailData.Prisoners[player.userID].savedInventory = kititems;
        }
        private InvItem AddItemToSave(Item item, string container) {
            InvItem iItem = new InvItem();
            iItem.ammo = 0;
            iItem.amount = item.amount;
            iItem.mods = new List<int>();
            iItem.skinid = item.skin;
            iItem.container = container;
            iItem.condition = item.condition;
            iItem.itemid = item.info.itemid;
            iItem.weapon = false;
            if (item.info.category.ToString() == "Weapon") {
                BaseProjectile weapon = item.GetHeldEntity() as BaseProjectile;
                if (weapon != null) {
                    if (weapon.primaryMagazine != null) {
                        iItem.weapon = true;
                        iItem.ammo = weapon.primaryMagazine.contents;
                        if (item.contents != null) foreach (var mod in item.contents.itemList) {
                            if (mod.info.itemid != 0) iItem.mods.Add(mod.info.itemid);
                        }
                    }
                }
            }
            return iItem;
        }
        public void RestoreInventory(BasePlayer player) {
            player.inventory.Strip();
            foreach (InvItem kitem in jailData.Prisoners[player.userID].savedInventory) {
                if (kitem.weapon) player.inventory.GiveItem(BuildWeapon(kitem.itemid, kitem.ammo, kitem.skinid, kitem.mods, kitem.condition), kitem.container == "belt" ? player.inventory.containerBelt : kitem.container == "wear" ? player.inventory.containerWear : player.inventory.containerMain);
                else player.inventory.GiveItem(BuildItem(kitem.itemid, kitem.amount, kitem.skinid, kitem.condition), kitem.container == "belt" ? player.inventory.containerBelt : kitem.container == "wear" ? player.inventory.containerWear : player.inventory.containerMain);
            }
        }
        private Item BuildItem(int itemid, int amount, ulong skin, float cond) {
            if (amount < 1) amount = 1;
            Item item = ItemManager.CreateByItemID(itemid, amount, skin);
            item.conditionNormalized = cond;
            return item;
        }
        private Item BuildWeapon(int id, int ammo, ulong skin, List<int> mods, float cond) {
            Item item = ItemManager.CreateByItemID(id, 1, skin);
            item.conditionNormalized = cond;
            var weapon = item.GetHeldEntity() as BaseProjectile;
            if (weapon != null) {
                (item.GetHeldEntity() as BaseProjectile).primaryMagazine.contents = ammo;
            }
            if (mods != null) foreach (var mod in mods) {
                item.contents.AddItem(BuildItem(mod, 1, 0, cond).info, 1);
            }
            return item;
        }
#endregion
#region Localization
        Dictionary<string, string> messages = new Dictionary<string, string>() {
            {
                "title", "<color=#afff00>Jail</color> : "
            }
            , {
                "noPlayers", "No players found."
            }
            , {
                "multiPlayers", "Multiple players found."
            }
            , {
                "invalidZID", "Invalid zone ID : "
            }
            , {
                "invalidZPos", "Unable to retrieve the zone location"
            }
            , {
                "invalidZRad", "Unable to retrieve the zone radius"
            }
            , {
                "newJailAdd", "New Jail added!"
            }
            , {
                "invalidSF", "Invalid spawnfile : "
            }
            , {
                "remJail", "Removed Jail : "
            }
            , {
                "noJail", "No prison found with that name"
            }
            , {
                "sentPrison", "You are being sent to prison!"
            }
            , {
                "checkTime", "Use /jail to check how much time you have left to serve"
            }
            , {
                "relPrison", "You are being released from prison!"
            }
            , {
                "welcomeJail", "Welcome to prison {0}"
            }
            , {
                "keepOut", "Keep Out! No visitors allowed in prison"
            }
            , {
                "keepIn", "You are not allowed to leave the prison"
            }
            , {
                "noRelease", "You are stuck in prison until a admin releases you"
            }
            , {
                "mins", "Minutes"
            }
            , {
                "secs", "Seconds"
            }
            , {
                "remainJail", "You have {0} {1} remaining of your prison sentence"
            }
            , {
                "synSend1", "/jail send <playername> <opt:time> <opt:reason> <opt:prisonname> - Send a player to Jail, time and prison name are optional"
            }
            , {
                "synFree", "/jail free <playername> - Free a player from Jail"
            }
            , {
                "synAdd", "/jail add <prisonname> <zoneID> <spawnfile> - Create a new prison"
            }
            , {
                "synRem", "/jail remove <prisonname> - Remove a prison"
            }
            , {
                "synZone", "/jail zone <radius> - Create a prison zone with required flags"
            }
            , {
                "synList", "/jail list - Lists all prison's"
            }
            , {
                "synWipe", "/jail wipe - Wipe's all prison data"
            }
            , {
                "synPurge", "/jail purge - Remove inactive players from prison"
            }
            , {
                "noPrisons", "The are no prisons available!"
            }
            , {
                "sentTo", "{0} has been sent to {1}"
            }
            , {
                "sentToBroadcast", "{0} has been sent to jail for: {1}"
            }
            , {
                "noCells", "The are no free cells available at {0}"
            }
            , {
                "noPos", "Unable to find a valid spawn point at {0}"
            }
            , {
                "relFrom", "{0} has been released from prison"
            }
            , {
                "ff", "You can not hurt other inmates"
            }
            , {
                "createJail", "You have successfully created a new prison zone, you can edit this zone with /zone_edit"
            }
            , {
                "jailID", "Zone ID: {0}"
            }
        }
        ;
#endregion
    }
}

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