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

FREE Teleportication : 1.5.7 1.5.7

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
#region License (GPL v2)
/*
    Teleportication - NextGen Teleportation Plugin
    Copyright (c) 2020-2025 RFC1920 <desolationoutpostpve@gmail.com>

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; version 2
    of the License only.This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
    GNU General Public License for more details.You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.Optionally you can also view the license at <http://www.gnu.org/licenses/>.*/
#endregion License (GPL v2)
// Reference: System.Data.SQLite
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.SQLite;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using UnityEngine;
namespace Oxide.Plugins {
    [Info("Teleportication", "RFC1920", "1.5.7")]
    [Description("NextGen Teleportation plugin")]
    internal class Teleportication : RustPlugin {
#region vars
        private SortedDictionary<ulong, Vector3> SavedPoints = new();
        private SortedDictionary<ulong, ulong> TPRRequests = new();
        private SortedDictionary<string, Vector3> monPos = new();
        private SortedDictionary<string, Vector3> monSize = new();
        private SortedDictionary<string, Vector3> cavePos = new();
        private readonly Dictionary<ulong, TPTimer> TeleportTimers = new();
        private readonly Dictionary<string, Dictionary<ulong, TPTimer>> CooldownTimers = new();
        private Dictionary<string, Dictionary<ulong, float>> DailyUsage = new();
        private readonly Dictionary<ulong, TPRTimer> TPRTimers = new();
        private int dateInt;
        //private Coroutine townPositionsC;
        //private List<Vector3> townPositions = new();
        private bool newsave;
        private const string HGUI = "gui.homes";
        private const string permTP_Use = "teleportication.use";
        private const string permTP_TP = "teleportication.tp";
        private const string permTP_OTHERS = "teleportication.tpothers";
        private const string permTP_TPB = "teleportication.tpb";
        private const string permTP_TPR = "teleportication.tpr";
        private const string permTP_Town = "teleportication.town";
        private const string permTP_Bandit = "teleportication.bandit";
        private const string permTP_Outpost = "teleportication.outpost";
        private const string permTP_Tunnel = "teleportication.tunnel";
        private const string permTP_Admin = "teleportication.admin";
        private ConfigData configData;
        private SQLiteConnection sqlConnection;
        public TextInfo TI = CultureInfo.CurrentCulture.TextInfo;
        private string connStr;
        private readonly string logfilename = "log";
        [PluginReference]
        private readonly Plugin Friends, Clans, Economics, ServerRewards, GridAPI, NoEscape, Vanish, ZoneManager, BankSystem, SteamFriends;
        //, CopyPaste, LootProtect;
        private readonly int blockLayer = LayerMask.GetMask("Construction");
        private readonly int groundLayer = LayerMask.GetMask("Terrain", "World");
        public class TPTimer {
            public Timer timer;
            public float start;
            public float cooldown;
            public string type;
            public BasePlayer source;
            public string targetName;
            public Vector3 targetLocation;
            public float counter;
            // Request count while in cooldown to determine bypass go/no-go
        }
        public class TPRTimer {
            public Timer timer;
            public float start;
            public float countdown;
            public string type;
        }
#endregion
#region Message
        private string Lang(string key, string id = null, params object[] args) => string.Format(lang.GetMessage(key, this, id), args);
        private void Message(IPlayer player, string key, params object[] args) => player.Message(Lang(key, player.Id, args));
#endregion
#region init
        private void OnServerInitialized() {
            Puts("HERE!");
            sqlConnection = new SQLiteConnection(connStr);
            sqlConnection.Open();
            LoadData();
            LoadConfigVariables();
            // Setup permissions from VIPSettings
            foreach (KeyValuePair<string, CmdOptions> ttype in configData.Types) {
                if (ttype.Value.VIPSettings == null) continue;
                if (ttype.Value.VIPSettings.Count > 0) {
                    foreach (KeyValuePair<string, VIPSetting> x in ttype.Value.VIPSettings) {
                        if (!permission.PermissionExists(x.Key, this)) permission.RegisterPermission(x.Key, this);
                    }
                }
            }
            if (configData.Options.WipeOnNewSave && newsave) {
                newsave = false;
                // Wipe homes and town, etc.CreateOrClearTables(true);
                //AutoSpawnTown();
            }
            FindMonuments();
            List<string> target = QuerySingleStringToList("SELECT location FROM rtp_server WHERE name='town'");
            if (target.Count > 0) {
                Vector3 townPos = StringToVector3(target[0]);
                //Puts($"Town position: {townPos}");
                NextTick(() => SetTownMapMarker(townPos));
            }
            MidnightDetect(true);
        }
        private void Init() {
            // Dummy file, creates the directory for us.DynamicConfigFile dataFile = Interface.GetMod().DataFileSystem.GetDatafile(Name + "/teleportication");
            dataFile.Save();
            connStr = $"Data Source={Path.Combine(Interface.GetMod().DataDirectory, Name, "teleportication.db")};";
            CooldownTimers.Add("Home", new Dictionary<ulong, TPTimer>());
            CooldownTimers.Add("Town", new Dictionary<ulong, TPTimer>());
            CooldownTimers.Add("TPA", new Dictionary<ulong, TPTimer>());
            CooldownTimers.Add("TPB", new Dictionary<ulong, TPTimer>());
            CooldownTimers.Add("TPR", new Dictionary<ulong, TPTimer>());
            CooldownTimers.Add("TP", new Dictionary<ulong, TPTimer>());
            CooldownTimers.Add("Bandit", new Dictionary<ulong, TPTimer>());
            CooldownTimers.Add("Outpost", new Dictionary<ulong, TPTimer>());
            CooldownTimers.Add("Tunnel", new Dictionary<ulong, TPTimer>());
            DailyUsage.Add("Home", new Dictionary<ulong, float>());
            DailyUsage.Add("Town", new Dictionary<ulong, float>());
            DailyUsage.Add("TPA", new Dictionary<ulong, float>());
            DailyUsage.Add("TPB", new Dictionary<ulong, float>());
            DailyUsage.Add("TPR", new Dictionary<ulong, float>());
            DailyUsage.Add("TP", new Dictionary<ulong, float>());
            DailyUsage.Add("Bandit", new Dictionary<ulong, float>());
            DailyUsage.Add("Outpost", new Dictionary<ulong, float>());
            DailyUsage.Add("Tunnel", new Dictionary<ulong, float>());
            AddCovalenceCommand("home", "CmdHomeTeleport");
            AddCovalenceCommand("homeg", "CmdHomeGUI");
            AddCovalenceCommand("sethome", "CmdSetHome");
            AddCovalenceCommand("town", "CmdTownTeleport");
            AddCovalenceCommand("bandit", "CmdTownTeleport");
            AddCovalenceCommand("outpost", "CmdTownTeleport");
            AddCovalenceCommand("tunnel", "CmdTownTeleport");
            AddCovalenceCommand("tpa", "CmdTpa");
            AddCovalenceCommand("tpb", "CmdTpb");
            AddCovalenceCommand("tpc", "CmdTpc");
            AddCovalenceCommand("tpr", "CmdTpr");
            AddCovalenceCommand("tp", "CmdTp");
            AddCovalenceCommand("tpadmin", "CmdTpAdmin");
            permission.RegisterPermission(permTP_Use, this);
            permission.RegisterPermission(permTP_TPB, this);
            permission.RegisterPermission(permTP_TPR, this);
            permission.RegisterPermission(permTP_TP, this);
            permission.RegisterPermission(permTP_OTHERS, this);
            permission.RegisterPermission(permTP_Town, this);
            permission.RegisterPermission(permTP_Bandit, this);
            permission.RegisterPermission(permTP_Outpost, this);
            permission.RegisterPermission(permTP_Tunnel, this);
            permission.RegisterPermission(permTP_Admin, this);
        }
        private void Unload() {
            foreach (BasePlayer player in BasePlayer.activePlayerList) {
                if (player == null) continue;
                CuiHelper.DestroyUi(player, HGUI);
            }
            sqlConnection.Close();
        }
        protected override void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string> {
                ["serverinfo"]
                = "Server Info - ", ["locations"] = "Locations:", ["flags"] = "Flags:", ["notauthorized"] = "You are not authorized for this command!", ["homesavail"] = "The following homes have been set:", ["homesavailfor"] = "The following homes have been set by {0}:", ["nohomes"] = "No homes have been set.", ["hometoomany"] = "You cannot set any more homes.Limit is {0}.", ["hometooclose"] = "Too close to another home - minimum distance {0}", ["homeset"] = "Home {0} has been set.", ["homeremoved"] = "Home {0} has been removed.", ["homewasremoved"] = "Home has been removed - {0}.", ["setblocked"] = "Home cannot be set here - {0}", ["blocked"] = "You cannot teleport while blocked!", ["blockedinvis"] = "You cannot teleport while invisible!", ["invalidhome"] = "Home invalid - {0}", ["lastused"] = " Last used: {0} minutes ago", ["lastuse"] = "last use", ["name"] = "name", ["lastday"] = " Not used since server restart", ["list"] = "list", ["home"] = "Home", ["tpb"] = "old location", ["debug"] = "Debug set to {0}", ["tpr"] = "another player", ["town"] = "Town", ["outpost"] = "Outpost", ["outpostset"] = "Outpost location has been set to {0}", ["tunnels"] = "Available Tunnel Entrances:\n{0}", ["bandit"] = "Bandit", ["banditset"] = "Bandit Town location has been set to {0}", ["InCooldownNoticeNoMoney"] = "Currently in cooldown for {0} for another {1} second(s).Insufficient funds to bypass.", ["InCooldownNoticeNoPmt"] = "Currently in cooldown for {0} for another {1} second(s).", ["InCooldownNoticePmt"] = "Currently in cooldown for {0} for another {1} second(s).Run again to pay {2} for bypass.", ["CooldownBypassedNotice"] = "Cooldown for {0} bypassed by paying {1}", ["limit"] = "You have hit the daily limit for {0}: ({1} of {2})", ["reqdenied"] = "Request to teleport to {0} was denied!", ["reqaccepted"] = "Request to teleport to {0} was accepted!", ["homemissing"] = "No such home...", ["crafting"] = "You are not allowed to teleport while crafting.", ["notowned"] = "No privileges at the target location!", ["missingfoundation"] = "Foundation missing or offset.", ["locationnotset"] = "{0} location has not been set!", ["townset"] = "Town location has been set to {0}!", ["cavetooclose"] = "You cannot use /{0} so close to a cave.", ["montooclose"] = "You cannot use /{0} so close to {1}.", ["onhurt"] = "You cannot use /{0} while injured.", ["oncold"] = "You are too cold to use /{0}!", ["onhot"] = "You are too hot to use /{0}!", ["onhostile"] = "You are marked as hostile and cannot use /{0} for {1} minutes...", ["onballoon"] = "You cannot use /{0} while on a balloon.", ["oncargo"] = "You cannot use /{0} while on the cargo ship.", ["onlift"] = "You cannot use /{0} while on a lift.", ["onmounted"] = "You cannot use /{0} while mounted.", ["onswimming"] = "You cannot use /{0} while swimming.", ["onwater"] = "You cannot use /{0} above water.", ["onboat"] = "You cannot use /{0} on a tugboat.", ["oniceberg"] = "You cannot use /{0} on an iceberg.", ["intunnel"] = "You cannot use /{0} to/from the tunnel system.", ["safezone"] = "You cannot use /{0} from a safe zone.", ["remaining"] = "You have {0} {1} teleports remaining for today.", ["teleporting"] = "Teleporting to {0} in {1} second(s)...", ["sortedby"] = "sorted by {0}", ["noprevious"] = "No previous location saved.", ["teleportinghome"] = "Teleporting to home {0} in {1} second(s)...", ["BackupDone"] = "Teleportication database has been backed up to {0}", ["importhelp"] = "/tpadmin import {r/n} {y/1/yes/true}\n\t import RTeleportion or NTeleportation\n\tadd y or 1 or true to actually import\n\totherwise display data only", ["tphelp"] = "/tp X,Z OR /tp X,Y,Z -- e.g./tp 121,-535 will teleport the player to that location on the map.\nIf Y is not specified, player will be moved to ground level.", ["tphelpnew"] = "/tp X,Z OR /tp X,Y,Z -- e.g./tp 121,-535 will teleport the player to that location on the map.\n  If Y is not specified, player will be moved to ground level.\n/tp YOURNAME PLAYERNAME\n  Teleport yourself to another player.\n/tp PLAYERNAME YOURNAME\n  Teleport specified player to your location, if allowed.", ["cannottp"] = "Cannot teleport to desired location.", ["obstructed"] = "The target location is too close to construction.", ["importdone"] = "Homes have been imported from datafile '{0}'", ["importing"] = "Importing data for {0}", ["tpcancelled"] = "Teleport cancelled!", ["tprself"] = "You cannot tpr to yourself.", ["playernotfound"] = "Source or target player not found", ["cooldown"] = "Cooldown:", ["cooldowns"] = "COOLDOWNS:", ["playerhomes"] = "PLAYER HOMES:", ["remaining"] = "Remaining:", ["tprnotify"] = "{0} has requested to be teleported to you.\nType /tpa to accept.", ["tpanotify"] = "{0} has accepted your teleport request.You will be teleported in {1} second(s).", ["tprreject"] = "{0} rejected your request.Or, the request timed out."
            }
            , this);
        }
        private void OnNewSave() => newsave = true;
        //private object OnPlayerRespawn(BasePlayer player)
        //{
        //    List<string> target = QuerySingleStringToList($"SELECT location FROM rtp_server WHERE name='outpost'");
        //    if (target[0]?.Length > 0)
        //    {
        //        Vector3 position = StringToVector3(target[0]);
        //        return new BasePlayer.SpawnPoint() { pos = position, rot = new Quaternion(0, 0, 0, 1) };
        //    }
        //    return null;
        //}
        private void LoadData() {
            bool found = false;
            using (SQLiteConnection c = new(connStr)) {
                c.Open();
                using (SQLiteCommand r = new("SELECT name FROM sqlite_master WHERE type='table' AND name='rtp_server'", c)) using (SQLiteDataReader rtbl = r.ExecuteReader()) {
                    while (rtbl.Read()) {
                        found = true;
                    }
                }
            }
            if (!found) CreateOrClearTables(true);
        }
