Beispiel #1
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:");
            }
        }
Beispiel #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:");
            }
        }
Beispiel #3
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:");
        }
Beispiel #4
0
        private void RequiredLevelValid(LevelRole role, LocalExperience localUser)
        {
            int level = User.CalculateLevel(localUser.Experience);

            if (role.RequiredLevel > level)
            {
                throw new LevelTooLowException(level, role.RequiredLevel);
            }
        }
Beispiel #5
0
        /// <inheritdoc />
        public async ValueTask <LocalExperience> CreateLocalExperienceAsync(GuildUserReference guildUser)
        {
            var localExperience = new LocalExperience
            {
                ServerId   = guildUser.GuildId,
                UserId     = guildUser.UserId,
                Experience = 0
            };
            await localExperienceRepository.AddAsync(localExperience);

            await unitOfWork.CommitAsync();

            return(localExperience);
        }
Beispiel #6
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);
        }
Beispiel #7
0
        public async Task SetExp(EventContext e)
        {
            using (var context = new MikiContext())
            {
                LocalExperience u = await context.Experience.FindAsync(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 e.Channel.SendMessage(":ok_hand:");
            }
        }
Beispiel #8
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:");
            }
        }
Beispiel #9
0
        public async Task GuildWeekly(EventContext context)
        {
            using (MikiContext database = new MikiContext())
            {
                Locale          locale   = Locale.GetEntity(context.Channel.Id);
                LocalExperience thisUser = await database.LocalExperience.FindAsync(context.Guild.Id.ToDbLong(), context.Author.Id.ToDbLong());

                GuildUser thisGuild = await database.GuildUsers.FindAsync(context.Guild.Id.ToDbLong());

                Timer timer = await database.Timers.FindAsync(context.Guild.Id.ToDbLong(), context.Author.Id.ToDbLong());

                if (thisUser == null)
                {
                    Log.ErrorAt("Guildweekly", "User is null");
                    return;
                }

                if (thisGuild == null)
                {
                    Log.ErrorAt("Guildweekly", "Guild is null");
                    return;
                }

                if (thisUser.Experience >= thisGuild.MinimalExperienceToGetRewards)
                {
                    if (timer == null)
                    {
                        timer = (await database.Timers.AddAsync(new Timer()
                        {
                            GuildId = context.Guild.Id.ToDbLong(),
                            UserId = context.Author.Id.ToDbLong(),
                            Value = DateTime.Now.AddDays(-30)
                        })).Entity;
                        await database.SaveChangesAsync();
                    }

                    if (timer.Value.AddDays(7) <= DateTime.Now)
                    {
                        SocketGuild guild = Bot.instance.Client.GetGuild(thisGuild.Id.FromDbLong());

                        GuildUser rival = await thisGuild.GetRival();

                        if (rival == null)
                        {
                            await Utils.Embed
                            .SetTitle(locale.GetString("miki_terms_weekly"))
                            .SetDescription(context.GetResource("guildweekly_error_no_rival"))
                            .QueueToChannel(context.Channel);

                            return;
                        }

                        if (rival.Experience > thisGuild.Experience)
                        {
                            await Utils.Embed
                            .SetTitle(locale.GetString("miki_terms_weekly"))
                            .SetDescription(context.GetResource("guildweekly_error_low_level"))
                            .QueueToChannel(context.Channel);

                            return;
                        }

                        int mekosGained = (int)Math.Round((((MikiRandom.NextDouble() + 1.25) * 0.5) * 10) * thisGuild.CalculateLevel(thisGuild.Experience));

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

                        if (user == null)
                        {
                            // TODO: Add response
                            return;
                        }

                        await user.AddCurrencyAsync(mekosGained, context.Channel);

                        await Utils.Embed
                        .SetTitle(locale.GetString("miki_terms_weekly"))
                        .AddInlineField("Mekos", mekosGained.ToString())
                        .QueueToChannel(context.Channel);

                        timer.Value = DateTime.Now;
                        await database.SaveChangesAsync();
                    }
                    else
                    {
                        await Utils.Embed
                        .SetTitle(locale.GetString("miki_terms_weekly"))
                        .SetDescription(context.GetResource("guildweekly_error_timer_running", (timer.Value.AddDays(7) - DateTime.Now).ToTimeString(locale)))
                        .QueueToChannel(context.Channel);
                    }
                }
                else
                {
                    await Utils.Embed
                    .SetTitle(locale.GetString("miki_terms_weekly"))
                    .SetDescription(locale.GetString("miki_guildweekly_insufficient_exp", thisGuild.MinimalExperienceToGetRewards))
                    .QueueToChannel(context.Channel);
                }
            }
        }
