Exemple #1
0
        public static async Task <T> Load <T>(string filePath, ulong setId = 0, bool logExceptions = true) where T : MemoryBase
        {
            if (!File.Exists(filePath))
            {
                return(null);
            }

            try {
                var jObj = JObject.Parse(await File.ReadAllTextAsync(filePath));

                if (jObj != null)
                {
                    T result = (T)Activator.CreateInstance(typeof(T));

                    result.id = setId;
                    result.Initialize();
                    result.ReadFromJson(jObj);

                    return(result);
                }
            }
            catch (Exception e) {
                if (logExceptions)
                {
                    await MopBot.HandleException(e, "An error has occured when loading memory.");
                }
            }

            return(null);
        }
Exemple #2
0
        public async Task ShowShopCommand(string shopId)
        {
            var server             = Context.server;
            var memory             = server.GetMemory();
            var cmdShopServerData  = memory.GetData <CommandShopSystem, CommandShopServerData>();
            var currencyServerData = memory.GetData <CurrencySystem, CurrencyServerData>();
            var shops = cmdShopServerData.Shops;

            if (!shops.TryGetValue(shopId, out Shop shop))
            {
                throw new BotError($"No such shop: `{shopId}`.");
            }

            var embedBuilder = MopBot.GetEmbedBuilder(server)
                               .WithTitle(shop.displayName)
                               .WithDescription(shop.description)
                               .WithThumbnailUrl(shop.thumbnailUrl)
                               .WithFooter(@"Use ""!shop buy rewards <item number>"" to buy stuff!");

            var items = shop.Items;

            if (items != null)
            {
                for (int i = 0; i < items.Length; i++)
                {
                    ShopItem item = items[i];
                    await shop.SafeItemAction(i, throwError : false, action : async item => {
                        embedBuilder.AddField($"#{i+1} - {item.name}", $"Costs {string.Join(", ",item.prices.Select(price => currencyServerData.Currencies[price.currency].ToString(price.amount)))}");
                    });
                }
            }

            await Context.ReplyAsync(embedBuilder.Build());
        }
        public async Task ShowXPCommand(SocketGuildUser user = null)
        {
            user ??= Context.socketServerUser;

            var   serverMemory = MemorySystem.memory[Context.server];
            ulong xp           = serverMemory[user].GetData <XPSystem, XPServerUserData>().xp;
            uint  level        = XPToLevel(xp);

            uint rank = (uint)serverMemory.GetSubMemories <ServerUserMemory>().Keys
                        .SelectIgnoreNull(key => {
                var botUser = MopBot.client.GetUser(key);

                if (botUser == null)
                {
                    return(null);
                }

                return(new KeyValuePair <ulong, ServerUserMemory>?(new KeyValuePair <ulong, ServerUserMemory>(key, serverMemory[botUser])));
            })
                        .OrderByDescending(pair => pair?.Value.GetData <XPSystem, XPServerUserData>().xp ?? 0)
                        .FirstIndex(pair => pair?.Key == user.Id) + 1;

            ulong thisLevelXP = LevelToXP(level);
            ulong nextLevelXP = LevelToXP(level + 1);

            var builder = MopBot.GetEmbedBuilder(Context)
                          .WithAuthor(user.Username, user.GetAvatarUrl())
                          .WithDescription($"**XP: **{xp-thisLevelXP}/{nextLevelXP-thisLevelXP} ({xp}/{nextLevelXP} Total)\r\n**Level: **{level}\r\n**Rank: **#{rank}");

            await Context.socketTextChannel.SendMessageAsync("", embed : builder.Build());
        }
Exemple #4
0
        public async Task UpdateSystems(bool allowBreak)
        {
            for (int i = 0; i < systems.Count; i++)
            {
                var system = systems[i];

                try {
                    if (!await system.Update())
                    {
                        if (allowBreak)
                        {
                            break;
                        }
                    }
                    else if (MopBot.client?.ConnectionState == ConnectionState.Connected)
                    {
                        foreach (var server in MopBot.client.Guilds)
                        {
                            if (system.IsEnabledForServer(server))
                            {
                                await system.ServerUpdate(server);
                            }
                        }
                    }
                }
                catch (Exception e) {
                    await MopBot.HandleException(e);

                    break;
                }
            }
        }
