Beispiel #1
0
        public async Task SetPrefix(string prefix)
        {
            var embed = new KaguyaEmbedBuilder();

            if (prefix.Length > 5)
            {
                await ConsoleLogger.LogAsync("Command prefix was too long. Not set.", DataStorage.JsonStorage.LogLvl.DEBUG);

                embed.WithDescription("Your command prefix may not be longer than 5 characters.");
                embed.SetColor(EmbedColor.RED);
                await ReplyAsync(embed : embed.Build());

                return;
            }

            Server server = await DatabaseQueries.GetOrCreateServerAsync(Context.Guild.Id);

            server.CommandPrefix = prefix;
            await DatabaseQueries.UpdateAsync(server);

            embed.WithDescription($"Command prefix has been changed to `{prefix}`.");
            embed.WithFooter($"Use this command again without specifying a prefix to reset it.");
            embed.SetColor(EmbedColor.VIOLET);

            await ReplyAsync(embed : embed.Build());
        }
Beispiel #2
0
        public async Task SwapLogLevel(string level)
        {
            LogLvl curLog          = ConfigProperties.LogLevel;
            string validSeverities = "Trace, Debug, Info, Warn, Error";

            ConfigProperties.LogLevel = level.ToLower() switch
            {
                "trace" => LogLvl.TRACE,
                "debug" => LogLvl.DEBUG,
                "info" => LogLvl.INFO,
                "warn" => LogLvl.WARN,
                "error" => LogLvl.ERROR,
                _ => throw new ArgumentOutOfRangeException($"Valid logtypes are `{validSeverities}`", new Exception())
            };

            var embed = new KaguyaEmbedBuilder
            {
                Description = $"Successfully changed LogLevel from `{curLog.Humanize()}` to `{ConfigProperties.LogLevel.Humanize()}`",
                Footer      = new EmbedFooterBuilder
                {
                    Text = $"Note: This loglevel will return back to `{curLog.Humanize()}` after a restart."
                }
            };

            embed.SetColor(EmbedColor.VIOLET);

            await ReplyAsync(embed : embed.Build());
        }
    }
Beispiel #3
0
        public async Task ResetLogChannel(string logType)
        {
            KaguyaEmbedBuilder embed;
            List <string>      logTypes = await LogQuery.LogSwitcher(logType, false, Context.Guild.Id);

            if (logTypes.Count == 0)
            {
                embed = new KaguyaEmbedBuilder
                {
                    Description = $"Please specify a valid log type."
                };

                embed.SetColor(EmbedColor.RED);

                goto Reply;
            }

            if (logTypes.Any(x => x.Equals("all", System.StringComparison.OrdinalIgnoreCase)))
            {
                embed = new KaguyaEmbedBuilder
                {
                    Description = $"Successfully disabled all log types."
                };
            }
            else
            {
                embed = new KaguyaEmbedBuilder
                {
                    Description = $"Successfully disabled logtype `{string.Join(", ", logTypes).ToUpper()}`."
                };
            }

Reply:
            await ReplyAsync(embed : embed.Build());
        }
Beispiel #4
0
        public async Task UnWarnUser(SocketGuildUser user, [Remainder] string reason = null)
        {
            Server server = await DatabaseQueries.GetOrCreateServerAsync(Context.Guild.Id);

            List <WarnedUser> warnings = await DatabaseQueries.GetAllForServerAndUserAsync <WarnedUser>(user.Id, server.ServerId);

            int warnCount = warnings.Count;
            var fields    = new List <EmbedFieldBuilder>();

            reason ??= "<No reason provided>";

            if (warnCount > 4 && !server.IsPremium)
            {
                warnCount = 4;
            }

            if (warnCount > 9 && server.IsPremium)
            {
                warnCount = 9;
            }

            if (warnings.Count == 0)
            {
                var reply = new KaguyaEmbedBuilder
                {
                    Description = $"{user.Username} has no warnings to remove!"
                };

                reply.SetColor(EmbedColor.RED);

                await ReplyAsync(embed : reply.Build());

                return;
            }

            for (int i = 0; i < warnCount; i++)
            {
                var field = new EmbedFieldBuilder
                {
                    Name  = $"Warning #{i + 1}",
                    Value = $"Reason: `{warnings.ElementAt(i).Reason}`"
                };

                fields.Add(field);
            }

            var embed = new KaguyaEmbedBuilder
            {
                Title  = $"Warnings for {user}",
                Fields = fields,
                Footer = new EmbedFooterBuilder
                {
                    Text = "Select a reaction to remove the warning."
                }
            };

            await ReactionReply(user, warnings, embed.Build(), warnCount, server, reason);
        }
Beispiel #5
0
        public async Task UnmuteUser(SocketGuildUser user, [Remainder] string reason = null)
        {
            Server server = await DatabaseQueries.GetOrCreateServerAsync(Context.Guild.Id);

            var mutedObject = await DatabaseQueries.GetFirstMatchAsync <MutedUser>(x => x.UserId == user.Id && x.ServerId == server.ServerId);

            reason ??= "<No reason provided>";

            if (mutedObject != null)
            {
                await DatabaseQueries.DeleteAsync(mutedObject);
            }

            if (server.IsPremium)
            {
                await DatabaseQueries.UpdateAsync(server);
            }

            try
            {
                SocketRole muteRole = Context.Guild.Roles.FirstOrDefault(x => x.Name.ToLower() == "kaguya-mute");

                if (!user.Roles.Contains(muteRole))
                {
                    await ReplyAsync($"{Context.User.Mention} **{user}** is not muted.");

                    return;
                }

                await user.RemoveRoleAsync(muteRole);
                await ReplyAsync($"{Context.User.Mention} Successfully unmuted **{user}**.");


                KaguyaEvents.TriggerUnmute(new ModeratorEventArgs(server, Context.Guild, user, (SocketGuildUser)Context.User, reason, null));
            }
            catch (NullReferenceException)
            {
                var errorEmbed = new KaguyaEmbedBuilder
                {
                    Description = "User was never muted because the mute role doesn't exist.",
                    Footer      = new EmbedFooterBuilder
                    {
                        Text = "Use the mute command to generate the mute role."
                    }
                };

                errorEmbed.SetColor(EmbedColor.RED);

                await ReplyAsync(embed : errorEmbed.Build());
            }
            catch (Exception e)
            {
                throw new KaguyaSupportException($"An unexpected error occurred.\n\nError Log: {e}");
            }
        }
Beispiel #6
0
        public async Task AddPhrase(params string[] args)
        {
            string s = "s";

            if (args.Length == 1)
            {
                s = "";
            }

            Server server = DatabaseQueries.GetOrCreateServerAsync(Context.Guild.Id).Result;
            List <FilteredPhrase> allFp = server.FilteredPhrases.ToList();

            if (args.Length == 0)
            {
                var embed0 = new KaguyaEmbedBuilder
                {
                    Description = "Please specify at least one phrase."
                };

                embed0.SetColor(EmbedColor.RED);

                await SendEmbedAsync(embed0);

                return;
            }

            foreach (string element in args)
            {
                var fp = new FilteredPhrase
                {
                    ServerId = server.ServerId,
                    Phrase   = element
                };

                if (allFp.Contains(fp))
                {
                    continue;
                }

                await DatabaseQueries.InsertIfNotExistsAsync(fp);

                await ConsoleLogger.LogAsync($"Server {server.ServerId} has added the phrase \"{element}\" to their word filter.",
                                             DataStorage.JsonStorage.LogLvl.DEBUG);
            }

            var embed = new KaguyaEmbedBuilder
            {
                Description = $"Successfully added {args.Length} phrase{s} to the filter."
            };

            embed.SetColor(EmbedColor.VIOLET);

            await ReplyAsync(embed : embed.Build());
        }
Beispiel #7
0
        /// <summary>
        /// Sends a basic error message in chat.
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="description"></param>
        /// <returns></returns>
        public static async Task SendBasicErrorEmbedAsync(this IMessageChannel channel, string description)
        {
            var embed = new KaguyaEmbedBuilder
            {
                Description = description
            };

            embed.SetColor(EmbedColor.RED);

            await channel.SendMessageAsync(embed : embed.Build());
        }
