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

FREE TpController : 1.1.21 1.1.21

Нет прав для скачивания
C#:
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Plugins;
using Rust;
using System;
using System.Collections.Generic;
using System.Collections;
using System.Globalization;
using System.Linq;
using UnityEngine;
using Oxide.Game.Rust.Cui;
using Facepunch.Extend;
using System.IO;
namespace Oxide.Plugins {
    [Info("TpController", "Lime", "1.1.21")]
    public class TpController : RustPlugin {
        [PluginReference("Friends")]
        Plugin Friends;
        [PluginReference("FriendSystem")]
        Plugin FriendSystem;
        [PluginReference("Clans")]
        Plugin Clans;
        [PluginReference("Economics")]
        Plugin Economics;
        [PluginReference("RustMap")]
        Plugin RustMap;
        static Plugin NoEscape => Interface.Oxide.GetLibrary<Oxide.Core.Libraries.Plugins>().Find("NoEscape");
        static class Debug {
            public static void Log(object message) {
                if (DEBUG) UnityEngine.Debug.Log(message);
            }
        }
        static bool DEBUG = false;
        static float GLOBAL_UI_SIZE => ConfigData.UI_GlobalSize.Value;
        //1.5f;
        static bool IsTPBlock(BasePlayer player, ref MessageInfo? message) {
            if (NoEscape?.CallHook("IsEscapeBlocked", player.UserIDString)?.ToString() == true.ToString()) return true;
            object obj = Interface.Call("CanTeleport", player);
            if (obj is string) {
                _plugin.Player.Message(player, obj.ToString());
                return true;
            }
            if (obj is bool) {
                if (!(bool)obj) return true;
            }
            if (obj != null) return true;
            if (player.HasParent()) {
                message = MessageInfo.Cant_InParent;
                return true;
            }
            return false;
        }
        static string _GUI_TP_Menu => $"{_plugin.Title}.{_plugin.Author}.{_plugin.Version}.TP.Menu";
        static string _GUI_TP_Button => $"{_plugin.Title}.{_plugin.Author}.{_plugin.Version}.TP.Button";
        static string _GUI_TP_Info => $"{_plugin.Title}.{_plugin.Author}.{_plugin.Version}.TP.Info";
        public static bool IsDebug = true;
        static TpController _plugin = null;
        static string Perm_TPAdmin = "tpcontroller.admin";
        void Loaded() {
            _plugin = this;
            LoadConfig();
            DATA.Load();
            permission.RegisterPermission(Perm_TPAdmin, this);
        }
        static void TryCatch(Action _try, Action _catch = null) => TryCatch(_try, (Exception e) => _catch?.Invoke());
        static void TryCatch<T>(Action _try, Action<T> _catch = null) where T : Exception {
            try {
                _try.Invoke();
            }
            catch (T e) {
                _catch?.Invoke(e);
            }
        }
        static void Foreach<T>(IEnumerable<T> _ienumerable, Action<T> _action) {
            foreach (T item in _ienumerable) _action.Invoke(item);
        }
        void OnServerInitialized() {
            List<string> _comps = new List<string>() {
                "TPR", "TPA", "TPATimer", "GUITP", "TPHome",
            }
            ;
            Foreach(BaseNetworkable.serverEntities, (ent) => TryCatch(() => (ent?.GetComponents<Component>() ?? new Component[0]).Where(comp => _comps.Contains(comp?.GetType()?.Name)).Select(comp => {
                UnityEngine.Object.Destroy(comp);
                return true;
            }
            )));
            Foreach(ConfigData.ToHome_Permissions.Value, (perm) => {
                if (perm.Key != "default" && !permission.PermissionExists(perm.Key)) permission.RegisterPermission(perm.Key, this);
            }
            );
            Foreach(ConfigData.ToHome_CountDay.Value, (perm) => {
                if (perm.Key != "default" && !permission.PermissionExists(perm.Key)) permission.RegisterPermission(perm.Key, this);
            }
            );
            Foreach(ConfigData.ToHome_CDTime.Value, (perm) => {
                if (perm.Key != "default" && !permission.PermissionExists(perm.Key)) permission.RegisterPermission(perm.Key, this);
            }
            );
            Foreach(ConfigData.ToHome_Time.Value, (perm) => {
                if (perm.Key != "default" && !permission.PermissionExists(perm.Key)) permission.RegisterPermission(perm.Key, this);
            }
            );
            Foreach(ConfigData.ToUser_Time.Value, (perm) => {
                if (perm.Key != "default" && !permission.PermissionExists(perm.Key)) permission.RegisterPermission(perm.Key, this);
            }
            );
            Foreach(ConfigData.ToUser_CDTime.Value, (perm) => {
                if (perm.Key != "default" && !permission.PermissionExists(perm.Key)) permission.RegisterPermission(perm.Key, this);
            }
            );
            Foreach(ConfigData.ToUser_CountDay.Value, (perm) => {
                if (perm.Key != "default" && !permission.PermissionExists(perm.Key)) permission.RegisterPermission(perm.Key, this);
            }
            );
            if (((Friends ?? FriendSystem) == null && Clans == null) && (ConfigData.FriendsKey.Value == 0 || ConfigData.FriendsKey.Value == 1)) PrintError("Plugin 'Friends/FriendSystem' or 'Clans' not loaded but in config setted!");
            if (Economics == null && (ConfigData.ToUser_Economics.Value || ConfigData.ToHome_Economics.Value)) PrintError("Plugin 'Economics' not loaded but in config setted!");
            if (!ConfigData.ToHome_DrawInMap.Value) return;
            if (RustMap == null) PrintError("Plugin 'RustMap' not loaded but in config setted!");
        }
        Dictionary<string, Vector3> GetPlayerHomes(string player) => ConfigData.ToHome_DrawInMap.Value ? DATA.GetHomes(player).ToDictionary(kv => kv.Key.ToString(), kv => kv.Value) : null;
        public class ConfigData {
            //Общие настройки
            public static ConfigItem<int> FriendsKey = new ConfigItem<int>(() => GetConfig("Настройки", "Друзья из (-2: OFF, -1: Team, 0: Team + Плагин Friends/FriendSystem/Clan, 1: Плагин Friends/FriendSystem/Clan)", 0), (value) => SetConfig(true, "Настройки", "Друзья из (-2: OFF, -1: Team, 0: Team + Плагин Friends/FriendSystem/Clan, 1: Плагин Friends/FriendSystem/Clan)", value));
            public static ConfigItem<bool> LogAdminTP = new ConfigItem<bool>(() => GetConfig("Логирование", "Команды администраторов", false), (value) => SetConfig(true, "Логирование", "Команды администраторов", value));
            public static ConfigItem<bool> LogPlayerTP = new ConfigItem<bool>(() => GetConfig("Логирование", "Тп к игроку", false), (value) => SetConfig(true, "Логирование", "Тп к игроку", value));
            public static ConfigItem<bool> LogPlayerHome = new ConfigItem<bool>(() => GetConfig("Логирование", "Тп на дом", false), (value) => SetConfig(true, "Логирование", "Тп на дом", value));
            //Игрок
            public static ConfigItem<bool> ToUser_CanTP = new ConfigItem<bool>(() => GetConfig("Игрок", "Разрешить телепортацию", true), (value) => SetConfig(true, "Игрок", "Разрешить телепортацию", value));
            public static ConfigItem<float> ToUser_CanYesTime = new ConfigItem<float>(() => GetConfig("Игрок", "Время ответа на запрос телепортации (в секундах)", 15), (value) => SetConfig(true, "Игрок", "Время ответа на запрос телепортации (в секундах)", value));
            public static ConfigItem<Dictionary<string, float>> ToUser_Time = new ConfigItem<Dictionary<string, float>>("Игрок", "Вермя на телепортацию ('Пермишен': Секунд)", new Dictionary<string, float>() {
                ["default"]
                = 15
            }
            );
            public static ConfigItem<Dictionary<string, float>> ToUser_CDTime = new ConfigItem<Dictionary<string, float>>(() => GetConfig("Игрок", "КД на телепортацию ('Пермишен': Минут)", new Dictionary<string, float>() {
                ["default"]
                = 15
            }
            ), (value) => SetConfig(true, "Игрок", "КД на телепортацию ('Пермишен': Минут)", value));
            public static ConfigItem<Dictionary<string, int>> ToUser_CountDay = new ConfigItem<Dictionary<string, int>>(() => GetConfig("Игрок", "Количество ТП в день(-1 - Бесконечно) ('Пермишен': Количество ТП)", new Dictionary<string, int>() {
                ["default"]
                = -1
            }
            ), (value) => SetConfig(true, "Игрок", "Количество ТП в день(-1 - Бесконечно) ('Пермишен': Количество ТП)", value));
            public static ConfigItem<bool> ToUser_CanTPDamage = new ConfigItem<bool>(() => !GetConfig("Игрок", "Отменять телепортацию при получении урона?", true), (value) => SetConfig(true, "Игрок", "Отменять телепортацию при получении урона?", !value));
            public static ConfigItem<bool> ToUser_CanTPInWater = new ConfigItem<bool>(() => !GetConfig("Игрок", "Отменять телепортацию при нахождении в воде?", true), (value) => SetConfig(true, "Игрок", "Отменять телепортацию при нахождении в воде?", !value));
            public static ConfigItem<bool> ToUser_CanTPOverWater = new ConfigItem<bool>(() => !GetConfig("Игрок", "Отменять телепортацию при нахождении над водой?", true), (value) => SetConfig(true, "Игрок", "Отменять телепортацию при нахождении над водой?", !value));
            public static ConfigItem<bool> ToUser_Economics = new ConfigItem<bool>(() => GetConfig("Игрок", "Использовать Economics", false), (value) => SetConfig(true, "Игрок", "Использовать Economics", value));
            public static ConfigItem<float> ToUser_EconomicsCash = new ConfigItem<float>(() => GetConfig("Игрок", "Economics цена за использование", 10f), (value) => SetConfig(true, "Игрок", "Economics цена за использование", value));
            public static ConfigItem<bool> ToUser_BuildingBlock = new ConfigItem<bool>("Игрок", "Разрешить телепортацию в BuildingBlock?", true);
            //Дом
            public static ConfigItem<bool> ToHome_CanTP = new ConfigItem<bool>(() => GetConfig("Дом", "Разрешить телепортацию", true), (value) => SetConfig(true, "Дом", "Разрешить телепортацию", value));
            public static ConfigItem<Dictionary<string, float>> ToHome_Time = new ConfigItem<Dictionary<string, float>>("Дом", "Вермя на телепортацию ('Пермишен': Секунд)", new Dictionary<string, float>() {
                ["default"]
                = 15
            }
            );
            public static ConfigItem<Dictionary<string, float>> ToHome_CDTime = new ConfigItem<Dictionary<string, float>>(() => GetConfig("Дом", "КД на телепортацию ('Пермишен': Минут)", new Dictionary<string, float>() {
                ["default"]
                = 15
            }
            ), (value) => SetConfig(true, "Дом", "КД на телепортацию ('Пермишен': Минут)", value));
            public static ConfigItem<Dictionary<string, int>> ToHome_Permissions = new ConfigItem<Dictionary<string, int>>(() => GetConfig("Дом", "Количество домов ('Пермишен': Количество)", new Dictionary<string, int>() {
                ["default"]
                = 5
            }
            ), (value) => SetConfig(true, "Дом", "Количество домов ('Пермишен': Количество)", value));
            public static ConfigItem<Dictionary<string, int>> ToHome_CountDay = new ConfigItem<Dictionary<string, int>>(() => GetConfig("Дом", "Количество ТП в день(-1 - Бесконечно) ('Пермишен': Количество ТП)", new Dictionary<string, int>() {
                ["default"]
                = -1
            }
            ), (value) => SetConfig(true, "Дом", "Количество ТП в день(-1 - Бесконечно) ('Пермишен': Количество ТП)", value));
            public static ConfigItem<bool> ToHome_CanTPDamage = new ConfigItem<bool>(() => !GetConfig("Дом", "Отменять телепортацию при получении урона?", true), (value) => SetConfig(true, "Дом", "Отменять телепортацию при получении урона?", !value));
            public static ConfigItem<bool> ToHome_CanTPInWater = new ConfigItem<bool>(() => !GetConfig("Дом", "Отменять телепортацию при нахождении в воде?", true), (value) => SetConfig(true, "Дом", "Отменять телепортацию при нахождении в воде?", !value));
            public static ConfigItem<bool> ToHome_CanTPOverWater = new ConfigItem<bool>(() => !GetConfig("Дом", "Отменять телепортацию при нахождении над водой?", true), (value) => SetConfig(true, "Дом", "Отменять телепортацию при нахождении над водой?", !value));
            public static ConfigItem<bool> ToHome_CanTPNotFoundation = new ConfigItem<bool>(() => !GetConfig("Дом", "Запретить ставить дом на земле?", true), (value) => SetConfig(true, "Дом", "Запретить ставить дом на земле?", !value));
            public static ConfigItem<bool> ToHome_CanTPNotFoundation_Your = new ConfigItem<bool>(() => !GetConfig("Дом", "Запретить ставить дом на чужом фундаменте?", true), (value) => SetConfig(true, "Дом", "Запретить ставить дом на чужом фундаменте?", !value));
            public static ConfigItem<bool> ToHome_Economics = new ConfigItem<bool>(() => GetConfig("Дом", "Использовать Economics", false), (value) => SetConfig(true, "Дом", "Использовать Economics", value));
            public static ConfigItem<float> ToHome_EconomicsCash = new ConfigItem<float>(() => GetConfig("Дом", "Economics цена за использование", 10f), (value) => SetConfig(true, "Дом", "Economics цена за использование", value));
            public static ConfigItem<bool> ToHome_DrawInMap = new ConfigItem<bool>("Дом", "Отображать дома на карте RustMap?", false);
            public static ConfigItem<bool> ToHome_BuildingBlock = new ConfigItem<bool>("Дом", "Разрешить телепортацию в BuildingBlock?", true);
            //UI
            public static ConfigItem<float> UI_GlobalSize = new ConfigItem<float>(() => GetConfig("UI", "Размер интерфейса(def 1)", 1.0f), (value) => SetConfig(true, "UI", "Размер интерфейса(def 1)", value));
            public static ConfigItem<int> UI_Radius = new ConfigItem<int>(() => GetConfig("UI", "Радиус круга из иконок", 100), (value) => SetConfig(true, "UI", "Радиус круга из иконок", value));
            public static ConfigItem<string> UI_Friend_Color = new ConfigItem<string>(() => GetConfig("UI", "Цвет UI круга друга rgba(от 0 до 1)", "0 0 0 1"), (value) => SetConfig(true, "UI", "Цвет UI круга друга rgba(от 0 до 1)", value));
            public static ConfigItem<string> UI_TPR_Color = new ConfigItem<string>(() => GetConfig("UI", "Цвет UI круга при отправке телепортации rgba(от 0 до 1)", "0 0 0 1"), (value) => SetConfig(true, "UI", "Цвет UI круга при отправке телепортации rgba(от 0 до 1)", value));
            public static ConfigItem<string> UI_TPA_Color = new ConfigItem<string>(() => GetConfig("UI", "Цвет UI круга при приеме телепортации rgba(от 0 до 1)", "0 0 0 1"), (value) => SetConfig(true, "UI", "Цвет UI круга при приеме телепортации rgba(от 0 до 1)", value));
            public static ConfigItem<string> UI_Home_TP_Color = new ConfigItem<string>(() => GetConfig("UI", "Цвет UI круга при телепортации домой rgba(от 0 до 1)", "0 0 0 1"), (value) => SetConfig(true, "UI", "Цвет UI круга при телепортации домой rgba(от 0 до 1)", value));
            public static ConfigItem<string> UI_Home_Get_Color = new ConfigItem<string>(() => GetConfig("UI", "Цвет UI круга дома rgba(от 0 до 1)", "0 0 0 1"), (value) => SetConfig(true, "UI", "Цвет UI круга дома rgba(от 0 до 1)", value));
            public static ConfigItem<string> UI_Home_Set_Color = new ConfigItem<string>(() => GetConfig("UI", "Цвет UI круга пустого дома rgba(от 0 до 1)", "0 0 0 1"), (value) => SetConfig(true, "UI", "Цвет UI круга пустого дома rgba(от 0 до 1)", value));
            public static ConfigItem<string> UI_Page_Color = new ConfigItem<string>(() => GetConfig("UI", "Цвет UI круга перехода на другую страницу rgba(от 0 до 1)", "0 0 0 1"), (value) => SetConfig(true, "UI", "Цвет UI круга перехода на другую страницу rgba(от 0 до 1)", value));
            public static ConfigItem<string> UI_Settings_Color = new ConfigItem<string>(() => GetConfig("UI", "Цвет UI круга настроек rgba(от 0 до 1)", "0 0 0 1"), (value) => SetConfig(true, "UI", "Цвет UI круга настроек rgba(от 0 до 1)", value));
            public static ConfigItem<string> UI_Home_TP_On_Image_Color = new ConfigItem<string>("UI", "Цвет UI картинки телепортации домой rgba(от 0 до 1)", "0 1 0 1");
            public static ConfigItem<string> UI_Home_TP_Off_Image_Color = new ConfigItem<string>("UI", "Цвет UI картинки отмены телепортации домой rgba(от 0 до 1)", "0.3921569 0.7254902 0.7254902 1");
            public static ConfigItem<string> UI_Home_Set_Image_Color = new ConfigItem<string>("UI", "Цвет UI картинки пустого дома rgba(от 0 до 1)", "0.3921569 0.7254902 0.7254902 1");
            public static ConfigItem<string> UI_Page_Image_Color = new ConfigItem<string>("UI", "Цвет UI картинки перехода на другую страницу rgba(от 0 до 1)", "0.3921569 0.7254902 0.7254902 1");
            public static ConfigItem<string> UI_Settings_On_Image_Color = new ConfigItem<string>("UI", "Цвет UI картинки настроек (галочка) rgba(от 0 до 1)", "0 1 0 1");
            public static ConfigItem<string> UI_Settings_Off_Image_Color = new ConfigItem<string>("UI", "Цвет UI картинки настроек (крестик) rgba(от 0 до 1)", "1 0 0 1");
            public static ConfigItem<string> UI_Yes_Image_Color = new ConfigItem<string>("UI", "Цвет UI картинки кнопки подтвердить rgba(от 0 до 1)", "0 1 0 1");
            public static ConfigItem<string> UI_No_Image_Color = new ConfigItem<string>("UI", "Цвет UI картинки кнопки отклонить rgba(от 0 до 1)", "1 0 0 1");
            //ConfigData.UI_Settings_On_Image_Color.Value
            //UI_Settings_Color
            public static void LoadAndSaveAll() {
                foreach (var Field in typeof(ConfigData).GetFields(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)) {
                    ConfigItem cObj = (ConfigItem)Field.GetValue(null);
                    Debug.Log($"{Field.FieldType.Name} {Field.Name} = {cObj.get.Invoke()}");
                    cObj.set.Invoke(cObj.get.Invoke());
                }
            }
            public static void SetConfig(bool replace, string group, string key, object value) {
                if (replace || _plugin.Config.Get(group, key) == null) _plugin.Config.Set(group, key, value);
                _plugin.Config.Save();
            }
            public static T GetConfig<T>(string group, string key, T defaultVal) {
                if (_plugin.Config.Get(group, key) == null) {
                    SetConfig(false, group, key, defaultVal);
                    return defaultVal;
                }
                return (T)Convert.ChangeType(_plugin.Config.Get<T>(group, key), typeof(T));
            }
            public class ConfigItem<T> : ConfigItem {
                public ConfigItem(string group, string key, T defaultValue) : this(() => GetConfig(group, key, defaultValue), (value) => SetConfig(true, group, key, value)) {
                }
                public ConfigItem(Func<T> get, Action<T> set) {
                    this.get = () => get.Invoke();
                    this.set = (value) => set.Invoke((T)value);
                }
                public T Value {
                    get {
                        return (T)get.Invoke();
                    }
                    set {
                        set.Invoke(value);
                    }
                }
                public static explicit operator T(ConfigItem<T> obj) => obj.Value;
            }
            public abstract class ConfigItem {
                public Func<object> get;
                public Action<object> set;
            }
        }
        static float GetUserTime(BasePlayer player) => GetUserTime(player.UserIDString);
        static float GetUserTime(ulong player) => GetUserTime(player.ToString());
        static float GetUserTime(string player) => Mathf.Min(ConfigData.ToUser_Time.Value.Where(kv => _plugin.permission.UserHasPermission(player, kv.Key) || kv.Key == "default").Select(kv => kv.Value).ToArray());
        static float GetHomeTime(BasePlayer player) => GetHomeTime(player.UserIDString);
        static float GetHomeTime(ulong player) => GetHomeTime(player.ToString());
        static float GetHomeTime(string player) => Mathf.Min(ConfigData.ToHome_Time.Value.Where(kv => _plugin.permission.UserHasPermission(player, kv.Key) || kv.Key == "default").Select(kv => kv.Value).ToArray());
        static DecayEntity GetFoundation(Vector3 pos) {
            RaycastHit hit;
            if (Physics.Raycast(pos, Vector3.down, out hit, 1f)) {
                var entity = hit.GetEntity();
                Debug.Log(entity?.ShortPrefabName ?? "NULL");
                switch (entity?.ShortPrefabName) {
                    case "foundation.triangle" : return entity as BuildingBlock;
                    case "foundation" : return entity as BuildingBlock;
                    case "floor" : return entity as BuildingBlock;
                    case "floor.triangle" : return entity as BuildingBlock;
                    case "rug.deployed" : return entity as DecayEntity;
                    case "rug.bear.deployed" : return entity as DecayEntity;
                }
            }
            return null;
        }
        static DecayEntity GetFoundationUp(Vector3 pos) {
            RaycastHit hit;
            if (Physics.Raycast(pos, Vector3.up, out hit, 3f)) {
                var entity = hit.GetEntity();
                Debug.Log(entity?.ShortPrefabName ?? "NULL");
                switch (entity?.ShortPrefabName) {
                    case "foundation.triangle" : return entity as BuildingBlock;
                    case "foundation" : return entity as BuildingBlock;
                }
            }
            return null;
        }
        static bool CanTeleportFoundation(BasePlayer player, Vector3 position) {
            Debug.Log("1");
            if (ConfigData.ToHome_CanTPNotFoundation.Value && ConfigData.ToHome_CanTPNotFoundation_Your.Value) return true;
            Debug.Log("2");
            DecayEntity foundation = GetFoundation(position);
            Debug.Log("3");
            if (foundation == null) return ConfigData.ToHome_CanTPNotFoundation.Value;
            Debug.Log("4");
            if (((BuildingBlock)foundation)?.grade == BuildingGrade.Enum.Twigs) return false;
            if (GetFoundationUp(position)) return false;
            if (foundation?.GetBuildingPrivilege() == null) return true;
            Debug.Log("5");
            List<string> regClan = GetNotExcept(ClanOrFriends.GetClanMembers(player) ?? new List<string>(), foundation.GetBuildingPrivilege().authorizedPlayers.Select(kv => kv.userid.ToString())).ToList();
            List<string> regFriends = GetNotExcept(ClanOrFriends.GetClanMembers(player) ?? new List<string>(), foundation.GetBuildingPrivilege().authorizedPlayers.Select(kv => kv.userid.ToString())).ToList();
            return foundation.GetBuildingPrivilege().IsAuthed(player) ? true : regClan.Count() > 0 ? true : regFriends.Count() > 0;
        }
        static IEnumerable<TValue> GetNotExcept<TValue>(IEnumerable<TValue> first, IEnumerable<TValue> second) => first.Distinct().Where(item => second.Contains(item));
        public enum MessageInfo {
            None, Cant_InParent, CoolDown_Use, TPR_TP_Yes, TPR_TP_No, TPR_TP, TPR_Send_TP, TPR_Command_Info, TPR_Cant_Count_0, TPR_Cant_Count_More, TPR_Cant_ActiveTP, TPR_Cant_MaxCountDay, TPR_Cant_RaidBlock, TPR_Cant_Economics, TPA_TP_Yes, TPA_TP_No, TPA_TP, TPA_Send_TP, TPA_Cant_Count_More, TPA_Cant_Count_0, TPA_Cant_Count_1, TPA_Cant_ActiveCount_More, TPA_Cant_RaidBlock, TPC_Cant_Count_More, TPC_Cant_Count_0, TPC_Cant_Count_1, TPC_Cant_ActiveCount_More, SetHome_Command_Info, SetHome_Set, SetHome_CantSet_Found, SetHome_CantSet_MaxCount, SetHome_CantSet_IsntNum, SetHome_CantSet_CantBuild, SetHome_CantSet_Foundation, DelHome_Command_Info, DelHome_Del, DelHome_CantDel_NotFound, DelHome_CantDel_IsntNum, TPHome_CantTP_NotFound, TPHome_CantTP_ActiveTP, TPHome_CantTP_IsntNum, TPHome_CantTP_Reason, TPHome_CantTP_RaidBlock, TPHome_CantTP_Foundation_NotSet, TPHome_CantTP_MaxCountDay, TPHome_CantTP_Economics, TPHome_Time, TPHome_Time_Now, HomeC_NotFound, HomeC_C, TPAdmin_TP, TPAdmin_TP_Player, TPAdmin_NotFound, TPAdmin_FoundMore, Reason_Cancel, Reason_Damage, Reason_InWater, Reason_OverWater, Reason_InAir, Reason_NoFriend, Reason_BuildingBlock
        }
        protected override void LoadDefaultMessages() {
            Dictionary<string, string> ru = new Dictionary<string, string>();
            foreach (var kv in new Dictionary<MessageInfo, string>() {
                [MessageInfo.CoolDown_Use]
                = "Вы не можете сделать это! Осталось {sec}сек.", [MessageInfo.TPR_TP] = "Вы были телепортированы к <color=#ffa500>{name}</color>.Осталось телепортаций {count}", [MessageInfo.TPR_TP_Yes] = "Ваш запрос на телопортацию подтвержден игроком <color=#ffa500>{name}</color>.Вы будете телепортированы через <color=#ffa500>{sec}</color> секунд.", [MessageInfo.TPR_TP_No] = "Запрос на телопортацию <color=#ffa500>отклонен</color> по причине <color=#ffa500>{reason}</color>", [MessageInfo.TPR_Send_TP] = "Вы отправили запрос на телепортацию игроку <color=#ffa500>{name}</color>", [MessageInfo.TPR_Cant_Count_0] = "Игрок <color=#ffa500>не найден!</color>", [MessageInfo.TPR_Cant_Count_More] = "Найдено <color=#ffa500>несколько игроков</color>", [MessageInfo.TPR_Cant_ActiveTP] = "У вас уже есть активная телепортация! Отменить текущую: </color=#ffa500>/tpc</color>", [MessageInfo.TPR_Cant_MaxCountDay] = "Использовано <color=#ffa500>максимально количество</color> телепортаций в день!", [MessageInfo.TPR_Cant_RaidBlock] = "У вас <color=#ffa500>блок</color> на телепортацию!", [MessageInfo.TPR_Command_Info] = "Для телепортации используйте: <color=#ffa500>/tpr Ник/SteamID</color>", [MessageInfo.TPR_Cant_Economics] = "У вас недастаточно баланса на счету", [MessageInfo.TPA_TP] = "<color=#ffa500>{name}</color> был телепортирован к вам", [MessageInfo.TPA_TP_Yes] = "Вы приняли запрос игрока <color=#ffa500>{name}</color>", [MessageInfo.TPA_TP_No] = "Запрос на телопортацию к вам <color=#ffa500>отклонен</color> по причине <color=#ffa500>{reason}</color>", [MessageInfo.TPA_Send_TP] = "Игрок <color=#ffa500>{name}</color> отправил запрос на телепортацию к вам\nПропишите <color=#ffa500>/tpa</color>, чтобы принять запрос", [MessageInfo.TPA_Cant_Count_More] = "Найдено <color=#ffa500>несколько игроков!</color>", [MessageInfo.TPA_Cant_Count_0] = "Не найдено активных запросов!", [MessageInfo.TPA_Cant_Count_1] = "Не найдено активных запросов от игрока <color=#ffa500>{name}</color>", [MessageInfo.TPA_Cant_ActiveCount_More] = "Найдено несколько активных запросов! <color=#ffa500>Укажите Ник или SteamID отправителя!</color>", [MessageInfo.TPA_Cant_RaidBlock] = "У вас <color=#ffa500>блок</color> на телепортацию!", [MessageInfo.TPC_Cant_Count_More] = "Найдено <color=#ffa500>несколько</color> игроков!", [MessageInfo.TPC_Cant_Count_0] = "Не найдено активных запросов!", [MessageInfo.TPC_Cant_Count_1] = "Не найдено активных запросов от игрока {name}!", [MessageInfo.TPC_Cant_ActiveCount_More] = "Найдено несколько активных запросов! Укажите имя или SteamID отправителя!", [MessageInfo.SetHome_Command_Info] = "Используйте: <color=#ffa500>/sethome Название</color>", [MessageInfo.SetHome_Set] = "Вы создали дом под названием <color=#ffa500>{home}</color>", [MessageInfo.SetHome_CantSet_Found] = "Дом с таким названием уже существует!", [MessageInfo.SetHome_CantSet_MaxCount] = "Достигнуто <color=#ffa500>максимальное</color> количество точек дома", [MessageInfo.SetHome_CantSet_CantBuild] = "Вы <color=#ffa500>не можете</color> поставить свой дом тут!", [MessageInfo.SetHome_CantSet_IsntNum] = "Название дома может состоять <color=#ffa500>только из цифр</color>", [MessageInfo.SetHome_CantSet_Foundation] = "Под вами не ваш(друга) или нету <color=#ffa500>фундамента</color>", [MessageInfo.DelHome_Command_Info] = "Используйте: <color=#ffa500>/removehome Название дома</color>", [MessageInfo.DelHome_Del] = "Вы успешно удалили дом <color=#ffa500>{home}</color>", [MessageInfo.DelHome_CantDel_NotFound] = "Дом с таким названием <color=#ffa500>не найден!</color>", [MessageInfo.DelHome_CantDel_IsntNum] = "Название дома может состоять <color=#ffa500>только из цифр</color>", [MessageInfo.TPHome_CantTP_NotFound] = "Дом с таким названием <color=#ffa500>не найден!</color>", [MessageInfo.TPHome_CantTP_ActiveTP] = "У вас уже есть активная телепортация домой! Отменить текущую: <color=#ffa500>/homec</color>", [MessageInfo.TPHome_Time] = "Вы успешно начали телепорт домой! Вы будете телепортированы через <color=#ffa500>{sec}</color> секунд.", [MessageInfo.TPHome_Time_Now] = "Вы были телепортированы домой! Осталось телепортаций {count}", [MessageInfo.TPHome_CantTP_IsntNum] = "Название дома может состоять <color=#ffa500>только из цифр</color>", [MessageInfo.TPHome_CantTP_Reason] = "Активные телепортации домой <color=#ffa500>отклонены!</color> по причине <color=#ffa500>{reason}</color>", [MessageInfo.TPHome_CantTP_RaidBlock] = "У вас <color=#ffa500>блок</color> на телепортацию!", [MessageInfo.TPHome_CantTP_Foundation_NotSet] = "Под вашим домом не ваш(друга) или нету <color=#ffa500>фундамента</color>", [MessageInfo.TPHome_CantTP_MaxCountDay] = "Использовано <color=#ffa500>максимально количество</color> телепортаций домой в день!", [MessageInfo.TPHome_CantTP_Economics] = "У вас недастаточно баланса на счету", [MessageInfo.HomeC_NotFound] = "Активных телепортаций домой <color=#ffa500>не найдено!</color>", [MessageInfo.HomeC_C] = "Активные телепортации домой <color=#ffa500>отклонены!</color>", [MessageInfo.TPAdmin_TP] = "Вы были телепортированы к <color=#ffa500>{val}</color>", [MessageInfo.TPAdmin_TP_Player] = "Игрок <color=#ffa500>{player}</color> телепортирован к <color=#ffa500>{val}</color>", [MessageInfo.TPAdmin_NotFound] = "Игрок не найден!", [MessageInfo.TPAdmin_FoundMore] = "Найдено <color=#ffa500>несколько</color> игроков!", [MessageInfo.Reason_Cancel] = "Отмена", [MessageInfo.Reason_Damage] = "Получение урона", [MessageInfo.Reason_InWater] = "В воде", [MessageInfo.Reason_OverWater] = "Над водой", [MessageInfo.Reason_NoFriend] = "Не друг", [MessageInfo.Cant_InParent] = "В транспорте", [MessageInfo.Reason_BuildingBlock] = "BuildingBlock",
            }
            ) ru.Add(kv.Key.ToString(), kv.Value);
            foreach (var kv in new Dictionary<KeyValuePair<TpSettings, bool>, string>() {
                [new KeyValuePair<TpSettings, bool>(TpSettings.Close_TP, false)]
                = "Закрыть при ТП", [new KeyValuePair<TpSettings, bool>(TpSettings.Close_Use, false)] = "Закрыть при USE", [new KeyValuePair<TpSettings, bool>(TpSettings.Whitelist_Fr, false)] = "TPC не друзей", [new KeyValuePair<TpSettings, bool>(TpSettings.AutoTPA_Fr, false)] = "Авто TPA друзей", [new KeyValuePair<TpSettings, bool>(TpSettings.Close_TP, true)] = "Закрыть меню после принятия/отклонения/отправки запроса", [new KeyValuePair<TpSettings, bool>(TpSettings.Close_Use, true)] = "Закрыть меню после каждого действия", [new KeyValuePair<TpSettings, bool>(TpSettings.Whitelist_Fr, true)] = "Принимать запросы только от друзей", [new KeyValuePair<TpSettings, bool>(TpSettings.AutoTPA_Fr, true)] = "Автоматически принимать запросы от друзей",
            }
            ) ru.Add("TpSettings_" + (!kv.Key.Value ? "Title" : "Message") + "_" + kv.Key.Key.ToString().ToLower(), kv.Value);
            lang.RegisterMessages(ru, this, "ru");
            Dictionary<string, string> en = new Dictionary<string, string>();
            foreach (var kv in new Dictionary<MessageInfo, string>() {
                [MessageInfo.CoolDown_Use]
                = "You can't do this! Wait {sec}sec.", [MessageInfo.TPR_TP] = "You has been teleported to <color=#ffa500>{name}</color>.Teleport count {count}", [MessageInfo.TPR_TP_Yes] = "Your request for teleportation is confirmed by the player <color=#ffa500>{name}</color>.You will be teleported from <color=#ffa500>{sec}</color> sec.", [MessageInfo.TPR_TP_No] = "Request for teleporting <color=#ffa500> rejected </color> due to <color=#ffa500>{reason}</color>", [MessageInfo.TPR_Send_TP] = "You have sent a request for teleportation to the player <color=#ffa500>{name}</color>", [MessageInfo.TPR_Cant_Count_0] = "Player <color=#ffa500>not found!</color>", [MessageInfo.TPR_Cant_Count_More] = "Found <color=#ffa500>more than one player</color>", [MessageInfo.TPR_Cant_ActiveTP] = "You already have an active teleportation! Cancel: </color=#ffa500>/tpc</color>", [MessageInfo.TPR_Cant_MaxCountDay] = "Used <color=#ffa500>maximum number</color> of teleports per day!", [MessageInfo.TPR_Cant_RaidBlock] = "You have a <color=#ffa500>block</color> to teleport!", [MessageInfo.TPR_Command_Info] = "For teleportation use: <color=#ffa500>/tpr Nickname/SteamID</color>", [MessageInfo.TPR_Cant_Economics] = "Not have money!", [MessageInfo.TPA_TP] = "<color=#ffa500>{name}</color> was teleported to you", [MessageInfo.TPA_TP_Yes] = "You have accepted a player request <color=#ffa500>{name}</color>", [MessageInfo.TPA_TP_No] = "The request to teleport you <color=#ffa500>was rejected</color> due to <color=#ffa500>{reason}</color>", [MessageInfo.TPA_Send_TP] = "Player <color=#ffa500>{name}</color> sent a request for teleportation to you\nPlease write <color=#ffa500>/tpa</color> to accept the request", [MessageInfo.TPA_Cant_Count_More] = "Found <color=#ffa500>more than one player</color>", [MessageInfo.TPA_Cant_Count_0] = "No active queries found!", [MessageInfo.TPA_Cant_Count_1] = "No active requests found from player <color=#ffa500>{name}</color>", [MessageInfo.TPA_Cant_ActiveCount_More] = "Found more than one active query! <color=#ffa500>Enter the nickname or SteamID!</color>", [MessageInfo.TPA_Cant_RaidBlock] = "You have a <color=#ffa500>block</color> to teleport!", [MessageInfo.TPC_Cant_Count_More] = "Found <color=#ffa500>more than one player</color>", [MessageInfo.TPC_Cant_Count_0] = "No active queries found!", [MessageInfo.TPC_Cant_Count_1] = "No active requests found from player <color=#ffa500>{name}</color>", [MessageInfo.TPC_Cant_ActiveCount_More] = "Found more than one active query! <color=#ffa500>Enter the nickname or SteamID!</color>", [MessageInfo.SetHome_Command_Info] = "Use: <color=#ffa500>/sethome name</color>", [MessageInfo.SetHome_Set] = "You created a home with name <color=#ffa500>{home}</color>", [MessageInfo.SetHome_CantSet_Found] = "A home with this name already exists!", [MessageInfo.SetHome_CantSet_MaxCount] = "Reached <color=#ffa500>maximum</color> number of points at home", [MessageInfo.SetHome_CantSet_CantBuild] = "You <color=#ffa500>can't</color> set your home here!", [MessageInfo.SetHome_CantSet_IsntNum] = "Home name can only consist of <color=#ffa500>numbers</color>", [MessageInfo.SetHome_CantSet_Foundation] = "Under you is not your (friend's) or not <color=#ffa500>foundation</color>", [MessageInfo.DelHome_Command_Info] = "Use: <color=#ffa500>/removehome name</color>", [MessageInfo.DelHome_Del] = "You have successfully removed the home with name <color=#ffa500>{home}</color>", [MessageInfo.DelHome_CantDel_NotFound] = "A home with this name <color=#ffa500>not found!</color>", [MessageInfo.DelHome_CantDel_IsntNum] = "Home name can only consist of <color=#ffa500>numbers</color>", [MessageInfo.TPHome_CantTP_NotFound] = "A home with this name <color=#ffa500>not found!</color>", [MessageInfo.TPHome_CantTP_ActiveTP] = "You already have an active teleportation to home! Cancel: <color=#ffa500>/homec</color>", [MessageInfo.TPHome_Time] = "You have successfully started a teleport home! You will be teleported from <color=#ffa500>{sec}</color> sec.", [MessageInfo.TPHome_Time_Now] = "You were teleported home!", [MessageInfo.TPHome_CantTP_IsntNum] = "Home name can only consist of <color=#ffa500>numbers</color>", [MessageInfo.TPHome_CantTP_Reason] = "Active teleportation home <color=#ffa500>rejected!</color> due to <color=#ffa500>{reason}</color>", [MessageInfo.TPHome_CantTP_RaidBlock] = "You have a <color=#ffa500>block</color> to teleport! Teleport count {count}", [MessageInfo.TPHome_CantTP_Foundation_NotSet] = "Under you is not your (friend's) or not <color=#ffa500>foundation</color>", [MessageInfo.TPHome_CantTP_MaxCountDay] = "Used <color=#ffa500>maximum number</color> of teleports to home per day!", [MessageInfo.TPHome_CantTP_Economics] = "Not have money!", [MessageInfo.HomeC_NotFound] = "Active teleportation to home <color=#ffa500>not found!</color>", [MessageInfo.HomeC_C] = "Active teleportation to home <color=#ffa500>rejected!</color>", [MessageInfo.TPAdmin_TP] = "You has been teleported to <color=#ffa500>{val}</color>", [MessageInfo.TPAdmin_TP_Player] = "Player <color=#ffa500>{player}</color> teleported to <color=#ffa500>{val}</color>", [MessageInfo.TPAdmin_NotFound] = "Player not found!", [MessageInfo.TPAdmin_FoundMore] = "Found <color=#ffa500>more than one player</color>", [MessageInfo.Reason_Cancel] = "Cancel", [MessageInfo.Reason_Damage] = "Damage", [MessageInfo.Reason_InWater] = "In water", [MessageInfo.Reason_OverWater] = "Over water", [MessageInfo.Reason_NoFriend] = "Not friend", [MessageInfo.Cant_InParent] = "In transport", [MessageInfo.Reason_BuildingBlock] = "BuildingBlock",
            }
            ) en.Add(kv.Key.ToString(), kv.Value);
            foreach (var kv in new Dictionary<KeyValuePair<TpSettings, bool>, string>() {
                [new KeyValuePair<TpSettings, bool>(TpSettings.Close_TP, false)]
                = "Close when TP", [new KeyValuePair<TpSettings, bool>(TpSettings.Close_Use, false)] = "Close when USE", [new KeyValuePair<TpSettings, bool>(TpSettings.Whitelist_Fr, false)] = "TPC if not friends", [new KeyValuePair<TpSettings, bool>(TpSettings.AutoTPA_Fr, false)] = "Auto TPA friends", [new KeyValuePair<TpSettings, bool>(TpSettings.Close_TP, true)] = "Close menu after accepting/rejecting/sending a request", [new KeyValuePair<TpSettings, bool>(TpSettings.Close_Use, true)] = "Close menu after each action", [new KeyValuePair<TpSettings, bool>(TpSettings.Whitelist_Fr, true)] = "Accept requests from friends only", [new KeyValuePair<TpSettings, bool>(TpSettings.AutoTPA_Fr, true)] = "Automatically accept requests from friends",
            }
            ) en.Add("TpSettings_" + (!kv.Key.Value ? "Title" : "Message") + "_" + kv.Key.Key.ToString().ToLower(), kv.Value);
            lang.RegisterMessages(en, this, "en");
        }
        public static void Message(BasePlayer player, MessageInfo info, params KeyValuePair<string, string>[] args) {
            try {
                string message = _plugin.lang.GetMessage(info.ToString(), _plugin, player.UserIDString);
                //Debug.Log($"{info} -> {message}");
                //Debug.Log($"{string.Join("\n", _plugin.lang.GetMessages(_plugin.lang.GetLanguage(player.UserIDString), _plugin).Select(kv => $"{kv.Key}: {kv.Value}").ToArray())}");
                foreach (var arg in args) message = message.Replace(arg.Key, arg.Value);
                _plugin.Player.Message(player, message);
            }
            catch {
            }
        }
        public static string GetMessage(BasePlayer player, MessageInfo info, params KeyValuePair<string, string>[] args) {
            try {
                string message = _plugin.lang.GetMessage(info.ToString(), _plugin, player?.UserIDString);
                foreach (var arg in args) message = message.Replace(arg.Key, arg.Value);
                return message;
            }
            catch {
            }
            return null;
        }
        public static string GetMessage(BasePlayer player, TpSettings settings, bool IsTitle, params KeyValuePair<string, string>[] args) {
            try {
                string message = _plugin.lang.GetMessage("TpSettings_" + (IsTitle ? "Title" : "Message") + "_" + settings.ToString().ToLower(), _plugin, player?.UserIDString);
                foreach (var arg in args) message = message.Replace(arg.Key, arg.Value);
                return message;
            }
            catch {
            }
            return null;
        }
        new void LoadConfig() {
            ConfigData.LoadAndSaveAll();
            SaveConfig();
        }
        public List<BasePlayer> FindPlayers(string filter) {
            if (filter == "") return new List<BasePlayer>();
            List<BasePlayer> players = new List<BasePlayer>();
            foreach (var player in BasePlayer.activePlayerList) {
                Debug.Log($"FindPlayers[{player.UserIDString.ToLower()}|{player.displayName.ToLower()}|{filter.ToLower()}]");
                if (player.UserIDString.Contains(filter)) players.Add(player);
                if (player.displayName.ToLower().Contains(filter.ToLower())) players.Add(player);
                if (player.displayName.ToLower() == filter.ToLower()) return new List<BasePlayer> {
                    player
                }
                ;
                if (player.UserIDString.ToLower() == filter.ToLower()) return new List<BasePlayer> {
                    player
                }
                ;
            }
            return players;
        }
        public List<BasePlayer> FindSleepers(string filter) {
            if (filter == "") return new List<BasePlayer>();
            List<BasePlayer> sleepers = new List<BasePlayer>();
            foreach (var sleeper in BasePlayer.sleepingPlayerList) {
                Debug.Log($"FindSleepers[{sleeper.UserIDString.ToLower()}|{sleeper.displayName.ToLower()}|{filter.ToLower()}]");
                if (sleeper.UserIDString.Contains(filter)) sleepers.Add(sleeper);
                if (sleeper.displayName.ToLower().Contains(filter.ToLower())) sleepers.Add(sleeper);
                if (sleeper.displayName.ToLower() == filter.ToLower()) return new List<BasePlayer> {
                    sleeper
                }
                ;
                if (sleeper.UserIDString.ToLower() == filter.ToLower()) return new List<BasePlayer> {
                    sleeper
                }
                ;
            }
            return sleepers;
        }
        public List<T> FindObjects<T>(IEnumerable<T> enumerable, string filter, Func<T, string> func) {
            if (filter == "") return new List<T>();
            List<T> objs = new List<T>();
            foreach (var obj in enumerable) {
                if (func.Invoke(obj).Contains(filter)) objs.Add(obj);
                if (func.Invoke(obj).ToLower() == filter.ToLower()) return new List<T> {
                    obj
                }
                ;
            }
            return objs;
        }
        static void PlayerInvoke(ConsoleSystem.Arg arg, Action<BasePlayer> action) {
            if (arg?.Player() != null) action?.Invoke(arg.Player());
        }
        public static void Teleport(BasePlayer player, Vector3 position) {
            //if (player.IsSleeping()) return;
            if (player.net?.connection != null) player.ClientRPCPlayer(null, player, "StartLoading");
            player.SetPlayerFlag(BasePlayer.PlayerFlags.Sleeping, true);
            if (!BasePlayer.sleepingPlayerList.Contains(player)) BasePlayer.sleepingPlayerList.Add(player);
            player.CancelInvoke("InventoryUpdate");
            player.MovePosition(position);
            if (player.net?.connection != null) player.ClientRPCPlayer(null, player, "ForcePositionTo", position);
            if (player.net?.connection != null) player.SetPlayerFlag(BasePlayer.PlayerFlags.ReceivingSnapshot, true);
            player.UpdateNetworkGroup();
            player.SendNetworkUpdateImmediate(false);
            if (player.net?.connection == null) return;
            try {
                player.ClearEntityQueue(null);
            }
            catch {
            }
            player.SendFullSnapshot();
            //_plugin.timer.Once(0.1f, player.EndSleeping);
        }
        public abstract class ITeleport : MonoBehaviour {
            public abstract BasePlayer Player {
                get;
            }
            public abstract bool IsToUser {
                get;
            }
            public int lastHP = 0;
            public virtual bool CanTP(out MessageInfo message) {
                Vector3 pos = Player.transform.position;
                message = MessageInfo.None;
                if ((IsToUser ? ConfigData.ToUser_CanTPDamage : ConfigData.ToHome_CanTPDamage).Value ? false : (Mathf.FloorToInt(Player.health) < lastHP || Player.IsWounded())) {
                    message = MessageInfo.Reason_Damage;
                    return false;
                }
                if ((IsToUser ? ConfigData.ToUser_CanTPInWater : ConfigData.ToHome_CanTPInWater).Value ? false : Player.IsSwimming()) {
                    message = MessageInfo.Reason_InWater;
                    return false;
                }
                if ((IsToUser ? ConfigData.ToUser_CanTPOverWater : ConfigData.ToHome_CanTPOverWater).Value ? false : TerrainMeta.HeightMap.GetHeight(pos) <= TerrainMeta.WaterMap.GetHeight(pos)) {
                    message = MessageInfo.Reason_OverWater;
                    return false;
                }
                if ((IsToUser ? ConfigData.ToUser_BuildingBlock : ConfigData.ToHome_BuildingBlock).Value ? false : Player.IsBuildingBlocked()) {
                    message = MessageInfo.Reason_BuildingBlock;
                    return false;
                }
                lastHP = Mathf.FloorToInt(Player.health);
                return true;
            }
        }
#region PlayerToPlayer
#region Commands
        [ChatCommand("tpr")]
        void ChatCommand_TPR(BasePlayer player, string command, string[] args) {
            Debug.Log("TPR.0");
            if (!ConfigData.ToUser_CanTP.Value) return;
            Debug.Log($"TPR.1.{Interface.Call("CanTeleport", player) ?? "NULL"}");
            object obj = Interface.Call("CanTeleport", player);
            if (obj is string) {
                Player.Message(player, obj.ToString());
                return;
            }
            if (obj is bool) {
                if (!(bool)obj) return;
            }
            if (obj != null) return;
            Debug.Log("TPR.2");
            if (DATA.TpToPlayer_CD.ContainsKey(player.UserIDString)) {
                Debug.Log("TPR.3");
                if (DATA.TpToPlayer_CD[player.UserIDString] > DateTime.Now.Ticks) {
                    Debug.Log("TPR.4");
                    Message(player, MessageInfo.CoolDown_Use, new KeyValuePair<string, string>("{sec}", Math.Round(new TimeSpan(DATA.TpToPlayer_CD[player.UserIDString] - DateTime.Now.Ticks).TotalSeconds, 1).ToString()));
                    Debug.Log("TPR.5");
                    return;
                }
                Debug.Log("TPR.6");
            }
            Debug.Log("TPR.7");
            if (args.Count() == 0) {
                Debug.Log("TPR.8");
                Message(player, MessageInfo.TPR_Command_Info);
                Debug.Log("TPR.9");
                return;
            }
            Debug.Log("TPR.10");
            List<BasePlayer> players = FindPlayers(string.Join(" ", args));
            Debug.Log("TPR.11");
            if (players.Count() > 1) {
                Debug.Log("TPR.12");
                Message(player, MessageInfo.TPR_Cant_Count_More);
                Debug.Log("TPR.13");
                return;
            }
            Debug.L
// ... [Code preview truncated due to length. Full source in attached file] ...

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

Другие ресурсы пользователя 15FPS

Сверху