public MusicService(DiscordSocketClient client, IGoogleApiService google, EvilMortyStrings strings, ILocalization localization, DbService db, SoundCloudApiService sc, IBotCredentials creds, EvilMortyBot bot) { _client = client; _google = google; _strings = strings; _localization = localization; _db = db; _sc = sc; _creds = creds; _log = LogManager.GetCurrentClassLogger(); _musicSettings = bot.AllGuildConfigs.ToDictionary(x => x.GuildId, x => x.MusicSettings) .ToConcurrent(); _client.LeftGuild += _client_LeftGuild; try { Directory.Delete(MusicDataPath, true); } catch { } _defaultVolumes = new ConcurrentDictionary <ulong, float>( bot.AllGuildConfigs .ToDictionary(x => x.GuildId, x => x.DefaultMusicVolume)); AutoDcServers = new ConcurrentHashSet <ulong>(bot.AllGuildConfigs.Where(x => x.AutoDcFromVc).Select(x => x.GuildId)); Directory.CreateDirectory(MusicDataPath); }
public HelpService(IBotConfigProvider bc, CommandHandler ch, EvilMortyStrings strings) { _bc = bc; _ch = ch; _strings = strings; _log = LogManager.GetCurrentClassLogger(); }
public SelfService(DiscordSocketClient client, EvilMortyBot bot, CommandHandler cmdHandler, DbService db, IBotConfigProvider bc, ILocalization localization, EvilMortyStrings strings, IBotCredentials creds, IDataCache cache) { _redis = cache.Redis; _bot = bot; _cmdHandler = cmdHandler; _db = db; _log = LogManager.GetCurrentClassLogger(); _localization = localization; _strings = strings; _client = client; _creds = creds; _bc = bc; _cache = cache; _imgs = cache.LocalImages; var sub = _redis.GetSubscriber(); sub.Subscribe(_creds.RedisKey() + "_reload_images", delegate { _imgs.Reload(); }, CommandFlags.FireAndForget); sub.Subscribe(_creds.RedisKey() + "_reload_bot_config", delegate { _bc.Reload(); }, CommandFlags.FireAndForget); Task.Run(async() => { await bot.Ready.Task.ConfigureAwait(false); foreach (var cmd in bc.BotConfig.StartupCommands) { var prefix = _cmdHandler.GetPrefix(cmd.GuildId); //if someone already has .die as their startup command, ignore it if (cmd.CommandText.StartsWith(prefix + "die")) { continue; } await cmdHandler.ExecuteExternal(cmd.GuildId, cmd.ChannelId, cmd.CommandText); await Task.Delay(400).ConfigureAwait(false); } }); Task.Run(async() => { await bot.Ready.Task.ConfigureAwait(false); await Task.Delay(5000).ConfigureAwait(false); if (client.ShardId == 0) { await LoadOwnerChannels().ConfigureAwait(false); } }); }
public CustomReactionsService(PermissionService perms, DbService db, EvilMortyStrings strings, DiscordSocketClient client, CommandHandler cmd, IBotConfigProvider bc, IUnitOfWork uow, IDataCache cache, GlobalPermissionService gperm, EvilMortyBot bot) { _log = LogManager.GetCurrentClassLogger(); _db = db; _client = client; _perms = perms; _cmd = cmd; _bc = bc; _strings = strings; _cache = cache; _gperm = gperm; var sub = _cache.Redis.GetSubscriber(); sub.Subscribe(_client.CurrentUser.Id + "_gcr.added", (ch, msg) => { Array.Resize(ref GlobalReactions, GlobalReactions.Length + 1); GlobalReactions[GlobalReactions.Length - 1] = JsonConvert.DeserializeObject <CustomReaction>(msg); }, StackExchange.Redis.CommandFlags.FireAndForget); sub.Subscribe(_client.CurrentUser.Id + "_gcr.deleted", (ch, msg) => { var id = int.Parse(msg); GlobalReactions = GlobalReactions.Where(cr => cr?.Id != id).ToArray(); }, StackExchange.Redis.CommandFlags.FireAndForget); sub.Subscribe(_client.CurrentUser.Id + "_gcr.edited", (ch, msg) => { var obj = new { Id = 0, Res = "", Ad = false, Dm = false, Ca = false }; obj = JsonConvert.DeserializeAnonymousType(msg, obj); var gcr = GlobalReactions.FirstOrDefault(x => x.Id == obj.Id); if (gcr != null) { gcr.Response = obj.Res; gcr.AutoDeleteTrigger = obj.Ad; gcr.DmResponse = obj.Dm; gcr.ContainsAnywhere = obj.Ca; } }, StackExchange.Redis.CommandFlags.FireAndForget); var items = uow.CustomReactions.GetGlobalAndFor(bot.AllGuildConfigs.Select(x => (long)x.GuildId)); GuildReactions = new ConcurrentDictionary <ulong, CustomReaction[]>(items .Where(g => g.GuildId != null && g.GuildId != 0) .GroupBy(k => k.GuildId.Value) .ToDictionary(g => g.Key, g => g.ToArray())); GlobalReactions = items.Where(g => g.GuildId == null || g.GuildId == 0).ToArray(); bot.JoinedGuild += Bot_JoinedGuild; _client.LeftGuild += _client_LeftGuild; }
public ChatterBotService(DiscordSocketClient client, PermissionService perms, EvilMortyBot bot, CommandHandler cmd, EvilMortyStrings strings, IBotCredentials creds) { _client = client; _log = LogManager.GetCurrentClassLogger(); _perms = perms; _cmd = cmd; _strings = strings; _creds = creds; ChatterBotGuilds = new ConcurrentDictionary <ulong, Lazy <IChatterBotSession> >( bot.AllGuildConfigs .Where(gc => gc.CleverbotEnabled) .ToDictionary(gc => gc.GuildId, gc => new Lazy <IChatterBotSession>(() => CreateSession(), true))); }
public TriviaGame(EvilMortyStrings strings, DiscordSocketClient client, IBotConfigProvider bc, IDataCache cache, ICurrencyService cs, IGuild guild, ITextChannel channel, TriviaOptions options) { _log = LogManager.GetCurrentClassLogger(); _cache = cache; _questionPool = new TriviaQuestionPool(_cache); _strings = strings; _client = client; _bc = bc; _cs = cs; _options = options; Guild = guild; Channel = channel; }
public PollService(DiscordSocketClient client, EvilMortyStrings strings, DbService db, EvilMortyStrings strs, IUnitOfWork uow) { _log = LogManager.GetCurrentClassLogger(); _client = client; _strings = strings; _db = db; _strs = strs; ActivePolls = uow.Polls.GetAllPolls() .ToDictionary(x => x.GuildId, x => { var pr = new PollRunner(db, x); pr.OnVoted += Pr_OnVoted; return(pr); }) .ToConcurrent(); }
public TicTacToe(EvilMortyStrings strings, DiscordSocketClient client, ITextChannel channel, IGuildUser firstUser, Options options) { _channel = channel; _strings = strings; _client = client; _options = options; _users = new[] { firstUser, null }; _state = new int?[, ] { { null, null, null }, { null, null, null }, { null, null, null }, }; _phase = Phase.Starting; _moveLock = new SemaphoreSlim(1, 1); }
public PermissionService(DiscordSocketClient client, DbService db, CommandHandler cmd, EvilMortyStrings strings) { _db = db; _cmd = cmd; _strings = strings; using (var uow = _db.UnitOfWork) { foreach (var x in uow.GuildConfigs.Permissionsv2ForAll(client.Guilds.ToArray().Select(x => (long)x.Id).ToList())) { Cache.TryAdd(x.GuildId, new PermissionCache() { Verbose = x.VerbosePermissions, PermRole = x.PermissionRole, Permissions = new PermissionsCollection <Permissionv2>(x.Permissions) }); } } }
public GamesService(CommandHandler cmd, IBotConfigProvider bc, EvilMortyBot bot, EvilMortyStrings strings, IDataCache data, CommandHandler cmdHandler, ICurrencyService cs) { _bc = bc; _cmd = cmd; _strings = strings; _images = data.LocalImages; _cmdHandler = cmdHandler; _log = LogManager.GetCurrentClassLogger(); _rng = new EvilMortyRandom(); _cs = cs; //8ball EightBallResponses = _bc.BotConfig.EightBallResponses.Select(ebr => ebr.Text).ToImmutableArray(); //girl ratings _t = new Timer((_) => { GirlRatings.Clear(); }, null, TimeSpan.FromDays(1), TimeSpan.FromDays(1)); //plantpick _cmd.OnMessageNoTrigger += PotentialFlowerGeneration; GenerationChannels = new ConcurrentHashSet <ulong>(bot .AllGuildConfigs .SelectMany(c => c.GenerateCurrencyChannelIds.Select(obj => obj.ChannelId))); try { TypingArticles = JsonConvert.DeserializeObject <List <TypingArticle> >(File.ReadAllText(TypingArticlesPath)); } catch (Exception ex) { _log.Warn("Error while loading typing articles {0}", ex.ToString()); TypingArticles = new List <TypingArticle>(); } }
public XpService(CommandHandler cmd, IBotConfigProvider bc, EvilMortyBot bot, DbService db, EvilMortyStrings 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); }
public LogCommandService(DiscordSocketClient client, EvilMortyStrings strings, EvilMortyBot bot, DbService db, MuteService mute, ProtectionService prot, GuildTimezoneService tz) { _client = client; _log = LogManager.GetCurrentClassLogger(); _strings = strings; _db = db; _mute = mute; _prot = prot; _tz = tz; GuildLogSettings = bot.AllGuildConfigs .ToDictionary(g => g.GuildId, g => g.LogSetting) .ToConcurrent(); _timerReference = new Timer(async(state) => { try { var keys = PresenceUpdates.Keys.ToList(); await Task.WhenAll(keys.Select(key => { if (PresenceUpdates.TryRemove(key, out var msgs)) { var title = GetText(key.Guild, "presence_updates"); var desc = string.Join(Environment.NewLine, msgs); return(key.SendConfirmAsync(title, desc.TrimTo(2048))); } return(Task.CompletedTask); })); } catch (Exception ex) { _log.Warn(ex); } }, null, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); //_client.MessageReceived += _client_MessageReceived; _client.MessageUpdated += _client_MessageUpdated; _client.MessageDeleted += _client_MessageDeleted; _client.UserBanned += _client_UserBanned; _client.UserUnbanned += _client_UserUnbanned; _client.UserJoined += _client_UserJoined; _client.UserLeft += _client_UserLeft; //_client.UserPresenceUpdated += _client_UserPresenceUpdated; _client.UserVoiceStateUpdated += _client_UserVoiceStateUpdated; _client.UserVoiceStateUpdated += _client_UserVoiceStateUpdated_TTS; _client.GuildMemberUpdated += _client_GuildUserUpdated; #if !GLOBAL_NADEKO _client.UserUpdated += _client_UserUpdated; #endif _client.ChannelCreated += _client_ChannelCreated; _client.ChannelDestroyed += _client_ChannelDestroyed; _client.ChannelUpdated += _client_ChannelUpdated; _mute.UserMuted += MuteCommands_UserMuted; _mute.UserUnmuted += MuteCommands_UserUnmuted; _prot.OnAntiProtectionTriggered += TriggeredAntiProtection; }