Beispiel #8
0
        private async Task <CommandInfo> FindCommandInfo(string cmd, Server server)
        {
            CommandService cmdInfo    = CommandHandler.Commands;
            var            allAliases = new List <string>();

            foreach (CommandInfo command in cmdInfo.Commands)
            {
                allAliases.AddRange(command.Aliases.Select(alias => alias.ToLower()));
            }

            /*We use LastOrDefault instead of FirstOrDefault
             * because there are two "help" commands with the same names, but only the
             * last one has the proper description / syntax to be displayed in chat.*/

            CommandInfo selectedCommandByName  = cmdInfo.Commands.LastOrDefault(x => x.Name.ToLower() == cmd);
            CommandInfo selectedCommandByAlias = cmdInfo.Commands.LastOrDefault(x => x.Aliases.Contains(cmd));

            CommandInfo selectedCommand;

            if (selectedCommandByAlias != null && selectedCommandByName == null || selectedCommandByAlias != null)
            {
                selectedCommand = selectedCommandByAlias;
            }

            else if (selectedCommandByName != null)
            {
                selectedCommand = selectedCommandByName;
            }

            else
            {
                var embed = new KaguyaEmbedBuilder
                {
                    Description =
                        $"Command `{server.CommandPrefix}{cmd}` does not exist. Please ensure you are typing the name (or ailias) correctly. " +
                        $"Use `{server.CommandPrefix}help` for a list of all commands."
                };

                embed.SetColor(EmbedColor.RED);

                await ReplyAsync(embed : embed.Build());

                selectedCommand = null;
            }

            return(selectedCommand);
        }
Beispiel #9
0
        public async Task Find([Remainder] string roleName)
        {
            SocketGuild guild = Context.Guild;
            IReadOnlyCollection <SocketRole> roles = guild.Roles;

            if (roles.All(x => x.Name.ToLower() != roleName.ToLower()))
            {
                var embed = new KaguyaEmbedBuilder
                {
                    Description = $"The role `{roleName.ToUpper()}` could not be found."
                };

                embed.SetColor(EmbedColor.RED);

                await ReplyAsync(embed : embed.Build());

                return;
            }

            int matchCount = roles.Count(x => x.Name.ToLower() == roleName.ToLower());

            if (matchCount > 1)
            {
                await MultipleMatchingRolesHandler(guild, roleName, roles);

                return;
            }

            SocketRole matchingRole = guild.Roles.FirstOrDefault(x => x.Name.ToLower() == roleName.ToLower());

            List <PaginatedMessage.Page> pages = Pages(guild, matchingRole);
            var pager = new PaginatedMessage
            {
                Pages = pages,
                Color = Color.Blue
            };

            await PagedReplyAsync(pager, new ReactionList
            {
                Backward = true,
                First    = true,
                Forward  = true,
                Jump     = true,
                Last     = true,
                Trash    = true
            });
        }
Beispiel #10
0
        public async Task RemovePhrase()
        {
            Server server = await DatabaseQueries.GetOrCreateServerAsync(Context.Guild.Id);

            List <FilteredPhrase> allFp = server.FilteredPhrases.ToList();

            foreach (FilteredPhrase element in allFp)
            {
                await DatabaseQueries.DeleteAsync(element);
            }

            var embed = new KaguyaEmbedBuilder
            {
                Description = $"Successfully cleared the server's word filter. ({allFp.Count} phrases)"
            };

            embed.SetColor(EmbedColor.VIOLET);

            await ReplyAsync(embed : embed.Build());
        }
Beispiel #11
0
        public async Task RemoveRole(params string[] roleNames)
        {
            if (roleNames.Length > 1)
            {
                var embed = new KaguyaEmbedBuilder
                {
                    Title = "Roles Created"
                };

                foreach (string role in roleNames)
                {
                    embed.AddField("Role Created", $"`{role}` has been created.");
                    await Context.Guild.CreateRoleAsync(role, GuildPermissions.None, Color.Default, false, false, null);
                }

                await ReplyAsync(embed : embed.Build());
            }
            else if (roleNames.Count() == 1)
            {
                var embed = new KaguyaEmbedBuilder
                {
                    Description = $"**{Context.User.Mention} Successfully created role `{roleNames[0]}`**"
                };

                await Context.Guild.CreateRoleAsync(roleNames[0], GuildPermissions.None, Color.Default, false, false, null);

                await ReplyAsync(embed : embed.Build());
            }
            else
            {
                var embed = new KaguyaEmbedBuilder
                {
                    Description = $"Please specify a role to create."
                };

                embed.SetColor(EmbedColor.RED);

                await ReplyAsync(embed : embed.Build());
            }
        }
Beispiel #12
0
        private static async Task <KaguyaEmbedBuilder> WarnEmbed(WarnedUser user, ICommandContext context)
        {
            List <WarnedUser> curWarns = await DatabaseQueries.GetAllForServerAndUserAsync <WarnedUser>(user.UserId, context.Guild.Id);

            int curCount = curWarns.Count;
            var embed    = new KaguyaEmbedBuilder
            {
                Title       = "⚠️ Warning Received",
                Description = $"Warned from `[Server: {context.Guild} | ID: {context.Guild.Id}]`\n" +
                              $"Warned by: `[User: {context.User} | ID: {context.User.Id}]`\n" +
                              $"Reason: `{user.Reason}`",
                Footer = new EmbedFooterBuilder
                {
                    Text =
                        $"You currently have {curCount} warnings."
                }
            };

            embed.SetColor(EmbedColor.RED);

            return(embed);
        }
Beispiel #13
0
        public async Task React(string text, ulong msgId = 0)
        {
            IMessage message = null;

            if (msgId == 0)
            {
                message = Context.Message;
            }

            if (msgId != 0)
            {
                message = await Context.Channel.GetMessageAsync(msgId);
            }

            if (text.Length > 10)
            {
                var embed = new KaguyaEmbedBuilder
                {
                    Description = "Your reaction may not be more than 10 characters long."
                };

                embed.SetColor(EmbedColor.RED);

                await ReplyAsync(embed : embed.Build());

                return;
            }

            text.Replace(" ", "");
            var emojis = new List <Emoji>();

            foreach (char letter in text)
            {
                emojis.Add(new Emoji($"{ReturnEmoji(letter)}"));
            }

            await(message as IUserMessage).AddReactionsAsync(emojis.ToArray());
        }
Beispiel #14
0
        public async Task Remind(string timeString, [Remainder] string text)
        {
            TimeSpan           time = timeString.ParseToTimespan();
            KaguyaEmbedBuilder embed;

            if (time.TotalSeconds < 10)
            {
                embed = new KaguyaEmbedBuilder
                {
                    Description = "You must set a reminder for at least 10 seconds from now."
                };

                embed.SetColor(EmbedColor.RED);

                await ReplyAsync(embed : embed.Build());

                return;
            }

            var reminder = new Reminder
            {
                UserId       = Context.User.Id,
                Expiration   = DateTime.Now.AddSeconds(time.TotalSeconds).ToOADate(),
                Text         = text,
                HasTriggered = false
            };

            await DatabaseQueries.InsertAsync(reminder);

            embed = new KaguyaEmbedBuilder
            {
                Description = $"Okay! I'll remind you in `{time.Humanize(3)}` to `{text}`"
            };

            await ReplyAsync(embed : embed.Build());
        }
