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

FREE DiscordCore : 0.14.6 0.14.6

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Ext.Discord;
using Oxide.Ext.Discord.Attributes;
using Oxide.Ext.Discord.DiscordEvents;
using Oxide.Ext.Discord.DiscordObjects;
using DiscordUser = Oxide.Ext.Discord.DiscordObjects.User;

namespace Oxide.Plugins
{
    [Info("Discord Core", "MJSU", "0.14.6")]
    [Description("Sets up a channel link between a user and a game server")]
    internal class DiscordCore : CovalencePlugin
    {
        #region Class Fields
        private StoredData _storedData; //Plugin Data
        private PluginConfig _pluginConfig; //Plugin Config

        [DiscordClient] private DiscordClient _client;

        private const string AccentColor = "de8732";
        private const string UsePermission = "discordcore.use";
        private const string PluginsPermission = "discordcore.plugins";

        private readonly Hash<string, DiscordCommand> _discordCommands = new Hash<string, DiscordCommand>();
        private readonly Hash<string, List<ChannelSubscription>> _channelSubscriptions = new Hash<string, List<ChannelSubscription>>();

        private readonly List<DiscordActivation> _pendingDiscordActivations = new List<DiscordActivation>();
        private readonly Hash<string, InGameActivation> _pendingInGameActivation = new Hash<string, InGameActivation>();

        private readonly List<Plugin> _hookPlugins = new List<Plugin>();

        private DiscordUser _bot;
        private Guild _discordServer;

        private enum ConnectionStateEnum : byte { Disconnected, Connecting, Connected }
        private ConnectionStateEnum _connectionState = ConnectionStateEnum.Disconnected;
        private DateTime _lastUpdate;
        private bool _initialized;
        private Timer _connectionTimeout;
        private int _guildCount;
        #endregion

        #region Setup & Loading
        private void Init()
        {
            ConfigLoad();

            _storedData = Interface.Oxide.DataFileSystem.ReadObject<StoredData>(Name);

            permission.RegisterPermission(UsePermission, this);
            permission.RegisterPermission(PluginsPermission, this);

            AddCovalenceCommand(_pluginConfig.GameChatCommand, nameof(DiscordChatCommand));
        }

        protected override void LoadDefaultConfig()
        {
            PrintWarning("Loading Default Config");
        }

        private void ConfigLoad()
        {
            Config.Settings.DefaultValueHandling = DefaultValueHandling.Populate;
            _pluginConfig = Config.ReadObject<PluginConfig>();
            Config.WriteObject(_pluginConfig);
        }

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                [LangKeys.NoPermission] = "You do not have permission to use this command",
                [LangKeys.ChatFormat] = $"[#BEBEBE][[#{AccentColor}]{Title}[/#]] {{0}}[/#]",
                [LangKeys.UnknownCommand] = "Unknown Command",
                [LangKeys.DiscordLeave] = "You have removed your discord bot connection",
                [LangKeys.DiscordLeaveFailed] = "You are not subscribed to discord and were not removed",
                [LangKeys.JoinAlreadySignedUp] = $"You're already signed up for discord.If you want to remove yourself from discord type [#{AccentColor}]/{{0}} leave[/#]",
                [LangKeys.JoinInvalidSyntax] = $"Invalid Syntax.Ex.[#{AccentColor}]/{{0}} join name#1234[/#] to sign up for discord",
                [LangKeys.JoinUnableToFindUser] = $"Unable to find user '{{0}}' in the {{1}} discord.Have you joined the {{1}} discord server @ [#{AccentColor}]discord.gg/{{2}}[/#]?",
                [LangKeys.JoinReceivedPm] = $"You have received a PM from the {{0}}.Please respond to the bot with your code to complete the discord activation.\n[#{AccentColor}]{{1}}[/#]",
                [LangKeys.JoinPleaseEnterCode] = "Please enter your code here to complete activation.",
                [LangKeys.DiscordJoinInvalidSyntax] = $"Invalid syntax.Type [#{AccentColor}]/{{0}} code 123456[/#] where 123456 is the code you got from discord",
                [LangKeys.DiscordJoinNoPendingActivations] = "You either don't have a pending activation or your code is invalid",
                [LangKeys.DiscordJoinSuccessfullyRegistered] = "You have successfully registered your discord with the server",
                [LangKeys.DiscordCommandsPreText] = "Available Commands:",
                [LangKeys.DiscordCommandsBotChannelAllowed] = "(Bot Channel Allowed)",
                [LangKeys.DiscordPlugins] = "List of Discord enabled plugins:\n",
                [LangKeys.DiscordJoinWrongChannel] = "Please use /{0} in this private message and not to any discord server channels",
                [LangKeys.DiscordUseCommandsHere] = "Please use all commands here.",
                [LangKeys.DiscordPrivateChannel] = "Please use all commands in the bot private message or in the bot channel",
                [LangKeys.DiscordNotAllowedBotChannel] = "This command is not allowed in the bot channel and can only be used here.",
                [LangKeys.DiscordMustSignUpBeforeCommands] = "You need to sign up for discord before you can start using commands.To begin type /{0}",
                [LangKeys.DiscordClientNotConnected] = "The discord client is not connected.Please contact an admin.",
                [LangKeys.GameJoinCodeNotMatch] = "Your activation code does not match! Please reply with only the code.",
                [LangKeys.DiscordCompleteActivation] = "To complete your discord activation in the server chat please type /{0} code {1}",