#endregion
#region commands
        [Command("tp")]
        private void CmdTp(IPlayer iplayer, string command, string[] args) {
            if (configData.Options.debug) {
                string debug = string.Join(",", args);
                Puts($"{debug}");
            }
            if (!iplayer.HasPermission(permTP_TP) && !iplayer.HasPermission(permTP_OTHERS) && !iplayer.HasPermission(permTP_Admin)) {
                Message(iplayer, "notauthorized");
                return;
            }
            BasePlayer player = iplayer.Object as BasePlayer;
            if (args.Length == 1) {
                // TP to coordinates X,Y,Z or X,0,Z (/tp 100,0,100 OR /tp 100,100)
                // 0 or no Y arg will be translated to the terrain height at the destination
                string[] input = args[0].Split(',');
                if (input.Length > 1) {
                    Vector3 pos = default(Vector3);
                    string parsed;
                    if (input.Length == 3) {
                        parsed = input[0] + "," + input[1] + "," + input[2];
                        DoLog($"Parsed arg input from X,Y,Z into coordinates: s:{parsed}/v:{pos}");
                        pos = StringToVector3(parsed);
                    }
                    else if (input.Length == 2) {
                        parsed = input[0] + ",0," + input[1];
                        pos = StringToVector3(parsed);
                        DoLog($"Parsed arg input from X,Y into coordinates: s:{parsed}/v:{pos}");
                        if (TerrainMeta.HeightMap.GetHeight(pos) > pos.y) {
                            // Ensure they are sent above the terrain
                            pos.y = TerrainMeta.HeightMap.GetHeight(pos);
                        }
                    }
                    else {
                        Message(iplayer, "tphelpnew");
                        return;
                    }
                    ulong userid = ulong.Parse(iplayer.Id);
                    if (CanTeleport(player, parsed, "TP")) {
                        if (!TeleportTimers.ContainsKey(userid)) {
                            AddTimer(player, pos, "TP", "TP");
                            HandleTimer(userid, "TP", true);
                            CreateCooldown(player, "TP");
                            if (!DailyUsage["TP"].ContainsKey(userid)) DailyUsage["TP"].Add(userid, 0);
                            float usage = GetDailyLimit(userid, "TP") - DailyUsage["TP"][userid];
                            if (usage > 0) {
                                Message(iplayer, "remaining", usage.ToString(), "TPB");
                            }
                        }
                        else if (TeleportTimers[userid].cooldown == 0) {
                            Teleport(player, pos, "TP");
                        }
                    }
                }
            }
            else if (args.Length == 2) {
                // Player to player tp (/tp src target), sleeping or not
                BasePlayer srcPlayer = FindPlayerByName(args[0], true);
                BasePlayer tgtPlayer = FindPlayerByName(args[1], true);
                if (srcPlayer == null || tgtPlayer == null) {
                    Message(iplayer, "playernotfound");
                    return;
                }
                // 'player' set above, i.e.the player running the command
                bool allowed = false;
                if (srcPlayer != player && tgtPlayer != player) {
                    if (iplayer.HasPermission(permTP_Admin)) {
                        // Allowed to tp 2nd player to 3rd player based on permTP_Admin
                        allowed = true;
                    }
                    else {
                        // No permission to tp 2nd player to 3rd player, i.e.not the calling player
                        Message(iplayer, "notauthorized");
                        return;
                    }
                }
                else if (tgtPlayer == player && iplayer.HasPermission(permTP_OTHERS)) {
                    // Allowed to tp srcPlayer to tgtPlayer (self) based on permTP_OTHERS
                    allowed = true;
                }
                else if (srcPlayer == player) {
                    // Allowed to tp srcPlayer (self) to tgtPlayer based on perm_TP
                    allowed = true;
                }
                if (allowed) {
                    if (TeleportTimers.ContainsKey(srcPlayer.userID)) TeleportTimers.Remove(srcPlayer.userID);
                    AddTimer(srcPlayer, tgtPlayer.transform.position, "TP", "TP");
                    HandleTimer(srcPlayer.userID, "TP", true);
                    if (!DailyUsage["TP"].ContainsKey(player.userID)) DailyUsage["TP"].Add(player.userID, 0);
                    float usage = GetDailyLimit(player.userID, "TP") - DailyUsage["TP"][player.userID];
                    if (usage > 0) {
                        Message(iplayer, "remaining", usage.ToString(), "TP");
                    }
                    return;
                }
                Message(iplayer, "notauthorized");
            }
            else {
                Message(iplayer, "tphelpnew");
            }
        }
        [Command("tpadmin")]
        private void CmdTpAdmin(IPlayer iplayer, string command, string[] args) {
            if (configData.Options.debug) {
                string debug = string.Join(",", args);
                Puts($"{debug}");
            }
            if (!iplayer.HasPermission(permTP_Admin)) {
                Message(iplayer, "notauthorized");
                return;
            }
            if (args.Length > 0) {
                switch (args[0]) {
                    case "import" :  // args[1] == r/n
                    // Import from N/RTeleportation
                    string otpplug = null;
                    bool doit = false;
                    if (args.Length > 1) {
                        switch (args[1]) {
                            case "r" : otpplug = "RTeleportation";
                            break;
                            case "n" : otpplug = "NTeleportation";
                            break;
                            default : Message(iplayer, "importhelp");
                            return;
                        }
                    }
                    if (args.Length > 2) {
                        doit = GetBoolValue(args[2]);
                    }
                    if (otpplug != null) {
                        try {
                            // Get user homes from data file
                            DynamicConfigFile tpfile = Interface.GetMod().DataFileSystem.GetFile(otpplug + "Home");
                            tpfile.Settings.NullValueHandling = NullValueHandling.Ignore;
                            tpfile.Settings.Converters = new JsonConverter[] {
                                new UnityVector3Converter(), new CustomComparerDictionaryCreationConverter<string>(StringComparer.OrdinalIgnoreCase)
                            }
                            ;
                            foreach (KeyValuePair<ulong, HomeData> userHomes in tpfile.ReadObject<Dictionary<ulong, HomeData>>()) {
                                foreach (KeyValuePair<string, Vector3> home in userHomes.Value.Locations) {
                                    if (doit) {
                                        RunUpdateQuery($"INSERT OR REPLACE INTO rtp_player VALUES('{userHomes.Key}', '{home.Key}', '{home.Value}', '0', 0)");
                                        Message(iplayer, "importing", userHomes.Key);
                                    }
                                    else {
                                        Message(iplayer, $"{userHomes.Key}: Home {home.Key} location {home.Value}");
                                    }
                                }
                            }
                            if (doit) Message(iplayer, "importdone", otpplug + "Home");
                        }
                        catch {
                            Puts($"Failed to open datafile, {otpplug}Home");
                        }
                        try {
                            // Get town location from config
                            DataFileSystem d = new(Interface.GetMod().ConfigDirectory);
                            string[] x = d.GetFiles("", $"{otpplug}.json");
                            OtherConfigData otpcfg = d.GetFile(otpplug).ReadObject<OtherConfigData>();
                            string townloc = otpcfg.Town.Location.Replace("  ", "").Replace(" ", ",");
                            if (townloc != null) {
                                if (doit) {
                                    RunUpdateQuery($"INSERT OR REPLACE INTO rtp_server VALUES('town', '({townloc})')");
                                    Message(iplayer, "importing", $"Town: ({townloc})");
                                }
                                else {
                                    Message(iplayer, $"Found town location ({townloc})");
                                }
                            }
                        }
                        catch {
                            Puts($"Failed to open cfgfile for {otpplug}");
                        }
                    }
                    break;
                    case "wipe" : Message(iplayer, "Wiping data!");
                    CreateOrClearTables(true);
                    FindMonuments();
                    break;
                    case "info" : Message(iplayer, Title);
                    Message(iplayer, "locations");
                    string loc = null;
                    using (SQLiteConnection c = new(connStr)) {
                        c.Open();
                        using (SQLiteCommand q = new("SELECT name, location FROM rtp_server ORDER BY name", c)) using (SQLiteDataReader svr = q.ExecuteReader()) {
                            while (svr.Read()) {
                                string nm = !svr.IsDBNull(0) ? svr.GetString(0) : "";
                                string lc = !svr.IsDBNull(1) ? svr.GetString(1) : "";
                                loc += "\t" + TI.ToTitleCase(nm) + ": " + lc.TrimEnd() + "\n";
                            }
                        }
                    }
                    Message(iplayer, loc);
                    string flags = $"\tHomeRequireFoundation:\t{configData.Options.HomeRequireFoundation}\n" + $"\tStrictFoundationCheck:\t{configData.Options.StrictFoundationCheck}\n" + $"\tHomeRemoveInvalid:\t{configData.Options.HomeRemoveInvalid}\n" + $"\tHonorBuildingPrivilege:\t{configData.Options.HonorBuildingPrivilege}\n" + $"\tHonorRelationships:\t{configData.Options.HonorRelationships}\n" + $"\tAutoGenBandit:\t{configData.Options.AutoGenBandit}\n" + $"\tAutoGenOutpost:\t{configData.Options.AutoGenOutpost}\n" + $"\tHomeMinimumDistance:\t{configData.Options.HomeMinimumDistance}\n" + $"\tDefaultMonoumentSize:\t{configData.Options.DefaultMonumentSize}\n" + $"\tCaveDistanceSmall:\t{configData.Options.CaveDistanceSmall}\n" + $"\tCaveDistanceMedium:\t{configData.Options.CaveDistanceMedium}\n" + $"\tCaveDistanceLarge:\t{configData.Options.CaveDistanceLarge}\n" + $"\tMinimumTemp:\t{configData.Options.MinimumTemp}\n" + $"\tMaximumTemp:\t{configData.Options.MaximumTemp}\n" + $"\tSetCommand:\t{configData.Options.SetCommand}\n" + $"\tListCommand:\t{configData.Options.ListCommand}\n" + $"\tRemoveCommand:\t{configData.Options.RemoveCommand}";
                    Message(iplayer, "flags");
                    Message(iplayer, flags);
                    break;
                    case "playerinfo" : case "pinfo" : Message(iplayer, $"{Title} Player Information");
                    Message(iplayer, Lang("cooldowns"));
                    string output = "";
                    foreach (KeyValuePair<string, Dictionary<ulong, TPTimer>> cdt in CooldownTimers) {
                        output += "\t" + cdt.Key + ": \n";
                        foreach (KeyValuePair<ulong, TPTimer> tinfo in cdt.Value) {
                            output += $"\t\t{BasePlayer.FindAwakeOrSleeping(tinfo.Key.ToString()).displayName}, " + $"{Lang("cooldown")} {tinfo.Value.cooldown}, " + $"{Lang("remaining")} {Math.Abs(Time.realtimeSinceStartup - tinfo.Value.start - tinfo.Value.cooldown)}\n";
                        }
                    }
                    output += $"\n{Lang("playerhomes")}\n";
                    Dictionary<string, int> pCount = new();
                    using (SQLiteConnection c = new(connStr)) {
                        c.Open();
                        using (SQLiteCommand q = new("SELECT userid FROM rtp_player ORDER BY userid", c)) using (SQLiteDataReader svr = q.ExecuteReader()) {
                            while (svr.Read()) {
                                string playerId = !svr.IsDBNull(0) ? svr.GetString(0) : "";
                                if (playerId.Length == 0) continue;
                                if (!pCount.ContainsKey(playerId)) {
                                    pCount.Add(playerId, 1);
                                    continue;
                                }
                                pCount[playerId]++;
                            }
                        }
                    }
                    foreach (KeyValuePair<string, int> pHomes in pCount) {
                        output += $"\t{BasePlayer.FindAwakeOrSleeping(pHomes.Key)?.displayName} has {pHomes.Value} homes\n";
                    }
                    Message(iplayer, output);
                    break;
                    case "debug" : configData.Options.debug = !configData.Options.debug;
                    Message(iplayer, "debug", configData.Options.debug.ToString());
                    break;
                    case "backup" : string backupfile = "teleportication_" + DateTime.Now.ToString("yyyy-MM-dd_HHmmss") + ".db";
                    if (args.Length > 1) {
                        backupfile = args[1] + ".db";
                    }
                    using (SQLiteConnection c = new(connStr)) {
                        c.Open();
                        string file = $"{Interface.GetMod().DataDirectory}{Path.DirectorySeparatorChar}{Name}{Path.DirectorySeparatorChar}{backupfile}";
                        SQLiteConnection.CreateFile(file);
                        SQLiteCommand cmd = c.CreateCommand();
                        cmd.CommandText = $"VACUUM INTO '{file}'";
                        cmd.ExecuteNonQuery();
                        Message(iplayer, "BackupDone", backupfile);
                    }
                    break;
                }
            }
        }
        [Command("sethome")]
        private void CmdSetHome(IPlayer iplayer, string command, string[] args) {
            if (args.Length == 1) CmdHomeTeleport(iplayer, "home", new string[] {
                configData.Options.SetCommand, args[0]
            }
            );
        }
        [Command("home")]
        private void CmdHomeTeleport(IPlayer iplayer, string command, string[] args) {
            if (configData.Options.debug) {
                string debug = string.Join(",", args);
                Puts($"{debug}");
            }
            if (!iplayer.HasPermission(permTP_Use)) {
                Message(iplayer, "notauthorized");
                return;
            }
            if (iplayer.Id == "server_console") return;
            BasePlayer player = iplayer.Object as BasePlayer;
            if (args.Length < 1 || (args.Length == 1 && args[0] == configData.Options.ListCommand)) {
                // List homes
                string available = Lang("homesavail") + "\n";
                bool hashomes = false;
                List<Vector3> allhomes = new();
                string firstHome = string.Empty;
                using (SQLiteConnection c = new(connStr)) {
                    c.Open();
                    string qh = $"SELECT name, location, lastused FROM rtp_player WHERE userid='{player.userID}'";
                    //Puts(qh);
                    using (SQLiteCommand q = new(qh, c)) using (SQLiteDataReader home = q.ExecuteReader()) {
                        while (home.Read()) {
                            string test = !home.IsDBNull(0) ? home.GetString(0) : "";
                            Vector3 position = StringToVector3(!home.IsDBNull(1) ? home.GetString(1) : "");
                            string pos = PositionToGrid(position);
                            if (test != "") {
                                string timesince = Math.Floor((Time.realtimeSinceStartup / 60) - (Convert.ToSingle(home.GetString(2)) / 60)).ToString();
                                if (int.Parse(timesince) < 0) {
                                    available += test + ": " + position + " [" + pos + "] " + Lang("lastday") + "\n";
                                }
                                else {
                                    available += test + ": " + position + " [" + pos + "] " + Lang("lastused", null, timesince) + "\n";
                                }
                                hashomes = true;
                                allhomes.Add(position);
                                firstHome = test;
                            }
                        }
                    }
                }
                if (hashomes) {
                    if (allhomes.Count == 1 && CanTeleport(player, allhomes[0].ToString(), "Home") && configData.Types["Home"].IfOneHomeJustGoThere) {
                        if (!TeleportTimers.ContainsKey(player.userID)) {
                            AddTimer(player, allhomes[0], "Home", "Home");
                            HandleTimer(player.userID, "Home", true);
                            CreateCooldown(iplayer.Object as BasePlayer, "Home");
                            if (!DailyUsage["Home"].ContainsKey(player.userID)) DailyUsage["Home"].Add(player.userID, 0);
                            float usage = GetDailyLimit(player.userID, "Home") - DailyUsage["Home"][player.userID];
                            if (usage > 0) {
                                Message(iplayer, "remaining", usage.ToString(), "Home");
                            }
                            Message(iplayer, "teleportinghome", firstHome + "(" + RemoveSpecialCharacters(firstHome) + ")", configData.Types["Home"].CountDown.ToString());
                        }
                        else if (TeleportTimers[player.userID].cooldown == 0) {
                            Teleport(player, allhomes[0], "home");
                        }
                        return;
                    }
                    Message(iplayer, available);
                }
                else {
                    Message(iplayer, "nohomes");
                }
            }
            else if (args.Length == 2 && (args[0] == configData.Options.ListCommand) && configData.Options.HonorRelationships) {
                // List a friend's homes
                BasePlayer target = BasePlayer.Find(args[1]);
                if (target != null && IsFriend(player.userID, target.userID)) {
                    string available = Lang("homesavailfor", null, RemoveSpecialCharacters(target.displayName)) + "\n";
                    bool hashomes = false;
                    using (SQLiteConnection c = new(connStr)) {
                        c.Open();
                        using (SQLiteCommand q = new($"SELECT name, location, lastused FROM rtp_player WHERE userid='{target.userID}'", c)) using (SQLiteDataReader home = q.ExecuteReader()) {
                            while (home.Read()) {
                                string test = !home.IsDBNull(0) ? home.GetString(0) : "";
                                string lastused = !home.IsDBNull(2) ? home.GetString(2) : "";
                                if (test != "") {
                                    string timesince = Math.Floor((Time.realtimeSinceStartup / 60) - (Convert.ToSingle(lastused) / 60)).ToString();
                                    //Puts($"Time since {timesince}");
                                    available += test + ": " + home.GetString(1) + " " + Lang("lastused", null, timesince) + "\n";
                                    hashomes = true;
                                }
                            }
                        }
                    }
                    if (hashomes) {
                        Message(iplayer, available);
                    }
                    else {
                        Message(iplayer, "nohomes");
                    }
                }
                else {
                    Message(iplayer, "notauthorized");
                }
            }
            else if (args.Length == 2 && args[0] == configData.Options.SetCommand) {
                // Set home
                string reason;
                if (CanSetHome(player, player.transform.position, out reason)) {
                    string home = args[1];
                    bool found = false;
                    using (SQLiteConnection c = new(connStr)) {
                        c.Open();
                        string q = $"SELECT name FROM rtp_player WHERE userid='{player.userID}' AND name='{home}'";
                        DoLog(q);
                        using (SQLiteCommand ct = new(q, c)) using (SQLiteDataReader pl = ct.ExecuteReader()) {
                            while (pl.Read()) {
                                if (!pl.IsDBNull(0) && pl.GetString(0) == home) found = true;
                            }
                        }
                    }
                    if (found) {
                        RunUpdateQuery($"UPDATE rtp_player SET location='{player.transform.position}' WHERE userid='{player.userID}' AND name='{home}'");
                    }
                    else {
                        RunUpdateQuery($"INSERT INTO rtp_player VALUES('{player.userID}', '{home}', '{player.transform.position}', '{Time.realtimeSinceStartup}', 0)");
                    }
                    Message(iplayer, "homeset", home);
                }
                else {
                    Message(iplayer, "setblocked", reason);
                }
            }
            else if (args.Length == 2 && args[0] == configData.Options.RemoveCommand) {
                // Remove home
                string home = args[1];
                List<string> found = QuerySingleStringToList($"SELECT location FROM rtp_player WHERE userid='{player.userID}' AND name='{home}'");
                if (found.Count > 0) {
                    RunUpdateQuery($"DELETE FROM rtp_player WHERE userid='{player.userID}' AND name='{home}'");
                    Message(iplayer, "homeremoved", home);
                }
                else {
                    Message(iplayer, "homemissing");
                }
            }
            else if (args.Length == 2) {
                // Use a friend's home: /home Playername home1
                BasePlayer target = BasePlayer.Find(args[0]);
                if (target != null && IsFriend(player.userID, target.userID)) {
                    string home = args[1];
                    List<string> homes = QuerySingleStringToList($"SELECT location FROM rtp_player WHERE userid='{target.userID}' AND name='{home}'");
                    if (homes.Count > 0 && CanTeleport(player, homes[0], "Home")) {
                        if (!TeleportTimers.ContainsKey(player.userID)) {
                            AddTimer(player, StringToVector3(homes[0]), "Home", "Home");
                            HandleTimer(player.userID, "Home", true);
                            CreateCooldown(iplayer.Object as BasePlayer, "Home");
                            if (!DailyUsage["Home"].ContainsKey(player.userID)) DailyUsage["Home"].Add(player.userID, 0);
                            float usage = GetDailyLimit(player.userID, "Home") - DailyUsage["Home"][player.userID];
                            if (usage > 0) {
                                Message(iplayer, "remaining", usage.ToString(), "Home");
                            }
                            Message(iplayer, "teleportinghome", home + "(" + RemoveSpecialCharacters(target.displayName) + ")", configData.Types["Home"].CountDown.ToString());
                        }
                        else if (TeleportTimers[player.userID].cooldown == 0) {
                            Teleport(player, StringToVector3(homes[0]), "home");
                        }
                    }
                }
            }
            else if (args.Length == 1) {
                CuiHelper.DestroyUi(player, HGUI);
                // Use an already set home
                string home = args[0];
                List<string> homes = QuerySingleStringToList($"SELECT location FROM rtp_player WHERE userid='{player.userID}' AND name='{home}'");
                if (homes.Count == 0) {
                    Message(iplayer, "homemissing");
                    return;
                }
                if (CanTeleport(player, homes[0], "Home")) {
                    if (!TeleportTimers.ContainsKey(player.userID)) {
                        AddTimer(player, StringToVector3(homes[0]), "Home", "Home");
                        HandleTimer(player.userID, "Home", true);
                        CreateCooldown(iplayer.Object as BasePlayer, "Home");
                        if (!DailyUsage["Home"].ContainsKey(player.userID)) DailyUsage["Home"].Add(player.userID, 0);
                        float usage = GetDailyLimit(player.userID, "Home") - DailyUsage["Home"][player.userID];
                        if (usage > 0) {
                            Message(iplayer, "remaining", usage.ToString(), "Home");
                        }
                        Message(iplayer, "teleportinghome", home, configData.Types["Home"].CountDown.ToString());
                    }
                    else if (TeleportTimers[player.userID].cooldown == 0) {
                        Teleport(player, StringToVector3(homes[0]), "home");
                    }
                }
            }
        }
        [Command("homeg")]
        private void CmdHomeGUI(IPlayer iplayer, string command, string[] args) {
            if (configData.Options.debug) {
                string debug = string.Join(",", args);
                Puts($"{debug}");
            }
            if (!iplayer.HasPermission(permTP_Use)) {
                Message(iplayer, "notauthorized");
                return;
            }
            if (iplayer.Id == "server_console") return;
            BasePlayer player = iplayer.Object as BasePlayer;
            string sort = "alpha";
            if (args.Length > 0) {
                sort = args[0];
            }
            if (sort == "closeit") {
                CuiHelper.DestroyUi(player, HGUI);
                return;
            }
            HomeGUI(player, sort);
        }
        [Command("town")]
        private void CmdTownTeleport(IPlayer iplayer, string command, string[] args) {
            if (iplayer.Id == "server_console") return;
            BasePlayer player = iplayer.Object as BasePlayer;
            if (args.Length > 0 && args[0] == configData.Options.SetCommand) {
                if (!iplayer.HasPermission(permTP_Admin)) {
                    Message(iplayer, "notauthorized");
                    return;
                }
                RunUpdateQuery($"INSERT OR REPLACE INTO rtp_server VALUES('{command}', '{player.transform.position}')");
                switch (command) {
                    case "town" : Message(iplayer, "townset", player.transform.position.ToString());
                    Puts(player.transform.position.ToString());
                    if (configData.Options.AddTownMapMarker) {
                        SetTownMapMarker(player.transform.position);
                    }
                    if (configData.Options.TownZoneId?.Length > 0) {
                        string[] zone_args = {
                            "name", "Town", "radius", "150"
                        }
                        ;
                        object ckzone = ZoneManager?.Call("CheckZoneID", configData.Options.TownZoneId);
                        if (ckzone != null && ckzone is bool && !(bool)ckzone) {
                            configData.Options.TownZoneId = UnityEngine.Random.Range(1, 99999999).ToString();
                            SaveConfig(configData);
                        }
                        if (configData.Options.TownZoneEnterMessage.Length > 0) {
                            List<string> arglist = zone_args.ToList();
                            arglist.Add("enter_message");
                            arglist.Add(configData.Options.TownZoneEnterMessage);
                            zone_args = arglist.ToArray();
                        }
                        if (configData.Options.TownZoneLeaveMessage.Length > 0) {
                            List<string> arglist = zone_args.ToList();
                            arglist.Add("leave_message");
                            arglist.Add(configData.Options.TownZoneLeaveMessage);
                            zone_args = arglist.ToArray();
                        }
                        ZoneManager?.Call("CreateOrUpdateZone", configData.Options.TownZoneId, zone_args, player.transform.position);
                        if (configData.Options.TownZoneFlags.Count > 0) {
                            foreach (string flag in configData.Options.TownZoneFlags) {
                                ZoneManager?.Call("AddFlag", configData.Options.TownZoneId, flag);
                            }
                        }
                    }
                    Interface.CallHook("OnTownSet", player.transform.position);
                    break;
                    case "bandit" : Message(iplayer, "banditset", player.transform.position.ToString());
                    break;
                    case "outpost" : Message(iplayer, "outpostset", player.transform.position.ToString());
                    break;
                }
                return;
            }
            switch (command) {
                case "tunnel" : if (!iplayer.HasPermission(permTP_Tunnel)) {
                    Message(iplayer, "notauthorized");
                    return;
                }
                string dtarget = null;
                if (args.Length > 0) {
                    dtarget = string.Join(" ", args);
                }
                if (dtarget == null) {
                    string res = "";
                    List<string> tunnels = QuerySingleStringToList("SELECT name FROM rtp_server WHERE name LIKE '%Tunnel%' ORDER BY name");
                    if (tunnels.Count > 0) {
                        foreach (string tun in tunnels) {
                            string nm = tun.Replace("Tunnel", "");
                            res += $" {nm}\n";
                        }
                    }
                    Message(iplayer, "tunnels", res);
                    return;
                }
                const string dtype = "Tunnel";
                List<string> tunnel = QuerySingleStringToList($"SELECT location FROM rtp_server WHERE name='Tunnel {dtarget}'");
                if (tunnel.Count > 0) {
                    if (CanTeleport(player, tunnel[0], dtype)) {
                        if (!TeleportTimers.ContainsKey(player.userID)) {
                            AddTimer(player, StringToVector3(tunnel[0]), dtype, Lang("town"));
                            HandleTimer(player.userID, dtype, true);
                            CreateCooldown(iplayer.Object as BasePlayer, "Town");
                            if (!DailyUsage["Town"].ContainsKey(player.userID)) DailyUsage["Town"].Add(playe
// ... [Code preview truncated due to length. Full source in attached file] ...

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