Exemple #5
0
        public async Task ShowCurrenciesCommand()
        {
            var context            = Context;
            var userId             = context.user.Id;
            var currencyServerData = context.server.GetMemory().GetData <CurrencySystem, CurrencyServerData>();

            var currencies = currencyServerData.Currencies;

            if (currencies.Count == 0)
            {
                throw new BotError("There are currently no currencies on this server.");
            }

            var builder = MopBot.GetEmbedBuilder(context)
                          .WithAuthor($"{context.user.GetDisplayName()}'s Coins & Points", context.user.GetAvatarUrl());

            foreach (var nameId in currencies)
            {
                var   currency = nameId.value;
                ulong amount   = currency.GetAmount(userId);               //currencyUserData[id];

                builder.AddField(
                    $"{currency.emote ?? "💰"} - **{amount} {StringUtils.ChangeForm(currency.displayName,amount==1)}**",
                    $"{currency.description ?? "No description"}\r\nId: `{nameId.name}`"
                    );
            }

            await context.ReplyAsync(embed : builder.Build());
        }
Exemple #6
0
        public async Task AvatarCommand(SocketGuildUser user, [Remainder] string args = null)
        {
            var embed = MopBot.GetEmbedBuilder(Context)
                        .WithAuthor($"{user.GetDisplayName()}'s avatar")
                        .WithImageUrl(user.GetAvatarUrl(size: 1024))
                        .WithFooter($"Requested by {Context.socketServerUser.GetDisplayName()}", Context.user.GetAvatarUrl())
                        .Build();

            await Context.ReplyAsync(embed, false);
        }
Exemple #7
0
        public static SocketUserMessage ToSocketUserMessage(this RestUserMessage restMessage, SocketTextChannel channel)
        {
            SocketUserMessage msgNew = MopBot.Construct <SocketUserMessage>(new Type[] { typeof(DiscordSocketClient), typeof(ulong), typeof(ISocketMessageChannel), typeof(SocketUser), typeof(MessageSource) }, new object[] { MopBot.client, restMessage.Id, channel, restMessage.Author, restMessage.Source });

            typeof(SocketMessage).GetField("<Content>k__BackingField", anyFlags).SetValue(msgNew, restMessage.Content);
            typeof(SocketUserMessage).GetField("_embeds", anyFlags).SetValue(msgNew, (ImmutableArray <Embed>)restMessage.Embeds);
            typeof(SocketUserMessage).GetField("_attachments", anyFlags).SetValue(msgNew, (ImmutableArray <Attachment>)restMessage.Attachments);

            return(msgNew);
        }
        private async Task ExecuteAction(MessageContext context, ModerationPunishment action, string reason, SocketGuildUser user = null)
        {
            user ??= context.socketServerUser ?? throw new ArgumentNullException($"Both {nameof(user)} and {nameof(context)}.{nameof(MessageContext.socketServerUser)} are null.");

            var embedBuilder = MopBot.GetEmbedBuilder(user.Guild)
                               .WithAuthor(user)
                               .WithDescription($"**Reason:** `{reason}`");

            bool RequirePermission(DiscordPermission discordPermission)
            {
                if (!context.server.CurrentUser.HasChannelPermission(context.socketServerChannel, DiscordPermission.BanMembers))
                {
                    action = ModerationPunishment.Announce;

                    embedBuilder.Title = $"{embedBuilder.Title}\r\n**Attempted to execute action '{action}', but the following permission was missing: `{DiscordPermission.BanMembers}`.";

                    return(false);
                }

                return(true);
            }

            switch (action)
            {
            case ModerationPunishment.Kick:
                if (RequirePermission(DiscordPermission.KickMembers))
                {
                    await user.KickAsync(reason : reason);

                    embedBuilder.Title = "User auto-kicked";
                }

                break;

            case ModerationPunishment.Ban:
                if (RequirePermission(DiscordPermission.KickMembers))
                {
                    await user.BanAsync(reason : reason);

                    embedBuilder.Title = "User auto-banned";
                }

                break;
            }

            if (action == ModerationPunishment.Announce)
            {
                embedBuilder.Title = "User violation detected";
            }

            var data = context.server.GetMemory().GetData <AutoModerationSystem, AutoModerationServerData>();

            await context.socketTextChannel.SendMessageAsync(data.announcementPrefix, embed : embedBuilder.Build());
        }