Beispiel #15
0
        public async Task Command()
        {
            DiscordShardedClient client = Client;
            SocketUser           owner  = client.GetUser(ConfigProperties.BotConfig.BotOwnerId);

            KaguyaStatistics stats = MemoryCache.MostRecentStats;

            int totalGuilds        = stats.Guilds;
            int totalTextChannels  = stats.TextChannels;
            int totalVoiceChannels = stats.VoiceChannels;

            Dictionary <string, int> mostPopCommand = MemoryCache.MostPopularCommandCache;

            string mostPopCommandName  = mostPopCommand?.Keys.First();
            string mostPopCommandCount = mostPopCommand?.Values.First().ToString("N0");

            string mostPopCommandText;

            if (mostPopCommandName == null || String.IsNullOrWhiteSpace(mostPopCommandCount))
            {
                mostPopCommandText = "Data not loaded into cache yet.";
            }
            else
            {
                mostPopCommandText = $"{mostPopCommandName} with {int.Parse(mostPopCommandCount.Replace(",", "")):N0} uses.";
            }

            var fields = new List <EmbedFieldBuilder>
            {
                new EmbedFieldBuilder
                {
                    Name  = "Author",
                    Value = $"User: `{owner}`\n" +
                            $"Id: `{owner.Id}`"
                },
                new EmbedFieldBuilder
                {
                    Name  = "Command Stats",
                    Value = $"Commands Run (Last 24 Hours): `{stats.CommandsLast24Hours:N0}`\n" +
                            $"Commands Run (All-time): `{stats.Commands:N0}`\n" +
                            $"Most Popular Command: `{mostPopCommandText}`"
                },
                new EmbedFieldBuilder
                {
                    Name  = "Global Stats",
                    Value = $"Uptime: `{(DateTime.Now - DateTime.Now.AddSeconds(-stats.UptimeSeconds)).Humanize(4, minUnit: TimeUnit.Second)}`\n" +
                            $"Guilds: `{totalGuilds:N0}`\n" +
                            $"Text Channels: `{totalTextChannels:N0}`\n" +
                            $"Voice Channels: `{totalVoiceChannels:N0}`\n" +
                            $"Users: `{stats.GuildUsers:N0}`\n" +
                            $"RAM Usage: `{stats.RamUsageMegabytes:N2} Megabytes`\n" +
                            $"Current Version: `{stats.Version}`"
                },
                new EmbedFieldBuilder
                {
                    Name  = "Kaguya User Stats",
                    Value = $"Unique Interactions (Users): `{stats.KaguyaUsers:N0}`\n" +
                            $"Total Points in Circulation: `{stats.Points:N0}`\n" +
                            $"Total Gambles: `{stats.Gambles:N0}`"
                }
            };

            var embed = new KaguyaEmbedBuilder
            {
                Title  = "Kaguya Statistics",
                Fields = fields
            };

            embed.SetColor(EmbedColor.GOLD);
            await ReplyAsync(embed : embed.Build());
        }
Beispiel #16
0
        public async Task ClearMessages(int amount = 10, string reason = null)
        {
            if (amount > 1000)
            {
                await SendBasicErrorEmbedAsync("You may not attempt to clear more than `1,000` messages " +
                                               "at a time.");

                return;
            }

            if (amount < 1)
            {
                await SendBasicErrorEmbedAsync("You must clear at least 1 message.");

                return;
            }

            Server server = await DatabaseQueries.GetOrCreateServerAsync(Context.Guild.Id);

            KaguyaEmbedBuilder embed;

            server.IsCurrentlyPurgingMessages = true;
            await DatabaseQueries.UpdateAsync(server);

            IMessage[]             messages        = (await Context.Channel.GetMessagesAsync(amount + 1).FlattenAsync()).ToArray();
            IEnumerable <IMessage> invalidMessages = messages.Where(x => x.Timestamp.DateTime < DateTime.Now.AddDays(-14));

            await((SocketTextChannel)Context.Channel).DeleteMessagesAsync(messages);

            // We take away 1 because the bot's own message is included in the collection.
            int    msgDisplayCount = messages.Length - 1;
            string s = msgDisplayCount == 1 ? string.Empty : "s";

            if (!invalidMessages.Any())
            {
                embed = new KaguyaEmbedBuilder
                {
                    Description = $"Successfully deleted `{msgDisplayCount}` message{s}."
                };

                await ReplyAndDeleteAsync("", false, embed.Build(), TimeSpan.FromSeconds(4));
            }
            else
            {
                embed = new KaguyaEmbedBuilder
                {
                    Description = $"Successfully deleted `{msgDisplayCount}` messages. Failed to delete " +
                                  $"`{amount - msgDisplayCount}` message{s}. This is likely because those " +
                                  "messages were posted more than two weeks ago. Messages posted more than two " +
                                  "weeks ago may not be deleted by Discord bots (this is a Discord-imposed limitation).",
                    Footer = new EmbedFooterBuilder
                    {
                        Text = "This message will be deleted in 15 seconds..."
                    }
                };

                embed.SetColor(EmbedColor.VIOLET);

                await ReplyAndDeleteAsync("", false, embed.Build(), TimeSpan.FromSeconds(15));
            }

            server.IsCurrentlyPurgingMessages = false;
            await DatabaseQueries.UpdateAsync(server);
        }
Beispiel #17
0
        public async Task Command(string action = null, int warnings = 0)
        {
            Server server = await DatabaseQueries.GetOrCreateServerAsync(Context.Guild.Id);

            var serverActions = await DatabaseQueries.GetFirstForServerAsync <WarnSetting>(server.ServerId);

            if (action == null && warnings == 0)
            {
                if (serverActions == null)
                {
                    var nullErrorEmbed = new KaguyaEmbedBuilder
                    {
                        Description = "Nothing has been configured."
                    };

                    nullErrorEmbed.SetColor(EmbedColor.RED);

                    await ReplyAsync(embed : nullErrorEmbed.Build());

                    return;
                }

                var curSettingsEmbed = new KaguyaEmbedBuilder
                {
                    Description = $"`{Context.Guild.Name}`. Here's what I've got:\n\n" +
                                  $"`Mute`: After `{(serverActions.Mute.IsZero() ? "N/A" : serverActions.Mute.ToString().Humanize())}` warnings.\n" +
                                  $"`Kick`: After `{(serverActions.Kick.IsZero() ? "N/A" : serverActions.Kick.ToString().Humanize())}` warnings.\n" +
                                  $"`Shadowban`: After `{(serverActions.Shadowban.IsZero() ? "N/A" : serverActions.Shadowban.ToString().Humanize())}` warnings.\n" +
                                  $"`Ban`: After `{(serverActions.Ban.IsZero() ? "N/A" : serverActions.Ban.ToString().Humanize())}` warnings.\n"
                };

                await ReplyAsync(embed : curSettingsEmbed.Build());

                return;
            }

            var actions = new string[]
            {
                "mute",
                "kick",
                "shadowban",
                "ban"
            };

            if (actions.All(x => x.ToLower() != action))
            {
                var errorEmbed = new KaguyaEmbedBuilder
                {
                    Description = $"`{Context.Message.Content}` is not a valid action. The only valid " +
                                  $"actions are `mute`, `kick`, `shadowban`, and `ban`."
                };

                errorEmbed.SetColor(EmbedColor.RED);

                await ReplyAsync(embed : errorEmbed.Build());

                return;
            }

            if (warnings < 0 || warnings > 99)
            {
                var numError = new KaguyaEmbedBuilder
                {
                    Description = "The amount of warnings must be between `0` and `99`."
                };

                numError.SetColor(EmbedColor.RED);

                await ReplyAsync(embed : numError.Build());

                return;
            }

            var newSetting = new WarnSetting
            {
                ServerId = Context.Guild.Id
            };

            if (serverActions != null)
            {
                newSetting = serverActions;
            }

            switch (action.ToLower())
            {
            case "mute":
                newSetting.Mute = warnings;

                break;

            case "kick":
                newSetting.Kick = warnings;

                break;

            case "shadowban":
                newSetting.Shadowban = warnings;

                break;

            case "ban":
                newSetting.Ban = warnings;

                break;
            }

            await DatabaseQueries.InsertOrReplaceAsync(newSetting);

            var successEmbed = new KaguyaEmbedBuilder
            {
                Description = $"Successfully updated the warn triggers for " +
                              $"`{Context.Guild.Name}`. Here's what I've got:\n\n" +
                              $"`Mute`: After `{(newSetting.Mute.IsZero() ? "N/A" : newSetting.Mute.ToString().Humanize())}` warnings.\n" +
                              $"`Kick`: After `{(newSetting.Kick.IsZero() ? "N/A" : newSetting.Kick.ToString().Humanize())}` warnings.\n" +
                              $"`Shadowban`: After `{(newSetting.Shadowban.IsZero() ? "N/A" : newSetting.Shadowban.ToString().Humanize())}` warnings.\n" +
                              $"`Ban`: After `{(newSetting.Ban.IsZero() ? "N/A" : newSetting.Ban.ToString().Humanize())}` warnings.\n"
            };

            successEmbed.SetColor(EmbedColor.PINK);

            await ReplyAsync(embed : successEmbed.Build());
        }
