Currency level up rewards (.xpcr) Bot owner only.
This commit is contained in:
		@@ -36,6 +36,8 @@ namespace NadekoBot.Modules.Xp.Services
 | 
			
		||||
        private readonly NadekoStrings _strings;
 | 
			
		||||
        private readonly IDataCache _cache;
 | 
			
		||||
        private readonly FontProvider _fonts;
 | 
			
		||||
        private readonly IBotCredentials _creds;
 | 
			
		||||
        private readonly CurrencyService _cs;
 | 
			
		||||
        public const int XP_REQUIRED_LVL_1 = 36;
 | 
			
		||||
 | 
			
		||||
        private readonly ConcurrentDictionary<ulong, ConcurrentHashSet<ulong>> _excludedRoles
 | 
			
		||||
@@ -60,7 +62,7 @@ namespace NadekoBot.Modules.Xp.Services
 | 
			
		||||
 | 
			
		||||
        public XpService(CommandHandler cmd, IBotConfigProvider bc,
 | 
			
		||||
            NadekoBot bot, DbService db, NadekoStrings strings, IDataCache cache,
 | 
			
		||||
            FontProvider fonts)
 | 
			
		||||
            FontProvider fonts, IBotCredentials creds, CurrencyService cs)
 | 
			
		||||
        {
 | 
			
		||||
            _db = db;
 | 
			
		||||
            _cmd = cmd;
 | 
			
		||||
@@ -70,6 +72,8 @@ namespace NadekoBot.Modules.Xp.Services
 | 
			
		||||
            _strings = strings;
 | 
			
		||||
            _cache = cache;
 | 
			
		||||
            _fonts = fonts;
 | 
			
		||||
            _creds = creds;
 | 
			
		||||
            _cs = cs;
 | 
			
		||||
 | 
			
		||||
            //load settings
 | 
			
		||||
            var allGuildConfigs = bot.AllGuildConfigs.Where(x => x.XpSettings != null);
 | 
			
		||||
@@ -105,6 +109,7 @@ namespace NadekoBot.Modules.Xp.Services
 | 
			
		||||
                {
 | 
			
		||||
                    var toNotify = new List<(IMessageChannel MessageChannel, IUser User, int Level, XpNotificationType NotifyType, NotifOf NotifOf)>();
 | 
			
		||||
                    var roleRewards = new Dictionary<ulong, List<XpRoleReward>>();
 | 
			
		||||
                    var curRewards = new Dictionary<ulong, List<XpCurrencyReward>>();
 | 
			
		||||
 | 
			
		||||
                    var toAddTo = new List<UserCacheItem>();
 | 
			
		||||
                    while (_addMessageXp.TryDequeue(out var usr))
 | 
			
		||||
@@ -120,14 +125,13 @@ namespace NadekoBot.Modules.Xp.Services
 | 
			
		||||
                        {
 | 
			
		||||
                            var xp = item.Select(x => bc.BotConfig.XpPerMessage).Sum();
 | 
			
		||||
 | 
			
		||||
                            //1. Mass query discord users and userxpstats and get them from local dict
 | 
			
		||||
                            //2. (better but much harder) Move everything to the database, and get old and new xp
 | 
			
		||||
                            // amounts for every user (in order to give rewards)
 | 
			
		||||
 | 
			
		||||
                            var usr = uow.Xp.GetOrCreateUser(item.Key.GuildId, item.Key.User.Id);
 | 
			
		||||
                            var du = uow.DiscordUsers.GetOrCreate(item.Key.User);
 | 
			
		||||
 | 
			
		||||
                            if (du.LastXpGain + TimeSpan.FromMinutes(_bc.BotConfig.XpMinutesTimeout) > DateTime.UtcNow)
 | 
			
		||||
                                continue;
 | 
			
		||||
 | 
			
		||||
                            du.LastXpGain = DateTime.UtcNow;
 | 
			
		||||
 | 
			
		||||
                            var globalXp = du.TotalXp;
 | 
			
		||||
                            var oldGlobalLevelData = new LevelStats(globalXp);
 | 
			
		||||
                            var newGlobalLevelData = new LevelStats(globalXp + xp);
 | 
			
		||||
@@ -156,21 +160,34 @@ namespace NadekoBot.Modules.Xp.Services
 | 
			
		||||
                                    toNotify.Add((first.Channel, first.User, newGuildLevelData.Level, usr.NotifyOnLevelUp, NotifOf.Server));
 | 
			
		||||
 | 
			
		||||
                                //give role
 | 
			
		||||
                                if (!roleRewards.TryGetValue(usr.GuildId, out var rewards))
 | 
			
		||||
                                if (!roleRewards.TryGetValue(usr.GuildId, out var rrews))
 | 
			
		||||
                                {
 | 
			
		||||
                                    rewards = uow.GuildConfigs.XpSettingsFor(usr.GuildId).RoleRewards.ToList();
 | 
			
		||||
                                    roleRewards.Add(usr.GuildId, rewards);
 | 
			
		||||
                                    rrews = uow.GuildConfigs.XpSettingsFor(usr.GuildId).RoleRewards.ToList();
 | 
			
		||||
                                    roleRewards.Add(usr.GuildId, rrews);
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                var rew = rewards.FirstOrDefault(x => x.Level == newGuildLevelData.Level);
 | 
			
		||||
                                if (rew != null)
 | 
			
		||||
                                if (!curRewards.TryGetValue(usr.GuildId, out var crews))
 | 
			
		||||
                                {
 | 
			
		||||
                                    var role = first.User.Guild.GetRole(rew.RoleId);
 | 
			
		||||
                                    crews = uow.GuildConfigs.XpSettingsFor(usr.GuildId).CurrencyRewards.ToList();
 | 
			
		||||
                                    curRewards.Add(usr.GuildId, crews);
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                var rrew = rrews.FirstOrDefault(x => x.Level == newGuildLevelData.Level);
 | 
			
		||||
                                if (rrew != null)
 | 
			
		||||
                                {
 | 
			
		||||
                                    var role = first.User.Guild.GetRole(rrew.RoleId);
 | 
			
		||||
                                    if (role != null)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        var __ = first.User.AddRoleAsync(role);
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                                //get currency reward for this level
 | 
			
		||||
                                var crew = crews.FirstOrDefault(x => x.Level == newGuildLevelData.Level);
 | 
			
		||||
                                if (crew != null)
 | 
			
		||||
                                {
 | 
			
		||||
                                    //give the user the reward if it exists
 | 
			
		||||
                                    await _cs.AddAsync(item.Key.User.Id, "Level-up Reward", crew.Amount, uow);
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
@@ -429,7 +446,13 @@ namespace NadekoBot.Modules.Xp.Services
 | 
			
		||||
 | 
			
		||||
        private bool SetUserRewarded(ulong userId)
 | 
			
		||||
        {
 | 
			
		||||
            return _rewardedUsers.Add(userId);
 | 
			
		||||
            var r = _cache.Redis.GetDatabase();
 | 
			
		||||
            var key = $"{_creds.RedisKey()}_user_xp_gain_{userId}";
 | 
			
		||||
 | 
			
		||||
            return r.StringSet(key, 
 | 
			
		||||
                true, 
 | 
			
		||||
                TimeSpan.FromMinutes(_bc.BotConfig.XpMinutesTimeout), 
 | 
			
		||||
                StackExchange.Redis.When.NotExists);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public FullUserStats GetUserStats(IGuildUser user)
 | 
			
		||||
 
 | 
			
		||||
@@ -17,11 +17,13 @@ namespace NadekoBot.Modules.Xp
 | 
			
		||||
    {
 | 
			
		||||
        private readonly DiscordSocketClient _client;
 | 
			
		||||
        private readonly DbService _db;
 | 
			
		||||
        private readonly IBotConfigProvider _bc;
 | 
			
		||||
 | 
			
		||||
        public Xp(DiscordSocketClient client,DbService db)
 | 
			
		||||
        public Xp(DiscordSocketClient client,DbService db, IBotConfigProvider bc)
 | 
			
		||||
        {
 | 
			
		||||
            _client = client;
 | 
			
		||||
            _db = db;
 | 
			
		||||
            _bc = bc;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
@@ -45,34 +47,39 @@ namespace NadekoBot.Modules.Xp
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public Task XpRoleRewards(int page = 1)
 | 
			
		||||
        public Task XpLevelUpRewards(int page = 1)
 | 
			
		||||
        {
 | 
			
		||||
            page--;
 | 
			
		||||
 | 
			
		||||
            if (page < 0 || page > 100)
 | 
			
		||||
                return Task.CompletedTask;
 | 
			
		||||
 | 
			
		||||
            var roles = _service.GetRoleRewards(Context.Guild.Id)
 | 
			
		||||
                .OrderBy(x => x.Level)
 | 
			
		||||
                .Skip(page * 9)
 | 
			
		||||
                .Take(9);
 | 
			
		||||
 | 
			
		||||
            var embed = new EmbedBuilder()
 | 
			
		||||
                .WithTitle(GetText("level_up_rewards"))
 | 
			
		||||
                .WithOkColor();
 | 
			
		||||
 | 
			
		||||
            if (!roles.Any())
 | 
			
		||||
                return Context.Channel.EmbedAsync(embed.WithDescription(GetText("no_role_rewards")));
 | 
			
		||||
            var rewards = _service.GetRoleRewards(Context.Guild.Id)
 | 
			
		||||
                .OrderBy(x => x.Level)
 | 
			
		||||
                .Select(x =>
 | 
			
		||||
                {
 | 
			
		||||
                    var str = Context.Guild.GetRole(x.RoleId)?.ToString();
 | 
			
		||||
                    if (str != null)
 | 
			
		||||
                        str = GetText("role_reward", Format.Bold(str));
 | 
			
		||||
                    return (x.Level, RoleStr: str);
 | 
			
		||||
                })
 | 
			
		||||
                .Where(x => x.RoleStr != null)
 | 
			
		||||
                .Concat(_service.GetCurrencyRewards(Context.Guild.Id)
 | 
			
		||||
                    .OrderBy(x => x.Level)
 | 
			
		||||
                    .Select(x => (x.Level, Format.Bold(x.Amount + _bc.BotConfig.CurrencySign))))
 | 
			
		||||
                    .GroupBy(x => x.Level)
 | 
			
		||||
                    .OrderBy(x => x.Key)
 | 
			
		||||
                    .Skip(page * 9)
 | 
			
		||||
                    .Take(9)
 | 
			
		||||
                    .ForEach(x => embed.AddField(GetText("level_x", x.Key), string.Join("\n", x.Select(y => y.Item2))));
 | 
			
		||||
 | 
			
		||||
            foreach (var rolerew in roles)
 | 
			
		||||
            {
 | 
			
		||||
                var role = Context.Guild.GetRole(rolerew.RoleId);
 | 
			
		||||
            if (!rewards.Any())
 | 
			
		||||
                return Context.Channel.EmbedAsync(embed.WithDescription(GetText("no_level_up_rewards")));
 | 
			
		||||
 | 
			
		||||
                if (role == null)
 | 
			
		||||
                    continue;
 | 
			
		||||
 | 
			
		||||
                embed.AddField(GetText("level_x", Format.Bold(rolerew.Level.ToString())), role.ToString());
 | 
			
		||||
            }
 | 
			
		||||
            return Context.Channel.EmbedAsync(embed);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -104,7 +111,7 @@ namespace NadekoBot.Modules.Xp
 | 
			
		||||
            if (amount == 0)
 | 
			
		||||
                await ReplyConfirmLocalized("cur_reward_cleared", level).ConfigureAwait(false);
 | 
			
		||||
            else
 | 
			
		||||
                await ReplyConfirmLocalized("cur_reward_added", level, Format.Bold(amount.ToString())).ConfigureAwait(false);
 | 
			
		||||
                await ReplyConfirmLocalized("cur_reward_added", level, Format.Bold(amount + _bc.BotConfig.CurrencySign)).ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public enum NotifyPlace
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user