Example #1
0
        public async Task SetExperienceAsync(IContext e)
        {
            var cache = e.GetService <ICacheClient>();

            if (!e.GetArgumentPack().Take(out string userName))
            {
                return;
            }

            var user = await e.GetGuild().FindUserAsync(userName);

            e.GetArgumentPack().Take(out int amount);
            var context = e.GetService <MikiDbContext>();

            var localUser = await LocalExperience.GetAsync(
                context,
                e.GetGuild().Id,
                user.Id);

            if (localUser == null)
            {
                localUser = await LocalExperience.CreateAsync(
                    context,
                    e.GetGuild().Id,
                    user.Id,
                    user.Username);
            }

            localUser.Experience = amount;
            await context.SaveChangesAsync();

            await cache.UpsertAsync($"user:{e.GetGuild().Id}:{e.GetAuthor().Id}:exp", localUser.Experience);

            e.GetChannel().QueueMessage(e, null, ":ok_hand:");
        }
Example #2
0
        public async Task SetExp(EventContext e)
        {
            ArgObject arg = e.Arguments.FirstOrDefault();

            IDiscordUser user = await arg.GetUserAsync(e.Guild);

            arg = arg.Next();

            int amount = arg?.AsInt() ?? 0;

            using (var context = new MikiContext())
            {
                LocalExperience u = await LocalExperience.GetAsync(context, e.Guild.Id.ToDbLong(), user);

                if (u == null)
                {
                    return;
                }
                u.Experience = amount;
                await context.SaveChangesAsync();

                await Global.RedisClient.UpsertAsync($"user:{e.Guild.Id}:{e.Author.Id}:exp", u.Experience);

                e.Channel.QueueMessageAsync(":ok_hand:");
            }
        }
Example #3
0
        public async Task SetExp(EventContext e)
        {
            var cache = (ICacheClient)e.Services.GetService(typeof(ICacheClient));

            if (!e.Arguments.Take(out string userName))
            {
                return;
            }

            IDiscordUser user = await DiscordExtensions.GetUserAsync(userName, e.Guild);

            e.Arguments.Take(out int amount);

            using (var context = new MikiContext())
            {
                LocalExperience u = await LocalExperience.GetAsync(context, e.Guild.Id.ToDbLong(), user.Id.ToDbLong(), user.Username);

                if (u == null)
                {
                    return;
                }
                u.Experience = amount;
                await context.SaveChangesAsync();

                await cache.UpsertAsync($"user:{e.Guild.Id}:{e.Author.Id}:exp", u.Experience);

                e.Channel.QueueMessage(":ok_hand:");
            }
        }
Example #4
0
        private async Task <LocalExperience> GetOrCreateExperienceProfileAsync(
            DbContext ctx, IDiscordGuildUser user)
        {
            LocalExperience newProfile = await LocalExperience.GetAsync(ctx, user.GuildId, user.Id)
                                         .ConfigureAwait(false);

            if (newProfile == null)
            {
                return(await LocalExperience.CreateAsync(ctx, user.GuildId, user.Id, user.Username)
                       .ConfigureAwait(false));
            }

            return(newProfile);
        }
Example #5
0
        public async Task SetExp(EventContext e)
        {
            using (var context = new MikiContext())
            {
                LocalExperience u = await LocalExperience.GetAsync(context, e.Guild.Id.ToDbLong(), e.message.MentionedUserIds.First().ToDbLong());

                if (u == null)
                {
                    return;
                }
                u.Experience = int.Parse(e.arguments.Split(' ')[1]);
                await context.SaveChangesAsync();

                await Global.redisClient.AddAsync($"user:{e.Guild.Id}:{e.Author.Id}:exp", new RealtimeExperienceObject()
                {
                    LastExperienceTime = DateTime.MinValue,
                    Experience         = u.Experience
                });

                e.Channel.QueueMessageAsync(":ok_hand:");
            }
        }
