C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System.Collections.Generic;
using Oxide.Game.Rust.Cui;
using Physics = UnityEngine.Physics;
using System.Collections;
using System.Linq;
using UnityEngine.Networking;
using Pool = Facepunch.Pool;
using ConVar;
using System;
using ProtoBuf;
using UnityEngine;
using Oxide.Core.Plugins;
using Oxide.Core;
using System.Text;
using Newtonsoft.Json;
using Object = System.Object;
using Vector3 = UnityEngine.Vector3;
namespace Oxide.Plugins {
[Info("IQTeleportation", "Mercury", "1.5.7")]
[Description("IQTeleportation")]
class IQTeleportation : RustPlugin {
private readonly List<String> exceptionsBuildingBlockEntities = new() {
"rug.deployed", "rug.bear.deployed", "sleepingbag_leather_deployed", "bed_deployed", "box.wooden.large", "woodbox",
}
;
private IEnumerator ProcessTWarp(BasePlayer player, Vector3 position, Int32 timeTeleportation) {
return ProcessTeleportation(player, () => false, () => TeleportationWarp(player, position), timeTeleportation );
}
private readonly List<UInt64> ItemIdCorrecteds = new List<UInt64> {
1074866732, 2004072627, 2017601552, 2006957888, 930560607, 1123047824, 1130765085, 442289265, 090353317, 15376018, 118372687
}
;
private void ParseMonuments() {
localAllMonuments.Clear();
Int32 countAddedMonuments = 0;
foreach (MonumentInfo monument in TerrainMeta.Path.Monuments) {
if (monument.Bounds.size == Vector3.zero) continue;
localAllMonuments.Add(monument);
countAddedMonuments++;
}
Puts(LanguageEn ? $"Information received about {countAddedMonuments} monuments on the map" : $"Получена информация о {countAddedMonuments} монументах на карте");
}
private String CanSetHome(BasePlayer player, BuildingBlock buildingBlock, String homeName, in Vector3 positionHome, Tugboat tugboatEntity = null) {
Configuration.HomeController.SetupHome homeController = config.homeController.setupHomeController;
Object canSetHome = Interface.Call("OnHomeAdd", player, homeName, positionHome);
if (canSetHome != null) {
if (canSetHome is String errorMessage && !String.IsNullOrWhiteSpace(errorMessage)) return errorMessage;
return GetLang("CAN_SETHOME_OTHER_MESSAGE", player.UserIDString);
}
String statusPlayer = CheckStatusPlayer(player);
if (!String.IsNullOrWhiteSpace(statusPlayer)) return statusPlayer;
if(homeController.noSetupInRaidBlock && IsRaidBlocked(player)) return GetLang("CAN_SETHOME_IS_RAIDBLOCK", player.UserIDString);
Dictionary<String, PlayerHome> pData = playerHomes[player.userID];
if (pData.Count >= config.homeController.homeCount.GetCount(player, true)) return GetLang("CAN_SETHOME_MAXIMUM_HOMES", player.UserIDString);
if (pData.ContainsKey(homeName)) return GetLang("CAN_SETHOME_EXIST_HOMENAME", player.UserIDString, homeName);
foreach (KeyValuePair<String, PlayerHome> homesPlayer in pData) {
if (Vector3.Distance(homesPlayer.Value.positionHome, positionHome) < 2.8f) return GetLang("CAN_SETHOME_DISTANCE_EXIST_HOME", player.UserIDString, homesPlayer.Key);
}
if (tugboatEntity != null) {
if (!config.homeController.setupHomeController.canSetupTugboatHome) return GetLang("CAN_SETHOME_TUGBOAT_DISABLE", player.UserIDString);
UInt64[] friendList = GetFriendList(player);
if(friendList == null || friendList.Length == 0) return String.Empty;
Boolean isAuthedFriend = tugboatEntity.children.OfType<VehiclePrivilege>().Any(vehiclePrivilege => friendList.Any(vehiclePrivilege.IsAuthed));
return !isAuthedFriend && !tugboatEntity.IsAuthed(player) ? GetLang("CAN_SETHOME_BUILDING_PRIVILAGE_AUTH_TUGBOAT", player.UserIDString) : String.Empty;
}
BuildingPrivlidge buildingPrivilage = player.GetBuildingPrivilege();
if(homeController.onlyBuildingPrivilage && buildingPrivilage == null) return GetLang("CAN_SETHOME_BUILDING_PRIVILAGE", player.UserIDString);
if (homeController.onlyBuildingAuth && buildingPrivilage != null && !player.IsBuildingAuthed()) return GetLang("CAN_SETHOME_BUILDING_PRIVILAGE_AUTH", player.UserIDString);
if (!buildingBlock) {
buildingBlock = GetBuildingBlock(positionHome);
if (!buildingBlock) return GetLang("CAN_SETHOME_BUILDING", player.UserIDString);
}
return String.Empty;
}
[ConsoleCommand("sethome")]
private void SetHomeConsoleCMD(ConsoleSystem.Arg arg) {
BasePlayer player = arg.Player();
if (player == null) return;
if (arg.Args.Length == 0) {
SendChat(GetLang("SYNTAX_COMMAND_SETHOME", player.UserIDString), player, true);
return;
}
String homeName = arg.Args[0];
SetHome(player, homeName);
}
private class ServerWarp {
public Vector3 position;
public String monumentParent;
public Boolean hideWarp;
public Vector3 GetPositionWarp() {
if (hideWarp) return default;
MonumentInfo monument = _.GetMonumentInName(monumentParent);
if (!monument) return position;
return monument.transform.TransformPoint(position);
}
public ServerWarp(MonumentInfo monument, Vector3 warpPosition) {
if (monument) {
position = monument.transform.InverseTransformPoint(warpPosition);
monumentParent = monument.name;
}
else {
position = warpPosition;
monumentParent = String.Empty;
}
hideWarp = false;
}
}
private Dictionary<UInt64, Dictionary<String, PlayerHome>> playerHomes = new();
[ConsoleCommand("ui_teleportation_command")]
private void UICommandConsole(ConsoleSystem.Arg arg) {
BasePlayer player = arg.Player();
if (player == null) return;
if (arg.Args.Length == 0) return;
String action = arg.Args[0];
switch (action) {
case "sethome" : {
if (arg.Args.Length < 1) return;
Dictionary<String, PlayerHome> pData = playerHomes[player.userID];
if (pData.Count >= config.homeController.homeCount.GetCount(player, true)) return;
String mbName = GetNextHomeName(pData);
if (bagInstalled.TryGetValue(player, out SleepingBag bag)) {
SetHome(player, mbName, bag);
bagInstalled.Remove(player);
}
break;
}
case "cancell.sethome" : {
if (bagInstalled.ContainsKey(player)) bagInstalled.Remove(player);
break;
}
case "tpa" : {
AcceptRequestTeleportation(player);
break;
}
case "tpc" : {
CancellTeleportation(player);
break;
}
}
}
private Dictionary<BasePlayer, BasePlayer> casheTeleportationLast = new ();
private class TeleportationQueueInfo {
public Boolean isAccepted;
public Boolean isActive;
public BasePlayer player;
}
[ChatCommand("sethome")]
private void SetHomeChatCMD(BasePlayer player, String cmd, String[] arg) {
if (arg.Length == 0) {
SendChat(GetLang("SYNTAX_COMMAND_SETHOME", player.UserIDString), player, true);
return;
}
String homeName = arg[0];
SetHome(player, homeName);
}
private class UserRepository {
public Coroutine activeTeleportation;
public Double cooldownWarp;
public Double cooldownHome;
public Double cooldownTeleportation;
public enum TeleportType {
Warp, Home, Teleportation
}
public void SetupCooldown(BasePlayer player, TeleportType teleportType) {
Int32 cooldown = teleportType switch {
TeleportType.Home => config.homeController.homeCooldown.GetCount(player), TeleportType.Teleportation => config.teleportationController.teleportCooldown.GetCount(player), TeleportType.Warp => config.warpsContoller.teleportWarpCooldown.GetCount(player), _ => throw new ArgumentOutOfRangeException(nameof(teleportType), teleportType, null)
}
;
switch (teleportType) {
case TeleportType.Home : cooldownHome = CurrentTime + cooldown;
break;
case TeleportType.Teleportation : cooldownTeleportation = CurrentTime + cooldown;
break;
case TeleportType.Warp : cooldownWarp = CurrentTime + cooldown;
break;
default : throw new ArgumentOutOfRangeException(nameof(teleportType), teleportType, null);
}
DeActiveTeleportation();
}
public String GetCooldownTitle(BasePlayer player, TeleportType teleportType) {
Double cooldownLeft = teleportType switch {
TeleportType.Warp => cooldownWarp - CurrentTime, TeleportType.Home => cooldownHome - CurrentTime, _ => cooldownTeleportation - CurrentTime
}
;
String cooldownLeftTitle = cooldownLeft <= 0 ? String.Empty : _.FormatTime(cooldownLeft, player.UserIDString);
return cooldownLeftTitle;
}
public Boolean IsActiveTeleportation() => activeTeleportation != null;
public void ActiveCoroutineController(Coroutine coroutine, BasePlayer target = null) {
DeActiveTeleportation();
activeTeleportation = coroutine;
}
public void DeActiveTeleportation() {
if (!IsActiveTeleportation()) return;
ServerMgr.Instance.StopCoroutine(activeTeleportation);
activeTeleportation = null;
}
}
[ConsoleCommand("rh")]
private void RemoveHomeShortConsoleCMD(ConsoleSystem.Arg arg) => RemoveHomeConsoleCMD(arg);
private Dictionary<BasePlayer, MapNote> playerPings = new();
[ChatCommand("home")]
private void HomeChatCMD(BasePlayer player, String cmd, String[] arg) {
if (arg.Length == 0) {
SendChat(GetLang("SYNTAX_COMMAND_HOME_TELEPORTATION", player.UserIDString), player, true);
return;
}
RequestHome(player, arg);
}
private Boolean AcceptRequestTeleportation(BasePlayer player, Boolean isAutoAccept = false) {
if (!playerTeleportationQueue.TryGetValue(player.userID, out TeleportationQueueInfo requester)) {
SendChat(GetLang("CAN_ACCEPT_TELEPORTATION_NOT_REQUEST", player.UserIDString), player, true);
return false;
}
if (!requester.isActive) {
SendChat(GetLang("CAN_ACCEPT_TELEPORTATION_NOT_REQUEST", player.UserIDString), player, true);
return false;
}
if (requester.isAccepted) {
SendChat(GetLang("CAN_ACCEPT_TELEPORTATION_ACTIVE_ACCEPTED", player.UserIDString), player, true);
return false;
}
String canTeleport = CanTeleportation(player, UserRepository.TeleportType.Teleportation, true);
if (!String.IsNullOrWhiteSpace(canTeleport)) {
SendChat(canTeleport, player, true);
localUsersRepository[requester.player].DeActiveTeleportation();
return false;
}
Object OnTeleportRequested = Interface.Call("OnTeleportRequested", player, requester.player);
if (OnTeleportRequested != null) {
if (OnTeleportRequested is String hookResult) {
SendChat(hookResult, player, true);
localUsersRepository[requester.player].DeActiveTeleportation();
return false;
}
if (OnTeleportRequested is Boolean hookResultBoolean) if (!hookResultBoolean) {
SendChat(GetLang("ACCESS_CANCELL_TELEPORTATION", player.UserIDString), player, true);
localUsersRepository[requester.player].DeActiveTeleportation();
return false;
}
}
requester.isAccepted = true;
if (config.teleportationController.teleportSetting.suggetionAcceptedUI) DestroyUI(player, InterfaceBuilder.IQ_TELEPORT_UI_TELEPORT);
Int32 teleportationCountdown = config.teleportationController.teleportCountdown.GetCount(requester.player);
Coroutine routineTeleportation = ServerMgr.Instance.StartCoroutine(ProcessTTarget(requester.player, player, teleportationCountdown));
localUsersRepository[requester.player].ActiveCoroutineController(routineTeleportation);
casheTeleportationLast[player] = requester.player;
String autoRequestMessage = isAutoAccept ? "CAN_REQUEST_TELEPORTATION_ACCESS_AUTO_TELEPORT" : "CAN_REQUEST_TELEPORTATION_ACCESS";
LogAction(player, TypeLog.AcceptTeleportation, requester.player, default, default);
SendChat(GetLang(autoRequestMessage, player.UserIDString, requester.player.displayName), player);
SendChat(GetLang("REQUEST_TELEPORTATION_ACCESS", requester.player.UserIDString, FormatTime(teleportationCountdown, requester.player.UserIDString)), requester.player);
Interface.Call("OnTeleportAccepted", player, requester.player, teleportationCountdown);
return true;
}
private const String permissionWarpAdmin = "iqteleportation.warpadmin";
[ChatCommand("tp")]
private void TpChatCMD(BasePlayer player, String cmd, String[] arg) {
if (player == null) return;
if (!player.IsAdmin && !permission.UserHasPermission(player.UserIDString, permissionTP)) return;
if (arg.Length == 0 && !casheTeleportationLast.ContainsKey(player)) {
SendChat(GetLang("SYNTAX_COMMAND_TELEPORT", player.UserIDString), player, true);
return;
}
String nameOrIDTarget = arg[0];
(BasePlayer, String) findPlayer = FindPlayerNameOrID(player, nameOrIDTarget);
BasePlayer targetPlayer = null;
if(!String.IsNullOrWhiteSpace(nameOrIDTarget)) targetPlayer = findPlayer.Item1;
String nameOrIDOnPlayer = String.Empty;
BasePlayer onPlayer = null;
if (arg.Length >= 2) {
nameOrIDOnPlayer = arg[1];
(BasePlayer, String) findOnPlayer = FindPlayerNameOrID(player, nameOrIDOnPlayer);
if (!String.IsNullOrWhiteSpace(nameOrIDOnPlayer)) {
onPlayer = targetPlayer;
targetPlayer = findOnPlayer.Item1;
}
if (onPlayer == null) {
SendChat(findOnPlayer.Item2 ?? GetLang("CAN_TELEPORT_PLAYER_NOT_FOUND_TP_ONE_PLAYER", player.UserIDString), player, true);
return;
}
if (targetPlayer == null) {
SendChat(findPlayer.Item2 ?? GetLang("CAN_TELEPORT_PLAYER_NOT_FOUND_TP_TARGET_PLAYER_ONE", player.UserIDString, nameOrIDTarget), player, true);
return;
}
}
else onPlayer = player;
if (targetPlayer == null) {
SendChat(findPlayer.Item2 ?? GetLang("CAN_TELEPORT_PLAYER_NOT_FOUND_TP_TARGET_PLAYER", player.UserIDString), player, true);
return;
}
MovePlayer(onPlayer, targetPlayer.transform.position);
SendChat(GetLang("CAN_TELEPORT_PLAYER_ACCES_TP", onPlayer.UserIDString, targetPlayer.displayName), onPlayer);
}
private MonumentInfo GetMonumentWherePlayerStand(BasePlayer player) {
MonumentInfo closestMonument = null;
foreach (MonumentInfo monument in localAllMonuments) {
Vector3 monumentCenter = monument.transform.TransformPoint(monument.Bounds.center);
Vector3 monumentSize = monument.transform.TransformVector(monument.Bounds.size);
Single monumentRadius = monumentSize.magnitude / 2f;
Single distanceToMonument = Vector3.Distance(player.transform.position, monumentCenter);
if (distanceToMonument <= monumentRadius) {
closestMonument = monument;
break;
}
}
return closestMonument;
}
private List<MonumentInfo> localAllMonuments = new();
private void ChatCommandWarp(BasePlayer player, String command, String[] args) {
if (!config.warpsContoller.useWarps) return;
if (!player.IsAdmin) if (!permission.UserHasPermission(player.UserIDString, permissionWarpAdmin)) return;
if (args.Length < 1) {
SendChat(GetLang("SYNTAX_COMMAND_WARPS", player.UserIDString), player, true);
return;
}
String action = args[0];
String warpName = args.Length >= 2 ? args[1].ToLower() : null;
MonumentInfo pMonument = GetMonumentWherePlayerStand(player);
Vector3 pPosition = player.transform.position;
switch (action) {
case "points" : {
if (string.IsNullOrWhiteSpace(warpName)) {
SendChat(GetLang("WARP_NOT_ARG_NAME", player.UserIDString), player, true);
return;
}
if (!serverWarps.TryGetValue(warpName, out List<ServerWarp> warpPoints)) {
SendChat(GetLang("WARP_NOTHING_NAME", player.UserIDString), player, true);
return;
}
for (Int32 indexPoint = 0; indexPoint < warpPoints.Count; indexPoint++) {
Vector3 warpPoint = warpPoints[indexPoint].GetPositionWarp();
if (warpPoint == default) return;
DrawSphereAndText(player, warpPoint, $"{indexPoint}");
}
SendChat(GetLang("WARP_SHOW_POINTS", player.UserIDString, warpName), player, true);
break;
}
case "list" : {
StringBuilder warpListBuilder = Pool.Get<StringBuilder>();
foreach (KeyValuePair<String, List<ServerWarp>> warps in serverWarps) {
warpListBuilder.AppendLine($"{warps.Key} :");
for (Int32 indexWarpPos = 0; indexWarpPos < warps.Value.Count; indexWarpPos++) {
Vector3 warpPoint = warps.Value[indexWarpPos].GetPositionWarp();
warpListBuilder.AppendLine($"{indexWarpPos} : {(warpPoint == default ? "NONE MONUMENT" : warpPoint)}");
}
warpListBuilder.AppendLine();
}
String message = warpListBuilder.ToString();
if (String.IsNullOrWhiteSpace(message)) message = GetLang("WARP_NOTHING", player.UserIDString);
SendChat(message, player);
Pool.FreeUnmanaged(ref warpListBuilder);
break;
}
case "create" : case "add" : case "set" : {
if (string.IsNullOrWhiteSpace(warpName)) {
SendChat(GetLang("WARP_NOT_ARG_NAME", player.UserIDString), player, true);
return;
}
if (serverWarps.ContainsKey(warpName)) {
for (Int32 indexPoint = 0; indexPoint < serverWarps[warpName].Count; indexPoint++) {
Vector3 warpPoint = serverWarps[warpName][indexPoint].GetPositionWarp();
if (warpPoint == default) continue;
if (Vector3.Distance(warpPoint, player.transform.position) > 5f) continue;
SendChat(GetLang("WARP_SETUP_POINTS_DISTANCE", player.UserIDString, indexPoint), player, true);
return;
}
serverWarps[warpName].Add(new ServerWarp(pMonument, pPosition));
SendChat(GetLang("WARP_SETUP_POINT_ACCESS", player.UserIDString, warpName), player);
return;
}
serverWarps.Add(warpName, new List<ServerWarp>() {
new(pMonument, pPosition)
}
);
cmd.AddChatCommand(warpName, this, nameof(ChatCommandTeleportationWarp));
cmd.AddConsoleCommand(warpName, this, nameof(ConsoleCommandTeleportationWarp));
SendChat(GetLang("WARP_SETUP_NEW", player.UserIDString, warpName, warpName.ToLower()), player);
break;
}
case "edit" : case "update" : {
if (string.IsNullOrWhiteSpace(warpName)) {
SendChat(GetLang("WARP_NOT_ARG_NAME", player.UserIDString), player, true);
return;
}
if (!serverWarps.TryGetValue(warpName, out List<ServerWarp> warpPoints)) {
SendChat(GetLang("WARP_NOTHING_NAME", player.UserIDString), player, true);
return;
}
if (args.Length < 3) {
String pointsKeys = GetWarpPoints(warpName);
SendChat(GetLang("WARP_NOTHING_KEY_POINTS", player.UserIDString, pointsKeys), player, true);
return;
}
String warpKeyString = args[2];
if (!Int32.TryParse(warpKeyString, out Int32 warpKey) || warpKey < 0) {
SendChat(GetLang("WARP_NOTHING_KEY_IS_NUMBER", player.UserIDString), player, true);
return;
}
if (warpPoints.Count < warpKey) {
String pointsKeys = GetWarpPoints(warpName);
SendChat(GetLang("WARP_REMOVED_POINT_NOTHING_KEYS", player.UserIDString, warpKey, warpName, pointsKeys), player, true);
return;
}
for (Int32 indexPoint = 0; indexPoint < serverWarps[warpName].Count; indexPoint++) {
Vector3 warpPoint = serverWarps[warpName][indexPoint].GetPositionWarp();
if(warpPoint == default) continue;
if (indexPoint == warpKey || Vector3.Distance(warpPoint, player.transform.position) > 5f) continue;
SendChat(GetLang("WARP_SETUP_POINTS_DISTANCE", player.UserIDString, indexPoint), player, true);
return;
}
serverWarps[warpName][warpKey] = new ServerWarp(pMonument, pPosition);
SendChat(GetLang("WARP_EDIT_POINT_ACCESS", player.UserIDString, warpName), player);
break;
}
case "remove" : case "delete" : {
//(IndexOutOfRangeException: Index was outside the bounds of the array.)
//warp remove jopa
if (string.IsNullOrWhiteSpace(warpName)) {
SendChat(GetLang("WARP_NOT_ARG_NAME", player.UserIDString), player, true);
return;
}
if (!serverWarps.TryGetValue(warpName, out List<ServerWarp> warpPoints)) {
SendChat(GetLang("WARP_NOTHING_NAME", player.UserIDString), player, true);
return;
}
String warpKeyString = args.Length >= 3 ? args[2] : String.Empty;
if (!String.IsNullOrWhiteSpace(warpKeyString) && warpPoints.Count > 1) {
if (!Int32.TryParse(warpKeyString, out Int32 warpKey) || warpKey < 0) {
SendChat(GetLang("WARP_NOTHING_KEY_IS_NUMBER", player.UserIDString), player, true);
return;
}
if (warpPoints.Count < warpKey) {
String pointsKeys = GetWarpPoints(warpName);
SendChat(GetLang("WARP_REMOVED_POINT_NOTHING_KEYS", player.UserIDString, warpKey, warpName, pointsKeys), player, true);
return;
}
serverWarps[warpName].RemoveAt(warpKey);
SendChat(GetLang("WARP_REMOVED_POINT", player.UserIDString, warpKey, warpName), player, true);
return;
}
serverWarps.Remove(warpName);
cmd.RemoveChatCommand(warpName, this);
cmd.RemoveConsoleCommand(warpName, this);
SendChat(GetLang("WARP_REMOVED", player.UserIDString, warpName), player);
break;
}
}
}
[ChatCommand("gmap")]
private void GMapTeleportChatCmd(BasePlayer player) => GMapTeleportTurn(player);
private const String effectSoundTimer = "assets/prefabs/weapons/mp5/effects/fire_select.prefab";
private void CheckAllHomes(BasePlayer player, String homeName = "") {
if (!playerHomes.TryGetValue(player.userID, out Dictionary<String, PlayerHome> pHome)) return;
if (!String.IsNullOrWhiteSpace(homeName)) {
if (!pHome.TryGetValue(homeName, out PlayerHome home)) return;
if (!CheckHome(player, homeName, home)) pHome.Remove(homeName);
return;
}
List<String> homesToRemove = Pool.Get<List<String>>();
foreach (KeyValuePair<String, PlayerHome> pData in pHome) {
if (!CheckHome(player, pData.Key, pHome[pData.Key])) homesToRemove.Add(pData.Key);
}
foreach (String home in homesToRemove) pHome.Remove(home);
Pool.FreeUnmanaged(ref homesToRemove);
}
private static ImageUI _imageUI;
private Boolean IsPlayerWithinBlockedMonument(BasePlayer player) {
if (config.generalController.monumentBlockedTeleportation.Count == 0) return false;
MonumentInfo monument = GetMonumentWherePlayerStand(player);
return monument && config.generalController.monumentBlockedTeleportation.Contains(monument.name);
}
private void TeleportationWarp(BasePlayer player, Vector3 position) {
if (!player.IsValid()) return;
String canTeleport = CanTeleportation(player, UserRepository.TeleportType.Warp);
if (!String.IsNullOrWhiteSpace(canTeleport)) {
SendChat(canTeleport, player, true);
return;
}
localUsersRepository[player].SetupCooldown(player, UserRepository.TeleportType.Warp);
MovePlayer(player, position);
SendChat(GetLang("WARP_TELEPORTATION_PLAYER", player.UserIDString), player);
}
private Dictionary<String, List<String>> cachedUI = new();
private void AutoClearData(Boolean isNewSave = false) {
Int32 settingClear = default;
List<UInt64> keysPlayersSetting = Pool.Get<List<UInt64>>();
keysPlayersSetting.AddRange(playerSettings.Keys);
DateTime currentDate = DateTime.Now;
foreach (UInt64 keyPlayer in keysPlayersSetting) {
SettingPlayer playerSetting = playerSettings[keyPlayer];
Int32 leftDays = (currentDate - playerSetting.firstConnection).Days;
if (leftDays < 7) continue;
playerSettings.Remove(keyPlayer);
settingClear++;
}
Pool.FreeUnmanaged(ref keysPlayersSetting);
if(settingClear != default) Puts(LanguageEn ? $"Automatic cleaning of user settings.{settingClear} users and their settings were deleted due to absence from the server for more than 7 days" : $"Автоматическая очистка настроек пользоваталей.Было удалено {settingClear} пользователей и их настройки из-за отсутствия более 7 дней на сервере");
if (isNewSave) {
playerHomes.Clear();
List<String> keysToRemove = new List<String>();
foreach (KeyValuePair<String, List<ServerWarp>> warps in serverWarps) {
List<ServerWarp> warpsToRemove = new List<ServerWarp>();
foreach (ServerWarp warp in warps.Value) {
if (String.IsNullOrWhiteSpace(warp.monumentParent)) warpsToRemove.Add(warp);
}
foreach (ServerWarp warp in warpsToRemove) warps.Value.Remove(warp);
if (warps.Value.Count == 0) keysToRemove.Add(warps.Key);
warpsToRemove.Clear();
warpsToRemove = null;
}
foreach (String key in keysToRemove) {
cmd.RemoveChatCommand(key, this);
cmd.RemoveConsoleCommand(key, this);
serverWarps.Remove(key);
}
keysToRemove.Clear();
keysToRemove = null;
}
WriteData();
}
private Boolean CheckHome(BasePlayer player, String homeName, PlayerHome pHome) {
if (pHome.netIdEntity != 0) {
if (tugboatsServer.TryGetValue(pHome.netIdEntity, out Tugboat tugboat) && tugboat && !tugboat.IsDestroyed) return true;
SendChat(GetLang("CAN_TELEPORT_HOME_NOT_TUGBOAT", player.UserIDString, homeName), player);
return false;
}
BuildingBlock buildingBlock = GetBuildingBlock(pHome.positionHome);
if (!buildingBlock) {
SendChat(GetLang("CAN_TELEPORT_HOME_NOT_BUILDING_BLOCK", player.UserIDString, homeName), player);
return false;
}
if (!config.homeController.setupHomeController.onlyBuildingAuth) return true;
BuildingPrivlidge privilege = buildingBlock.GetBuildingPrivilege();
if (privilege == null || privilege.IsAuthed(player)) return true;
SendChat(GetLang("CAN_TELEPORT_HOME_NOT_AUTH_BUILDING_PRIVILAGE", player.UserIDString, homeName), player);
return false;
}
[ConsoleCommand("homelist")]
private void ConsoleCommand_HomeList(ConsoleSystem.Arg arg) {
BasePlayer player = arg.Player();
if (player == null) return;
Dictionary<String, Vector3> homeList = GetHomes(player.userID);
if (homeList == null || homeList.Count == 0) {
SendChat(GetLang("HOMELIST_COMMAND_EMPTY", player.UserIDString), player);
return;
}
String homesPlayerOnCord = String.Empty;
foreach (KeyValuePair<String, Vector3> homeInfo in homeList) {
String cordMap = MapHelper.PositionToString(homeInfo.Value);
homesPlayerOnCord += GetLang("HOMELIST_COMMAND_FORTMAT_HOME", player.UserIDString, homeInfo.Key, cordMap);
}
SendChat(GetLang("HOMELIST_COMMAND_ALL_LIST", player.UserIDString, homesPlayerOnCord), player);
}
private void OnServerInitialized() {
RegisteredPermissions();
if(config.teleportationController.teleportSetting.suggetionAcceptedUI || config.homeController.suggetionSetHomeAfterInstallBed) {
_imageUI = new ImageUI();
_imageUI.DownloadImage();
}
AutoClearData();
if (config.generalController.monumentBlockedTeleportation.Count != 0 || config.warpsContoller.useWarps) ParseMonuments();
if (config.homeController.setupHomeController.canSetupTugboatHome) ParseTugboats();
foreach (BasePlayer player in BasePlayer.activePlayerList) OnPlayerConnected(player);
ValidateWarps();
timerCheckHomes = timer.Every(300, () => {
List<BasePlayer> players = Pool.Get<List<BasePlayer>>();
players.AddRange(BasePlayer.activePlayerList);
for (Int32 i = 0; i < players.Count; i++) {
BasePlayer player = players[i];
if (player == null || !player.IsConnected) continue;
CheckAllHomes(player);
}
Pool.FreeUnmanaged(ref players);
}
);
}
protected override void SaveConfig() => Config.WriteObject(config);
void OnPlayerDisconnected(BasePlayer player, String reason) => DestroyPing(player);
private const String tpaLog = LanguageEn ? "" : "принял запрос на телепортацию от";
private Single GetGroundPosition(in Vector3 pos) {
Single y = TerrainMeta.HeightMap.GetHeight(pos);
return Physics.Raycast(new Vector3(pos.x, pos.y + 200f, pos.z), Vector3.down, out RaycastHit hitInfo, float.MaxValue, (Rust.Layers.Mask.Vehicle_Large | Rust.Layers.Solid | Rust.Layers.Mask.Water)) ? Mathf.Max(hitInfo.point.y, y) : y;
}
[ConsoleCommand("sh")]
private void SetHomeShortConsoleCMD(ConsoleSystem.Arg arg) => SetHomeConsoleCMD(arg);
private (BasePlayer, String) FindPlayerNameOrID(BasePlayer finder, String nameOrID, Boolean findSleeper = false) {
List<BasePlayer> players = Pool.Get<List<BasePlayer>>();
players.AddRange(findSleeper ? BasePlayer.allPlayerList : BasePlayer.activePlayerList);
if (nameOrID.IsSteamId() && ulong.TryParse(nameOrID, out UInt64 userID)) {
BasePlayer player = BasePlayer.FindByID(userID);
Pool.FreeUnmanaged(ref players);
return (player, null);
}
List<BasePlayer> matchingPlayers = Pool.Get<List<BasePlayer>>();
try {
matchingPlayers.AddRange(players.Where(player => player.displayName != null && player.displayName.IndexOf(nameOrID, StringComparison.OrdinalIgnoreCase) >= 0));
switch (matchingPlayers.Count) {
case 1 : {
BasePlayer foundPlayer = matchingPlayers[0];
return (foundPlayer, null);
}
case > 1 : {
String nicknameList = String.Join(", ", matchingPlayers.Take(3).Select(p => p.displayName));
return (null, GetLang("FIND_PLAYER_INFO_MATCHES", finder.UserIDString, nameOrID, nicknameList));
}
default : return (null, null);
}
}
finally {
Pool.FreeUnmanaged(ref players);
Pool.FreeUnmanaged(ref matchingPlayers);
}
}
private void RunEffect(BasePlayer player, String effectPath) {
if (!config.generalController.useSoundEffects) return;
Effect effect = new Effect(effectPath, player, 0, new Vector3(), new Vector3());
EffectNetwork.Send(effect, player.Connection);
}
private static Double CurrentTime => Facepunch.Math.Epoch.Current;
private String CanRequestTeleportation(BasePlayer player, BasePlayer targetPlayer, String error = "") {
if (!targetPlayer) return error ?? GetLang("CAN_REQUEST_TELEPORTATION_NOT_FOUND_PLAYER", player.UserIDString);
// if (player.userID == targetPlayer.userID)
// return GetLang("CAN_REQUEST_TELEPORTATION_NOTHING_TELEPORT_ME", player.UserIDString);
if (playerTeleportationQueue.ContainsKey(player.userID)) return playerTeleportationQueue[player.userID].player ? GetLang("CAN_REQUEST_TELEPORTATION_TELEPORTED_REQUEST_ACTUALY_NAME", player.UserIDString, playerTeleportationQueue[player.userID].player.displayName) : GetLang("CAN_REQUEST_TELEPORTATION_TELEPORTED_REQUEST_ACTUALY", player.UserIDString);
if (playerTeleportationQueue.ContainsKey(targetPlayer.userID)) return GetLang("CAN_REQUEST_TELEPORTATION_ALREADY_REQUEST_TARGET", player.UserIDString);
String canTeleport = CanTeleportation(player, UserRepository.TeleportType.Teleportation);
if (!String.IsNullOrWhiteSpace(canTeleport)) return canTeleport;
if (config.teleportationController.teleportSetting.onlyTeleportationFriends && !IsFriends(player, targetPlayer.userID)) return GetLang("CAN_REQUEST_TELEPORTATION_ONLY_REQUEST_FRIENDS", player.UserIDString);
return String.Empty;
}
private Object OnMapMarkerAdd(BasePlayer player, MapNote note) {
if (player == null || note == null) return null;
Vector3 positionTeleportation = note.worldPosition;
positionTeleportation.y = GetGroundPosition(positionTeleportation);
if (config.teleportationController.teleportSetting.useGMapTeleport) {
RelationshipManager.PlayerTeam teams = player.Team;
if (teams != null) {
foreach (UInt64 teamsMember in teams.members) {
if (teamsMember == player.userID) continue;
BasePlayer teamPlayer = BasePlayer.FindByID(teamsMember);
if (teamPlayer == null) continue;
if (Vector3.Distance(positionTeleportation, teamPlayer.transform.position) < 30f) {
RequestTeleportation(player, new [] {
teamPlayer.UserIDString
}
);
return false;
}
}
}
}
if (config.teleportationController.teleportSetting.useGMapTeleportAdmin) {
if (playerSettings[player.userID].useTeleportGMap && (player.IsAdmin || permission.UserHasPermission(player.UserIDString, permissionGMapTeleport))) {
MovePlayer(player, positionTeleportation);
return false;
}
}
return null;
}
[ChatCommand("sh")]
private void SetHomeShortChatCMD(BasePlayer player, String cmd, String[] arg) => SetHomeChatCMD(player, cmd, arg);
private Dictionary<String, Vector3> GetHomes(UInt64 userID) {
Dictionary<String, Vector3> homeList = new();
if (!playerHomes.TryGetValue(userID, out Dictionary<String, PlayerHome> home)) return homeList;
foreach (KeyValuePair<String, PlayerHome> pHome in home) {
Vector3 positionHome = default;
if (pHome.Value.netIdEntity != 0) {
if (tugboatsServer.TryGetValue(pHome.Value.netIdEntity, out Tugboat tugboat) && tugboat && !tugboat.IsDestroyed) positionHome = tugboat.transform.TransformPoint(pHome.Value.positionHome);
}
else positionHome = pHome.Value.positionHome;
if (positionHome == default) continue;
homeList.TryAdd(pHome.Key, positionHome);
}
return homeList;
}
protected override void LoadConfig() {
base.LoadConfig();
try {
config = Config.ReadObject<Configuration>();
if (config == null) LoadDefaultConfig();
}
catch {
PrintWarning(LanguageEn ? $"Error reading #321562 configuration 'oxide/config/{Name}', creating a new configuration!!" : $"Ошибка чтения #3212 конфигурации 'oxide/config/{Name}', создаём новую конфигурацию!!");
LoadDefaultConfig();
}
NextTick(SaveConfig);
}
private Dictionary<String, List<ServerWarp>> serverWarps = new();
private void AutoTeleportTurn(BasePlayer player) {
if (!playerSettings.TryGetValue(player.userID, out SettingPlayer setting)) return;
setting.autoAcceptTeleportationFriends = !setting.autoAcceptTeleportationFriends;
String message = setting.autoAcceptTeleportationFriends ? GetLang("AUTO_ACCEPT_TELEPORTATION_FRIEND_TRUE", player.UserIDString) : GetLang("AUTO_ACCEPT_TELEPORTATION_FRIEND_FALSE", player.UserIDString);
SendChat(message, player);
}
private MonumentInfo GetMonumentInName(String nameMonument) {
if (String.IsNullOrWhiteSpace(nameMonument)) return null;
foreach (MonumentInfo monument in localAllMonuments) {
if (monument.name.Equals(nameMonument)) return monument;
}
return null;
}
private void OnEntityKill(Tugboat tugboat) {
if (tugboat == null) return;
UInt64 netIDTugBoat = tugboat.net.ID.Value;
if (tugboatsServer.ContainsKey(netIDTugBoat)) tugboatsServer.Remove(netIDTugBoat);
}
private void LogAction(BasePlayer player, TypeLog typeLog, BasePlayer targetPlayer = default, Vector3 position = default, String homeName = default) {
if (!config.generalController.useLogged) return;
String typeAction = typeLog switch {
TypeLog.RequestTeleportation => $"{player.displayName}({player.userID}) {tprLog} {targetPlayer.displayName}({targetPlayer.userID})", TypeLog.AcceptTeleportation => $"{player.displayName}({player.userID}) {tpaLog} {targetPlayer.displayName}({targetPlayer.userID})", TypeLog.RequestHomeTeleportation => $"{player.displayName}({player.userID}) {homeLog} `{homeName}` ({position})", _ => ""
}
;
LogToFile("IQTeleportation", typeAction, _, true, true);
}
private IEnumerator ProcessTTarget(BasePlayer player, BasePlayer targetPlayer, Int32 timeTeleportation) {
Vector3 teleportationPosition = config.teleportationController.teleportSetting.teleportPosInAccept ? targetPlayer.transform.position : default;
return ProcessTeleportation(player, () => {
if (!targetPlayer) {
ClearQueue(player, targetPlayer);
SendChat(GetLang("ACCESS_CANCELL_TELEPORTATION", player.UserIDString, $"{GetLang("ACCESS_CANCELL_TELEPORTATION_DEAD_TARGET_DISCONNECTED", player.UserIDString)}"), player);
return true;
}
if (!targetPlayer.IsDead()) return false;
ClearQueue(player, targetPlayer);
SendChat(GetLang("ACCESS_CANCELL_TELEPORTATION", targetPlayer.UserIDString, $"{GetLang("ACCESS_CANCELL_TELEPORTATION_DEAD", targetPlayer.UserIDString)}"), targetPlayer);
SendChat(GetLang("ACCESS_CANCELL_TELEPORTATION", player.UserIDString, $"{GetLang("ACCESS_CANCELL_TELEPORTATION_DEAD_TARGET", player.UserIDString)}"), player);
return true;
}
, () => TeleportationPlayer(player, targetPlayer, teleportationPosition), timeTeleportation, targetPlayer );
}
private const Single radiusCheckLayerHome = 2f;
private void DestroyPing(BasePlayer player) {
if (!player) return;
if (!playerPings.TryGetValue(player, out MapNote note)) return;
if (note == null) return;
player.State.pings.Remove(note);
player.DirtyPlayerState();
player.SendPingsToClient();
player.TeamUpdate(true);
playerPings?.Remove(player);
}
private static void AddUI(BasePlayer player, String json) => CommunityEntity.ServerInstance.ClientRPC<String>(RpcTarget.Player("AddUI", player.net.connection), json);
private void CreateMapMarkerPlayer(BasePlayer player, Vector3 position, String homeName) {
if (player.State?.pointsOfInterest == null) player.State.pointsOfInterest = new List<MapNote>();
if (player.State.pointsOfInterest.Count >= ConVar.Server.maximumMapMarkers) return;
MapNote note = Pool.Get<MapNote>();
note.worldPosition = position;
note.isPing = false;
note.colourIndex = 2;
note.icon = 2;
note.noteType = 1;
note.label = homeName;
player.State.pointsOfInterest.Add(note);
player.DirtyPlayerState();
player.TeamUpdate();
using MapNoteList mapNoteList = Pool.Get<MapNoteList>();
mapNoteList.notes = Pool.Get<List<MapNote>>();
if (player.ServerCurrentDeathNote != null) mapNoteList.notes.Add(player.ServerCurrentDeathNote);
if (player.State.pointsOfInterest != null) mapNoteList.notes.AddRange(player.State.pointsOfInterest);
player.ClientRPC(RpcTarget.Player("Client_ReceiveMarkers", player), mapNoteList);
mapNoteList.notes.Clear();
Pool.FreeUnmanaged(ref mapNoteList.notes);
}
/// <summary>
/// - Корректировка очистки списка установленных спальников игроков, для оптимизации
/// - Исправление к обновлению игры
/// - Исправлена некорректный выбор времени полета к игроку с привилегией, бралось время привилегии того к кому телепортируется игрока, а не того кто телепортируется
/// </summary>
private Timer timerCheckHomes = null;
private Dictionary<BasePlayer, UserRepository> localUsersRepository = new();
private void Unload() {
WriteData();
InterfaceBuilder.DestroyAll();
if (_imageUI != null) {
_imageUI.UnloadImages();
_imageUI = null;
}
if (cachedUI != null) {
cachedUI.Clear();
cachedUI = null;
}
if (timerCheckHomes != null || !timerCheckHomes.Destroyed) {
timerCheckHomes.Destroy();
timerCheckHomes = null;
}
if (bagInstalled != null && bagInstalled.Count != 0) {
bagInstalled.Clear();
bagInstalled = null;
}
if (config.homeController.addedPingMarker) {
if (playerPings != null) {
// ... [Code preview truncated due to length. Full source in attached file] ...