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

FREE PoundBot : 2.0.1 2.0.1

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Libraries;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace Oxide.Plugins {
    [Info("Pound Bot", "MrPoundsign", "2.0.1")]
    [Description("Connector for the Discord bot PoundBot.")]
    class PoundBot : CovalencePlugin {
        const string EntityDeathURI = "/entity_death";
        const string ApiMessageBaseURI = "/messages";
        const string ApiRolesURI = "/roles";
        const string ApiChatURI = "/chat";
        const string ApiRegisteredPlayersURI = "/players/registered";
        const string ApiDiscordAuthURI = "/discord_auth";
        const string ApiClansURI = "/clans";
        private string ApiBaseURI;
        enum DebugLevels {
            TRACE, INFO
        }
        ;
        protected string DebugURI = "";
        protected int DebugLevel = (int)DebugLevels.INFO;
        protected int ApiRetrySeconds = 1;
        protected int ApiRetryNotify = 30;
        protected string RegisteredUsersGroup;
        protected bool ApiInError;
        protected bool ApiRetry;
        protected uint ApiRetryAttempts;
        protected DateTime ApiErrorTime;
        protected DateTime LastApiAttempt;
        private Dictionary<string, string> RequestHeaders;
        protected bool RegisteredUsersInFlight;
        private ChannelList KnownChannelList;
        class ApiErrorResponse {
            public string Error;
        }
        class ApiRequest {
            public RequestMethod Method;
            public string URI;
            public string Body;
            public Plugin Plugin;
            public string RequestUUID;
            public ApiRequest(RequestMethod method, string uri, string body, Plugin plugin) {
                Method = method;
                URI = uri;
                Body = body;
                Plugin = plugin;
                RequestUUID = Guid.NewGuid().ToString();
            }
        }
#region PoundBot messages
        class Channel {
            public string ID;
            public string Name;
            public bool CanSend;
            public bool CanStyle;
            public bool IsAvailable() {
                return CanSend || CanStyle;
            }
        }
        class ChannelList {
            public Channel[] Channels;
            public bool CanSendTo(string channel) {
                foreach (Channel chan in Channels) {
                    if (chan.Name == channel || chan.ID == channel) {
                        return chan.CanSend;
                    }
                }
                return false;
            }
            public bool CanStyleTo(string channel) {
                foreach (Channel chan in Channels) {
                    if (chan.Name == channel || chan.ID == channel) {
                        return chan.CanStyle;
                    }
                }
                return false;
            }
        }
        class DiscordAuth {
            public string PlayerID;
            public string DisplayName;
            public string ClanTag;
            public string DiscordName;
            public int Pin;
            public DateTime CreatedAt;
            public DiscordAuth(string displayName, string discordName, string playerid) {
                Pin = new System.Random().Next(1, 9999);
                DisplayName = displayName;
                DiscordName = discordName;
                PlayerID = playerid;
                CreatedAt = DateTime.UtcNow;
            }
        }
        public class GameMessageEmbedStyle {
            public string Color {
                get;
                set;
            }
        }
        class GameMessagePart {
            public string Content {
                get;
                set;
            }
            public bool Escape {
                get;
                set;
            }
        }
        class GameMessage {
            public GameMessagePart[] MessageParts {
                get;
                set;
            }
            public int Type {
                get;
                set;
            }
            // 0 = plain, 1 = embedded
            public GameMessageEmbedStyle EmbedStyle {
                get;
                set;
            }
        }
        class RoleSyncRequest {
            public string GuildID;
            public string[] PlayerIDs;
        }
        class EntityDeath {
            public string Name;
            public string GridPos;
            public string[] OwnerIDs;
            public DateTime CreatedAt;
            public EntityDeath(string name, string gridpos, string[] ownerIDs) {
                Name = name;
                GridPos = gridpos;
                OwnerIDs = ownerIDs;
                CreatedAt = DateTime.UtcNow;
            }
        }
#endregion
#region Configuration
        protected override void LoadDefaultConfig() {
            Config["api.url"] = "https://api.poundbot.com/";
            Config["api.key"] = "API KEY HERE";
            Config["config.version"] = 2;
            Config["players.registered.group"] = "poundbot.registered";
        }
        void UpgradeConfig() {
            string configVersion = "config.version";
            bool dirty = false;
            if (Config[configVersion] == null) {
                Config[configVersion] = 1;
            }
            else {
                try {
                    var foo = (string)Config[configVersion];
                    Config[configVersion] = 2;
                    dirty = true;
                }
                catch (InvalidCastException) {
                }
                // testing if it can be converted to a string or not.No need to change it because it's not a string.}
                if ((int)Config[configVersion] < 2) {
                    LogWarning(string.Format(lang.GetMessage("config.upgrading", this), "1.1.2"));
                    // Update the API endpoint
                    string api_url = (string)Config["api_url"];
                    if (api_url == "http://poundbot.mrpoundsign.com/" || api_url == "http://api.poundbot.com/") {
                        Config["api.url"] = "https://api.poundbot.com/";
                    }
                    else {
                        Config["api.url"] = (string)Config["api_url"];
                    }
                    Config["api.key"] = (string)Config["api_key"];
                    Config.Remove("api_url");
                    Config.Remove("api_key");
                    Config["players.registered.group"] = "poundbot.registered";
                    Config[configVersion] = 2;
                    dirty = true;
                }
                if (dirty) {
                    SaveConfig();
                }
            }
#endregion
#region Language
            protected override void LoadDefaultMessages() {
                lang.RegisterMessages(new Dictionary<string, string> {
                    ["config.upgrading"]
                    = "Upgrading config to v{0}", ["config.api_key_updated"] = "Your API key has been updated.Check config/PoundBot.json.", ["command.poundbot_register"] = "pbreg", ["connector.reconnected"] = "Reconnected with PoundBot", ["connector.time_in_error"] = "Total time in error: {0}", ["connector.error"] = "Error communicating with PoundBot: {0}:{1}", ["connector.error_with_rid"] = "Error communicating with PoundBot: [{0}] {1}:{2}", ["connector.user_error"] = "Cannot connect to PoundBot right now.Please alert the admins.", ["discord.pin"] = "Enter the following PIN to the bot in discord: {0}.", ["discord.connected"] = "You are registered.", ["discord.already_connected"] = "You are already registered.", ["discord.not_connected"] = "Registration not found.", ["discord.channels_updated"] = "Channel cache updated.", ["discord.channel_cannot_send"] = "Cannot send to channel {0}.Please check that the bot can send to this channel.Run pb.updatechannels after making Discord changes to update the cache.", ["discord.channel_cannot_style"] = "Cannot send to channel {0}.Please check that the bot can embed links to this channel.Run pb.updatechannels after making Discord changes to update the cache.", ["usage.pbreg"] = "Usage: {0} \"<discord name>\"\n Example: {0} \"Fancy Guy#8080\"", ["usage.set_api_key"] = "Usage:\n\tpb.set_api_key <api key>", ["discord.console.registration_attempt"] = "Player {0}({1}) attempting to register as {2}",
                }
                , this);
            }
#endregion
#region Oxide API
            void Init() {
                UpgradeConfig();
                ApiBaseURI = $"{Config["api.url"]}api";
                ApplyConfig();
                RegisteredUsersGroup = (string)Config["players.registered.group"];
                permission.RegisterPermission(RegisteredUsersGroup, this);
                if (!permission.GroupExists(RegisteredUsersGroup)) {
                    permission.CreateGroup(RegisteredUsersGroup, "PoundBot Registered Users", 0);
                }
                AddLocalizedCommand("command.poundbot_register", "CommandPoundBotRegister");
                Connected();
                timer.Every(5f, () => {
                    if (RegisteredUsersInFlight) return;
                    RegisteredUsersInFlight = true;
                    Request(new ApiRequest(RequestMethod.GET, ApiRegisteredPlayersURI, null, this), (code, response) => {
                        RegisteredUsersInFlight = false;
                        if (code == 200) {
                            string[] groupPlayerIDs = permission.GetUsersInGroup(RegisteredUsersGroup);
                            string[] playerIDs = JsonConvert.DeserializeObject<string[]>(response);
                            for (int i = 0; i < groupPlayerIDs.Length; i++) {
                                groupPlayerIDs[i] = groupPlayerIDs[i].Substring(0, groupPlayerIDs[i].IndexOf(' '));
                            }
                            // hot group diff action
                            string[] playersToRemove = groupPlayerIDs.Except(playerIDs).ToArray();
                            string[] playersToAdd = playerIDs.Except(groupPlayerIDs).ToArray();
                            if (playersToAdd.Length + playersToRemove.Length == 0) {
                                return true;
                            }
                            foreach (string id in playersToRemove) {
                                Puts($"Removing user {id} from {RegisteredUsersGroup}");
                                permission.RemoveUserGroup(id, RegisteredUsersGroup);
                            }
                            foreach (string id in playersToAdd) {
                                Puts($"Adding user {id} to {RegisteredUsersGroup}");
                                permission.AddUserGroup(id, RegisteredUsersGroup);
                            }
                            return true;
                        }
                        Puts("Unuccessful registered players get");
                        Puts(response);
                        return false;
                    }
                    );
                }
                );
            }
#endregion
            private void ApplyConfig() {
                RequestHeaders = new Dictionary<string, string> {
                    ["Content-type"]
                    = "application/json", ["Authorization"] = $"Token {Config["api.key"]}", ["X-PoundBotConnector-Version"] = Version.ToString(), ["User-Agent"] = $"PoundBotConnector/{Version.ToString()}", ["X-PoundBot-Game"] = covalence.Game.ToLower()
                }
                ;
            }
#region API
            // private Dictionary<string, string> Headers() => RequestHeaders;
            private string API_RegisteredUsersGroup() => RegisteredUsersGroup;
            private string ApiBase() => ApiBaseURI;
            private bool ApiRequestOk() {
                if (ApiInError && !ApiRetry && (LastApiAttempt.AddSeconds(ApiRetrySeconds) < DateTime.Now)) {
                    ApiRetryAttempts++;
                    if (ApiRetryAttempts == 1 || ApiRetryAttempts % ApiRetryNotify == 0) {
                        Puts(string.Format(lang.GetMessage("connector.time_in_error", this), DateTime.Now.Subtract(ApiErrorTime)));
                    }
                    ApiRetry = true;
                }
                return (!ApiInError || ApiRetry);
            }
            private void ApiError(int code, string response, string requestID = null) {
                string error;
                if (ApiInError) {
                    if (ApiRetry) {
                        LastApiAttempt = DateTime.Now;
                        ApiRetry = false;
                    }
                    if (ApiRetryAttempts % ApiRetryNotify != 0) return;
                }
                else {
                    ApiErrorTime = DateTime.Now;
                    LastApiAttempt = DateTime.Now;
                    ApiInError = true;
                    ApiRetry = false;
                }
                if (code == 0) {
                    error = "Connection Failure!";
                }
                else {
                    try {
                        var air = JsonConvert.DeserializeObject<ApiErrorResponse>(response);
                        error = air.Error;
                    }
                    catch {
                        error = response;
                    }
                }
                if (code == 0) {
                    Puts(string.Format(lang.GetMessage("connector.error", this), code, error));
                    return;
                }
                Puts(string.Format(lang.GetMessage("connector.error_with_rid", this), requestID, code, error));
            }
            private bool ApiSuccess(bool success) {
                // Reset retry variables if we're successful
                if (ApiInError && success) {
                    Puts(lang.GetMessage("connector.reconnected", this));
                    Puts(string.Format(lang.GetMessage("connector.time_in_error", this), DateTime.Now.Subtract(ApiErrorTime)));
                    ApiRetryAttempts = 0;
                    ApiInError = false;
                    ApiRetry = true;
                    Connected();
                }
                return success;
            }
#region Requests
            private bool Request(ApiRequest api_request, Func<int, string, bool> callback) {
                if (!ApiRequestOk()) return false;
                if (DebugURI.Length > 0 && api_request.URI.StartsWith(DebugURI)) {
                    Puts($"Request from {api_request.Plugin.Name} to {api_request.URI} with RequestUUID {api_request.RequestUUID}\n{api_request.Body}");
                }
                if (api_request.Plugin == null) {
                    api_request.Plugin = this;
                }
                Dictionary<string, string> rHeaders = new Dictionary<string, string>(RequestHeaders);
                rHeaders["X-Request-ID"] = api_request.RequestUUID;
                webrequest.Enqueue($"{ApiBaseURI}{api_request.URI}", api_request.Body, (code, response) => {
                    if (!ApiSuccess(callback(code, response))) {
                        ApiError(code, response, rHeaders["X-Request-ID"]);
                    }
                }
                , api_request.Plugin, api_request.Method, rHeaders, 12000f);
                return true;
            }
            // Returns true if request was sent, false otherwise.private bool API_Request(string uri, string body, Func<int, string, bool> callback, Plugin owner, RequestMethod method = RequestMethod.GET, Dictionary<string, string> headers = null)
            {
                return Request(new ApiRequest(method, uri, body, this), callback);
            }
#endregion
#region Messages API
            private bool API_SendChannelMessage(Plugin owner, string channel, KeyValuePair<string, bool>[] message_parts, string embed_color = null, Func<int, string, bool> callback = null, Dictionary<string, string> headers = null, string type = "plain") {
                List<GameMessagePart> parts = new List<GameMessagePart>();
                foreach (KeyValuePair<string, bool> part in message_parts) {
                    parts.Add(new GameMessagePart {
                        Content = part.Key, Escape = part.Value
                    }
                    );
                }
                GameMessage sm = new GameMessage {
                    MessageParts = parts.ToArray()
                }
                ;
                if (embed_color != null) {
                    if (!KnownChannelList.CanStyleTo(channel)) {
                        Puts(string.Format(lang.GetMessage("discord.channel_cannot_style", this), channel));
                        return false;
                    }
                    sm.Type = 1;
                    sm.EmbedStyle = new GameMessageEmbedStyle {
                        Color = embed_color
                    }
                    ;
                }
                else {
                    if (!KnownChannelList.CanSendTo(channel)) {
                        Puts(string.Format(lang.GetMessage("discord.channel_cannot_send", this), channel));
                        return false;
                    }
                }
                if (channel[0] == '#') {
                    channel = channel.Substring(1);
                }
                if (callback == null) {
                    callback = (int code, string response) => (code == 200);
                }
                string body = JsonConvert.SerializeObject(sm);
                return Request(new ApiRequest(RequestMethod.POST, $"{ApiMessageBaseURI}/{channel}", body, owner), callback);
            }
            private bool API_GetChannelMessage(Plugin owner, string channel, Func<int, string, bool> callback = null) {
                return Request(new ApiRequest(RequestMethod.GET, ApiChatURI, null, owner), callback);
            }
#endregion
#region Roles API
            private bool API_SendRole(Plugin owner, string[] groupPlayerIDs, string role, Func<int, string, bool> callback) {
                RoleSyncRequest rsr = new RoleSyncRequest {
                    PlayerIDs = groupPlayerIDs,
                }
                ;
                return Request(new ApiRequest(RequestMethod.POST, $"{ApiRolesURI}/{role}", JsonConvert.SerializeObject(rsr), owner), callback);
            }
#endregion
            private bool API_SendEntityDeath(Plugin owner, string name, string gridPos, string[] owners, Func<int, string, bool> callback) {
                EntityDeath di = new EntityDeath(name, gridPos, owners);
                return Request(new ApiRequest(RequestMethod.PUT, EntityDeathURI, JsonConvert.SerializeObject(di), owner), callback);
            }
            private bool API_SendClans(Plugin owner, List<JObject> clans, Func<int, string, bool> callback) {
                return Request(new ApiRequest(RequestMethod.PUT, ApiClansURI, JsonConvert.SerializeObject(clans), owner), callback);
            }
            private bool API_SendClan(Plugin owner, string tag, JObject clan, Func<int, string, bool> callback) {
                return Request(new ApiRequest(RequestMethod.PUT, $"{ApiClansURI}/{tag}", JsonConvert.SerializeObject(clan), owner), callback);
            }
            private bool API_DeleteClan(Plugin owner, string tag, Func<int, string, bool> callback) {
                return Request(new ApiRequest(RequestMethod.DELETE, $"{ApiClansURI}/{tag}", null, owner), callback);
            }
            private void Connected() {
                UpdateChannels();
                Interface.Call("OnPoundBotConnected");
            }
#endregion
            private void UpdateChannels() {
                Request(new ApiRequest(RequestMethod.GET, ApiMessageBaseURI, null, this), (code, response) => {
                    if (code == 200) {
                        KnownChannelList = JsonConvert.DeserializeObject<ChannelList>(response);
                        Puts(lang.GetMessage("discord.channels_updated", this));
                        return true;
                    }
                    return false;
                }
                );
            }
            public void PrintChannels(bool all = false) {
                foreach (Channel c in KnownChannelList.Channels) {
                    if (all || c.IsAvailable()) {
                        Puts($"ID: {c.ID}, Name: {c.Name}, CanSend: {c.CanSend}, CanStyle: {c.CanStyle}");
                    }
                }
            }
#region Helpers
            private void AddLocalizedCommand(string key, string command) {
                foreach (var language in lang.GetLanguages(this)) {
                    var messages = lang.GetMessages(language, this);
                    foreach (var message in messages.Where(m => m.Key.Equals(key))) if (!string.IsNullOrEmpty(message.Value)) AddCovalenceCommand(message.Value, command);
                }
            }
#endregion
#region Commands
            private void CommandPoundBotRegister(IPlayer player, string command, string[] args) {
                if (args.Length != 1) {
                    player.Message(string.Format(lang.GetMessage("usage.pbreg", this, player.Id), lang.GetMessage("command.poundbot_register", this, player.Id)));
                    return;
                }
                if (args[0] == "check") {
                    Request(new ApiRequest(RequestMethod.GET, $"{ApiDiscordAuthURI}/check/{player.Id}", null, this), (code, response) => {
                        if (code == 200) {
                            player.Message(lang.GetMessage("discord.connected", this, player.Id));
                            return true;
                        }
                        if (code == 404)  // Method not allowed means we're already connected
                        {
                            player.Message(lang.GetMessage("discord.not_connected", this, player.Id));
                            return true;
                        }
                        return false;
                    }
                    );
                    return;
                }
                Regex r = new Regex(@"^[^#]+#[0-9]+$");
                if (!r.Match(args[0]).Success) {
                    player.Message(lang.GetMessage("usage.pbreg", this, player.Id));
                    return;
                }
                string.Format(lang.GetMessage("discord.console.registration_attempt", this), player.Name, player.Id, args[0]);
                var da = new DiscordAuth(player.Name, args[0], player.Id);
                Request(new ApiRequest(RequestMethod.PUT, ApiDiscordAuthURI, JsonConvert.SerializeObject(da), this), (code, response) => {
                    if (code == 200) {
                        player.Message(string.Format(lang.GetMessage("discord.pin", this, player.Id), da.Pin.ToString("D4")));
                        return true;
                    }
                    if (code == 409)  // Conflict means we're already connected
                    {
                        player.Message(lang.GetMessage("discord.already_connected", this, player.Id));
                        return true;
                    }
                    return false;
                }
                );
            }
            [Command("pb.update_channels")]
            private void ConsoleCommandUpdateChannels(IPlayer player, string command, string[] args) {
                UpdateChannels();
            }
            [Command("pb.channels")]
            private void ConsoleCommandChannels(IPlayer player, string command, string[] args) {
                PrintChannels((args.Length != 0));
            }
            [Command("pb.set_api_key")]
            private void ConsoleCommandSetAPIKey(IPlayer player, string command, string[] args) {
                if (args.Count() != 1) {
                    Puts(lang.GetMessage("usage.set_api_key", this));
                    return;
                }
                Puts(lang.GetMessage("config.api_key_updated", this));
                Config["api.key"] = args[0];
                SaveConfig();
                ApplyConfig();
            }
            [Command("pb.set_debug_uri")]
            private void ConsoleCommandSetDebugURI(IPlayer player, string command, string[] args) {
                if (args.Count() != 1) {
                    Puts(lang.GetMessage("usage.set_debug_uri", this));
                    return;
                }
                DebugURI = args[0];
            }
#endregion
        }
    }

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