Example #6
0
        public async Task CheckAsync(IDiscordMessage e)
        {
            if (e.Author.IsBot)
            {
                return;
            }

            if (isSyncing)
            {
                return;
            }

            try
            {
                if (await e.GetChannelAsync() is IDiscordGuildChannel channel)
                {
                    string key = GetContextKey(channel.GuildId, e.Author.Id);

                    if (lastTimeExpGranted.GetOrAdd(e.Author.Id, DateTime.Now).AddMinutes(1) < DateTime.Now)
                    {
                        int currentExp = 0;
                        if (!await Global.RedisClient.ExistsAsync(key))
                        {
                            using (var context = new MikiContext())
                            {
                                LocalExperience user = await LocalExperience.GetAsync(
                                    context,
                                    (long)channel.GuildId,
                                    e.Author
                                    );

                                await Global.RedisClient.AddAsync(key, user.Experience);

                                currentExp = user.Experience;
                            }
                        }
                        else
                        {
                            currentExp = await Global.RedisClient.GetAsync <int>(key);
                        }

                        var bonusExp = MikiRandom.Next(1, 4);
                        currentExp += bonusExp;

                        if (!experienceQueue.ContainsKey(e.Author.Id))
                        {
                            var expObject = new ExperienceAdded()
                            {
                                UserId     = e.Author.Id.ToDbLong(),
                                GuildId    = channel.GuildId.ToDbLong(),
                                Experience = bonusExp,
                                Name       = e.Author.Username,
                            };

                            experienceQueue.AddOrUpdate(e.Author.Id, expObject, (u, eo) =>
                            {
                                eo.Experience += expObject.Experience;
                                return(eo);
                            });
                        }
                        else
                        {
                            experienceQueue[e.Author.Id].Experience += bonusExp;
                        }

                        int level = User.CalculateLevel(currentExp);

                        if (User.CalculateLevel(currentExp - bonusExp) != level)
                        {
                            await LevelUpLocalAsync(e, level);
                        }

                        lastTimeExpGranted.AddOrUpdate(e.Author.Id, DateTime.Now, (x, d) => DateTime.Now);

                        await Global.RedisClient.AddAsync(key, currentExp);
                    }
                }

                if (DateTime.Now >= lastDbSync + new TimeSpan(0, 1, 0))
                {
                    isSyncing = true;
                    Log.Message($"Applying Experience for {experienceQueue.Count} users");
                    lastDbSync = DateTime.Now;

                    try
                    {
                        await UpdateGlobalDatabase();
                        await UpdateLocalDatabase();
                        await UpdateGuildDatabase();
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex.Message + "\n" + ex.StackTrace);
                    }
                    finally
                    {
                        experienceQueue.Clear();
                        isSyncing = false;
                    }
                    Log.Message($"Done Applying!");
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex.ToString());
            }
        }
Example #7
0
        public async Task IAmAsync(EventContext e)
        {
            using (var context = new MikiContext())
            {
                string roleName = e.Arguments.ToString();

                List <IDiscordRole> roles = await GetRolesByName(e.Guild, roleName);

                IDiscordRole role = null;

                if (roles.Count > 1)
                {
                    List <LevelRole> levelRoles = await context.LevelRoles.Where(x => x.GuildId == (long)e.Guild.Id).ToListAsync();

                    if (levelRoles.Where(x => x.Role.Name.ToLower() == roleName.ToLower()).Count() > 1)
                    {
                        e.ErrorEmbed("two roles configured have the same name.")
                        .ToEmbed().QueueToChannel(e.Channel);
                        return;
                    }
                    else
                    {
                        role = levelRoles.Where(x => x.Role.Name.ToLower() == roleName.ToLower()).FirstOrDefault().Role;
                    }
                }
                else
                {
                    role = roles.FirstOrDefault();
                }

                if (role == null)
                {
                    e.ErrorEmbedResource("error_role_null")
                    .ToEmbed().QueueToChannel(e.Channel);
                    return;
                }

                IDiscordGuildUser author = await e.Guild.GetUserAsync(e.Author.Id);

                if (author.RoleIds.Contains(role.Id))
                {
                    e.ErrorEmbed(e.GetResource("error_role_already_given"))
                    .ToEmbed().QueueToChannel(e.Channel);
                    return;
                }

                LevelRole newRole = await context.LevelRoles.FindAsync(e.Guild.Id.ToDbLong(), role.Id.ToDbLong());

                User user = (await context.Users.FindAsync(e.Author.Id.ToDbLong()));

                IDiscordGuildUser discordUser = await e.Guild.GetUserAsync(user.Id.FromDbLong());

                LocalExperience localUser = await LocalExperience.GetAsync(context, e.Guild.Id.ToDbLong(), discordUser);

                if (!newRole?.Optable ?? false)
                {
                    await e.ErrorEmbed(e.GetResource("error_role_forbidden"))
                    .ToEmbed().SendToChannel(e.Channel);

                    return;
                }

                int level = User.CalculateLevel(localUser.Experience);

                if (newRole.RequiredLevel > level)
                {
                    await e.ErrorEmbed(e.GetResource("error_role_level_low", newRole.RequiredLevel - level))
                    .ToEmbed().SendToChannel(e.Channel);

                    return;
                }

                if (newRole.RequiredRole != 0 && !discordUser.RoleIds.Contains(newRole.RequiredRole.FromDbLong()))
                {
                    await e.ErrorEmbed(
                        e.GetResource(
                            "error_role_required",
                            $"**{(await e.Guild.GetRoleAsync(newRole.RequiredRole.FromDbLong())).Name}**"
                            )).ToEmbed().SendToChannel(e.Channel);

                    return;
                }

                if (newRole.Price > 0)
                {
                    if (user.Currency >= newRole.Price)
                    {
                        await e.Channel.SendMessageAsync($"Getting this role costs you {newRole.Price} mekos! type `yes` to proceed.");

                        IDiscordMessage m = await e.EventSystem.GetCommandHandler <MessageListener>().WaitForNextMessage(e.CreateSession());

                        if (m.Content.ToLower()[0] == 'y')
                        {
                            await user.AddCurrencyAsync(-newRole.Price);

                            await context.SaveChangesAsync();
                        }
                        else
                        {
                            await e.ErrorEmbed("Purchase Cancelled")
                            .ToEmbed().SendToChannel(e.Channel);

                            return;
                        }
                    }
                    else
                    {
                        await e.ErrorEmbed(e.GetResource("user_error_insufficient_mekos"))
                        .ToEmbed().SendToChannel(e.Channel);

                        return;
                    }
                }

                await author.AddRoleAsync(newRole.Role);

                Utils.Embed.SetTitle("I AM")
                .SetColor(128, 255, 128)
                .SetDescription($"You're a(n) {role.Name} now!")
                .ToEmbed().QueueToChannel(e.Channel);
            }
        }
