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

FREE TebexDonate : 1.6.4 1.6.4

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using System.Text;
#if RUST
using System.Globalization;
#endif
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
#if RUST
using Oxide.Core;
#endif
using Oxide.Core.Libraries;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
#if RUST
using Oxide.Game.Rust.Cui;
using UnityEngine;
#endif
namespace Oxide.Plugins {
    [Info("Tebex Donate", "Tebex", "1.6.4")]
    [Description("Official Plugin for the Tebex Server Monetization Platform.")]
    public class TebexDonate : CovalencePlugin {
#region Classes and Structures
        private class Category : SubCategory {
            public SortedDictionary<int, SubCategory> SubCategories {
                get;
            }
            public Category(int id, string name, int parentId, SortedDictionary<int, Package> packages, SortedDictionary<int, SubCategory> subCategories) : base(id, name, parentId, packages) {
                SubCategories = subCategories;
            }
        }
        private struct Command {
            public int Id {
                get;
            }
            public bool Online {
                get;
            }
            public string PlayerId {
                get;
            }
            public string PlayerName {
                get;
            }
            public string CommandString {
                get;
            }
            public Command(int id, bool online, string playerId, string playerName, string commandString) {
                Id = id;
                Online = online;
                PlayerId = playerId;
                PlayerName = playerName;
                CommandString = commandString;
            }
            public string ReplaceVariables() => CommandString.Replace("{id}", PlayerId).Replace("{username}", PlayerName);
        }
        [JsonObject]
        private class Event {
            [JsonProperty("username_id")]
            public string UsernameId {
                get;
            }
            [JsonProperty("event_type")]
            public string EventType {
                get;
            }
            [JsonProperty("event_date")]
            public string EventDate {
                get;
            }
            [JsonProperty("ip")]
            public string IpAddress {
                get;
            }
            public Event(string usernameId, string eventType, string eventDate, string ipAddress) {
                UsernameId = usernameId;
                EventType = eventType;
                EventDate = eventDate;
                IpAddress = ipAddress;
            }
            public override string ToString() => $"{{\"username_id\": \"{UsernameId}\", \"event_type\": \"{EventType}\", \"event_date\": \"{EventDate}\", \"ip\": \"{IpAddress}\"}}";
        }
        private class Package {
            public int Id {
                get;
            }
            public string Name {
                get;
            }
            public string Price {
                get;
            }
            public bool Image {
                get;
            }
            public string ImageUrl {
                get;
            }
            public Package(int id, string name, string price, bool image, string imageUrl) {
                Id = id;
                Name = name;
                Price = price;
                Image = image;
                ImageUrl = imageUrl;
            }
        }
        private class SubCategory {
            public int Id {
                get;
            }
            public string Name {
                get;
            }
            public int ParentId {
                get;
            }
            public SortedDictionary<int, Package> Packages {
                get;
            }
            public SubCategory(int id, string name, int parentId, SortedDictionary<int, Package> packages) {
                Id = id;
                Name = name;
                ParentId = parentId;
                Packages = packages;
            }
        }
#if RUST
        private class RustUIBuilder {
            public string Panel {
                get;
            }
            private CuiElementContainer container;
            public RustUIBuilder(string panel, string colour, string anchorMin, string anchorMax) {
                Panel = panel;
                container = CreateElementContainer(panel, colour, anchorMin, anchorMax);
            }
            public RustUIBuilder AddPanel(string panel, string colour, string anchorMin, string anchorMax, bool cursor) {
                container.Add(new CuiPanel() {
                    Image = {
                        Color = colour
                    }
                    , RectTransform = {
                        AnchorMin = anchorMin, AnchorMax = anchorMax
                    }
                    , CursorEnabled = cursor
                }
                , panel, CuiHelper.GetGuid());
                return this;
            }
            public RustUIBuilder AddButton(string panel, string colour, string text, int size, string anchorMin, string anchorMax, string command, TextAnchor align) {
                container.Add(new CuiButton() {
                    Button = {
                        Color = colour, Command = command
                    }
                    , RectTransform = {
                        AnchorMin = anchorMin, AnchorMax = anchorMax
                    }
                    , Text = {
                        Text = text, FontSize = size, Align = align
                    }
                }
                , panel, CuiHelper.GetGuid());
                return this;
            }
            public RustUIBuilder AddImage(string panel, string url, string anchorMin, string anchorMax) {
                container.Add(new CuiElement() {
                    Name = CuiHelper.GetGuid(), Parent = panel, Components = {
                        new CuiRawImageComponent() {
                            Url = url
                        }
                        , new CuiRectTransformComponent() {
                            AnchorMin = anchorMin, AnchorMax = anchorMax
                        }
                    }
                }
                );
                return this;
            }
            public RustUIBuilder AddLabel(string panel, string text, int size, string anchorMin, string anchorMax, TextAnchor align) {
                container.Add(new CuiLabel() {
                    Text = {
                        FontSize = size, Align = align, Text = text
                    }
                    , RectTransform = {
                        AnchorMin = anchorMin, AnchorMax = anchorMax
                    }
                }
                , panel, CuiHelper.GetGuid());
                return this;
            }
            public CuiElementContainer GetContainer() => container;
            private CuiElementContainer CreateElementContainer(string panel, string colour, string anchorMin, string anchorMax) {
                return new CuiElementContainer() {
                    {
                        new CuiPanel() {
                            Image = {
                                Color = colour
                            }
                            , RectTransform = {
                                AnchorMin = anchorMin, AnchorMax = anchorMax
                            }
                            , CursorEnabled = true
                        }
                        , new CuiElement().Parent = "Overlay", panel
                    }
                }
                ;
            }
        }
        private class RustUIManager {
            private static Dictionary<string, CuiElementContainer> availableUIs = new Dictionary<string, CuiElementContainer>();
            private static Dictionary<ulong, string> openUIs = new Dictionary<ulong, string>();
            public static void ClearUIs() {
                foreach (BasePlayer player in BasePlayer.activePlayerList) CloseUI(player);
                availableUIs.Clear();
                openUIs.Clear();
            }
            public static void CloseUI(BasePlayer player) {
                string element;
                if (openUIs.TryGetValue(player.userID, out element)) {
                    CuiHelper.DestroyUi(player, element);
                    openUIs.Remove(player.userID);
                }
            }
            public static void GenerateUIs(string storeName, string storeCurrency, string storeCurrencySymbol, SortedDictionary<int, Category> orderedCategories) {
                RustUIBuilder baseUIBuilder = GenerateBaseUI("TD_Listings", storeName, storeCurrency, null, "TD_Close");
                double anchorMinX = 0.01;
                double anchorMaxX = 0.10;
                double anchorIncrement = 0.095;
                foreach (KeyValuePair<int, Category> orderedCategory in orderedCategories) {
                    Category category = orderedCategory.Value;
                    RustUIBuilder categoryUIBuilder = GenerateBaseUI($"TD_Listings_{category.Id}", storeName, storeCurrency, category.Name, $"TD_Open {baseUIBuilder.Panel}");
                    double categoryAnchorMinX = 0.01;
                    double categoryAnchorMaxX = 0.10;
                    foreach (KeyValuePair<int, SubCategory> orderedSubCategory in category.SubCategories) {
                        SubCategory subCategory = orderedSubCategory.Value;
                        RustUIBuilder subCategoryUIBuilder = GenerateBaseUI($"TD_Listings_{subCategory.Id}", storeName, storeCurrency, $"{category.Name} -> {subCategory.Name}", $"TD_Open {categoryUIBuilder.Panel}");
                        subCategoryUIBuilder = subCategoryUIBuilder.AddPanel(subCategoryUIBuilder.Panel, HexToRust(Instance.buyUIButtonColour, Instance.buyUIButtonColourTransparency), "0.01 0.06", "0.99 0.86", true);
                        subCategoryUIBuilder = AddPackages(subCategoryUIBuilder, storeCurrencySymbol, subCategory.Packages);
                        categoryUIBuilder = categoryUIBuilder.AddButton(categoryUIBuilder.Panel, HexToRust(Instance.buyUIButtonColour, Instance.buyUIButtonColourTransparency), subCategory.Name, 14, $"{categoryAnchorMinX} 0.88", $"{categoryAnchorMaxX} 0.93", $"TD_Open TD_Listings_{subCategory.Id}", TextAnchor.MiddleCenter);
                        categoryAnchorMinX += anchorIncrement;
                        categoryAnchorMaxX += anchorIncrement;
                        availableUIs.Add(subCategoryUIBuilder.Panel, subCategoryUIBuilder.GetContainer());
                    }
                    if (category.Packages.Count > 0) {
                        categoryUIBuilder = categoryUIBuilder.AddPanel(categoryUIBuilder.Panel, HexToRust(Instance.buyUIButtonColour, Instance.buyUIButtonColourTransparency), "0.01 0.06", "0.99 0.86", true);
                        categoryUIBuilder = AddPackages(categoryUIBuilder, storeCurrencySymbol, category.Packages);
                    }
                    else categoryUIBuilder = categoryUIBuilder.AddLabel(categoryUIBuilder.Panel, Instance.lang.GetMessage("BuyUISelectSubCategory", Instance), 18, "0.01 0.02", "0.99 0.86", TextAnchor.MiddleCenter);
                    baseUIBuilder = baseUIBuilder.AddButton(baseUIBuilder.Panel, HexToRust(Instance.buyUIButtonColour, Instance.buyUIButtonColourTransparency), category.Name, 14, $"{anchorMinX} 0.88", $"{anchorMaxX} 0.93", $"TD_Open TD_Listings_{category.Id}", TextAnchor.MiddleCenter);
                    anchorMinX += anchorIncrement;
                    anchorMaxX += anchorIncrement;
                    availableUIs.Add(categoryUIBuilder.Panel, categoryUIBuilder.GetContainer());
                }
                baseUIBuilder = baseUIBuilder.AddLabel(baseUIBuilder.Panel, Instance.lang.GetMessage("BuyUISelectCategory", Instance), 18, "0.01 0.02", "0.99 0.86", TextAnchor.MiddleCenter);
                availableUIs.Add(baseUIBuilder.Panel, baseUIBuilder.GetContainer());
            }
            public static void OpenUI(BasePlayer player, string element) {
                CuiElementContainer container;
                if (!availableUIs.TryGetValue(element, out container)) return;
                string openElement;
                if (openUIs.TryGetValue(player.userID, out openElement)) CuiHelper.DestroyUi(player, openElement);
                openUIs[player.userID] = element;
                CuiHelper.AddUi(player, container.ToJson());
            }
            private static RustUIBuilder AddPackages(RustUIBuilder builder, string storeCurrencySymbol, SortedDictionary<int, Package> orderedPackages) {
                int currentPackage = 0;
                double packageAnchorMinX = 0.02;
                double packageAnchorMinY = 0.67;
                double packageAnchorMaxX = 0.13;
                double packageAnchorMaxY = 0.85;
                double packageAnchorXIncrement = 0.1215;
                double packageAnchorYDecrement = 0.2;
                foreach (KeyValuePair<int, Package> orderedPackage in orderedPackages) {
                    Package package = orderedPackage.Value;
                    string imageIcon = "";
                    if (package.Image) imageIcon = Instance.ImageLibrary?.Call<string>("GetImage", package.ImageUrl, 0uL);
                    if (string.IsNullOrEmpty(imageIcon)) imageIcon = Instance.ImageLibrary?.Call<string>("GetImage", Instance.buyUIDefaultPackageImageUrl, 0uL);
                    builder = builder.AddPanel(builder.Panel, HexToRust(Instance.buyUIBackgroundColour, Instance.buyUIBackgroundColourTransparency), $"{packageAnchorMinX} {packageAnchorMinY}", $"{packageAnchorMaxX} {packageAnchorMaxY}", true).AddLabel(builder.Panel, package.Name, 12, $"{packageAnchorMinX} {packageAnchorMaxY - 0.05}", $"{packageAnchorMaxX} {packageAnchorMaxY}", TextAnchor.MiddleCenter).AddImage(builder.Panel, imageIcon, $"{packageAnchorMinX + 0.005} {packageAnchorMinY + 0.01}", $"{packageAnchorMaxX - ((packageAnchorMaxX - packageAnchorMinX) / 2) - 0.005} {packageAnchorMaxY - 0.055}").AddLabel(builder.Panel, $"{storeCurrencySymbol}{package.Price}", 12, $"{packageAnchorMaxX - ((packageAnchorMaxX - packageAnchorMinX) / 2) + 0.005} {packageAnchorMaxY - (packageAnchorYDecrement / 2)}", $"{packageAnchorMaxX - 0.005} {packageAnchorMaxY - 0.055}", TextAnchor.MiddleCenter).AddButton(builder.Panel, HexToRust(Instance.buyUIButtonColour, Instance.buyUIButtonColourTransparency), "Buy", 16, $"{packageAnchorMaxX - ((packageAnchorMaxX - packageAnchorMinX) / 2) + 0.005} {packageAnchorMinY + 0.01}", $"{packageAnchorMaxX - 0.005} {packageAnchorMaxY - (packageAnchorYDecrement / 2) - 0.01}", $"TD_Buy {package.Id}", TextAnchor.MiddleCenter);
                    currentPackage++;
                    if (currentPackage == 8) {
                        currentPackage = 0;
                        packageAnchorMinX = 0.02;
                        packageAnchorMinY -= packageAnchorYDecrement;
                        packageAnchorMaxX = 0.13;
                        packageAnchorMaxY -= packageAnchorYDecrement;
                    }
                    else {
                        packageAnchorMinX += packageAnchorXIncrement;
                        packageAnchorMaxX += packageAnchorXIncrement;
                    }
                }
                return builder;
            }
            private static RustUIBuilder GenerateBaseUI(string panelName, string storeName, string storeCurrency, string currentCategory, string closeCommand) {
                string header = $"{storeName}" + (currentCategory != null ? $" - {currentCategory}" : "");
                return new RustUIBuilder(panelName, HexToRust(Instance.buyUIBackgroundColour, Instance.buyUIBackgroundColourTransparency), "0.02 0.2", "0.98 0.9").AddLabel(panelName, header, 18, "0.01 0.94", "0.99 0.99", TextAnchor.MiddleCenter).AddButton(panelName, HexToRust(Instance.buyUIButtonExitColour, Instance.buyUIButtonExitColourTransparency), "Go Back", 18, "0.93 0.94", "0.99 0.99", closeCommand, TextAnchor.MiddleCenter);
            }
            private static string HexToRust(string hex, float alpha = 1f) {
                if (hex.StartsWith("#")) hex = hex.TrimStart('#');
                int red = int.Parse(hex.Substring(0, 2), NumberStyles.AllowHexSpecifier);
                int green = int.Parse(hex.Substring(2, 2), NumberStyles.AllowHexSpecifier);
                int blue = int.Parse(hex.Substring(4, 2), NumberStyles.AllowHexSpecifier);
                return $"{(double)red / 255} {(double)green / 255} {(double)blue / 255} {alpha}";
            }
        }
#endif
#endregion
#region Constants and Variables
        public static TebexDonate Instance;
        private Queue<Event> events;
#region API
        private static readonly string BASE_URL = "https://plugin.buycraft.net";
        private bool buyCommandReady;
        private SortedDictionary<int, Category> listings;
        private bool logEvents;
        private string storeCurrency;
        private string storeCurrencySymbol;
        private string storeName;
        private string storeUrl;
        private bool validated;
#endregion
#region Configuration
        private string buyCommand;
        private bool buyEnabled;
#region UI
        private bool buyUIEnabled;
        private string buyUIBackgroundColour;
        private float buyUIBackgroundColourTransparency;
        private string buyUIButtonColour;
        private float buyUIButtonColourTransparency;
        private string buyUIButtonExitColour;
        private float buyUIButtonExitColourTransparency;
        private string buyUIDefaultPackageImageUrl;
        private ulong buyUIMessageAvatarId;
#endregion
        private bool debugLogActions;
        private bool debugLogResponseErrors;
        private bool debugLogStackTraces;
        private float commandCheckInterval;
        private float eventLogInterval;
        private string secretKey;
#endregion
#region Plugin References
        [PluginReference]
        private Plugin ImageLibrary;
#endregion
#region Timers
        private Timer checkTimer;
        private Timer eventTimer;
        private Timer validationTimer;
#endregion
#endregion
#region Initialisation
        protected override void LoadDefaultConfig() {
            Config["Buy Command", "Alias"] = buyCommand = GetConfig("Buy Command", "Alias", "buy");
            Config["Buy Command", "Enabled"] = buyEnabled = GetConfig("Buy Command", "Enabled", true);
            Config["Buy Command", "UI", "Enabled"] = buyUIEnabled = GetConfig("Buy Command", "UI", "Enabled", true);
            Config["Buy Command", "UI", "Background Colour"] = buyUIBackgroundColour = GetConfig("Buy Command", "UI", "Background Colour", "#2a2a2a");
            Config["Buy Command", "UI", "Background Colour Transparency"] = buyUIBackgroundColourTransparency = GetConfig("Buy Command", "UI", "Background Colour Transparency", 0.9f);
            Config["Buy Command", "UI", "Button Colour"] = buyUIButtonColour = GetConfig("Buy Command", "UI", "Button Colour", "#a8a8a8");
            Config["Buy Command", "UI", "Button Colour Transparency"] = buyUIButtonColourTransparency = GetConfig("Buy Command", "UI", "Button Colour Transparency", 0.5f);
            Config["Buy Command", "UI", "Button Exit Colour"] = buyUIButtonExitColour = GetConfig("Buy Command", "UI", "Button Exit Colour", "#b31b1b");
            Config["Buy Command", "UI", "Button Exit Colour Transparency"] = buyUIButtonExitColourTransparency = GetConfig("Buy Command", "UI", "Button Exit Colour Transparency", 0.9f);
            Config["Buy Command", "UI", "Default Package Image URL"] = buyUIDefaultPackageImageUrl = GetConfig("Buy Command", "UI", "Default Package Image URL", "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/b5/b5bd56c1aa4644a474a2e4972be27ef9e82e517e_full.jpg");
            Config["Buy Command", "UI", "Message Avatar ID"] = buyUIMessageAvatarId = GetConfig("Buy Command", "UI", "Message Avatar ID", 0uL);
            Config["Debug", "Log Actions"] = debugLogActions = GetConfig("Debug", "Log Actions", true);
            Config["Debug", "Log Stack Traces"] = debugLogStackTraces = GetConfig("Debug", "Log Stack Traces", true);
            Config["Debug", "Log Response Errors"] = debugLogResponseErrors = GetConfig("Debug", "Log Response Errors", true);
            Config["Command Check Interval"] = commandCheckInterval = GetConfig("Command Check Interval", 225f);
            Config["Event Log Interval"] = eventLogInterval = GetConfig("Event Log Interval", 60f);
            if (eventLogInterval < 60f) eventLogInterval = 60f;
            Config["Secret key of your shop (do not tell it anyone)"] = secretKey = GetConfig("Secret key of your shop (do not tell it anyone)", "");
            SaveConfig();
        }
        protected override void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string> {
                ["BuyCheckoutURL"]
                = "Visit {url} to purchase this item!", ["BuyCommand"] = "You can buy packages from our store at {url}", ["BuyUISelectCategory"] = "Select a category to view our packages!", ["BuyUISelectSubCategory"] = "Select a sub-category to view our packages!"
            }
            , this);
        }
        private void OnServerInitialized() {
            Instance = this;
            events = new Queue<Event>();
            LoadDefaultConfig();
            LoadDefaultMessages();
            buyCommandReady = false;
            listings = new SortedDictionary<int, Category>();
            if (buyEnabled) AddCovalenceCommand(buyCommand, "BuyCommand");
            logEvents = false;
            validated = false;
            StartValidationTimer();
#if RUST
            ImageLibrary?.Call<bool>("AddImage", buyUIDefaultPackageImageUrl, buyUIDefaultPackageImageUrl, 0uL);
#endif
        }
        private void Unload() {
#if RUST
            if (!Interface.Oxide.IsShuttingDown) RustUIManager.ClearUIs();
#endif
            if (checkTimer != null && !checkTimer.Destroyed) checkTimer.Destroy();
            if (eventTimer != null && !eventTimer.Destroyed) eventTimer.Destroy();
            if (validationTimer != null && !validationTimer.Destroyed) validationTimer.Destroy();
        }