Beispiel #10
0
        public async Task ProfileAsync(EventContext e)
        {
            Stopwatch sw = new Stopwatch();

            sw.Start();

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

                if (e.message.MentionedUserIds.Count() > 0)
                {
                    uid = e.message.MentionedUserIds.First();
                    id  = uid.ToDbLong();
                }
                else
                {
                    uid = e.message.Author.Id;
                    id  = uid.ToDbLong();
                }

                User account = await context.Users.FindAsync(id);

                Locale       locale      = Locale.GetEntity(e.Channel.Id.ToDbLong());
                IDiscordUser discordUser = await e.Guild.GetUserAsync(uid);

                if (account != null)
                {
                    IDiscordEmbed embed = Utils.Embed
                                          .SetDescription(account.Title)
                                          .SetAuthor(locale.GetString("miki_global_profile_user_header", account.Name), "http://veld.one/assets/profile-icon.png", "https://patreon.com/mikibot")
                                          .SetThumbnailUrl(discordUser.AvatarUrl);

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

                    LocalExperience localExp = await context.Experience.FindAsync(serverid, id);

                    int globalExp = account.Total_Experience;

                    int rank = await account.GetLocalRank(e.Guild.Id);

                    EmojiBarSet onBarSet  = new EmojiBarSet("<:mbaronright:334479818924228608>", "<:mbaronmid:334479818848468992>", "<:mbaronleft:334479819003789312>");
                    EmojiBarSet offBarSet = new EmojiBarSet("<:mbaroffright:334479818714513430>", "<:mbaroffmid:334479818504536066>", "<:mbaroffleft:334479818949394442>");

                    EmojiBar expBar = new EmojiBar(account.CalculateMaxExperience(localExp.Experience), onBarSet, offBarSet, 6);

                    string infoValue = new MessageBuilder()
                                       .AppendText(locale.GetString("miki_module_accounts_information_level", account.CalculateLevel(localExp.Experience), localExp.Experience, account.CalculateMaxExperience(localExp.Experience)))
                                       .AppendText(await expBar.Print(localExp.Experience, e.Channel))
                                       .AppendText(locale.GetString("miki_module_accounts_information_rank", rank))
                                       .AppendText("Reputation: " + account.Reputation, MessageFormatting.PLAIN, false)
                                       .Build();

                    embed.AddInlineField(locale.GetString("miki_generic_information"), infoValue);

                    int globalLevel = account.CalculateLevel(account.Total_Experience);
                    int globalRank  = account.CalculateMaxExperience(account.Total_Experience);

                    EmojiBar globalExpBar = new EmojiBar(account.CalculateMaxExperience(account.Total_Experience), onBarSet, offBarSet, 6);

                    string globalInfoValue = new MessageBuilder()
                                             .AppendText(locale.GetString("miki_module_accounts_information_level", globalLevel, account.Total_Experience, globalRank))
                                             .AppendText(await globalExpBar.Print(account.Total_Experience, e.Channel))
                                             .AppendText(locale.GetString("miki_module_accounts_information_rank", account.GetGlobalRank()), MessageFormatting.PLAIN, false)
                                             .Build();

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

                    embed.AddInlineField(locale.GetString("miki_generic_mekos"), account.Currency + "🔸");

                    List <Marriage> marriages = Marriage.GetMarriages(context, id);

                    marriages = marriages.OrderBy(mar => mar.TimeOfMarriage).ToList();

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

                    int maxCount = marriages.Count;

                    for (int i = 0; i < maxCount; i++)
                    {
                        users.Add(await context.Users.FindAsync(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 && marriages[i].TimeOfMarriage != null)
                            {
                                marriageStrings.Add("💕 " + users[i].Name + " (_" + marriages[i].TimeOfMarriage.ToShortDateString() + "_)");
                            }
                        }

                        embed.AddInlineField(
                            locale.GetString("miki_module_accounts_profile_marriedto"),
                            string.Join("\n", marriageStrings));
                    }

                    Random r = new Random((int)id - 3);

                    embed.Color = new IA.SDK.Color((float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble());

                    List <CommandUsage> List = context.CommandUsages.Where(c => c.UserId == id).OrderByDescending(c => c.Amount).ToList();
                    string favCommand        = (List.Count > 0) ? List[0].Name + " (" + List[0].Amount + ")" : "none (yet!)";

                    embed.AddInlineField(locale.GetString("miki_module_accounts_profile_favourite_command"), favCommand);

                    string achievements = AchievementManager.Instance.PrintAchievements(context, account.Id.FromDbLong());

                    embed.AddInlineField(
                        locale.GetString("miki_generic_achievements"),
                        achievements != "" ? achievements : locale.GetString("miki_placeholder_null"));

                    embed.AddInlineField(locale.GetString("miki_module_accounts_profile_url"), "http://miki.veld.one/profile/" + account.Id);

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

                    sw.Stop();

                    await embed.SendToChannel(e.Channel);
                }
                else
                {
                    await Utils.ErrorEmbed(locale, locale.GetString("miki_module_accounts_error_null")).SendToChannel(e.Channel);
                }
            }
        }
