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

FREE RustApp : 2.5.4 2.5.4

Нет прав для скачивания
C#:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using ConVar;
using JetBrains.Annotations;
using Network;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Libraries;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Rust;
using Steamworks;
using Unity.Collections;
using UnityEngine;
using UnityEngine.Networking;
using Color = System.Drawing.Color;
using Graphics = System.Drawing.Graphics;
using Pool = Facepunch.Pool;
using Star = ProtoBuf.PatternFirework.Star;
namespace Oxide.Plugins {
    [Info("RustApp", "RustApp.io", "2.5.4")]
    public class RustApp : RustPlugin {
#region Variables
        // References to other plugin with API
        [PluginReference]
        private Plugin NoEscape, RaidZone, RaidBlock, MultiFighting, TGPP, ExtRaidBlock;
        private static MetaInfo _MetaInfo = MetaInfo.Read();
        private static CheckInfo _CheckInfo = CheckInfo.Read();
        private static bool _TempWipeMarker = false;
        private static RustApp _RustApp;
        private static Configuration _Settings;
        private static RustAppEngine _RustAppEngine;
        private static JsonSerializer _jsonSerializer = JsonSerializer.CreateDefault(null);
        private static (string name, string value)[] _ApiHeaders = Array.Empty<(string, string)>();
#endregion
#region Web API
        private static class Api {
            public static bool ErrorContains(string error, string text) {
                return error.Contains(text, StringComparison.OrdinalIgnoreCase);
            }
        }
        private static class CourtApi {
#region Shared
            public class PluginServerDto {
                public string name = ConVar.Server.hostname;
                public string hostname = ConVar.Server.hostname;
                public string level = SteamServer.MapName ?? ConVar.Server.level;
                public string level_url = ConVar.Server.levelurl;
                // Thanks for the information, DezLife
                public string level_image_url = MapUploader.ImageUrl;
                public string description = ConVar.Server.description + " " + ConVar.Server.motd;
                public string branch = ConVar.Server.branch;
                public string avatar_big = ConVar.Server.logoimage;
                public string avatar_url = ConVar.Server.logoimage;
                public string banner_url = ConVar.Server.headerimage;
                public int online = BasePlayer.activePlayerList.Count + ServerMgr.Instance.connectionQueue.queue.Count + ServerMgr.Instance.connectionQueue.joining.Count;
                public int slots = ConVar.Server.maxplayers;
                public int reserved = ServerMgr.Instance.connectionQueue.ReservedCount;
                public string version = _RustApp.Version.ToString();
                public string protocol = Protocol.printable.ToString();
                public string performance = _RustApp.TotalHookTime.ToString();
                public int port = ConVar.Server.port;
                public bool connected = _RustAppEngine?.AuthWorker.IsAuthed ?? false;
            }
#endregion
            private static string BaseUrl => _Settings?.admin_panel_api_url ?? "https://court.rustapp.io";
#region GetServerInfo
            public static StableRequest<object> GetServerInfo() {
                return new StableRequest<object>($"{BaseUrl}/plugin/", RequestMethod.GET, null);
            }
#endregion
#region SendPairDetails
            public class PluginPairPayload : PluginServerDto {
            }
            public class PluginPairResponse {
                [CanBeNull]
                public int ttl;
                [CanBeNull]
                public string token;
            }
            public static StableRequest<PluginPairResponse> SendPairDetails(string code) {
                return new StableRequest<PluginPairResponse>($"{BaseUrl}/plugin/pair?code={code}", RequestMethod.POST, new PluginPairPayload());
            }
#endregion
#region StateUpdate
            public class PluginStatePlayerMetaDto {
                public Dictionary<string, string> tags = new Dictionary<string, string>();
                public Dictionary<string, string> fields = new Dictionary<string, string>();
            }
            public static Dictionary<ulong, PluginStatePlayerDto> players = new Dictionary<ulong, PluginStatePlayerDto>();
            public class PluginStatePlayerDto {
                public static PluginStatePlayerDto FromConnection(Network.Connection connection, string status) {
                    var userid = connection.userid;
                    if (!players.TryGetValue(userid, out var payload)) {
                        payload = new PluginStatePlayerDto();
                        players[userid] = payload;
                        payload.steam_id = connection.player is BasePlayer basePlayer ? basePlayer.UserIDString : userid.ToString();
                        payload.steam_name = connection.username.Replace("<blank>", "blank");
                        payload.ip = IPAddressWithoutPort(connection.ipaddress);
                        payload.no_license = DetectNoLicense(connection);
                        payload.team = new List<string>();
                    }
                    payload.ping = Network.Net.sv.GetAveragePing(connection);
                    payload.seconds_connected = (int)connection.GetSecondsConnected();
                    payload.language = _RustApp.lang.GetLanguage(payload.steam_id);
                    payload.status = status;
                    try {
                        payload.meta = CollectPlayerMeta(payload.steam_id, payload.meta);
                    }
                    catch {
                    }
                    payload.team.Clear();
                    var newTeam = RelationshipManager.ServerInstance.FindPlayersTeam(userid);
                    if (newTeam == null) {
                        return payload;
                    }
                    foreach (var member in newTeam.members) {
                        if (member != userid) {
                            payload.team.Add(member.ToString());
                        }
                    }
                    return payload;
                }
                public static PluginStatePlayerDto FromPlayer(BasePlayer player) {
                    var payload = FromConnection(player.Connection, "active");
                    payload.position = player.transform.position.ToString();
                    payload.rotation = player.eyes.rotation.ToString();
                    payload.coords = MapHelper.PositionToString(player.transform.position);
                    payload.can_build = DetectBuildingAuth(player);
                    payload.is_raiding = DetectIsRaidBlock(player);
                    payload.is_alive = player.IsAlive();
                    return payload;
                }
                public string steam_id;
                public string steam_name;
                public string ip;
                public int ping = 0;
                public int seconds_connected;
                public string language;
                [CanBeNull]
                public string position;
                [CanBeNull]
                public string rotation;
                [CanBeNull]
                public string coords;
                public bool can_build = false;
                public bool is_raiding = false;
                public bool no_license = false;
                public bool is_alive = false;
                public string status;
                public PluginStatePlayerMetaDto meta = new PluginStatePlayerMetaDto();
                public List<string> team;
            }
            public class PluginStateUpdatePayload : PluginServerDto {
                public PluginServerDto server_info = new PluginServerDto();
                public List<PluginStatePlayerDto> players;
                public Dictionary<string, string> disconnected;
                public Dictionary<string, string> team_changes;
            }
            public static StableRequest<object> SendStateUpdate(PluginStateUpdatePayload data) {
                return new StableRequest<object>($"{BaseUrl}/plugin/state", RequestMethod.PUT, data);
            }
#endregion
#region SendChatMessages
            public class PluginChatMessageDto {
                public string steam_id;
                [CanBeNull]
                public string target_steam_id;
                public bool is_team;
                public string text;
            }
            public class PluginChatMessagePayload {
                public List<PluginChatMessageDto> messages;
            }
            public static StableRequest<object> SendChatMessages(PluginChatMessagePayload payload) {
                return new StableRequest<object>($"{BaseUrl}/plugin/chat", RequestMethod.POST, payload);
            }
#endregion
#region SendReports
            public class PluginReportDto {
                public string initiator_steam_id;
                [CanBeNull]
                public string target_steam_id;
                public List<string> sub_targets_steam_ids;
                public string reason;
                [CanBeNull]
                public string message;
            }
            public class PluginReportBatchPayload {
                public List<CourtApi.PluginReportDto> reports;
            }
            public static StableRequest<object> SendReports(PluginReportBatchPayload payload) {
                return new StableRequest<object>($"{BaseUrl}/plugin/reports", RequestMethod.POST, payload);
            }
#endregion
#region SendContact
            public static StableRequest<object> SendContact(string steamId, string contact) {
                return new StableRequest<object>($"{BaseUrl}/plugin/contact", RequestMethod.POST, new {
                    steam_id = steamId, message = contact
                }
                );
            }
#endregion
#region SendWipe
            public static StableRequest<object> SendWipe() {
                return new StableRequest<object>($"{BaseUrl}/plugin/wipe", RequestMethod.POST, null);
            }
#endregion
#region Sleeping bag
            public class PluginSleepingBagDto {
                public string initiator_steam_id;
                public string target_steam_id;
                public string position;
                public bool are_friends;
            }
            public class PluginSleepingBagBatchDto {
                public List<PluginSleepingBagDto> sleeping_bags = new List<PluginSleepingBagDto>();
            }
            public static StableRequest<object> SleepingBagCreate(PluginSleepingBagBatchDto payload) {
                return new StableRequest<object>($"{BaseUrl}/plugin/sleeping-bag", RequestMethod.POST, payload);
            }
#endregion
#region BanCreate
            public class PluginBanCreatePayload {
                public string target_steam_id;
                public string reason;
                public bool global;
                public bool ban_ip;
                public string duration;
                public string comment;
            }
            public static StableRequest<object> BanCreate(PluginBanCreatePayload payload) {
                return new StableRequest<object>($"{BaseUrl}/plugin/ban", RequestMethod.POST, payload);
            }
#endregion
#region BanDelete
            public static StableRequest<object> BanDelete(string steamId) {
                return new StableRequest<object>($"{BaseUrl}/plugin/unban", RequestMethod.POST, new {
                    target_steam_id = steamId
                }
                );
            }
#endregion
#region PlayerAlert
            public static class PluginPlayerAlertType {
                public static readonly string join_with_ip_ban = "join_with_ip_ban";
                public static readonly string custom_api = "custom_api";
            }
            public class PluginPlayerAlertDto {
                public string type;
                public object meta;
            }
            public class PluginPlayerAlertJoinWithIpBanMeta {
                public string steam_id;
                public string ip;
                public int ban_id;
            }
            public class PluginPlayerAlertDugUpStashMeta {
                public string steam_id;
                public string owner_steam_id;
                public string position;
                public string square;
            }
            public static StableRequest<object> CreatePlayerAlerts(List<PluginPlayerAlertDto> alerts) {
                return new StableRequest<object>($"{BaseUrl}/plugin/alerts", RequestMethod.POST, new {
                    alerts
                }
                );
            }
#endregion
#region PlayerAlertCustom
            public class PluginPlayerAlertCustomDto {
                public string msg;
                public object data;
                public string custom_icon;
                public bool hide_in_table = false;
                public string category;
                public List<string> custom_links;
            }
            public class PluginPlayerAlertCustomAlertMeta {
                public string name = "";
                public string custom_icon = null;
                public List<string> custom_links = null;
            }
            public static StableRequest<object> CreatePlayerAlertsCustom(PluginPlayerAlertCustomDto payload) {
                return new StableRequest<object>($"{BaseUrl}/plugin/custom-alert", RequestMethod.POST, payload);
            }
#endregion
#region SendSignage
            public class PluginSignageCreateDto {
                public string steam_id;
                public ulong net_id;
                public byte[] base64_image;
                public string type;
                public string position;
                public string square;
            }
            public static StableRequest<object> SendSignage(PluginSignageCreateDto payload) {
                return new StableRequest<object>($"{BaseUrl}/plugin/signage", RequestMethod.POST, payload);
            }
#endregion
#region SendSignageDestroyed
            public class SignageDestroyedDto {
                public List<string> net_ids;
            }
            public static StableRequest<object> SendSignageDestroyed(SignageDestroyedDto payload) {
                return new StableRequest<object>($"{BaseUrl}/plugin/signage", RequestMethod.DELETE, payload);
            }
#endregion
#region SendKills
            public class PluginKillsDto {
                public List<PluginKillEntryDto> kills;
            }
            public class PluginKillEntryDto {
                public string initiator_steam_id;
                public string target_steam_id;
                public string game_time;
                public float distance;
                public string weapon;
                public bool is_headshot;
                public List<CombatLogEventDto> hit_history;
            }
            public class CombatLogEventDto {
                public float time;
                public string attacker_steam_id;
                public string target_steam_id;
                public string attacker;
                public string target;
                public string weapon;
                public string ammo;
                public string bone;
                public float distance;
                public float hp_old;
                public float hp_new;
                public string info;
                public int proj_hits;
                public float pi;
                public float proj_travel;
                public float pm;
                public int desync;
                public bool ad;
                public CombatLogEventDto(float time, CombatLog.Event ev) {
                    if (ev.attacker == "player") {
                        var attacker = BaseNetworkable.serverEntities.Find(new NetworkableId(ev.attacker_id)) as BasePlayer;
                        ;
                        this.attacker_steam_id = attacker?.UserIDString ?? "";
                    }
                    if (ev.target == "player") {
                        var target = BaseNetworkable.serverEntities.Find(new NetworkableId(ev.target_id)) as BasePlayer;
                        this.target_steam_id = target?.UserIDString ?? "";
                    }
                    this.time = time - ev.time;
                    this.attacker = ev.attacker;
                    this.target = ev.target;
                    this.weapon = ev.weapon;
                    this.ammo = ev.ammo;
                    this.bone = ev.bone;
                    this.distance = (float)Math.Round(ev.distance, 2);
                    this.hp_old = (float)Math.Round(ev.health_old, 2);
                    this.hp_new = (float)Math.Round(ev.health_new, 2);
                    this.info = ev.info;
                    this.proj_hits = ev.proj_hits;
                    this.proj_travel = ev.proj_travel;
                    this.desync = ev.desync;
                    this.pi = ev.proj_integrity;
                    this.pm = ev.proj_mismatch;
                    this.ad = ev.attacker_dead;
                }
                public string getInitiator() {
                    if (this.attacker != "player") {
                        return this.attacker;
                    }
                    return this.attacker_steam_id;
                }
                public string getTarget() {
                    if (this.target != "player") {
                        return this.target;
                    }
                    return this.target_steam_id;
                }
            }
            public static StableRequest<object> SendKills(PluginKillsDto payload) {
                return new StableRequest<object>($"{BaseUrl}/plugin/kills", RequestMethod.POST, payload);
            }
#endregion
#region PlayerMuteGetActive
            public class PlayerMuteDto {
                public string target_steam_id;
                public string reason;
                public long left_time_ms;
                public long received_at = DateTimeOffset.Now.ToUnixTimeMilliseconds();
                private long GetExpiredAt() {
                    return received_at + left_time_ms;
                }
                public string GetLeftTime() {
                    var leftMs = LeftSeconds();
                    if (leftMs <= 0) return RustApp._RustApp.lang.GetMessage("Time.Seconds", RustApp._RustApp, null).Replace("%COUNT%", "0");
                    var time = TimeSpan.FromMilliseconds(leftMs);
                    var parts = new List<string>();
                    if (time.Days > 0) parts.Add(RustApp._RustApp.lang.GetMessage("Time.Days", RustApp._RustApp, null).Replace("%COUNT%", time.Days.ToString()));
                    if (time.Hours > 0) parts.Add(RustApp._RustApp.lang.GetMessage("Time.Hours", RustApp._RustApp, null).Replace("%COUNT%", time.Hours.ToString()));
                    if (time.Minutes > 0) parts.Add(RustApp._RustApp.lang.GetMessage("Time.Minutes", RustApp._RustApp, null).Replace("%COUNT%", time.Minutes.ToString()));
                    if (time.Seconds > 0) parts.Add(RustApp._RustApp.lang.GetMessage("Time.Seconds", RustApp._RustApp, null).Replace("%COUNT%", time.Seconds.ToString()));
                    return string.Join(", ", parts);
                }
                public string GetUnmuteDate() {
                    var date = DateTimeOffset.FromUnixTimeMilliseconds(GetExpiredAt());
                    return $"{date.DateTime.ToShortDateString()} {date.DateTime.ToShortTimeString()}";
                }
                public long LeftSeconds() {
                    return GetExpiredAt() - DateTimeOffset.Now.ToUnixTimeMilliseconds();
                }
            }
            public class PlayerMuteDtoIn {
                public List<PlayerMuteDto> data;
            }
            public static StableRequest<PlayerMuteDtoIn> PlayerMuteGetActive() {
                return new StableRequest<PlayerMuteDtoIn>($"{BaseUrl}/plugin/player-mute/get-active", RequestMethod.GET, null);
            }
#endregion
#region PlayerMuteCreate
            public class PlayerMuteCreateDto {
                public string target_steam_id;
                public string reason;
                public string duration;
                public bool broadcast;
                [CanBeNull]
                public string comment;
                [CanBeNull]
                public string references_message;
            }
            public static StableRequest<object> PlayerMuteCreate(PlayerMuteCreateDto data) {
                return new StableRequest<object>($"{BaseUrl}/plugin/player-mute/mute-player", RequestMethod.POST, data);
            }
#endregion
#region PlayerMuteDelete
            public class PlayerMuteDeleteDto {
                public string target_steam_id;
            }
            public static StableRequest<object> PlayerMuteDelete(PlayerMuteDeleteDto data) {
                return new StableRequest<object>($"{BaseUrl}/plugin/player-mute/unmute-player", RequestMethod.POST, data);
            }
#endregion
        }
        private static class QueueApi {
#region Shared
            public class QueueTaskResponse {
                public string id;
                public QueueTaskRequestConfigDto request;
            }
            public class QueueTaskRequestConfigDto {
                public string name;
                public JObject data;
            }
#endregion
            private static string BaseUrl => _Settings?.admin_panel_queue_url ?? "https://queue.rustapp.io";
#region GetQueueTasks
            public static StableRequest<List<QueueTaskResponse>> GetQueueTasks() {
                return new StableRequest<List<QueueTaskResponse>>($"{BaseUrl}/", RequestMethod.GET, null);
            }
#endregion
#region ProcessQueueTasks
            public class QueueTaskResponsePayload {
                public Dictionary<string, object> data;
            }
            public static StableRequest<object> ProcessQueueTasks(QueueTaskResponsePayload payload) {
                return new StableRequest<object>($"{BaseUrl}/", RequestMethod.PUT, payload);
            }
#endregion
        }
        private static class BanApi {
            private static string BaseUrl => _Settings?.admin_panel_ban_url ?? "https://ban.rustapp.io";
#region BanGetBatch
            public class BanGetBatchEntryPayloadDto {
                public string steam_id;
                public string ip;
            }
            public class BanGetBatchPayload {
                public List<BanGetBatchEntryPayloadDto> players;
            }
            public class BanGetBatchEntryResponseDto {
                public string steam_id;
                public string ip;
                public List<BanDto> bans;
            }
            public class BanDto {
                public int id;
                public string steam_id;
                public string ban_ip;
                public string reason;
                public long expired_at;
                public bool ban_ip_active;
                public bool computed_is_active;
                public int sync_project_id = 0;
                public bool sync_should_kick = false;
            }
            public class BanGetBatchResponse {
                public List<BanGetBatchEntryResponseDto> entries;
            }
            public static StableRequest<BanGetBatchResponse> BanGetBatch(BanGetBatchPayload payload) {
                return new StableRequest<BanGetBatchResponse>($"{BaseUrl}/plugin/v2", RequestMethod.POST, payload);
            }
#endregion
        }
#endregion
#region Configuration
        public class MetaInfo {
            public static MetaInfo Read() {
                if (!Interface.Oxide.DataFileSystem.ExistsDatafile("RustApp_Configuration")) {
                    _MetaInfo = null;
                    return null;
                }
                var obj = Interface.Oxide.DataFileSystem.ReadObject<MetaInfo>("RustApp_Configuration");
                _MetaInfo = obj;
                return obj;
            }
            public static void write(MetaInfo courtMeta) {
                Interface.Oxide.DataFileSystem.WriteObject("RustApp_Configuration", courtMeta);
                MetaInfo.Read();
            }
            [JsonProperty("It is access for RustApp Court, never edit or share it")]
            public string Value;
        }
        public class CheckInfo {
            public static CheckInfo Read() {
                if (!Interface.Oxide.DataFileSystem.ExistsDatafile("RustApp_CheckMeta")) {
                    return new CheckInfo();
                }
                return Interface.Oxide.DataFileSystem.ReadObject<CheckInfo>("RustApp_CheckMeta");
            }
            public static void write(CheckInfo courtMeta) {
                // Clear checks > 30 days ago
                courtMeta.LastChecks = courtMeta.LastChecks.Where(v => _RustApp.CurrentTime() - v.Value < 30 * 24 * 60 * 60).ToDictionary(v => v.Key, v => v.Value);
                Interface.Oxide.DataFileSystem.WriteObject("RustApp_CheckMeta", courtMeta);
            }
            [JsonProperty("List of recent checks to show green-check on player")]
            public Dictionary<string, double> LastChecks = new Dictionary<string, double>();
        }
        private class Configuration {
            [JsonProperty("[UI] Chat commands")]
            public List<string> report_ui_commands = new List<string>();
            [JsonProperty("[UI] Report reasons")]
            public List<string> report_ui_reasons = new List<string>();
            [JsonProperty("[UI] Cooldown between reports (seconds)")]
            public int report_ui_cooldown = 300;
            [JsonProperty("[UI] Auto-parse reports from F7 (ingame reports)")]
            public bool report_ui_auto_parse = true;
            [JsonProperty("[UI • Starter Plan] Show 'recently checked' checkbox (amount of days)")]
            public int report_ui_show_check_in = 7;
            [JsonProperty("[Chat] SteamID for message avatar (default account contains RustApp logo)")]
            public string chat_default_avatar_steamid = "76561198134964268";
            [JsonProperty("[Check] Command to send contact")]
            public string check_contact_command = "contact";
            [JsonProperty("[Components • Custom actions] Allow console command execution")]
            public bool components_custom_actions_enabled = true;
            [JsonProperty("[Components • Signages] Collect signages")]
            public bool components_signages_enabled = true;
            [JsonProperty("[Components • Kills] Collect kills")]
            public bool components_kills_enabled = true;
            [JsonProperty("[Components • Mutes] Support mutes system")]
            public bool components_mutes_enabled = true;
            [JsonProperty("[Admin panel] API URL")]
            public string admin_panel_api_url = "http://127.0.0.1:3000/api/rust";
            [JsonProperty("[Admin panel] Queue URL")]
            public string admin_panel_queue_url = "http://127.0.0.1:3000/api/rust/queue";
            [JsonProperty("[Admin panel] Ban API URL")]
            public string admin_panel_ban_url = "http://127.0.0.1:3000/api/rust/ban";
            public static Configuration Generate() {
                return new Configuration {
                    report_ui_commands = new List<string> {
                        "report", "reports"
                    }
                    , report_ui_reasons = new List<string> {
                        "Cheat", "Macros", "Abuse"
                    }
                    , report_ui_cooldown = 300, report_ui_auto_parse = true, report_ui_show_check_in = 7, chat_default_avatar_steamid = "76561198134964268", components_custom_actions_enabled = true, components_kills_enabled = true, components_signages_enabled = true, components_mutes_enabled = true, admin_panel_api_url = "http://127.0.0.1:3000/api/rust", admin_panel_queue_url = "http://127.0.0.1:3000/api/rust/queue", admin_panel_ban_url = "http://127.0.0.1:3000/api/rust/ban",
                }
                ;
            }
        }
#endregion
#region Workers
        private class RustAppEngine : RustAppWorker {
            public GameObject ChildObjectToWorkers;
            public AuthWorker? AuthWorker;
            public BanWorker? BanWorker;
            public StateWorker? StateWorker;
            public CheckWorker? CheckWorker;
            public QueueWorker? QueueWorker;
            public ChatWorker? ChatWorker;
            public ReportWorker? ReportWorker;
            public PlayerAlertsWorker? PlayerAlertsWorker;
            public SignageWorker? SignageWorker;
            public KillsWorker? KillsWorker;
            public PlayerMuteWorker? PlayerMuteWorker;
            public SleepingBagWorker? SleepingBagWorker;
            private void Awake() {
                base.Awake();
                SetupAuthWorker();
            }
            public bool IsPairingNow() {
                return this.gameObject.GetComponent<PairWorker>() != null;
            }
            private void SetupAuthWorker() {
                SetupHeaders();
                AuthWorker = this.gameObject.AddComponent<AuthWorker>();
                AuthWorker.OnAuthSuccess += () => {
                    Trace("Authed success, components enabled");
                    CreateSubWorkers();
                }
                ;
                AuthWorker.OnAuthFailed += () => {
                    Trace("Auth failed, components disabled");
                    DestroySubWorkers();
                }
                ;
                AuthWorker.CycleAuthUpdate();
            }
            public void SetupHeaders() {
                _ApiHeaders = new[] {
                    ("x-plugin-auth", _MetaInfo?.Value ?? ""), ("x-plugin-version", _RustApp.Version.ToString()), ("x-plugin-port", ConVar.Server.port.ToString()), ("Content-Type", "application/json")
                }
                ;
            }
            private void CreateSubWorkers() {
                ChildObjectToWorkers = this.gameObject.CreateChild();
                StateWorker = ChildObjectToWorkers.AddComponent<StateWorker>();
                CheckWorker = ChildObjectToWorkers.AddComponent<CheckWorker>();
                QueueWorker = ChildObjectToWorkers.AddComponent<QueueWorker>();
                ChatWorker = ChildObjectToWorkers.AddComponent<ChatWorker>();
                BanWorker = ChildObjectToWorkers.AddComponent<BanWorker>();
                ReportWorker = ChildObjectToWorkers.AddComponent<ReportWorker>();
                PlayerAlertsWorker = ChildObjectToWorkers.AddComponent<PlayerAlertsWorker>();
                SignageWorker = ChildObjectToWorkers.AddComponent<SignageWorker>();
                KillsWorker = ChildObjectToWorkers.AddComponent<KillsWorker>();
                PlayerMuteWorker = ChildObjectToWorkers.AddComponent<PlayerMuteWorker>();
                SleepingBagWorker = ChildObjectToWorkers.AddComponent<SleepingBagWorker>();
            }
            private void DestroySubWorkers() {
                if (ChildObjectToWorkers == null) {
                    return;
                }
                UnityEngine.Object.Destroy(ChildObjectToWorkers);
            }
        }
        private class AuthWorker : RustAppWorker {
            public bool? IsAuthed;
            public Action? OnAuthSuccess;
            public Action? OnAuthFailed;
            public void CycleAuthUpdate() {
                InvokeRepeating(nameof(CheckAuthStatus), 0f, 5f);
            }
            public void CheckAuthStatus() {
                Action onError = () => {
                    if (IsAuthed == false) {
                        return;
                    }
                    IsAuthed = false;
                    OnAuthFailed?.Invoke();
                }
                ;
                Action onSuccess = () => {
                    if (IsAuthed == true) {
                        return;
                    }
                    Log("Connection to the service established");
                    IsAuthed = true;
                    OnAuthSuccess?.Invoke();
                    if (_TempWipeMarker) {
                        _TempWipeMarker = false;
                        CourtApi.SendWipe().Execute();
                    }
                }
                ;
                CourtApi.GetServerInfo().Execute(() => {
                    onSuccess();
                    return;
                }
                , (err) => {
                    // secret = ""
                    var codeError1 = Api.ErrorContains(err, "some of required headers are wrong or missing");
                    // secret = "123"
                    var codeError2 = Api.ErrorContains(err, "authorization secret is corrupted");
                    // server.ip != this.ip || server.port != this.port
                    var codeError3 = Api.ErrorContains(err, "Check server configuration, required");
                    if (codeError1 || codeError2 || codeError3) {
                        if (IsAuthed != false) {
                            Error("Your server is not paired with our network, follow instructions to pair server:");
                            Error("1. If you already start pairing, enter 'ra.pair %code%' which you get from our site");
                            Error("2. Open servers page, press 'connect server', and enter command which you get on it");
                        }
                        onError();
                        return;
                    }
                    // version < minVersion
                    var versionError1 = Api.ErrorContains(err, " is lower than minimal: ");
                    // if we block some version
                    var versionError2 = Api.ErrorContains(err, "This version contains serious bug, please update plugin");
                    if (versionError1 || versionError2) {
                        Error("Your plugin is outdated, you should download new version!");
                        Error("1. Open servers page, press 'update' near server to download new version, then just replace plugin");
                        Error("2. If you don't have 'update' button, press settings icon and choose 'download plugin' button");
                        onError();
                        return;
                    }
                    // if tariff finished/balance zero
                    var paymentError1 = Api.ErrorContains(err, "У вас кончились средства на балансе проекта, пополните на");
                    // If some limits broken
                    var paymentError2 = Api.ErrorContains(err, "Вы превысили лимиты по");
                    if (paymentError1) {
                        Error("Your balance is not enough to continue working with our service, top-up it");
                        onError();
                        return;
                    }
                    if (paymentError2) {
                        Error("You have reached your limits, please upgrade your plan");
                        onError();
                        return;
                    }
                    Debug($"Unknown exception in auth: {err}");
                }
                );
            }
        }
        private class PairWorker : RustAppWorker {
            private string EnteredCode;
            public void StartPairing(string code) {
                EnteredCode = code;
                CourtApi.SendPairDetails(EnteredCode).Execute(() => {
                    InvokeRepeating(nameof(WaitPairFinish), 0f, 1f);
                }
                , (err) => {
                    if (Api.ErrorContains(err, "code not exists")) {
                        Error("Pairing failed: requested code not exists");
                    }
                    else if (Api.ErrorContains(err, "pairing prevented from abuse")) {
                        Error("Pairing failed: seems this server was already connected to another project, please contact TG: @rustapp_help if you think, that it is wrong");
                    }
                    else {
                        Debug($"Pairing failed: unknown exception {err}");
                    }
                    Destroy(this);
                }
                );
            }
            public void WaitPairFinish() {
                CourtApi.SendPairDetails(EnteredCode).Execute((data) => {
                    if (data?.token == null || data.token.Length == 0) {
                        Log("Complete pairing on site...");
                        return;
                    }
                    Action saveData = () => {
                        MetaInfo.write(new MetaInfo {
                            Value = data.token
                        }
                        );
                        _RustApp.timer.Once(1f, () => _RustAppEngine?.AuthWorker?.CheckAuthStatus());
                        _MetaInfo = MetaInfo.Read();
                        _RustAppEngine.SetupHeaders();
                        Log("Pairing completed, reloading...");
                        Destroy(this);
                    }
                    ;
                    if (_RustAppEngine?.StateWorker != null) {
                        _RustAppEngine?.StateWorker?.SendUpdate(() => saveData());
                    }
                    else {
                        saveData();
                    }
                }
                , (err) => {
                    if (Api.ErrorContains(err, "code not exists")) {
                        Error("Pairing failed: seems you closed modal on site");
                    }
                    else {
                        Error($"Pairing failed: unknown exception {err}");
                    }
                    Destroy(this);
                }
                );
            }
        }
        private class StateWorker : RustAppWorker {
            public Dictionary<string, string> DisconnectReasons = new Dictionary<string, string>();
            public Dictionary<string, string> TeamChanges = new Dictionary<string, string>();
            private void Awake() {
                base.Awake();
                InvokeRepeating(nameof(CycleSendUpdate), 0f, 5f);
            }
            public void CycleSendUpdate() {
                SendUpdate();
            }
            public void SendUpdate(Action? onFinished = null) {
                var players = Pool.Get<List<CourtApi.PluginStatePlayerDto>>();
                CollectPlayers(players);
                var disconnected = Pool.Get<Dictionary<string, string>>();
                ResurrectDictionary(DisconnectReasons, disconnected);
                var teamChanges = Pool.Get<Dictionary<string, string>>();
                ResurrectDictionary(TeamChanges, teamChanges);
                DisconnectReasons.Clear();
                TeamChanges.Clear();
                CourtApi.SendStateUpdate(new CourtApi.PluginStateUpdatePayload {
                    players = players, disconnected = disconnected, team_changes = teamChanges
                }
                ).Execute(() => {
                    Pool.FreeUnmanaged(ref disconnected);
                    Pool.FreeUnmanaged(ref teamChanges);
                    Trace("State was sent successfull");
                    onFinished?.Invoke();
                }
                , (err) => {
                    onFinished?.Invoke();
                    Debug($"State sent error: {err}");
                    ResurrectDictionary(disconnected, DisconnectReasons);
                    Pool.FreeUnmanaged(ref disconnected);
                    ResurrectDictionary(teamChanges, TeamChanges);
                    Pool.FreeUnmanaged(ref teamChanges);
                }
                );
                Pool.FreeUnmanaged(ref players);
            }
            private void CollectPlayers(List<CourtApi.PluginStatePlayerDto> playerStateDtos) {
                foreach (var player in BasePlayer.activePlayerList) {
                    try {
                        playerStateDtos.Add(CourtApi.PluginStatePlayerDto.FromPlayer(player));
                    }
                    catch {
                    }
                }
                foreach (var connection in ServerMgr.Instance.connectionQueue.joining) {
                    try {
                        playerStateDtos.Add(CourtApi.PluginStatePlayerDto.FromConnection(connection, "joining"));
                    }
                    catch {
                    }
                }
                foreach (var connection in ServerMgr.Instance.connectionQueue.queue) {
                    if (connection == null) {
                        continue;
                    }
                    try {
                        playerStateDtos.Add(CourtApi.PluginStatePlayerDto.FromConnection(connection, "queued"));
                    }
                    catch {
                    }
                }
            }
            private void CollectFakeDisconnects(Dictionary<string, string> disconnect) {
                foreach (var player in BasePlayer.activePlayerList) {
                    try {
                        disconnect.Add(player.UserIDString, "plugin-unload");
                    }
                    catch {
                    }
                }
                foreach (var connection in ServerMgr.Instance.connectionQueue.joining) {
                    try {
                        disconnect.Add(connection.userid.ToString(), "plugin-unload");
                    }
                    catch {
                    }
                }
                foreach (var connection in ServerMgr.Instance.connectionQueue.queue) {
                    if (connection == null) {
                        continue;
                    }
                    try {
                        disconnect.Add(connection.userid.ToString(), "plugin-unload");
                    }
                    catch {
                    }
                }
            }
            public void OnDestroy() {
                base.OnDestroy();
            }
        }
        private class CheckWorker : RustAppWorker {
            private Dictionary<string, bool> ShowedNoticyCache = new Dictionary<string, bool>();
            public bool IsNoticeActive(string steamId) {
                if (!ShowedNoticyCache.TryGetValue(steamId, out var value)) {
                    return false;
                }
                return value;
            }
            public void SetNoticeActive(string steamId, bool value) {
                BasePlayer player = null;
                if (ulong.TryParse(steamId, out var userid)) {
                    player = BasePlayer.FindByID(userid);
                }
                if (player != null) {
                    // TODO: Deprecated
                    if (value) {
                        Interface.Oxide.CallHook("RustApp_OnCheckNoticeShowed", player);
                    }
                    else {
                        Interface.Oxide.CallHook("RustApp_OnCheckNoticeHidden", player);
                    }
                }
                // TODO: New hook
                Interface.Oxide.CallHook("RustApp_CheckNoticeState", steamId, value);
                ShowedNoticyCache[steamId] = value;
                if (player != null) {
                    if (value) {
                        _RustApp.DrawNoticeInterface(player);
                    }
                    else {
                        CuiHelper.DestroyUi(player, CheckLayer);
                    }
                }
            }
            public void OnDestroy() {
                base.OnDestroy();
                foreach (var check in ShowedNoticyCache.ToList()) {
                    if (check.Value == false) {
                        continue;
                    }
                    SetNoticeActive(check.Key, false);
                }
            }
        }
        private class QueueWorker : RustAppWorker {
            private List<string> QueueProcessedIds = new List<string>();
            private void Awake() {
                base.Awake();
                InvokeRepeating(nameof(GetQueueTasks), 0f, 2f);
            }
            private void GetQueueTasks() {
                QueueApi.GetQueueTasks().Execute(CallQueueTasks, (error) => {
                    Debug($"Queue retreive failed {error}");
                }
                );
            }
            private void CallQueueTasks(List<QueueApi.QueueTaskResponse> queuesTasks) {
                if (queuesTasks == null || queuesTasks.Count == 0) {
                    return;
                }
                Dictionary<string, object> queueResponses = new Dictionary<string, object>();
                foreach (var task in queuesTasks) {
                    if (QueueProcessedIds.Contains(task.id)) {
                        Debug($"This task was already processed: {task.id}");
                        return;
                    }
                    try {
                        Trace($"Calling: {ConvertToRustAppQueueFormat(task.request.name, true)}");
                        // To get our official response
                        var response = (object)_RustApp.Call(ConvertToRustAppQueueFormat(task.request.name, true), task.request.data);
                        QueueProcessedIds.Add(task.id);
                        queueResponses.Add(task.id, response);
                        // Just to broadcast event RustApp_Queue%name%
                        Interface.Oxide.CallHook(ConvertToRustAppQueueFormat(task.request.name, false), task.request.data);
                    }
                    catch (Exception exc) {
                        Error($"Failed to process task {task.id} {task.request.name}: {exc.ToString()}");
                        queueResponses.Add(task.id, null);
                    }
                }
                ProcessQueueTasks(queueResponses);
            }
            private void ProcessQueueTasks(Dictionary<string, object> queueResponses) {
                if (queueResponses.Keys.Count == 0) {
                    return;
                }
                QueueApi.ProcessQueueTasks(new QueueApi.QueueTaskResponsePayload {
                    data = queueResponses
                }
                ).Execute(() => {
                    QueueProcessedIds.Clear();
                    Trace("Ответ по очередям успешно доставлен");
                }
                , (err) => {
                    QueueProcessedIds.Clear();
                    Debug($"Failed to process queue: {err}");
                }
                );
            }
            private string ConvertToRustAppQueueFormat(string input, bool isInternalCall) {
 
// ... [Code preview truncated due to length. Full source in attached file] ...

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