#endregion
#region Commands
#region Player Commands
        private void BuyCommand(IPlayer player, string command, string[] args) {
            if (!buyCommandReady) return;
            if (player.IsServer) {
                Puts("You cannot use this command from the console window!");
                return;
            }
#if RUST
            if (buyUIEnabled) RustUIManager.OpenUI(player.Object as BasePlayer, "TD_Listings");
            else
#endif
            player.Message(lang.GetMessage("BuyCommand", this, player.Id).Replace("{url}", storeUrl));
        }
#endregion
#region Server Commands
        [Command("tebex:info")]
        private void TebexInfoCommand(IPlayer player, string command, string[] args) {
            if (!player.IsServer) return;
            FetchStoreInformation(true, secretKey);
        }
        [Command("tebex:secret")]
        private void TebexSecretCommand(IPlayer player, string command, string[] args) {
            if (!player.IsServer) return;
            if (args.Length != 1) {
                PrintWarning("Usage: tebex:secret <secret>");
                return;
            }
            FetchStoreInformation(true, args[0]);
        }
#endregion
#region UI Commands
#if RUST
        [Command("TD_Buy")]
        private void TebexUI_Buy(IPlayer player, string command, string[] args) {
            if (args.Length != 1) return;
            CheckoutURL(player, args[0]);
        }
        [Command("TD_Open")]
        private void TebexUI_Open(IPlayer player, string command, string[] args) {
            if (args.Length != 1) return;
            RustUIManager.OpenUI(player.Object as BasePlayer, args[0]);
        }
        [Command("TD_Close")]
        private void TebexUI_Close(IPlayer player, string command, string[] args) => RustUIManager.CloseUI(player.Object as BasePlayer);
