public static async Task ReactionClear(ModCoreShard bot, MessageReactionsClearEventArgs e) { GuildSettings cfg = null; using (var db = bot.Database.CreateContext()) { cfg = e.Channel.Guild.GetGuildSettings(db); if (cfg == null) { return; } var emoji = cfg.Starboard.Emoji; DiscordEmoji em = null; if (emoji.EmojiId != 0) { em = DiscordEmoji.FromGuildEmote(e.Client, (ulong)emoji.EmojiId); } else { em = DiscordEmoji.FromUnicode(e.Client, emoji.EmojiName); } if (cfg.Starboard.Enable) { var c = e.Channel.Guild.Channels.First(x => x.Key == (ulong)cfg.Starboard.ChannelId).Value; if (db.StarDatas.Any(x => (ulong)x.MessageId == e.Message.Id)) { await(await c.GetMessageAsync((ulong)db.StarDatas.First(x => (ulong)x.MessageId == e.Message.Id).StarboardMessageId)).DeleteAsync(); db.StarDatas.RemoveRange(db.StarDatas.Where(x => (ulong)x.MessageId == e.Message.Id)); await db.SaveChangesAsync(); } } } }
public static async Task GuildAdded(ModCoreShard bot, GuildCreateEventArgs args) { // ModCore checks whether a guild has: // - more than 15 bots // - more bots than users // - not whitelisted }
public static async Task OnChannelRemove(ModCoreShard shard, ChannelDeleteEventArgs ea) { if (ea.Guild == null) { return; } using (var db = shard.Database.CreateContext()) { var cfg = ea.Guild.GetGuildSettings(db); if (cfg == null || !cfg.RoleState.Enable) { return; } var rs = cfg.RoleState; var chperms = db.RolestateOverrides.Where(xs => xs.GuildId == (long)ea.Guild.Id && xs.ChannelId == (long)ea.Channel.Id); if (chperms.Any()) { db.RolestateOverrides.RemoveRange(chperms); await db.SaveChangesAsync(); } } }
public static async Task MemberUpdated(ModCoreShard bot, GuildMemberUpdateEventArgs e) { var db = bot.SharedData.ModCore.CreateGlobalContext(); var gst = e.Guild.GetGuildSettings(db); if (gst == null) { return; } if (gst.LogUpdates) { var log = e.Guild.GetChannel(gst.UpdateChannel); var embed = new DiscordEmbedBuilder() .WithTitle("Member Updated:") .WithDescription($"{e.Member.Username}#{e.Member.Discriminator}"); // TODO ModCore color scheme embed.WithColor(new DiscordColor("#089FDF")); embed.WithThumbnail(e.Member.AvatarUrl); if (e.NicknameAfter != e.NicknameBefore) { var after = e.Member.Username; var before = e.Member.Username; if (!string.IsNullOrEmpty(e.NicknameAfter)) { after = e.NicknameAfter; } if (!string.IsNullOrEmpty(e.NicknameBefore)) { before = e.NicknameBefore; } embed.AddField("Nickname update", $"{before} to {after}"); } if (e.RolesAfter != e.RolesBefore) { var added = e.RolesAfter.Where(x => !e.RolesBefore.Contains(x)); var removed = e.RolesBefore.Where(x => !e.RolesAfter.Contains(x)); if (added.Count() > 0) { embed.AddField("Added roles", string.Join(", ", added.Select(x => x.Name))); } if (removed.Count() > 0) { embed.AddField("Removed roles", string.Join(", ", removed.Select(x => x.Name))); } } await log.SendMessageAsync(embed : embed); } }
public static async Task OnMemberLeave(ModCoreShard shard, GuildMemberRemoveEventArgs ea) { using (var db = shard.Database.CreateContext()) { var cfg = ea.Guild.GetGuildSettings(db); if (cfg == null || !cfg.RoleState.Enable) { return; } var rs = cfg.RoleState; if (ea.Member.Roles.Any()) // no roles or cache miss, but at this point little can be done about it { var rsx = rs.IgnoredRoleIds; var roles = ea.Member.Roles.Select(xr => xr.Id).Except(rsx).Select(xul => (long)xul); var state = db.RolestateRoles.SingleOrDefault(xs => xs.GuildId == (long)ea.Guild.Id && xs.MemberId == (long)ea.Member.Id); if (state == null) // no rolestate, create it { state = new DatabaseRolestateRoles { GuildId = (long)ea.Guild.Id, MemberId = (long)ea.Member.Id, RoleIds = roles.ToArray() }; await db.RolestateRoles.AddAsync(state); } else // rolestate exists, update it { state.RoleIds = roles.ToArray(); db.RolestateRoles.Update(state); } } var nickstate = db.RolestateNicks.SingleOrDefault(xs => xs.GuildId == (long)ea.Guild.Id && xs.MemberId == (long)ea.Member.Id); shard.Client.Logger.Log(LogLevel.Debug, "ModCore", $"Do nickname shites: {ea.Member.Nickname}", System.DateTime.Now); if (nickstate == null) // no nickstate, create it { shard.Client.Logger.Log(LogLevel.Debug, "ModCore", "Create nickname shites", System.DateTime.Now); nickstate = new DatabaseRolestateNick { GuildId = (long)ea.Guild.Id, MemberId = (long)ea.Member.Id, Nickname = ea.Member.Nickname }; await db.RolestateNicks.AddAsync(nickstate); } else // nickstate exists, update it { shard.Client.Logger.Log(LogLevel.Debug, "ModCore", "Update nickname shites", System.DateTime.Now); nickstate.Nickname = ea.Member.Nickname; db.RolestateNicks.Update(nickstate); } // at this point, channel overrides do not exist await db.SaveChangesAsync(); } }
public static async Task UpdateCompleteAsync(ModCoreShard bot, GuildCreateEventArgs e) { if (e.Guild.Id == bot.SharedData.StartNotify.guild) { await e.Guild.GetChannel(bot.SharedData.StartNotify.channel).ElevatedMessageAsync("Done updating. We're back online!"); bot.SharedData.StartNotify = default; } }
public static async Task CommandError(ModCoreShard bot, GuildBanRemoveEventArgs e) { var t = Timers.FindNearestTimer(TimerActionType.Unban, e.Member.Id, 0, e.Guild.Id, bot.Database); if (t != null) { await Timers.UnscheduleTimerAsync(t, bot.Client, bot.Database, bot.SharedData); } }
public static async Task BotListUpdate(ModCoreShard bot, ReadyEventArgs e) { await bot.SharedData.BotsDiscordPl.UpdateShardAsync(bot.ShardId, e.Client.Guilds.Count); bot.SharedData.ReadysReceived++; if (bot.SharedData.ReadysReceived == bot.SharedData.ModCore.Shards.Count) { await bot.SharedData.DiscordBots.UpdateGuildCount(bot.SharedData.ModCore.Shards.Select(x => x.Client.Guilds.Count).Sum()); } }
public static async Task PresenceUpdated(ModCoreShard bot, PresenceUpdateEventArgs e) { // TODO fix me var db = bot.SharedData.ModCore.CreateGlobalContext(); var loggers = db.GuildConfig.Where(x => x.GetSettings().LogUpdates).Select(x => x.GuildId); var guilds = bot?.Parent?.Shards?.SelectMany(x => x.Client?.Guilds?.Where(y => y.Value.GetGuildSettings(db)?.LogUpdates ?? false)); if (guilds != null) { foreach (var g in guilds.Select(x => x.Value)) { if (await IsInGuild(e.UserAfter, g)) { var gst = g.GetGuildSettings(db); var log = g.GetChannel(gst.UpdateChannel); var embed = new DiscordEmbedBuilder() .WithTitle("User Updated:") .WithDescription($"{e.UserAfter.Username}#{e.UserAfter.Discriminator}"); if (e.UserAfter.Username != e.UserBefore.Username) { embed.AddField("Changed username", $"{e.UserBefore.Username} to {e.UserAfter.Username}"); } if (e.UserAfter.Discriminator != e.UserBefore.Discriminator) { embed.AddField("Changed discriminator", $"{e.UserBefore.Discriminator} to {e.UserAfter.Discriminator}"); } if (e.UserAfter.AvatarUrl != e.UserBefore.AvatarUrl) { embed.AddField("Changed avatar", $"[Old Avatar]({e.UserBefore.AvatarUrl})" + $"\nNote: this link may 404 later due to cache invalidation"); } if (e.UserAfter.IsBot != e.UserBefore.IsBot) { embed.AddField("Magically transformed between bot form and human form", $"Wait, what the f**k this isn't possible"); } // TODO ModCore color scheme embed.WithColor(new DiscordColor("#089FDF")); embed.WithThumbnail(e.UserAfter.AvatarUrl); if (embed.Fields.Count > 0) { await log.SendMessageAsync(embed : embed); } } } } }
public static async Task OnChannelUpdate(ModCoreShard shard, ChannelUpdateEventArgs ea) { if (ea.Guild == null) return; using (var db = shard.Database.CreateContext()) { var cfg = ea.Guild.GetGuildSettings(db); if (cfg == null || !cfg.RoleState.Enable) return; var rs = cfg.RoleState; if (rs.IgnoredChannelIds.Contains(ea.ChannelAfter.Id)) return; var os = ea.ChannelAfter.PermissionOverwrites.Where(xo => xo.Type.ToString().ToLower() == "member").ToDictionary(xo => (long)xo.Id, xo => xo); var osids = os.Select(xo => xo.Key).ToArray(); var chperms = db.RolestateOverrides.Where(xs => xs.GuildId == (long)ea.Guild.Id && xs.ChannelId == (long)ea.ChannelAfter.Id) .ToDictionary(xs => xs.MemberId, xs => xs); var permids = chperms.Select(xo => xo.Key).ToArray(); var del = permids.Except(osids); var add = osids.Except(permids); var mod = osids.Intersect(permids); if (del.Any()) db.RolestateOverrides.RemoveRange(del.Select(xid => chperms[xid])); if (add.Any()) await db.RolestateOverrides.AddRangeAsync(add.Select(xid => new DatabaseRolestateOverride { ChannelId = (long)ea.ChannelAfter.Id, GuildId = (long)ea.Guild.Id, MemberId = xid, PermsAllow = (long)os[xid].Allowed, PermsDeny = (long)os[xid].Denied })); if (mod.Any()) foreach (var xid in mod) { chperms[xid].PermsAllow = (long)os[xid].Allowed; chperms[xid].PermsDeny = (long)os[xid].Denied; db.RolestateOverrides.Update(chperms[xid]); } if (del.Any() || add.Any() || mod.Any()) await db.SaveChangesAsync(); } }
public static async Task CheckNewMember(ModCoreShard bot, GuildMemberAddEventArgs e) { GuildSettings settings; DatabaseBan[] bans; using (var db = bot.Database.CreateContext()) { if (!db.Bans.Any(x => x.UserId == (long)e.Member.Id)) { return; } bans = db.Bans.Where(x => x.UserId == (long)e.Member.Id).ToArray(); settings = e.Guild.GetGuildSettings(db) ?? new GuildSettings(); } var prevowns = new List <ulong>(); int count = 0; var guilds = bot.SharedData.ModCore.Shards.SelectMany(x => x.Client.Guilds.Values); foreach (var b in bans) { var g = guilds.First(x => x.Id == (ulong)b.GuildId); if (prevowns.Contains(g.Owner.Id)) { continue; } count++; prevowns.Add(g.Owner.Id); } if (settings.GlobalWarn.Enable && count > 2) { var embed = new DiscordEmbedBuilder() .WithColor(new DiscordColor("#C1272D")) .WithTitle($"@{e.Member.Username}#{e.Member.Discriminator} - ID: {e.Member.Id}"); var BanString = new StringBuilder(); foreach (DatabaseBan ban in bans) { BanString.Append($"[{ban.GuildId} - {ban.BanReason}] "); } embed.AddField("Bans", BanString.ToString()); if (settings.GlobalWarn.WarnLevel == GlobalWarnLevel.Owner) { await e.Guild.Owner.ElevatedMessageAsync(embed : embed); } else if (settings.GlobalWarn.WarnLevel == GlobalWarnLevel.JoinLog) { await e.Guild.Channels.First(x => x.Key == (ulong)settings.JoinLog.ChannelId).Value.ElevatedMessageAsync(embed: embed); } } }
public static async Task OnReady(ModCoreShard shard, ReadyEventArgs ea) { using (var db = shard.Database.CreateContext()) { if (!db.Timers.Any()) { return; } var ids = ea.Client.Guilds.Select(xg => (long)xg.Key).ToArray(); var timers = db.Timers.Where(xt => ids.Contains(xt.GuildId)).ToArray(); if (!timers.Any()) { return; } // lock timers await shard.SharedData.TimerSempahore.WaitAsync(); try { var now = DateTimeOffset.UtcNow; var past = timers.Where(xt => xt.DispatchAt <= now.AddSeconds(30)).ToArray(); if (past.Any()) { foreach (var xt in past) { // dispatch past timers _ = DispatchTimer(new TimerData(null, xt, shard.Client, shard.Database, shard.SharedData, null)); } db.Timers.RemoveRange(past); await db.SaveChangesAsync(); } } catch (Exception ex) { ea.Client.DebugLogger.LogMessage(LogLevel.Error, "ModCore", $"Caught Exception in Timer Ready: {ex.GetType().ToString()}\n{ex.StackTrace}", DateTime.UtcNow); } finally { // unlock the timers shard.SharedData.TimerSempahore.Release(); } await RescheduleTimers(shard.Client, shard.Database, shard.SharedData); } }
public static async Task MessageEdited(ModCoreShard bot, MessageUpdateEventArgs e) { await Task.Yield(); if ((!string.IsNullOrEmpty(e.MessageBefore.Content) || e.Message.Embeds.Count > 0) && !e.Message.Author.IsBot) { if (bot.SharedData.EditedMessages.ContainsKey(e.Channel.Id)) { bot.SharedData.EditedMessages[e.Channel.Id] = e.MessageBefore; } else { bot.SharedData.EditedMessages.TryAdd(e.Channel.Id, e.MessageBefore); } } }
public static async Task MessageSniped(ModCoreShard bot, MessageDeleteEventArgs e) { await Task.Yield(); if (!string.IsNullOrEmpty(e.Message.Content) || e.Message.Embeds.Count > 0) { if (bot.SharedData.DeletedMessages.ContainsKey(e.Channel.Id)) { bot.SharedData.DeletedMessages[e.Channel.Id] = e.Message; } else { bot.SharedData.DeletedMessages.TryAdd(e.Channel.Id, e.Message); } } }
public static async Task CommandError(ModCoreShard bot, CommandErrorEventArgs e) { var cfg = e.Context.GetGuildSettings() ?? new GuildSettings(); var ctx = e.Context; if (await NotifyCommandDisabled(e, cfg, ctx)) { return; } if (await NotifyCommandNotFound(bot, e, cfg, ctx)) { return; } await NotifyCommandErrored(e, cfg, ctx); }
public static async Task OnMemberUpdate(ModCoreShard shard, GuildMemberUpdateEventArgs ea) { using (var db = shard.Database.CreateContext()) { var cfg = ea.Guild.GetGuildSettings(db); if (cfg == null || !cfg.RoleState.Enable) { return; } var rs = cfg.RoleState; var gld = ea.Guild; var roleids = db.RolestateRoles.SingleOrDefault(xs => xs.GuildId == (long)ea.Guild.Id && xs.MemberId == (long)ea.Member.Id); if (roleids == null) { roleids = new DatabaseRolestateRoles { GuildId = (long)ea.Guild.Id, MemberId = (long)ea.Member.Id }; } roleids.RoleIds = ea.RolesAfter .Select(xr => xr.Id) .Except(rs.IgnoredRoleIds) .Select(xid => (long)xid) .ToArray(); db.RolestateRoles.Update(roleids); var nick = db.RolestateNicks.SingleOrDefault(xs => xs.GuildId == (long)ea.Guild.Id && xs.MemberId == (long)ea.Member.Id); if (nick == null) { nick = new DatabaseRolestateNick { GuildId = (long)ea.Guild.Id, MemberId = (long)ea.Member.Id, }; } nick.Nickname = ea.NicknameAfter; db.RolestateNicks.Update(nick); await db.SaveChangesAsync(); } }
public static void InstallListeners(DiscordClient client, ModCoreShard bot) { // find all methods from ModCore with AsyncListener attr ListenerMethods = from a in AppDomain.CurrentDomain.GetAssemblies() from t in a.GetTypes() //where t.Namespace.StartsWith("ModCore") from m in t.GetMethods() let attribute = m.GetCustomAttribute(typeof(AsyncListenerAttribute), true) where attribute != null select new ListenerMethod { Method = m, Attribute = attribute as AsyncListenerAttribute }; foreach (var listener in ListenerMethods) { listener.Attribute.Register(bot, client, listener.Method); } }
public static async Task LogLeaveMember(ModCoreShard bot, GuildMemberRemoveEventArgs e) { GuildSettings cfg; using (var db = bot.Database.CreateContext()) cfg = e.Guild.GetGuildSettings(db); if (cfg == null || !cfg.JoinLog.Enable) { return; } var m = e.Member; var c = e.Guild.GetChannel(cfg.JoinLog.ChannelId); if (c == null) { return; } var embed = new DiscordEmbedBuilder() .WithTitle("Member left") .WithDescription($"ID: ({m.Id})") .WithAuthor($"{m.Username}#{m.Discriminator}", iconUrl: string.IsNullOrEmpty(m.AvatarHash) ? m.DefaultAvatarUrl : m.AvatarUrl); if (m.JoinedAt.DateTime == DateTime.MinValue) { embed.AddField("Join Date", $"{m.JoinedAt.DateTime}"); } embed .AddField("Leave Date", $"{DateTime.Now}") .AddField("Register Date", $"{m.CreationTimestamp.DateTime}") .WithColor(DiscordColor.Red); await c.ElevatedMessageAsync(embed); }
public static async Task ReactionAdd(ModCoreShard bot, MessageReactionAddEventArgs e) { GuildSettings cfg = null; using (var db = bot.Database.CreateContext()) { cfg = e.Channel.Guild.GetGuildSettings(db); if (cfg == null) { return; } if (cfg.ReactionRoles.Any(x => (ulong)x.ChannelId == e.Channel.Id && (ulong)x.MessageId == e.Message.Id && (ulong)x.Reaction.EmojiId == e.Emoji.Id && x.Reaction.EmojiName == e.Emoji.Name)) { var rrid = (ulong)cfg.ReactionRoles.First( x => (ulong)x.ChannelId == e.Channel.Id && (ulong)x.MessageId == e.Message.Id && (ulong)x.Reaction.EmojiId == e.Emoji.Id && x.Reaction.EmojiName == e.Emoji.Name).RoleId; var rrrole = e.Channel.Guild.GetRole(rrid); var mem = await e.Channel.Guild.GetMemberAsync(e.User.Id); if (!mem.Roles.Any(x => x.Id == rrid)) { await mem.GrantRoleAsync(rrrole); } } var emoji = cfg.Starboard.Emoji; DiscordEmoji em = null; if (emoji.EmojiId != 0) { em = DiscordEmoji.FromGuildEmote(bot.Client, (ulong)emoji.EmojiId); } else { em = DiscordEmoji.FromUnicode(bot.Client, emoji.EmojiName); } if (!cfg.Starboard.AllowNSFW && e.Channel.IsNSFW) { return; } if (cfg.Starboard.Enable && e.Emoji == em) { long sbmid = 0; var c = e.Channel.Guild.Channels.First(x => x.Key == (ulong)cfg.Starboard.ChannelId).Value; if (c.Id == e.Channel.Id) // star on starboard entry { /*if (db.StarDatas.Any(x => (ulong)x.StarboardMessageId == e.Message.Id)) * { * var other = db.StarDatas.First(x => (ulong)x.StarboardMessageId == e.Message.Id); * var count = db.StarDatas.Count(x => (ulong)x.StarboardMessageId == e.Message.Id); * if (!db.StarDatas.Any(x => x.MessageId == other.MessageId && x.StargazerId == (long)e.User.Id)) * { * var chn = await e.Client.GetChannelAsync((ulong)other.ChannelId); * var msg = await chn.GetMessageAsync((ulong)other.MessageId); * * if (msg.Author.Id == e.User.Id || e.User.IsBot) * return; * * var d = await (await c.GetMessageAsync((ulong)other.StarboardMessageId)).ModifyAsync($"{e.Emoji}: {count + 1} ({msg.Id}) in {msg.Channel.Mention}", embed: BuildMessageEmbed(msg)); * sbmid = (long)d.Id; * await db.StarDatas.AddAsync(new DatabaseStarData * { * ChannelId = other.ChannelId, * GuildId = (long)e.Channel.Guild.Id, * MessageId = other.MessageId, * AuthorId = other.AuthorId, * StarboardMessageId = sbmid, * StargazerId = (long)e.User.Id, * }); * await db.SaveChangesAsync(); * } * }*/ // Removing this behaviour for jump links. } else // star on actual message { if (e.Message.Author.Id == e.User.Id || e.User.IsBot) { return; } if (db.StarDatas.Any(x => (ulong)x.MessageId == e.Message.Id)) { var count = db.StarDatas.Count(x => (ulong)x.MessageId == e.Message.Id); if (db.StarDatas.Any(x => (ulong)x.MessageId == e.Message.Id && x.StarboardMessageId != 0)) { var other = db.StarDatas.First(x => (ulong)x.MessageId == e.Message.Id && x.StarboardMessageId != 0); var msg = await c.GetMessageAsync((ulong)other.StarboardMessageId); var d = await msg.ModifyAsync($"{e.Emoji}: {count + 1} ({e.Message.Id}) in {e.Message.Channel.Mention}", embed : BuildMessageEmbed(e.Message)); sbmid = (long)d.Id; } else { if (count + 1 >= cfg.Starboard.Minimum) { // create msg var d = await c.ElevatedMessageAsync($"{e.Emoji}: {count + 1} ({e.Message.Id}) in {e.Message.Channel.Mention}", embed : BuildMessageEmbed(e.Message)); sbmid = (long)d.Id; } } } else if (cfg.Starboard.Minimum <= 1) { var d = await c.ElevatedMessageAsync($"{e.Emoji}: 1 ({e.Message.Id}) in {e.Message.Channel.Mention}", embed : BuildMessageEmbed(e.Message)); sbmid = (long)d.Id; } await db.StarDatas.AddAsync(new DatabaseStarData { ChannelId = (long)e.Channel.Id, GuildId = (long)e.Channel.Guild.Id, MessageId = (long)e.Message.Id, AuthorId = (long)e.Message.Author.Id, StarboardMessageId = sbmid, StargazerId = (long)e.User.Id, }); // somebody once told me... var allstars = db.StarDatas.Where(x => (ulong)x.MessageId == e.Message.Id).ToList(); allstars.ForEach(x => x.StarboardMessageId = sbmid); db.StarDatas.UpdateRange(allstars); await db.SaveChangesAsync(); } } } }
public static async Task OnGuildAvailable(ModCoreShard shard, GuildCreateEventArgs ea) { // Ensure full member cache? ////if(ea.Guild.MemberCount < 10000) //// await ea.Guild.GetAllMembersAsync(); // haha lets not using (var db = shard.Database.CreateContext()) { var cfg = ea.Guild.GetGuildSettings(db); if (cfg == null || !cfg.RoleState.Enable) return; var rs = cfg.RoleState; var chperms = db.RolestateOverrides.Where(xs => xs.GuildId == (long)ea.Guild.Id); var prms = chperms.GroupBy(xs => xs.ChannelId).ToDictionary(xg => xg.Key, xg => xg.ToDictionary(xs => xs.MemberId, xs => xs)); var any = false; foreach (var chn in ea.Guild.Channels) { if (rs.IgnoredChannelIds.Contains(chn.Key)) continue; if (!prms.ContainsKey((long)chn.Key)) { any = true; var os = chn.Value.PermissionOverwrites.Where(xo => xo.Type.ToString().ToLower() == "member"); if (!os.Any()) continue; await db.RolestateOverrides.AddRangeAsync(os.Select(xo => new DatabaseRolestateOverride { ChannelId = (long)chn.Value.Id, GuildId = (long)chn.Value.Guild.Id, MemberId = (long)xo.Id, PermsAllow = (long)xo.Allowed, PermsDeny = (long)xo.Denied })); } else { var cps = prms[(long)chn.Value.Id]; var os = chn.Value.PermissionOverwrites.Where(xo => xo.Type.ToString().ToLower() == "member").ToDictionary(xo => (long)xo.Id, xo => xo); var osids = os.Keys.ToArray(); var del = cps.Keys.Except(osids); var add = osids.Except(cps.Keys); var mod = osids.Intersect(cps.Keys); if (any |= del.Any()) db.RolestateOverrides.RemoveRange(del.Select(xid => cps[xid])); if (any |= add.Any()) await db.RolestateOverrides.AddRangeAsync(add.Select(xid => new DatabaseRolestateOverride { ChannelId = (long)chn.Key, GuildId = (long)ea.Guild.Id, MemberId = xid, PermsAllow = (long)os[xid].Allowed, PermsDeny = (long)os[xid].Denied })); if (any |= mod.Any()) foreach (var xid in mod) { cps[xid].PermsAllow = (long)os[xid].Allowed; cps[xid].PermsDeny = (long)os[xid].Denied; db.RolestateOverrides.Update(cps[xid]); } } } if (any) await db.SaveChangesAsync(); } }
public static async Task OnMemberJoin(ModCoreShard shard, GuildMemberAddEventArgs ea) { var gld = ea.Guild; GuildSettings cfg = null; GuildRoleStateConfig rs = null; DatabaseRolestateRoles roleids = null; DatabaseRolestateOverride[] chperms = null; DatabaseRolestateNick nick = null; using (var db = shard.Database.CreateContext()) { cfg = ea.Guild.GetGuildSettings(db); if (cfg == null || !cfg.RoleState.Enable) return; rs = cfg.RoleState; roleids = db.RolestateRoles.SingleOrDefault(xs => xs.GuildId == (long)ea.Guild.Id && xs.MemberId == (long)ea.Member.Id); chperms = db.RolestateOverrides.Where(xs => xs.GuildId == (long)ea.Guild.Id && xs.MemberId == (long)ea.Member.Id).ToArray(); nick = db.RolestateNicks.SingleOrDefault(xs => xs.GuildId == (long)ea.Guild.Id && xs.MemberId == (long)ea.Member.Id); } if (roleids?.RoleIds != null) { var oroles = roleids.RoleIds .Select(xid => (ulong)xid) .Except(rs.IgnoredRoleIds) .Select(xid => gld.GetRole(xid)) .Where(xr => xr != null).ToList(); var roles = oroles; var highestself = ea.Guild.CurrentMember.Roles.Select(x => x.Position).Max(); roles.RemoveAll(x => x.Position > highestself); if (roles.Any()) await ea.Member.ReplaceRolesAsync(roles, "Restoring Role State."); } else { var ar = cfg.AutoRole; if (ar.Enable && ea.Guild.Roles.Count(x => x.Value.Id == (ulong)ar.RoleId) > 0) { var role = ea.Guild.Roles.First(x => x.Value.Id == (ulong)ar.RoleId); await ea.Member.GrantRoleAsync(role.Value, "AutoRole"); } } if (chperms.Any()) { foreach (var chperm in chperms) { var chn = gld.GetChannel((ulong)chperm.ChannelId); if (chn == null) continue; await chn.AddOverwriteAsync(ea.Member, (Permissions)chperm.PermsAllow, (Permissions)chperm.PermsDeny, "Restoring Role State"); } } if(nick != null) { ea.Client.DebugLogger.LogMessage(LogLevel.Debug, "ModCore", $"Set new old nick: {nick.Nickname}", System.DateTime.Now); var m = await ea.Guild.GetMemberAsync(ea.Member.Id); await m.ModifyAsync(x => x.Nickname = nick.Nickname); } }
public static Task OnGuildCreated(ModCoreShard shard, GuildCreateEventArgs ea) => OnGuildAvailable(shard, ea);
public void Register(ModCoreShard bot, DiscordClient client, MethodInfo listener) { // TODO redo this with linq expressions // nope, there's no cleaner way to do this. sorry Task OnEventWithArgs(DiscordClient c, object e) { _ = Task.Run(async() => { try { await(Task) listener.Invoke(null, new[] { bot, e }); } catch (Exception ex) { Console.WriteLine($"<AsyncListener> Uncaught exception in listener thread: {ex}"); Console.WriteLine(ex.StackTrace); } }); return(Task.CompletedTask); } Task OnCnextEvent(CommandsNextExtension cmd, object e) { _ = Task.Run(async() => { try { await(Task) listener.Invoke(null, new[] { bot, e }); } catch (Exception ex) { Console.WriteLine($"<AsyncListener> Uncaught exception in listener thread: {ex}"); Console.WriteLine(ex.StackTrace); } }); return(Task.CompletedTask); } switch (Target) { case EventTypes.ClientErrored: client.ClientErrored += OnEventWithArgs; break; case EventTypes.SocketErrored: client.SocketErrored += OnEventWithArgs; break; case EventTypes.SocketOpened: client.SocketOpened += OnEventWithArgs; break; case EventTypes.SocketClosed: client.SocketClosed += OnEventWithArgs; break; case EventTypes.Ready: client.Ready += OnEventWithArgs; break; case EventTypes.Resumed: client.Resumed += OnEventWithArgs; break; case EventTypes.ChannelCreated: client.ChannelCreated += OnEventWithArgs; break; case EventTypes.DmChannelCreated: client.DmChannelCreated += OnEventWithArgs; break; case EventTypes.ChannelUpdated: client.ChannelUpdated += OnEventWithArgs; break; case EventTypes.ChannelDeleted: client.ChannelDeleted += OnEventWithArgs; break; case EventTypes.DmChannelDeleted: client.DmChannelDeleted += OnEventWithArgs; break; case EventTypes.ChannelPinsUpdated: client.ChannelPinsUpdated += OnEventWithArgs; break; case EventTypes.GuildCreated: client.GuildCreated += OnEventWithArgs; break; case EventTypes.GuildAvailable: client.GuildAvailable += OnEventWithArgs; break; case EventTypes.GuildUpdated: client.GuildUpdated += OnEventWithArgs; break; case EventTypes.GuildDeleted: client.GuildDeleted += OnEventWithArgs; break; case EventTypes.GuildUnavailable: client.GuildUnavailable += OnEventWithArgs; break; case EventTypes.MessageCreated: client.MessageCreated += OnEventWithArgs; break; case EventTypes.PresenceUpdated: client.PresenceUpdated += OnEventWithArgs; break; case EventTypes.GuildBanAdded: client.GuildBanAdded += OnEventWithArgs; break; case EventTypes.GuildBanRemoved: client.GuildBanRemoved += OnEventWithArgs; break; case EventTypes.GuildEmojisUpdated: client.GuildEmojisUpdated += OnEventWithArgs; break; case EventTypes.GuildIntegrationsUpdated: client.GuildIntegrationsUpdated += OnEventWithArgs; break; case EventTypes.GuildMemberAdded: client.GuildMemberAdded += OnEventWithArgs; break; case EventTypes.GuildMemberRemoved: client.GuildMemberRemoved += OnEventWithArgs; break; case EventTypes.GuildMemberUpdated: client.GuildMemberUpdated += OnEventWithArgs; break; case EventTypes.GuildRoleCreated: client.GuildRoleCreated += OnEventWithArgs; break; case EventTypes.GuildRoleUpdated: client.GuildRoleUpdated += OnEventWithArgs; break; case EventTypes.GuildRoleDeleted: client.GuildRoleDeleted += OnEventWithArgs; break; case EventTypes.MessageAcknowledged: client.MessageAcknowledged += OnEventWithArgs; break; case EventTypes.MessageUpdated: client.MessageUpdated += OnEventWithArgs; break; case EventTypes.MessageDeleted: client.MessageDeleted += OnEventWithArgs; break; case EventTypes.MessagesBulkDeleted: client.MessagesBulkDeleted += OnEventWithArgs; break; case EventTypes.TypingStarted: client.TypingStarted += OnEventWithArgs; break; case EventTypes.UserSettingsUpdated: client.UserSettingsUpdated += OnEventWithArgs; break; case EventTypes.UserUpdated: client.UserUpdated += OnEventWithArgs; break; case EventTypes.VoiceStateUpdated: client.VoiceStateUpdated += OnEventWithArgs; break; case EventTypes.VoiceServerUpdated: client.VoiceServerUpdated += OnEventWithArgs; break; case EventTypes.GuildMembersChunked: client.GuildMembersChunked += OnEventWithArgs; break; case EventTypes.UnknownEvent: client.UnknownEvent += OnEventWithArgs; break; case EventTypes.MessageReactionAdded: client.MessageReactionAdded += OnEventWithArgs; break; case EventTypes.MessageReactionRemoved: client.MessageReactionRemoved += OnEventWithArgs; break; case EventTypes.MessageReactionsCleared: client.MessageReactionsCleared += OnEventWithArgs; break; case EventTypes.WebhooksUpdated: client.WebhooksUpdated += OnEventWithArgs; break; case EventTypes.Heartbeated: client.Heartbeated += OnEventWithArgs; break; case EventTypes.CommandExecuted: bot.Commands.CommandExecuted += OnCnextEvent; break; case EventTypes.CommandErrored: bot.Commands.CommandErrored += OnCnextEvent; break; } }
public static async Task ReactionAdd(ModCoreShard bot, MessageReactionAddEventArgs e) { GuildSettings cfg = null; using (var db = bot.Database.CreateContext()) { cfg = e.Channel.Guild.GetGuildSettings(db); if (cfg == null) { return; } if (cfg.ReactionRoles.Any(x => (ulong)x.ChannelId == e.Channel.Id && (ulong)x.MessageId == e.Message.Id && (ulong)x.Reaction.EmojiId == e.Emoji.Id && x.Reaction.EmojiName == e.Emoji.Name)) { var rrid = (ulong)cfg.ReactionRoles.First( x => (ulong)x.ChannelId == e.Channel.Id && (ulong)x.MessageId == e.Message.Id && (ulong)x.Reaction.EmojiId == e.Emoji.Id && x.Reaction.EmojiName == e.Emoji.Name).RoleId; var rrrole = e.Channel.Guild.GetRole(rrid); var mem = await e.Channel.Guild.GetMemberAsync(e.User.Id); if (!mem.Roles.Any(x => x.Id == rrid)) { await mem.GrantRoleAsync(rrrole); } } var emoji = cfg.Starboard.Emoji; DiscordEmoji em = null; if (emoji.EmojiId != 0) { em = DiscordEmoji.FromGuildEmote(e.Client, (ulong)emoji.EmojiId); } else { em = DiscordEmoji.FromUnicode(e.Client, emoji.EmojiName); } if (!cfg.Starboard.AllowNSFW && e.Channel.IsNSFW) { return; } if (cfg.Starboard.Enable && e.Emoji == em) { long sbmid = 0; var c = e.Channel.Guild.Channels.First(x => x.Key == (ulong)cfg.Starboard.ChannelId).Value; if (c.Id == e.Channel.Id) // star on starboard entry { if (db.StarDatas.Any(x => (ulong)x.StarboardMessageId == e.Message.Id)) { var other = db.StarDatas.First(x => (ulong)x.StarboardMessageId == e.Message.Id); var count = db.StarDatas.Count(x => (ulong)x.StarboardMessageId == e.Message.Id); if (!db.StarDatas.Any(x => x.MessageId == other.MessageId && x.StargazerId == (long)e.User.Id)) { var chn = await e.Client.GetChannelAsync((ulong)other.ChannelId); var msg = await chn.GetMessageAsync((ulong)other.MessageId); if (msg.Author.Id == e.User.Id || e.User.IsBot) { return; } var d = await(await c.GetMessageAsync((ulong)other.StarboardMessageId)).ModifyAsync($"{e.Emoji}: {count + 1} ({msg.Id}) in {msg.Channel.Mention}", embed: BuildMessageEmbed(msg)); sbmid = (long)d.Id; await db.StarDatas.AddAsync(new DatabaseStarData { ChannelId = other.ChannelId, GuildId = (long)e.Channel.Guild.Id, MessageId = other.MessageId, AuthorId = other.AuthorId, StarboardMessageId = sbmid, StargazerId = (long)e.User.Id, }); await db.SaveChangesAsync(); } } } else // star on actual message { if (db.StarDatas.Any(x => (ulong)x.MessageId == e.Message.Id)) { var other = db.StarDatas.First(x => (ulong)x.MessageId == e.Message.Id); var count = db.StarDatas.Count(x => (ulong)x.MessageId == e.Message.Id); var msg = await c.GetMessageAsync((ulong)other.StarboardMessageId); if (msg.Author.Id == e.User.Id || e.User.IsBot) { return; } var d = await msg.ModifyAsync($"{e.Emoji}: {count + 1} ({e.Message.Id}) in {e.Message.Channel.Mention}", embed : BuildMessageEmbed(e.Message)); sbmid = (long)d.Id; } else { var d = await c.ElevatedMessageAsync($"{e.Emoji}: 1 ({e.Message.Id}) in {e.Message.Channel.Mention}", embed : BuildMessageEmbed(e.Message)); sbmid = (long)d.Id; } await db.StarDatas.AddAsync(new DatabaseStarData { ChannelId = (long)e.Channel.Id, GuildId = (long)e.Channel.Guild.Id, MessageId = (long)e.Message.Id, AuthorId = (long)e.Message.Author.Id, StarboardMessageId = sbmid, StargazerId = (long)e.User.Id, }); await db.SaveChangesAsync(); } } } }
public static async Task ReactionRemove(ModCoreShard bot, MessageReactionRemoveEventArgs e) { GuildSettings cfg = null; using (var db = bot.Database.CreateContext()) { cfg = e.Channel.Guild.GetGuildSettings(db); if (cfg == null) { return; } if (cfg.ReactionRoles.Any(x => (ulong)x.ChannelId == e.Channel.Id && (ulong)x.MessageId == e.Message.Id && (ulong)x.Reaction.EmojiId == e.Emoji.Id && x.Reaction.EmojiName == e.Emoji.Name)) { var rrid = (ulong)cfg.ReactionRoles.First( x => (ulong)x.ChannelId == e.Channel.Id && (ulong)x.MessageId == e.Message.Id && (ulong)x.Reaction.EmojiId == e.Emoji.Id && x.Reaction.EmojiName == e.Emoji.Name).RoleId; var rrrole = e.Channel.Guild.GetRole(rrid); var mem = await e.Channel.Guild.GetMemberAsync(e.User.Id); if (mem.Roles.Any(x => x.Id == rrid)) { await mem.RevokeRoleAsync(rrrole); } } var emoji = cfg.Starboard.Emoji; DiscordEmoji em = null; if (emoji.EmojiId != 0) { em = DiscordEmoji.FromGuildEmote(e.Client, (ulong)emoji.EmojiId); } else { em = DiscordEmoji.FromUnicode(e.Client, emoji.EmojiName); } if (cfg.Starboard.Enable && e.Emoji == em) { var c = e.Channel.Guild.Channels.First(x => x.Key == (ulong)cfg.Starboard.ChannelId).Value; if (c.Id == e.Channel.Id) { if (db.StarDatas.Any(x => (ulong)x.StarboardMessageId == e.Message.Id && (ulong)x.StargazerId == e.User.Id)) { var star = db.StarDatas.First(x => (ulong)x.StarboardMessageId == e.Message.Id && (ulong)x.StargazerId == e.User.Id); var count = db.StarDatas.Count(x => (ulong)x.StarboardMessageId == e.Message.Id); var m = await c.GetMessageAsync((ulong)star.StarboardMessageId); var chn = await e.Client.GetChannelAsync((ulong)star.ChannelId); var msg = await chn.GetMessageAsync((ulong)star.MessageId); if (count - 1 > 0) { await m.ModifyAsync($"{e.Emoji}: {count - 1} ({msg.Id}) in {msg.Channel.Mention}", embed : BuildMessageEmbed(msg)); } else { await m.DeleteAsync(); } db.StarDatas.Remove(star); await db.SaveChangesAsync(); } } else { if (db.StarDatas.Any(x => (ulong)x.MessageId == e.Message.Id && (ulong)x.StargazerId == e.User.Id)) { var star = db.StarDatas.First(x => (ulong)x.MessageId == e.Message.Id && (ulong)x.StargazerId == e.User.Id); var count = db.StarDatas.Count(x => (ulong)x.MessageId == e.Message.Id); var m = await c.GetMessageAsync((ulong)star.StarboardMessageId); if (count - 1 > 0) { await m.ModifyAsync($"{e.Emoji}: {count - 1} ({e.Message.Id}) in {e.Message.Channel.Mention}", embed : BuildMessageEmbed(e.Message)); } else { await m.DeleteAsync(); } db.StarDatas.Remove(star); await db.SaveChangesAsync(); } } } } }
public static async Task ReactionRemove(ModCoreShard bot, MessageReactionRemoveEventArgs e) { GuildSettings cfg = null; using (var db = bot.Database.CreateContext()) { cfg = e.Channel.Guild.GetGuildSettings(db); if (cfg == null) { return; } if (cfg.ReactionRoles.Any(x => (ulong)x.ChannelId == e.Channel.Id && (ulong)x.MessageId == e.Message.Id && (ulong)x.Reaction.EmojiId == e.Emoji.Id && x.Reaction.EmojiName == e.Emoji.Name)) { var rrid = (ulong)cfg.ReactionRoles.First( x => (ulong)x.ChannelId == e.Channel.Id && (ulong)x.MessageId == e.Message.Id && (ulong)x.Reaction.EmojiId == e.Emoji.Id && x.Reaction.EmojiName == e.Emoji.Name).RoleId; var rrrole = e.Channel.Guild.GetRole(rrid); var mem = await e.Channel.Guild.GetMemberAsync(e.User.Id); if (mem.Roles.Any(x => x.Id == rrid)) { await mem.RevokeRoleAsync(rrrole); } } var emoji = cfg.Starboard.Emoji; DiscordEmoji em = null; if (emoji.EmojiId != 0) { em = DiscordEmoji.FromGuildEmote(bot.Client, (ulong)emoji.EmojiId); } else { em = DiscordEmoji.FromUnicode(bot.Client, emoji.EmojiName); } if (cfg.Starboard.Enable && e.Emoji == em) { var c = e.Channel.Guild.Channels.First(x => x.Key == (ulong)cfg.Starboard.ChannelId).Value; if (c.Id == e.Channel.Id) { /*if (db.StarDatas.Any(x => (ulong)x.StarboardMessageId == e.Message.Id && (ulong)x.StargazerId == e.User.Id)) * { * var star = db.StarDatas.First(x => (ulong)x.StarboardMessageId == e.Message.Id && (ulong)x.StargazerId == e.User.Id); * var count = db.StarDatas.Count(x => (ulong)x.StarboardMessageId == e.Message.Id); * var m = await c.GetMessageAsync((ulong)star.StarboardMessageId); * var chn = await e.Client.GetChannelAsync((ulong)star.ChannelId); * var msg = await chn.GetMessageAsync((ulong)star.MessageId); * if (count - 1 >= cfg.Starboard.Minimum) * await m.ModifyAsync($"{e.Emoji}: {count - 1} ({msg.Id}) in {msg.Channel.Mention}", embed: BuildMessageEmbed(msg)); * else * await m.DeleteAsync(); * db.StarDatas.Remove(star); * await db.SaveChangesAsync(); * }*/ // Removing behaviour due to jump links } else { long nsbid = 0; if (db.StarDatas.Any(x => (ulong)x.MessageId == e.Message.Id && (ulong)x.StargazerId == e.User.Id && x.StarboardMessageId != 0)) { var star = db.StarDatas.First(x => (ulong)x.MessageId == e.Message.Id && (ulong)x.StargazerId == e.User.Id); var count = db.StarDatas.Count(x => (ulong)x.MessageId == e.Message.Id); if (db.StarDatas.Any(x => (ulong)x.MessageId == e.Message.Id && (ulong)x.StargazerId == e.User.Id && x.StarboardMessageId != 0)) { var mid = db.StarDatas.First(x => (ulong)x.MessageId == e.Message.Id && (ulong)x.StargazerId == e.User.Id && x.StarboardMessageId != 0) .StarboardMessageId; var m = await c.GetMessageAsync((ulong)mid); if (count - 1 >= cfg.Starboard.Minimum) { await m.ModifyAsync($"{e.Emoji}: {count - 1} ({e.Message.Id}) in {e.Message.Channel.Mention}", embed : BuildMessageEmbed(e.Message)); nsbid = mid; } else { await m.DeleteAsync(); } } db.StarDatas.Remove(star); await db.SaveChangesAsync(); // somebody once told me... var allstars = db.StarDatas.Where(x => (ulong)x.MessageId == e.Message.Id).ToList(); allstars.ForEach(x => x.StarboardMessageId = nsbid); db.StarDatas.UpdateRange(allstars); await db.SaveChangesAsync(); } } } } }
public static async Task LogNewMember(ModCoreShard bot, GuildMemberAddEventArgs e) { GuildSettings cfg; using (var db = bot.Database.CreateContext()) cfg = e.Guild.GetGuildSettings(db); if (cfg == null) { return; } DiscordChannel c; if (cfg.JoinLog.Enable) { var m = e.Member; c = e.Guild.GetChannel(cfg.JoinLog.ChannelId); if (c != null) { var embed = new DiscordEmbedBuilder() .WithTitle("New member joined") .WithDescription($"ID: ({m.Id})") .WithAuthor($"{m.Username}#{m.Discriminator}", iconUrl: string.IsNullOrEmpty(m.AvatarHash) ? m.DefaultAvatarUrl : m.AvatarUrl) .AddField("Join Date", $"{m.JoinedAt.DateTime}") .AddField("Register Date", $"{m.CreationTimestamp.DateTime}") .WithColor(DiscordColor.Green); await c.ElevatedMessageAsync(embed); } } if (!cfg.Welcome.Enable) { return; } if (cfg.Welcome.ChannelId == 0) { return; } c = e.Guild.GetChannel(cfg.Welcome.ChannelId); if (c == null) { return; } var msg = cfg.Welcome.Message; string attachment = null; string embedtitle = null; var isEmbed = false; msg = WelcomeRegex.Replace(msg, m => { var str = m.Groups[1].Value; switch (str) { case "username": return(e.Member.Username); case "discriminator": return(e.Member.Discriminator); case "mention": return(e.Member.Mention); case "userid": return(e.Member.Id.ToString()); case "guildname": return(e.Guild.Name); case "channelname": return(c.Name); case "membercount": return(e.Guild.MemberCount.ToString()); case "prefix": return(cfg.Prefix ?? "?>"); case "owner-username": return(e.Guild.Owner.Username); case "owner-discriminator": return(e.Guild.Owner.Discriminator); case "guild-icon-url": return(e.Guild.IconUrl); case "channel-count": return(e.Guild.Channels.Count.ToString()); case "role-count": return(e.Guild.Roles.Count.ToString()); case "isembed": isEmbed = true; return(""); default: if (str.StartsWith("image:")) { attachment = str.Substring("image:".Length); } else if (str.StartsWith("embed-title:")) { embedtitle = str.Substring("embed-title:".Length); } return(""); } }); if (!isEmbed) { await c.SafeMessageAsync(privileged : false, s : $"{msg}\n\n{attachment}"); } else { var embed = new DiscordEmbedBuilder() .WithDescription(msg); if (!string.IsNullOrWhiteSpace(embedtitle)) { embed.WithTitle(embedtitle); } if (!string.IsNullOrWhiteSpace(attachment)) { embed.WithImageUrl(attachment); } await c.ElevatedMessageAsync(embed); } }
private static async Task <bool> NotifyCommandNotFound(ModCoreShard bot, CommandErrorEventArgs e, GuildSettings cfg, CommandContext ctx) { if (!(e.Exception is CommandNotFoundException commandNotFound)) { return(false); } // return instead of proceeding, since qualifiedName below this will throw // (since there is no Command obj) if (!cfg.SpellingHelperEnabled) { return(true); } // TODO: this only gives the first invalid token, so "a b" will just recognize as "a". // it should probably take into consideration all the tokens. var attemptedName = commandNotFound.CommandName; try { // TODO: i intended on using the library for more than just this, // but i ended up using it like this, so can probably just copy code from that lib // instead of nugetting it var leveshtein = new Levenshtein(); // lower is better // TODO: add checks var everything = bot.SharedData.Commands.Select(x => x.cmd).ToList(); var some_of_them = new List <Command>(); for (int i = 0; i < everything.Count(); i++) { if (await CanExecute(everything[i], ctx)) { some_of_them.Add(everything[i]); } } var ordered = some_of_them .Where(c => !(c is CommandGroup group) || @group.IsExecutableWithoutSubcommands) .Select(c => (qualifiedName: c.QualifiedName, description: c.Description)) .OrderBy(c => leveshtein.Distance(attemptedName, c.qualifiedName)) .DistinctBy(c => c.qualifiedName).Take(1).ToArray(); var embed = new DiscordEmbedBuilder() .WithTitle("Command **" + attemptedName.Truncate(200) + "** not found") .WithDescription("Did you mean..."); foreach (var(qualifiedName, description) in ordered) { embed.AddField(qualifiedName.Truncate(256), description?.Truncate(999) ?? "<no desc>"); } await ctx.RespondAsync(embed : embed); } catch (Exception ex) { e.Context.Client.Logger.Log(LogLevel.Critical, "CommandErrored", ex.ToString(), DateTime.Now); } return(true); }