Exemple #9
0
        public override async Task OnMessageReceived(MessageContext context)
        {
            var server  = context.server;
            var channel = context.socketTextChannel;

            if (channel == null)
            {
                return;
            }

            var triviaServerMemory = server.GetMemory().GetData <TriviaSystem, TriviaServerData>();
            var qa = triviaServerMemory.currentQuestion;

            if (qa == null || channel.Id != triviaServerMemory.currentChannel)
            {
                return;
            }

            var regex = GetCurrentQuestionRegex(triviaServerMemory);

            string text  = context.content.ToLower().RemoveWhitespaces();
            var    match = regex.Match(context.content);

            if (match.Success)
            {
                triviaServerMemory.currentQuestion = null;

                var user = context.socketServerUser;

                CurrencyAmount.TryGiveToUser(ref triviaServerMemory.currencyRewards, user, out string givenString);

                var timeSpan = DateTime.Now - triviaServerMemory.lastTriviaPost.AddSeconds(triviaServerMemory.postIntervalInSeconds);
                var embed    = MopBot.GetEmbedBuilder(server)
                               .WithDescription($"{user.Mention} wins{(givenString!=null ? $", and gets {givenString}" : null)}!\r\nThe question was `{qa.question}`, and their answer was `{match.Groups[1].Value}`.\r\n\r\nThe next question will come up in `{timeSpan:m'm 's's'}` from now.")
                               .Build();

                await channel.SendMessageAsync(embed : embed);

                var currentUser = server.CurrentUser;

                if (triviaServerMemory.lockTriviaChannel && currentUser.HasChannelPermission(channel, DiscordPermission.ManageChannel))
                {
                    //Lock the channel, since the question has been answered.

                    await channel.ModifyPermissions(currentUser, op => op.Modify(sendMessages: PermValue.Allow));                   //Make sure we're still allowed to post

                    await channel.ModifyPermissions(server.EveryoneRole, op => op.Modify(sendMessages: PermValue.Deny));            //Forbid posting for everyone else
                }

                return;
            }
        }
Exemple #10
0
        public async Task ListSystems()
        {
            var server   = Context.server;
            var isMaster = Context.user.IsBotMaster();
            var builder  = MopBot.GetEmbedBuilder(server);

            foreach (var system in allSystems.Where(s => (!s.Configuration.Hidden || isMaster) && !s.Configuration.AlwaysEnabled).OrderBy(s => s.GetType().Name))
            {
                builder.AddField($"{(system.IsEnabledForServer(server) ? ":white_check_mark:" : ":x:")} - {system.Name}", system.Configuration.Description ?? "`Configuration missing.`");
            }

            await ReplyAsync(embed : builder.Build());
        }
Exemple #11
0
        public async Task ShowIssue(uint issueId)
        {
            var data  = Context.server.GetMemory().GetData <IssueSystem, IssueServerData>();
            var issue = data.issues.FirstOrDefault(i => i.issueId == issueId) ?? throw new BotError($"An issue with Id #{issueId} could not be found.");

            var user    = Context.user;
            var builder = MopBot.GetEmbedBuilder(Context)
                          .WithAuthor($"Requested by {user.GetDisplayName()}", user.GetAvatarUrl())
                          .WithTitle($"Issue #{issue.issueId}")
                          .WithDescription($"**Status:** {StatusText[issue.status]}```\r\n{issue.text}```");

            await Context.messageChannel.SendMessageAsync(embed : builder.Build());
        }
