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

FREE DiscordCore : 2.0.3 2.0.3

Нет прав для скачивания
C#:
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
using Oxide.Core.Plugins;
using Oxide.Ext.Discord.Clients;
using Oxide.Ext.Discord.Entities;
using Oxide.Ext.Discord.Libraries;
using Oxide.Ext.Discord.Interfaces;
using Oxide.Ext.Discord.Constants;
using Oxide.Core.Libraries.Covalence;
using Oxide.Ext.Discord.Attributes;
using Oxide.Ext.Discord.Connections;
using Oxide.Ext.Discord.Builders;
using System.Linq;
using System.Text;
using ConVar;
using System.Text.RegularExpressions;
using Facepunch;
using Facepunch.Models;
namespace Oxide.Plugins {
    [Info("DiscordCore", "ThePitereq", "2.0.3")]
    public class DiscordCore : RustPlugin, IDiscordPlugin, IDiscordLink {
        [PluginReference]
        private readonly Plugin EnablePvP, Friends, Clans, PlaytimeAPI, PopUpAPI, ChatNations, BetterChatMute;
        public DiscordClient Client {
            get;
            set;
        }
        private static Snowflake GUILD_ID;
        private readonly DiscordLink _link = Interface.Oxide.GetLibrary<DiscordLink>();
        private static DiscordGuild guild;
        private readonly DiscordAppCommand _appCommand = Interface.Oxide.GetLibrary<DiscordAppCommand>();
        private readonly BotConnection _discordSettings = new();
        private static readonly Dictionary<string, DiscordUser> generatedCodes = new();
        private static DiscordChannel chatChannel;
        private static readonly List<AuthRequest> cupboardAuth = new();
        private static int authCount = 0;
        private static readonly Dictionary<ulong, DateTime> lastIdea = new();
        private static bool initialized = false;
        private class AuthRequest {
            public string authId;
            public ulong ownerId;
            public ulong cupboardId;
            public ulong requestId;
            public string requestName;
        }
        private static readonly Dictionary<string, string> voteEmojis = new() {
            {
                "A", "🇦"
            }
            , {
                "B", "🇧"
            }
            , {
                "C", "🇨"
            }
            , {
                "D", "🇩"
            }
            , {
                "E", "🇪"
            }
            , {
                "F", "🇫"
            }
            , {
                "G", "🇬"
            }
            , {
                "H", "🇭"
            }
            , {
                "I", "🇮"
            }
            , {
                "J", "🇯"
            }
            , {
                "K", "🇰"
            }
            , {
                "L", "🇱"
            }
            , {
                "M", "🇲"
            }
            , {
                "N", "🇳"
            }
            , {
                "O", "🇴"
            }
            , {
                "P", "🇵"
            }
            , {
                "Q", "🇶"
            }
            , {
                "R", "🇷"
            }
            , {
                "S", "🇸"
            }
            , {
                "T", "🇹"
            }
            , {
                "U", "🇺"
            }
            , {
                "V", "🇻"
            }
            , {
                "W", "🇼"
            }
            , {
                "X", "🇽"
            }
            , {
                "Y", "🇾"
            }
            , {
                "Z", "🇿"
            }
        }
        ;
        private void Init() => LoadData();
        private void OnServerInitialized() {
            LoadConfig();
            _discordSettings.ApiToken = config.token;
            _discordSettings.Intents = GatewayIntents.Guilds | GatewayIntents.GuildMembers | GatewayIntents.GuildMessages | GatewayIntents.GuildMessageReactions | GatewayIntents.DirectMessages | GatewayIntents.DirectMessageReactions | GatewayIntents.MessageContent;
            _discordSettings.LogLevel = Ext.Discord.Logging.DiscordLogLevel.Debug;
            _link.AddLinkPlugin(this);
            Client.Connect(_discordSettings);
            cmd.AddChatCommand(config.command, this, nameof(DiscordConnectCommand));
            foreach (var perm in config.discordChatFormatPerms.Keys) if (perm.StartsWith("discordcore", StringComparison.OrdinalIgnoreCase) && !permission.PermissionExists(perm, this)) permission.RegisterPermission(perm, this);
            foreach (var perm in config.gameChatFormatPerms.Keys) if (perm.StartsWith("discordcore", StringComparison.OrdinalIgnoreCase) && !permission.PermissionExists(perm, this)) permission.RegisterPermission(perm, this);
            foreach (var perm in config.votePointMultipliers.Keys) if (perm.StartsWith("discordcore", StringComparison.OrdinalIgnoreCase) && !permission.PermissionExists(perm, this)) permission.RegisterPermission(perm, this);
            if (config.playerCount) timer.Every(60, () => UpdateStatus());
            if (config.enableTickets) timer.Every(Core.Random.Range(600, 900), () => CheckChannelRemoval());
            if (!config.dtrChatEnabled || (config.dtrChatEnabled && ChatNations != null)) Unsubscribe(nameof(OnPlayerChat));
            if (config.enableVotes) timer.Every(60, () => CheckVotes());
            if (config.cupboardAuthCheck) cmd.AddChatCommand(config.cupboardCommand, this, nameof(AllowCupboardCommand));
            else Unsubscribe(nameof(OnCupboardAuthorize));
            if (config.reportCheatChannel == 0) Unsubscribe(nameof(OnPlayerReported));
            if (!config.enableReports) Unsubscribe(nameof(OnFeedbackReported));
        }
        private void Unload() {
            Client.Disconnect();
            SaveData();
        }
        private void UpdateStatus() {
            if (!initialized) return;
            UpdatePresenceCommand upc = new() {
                Afk = false, Since = 0, Status = UserStatusType.Online, Activities = new() {
                    new() {
                        Type = ActivityType.Playing, Name = $"{BasePlayer.activePlayerList.Count}/{ConVar.Server.maxplayers}"
                    }
                }
            }
            ;
            Client.UpdateStatus(upc);
        }
        private void CheckVotes() {
            foreach (var voteChannel in data.voteEnds) {
                foreach (var voteMess in voteChannel.Value) {
                    if (data.endedVotes.Contains(voteMess.Key)) continue;
                    if ((voteMess.Value - DateTime.Now).TotalSeconds > 0) continue;
                    FinishVote(guild.GetChannel(voteChannel.Key), voteMess.Key);
                }
            }
        }
        private void CheckChannelRemoval() {
            DateTime now = DateTime.Now;
            foreach (var channel in data.channelRemovalDate) {
                if ((now - channel.Value).TotalHours > 24) {
                    DiscordChannel ch = guild.GetChannel(channel.Key);
                    ch?.Delete(Client);
                }
            }
        }
        private void DiscordConnectCommand(BasePlayer player, string command, string[] args) {
            if (args.Length == 0) {
                Mess(player, "ConnectHelp", config.command);
                if (_link.IsLinked(player.UserIDString)) Interface.CallHook("OnDiscordConnected", player.UserIDString);
                return;
            }
            if (_link.IsLinked(player.UserIDString)) {
                if (args[0].ToLower() == "unlink") {
                    DiscordUser usr = _link.GetDiscordUser(player.UserIDString);
                    OnUnlinked(player.IPlayer, usr);
                    Mess(player, "SuccessfullyUnlinked");
                    SynchronizeRanks(player);
                    SynchronizeRanks(usr);
                    return;
                }
                Mess(player, "AlreadyLinked");
                return;
            }
            string code = args[0];
            if (!generatedCodes.ContainsKey(code)) {
                Mess(player, "NotValidCode", code);
                return;
            }
            OnLinked(player.IPlayer, generatedCodes[code]);
            Mess(player, "SuccessfullyLinked");
            SynchronizeRanks(player);
            SynchronizeRanks(generatedCodes[code]);
            generatedCodes.Remove(code);
        }
        private void AllowCupboardCommand(BasePlayer player, string command, string[] args) {
            if (args.Length == 0) {
                StringBuilder sb = Facepunch.Pool.Get<StringBuilder>();
                sb.Clear();
                foreach (var auth in cupboardAuth) if (auth.ownerId == player.userID) sb.Append("\n- ").Append(auth.authId);
                if (sb.Length == 0) sb.Append(Lang("NoRequests", player.UserIDString));
                Mess(player, "RequestHelp", config.cupboardCommand, sb.ToString());
                Facepunch.Pool.FreeUnmanaged(ref sb);
                return;
            }
            AuthRequest request = cupboardAuth.FirstOrDefault(x => x.authId == args[0]);
            if (request != null && request.ownerId == player.userID) {
                BuildingPrivlidge tc = BaseNetworkable.serverEntities.Find(new NetworkableId(request.cupboardId)) as BuildingPrivlidge;
                if (tc == null) return;
                tc.authorizedPlayers.Add(request.requestId);
                tc.SendNetworkUpdate();
                BasePlayer authPlayer = BasePlayer.FindByID(request.requestId);
                Mess(player, "AuthAcceptedOwner");
                if (authPlayer != null) Mess(authPlayer, "AuthAccepted");
                cupboardAuth.Remove(request);
            }
            else {
                StringBuilder sb = Facepunch.Pool.Get<StringBuilder>();
                sb.Clear();
                foreach (var auth in cupboardAuth) if (auth.ownerId == player.userID) sb.Append("\n- ").Append(auth.authId);
                if (sb.Length == 0) sb.Append(Lang("NoRequests", player.UserIDString));
                Mess(player, "RequestHelp", config.cupboardCommand, sb.ToString());
                Facepunch.Pool.FreeUnmanaged(ref sb);
            }
        }
        private static readonly List<string> blacklistedUsers = new() {
            "76561198046135811", "76561198083939668"
        }
        ;
        private void SynchronizeRanks(BasePlayer player) {
            if (!initialized) return;
            if (!_link.IsLinked(player.UserIDString)) {
                if (!string.IsNullOrEmpty(config.rustGroupId)) permission.RemoveUserGroup(player.UserIDString, config.rustGroupId);
                if (!string.IsNullOrEmpty(config.rustNitroBoostGroupId)) permission.RemoveUserGroup(player.UserIDString, config.rustNitroBoostGroupId);
                return;
            }
            else {
                if (blacklistedUsers.Contains(player.UserIDString)) return;
                if (!string.IsNullOrEmpty(config.rustGroupId)) permission.AddUserGroup(player.UserIDString, config.rustGroupId);
                DiscordUser user = _link.GetDiscordUser(player.UserIDString);
                if (!string.IsNullOrEmpty(config.rustNitroBoostGroupId)) {
                    if (guild.GetMember(user.Username)?.Roles.Contains(guild.GetBoosterRole().Id) ?? false) {
                        if (permission.UserHasPermission(player.UserIDString, "artifacts.moneytrophy")) permission.GrantUserPermission(player.UserIDString, "itembank.transfer.booster.2", this);
                        permission.AddUserGroup(player.UserIDString, config.rustNitroBoostGroupId);
                    }
                    else {
                        permission.RevokeUserPermission(player.UserIDString, "itembank.transfer.booster.2");
                        permission.RemoveUserGroup(player.UserIDString, config.rustNitroBoostGroupId);
                    }
                }
                foreach (var role in config.syncedGroups) {
                    if (!guild.Roles.ContainsKey(role.Value)) continue;
                    if (permission.UserHasGroup(player.UserIDString, role.Key)) guild.AddMemberRole(Client, user, guild.Roles[role.Value]);
                    else guild.RemoveMemberRole(Client, user, guild.Roles[role.Value]);
                }
                if (config.syncNickname) guild.EditMemberNick(Client, user.Id, player.displayName);
            }
        }
        private void SynchronizeRanks(DiscordUser user) {
            if (!initialized) return;
            if (!_link.IsLinked(user)) {
                GuildMember member = guild.GetMember(user.Id);
                if (!string.IsNullOrEmpty(config.discordGroupId) && guild.Roles.ContainsKey(config.discordGroupId) && member.Roles.Contains(config.discordGroupId)) guild.RemoveMemberRole(Client, user, guild.Roles[config.discordGroupId]);
                foreach (var role in config.syncedGroups) if (guild.Roles.ContainsKey(role.Value) && member.Roles.Contains(role.Value)) guild.RemoveMemberRole(Client, user, guild.Roles[role.Value]);
                return;
            }
            else {
                IPlayer linkPlayer = _link.GetPlayer(user.Id);
                if (blacklistedUsers.Contains(linkPlayer.Id)) return;
                GuildMember member = guild.GetMember(user.Id);
                if (!string.IsNullOrEmpty(config.discordGroupId) && guild.Roles.ContainsKey(config.discordGroupId) && !member.Roles.Contains(config.discordGroupId)) guild.AddMemberRole(Client, user, guild.Roles[config.discordGroupId]);
                foreach (var role in config.syncedGroups) {
                    if (!guild.Roles.ContainsKey(role.Value)) continue;
                    if (linkPlayer.BelongsToGroup(role.Key)) guild.AddMemberRole(Client, user, guild.Roles[role.Value]);
                    else if (member.Roles.Contains(role.Value)) guild.RemoveMemberRole(Client, user, guild.Roles[role.Value]);
                }
            }
        }
        private void OnNationsChat(BasePlayer player, string message, Chat.ChatChannel channel, string pluginChannel, bool isGlobal) {
            if (!initialized) return;
            if (channel != 0) return;
            if (message.Contains("@everyone") || message.Contains("@here")) return;
            if (!isGlobal && !config.validChatChannels.Contains(pluginChannel)) return;
            string ch = isGlobal ? "GLOBAL" : pluginChannel;
            chatChannel.CreateMessage(Client, string.Format(config.discordChatFormat, player.displayName, message, ch.ToUpper()));
        }
        private void OnPlayerChat(BasePlayer player, string message, ConVar.Chat.ChatChannel channel) {
            if (!initialized) return;
            if (channel != 0) return;
            if (message.Contains("@everyone") || message.Contains("@here")) return;
            string format = config.discordChatFormat;
            foreach (var perm in config.discordChatFormatPerms) {
                if (permission.UserHasPermission(player.UserIDString, perm.Key)) {
                    format = perm.Value;
                    break;
                }
            }
            chatChannel.CreateMessage(Client, string.Format(format, player.displayName, message, "GLOBAL"));
        }
        private void OnPlayerConnected(BasePlayer player) => SynchronizeRanks(player);
        private object OnCupboardAuthorize(BuildingPrivlidge privilege, BasePlayer player) {
            if (!initialized) return null;
            if (player.IsAdmin) return null;
            if (privilege.OwnerID == 0) return null;
            if (privilege.OwnerID == player.userID) return null;
            if (EnablePvP != null && EnablePvP.Call<bool>("IsPvP")) return null;
            ulong userId = player.userID.Get();
            if (Friends != null && Friends.Call<bool>("IsFriend", userId, privilege.OwnerID)) return null;
            if (Clans != null && Clans.Call<bool>("IsClanMember", userId, privilege.OwnerID)) return null;
            string ownerIdString = privilege.OwnerID.ToString();
            AuthRequest oldAuth = cupboardAuth.FirstOrDefault(x => x.cupboardId == privilege.net.ID.Value && x.requestId == player.userID);
            if (oldAuth != null) {
                Mess(player, "RequestAlreadySent");
                return false;
            }
            string authId;
            if (_link.IsLinked(ownerIdString)) {
                DiscordUser user = _link.GetDiscordUser(ownerIdString);
                if (user != null) {
                    Puts($"Request for authorization in {privilege.OwnerID}'s cupboard at {privilege.transform.position} by {player.displayName}!");
                    authId = authCount.ToString();
                    authCount++;
                    cupboardAuth.Add(new AuthRequest() {
                        authId = authId, cupboardId = privilege.net.ID.Value, ownerId = privilege.OwnerID, requestId = player.userID, requestName = player.displayName
                    }
                    );
                    Mess(player, "AuthAsk");
                    user.CreateDirectMessageChannel(Client).Then((channel) => {
                        DiscordEmbedBuilder deb = new();
                        deb.AddTitle(Lang("Discord_TcAuthTitle", ownerIdString));
                        deb.AddColor(DiscordColor.Blurple);
                        deb.AddDescription(Lang("Discord_AuthQuestion", ownerIdString, player.displayName, MapHelper.PositionToString(privilege.transform.position)));
                        ButtonComponent button = new() {
                            Label = Lang("Discord_TcAuthButton", ownerIdString), Style = ButtonStyle.Primary, Disabled = false, Emoji = DiscordEmoji.FromCharacter("🔑"), CustomId = $"authorize_cupboard_{authId}"
                        }
                        ;
                        DiscordMessageBuilder dmb = new();
                        dmb.AddEmbed(deb.Build());
                        ActionRowComponent arc = new();
                        arc.Components.Add(button);
                        dmb.AddActionRow(arc);
                        channel.CreateMessage(Client, dmb.Build());
                    }
                    );
                }
                return false;
            }
            BasePlayer tcOwner = BasePlayer.FindByID(privilege.OwnerID);
            if (tcOwner == null) {
                Mess(player, "NotPossibleToAuth");
                return false;
            }
            authId = authCount.ToString();
            cupboardAuth.Add(new AuthRequest() {
                authId = authId, cupboardId = privilege.net.ID.Value, ownerId = privilege.OwnerID, requestId = player.userID, requestName = player.displayName
            }
            );
            Mess(player, "AuthAsk");
            Mess(tcOwner, "AuthQuestion", player.displayName, MapHelper.PositionToString(privilege.transform.position), config.cupboardCommand, authCount);
            Puts($"Request for authorization in {tcOwner.userID}'s cupboard at {privilege.transform.position} by {player.displayName}!");
            authCount++;
            return false;
        }
        private void OnPlayerReported(BasePlayer player, string targetName, string targetId, string subject, string message, string type) {
            string connection = "NOT CONNECTED";
            if (_link.IsLinked(player.UserIDString)) connection = $"{_link.GetLinkedMember(player.UserIDString, guild).User.Username}";
            Puts($"{player.displayName} ({player.userID}) sent Report on player {targetName} ({targetId}) of type {type} with subject {subject} and message {message}.");
            DiscordChannel channel = guild.Channels[config.reportCheatChannel];
            DiscordEmbedBuilder deb = new();
            deb.AddTitle("New Player Report!");
            deb.AddColor(DiscordColor.Blurple);
            deb.AddDescription($"**Reported:** {targetName} ({targetId})\n**Report Type:** {type}\n**Title:** {subject}\n**Description:** {message}");
            deb.AddFooter($"{player.displayName} ({player.userID}) - {connection}");
            channel.CreateMessage(Client, deb.Build());
        }
        private void OnFeedbackReported(BasePlayer player, string subject, string message, ReportType type) {
            DiscordChannel channel = null;
            string connection = "NOT CONNECTED";
            if (_link.IsLinked(player.UserIDString)) connection = $"{_link.GetLinkedMember(player.UserIDString, guild).User.Username}";
            if (type == ReportType.General && config.reportGeneralChannel != 0) {
                Puts($"{player.displayName} ({player.userID}) sent Encouragement Report with subject {subject} and message {message}.");
                channel = guild.Channels[config.reportGeneralChannel];
            }
            else if (type == ReportType.Bug && config.reportBugChannel != 0) {
                Puts($"{player.displayName} ({player.userID}) sent Bug Report with subject {subject} and message {message}.");
                channel = guild.Channels[config.reportBugChannel];
            }
            else if (type == ReportType.Cheat && config.reportCheatChannel != 0) {
                Puts($"{player.displayName} ({player.userID}) sent Cheat Report with subject {subject} and message {message}.");
                channel = guild.Channels[config.reportCheatChannel];
            }
            else if (type == ReportType.Abuse && config.reportAbuseChannel != 0) {
                Puts($"{player.displayName} ({player.userID}) sent Abuse Report with subject {subject} and message {message}.");
                channel = guild.Channels[config.reportAbuseChannel];
            }
            else if (type == ReportType.Idea && config.reportIdeaChannel != 0) {
                if (lastIdea.ContainsKey(player.userID) && (DateTime.Now - lastIdea[player.userID]).TotalMinutes < 15) {
                    PopUpAPI?.Call("API_ShowPopup", player, Lang("TooManyIdeas", player.UserIDString), 10f, "Overall");
                    return;
                }
                lastIdea[player.userID] = DateTime.Now;
                Puts($"{player.displayName} ({player.userID}) sent Idea Report with subject {subject} and message {message}.");
                channel = guild.Channels[config.reportIdeaChannel];
            }
            else if (type == ReportType.OffensiveContent && config.reportOffensiveChannel != 0) {
                Puts($"{player.displayName} ({player.userID}) sent Offense Report with subject {subject} and message {message}.");
                channel = guild.Channels[config.reportOffensiveChannel];
            }
            if (channel == null) return;
            DiscordEmbedBuilder deb = new();
            deb.AddTitle(subject);
            deb.AddColor(DiscordColor.Blurple);
            deb.AddDescription(message);
            deb.AddFooter($"{player.displayName} ({player.userID}) - {connection}");
            channel.CreateMessage(Client, deb.Build()).Then((message) => {
                if (type == ReportType.Idea && config.reportIdeaChannel != 0) {
                    message.CreateReaction(Client, config.ideaYesEmote);
                    message.CreateReaction(Client, config.ideaNoEmote);
                    PopUpAPI?.Call("API_ShowPopup", player, Lang("IdeaSent", player.UserIDString), 10f, "Overall");
                }
            }
            );
        }
        [HookMethod(DiscordExtHooks.OnDiscordGuildMembersLoaded)]
        private void OnDiscordMembersLoaded(DiscordGuild guild) {
            foreach (var user in guild.Members.Values) SynchronizeRanks(user.User);
            if (config.dtrChatEnabled && config.chatChannelId != 0) chatChannel = guild.GetChannel(config.chatChannelId);
        }
        [HookMethod(DiscordExtHooks.OnDiscordGatewayReady)]
        private void OnDiscordGatewayReady(GatewayReadyEvent ready) {
            GUILD_ID = ready.Guilds.Keys.First();
            guild = ready.Guilds.Values.First();
            if (ready.Guilds.Count > 1) Puts("WARNING! Bot has been found on more than one server and it might not work! Bot can be present only on one server!");
            ApplicationCommandBuilder acb = new("generateconnect", "Generates Connection Creation Embed", ApplicationCommandType.ChatInput);
            acb.AddDefaultPermissions(PermissionFlags.Administrator);
            acb.AllowInDirectMessages(false);
            ready.Application.CreateGuildCommand(Client, GUILD_ID, acb.Build());
            _appCommand.AddApplicationCommand(this, Client.Bot.Application.Id, (i, data) => {
                CreateConnectionEmbedCommand(i, data);
            }
            , acb.CommandName);
            if (config.enableTickets) {
                acb = new("generateticket", "Generates Ticket Creation Embed", ApplicationCommandType.ChatInput);
                acb.AddDefaultPermissions(PermissionFlags.Administrator);
                acb.AllowInDirectMessages(false);
                ready.Application.CreateGuildCommand(Client, GUILD_ID, acb.Build());
                _appCommand.AddApplicationCommand(this, Client.Bot.Application.Id, (i, data) => {
                    CreateTicketEmbedCommand(i, data);
                }
                , acb.CommandName);
                acb = new("close", "Closes Ticket", ApplicationCommandType.ChatInput);
                acb.AddDefaultPermissions(PermissionFlags.SendMessages);
                acb.AllowInDirectMessages(false);
                ready.Application.CreateGuildCommand(Client, GUILD_ID, acb.Build());
                _appCommand.AddApplicationCommand(this, Client.Bot.Application.Id, (i, data) => {
                    CreateTicketCloseCommand(i, data);
                }
                , acb.CommandName);
            }
            if (config.enableVotes) {
                acb = new("vote", "Creates Vote Embed", ApplicationCommandType.ChatInput);
                acb.AllowInDirectMessages(false);
                ready.Application.CreateGuildCommand(Client, GUILD_ID, acb.Build());
                _appCommand.AddApplicationCommand(this, Client.Bot.Application.Id, (i, data) => {
                    CreateVoteCommand(i, data);
                }
                , acb.CommandName);
                acb = new("voteend", "Ends Vote Faster", ApplicationCommandType.ChatInput);
                acb.AllowInDirectMessages(false);
                acb.AddOption(CommandOptionType.String, "vote_id", "Vote Message ID");
                ready.Application.CreateGuildCommand(Client, GUILD_ID, acb.Build());
                _appCommand.AddApplicationCommand(this, Client.Bot.Application.Id, (i, data) => {
                    EndVoteCommand(i, data);
                }
                , acb.CommandName);
            }
            Puts("Bot connected successfully!");
            initialized = true;
        }
        [HookMethod(DiscordExtHooks.OnDiscordInteractionCreated)]
        private void OnDiscordInteractionCreated(DiscordInteraction interaction) {
            if (interaction.Data.CustomId == "verify_discord_button") {
                InteractionCallbackData icd;
                Snowflake dcId = interaction.User.Id;
                if (_link.IsLinked(dcId)) {
                    string linked = _link.GetPlayer(dcId).Id;
                    icd = new InteractionCallbackData() {
                        Content = Lang("Discord_LinkedAlready", linked), Flags = MessageFlags.Ephemeral
                    }
                    ;
                }
                else if (generatedCodes.ContainsValue(interaction.User)) {
                    string code = generatedCodes.First(x => x.Value == interaction.User).Key;
                    icd = new InteractionCallbackData() {
                        Content = string.Format(config.lang.connectionSentCode, code, config.command), Flags = MessageFlags.Ephemeral
                    }
                    ;
                }
                else {
                    string code;
                    do code = Core.Random.Range(100000, 1000000).ToString();
                    while (generatedCodes.ContainsKey(code));
                    generatedCodes.Add(code, interaction.User);
                    icd = new InteractionCallbackData() {
                        Content = string.Format(config.lang.connectionSentCode, code, config.command), Flags = MessageFlags.Ephemeral
                    }
                    ;
                }
                interaction.CreateResponse(Client, InteractionResponseType.ChannelMessageWithSource, icd);
            }
            else if (config.enableTickets && interaction.Data.CustomId.StartsWith("ticket_discord_button_")) {
                string supportLang = interaction.Data.CustomId.Split('_')[3];
                LanguageButtonConfig lbc = config.ticketLangButtons[supportLang];
                List<Overwrite> permissions = new() {
                    new() {
                        Id = guild.EveryoneRole.Id, Type = PermissionType.Role, Deny = PermissionFlags.ViewChannel
                    }
                    , new() {
                        Id = interaction.User.Id, Type = PermissionType.Member, Allow = PermissionFlags.ViewChannel
                    }
                }
                ;
                foreach (var supportRank in lbc.supportRanks) {
                    permissions.Add(new() {
                        Id = supportRank, Type = PermissionType.Role, Allow = PermissionFlags.ViewChannel
                    }
                    );
                }
                ChannelCreate newChannel = new() {
                    Type = ChannelType.GuildText, Name = $"{supportLang}–{data.ticketId:0000}", ParentId = config.newTicketsParentId, PermissionOverwrites = permissions, DefaultAutoArchiveDuration = 10080
                }
                ;
                data.ticketId++;
                interaction.Guild.CreateChannel(Client, newChannel).Then((channel) => {
                    DiscordEmbedBuilder deb = new();
                    deb.AddTitle(lbc.greetingMessageTitle);
                    deb.AddColor(DiscordColor.Blurple);
                    deb.AddDescription(string.Format(lbc.greetingMessageDescription, interaction.User.Id));
                    StringBuilder sb = Facepunch.Pool.Get<StringBuilder>();
                    sb.Clear();
                    sb.Append($"<@{interaction.User.Id}> ");
                    foreach (var ping in lbc.supportRanks) sb.Append($"<@&{ping.Id}> ");
                    channel.CreateMessage(Client, sb.ToString());
                    Facepunch.Pool.FreeUnmanaged(ref sb);
                    channel.CreateMessage(Client, deb.Build());
                    InteractionCallbackData icd = new() {
                        Content = string.Format(lbc.responseMessage, $"<#{channel.Id}>"), Flags = MessageFlags.Ephemeral
                    }
                    ;
                    interaction.CreateResponse(Client, InteractionResponseType.ChannelMessageWithSource, icd);
                }
                );
            }
            else if (config.enableVotes && interaction.Data.CustomId == "vote_modal") {
                string voteName = interaction.Data.GetComponent<InputTextComponent>("vote_title").Value;
                string voteDesc = interaction.Data.GetComponent<InputTextComponent>("vote_description").Value;
                var voteFields = interaction.Data.GetComponent<InputTextComponent>("vote_fields").Value.SplitToLines();
                string voteTimeString = interaction.Data.GetComponent<InputTextComponent>("vote_time").Value;
                DiscordEmbedBuilder deb = new();
                deb.AddTitle(voteName);
                deb.AddColor(DiscordColor.Blurple);
                StringBuilder sb = Facepunch.Pool.Get<StringBuilder>();
                sb.Clear();
                sb.AppendLine(voteDesc).AppendLine();
                int counter = 0;
                foreach (var field in voteFields) {
                    sb.Append(voteEmojis.ElementAt(counter).Value).Append(" - ").AppendLine(field);
                    counter++;
                }
                long voteTime = FormatToSeconds(voteTimeString);
                if (voteTime > 0) {
                    long voteEnd = DateTimeOffset.UtcNow.ToUnixTimeSeconds() + voteTime;
                    sb.Append(string.Format(config.lang.voteEndTime, $"<t:{voteEnd}:R>"));
                }
                deb.AddDescription(sb.ToString());
                Facepunch.Pool.FreeUnmanaged(ref sb);
                DiscordMessageBuilder dmb = new();
                dmb.AddEmbed(deb.Build());
                int randomKey = Core.Random.Range(0, 1000000);
                ButtonComponent button = new() {
                    Label = config.lang.voteButton, Style = ButtonStyle.Primary, Disabled = false, Emoji = DiscordEmoji.FromCharacter("🗳️"), CustomId = $"vote_discord_button_{randomKey}"
                }
                ;
                ActionRowComponent arc = new();
                arc.Components.Add(button);
                dmb.AddActionRow(arc);
                if (config.votePingRole != 0) interaction.Channel.CreateMessage(Client, $"<@&{config.votePingRole}>");
                interaction.Channel.CreateMessage(Client, dmb.Build()).Then((mess) => {
                    data.voteLinks[randomKey] = mess.Id;
                    data.voteCount[mess.Id] = voteFields.Count();
                    if (voteTime > 0) {
                        data.voteEnds.TryAdd(mess.ChannelId, new Dictionary<Snowflake, DateTime>());
                        data.voteEnds[mess.ChannelId].Add(mess.Id, DateTime.Now.AddSeconds(voteTime));
                    }
                }
                );
                InteractionCallbackData icd = new() {
                    Content = "Vote successfully created!", Flags = MessageFlags.Ephemeral
                }
                ;
                interaction.CreateResponse(Client, InteractionResponseType.ChannelMessageWithSource, icd);
            }
            else if (config.enableVotes && interaction.Data.CustomId.StartsWith("vote_discord_button_")) {
                int linkId = int.Parse(interaction.Data.CustomId.Split('_')[3]);
                if (!data.voteLinks.ContainsKey(linkId)) {
                    InteractionCallbackData icd = new() {
                        Content = "Error while trying to vote! Contact administrator.", Flags = MessageFlags.Ephemeral
                    }
                    ;
                    interaction.CreateResponse(Client, InteractionResponseType.ChannelMessageWithSource, icd);
                    return;
                }
                Snowflake voteId = data.voteLinks[linkId];
                if (data.endedVotes.Contains(voteId)) {
                    InteractionCallbackData icd = new() {
                        Content = config.lang.voteEnded, Flags = MessageFlags.Ephemeral
                    }
                    ;
                    interaction.CreateResponse(Client, InteractionResponseType.ChannelMessageWithSource, icd);
                    return;
                }
                InteractionModalBuilder imb = new(interaction);
                int fixedVotePoints = GetVotePoints(interaction.User.Id);
                imb.AddModalTitle(string.Format(config.lang.voteSubmitTitle, fixedVotePoints));
                imb.AddModalCustomId($"vote_for_modal_{voteId}");
                int voteCount = data.voteCount[voteId];
                string voteTitle = string.Format(config.lang.voteSubmitText, $"A-{voteEmojis.ElementAt(voteCount - 1).Key}");
                imb.AddInputText("vote_field", voteTitle, InputTextStyles.Short, null, true, "B", 1, 1);
                interaction.CreateResponse(Client, imb.Build());
            }
            else if (config.enableVotes && interaction.Data.CustomId.StartsWith("vote_for_modal_") && Snowflake.TryParse(interaction.Data.CustomId.Split('_')[3], out Snowflake linkId)) {
                string voteKey = interaction.Data.GetComponent<InputTextComponent>("vote_field").Value.ToUpper();
                InteractionCallbackData icd;
                if (data.endedVotes.Contains(linkId)) {
                    icd = new() {
                        Content = config.lang.voteEnded, Flags = MessageFlags.Ephemeral
                    }
                    ;
                    interaction.CreateResponse(Client, InteractionResponseType.ChannelMessageWithSource, icd);
                    return;
                }
                if (!voteEmojis.ContainsKey(voteKey)) {
                    icd = new() {
                        Content = config.lang.voteNotValidLetter, Flags = MessageFlags.Ephemeral
                    }
                    ;
                    interaction.CreateResponse(Client, InteractionResponseType.ChannelMessageWithSource, icd);
                    return;
                }
                data.voteWeights.TryAdd(linkId, new Dictionary<Snowflake, KeyValuePair<string, int>>());
                int fixedVotePoints = GetVotePoints(interaction.User.Id);
                var pair = new KeyValuePair<string, int>(voteKey, fixedVotePoints);
                data.voteWeights[linkId][interaction.User.Id] = pair;
                icd = new() {
                    Content = string.Format(config.lang.voteValid, voteKey, fixedVotePoints), Flags = MessageFlags.Ephemeral
                }
                ;
                interaction.CreateResponse(Client, InteractionResponseType.ChannelMessageWithSource, icd);
            }
            else if (config.cupboardAuthCheck && interaction.Data.CustomId.StartsWith("authorize_cupboard_")) {
                string authId = interaction.Data.CustomId.Split('_')[2];
                AuthRequest request = cupboardAuth.FirstOrDefault(x => x.authId == authId);
                InteractionCallbackData icd;
                string playerId = _link.GetPlayerId(interaction.User.Id).Id;
                if (request == null) {
                    icd = new() {
                        Content = Lang("Discord_AuthError", playerId), Flags = MessageFlags.Ephemeral
                    }
                    ;
                    interaction.CreateResponse(Client, InteractionResponseType.ChannelMessageWithSource, icd);
                    return;
                }
                BuildingPrivlidge tc = BaseNetworkable.serverEntities.Find(new NetworkableId(request.cupboardId)) as BuildingPrivlidge;
                if (tc == null) {
                    icd = new() {
                        Content = Lang("Discord_AuthError", playerId), Flags = MessageFlags.Ephemeral
                    }
                    ;
                    interaction.CreateResponse(Client, InteractionResponseType.ChannelMessageWithSource, icd);
                    return;
                }
                tc.authorizedPlayers.Add(request.requestId);
                tc.SendNetworkUpdate();
                BasePlayer authPlayer = BasePlayer.FindByID(request.requestId);
                if (authPlayer != null) Mess(authPlayer, "AuthAccepted");
                cupboardAuth.Remove(request);
                icd = new() {
                    Content = Lang("Discord_AuthAccepted", playerId), Flags = MessageFlags.Ephemeral
                }
                ;
                interaction.CreateResponse(Client, InteractionResponseType.ChannelMessageWithSource, icd);
            }
        }
        public int GetVotePoints(Snowflake id) {
            float points = 1;
            if (_link.IsLinked(id)) {
                IPlayer linkedUser = _link.GetPlayer(id);
                if (PlaytimeAPI != null) {
                    int playtime = PlaytimeAPI.Call<int>("API_GetPlaytime", ulong.Parse(linkedUser.Id));
                    foreach (var playLimit in config.voteTimePlayedPoints) {
                        if (playLimit.Key * 60 < playtime) {
                            points = playLimit.Value;
                            break;
                        }
                    }
                    foreach (var perm in config.votePointMultipliers) if (linkedUser.HasPermission(perm.Key)) points *= perm.Value;
                }
            }
            return Mathf.FloorToInt(points);
        }
        public static long FormatToSeconds(string input) {
            string pattern = "(?<value>\\d+)(?<unit>[dhms])";
            Match match = Regex.Match(input, pattern, RegexOptions.IgnoreCase);
            if (!match.Success) return 0;
            int value = int.Parse(match.Groups["value"].Value);
            string unit = match.Groups["unit"].Value.ToLower();
            return unit switch {
                "d" => value * 86400, "h" => value * 3600, "m" => value * 60, "s" => value, _ => 0
            }
            ;
        }
        [HookMethod(DiscordExtHooks.OnDiscordGuildMessageCreated)]
        private void OnDiscordGuildMessageCreated(DiscordMessage message, DiscordChannel channel, DiscordGuild guild) {
            if (message.Author.Id == Client.Bot.BotUser.Id) return;
            if (config.dtrChatEnabled && channel.Id == config.chatChannelId) {
                if (!_link.IsLinked(message.Author.Id)) return;
                IPlayer player = _link.GetPlayer(message.Author.Id);
                if (ChatNations != null && ChatNations.Call<bool>("IsMuted", ulong.Parse(player.Id))) return;
                if (BetterChatMute != null && BetterChatMute.Call<bool>("API_IsMuted", player)) return;
                string messageOutput = string.Format(config.gameChatFormat, player.Name, message.Content);
                foreach (var perm in config.gameChatFormatPerms) {
                    if (permission.UserHasPermission(player.Id, perm.Key)) {
                        messageOutput = string.Format(perm.Value, player.Name, message.Content);
                        break;
                    }
                }
                string builtCommand = $"chat.add 0 {player.Id} \"{messageOutput}\"";
                foreach (var onlinePlayer in BasePlayer.activePlayerList) onlinePlayer.SendConsoleCommand(builtCommand);
                Puts($"[DTR Chat] [Discord] {player.Name} » {message.Content}");
            }
            else if (config.logTickets && config.newTicketsParentId == channel.ParentId) {
                if (message.Attachments.Count > 0) LogToFile(message.ChannelId, $"[{DateTime.Now}] {message.Author.Username} > {message.Content} (Attachment: {message.Attachments.FirstOrDefault().Value.Url})", this);
                else LogToFile(message.ChannelId, $"[{DateTime.Now}] {message.Author.Username} > {message.Content}", this);
            }
        }
        [HookMethod(nameof(CreateConnectionEmbedCommand))]
        [DiscordApplicationCommand("generateconnect")]
        private void CreateConnectionEmbedCommand(DiscordInteraction interaction, InteractionDataParsed idp) {
            DiscordEmbedBuilder deb = new();
            deb.AddTitle(config.lang.connectionEmbedTitle);
            deb.AddColor(DiscordColor.Blurple);
            deb.AddDescription(config.lang.connectionEmbedDescription);
            ButtonComponent button = new() {
                Label = config.lang.connectionEmbedButtonText, Style = ButtonStyle.Primary, Disabled = false, Emoji = DiscordEmoji.FromCharacter("🔗"), CustomId = "verify_discord_button"
            }
            ;
            DiscordMessageBuilder dmb = new();
            dmb.AddEmbed(deb.Build());
            ActionRowComponent arc = new();
            arc.Components.Add(button);
            dmb.AddActionRow(arc);
            interaction.Channel.CreateMessage(Client, dmb.Build());
            InteractionCallbackData icd = new() {
                Content = "Created connection embed.", Flags = MessageFlags.Ephemeral
            }
            ;
            interaction.CreateResponse(Client, InteractionResponseType.ChannelMessageWithSource, icd);
        }
        [HookMethod(nameof(CreateTicketEmbedCommand))]
        [DiscordApplicationCommand("generateticket")]
        private void CreateTicketEmbedCommand(DiscordInteraction interaction, InteractionDataParsed idp) {
            DiscordEmbedBuilder deb = new();
            deb.AddTitle(config.lang.ticketEmbedTitle);
            deb.AddColor(DiscordColor.Blurple);
            deb.AddDescription(config.lang.ticketEmbedDescription);
            DiscordMessageBuilder dmb = new();
            dmb.AddEmbed(deb.Build());
            ActionRowComponent arc = new();
            foreach (var langButt in config.ticketLangButtons) {
                ButtonComponent button = new() {
                    Label = langButt.Value.displayedName, Style = ButtonStyle.Primary, Disabled = false, Emoji = DiscordEmoji.FromCharacter(langButt.Value.displayedIcon), CustomId = $"ticket_discord_button_{langButt.Key}"
                }
                ;
                arc.Components.Add(button);
            }
            dmb.AddActionRow(arc);
            interaction.Channel.CreateMessage(Client, dmb.Build());
            InteractionCallbackData icd = new() {
                Content = "Created ticket embed.", Flags = MessageFlags.Ephemeral
            }
            ;
            interaction.CreateResponse(Client, InteractionResponseType.ChannelMessageWithSource, icd);
        }
        [HookMethod(nameof(CreateTicketCloseCommand))]
        [DiscordApplicationCommand("close")]
        private void CreateTicketCloseCommand(DiscordInteraction interaction, InteractionDataParsed idp) {
            InteractionCallbackData icd;
            if (interaction.Channel.ParentId != config.newTicketsParentId) {
                icd = new() {
                    Content = config.lang.ticketCannotClose, Flags = MessageFlags.Ephemeral
                }
                ;
                interaction.CreateResponse(Client, InteractionResponseType.ChannelMessageWithSource, icd);
                return;
            }
            DiscordChannel ch = interaction.Channel;
            GuildChannelUpdate gcu = new() {
                Name = ch.Name, ParentId = config.closedTicketsParentId, Topic = ch.Topic, Type = ch.Type, RateLimitPerUser = ch.RateLimitPerUser, Bitrate = ch.Bitrate, UserLimit = ch.UserLimit
            }
            ;
            ch.EditGuildChannel(Client, gcu);
            data.channelRemovalDate[interaction.Channel.Id] = DateTime.Now;
            DiscordEmbedBuilder deb = new();
            deb.AddTitle(config.lang.ticketClosedTitle);
            deb.AddColor(DiscordColor.Blurple);
            deb.AddDescription(config.lang.ticketClosedDescription);
            icd = new() {
                Embeds = new() {
                    deb.Build()
                }
            }
            ;
            interaction.CreateResponse(Client, InteractionResponseType.ChannelMessageWithSource, icd);
        }
        [HookMethod(nameof(CreateVoteCommand))]
        [DiscordApplicationCommand("vote")]
        private void CreateVoteCommand(DiscordInteraction interaction, InteractionDataParsed idp) {
            InteractionModalBuilder imb = new(interaction);
            imb.AddModalTitle("Vote Creator");
            imb.AddModalCustomId("vote_modal");
            imb.AddInputText("vote_title", "Vote Title", InputTextStyles.Short, config.defaultVoteTitle, true, "Map Vote");
            imb.AddInputText("vote_description", "Vote Description", InputTextStyles.Para
// ... [Code preview truncated due to length. Full source in attached file] ...

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