Exemple #1
0
        // forwards dms
        public async Task LateExecute(DiscordSocketClient client, IGuild guild, IUserMessage msg)
        {
            if (msg.Channel is IDMChannel && ForwardDMs && ownerChannels.Any())
            {
                var title = _strings.GetText("dm_from",
                                             _localization.DefaultCultureInfo,
                                             "Administration".ToLowerInvariant()) +
                            $" [{msg.Author}]({msg.Author.Id})";

                var attachamentsTxt = _strings.GetText("attachments",
                                                       _localization.DefaultCultureInfo,
                                                       "Administration".ToLowerInvariant());

                var toSend = msg.Content;

                if (msg.Attachments.Count > 0)
                {
                    toSend += $"\n\n{Format.Code(attachamentsTxt)}:\n" +
                              string.Join("\n", msg.Attachments.Select(a => a.ProxyUrl));
                }

                if (ForwardDMsToAllOwners)
                {
                    var allOwnerChannels = ownerChannels.Values;

                    foreach (var ownerCh in allOwnerChannels.Where(ch => ch.Recipient.Id != msg.Author.Id))
                    {
                        try
                        {
                            await ownerCh.SendConfirmAsync(title, toSend).ConfigureAwait(false);
                        }
                        catch
                        {
                            _log.Warn("Can't contact owner with id {0}", ownerCh.Recipient.Id);
                        }
                    }
                }
                else
                {
                    var firstOwnerChannel = ownerChannels.Values.First();
                    if (firstOwnerChannel.Recipient.Id != msg.Author.Id)
                    {
                        try
                        {
                            await firstOwnerChannel.SendConfirmAsync(title, toSend).ConfigureAwait(false);
                        }
                        catch
                        {
                            // ignored
                        }
                    }
                }
            }
        }
Exemple #2
0
        private async Task Pr_OnVoted(IUserMessage msg, IGuildUser usr)
        {
            var toDelete = await msg.Channel.SendConfirmAsync(_strs.GetText("poll_voted", usr.Guild.Id, "Games".ToLowerInvariant(), Format.Bold(usr.ToString())))
                           .ConfigureAwait(false);

            toDelete.DeleteAfter(5);
            try { await msg.DeleteAsync().ConfigureAwait(false); } catch { }
        }
Exemple #3
0
        public async Task <bool> TryExecuteEarly(DiscordSocketClient client, IGuild guild, IUserMessage usrMsg)
        {
            if (!(guild is SocketGuild sg))
            {
                return(false);
            }
            try
            {
                var message = PrepareMessage(usrMsg, out IChatterBotSession cbs);
                if (message == null || cbs == null)
                {
                    return(false);
                }

                var pc = _perms.GetCache(guild.Id);
                if (!pc.Permissions.CheckPermissions(usrMsg,
                                                     "cleverbot",
                                                     "Games".ToLowerInvariant(),
                                                     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 usrMsg.Channel.SendErrorAsync(returnMsg).ConfigureAwait(false); } catch { }
                        _log.Info(returnMsg);
                    }
                    return(true);
                }

                var cleverbotExecuted = await TryAsk(cbs, (ITextChannel)usrMsg.Channel, message).ConfigureAwait(false);

                if (cleverbotExecuted)
                {
                    _log.Info($@"CleverBot Executed
Server: {guild.Name} [{guild.Id}]
Channel: {usrMsg.Channel?.Name} [{usrMsg.Channel?.Id}]
UserId: {usrMsg.Author} [{usrMsg.Author.Id}]
Message: {usrMsg.Content}");
                    return(true);
                }
            }
            catch (Exception ex) { _log.Warn(ex, "Error in cleverbot"); }
            return(false);
        }
Exemple #4
0
 private string GetText(string key, params object[] replacements) =>
 _strings.GetText(key,
                  _channel.GuildId,
                  typeof(Games).Name.ToLowerInvariant(),
                  replacements);
Exemple #5
0
        public XpService(CommandHandler cmd, IBotConfigProvider bc,
                         Kotocorn bot, DbService db, KotocornStrings strings, IDataCache cache,
                         FontProvider fonts, IBotCredentials creds, ICurrencyService cs)
        {
            _db      = db;
            _cmd     = cmd;
            _bc      = bc;
            _images  = cache.LocalImages;
            _log     = LogManager.GetCurrentClassLogger();
            _strings = strings;
            _cache   = cache;
            _fonts   = fonts;
            _creds   = creds;
            _cs      = cs;

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

            _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 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, 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();

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

            _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);
        }
Exemple #6
0
 private string GetText(string text, IGuild guild, params object[] replacements) =>
 _strings.GetText(text, guild?.Id, "Help".ToLowerInvariant(), replacements);
Exemple #7
0
 private string GetText(IGuild guild, string key, params object[] replacements) =>
 _strings.GetText(key, guild.Id, "Administration".ToLowerInvariant(), replacements);
Exemple #8
0
 private string GetText(ITextChannel ch, string key, params object[] rep)
 => _strings.GetText(key, ch.GuildId, "Games".ToLowerInvariant(), rep);
Exemple #9
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;
            }));
        }
Exemple #10
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 = GetCache(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))
                {
                    var guildUser = user as IGuildUser;
                    if (guildUser == null)
                    {
                        return(true);
                    }

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

                    var permRole = pc.PermRole;
                    ulong.TryParse(permRole, out var rid);
                    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);
        }