Exemple #12
0
        private static async Task ModifyXP(Func <ulong, ulong> xpModifier, SocketGuildUser user, SocketUserMessage message = null)
        {
            var server       = user.Guild;
            var serverMemory = MemorySystem.memory[server];
            var userMemory   = serverMemory[user];
            var xpUserData   = userMemory.GetData <XPSystem, XPServerUserData>();

            uint prevLvl = XPToLevel(xpUserData.xp);

            xpUserData.xp = xpModifier(xpUserData.xp);

            uint newLvl = XPToLevel(xpUserData.xp);

            if (message != null)
            {
                if (newLvl > prevLvl)
                {
                    try {
                        await message.AddReactionAsync(EmoteUtils.Parse("🌟"));
                    }
                    catch (Exception e) {
                        await MopBot.HandleException(e);
                    }
                }

                /*var mentionChannel = (ITextChannel)(serverMemory.GetData<ChannelSystem,ChannelServerData>().GetChannelByRole(ChannelRole.BotArea) ?? channel);
                 * string text = $"{user.Name()} has just reached level {newLvl}! :star:";
                 *
                 * var xpServerData = serverMemory.GetData<XPSystem,XPServerData>();
                 *
                 * if(xpServerData.levelRewards.TryGetValue(newLvl,out ulong[] roleIds)) {
                 *      var oldAccessLevel = user.GetAccessLevel();
                 *      var oldCommandList = CommandService.commands.Where(h => oldAccessLevel>=h.minAccessLevel);
                 *      var roles = roleIds.Select(id => server.GetRole(id));
                 *
                 *      text += $"\r\nThe following roles are now available to them:```{string.Join("\r\n",roles.Select(role => role.Name))}```";
                 *
                 *      await user.AddRolesAsync(roles);
                 *
                 *      var newAccessLevel = user.GetAccessLevel(roleIds);
                 *      var newCommandList = CommandService.commands.Where(h => newAccessLevel>=h.minAccessLevel);
                 *      var newCommandsOnly = newCommandList.Where(h => !oldCommandList.Contains(h)).ToArray();
                 *
                 *      if(newCommandsOnly.Length>0) {
                 *              text += $"\r\nThe following commands are now available to them:```{string.Join("\r\n",newCommandsOnly.Select(h => $"{string.Join("/",h.aliases)}-{h.description}"))}```";
                 *      }
                 * }
                 *
                 * await mentionChannel.SendMessageAsync(text);*/
            }
        }
Exemple #13
0
        public async Task HelpCommand()
        {
            var context = Context;
            var builder = MopBot.GetEmbedBuilder(context)
                          .WithAuthor($"Commands available to @{context.socketServerUser.GetDisplayName()}:", context.user.GetAvatarUrl())
                          .WithFooter($"You can type {context.server.GetMemory().GetData<CommandSystem, CommandServerData>().commandPrefix}help <command> to see groups' commands and commands' syntaxes.");

            foreach ((var aliases, string description, _) in GetAvailableCommands(context.server, context.socketServerUser, true))
            {
                builder.AddField(string.Join("/", aliases), description);
            }

            await context.socketTextChannel.SendMessageAsync(embed : builder.Build());
        }
