Exemplo n.º 1
0
        public async Task <MusicPlayer> GetOrCreatePlayer(ulong guildId, IVoiceChannel voiceCh, ITextChannel textCh)
        {
            string GetText(string text, params object[] replacements) =>
            _strings.GetText(text, _localization.GetCultureInfo(textCh.Guild), "Music".ToLowerInvariant(), replacements);

            if (voiceCh == null || voiceCh.Guild != textCh.Guild)
            {
                if (textCh != null)
                {
                    await textCh.SendErrorAsync(GetText("must_be_in_voice")).ConfigureAwait(false);
                }
                throw new NotInVoiceChannelException();
            }
            return(MusicPlayers.GetOrAdd(guildId, _ =>
            {
                var vol = GetDefaultVolume(guildId);
                if (!_musicSettings.TryGetValue(guildId, out var ms))
                {
                    ms = new MusicSettings();
                }

                var mp = new MusicPlayer(this, ms, _google, voiceCh, textCh, vol);

                IUserMessage playingMessage = null;
                IUserMessage lastFinishedMessage = null;

                mp.OnCompleted += async(s, song) =>
                {
                    try
                    {
                        lastFinishedMessage?.DeleteAfter(0);

                        try
                        {
                            lastFinishedMessage = await mp.OutputTextChannel.EmbedAsync(new EmbedBuilder().WithOkColor()
                                                                                        .WithAuthor(eab => eab.WithName(GetText("finished_song")).WithMusicIcon())
                                                                                        .WithDescription(song.PrettyName)
                                                                                        .WithFooter(ef => ef.WithText(song.PrettyInfo)))
                                                  .ConfigureAwait(false);
                        }
                        catch
                        {
                            // ignored
                        }

                        var(Index, Current) = mp.Current;
                        if (Current == null &&
                            !mp.RepeatCurrentSong &&
                            !mp.RepeatPlaylist &&
                            !mp.FairPlay &&
                            AutoDcServers.Contains(guildId))
                        {
                            await DestroyPlayer(guildId).ConfigureAwait(false);
                        }
                    }
                    catch
                    {
                        // ignored
                    }
                };
                mp.OnStarted += async(player, song) =>
                {
                    //try { await mp.UpdateSongDurationsAsync().ConfigureAwait(false); }
                    //catch
                    //{
                    //    // ignored
                    //}
                    var sender = player;
                    if (sender == null)
                    {
                        return;
                    }
                    try
                    {
                        playingMessage?.DeleteAfter(0);

                        playingMessage = await mp.OutputTextChannel.EmbedAsync(new EmbedBuilder().WithOkColor()
                                                                               .WithAuthor(eab => eab.WithName(GetText("playing_song", song.Index + 1)).WithMusicIcon())
                                                                               .WithDescription(song.Song.PrettyName)
                                                                               .WithFooter(ef => ef.WithText(mp.PrettyVolume + " | " + song.Song.PrettyInfo)))
                                         .ConfigureAwait(false);
                    }
                    catch
                    {
                        // ignored
                    }
                };
                mp.OnPauseChanged += async(player, paused) =>
                {
                    try
                    {
                        IUserMessage msg;
                        if (paused)
                        {
                            msg = await mp.OutputTextChannel.SendConfirmAsync(GetText("paused")).ConfigureAwait(false);
                        }
                        else
                        {
                            msg = await mp.OutputTextChannel.SendConfirmAsync(GetText("resumed")).ConfigureAwait(false);
                        }

                        msg?.DeleteAfter(10);
                    }
                    catch
                    {
                        // ignored
                    }
                };
                _log.Info("Done creating");
                return mp;
            }));
        }
Exemplo n.º 2
0
 private string GetText(string key, params object[] replacements) =>
 _strings.GetText(key,
                  _channel.GuildId,
                  typeof(Games).Name.ToLowerInvariant(),
                  replacements);