Beispiel #11
0
        public async Task CheckAsync(IDiscordMessage e)
        {
            if (e.Author.IsBot)
            {
                return;
            }

            RealtimeExperienceObject o;

            if (!await Global.redisClient.ExistsAsync($"user:{e.Guild.Id}:{e.Author.Id}:exp"))
            {
                using (var context = new MikiContext())
                {
                    LocalExperience user = await context.LocalExperience.FindAsync(e.Guild.Id.ToDbLong(), e.Author.Id.ToDbLong());

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

            o = await Global.redisClient.GetAsync <RealtimeExperienceObject>($"user:{e.Guild.Id}:{e.Author.Id}:exp");

            if (o.LastExperienceTime.AddMinutes(1) < DateTime.Now)
            {
                var ranNum = MikiRandom.Next(4, 10);
                o.Experience += ranNum;

                if (!experienceQueue.ContainsKey(e.Author.Id))
                {
                    experienceQueue.Add(e.Author.Id, new ExperienceAdded()
                    {
                        UserId     = e.Author.Id.ToDbLong(),
                        GuildId    = e.Guild.Id.ToDbLong(),
                        Experience = ranNum,
                        Name       = e.Author.Username,
                    });
                }
                else
                {
                    experienceQueue[e.Author.Id].Experience += ranNum;
                }

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

                if (User.CalculateLevel(o.Experience - ranNum) != level)
                {
                    await LevelUpLocalAsync(e, level);
                }

                o.LastExperienceTime = DateTime.Now;

                await Global.redisClient.AddAsync($"user:{e.Guild.Id}:{e.Author.Id}:exp", o);
            }

            if (DateTime.Now >= lastDbSync + new TimeSpan(0, 1, 0))
            {
                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);
                }
                experienceQueue.Clear();
                Log.Message($"Done Applying!");
            }
        }
Beispiel #12
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);
            }
        }
