public async Task SetSensitivityAsync(CommandContext ctx, [Description("Sensitivity (number of users allowed to join within a given timespan).")] short sensitivity) { if (sensitivity < 2 || sensitivity > 20) { throw new CommandFailedException("The sensitivity is not in the valid range ([2, 20])."); } DatabaseGuildConfig gcfg = await this.ModifyGuildConfigAsync(ctx.Guild.Id, cfg => { cfg.AntifloodSensitivity = sensitivity; }); DiscordChannel logchn = this.Shared.GetLogChannelForGuild(ctx.Client, ctx.Guild); if (!(logchn is null)) { var emb = new DiscordEmbedBuilder { Title = "Guild config changed", Color = this.ModuleColor }; emb.AddField("User responsible", ctx.User.Mention, inline: true); emb.AddField("Invoked in", ctx.Channel.Mention, inline: true); emb.AddField("Antiflood sensitivity changed to", $"Max {gcfg.AntifloodSensitivity} users per {gcfg.AntifloodCooldown}s"); await logchn.SendMessageAsync(embed : emb.Build()); } await this.InformAsync(ctx, $"Antiflood sensitivity for this guild has been changed to {Formatter.Bold(gcfg.AntifloodSensitivity.ToString())} users per {gcfg.AntifloodCooldown}s", important : false); }
public async Task SetSensitivityAsync(CommandContext ctx, [Description("Cooldown (in seconds).")] short cooldown) { if (cooldown < 2 || cooldown > 60) { throw new CommandFailedException("The cooldown is not in the valid range ([2, 60])."); } DatabaseGuildConfig gcfg = await this.ModifyGuildConfigAsync(ctx.Guild.Id, cfg => { cfg.AntiInstantLeaveCooldown = cooldown; }); DiscordChannel logchn = this.Shared.GetLogChannelForGuild(ctx.Client, ctx.Guild); if (!(logchn is null)) { var emb = new DiscordEmbedBuilder { Title = "Guild config changed", Color = this.ModuleColor }; emb.AddField("User responsible", ctx.User.Mention, inline: true); emb.AddField("Invoked in", ctx.Channel.Mention, inline: true); emb.AddField("Instant leave cooldown changed to", $"{gcfg.AntiInstantLeaveCooldown}s"); await logchn.SendMessageAsync(embed : emb.Build()); } await this.InformAsync(ctx, $"Instant leave cooldown for this guild has been changed to {Formatter.Bold(gcfg.AntiInstantLeaveCooldown.ToString())}s", important : false); }
public async Task <DiscordRole> GetOrCreateMuteRoleAsync(DiscordGuild guild) { DiscordRole muteRole = null; await this.csem.WaitAsync(); try { using (DatabaseContext db = this.shard.Database.CreateContext()) { DatabaseGuildConfig gcfg = guild.GetGuildConfig(db); muteRole = guild.GetRole(gcfg.MuteRoleId); if (muteRole is null) { muteRole = guild.Roles.Values.FirstOrDefault(r => r.Name.ToLowerInvariant() == "gf_mute"); } if (muteRole is null) { muteRole = await guild.CreateRoleAsync("gf_mute", hoist : false, mentionable : false); foreach (DiscordChannel channel in guild.Channels.Values.Where(c => c.Type == ChannelType.Text)) { await channel.AddOverwriteAsync(muteRole, deny : Permissions.SendMessages | Permissions.SendTtsMessages | Permissions.AddReactions); await Task.Delay(100); } gcfg.MuteRoleId = muteRole.Id; db.GuildConfig.Update(gcfg); await db.SaveChangesAsync(); } } } finally { this.csem.Release(); } return(muteRole); }
public async Task ExecuteGroupAsync(CommandContext ctx, [Description("Enable?")] bool enable, [Description("Cooldown (join-leave max seconds).")] short cooldown) { if (cooldown < 2 || cooldown > 60) { throw new CommandFailedException("The cooldown is not in the valid range ([2, 60])."); } DatabaseGuildConfig gcfg = await this.ModifyGuildConfigAsync(ctx.Guild.Id, cfg => { cfg.AntiInstantLeaveCooldown = cooldown; cfg.AntiInstantLeaveEnabled = enable; }); DiscordChannel logchn = this.Shared.GetLogChannelForGuild(ctx.Client, ctx.Guild); if (!(logchn is null)) { var emb = new DiscordEmbedBuilder { Title = "Guild config changed", Description = $"AntiInstantLeave {(enable ? "enabled" : "disabled")}", Color = this.ModuleColor }; emb.AddField("User responsible", ctx.User.Mention, inline: true); emb.AddField("Invoked in", ctx.Channel.Mention, inline: true); if (enable) { emb.AddField("Instant leave cooldown", gcfg.AntiInstantLeaveCooldown.ToString(), inline: true); } await logchn.SendMessageAsync(embed : emb.Build()); } await this.InformAsync(ctx, $"{Formatter.Bold(enable ? "Enabled" : "Disabled")} instant leave actions.", important : false); }
public async Task SetSensitivityAsync(CommandContext ctx, [Description("Sensitivity (messages per 5s to trigger action).")] short sensitivity) { if (sensitivity < 4 || sensitivity > 10) { throw new CommandFailedException("The sensitivity is not in the valid range ([4, 10])."); } DatabaseGuildConfig gcfg = await this.ModifyGuildConfigAsync(ctx.Guild.Id, cfg => { cfg.RatelimitSettings.Sensitivity = sensitivity; }); DiscordChannel logchn = this.Shared.GetLogChannelForGuild(ctx.Client, ctx.Guild); if (!(logchn is null)) { var emb = new DiscordEmbedBuilder { Title = "Guild config changed", Color = this.ModuleColor }; emb.AddField("User responsible", ctx.User.Mention, inline: true); emb.AddField("Invoked in", ctx.Channel.Mention, inline: true); emb.AddField("Ratelimit sensitivity changed to", $"Max {gcfg.RatelimitSensitivity} msgs per 5s"); await logchn.SendMessageAsync(embed : emb.Build()); } await this.InformAsync(ctx, $"Ratelimit sensitivity for this guild has been changed to {Formatter.Bold(gcfg.RatelimitSensitivity.ToString())} msgs per 5s", important : false); }
public async Task SetCooldownAsync(CommandContext ctx, [Description("Cooldown.")] TimeSpan cooldown) { if (cooldown.TotalSeconds < 5 || cooldown.TotalSeconds > 60) { throw new CommandFailedException("The cooldown timespan is not in the valid range ([5, 60] seconds)."); } DatabaseGuildConfig gcfg = await this.ModifyGuildConfigAsync(ctx.Guild.Id, cfg => { cfg.AntifloodCooldown = (short)cooldown.TotalSeconds; }); DiscordChannel logchn = this.Shared.GetLogChannelForGuild(ctx.Client, ctx.Guild); if (!(logchn is null)) { var emb = new DiscordEmbedBuilder { Title = "Guild config changed", Color = this.ModuleColor }; emb.AddField("User responsible", ctx.User.Mention, inline: true); emb.AddField("Invoked in", ctx.Channel.Mention, inline: true); emb.AddField("Antiflood cooldown changed to", $"{gcfg.AntifloodCooldown}s"); await logchn.SendMessageAsync(embed : emb.Build()); } await this.InformAsync(ctx, $"Antiflood cooldown for this guild has been changed to {gcfg.AntifloodCooldown}s", important : false); }
public static DatabaseGuildConfig GetGuildSettings(this DiscordGuild guild, DatabaseContextBuilder dbb) { DatabaseGuildConfig gcfg = null; using (DatabaseContext db = dbb.CreateContext()) gcfg = guild.GetGuildConfig(db); return(gcfg); }
public static async Task <DatabaseGuildConfig> GetGuildConfigAsync(this TheGodfatherModule module, ulong gid) { DatabaseGuildConfig gcfg = null; using (DatabaseContext db = module.Database.CreateContext()) gcfg = await db.GuildConfig.FindAsync((long)gid) ?? new DatabaseGuildConfig(); return(gcfg); }
public static GuildSettings GetGuildSettings(this CommandContext ctx) { var dbb = ctx.Services.GetService <DatabaseContextBuilder>(); DatabaseGuildConfig cfg = null; using (var db = dbb.CreateContext()) cfg = db.GuildConfig.SingleOrDefault(xc => (ulong)xc.GuildId == ctx.Guild.Id); return(cfg?.GetSettings()); }
public async Task ExecuteGroupAsync(CommandContext ctx, [Description("Enable?")] bool enable) { DatabaseGuildConfig gcfg = await this.ModifyGuildConfigAsync(ctx.Guild.Id, cfg => { cfg.LinkfilterEnabled = enable; }); await this.InformAsync(ctx, $"{(enable ? "Enabled" : "Disabled")} link filtering!", important : false); await this.LogConfigChangeAsync(ctx, "Linkfilter", gcfg.LinkfilterEnabled); }
public async Task BootersAsync(CommandContext ctx, [Description("Enable?")] bool enable) { DatabaseGuildConfig gcfg = await this.ModifyGuildConfigAsync(ctx.Guild.Id, cfg => { cfg.LinkfilterBootersEnabled = enable; }); await this.InformAsync(ctx, $"{(enable ? "Enabled" : "Disabled")} DDoS/Booter website filtering!", important : false); await this.LogConfigChangeAsync(ctx, "DDoS/Booter websites filtering", gcfg.LinkfilterBootersEnabled); }
public async Task ExecuteGroupAsync(CommandContext ctx, [Description("Enable?")] bool enable, [Description("Sensitivity (number of users allowed to join within a given timespan).")] short sensitivity, [Description("Action type.")] PunishmentActionType action = PunishmentActionType.Kick, [Description("Cooldown.")] TimeSpan?cooldown = null) { if (sensitivity < 2 || sensitivity > 20) { throw new CommandFailedException("The sensitivity is not in the valid range ([2, 20])."); } if (cooldown?.TotalSeconds < 5 || cooldown?.TotalSeconds > 60) { throw new CommandFailedException("The cooldown timespan is not in the valid range ([5, 60] seconds)."); } var settings = new AntifloodSettings { Action = action, Cooldown = (short?)cooldown?.TotalSeconds ?? 10, Enabled = enable, Sensitivity = sensitivity }; using (DatabaseContext db = this.Database.CreateContext()) { DatabaseGuildConfig gcfg = await this.GetGuildConfigAsync(ctx.Guild.Id); gcfg.AntifloodSettings = settings; db.GuildConfig.Update(gcfg); await db.SaveChangesAsync(); } DiscordChannel logchn = this.Shared.GetLogChannelForGuild(ctx.Client, ctx.Guild); if (!(logchn is null)) { var emb = new DiscordEmbedBuilder { Title = "Guild config changed", Description = $"Antiflood {(enable ? "enabled" : "disabled")}", Color = this.ModuleColor }; emb.AddField("User responsible", ctx.User.Mention, inline: true); emb.AddField("Invoked in", ctx.Channel.Mention, inline: true); if (enable) { emb.AddField("Antiflood sensitivity", settings.Sensitivity.ToString(), inline: true); emb.AddField("Antiflood cooldown", settings.Cooldown.ToString(), inline: true); emb.AddField("Antiflood action", settings.Action.ToTypeString(), inline: true); } await logchn.SendMessageAsync(embed : emb.Build()); } await this.InformAsync(ctx, $"{Formatter.Bold(enable ? "Enabled" : "Disabled")} antiflood actions.", important : false); }
public static async Task MemberJoinEventHandlerAsync(TheGodfatherShard shard, GuildMemberAddEventArgs e) { DatabaseGuildConfig gcfg = e.Guild.GetGuildSettings(shard.Database); await Task.Delay(TimeSpan.FromSeconds(gcfg.AntiInstantLeaveSettings.Cooldown + 1)); if (e.Member.Guild is null) { return; } DiscordChannel wchn = e.Guild.GetChannel(gcfg.WelcomeChannelId); if (!(wchn is null)) { if (string.IsNullOrWhiteSpace(gcfg.WelcomeMessage)) { await wchn.EmbedAsync($"Welcome to {Formatter.Bold(e.Guild.Name)}, {e.Member.Mention}!", StaticDiscordEmoji.Wave); } else { await wchn.EmbedAsync(gcfg.WelcomeMessage.Replace("%user%", e.Member.Mention), StaticDiscordEmoji.Wave); } } try { using (DatabaseContext db = shard.Database.CreateContext()) { IQueryable <ulong> rids = db.AutoAssignableRoles .Where(dbr => dbr.GuildId == e.Guild.Id) .Select(dbr => dbr.RoleId); foreach (ulong rid in rids.ToList()) { try { DiscordRole role = e.Guild.GetRole(rid); if (!(role is null)) { await e.Member.GrantRoleAsync(role); } else { db.AutoAssignableRoles.Remove(db.AutoAssignableRoles.Single(r => r.GuildId == e.Guild.Id && r.RoleId == rid)); } } catch (Exception exc) { shard.Log(LogLevel.Debug, $"| Failed to assign an automatic role to a new member!\n" + $"| {e.Guild.ToString()}\n" + $"| Exception: {exc.GetType()}\n" + $"| Message: {exc.Message}" ); } }
private static async Task RegisterGuildAsync(SharedData shared, DatabaseContextBuilder dbb, ulong gid) { shared.GuildConfigurations.TryAdd(gid, CachedGuildConfig.Default); using (DatabaseContext db = dbb.CreateContext()) { var gcfg = new DatabaseGuildConfig { GuildId = gid }; if (!db.GuildConfig.Contains(gcfg)) { db.GuildConfig.Add(gcfg); await db.SaveChangesAsync(); } } }
public static async Task <DatabaseGuildConfig> ModifyGuildConfigAsync(this TheGodfatherModule module, ulong gid, Action <DatabaseGuildConfig> action) { DatabaseGuildConfig gcfg = null; using (DatabaseContext db = module.Database.CreateContext()) { gcfg = await db.GuildConfig.FindAsync((long)gid) ?? new DatabaseGuildConfig(); action(gcfg); db.GuildConfig.Update(gcfg); await db.SaveChangesAsync(); } CachedGuildConfig cgcfg = module.Shared.GetGuildConfig(gid); cgcfg = gcfg.CachedConfig; module.Shared.UpdateGuildConfig(gid, _ => cgcfg); return(gcfg); }
public async Task GetOrSetCurrencyAsync(CommandContext ctx, [RemainingText, Description("New currency.")] string currency = null) { if (string.IsNullOrWhiteSpace(currency)) { await this.InformAsync(ctx, StaticDiscordEmoji.MoneyBag, $"Currency for this guild: {this.Shared.GetGuildConfig(ctx.Guild.Id).Currency ?? "credit"}"); } else { if (currency.Length > 30) { throw new CommandFailedException("Currency name cannot be longer than 30 characters!"); } DatabaseGuildConfig gcfg = await this.ModifyGuildConfigAsync(ctx.Guild.Id, cfg => { cfg.Currency = currency; }); await this.InformAsync(ctx, $"Changed the currency to: {gcfg.Currency}", important : false); } }
public async Task GetOrSetPrefixAsync(CommandContext ctx, [Description("Prefix to set.")] string prefix = null) { if (string.IsNullOrWhiteSpace(prefix)) { string p = this.Shared.GetGuildPrefix(ctx.Guild.Id); await this.InformAsync(ctx, StaticDiscordEmoji.Information, $"Current prefix for this guild: {Formatter.Bold(p)}"); return; } if (prefix.Length > 12) { throw new CommandFailedException("Prefix cannot be longer than 12 characters."); } DatabaseGuildConfig gcfg = await this.ModifyGuildConfigAsync(ctx.Guild.Id, cfg => { cfg.Prefix = (prefix == this.Shared.BotConfiguration.DefaultPrefix) ? null : prefix; }); await this.InformAsync(ctx, $"Successfully changed the prefix for this guild to: {Formatter.Bold(gcfg.Prefix ?? this.Shared.BotConfiguration.DefaultPrefix)}", important : false); }
public async Task SetActionAsync(CommandContext ctx, [Description("Action type.")] PunishmentActionType action) { DatabaseGuildConfig gcfg = await this.ModifyGuildConfigAsync(ctx.Guild.Id, cfg => { cfg.AntifloodAction = action; }); DiscordChannel logchn = this.Shared.GetLogChannelForGuild(ctx.Client, ctx.Guild); if (!(logchn is null)) { var emb = new DiscordEmbedBuilder { Title = "Guild config changed", Color = this.ModuleColor }; emb.AddField("User responsible", ctx.User.Mention, inline: true); emb.AddField("Invoked in", ctx.Channel.Mention, inline: true); emb.AddField("Antiflood action changed to", gcfg.AntifloodAction.ToTypeString()); await logchn.SendMessageAsync(embed : emb.Build()); } await this.InformAsync(ctx, $"Antiflood action for this guild has been changed to {Formatter.Bold(gcfg.AntifloodAction.ToTypeString())}", important : false); }
public async Task ExecuteGroupAsync(CommandContext ctx, [Description("Enable?")] bool enable, [Description("Sensitivity (messages per 5s to trigger action).")] short sensitivity, [Description("Action type.")] PunishmentActionType action = PunishmentActionType.PermanentMute) { if (sensitivity < 4 || sensitivity > 10) { throw new CommandFailedException("The sensitivity is not in the valid range ([4, 10])."); } DatabaseGuildConfig gcfg = await this.ModifyGuildConfigAsync(ctx.Guild.Id, cfg => { cfg.RatelimitEnabled = enable; cfg.RatelimitAction = action; cfg.RatelimitSensitivity = sensitivity; }); DiscordChannel logchn = this.Shared.GetLogChannelForGuild(ctx.Client, ctx.Guild); if (!(logchn is null)) { var emb = new DiscordEmbedBuilder { Title = "Guild config changed", Description = $"Ratelimit {(enable ? "enabled" : "disabled")}", Color = this.ModuleColor }; emb.AddField("User responsible", ctx.User.Mention, inline: true); emb.AddField("Invoked in", ctx.Channel.Mention, inline: true); if (enable) { emb.AddField("Ratelimit sensitivity", gcfg.RatelimitSensitivity.ToString(), inline: true); emb.AddField("Ratelimit action", gcfg.RatelimitAction.ToTypeString(), inline: true); } await logchn.SendMessageAsync(embed : emb.Build()); } await this.InformAsync(ctx, $"{Formatter.Bold(gcfg.RatelimitEnabled ? "Enabled" : "Disabled")} ratelimit actions.", important : false); }
public static async Task SetGuildSettingsAsync(this CommandContext ctx, GuildSettings gcfg) { var dbb = ctx.Services.GetService <DatabaseContextBuilder>(); using (var db = dbb.CreateContext()) { var cfg = db.GuildConfig.SingleOrDefault(xc => (ulong)xc.GuildId == ctx.Guild.Id); if (cfg == null) { cfg = new DatabaseGuildConfig { GuildId = (long)ctx.Guild.Id }; cfg.SetSettings(gcfg); await db.GuildConfig.AddAsync(cfg); } else { cfg.SetSettings(gcfg); db.GuildConfig.Update(cfg); } await db.SaveChangesAsync(); } }