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.Globalization;
using System.Linq;
using UnityEngine;
using Oxide.Game.Rust.Cui;
using Facepunch.Extend;
using System.IO;
namespace Oxide.Plugins {
[Info("TpController", "Arch_Dem0n", "1.1.6")]
public class TpController : RustPlugin {
[PluginReference("Friends")]
Plugin Friends;
[PluginReference("FriendSystem")]
Plugin FriendSystem;
[PluginReference("Clans")]
Plugin Clans;
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.RegisterPermission(perm.Key, this);
}
);
Foreach(ConfigData.ToHome_CountDay.Value, (perm) => {
if (perm.Key != "default") permission.RegisterPermission(perm.Key, this);
}
);
Foreach(ConfigData.ToHome_CDTime.Value, (perm) => {
if (perm.Key != "default") permission.RegisterPermission(perm.Key, this);
}
);
Foreach(ConfigData.ToUser_CDTime.Value, (perm) => {
if (perm.Key != "default") permission.RegisterPermission(perm.Key, this);
}
);
Foreach(ConfigData.ToUser_CountDay.Value, (perm) => {
if (perm.Key != "default") 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!");
}
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<float> ToUser_Time = new ConfigItem<float>(() => GetConfig("Игрок", "Вермя на телепортацию (в секундах)", 15), (value) => SetConfig(true, "Игрок", "Вермя на телепортацию (в секундах)", value));
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> ToHome_CanTP = new ConfigItem<bool>(() => GetConfig("Дом", "Разрешить телепортацию", true), (value) => SetConfig(true, "Дом", "Разрешить телепортацию", value));
public static ConfigItem<float> ToHome_Time = new ConfigItem<float>(() => GetConfig("Дом", "Вермя на телепортацию (в секундах)", 15), (value) => SetConfig(true, "Дом", "Вермя на телепортацию (в секундах)", value));
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_CanTPNotYourFoundation = new ConfigItem<bool>(() => !GetConfig("Дом", "Запретить ставить дом на чужом фундаменте (на земле)?", true), (value) => SetConfig(true, "Дом", "Запретить ставить дом на чужом фундаменте (на земле)?", !value));
//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));
//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(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 class ConfigItem {
public Func<object> get;
public Action<object> set;
}
}
static BuildingBlock GetFoundation(Vector3 pos) {
RaycastHit hit;
if (Physics.Raycast(pos, Vector3.down, out hit, 0.2f)) {
var entity = hit.GetEntity();
Debug.Log(entity?.ShortPrefabName ?? "NULL");
if (entity?.ShortPrefabName?.Contains("foundation") ?? false) return entity as BuildingBlock;
}
return null;
}
static bool CanTeleportFoundation(BasePlayer player, Vector3 position) {
Debug.Log("1");
if (ConfigData.ToHome_CanTPNotYourFoundation.Value) return true;
Debug.Log("2");
BuildingBlock foundation = GetFoundation(position);
Debug.Log("3");
if (foundation == null) return false;
Debug.Log("4");
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 {
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, 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_Time, TPHome_Time_Now, HomeC_NotFound, HomeC_C, TPAdmin_TP, TPAdmin_TP_Player, TPAdmin_NotFound, TPAdmin_FoundMore, Reason_Cancel, Reason_Damage, Reason_InWater, Reason_InAir, Reason_NoFriend
}
protected override void LoadDefaultMessages() {
Dictionary<string, string> ru = new Dictionary<string, string>();
foreach (var kv in new Dictionary<MessageInfo, string>() {
[MessageInfo.CoolDown_Use]
= "Вы не можете сделать это! Осталось {min}мин.", [MessageInfo.TPR_TP] = "Вы были телепортированы к <color=orange>{name}</color>", [MessageInfo.TPR_TP_Yes] = "Ваш запрос на телопортацию подтвержден игроком <color=orange>{name}</color>", [MessageInfo.TPR_TP_No] = "Запрос на телопортацию <color=orange>отклонен</color> по причине <color=orange>{reason}</color>", [MessageInfo.TPR_Send_TP] = "Вы отправили запрос на телепортацию игроку <color=orange>{name}</color>", [MessageInfo.TPR_Cant_Count_0] = "Игрок <color=orange>не найден!</color>", [MessageInfo.TPR_Cant_Count_More] = "Найдено <color=orange>несколько игроков</color>", [MessageInfo.TPR_Cant_ActiveTP] = "У вас уже есть активная телепортация! Отменить текущую: </color=orange>/tpc</color>", [MessageInfo.TPR_Cant_MaxCountDay] = "Использовано <color=orange>максимально количество</color> телепортаций в день!", [MessageInfo.TPR_Cant_RaidBlock] = "У вас <color=orange>блок</color> на телепортацию!", [MessageInfo.TPR_Command_Info] = "Для телепортации используйте: <color=orange>/tpr Ник/SteamID</color>", [MessageInfo.TPA_TP] = "<color=orange>{name}</color> был телепортирован к вам", [MessageInfo.TPA_TP_Yes] = "Вы приняли запрос игрока <color=orange>{name}</color>", [MessageInfo.TPA_TP_No] = "Запрос на телопортацию к вам <color=orange>отклонен</color> по причине <color=orange>{reason}</color>", [MessageInfo.TPA_Send_TP] = "Игрок <color=orange>{name}</color> отправил запрос на телепортацию к вам\nПропишите <color=orange>/tpa</color>, чтобы принять запрос", [MessageInfo.TPA_Cant_Count_More] = "Найдено <color=orange>несколько игроков!</color>", [MessageInfo.TPA_Cant_Count_0] = "Не найдено активных запросов!", [MessageInfo.TPA_Cant_Count_1] = "Не найдено активных запросов от игрока <color=orange>{name}</color>", [MessageInfo.TPA_Cant_ActiveCount_More] = "Найдено несколько активных запросов! <color=orange>Укажите Ник или SteamID отправителя!</color>", [MessageInfo.TPA_Cant_RaidBlock] = "У вас <color=orange>блок</color> на телепортацию!", [MessageInfo.TPC_Cant_Count_More] = "Найдено <color=orange>несколько</color> игроков!", [MessageInfo.TPC_Cant_Count_0] = "Не найдено активных запросов!", [MessageInfo.TPC_Cant_Count_1] = "Не найдено активных запросов от игрока {name}!", [MessageInfo.TPC_Cant_ActiveCount_More] = "Найдено несколько активных запросов! Укажите имя или SteamID отправителя!", [MessageInfo.SetHome_Command_Info] = "Используйте: <color=orange>/sethome Название</color>", [MessageInfo.SetHome_Set] = "Вы создали дом под названием <color=orange>{home}</color>", [MessageInfo.SetHome_CantSet_Found] = "Дом с таким названием уже существует!", [MessageInfo.SetHome_CantSet_MaxCount] = "Достигнуто <color=orange>максимальное</color> количество точек дома", [MessageInfo.SetHome_CantSet_CantBuild] = "Вы <color=orange>не можете</color> поставить свой дом тут!", [MessageInfo.SetHome_CantSet_IsntNum] = "Название дома может состоять <color=orange>только из цифр</color>", [MessageInfo.SetHome_CantSet_Foundation] = "Под вами не ваш(друга) или нету <color=orange>фундамента</color>", [MessageInfo.DelHome_Command_Info] = "Используйте: <color=orange>/removehome Название дома</color>", [MessageInfo.DelHome_Del] = "Вы успешно удалили дом <color=orange>{home}</color>", [MessageInfo.DelHome_CantDel_NotFound] = "Дом с таким названием <color=orange>не найден!</color>", [MessageInfo.DelHome_CantDel_IsntNum] = "Название дома может состоять <color=orange>только из цифр</color>", [MessageInfo.TPHome_CantTP_NotFound] = "Дом с таким названием <color=orange>не найден!</color>", [MessageInfo.TPHome_CantTP_ActiveTP] = "У вас уже есть активная телепортация домой! Отменить текущую: <color=orange>/homec</color>", [MessageInfo.TPHome_Time] = "Вы успешно начали телепорт домой!", [MessageInfo.TPHome_Time_Now] = "Вы были телепортированы домой!", [MessageInfo.TPHome_CantTP_IsntNum] = "Название дома может состоять <color=orange>только из цифр</color>", [MessageInfo.TPHome_CantTP_Reason] = "Активные телепортации домой <color=orange>отклонены!</color> по причине <color=orange>{reason}</color>", [MessageInfo.TPHome_CantTP_RaidBlock] = "У вас <color=orange>блок</color> на телепортацию!", [MessageInfo.TPHome_CantTP_Foundation_NotSet] = "Под вашим домом не ваш(друга) или нету <color=orange>фундамента</color>", [MessageInfo.TPHome_CantTP_MaxCountDay] = "Использовано <color=orange>максимально количество</color> телепортаций домой в день!", [MessageInfo.HomeC_NotFound] = "Активных телепортаций домой <color=orange>не найдено!</color>", [MessageInfo.HomeC_C] = "Активные телепортации домой <color=orange>отклонены!</color>", [MessageInfo.TPAdmin_TP] = "Вы были телепортированы к <color=orange>{val}</color>", [MessageInfo.TPAdmin_TP_Player] = "Игрок <color=orange>{player}</color> телепортирован к <color=orange>{val}</color>", [MessageInfo.TPAdmin_NotFound] = "Игрок не найден!", [MessageInfo.TPAdmin_FoundMore] = "Найдено <color=orange>несколько</color> игроков!", [MessageInfo.Reason_Cancel] = "Отмена", [MessageInfo.Reason_Damage] = "Получение урона", [MessageInfo.Reason_InWater] = "В воде", [MessageInfo.Reason_NoFriend] = "Не друг", [MessageInfo.Cant_InParent] = "В транспорте",
}
) 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 {min}min.", [MessageInfo.TPR_TP] = "You has been teleported to <color=orange>{name}</color>", [MessageInfo.TPR_TP_Yes] = "Your request for teleportation is confirmed by the player <color=orange>{name}</color>", [MessageInfo.TPR_TP_No] = "Request for teleporting <color=orange> rejected </color> due to <color=orange>{reason}</color>", [MessageInfo.TPR_Send_TP] = "You have sent a request for teleportation to the player <color=orange>{name}</color>", [MessageInfo.TPR_Cant_Count_0] = "Player <color=orange>not found!</color>", [MessageInfo.TPR_Cant_Count_More] = "Found <color=orange>more than one player</color>", [MessageInfo.TPR_Cant_ActiveTP] = "You already have an active teleportation! Cancel: </color=orange>/tpc</color>", [MessageInfo.TPR_Cant_MaxCountDay] = "Used <color=orange>maximum number</color> of teleports per day!", [MessageInfo.TPR_Cant_RaidBlock] = "You have a <color=orange>block</color> to teleport!", [MessageInfo.TPR_Command_Info] = "For teleportation use: <color=orange>/tpr Nickname/SteamID</color>", [MessageInfo.TPA_TP] = "<color=orange>{name}</color> was teleported to you", [MessageInfo.TPA_TP_Yes] = "You have accepted a player request <color=orange>{name}</color>", [MessageInfo.TPA_TP_No] = "The request to teleport you <color=orange>was rejected</color> due to <color=orange>{reason}</color>", [MessageInfo.TPA_Send_TP] = "Player <color=orange>{name}</color> sent a request for teleportation to you\nPlease write <color=orange>/tpa</color> to accept the request", [MessageInfo.TPA_Cant_Count_More] = "Found <color=orange>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=orange>{name}</color>", [MessageInfo.TPA_Cant_ActiveCount_More] = "Found more than one active query! <color=orange>Enter the nickname or SteamID!</color>", [MessageInfo.TPA_Cant_RaidBlock] = "You have a <color=orange>block</color> to teleport!", [MessageInfo.TPC_Cant_Count_More] = "Found <color=orange>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=orange>{name}</color>", [MessageInfo.TPC_Cant_ActiveCount_More] = "Found more than one active query! <color=orange>Enter the nickname or SteamID!</color>", [MessageInfo.SetHome_Command_Info] = "Use: <color=orange>/sethome name</color>", [MessageInfo.SetHome_Set] = "You created a home with name <color=orange>{home}</color>", [MessageInfo.SetHome_CantSet_Found] = "A home with this name already exists!", [MessageInfo.SetHome_CantSet_MaxCount] = "Reached <color=orange>maximum</color> number of points at home", [MessageInfo.SetHome_CantSet_CantBuild] = "You <color=orange>can't</color> set your home here!", [MessageInfo.SetHome_CantSet_IsntNum] = "Home name can only consist of <color=orange>numbers</color>", [MessageInfo.SetHome_CantSet_Foundation] = "Under you is not your (friend's) or not <color=orange>foundation</color>", [MessageInfo.DelHome_Command_Info] = "Use: <color=orange>/removehome name</color>", [MessageInfo.DelHome_Del] = "You have successfully removed the home with name <color=orange>{home}</color>", [MessageInfo.DelHome_CantDel_NotFound] = "A home with this name <color=orange>not found!</color>", [MessageInfo.DelHome_CantDel_IsntNum] = "Home name can only consist of <color=orange>numbers</color>", [MessageInfo.TPHome_CantTP_NotFound] = "A home with this name <color=orange>not found!</color>", [MessageInfo.TPHome_CantTP_ActiveTP] = "You already have an active teleportation to home! Cancel: <color=orange>/homec</color>", [MessageInfo.TPHome_Time] = "You have successfully started a teleport home!", [MessageInfo.TPHome_Time_Now] = "You were teleported home!", [MessageInfo.TPHome_CantTP_IsntNum] = "Home name can only consist of <color=orange>numbers</color>", [MessageInfo.TPHome_CantTP_Reason] = "Active teleportation home <color=orange>rejected!</color> due to <color=orange>{reason}</color>", [MessageInfo.TPHome_CantTP_RaidBlock] = "You have a <color=orange>block</color> to teleport!", [MessageInfo.TPHome_CantTP_Foundation_NotSet] = "Under you is not your (friend's) or not <color=orange>foundation</color>", [MessageInfo.TPHome_CantTP_MaxCountDay] = "Used <color=orange>maximum number</color> of teleports to home per day!", [MessageInfo.HomeC_NotFound] = "Active teleportation to home <color=orange>not found!</color>", [MessageInfo.HomeC_C] = "Active teleportation to home <color=orange>rejected!</color>", [MessageInfo.TPAdmin_TP] = "You has been teleported to <color=orange>{val}</color>", [MessageInfo.TPAdmin_TP_Player] = "Player <color=orange>{player}</color> teleported to <color=orange>{val}</color>", [MessageInfo.TPAdmin_NotFound] = "Player not found!", [MessageInfo.TPAdmin_FoundMore] = "Found <color=orange>more than one player</color>", [MessageInfo.Reason_Cancel] = "Cancel", [MessageInfo.Reason_Damage] = "Damage", [MessageInfo.Reason_InWater] = "In water", [MessageInfo.Reason_NoFriend] = "Not friend", [MessageInfo.Cant_InParent] = "In transport",
}
) 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<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);
}
#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>("{min}", Math.Round(new TimeSpan(DATA.TpToPlayer_CD[player.UserIDString] - DateTime.Now.Ticks).TotalMinutes, 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.Log("TPR.14");
if (players.Count() == 0) {
Debug.Log("TPR.15");
Message(player, MessageInfo.TPR_Cant_Count_0);
Debug.Log("TPR.16");
return;
}
Debug.Log("TPR.17");
MessageInfo? message = null;
if (IsTPBlock(player, ref message)) {
Debug.Log("TPR.18");
Message(player, message ?? MessageInfo.TPR_Cant_RaidBlock);
Debug.Log("TPR.19");
return;
}
Debug.Log("TPR.20");
if (players.Count() == 1) {
Debug.Log("TPR.21");
switch (TPR.TP(player, players.FirstOrDefault())) {
case 1 : Debug.Log("TPR.22.1");
Message(player, MessageInfo.TPR_Cant_ActiveTP);
Debug.Log("TPR.22.2");
return;
case 2 : Debug.Log("TPR.23.1");
Message(player, MessageInfo.TPR_Cant_MaxCountDay);
Debug.Log("TPR.23.2");
return;
case 0 : Debug.Log("TPR.24");
return;
}
Debug.Log("TPR.25");
return;
}
Debug.Log("TPR.26");
}
[ChatCommand("tpa")]
void ChatCommand_TPA(BasePlayer player, string command, string[] args) {
if (!ConfigData.ToUser_CanTP.Value) return;
List<BasePlayer> players = FindPlayers(string.Join(" ", args));
if (players.Count() > 1) {
Message(player, MessageInfo.TPA_Cant_Count_More);
return;
}
MessageInfo? message = null;
if (IsTPBlock(player, ref message)) {
Message(player, message ?? MessageInfo.TPA_Cant_RaidBlock);
return;
}
switch (TPA.Yes(player, players.Count() > 0 ? players.FirstOrDefault() : null)) {
case 0 : return;
case 1 : Message(player, MessageInfo.TPA_Cant_Count_0);
return;
case 2 : Message(player, MessageInfo.TPA_Cant_ActiveCount_More);
return;
case 3 : Message(player, MessageInfo.TPA_Cant_Count_1, new KeyValuePair<string, string>("{name}", (players.Count() > 0 ? players.FirstOrDefault() : null)?.displayName ?? "[НЕ УКАЗАНО]"));
return;
}
return;
}
[ChatCommand("tpc")]
void ChatCommand_TPC(BasePlayer player, string command, string[] args) {
Debug.Log("TPC.0");
if (!ConfigData.ToUser_CanTP.Value) return;
Debug.Log("TPC.1");
List<BasePlayer> players = FindPlayers(string.Join(" ", args));
Debug.Log("TPC.2");
if (players.Count() > 1) {
Debug.Log("TPC.3");
Message(player, MessageInfo.TPC_Cant_Count_More);
Debug.Log("TPC.4");
return;
}
Debug.Log("TPC.5");
TPC(player, players.Count() > 0 ? players.FirstOrDefault() : null);
}
[ConsoleCommand("tp.tpr")]
void ConsoleCommand_TPR(ConsoleSystem.Arg arg) => PlayerInvoke(arg, (player) => {
if (DATA.GetSettings(player.UserIDString, TpSettings.Close_TP) || DATA.GetSettings(player.UserIDString, TpSettings.Close_Use)) GUITP.Stop(player);
ChatCommand_TPR(player, "tpr", arg.Args);
}
);
[ConsoleCommand("tp.tpa")]
void ConsoleCommand_TPA(ConsoleSystem.Arg arg) => PlayerInvoke(arg, (player) => {
if (DATA.GetSettings(player.UserIDString, TpSettings.Close_TP) || DATA.GetSettings(player.UserIDString, TpSettings.Close_Use)) GUITP.Stop(player);
ChatCommand_TPA(player, "tpa", arg.Args);
}
);
[ConsoleCommand("tp.tpc")]
void ConsoleCommand_TPC(ConsoleSystem.Arg arg) => PlayerInvoke(arg, (player) => {
if (DATA.GetSettings(player.UserIDString, TpSettings.Close_TP) || DATA.GetSettings(player.UserIDString, TpSettings.Close_Use)) GUITP.Stop(player);
ChatCommand_TPC(player, "tpc", arg.Args);
}
);
#endregion
#region Components
public static void TPC(BasePlayer player1, BasePlayer player2) {
Debug.Log("TPC.TPC.6");
int retA = TPA.TPC(player1, player2);
Debug.Log($"TPC.TPC.7.{retA}");
if (retA == 0) return;
Debug.Log($"TPC.TPC.8.{retA}");
int retR = TPR.TPC(player1, player2);
Debug.Log($"TPC.TPC.9.{retR}");
if (retR == 0) return;
Debug.Log($"TPC.TPC.10.{retR}");
int retH = TPHome.HOMEC(player1);
Debug.Log($"TPC.TPC.11.{retH}");
if (retH == 0) return;
Debug.Log($"TPC.TPC.12.{retH}");
if (retA <= 1 && retR <= 1) {
Debug.Log("TPC.TPC.13");
Message(player1, MessageInfo.TPC_Cant_Count_0);
Debug.Log("TPC.TPC.14");
return;
}
Debug.Log($"TPC.TPC.15.{retA}");
switch (retA) {
case 2 : Message(player1, MessageInfo.TPC_Cant_ActiveCount_More);
return;
case 3 : Message(player1, MessageInfo.TPC_Cant_Count_1);
return;
default : return;
}
}
public List<KeyValuePair<int, BasePlayer>> GetFriends(BasePlayer player) {
List<KeyValuePair<int, BasePlayer>> ret = new List<KeyValuePair<int, BasePlayer>>();
if (Clans != null) ret.AddRange(ClanOrFriends.GetClanMembers(player).Where(val => BasePlayer.Find(val)).Select(val => new KeyValuePair<int, BasePlayer>(1, BasePlayer.Find(val))));
if (Friends ?? FriendSystem != null) ret.AddRange(ClanOrFriends.GetFriends(player).Where(val => BasePlayer.Find(val)).Select(val => new KeyValuePair<int, BasePlayer>(0, BasePlayer.Find(val))));
return ret;
}
public List<BasePlayer> GetFriendList(BasePlayer player) {
List<BasePlayer> ret = new List<BasePlayer>();
if (Clans != null) ret.AddRange(ClanOrFriends.GetClanMembers(player).Where(val => BasePlayer.Find(val)).Select(val => BasePlayer.Find(val)));
if (Friends ?? FriendSystem != null) ret.AddRange(ClanOrFriends.GetFriends(player).Where(val => BasePlayer.Find(val)).Select(val => BasePlayer.Find(val)));
return ret;
}
static class ClanOrFriends {
public static List<string> GetClanMembersUmod(BasePlayer player) {
var clanTag = _plugin.Clans.Call<string>("GetClanOf", player.userID);
if (clanTag == null) return null;
var resultRaw = _plugin.Clans.Call<JObject>("GetClan", clanTag);
if (resultRaw == null) return null;
var result = JsonConvert.DeserializeObject<ClanUModGetClanResult>(resultRaw.ToString());
if (result == null) return null;
var members = JsonConvert.DeserializeObject<Dictionary<string, string>>(result.members.ToString());
return members != null ? new List<string>(members.Keys) : null;
}
class ClanUModGetClanResult {
public string tag;
public string owner;
public JArray moderators;
public JArray members;
public JArray invited;
public JArray allies;
public JArray invitedallies;
}
public static List<string> GetClanMembersOvh(BasePlayer player) {
var result = _plugin.Clans.Call<List<ulong>>("ApiGetClanMembers", player.userID);
return result?.ConvertAll(i => i.ToString());
}
public static List<string> GetFriendsOvh(BasePlayer player) {
var result = (List<ulong>)(_plugin.Friends ?? _plugin.FriendSystem).CallHook("ApiGetFriends", player.userID);
return result?.ConvertAll(i => i.ToString());
}
public static List<string> GetFriends(BasePlayer player) {
if (_plugin.Friends ?? _plugin.FriendSystem == null) return null;
if (_plugin.FriendSystem != null) return _plugin.FriendSystem.Call<ulong[]>("GetFriend", player.userID).Select(val => val.ToString()).ToList();
if ((_plugin.Friends ?? _plugin.FriendSystem).Author.ToLower().Contains("sanlerus")) return GetFriendsOvh(player);
//Friends by Moscow.OVH
var friends = (_plugin.Friends ?? _plugin.FriendSystem).Call<string[]>("GetFriends", player.UserIDString);
//Friends by dcode (Oxide)
return friends != null ? friends.ToList() : null;
}
public static List<string> GetClanMembers(BasePlayer player) {
if (_plugin.Clans == null) return null;
if (_plugin.Clans.Author.ToLower().Contains("k1lly0u")) return GetClanMembersUmod(player);
//Clans by k1lly0u (uMod/Oxide)
if (_plugin.Clans.Author.ToLower().Contains("sanlerus")) return GetClanMembersOvh(player);
//Clans by Moscow.OVH
return _plugin.Clans.Call<List<string>>("GetClanMembers", player.userID);
}
}
///<summary>Отправитель ТП</summary>
public class TPR : MonoBehaviour {
/// <summary>Отменить ТП со стороны отправителя</summary>
/// <param name="from">Отправитель</param>
/// <param name="to">Получатель</param>
/// <exception cref="0 - ТП отменено"></exception>
/// <exception cref="1 - Не найдено активных ТП"></exception>
/// <exception cref="2 - Несколько активных ТП и получатель не указан"></exception>
/// <exception cref="3 - Получатель ТП не найден"></exception>
public static int TPC(BasePlayer from, BasePlayer to) {
Debug.Log("TPR.TPC.0");
if (from.GetComponents<TPR>().Count() == 0) return 1;
Debug.Log("TPR.TPC.1");
if (from.GetComponents<TPA>().Count() == 1) {
Debug.Log("TPR.TPC.2");
from.GetComponent<TPR>().StopTP(GetMessage(null, MessageInfo.Reason_Cancel));
Debug.Log("TPR.TPC.3");
return 0;
}
Debug.Log("TPR.TPC.4");
if (from.GetComponents<TPR>().Count() > 1 &
// ... [Code preview truncated due to length. Full source in attached file] ...