                [LangKeys.DiscordUserJoin] = "If you would like to link your discord account with the {0} server respond to this message with /{1}." +
                                      "This provides you with a bot which gives you access to commands while not on the server.Once you sign up type /{2} to learn more",
                [LangKeys.HelpNotLinked] = "Discord: Allows communication between a server and discord.\n" +
                               "Type /{0} - (In a private message to the bot) - to start linking your server player and discord together\n" +
                               "Type /{1} - to see this message again",
                [LangKeys.HelpLinked] = "Discord: Allows communication between a server and discord.\n" +
                                  "Type /{0} - (In a private message to the bot) - to see the list of available commands\n" +
                                  "Type /{1} - (In a private message to the bot) - to unlink your discord from the game server\n" +
                                  "Type /{2} - to see this message again",

                [LangKeys.HelpText] = $"Allows players to link their player and discord accounts together.Players must first join the {{0}} Discord @ [#{AccentColor}]discord.gg/{{1}}[/#]\n" +
                                      $"Type [#{AccentColor}]/{{2}} join discordusername#discorduserid[/#] to start the activation of discord\n" +
                                      $"Type [#{AccentColor}]/{{2}} leave[/#] to remove yourself from discord\n" +
                                      $"Type [#{AccentColor}]/{{2}}[/#] to see this message again"
            }, this);
        }
        
        private void OnServerInitialized()
        {
            ConnectClient();
            _lastUpdate = DateTime.Now;
            timer.Every(60, () =>
            {
                if (_connectionState != ConnectionStateEnum.Connecting && (DateTime.Now - _lastUpdate).TotalSeconds > 120)
                {
                    PrintWarning("Heartbeat timed out.Reconnecting");
                    CloseClient();
                    ConnectClient();
                }
            });
        }

        private void Unload()
        {
            CloseClient();
        }

        private void ConnectClient()
        {
            if (string.IsNullOrEmpty(_pluginConfig.DiscordApiKey))
            {
                PrintWarning("Please enter your discord bot API key and reload the plugin");
                return;
            }
            
            _connectionState = ConnectionStateEnum.Connecting;
            timer.In(5f, () =>
            {
                Discord.CreateClient(this, _pluginConfig.DiscordApiKey); // Create a new DiscordClient
                timer.In(60f, () =>
                {
                    if (_connectionState == ConnectionStateEnum.Connecting)
                    {
                        _connectionState = ConnectionStateEnum.Disconnected;
                    }
                });
            });
        }

        private void CloseClient()
        {
            _connectionState = ConnectionStateEnum.Disconnected;
            Discord.CloseClient(_client);
        }

        private void OnPluginUnloaded(Plugin plugin)
        {
            foreach (KeyValuePair<string, DiscordCommand> commands in _discordCommands.Where(dc => dc.Value.PluginName == plugin.Name).ToList())
            {
                UnregisterCommand(commands.Key, plugin);
            }

            foreach (KeyValuePair<string, List<ChannelSubscription>> channelSubscription in _channelSubscriptions)
            {
                if (channelSubscription.Value.Any(cs => cs.PluginName == plugin.Name))
                {
                    UnsubscribeChannel(channelSubscription.Key, plugin);
                }
            }

            if (_hookPlugins.Contains(plugin))
            {
                _hookPlugins.Remove(plugin);
                _client.Plugins.Remove(plugin);
            }
        }

        private void OnUserConnected(IPlayer player)
        {
            DiscordInfo info = _storedData.PlayerDiscordInfo[player.Id];
            if (info == null)
            {
                return;
            }

            info.DisplayName = player.Name;
            NextTick(SaveData);
        }
        #endregion

        #region Chat Commands
        private void DiscordChatCommand(IPlayer player, string cmd, string[] args)
        {
            if (!player.HasPermission(UsePermission) && !player.IsAdmin)
            {
                Chat(player, Lang(LangKeys.NoPermission, player));
                return;
            }

            if (args.Length == 0)
            {
                DisplayHelp(player);
                return;
            }

            switch (args[0].ToLower())
            {
                case "join":
                    HandleJoin(player, args);
                    break;

                case "code":
                    HandleDiscordJoinCode(player, args);
                    break;

                case "leave":
                    if (_storedData.PlayerDiscordInfo.ContainsKey(player.Id))
                    {
                        _storedData.PlayerDiscordInfo.Remove(player.Id);
                        SaveData();
                        Chat(player, Lang(LangKeys.DiscordLeave, player));
                        Interface.Call("OnDiscordCoreLeave", player);
                    }
                    else
                    {
                        Chat(player, Lang(LangKeys.DiscordLeaveFailed, player));
                    }
                    break;

                default:
                    DisplayHelp(player);
                    break;
            }
        }

        private void DisplayHelp(IPlayer player)
        {
            Chat(player, Lang(LangKeys.HelpText, player, GetDiscordName(), _pluginConfig.JoinCode, _pluginConfig.GameChatCommand));
        }

        private void HandleJoin(IPlayer player, string[] args)
        {
            if (_storedData.PlayerDiscordInfo.ContainsKey(player.Id))
            {
                Chat(player, Lang(LangKeys.JoinAlreadySignedUp, player, _pluginConfig.GameChatCommand));
                return;
            }

            if (args.Length < 2)
            {
                Chat(player, Lang(LangKeys.JoinInvalidSyntax, player, _pluginConfig.GameChatCommand));
                return;
            }

            if (_client == null)
            {
                Chat(player, Lang(LangKeys.DiscordClientNotConnected, player));
                return;
            }

            DiscordUser user = GetUserByUsername(args[1]);
            if (user == null)
            {
                Chat(player, Lang(LangKeys.JoinUnableToFindUser, player, args[1], GetDiscordName(), _pluginConfig.JoinCode));
                return;
            }

            if (_storedData.PlayerDiscordInfo.Values.Any(di => di.DiscordId == user.id))
            {
                Chat(player, Lang(LangKeys.JoinAlreadySignedUp, player, _pluginConfig.GameChatCommand));
                return;
            }

            string code = Core.Random.Range(0, 1000000).ToString("D6");
            _pendingInGameActivation[user.id] = new InGameActivation
            {
                Code = code,
                PlayerId = player.Id
            };

            Chat(player, Lang(LangKeys.JoinReceivedPm, player, _bot.username, code));
            CreateChannelActivation(player, user, code, Lang(LangKeys.JoinPleaseEnterCode, player));
        }

        private void HandleDiscordJoinCode(IPlayer player, string[] args)
        {
            if (_storedData.PlayerDiscordInfo.ContainsKey(player.Id))
            {
                Chat(player, Lang(LangKeys.JoinAlreadySignedUp, player, _pluginConfig.GameChatCommand));
                return;
            }

            if (args.Length < 2)
            {
                Chat(player, Lang(LangKeys.DiscordJoinInvalidSyntax, player, _pluginConfig.GameChatCommand));
                return;
            }

            DiscordActivation act = _pendingDiscordActivations.FirstOrDefault(a => a.Code == args[1]);
            if (act == null)
            {
                Chat(player, Lang(LangKeys.DiscordJoinNoPendingActivations, player));
                return;
            }

            _storedData.PlayerDiscordInfo[player.Id] = new DiscordInfo
            {
                DisplayName = player.Name,
                PlayerId = player.Id,
                DiscordId = act.DiscordId,
                ChannelId = act.ChannelId
            };

            SaveData();
            SendMessageToUser(player.Id, Lang(LangKeys.DiscordJoinSuccessfullyRegistered, player));
            Chat(player, Lang(LangKeys.DiscordJoinSuccessfullyRegistered, player));
            Interface.Call("OnDiscordCoreJoin", player);
        }
        #endregion

        #region Internal Discord Commands
        private object HandleHelp(IPlayer player, string channelId, string cmd, string[] args)
        {
            string message;
            if (player == null)
            {
                message = Lang(LangKeys.HelpNotLinked, null, _pluginConfig.DiscordJoinCommand, _pluginConfig.HelpCommand);
            }
            else
            {
                message = Lang(LangKeys.HelpLinked, player, _pluginConfig.CommandsCommand, _pluginConfig.LeaveCommand, _pluginConfig.HelpCommand);
            }
            
            SendMessageToChannel(channelId, message);
            return null;
        }

        private object HandleCommands(IPlayer player, string channelId, string cmd, string[] args)
        {
            string commands = $"Discord: {Lang(LangKeys.DiscordCommandsPreText, player)}\n";
            foreach (KeyValuePair<string, DiscordCommand> command in _discordCommands)
            {
                if (!string.IsNullOrEmpty(command.Value.Permission) && !player.HasPermission(command.Value.Permission))
                {
                    continue;
                }

                string commandText = $"/{command.Key}";
                string botChannel = $" {(_pluginConfig.EnableBotChannel && command.Value.AllowInBotChannel ? Lang(LangKeys.DiscordCommandsBotChannelAllowed, player) : "")}";
                string helpText = lang.GetMessage(command.Value.HelpText, command.Value.Plugin, player.Id);

                commands += $"{commandText}{botChannel} - {helpText}\n";
            }

            SendMessageToChannel(channelId, commands);
            return null;
        }

        private object HandleLeave(IPlayer player, string channelId, string cmd, string[] args)
        {
            SendMessageToChannel(channelId, "Discord: " + Lang(LangKeys.DiscordLeave, player));
            _storedData.PlayerDiscordInfo.Remove(player.Id);
            SaveData();
            Interface.Call("OnDiscordCoreLeave", player);
            return null;
        }

        private object HandlePlugins(IPlayer player, string channelId, string cmd, string[] args)
        {
            string pluginList = _discordCommands.Select(dc => dc.Value.PluginName).Distinct().Aggregate("Discord: " + Lang(LangKeys.DiscordPlugins, player), (current, plugin) => current + $"{plugin}\n");
            SendMessageToChannel(channelId, pluginList);
            return null;
        }

        #endregion

        #region Discord Hooks
        private void Discord_Ready(Ready ready)
        {
            try
            {
                _guildCount = ready.Guilds.Count;
                if (_guildCount > 1)
                {
                    if (string.IsNullOrEmpty(_pluginConfig.BotGuildId))
                    {
                        PrintError("Bot Guild Id is blank and the bot is in multiple guilds." +
                                   "Please set the bot guild id to the discord server you wish it to work for.");
                        return;
                    }

                    if (ready.Guilds.All(g => g.id != _pluginConfig.BotGuildId))
                    {
                        PrintError("Failed to find a matching guild for the Bot Guild Id." +
                                   "Please make sure your guild Id is correct and the bot is in that discord server.");
                        return;
                    }
                }

                _bot = ready.User;
                Puts($"Connected to bot: {_bot.username}");

                _connectionTimeout = timer.In(60f, () =>
                {
                    CloseClient();
                    ConnectClient();
                });
            }
            catch (Exception ex)
            {
                _connectionState = ConnectionStateEnum.Disconnected;
                PrintError($"Failed to load DiscordCore: {ex}");
            }
        }
        
        private void Discord_GuildCreate(Guild guild)
        {
            if (_connectionState != ConnectionStateEnum.Connecting)
            {
                return;
            }

            if (_guildCount != 1 && guild.id != _pluginConfig.BotGuildId)
            {
                return;
            }

            GuildConnected(guild);
        }

        private void GuildConnected(Guild guild)
        {
            try
            {
                _connectionTimeout?.Destroy();
                _discordServer = guild;
                Puts($"Discord connected to server: {_discordServer.name}");

                _connectionState = ConnectionStateEnum.Connected;

                if (!_initialized)
                {
                    _initialized = true;
                    Interface.Call("OnDiscordCoreReady");
                }

                if (_pluginConfig.EnableBotChannel)
                {
                    if (_discordServer.channels.All(c => c.name != _pluginConfig.BotChannel && c.id != _pluginConfig.BotChannel))
                    {
                        PrintWarning($"Bot channel is enabled but there is no channel found with name or id '{_pluginConfig.BotChannel}' on the discord server");
                    }
                }
            }
            catch (Exception ex)
            {
                _connectionState = ConnectionStateEnum.Disconnected;
                PrintError($"Failed to connect to guild: {ex}");
            }
        }

        private void DiscordSocket_HeartbeatSent()
        {
            _lastUpdate = DateTime.Now;
        }

        private void Discord_MessageCreate(Message message)
        {
            if (!_initialized)
            {
                return;
            }

            if (message.author.username == _bot.username)
            {
                Interface.Oxide.CallHook("OnDiscordBotMessage", message);
                return;
            }

            bool botChannel = false;
            string content = message.content;

            Channel channel = _discordServer.channels.FirstOrDefault(c => c.id == message.channel_id);
            if (channel != null) 
            {
                bool shouldReturn = true;
                if (content.ToLower().StartsWith(_pluginConfig.DiscordJoinCommand))
                {
                    message.author.CreateDM(_client, pmChannel =>
                    {
                        pmChannel.CreateMessage(_client, Lang(LangKeys.DiscordJoinWrongChannel, null, _pluginConfig.DiscordJoinCommand));
                    });
                    NextTick(() =>
                    {
                        message.DeleteMessage(_client);
                    });
                }
                else if (content.StartsWith("/"))
                {
                    if (!_pluginConfig.EnableBotChannel)
                    {
                        NextTick(() =>
                        {
                            message.DeleteMessage(_client);
                        });
                        message.author.CreateDM(_client, pmChannel =>
                        {
                            pmChannel.CreateMessage(_client, Lang(LangKeys.DiscordUseCommandsHere));
                        });
                    }
                    else
                    {
                        if (!channel.name.ToLower().Equals(_pluginConfig.BotChannel.ToLower()) && channel.id != _pluginConfig.BotChannel)
                        {
                            NextTick(() =>
                            {
                                message.DeleteMessage(_client);
                            });
                            message.author.CreateDM(_client, pmChannel =>
                            {
                                pmChannel.CreateMessage(_client, Lang(LangKeys.DiscordPrivateChannel));
                            });
                        }
                        else
                        {
                            string cmd = content.TrimStart('/').Split(' ')[0];
                            if (_discordCommands.ContainsKey(cmd) && !_discordCommands[cmd].AllowInBotChannel)
                            {
                                NextTick(() =>
                                {
                                    message.DeleteMessage(_client);
                                });
                                message.author.CreateDM(_client, pmChannel =>
                                {
                                    pmChannel.CreateMessage(_client, Lang(LangKeys.DiscordNotAllowedBotChannel));
                                });
                            }
                            else
                            {
                                botChannel = true;
                                shouldReturn = false;
                            }
                        }
                    }
                }
                else if (_channelSubscriptions.ContainsKey(channel.id))
                {
                    object output = null;
                    foreach (ChannelSubscription subscription in _channelSubscriptions[channel.id])
                    {
                        try
                        {
                            output = subscription.Method.Invoke(message);
                        }
                        catch (Exception ex)
                        {
                            PrintError($"Error invoking method on plugin {subscription.PluginName} on subscribed channel method {subscription.Method.Method.Name}:\n{ex}");
                        }
                    }

                    if (output != null)
                    {
                        shouldReturn = false;
                    }
                }

                if (shouldReturn)
                {
                    return;
                }
            }

            InGameActivation inGameActivation = _pendingInGameActivation[message.author.id];
            if (inGameActivation != null)
            {
                HandleGameServerJoin(message, inGameActivation);
                return;
            }

            if (content.ToLower().StartsWith("/join"))
            {
                HandleDiscordJoin(message);
                return;
            }

            //Puts($"MessageCreate: {content}");

            DiscordInfo info = _storedData.GetInfoByDiscordId(message.author.id);
            if (info == null && !botChannel)
            {
                SendMessageToUser(message.author.id, Lang(LangKeys.DiscordMustSignUpBeforeCommands, null, _pluginConfig.DiscordJoinCommand));
                return;
            }

            try
            {
                IPlayer player = info == null ? null : covalence.Players.FindPlayerById(info.PlayerId);
                if (content.StartsWith("/"))
                {
                    string[] args;
                    string command;

                    ParseCommand(message.content.TrimStart('/'), out command, out args);
                    DiscordCommand discord = _discordCommands[command];
                    if (discord != null)
                    {
                        if (!string.IsNullOrEmpty(discord.Permission) && !player.HasPermission(discord.Permission))
                        {
                            SendMessageToUser(player, Lang(LangKeys.NoPermission, player));
                            return;
                        }
                        
                        discord.Method(player, message.channel_id, command, args);
                    }
                    else
                    {
                        SendMessageToUser(message.author.id, Lang(LangKeys.UnknownCommand, player));
                    }
                }
                else
                {
                    Interface.Call("OnDiscordChat", player, message.content);
                }
            }
            catch (Exception ex)
            {
                PrintError($"Error in message create:\n{ex}");
            }
        }

        private void Discord_MemberAdded(GuildMember member)
        {
            if (!_pluginConfig.EnabledJoinNotifications)
            {
                return;
            }
            
            member.user.CreateDM(_client, channel =>
            {
                channel.CreateMessage(_client, Lang(LangKeys.DiscordUserJoin, null, _discordServer.name, _pluginConfig.DiscordJoinCommand, _pluginConfig.HelpCommand));
            });
        }

        private void Discord_ChannelDelete(Channel channel)
        {
            // Delete all subscriptions to this channel for all plugins
            _channelSubscriptions.Remove(channel.id);

            //TODO: Remove once fix is implemented in Discord Extension
            _discordServer.channels.RemoveAll(c => c.id == channel.id);
        }

        private void Discord_UnhandledEvent(JObject messageObject)
        {
            if (_connectionState == ConnectionStateEnum.Connected)
            {
                PrintError($"Unhandled Event: {messageObject}");
                CloseClient();
                ConnectClient();
            }
        }

        private void DiscordSocket_WebSocketErrored(Exception exception, string message)
        {
            if (_connectionState == ConnectionStateEnum.Connected)
            {
                PrintError($"WebSocketError: {exception}\n{message}");
                CloseClient();
                ConnectClient();
            }
        }

        private void DiscordSocket_WebSocketClosed(string reason, int code, bool clean)
        {
            if (_connectionState == ConnectionStateEnum.Connected)
            {
                PrintWarning("WebSocketClose Detected.Restarting Connection.");
                CloseClient();
                ConnectClient();
            }
        }
        #endregion

        #region Joining
        private void HandleGameServerJoin(Message message, InGameActivation activation)
        {
            if (activation.Code != message.content)
            {
                message.Reply(_client, Lang(LangKeys.GameJoinCodeNotMatch), false);
                return;
            }

            _pendingInGameActivation.Remove(message.author.id);
            _storedData.PlayerDiscordInfo[activation.PlayerId] = new DiscordInfo
            {
                ChannelId = message.channel_id,
                DiscordId = message.author.id,
                PlayerId = activation.PlayerId,
                DisplayName = activation.DisplayName
            };

            IPlayer player = covalence.Players.FindPlayer(activation.PlayerId);
            SaveData();
            Chat(player, Lang(LangKeys.DiscordJoinSuccessfullyRegistered, player));
            message.Reply(_client, $"Discord: {Lang(LangKeys.DiscordJoinSuccessfullyRegistered, player)}", false);
            Interface.Call("OnDiscordCoreJoin", player);
        }

        private void HandleDiscordJoin(Message message)
        {
            if (_storedData.PlayerDiscordInfo.Any(di => di.Value.DiscordId == message.author.id))
            {
                message.Reply(_client, Formatter.ToPlaintext(Lang(LangKeys.JoinAlreadySignedUp, null, _pluginConfig.DiscordJoinCommand)), false);
                return;
            }

            string code = Core.Random.Range(0, 1000000).ToString("D6");
            _pendingDiscordActivations.Add(new DiscordActivation
            {
                Code = code,
                DiscordId = message.author.id,
                ChannelId = message.channel_id,
            });

            message.Reply(_client, Lang(LangKeys.DiscordCompleteActivation, null, _pluginConfig.GameChatCommand, code), false);
        }

        private DiscordUser GetUserByUsername(string userName)
        {
            return _discordServer.members.FirstOrDefault(m => $"{m?.user?.username?.ToLower()}#{m?.user?.discriminator}" == userName.ToLower())?.user;
        }

        private void CreateNewDmChannel(string discordId, string message)
        {
            DiscordInfo info = _storedData.GetInfoByDiscordId(discordId);
            if (info == null)
            {
                return;
            }

            DiscordUser.GetUser(_client, discordId, user =>
            {
                user?.CreateDM(_client, channel =>
                {
                    channel.CreateMessage(_client, message);
                    info.ChannelId = channel.id;
                    SaveData();
                });
            });
        }
        
        private void CreateNewDmChannel(string discordId, Message message)
        {
            DiscordInfo info = _storedData.GetInfoByDiscordId(discordId);
            if (info == null)
            {
                return;
            }

            DiscordUser.GetUser(_client, discordId, user =>
            {
                user?.CreateDM(_client, channel =>
                {
                    channel.CreateMessage(_client, message);
                    info.ChannelId = channel.id;
                    SaveData();
                });
            });
        }

        private void CreateChannelActivation(IPlayer player, DiscordUser user, string code, string message)
        {
            user.CreateDM(_client, channel =>
            {
                channel.CreateMessage(_client, message);
                _pendingInGameActivation[user.id] = new InGameActivation
                {
                    PlayerId = player.Id,
                    Code = code,
                    ChannelId = channel.id,
                    DisplayName = player.Name
                };
            });
        }
        #endregion

        #region API

        #region Discord Server
        [HookMethod("IsReady")]
        public bool IsReady()
        {
            return _client?.DiscordServer != null;
        }

        [HookMethod("GetClient")]
        public DiscordClient GetClient()
        {
            return _client;
        }

        [HookMethod("GetBot")]
        public DiscordUser GetBot()
        {
            return _bot;
        }

        [HookMethod("GetDiscordName")]
        public string GetDiscordName()
        {
            return _client?.DiscordServer.name ?? "Not Connected";
        }

        [HookMethod("GetDiscordJoinCode")]
        public string GetDiscordJoinCode()
        {
            return _pluginConfig.JoinCode;
        }

        [HookMethod("UpdatePresence")]
        public void UpdatePresence(Presence presence)
        {
            _client?.UpdateStatus(presence);
        }

        [HookMethod("RegisterPluginForExtensionHooks")]
        public void RegisterPluginForExtensionHooks(Plugin plugin)
        {
            if (!_client.Plugins.Contains(plugin))
            {
                _client.Plugins.Add(plugin);
            }

            if (!_hookPlugins.Contains(plugin))
            {
                _hookPlugins.Add(plugin);
            }
        }
        #endregion

        #region Send Message

        #region Channel
        [HookMethod("SendMessageToChannel")]
        public void SendMessageToChannel(string channelNameOrId, string message)
        {
            Channel channel = GetChannel(channelNameOrId);

            channel?.CreateMessage(_client,  StripRustTags(Formatter.ToPlaintext(message)));
        }
        
        [HookMethod("SendMessageToChannel")]
        public void SendMessageToChannel(string channelNameOrId, Message message)
        {
            Channel channel = GetChannel(channelNameOrId);

            channel?.CreateMessage(_client, message);
        }
        #endregion

        #region User
        [HookMethod("SendMessageToUser")]
        public void SendMessageToUser(string id, string message)
        {
            DiscordInfo info = _storedData.PlayerDiscordInfo[id];
            if (info == null)
            {
                info = _storedData.GetInfoByDiscordId(id);
                if (info == null)
                {
                    return;
                }
            }

            Channel.GetChannel(_client, info.ChannelId, channel =>
            {
                if (channel != null)
                {
                    channel.CreateMessage(_client, StripRustTags(Formatter.ToPlaintext(message)));
                }
                else
                {
                    CreateNewDmChannel(info.DiscordId, StripRustTags(Formatter.ToPlaintext(message)));
                }
            });
        }

        [HookMethod("SendMessageToUser")]
        public void SendMessageToUser(IPlayer player, string message)
        {
            SendMessageToUser(player.Id, message);
        }
        
        [HookMethod("SendMessageToUser")]
        public void SendMessageUser(string id, Message message)
        {
            DiscordInfo info = _storedData.PlayerDiscordInfo[id];
            if (info == null)
            {
                info = _storedData.GetInfoByDiscordId(id);
                if (info == null)
                {
                    return;
                }
            }

            Channel.GetChannel(_client, info.ChannelId, channel =>
            {
                if (channel != null)
                {
                    channel.CreateMessage(_client, message);
                }
                else
                {
                    CreateNewDmChannel(info.DiscordId, message);
                }
            });
        }
        
        [HookMethod("SendMessageToUser")]
        public void SendMessageUser(IPlayer player, Message message)
        {
            SendMessageUser(player.Id, message);
        }
        #endregion
        #endregion

        #region Message
        [HookMethod("DeleteMessage")]
        public void DeleteMessage(Message message)
        {
            message.DeleteMessage(_client);
        }
        #endregion

        #region User
        [HookMethod("GetAllUsers")]
        public List<string> GetAllUsers()
        {
            return _storedData.PlayerDiscordInfo.Keys.ToList();
        }

        [HookMethod("GetGuildMember")]
        public GuildMember GetGuildMember(string steamId)
        {
            return _discordServer.members.FirstOrDefault(m => _storedData.PlayerDiscordInfo[steamId]?.DiscordId == m.user.id);
        }

        [HookMethod("GetLinkedPlayers")]
        public List<DiscordUser> GetLinkedPlayers()
        {
            return _discordServer.members.Where(m => _storedData.PlayerDiscordInfo.Values.Any(pdi => pdi.DiscordId == m.user.id)).Select(m => m.user).ToList();
        }

        [HookMethod("GetGuildAllUsers")]
        public List<DiscordUser> GetGuildAllUsers()
        {
            return _discordServer.members.Select(u => u.user).ToList();
        }

        [HookMethod("GetUserDiscordInfo")]
        public JObject GetUserDiscordInfo(object user)
        {
            DiscordInfo info = null;
            if (user is string)
            {
                info = _storedData.PlayerDiscordInfo[(string)user];
                if (info == null)
                {
                    info = _storedData.GetInfoByDiscordId((string)user);
                }
            }
            else if (user is IPlayer)
            {
                info = _storedData.PlayerDiscordInfo[((IPlayer)user).Id];
            }

            return info != null ? JObject.FromObject(info) : null;
        }

        [HookMethod("GetUsersDiscordInfo")]
        public List<JObject> GetUsersDiscordInfo(List<object> users)
        {
            return users.Select(GetUserDiscordInfo).Where(i => i != null).ToList();
        }

        [HookMethod("GetSteamIdFromDiscordId")]
        public string GetSteamIdFromDiscordId(string discordId)
        {
            return _storedData.GetInfoByDiscordId(discordId)?.PlayerId;
        }

        [HookMethod("GetDiscordIdFromSteamId")]
        public string GetDiscordIdFromSteamId(string steamId)
        {
            return _storedData.PlayerDiscordInfo[steamId]?.DiscordId;
        }

        [HookMethod("KickDiscordUser")]
        public void KickDiscordUser(string id)
        {
            DiscordInfo info = _storedData.PlayerDiscordInfo[id];
            if (info == null)
            {
                info = _storedData.GetInfoByDiscordId(id);
                if (info == null)
                {
                    return;
                }

            }

            _discordServer.RemoveGuildMember(_client, info.DiscordId);
        }

        [HookMethod("BanDiscordUser")]
        public void BanDiscordUser(string id, int? deleteMessageDays)
        {
            DiscordInfo info = _storedData.PlayerDiscordInfo[id];
            if (info == null)
            {
                info = _storedData.GetInfoByDiscordId(id);
                if (info == null)
                {
                    return;
                }

            }

            _discordServer.CreateGuildBan(_client, info.DiscordId, deleteMessageDays);
        }
        #endregion

        #region Discord Chat Commands
        [HookMethod("RegisterCommand")]
        public void RegisterCommand(string command, Plugin plugin, Func<IPlayer, string, string, string[], object> method, string helpText, string permission = null, bool allowInBotChannel = false)
        {
            command = command.TrimStart('/');
            if (_discordCommands.ContainsKey(command) && _discordCommands[command].PluginName != plugin.Name)
            {
                PrintWarning($"Discord Commands already contains command: {command}.Previously registered to {_discordCommands[command].PluginName}");
            }

            if (plugin == null)
            {
                PrintWarning($"Cannot register command: {command} with a null plugin!");
                return;
            }

            //Puts($"Registered Command: /{command} for plugin: {pluginName}");

            _discordCommands[command] = new DiscordCommand
            {
                PluginName = plugin.Name,
                Plugin = plugin,
                Method = method,
                HelpText = helpText,
                Permission = permission,
                AllowInBotChannel = allowInBotChannel
            };
        }

        [HookMethod("UnregisterCommand")]
        public void UnregisterCommand(string command, Plugin plugin)
        {
            command = command.TrimStart('/');
            if (!_discordCommands.ContainsKey(command))
            {
                PrintWarning($"Command: {command} could not be unregistered because it was not found");
                return;
            }

            if (_discordCommands[command]?.PluginName != plugin.Name)
            {
                PrintWarning("Cannot unregister commands which don't belong to your plugin\n" +
                             $"Command: {command} CommandPlugin:{_discordCommands[command]?.PluginName} Unregistering Plugin: {plugin.Title}");
                return;
            }

            _discordCommands.Remove(command);
        }
        #endregion

        #region Channel
        [HookMethod("GetAllChannels")]
        public List<Channel> GetAllChannels()
        {
            return _discordServer.channels.ToList();
        }
        
        [HookMethod("GetAllDms")]
        public List<Channel> GetAllDms()
        {
            return _client.DMs.ToList();
        }

        [HookMethod("GetChannel")]
        public Channel GetChannel(string nameOrId)
        {
            Channel channel = GetAllChannels().FirstOrDefault(c => string.Equals(c.name, nameOrId, StringComparison.InvariantCultureIgnoreCase)
                                                                      || c.id == nameOrId);
            if (channel != null)
            {
                return channel;
            }

            channel = GetAllDms().FirstOrDefault(d => d.id == nameOrId);
            return channel;
        }

        [HookMethod("GetChannelMessages")]
        public void GetChannelMessages(string nameOrId, string responseKey)
        {
            GetChannel(nameOrId)?.GetChannelMessages(_client, messages =>
            {
                Interface.Call("OnGetChannelMessages", messages, responseKey);
            });
        }

        [HookMethod("SubscribeChannel")]
        public void SubscribeChannel(string channelNameOrId, Plugin plugin, Func<Message, object> method)
        {
            if (_connectionState != ConnectionStateEnum.Connected)
            {
                PrintError("Trying to subscribe to channel while bot is not in connect state");
                return;
            }

            Channel channel = GetChannel(channelNameOrId);
            if (channel == null)
            {
                PrintError($"Channel not found in guild: {channelNameOrId}");
                return;
            }

            if (!_channelSubscriptions.ContainsKey(channel.id))
            {
                _channelSubscriptions[channel.id] = new List<ChannelSubscription>();
            }

            List<ChannelSubscription> subscriptions = _channelSubscriptions[channel.id];
            if (subscriptions.Any(s => s.PluginName == plugin.Name))
            {
                LogWarning($"The plugin {plugin.Title} already has a subscription to channel {channelNameOrId}");
                return;
            }

            subscriptions.Add(new ChannelSubscription
            {
                PluginName = plugin.Name,
                Method = method
            });

            Interface.Call("OnChannelSubscribed", channel, plugin);
        }

        [HookMethod("UnsubscribeChannel")]
        public void UnsubscribeChannel(string channelNameOrId, Plugin plugin)
        {
            if (_connectionState != ConnectionStateEnum.Connected)
            {
                PrintError("Trying to unsubscribe to channel while bot is not in connect state");
                return;
            }

            Channel channel = GetChannel(channelNameOrId);
            if (channel == null)
            {
                PrintError($"Channel not found in guild: {channelNameOrId}");
                return;
            }

            List<ChannelSubscription> subscriptions = _channelSubscriptions[channel.id];

            subscriptions?.RemoveAll(s => s.PluginName == plugin.Name);
            Interface.Call("OnChannelUnsubscribed", channel, plugin);
        }
        #endregion

        #region Roles
        [HookMethod("GetRoles")]
        public List<Role> GetRoles()
        {
            return _discordServer.roles;
        }
        
        [HookMethod("GetRole")]
        public Role GetRole(string nameOrId)
        {
            return _discordServer.roles.FirstOrDefault(r => r.id == nameOrId || string.Equals(r.name, nameOrId, StringComparison.OrdinalIgnoreCase));
        }

        [HookMethod("UserHasRole")]
        public bool UserHasRole(string userId, string nameOrId)
        {
            GuildMember member = GetGuildMember(userId);
            if (member == null)
            {
                return false;
            }

            Role role = GetRole(nameOrId);
            if (role == null)
            {
                return false;
            }
            
            return member.roles.Any(r => r == role.id);
        }

        [HookMethod("AddRoleToUser")]
        public void AddRoleToUser(string userId, string roleId)
        {
            Role role = GetRole(roleId);
            if (role == null)
            {
                PrintWarning($"Tried to add a role to player that doesn't exist: '{roleId}'");
                return;
            }

            _discordServer.AddGuildMemberRole(_client, userId, role.id);
        }

        [HookMethod("RemoveRoleFromUser")]
        public void RemoveRoleFromUser(string userId, string roleId)
        {
            Role role = GetRole(roleId);
            if (role == null)
            {
                PrintWarning($"Tried to remove a role from a player that doesn't exist: '{roleId}'");
                return;
            }

            _discordServer.RemoveGuildMemberRole(_client, userId, role.id);
        }

        [HookMethod("CreateGuildRole")]
        public void CreateGuildRole(Role role)
        {
            _discordServer.CreateGuildRole(_client, role);
        }

        [HookMethod("DeleteGuildRole")]
        public void DeleteGuildRole(string roleId)
        {
            _discordServer.DeleteGuildRole(_client, roleId);
        }

        [HookMethod("DeleteGuildRole")]
        public void DeleteGuildRole(Role role)
        {
            DeleteGuildRole(role.id);
        }
        #endregion
        #endregion

        #region Method Handling
        /// <summary>
        /// Parses the specified command into uMod command format
        /// Sourced from RustCore.cs of OxideMod (https://github.com/theumod/uMod.Rust/blob/oxide/src/RustCore.cs)
        /// </summary>
        /// <param name="argstr"></param>
        /// <param name="command"></param>
        /// <param name="args"></param>
        private void ParseCommand(string argstr, out string command, out string[] args)
        {
            List<string> argList = new List<string>();
            StringBu
// ... [Code preview truncated due to length. Full source in attached file] ...

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