Beispiel #18
0
        public async Task RemovePhrase(params string[] args)
        {
            string s = "s";

            if (args.Length == 1)
            {
                s = "";
            }

            Server server = await DatabaseQueries.GetOrCreateServerAsync(Context.Guild.Id);

            List <FilteredPhrase> allFp = server.FilteredPhrases.ToList();

            if (args.Length == 0)
            {
                var embed0 = new KaguyaEmbedBuilder
                {
                    Description = "Please specify at least one phrase."
                };

                embed0.SetColor(EmbedColor.RED);

                await Context.Channel.SendEmbedAsync(embed0);

                return;
            }

            int  remCount = 0;
            bool matches  = false;

            foreach (string element in args)
            {
                if (!allFp.Any(x => x.Phrase.ToLower() == element.ToLower() && x.ServerId == server.ServerId))
                {
                    continue;
                }

                await DatabaseQueries.DeleteAsync(allFp.FirstOrDefault(x =>
                                                                       x.Phrase.ToLower() == element.ToLower() && x.ServerId == server.ServerId));

                matches = true;
                remCount++;

                await ConsoleLogger.LogAsync($"Server {server.ServerId} has removed the phrase \"{element}\" from their word filter.",
                                             DataStorage.JsonStorage.LogLvl.DEBUG);
            }

            KaguyaEmbedBuilder embed;

            if (!matches)
            {
                embed = new KaguyaEmbedBuilder(EmbedColor.RED)
                {
                    Description = "The phrases you wrote here are not present in your filter.",
                    Footer      = new EmbedFooterBuilder
                    {
                        Text = "If your phrase has a space, wrap it in quotation marks."
                    }
                };
            }
            else
            {
                if (remCount == args.Length)
                {
                    embed = new KaguyaEmbedBuilder(EmbedColor.VIOLET)
                    {
                        Description = $"Successfully removed `{args.Length:N0}` phrase{s} from the filter."
                    };
                }
                else
                {
                    s     = remCount == 0 ? "" : "s";
                    embed = new KaguyaEmbedBuilder(EmbedColor.ORANGE)
                    {
                        Description = $"Successfully removed `{remCount:N0}` phrase{s} from the filter.\n" +
                                      $"`{args.Length - remCount}` phrases did not exist in the filter."
                    };
                }
            }

            await ReplyAsync(embed : embed.Build());
        }
Beispiel #19
0
        public async Task RemoveRole([Remainder] string targetRole)
        {
            var roles = new List <SocketRole>();

            roles = Context.Guild.Roles.Where(r => r.Name.ToLower() == targetRole.ToLower()).ToList();

            if (roles.Count > 1)
            {
                var emojis = new Emoji[]
                {
                    new Emoji("1⃣"),
                    new Emoji("2⃣"),
                    new Emoji("3⃣"),
                    new Emoji("4⃣"),
                    new Emoji("5⃣"),
                    new Emoji("6⃣"),
                    new Emoji("7⃣"),
                    new Emoji("8⃣"),
                    new Emoji("9⃣")
                };

                var embed = new KaguyaEmbedBuilder
                {
                    Description = $"I found `{roles.Count.ToWords()}` roles that match this name. Please " +
                                  $"select the role that you want to delete, or use the ⛔ reaction " +
                                  $"to delete all roles with this name.",
                    Fields = new List <EmbedFieldBuilder>()
                };

                var callbacks = new List <(IEmote, Func <SocketCommandContext, SocketReaction, Task>)>();

                for (int i = 0; i < roles.Count; i++)
                {
                    int        roleIndex = i + 1;
                    SocketRole role      = roles.ElementAt(i);

                    embed.Fields.Add(new EmbedFieldBuilder
                    {
                        Name  = $"Role #{roleIndex}",
                        Value = $"Exact Name: `{role.Name}`\n" +
                                $"Number of users who have this role: " +
                                $"`{Context.Guild.Users.Count(x => x.Roles.Contains(role))}`\n" +
                                $"Permissions: `{roles.Count}`\n" +
                                $"Created: `{role.CreatedAt.Humanize()}`\n" +
                                $"Position in role list (higher number = higher position): `{role.Position}`"
                    });

                    callbacks.Add((emojis[i], async(c, r) =>
                    {
                        await role.DeleteAsync();
                        await ReplyAsync($"{Context.User.Mention} `Successfully deleted Role #{roleIndex}`");
                    }
                                   ));
                }

                callbacks.Add((new Emoji("⛔"), async(c, r) =>
                {
                    foreach (SocketRole role in roles)
                    {
                        await role.DeleteAsync();
                    }

                    await ReplyAsync($"{Context.User.Mention} Successfully deleted `{roles.Count.ToWords()}` roles.");
                }
                               ));

                var data = new ReactionCallbackData("", embed.Build(), false, false, TimeSpan.FromSeconds(120));
                data.SetCallbacks(callbacks);
                await InlineReactionReplyAsync(data);
            }
            else if (roles.Count == 1)
            {
                SocketRole role  = roles.First();
                var        embed = new KaguyaEmbedBuilder
                {
                    Description = $"{Context.User.Mention} Successfully deleted role `{role.Name}`"
                };

                await role.DeleteAsync();

                await ReplyAsync(embed : embed.Build());
            }
            else
            {
                var embed = new KaguyaEmbedBuilder
                {
                    Description = $"I could not find the specified role."
                };

                embed.SetColor(EmbedColor.RED);

                await ReplyAsync(embed : embed.Build());
            }
        }
Beispiel #20
0
        public async Task Command(IGuildUser user = null, [Remainder] string reason = null)
        {
            Server server = await DatabaseQueries.GetOrCreateServerAsync(Context.Guild.Id);

            List <Praise> userPraise = await DatabaseQueries.GetAllForServerAndUserAsync <Praise>(Context.User.Id, server.ServerId);

            double lastGivenPraise = DatabaseQueries.GetLastPraiseTime(Context.User.Id, Context.Guild.Id);

            if (user == null && reason == null)
            {
                await SendBasicSuccessEmbedAsync($"You currently have `{userPraise.Count}` praise.");

                return;
            }

            if (user == null)
            {
                var curEmbed = new KaguyaEmbedBuilder
                {
                    Description = $"You currently have `{userPraise.Count}` praise."
                };

                await Context.Channel.SendEmbedAsync(curEmbed);

                return;
            }

            if (user == Context.User)
            {
                var userErrorEmbed = new KaguyaEmbedBuilder
                {
                    Description = $"You can't praise yourself!"
                };

                userErrorEmbed.SetColor(EmbedColor.RED);

                await ReplyAsync(embed : userErrorEmbed.Build());

                return;
            }

            double cooldownTime = DateTime.Now.AddHours(-server.PraiseCooldown).ToOADate();

            if (!(lastGivenPraise < cooldownTime))
            {
                var timeErrorEmbed = new KaguyaEmbedBuilder
                {
                    Description = $"Sorry, you must wait " +
                                  $"`{(DateTime.FromOADate(lastGivenPraise) - DateTime.FromOADate(cooldownTime)).Humanize()}` " +
                                  $"before giving praise again."
                };

                timeErrorEmbed.SetColor(EmbedColor.RED);

                await ReplyAsync(embed : timeErrorEmbed.Build());

                return;
            }

            if (reason == null)
            {
                reason = "No reason provided.";
            }

            var praise = new Praise
            {
                UserId    = user.Id,
                ServerId  = server.ServerId,
                GivenBy   = Context.User.Id,
                Reason    = reason,
                Server    = server,
                TimeGiven = DateTime.Now.ToOADate()
            };

            await DatabaseQueries.InsertAsync(praise);

            List <Praise> newTargetPraise = await DatabaseQueries.GetAllForServerAndUserAsync <Praise>(praise.UserId, praise.ServerId);

            int newTargetPraiseCount = newTargetPraise.Count;

            var embed = new KaguyaEmbedBuilder
            {
                Description = $"Successfully awarded `{user}` with `+1` praise.\n" +
                              $"Reason: `{reason}`",
                Footer = new EmbedFooterBuilder
                {
                    Text = $"{user.Username} now has {newTargetPraiseCount} praise. " +
                           $"You have {userPraise.Count} praise."
                }
            };

            await ReplyAsync(embed : embed.Build());
        }
