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

FREE Teleportation : 1.1.4 1.1.4

Нет прав для скачивания
C#:
using Oxide.Core;
using Oxide.Core.Plugins;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using ConVar;
using Newtonsoft.Json;
using Oxide.Core.Libraries.Covalence;
using Oxide.Game.Rust.Cui;
using Rust;
using UnityEngine;
using VLB;
using Color = UnityEngine.Color;
using Physics = UnityEngine.Physics;
using Time = UnityEngine.Time;
namespace Oxide.Plugins {
    [Info("Teleportation", "BadMandarin", "1.1.4")]
    [Description("Teleportation")]
    class Teleportation : RustPlugin {
#region Classes
        private class ParentPosition {
            public static Vector3 GetOffsetPosition(Transform parent, Vector3 child) {
                return parent.InverseTransformPoint(child);
            }
            public static Vector3 GetFinalPosition(Transform parent, Vector3 offset) {
                return parent.TransformPoint(offset);
            }
        }
        if (time.Days == 0) {
            if (time.Seconds != 0 && b < maxSubstr) {
                if (!string.IsNullOrEmpty(result)) result += " ";
                result += $"{Format(time.Seconds, "s", "s", "s")}";
                b++;
            }
        }
        break;
    }
    return result;
}
private static string Format(int units, string form1, string form2, string form3) {
    var tmp = units % 10;
    if (units >= 5 && units <= 20 || tmp >= 5 && tmp <= 9) return $"{units}{form1}";
    if (tmp >= 2 && tmp <= 4) return $"{units}{form2}";
    return $"{units}{form3}";
}
private static DateTime Epoch = new DateTime(1970, 1, 1);
public static double GetTimeStamp() {
    return DateTime.Now.Subtract(Epoch).TotalSeconds;
}
}
private static class PlayerHelper {
    private static bool FindPlayerPredicate(BasePlayer player, string nameOrUserId) {
        return player.displayName.IndexOf(nameOrUserId, StringComparison.OrdinalIgnoreCase) != -1 || player.UserIDString == nameOrUserId;
    }
    public static bool Find(string nameOrUserId, out BasePlayer target) {
        nameOrUserId = nameOrUserId.ToLower();
        foreach (BasePlayer activePlayer in BasePlayer.activePlayerList) {
            if (FindPlayerPredicate(activePlayer, nameOrUserId)) {
                target = activePlayer;
                return true;
            }
        }
        foreach (BasePlayer sleepingPlayer in BasePlayer.sleepingPlayerList) {
            if (FindPlayerPredicate(sleepingPlayer, nameOrUserId)) {
                target = sleepingPlayer;
                return true;
            }
        }
        target = (BasePlayer) null;
        return false;
    }
    public static bool FindOnlineMultiple(string nameOrUserId, BasePlayer player, out BasePlayer target) {
        if (nameOrUserId == string.Empty) {
            _plugin.SendMessage(player, "PLAYER.NOT.FOUND");
            target = (BasePlayer) null;
            return false;
        }
        List<BasePlayer> activePlayers = new List<BasePlayer>();
        nameOrUserId = nameOrUserId.ToLower();
        foreach (BasePlayer activePlayer in BasePlayer.activePlayerList) {
            if (FindPlayerPredicate(activePlayer, nameOrUserId)) {
                activePlayers.Add(activePlayer);
            }
        }
        switch (activePlayers.Count) {
            case 0 : _plugin.SendMessage(player, $"PLAYER.NOT.FOUND.PARAM", nameOrUserId);
            target = null;
            return false;
            case 1 : target = activePlayers[0];
            return true;
            default : var text = "";
            foreach (var activePlayer in activePlayers) {
                text += $" {activePlayer.displayName},";
            }
            _plugin.SendMessage(player, "PLAYER.FIND.MULTIPLE");
            target = null;
            return false;
        }
    }
    public static bool FindOnlineAndOfflineMultiple(string nameOrUserId, BasePlayer player, out BasePlayer target) {
        if (nameOrUserId == string.Empty) {
            _plugin.SendMessage(player, "PLAYER.NOT.FOUND");
            target = (BasePlayer) null;
            return false;
        }
        List<BasePlayer> activePlayers = new List<BasePlayer>();
        nameOrUserId = nameOrUserId.ToLower();
        foreach (BasePlayer activePlayer in BasePlayer.activePlayerList) {
            if (FindPlayerPredicate(activePlayer, nameOrUserId)) {
                activePlayers.Add(activePlayer);
            }
        }
        foreach (BasePlayer activePlayer in BasePlayer.sleepingPlayerList) {
            if (FindPlayerPredicate(activePlayer, nameOrUserId)) {
                activePlayers.Add(activePlayer);
            }
        }
        switch (activePlayers.Count) {
            case 0 : _plugin.SendMessage(player, $"PLAYER.NOT.FOUND.PARAM", nameOrUserId);
            target = null;
            return false;
            case 1 : target = activePlayers[0];
            return true;
            default : var text = "";
            foreach (var activePlayer in activePlayers) {
                text += $" {activePlayer.displayName},";
            }
            _plugin.SendMessage(player, "PLAYER.FIND.MULTIPLE");
            target = null;
            return false;
        }
    }
    public static bool FindOnline(string nameOrUserId, out BasePlayer target) {
        if (nameOrUserId == string.Empty) {
            target = (BasePlayer) null;
            return false;
        }
        nameOrUserId = nameOrUserId.ToLower();
        foreach (BasePlayer activePlayer in BasePlayer.activePlayerList) {
            if (FindPlayerPredicate(activePlayer, nameOrUserId)) {
                target = activePlayer;
                return true;
            }
        }
        target = (BasePlayer) null;
        return false;
    }
}
public class Request {
    public bool IsHome = false;
    public SettingMonument.AvailableMonument Monument;
    public BasePlayer Target = null;
    public BasePlayer Player = null;
    public Vector3 Position = Vector3.zero;
    public RealTimeSince RequestTimeout = 0;
    public bool RequestConfirmed = false;
    public Request(BasePlayer player, bool isHome, Vector3 position = default(Vector3), BasePlayer target = null, SettingMonument.AvailableMonument monument = null) {
        this.IsHome = isHome;
        this.Monument = monument;
        this.Target = target;
        this.Player = player;
        this.Position = position;
    }
}
#endregion
#region Variables
[PluginReference]
private Plugin IQChat, ImageLibrary, Friends, Clans;
private const string TeleportImage = "https://i.imgur.com/kTyCOMy.png";
private static Teleportation _plugin;
private const string Layer = "UI.Teleportation";
private const string LayerBlur = "UI.Teleportation.Layer";
private const string LayerNotification = "UI.Teleportation.Notification";
private const string AdminPermission = "teleportation.admin";
private const string EffectPrefab = "assets/prefabs/locks/keypad/effects/lock.code.denied.prefab";
private readonly int triggerLayer = LayerMask.GetMask("Trigger");
private readonly int groundLayer = LayerMask.GetMask("Terrain", "World");
private readonly int buildingLayer = LayerMask.GetMask("Terrain", "World", "Construction", "Deployed");
private readonly int blockLayer = LayerMask.GetMask("Construction");
private readonly int deployedLayer = LayerMask.GetMask("Deployed");
#endregion
#region OxideHooks
void OnServerInitialized() {
    _plugin = this;
    PluginData.LoadData();
    StartPluginLoad();
}
void OnNewSave(string fileName) {
    if (_config.AutoWipe) {
        PrintWarning("Wipe detected! wiping data file...");
        _data.PlayersData = new Dictionary<ulong, PlayerData>();
        PluginData.SaveData();
    }
}
void OnServerSave() {
    PluginData.SaveData();
}
void Unload() {
    PluginData.SaveData();
    for (var i = 0; i < MarkerBag.MarkerBags.Count; i++) UnityEngine.Object.Destroy(MarkerBag.MarkerBags[i]);
    for (var i = 0; i < TeleportMgr.ManagersList.Count; i++) UnityEngine.Object.Destroy(TeleportMgr.ManagersList[i]);
    for (var i = 0; i < _config.SettingsMonument.AvailableMonuments.Count; i++) {
        var monument = _config.SettingsMonument.AvailableMonuments[i];
        if(monument.CreatedBag != null) monument.CreatedBag.Kill();
    }
}
void OnPlayerConnected(BasePlayer player) {
    if (player == null) return;
    if (player.HasPlayerFlag(BasePlayer.PlayerFlags.ReceivingSnapshot)) {
        timer.Once(2f, () => OnPlayerConnected(player));
        return;
    }
    if (!player.IsConnected) return;
    player.GetOrAddComponent<TeleportMgr>();
}
object CanRenameBed(BasePlayer player, SleepingBag bed, string bedName) {
    if (_config.SettingsMonument.AvailableMonuments.Exists(x => x.CreatedBag != null && x.CreatedBag == bed)) return false;
    return null;
}
object OnSleepingBagValidCheck(SleepingBag bag, ulong targetPlayerID, bool ignoreTimers) {
    if (_config.SettingsMonument.AvailableMonuments.Exists(x => x.CreatedBag != null && x.CreatedBag == bag)) {
        var player = BasePlayer.FindByID(targetPlayerID);
        if (player != null && player.IsHostile()) return false;
        return true;
    }
    return null;
}
#endregion
#region Commands
#region ConsoleCommands
[ConsoleCommand("home")]
void ConsoleCmdHome(ConsoleSystem.Arg arg) {
    var player = arg.Player();
    if (player == null) return;
    if (arg.HasArgs() == false) return;
    ChatCommandHome(player, "", arg.Args);
}
[ConsoleCommand("tpc")]
void ConsoleCmdTpc(ConsoleSystem.Arg arg) {
    var player = arg.Player();
    if (player == null) return;
    if (arg.HasArgs() == false) return;
    ChatCommandTpc(player, "", arg.Args);
}
[ConsoleCommand("tp")]
void ConsoleCmdTp(ConsoleSystem.Arg arg) {
    var player = arg.Player();
    if (player == null) return;
    if (arg.HasArgs() == false) return;
    ChatCommandTp(player, "", arg.Args);
}
[ConsoleCommand("tpa")]
void ConsoleCmdTpa(ConsoleSystem.Arg arg) {
    var player = arg.Player();
    if (player == null) return;
    if (arg.HasArgs() == false) return;
    ChatCommandTpa(player, "", arg.Args);
}
[ConsoleCommand("tpr")]
void ConsoleCmdTpr(ConsoleSystem.Arg arg) {
    var player = arg.Player();
    if (player == null) return;
    if (arg.HasArgs() == false) return;
    ChatCommandTpr(player, "", arg.Args);
}
[ConsoleCommand("tpm")]
void ConsoleCmdTpm(ConsoleSystem.Arg arg) {
    var player = arg.Player();
    if (player == null) return;
    if (arg.HasArgs() == false) return;
    ChatCommandTpMonument(player, "", arg.Args);
}
#endregion
[ChatCommand("atp")]
private void ChatCommandAtp(BasePlayer player, string command, string[] args) {
    var data = PluginData.GetForPlayer(player.userID);
    if (data == null) return;
    data.AutoAccept = !data.AutoAccept;
    SendMessage(player, "ATP.MODE", GetMessage(player, data.AutoAccept ? "ENABLED" : "DISABLED"));
}
[ChatCommand("tpc")]
private void ChatCommandTpc(BasePlayer player, string command, string[] args) {
    var teleportMgr = TeleportMgr.GetManager(player);
    if (teleportMgr == null) return;
    if (teleportMgr.Request != null) {
        if (teleportMgr.Request.IsHome) {
            teleportMgr.CancelTeleport();
            SendMessage(player, "HOME.PLAYER.CANCEL");
            return;
        }
        if (teleportMgr.Request.Monument != null) {
            teleportMgr.CancelTeleport();
            return;
        }
        if (teleportMgr.Request.Target != null) {
            //var objTarget = TeleportMgr.GetManager(teleportMgr.Request.Target);
            SendMessage(teleportMgr.Request.Target, "TPR.TARGET.CANCEL", player.displayName);
            //objTarget.CancelTeleport();
        }
        SendMessage(player, "TPR.PLAYER.CANCEL", teleportMgr.Request.Target.displayName);
        teleportMgr.CancelTeleport();
        return;
    }
    var pendingRequest = teleportMgr.IncomingRequests.FirstOrDefault();
    if (pendingRequest != null) {
        if (pendingRequest.Player != null) {
            var objTarget = TeleportMgr.GetManager(pendingRequest.Player);
            SendMessage(player, "TPR.PLAYER.CANCEL", pendingRequest.Player.displayName);
            SendMessage(pendingRequest.Player, "TPR.TARGET.CANCEL", player.displayName);
            objTarget.CancelTeleport();
        }
        //teleportMgr.IncomingRequests.Remove(pendingRequest);
        //teleportMgr.CancelTeleport();
        return;
    }
}
[ChatCommand("tp")]
private void ChatCommandTp(BasePlayer player, string command, string[] args) {
    if(player.IsAdmin == false && permission.UserHasPermission(player.UserIDString, AdminPermission) == false) return;
    switch (args.Length) {
        case 0 : break;
        case 1 : string name = args[0];
        BasePlayer target = null;
        if(!PlayerHelper.FindOnlineAndOfflineMultiple(name, player, out target)) {
            return;
        }
        if (target == null) {
            Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
            SendMessage(player, "PLAYER.NOT.FOUND");
            return;
        }
        Teleport(player, target);
        break;
        case 2 : string name1 = args[0];
        string name2 = args[1];
        BasePlayer target1 = null;
        if(!PlayerHelper.FindOnlineAndOfflineMultiple(name1, player, out target1)) {
            return;
        }
        BasePlayer target2 = null;
        if(!PlayerHelper.FindOnlineAndOfflineMultiple(name2, player, out target2)) {
            return;
        }
        if (target1 == null || target2 == null) {
            SendMessage(player, "PLAYER.NOT.FOUND");
            return;
        }
        Teleport(target1, target2);
        break;
        case 3 : float x = float.Parse(args[0]);
        float y = float.Parse(args[1]);
        float z = float.Parse(args[2]);
        Teleport(player, x, y, z);
        break;
    }
}
[ChatCommand("tphome")]
private void ChatCommandTpHome(BasePlayer player, string command, string[] args) {
    if(player.IsAdmin == false && permission.UserHasPermission(player.UserIDString, AdminPermission) == false) return;
    string name = args[0];
    BasePlayer target = null;
    PlayerData data = null;
    switch (args.Length) {
        case 1 : if(!PlayerHelper.FindOnlineAndOfflineMultiple(name, player, out target)) {
            return;
        }
        if (target == null) {
            Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
            SendMessage(player, "PLAYER.NOT.FOUND");
            return;
        }
        data = PluginData.GetForPlayer(target.userID);
        if (data == null) break;
        if (data.HomesList.Count < 1) {
            SendMessage(player, "TP.HOMELIST.ZERO");
            return;
        }
        string homes = "";
        for (var i = data.HomesList.Count - 1; i >= 0; i--) {
            var home = data.HomesList[i];
            homes += $"{home.HomeName}";
            if (i != 0) homes += ", ";
        }
        SendMessage(player, "TP.HOMELIST.FOUND", homes);
        break;
        case 2 : if(!PlayerHelper.FindOnlineAndOfflineMultiple(name, player, out target)) {
            return;
        }
        if (target == null) {
            Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
            SendMessage(player, "PLAYER.NOT.FOUND");
            return;
        }
        data = PluginData.GetForPlayer(target.userID);
        if (data == null) break;
        if (data.HomesList.Count < 1) {
            SendMessage(player, "TP.HOMELIST.ZERO");
            return;
        }
        var playerHome = data.HomesList.Find(x => x.HomeName.Contains(string.Join(" ", args.Skip(1))));
        if (playerHome == null) break;
        Teleport(player, playerHome.HomePos);
        break;
        case 3 : break;
    }
}
[ConsoleCommand("UI_Teleportation")]
private void ConsoleCommandTeleportation(ConsoleSystem.Arg arg) {
    var player = arg?.Connection?.player as BasePlayer;
    if (player == null) return;
    switch (arg.GetString(0)) {
        case "close" : CuiHelper.DestroyUi(player, Layer);
        CuiHelper.DestroyUi(player, LayerBlur);
        break;
    }
}
[ChatCommand("tpa")]
private void ChatCommandTpa(BasePlayer player, string command, string[] args) {
    var teleportMgr = TeleportMgr.GetManager(player);
    if (teleportMgr == null) return;
    if (teleportMgr.HasRequest()) {
        SendMessage(player, "TPA.HAVE.REQUEST");
        return;
    }
    var pendingRequest = teleportMgr.IncomingRequests.FirstOrDefault(x => x.RequestConfirmed == false);
    if (pendingRequest == null) {
        SendMessage(player, "TPA.ZERO.REQUEST");
        return;
    }
    if (pendingRequest.RequestConfirmed) {
        SendMessage(player, "TPA.REQUEST.CONFIRMED");
        return;
    }
    var pendingPlayer = pendingRequest.Player;
    var pendingTeleportMgr = TeleportMgr.GetManager(pendingPlayer);
    if (pendingTeleportMgr == null) return;
    if (player.IsWounded() && _config.SettingsResolution.CantTeleportWounded) {
        Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
        SendMessage(player, "TP.CANCEL.BLOOD.OR.WOUNDED");
        return;
    }
    if (player.metabolism.bleeding.value > _config.SettingsResolution.SettingsBleeding.NeedBleedingAmount && _config.SettingsResolution.SettingsBleeding.CantTeleportBleeding) {
        Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
        SendMessage(player, "TP.CANCEL.BLOOD.OR.WOUNDED");
        return;
    }
    if (_config.SettingsResolution.CantTeleportMounted && player.isMounted) {
        Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
        SendMessage(player, "CAN.TP.MOUNTED");
        return;
    }
    if (_config.SettingsResolution.CantTeleportParent && player.HasParent()) {
        Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
        SendMessage(player, "CAN.TP.PARENT");
        return;
    }
    if (_config.SettingsResolution.CantTeleportWater && player.IsSwimming()) {
        Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
        SendMessage(player, "CAN.TP.WATER");
        return;
    }
    if (player.IsBuildingBlocked() && _config.SettingsResolution.CantTeleportInBuild) {
        Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
        SendMessage(player, "TP.CANCEL.BUILD.DONT.AUTH");
        return;
    }
    var ret = Interface.Call("CanTeleport", player) as string;
    if (ret != null) {
        SendMessageWithoutLang(player, ret);
        return;
    }
    SendMessage(player, "TPA.PLAYER.ACCEPT", pendingPlayer.displayName);
    SendMessage(pendingPlayer, "TPA.TARGET.ACCEPT");
    CuiHelper.DestroyUi(player, LayerNotification);
    //teleportMgr.IncomingRequest = null;
    pendingTeleportMgr.AcceptRequest();
}
[ChatCommand("tpr")]
private void ChatCommandTpr(BasePlayer player, string command, string[] args) {
    if (GetTeleportTimeTpr(player.userID) <= 0) return;
    if (args.Length < 1) {
        Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
        SendMessage(player, "TPR.HELP");
        return;
    }
    var ret = Interface.Call("CanTeleport", player) as string;
    if (ret != null) {
        SendMessageWithoutLang(player, ret);
        return;
    }
    var message = CanTeleportPlayer(player);
    if (string.IsNullOrEmpty(message) == false) {
        Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
        SendMessageWithoutLang(player, message);
        return;
    }
    var data = PluginData.GetForPlayer(player.userID);
    if (data == null) return;
    if (data.CooldownTeleport >= GetCurrentTime()) {
        SendMessage(player, "TPR.COOLDOWN", TimeHelper.FormatTime(TimeSpan.FromSeconds(data.CooldownTeleport - GetCurrentTime()), language : lang.GetLanguage(player.UserIDString)));
        return;
    }
    BasePlayer target = null;
    if(!PlayerHelper.FindOnlineMultiple(string.Join(" ", args), player, out target)) {
        return;
    }
    if (target == null) return;
    if (target == player) return;
    var teleportMgr = TeleportMgr.GetManager(player);
    if (teleportMgr == null) return;
    if (teleportMgr.HasRequest()) {
        SendMessage(player, "TPR.PLAYER.CANCEL.REQUEST");
        return;
    }
    var targetTeleportMgr = TeleportMgr.GetManager(target);
    if (targetTeleportMgr == null) return;
    teleportMgr.InitRequest(target.transform.position, false, target);
    targetTeleportMgr.IncomingRequests.Add(teleportMgr.Request);
    SendMessage(player, "TPR.PLAYER.SEND", target.displayName);
    SendMessage(target, "TPR.TARGET.SEND", player.displayName);
    var targetData = PluginData.GetForPlayer(target.userID);
    if (targetData?.AutoAccept == true && IsFriend(player.userID, target.userID)) {
        ChatCommandTpa(target, "", new string[] {
            ""
        }
        );
        return;
    }
    CuiElementContainer container = new CuiElementContainer();
    container.Add(new CuiPanel {
        CursorEnabled = false, RectTransform = {
            AnchorMin = "0.5 0", AnchorMax = "0.5 0", OffsetMax = "0 0"
        }
        , Image = {
            Color = GetColor("#FFFFFF", 0.4f)
        }
    }
    , "Hud", LayerNotification);
    container.Add(new CuiElement() {
        Parent = LayerNotification, Name = LayerNotification + ".Main", Components = {
            new CuiRawImageComponent() {
                Png = GetImage(TeleportImage)
            }
            , new CuiRectTransformComponent() {
                AnchorMin = $"0 0", AnchorMax = $"1 1", OffsetMin = "-200 81", OffsetMax = "180 117.6"
            }
            ,
        }
    }
    );
    container.Add(new CuiPanel() {
        RectTransform = {
            AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "-151 81", OffsetMax = "132 117.6"
        }
        , Image = {
            Color = "0.9686275 0.9215686 0.8823529 0.13529412"
        }
    }
    , LayerNotification);
    container.Add(new CuiLabel() {
        RectTransform = {
            AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "-151 81", OffsetMax = "132 117.6"
        }
        , Text = {
            Text = GetMessage(player, "TPR.UI.REQUEST" , player.displayName), Font = "RobotoCondensed-Bold.ttf", Align = TextAnchor.MiddleCenter, FontSize = 16, Color = GetColor("#FFFFFFB2")
        }
        ,
    }
    , LayerNotification);
    container.Add(new CuiButton() {
        RectTransform = {
            AnchorMin = "0.02 0", AnchorMax = "0 1", OffsetMax = "49 0"
        }
        , Button = {
            Color = "0 0 0 0", Command = "chat.say /tpc"
        }
        , Text = {
            Text = GetMessage(player, "TPR.UI.REQUEST.NO"), Align = TextAnchor.MiddleCenter, Color = GetColor("#D12C2C"), FontSize = 16
        }
    }
    , LayerNotification + ".Main");
    container.Add(new CuiButton() {
        RectTransform = {
            AnchorMin = "0.98 0", AnchorMax = "1 1", OffsetMin = "-49 0"
        }
        , Button = {
            Color = "0 0 0 0", Command = "chat.say /tpa"
        }
        , Text = {
            Text = GetMessage(player, "TPR.UI.REQUEST.YES"), Align = TextAnchor.MiddleCenter, Color = GetColor("#C1FF9B"), FontSize = 16
        }
    }
    , LayerNotification + ".Main");
    CuiHelper.AddUi(target, container);
}
[ChatCommand("removehome")]
private void ChatCommandRemoveHome(BasePlayer player, string command, string[] args) {
    if (args.Length < 1) {
        Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
        SendMessage(player, "REMOVE.HOME.HELP");
        return;
    }
    string homeName = string.Join(" ", args);
    var data = PluginData.GetForPlayer(player.userID);
    var home = data.GetHome(homeName);
    if (home == null) {
        SendMessage(player, "REMOVE.HOME.NONE");
        return;
    }
    if (home.SleepingBagId != 0) {
        var bag = BaseNetworkable.serverEntities.Find(home.SleepingBagId);
        if (bag != null) bag.Kill();
    }
    data.HomesList.Remove(home);
    SendMessage(player, "REMOVE.HOME.SUCCESS", homeName);
}
[ChatCommand("homelist")]
private void ChatCommandHomeList(BasePlayer player, string command, string[] args) {
    var data = PluginData.GetForPlayer(player.userID);
    if (data == null) return;
    if (data.HomesList.Count < 1) {
        SendMessage(player, "HOMELIST.ZERO");
        return;
    }
    string homes = "";
    for (var i = data.HomesList.Count - 1; i >= 0; i--) {
        var home = data.HomesList[i];
        homes += $"{home.HomeName}";
        if (i != 0) homes += ", ";
    }
    SendMessage(player, "HOMELIST.FOUND", homes);
}
[ChatCommand("sethome")]
private void ChatCommandSetHome(BasePlayer player, string command, string[] args) {
    if (GetHomeLimit(player.userID) <= 0) return;
    var foundationList = GetFoundation(player.ServerPosition);
    if (foundationList == null || foundationList.Count == 0) {
        SendMessage(player, "FOUNDATION.NOT.FOUND");
        return;
    }
    var foundation = foundationList?.First();
    if (foundation == null) {
        SendMessage(player, "FOUNDATION.NOT.FOUND");
        return;
    }
    string err = CheckFoundation(player.userID, player.ServerPosition);
    if (err != null) {
        SendMessage(player, err);
        return;
    }
    err = CheckInsideBlock(player.ServerPosition);
    if (err != null) {
        SendMessage(player, err);
        return;
    }
    if (player.GetBuildingPrivilege(player.WorldSpaceBounds()) != null && !player.GetBuildingPrivilege(player.WorldSpaceBounds()).authorizedPlayers.Select(p => p.userid).Contains(player.userID)) {
        Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
        SendMessage(player, "SETHOME.CANCEL.BUILD");
        return;
    }
    if (args.Length != 1) {
        SendMessage(player, "SETHOME.HELP");
        return;
    }
    if (player.IsWounded() && _config.SettingsResolution.CantTeleportWounded || player.metabolism.bleeding.value > _config.SettingsResolution.SettingsBleeding.NeedBleedingAmount && _config.SettingsResolution.SettingsBleeding.CantTeleportBleeding) {
        SendMessage(player, "BLOOD.OR.WOUNDED");
        return;
    }
    SetHome(player, args[0]);
}
[ChatCommand("home")]
private void ChatCommandHome(BasePlayer player, string command, string[] args) {
    if (args.Length != 1) {
        Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
        SendMessage(player, "HOME.HELP");
        return;
    }
    if (GetTeleportTimeHome(player.userID) <= 0) return;
    var data = PluginData.GetForPlayer(player.userID);
    var homeName = string.Join(" ", args);
    var home = data.GetHome(homeName);
    if (home == null) {
        Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
        SendMessage(player, "HOME.NOT.FOUND.OR.REMOVED");
        return;
    }
    var foundationList = GetFoundation(home.HomePos);
    if (foundationList == null || foundationList.Count == 0) {
        SendMessage(player, "FOUNDATION.NOT.FOUND");
        return;
    }
    var ret = Interface.Call("CanTeleport", player) as string;
    if (ret != null) {
        SendMessageWithoutLang(player, ret);
        return;
    }
    if (_config.SettingsHome.EnableSleepingBags) {
        if (home.SleepingBagId == 0) {
            data.HomesList.Remove(home);
            Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
            SendMessage(player, "HOME.NOT.FOUND.BAG");
            return;
        }
        var bag = BaseNetworkable.serverEntities.Find(home.SleepingBagId);
        if (bag == null) {
            data.HomesList.Remove(home);
            Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
            SendMessage(player, "HOME.NOT.FOUND.BAG");
            return;
        }
    }
    if (data.CooldownHome > GetCurrentTime()) {
        Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
        SendMessage(player, "HOME.COOLDOWN", TimeHelper.FormatTime(TimeSpan.FromSeconds(data.CooldownHome - GetCurrentTime())));
        return;
    }
    var message = CanTeleportPlayer(player);
    if (!string.IsNullOrEmpty(message)) {
        Effect.server.Run(EffectPrefab, player, 0, Vector3.zero, Vector3.forward);
        SendMessageWithoutLang(player, message);
        return;
    }
    string err = CheckInsideBlock(home.HomePos);
    if (err != null) {
        SendMessage(player, "HOME.REMOVED.INSIDE.BLOCK", home.HomeName);
        data.HomesList.Remove(home);
        return;
    }
    var teleportMgr = TeleportMgr.GetManager(player);
    if (teleportMgr == null) return;
    if (teleportMgr.HasRequest()) {
        SendMessage(player, "TPR.PLAYER.CANCEL.REQUEST");
        return;
    }
    teleportMgr.InitRequest(home.HomePos, true);
    SendMessage(player, "HOME.TELEPORTATION", TimeHelper.FormatTime(TimeSpan.FromSeconds(GetTeleportTimeHome(player.userID)), language : lang.GetLanguage(player.UserIDString)));
}
[ChatCommand("tpm")]
private void ChatCommandTpMonument(BasePlayer player, string command, string[] args) {
    if (args.Length < 1) {
        SendMessage(player, "TPM.HELP");
        return;
    }
    switch (args[0]) {
        case "add" : {
            if (player.IsAdmin == false) break;
            var closestMonument = FindClosestMonument(player.transform.position);
            if (closestMonument == null) {
                SendMessage(player, "TPM.ADMIN.CLOSEST.NOT.FOUND");
                break;
            }
            var monumentInfo = _config.SettingsMonument.AvailableMonuments.Find(x => closestMonument.name.Contains(x.ShortPrefabName));
            if (monumentInfo != null) {
                SendMessage(player, "TPM.ADMIN.EXISTS");
                break;
            }
            Vector3 positionOffset = ParentPosition.GetOffsetPosition(closestMonument.transform, player.transform.position);
            string name = GetShortMonumentName(closestMonument.name);
            SleepingBag bag = null;
            if (_config.SettingsMonument.EnableSleepingBags) {
                bag = CreateSleepingBag(null, ParentPosition.GetFinalPosition(closestMonument.transform, positionOffset) - new Vector3(0, 100f, 0), name);
                bag.SetPublic(false);
                bag.OwnerID = 0;
                bag.deployerUserID = 0;
                bag.spawnOffset += new Vector3(0, 100f, 0);
                bag.unlockTime = Time.realtimeSinceStartup + 30f;
                bag.secondsBetweenReuses = 30f;
            }
            monumentInfo = new SettingMonument.AvailableMonument() {
                ShortPrefabName = name, CoolDown = 300f, CoolDownPublic = 30f, TeleportTime = 30f, Name = name, PositionOffset = positionOffset, ShortCutCommand = "", CreatedBag = bag, MonumentInfo = closestMonument,
            }
            ;
            _config.SettingsMonument.AvailableMonuments.Add(monumentInfo);
            SaveConfig();
            SendMessage(player, "TPM.ADMIN.SUCCESS");
            break;
        }
        case "remove" : {
            if (player.IsAdmin == false) break;
            if (args.Length < 2) break;
            string name = string.Join(" ", args.Skip(1));
            var monumentInfo = _config.SettingsMonument.AvailableMonuments.Find(x => x.Name == name);
            if (monumentInfo == null) {
                SendMessage(player, "TPM.ADMIN.REMOVE.NOT.FOUND");
                break;
            }
            _config.SettingsMonument.AvailableMonuments.Remove(monumentInfo);
            SaveConfig();
            SendMessage(player, "TPM.ADMIN.REMOVE.SUCCESS");
            break;
        }
        case "list" : {
            if (_config.SettingsMonument.AvailableMonuments.Count < 1) {
                SendMessage(player, "TPM.NO.AVAILABLE.MONUMENTS");
                break;
            }
            string monuments = "";
            for (var i = _config.SettingsMonument.AvailableMonuments.Count - 1; i >= 0; i--) {
                var availableMonument = _config.SettingsMonument.AvailableMonuments[i];
                monuments += $"\n/tpm {availableMonument.Name}" + (string.IsNullOrEmpty(availableMonument.ShortCutCommand) ? "" : $" (/{availableMonument.ShortCutCommand})");
            }
            SendMessage(player, "TPM.LIST.FOUND", monuments);
            break;
        }
        default : {
            if (args.Length < 1) {
                SendMessage(player, "TPM.HELP");
                break;
            }
            if (player.IsHostile()) {
                SendMessage(player, "TPM.HOSTILE");
                break;
            }
            string name = string.Join(" ", args);
            var monumentInfo = _config.SettingsMonument.AvailableMonuments.Find(x => x.Name == name);
            if (monumentInfo == null) {
                SendMessage(player, "TPM.NOT.FOUND");
                break;
            }
            if (monumentInfo.MonumentInfo == null) {
                SendMessage(player, "TPM.NOT.FOUND");
                break;
            }
            var data = PluginData.GetForPlayer(player.userID);
            if (data == null) break;
            double cooldown = data.GetMonumentCooldown(monumentInfo.Name);
            if (cooldown > GetCurrentTime()) {
                SendMessage(player, "TPM.COOLDOWN", TimeHelper.FormatTime(TimeSpan.FromSeconds(cooldown - GetCurrentTime())));
                break;
            }
            var teleportMgr = TeleportMgr.GetManager(player);
            if (teleportMgr == null) break;
            teleportMgr.InitRequest(ParentPosition.GetFinalPosition(monumentInfo.MonumentInfo.transform, monumentInfo.PositionOffset), false, null, monumentInfo);
            SendMessage(player, "TPM.TP.SUCCESS", TimeHelper.FormatTime(TimeSpan.FromSeconds(monumentInfo.TeleportTime)));
            break;
        }
    }
}
private MonumentInfo FindClosestMonument(Vector3 position) {
    MonumentInfo info = null;
    float minDistance = float.MaxValue;
    var monuments = TerrainMeta.Path.Monuments;
    foreach (var monument in monuments) {
        float distance = Vector3.Distance(position, monument.transform.position);
        if (distance > minDistance) continue;
        minDistance = distance;
        info = monument;
    }
    return info;
}
private MonumentInfo FindMonument(string shortPrefabName) {
    return TerrainMeta.Path.Monuments.Find(x => x.name.Contains(shortPrefabName));
}
private string GetShortMonumentName(string fullName) {
    var split = fullName.Split('/');
    return split[split.Length - 1].Replace(".prefab", string.Empty);
}
#endregion
#region Utils
private string CanTeleportPlayer(BasePlayer player) {
    if (player.IsSwimming() && _config.SettingsResolution.CantTeleportSwimming) return GetMessage(player, "CAN.TP.SWIMMING");
    if (!player.IsAlive()) return GetMessage(player, "CAN.TP.ALIVE");
    if (_config.SettingsResolution.CantTeleportMounted && player.isMounted) return GetMessage(player, "CAN.TP.MOUNTED");
    if (_config.SettingsResolution.CantTeleportParent && player.HasParent()) return GetMessage(player, "CAN.TP.PARENT");
    if (_config.SettingsResolution.CantTeleportWater && player.IsSwimming()) return GetMessage(player, "CAN.TP.WATER");
    if (player.metabolism.radiation_poison.value > _config.SettingsResolution.SettingsRadiation.NeedRadiationAmount && _config.SettingsResolution.SettingsRadiation.CantTeleportRadiation) return GetMessage(player, "CAN.TP.RADIATION");
    if (player.metabolism.bleeding.value > _config.SettingsResolution.SettingsBleeding.NeedBleedingAmount && _config.SettingsResolution.SettingsBleeding.CantTeleportBleeding) return GetMessage(player, "CAN.TP.BLEEDING");
    if (player.IsWounded() && _config.SettingsResolution.CantTeleportWounded) return GetMessage(player, "CAN.TP.WOUNDED");
    if (player.IsWounded() && _config.SettingsResolution.CantTeleportCrawling) return GetMessage(player, "CAN.TP.CRAWLING");
    if (player.metabolism.temperature.value < _config.SettingsResolution.SettingsTemperature.MinNeedTemperature && _config.SettingsResolution.SettingsTemperature.CantTeleportTemperature) return GetMessage(player, "CAN.TP.TEMPERATURE");
    var privilege = player.GetBuildingPrivilege(player.WorldSpaceBounds());
    if (privilege != null && !player.IsBuildingAuthed() && _config.SettingsResolution.CantTeleportInBuild) return GetMessage(player, "CAN.TP.BUILDINGBLOCK");
    return "";
}
private static void DrawMarker(BasePlayer player, Vector3 position, string text, int length = 1) {
    if (player == null || player.IsNpc) return;
    player.SetPlayerFlag(BasePlayer.PlayerFlags.IsAdmin, true);
    player.SendEntityUpdate();
    player.SendConsoleCommand("ddraw.text", length, Color.white, position, text);
    player.SendConsoleCommand("camspeed 0");
    if (player.Connection.authLevel < 2) player.SetPlayerFlag(BasePlayer.PlayerFlags.IsAdmin, false);
    player.SendEntityUpdate();
}
private static double GetCurrentTime() {
    return new TimeSpan(DateTime.UtcNow.Ticks).TotalSeconds;
}
private static string GetColor(string hex, float alpha = 1f) {
    if (hex.Length != 7) hex = "#FFFFFF";
    if (alpha < 0 || alpha > 1f) alpha = 1f;
    var color = ColorTranslator.FromHtml(hex);
    var r = Convert.ToInt16(color.R) / 255f;
    var g = Convert.ToInt16(color.G) / 255f;
    var b = Convert.ToInt16(color.B) / 255f;
    return $"{r} {g} {b} {alpha}";
}
private void RegisterPermissions() {
    if(!permission.PermissionExists(AdminPermission)) permission.RegisterPermission(AdminPermission, this);
    foreach (var perm in _config.SettingsHome.CooldownTeleportation) {
        if(!permission.PermissionExists(perm.Key)) permission.RegisterPermission(perm.Key, this);
    }
    foreach (var perm in _config.SettingsHome.CountHome) {
        if(!permission.PermissionExists(perm.Key)) permission.RegisterPermission(perm.Key, this);
    }
    foreach (var perm in _config.SettingsHome.TeleportationTime) {
        if(!permission.PermissionExists(perm.Key)) permission.RegisterPermission(perm.Key, this);
    }
    foreach (var perm in _config.SettingsTeleport.CooldownTeleportation) {
        if(!permission.PermissionExists(perm.Key)) permission.RegisterPermission(perm.Key, this);
    }
    foreach (var perm in _config.SettingsTeleport.TeleportationTime) {
        if(!permission.PermissionExists(perm.Key)) permission.RegisterPermission(perm.Key, this);
    }
}
private void SetHome(BasePlayer player, string name) {
    var userId= player.userID;
    var playerPosition = player.GetNetworkPosition();
    var playerData = PluginData.GetForPlayer(player.userID);
    if (playerData == null) return;
    foreach (var home in playerData.HomesList) {
        if (home.HomeName == name) {
            SendMessage(player, "SETHOME.ALREADY.EXISTS");
            return;
        }
        if (Vector3.Distance(playerPosition, home.HomePos) > 30) continue;
        SendMessage(player, "SETHOME.CANCEL.RADIUS");
        return;
    }
    if (GetHomeLimit(userId) == playerData.HomesList.Count) {
        SendMessage(player, "SETHOME.CANCEL.MAXHOUSE");
        return;
    }
    SleepingBag sleepingBag = null;
    if (_config.SettingsHome.EnableSleepingBags) {
        sleepingBag = CreateSleepingBag(player, playerPosition, $"{name}");
        //List<BuildingBlock> foundations = new List<BuildingBlock>();
        //Vis.Components(sleepingBag.transform.position,.3f, foundations);
        var foundation = GetFoundation(sleepingBag.transform.position);
        sleepingBag.buildingID = foundation[0].buildingID;
        sleepingBag.gameObject.AddComponent<MarkerBag>();
        sleepingBag.skinID = 214;
    }
    playerData.HomesList.Add(new PlayerData.Home(playerPosition, name, sleepingBag?.net.ID ?? 0));
    SendMessage(player, "SETHOME.SUCCESS", name);
}
private SleepingBag CreateSleepingBag(BasePlayer player, Vector3 pos, string name) {
    SleepingBag sleepingBag = GameManager.server.CreateEntity("assets/prefabs/deployable/sleeping bag/sleepingbag_leather_deployed.prefab", pos, Quaternion.identity) as SleepingBag;
    if (sleepingBag == null) return null;
    sleepingBag.deployerUserID = player?.userID ?? 0;
    sleepingBag.niceName = name;
    sleepingBag.OwnerID = player?.userID ?? 0;
    sleepingBag.gameObject.AddComponent<DestroyOnGroundMissing>();
    sleepingBag.gameObject.AddComponent<GroundWatch>();
    sleepingBag.Spawn();
    return sleepingBag;
}
private float GetTeleportTimeHome(ulong uid) {
    float min = 9999f;
    bool set = false;
    foreach (var privilege in _config.SettingsHome.TeleportationTime) {
        if (permission.UserHasPermission(uid.ToString(), privilege.Key)) {
            min = Mathf.Min(min, privilege.Value);
            set = true;
        }
    }
    return set ? min : -1f;
}
private float GetTeleportTimeTpr(ulong uid) {
    float min = 9999f;
    bool set = false;
    foreach (var privilege in _config.SettingsTeleport.TeleportationTime) {
        if (permission.UserHasPermission(uid.ToString(), privilege.Key)) {
            min = Mathf.Min(min, privilege.Value);
            set = true;
        }
    }
    return set ? min : -1f;
}
private float GetTeleportCooldownHome(ulong uid) {
    float min = 9999f;
    bool set = false;
    foreach (var privilege in _config.SettingsHome.CooldownTeleportation) {
        if (permission.UserHasPermission(uid.ToString(), privilege.Key)) {
            min = Mathf.Min(min, privilege.Value);
            set = true;
        }
    }
    return set ? min : -1f;
}
private float GetTeleportCooldownTpr(ulong uid) {
    float min = 9999f;
    bool set = false;
    foreach (var privilege in _config.SettingsTeleport.CooldownTeleportation) {
        if (permission.UserHasPermission(uid.ToString(), privilege.Key)) {
            min = Mathf.Min(min, privilege.Value);
            set = true;
        }
    }
    return set ? min : -1f;
}
private int GetHomeLimit(ulong uid) {
    int max = -1;
    foreach (var privilege in _config.SettingsHome.CountHome) if (permission.UserHasPermission(uid.ToString(), privilege.Key)) max = Mathf.Max(max, privilege.Value);
    return max;
}
private string CheckInsideBlock(Vector3 targetLocation) {
    List<BuildingBlock> blocks = Facepunch.Pool.GetList<BuildingBlock>();
    Vis.Entities(targetLocation + new Vector3(0, 0.25f), 0.1f, blocks, blockLayer);
    bool inside = blocks.Count > 0;
    Facepunch.Pool.FreeList(ref blocks);
    return inside ? "FOUNDATION.HOME.INSIDE.BLOCK" : null;
}
private string CheckFoundation(ulong userID, Vector3 position) {
    if (CheckInsideBattery(position) != null) return "FOUNDATION.NOT.FOUND";
    if (UnderneathFoundation(position)) return "FOUNDATION.NOT.FOUND";
#if DEBUG
    Puts($"CheckFoundation() looking for foundation at {position}");
#endif
    var entities = GetFoundation(position);
    entities.RemoveAll(x => !x.IsValid() || x.IsDestroyed);
    if (entities.Count == 0) return "FOUNDATION.NOT.FOUND";
    if (!_config.SettingsHome.CheckFoundationForOwner) return null;
    for (var i = 0; i < entities.Count; i++) {
        if (IsFriend(userID, entities[i].OwnerID)) return null;
    }
    return "FOUNDATION.NOT.OWNED";
}
private List<BuildingBlock> GetFoundation(Vector3 position) {
    RaycastHit hit;
    var entities = new List<BuildingBlock>();
    if (Physics.Raycast(position + new Vector3(0f, 0.2f, 0f), Vector3.down, out hit, 3f, blockLayer) && hit.GetEntity().IsValid()) {
        var entity = hit.GetEntity();
        if (_config.SettingsHome.AvailableFoundations.Contains(entity.PrefabName)) {
#if DEBUG
            Puts($"  GetFoundation() found {entity.PrefabName} at {entity.transform.position}");
#endif
            entities.Add(entity as BuildingBlock);
        }
    }
    else {
#if DEBUG
        Puts("  GetFoundation() none found.");
#endif
    }
    return entities;
}
private bool UnderneathFoundation(Vector3 position) {
    RaycastHit hit;
    if (Physics.Raycast(position + new Vector3(0f, 3f, 0f), Vector3.down, out hit, 5f, Layers.Mask.Construction, QueryTriggerInteraction.Ignore)) {
        var block = hit.GetEntity() as BuildingBlock;
        if (block.IsValid() && (block.prefabID == 72949757 || block.prefabID == 3234260181)) {
            return hit.point.y > position.y;
        }
    }
    return false;
}
bool IsFriend(ulong playerid, ulong ownerid) {
    if (playerid == ownerid) return true;
    if (_config.UseFriends && Friends != null && Friends.IsLoaded) {
        var fr = Friends?.CallHook("AreFriends", playerid, ownerid);
        if (fr != null && fr is bool && (bool)fr) {
            return true;
        }
    }
    if (_config.UseClans && Clans != null && Clans.IsLoaded) {
        string playerclan = (string)Clans?.CallHook("GetClanOf", playerid);
        string ownerclan = (string)Clans?.CallHook("GetClanOf", ownerid);
        if (playerclan != null && ownerclan != null && playerclan == ownerclan) {
            return true;
        }
    }
    if (_config.UseTeams) {
        RelationshipManager.PlayerTeam playerTeam;
        if (RelationshipManager.ServerInstance.playerToTeam.TryGetValue(playerid, out playerTeam)) {
            if (playerTeam.members.Contains(ownerid)) {
                return true;
            }
        }
    }
    return false;
}
private string CheckInsideBattery(Vector3 targetLocation) {
    var batteries = new List<ElectricBattery>();
    Vis.Entities(targetLocation, 0.35f, batteries, deployedLayer);
    return batteries.Count > 0 ? "TPTargetInsideBlock" : null;
}
private void Teleport(BasePlayer player, BasePlayer target) {
    //if (target.GetComponentInParent<Component>() != null ||
    //    target.GetComponentInParent<HotAirBalloon>() != null || target.GetComponentInParent<Spawnable>() != null || (target.GetParentEntity() != null && target.GetParentEntity().name.Contains("cave")) || (target.GetParentEntity() != null && target.GetParentEntity().name.Contains("junkpile_water")) || (target.GetParentEntity() != null && target.GetParentEntity().name.Contains("cargo")))
    if(target.HasParent()) {
        player.PauseFlyHackDetection(10f);
        player.SetParent(target.GetParentEntity());
        player.SendNetworkUpdateImmediate();
    }
    Teleport(player, target.transform.position, target);
}
private void Teleport(BasePlayer player, float x, float y, float z) => Teleport(player, new Vector3(x, y, z));
private void Teleport(BasePlayer player, Vector3 position, BasePlayer target = null) {
    if (player.IsDead() && player.IsConnected) {
        player.RespawnAt(position, Quaternion.identity);
        return;
    }
    if (target == null) {
        if (player.HasParent()) {
            player.SetParent(null);
            player.SendNetworkUpdate();
        }
    }
    else {
        if (target.HasParent()) {
            player.SetParent(target.GetParentEntity());
            player.SendNetworkUpdate();
        }
    }
    var 
// ... [Code preview truncated due to length. Full source in attached file] ...

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