Beispiel #13
0
        public async Task CheckAsync(IDiscordMessage e)
        {
            if (e.Author.IsBot)
            {
                return;
            }

            if (!lastTimeExpGranted.ContainsKey(e.Author.Id))
            {
                lastTimeExpGranted.Add(e.Author.Id, DateTime.MinValue);
            }

            if (lastTimeExpGranted[e.Author.Id].AddMinutes(1) < DateTime.Now)
            {
                using (var context = new MikiContext())
                {
                    User a = await context.Users.FindAsync(e.Author.Id.ToDbLong());

                    if (a == null)
                    {
                        a = User.Create(context, e);
                    }

                    try
                    {
                        LocalExperience experience = await context.Experience.FindAsync(e.Guild.Id.ToDbLong(), a.Id);

                        if (experience == null)
                        {
                            experience = context.Experience.Add(new LocalExperience()
                            {
                                server_id = e.Guild.Id.ToDbLong(), user_id = a.Id, Experience = 0, LastExperienceTime = DateTime.Now - new TimeSpan(1)
                            });
                        }

                        GuildUser guildUser = await context.GuildUsers.FindAsync(e.Guild.Id.ToDbLong());

                        if (guildUser == null)
                        {
                            int value = await context.Database.SqlQuery <int>
                                            ("select Sum(Experience) as value from LocalExperience where ServerId = @p0;", e.Guild.Id.ToDbLong())
                                        .FirstAsync();

                            guildUser = context.GuildUsers.Add(new GuildUser()
                            {
                                Name              = e.Guild.Name,
                                Id                = e.Guild.Id.ToDbLong(),
                                Experience        = value,
                                UserCount         = Bot.instance.Client.GetGuild(e.Guild.Id).Users.Count,
                                LastRivalRenewed  = DateTime.Now.AddYears(-1),
                                LastRewardClaimed = DateTime.Now.AddYears(-1)
                            });
                            await context.SaveChangesAsync();
                        }

                        if (experience.LastExperienceTime == null)
                        {
                            experience.LastExperienceTime = DateTime.Now;
                        }

                        int currentLocalLevel  = a.CalculateLevel(experience.Experience);
                        int currentGlobalLevel = a.CalculateLevel(a.Total_Experience);
                        int addedExperience    = Global.random.Next(1, 10);

                        experience.Experience += addedExperience;
                        a.Total_Experience    += addedExperience;
                        guildUser.Experience  += addedExperience;

                        if (currentLocalLevel != a.CalculateLevel(experience.Experience))
                        {
                            await LevelUpLocalAsync(e, a, currentLocalLevel + 1);
                        }
                        if (currentGlobalLevel != a.CalculateLevel(a.Total_Experience))
                        {
                            await LevelUpGlobalAsync(e, a, currentGlobalLevel + 1);
                        }

                        experience.LastExperienceTime   = DateTime.Now;
                        lastTimeExpGranted[e.Author.Id] = DateTime.Now;
                    }
                    catch (Exception ex)
                    {
                        Log.ErrorAt("Accounts.Check", ex.Message + ex.StackTrace + ex.Source);
                    }

                    await context.SaveChangesAsync();
                }
            }
        }
Beispiel #14
0
 private ValueTask UpdateLocalExperienceAsync(LocalExperience localExperience)
 => localExperienceRepository.EditAsync(localExperience);
Beispiel #15
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);
            }
        }