Beispiel #21
0
        public async Task RedeemKey(params string[] keys)
        {
            User user = await DatabaseQueries.GetOrCreateUserAsync(Context.User.Id);

            Server server = await DatabaseQueries.GetOrCreateServerAsync(Context.Guild.Id);

            List <PremiumKey> existingPremiumKeys = await DatabaseQueries.GetAllAsync <PremiumKey>();

            foreach (string keyString in keys)
            {
                PremiumKey premiumKey = existingPremiumKeys.FirstOrDefault(x => x.Key == keyString && x.UserId == 0 && x.ServerId == 0);

                if (premiumKey == null)
                {
                    await Context.Message.DeleteAsync();

                    var embed0 = new KaguyaEmbedBuilder
                    {
                        Description = "Key does not exist or has already been redeemed.",
                        Footer      = new EmbedFooterBuilder
                        {
                            Text = $"If you need assistance, please join the server provided in {server.CommandPrefix}invite"
                        }
                    };

                    embed0.SetColor(EmbedColor.RED);

                    await ReplyAsync(embed : embed0.Build());

                    return;
                }

                IKey newKey;

                if (!string.IsNullOrEmpty(premiumKey?.Key))
                {
                    newKey = new PremiumKey
                    {
                        Key             = premiumKey.Key,
                        LengthInSeconds = premiumKey.LengthInSeconds,
                        KeyCreatorId    = premiumKey.KeyCreatorId,
                        UserId          = Context.User.Id,
                        ServerId        = Context.Guild.Id
                    };

                    await DatabaseQueries.InsertOrReplaceAsync((PremiumKey)newKey);
                }
                else
                {
                    await Context.Message.DeleteAsync();

                    throw new KaguyaSupportException("Failed to redeem your key. Please " +
                                                     "join our support server for assistance.");
                }

                TimeSpan ts = $"{newKey.LengthInSeconds}s".ParseToTimespan();

                user.TotalDaysPremium += (int)TimeSpan.FromSeconds(newKey.LengthInSeconds).TotalDays;
                int totalDaysSupported = user.TotalDaysPremium;

                double userPremiumExpiration = user.PremiumExpiration;
                if (userPremiumExpiration < DateTime.Now.ToOADate())
                {
                    userPremiumExpiration = DateTime.Now.ToOADate();
                }

                userPremiumExpiration  = DateTime.FromOADate(userPremiumExpiration).AddSeconds(premiumKey.LengthInSeconds).ToOADate();
                user.PremiumExpiration = userPremiumExpiration;

                // If the server has never been premium before, or was but it has expired,
                // we need to reset the expiration to Now + the key's length.
                if (server.PremiumExpiration < DateTime.Now.ToOADate())
                {
                    server.PremiumExpiration = DateTime.Now.AddSeconds(premiumKey.LengthInSeconds).ToOADate();
                }
                else
                {
                    server.PremiumExpiration = DateTime.FromOADate(server.PremiumExpiration)
                                               .AddSeconds(premiumKey.LengthInSeconds).ToOADate();
                }

                var embed = new KaguyaEmbedBuilder
                {
                    Description = $"Successfully redeemed `" +
                                  $"{ts.Humanize(maxUnit: TimeUnit.Day)}` of Kaguya Premium!\n" +
                                  $"This server's subscription will expire on: `{DateTime.FromOADate(server.PremiumExpiration).ToLongDateString()}`\n" +
                                  $"Your personal subscription will expire on: `{DateTime.FromOADate(userPremiumExpiration).ToLongDateString()}`\n" +
                                  $"You've supported for `{totalDaysSupported:N0}` days! " +
                                  $"That's `{ServerUptimeCalcInDays(totalDaysSupported):N2} days` of server uptime 💙",
                    Footer = new EmbedFooterBuilder
                    {
                        Text = "It may not seem like a lot, but it all adds up. Thanks for your support!"
                    }
                };

                embed.SetColor(EmbedColor.GOLD);

                await ReplyAsync(embed : embed.Build());

#if !DEBUG
                await SendEmbedToBotOwner(Context, newKey);
#endif
                await DatabaseQueries.UpdateAsync(user);

                await DatabaseQueries.UpdateAsync(server);

                await ApplyRewardsToUser(user, Context.User, premiumKey);
            }
        }
