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 SelfCommands(DbService db, EvilMortyBot bot, DiscordSocketClient client, IBotCredentials creds, IDataCache cache) { _client = client; _bot = bot; _creds = creds; }
public FilterService(DiscordSocketClient _client, EvilMortyBot bot) { _log = LogManager.GetCurrentClassLogger(); InviteFilteringServers = new ConcurrentHashSet <ulong>(bot.AllGuildConfigs.Where(gc => gc.FilterInvites).Select(gc => gc.GuildId)); InviteFilteringChannels = new ConcurrentHashSet <ulong>(bot.AllGuildConfigs.SelectMany(gc => gc.FilterInvitesChannelIds.Select(fci => fci.ChannelId))); var dict = bot.AllGuildConfigs.ToDictionary(gc => gc.GuildId, gc => new ConcurrentHashSet <string>(gc.FilteredWords.Select(fw => fw.Word))); ServerFilteredWords = new ConcurrentDictionary <ulong, ConcurrentHashSet <string> >(dict); var serverFiltering = bot.AllGuildConfigs.Where(gc => gc.FilterWords); WordFilteringServers = new ConcurrentHashSet <ulong>(serverFiltering.Select(gc => gc.GuildId)); WordFilteringChannels = new ConcurrentHashSet <ulong>(bot.AllGuildConfigs.SelectMany(gc => gc.FilterWordsChannelIds.Select(fwci => fwci.ChannelId))); //LinkFilteringServers = new ConcurrentHashSet<ulong>(bot.AllGuildConfigs.Where(gc => gc.FilterLinks).Select(x => x.GuildId)); _client.MessageUpdated += (oldData, newMsg, channel) => { var _ = Task.Run(() => { var guild = (channel as ITextChannel)?.Guild; var usrMsg = newMsg as IUserMessage; if (guild == null || usrMsg == null) { return(Task.CompletedTask); } return(TryBlockEarly(guild, usrMsg)); }); return(Task.CompletedTask); }; }
public StreamRoleService(DiscordSocketClient client, DbService db, EvilMortyBot bot) { this._log = LogManager.GetCurrentClassLogger(); this._db = db; this._client = client; guildSettings = bot.AllGuildConfigs .ToDictionary(x => x.GuildId, x => x.StreamRole) .Where(x => x.Value != null && x.Value.Enabled) .ToConcurrent(); _client.GuildMemberUpdated += Client_GuildMemberUpdated; var _ = Task.Run(async() => { try { await Task.WhenAll(client.Guilds.Select(g => RescanUsers(g))).ConfigureAwait(false); } catch { // ignored } }); }
public Utility(EvilMortyBot evilMorty, DiscordSocketClient client, IStatsService stats, IBotCredentials creds, DbService db) { _client = client; _stats = stats; _creds = creds; _bot = evilMorty; _db = db; }
//commandmap public CommandMapService(EvilMortyBot bot) { _log = LogManager.GetCurrentClassLogger(); AliasMaps = new ConcurrentDictionary <ulong, ConcurrentDictionary <string, string> >( bot.AllGuildConfigs.ToDictionary( x => x.GuildId, x => new ConcurrentDictionary <string, string>(x.CommandAliases .Distinct(new CommandAliasEqualityComparer()) .ToDictionary(ca => ca.Trigger, ca => ca.Mapping)))); }
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 GameVoiceChannelService(DiscordSocketClient client, DbService db, EvilMortyBot bot) { _log = LogManager.GetCurrentClassLogger(); _db = db; _client = client; GameVoiceChannels = new ConcurrentHashSet <ulong>( bot.AllGuildConfigs.Where(gc => gc.GameVoiceChannel != null) .Select(gc => gc.GameVoiceChannel.Value)); _client.UserVoiceStateUpdated += Client_UserVoiceStateUpdated; }
public VerboseErrorsService(EvilMortyBot bot, DbService db, CommandHandler ch, HelpService hs) { _db = db; _ch = ch; _hs = hs; _ch.CommandErrored += LogVerboseError; guildsEnabled = new ConcurrentHashSet <ulong>(bot .AllGuildConfigs .Where(x => x.VerboseErrors) .Select(x => x.GuildId)); }
public FF14Service(DiscordSocketClient client, DbService db, EvilMortyBot bot, IDataCache cache, FontProvider fonts) { Http = new HttpClient(); Http.AddFakeHeaders(); _client = client; _db = db; _log = LogManager.GetCurrentClassLogger(); _imgs = cache.LocalImages; _cache = cache; _fonts = fonts; }
public RoleCommandsService(DiscordSocketClient client, DbService db, EvilMortyBot bot) { _log = LogManager.GetCurrentClassLogger(); _db = db; _client = client; #if !GLOBAL_NADEKO _models = bot.AllGuildConfigs.ToDictionary(x => x.GuildId, x => x.ReactionRoleMessages) .ToConcurrent(); _client.ReactionAdded += _client_ReactionAdded; _client.ReactionRemoved += _client_ReactionRemoved; #endif }
public GreetSettingsService(DiscordSocketClient client, EvilMortyBot bot, DbService db) { _db = db; _client = client; _log = LogManager.GetCurrentClassLogger(); GuildConfigsCache = new ConcurrentDictionary <ulong, GreetSettings>( bot.AllGuildConfigs .ToDictionary(g => g.GuildId, GreetSettings.Create)); _client.UserJoined += UserJoined; _client.UserLeft += UserLeft; 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 ProtectionService(DiscordSocketClient client, EvilMortyBot bot, MuteService mute, DbService db) { _log = LogManager.GetCurrentClassLogger(); _client = client; _mute = mute; _db = db; _bot = bot; Initialize(); _client.MessageReceived += HandleAntiSpam; _client.UserJoined += HandleAntiRaid; _bot.JoinedGuild += _bot_JoinedGuild; _client.LeftGuild += _client_LeftGuild; }
public AdministrationService(EvilMortyBot bot, CommandHandler cmdHandler, DbService db) { _log = LogManager.GetCurrentClassLogger(); _bot = bot; _db = db; DeleteMessagesOnCommand = new ConcurrentHashSet <ulong>(bot.AllGuildConfigs .Where(g => g.DeleteMessageOnCommand) .Select(g => g.GuildId)); DeleteMessagesOnCommandChannels = new ConcurrentDictionary <ulong, bool>(bot.AllGuildConfigs .SelectMany(x => x.DelMsgOnCmdChannels) .ToDictionary(x => x.ChannelId, x => x.State) .ToConcurrent()); cmdHandler.CommandExecuted += DelMsgOnCmd_Handler; }
public GuildTimezoneService(DiscordSocketClient client, EvilMortyBot bot, DbService db) { _timezones = bot.AllGuildConfigs .Select(GetTimzezoneTuple) .Where(x => x.Timezone != null) .ToDictionary(x => x.GuildId, x => x.Timezone) .ToConcurrent(); var curUser = client.CurrentUser; if (curUser != null) { AllServices.TryAdd(curUser.Id, this); } _db = db; bot.JoinedGuild += Bot_JoinedGuild; }
public WebMiningService(EvilMortyBot evilMorty, IBotCredentials creds, DbService db, CurrencyService cs) { _log = LogManager.GetCurrentClassLogger(); _creds = creds; _http = new HttpClient(); _db = db; _cs = cs; if (!string.IsNullOrWhiteSpace(_creds.MiningProxyCreds)) { var byteArray = Encoding.ASCII.GetBytes(_creds.MiningProxyCreds); _http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray)); } if (evilMorty.Client.ShardId == 0) { _reqTask = RequestAsync(); } }
public Localization(IBotConfigProvider bcp, EvilMortyBot bot, DbService db) { _log = LogManager.GetCurrentClassLogger(); var cultureInfoNames = bot.AllGuildConfigs.ToDictionary(x => x.GuildId, x => x.Locale); var defaultCulture = bcp.BotConfig.Locale; _db = db; if (string.IsNullOrWhiteSpace(defaultCulture)) { DefaultCultureInfo = new CultureInfo("en-US"); } else { try { DefaultCultureInfo = new CultureInfo(defaultCulture); } catch { _log.Warn("Unable to load default bot's locale/language. Using en-US."); DefaultCultureInfo = new CultureInfo("en-US"); } } GuildCultureInfos = new ConcurrentDictionary <ulong, CultureInfo>(cultureInfoNames.ToDictionary(x => x.Key, x => { CultureInfo cultureInfo = null; try { if (x.Value == null) { return(null); } cultureInfo = new CultureInfo(x.Value); } catch { } return(cultureInfo); }).Where(x => x.Value != null)); }
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 FeedsService(EvilMortyBot bot, DbService db, DiscordSocketClient client) { _db = db; _subs = bot .AllGuildConfigs .SelectMany(x => x.FeedSubs) .GroupBy(x => x.Url) .ToDictionary(x => x.Key, x => x.ToHashSet()) .ToConcurrent(); _client = client; foreach (var kvp in _subs) { // to make sure rss feeds don't post right away, but // only the updates from after the bot has started _lastPosts.AddOrUpdate(kvp.Key, DateTime.UtcNow, (k, old) => DateTime.UtcNow); } #if !GLOBAL_NADEKO var _ = Task.Run(TrackFeeds); #endif }
public MuteService(DiscordSocketClient client, EvilMortyBot bot, DbService db) { _client = client; _db = db; GuildMuteRoles = bot .AllGuildConfigs .Where(c => !string.IsNullOrWhiteSpace(c.MuteRoleName)) .ToDictionary(c => c.GuildId, c => c.MuteRoleName) .ToConcurrent(); MutedUsers = new ConcurrentDictionary <ulong, ConcurrentHashSet <ulong> >(bot .AllGuildConfigs .ToDictionary( k => k.GuildId, v => new ConcurrentHashSet <ulong>(v.MutedUsers.Select(m => m.UserId)) )); foreach (var conf in bot.AllGuildConfigs) { foreach (var x in conf.UnmuteTimers) { TimeSpan after; if (x.UnmuteAt - TimeSpan.FromMinutes(2) <= DateTime.UtcNow) { after = TimeSpan.FromMinutes(2); } else { after = x.UnmuteAt - DateTime.UtcNow; } StartUnmuteTimer(conf.GuildId, x.UserId, after); } } _client.UserJoined += Client_UserJoined; }
public CommandHandler(DiscordSocketClient client, DbService db, IBotConfigProvider bcp, CommandService commandService, IBotCredentials credentials, EvilMortyBot bot) { _client = client; _commandService = commandService; _creds = credentials; _bot = bot; _db = db; _bcp = bcp; _log = LogManager.GetCurrentClassLogger(); _clearUsersOnShortCooldown = new Timer(_ => { UsersOnShortCooldown.Clear(); }, null, GlobalCommandsCooldown, GlobalCommandsCooldown); DefaultPrefix = bcp.BotConfig.DefaultPrefix; _prefixes = bot.AllGuildConfigs .Where(x => x.Prefix != null) .ToDictionary(x => x.GuildId, x => x.Prefix) .ToConcurrent(); }
public MessageRepeaterService(EvilMortyBot bot, DiscordSocketClient client) { var _ = Task.Run(async() => { await bot.Ready.Task.ConfigureAwait(false); Repeaters = new ConcurrentDictionary <ulong, ConcurrentQueue <RepeatRunner> >( bot.AllGuildConfigs .Select(gc => { var guild = client.GetGuild(gc.GuildId); if (guild == null) { return(0, null); } return(gc.GuildId, new ConcurrentQueue <RepeatRunner>(gc.GuildRepeaters .Select(gr => new RepeatRunner(client, guild, gr)) .Where(x => x.Guild != null))); }) .Where(x => x.Item2 != null) .ToDictionary(x => x.GuildId, x => x.Item2)); RepeaterReady = true; }); }
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 SearchesService(DiscordSocketClient client, IGoogleApiService google, DbService db, EvilMortyBot bot, IDataCache cache, FontProvider fonts) { Http = new HttpClient(); Http.AddFakeHeaders(); _client = client; _google = google; _db = db; _log = LogManager.GetCurrentClassLogger(); _imgs = cache.LocalImages; _cache = cache; _fonts = fonts; _blacklistedTags = new ConcurrentDictionary <ulong, HashSet <string> >( bot.AllGuildConfigs.ToDictionary( x => x.GuildId, x => new HashSet <string>(x.NsfwBlacklistedTags.Select(y => y.Tag)))); //translate commands _client.MessageReceived += (msg) => { var _ = Task.Run(async() => { try { var umsg = msg as SocketUserMessage; if (umsg == null) { return; } if (!TranslatedChannels.TryGetValue(umsg.Channel.Id, out var autoDelete)) { return; } var key = new UserChannelPair() { UserId = umsg.Author.Id, ChannelId = umsg.Channel.Id, }; if (!UserLanguages.TryGetValue(key, out string langs)) { return; } var text = await Translate(langs, umsg.Resolve(TagHandling.Ignore)) .ConfigureAwait(false); if (autoDelete) { try { await umsg.DeleteAsync().ConfigureAwait(false); } catch { } } await umsg.Channel.SendConfirmAsync($"{umsg.Author.Mention} `:` " + text.Replace("<@ ", "<@").Replace("<@! ", "<@!")).ConfigureAwait(false); } catch { } }); return(Task.CompletedTask); }; //joke commands if (File.Exists("data/wowjokes.json")) { WowJokes = JsonConvert.DeserializeObject <List <WoWJoke> >(File.ReadAllText("data/wowjokes.json")); } else { _log.Warn("data/wowjokes.json is missing. WOW Jokes are not loaded."); } if (File.Exists("data/magicitems.json")) { MagicItems = JsonConvert.DeserializeObject <List <MagicItem> >(File.ReadAllText("data/magicitems.json")); } else { _log.Warn("data/magicitems.json is missing. Magic items are not loaded."); } }
public StatsService(DiscordSocketClient client, CommandHandler cmdHandler, IBotCredentials creds, EvilMortyBot evilMorty, IDataCache cache) { _log = LogManager.GetCurrentClassLogger(); _client = client; _creds = creds; _redis = cache.Redis; _started = DateTime.UtcNow; _client.MessageReceived += _ => Task.FromResult(Interlocked.Increment(ref _messageCounter)); cmdHandler.CommandExecuted += (_, e) => Task.FromResult(Interlocked.Increment(ref _commandsRan)); _client.ChannelCreated += (c) => { var _ = Task.Run(() => { if (c is ITextChannel) { Interlocked.Increment(ref _textChannels); } else if (c is IVoiceChannel) { Interlocked.Increment(ref _voiceChannels); } }); return(Task.CompletedTask); }; _client.ChannelDestroyed += (c) => { var _ = Task.Run(() => { if (c is ITextChannel) { Interlocked.Decrement(ref _textChannels); } else if (c is IVoiceChannel) { Interlocked.Decrement(ref _voiceChannels); } }); return(Task.CompletedTask); }; _client.GuildAvailable += (g) => { var _ = Task.Run(() => { var tc = g.Channels.Count(cx => cx is ITextChannel); var vc = g.Channels.Count - tc; Interlocked.Add(ref _textChannels, tc); Interlocked.Add(ref _voiceChannels, vc); }); return(Task.CompletedTask); }; _client.JoinedGuild += (g) => { var _ = Task.Run(() => { var tc = g.Channels.Count(cx => cx is ITextChannel); var vc = g.Channels.Count - tc; Interlocked.Add(ref _textChannels, tc); Interlocked.Add(ref _voiceChannels, vc); }); return(Task.CompletedTask); }; _client.GuildUnavailable += (g) => { var _ = Task.Run(() => { var tc = g.Channels.Count(cx => cx is ITextChannel); var vc = g.Channels.Count - tc; Interlocked.Add(ref _textChannels, -tc); Interlocked.Add(ref _voiceChannels, -vc); }); return(Task.CompletedTask); }; _client.LeftGuild += (g) => { var _ = Task.Run(() => { var tc = g.Channels.Count(cx => cx is ITextChannel); var vc = g.Channels.Count - tc; Interlocked.Add(ref _textChannels, -tc); Interlocked.Add(ref _voiceChannels, -vc); }); return(Task.CompletedTask); }; if (_client.ShardId == 0) { _carbonitexTimer = new Timer(async(state) => { if (string.IsNullOrWhiteSpace(_creds.CarbonKey)) { return; } try { using (var http = new HttpClient()) { using (var content = new FormUrlEncodedContent( new Dictionary <string, string> { { "servercount", evilMorty.GuildCount.ToString() }, { "key", _creds.CarbonKey } })) { content.Headers.Clear(); content.Headers.Add("Content-Type", "application/x-www-form-urlencoded"); await http.PostAsync("https://www.carbonitex.net/discord/data/botdata.php", content).ConfigureAwait(false); } } } catch { // ignored } }, null, TimeSpan.FromHours(1), TimeSpan.FromHours(1)); } _botlistTimer = new Timer(async(state) => { if (string.IsNullOrWhiteSpace(_creds.BotListToken)) { return; } try { using (var http = new HttpClient()) { using (var content = new FormUrlEncodedContent( new Dictionary <string, string> { { "shard_count", _creds.TotalShards.ToString() }, { "shard_id", client.ShardId.ToString() }, { "server_count", client.Guilds.Count().ToString() } })) { content.Headers.Clear(); content.Headers.Add("Content-Type", "application/x-www-form-urlencoded"); http.DefaultRequestHeaders.Add("Authorization", _creds.BotListToken); await http.PostAsync($"https://discordbots.org/api/bots/{client.CurrentUser.Id}/stats", content).ConfigureAwait(false); } } } catch (Exception ex) { _log.Error(ex); // ignored } }, null, TimeSpan.FromMinutes(5), TimeSpan.FromHours(1)); var platform = "other"; if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { platform = "linux"; } else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { platform = "osx"; } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { platform = "windows"; } _dataTimer = new Timer(async(state) => { try { using (var http = new HttpClient()) { using (var content = new FormUrlEncodedContent( new Dictionary <string, string> { { "id", string.Concat(MD5.Create().ComputeHash(Encoding.ASCII.GetBytes(_creds.ClientId.ToString())).Select(x => x.ToString("X2"))) }, { "guildCount", evilMorty.GuildCount.ToString() }, { "version", BotVersion }, { "platform", platform } })) { content.Headers.Clear(); content.Headers.Add("Content-Type", "application/x-www-form-urlencoded"); await http.PostAsync("https://selfstats.evilMortybot.me/", content).ConfigureAwait(false); } } } catch { // ignored } }, null, TimeSpan.FromSeconds(1), TimeSpan.FromHours(1)); }
public CmdCdService(EvilMortyBot bot) { CommandCooldowns = new ConcurrentDictionary <ulong, ConcurrentHashSet <CommandCooldown> >( bot.AllGuildConfigs.ToDictionary(k => k.GuildId, v => new ConcurrentHashSet <CommandCooldown>(v.CommandCooldowns))); }
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; }
public PlayingRotateService(DiscordSocketClient client, IBotConfigProvider bcp, DbService db, IDataCache cache, EvilMortyBot bot, MusicService music) { _client = client; _bcp = bcp; _db = db; _log = LogManager.GetCurrentClassLogger(); _cache = cache; if (client.ShardId == 0) { _rep = new ReplacementBuilder() .WithClient(client) .WithMusic(music) .Build(); _t = new Timer(async(objState) => { try { bcp.Reload(); var state = (TimerState)objState; if (!BotConfig.RotatingStatuses) { return; } if (state.Index >= BotConfig.RotatingStatusMessages.Count) { state.Index = 0; } if (!BotConfig.RotatingStatusMessages.Any()) { return; } var msg = BotConfig.RotatingStatusMessages[state.Index++]; var status = msg.Status; if (string.IsNullOrWhiteSpace(status)) { return; } status = _rep.Replace(status); try { await bot.SetGameAsync(status, msg.Type).ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } } catch (Exception ex) { _log.Warn("Rotating playing status errored.\n" + ex); } }, new TimerState(), TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1)); } }