Exemplo n.º 3
0
        public XpService(DiscordSocketClient client, CommandHandler cmd, IBotConfigProvider bc,
                         NadekoBot bot, DbService db, NadekoStrings strings, IDataCache cache,
                         FontProvider fonts, IBotCredentials creds, ICurrencyService cs, IHttpClientFactory http)
        {
            _db          = db;
            _cmd         = cmd;
            _bc          = bc;
            _images      = cache.LocalImages;
            _log         = LogManager.GetCurrentClassLogger();
            _strings     = strings;
            _cache       = cache;
            _fonts       = fonts;
            _creds       = creds;
            _cs          = cs;
            _httpFactory = http;
            InternalReloadXpTemplate();

            if (client.ShardId == 0)
            {
                var sub = _cache.Redis.GetSubscriber();
                sub.Subscribe(_creds.RedisKey() + "_reload_xp_template",
                              (ch, val) => InternalReloadXpTemplate());
            }
            //load settings
            var allGuildConfigs = bot.AllGuildConfigs.Where(x => x.XpSettings != null);

            _excludedChannels = allGuildConfigs
                                .ToDictionary(
                x => x.GuildId,
                x => new ConcurrentHashSet <ulong>(x.XpSettings
                                                   .ExclusionList
                                                   .Where(ex => ex.ItemType == ExcludedItemType.Channel)
                                                   .Select(ex => ex.ItemId)
                                                   .Distinct()))
                                .ToConcurrent();

            _excludedRoles = allGuildConfigs
                             .ToDictionary(
                x => x.GuildId,
                x => new ConcurrentHashSet <ulong>(x.XpSettings
                                                   .ExclusionList
                                                   .Where(ex => ex.ItemType == ExcludedItemType.Role)
                                                   .Select(ex => ex.ItemId)
                                                   .Distinct()))
                             .ToConcurrent();

            _excludedServers = new ConcurrentHashSet <ulong>(
                allGuildConfigs.Where(x => x.XpSettings.ServerExcluded)
                .Select(x => x.GuildId));

            _cmd.OnMessageNoTrigger += _cmd_OnMessageNoTrigger;

            updateXpTask = Task.Run(async() =>
            {
                while (true)
                {
                    await Task.Delay(TimeSpan.FromSeconds(5));
                    try
                    {
                        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))
                        {
                            toAddTo.Add(usr);
                        }

                        var group = toAddTo.GroupBy(x => (GuildId: x.Guild.Id, x.User));
                        if (toAddTo.Count == 0)
                        {
                            continue;
                        }

                        using (var uow = _db.UnitOfWork)
                        {
                            foreach (var item in group)
                            {
                                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);

                                var globalXp           = du.TotalXp;
                                var oldGlobalLevelData = new LevelStats(globalXp);
                                var newGlobalLevelData = new LevelStats(globalXp + xp);

                                var oldGuildLevelData = new LevelStats(usr.Xp + usr.AwardedXp);
                                usr.Xp     += xp;
                                du.TotalXp += xp;
                                if (du.Club != null)
                                {
                                    du.Club.Xp += xp;
                                }
                                var newGuildLevelData = new LevelStats(usr.Xp + usr.AwardedXp);

                                if (oldGlobalLevelData.Level < newGlobalLevelData.Level)
                                {
                                    du.LastLevelUp = DateTime.UtcNow;
                                    var first      = item.First();
                                    if (du.NotifyOnLevelUp != XpNotificationType.None)
                                    {
                                        toNotify.Add((first.Channel, first.User, newGlobalLevelData.Level, du.NotifyOnLevelUp, NotifOf.Global));
                                    }
                                }

                                if (oldGuildLevelData.Level < newGuildLevelData.Level)
                                {
                                    usr.LastLevelUp = DateTime.UtcNow;
                                    //send level up notification
                                    var first = item.First();
                                    if (usr.NotifyOnLevelUp != XpNotificationType.None)
                                    {
                                        toNotify.Add((first.Channel, first.User, newGuildLevelData.Level, usr.NotifyOnLevelUp, NotifOf.Server));
                                    }

                                    //give role
                                    if (!roleRewards.TryGetValue(usr.GuildId, out var rrews))
                                    {
                                        rrews = uow.GuildConfigs.XpSettingsFor(usr.GuildId).RoleRewards.ToList();
                                        roleRewards.Add(usr.GuildId, rrews);
                                    }

                                    if (!curRewards.TryGetValue(usr.GuildId, out var crews))
                                    {
                                        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.Complete();
                        }

                        await Task.WhenAll(toNotify.Select(async x =>
                        {
                            if (x.NotifOf == NotifOf.Server)
                            {
                                if (x.NotifyType == XpNotificationType.Dm)
                                {
                                    var chan = await x.User.GetOrCreateDMChannelAsync();
                                    if (chan != null)
                                    {
                                        await chan.SendConfirmAsync(_strings.GetText("level_up_dm",
                                                                                     (x.MessageChannel as ITextChannel)?.GuildId,
                                                                                     "xp",
                                                                                     x.User.Mention, Format.Bold(x.Level.ToString()),
                                                                                     Format.Bold((x.MessageChannel as ITextChannel)?.Guild.ToString() ?? "-")))
                                        ;
                                    }
                                }
                                else // channel
                                {
                                    await x.MessageChannel.SendConfirmAsync(_strings.GetText("level_up_channel",
                                                                                             (x.MessageChannel as ITextChannel)?.GuildId,
                                                                                             "xp",
                                                                                             x.User.Mention, Format.Bold(x.Level.ToString())))
                                    ;
                                }
                            }
                            else
                            {
                                IMessageChannel chan;
                                if (x.NotifyType == XpNotificationType.Dm)
                                {
                                    chan = await x.User.GetOrCreateDMChannelAsync();
                                }
                                else // channel
                                {
                                    chan = x.MessageChannel;
                                }
                                await chan.SendConfirmAsync(_strings.GetText("level_up_global",
                                                                             (x.MessageChannel as ITextChannel)?.GuildId,
                                                                             "xp",
                                                                             x.User.Mention, Format.Bold(x.Level.ToString())))
                                ;
                            }
                        }));
                    }
                    catch (Exception ex)
                    {
                        _log.Warn(ex);
                    }
                }
            });

            _clearRewardTimerTokenSource = new CancellationTokenSource();
            var token = _clearRewardTimerTokenSource.Token;

            //just a first line, in order to prevent queries. But since other shards can try to do this too,
            //i'll check in the db too.
            _clearRewardTimer = Task.Run(async() =>
            {
                while (!token.IsCancellationRequested)
                {
                    _rewardedUsers.Clear();

                    await Task.Delay(TimeSpan.FromMinutes(_bc.BotConfig.XpMinutesTimeout));
                }
            }, token);
        }
        private Task UserUpdatedEventHandler(SocketUser iuser, SocketVoiceState before, SocketVoiceState after)
        {
            var user  = (iuser as SocketGuildUser);
            var guild = user?.Guild;

            if (guild == null)
            {
                return(Task.CompletedTask);
            }

            var botUserPerms = guild.CurrentUser.GuildPermissions;

            if (before.VoiceChannel == after.VoiceChannel)
            {
                return(Task.CompletedTask);
            }

            if (!VoicePlusTextCache.Contains(guild.Id))
            {
                return(Task.CompletedTask);
            }

            var _ = Task.Run(async() =>
            {
                try
                {
                    if (!botUserPerms.ManageChannels || !botUserPerms.ManageRoles)
                    {
                        try
                        {
                            await guild.Owner.SendErrorAsync(
                                _strings.GetText("vt_exit",
                                                 guild.Id,
                                                 "Administration".ToLowerInvariant(),
                                                 Format.Bold(guild.Name))).ConfigureAwait(false);
                        }
                        catch
                        {
                            // ignored
                        }
                        using (var uow = _db.UnitOfWork)
                        {
                            uow.GuildConfigs.For(guild.Id, set => set).VoicePlusTextEnabled = false;
                            VoicePlusTextCache.TryRemove(guild.Id);
                            await uow.CompleteAsync().ConfigureAwait(false);
                        }
                        return;
                    }

                    var semaphore = _guildLockObjects.GetOrAdd(guild.Id, (key) => new SemaphoreSlim(1, 1));

                    try
                    {
                        await semaphore.WaitAsync().ConfigureAwait(false);

                        var beforeVch = before.VoiceChannel;
                        if (beforeVch != null)
                        {
                            var beforeRoleName = GetRoleName(beforeVch);
                            var beforeRole     = guild.Roles.FirstOrDefault(x => x.Name == beforeRoleName);
                            if (beforeRole != null)
                            {
                                _log.Info("Removing role " + beforeRoleName + " from user " + user.Username);
                                await user.RemoveRoleAsync(beforeRole).ConfigureAwait(false);
                                await Task.Delay(200).ConfigureAwait(false);
                            }
                        }
                        var afterVch = after.VoiceChannel;
                        if (afterVch != null && guild.AFKChannel?.Id != afterVch.Id)
                        {
                            var roleName  = GetRoleName(afterVch);
                            var roleToAdd = guild.Roles.FirstOrDefault(x => x.Name == roleName) ??
                                            (IRole)await guild.CreateRoleAsync(roleName, GuildPermissions.None).ConfigureAwait(false);

                            ITextChannel textChannel = guild.TextChannels
                                                       .FirstOrDefault(t => t.Name == GetChannelName(afterVch.Name).ToLowerInvariant());
                            if (textChannel == null)
                            {
                                var created = (await guild.CreateTextChannelAsync(GetChannelName(afterVch.Name).ToLowerInvariant()).ConfigureAwait(false));

                                try { await guild.CurrentUser.AddRoleAsync(roleToAdd).ConfigureAwait(false); } catch { /*ignored*/ }
                                await Task.Delay(50).ConfigureAwait(false);
                                await created.AddPermissionOverwriteAsync(roleToAdd, new OverwritePermissions(
                                                                              readMessages: PermValue.Allow,
                                                                              sendMessages: PermValue.Allow))
                                .ConfigureAwait(false);
                                await Task.Delay(50).ConfigureAwait(false);
                                await created.AddPermissionOverwriteAsync(guild.EveryoneRole, new OverwritePermissions(
                                                                              readMessages: PermValue.Deny,
                                                                              sendMessages: PermValue.Deny))
                                .ConfigureAwait(false);
                                await Task.Delay(50).ConfigureAwait(false);
                            }
                            _log.Info("Adding role " + roleToAdd.Name + " to user " + user.Username);
                            await user.AddRoleAsync(roleToAdd).ConfigureAwait(false);
                        }
                    }
                    finally
                    {
                        semaphore.Release();
                    }
                }
                catch (Exception ex)
                {
                    _log.Warn(ex);
                }
            });

            return(Task.CompletedTask);
        }
