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

FREE OurServers : 0.0.8 0.0.8

Нет прав для скачивания
C#:
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Oxide.Game.Rust.Cui;
using UnityEngine;
namespace Oxide.Plugins {
    [Info("Our Servers", "https://topplugin.ru/", "0.0.8")]
    [Description("Show information about other servers (with fetching current online)")]
    public class OurServers : RustPlugin {
#region Classes
        private class Server {
            [JsonProperty("Name of your server in interface")]
            public string DisplayName;
            [JsonProperty("Description of your server in interface")]
            public string Description;
            [JsonProperty("IP:Port of server (ex: 127.0.0.1:12000)")]
            public string IPAndPort;
            [JsonProperty("Interface width (increase it, if your description is very length)")]
            public int ServerWidth = 250;
            [JsonIgnore]
            public int CurrentOnline;
            [JsonIgnore]
            public int MaxOnline;
            [JsonIgnore]
            public bool Status = false;
            public string IP() => IPAndPort.Split(':')[0];
            public int Port() => int.Parse(IPAndPort.Split(':')[1]);
            public int GetOnline() => Mathf.Min(MaxOnline, CurrentOnline);
            public void UpdateStatus(bool status) => Status = status;
        }
        private class Configuration {
            [JsonProperty("Servers configure")]
            public List<Server> Servers = new List<Server>();
            [JsonProperty("Command to open interface")]
            public string Command = "servers";
            [JsonProperty("Use chat instead of UI")]
            public bool UseChat = false;
            [JsonProperty("Information update interval in seconds (should be > 30)")]
            public int Interval = 60;
            [JsonProperty("Which API to use? (Possible options: steampowered or battlemetrics) (Default: battlemetrics)")]
            public string API = "battlemetrics";
            [JsonProperty("Steampowered API key")]
            public string SteamWebApiKey = "!!! You can get it HERE > https://steamcommunity.com/dev/apikey < and you need to insert HERE !!!";
            public static Configuration Generate() {
                return new Configuration {
                    Servers = new List<Server> {
                        new Server {
                            DisplayName = "UMOD-SERVER #1 - PROCEDURAL", Description = "Example server, with example description", IPAndPort = "8.8.8.8:12000", ServerWidth = 250
                        }
                        , new Server {
                            DisplayName = "UMOD-SERVER #2 - BARREN", Description = "Example server, with example description", IPAndPort = "1.1.1.1:13000"
                        }
                    }
                }
                ;
            }
        }
        public class BattlemetricsApiResponse {
            [JsonProperty("data")]
            public List<ServerData> data;
            public class ServerData {
                [JsonProperty("id")]
                public string id;
                [JsonProperty("type")]
                public string type;
                [JsonProperty("attributes")]
                public Attributes attributes;
                public class Attributes {
                    [JsonProperty("id")]
                    public string id;
                    [JsonProperty("name")]
                    public string name;
                    [JsonProperty("ip")]
                    public string ip;
                    [JsonProperty("port")]
                    public int port;
                    [JsonProperty("portQuery")]
                    public int portQuery;
                    [JsonProperty("players")]
                    public int players;
                    [JsonProperty("maxPlayers")]
                    public int maxPlayers;
                    [JsonProperty("status")]
                    public string status;
                }
            }
        }
        public class SteampoweredApi {
            [JsonProperty("response")]
            public Response response;
            public class Response {
                [JsonProperty("servers")]
                public List<ServerData> servers;
                public class ServerData {
                    [JsonProperty("addr")]
                    public string addr;
                    [JsonProperty("gameport")]
                    public int gameport;
                    [JsonProperty("steamid")]
                    public string steamid;
                    [JsonProperty("name")]
                    public string name;
                    [JsonProperty("appid")]
                    public int appid;
                    [JsonProperty("gamedir")]
                    public string gamedir;
                    [JsonProperty("version")]
                    public string version;
                    [JsonProperty("product")]
                    public string product;
                    [JsonProperty("region")]
                    public int region;
                    [JsonProperty("players")]
                    public int players;
                    [JsonProperty("max_players")]
                    public int max_players;
                    [JsonProperty("bots")]
                    public int bots;
                    [JsonProperty("map")]
                    public string map;
                    [JsonProperty("secure")]
                    public bool secure;
                    [JsonProperty("dedicated")]
                    public bool dedicated;
                    [JsonProperty("os")]
                    public string os;
                    [JsonProperty("gametype")]
                    public string gametype;
                }
            }
        }
#endregion
#region Variables
        // Coroutines
        private Coroutine UpdateAction;
        // Configuration
        private Configuration Settings;
        private bool Initialized;
        private bool Broken;
#endregion
#region Initialization
        protected override void LoadConfig() {
            base.LoadConfig();
            try {
                Settings = Config.ReadObject<Configuration>();
                if (Settings?.Servers == null) LoadDefaultConfig();
                SaveConfig();
                if (Settings.API == "steampowered" && (Settings.SteamWebApiKey == null || Settings.SteamWebApiKey == string.Empty || Settings.SteamWebApiKey.Length != 32)) {
                    PrintError("Steampowered API requires an Steam Web API key to work! Check your configuration!");
                    Broken = true;
                }
            }
            catch {
                PrintError("Error reading config, please check!");
                Broken = true;
            }
        }
        protected override void SaveConfig() => Config.WriteObject(Settings);
        protected override void LoadDefaultConfig() {
            Settings = Configuration.Generate();
            SaveConfig();
        }
        private void OnServerInitialized() {
            if (Broken) return;
            cmd.AddChatCommand(Settings.Command, this, nameof(CmdShowServers));
            if (Settings.Interval < 30) {
                PrintError($"Update interval should be bigger then 30 s!");
                Settings.Interval = 30;
            }
            UpdateAction = ServerMgr.Instance.StartCoroutine(UpdateOnline());
        }
        private void Unload() {
            if (UpdateAction != null) ServerMgr.Instance.StopCoroutine(UpdateAction);
        }
#endregion
#region Functions
        private IEnumerator UpdateOnline() {
            while (true) {
                foreach (var check in Settings.Servers) {
                    if (Settings.API == "steampowered") {
                        string url = $"https://api.steampowered.com/IGameServersService/GetServerList/v1/?format=json&key={Settings.SteamWebApiKey}&filter=\\gameaddr\\{check.IP()}:{check.Port()}";
                        webrequest.Enqueue(url, "", (code, response) => {
                            switch (code) {
                                case 200 : try {
                                    SteampoweredApi data = JsonConvert.DeserializeObject<SteampoweredApi>(response);
                                    if (data.response.servers != null) {
                                        switch (data.response.servers.Count) {
                                            case 1 : SteampoweredApi.Response.ServerData serverData = data.response.servers.Last();
                                            if (serverData.addr != $"{check.IP()}:{check.Port()}") {
                                                PrintError($"Steampowered API: The response from Steampowered does not match the IP or port of the expected server! (Request: {check.IP()}:{check.Port()}, Response: {serverData.addr})");
                                            }
                                            else {
                                                check.CurrentOnline = serverData.players;
                                                check.MaxOnline = serverData.max_players;
                                                check.UpdateStatus(true);
                                                Initialized = true;
                                            }
                                            break;
                                            default : PrintError($"Steampowered API: The number of results is different than expected! Contact the plugin developer! (Server: {check.IP()}:{check.Port()}, Count: {data.response.servers.Count})");
                                            break;
                                        }
                                    }
                                    else {
                                        check.UpdateStatus(false);
                                    }
                                }
                                catch {
                                    PrintError($"Steampowered API: Error parsing response from server.Perhaps the format has changed.Contact the plugin developer!");
                                }
                                break;
                                case 403 : PrintError($"Steampowered API: Invalid Steam Web API key! Check it with your key indicated on the page: https://steamcommunity.com/dev/apikey");
                                break;
                                default : PrintError($"Steampowered API HTTP CODE: {code}");
                                break;
                            }
                        }
                        , this);
                    }
                    else {
                        string url = $"https://api.battlemetrics.com/servers?filter[search]=\"{check.IP()}:{check.Port()}\"";
                        webrequest.Enqueue(url, "", (code, response) => {
                            if (code == 200) {
                                try {
                                    BattlemetricsApiResponse apiResponse = JsonConvert.DeserializeObject<BattlemetricsApiResponse>(response);
                                    switch (apiResponse.data.Count) {
                                        case 1 : BattlemetricsApiResponse.ServerData serverData = apiResponse.data.Last();
                                        if (check.IP() != serverData.attributes.ip || check.Port() != serverData.attributes.port) {
                                            PrintError($"Battlemetrics API: The response from Battlemetrics does not match the IP or port of the expected server! (Request: {check.IP()}:{check.Port()}, Response: {serverData.attributes.ip}:{serverData.attributes.port})");
                                        }
                                        else {
                                            check.CurrentOnline = serverData.attributes.players;
                                            check.MaxOnline = serverData.attributes.maxPlayers;
                                            check.UpdateStatus((serverData.attributes.status == "online"));
                                            Initialized = true;
                                        }
                                        break;
                                        case 0 : PrintError($"Battlemetrics API: Server '{check.IP()}:{check.Port()}' not found! Perhaps he has not yet been interviewed.Wait a while.");
                                        break;
                                        default : PrintError($"Battlemetrics API: The number of results is different than expected! Contact the plugin developer! (Server: {check.IP()}:{check.Port()}, Count: {apiResponse.data.Count})");
                                        break;
                                    }
                                }
                                catch {
                                    PrintError($"Battlemetrics API: Error parsing response from server.Perhaps the format has changed.Contact the plugin developer!");
                                }
                            }
                            else {
                                PrintError($"Battlemetrics API HTTP CODE: {code}");
                            }
                        }
                        , this);
                    }
                    yield return new WaitForSeconds(1f);
                }
                yield return new WaitForSeconds(Settings.Interval);
            }
        }
#endregion
#region Commands
        [ConsoleCommand("UI_OurServersHandler")]
        private void CmdConsoleHandler(ConsoleSystem.Arg args) {
            BasePlayer player = args.Player();
            if (player == null || !args.HasArgs(1)) return;
            switch (args.Args[0].ToLower()) {
                case "show" : {
                    if (!args.HasArgs(2)) return;
                    int index = 0;
                    if (!int.TryParse(args.Args[1], out index) || Settings.Servers.ElementAtOrDefault(index) == null) return;
                    UI_DrawInterface(player, index);
                    break;
                }
                case "hide" : {
                    UI_DrawInterface(player, -2);
                    break;
                }
            }
        }
        private void CmdShowServers(BasePlayer player, string command, string[] args) {
            if (!Initialized) return;
            if (Settings.UseChat) {
                string resultMessage = "";
                foreach (var server in Settings.Servers) resultMessage += $"{server.DisplayName} (IP: {server.IPAndPort}) - " + ((server.Status) ? $"{server.GetOnline()}/{server.MaxOnline} players online" : "OFFLINE") + "\n\n";
                player.ChatMessage(resultMessage);
            }
            else {
                UI_DrawInterface(player);
            }
        }
#endregion
#region Interface
        private const string Layer = "UI_OurServersLayer";
        private void UI_DrawInterface(BasePlayer player, int index = -1) {
            CuiHelper.DestroyUi(player, Layer);
            CuiElementContainer container = new CuiElementContainer();
            float fadeSpeed = 1f;
            Server choosedServer = null;
            if (index >= 0) {
                fadeSpeed = 0f;
                choosedServer = Settings.Servers.ElementAtOrDefault(index);
            }
            else if (index == -2) {
                fadeSpeed = 0;
            }
            container.Add(new CuiPanel {
                CursorEnabled = true, RectTransform = {
                    AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0"
                }
                , Image = {
                    FadeIn = fadeSpeed, Color = "0 0 0 0.7"
                }
            }
            , "Overlay", Layer);
            container.Add(new CuiButton {
                RectTransform = {
                    AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0"
                }
                , Button = {
                    Color = "0 0 0 0", Close = Layer
                }
                , Text = {
                    Text = ""
                }
            }
            , Layer);
            float panelWidth = 80;
            var list = Settings.Servers.Where(p => p.CurrentOnline > -1).ToList();
            float topPosition = list.Count / 2f * panelWidth + (list.Count - 1) / 2f * 15;
            float startPosition = 0.5f;
            if (list.Count >= 6) {
                startPosition = 0.25f;
                topPosition /= 2f;
            }
            foreach (var check in list) {
                float leftPosition = check.ServerWidth * -1 - 83f;
                if (list.IndexOf(check) == list.Count - 1 && startPosition == 0.25f) startPosition = 0.5f;
                container.Add(new CuiPanel {
                    RectTransform = {
                        AnchorMin = $"{startPosition} 0.5", AnchorMax = $"{startPosition} {0.5f}", OffsetMin = $"{leftPosition} {topPosition - panelWidth}", OffsetMax = $"{check.ServerWidth} {topPosition}"
                    }
                    , Image = {
                        FadeIn = fadeSpeed, Color = "1 1 1 0.03008521"
                    }
                }
                , Layer, check.IPAndPort);
                if (check != choosedServer) {
                    container.Add(new CuiPanel {
                        RectTransform = {
                            AnchorMin = "1 0", AnchorMax = "1 1", OffsetMin = "3 0", OffsetMax = "83 0"
                        }
                        , Image = {
                            FadeIn = fadeSpeed, Color = "1 1 1 0.03008521"
                        }
                    }
                    , check.IPAndPort, check.IPAndPort + ".Help");
                    container.Add(new CuiButton {
                        RectTransform = {
                            AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "10 10", OffsetMax = "-10 -10"
                        }
                        , Button = {
                            Color = "1 1 1 0", Sprite = "assets/icons/circle_closed_toedge.png", Command = $"UI_OurServersHandler show {Settings.Servers.IndexOf(check)}"
                        }
                        , Text = {
                            FadeIn = fadeSpeed, Text = "i", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-bold.ttf", FontSize = 50, Color = "1 1 1 0.7"
                        }
                    }
                    , check.IPAndPort + ".Help");
                    container.Add(new CuiLabel {
                        RectTransform = {
                            AnchorMin = "0 1", AnchorMax = "1 1", OffsetMin = "15 -45", OffsetMax = "-15 -10"
                        }
                        , Text = {
                            FadeIn = fadeSpeed, Text = check.DisplayName, Font = "robotocondensed-bold.ttf", FontSize = 20, Align = TextAnchor.LowerLeft
                        }
                    }
                    , check.IPAndPort);
                    container.Add(new CuiLabel {
                        RectTransform = {
                            AnchorMin = "0 1", AnchorMax = "1 1", OffsetMin = "15 -25", OffsetMax = "-15 -5"
                        }
                        , Text = {
                            FadeIn = fadeSpeed, Text = check.IPAndPort, Font = "robotocondensed-regular.ttf", FontSize = 16, Color = "1 1 1 0.6", Align = TextAnchor.MiddleLeft
                        }
                    }
                    , check.IPAndPort);
                    container.Add(new CuiLabel {
                        RectTransform = {
                            AnchorMin = "0 1", AnchorMax = "1 1", OffsetMin = "15 -45", OffsetMax = "-15 -5"
                        }
                        , Text = {
                            FadeIn = fadeSpeed, Text = ((check.Status) ? $"{check.GetOnline()} / {check.MaxOnline}" : "OFFLINE"), Font = "robotocondensed-regular.ttf", FontSize = 32, Color = "1 1 1 0.4", Align = TextAnchor.MiddleRight
                        }
                    }
                    , check.IPAndPort);
                    container.Add(new CuiPanel {
                        RectTransform = {
                            AnchorMin = "0 0", AnchorMax = "1 0", OffsetMin = "15 10", OffsetMax = "-15 30"
                        }
                        , Image = {
                            FadeIn = fadeSpeed, Color = ((check.Status) ? "1 1 1 0.4" : "1 0.2 0 0.4")
                        }
                    }
                    , check.IPAndPort, check.IPAndPort + ".Online");
                    container.Add(new CuiPanel {
                        RectTransform = {
                            AnchorMin = "0 0", AnchorMax = $"{(float) check.GetOnline() / check.MaxOnline} 1", OffsetMin = "0 0", OffsetMax = "0 0"
                        }
                        , Image = {
                            FadeIn = fadeSpeed, Color = "0.6 0.9 0.6 0.8"
                        }
                    }
                    , check.IPAndPort + ".Online");
                }
                else {
                    container.Add(new CuiPanel {
                        RectTransform = {
                            AnchorMin = "1 0", AnchorMax = "1 1", OffsetMin = "3 0", OffsetMax = "83 0"
                        }
                        , Image = {
                            FadeIn = fadeSpeed, Color = "1 1 1 0.03008521"
                        }
                    }
                    , check.IPAndPort, check.IPAndPort + ".Help");
                    container.Add(new CuiButton {
                        RectTransform = {
                            AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "10 10", OffsetMax = "-10 -10"
                        }
                        , Button = {
                            Color = "1 1 1 0", Sprite = "assets/icons/circle_closed_toedge.png", Command = $"UI_OurServersHandler hide"
                        }
                        , Text = {
                            FadeIn = fadeSpeed, Text = "X", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-bold.ttf", FontSize = 50, Color = "1 1 1 0.7"
                        }
                    }
                    , check.IPAndPort + ".Help");
                    container.Add(new CuiLabel {
                        RectTransform = {
                            AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "15 15", OffsetMax = "-15 -15"
                        }
                        , Text = {
                            FadeIn = fadeSpeed, Text = check.Description, Font = "robotocondensed-regular.ttf", FontSize = 16, Color = "1 1 1 1", Align = TextAnchor.MiddleCenter
                        }
                    }
                    , check.IPAndPort);
                }
                if (startPosition < 0.5f) {
                    startPosition = 0.75f;
                }
                else if (startPosition > 0.5f) {
                    startPosition = 0.25f;
                    topPosition -= panelWidth + 15;
                }
                else {
                    topPosition -= panelWidth + 15;
                }
            }
            CuiHelper.AddUi(player, container);
        }
#endregion
    }
}

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