Example #8
0
        public async Task ProfileAsync(EventContext e)
        {
            Stopwatch sw = new Stopwatch();

            sw.Start();

            using (var context = new MikiContext())
            {
                long  id  = 0;
                ulong uid = 0;

                var arg = e.Arguments.FirstOrDefault();

                if (arg != null)
                {
                    uid = (await arg.GetUserAsync(e.Guild)).Id;
                    id  = uid.ToDbLong();
                }
                else
                {
                    uid = e.message.Author.Id;
                    id  = uid.ToDbLong();
                }

                IDiscordGuildUser discordUser = await e.Guild.GetUserAsync(uid);

                User account = await User.GetAsync(context, discordUser);

                string icon = "";

                if (await account.IsDonatorAsync(context))
                {
                    icon = "https://cdn.discordapp.com/emojis/421969679561785354.png";
                }

                if (account != null)
                {
                    EmbedBuilder embed = Utils.Embed
                                         .SetDescription(account.Title)
                                         .SetAuthor(e.GetResource("miki_global_profile_user_header", account.Name), icon, "https://patreon.com/mikibot")
                                         .SetThumbnail(discordUser.GetAvatarUrl());

                    long serverid = e.Guild.Id.ToDbLong();

                    LocalExperience localExp = await LocalExperience.GetAsync(context, e.Guild.Id.ToDbLong(), discordUser);

                    if (localExp == null)
                    {
                        localExp = await LocalExperience.CreateAsync(context, serverid, discordUser);
                    }

                    int rank = await localExp.GetRank(context);

                    int localLevel  = User.CalculateLevel(localExp.Experience);
                    int maxLocalExp = User.CalculateLevelExperience(localLevel);
                    int minLocalExp = User.CalculateLevelExperience(localLevel - 1);

                    EmojiBar expBar = new EmojiBar(maxLocalExp - minLocalExp, onBarSet, offBarSet, 6);

                    string infoValue = new MessageBuilder()
                                       .AppendText(e.GetResource("miki_module_accounts_information_level", localLevel, localExp.Experience, maxLocalExp))
                                       .AppendText(await expBar.Print(localExp.Experience - minLocalExp, (IDiscordGuildChannel)e.Channel))
                                       .AppendText(e.GetResource("miki_module_accounts_information_rank", rank))
                                       .AppendText("Reputation: " + account.Reputation, MessageFormatting.Plain, false)
                                       .Build();

                    embed.AddInlineField(e.GetResource("miki_generic_information"), infoValue);

                    int globalLevel  = User.CalculateLevel(account.Total_Experience);
                    int maxGlobalExp = User.CalculateLevelExperience(globalLevel);
                    int minGlobalExp = User.CalculateLevelExperience(globalLevel - 1);

                    int globalRank = await account.GetGlobalRankAsync();

                    EmojiBar globalExpBar = new EmojiBar(maxGlobalExp - minGlobalExp, onBarSet, offBarSet, 6);

                    string globalInfoValue = new MessageBuilder()
                                             .AppendText(e.GetResource("miki_module_accounts_information_level", globalLevel, account.Total_Experience, maxGlobalExp))
                                             .AppendText(
                        await globalExpBar.Print(account.Total_Experience - minGlobalExp, e.Channel as IDiscordGuildChannel)
                        )
                                             .AppendText(e.GetResource("miki_module_accounts_information_rank", globalRank), MessageFormatting.Plain, false)
                                             .Build();

                    embed.AddInlineField(e.GetResource("miki_generic_global_information"), globalInfoValue);
                    embed.AddInlineField(e.GetResource("miki_generic_mekos"), account.Currency + "<:mekos:421972155484471296>");

                    List <UserMarriedTo> Marriages = await Marriage.GetMarriagesAsync(context, id);

                    Marriages.RemoveAll(x => x.Marriage.IsProposing);

                    List <string> users = new List <string>();

                    int maxCount = Marriages?.Count ?? 0;

                    for (int i = 0; i < maxCount; i++)
                    {
                        users.Add(await User.GetNameAsync(context, Marriages[i].GetOther(id)));
                    }

                    if (Marriages?.Count > 0)
                    {
                        List <string> MarriageStrings = new List <string>();

                        for (int i = 0; i < maxCount; i++)
                        {
                            if (Marriages[i].GetOther(id) != 0)
                            {
                                MarriageStrings.Add($"💕 {users[i]} (_{Marriages[i].Marriage.TimeOfMarriage.ToShortDateString()}_)");
                            }
                        }

                        string marriageText = string.Join("\n", MarriageStrings);
                        if (string.IsNullOrEmpty(marriageText))
                        {
                            marriageText = e.GetResource("miki_placeholder_null");
                        }

                        embed.AddInlineField(
                            e.GetResource("miki_module_accounts_profile_marriedto"),
                            marriageText);
                    }

                    Random r = new Random((int)id - 3);
                    Color  c = new Color((float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble());

                    embed.SetColor(c);

                    CommandUsage favouriteCommand = await context.CommandUsages
                                                    .OrderByDescending(x => x.Amount)
                                                    .FirstOrDefaultAsync(x => x.UserId == id);

                    string favCommand = $"{favouriteCommand?.Name ?? e.GetResource("miki_placeholder_null")} ({ favouriteCommand?.Amount ?? 0 })";

                    embed.AddInlineField(e.GetResource("miki_module_accounts_profile_favourite_command"),
                                         favCommand);

                    List <Achievement> allAchievements = await context.Achievements.Where(x => x.Id == id).ToListAsync();

                    string achievements = e.GetResource("miki_placeholder_null");

                    if (allAchievements != null)
                    {
                        if (allAchievements.Count > 0)
                        {
                            achievements = AchievementManager.Instance.PrintAchievements(allAchievements);
                        }
                    }

                    embed.AddInlineField(
                        e.GetResource("miki_generic_achievements"),
                        achievements);

                    embed.SetFooter(
                        e.GetResource("miki_module_accounts_profile_footer", account.DateCreated.ToShortDateString(),
                                      sw.ElapsedMilliseconds), "");

                    sw.Stop();

                    embed.ToEmbed().QueueToChannel(e.Channel);
                }
                else
                {
                    e.ErrorEmbed(e.GetResource("error_account_null"))
                    .ToEmbed().QueueToChannel(e.Channel);
                }
            }
        }
Example #9
0
        public async Task IAmAsync(IContext e)
        {
            var context            = e.GetService <MikiDbContext>();
            var userService        = e.GetService <IUserService>();
            var transactionService = e.GetService <ITransactionService>();
            var locale             = e.GetLocale();

            string roleName = e.GetArgumentPack().Pack.TakeAll();

            List <IDiscordRole> roles = await GetRolesByNameAsync(e.GetGuild(), roleName);

            IDiscordRole role;

            // checking if the role has a duplicate name.
            if (roles.Count > 1)
            {
                var roleIds = roles.Select(x => (long)x.Id);
                List <LevelRole> levelRoles = await context.LevelRoles
                                              .Where(x => roleIds.Contains(x.RoleId))
                                              .ToListAsync();

                if (!levelRoles.Any())
                {
                    return;
                }

                if (levelRoles.Count > 1)
                {
                    await e.ErrorEmbed("two roles configured have the same name.")
                    .ToEmbed().QueueAsync(e, e.GetChannel());

                    return;
                }

                role = roles.FirstOrDefault(x => levelRoles.First().RoleId == (long)x.Id);
            }
            else
            {
                role = roles.FirstOrDefault();
            }

            if (role == null)
            {
                throw new RoleNullException();
            }

            if (!(e.GetAuthor() is IDiscordGuildUser author))
            {
                throw new InvalidCastException("User was not proper Guild Member");
            }

            if (author.RoleIds.Contains(role.Id))
            {
                await e.ErrorEmbed(locale.GetString("error_role_already_given"))
                .ToEmbed()
                .QueueAsync(e, e.GetChannel());

                return;
            }

            LevelRole newRole = await context.LevelRoles.FindAsync(
                e.GetGuild().Id.ToDbLong(), role.Id.ToDbLong());

            if (newRole == null)
            {
                throw new RoleNotSetupException();
            }

            User user = await userService.GetOrCreateUserAsync(e.GetAuthor());

            var localUser = await LocalExperience.GetAsync(
                context, e.GetGuild().Id, author.Id);

            if (localUser == null)
            {
                localUser = await LocalExperience.CreateAsync(
                    context, e.GetGuild().Id, author.Id, author.Username);
            }

            if (!newRole.Optable)
            {
                await e.ErrorEmbed(e.GetLocale().GetString("error_role_forbidden"))
                .ToEmbed()
                .QueueAsync(e, e.GetChannel());

                return;
            }

            RequiredLevelValid(newRole, localUser);

            if (newRole.RequiredRole != 0 &&
                !author.RoleIds.Contains(newRole.RequiredRole.FromDbLong()))
            {
                var requiredRole = await e.GetGuild().GetRoleAsync(newRole.RequiredRole.FromDbLong());

                throw new RequiredRoleMissingException(requiredRole);
            }

            if (newRole.Price > 0)
            {
                await transactionService.CreateTransactionAsync(
                    new TransactionRequest.Builder()
                    .WithAmount(newRole.Price)
                    .WithReceiver(AppProps.Currency.BankId)
                    .WithSender(user.Id)
                    .Build());
            }

            var me = await e.GetGuild().GetSelfAsync();

            if (!await me.HasPermissionsAsync(GuildPermission.ManageRoles))
            {
                await e.ErrorEmbed(locale.GetString("permission_missing", "give roles")).ToEmbed()
                .QueueAsync(e, e.GetChannel());

                return;
            }

            int hierarchy = await me.GetHierarchyAsync();

            if (role.Position >= hierarchy)
            {
                await e.ErrorEmbed(e.GetLocale().GetString("permission_error_low", "give roles")).ToEmbed()
                .QueueAsync(e, e.GetChannel());

                return;
            }

            await author.AddRoleAsync(role);

            await new EmbedBuilder()
            .SetTitle("I AM")
            .SetColor(128, 255, 128)
            .SetDescription($"You're a(n) {role.Name} now!")
            .ToEmbed()
            .QueueAsync(e, e.GetChannel());
        }
Example #10
0
            public async Task ProfileAsync(IContext e)
            {
                var args   = e.GetArgumentPack();
                var locale = e.GetLocale();

                var context             = e.GetService <MikiDbContext>();
                var userService         = e.GetService <IUserService>();
                var leaderboardsService = e.GetService <LeaderboardsService>();

                var guild = e.GetGuild();
                IDiscordGuildUser self = null;

                if (guild != null)
                {
                    self = await guild.GetSelfAsync();
                }

                var discordUser = args.Take(out string arg)
                    ? await e.GetGuild().FindUserAsync(arg)
                    : e.GetAuthor();

                var account = await userService.GetOrCreateUserAsync(discordUser);

                var embed = new EmbedBuilder()
                            .SetDescription(account.Title)
                            .SetAuthor(
                    locale.GetString("miki_global_profile_user_header", discordUser.Username),
                    await GetProfileIconAsync(userService, (long)discordUser.Id),
                    "https://patreon.com/mikibot")
                            .SetThumbnail(discordUser.GetAvatarUrl());

                var infoValueBuilder = new MessageBuilder();

                if (e.GetGuild() != null)
                {
                    var localExp = await LocalExperience.GetAsync(
                        context,
                        e.GetGuild().Id,
                        discordUser.Id);

                    if (localExp == null)
                    {
                        localExp = await LocalExperience.CreateAsync(
                            context,
                            e.GetGuild().Id,
                            discordUser.Id,
                            discordUser.Username);
                    }

                    var rank = await leaderboardsService.GetLocalRankAsync(
                        (long)e.GetGuild().Id, x => x.Experience > localExp.Experience);

                    var localLevel  = User.CalculateLevel(localExp.Experience);
                    var maxLocalExp = User.CalculateLevelExperience(localLevel);
                    var minLocalExp = User.CalculateLevelExperience(localLevel - 1);

                    var expBar = new EmojiBar(maxLocalExp - minLocalExp, onBarSet, offBarSet, 6);
                    infoValueBuilder.AppendText(e.GetLocale().GetString(
                                                    "miki_module_accounts_information_level",
                                                    localLevel,
                                                    localExp.Experience.ToString("N0"),
                                                    maxLocalExp.ToString("N0")));

                    if (self == null ||
                        await self.HasPermissionsAsync(GuildPermission.UseExternalEmojis))
                    {
                        infoValueBuilder.AppendText(
                            expBar.Print(localExp.Experience - minLocalExp));
                    }

                    infoValueBuilder.AppendText(locale.GetString(
                                                    "miki_module_accounts_information_rank",
                                                    rank.ToString("N0")));
                }

                infoValueBuilder.AppendText(
                    $"Reputation: {account.Reputation:N0}",
                    newLine: false);

                embed.AddInlineField(locale.GetString("miki_generic_information"),
                                     infoValueBuilder.Build());

                var globalLevel  = User.CalculateLevel(account.Total_Experience);
                var maxGlobalExp = User.CalculateLevelExperience(globalLevel);
                var minGlobalExp = User.CalculateLevelExperience(globalLevel - 1);

                var globalRank = await leaderboardsService.GetGlobalRankAsync((long)discordUser.Id);

                var globalExpBar = new EmojiBar(
                    maxGlobalExp - minGlobalExp, onBarSet, offBarSet, 6);

                var globalInfoBuilder = new MessageBuilder()
                                        .AppendText(locale.GetString(
                                                        "miki_module_accounts_information_level",
                                                        globalLevel.ToString("N0"),
                                                        account.Total_Experience.ToString("N0"),
                                                        maxGlobalExp.ToString("N0")));

                if (self == null || await self.HasPermissionsAsync(GuildPermission.UseExternalEmojis))
                {
                    globalInfoBuilder.AppendText(
                        globalExpBar.Print(maxGlobalExp - minGlobalExp));
                }

                var globalInfo = globalInfoBuilder
                                 .AppendText(
                    locale.GetString(
                        "miki_module_accounts_information_rank",
                        globalRank?.ToString("N0") ?? "We haven't calculated your rank yet!"),
                    MessageFormatting.Plain,
                    false)
                                 .Build();

                embed.AddInlineField(
                    locale.GetString("miki_generic_global_information"),
                    globalInfo);

                embed.AddInlineField(
                    locale.GetString("miki_generic_mekos"),
                    $"{account.Currency:N0} {AppProps.Emoji.Mekos}");

                var repository = e.GetService <MarriageService>();
                var marriages  =
                    (await repository.GetMarriagesAsync((long)discordUser.Id))
                    .Where(x => !x.Marriage.IsProposing)
                    .ToList();

                var users = new List <string>();

                var maxCount = marriages.Count;

                for (var i = 0; i < maxCount; i++)
                {
                    users.Add((await e.GetService <IDiscordClient>()
                               .GetUserAsync(marriages[i].GetOther(discordUser.Id))).Username);
                }

                if (marriages.Count > 0)
                {
                    List <string> marriageStrings = new List <string>();

                    for (int i = 0; i < maxCount; i++)
                    {
                        if (marriages[i].GetOther((long)discordUser.Id) == 0)
                        {
                            continue;
                        }

                        marriageStrings.Add(
                            $"💕 {users[i]} (_{marriages[i].Marriage.TimeOfMarriage.ToShortDateString()}_)");
                    }

                    string marriageText = string.Join("\n", marriageStrings);
                    if (string.IsNullOrEmpty(marriageText))
                    {
                        marriageText = locale.GetString("miki_placeholder_null");
                    }

                    embed.AddInlineField(
                        locale.GetString("miki_module_accounts_profile_marriedto"),
                        marriageText);
                }

                var random = new Random((int)(discordUser.Id - 3));

                embed.SetColor(
                    (float)random.NextDouble(),
                    (float)random.NextDouble(),
                    (float)random.NextDouble());

                List <Achievement> allAchievements = await context.Achievements
                                                     .Where(x => x.UserId == (long)discordUser.Id)
                                                     .ToListAsync();

                var achievementService = e.GetService <AchievementService>();
                var achievements       = allAchievements?.Any() ?? false
                    ? achievementService.PrintAchievements(allAchievements)
                    : locale.GetString("miki_placeholder_null");

                embed.AddInlineField(
                    locale.GetString("miki_generic_achievements"), achievements);

                await embed.ToEmbed()
                .QueueAsync(e, e.GetChannel());
            }
Example #11
0
        public async Task ProfileAsync(CommandContext e)
        {
            Stopwatch sw = new Stopwatch();

            sw.Start();

            var   context = e.GetService <MikiDbContext>();
            long  id      = 0;
            ulong uid     = 0;

            IDiscordGuildUser discordUser = null;

            MarriageRepository repository = new MarriageRepository(context);

            if (e.Arguments.Take(out string arg))
            {
                discordUser = await DiscordExtensions.GetUserAsync(arg, e.Guild);

                if (discordUser == null)
                {
                    throw new UserNullException();
                }

                uid = discordUser.Id;
                id  = uid.ToDbLong();
            }
            else
            {
                uid         = e.Message.Author.Id;
                discordUser = await e.Guild.GetMemberAsync(uid);

                id = uid.ToDbLong();
            }

            User account = await User.GetAsync(context, discordUser.Id.ToDbLong(), discordUser.Username);

            string icon = "";

            if (await account.IsDonatorAsync(context))
            {
                icon = "https://cdn.discordapp.com/emojis/421969679561785354.png";
            }

            if (account != null)
            {
                EmbedBuilder embed = new EmbedBuilder()
                                     .SetDescription(account.Title)
                                     .SetAuthor(e.Locale.GetString("miki_global_profile_user_header", discordUser.Username), icon, "https://patreon.com/mikibot")
                                     .SetThumbnail(discordUser.GetAvatarUrl());

                long serverid = e.Guild.Id.ToDbLong();

                LocalExperience localExp = await LocalExperience.GetAsync(context, e.Guild.Id.ToDbLong(), (long)discordUser.Id, discordUser.Username);

                int rank = await localExp.GetRankAsync(context);

                int localLevel  = User.CalculateLevel(localExp.Experience);
                int maxLocalExp = User.CalculateLevelExperience(localLevel);
                int minLocalExp = User.CalculateLevelExperience(localLevel - 1);

                EmojiBar expBar = new EmojiBar(maxLocalExp - minLocalExp, onBarSet, offBarSet, 6);

                string infoValue = new MessageBuilder()
                                   .AppendText(e.Locale.GetString("miki_module_accounts_information_level", localLevel, localExp.Experience.ToFormattedString(), maxLocalExp.ToFormattedString()))
                                   .AppendText(await expBar.Print(localExp.Experience - minLocalExp, e.Guild, (IDiscordGuildChannel)e.Channel))
                                   .AppendText(e.Locale.GetString("miki_module_accounts_information_rank", rank.ToFormattedString()))
                                   .AppendText("Reputation: " + account.Reputation.ToFormattedString(), MessageFormatting.Plain, false)
                                   .Build();

                embed.AddInlineField(e.Locale.GetString("miki_generic_information"), infoValue);

                int globalLevel  = User.CalculateLevel(account.Total_Experience);
                int maxGlobalExp = User.CalculateLevelExperience(globalLevel);
                int minGlobalExp = User.CalculateLevelExperience(globalLevel - 1);

                int?globalRank = await account.GetGlobalRankAsync(context);

                EmojiBar globalExpBar = new EmojiBar(maxGlobalExp - minGlobalExp, onBarSet, offBarSet, 6);

                string globalInfoValue = new MessageBuilder()
                                         .AppendText(e.Locale.GetString("miki_module_accounts_information_level", globalLevel.ToFormattedString(), account.Total_Experience.ToFormattedString(), maxGlobalExp.ToFormattedString()))
                                         .AppendText(
                    await globalExpBar.Print(account.Total_Experience - minGlobalExp, e.Guild, e.Channel as IDiscordGuildChannel)
                    )
                                         .AppendText(e.Locale.GetString("miki_module_accounts_information_rank", globalRank?.ToFormattedString() ?? "We haven't calculated your rank yet!"), MessageFormatting.Plain, false)
                                         .Build();

                embed.AddInlineField(e.Locale.GetString("miki_generic_global_information"), globalInfoValue);
                embed.AddInlineField(e.Locale.GetString("miki_generic_mekos"), account.Currency.ToFormattedString() + "<:mekos:421972155484471296>");

                List <UserMarriedTo> Marriages = await repository.GetMarriagesAsync(id);

                Marriages.RemoveAll(x => x.Marriage.IsProposing);

                List <string> users = new List <string>();

                int maxCount = Marriages?.Count ?? 0;

                for (int i = 0; i < maxCount; i++)
                {
                    users.Add((await MikiApp.Instance.Discord.GetUserAsync(Marriages[i].GetOther(id).FromDbLong())).Username);
                }

                if (Marriages?.Count > 0)
                {
                    List <string> MarriageStrings = new List <string>();

                    for (int i = 0; i < maxCount; i++)
                    {
                        if (Marriages[i].GetOther(id) != 0)
                        {
                            MarriageStrings.Add($"💕 {users[i]} (_{Marriages[i].Marriage.TimeOfMarriage.ToShortDateString()}_)");
                        }
                    }

                    string marriageText = string.Join("\n", MarriageStrings);
                    if (string.IsNullOrEmpty(marriageText))
                    {
                        marriageText = e.Locale.GetString("miki_placeholder_null");
                    }

                    embed.AddInlineField(
                        e.Locale.GetString("miki_module_accounts_profile_marriedto"),
                        marriageText);
                }

                Random r = new Random((int)id - 3);
                Color  c = new Color((float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble());

                embed.SetColor(c);

                List <Achievement> allAchievements = await context.Achievements.Where(x => x.UserId == id)
                                                     .ToListAsync();

                string achievements = e.Locale.GetString("miki_placeholder_null");

                if (allAchievements != null)
                {
                    if (allAchievements.Count > 0)
                    {
                        achievements = AchievementManager.Instance.PrintAchievements(allAchievements);
                    }
                }

                embed.AddInlineField(
                    e.Locale.GetString("miki_generic_achievements"),
                    achievements);

                embed.SetFooter(
                    e.Locale.GetString(
                        "miki_module_accounts_profile_footer",
                        account.DateCreated.ToShortDateString(),
                        sw.ElapsedMilliseconds),
                    "");

                sw.Stop();

                await embed.ToEmbed().QueueToChannelAsync(e.Channel);
            }
            else
            {
                await e.ErrorEmbed(e.Locale.GetString("error_account_null"))
                .ToEmbed().QueueToChannelAsync(e.Channel);
            }
        }
Example #12
0
        public async Task IAmAsync(EventContext e)
        {
            using (var context = new MikiContext())
            {
                string roleName = e.Arguments.ToString();

                List <IDiscordRole> roles = await GetRolesByName(e.Guild, roleName);

                IDiscordRole role = null;

                // checking if the role has a duplicate name.
                if (roles.Count > 1)
                {
                    List <LevelRole> levelRoles = await context.LevelRoles.Where(x => x.GuildId == (long)e.Guild.Id).ToListAsync();

                    if (levelRoles.Where(x => x.GetRoleAsync().Result.Name.ToLower() == roleName.ToLower()).Count() > 1)
                    {
                        await e.ErrorEmbed("two roles configured have the same name.")
                        .ToEmbed().QueueToChannelAsync(e.Channel);

                        return;
                    }
                    else
                    {
                        role = levelRoles.Where(x => x.GetRoleAsync().Result.Name.ToLower() == roleName.ToLower()).FirstOrDefault().GetRoleAsync().Result;
                    }
                }
                else
                {
                    role = roles.FirstOrDefault();
                }

                // checking if the role is null
                if (role == null)
                {
                    await e.ErrorEmbedResource("error_role_null")
                    .ToEmbed().QueueToChannelAsync(e.Channel);

                    return;
                }

                IDiscordGuildUser author = await e.Guild.GetMemberAsync(e.Author.Id);

                if (author.RoleIds.Contains(role.Id))
                {
                    await e.ErrorEmbed(e.Locale.GetString("error_role_already_given"))
                    .ToEmbed().QueueToChannelAsync(e.Channel);

                    return;
                }

                LevelRole newRole = await context.LevelRoles.FindAsync(e.Guild.Id.ToDbLong(), role.Id.ToDbLong());

                IDiscordRole discordRole = await newRole.GetRoleAsync();

                User user = (await context.Users.FindAsync(e.Author.Id.ToDbLong()));

                IDiscordGuildUser discordUser = await e.Guild.GetMemberAsync(user.Id.FromDbLong());

                LocalExperience localUser = await LocalExperience.GetAsync(context, e.Guild.Id.ToDbLong(), discordUser.Id.ToDbLong(), discordUser.Username);

                if (!newRole?.Optable ?? false)
                {
                    await e.ErrorEmbed(e.Locale.GetString("error_role_forbidden"))
                    .ToEmbed().SendToChannel(e.Channel);

                    return;
                }

                int level = User.CalculateLevel(localUser.Experience);

                if (newRole.RequiredLevel > level)
                {
                    await e.ErrorEmbed(e.Locale.GetString("error_role_level_low", newRole.RequiredLevel - level))
                    .ToEmbed().SendToChannel(e.Channel);

                    return;
                }

                if (newRole.RequiredRole != 0 && !discordUser.RoleIds.Contains(newRole.RequiredRole.FromDbLong()))
                {
                    var requiredRole = await e.Guild.GetRoleAsync(newRole.RequiredRole.FromDbLong());

                    await e.ErrorEmbed(
                        e.Locale.GetString(
                            "error_role_required", $"**{requiredRole.Name}**"
                            )
                        ).ToEmbed().QueueToChannelAsync(e.Channel);

                    return;
                }

                if (newRole.Price > 0)
                {
                    if (user.Currency >= newRole.Price)
                    {
                        user.RemoveCurrency(newRole.Price);
                        await context.SaveChangesAsync();
                    }
                    else
                    {
                        await e.ErrorEmbed(e.Locale.GetString("user_error_insufficient_mekos"))
                        .ToEmbed().SendToChannel(e.Channel);

                        return;
                    }
                }

                var me = await e.Guild.GetSelfAsync();

                if (!await me.HasPermissionsAsync(GuildPermission.ManageRoles))
                {
                    await e.ErrorEmbed(e.Locale.GetString("permission_error_low", "give roles")).ToEmbed()
                    .QueueToChannelAsync(e.Channel);

                    return;
                }

                if (discordRole.Position >= await me.GetHierarchyAsync())
                {
                    await e.ErrorEmbed(e.Locale.GetString("permission_error_low", "give roles")).ToEmbed()
                    .QueueToChannelAsync(e.Channel);

                    return;
                }

                await author.AddRoleAsync(discordRole);

                await new EmbedBuilder()
                .SetTitle("I AM")
                .SetColor(128, 255, 128)
                .SetDescription($"You're a(n) {role.Name} now!")
                .ToEmbed().QueueToChannelAsync(e.Channel);
            }
        }