Exemplo n.º 5
0
        public XpService(CommandHandler cmd, IBotConfigProvider bc,
                         IEnumerable <GuildConfig> allGuildConfigs, IImagesService images,
                         DbService db, NadekoStrings strings, IDataCache cache)
        {
            _db      = db;
            _cmd     = cmd;
            _bc      = bc;
            _images  = images;
            _log     = LogManager.GetCurrentClassLogger();
            _strings = strings;
            _cache   = cache;

            //load settings
            allGuildConfigs   = allGuildConfigs.Where(x => x.XpSettings != null);
            _excludedChannels = allGuildConfigs
                                .ToDictionary(
                x => x.GuildId,
                x => new ConcurrentHashSet <ulong>(x.XpSettings
                                                   .ExclusionList
                                                   .Where(ex => ex.ItemType == ExcludedItemType.Channel)
                                                   .Select(ex => ex.ItemId)
                                                   .Distinct()))
                                .ToConcurrent();

            _excludedRoles = allGuildConfigs
                             .ToDictionary(
                x => x.GuildId,
                x => new ConcurrentHashSet <ulong>(x.XpSettings
                                                   .ExclusionList
                                                   .Where(ex => ex.ItemType == ExcludedItemType.Role)
                                                   .Select(ex => ex.ItemId)
                                                   .Distinct()))
                             .ToConcurrent();

            _excludedServers = new ConcurrentHashSet <ulong>(
                allGuildConfigs.Where(x => x.XpSettings.ServerExcluded)
                .Select(x => x.GuildId));

            //todo 60 move to font provider or somethign
            _fonts = new FontCollection();
            if (Directory.Exists("data/fonts"))
            {
                foreach (var file in Directory.GetFiles("data/fonts"))
                {
                    _fonts.Install(file);
                }
            }

            InitializeFonts();

            _cmd.OnMessageNoTrigger += _cmd_OnMessageNoTrigger;

            updateXpTimer = new Timer(async _ =>
            {
                try
                {
                    var toNotify    = new List <(IMessageChannel MessageChannel, IUser User, int Level, XpNotificationType NotifyType, NotifOf NotifOf)>();
                    var roleRewards = new Dictionary <ulong, List <XpRoleReward> >();

                    var toAddTo = new List <UserCacheItem>();
                    while (_addMessageXp.TryDequeue(out var usr))
                    {
                        toAddTo.Add(usr);
                    }

                    var group = toAddTo.GroupBy(x => (GuildId: x.Guild.Id, User: x.User));
                    if (toAddTo.Count == 0)
                    {
                        return;
                    }

                    using (var uow = _db.UnitOfWork)
                    {
                        foreach (var item in group)
                        {
                            var xp = item.Select(x => bc.BotConfig.XpPerMessage).Sum();

                            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);

                            var oldGuildLevelData = new LevelStats(usr.Xp + usr.AwardedXp);
                            usr.Xp     += xp;
                            du.TotalXp += xp;
                            if (du.Club != null)
                            {
                                du.Club.Xp += xp;
                            }
                            var newGuildLevelData = new LevelStats(usr.Xp + usr.AwardedXp);

                            if (oldGlobalLevelData.Level < newGlobalLevelData.Level)
                            {
                                du.LastLevelUp = DateTime.UtcNow;
                                var first      = item.First();
                                if (du.NotifyOnLevelUp != XpNotificationType.None)
                                {
                                    toNotify.Add((first.Channel, first.User, newGlobalLevelData.Level, du.NotifyOnLevelUp, NotifOf.Global));
                                }
                            }

                            if (oldGuildLevelData.Level < newGuildLevelData.Level)
                            {
                                usr.LastLevelUp = DateTime.UtcNow;
                                //send level up notification
                                var first = item.First();
                                if (usr.NotifyOnLevelUp != XpNotificationType.None)
                                {
                                    toNotify.Add((first.Channel, first.User, newGuildLevelData.Level, usr.NotifyOnLevelUp, NotifOf.Server));
                                }

                                //give role
                                if (!roleRewards.TryGetValue(usr.GuildId, out var rewards))
                                {
                                    rewards = uow.GuildConfigs.XpSettingsFor(usr.GuildId).RoleRewards.ToList();
                                    roleRewards.Add(usr.GuildId, rewards);
                                }

                                var rew = rewards.FirstOrDefault(x => x.Level == newGuildLevelData.Level);
                                if (rew != null)
                                {
                                    var role = first.User.Guild.GetRole(rew.RoleId);
                                    if (role != null)
                                    {
                                        var __ = first.User.AddRoleAsync(role);
                                    }
                                }
                            }
                        }

                        uow.Complete();
                    }

                    await Task.WhenAll(toNotify.Select(async x =>
                    {
                        if (x.NotifOf == NotifOf.Server)
                        {
                            if (x.NotifyType == XpNotificationType.Dm)
                            {
                                var chan = await x.User.GetOrCreateDMChannelAsync().ConfigureAwait(false);
                                if (chan != null)
                                {
                                    await chan.SendConfirmAsync(_strings.GetText("level_up_dm",
                                                                                 (x.MessageChannel as ITextChannel)?.GuildId,
                                                                                 "xp",
                                                                                 x.User.Mention, Format.Bold(x.Level.ToString()),
                                                                                 Format.Bold((x.MessageChannel as ITextChannel)?.Guild.ToString() ?? "-")))
                                    .ConfigureAwait(false);
                                }
                            }
                            else // channel
                            {
                                await x.MessageChannel.SendConfirmAsync(_strings.GetText("level_up_channel",
                                                                                         (x.MessageChannel as ITextChannel)?.GuildId,
                                                                                         "xp",
                                                                                         x.User.Mention, Format.Bold(x.Level.ToString())))
                                .ConfigureAwait(false);
                            }
                        }
                        else
                        {
                            IMessageChannel chan;
                            if (x.NotifyType == XpNotificationType.Dm)
                            {
                                chan = await x.User.GetOrCreateDMChannelAsync().ConfigureAwait(false);
                            }
                            else // channel
                            {
                                chan = x.MessageChannel;
                            }
                            await chan.SendConfirmAsync(_strings.GetText("level_up_global",
                                                                         (x.MessageChannel as ITextChannel)?.GuildId,
                                                                         "xp",
                                                                         x.User.Mention, Format.Bold(x.Level.ToString())))
                            .ConfigureAwait(false);
                        }
                    }));
                }
                catch (Exception ex)
                {
                    _log.Warn(ex);
                }
            }, null, TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(5));


            //just a first line, in order to prevent queries. But since other shards can try to do this too,
            //i'll check in the db too.
            var clearRewardTimer = Task.Run(async() =>
            {
                while (true)
                {
                    _rewardedUsers.Clear();

                    await Task.Delay(TimeSpan.FromMinutes(_bc.BotConfig.XpMinutesTimeout));
                }
            });
        }