Beispiel #22
0
        public async Task Command()
        {
            // Cooldown in seconds.
            const int FISHING_COOLDOWN         = 15;
            const int FISHING_COOLDOWN_PREMIUM = 5;

            User user = await DatabaseQueries.GetOrCreateUserAsync(Context.User.Id);

            Server server = await DatabaseQueries.GetOrCreateServerAsync(Context.Guild.Id);

            if (user.Points < user.FishCost())
            {
                var baitEmbed = new KaguyaEmbedBuilder(EmbedColor.RED)
                {
                    Description = $"You do not have enough points to play the fishing game.",
                    Footer      = new EmbedFooterBuilder
                    {
                        Text = $"You need {user.FishCost()} points to play. You have {user.Points} points."
                    }
                };

                await SendEmbedAsync(baitEmbed);

                return;
            }

            bool isPremium = user.IsPremium;

            if (user.LastFished >= DateTime.Now.AddSeconds(-FISHING_COOLDOWN).ToOADate() && !isPremium ||
                user.LastFished >= DateTime.Now.AddSeconds(-FISHING_COOLDOWN_PREMIUM).ToOADate() && isPremium)
            {
                TimeSpan ts = DateTime.FromOADate(user.LastFished) - DateTime.Now.AddSeconds(-15);

                if (isPremium)
                {
                    ts -= TimeSpan.FromSeconds(10);
                }

                var errorEmbed = new KaguyaEmbedBuilder(EmbedColor.RED)
                {
                    Description = $"Please wait `{ts.Humanize(minUnit: TimeUnit.Second)}` before fishing again."
                };

                await ReplyAndDeleteAsync("", false, errorEmbed.Build(), TimeSpan.FromSeconds(3));

                return;
            }

            int value;
            var embed = new KaguyaEmbedBuilder
            {
                Description = $"🎣 | {Context.User.Mention} "
            };

            var    r      = new Random();
            double roll   = r.NextDouble();
            int    fishId = r.Next(int.MaxValue);
            int    fishExp;

            while (await DatabaseQueries.ItemExistsAsync <Fish>(x => x.FishId == fishId))
            {
                fishId = r.Next(int.MaxValue);
            }

            var bonuses = new FishHandler.FishLevelBonuses(user.FishExp);

            roll *= 1 - (bonuses.BonusLuckPercent / 100);

            if (isPremium)
            {
                roll *= 0.95;
            }

            FishType fishType = GetFishType(roll);

            switch (fishType)
            {
            case FishType.SEAWEED:
                value              = 2;
                fishExp            = 0;
                embed.Description += $"Aw man, you caught `seaweed`. Better luck next time!";
                embed.SetColor(EmbedColor.GRAY);

                break;

            case FishType.PINFISH:
                value              = 15;
                fishExp            = r.Next(1, 3);
                embed.Description += $"you caught a `pinfish`!";
                embed.SetColor(EmbedColor.GRAY);

                break;

            case FishType.SMALL_BASS:
                value              = 25;
                fishExp            = r.Next(2, 6);
                embed.Description += $"you caught a `small bass`!";
                embed.SetColor(EmbedColor.GREEN);

                break;

            case FishType.SMALL_SALMON:
                value              = 25;
                fishExp            = r.Next(2, 6);
                embed.Description += $"you caught a `small salmon`!";
                embed.SetColor(EmbedColor.GREEN);

                break;

            case FishType.CATFISH:
                value              = 75;
                fishExp            = r.Next(5, 9);
                embed.Description += $"you caught a `catfish`!";
                embed.SetColor(EmbedColor.GREEN);

                break;

            case FishType.LARGE_BASS:
                value              = 150;
                fishExp            = r.Next(7, 11);
                embed.Description += $"Wow, you caught a `large bass`!";
                embed.SetColor(EmbedColor.LIGHT_BLUE);

                break;

            case FishType.LARGE_SALMON:
                value              = 150;
                fishExp            = r.Next(7, 11);
                embed.Description += $"Wow, you caught a `large salmon`!";
                embed.SetColor(EmbedColor.LIGHT_BLUE);

                break;

            case FishType.RED_DRUM:
                value              = 200;
                fishExp            = r.Next(7, 20);
                embed.Description += $"Holy smokes, you caught a `red drum`!";
                embed.SetColor(EmbedColor.RED);

                break;

            case FishType.TRIGGERFISH:
                value              = 350;
                fishExp            = r.Next(11, 30);
                embed.Description += $"Holy smokes, you caught a `triggerfish`!";
                embed.SetColor(EmbedColor.LIGHT_PURPLE);

                break;

            case FishType.GIANT_SEA_BASS:
                value              = 500;
                fishExp            = r.Next(18, 36);
                embed.Description += $"No way, you caught a `giant sea bass`! Nice work!";
                embed.SetColor(EmbedColor.LIGHT_PURPLE);

                break;

            case FishType.SMALLTOOTH_SAWFISH:
                value              = 1000;
                fishExp            = r.Next(29, 42);
                embed.Description += $"No way, you caught a `smalltooth sawfish`! Nice work!";
                embed.SetColor(EmbedColor.LIGHT_PURPLE);

                break;

            case FishType.DEVILS_HOLE_PUPFISH:
                value              = 2500;
                fishExp            = r.Next(40, 95);
                embed.Description += $"I can't believe my eyes!! you caught a `devils hold pupfish`! You're crazy!";
                embed.SetColor(EmbedColor.VIOLET);

                break;

            case FishType.ORANTE_SLEEPER_RAY:
                value              = 5000;
                fishExp            = r.Next(75, 325);
                embed.Description += $"Hot diggity dog, you caught an `orante sleeper ray`! This is unbelievable!";
                embed.SetColor(EmbedColor.ORANGE);

                break;

            case FishType.GIANT_SQUID:
                value              = 20000;
                fishExp            = r.Next(400, 900);
                embed.Description += $"Well butter my buttcheeks and call me a biscuit, you caught the second " +
                                     $"rarest fish in the sea! It's a `giant squid`!! Congratulations!";

                embed.SetColor(EmbedColor.ORANGE);

                break;

            case FishType.BIG_KAHUNA:
                value              = 50000;
                fishExp            = r.Next(1250, 4500);
                embed.Description += $"<a:siren:429784681316220939> NO WAY! You hit the jackpot " +
                                     $"and caught the **Legendary `BIG KAHUNA`**!!!! " +
                                     $"What an incredible moment this is! <a:siren:429784681316220939>";

                embed.SetColor(EmbedColor.GOLD);

                break;

            default:
                value              = 0;
                fishExp            = 0;
                embed.Description += $"Oh no, it took your bait! Better luck next time...";
                embed.SetColor(EmbedColor.GRAY);

                break;
            }

            user.FishExp   += fishExp;
            user.Points    -= user.FishCost();
            user.LastFished = DateTime.Now.ToOADate();

            var fish = new Fish
            {
                FishId     = fishId,
                UserId     = Context.User.Id,
                ServerId   = Context.Guild.Id,
                TimeCaught = DateTime.Now.ToOADate(),
                FishType   = fishType,
                FishString = fishType.ToString(),
                Value      = value,
                Exp        = fishExp,
                Sold       = false
            };

            value = Fish.GetPayoutForFish(fish, user.FishExp);

            await DatabaseQueries.InsertAsync(fish);

            await DatabaseQueries.UpdateAsync(user);

            await KaguyaEvents.TriggerFish(new FishHandlerEventArgs(user, fish, Context)); // Triggers the fish EXP service.

            if (fishType != FishType.BAIT_STOLEN)
            {
                List <Fish> existingFish = (await DatabaseQueries.GetFishForUserMatchingTypeAsync(fishType, user.UserId)).ToList();
                int         fishCount    = existingFish.Count(x => !x.Sold);
                string      fishString   = fishType.ToString().Replace("_", " ").ToLower();

                embed.Description += $"\n\nFish ID: `{fishId}`\n" +
                                     $"Fish Value: `{value:N0}` points.\n" +
                                     $"Fishing Exp Earned: `{fishExp:N0} exp`\n" +
                                     $"Points Remaining: `{user.Points:N0} (-{user.FishCost()})`\n\n" +
                                     $"You now have `{fishCount}` `{fishString}`";
            }
            else
            {
                embed.Description += $"\nPoints Remaining: `{user.Points:N0} (-{user.FishCost()})`";
            }

            embed.Footer = new EmbedFooterBuilder
            {
                Text = $"Use the {server.CommandPrefix}myfish command to view your fishing stats!\n" +
                       $"The {server.CommandPrefix}sellfish command may be used to sell your fish."
            };

            // Fish Embed
            await ReplyAsync(embed : embed.Build());
        }
Beispiel #23
0
        public static Task Initialize()
        {
            var timer = new Timer(DURATION_MS);

            timer.AutoReset = true;
            timer.Enabled   = true;
            timer.Elapsed  += async(sender, e) =>
            {
                List <User> users = await DatabaseQueries.GetAllAsync <User>(x => x.ActiveRateLimit > 0 && x.UserId != 146092837723832320);

                foreach (User registeredUser in users)
                {
                    if (registeredUser.LastRatelimited < DateTime.Now.Add(TimeSpan.FromDays(-30)).ToOADate() &&
                        registeredUser.RateLimitWarnings > 0)
                    {
                        registeredUser.RateLimitWarnings = 0;
                        await ConsoleLogger.LogAsync($"User [ID: {registeredUser.UserId}] has had their Ratelimit Warnings reset " +
                                                     $"due to not being ratelimited for 30 days.", LogLvl.INFO);
                    }

                    // The user has been rate limited within the last 30 seconds.
                    // Don't accidentally double-rate-limit them.
                    if (registeredUser.LastRatelimited > DateTime.Now.AddSeconds(-30).ToOADate() &&
                        registeredUser.RateLimitWarnings > 0)
                    {
                        return;
                    }

                    if (registeredUser.ActiveRateLimit >= THRESHOLD_REG && !registeredUser.IsPremium ||
                        registeredUser.ActiveRateLimit >= THRESHOLD_PREMIUM && registeredUser.IsPremium)
                    {
                        registeredUser.LastRatelimited = DateTime.Now.ToOADate();
                        registeredUser.RateLimitWarnings++;
                        if (registeredUser.RateLimitWarnings > 7 && registeredUser.ActiveRateLimit > 0)
                        {
                            SocketUser socketUser = ConfigProperties.Client.GetUser(registeredUser.UserId);

                            var maxRlimitEmbed = new KaguyaEmbedBuilder(EmbedColor.RED)
                            {
                                Description = "You have exceeded your maximum allotment of ratelimit strikes, therefore " +
                                              "you will be permanently blacklisted."
                            };

                            try
                            {
                                await socketUser.SendMessageAsync(embed : maxRlimitEmbed.Build());
                            }
                            catch (HttpException)
                            {
                                await ConsoleLogger.LogAsync($"Attempted to DM user {socketUser.Id} about " +
                                                             $"acheiving the maximum allotted ratelimit strikes, " +
                                                             $"but a Discord.Net.HttpException was thrown.", LogLvl.WARN);
                            }

                            var bl = new UserBlacklist
                            {
                                UserId     = socketUser.Id,
                                Expiration = DateTime.MaxValue.ToOADate(),
                                Reason     = "Ratelimit service: Automatic permanent blacklist for surpassing " +
                                             "7 ratelimit strikes in one month.",
                                User = registeredUser
                            };

                            registeredUser.ActiveRateLimit = 0;
                            await DatabaseQueries.UpdateAsync(registeredUser);

                            await DatabaseQueries.InsertOrReplaceAsync(bl);

                            await ConsoleLogger.LogAsync(
                                $"User [Name: {socketUser.Username} | ID: {socketUser.Id} | Supporter: {registeredUser.IsPremium}] " +
                                "has been permanently blacklisted. Reason: Excessive Ratelimiting", LogLvl.WARN);

                            return;
                        }

                        SocketUser user = ConfigProperties.Client.GetUser(registeredUser.UserId);

                        if (user == null)
                        {
                            return;
                        }

                        string[] durations =
                        {
                            "60s",
                            "5m",
                            "30m",
                            "3h",
                            "12h",
                            "1d",
                            "3d"
                        };

                        List <TimeSpan> timeSpans     = durations.Select(RegexTimeParser.ParseToTimespan).ToList();
                        string          humanizedTime = timeSpans.ElementAt(registeredUser.RateLimitWarnings - 1).Humanize();

                        var tempBlacklist = new UserBlacklist
                        {
                            UserId     = user.Id,
                            Expiration = (DateTime.Now + timeSpans.ElementAt(registeredUser.RateLimitWarnings - 1)).ToOADate(),
                            Reason     = $"Ratelimit service: Automatic {timeSpans.ElementAt(registeredUser.RateLimitWarnings - 1)} " +
                                         $"temporary blacklist for surpassing a ratelimit strike",
                            User = registeredUser
                        };

                        await DatabaseQueries.InsertOrReplaceAsync(tempBlacklist);

                        var curRlimEmbed = new KaguyaEmbedBuilder
                        {
                            Description = $"You have been ratelimited for `{humanizedTime}`\n\n" +
                                          $"For this time, you may not use any commands or earn experience points.",
                            Footer = new EmbedFooterBuilder
                            {
                                Text = $"You have {registeredUser.RateLimitWarnings} ratelimit strikes. Receiving " +
                                       $"{durations.Length - registeredUser.RateLimitWarnings} more strikes will result " +
                                       $"in a permanent blacklist."
                            }
                        };

                        curRlimEmbed.SetColor(EmbedColor.RED);

                        bool dm = true;

                        try
                        {
                            await user.SendMessageAsync(embed : curRlimEmbed.Build());
                        }
                        catch (Exception)
                        {
                            dm = false;
                        }

                        await ConsoleLogger.LogAsync($"User [Name: {user?.Username} | ID: {user?.Id} | Supporter: {registeredUser.IsPremium}] " +
                                                     $"has been ratelimited. Duration: {humanizedTime} Direct Message Sent: {dm}", LogLvl.INFO);
                    }

                    if (registeredUser.ActiveRateLimit > 0)
                    {
                        registeredUser.ActiveRateLimit = 0;
                        await DatabaseQueries.UpdateAsync(registeredUser);
                    }
                }
            };

            return(Task.CompletedTask);
        }