Beispiel #16
0
        public async Task ProfileAsync(EventContext e)
        {
            Stopwatch sw = new Stopwatch();

            sw.Start();

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

                if (e.message.MentionedUserIds.Any())
                {
                    uid = e.message.MentionedUserIds.First();
                    id  = uid.ToDbLong();
                }
                else
                {
                    uid = e.message.Author.Id;
                    id  = uid.ToDbLong();
                }

                Locale       locale      = new Locale(e.Channel.Id.ToDbLong());
                IDiscordUser discordUser = await e.Guild.GetUserAsync(uid);

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

                EmojiBarSet onBarSet = new EmojiBarSet(
                    "<:mbarlefton:391971424442646534>",
                    "<:mbarmidon:391971424920797185>",
                    "<:mbarrighton:391971424488783875>");

                EmojiBarSet offBarSet = new EmojiBarSet(
                    "<:mbarleftoff:391971424824459265>",
                    "<:mbarmidoff:391971424824197123>",
                    "<:mbarrightoff:391971424862208000>");

                if (account != null)
                {
                    IDiscordEmbed embed = Utils.Embed
                                          .SetDescription(account.Title)
                                          .SetAuthor(locale.GetString("miki_global_profile_user_header", account.Name), "", "https://patreon.com/mikibot")
                                          .SetThumbnailUrl(discordUser.AvatarUrl);

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

                    LocalExperience localExp = account.LocalExperience.FirstOrDefault(x => x.ServerId == e.Guild.Id.ToDbLong());
                    if (localExp == null)
                    {
                        localExp = await LocalExperience.CreateAsync(context, serverid, id);
                    }

                    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(locale.GetString("miki_module_accounts_information_level", localLevel, localExp.Experience, maxLocalExp))
                                       .AppendText(await expBar.Print(localExp.Experience - minLocalExp, e.Channel))
                                       .AppendText(locale.GetString("miki_module_accounts_information_rank", rank))
                                       .AppendText("Reputation: " + account.Reputation, MessageFormatting.Plain, false)
                                       .Build();
                    embed.AddInlineField(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();

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

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

                    embed.AddInlineField(locale.GetString("miki_generic_global_information"), globalInfoValue);
                    embed.AddInlineField(locale.GetString("miki_generic_mekos"), account.Currency + "🔸");

                    List <Marriage> Marriages = account.Marriages?
                                                .Select(x => x.Marriage)
                                                .Where(x => !x.IsProposing)
                                                .OrderBy(mar => mar.TimeOfMarriage)
                                                .ToList();

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

                    int maxCount = Marriages?.Count ?? 0;

                    for (int i = 0; i < maxCount; i++)
                    {
                        users.Add(await context.Users.FindAsync(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].Name} (_{Marriages[i].TimeOfMarriage.ToShortDateString()}_)");
                            }
                        }

                        embed.AddInlineField(
                            locale.GetString("miki_module_accounts_profile_marriedto"),
                            string.Join("\n", MarriageStrings));
                    }

                    Random r = new Random((int)id - 3);

                    embed.Color = new Miki.Common.Color((float)r.NextDouble(), (float)r.NextDouble(),
                                                        (float)r.NextDouble());

                    CommandUsage favouriteCommand = account.CommandsUsed?
                                                    .OrderByDescending(c => c.Amount)
                                                    .FirstOrDefault();

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

                    embed.AddInlineField(locale.GetString("miki_module_accounts_profile_favourite_command"),
                                         favCommand);

                    if (account.Achievements != null)
                    {
                        string achievements = AchievementManager.Instance.PrintAchievements(account.Achievements);

                        embed.AddInlineField(
                            locale.GetString("miki_generic_achievements"),
                            achievements != "" ? achievements : locale.GetString("miki_placeholder_null"));
                    }

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

                    sw.Stop();

                    embed.QueueToChannel(e.Channel);
                }
                else
                {
                    e.ErrorEmbed(locale.GetString("error_account_null"))
                    .QueueToChannel(e.Channel);
                }
            }
        }
Beispiel #17
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());
            }
Beispiel #18
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());
        }
Beispiel #19
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);
            }
        }
Beispiel #20
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);
                }
            }
        }
Beispiel #21
0
        public async Task GuildWeeklyAsync(CommandContext e)
        {
            var database = e.GetService <MikiDbContext>();

            LocalExperience thisUser = await database.LocalExperience.FindAsync(e.Guild.Id.ToDbLong(), e.Author.Id.ToDbLong());

            GuildUser thisGuild = await database.GuildUsers.FindAsync(e.Guild.Id.ToDbLong());

            Timer timer = await database.Timers.FindAsync(e.Guild.Id.ToDbLong(), e.Author.Id.ToDbLong());

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

            if (thisGuild == null)
            {
                return;
            }

            if (thisUser.Experience >= thisGuild.MinimalExperienceToGetRewards)
            {
                if (timer == null)
                {
                    timer = (await database.Timers.AddAsync(new Timer()
                    {
                        GuildId = e.Guild.Id.ToDbLong(),
                        UserId = e.Author.Id.ToDbLong(),
                        Value = DateTime.Now.AddDays(-30)
                    })).Entity;
                    await database.SaveChangesAsync();
                }

                if (timer.Value.AddDays(7) <= DateTime.Now)
                {
                    GuildUser rival = await thisGuild.GetRivalOrDefaultAsync(database);

                    if (rival == null)
                    {
                        throw new RivalNullException();
                    }

                    if (rival.Experience > thisGuild.Experience)
                    {
                        await new EmbedBuilder()
                        .SetTitle(e.Locale.GetString("miki_terms_weekly"))
                        .SetDescription(e.Locale.GetString("guildweekly_error_low_level"))
                        .ToEmbed().QueueToChannelAsync(e.Channel);
                        return;
                    }

                    int mekosGained = (int)Math.Round((((MikiRandom.NextDouble() + thisGuild.GuildHouseMultiplier) * 0.5) * 10) * thisGuild.CalculateLevel(thisGuild.Experience));

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

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

                    await user.AddCurrencyAsync(mekosGained, e.Channel);

                    await new EmbedBuilder()
                    .SetTitle(e.Locale.GetString("miki_terms_weekly"))
                    .AddInlineField("Mekos", mekosGained.ToFormattedString())
                    .ToEmbed().QueueToChannelAsync(e.Channel);

                    timer.Value = DateTime.Now;
                    await database.SaveChangesAsync();
                }
                else
                {
                    await new EmbedBuilder()
                    .SetTitle(e.Locale.GetString("miki_terms_weekly"))
                    .SetDescription(e.Locale.GetString("guildweekly_error_timer_running", (timer.Value.AddDays(7) - DateTime.Now).ToTimeString(e.Locale)))
                    .ToEmbed().QueueToChannelAsync(e.Channel);
                }
            }
            else
            {
                await new EmbedBuilder()
                .SetTitle(e.Locale.GetString("miki_terms_weekly"))
                .SetDescription(e.Locale.GetString("miki_guildweekly_insufficient_exp", thisGuild.MinimalExperienceToGetRewards.ToFormattedString()))
                .ToEmbed().QueueToChannelAsync(e.Channel);
            }
        }