#endif
#endregion
#endregion
#region Oxide Hooks
#if RUST
        private object OnPlayerCommand(BasePlayer player, string command, string[] args) {
            string fullCommand = command.ToLower();
            if (!fullCommand.StartsWith("/")) return null;
            switch (fullCommand.Split(' ')[0]) {
                case "/td_buy" : return true;
                case "/td_close" : return true;
                case "/td_open" : return true;
            }
            return null;
        }
#endif
        private void OnUserConnected(IPlayer player) => events.Enqueue(new Event(player.Id, "server.join", FormattedUtcDate(), player.Address));
        private void OnUserDisconnected(IPlayer player) {
#if RUST
            var basePlayer = player.Object as BasePlayer;
            if (basePlayer != null) RustUIManager.CloseUI(basePlayer);
#endif
            events.Enqueue(new Event(player.Id, "server.leave", FormattedUtcDate(), player.Address));
        }
#endregion
#region Web Request Methods
        private void CheckCommandQueue(bool first) {
            if (validated) {
                if (first && validationTimer != null && !validationTimer.Destroyed) validationTimer.Destroy();
            }
            else return;
            if (debugLogActions) PrintWarning("Attempting to process commands in the queue...");
            webrequest.Enqueue($"{BASE_URL}/queue", "", (code, response) => {
                float secondsUntilNextCheck = 225f;
                if (response != null) {
                    try {
                        var jObject = JObject.Parse(response);
                        switch (code) {
                            case 200 : break;
                            case 403 : StartValidationTimer(60f);
                            goto default;
                            default : PrintWarning($"An error occurred whilst checking the command queue: {jObject["error_message"].ToString()}");
                            return;
                        }
                        if ((bool) jObject["meta"]["execute_offline"]) {
                            if (debugLogActions) PrintWarning("Processing offline commands...");
                            ProcessOfflineCommands();
                        }
                        JArray jObjectPlayers = (JArray) jObject["players"];
                        secondsUntilNextCheck = jObject["meta"]["next_check"].ToObject<int>();
                        if (jObjectPlayers.Count > 0) {
                            int processed = 0;
                            foreach (var player in jObjectPlayers) {
                                IPlayer target = players.FindPlayerById(player["uuid"].ToString());
                                if (target == null || !target.IsConnected) continue;
                                if (debugLogActions) PrintWarning($"Processing online commands for {target.Id}...");
                                ProcessOnlineCommands(target, player["id"].ToString());
                                processed++;
                            }
                            if (processed == 0 && debugLogActions) PrintWarning("There are no online commands that need to be processed!");
                        }
                        else if (debugLogActions) PrintWarning("There are no online commands that need to be processed!");
                    }
                    catch (Exception e) {
                        PrintError($"An exception was thrown whilst checking the command queue: {e.Message}");
                        if (debugLogResponseErrors) PrintError($"Associated response: {response}");
                        if (debugLogStackTraces) PrintError(e.StackTrace);
                    }
                    checkTimer = timer.In(secondsUntilNextCheck, () => CheckCommandQueue(false));
                    return;
                }
                if (commandCheckInterval > secondsUntilNextCheck) secondsUntilNextCheck = commandCheckInterval;
                checkTimer = timer.In(secondsUntilNextCheck, () => CheckCommandQueue(false));
                PrintError($"An unhandled error occurred whilst checking the command queue (response code: {code}).");
            }
            , this, RequestMethod.GET, AddToHeaders(secretKey), 3000f);
        }
        private void CheckoutURL(IPlayer player, string packageId) {
            webrequest.Enqueue($"{BASE_URL}/checkout?username={player.Name}&package_id={packageId}", "", (code, response) => {
                if (response != null) {
                    try {
                        var jObject = JObject.Parse(response);
                        switch (code) {
                            case 200 : case 201 : break;
                            case 403 : StartValidationTimer(60f);
                            goto default;
                            default : PrintWarning($"An error occurred whilst retrieving a checkout URL: {jObject["error_message"].ToString()}");
                            return;
                        }
                        string message = lang.GetMessage("BuyCheckoutURL", this, player.Id).Replace("{url}", jObject["url"].ToString());
#if RUST
                        if ($"{buyUIMessageAvatarId}".IsSteamId()) {
                            var basePlayer = player.Object as BasePlayer;
                            basePlayer?.SendConsoleCommand("chat.add", 2, buyUIMessageAvatarId, message);
                        }
                        else player.Message(message);
                        player.Command("TD_Close");
#else
                        player.Message(message);
#endif
                    }
                    catch (Exception e) {
                        PrintError($"An exception was thrown whilst retrieving a checkout URL: {e.Message}");
                        if (debugLogResponseErrors) PrintError($"Associated response: {response}");
                        if (debugLogStackTraces) PrintError(e.StackTrace);
                    }
                    return;
                }
                PrintError($"An unhandled error occurred whilst retrieving a checkout URL (response code: {code}, username: {player.Name}, package ID: {packageId}).");
            }
            , this, RequestMethod.POST, AddToHeaders(secretKey), 3000f);
        }
        private void DeleteCommands(List<Command> commands) {
            if (commands.Count < 1) return;
            string commandIds = $"ids[]={commands[0].Id}";
            for (int i = 0; i < commands.Count; i++) {
                Command command = commands[i];
                if (debugLogActions) PrintWarning($"Queueing command {command.Id} for deletion: {command.ReplaceVariables()}");
                if (i == 0) continue;
                commandIds += $"&ids[]={command.Id}";
            }
            webrequest.Enqueue($"{BASE_URL}/queue?{commandIds}", "", (code, response) => {
                switch (code) {
                    case 204 : if (debugLogActions) PrintWarning("Successfully deleted all executed commands.");
                    return;
                    case 403 : StartValidationTimer(60f);
                    goto default;
                    default : if (response != null) {
                        try {
                            var jObject = JObject.Parse(response);
                            PrintWarning($"An error occurred whilst deleting executed commands: {jObject["error_message"].ToString()}");
                            return;
                        }
                        catch (Exception e) {
                            PrintError($"An exception was thrown whilst deleting executed commands: {e.Message}");
                            if (debugLogResponseErrors) PrintError($"Associated response: {response}");
                            if (debugLogStackTraces) PrintError(e.StackTrace);
                            return;
                        }
                    }
                    break;
                }
                PrintError($"An unhandled error occurred whilst deleting executed commands (response code: {code}).");
            }
            , this, RequestMethod.DELETE, AddToHeaders(secretKey), 3000f);
        }
        private void FetchListings() {
            buyCommandReady = false;
            listings.Clear();
            if (debugLogActions) PrintWarning("Attempting to fetch category and package listings...");
            webrequest.Enqueue($"{BASE_URL}/listing", "", (code, response) => {
                if (response != null) {
                    try {
                        var jObject = JObject.Parse(response);
                        switch (code) {
                            case 200 : break;
                            case 403 : StartValidationTimer(60f);
                            goto default;
                            default : PrintWarning($"An error occurred whilst fetching your store listings: {jObject["error_message"].ToString()}");
                            return;
                        }
                        JArray categories = (JArray) jObject["categories"];
                        if (categories.Count > 0) {
                            foreach (var jCategory in categories) {
                                Category category = new Category(jCategory["id"].ToObject<int>(), jCategory["name"].ToString(), -1, new SortedDictionary<int, Package>(), new SortedDictionary<int, SubCategory>());
                                JArray subCategories = (JArray)jCategory["subcategories"];
                                int order = jCategory["order"].ToObject<int>();
                                if (subCategories.Count > 0) foreach (var jSubCategory in subCategories) {
                                    SubCategory subCategory = new SubCategory(jSubCategory["id"].ToObject<int>(), jSubCategory["name"].ToString(), category.Id, new SortedDictionary<int, Package>());
                                    JArray subCategoryPackages = (JArray)jSubCategory["packages"];
                                    int subCategoryOrder = jSubCategory["order"].ToObject<int>();
                                    if (subCategoryPackages.Count > 0) foreach (var jSubCategoryPackage in subCategoryPackages) {
                                        bool image = jSubCategoryPackage["image"].Type != JTokenType.Boolean;
                                        Package package = new Package(jSubCategoryPackage["id"].ToObject<int>(), jSubCategoryPackage["name"].ToString(), jSubCategoryPackage["price"].ToString(), image, image ? null : jSubCategoryPackage["image"].ToString());
#if RUST
                                        if (package.Image) ImageLibrary?.Call("AddImage", package.ImageUrl, package.ImageUrl, 0uL);
#endif
                                        int packageOrder = jSubCategoryPackage["order"].ToObject<int>();
                                        while (subCategory.Packages.ContainsKey(packageOrder)) packageOrder++;
                                        subCategory.Packages.Add(packageOrder, package);
                                    }
                                    while (category.SubCategories.ContainsKey(subCategoryOrder)) subCategoryOrder++;
                                    category.SubCategories.Add(subCategoryOrder, subCategory);
                                }
                                JArray packages = (JArray)jCategory["packages"];
                                if (packages.Count > 0) foreach (var jPackage in packages) {
                                    bool image = jPackage["image"].Type != JTokenType.Boolean;
                                    Package package = new Package(jPackage["id"].ToObject<int>(), jPackage["name"].ToString(), jPackage["price"].ToString(), image, image ? jPackage["image"].ToString() : null);
                                    int packageOrder = jPackage["order"].ToObject<int>();
                                    while (category.Packages.ContainsKey(packageOrder)) packageOrder++;
                                    category.Packages.Add(packageOrder, package);
                                }
                                while (listings.ContainsKey(order)) order++;
                                listings.Add(order, category);
                                if (debugLogActions) PrintWarning($"Successfully added category {category.Name} to the stored listings!");
                            }
                            if (debugLogActions) PrintWarning("Successfully added all categories to the stored listings!");
                        }
                        else if (debugLogActions) PrintWarning("No categories or package listings were found on your store!");
#if RUST
                        RustUIManager.ClearUIs();
                        RustUIManager.GenerateUIs(storeName, storeCurrency, storeCurrencySymbol, listings);
#endif
                        buyCommandReady = true;
                    }
                    catch (Exception e) {
                        PrintError($"An exception was thrown whilst fetching your store listings: {e.Message}");
                        if (debugLogResponseErrors) PrintError($"Associated response: {response}");
                        if (debugLogStackTraces) PrintError(e.StackTrace);
                    }
                    return;
                }
                PrintError($"An unhandled error occurred whilst fetching your store listings from the secret key provided (response code: {code}).");
            }
            , this, RequestMethod.GET, AddToHeaders(secretKey), 3000f);
        }
        private void FetchStoreInformation(bool command, string secretKey) {
            if (!command && !validated) validationTimer = timer.In(60f, () => FetchStoreInformation(false, this.secretKey));
            if (secretKey.Equals("")) {
                PrintWarning("You have not yet set your store's secret key in the configuration file!");
                PrintWarning("Use the \"tebex:secret <secret>\" command to update it without having to reload the plugin.");
                return;
            }
            webrequest.Enqueue($"{BASE_URL}/information", "", (code, response) => {
                if (response != null) {
                    try {
                        var jObject = JObject.Parse(response);
                        switch (code) {
                            case 200 : break;
                            case 403 : StartValidationTimer(60f);
                            goto default;
                            default : PrintWarning($"An error occurred whilst fetching your store information: {jObject["error_message"].ToString()}");
                            return;
                        }
                        storeCurrency = jObject["account"]["currency"]["iso_4217"].ToString();
                        storeCurrencySymbol = jObject["account"]["currency"]["symbol"].ToString();
                        storeName = jObject["account"]["name"].ToString();
                        storeUrl = jObject["account"]["domain"].ToString();
                        Puts("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
                        Puts("Successfully retrieved store information from your secret key!");
                        Puts("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
                        Puts($"Account: {storeName} ({storeCurrency})");
                        Puts($"Server: {jObject["server"]["name"].ToString()}");
                        Puts($"URL: {storeUrl}");
                        Puts("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
                        if (!validated || !secretKey.Equals(this.secretKey)) {
                            validated = true;
                            this.secretKey = secretKey;
                            Config["Secret key of your shop (do not tell it anyone)"] = secretKey;
                            SaveConfig();
                            CheckCommandQueue(true);
                        }
                        logEvents = jObject["account"]["log_events"].ToObject<bool>();
                        if (logEvents) StartEventTimer(eventLogInterval);
                        else if (eventTimer != null && !eventTimer.Destroyed) eventTimer.Destroy();
                        FetchListings();
                    }
                    catch (Exception e) {
                        PrintError($"An exception was thrown whilst validating your secret key: {e.Message}");
                        if (debugLogResponseErrors) PrintError($"Associated response: {response}");
                        if (debugLogStackTraces) PrintError(e.StackTrace);
                    }
                    return;
                }
                PrintError($"An unhandled error occurred whilst fetching your store information from the secret key provided (response code: {code}).");
            }
            , this, RequestMethod.GET, AddToHeaders(secretKey), 3000f);
        }
        private void LogEvents() {
            if (!logEvents) return;
            if (eventTimer != null && !eventTimer.Destroyed) eventTimer.Destroy();
            Queue<Event> events = new Queue<Event>(this.events);
            eventTimer = timer.In(eventLogInterval, () => LogEvents());
            if (events.Count < 1) return;
            Dictionary<string, string> headers = new Dictionary<string, string>() {
                ["Content-Type"]
                = "application/json"
            }
            ;
            Event nextEvent = events.Dequeue();
            StringBuilder payload = new StringBuilder("[").Append(nextEvent.ToString());
            while (events.Count > 0) {
                nextEvent = events.Dequeue();
                payload.Append(",").Append(nextEvent.ToString());
            }
            if (debugLogActions) PrintWarning("Attempting to log all stored connection events...");
            webrequest.Enqueue($"{BASE_URL}/events", payload.Append("]").ToString(), (code, response) => {
                switch (code) {
                    case 204 : foreach (Event @event in events) this.events.Dequeue();
                    if (debugLogActions) PrintWarning("Successfully logged all stored connection events!");
                    return;
                    case 403 : StartValidationTimer(60f);
                    goto default;
                    default : if (response != null) {
                        try {
                            var jObject = JObject.Parse(response);
                            PrintWarning($"An error occurred whilst logging player connection events: {jObject["error_message"].ToString()}");
                        }
                        catch (Exception e) {
                            PrintError($"An exception was thrown whilst logging player connection events: {e.Message}");
                            if (debugLogResponseErrors) PrintError($"Associated response: {response}");
                            if (debugLogStackTraces) PrintError(e.StackTrace);
                        }
                        return;
                    }
                    break;
                }
                PrintError($"An unhandled error occurred whilst logging player connection events (response code: {code}).");
            }
            , this, RequestMethod.POST, AddToHeaders(headers, secretKey), 3000f);
        }
        private void ProcessCommands(List<Command> commands) {
            if (commands.Count < 1) return;
            List<Command> executedCommands = new List<Command>();
            foreach (Command command in commands) {
                string commandString = command.ReplaceVariables();
                if (debugLogActions) {
                    string type = command.Online ? "online" : "offline";
                    PrintWarning($"Processed {type} command for {command.PlayerId}: {commandString}");
                }
                executedCommands.Add(command);
                server.Command(commandString);
                if (executedCommands.Count == 15) {
                    DeleteCommands(executedCommands);
                    executedCommands.Clear();
                }
            }
            if (executedCommands.Count > 0) DeleteCommands(executedCommands);
        }
        private void ProcessOfflineCommands() {
            webrequest.Enqueue($"{BASE_URL}/queue/offline-commands", "", (code, response) => {
                if (response != null) {
                    try {
                        var jObject = JObject.Parse(response);
                        switch (code) {
                            case 200 : break;
                            case 403 : StartValidationTimer(60f);
                            goto default;
                            default : PrintWarning($"An error occurred whilst processing the offline commands: {jObject["error_message"].ToString()}");
                            return;
                        }
                        List<Command> commands = new List<Command>();
                        foreach (var command in (JArray) jObject["commands"]) {
                            int id = (int) command["id"];
                            string playerId = command["player"]["uuid"].ToString();
                            string playerName = command["player"]["name"].ToString();
                            string commandString = command["command"].ToString();
                            commands.Add(new Command(id, false, playerId, playerName, commandString));
                        }
                        ProcessCommands(commands);
                    }
                    catch (Exception e) {
                        PrintError($"An exception was thrown whilst processing the offline commands: {e.Message}");
                        if (debugLogResponseErrors) PrintError($"Associated response: {response}");
                        if (debugLogStackTraces) PrintError(e.StackTrace);
                    }
                    return;
                }
                PrintError($"An unhandled error occurred whilst processing the offline commands (response code: {code}).");
            }
            , this, RequestMethod.GET, AddToHeaders(secretKey), 3000f);
        }
        private void ProcessOnlineCommands(IPlayer player, string shopPlayerId) {
            webrequest.Enqueue($"{BASE_URL}/queue/online-commands/{shopPlayerId}", "", (code, response) => {
                if (response != null) {
                    try {
                        var jObject = JObject.Parse(response);
                        switch (code) {
                            case 200 : break;
                            case 403 : StartValidationTimer(60f);
                            goto default;
                            default : PrintWarning($"An error occurred whilst processing the online commands for {player.Id}: {jObject["error_message"].ToString()}");
                            return;
      
// ... [Code preview truncated due to length. Full source in attached file] ...

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