Beispiel #24
0
        public async Task DeleteRoles()
        {
            KaguyaEmbedBuilder embed;

            var confirmEmbed = new KaguyaEmbedBuilder
            {
                Description = $"{Context.User.Username}, are you sure you " +
                              $"wish to preform this action?"
            };

            confirmEmbed.SetColor(EmbedColor.VIOLET);

            var timeoutEmbed = new KaguyaEmbedBuilder
            {
                Description = "Timeout reached - reactions disabled. No action will be taken."
            };

            timeoutEmbed.SetColor(EmbedColor.RED);

            await InlineReactionReplyAsync(new ReactionCallbackData("", confirmEmbed.Build(), true, true, TimeSpan.FromSeconds(60))
                                           .WithCallback(GlobalProperties.CheckMarkEmoji(), async(c, r) =>
            {
                int i = 0;
                int j = 0;
                string failString = "";

                foreach (SocketRole role in Context.Guild.Roles.Where(x =>
                                                                      !x.Members.Any() && x.Name.ToLower() != "kaguya-mute"))
                {
                    try
                    {
                        await role.DeleteAsync();
                        i++;
                    }
                    catch (Exception)
                    {
                        j++;
                    }
                }

                if (j != 0)
                {
                    failString = $"However, I failed to delete `{j}` roles. These roles are likely " +
                                 "managed by integrations, therefore they cannot be deleted. \n" +
                                 "*Hint: Is my role at the top of the hierarchy?*";
                }

                if (i == 0 && j == 0)
                {
                    embed = new KaguyaEmbedBuilder
                    {
                        Description = "Actually, there weren't any roles to delete - no action has been taken."
                    };

                    await ReplyAsync(embed: embed.Build());
                }

                else
                {
                    embed = new KaguyaEmbedBuilder
                    {
                        Description = $"Successfully deleted `{i}` roles. {failString}"
                    };

                    await ReplyAsync(embed: embed.Build());
                }
            })
                                           .WithCallback(new Emoji("⛔"), async(c, r) =>
            {
                embed = new KaguyaEmbedBuilder
                {
                    Description = $"Okay, no action will be taken."
                };

                await ReplyAsync(embed: embed.Build());
            }));
        }
Beispiel #25
0
        public async Task Command(int bet)
        {
            if (bet < 5)
            {
                throw new ArgumentOutOfRangeException(nameof(bet), "Your bet must be at least `5` points.");
            }

            User user = await DatabaseQueries.GetOrCreateUserAsync(Context.User.Id);

            if (bet > MAX_BET && !user.IsPremium)
            {
                await SendBasicErrorEmbedAsync($"Sorry, but only premium subscribers may bet more than " +
                                               $"`{MAX_BET:N0}` points.");

                return;
            }

            if (bet > MAX_PREMIUM_BET && user.IsPremium)
            {
                await SendBasicErrorEmbedAsync($"Sorry, but you may not bet more than " +
                                               $"`{MAX_PREMIUM_BET:N0}` points.");

                return;
            }

            if (user.Points < bet)
            {
                await SendBasicErrorEmbedAsync($"You don't have enough points to perform this action.\n" +
                                               $"Current points: `{user.Points:N0}` points.");

                return;
            }

            var r    = new Random();
            int roll = r.Next(101);

            if (roll > 100)
            {
                roll = 100;
            }

            if (user.IsPremium)
            {
                roll = (int)(roll * 1.05);
            }

            RollResult rollResult = GetRollResult(roll);
            int        payout     = GetPayout(rollResult, bet);
            bool       winner;

            var embed = new KaguyaEmbedBuilder
            {
                Title = $"Kaguya Betting: "
            };

            switch (rollResult)
            {
            case RollResult.LOSS:
                winner            = false;
                embed.Title      += "Loser";
                embed.Description = $"{Context.User.Mention} rolled `{roll}` and lost their bet of " +
                                    $"`{bet:N0}` points! Better luck next time!";

                break;

            default:
                winner            = true;
                embed.Title      += "Winner!";
                embed.Description = $"{Context.User.Mention} rolled `{roll}` and won " +
                                    $"`{payout:N0}` points, **`{GetMultiplier(rollResult)}x`** their bet!";

                break;
            }

            user = user.AddPoints((uint)payout);
            var gh = new GambleHistory
            {
                UserId = user.UserId,
                Action = GambleAction.BET_ROLL,
                Bet    = bet,
                Payout = payout,
                Roll   = roll,
                Time   = DateTime.Now.ToOADate(),
                Winner = winner
            };

            await DatabaseQueries.InsertAsync(gh);

            await DatabaseQueries.UpdateAsync(user);

            List <GambleHistory> allGh = await DatabaseQueries.GetAllForUserAsync <GambleHistory>(user.UserId);

            var footer = new EmbedFooterBuilder
            {
                Text = $"New points balance: {user.Points:N0} | Lifetime Bets: {allGh.Count:N0}"
            };

            embed.Footer = footer;
            embed.SetColor(GetEmbedColorBasedOnRoll(rollResult));

            await SendEmbedAsync(embed);
        }