Exemple #14
0
        public async Task ShowEntry(uint entryId)
        {
            var context = Context;
            var data    = context.server.GetMemory().GetData <ChangelogSystem, ChangelogServerData>();
            var entry   = data.entries.FirstOrDefault(i => i.entryId == entryId);

            if (entry == null)
            {
                throw new BotError($"An entry with Id #{entryId} could not be found.");
            }

            var user    = context.user;
            var builder = MopBot.GetEmbedBuilder(context)
                          .WithAuthor($"Requested by {user.GetDisplayName()}", user.GetAvatarUrl())
                          .WithTitle($"Entry #{entry.entryId}")
                          .WithDescription($"**Status:** {(data.entryTypes.TryGetValue(entry.type, out var entryType) ? $"{entryType.discordPrefix} - {entryType.name}" : $"UNKNOWN (`{entry.type}`)")}```\r\n{entry.text}```");
Exemple #15
0
        public EmbedBuilder ToBuilder(SocketGuild server)
        {
            var builder = MopBot.GetEmbedBuilder(server);

            if (authorName != null)
            {
                builder.WithAuthor(authorName, imageUrl);
            }

            if (description != null)
            {
                builder.WithDescription(description);
            }

            return(builder);
        }
Exemple #16
0
        public override async Task ServerUpdate(SocketGuild server)
        {
            var    memory   = server.GetMemory().GetData <ConfigurationSystem, ConfigurationServerData>();
            string nickname = memory.forcedNickname;

            var currentUser = server.GetUser(MopBot.client.CurrentUser.Id);

            if (currentUser != null && !string.Equals(currentUser.Nickname, nickname, StringComparison.InvariantCulture) && !(nickname == "MopBot" && currentUser.Nickname == null) && currentUser.HasDiscordPermission(p => p.ChangeNickname))
            {
                try {
                    await currentUser.ModifyAsync(u => u.Nickname = nickname);
                }
                catch (Exception e) {
                    await MopBot.HandleException(e);
                }
            }
        }
Exemple #17
0
        public async Task MoveMessagesCommand(SocketTextChannel sourceChannel, int numMessages, SocketTextChannel destinationChannel, ulong bottomMessageId = 0, bool allowGrouping = true)
        {
            var context = Context;

            context.server.CurrentUser.RequirePermission(destinationChannel, DiscordPermission.ManageMessages);

            var messageList = await CopyMessagesInternal(sourceChannel, numMessages, destinationChannel, bottomMessageId, allowGrouping);

            try {
                await context.socketTextChannel.DeleteMessagesAsync(messageList);
            }
            catch (Exception e) {
                await MopBot.HandleException(e);

                await context.ReplyAsync($"Error deleting messages: ```{string.Join("\r\n", messageList.Select(m => m == null ? "NULL" : m.Id.ToString()))}```");
            }
        }
Exemple #18
0
        public async Task SetupShopCommand(string shopId, string displayName, string description = null, string thumbnailUrl = null)
        {
            StringUtils.CheckAndLowerStringId(ref shopId);
            MopBot.CheckForNullOrEmpty(displayName, nameof(displayName));

            var context           = Context;
            var cmdShopServerData = context.server.GetMemory().GetData <CommandShopSystem, CommandShopServerData>();
            var shops             = cmdShopServerData.Shops;

            if (!shops.TryGetValue(shopId, out Shop shop))
            {
                shops[shopId] = shop = new Shop();
            }

            shop.displayName  = displayName;
            shop.description  = description;
            shop.thumbnailUrl = thumbnailUrl;
        }
Exemple #19
0
        public override async Task Initialize()
        {
            if (string.IsNullOrWhiteSpace(GlobalConfiguration.config.token))
            {
                throw new ArgumentException($"Add bot's token to '{GlobalConfiguration.ConfigurationFile}' file.");
            }

            MopBot.client = client = new DiscordSocketClient(new DiscordSocketConfig()
            {
                LogLevel         = LogSeverity.Debug,
                MessageCacheSize = 1000
            });

            MopBot.OnClientInit(client);

            await MopBot.TryCatchLogged("Attempting Login...", () => client.LoginAsync(TokenType.Bot, GlobalConfiguration.config.token.Trim()));

            await MopBot.TryCatchLogged("Attempting Connection...", () => client.StartAsync());
        }
Exemple #20
0
        public async Task AddItemCommand(string shopId, string itemName, string itemPrice, string itemCommand)
        {
            MopBot.CheckForNullOrEmpty(itemName, nameof(itemName));
            MopBot.CheckForNullOrEmpty(itemCommand, nameof(itemCommand));

            var serverMemory      = Context.server.GetMemory();
            var cmdShopServerData = serverMemory.GetData <CommandShopSystem, CommandShopServerData>();
            var shops             = cmdShopServerData.Shops;

            if (!shops.TryGetValue(shopId, out Shop shop))
            {
                throw new BotError($"No such shop: `{shopId}`.");
            }

            var item = new ShopItem(itemName, CurrencyAmount.ParseMultiple(itemPrice, serverMemory), new SudoCommand(itemCommand, Context.user.Id));

            lock (shop) {
                shop.Items = shop.Items?.Append(item)?.ToArray() ?? new[] { item };
            }
        }
Exemple #21
0
        public async Task HelpCommand([Remainder] string cmdOrGroup)
        {
            var context = Context;

            cmdOrGroup = cmdOrGroup.Trim().ToLower();

            var match = GroupCommandRegex.Match(cmdOrGroup);

            if (!match.Success)
            {
                throw new BotError($"Invalid input: `{cmdOrGroup}`.");
            }

            string groupA = match.Groups[1].Value;
            string groupB = match.Groups[2].Value;

            var strComparer = MopBot.StrComparerIgnoreCase;
            var cmdPrefix   = context.server.GetMemory().GetData <CommandSystem, CommandServerData>().commandPrefix;

            EmbedBuilder builder = null;

            EmbedBuilder PrepareBuilder() => builder = MopBot.GetEmbedBuilder(context);
        public async Task MoveMessagesCommand(int numMessages, SocketGuildChannel channel, ulong bottomMessageId = 0)
        {
            var context = Context;

            context.server.CurrentUser.RequirePermission(channel, DiscordPermission.ManageMessages);

            if (!(channel is ITextChannel toChannel))
            {
                throw new BotError($"<#{channel.Id}> isn't a text channel.");
            }

            var messageList = await CopyMessagesInternal(numMessages, toChannel, bottomMessageId);

            try {
                await context.socketTextChannel.DeleteMessagesAsync(messageList);
            }
            catch (Exception e) {
                await MopBot.HandleException(e);

                await context.ReplyAsync($"Error deleting messages: ```{string.Join("\r\n",messageList.Select(m => m==null ? "NULL" : m.Id.ToString()))}```");
            }
        }
Exemple #23
0
        public override async Task OnUserJoined(SocketGuildUser user)
        {
            var server      = user.Guild;
            var memory      = server.GetMemory();
            var welcomeData = memory.GetData <WelcomeSystem, WelcomeServerData>();

            if (!server.TryGetTextChannel(welcomeData.channel, out var welcomeChannel))
            {
                return;
            }

            string msg;

            if (!memory.GetSubMemories <ServerUserMemory>().Any(p => p.Key == user.Id))
            {
                msg = welcomeData.messageJoin;
            }
            else
            {
                msg = welcomeData.messageRejoin;
            }

            await welcomeChannel.SendMessageAsync(user.Mention, embed : MopBot.GetEmbedBuilder(server).WithDescription(msg).Build());
        }
Exemple #24
0
        public override async Task OnMessageReceived(MessageContext message)
        {
            var localServerData = message.server.GetMemory().GetData <ChannelLinkingSystem, ChannelLinkingServerData>();
            var channelLinks    = localServerData.channelLinks;

            if (channelLinks == null)
            {
                return;
            }

            ulong channelId = message.messageChannel.Id;

            if (!channelLinks.TryGetValue(channelId, out ulong linkId))
            {
                return;
            }

            var channelLinkingData = MemorySystem.memory.GetData <ChannelLinkingSystem, ChannelLinkingGlobalData>();

            if (!channelLinkingData.links.TryGetValue(linkId, out var channelLink))
            {
                channelLinks.Remove(channelId);

                return;
            }

            //string inviteUrl = await BotUtils.GetInviteUrl(message.server);
            //string linkedServerName = inviteUrl!=null ? $"({message.server.Name})[{inviteUrl}]" : message.server.Name;

            string authorStr       = $"{message.user.Username}#{message.user.Discriminator} [{message.server.Name}/#{message.Channel.Name}]";
            string authorAvatarUrl = message.user.GetAvatarUrl();

            var builder = MopBot.GetEmbedBuilder(message)
                          .WithColor(message.socketServerUser.Roles.OrderByDescending(r => r.Position).FirstOrDefault(r => !r.Color.ColorEquals(Discord.Color.Default))?.Color ?? Discord.Color.Default)
                          .WithAuthor(authorStr, authorAvatarUrl)       //,$@"https://discordapp.com/channels/@me/{message.user.Id}"
                          .WithDescription(message.content);
Exemple #25
0
 private static EmbedBuilder GetUserEmbed(SocketGuild server, IUser user) => MopBot.GetEmbedBuilder(server)
 .WithAuthor(user)
 .WithFooter($"User ID: {user.Id}")
 .WithCurrentTimestamp();
Exemple #26
0
        public async Task SetQuestionsCommand(string url = null)
        {
            var server = Context.server;

            if (!Context.socketMessage.Attachments.TryGetFirst(a => a.Filename.EndsWith(".txt") || a.Filename.EndsWith(".json"), out Attachment file) && url == null)
            {
                await Context.ReplyAsync("Expected a .json file attachment or a link to it.");

                return;
            }

            string filePath  = MopBot.GetTempFileName("TriviaQuestions", ".json");
            string urlString = file?.Url ?? url;

            if (!Uri.TryCreate(urlString, UriKind.Absolute, out Uri uri))
            {
                await Context.ReplyAsync($"Invalid Url: `{urlString}`.");

                return;
            }

            using (var client = new WebClient()) {
                try {
                    client.DownloadFile(uri, filePath);
                }
                catch (Exception e) {
                    if (File.Exists(filePath))
                    {
                        File.Delete(filePath);
                    }

                    throw new BotError($"`{e.GetType().Name}` exception has occured during file download.");
                }
            }

            var json = File.ReadAllText(filePath);

            File.Delete(filePath);

            Dictionary <string, string[]> dict;

            try {
                dict = JsonConvert.DeserializeObject <Dictionary <string, string[]> >(json);
            }
            catch (Exception e) {
                throw new BotError($"Failed to parse the JSON file: `{e.Message}`.");
            }

            if (dict == null)
            {
                throw new BotError("Failed to parse the JSON file: Unknown error.");
            }

            var triviaServerData = server.GetMemory().GetData <TriviaSystem, TriviaServerData>();
            var questions        = triviaServerData.questions ??= new List <TriviaQuestion>();

            foreach (var pair in dict)
            {
                var key = pair.Key;

                if (string.IsNullOrWhiteSpace(key))
                {
                    throw new BotError("Failed to parse the JSON file: Some question is null.");
                }

                var value = pair.Value;

                if (value == null || value.Length == 0)
                {
                    throw new BotError($"Failed to parse the JSON file: Question `{key}`'s answers are missing or are null.");
                }

                questions.Add(new TriviaQuestion(key, value));
            }
        }
Exemple #27
0
        public override async Task ServerUpdate(SocketGuild server)
        {
            var triviaServerData = server.GetMemory().GetData <TriviaSystem, TriviaServerData>();

            if (!triviaServerData.IsReady)
            {
                return;                 //TODO: Let the admins know that this is misconfigured.
            }

            var now = DateTime.Now;

            if ((now - triviaServerData.lastTriviaPost).TotalSeconds <= triviaServerData.postIntervalInSeconds)
            {
                return;
            }

            triviaServerData.lastTriviaPost = now;
            triviaServerData.currentChannel = triviaServerData.triviaChannels[MopBot.Random.Next(triviaServerData.triviaChannels.Count)];

            var channel = server.GetTextChannel(triviaServerData.currentChannel);

            if (channel == null)
            {
                return;                 //TODO: Same as above
            }

            TriviaQuestion[] validQuestions;

            //Find questions we didn't pick yet, handle running out of them.
            while (true)
            {
                lock (triviaServerData.questions) {
                    validQuestions = triviaServerData.questions.Where(q => !q.wasPosted).ToArray();
                }

                if (validQuestions.Length == 0)
                {
                    if (triviaServerData.autoClearCache && triviaServerData.questions.Count > 0)
                    {
                        ClearCache(triviaServerData);

                        continue;
                    }
                    else
                    {
                        await channel.SendMessageAsync($"{server.Owner.Mention} We're out of trivia questions!\r\n\r\nAdd new questions, or..\r\n• Use `!trivia clearcache` to clear list of used questions;\r\n• Use `!trivia autoclearcache true` to automate this process, if you're fully okay with same questions being repeat;");

                        return;
                    }
                }

                break;
            }

            //Set new question
            triviaServerData.currentQuestion           = validQuestions[MopBot.Random.Next(validQuestions.Length)];
            triviaServerData.currentQuestion.wasPosted = true;
            currentQuestionRegex = null;             //This will cause a new one to be made, when needed.

            string     mention             = null;
            SocketRole role                = null;
            bool       disallowRoleMention = false;
            var        currentUser         = server.CurrentUser;

            if (triviaServerData.triviaRole > 0)
            {
                role = server.GetRole(triviaServerData.triviaRole);

                if (role != null)
                {
                    if (!role.IsMentionable && currentUser.HasDiscordPermission(gp => gp.ManageRoles))
                    {
                        await role.ModifyAsync(rp => rp.Mentionable = true);

                        disallowRoleMention = true;
                    }

                    mention = role.Mention;
                }
                else
                {
                    triviaServerData.triviaRole = 0;
                }
            }

            var embedBuilder = MopBot.GetEmbedBuilder(server)
                               .WithAuthor("The next question is...")  //.WithTitle("The next question is...")
                               .WithDescription($"**{triviaServerData.currentQuestion.question}**")
                               .WithFooter("Type your answer right in this channel!");

            if (triviaServerData.thumbnailUrls?.Length > 0 == true)
            {
                try {
                    embedBuilder.WithThumbnailUrl(triviaServerData.thumbnailUrls[MopBot.Random.Next(triviaServerData.thumbnailUrls.Length)]);
                }
                catch {}
            }

            await channel.SendMessageAsync(mention, embed : embedBuilder.Build());

            if (disallowRoleMention)
            {
                await role.ModifyAsync(rp => rp.Mentionable = false);
            }

            if (triviaServerData.lockTriviaChannel && currentUser.HasChannelPermission(channel, DiscordPermission.ManageChannel))
            {
                //Unlock the channel, since there's a question now.

                await channel.ModifyPermissions(server.EveryoneRole, op => op.SendMessages == PermValue.Deny?op.Modify(sendMessages : PermValue.Inherit) : op);
            }
        }