Exemplo n.º 6
0
 private string GetText(string text, IGuild guild, params object[] replacements) =>
 _strings.GetText(text, guild?.Id, "Help".ToLowerInvariant(), replacements);
Exemplo n.º 7
0
 private string GetText(ITextChannel ch, string key, params object[] rep)
 => _strings.GetText(key, ch.GuildId, "Games".ToLowerInvariant(), rep);
Exemplo n.º 8
0
        private async Task UpdateLoop()
        {
            while (true)
            {
                await Task.Delay(TimeSpan.FromSeconds(5));

                try
                {
                    var toNotify =
                        new List <(IGuild Guild, IMessageChannel MessageChannel, IUser User, int Level,
                                   XpNotificationLocation 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))
                    {
                        toAddTo.Add(usr);
                    }

                    var group = toAddTo.GroupBy(x => (GuildId: x.Guild.Id, x.User));
                    if (toAddTo.Count == 0)
                    {
                        continue;
                    }

                    using (var uow = _db.GetDbContext())
                    {
                        foreach (var item in group)
                        {
                            var xp = item.Sum(x => x.XpAmount);

                            //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);

                            var globalXp           = du.TotalXp;
                            var oldGlobalLevelData = new LevelStats(globalXp);
                            var newGlobalLevelData = new LevelStats(globalXp + xp);

                            var oldGuildLevelData = new LevelStats(usr.Xp + usr.AwardedXp);
                            usr.Xp     += xp;
                            du.TotalXp += xp;
                            if (du.Club != null)
                            {
                                du.Club.Xp += xp;
                            }
                            var newGuildLevelData = new LevelStats(usr.Xp + usr.AwardedXp);

                            if (oldGlobalLevelData.Level < newGlobalLevelData.Level)
                            {
                                du.LastLevelUp = DateTime.UtcNow;
                                var first = item.First();
                                if (du.NotifyOnLevelUp != XpNotificationLocation.None)
                                {
                                    toNotify.Add((first.Guild, first.Channel, first.User, newGlobalLevelData.Level,
                                                  du.NotifyOnLevelUp, NotifOf.Global));
                                }
                            }

                            if (oldGuildLevelData.Level < newGuildLevelData.Level)
                            {
                                usr.LastLevelUp = DateTime.UtcNow;
                                //send level up notification
                                var first = item.First();
                                if (usr.NotifyOnLevelUp != XpNotificationLocation.None)
                                {
                                    toNotify.Add((first.Guild, first.Channel, first.User, newGuildLevelData.Level,
                                                  usr.NotifyOnLevelUp, NotifOf.Server));
                                }

                                //give role
                                if (!roleRewards.TryGetValue(usr.GuildId, out var rrews))
                                {
                                    rrews = uow.GuildConfigs.XpSettingsFor(usr.GuildId).RoleRewards.ToList();
                                    roleRewards.Add(usr.GuildId, rrews);
                                }

                                if (!curRewards.TryGetValue(usr.GuildId, out var crews))
                                {
                                    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.SaveChanges();
                    }

                    await Task.WhenAll(toNotify.Select(async x =>
                    {
                        if (x.NotifOf == NotifOf.Server)
                        {
                            if (x.NotifyType == XpNotificationLocation.Dm)
                            {
                                var chan = await x.User.GetOrCreateDMChannelAsync();
                                if (chan != null)
                                {
                                    await chan.SendConfirmAsync(_strings.GetText("level_up_dm",
                                                                                 x.Guild.Id,
                                                                                 "xp",
                                                                                 x.User.Mention, Format.Bold(x.Level.ToString()),
                                                                                 Format.Bold(x.Guild.ToString() ?? "-")));
                                }
                            }
                            else if (x.MessageChannel != null) // channel
                            {
                                await x.MessageChannel.SendConfirmAsync(_strings.GetText("level_up_channel",
                                                                                         x.Guild.Id,
                                                                                         "xp",
                                                                                         x.User.Mention, Format.Bold(x.Level.ToString())));
                            }
                        }
                        else
                        {
                            IMessageChannel chan;
                            if (x.NotifyType == XpNotificationLocation.Dm)
                            {
                                chan = await x.User.GetOrCreateDMChannelAsync();
                            }
                            else // channel
                            {
                                chan = x.MessageChannel;
                            }

                            await chan.SendConfirmAsync(_strings.GetText("level_up_global",
                                                                         x.Guild.Id,
                                                                         "xp",
                                                                         x.User.Mention, Format.Bold(x.Level.ToString())));
                        }
                    }));
                }
                catch (Exception ex)
                {
                    _log.Warn(ex);
                }
            }
        }
 private string GetText(IGuild guild, string key, params object[] replacements) =>
 _strings.GetText(key, guild.Id, "Administration".ToLowerInvariant(), replacements);
Exemplo n.º 10
0
 private string GetText(ulong gid, string key, params object[] rep)
 => _strings.GetText(key, gid, "Games".ToLowerInvariant(), rep);
Exemplo n.º 11
0
 private string GetText(string key, params object[] replacements)
 => _strings.GetText(key,
                     _guild.Id,
                     "Games".ToLowerInvariant(),
                     replacements);
Exemplo n.º 12
0
 public string GetText(FollowedStream fs, string key, params object[] replacements) =>
 _strings.GetText(key,
                  fs.GuildId,
                  "Searches".ToLowerInvariant(),
                  replacements);
Exemplo n.º 13
0
        public async Task <bool> RunBehavior(DiscordSocketClient client, IGuild guild, IUserMessage msg)
        {
            // maybe this message is a custom reaction
            var cr = await Task.Run(() => TryGetCustomReaction(msg)).ConfigureAwait(false);

            if (cr != null)
            {
                try
                {
                    if (_gperm.BlockedModules.Contains("ActualCustomReactions"))
                    {
                        return(true);
                    }

                    if (guild is SocketGuild sg)
                    {
                        var pc = _perms.GetCacheFor(guild.Id);
                        if (!pc.Permissions.CheckPermissions(msg, cr.Trigger, "ActualCustomReactions",
                                                             out int index))
                        {
                            if (pc.Verbose)
                            {
                                var returnMsg = _strings.GetText("trigger", guild.Id,
                                                                 "Permissions".ToLowerInvariant(),
                                                                 index + 1,
                                                                 Format.Bold(pc.Permissions[index].GetCommand(_cmd.GetPrefix(guild),
                                                                                                              (SocketGuild)guild)));
                                try { await msg.Channel.SendErrorAsync(returnMsg).ConfigureAwait(false); } catch { }
                                _log.Info(returnMsg);
                            }
                            return(true);
                        }
                    }
                    var sentMsg = await cr.Send(msg, _client, this).ConfigureAwait(false);


                    var reactions = cr.GetReactions();
                    foreach (var reaction in reactions)
                    {
                        try
                        {
                            await sentMsg.AddReactionAsync(reaction.ToIEmote());
                        }
                        catch
                        {
                            _log.Warn($"Unable to add reactions to message {0} in server {1}");
                        }
                        finally
                        {
                            await Task.Delay(100);
                        }
                    }

                    if (cr.AutoDeleteTrigger)
                    {
                        try { await msg.DeleteAsync().ConfigureAwait(false); } catch { }
                    }
                    return(true);
                }
                catch (Exception ex)
                {
                    _log.Warn(ex.Message);
                }
            }
            return(false);
        }
Exemplo n.º 14
0
        public async Task <bool> TryBlockLate(DiscordSocketClient client, IUserMessage msg, IGuild guild, IMessageChannel channel, IUser user, string moduleName, string commandName)
        {
            await Task.Yield();

            if (guild == null)
            {
                return(false);
            }
            else
            {
                var resetCommand = commandName == "resetperms";

                PermissionCache pc = GetCacheFor(guild.Id);
                if (!resetCommand && !pc.Permissions.CheckPermissions(msg, commandName, moduleName, out int index))
                {
                    if (pc.Verbose)
                    {
                        try { await channel.SendErrorAsync(_strings.GetText("trigger", guild.Id, "Permissions".ToLowerInvariant(), index + 1, Format.Bold(pc.Permissions[index].GetCommand(_cmd.GetPrefix(guild), (SocketGuild)guild)))).ConfigureAwait(false); } catch { }
                    }
                    return(true);
                }


                if (moduleName == nameof(Permissions))
                {
                    if (!(user is IGuildUser guildUser))
                    {
                        return(true);
                    }

                    if (guildUser.GuildPermissions.Administrator)
                    {
                        return(false);
                    }

                    var permRole = pc.PermRole;
                    if (!ulong.TryParse(permRole, out var rid))
                    {
                        rid = 0;
                    }
                    string returnMsg;
                    IRole  role;
                    if (string.IsNullOrWhiteSpace(permRole) || (role = guild.GetRole(rid)) == null)
                    {
                        returnMsg = $"You need Admin permissions in order to use permission commands.";
                        if (pc.Verbose)
                        {
                            try { await channel.SendErrorAsync(returnMsg).ConfigureAwait(false); } catch { }
                        }

                        return(true);
                    }
                    else if (!guildUser.RoleIds.Contains(rid))
                    {
                        returnMsg = $"You need the {Format.Bold(role.Name)} role in order to use permission commands.";
                        if (pc.Verbose)
                        {
                            try { await channel.SendErrorAsync(returnMsg).ConfigureAwait(false); } catch { }
                        }

                        return(true);
                    }
                    return(false);
                }
            }

            return(false);
        }