Beispiel #26
0
        public async Task OsuRecentCommand([Remainder] string player = null)
        {
            var       embed  = new KaguyaEmbedBuilder();
            OsuClient client = OsuBase.Client;

            User user = await DatabaseQueries.GetOrCreateUserAsync(Context.User.Id);

            Server server = await DatabaseQueries.GetOrCreateServerAsync(Context.Guild.Id);

            OsuSharp.User osuPlayer = player == null
                ? await client.GetUserByUserIdAsync(user.OsuId, GameMode.Standard)
                : await client.GetUserByUsernameAsync(player, GameMode.Standard);

            // Maybe the user provided an ID to search for.
            if (osuPlayer == null && long.TryParse(player, out long id))
            {
                osuPlayer = await client.GetUserByUserIdAsync(id, GameMode.Standard);
            }

            // If it's still null, they don't exist.
            if (osuPlayer == null)
            {
                embed.Description = $"{Context.User.Mention} Failed to acquire username! " +
                                    "Please specify a player or set your osu! username with " +
                                    $"`{server.CommandPrefix}osuset`!";

                await ReplyAsync(embed : embed.Build());

                return;
            }

            Score osuRecent = player == null
                ? (await client.GetUserRecentsByUserIdAsync(user.OsuId, GameMode.Standard, 1)).FirstOrDefault()
                : (await client.GetUserRecentsByUsernameAsync(player, GameMode.Standard, 1)).FirstOrDefault();

            if (osuRecent == null)
            {
                embed.WithAuthor(author =>
                {
                    author
                    .WithName($"{osuPlayer.Username} doesn't have any recent plays.")
                    .WithIconUrl("https://a.ppy.sh/" + osuPlayer.UserId);
                });

                await SendEmbedAsync(embed);

                return;
            }

            // Reset the embed as its values were changed in the above code.
            embed = new KaguyaEmbedBuilder();

            Beatmap beatmap = await osuRecent.GetBeatmapAsync();

            //Author
            embed.WithAuthor(author =>
            {
                author
                .WithName($"Recent: {osuPlayer.Username} | {beatmap.Title} [{beatmap.Difficulty}] by {beatmap.Author}")
                .WithIconUrl("https://a.ppy.sh/" + osuPlayer.UserId);
            });

            //Description
            PerformanceData scoredPerformance = await OppaiClient.GetPPAsync(osuRecent.BeatmapId, osuRecent.Mods, (float)osuRecent.Accuracy, osuRecent.MaxCombo);

            PerformanceData wouldbePerformance = await OppaiClient.GetPPAsync(osuRecent.BeatmapId, osuRecent.Mods, (float)osuRecent.Accuracy, beatmap.MaxCombo);

            string beatmapLink    = $"https://osu.ppy.sh/b/{beatmap.BeatmapId}";
            string discussionLink = $"https://osu.ppy.sh/beatmapsets/{beatmap.BeatmapsetId}/discussion";
            string downloadLink   = $"https://osu.ppy.sh/beatmapsets/{beatmap.BeatmapsetId}/download";
            var    descSb         = new StringBuilder();

            // Links (Row 0)
            descSb.AppendLine($"**Links:** [Listing]({beatmapLink}) ▸ [Modding]({discussionLink}) ▸ [Download]({downloadLink})");
            descSb.AppendLine();
            // Row 1
            descSb.AppendLine($@"• {OsuBase.OsuGradeEmote(osuRecent.Rank)} {osuRecent.Mods.ToModeString(OsuBase.Client)
                                                                                             .Replace("No Mode", "No Mod")
                                                                                             .Replace("DTNC", "NC")} | {scoredPerformance.Stars:N2}★");
            // Row 2
            descSb.Append($"• **Combo:** {osuRecent.MaxCombo:N0}x / {beatmap.MaxCombo:N0}x ▸ ");
            descSb.AppendLine($"**Accuracy:** {osuRecent.Accuracy:N2}% ▸ **Score:** {osuRecent.TotalScore:N0}");
            // Row 3
            descSb.Append($"• {osuRecent.Count300:N0} / {osuRecent.Count100:N0} / {osuRecent.Count50:N0} / {osuRecent.Miss:N0} ▸ ");
            descSb.AppendLine($"**BPM:** {beatmap.Bpm:N0} ▸ **Length:** {beatmap.TotalLength.TotalMinutes:00}:{beatmap.TotalLength.Seconds:00}");
            // Row 4
            descSb.Append($"• **CS:** {GetStatNumAsString(scoredPerformance.Cs)} ▸ **AR:** {GetStatNumAsString(scoredPerformance.Ar)} ▸ ");
            descSb.AppendLine($"**OD:** {GetStatNumAsString(scoredPerformance.Od)} ▸ **HP:** {GetStatNumAsString(scoredPerformance.Hp)}");
            // Row 5
            descSb.AppendLine($"• **Performance:** {scoredPerformance.Pp:N2}pp ({wouldbePerformance.Pp:N2}pp for {osuRecent.Accuracy:N2}% FC)");

            if (osuRecent.MaxCombo == beatmap.MaxCombo)
            {
                embed.SetColor(EmbedColor.GOLD);
                descSb.Append("Full combo!");
            }
            embed.Description = descSb.ToString();

            //Footer
            TimeSpan difference   = DateTime.UtcNow - osuRecent.Date.Value.DateTime;
            string   humanizedDif = difference.Humanize(2, minUnit: TimeUnit.Second);

            embed.WithFooter($"{osuPlayer.Username} performed this play {humanizedDif} ago.");

            await ReplyAsync(embed : embed.Build());
        }
Beispiel #27
0
        public async Task Command(IGuildUser guildUser = null, [Remainder] string reason = null)
        {
            User user = await DatabaseQueries.GetOrCreateUserAsync(Context.User.Id);

            List <Rep> rep = await DatabaseQueries.GetAllForUserAsync <Rep>(user.UserId);

            int repCount = rep.Count;

            if (guildUser == null)
            {
                var curRepEmbed = new KaguyaEmbedBuilder
                {
                    Description = $"You have `{repCount}` rep."
                };

                await ReplyAsync(embed : curRepEmbed.Build());

                return;
            }

            if (!user.CanGiveRep)
            {
                var denyEmbed = new KaguyaEmbedBuilder
                {
                    Description = $"{Context.User.Mention} you must wait " +
                                  $"`{(DateTime.FromOADate(user.LastGivenRep) - DateTime.Now.AddHours(-24)).Humanize()}` " +
                                  $"before giving rep again."
                };

                denyEmbed.SetColor(EmbedColor.RED);

                await ReplyAsync(embed : denyEmbed.Build());

                return;
            }

            if (guildUser == Context.User)
            {
                var invalidUserEmbed = new KaguyaEmbedBuilder
                {
                    Description = $"You may not rep yourself!"
                };

                invalidUserEmbed.SetColor(EmbedColor.RED);

                await ReplyAsync(embed : invalidUserEmbed.Build());

                return;
            }

            if (guildUser.IsBot)
            {
                var invalidUserEmbed = new KaguyaEmbedBuilder
                {
                    Description = $"Sorry, rep can't be given to bots."
                };

                invalidUserEmbed.SetColor(EmbedColor.RED);

                await ReplyAsync(embed : invalidUserEmbed.Build());

                return;
            }

            User target = await DatabaseQueries.GetOrCreateUserAsync(guildUser.Id);

            if (target.IsBlacklisted)
            {
                var invalidUserEmbed = new KaguyaEmbedBuilder
                {
                    Description = $"Sorry, rep can't be given to blacklisted users. " +
                                  $"This person may appeal their blacklist by filling " +
                                  $"out [this form](https://forms.gle/bnLFWbNiEyF4uE9E9)"
                };

                invalidUserEmbed.SetColor(EmbedColor.RED);

                await ReplyAsync(embed : invalidUserEmbed.Build());

                return;
            }

            var newTargetRep = new Rep
            {
                UserId    = guildUser.Id,
                GivenBy   = user.UserId,
                TimeGiven = DateTime.Now.ToOADate(),
                Reason    = reason ?? "No reason provided."
            };

            await DatabaseQueries.InsertAsync(newTargetRep);

            user.LastGivenRep = DateTime.Now.ToOADate();

            await DatabaseQueries.UpdateAsync(user);

            List <Rep> targetRepList = await DatabaseQueries.GetAllForUserAsync <Rep>(target.UserId);

            var embed = new KaguyaEmbedBuilder
            {
                Description = $"Successfully added one rep to `{guildUser}`! \nYou may give rep again in `24 hours`.",
                Footer      = new EmbedFooterBuilder
                {
                    Text = $"{guildUser.Username} now has {targetRepList.Count} rep. You have {repCount} rep."
                }
            };

            embed.SetColor(EmbedColor.GOLD);

            await ReplyAsync(embed : embed.Build());
        }