Beispiel #22
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());
            }
        }
Beispiel #23
0
        public async Task CheckAsync(IDiscordMessage e)
        {
            if (e.Author.IsBot)
            {
                return;
            }

            if (!lastTimeExpGranted.ContainsKey(e.Author.Id))
            {
                lastTimeExpGranted.Add(e.Author.Id, DateTime.MinValue);
            }

            if (lastTimeExpGranted[e.Author.Id].AddMinutes(1) < DateTime.Now)
            {
                int addedExperience = MikiRandom.Next(2, 5);

                await MeruUtils.TryAsync(async() =>
                {
                    User a;
                    LocalExperience experience;

                    long userId = e.Author.Id.ToDbLong();

                    int currentGlobalLevel = 0;
                    int currentLocalLevel  = 0;

                    using (var context = new MikiContext())
                    {
                        a = await context.Users.FindAsync(e.Author.Id.ToDbLong());

                        if (a == null)
                        {
                            a = await User.CreateAsync(e);
                        }

                        experience = await context.Experience.FindAsync(e.Guild.Id.ToDbLong(), userId);

                        if (experience == null)
                        {
                            experience = await LocalExperience.CreateAsync(context, e.Guild.Id.ToDbLong(), e.Author.Id.ToDbLong());
                        }

                        if (experience.LastExperienceTime == null)
                        {
                            experience.LastExperienceTime = DateTime.Now;
                        }

                        GuildUser guildUser = await context.GuildUsers.FindAsync(e.Guild.Id.ToDbLong());
                        if (guildUser == null)
                        {
                            long guildId  = e.Guild.Id.ToDbLong();
                            int?userCount = Bot.instance.Client.GetGuild(e.Guild.Id).Users.Count;

                            int?value = await context.Experience
                                        .Where(x => x.ServerId == guildId)
                                        .SumAsync(x => x.Experience);

                            guildUser                  = new GuildUser();
                            guildUser.Name             = e.Guild.Name;
                            guildUser.Id               = guildId;
                            guildUser.Experience       = value ?? 0;
                            guildUser.UserCount        = userCount ?? 0;
                            guildUser.LastRivalRenewed = Utils.MinDbValue;
                            guildUser.MinimalExperienceToGetRewards = 100;

                            guildUser = context.GuildUsers.Add(guildUser);
                        }

                        currentLocalLevel  = User.CalculateLevel(experience.Experience);
                        currentGlobalLevel = User.CalculateLevel(a.Total_Experience);

                        experience.Experience += addedExperience;
                        a.Total_Experience    += addedExperience;
                        guildUser.Experience  += addedExperience;

                        await context.SaveChangesAsync();
                    }


                    if (currentLocalLevel != User.CalculateLevel(experience.Experience))
                    {
                        await LevelUpLocalAsync(e, a, currentLocalLevel + 1);
                    }

                    if (currentGlobalLevel != User.CalculateLevel(a.Total_Experience))
                    {
                        await LevelUpGlobalAsync(e, a, currentGlobalLevel + 1);
                    }

                    lastTimeExpGranted[e.Author.Id] = DateTime.Now;
                });
            }
        }