merged gc rework branch, but deleted all migrations as they're incompatible
This commit is contained in:
parent
e97fbe64c5
commit
5450d40bae
114 changed files with 9639 additions and 9175 deletions
CHANGELOG.md
src/EllieBot
Bot.cs
Db
EllieContext.csEllieDbService.cs
Extensions
Models
Migrations
MigrationQueries.cs
PostgreSql
20250126062816_cleanup.sql20250127062816_init.Designer.cs20250127062816_init.csPostgreSqlContextModelSnapshot.cs
Sqlite
Modules
Administration
Administration.csAdministrationService.cs
AutoAssignableRoles
AutoPublishService.csGameVoiceChannel
Mute
Notify
Protection
Role
SelfAssignableRoles
Timezone
UserPunish
VcRole
Expressions
Gambling
Games/ChatterBot
Permissions
Searches
Feeds
StreamNotification
Translate
_common/StreamNotifications/Models
Utility
Xp
|
@ -188,7 +188,7 @@ Mostly based on [keepachangelog](https://keepachangelog.com/en/1.1.0/) except da
|
|||
|
||||
- Self Assigned Roles reworked! Use `.h .sar` for the list of commands
|
||||
- `.sar autodel`
|
||||
- Toggles the automatic deletion of the user's message and Nadeko's confirmations for .iam and .iamn commands.
|
||||
- Toggles the automatic deletion of the user's message and Ellie's confirmations for .iam and .iamn commands.
|
||||
- `.sar ad`
|
||||
- Adds a role to the list of self-assignable roles. You can also specify a group.
|
||||
- If 'Exclusive self-assignable roles' feature is enabled (.sar exclusive), users will be able to pick one role
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
#nullable disable
|
||||
using DryIoc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using EllieBot.Common.Configs;
|
||||
using EllieBot.Common.ModuleBehaviors;
|
||||
using EllieBot.Db.Models;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using RunMode = Discord.Commands.RunMode;
|
||||
|
@ -15,10 +12,7 @@ namespace EllieBot;
|
|||
|
||||
public sealed class Bot : IBot
|
||||
{
|
||||
public event Func<GuildConfig, Task> JoinedGuild = delegate { return Task.CompletedTask; };
|
||||
|
||||
public DiscordSocketClient Client { get; }
|
||||
public IReadOnlyCollection<GuildConfig> AllGuildConfigs { get; private set; }
|
||||
|
||||
private IContainer Services { get; set; }
|
||||
|
||||
|
@ -102,7 +96,6 @@ public sealed class Bot : IBot
|
|||
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
AllGuildConfigs = await uow.GuildConfigs.GetAllGuildConfigs(startingGuildIdList);
|
||||
uow.EnsureUserCreated(bot.Id, bot.Username, bot.Discriminator, bot.AvatarId);
|
||||
}
|
||||
|
||||
|
@ -114,10 +107,6 @@ public sealed class Bot : IBot
|
|||
|
||||
var svcs = new Container();
|
||||
|
||||
// this is required in order for marmalade unloading to work
|
||||
// svcs.Components.Remove<IPlanner, Planner>();
|
||||
// svcs.Components.Add<IPlanner, RemovablePlanner>();
|
||||
|
||||
svcs.AddSingleton<IBotCreds>(_ => _credsProvider.GetCreds());
|
||||
svcs.AddSingleton<DbService, DbService>(_db);
|
||||
svcs.AddSingleton<IBotCredsProvider>(_credsProvider);
|
||||
|
@ -245,16 +234,6 @@ public sealed class Bot : IBot
|
|||
private Task Client_JoinedGuild(SocketGuild arg)
|
||||
{
|
||||
Log.Information("Joined server: {GuildName} [{GuildId}]", arg.Name, arg.Id);
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
GuildConfig gc;
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
gc = uow.GuildConfigsForId(arg.Id, null);
|
||||
}
|
||||
|
||||
await JoinedGuild.Invoke(gc);
|
||||
});
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#nullable disable
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Diagnostics;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using EllieBot.Db.Models;
|
||||
using EllieBot.Modules.Administration.Services;
|
||||
|
||||
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
||||
|
||||
|
@ -11,6 +11,11 @@ namespace EllieBot.Db;
|
|||
public abstract class EllieContext : DbContext
|
||||
{
|
||||
public DbSet<GuildConfig> GuildConfigs { get; set; }
|
||||
public DbSet<Permissionv2> Permissions { get; set; }
|
||||
|
||||
//new
|
||||
public DbSet<XpSettings> XpSettings { get; set; }
|
||||
|
||||
public DbSet<GreetSettings> GreetSettings { get; set; }
|
||||
|
||||
public DbSet<Quote> Quotes { get; set; }
|
||||
|
@ -46,7 +51,6 @@ public abstract class EllieContext : DbContext
|
|||
public DbSet<AutoTranslateChannel> AutoTranslateChannels { get; set; }
|
||||
public DbSet<AutoTranslateUser> AutoTranslateUsers { get; set; }
|
||||
|
||||
public DbSet<Permissionv2> Permissions { get; set; }
|
||||
|
||||
public DbSet<BankUser> BankUsers { get; set; }
|
||||
|
||||
|
@ -76,7 +80,7 @@ public abstract class EllieContext : DbContext
|
|||
{
|
||||
// load all entities from current assembly
|
||||
modelBuilder.ApplyConfigurationsFromAssembly(typeof(EllieContext).Assembly);
|
||||
|
||||
|
||||
#region Notify
|
||||
|
||||
modelBuilder.Entity<Notify>(e =>
|
||||
|
@ -170,10 +174,10 @@ public abstract class EllieContext : DbContext
|
|||
modelBuilder.Entity<UserBetStats>(ubs =>
|
||||
{
|
||||
ubs.HasIndex(x => new
|
||||
{
|
||||
x.UserId,
|
||||
x.Game
|
||||
})
|
||||
{
|
||||
x.UserId,
|
||||
x.Game
|
||||
})
|
||||
.IsUnique();
|
||||
|
||||
ubs.HasIndex(x => x.MaxWin)
|
||||
|
@ -221,174 +225,8 @@ public abstract class EllieContext : DbContext
|
|||
|
||||
configEntity.Property(x => x.VerboseErrors)
|
||||
.HasDefaultValue(true);
|
||||
|
||||
modelBuilder.Entity<GuildConfig>()
|
||||
.HasMany(x => x.DelMsgOnCmdChannels)
|
||||
.WithOne()
|
||||
.HasForeignKey(x => x.GuildConfigId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<GuildConfig>()
|
||||
.HasMany(x => x.FollowedStreams)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<GuildConfig>()
|
||||
.HasMany(x => x.GenerateCurrencyChannelIds)
|
||||
.WithOne(x => x.GuildConfig)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<GuildConfig>()
|
||||
.HasMany(x => x.Permissions)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<GuildConfig>()
|
||||
.HasMany(x => x.CommandCooldowns)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<GuildConfig>()
|
||||
.HasMany(x => x.FilterInvitesChannelIds)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<GuildConfig>()
|
||||
.HasMany(x => x.FilterLinksChannelIds)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<GuildConfig>()
|
||||
.HasMany(x => x.FilteredWords)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<GuildConfig>()
|
||||
.HasMany(x => x.FilterWordsChannelIds)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<GuildConfig>()
|
||||
.HasMany(x => x.MutedUsers)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<GuildConfig>()
|
||||
.HasOne(x => x.AntiRaidSetting)
|
||||
.WithOne()
|
||||
.HasForeignKey<AntiRaidSetting>(x => x.GuildConfigId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
// start antispam
|
||||
|
||||
modelBuilder.Entity<GuildConfig>()
|
||||
.HasOne(x => x.AntiSpamSetting)
|
||||
.WithOne()
|
||||
.HasForeignKey<AntiSpamSetting>(x => x.GuildConfigId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<AntiSpamSetting>()
|
||||
.HasMany(x => x.IgnoredChannels)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
// end antispam
|
||||
|
||||
modelBuilder.Entity<GuildConfig>()
|
||||
.HasOne(x => x.AntiAltSetting)
|
||||
.WithOne()
|
||||
.HasForeignKey<AntiAltSetting>(x => x.GuildConfigId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<GuildConfig>()
|
||||
.HasMany(x => x.UnmuteTimers)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<GuildConfig>()
|
||||
.HasMany(x => x.UnbanTimer)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<GuildConfig>()
|
||||
.HasMany(x => x.UnroleTimer)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<GuildConfig>()
|
||||
.HasMany(x => x.VcRoleInfos)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<GuildConfig>()
|
||||
.HasMany(x => x.CommandAliases)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<GuildConfig>()
|
||||
.HasMany(x => x.SlowmodeIgnoredRoles)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<GuildConfig>()
|
||||
.HasMany(x => x.SlowmodeIgnoredUsers)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
// start shop
|
||||
modelBuilder.Entity<GuildConfig>()
|
||||
.HasMany(x => x.ShopEntries)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<ShopEntry>()
|
||||
.HasMany(x => x.Items)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
// end shop
|
||||
|
||||
// start streamrole
|
||||
|
||||
modelBuilder.Entity<GuildConfig>()
|
||||
.HasOne(x => x.StreamRole)
|
||||
.WithOne(x => x.GuildConfig)
|
||||
.HasForeignKey<StreamRoleSettings>(x => x.GuildConfigId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<StreamRoleSettings>()
|
||||
.HasMany(x => x.Whitelist)
|
||||
.WithOne(x => x.StreamRoleSettings)
|
||||
.HasForeignKey(x => x.StreamRoleSettingsId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<StreamRoleSettings>()
|
||||
.HasMany(x => x.Blacklist)
|
||||
.WithOne(x => x.StreamRoleSettings)
|
||||
.HasForeignKey(x => x.StreamRoleSettingsId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
// end streamrole
|
||||
|
||||
modelBuilder.Entity<GuildConfig>()
|
||||
.HasOne(x => x.XpSettings)
|
||||
.WithOne(x => x.GuildConfig)
|
||||
.HasForeignKey<XpSettings>(x => x.GuildConfigId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<GuildConfig>()
|
||||
.HasMany(x => x.FeedSubs)
|
||||
.WithOne(x => x.GuildConfig)
|
||||
.HasForeignKey(x => x.GuildConfigId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<FeedSub>()
|
||||
.HasAlternateKey(x => new
|
||||
{
|
||||
x.GuildConfigId,
|
||||
x.Url
|
||||
});
|
||||
|
||||
modelBuilder.Entity<PlantedCurrency>().HasIndex(x => x.MessageId).IsUnique();
|
||||
|
||||
modelBuilder.Entity<PlantedCurrency>().HasIndex(x => x.ChannelId);
|
||||
|
@ -397,9 +235,7 @@ public abstract class EllieContext : DbContext
|
|||
|
||||
#endregion
|
||||
|
||||
#region WarningPunishments
|
||||
|
||||
var warnpunishmentEntity = modelBuilder.Entity<WarningPunishment>(b =>
|
||||
modelBuilder.Entity<WarningPunishment>(b =>
|
||||
{
|
||||
b.HasAlternateKey(x => new
|
||||
{
|
||||
|
@ -408,8 +244,6 @@ public abstract class EllieContext : DbContext
|
|||
});
|
||||
});
|
||||
|
||||
#endregion
|
||||
|
||||
#region MusicPlaylists
|
||||
|
||||
var musicPlaylistEntity = modelBuilder.Entity<MusicPlaylist>();
|
||||
|
@ -489,33 +323,6 @@ public abstract class EllieContext : DbContext
|
|||
|
||||
#endregion
|
||||
|
||||
#region XpRoleReward
|
||||
|
||||
modelBuilder.Entity<XpRoleReward>()
|
||||
.HasIndex(x => new
|
||||
{
|
||||
x.XpSettingsId,
|
||||
x.Level
|
||||
})
|
||||
.IsUnique();
|
||||
|
||||
modelBuilder.Entity<XpSettings>()
|
||||
.HasMany(x => x.RoleRewards)
|
||||
.WithOne(x => x.XpSettings)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<XpSettings>()
|
||||
.HasMany(x => x.CurrencyRewards)
|
||||
.WithOne(x => x.XpSettings)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<XpSettings>()
|
||||
.HasMany(x => x.ExclusionList)
|
||||
.WithOne(x => x.XpSettings)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Club
|
||||
|
||||
var ci = modelBuilder.Entity<ClubInfo>();
|
||||
|
@ -806,8 +613,15 @@ public abstract class EllieContext : DbContext
|
|||
|
||||
#if DEBUG
|
||||
private static readonly ILoggerFactory _debugLoggerFactory = LoggerFactory.Create(x => x.AddConsole());
|
||||
#endif
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
=> optionsBuilder.UseLoggerFactory(_debugLoggerFactory);
|
||||
{
|
||||
#if DEBUG
|
||||
optionsBuilder.UseLoggerFactory(_debugLoggerFactory);
|
||||
#endif
|
||||
|
||||
optionsBuilder.ConfigureWarnings(x => x.Log(RelationalEventId.PendingModelChangesWarning)
|
||||
.Ignore());
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@
|
|||
using LinqToDB.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using EllieBot.Migrations;
|
||||
|
||||
namespace EllieBot.Db;
|
||||
|
||||
|
@ -28,14 +27,14 @@ public sealed class EllieDbService : DbService
|
|||
public override async Task SetupAsync()
|
||||
{
|
||||
await using var context = CreateRawDbContext(DbType, ConnString);
|
||||
|
||||
|
||||
await RunMigration(context);
|
||||
|
||||
// make sure sqlite db is in wal journal mode
|
||||
if (context is SqliteContext)
|
||||
{
|
||||
await context.Database.ExecuteSqlRawAsync("PRAGMA journal_mode=WAL");
|
||||
}
|
||||
|
||||
await RunMigration(context);
|
||||
}
|
||||
|
||||
public override EllieContext CreateRawDbContext(string dbType, string connString)
|
||||
|
|
|
@ -9,4 +9,40 @@ public static class DbExtensions
|
|||
public static T GetById<T>(this DbSet<T> set, int id)
|
||||
where T : DbEntity
|
||||
=> set.FirstOrDefault(x => x.Id == id);
|
||||
|
||||
public static GuildConfig GuildConfigsForId(this DbContext ctx, ulong guildId)
|
||||
{
|
||||
var query = ctx.Set<GuildConfig>().Where(gc => gc.GuildId == guildId);
|
||||
return query.FirstOrDefault();
|
||||
}
|
||||
|
||||
public static GuildFilterConfig FilterConfigForId(
|
||||
this DbContext ctx,
|
||||
ulong guildId,
|
||||
Func<IQueryable<GuildFilterConfig>, IQueryable<GuildFilterConfig>> includes = default)
|
||||
{
|
||||
includes ??= static set => set;
|
||||
|
||||
var gfc = includes(ctx.Set<GuildFilterConfig>()
|
||||
.Where(gc => gc.GuildId == guildId))
|
||||
.FirstOrDefault();
|
||||
|
||||
if (gfc is null)
|
||||
{
|
||||
ctx.Add(gfc = new GuildFilterConfig()
|
||||
{
|
||||
});
|
||||
}
|
||||
|
||||
return gfc;
|
||||
}
|
||||
|
||||
public static GuildConfig GuildConfigsForId(
|
||||
this DbContext ctx,
|
||||
ulong guildId,
|
||||
Func<IQueryable<GuildConfig>, IQueryable<GuildConfig>> set)
|
||||
{
|
||||
var query = ctx.Set<GuildConfig>().Where(gc => gc.GuildId == guildId);
|
||||
return query.FirstOrDefault();
|
||||
}
|
||||
}
|
|
@ -84,7 +84,7 @@ public static class DiscordUserExtensions
|
|||
> users.AsQueryable().Where(y => y.UserId == id).Select(y => y.TotalXp).FirstOrDefault())
|
||||
.Count()
|
||||
+ 1;
|
||||
|
||||
|
||||
public static Task<List<DiscordUser>> GetTopRichest(
|
||||
this DbSet<DiscordUser> users,
|
||||
ulong botId,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#nullable disable
|
||||
using LinqToDB;
|
||||
using LinqToDB.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using EllieBot.Db.Models;
|
||||
|
@ -29,102 +30,23 @@ public static class GuildConfigExtensions
|
|||
/// <param name="ctx">Db Context</param>
|
||||
/// <param name="guildId">Id of the guild to get stream role settings for.</param>
|
||||
/// <returns>Guild'p stream role settings</returns>
|
||||
public static StreamRoleSettings GetStreamRoleSettings(this DbContext ctx, ulong guildId)
|
||||
public static async Task<StreamRoleSettings> GetOrCreateStreamRoleSettings(this DbContext ctx, ulong guildId)
|
||||
{
|
||||
var conf = ctx.GuildConfigsForId(guildId,
|
||||
set => set.Include(y => y.StreamRole)
|
||||
.Include(y => y.StreamRole.Whitelist)
|
||||
.Include(y => y.StreamRole.Blacklist));
|
||||
var srs = await ctx.GetTable<StreamRoleSettings>()
|
||||
.Where(x => x.GuildId == guildId)
|
||||
.FirstOrDefaultAsyncEF();
|
||||
|
||||
if (conf.StreamRole is null)
|
||||
conf.StreamRole = new();
|
||||
if (srs is not null)
|
||||
return srs;
|
||||
|
||||
return conf.StreamRole;
|
||||
}
|
||||
|
||||
private static IQueryable<GuildConfig> IncludeEverything(this DbSet<GuildConfig> configs)
|
||||
=> configs
|
||||
.AsSplitQuery()
|
||||
.Include(gc => gc.CommandCooldowns)
|
||||
.Include(gc => gc.FollowedStreams)
|
||||
.Include(gc => gc.StreamRole)
|
||||
.Include(gc => gc.DelMsgOnCmdChannels)
|
||||
.Include(gc => gc.XpSettings)
|
||||
.ThenInclude(x => x.ExclusionList);
|
||||
|
||||
public static async Task<GuildConfig[]> GetAllGuildConfigs(
|
||||
this DbSet<GuildConfig> configs,
|
||||
List<ulong> availableGuilds)
|
||||
{
|
||||
var result = await configs
|
||||
.IncludeEverything()
|
||||
.Where(x => availableGuilds.Contains(x.GuildId))
|
||||
.AsNoTracking()
|
||||
.ToArrayAsync();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and creates if it doesn't exist a config for a guild.
|
||||
/// </summary>
|
||||
/// <param name="ctx">Context</param>
|
||||
/// <param name="guildId">Id of the guide</param>
|
||||
/// <param name="includes">Use to manipulate the set however you want. Pass null to include everything</param>
|
||||
/// <returns>Config for the guild</returns>
|
||||
public static GuildConfig GuildConfigsForId(
|
||||
this DbContext ctx,
|
||||
ulong guildId,
|
||||
Func<DbSet<GuildConfig>, IQueryable<GuildConfig>> includes)
|
||||
{
|
||||
GuildConfig config;
|
||||
|
||||
if (includes is null)
|
||||
config = ctx.Set<GuildConfig>().IncludeEverything().FirstOrDefault(c => c.GuildId == guildId);
|
||||
else
|
||||
srs = new()
|
||||
{
|
||||
var set = includes(ctx.Set<GuildConfig>());
|
||||
config = set.FirstOrDefault(c => c.GuildId == guildId);
|
||||
}
|
||||
GuildId = guildId,
|
||||
};
|
||||
|
||||
if (config is null)
|
||||
{
|
||||
ctx.Set<GuildConfig>()
|
||||
.Add(config = new()
|
||||
{
|
||||
GuildId = guildId,
|
||||
Permissions = Permissionv2.GetDefaultPermlist,
|
||||
WarningsInitialized = true,
|
||||
});
|
||||
ctx.SaveChanges();
|
||||
}
|
||||
ctx.Set<StreamRoleSettings>().Add(srs);
|
||||
|
||||
if (!config.WarningsInitialized)
|
||||
{
|
||||
config.WarningsInitialized = true;
|
||||
}
|
||||
|
||||
return config;
|
||||
|
||||
// ctx.GuildConfigs
|
||||
// .ToLinqToDBTable()
|
||||
// .InsertOrUpdate(() => new()
|
||||
// {
|
||||
// GuildId = guildId,
|
||||
// Permissions = Permissionv2.GetDefaultPermlist,
|
||||
// WarningsInitialized = true,
|
||||
// WarnPunishments = DefaultWarnPunishments
|
||||
// },
|
||||
// _ => new(),
|
||||
// () => new()
|
||||
// {
|
||||
// GuildId = guildId
|
||||
// });
|
||||
//
|
||||
// if(includes is null)
|
||||
// return ctx.GuildConfigs
|
||||
// .ToLinqToDBTable()
|
||||
// .First(x => x.GuildId == guildId);
|
||||
return srs;
|
||||
}
|
||||
|
||||
public static LogSetting LogSettingsFor(this DbContext ctx, ulong guildId)
|
||||
|
@ -148,6 +70,8 @@ public static class GuildConfigExtensions
|
|||
return logSetting;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static IEnumerable<GuildConfig> PermissionsForAll(this DbSet<GuildConfig> configs, List<ulong> include)
|
||||
{
|
||||
var query = configs.AsQueryable().Where(x => include.Contains(x.GuildId)).Include(gc => gc.Permissions);
|
||||
|
@ -182,45 +106,24 @@ public static class GuildConfigExtensions
|
|||
return config;
|
||||
}
|
||||
|
||||
public static IEnumerable<FollowedStream> GetFollowedStreams(this DbSet<GuildConfig> configs)
|
||||
=> configs.AsQueryable().Include(x => x.FollowedStreams).SelectMany(gc => gc.FollowedStreams).ToArray();
|
||||
|
||||
public static IEnumerable<FollowedStream> GetFollowedStreams(this DbSet<GuildConfig> configs, List<ulong> included)
|
||||
=> configs.AsQueryable()
|
||||
.Where(gc => included.Contains(gc.GuildId))
|
||||
.Include(gc => gc.FollowedStreams)
|
||||
.SelectMany(gc => gc.FollowedStreams)
|
||||
.ToList();
|
||||
|
||||
|
||||
public static XpSettings XpSettingsFor(this DbContext ctx, ulong guildId)
|
||||
public static async Task<XpSettings> XpSettingsFor(this DbContext ctx, ulong guildId)
|
||||
{
|
||||
var gc = ctx.GuildConfigsForId(guildId,
|
||||
set => set.Include(x => x.XpSettings)
|
||||
.ThenInclude(x => x.RoleRewards)
|
||||
.Include(x => x.XpSettings)
|
||||
.ThenInclude(x => x.CurrencyRewards)
|
||||
.Include(x => x.XpSettings)
|
||||
.ThenInclude(x => x.ExclusionList));
|
||||
var srs = await ctx.GetTable<XpSettings>()
|
||||
.Where(x => x.GuildId == guildId)
|
||||
.FirstOrDefaultAsyncLinqToDB();
|
||||
|
||||
if (gc.XpSettings is null)
|
||||
gc.XpSettings = new();
|
||||
if (srs is not null)
|
||||
return srs;
|
||||
|
||||
return gc.XpSettings;
|
||||
srs = await ctx.GetTable<XpSettings>()
|
||||
.InsertWithOutputAsync(() => new()
|
||||
{
|
||||
GuildId = guildId,
|
||||
});
|
||||
|
||||
return srs;
|
||||
}
|
||||
|
||||
public static IEnumerable<GeneratingChannel> GetGeneratingChannels(this DbSet<GuildConfig> configs)
|
||||
=> configs.AsQueryable()
|
||||
.Include(x => x.GenerateCurrencyChannelIds)
|
||||
.Where(x => x.GenerateCurrencyChannelIds.Any())
|
||||
.SelectMany(x => x.GenerateCurrencyChannelIds)
|
||||
.Select(x => new GeneratingChannel
|
||||
{
|
||||
ChannelId = x.ChannelId,
|
||||
GuildId = x.GuildConfig.GuildId
|
||||
})
|
||||
.ToArray();
|
||||
|
||||
public class GeneratingChannel
|
||||
{
|
||||
public ulong GuildId { get; set; }
|
||||
|
|
|
@ -9,7 +9,7 @@ public static class UserXpExtensions
|
|||
{
|
||||
public static async Task<UserXpStats?> GetGuildUserXp(this ITable<UserXpStats> table, ulong guildId, ulong userId)
|
||||
=> await table.FirstOrDefaultAsyncLinqToDB(x => x.GuildId == guildId && x.UserId == userId);
|
||||
|
||||
|
||||
public static UserXpStats GetOrCreateUserXpStats(this DbContext ctx, ulong guildId, ulong userId)
|
||||
{
|
||||
var usr = ctx.Set<UserXpStats>().FirstOrDefault(x => x.UserId == userId && x.GuildId == guildId);
|
||||
|
|
|
@ -1,8 +1,21 @@
|
|||
#nullable disable
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
public class CommandAlias : DbEntity
|
||||
{
|
||||
public ulong GuildId { get; set; }
|
||||
public string Trigger { get; set; }
|
||||
public string Mapping { get; set; }
|
||||
}
|
||||
|
||||
public class CommandAliasEntityConfiguration : IEntityTypeConfiguration<CommandAlias>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<CommandAlias> builder)
|
||||
{
|
||||
builder.HasIndex(x => x.GuildId);
|
||||
}
|
||||
}
|
|
@ -1,8 +1,25 @@
|
|||
#nullable disable
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
public class CommandCooldown : DbEntity
|
||||
{
|
||||
{
|
||||
public ulong GuildId { get; set; }
|
||||
public int Seconds { get; set; }
|
||||
public string CommandName { get; set; }
|
||||
}
|
||||
|
||||
public class CommandCooldownEntityConfiguration : IEntityTypeConfiguration<CommandCooldown>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<CommandCooldown> builder)
|
||||
{
|
||||
builder.HasIndex(x => new
|
||||
{
|
||||
x.GuildId,
|
||||
x.CommandName
|
||||
})
|
||||
.IsUnique();
|
||||
}
|
||||
}
|
|
@ -1,16 +1,25 @@
|
|||
#nullable disable
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
public class DelMsgOnCmdChannel : DbEntity
|
||||
{
|
||||
public int GuildConfigId { get; set; }
|
||||
|
||||
public ulong GuildId { get; set; }
|
||||
public ulong ChannelId { get; set; }
|
||||
public bool State { get; set; }
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
=> ChannelId.GetHashCode();
|
||||
|
||||
public override bool Equals(object obj)
|
||||
=> obj is DelMsgOnCmdChannel x && x.ChannelId == ChannelId;
|
||||
}
|
||||
public class DelMsgOnCmdChannelEntityConfiguration : IEntityTypeConfiguration<DelMsgOnCmdChannel>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<DelMsgOnCmdChannel> builder)
|
||||
{
|
||||
builder.HasIndex(x => new
|
||||
{
|
||||
x.GuildId,
|
||||
x.ChannelId
|
||||
}).IsUnique();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#nullable disable
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
|
||||
// FUTURE remove LastLevelUp from here and UserXpStats
|
||||
public class DiscordUser : DbEntity
|
||||
{
|
||||
|
|
|
@ -1,19 +1,29 @@
|
|||
#nullable disable
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
public class FeedSub : DbEntity
|
||||
{
|
||||
public int GuildConfigId { get; set; }
|
||||
public GuildConfig GuildConfig { get; set; }
|
||||
public ulong GuildId { get; set; }
|
||||
|
||||
public ulong ChannelId { get; set; }
|
||||
public string Url { get; set; }
|
||||
|
||||
|
||||
public string Message { get; set; }
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
=> Url.GetHashCode(StringComparison.InvariantCulture) ^ GuildConfigId.GetHashCode();
|
||||
|
||||
public override bool Equals(object obj)
|
||||
=> obj is FeedSub s && s.Url.ToLower() == Url.ToLower() && s.GuildConfigId == GuildConfigId;
|
||||
public sealed class FeedSubEntityConfiguration : IEntityTypeConfiguration<FeedSub>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<FeedSub> builder)
|
||||
{
|
||||
builder
|
||||
.HasIndex(x => new
|
||||
{
|
||||
x.GuildId,
|
||||
x.Url
|
||||
})
|
||||
.IsUnique();
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
#nullable disable
|
||||
#nullable disable
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
public class FlagTranslateChannel : DbEntity
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
#nullable disable
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
public class FollowedStream : DbEntity
|
||||
public class FollowedStream
|
||||
{
|
||||
public enum FType
|
||||
{
|
||||
|
@ -12,7 +15,7 @@ public class FollowedStream : DbEntity
|
|||
Trovo = 6,
|
||||
Kick = 7,
|
||||
}
|
||||
|
||||
public int Id { get; set; }
|
||||
public ulong GuildId { get; set; }
|
||||
public ulong ChannelId { get; set; }
|
||||
public string Username { get; set; }
|
||||
|
@ -29,6 +32,17 @@ public class FollowedStream : DbEntity
|
|||
|
||||
public override bool Equals(object obj)
|
||||
=> obj is FollowedStream fs && Equals(fs);
|
||||
}
|
||||
|
||||
|
||||
public sealed class FollowedStreamEntityConfig : IEntityTypeConfiguration<FollowedStream>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<FollowedStream> builder)
|
||||
{
|
||||
builder.HasIndex(x => new
|
||||
{
|
||||
x.GuildId,
|
||||
x.Username,
|
||||
x.Type,
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,14 +1,24 @@
|
|||
#nullable disable
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
public class GCChannelId : DbEntity
|
||||
{
|
||||
public GuildConfig GuildConfig { get; set; }
|
||||
public ulong GuildId { get; set; }
|
||||
public ulong ChannelId { get; set; }
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
=> obj is GCChannelId gc && gc.ChannelId == ChannelId;
|
||||
|
||||
public override int GetHashCode()
|
||||
=> ChannelId.GetHashCode();
|
||||
public class GCChannelIdEntityConfiguration : IEntityTypeConfiguration<GCChannelId>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<GCChannelId> builder)
|
||||
{
|
||||
builder.HasIndex(x => new
|
||||
{
|
||||
x.GuildId,
|
||||
x.ChannelId
|
||||
})
|
||||
.IsUnique();
|
||||
}
|
||||
}
|
|
@ -1,85 +1,59 @@
|
|||
#nullable disable
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
public class GuildFilterConfig
|
||||
{
|
||||
[Key]
|
||||
public int Id { get; set; }
|
||||
|
||||
public ulong GuildId { get; set; }
|
||||
public bool FilterInvites { get; set; }
|
||||
public bool FilterLinks { get; set; }
|
||||
public bool FilterWords { get; set; }
|
||||
public HashSet<FilterChannelId> FilterInvitesChannelIds { get; set; } = new();
|
||||
public HashSet<FilterLinksChannelId> FilterLinksChannelIds { get; set; } = new();
|
||||
|
||||
public HashSet<FilteredWord> FilteredWords { get; set; } = new();
|
||||
public HashSet<FilterWordsChannelId> FilterWordsChannelIds { get; set; } = new();
|
||||
}
|
||||
|
||||
public sealed class GuildFilterConfigEntityConfiguration : IEntityTypeConfiguration<GuildFilterConfig>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<GuildFilterConfig> builder)
|
||||
{
|
||||
builder.HasIndex(x => x.GuildId);
|
||||
}
|
||||
}
|
||||
|
||||
public class GuildConfig : DbEntity
|
||||
{
|
||||
// public bool Keep { get; set; }
|
||||
public ulong GuildId { get; set; }
|
||||
|
||||
public string Prefix { get; set; }
|
||||
|
||||
public bool DeleteMessageOnCommand { get; set; }
|
||||
public HashSet<DelMsgOnCmdChannel> DelMsgOnCmdChannels { get; set; } = new();
|
||||
|
||||
public string AutoAssignRoleIds { get; set; }
|
||||
|
||||
//todo FUTURE: DELETE, UNUSED
|
||||
public bool ExclusiveSelfAssignedRoles { get; set; }
|
||||
public bool AutoDeleteSelfAssignedRoleMessages { get; set; }
|
||||
|
||||
|
||||
//stream notifications
|
||||
public HashSet<FollowedStream> FollowedStreams { get; set; } = new();
|
||||
|
||||
//currencyGeneration
|
||||
public HashSet<GCChannelId> GenerateCurrencyChannelIds { get; set; } = new();
|
||||
|
||||
public List<Permissionv2> Permissions { get; set; }
|
||||
public bool VerbosePermissions { get; set; } = true;
|
||||
public string PermissionRole { get; set; }
|
||||
|
||||
public HashSet<CommandCooldown> CommandCooldowns { get; set; } = new();
|
||||
|
||||
//filtering
|
||||
public bool FilterInvites { get; set; }
|
||||
public bool FilterLinks { get; set; }
|
||||
public HashSet<FilterChannelId> FilterInvitesChannelIds { get; set; } = new();
|
||||
public HashSet<FilterLinksChannelId> FilterLinksChannelIds { get; set; } = new();
|
||||
|
||||
public bool FilterWords { get; set; }
|
||||
public HashSet<FilteredWord> FilteredWords { get; set; } = new();
|
||||
public HashSet<FilterWordsChannelId> FilterWordsChannelIds { get; set; } = new();
|
||||
|
||||
// mute
|
||||
public HashSet<MutedUserId> MutedUsers { get; set; } = new();
|
||||
|
||||
public string MuteRoleName { get; set; }
|
||||
|
||||
// chatterbot
|
||||
public bool CleverbotEnabled { get; set; }
|
||||
|
||||
// protection
|
||||
public AntiRaidSetting AntiRaidSetting { get; set; }
|
||||
public AntiSpamSetting AntiSpamSetting { get; set; }
|
||||
public AntiAltSetting AntiAltSetting { get; set; }
|
||||
|
||||
// time
|
||||
public string Locale { get; set; }
|
||||
public string TimeZoneId { get; set; }
|
||||
|
||||
|
||||
// timers
|
||||
public HashSet<UnmuteTimer> UnmuteTimers { get; set; } = new();
|
||||
public HashSet<UnbanTimer> UnbanTimer { get; set; } = new();
|
||||
public HashSet<UnroleTimer> UnroleTimer { get; set; } = new();
|
||||
|
||||
// vcrole
|
||||
public HashSet<VcRoleInfo> VcRoleInfos { get; set; }
|
||||
|
||||
// aliases
|
||||
public HashSet<CommandAlias> CommandAliases { get; set; } = new();
|
||||
public bool WarningsInitialized { get; set; }
|
||||
public HashSet<SlowmodeIgnoredUser> SlowmodeIgnoredUsers { get; set; }
|
||||
public HashSet<SlowmodeIgnoredRole> SlowmodeIgnoredRoles { get; set; }
|
||||
|
||||
public List<ShopEntry> ShopEntries { get; set; }
|
||||
public ulong? GameVoiceChannel { get; set; }
|
||||
public bool VerboseErrors { get; set; } = true;
|
||||
|
||||
public StreamRoleSettings StreamRole { get; set; }
|
||||
|
||||
public XpSettings XpSettings { get; set; }
|
||||
public List<FeedSub> FeedSubs { get; set; } = new();
|
||||
public bool NotifyStreamOffline { get; set; }
|
||||
public bool DeleteStreamOnlineMessage { get; set; }
|
||||
public int WarnExpireHours { get; set; }
|
||||
|
@ -88,4 +62,9 @@ public class GuildConfig : DbEntity
|
|||
public bool DisableGlobalExpressions { get; set; } = false;
|
||||
|
||||
public bool StickyRoles { get; set; }
|
||||
|
||||
public string TimeZoneId { get; set; }
|
||||
public string Locale { get; set; }
|
||||
|
||||
public List<Permissionv2> Permissions { get; set; }
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
|
@ -6,14 +6,14 @@ public class NCPixel
|
|||
{
|
||||
[Key]
|
||||
public int Id { get; set; }
|
||||
|
||||
|
||||
public required int Position { get; init; }
|
||||
|
||||
|
||||
public required long Price { get; init; }
|
||||
|
||||
|
||||
public required ulong OwnerId { get; init; }
|
||||
public required uint Color { get; init; }
|
||||
|
||||
|
||||
[MaxLength(256)]
|
||||
public required string Text { get; init; }
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
#nullable disable
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Diagnostics;
|
||||
|
||||
|
@ -7,7 +9,8 @@ namespace EllieBot.Db.Models;
|
|||
[DebuggerDisplay("{PrimaryTarget}{SecondaryTarget} {SecondaryTargetName} {State} {PrimaryTargetId}")]
|
||||
public class Permissionv2 : DbEntity, IIndexed
|
||||
{
|
||||
public int? GuildConfigId { get; set; }
|
||||
public ulong GuildId { get; set; }
|
||||
|
||||
public int Index { get; set; }
|
||||
|
||||
public PrimaryPermissionType PrimaryTarget { get; set; }
|
||||
|
@ -49,4 +52,12 @@ public enum SecondaryPermissionType
|
|||
Module,
|
||||
Command,
|
||||
AllModules
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class Permissionv2EntityConfiguration : IEntityTypeConfiguration<Permissionv2>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Permissionv2> builder)
|
||||
{
|
||||
builder.HasIndex(x => x.GuildId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ public sealed class SarGroup
|
|||
public ulong? RoleReq { get; set; }
|
||||
public ICollection<Sar> Roles { get; set; } = [];
|
||||
public bool IsExclusive { get; set; }
|
||||
|
||||
|
||||
[MaxLength(100)]
|
||||
public string? Name { get; set; }
|
||||
}
|
|
@ -1,16 +1,21 @@
|
|||
#nullable disable
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
public enum ShopEntryType
|
||||
{
|
||||
Role,
|
||||
|
||||
List,
|
||||
Command
|
||||
}
|
||||
|
||||
public class ShopEntry : DbEntity, IIndexed
|
||||
{
|
||||
public ulong GuildId { get; set; }
|
||||
|
||||
public int Index { get; set; }
|
||||
public int Price { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
@ -25,7 +30,7 @@ public class ShopEntry : DbEntity, IIndexed
|
|||
//list
|
||||
public HashSet<ShopEntryItem> Items { get; set; } = new();
|
||||
public ulong? RoleRequirement { get; set; }
|
||||
|
||||
|
||||
// command
|
||||
public string Command { get; set; }
|
||||
}
|
||||
|
@ -43,4 +48,22 @@ public class ShopEntryItem : DbEntity
|
|||
|
||||
public override int GetHashCode()
|
||||
=> Text.GetHashCode(StringComparison.InvariantCulture);
|
||||
}
|
||||
|
||||
public class ShopEntryEntityConfiguration : IEntityTypeConfiguration<ShopEntry>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<ShopEntry> builder)
|
||||
{
|
||||
builder.HasIndex(x => new
|
||||
{
|
||||
x.GuildId,
|
||||
x.Index
|
||||
})
|
||||
.IsUnique();
|
||||
|
||||
builder
|
||||
.HasMany(x => x.Items)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
}
|
||||
}
|
|
@ -1,10 +1,16 @@
|
|||
#nullable disable
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
public class StreamRoleSettings : DbEntity
|
||||
{
|
||||
public int GuildConfigId { get; set; }
|
||||
public GuildConfig GuildConfig { get; set; }
|
||||
|
||||
public ulong GuildId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the feature is enabled in the guild.
|
||||
|
@ -42,7 +48,7 @@ public class StreamRoleBlacklistedUser : DbEntity
|
|||
{
|
||||
public int StreamRoleSettingsId { get; set; }
|
||||
public StreamRoleSettings StreamRoleSettings { get; set; }
|
||||
|
||||
|
||||
public ulong UserId { get; set; }
|
||||
public string Username { get; set; }
|
||||
|
||||
|
@ -62,7 +68,7 @@ public class StreamRoleWhitelistedUser : DbEntity
|
|||
{
|
||||
public int StreamRoleSettingsId { get; set; }
|
||||
public StreamRoleSettings StreamRoleSettings { get; set; }
|
||||
|
||||
|
||||
public ulong UserId { get; set; }
|
||||
public string Username { get; set; }
|
||||
|
||||
|
@ -71,4 +77,25 @@ public class StreamRoleWhitelistedUser : DbEntity
|
|||
|
||||
public override int GetHashCode()
|
||||
=> UserId.GetHashCode();
|
||||
}
|
||||
|
||||
public class StreamRoleSettingsEntityConfiguration : IEntityTypeConfiguration<StreamRoleSettings>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<StreamRoleSettings> builder)
|
||||
{
|
||||
builder.HasIndex(x => x.GuildId)
|
||||
.IsUnique();
|
||||
|
||||
builder
|
||||
.HasMany(x => x.Whitelist)
|
||||
.WithOne(x => x.StreamRoleSettings)
|
||||
.HasForeignKey(x => x.StreamRoleSettingsId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder
|
||||
.HasMany(x => x.Blacklist)
|
||||
.WithOne(x => x.StreamRoleSettings)
|
||||
.HasForeignKey(x => x.StreamRoleSettingsId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
}
|
||||
}
|
|
@ -1,8 +1,26 @@
|
|||
#nullable disable
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
public class VcRoleInfo : DbEntity
|
||||
{
|
||||
public ulong GuildId { get; set; }
|
||||
public ulong VoiceChannelId { get; set; }
|
||||
|
||||
public ulong RoleId { get; set; }
|
||||
}
|
||||
|
||||
public class VcRoleInfoEntityConfiguration : IEntityTypeConfiguration<VcRoleInfo>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<VcRoleInfo> builder)
|
||||
{
|
||||
builder.HasIndex(x => new
|
||||
{
|
||||
x.GuildId,
|
||||
x.VoiceChannelId
|
||||
})
|
||||
.IsUnique();
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
#nullable disable
|
||||
using EllieBot.Db.Models;
|
||||
|
||||
namespace EllieBot.Services.Database.Models;
|
||||
namespace Ellieices.Database.Models;
|
||||
|
||||
public class WaifuInfo : DbEntity
|
||||
{
|
||||
|
|
|
@ -1,12 +1,30 @@
|
|||
namespace EllieBot.Db.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
public class AntiAltSetting
|
||||
{
|
||||
public int GuildConfigId { get; set; }
|
||||
|
||||
[Key]
|
||||
public int Id { get; set; }
|
||||
|
||||
public int GuildConfigId { get; set; }
|
||||
|
||||
public ulong GuildId { get; set; }
|
||||
|
||||
public TimeSpan MinAge { get; set; }
|
||||
public PunishmentAction Action { get; set; }
|
||||
public int ActionDurationMinutes { get; set; }
|
||||
public ulong? RoleId { get; set; }
|
||||
}
|
||||
|
||||
public class AntiAltSettingEntityConfiguration : IEntityTypeConfiguration<AntiAltSetting>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<AntiAltSetting> builder)
|
||||
{
|
||||
builder.HasIndex(x => x.GuildId)
|
||||
.IsUnique();
|
||||
}
|
||||
}
|
|
@ -1,11 +1,13 @@
|
|||
#nullable disable
|
||||
namespace EllieBot.Db.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
public class AntiRaidSetting : DbEntity
|
||||
{
|
||||
public int GuildConfigId { get; set; }
|
||||
|
||||
public ulong GuildId { get; set; }
|
||||
public int UserThreshold { get; set; }
|
||||
public int Seconds { get; set; }
|
||||
public PunishmentAction Action { get; set; }
|
||||
|
@ -15,4 +17,13 @@ public class AntiRaidSetting : DbEntity
|
|||
/// Mute, Chatmute, Voicemute, etc...
|
||||
/// </summary>
|
||||
public int PunishDuration { get; set; }
|
||||
}
|
||||
|
||||
public class AntiRaidSettingEntityConfiguration : IEntityTypeConfiguration<AntiRaidSetting>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<AntiRaidSetting> builder)
|
||||
{
|
||||
builder.HasIndex(x => x.GuildId)
|
||||
.IsUnique();
|
||||
}
|
||||
}
|
|
@ -3,10 +3,4 @@
|
|||
public class AntiSpamIgnore : DbEntity
|
||||
{
|
||||
public ulong ChannelId { get; set; }
|
||||
|
||||
public override int GetHashCode()
|
||||
=> ChannelId.GetHashCode();
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
=> obj is AntiSpamIgnore inst && inst.ChannelId == ChannelId;
|
||||
}
|
|
@ -1,13 +1,34 @@
|
|||
namespace EllieBot.Db.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
#nullable disable
|
||||
public class AntiSpamSetting : DbEntity
|
||||
{
|
||||
public int GuildConfigId { get; set; }
|
||||
|
||||
|
||||
public ulong GuildId { get; set; }
|
||||
|
||||
public PunishmentAction Action { get; set; }
|
||||
public int MessageThreshold { get; set; } = 3;
|
||||
public int MuteTime { get; set; }
|
||||
public ulong? RoleId { get; set; }
|
||||
public HashSet<AntiSpamIgnore> IgnoredChannels { get; set; } = new();
|
||||
public List<AntiSpamIgnore> IgnoredChannels { get; set; } = new();
|
||||
}
|
||||
|
||||
// setup model
|
||||
public class AntiSpamEntityConfiguration : IEntityTypeConfiguration<AntiSpamSetting>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<AntiSpamSetting> builder)
|
||||
{
|
||||
builder.HasIndex(x => x.GuildId)
|
||||
.IsUnique();
|
||||
|
||||
builder.HasMany(x => x.IgnoredChannels)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
|
@ -24,4 +24,4 @@ public sealed class ButtonRole
|
|||
public string Label { get; set; } = string.Empty;
|
||||
|
||||
public bool Exclusive { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,16 +1,21 @@
|
|||
#nullable disable
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
public class FilterChannelId : DbEntity
|
||||
public class FilterChannelId
|
||||
{
|
||||
[Key]
|
||||
public int Id { get; set; }
|
||||
|
||||
public ulong ChannelId { get; set; }
|
||||
|
||||
public bool Equals(FilterChannelId other)
|
||||
protected bool Equals(FilterChannelId other)
|
||||
=> ChannelId == other.ChannelId;
|
||||
|
||||
public override bool Equals(object obj)
|
||||
=> obj is FilterChannelId fci && Equals(fci);
|
||||
public override bool Equals(object? obj)
|
||||
=> obj is FilterChannelId fci && fci.Equals(this);
|
||||
|
||||
public override int GetHashCode()
|
||||
=> ChannelId.GetHashCode();
|
||||
}
|
||||
}
|
|
@ -1,12 +1,16 @@
|
|||
#nullable disable
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
public class FilterLinksChannelId : DbEntity
|
||||
{
|
||||
public ulong ChannelId { get; set; }
|
||||
|
||||
public override bool Equals(object obj)
|
||||
=> obj is FilterLinksChannelId f && f.ChannelId == ChannelId;
|
||||
protected bool Equals(FilterLinksChannelId other)
|
||||
=> ChannelId == other.ChannelId;
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
=> obj is FilterLinksChannelId other && Equals(other);
|
||||
|
||||
public override int GetHashCode()
|
||||
=> ChannelId.GetHashCode();
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
#nullable disable
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
public class FilterWordsChannelId : DbEntity
|
||||
{
|
||||
public int? GuildConfigId { get; set; }
|
||||
public ulong ChannelId { get; set; }
|
||||
|
||||
public bool Equals(FilterWordsChannelId other)
|
||||
protected bool Equals(FilterWordsChannelId other)
|
||||
=> ChannelId == other.ChannelId;
|
||||
|
||||
public override bool Equals(object obj)
|
||||
=> obj is FilterWordsChannelId fci && Equals(fci);
|
||||
=> obj is FilterWordsChannelId other && Equals(other);
|
||||
|
||||
public override int GetHashCode()
|
||||
=> ChannelId.GetHashCode();
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
#nullable disable
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
public class FilteredWord : DbEntity
|
||||
{
|
||||
public string Word { get; set; }
|
||||
public string Word { get; set; } = string.Empty;
|
||||
|
||||
public override bool Equals(object? obj) => obj is FilteredWord fw && fw.Word == Word;
|
||||
|
||||
public override int GetHashCode() => Word.GetHashCode();
|
||||
}
|
|
@ -1,13 +1,24 @@
|
|||
#nullable disable
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
public class MutedUserId : DbEntity
|
||||
{
|
||||
public ulong GuildId { get; set; }
|
||||
public ulong UserId { get; set; }
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
=> UserId.GetHashCode();
|
||||
|
||||
public override bool Equals(object obj)
|
||||
=> obj is MutedUserId mui ? mui.UserId == UserId : false;
|
||||
public class MutedUserIdEntityConfiguration : IEntityTypeConfiguration<MutedUserId>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<MutedUserId> builder)
|
||||
{
|
||||
builder.HasIndex(x => new
|
||||
{
|
||||
x.GuildId,
|
||||
x.UserId
|
||||
})
|
||||
.IsUnique();
|
||||
}
|
||||
}
|
|
@ -7,6 +7,6 @@ public class TempRole
|
|||
public bool Remove { get; set; }
|
||||
public ulong RoleId { get; set; }
|
||||
public ulong UserId { get; set; }
|
||||
|
||||
|
||||
public DateTime ExpiresAt { get; set; }
|
||||
}
|
|
@ -1,20 +1,24 @@
|
|||
#nullable disable
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
public class SlowmodeIgnoredRole : DbEntity
|
||||
{
|
||||
public ulong GuildId { get; set; }
|
||||
public ulong RoleId { get; set; }
|
||||
}
|
||||
|
||||
// override object.Equals
|
||||
public override bool Equals(object obj)
|
||||
public class SlowmodeIgnoredRoleEntityConfiguration : IEntityTypeConfiguration<SlowmodeIgnoredRole>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<SlowmodeIgnoredRole> builder)
|
||||
{
|
||||
if (obj is null || GetType() != obj.GetType())
|
||||
return false;
|
||||
|
||||
return ((SlowmodeIgnoredRole)obj).RoleId == RoleId;
|
||||
builder.HasIndex(x => new
|
||||
{
|
||||
x.GuildId,
|
||||
x.RoleId
|
||||
})
|
||||
.IsUnique();
|
||||
}
|
||||
|
||||
// override object.GetHashCode
|
||||
public override int GetHashCode()
|
||||
=> RoleId.GetHashCode();
|
||||
}
|
|
@ -1,20 +1,24 @@
|
|||
#nullable disable
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
public class SlowmodeIgnoredUser : DbEntity
|
||||
{
|
||||
public ulong GuildId { get; set; }
|
||||
public ulong UserId { get; set; }
|
||||
}
|
||||
|
||||
// override object.Equals
|
||||
public override bool Equals(object obj)
|
||||
public class SlowmodeIgnoredUserEntityConfiguration : IEntityTypeConfiguration<SlowmodeIgnoredUser>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<SlowmodeIgnoredUser> builder)
|
||||
{
|
||||
if (obj is null || GetType() != obj.GetType())
|
||||
return false;
|
||||
|
||||
return ((SlowmodeIgnoredUser)obj).UserId == UserId;
|
||||
builder.HasIndex(x => new
|
||||
{
|
||||
x.GuildId,
|
||||
x.UserId
|
||||
})
|
||||
.IsUnique();
|
||||
}
|
||||
|
||||
// override object.GetHashCode
|
||||
public override int GetHashCode()
|
||||
=> UserId.GetHashCode();
|
||||
}
|
|
@ -1,14 +1,26 @@
|
|||
#nullable disable
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
public class UnbanTimer : DbEntity
|
||||
{
|
||||
public ulong GuildId { get; set; }
|
||||
public ulong UserId { get; set; }
|
||||
public DateTime UnbanAt { get; set; }
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
=> UserId.GetHashCode();
|
||||
|
||||
public override bool Equals(object obj)
|
||||
=> obj is UnbanTimer ut ? ut.UserId == UserId : false;
|
||||
public class UnbanTimerEntityConfiguration : IEntityTypeConfiguration<UnbanTimer>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<UnbanTimer> builder)
|
||||
{
|
||||
builder.HasIndex(x => new
|
||||
{
|
||||
x.GuildId,
|
||||
x.UserId
|
||||
})
|
||||
.IsUnique();
|
||||
}
|
||||
}
|
|
@ -1,14 +1,25 @@
|
|||
#nullable disable
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
public class UnmuteTimer : DbEntity
|
||||
{
|
||||
public ulong GuildId { get; set; }
|
||||
public ulong UserId { get; set; }
|
||||
public DateTime UnmuteAt { get; set; }
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
=> UserId.GetHashCode();
|
||||
|
||||
public override bool Equals(object obj)
|
||||
=> obj is UnmuteTimer ut ? ut.UserId == UserId : false;
|
||||
public class UnmuteTimerEntityConfiguration : IEntityTypeConfiguration<UnmuteTimer>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<UnmuteTimer> builder)
|
||||
{
|
||||
builder.HasIndex(x => new
|
||||
{
|
||||
x.GuildId,
|
||||
x.UserId
|
||||
}).IsUnique();
|
||||
}
|
||||
}
|
|
@ -1,15 +1,27 @@
|
|||
#nullable disable
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
// todo UN* remove unroletimer in favor of temprole
|
||||
public class UnroleTimer : DbEntity
|
||||
{
|
||||
public ulong GuildId { get; set; }
|
||||
public ulong UserId { get; set; }
|
||||
public ulong RoleId { get; set; }
|
||||
public DateTime UnbanAt { get; set; }
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
=> UserId.GetHashCode() ^ RoleId.GetHashCode();
|
||||
|
||||
public override bool Equals(object obj)
|
||||
=> obj is UnroleTimer ut ? ut.UserId == UserId && ut.RoleId == RoleId : false;
|
||||
public class UnroleTimerEntityConfiguration : IEntityTypeConfiguration<UnroleTimer>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<UnroleTimer> builder)
|
||||
{
|
||||
builder.HasIndex(x => new
|
||||
{
|
||||
x.GuildId,
|
||||
x.UserId
|
||||
})
|
||||
.IsUnique();
|
||||
}
|
||||
}
|
13
src/EllieBot/Db/Models/xp/ExcludedItem.cs
Normal file
13
src/EllieBot/Db/Models/xp/ExcludedItem.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
namespace EllieBot.Db.Models;
|
||||
|
||||
public class ExcludedItem : DbEntity
|
||||
{
|
||||
public ulong ItemId { get; set; }
|
||||
public ExcludedItemType ItemType { get; set; }
|
||||
|
||||
public override int GetHashCode()
|
||||
=> ItemId.GetHashCode() ^ ItemType.GetHashCode();
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
=> obj is ExcludedItem ei && ei.ItemId == ItemId && ei.ItemType == ItemType;
|
||||
}
|
3
src/EllieBot/Db/Models/xp/ExcludedItemType.cs
Normal file
3
src/EllieBot/Db/Models/xp/ExcludedItemType.cs
Normal file
|
@ -0,0 +1,3 @@
|
|||
namespace EllieBot.Db.Models;
|
||||
|
||||
public enum ExcludedItemType { Channel, Role }
|
8
src/EllieBot/Db/Models/xp/XpCurrencyReward.cs
Normal file
8
src/EllieBot/Db/Models/xp/XpCurrencyReward.cs
Normal file
|
@ -0,0 +1,8 @@
|
|||
namespace EllieBot.Db.Models;
|
||||
|
||||
public class XpCurrencyReward : DbEntity
|
||||
{
|
||||
public int XpSettingsId { get; set; }
|
||||
public int Level { get; set; }
|
||||
public int Amount { get; set; }
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
public class XpCurrencyRewardEntityConfiguration : IEntityTypeConfiguration<XpCurrencyReward>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<XpCurrencyReward> builder)
|
||||
{
|
||||
builder.HasIndex(x => new
|
||||
{
|
||||
x.Level,
|
||||
x.XpSettingsId
|
||||
})
|
||||
.IsUnique();
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
namespace EllieBot.Db.Models;
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
public enum XpNotificationLocation
|
||||
{
|
||||
|
|
13
src/EllieBot/Db/Models/xp/XpRoleReward.cs
Normal file
13
src/EllieBot/Db/Models/xp/XpRoleReward.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
namespace EllieBot.Db.Models;
|
||||
|
||||
public class XpRoleReward : DbEntity
|
||||
{
|
||||
public int XpSettingsId { get; set; }
|
||||
public int Level { get; set; }
|
||||
public ulong RoleId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the role should be removed (true) or added (false)
|
||||
/// </summary>
|
||||
public bool Remove { get; set; }
|
||||
}
|
17
src/EllieBot/Db/Models/xp/XpRoleRewardEntityConfiguration.cs
Normal file
17
src/EllieBot/Db/Models/xp/XpRoleRewardEntityConfiguration.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
public class XpRoleRewardEntityConfiguration : IEntityTypeConfiguration<XpRoleReward>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<XpRoleReward> builder)
|
||||
{
|
||||
builder.HasIndex(x => new
|
||||
{
|
||||
x.XpSettingsId,
|
||||
x.Level
|
||||
})
|
||||
.IsUnique();
|
||||
}
|
||||
}
|
|
@ -1,64 +1,15 @@
|
|||
#nullable disable
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
public class XpSettings : DbEntity
|
||||
{
|
||||
public int GuildConfigId { get; set; }
|
||||
public GuildConfig GuildConfig { get; set; }
|
||||
public ulong GuildId { get; set; }
|
||||
public bool ServerExcluded { get; set; }
|
||||
public HashSet<ExcludedItem> ExclusionList { get; set; } = new();
|
||||
|
||||
public HashSet<XpRoleReward> RoleRewards { get; set; } = new();
|
||||
public HashSet<XpCurrencyReward> CurrencyRewards { get; set; } = new();
|
||||
public HashSet<ExcludedItem> ExclusionList { get; set; } = new();
|
||||
public bool ServerExcluded { get; set; }
|
||||
}
|
||||
|
||||
public enum ExcludedItemType { Channel, Role }
|
||||
|
||||
public class XpRoleReward : DbEntity
|
||||
{
|
||||
public int XpSettingsId { get; set; }
|
||||
public XpSettings XpSettings { get; set; }
|
||||
|
||||
public int Level { get; set; }
|
||||
public ulong RoleId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the role should be removed (true) or added (false)
|
||||
/// </summary>
|
||||
public bool Remove { get; set; }
|
||||
|
||||
public override int GetHashCode()
|
||||
=> Level.GetHashCode() ^ XpSettingsId.GetHashCode();
|
||||
|
||||
public override bool Equals(object obj)
|
||||
=> obj is XpRoleReward xrr && xrr.Level == Level && xrr.XpSettingsId == XpSettingsId;
|
||||
}
|
||||
|
||||
public class XpCurrencyReward : DbEntity
|
||||
{
|
||||
public int XpSettingsId { get; set; }
|
||||
public XpSettings XpSettings { get; set; }
|
||||
|
||||
public int Level { get; set; }
|
||||
public int Amount { get; set; }
|
||||
|
||||
public override int GetHashCode()
|
||||
=> Level.GetHashCode() ^ XpSettingsId.GetHashCode();
|
||||
|
||||
public override bool Equals(object obj)
|
||||
=> obj is XpCurrencyReward xrr && xrr.Level == Level && xrr.XpSettingsId == XpSettingsId;
|
||||
}
|
||||
|
||||
public class ExcludedItem : DbEntity
|
||||
{
|
||||
public XpSettings XpSettings { get; set; }
|
||||
|
||||
public ulong ItemId { get; set; }
|
||||
public ExcludedItemType ItemType { get; set; }
|
||||
|
||||
public override int GetHashCode()
|
||||
=> ItemId.GetHashCode() ^ ItemType.GetHashCode();
|
||||
|
||||
public override bool Equals(object obj)
|
||||
=> obj is ExcludedItem ei && ei.ItemId == ItemId && ei.ItemType == ItemType;
|
||||
}
|
22
src/EllieBot/Db/Models/xp/XpSettingsEntityConfiguration.cs
Normal file
22
src/EllieBot/Db/Models/xp/XpSettingsEntityConfiguration.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace EllieBot.Db.Models;
|
||||
|
||||
public class XpSettingsEntityConfiguration : IEntityTypeConfiguration<XpSettings>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<XpSettings> builder)
|
||||
{
|
||||
builder.HasIndex(x => x.GuildId)
|
||||
.IsUnique();
|
||||
|
||||
builder.HasMany(x => x.CurrencyRewards)
|
||||
.WithOne();
|
||||
|
||||
builder.HasMany(x => x.RoleRewards)
|
||||
.WithOne();
|
||||
|
||||
builder.HasMany(x => x.ExclusionList)
|
||||
.WithOne();
|
||||
}
|
||||
}
|
|
@ -1,133 +0,0 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace EllieBot.Migrations;
|
||||
|
||||
public static class MigrationQueries
|
||||
{
|
||||
public static void MergeAwardedXp(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.Sql("""
|
||||
UPDATE UserXpStats
|
||||
SET Xp = AwardedXp + Xp,
|
||||
AwardedXp = 0
|
||||
WHERE AwardedXp > 0;
|
||||
""");
|
||||
}
|
||||
|
||||
public static void MigrateSar(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
if (migrationBuilder.IsNpgsql())
|
||||
return;
|
||||
|
||||
migrationBuilder.Sql("""
|
||||
INSERT INTO GroupName (Number, GuildConfigId)
|
||||
SELECT DISTINCT "Group", GC.Id
|
||||
FROM SelfAssignableRoles as SAR
|
||||
INNER JOIN GuildConfigs as GC
|
||||
ON SAR.GuildId = GC.GuildId
|
||||
WHERE SAR.GuildId not in (SELECT GuildConfigs.GuildId from GroupName LEFT JOIN GuildConfigs ON GroupName.GuildConfigId = GuildConfigs.Id);
|
||||
|
||||
INSERT INTO SarGroup (Id, GroupNumber, Name, IsExclusive, GuildId)
|
||||
SELECT GN.Id, GN.Number, GN.Name, GC.ExclusiveSelfAssignedRoles, GC.GuildId
|
||||
FROM GroupName as GN
|
||||
INNER JOIN GuildConfigs as GC ON GN.GuildConfigId = GC.Id;
|
||||
|
||||
INSERT INTO Sar (GuildId, RoleId, SarGroupId, LevelReq)
|
||||
SELECT SAR.GuildId, SAR.RoleId, (SELECT Id FROM SarGroup WHERE SG.Number = SarGroup.GroupNumber AND SG.GuildId = SarGroup.GuildId), MIN(SAR.LevelRequirement)
|
||||
FROM SelfAssignableRoles as SAR
|
||||
INNER JOIN (SELECT GuildId, gn.Number FROM GroupName as gn
|
||||
INNER JOIN GuildConfigs as gc ON gn.GuildConfigId =gc.Id
|
||||
) as SG
|
||||
ON SG.GuildId = SAR.GuildId
|
||||
WHERE SG.Number IN (SELECT GroupNumber FROM SarGroup WHERE Sar.GuildId = SarGroup.GuildId)
|
||||
GROUP BY SAR.GuildId, SAR.RoleId;
|
||||
|
||||
INSERT INTO SarAutoDelete (GuildId, IsEnabled)
|
||||
SELECT GuildId, AutoDeleteSelfAssignedRoleMessages FROM GuildConfigs WHERE AutoDeleteSelfAssignedRoleMessages = TRUE;
|
||||
""");
|
||||
}
|
||||
|
||||
public static void UpdateUsernames(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.Sql("UPDATE DiscordUser SET Username = '??' || Username WHERE Discriminator = '????';");
|
||||
}
|
||||
|
||||
public static void MigrateRero(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
if (migrationBuilder.IsSqlite())
|
||||
{
|
||||
migrationBuilder.Sql(
|
||||
@"insert or ignore into reactionroles(guildid, channelid, messageid, emote, roleid, 'group', levelreq, dateadded)
|
||||
select guildid, channelid, messageid, emotename, roleid, exclusive, 0, reactionrolemessage.dateadded
|
||||
from reactionrole
|
||||
left join reactionrolemessage on reactionrolemessage.id = reactionrole.reactionrolemessageid
|
||||
left join guildconfigs on reactionrolemessage.guildconfigid = guildconfigs.id;");
|
||||
}
|
||||
else if (migrationBuilder.IsNpgsql())
|
||||
{
|
||||
migrationBuilder.Sql(
|
||||
@"insert into reactionroles(guildid, channelid, messageid, emote, roleid, ""group"", levelreq, dateadded)
|
||||
select guildid, channelid, messageid, emotename, roleid, exclusive::int, 0, reactionrolemessage.dateadded
|
||||
from reactionrole
|
||||
left join reactionrolemessage on reactionrolemessage.id = reactionrole.reactionrolemessageid
|
||||
left join guildconfigs on reactionrolemessage.guildconfigid = guildconfigs.id
|
||||
ON CONFLICT DO NOTHING;");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException("This database provider doesn't have an implementation for MigrateRero");
|
||||
}
|
||||
}
|
||||
|
||||
public static void GuildConfigCleanup(MigrationBuilder builder)
|
||||
{
|
||||
builder.Sql($"""
|
||||
DELETE FROM "DelMsgOnCmdChannel" WHERE "GuildConfigId" is NULL;
|
||||
DELETE FROM "WarningPunishment" WHERE "GuildConfigId" NOT IN (SELECT "Id" from "GuildConfigs");
|
||||
DELETE FROM "StreamRoleBlacklistedUser" WHERE "StreamRoleSettingsId" is NULL;
|
||||
DELETE FROM "Permissions" WHERE "GuildConfigId" NOT IN (SELECT "Id" from "GuildConfigs");
|
||||
""");
|
||||
}
|
||||
|
||||
public static void GreetSettingsCopy(MigrationBuilder builder)
|
||||
{
|
||||
builder.Sql("""
|
||||
INSERT INTO GreetSettings (GuildId, GreetType, MessageText, IsEnabled, ChannelId, AutoDeleteTimer)
|
||||
SELECT GuildId, 0, ChannelGreetMessageText, SendChannelGreetMessage, GreetMessageChannelId, AutoDeleteGreetMessagesTimer
|
||||
FROM GuildConfigs
|
||||
WHERE SendChannelGreetMessage = TRUE;
|
||||
|
||||
INSERT INTO GreetSettings (GuildId, GreetType, MessageText, IsEnabled, ChannelId, AutoDeleteTimer)
|
||||
SELECT GuildId, 1, DmGreetMessageText, SendDmGreetMessage, GreetMessageChannelId, 0
|
||||
FROM GuildConfigs
|
||||
WHERE SendDmGreetMessage = TRUE;
|
||||
|
||||
INSERT INTO GreetSettings (GuildId, GreetType, MessageText, IsEnabled, ChannelId, AutoDeleteTimer)
|
||||
SELECT GuildId, 2, ChannelByeMessageText, SendChannelByeMessage, ByeMessageChannelId, AutoDeleteByeMessagesTimer
|
||||
FROM GuildConfigs
|
||||
WHERE SendChannelByeMessage = TRUE;
|
||||
|
||||
INSERT INTO GreetSettings (GuildId, GreetType, MessageText, IsEnabled, ChannelId, AutoDeleteTimer)
|
||||
SELECT GuildId, 3, BoostMessage, SendBoostMessage, BoostMessageChannelId, BoostMessageDeleteAfter
|
||||
FROM GuildConfigs
|
||||
WHERE SendBoostMessage = TRUE;
|
||||
""");
|
||||
}
|
||||
|
||||
public static void AddGuildIdsToWarningPunishment(MigrationBuilder builder)
|
||||
{
|
||||
builder.Sql("""
|
||||
DELETE FROM WarningPunishment WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE WarningPunishment
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE Id = GuildConfigId);
|
||||
|
||||
DELETE FROM WarningPunishment as wp
|
||||
WHERE (wp.Count, wp.GuildConfigId) in (
|
||||
SELECT wp2.Count, wp2.GuildConfigId FROM WarningPunishment as wp2
|
||||
GROUP BY wp2.Count, wp2.GuildConfigId
|
||||
HAVING COUNT(id) > 1
|
||||
);
|
||||
""");
|
||||
}
|
||||
}
|
333
src/EllieBot/Migrations/PostgreSql/20250126062816_cleanup.sql
Normal file
333
src/EllieBot/Migrations/PostgreSql/20250126062816_cleanup.sql
Normal file
|
@ -0,0 +1,333 @@
|
|||
START TRANSACTION;
|
||||
|
||||
ALTER TABLE antialtsetting DROP CONSTRAINT fk_antialtsetting_guildconfigs_guildconfigid;
|
||||
|
||||
ALTER TABLE antiraidsetting DROP CONSTRAINT fk_antiraidsetting_guildconfigs_guildconfigid;
|
||||
|
||||
ALTER TABLE antispamsetting DROP CONSTRAINT fk_antispamsetting_guildconfigs_guildconfigid;
|
||||
|
||||
ALTER TABLE commandalias DROP CONSTRAINT fk_commandalias_guildconfigs_guildconfigid;
|
||||
|
||||
ALTER TABLE commandcooldown DROP CONSTRAINT fk_commandcooldown_guildconfigs_guildconfigid;
|
||||
|
||||
ALTER TABLE delmsgoncmdchannel DROP CONSTRAINT fk_delmsgoncmdchannel_guildconfigs_guildconfigid;
|
||||
|
||||
ALTER TABLE excludeditem DROP CONSTRAINT fk_excludeditem_xpsettings_xpsettingsid;
|
||||
|
||||
ALTER TABLE feedsub DROP CONSTRAINT fk_feedsub_guildconfigs_guildconfigid;
|
||||
|
||||
ALTER TABLE filterchannelid DROP CONSTRAINT fk_filterchannelid_guildconfigs_guildconfigid;
|
||||
|
||||
ALTER TABLE filteredword DROP CONSTRAINT fk_filteredword_guildconfigs_guildconfigid;
|
||||
|
||||
ALTER TABLE filterlinkschannelid DROP CONSTRAINT fk_filterlinkschannelid_guildconfigs_guildconfigid;
|
||||
|
||||
ALTER TABLE filterwordschannelid DROP CONSTRAINT fk_filterwordschannelid_guildconfigs_guildconfigid;
|
||||
|
||||
ALTER TABLE followedstream DROP CONSTRAINT fk_followedstream_guildconfigs_guildconfigid;
|
||||
|
||||
ALTER TABLE gcchannelid DROP CONSTRAINT fk_gcchannelid_guildconfigs_guildconfigid;
|
||||
|
||||
ALTER TABLE muteduserid DROP CONSTRAINT fk_muteduserid_guildconfigs_guildconfigid;
|
||||
|
||||
ALTER TABLE permissions DROP CONSTRAINT fk_permissions_guildconfigs_guildconfigid;
|
||||
|
||||
ALTER TABLE shopentry DROP CONSTRAINT fk_shopentry_guildconfigs_guildconfigid;
|
||||
|
||||
ALTER TABLE slowmodeignoredrole DROP CONSTRAINT fk_slowmodeignoredrole_guildconfigs_guildconfigid;
|
||||
|
||||
ALTER TABLE slowmodeignoreduser DROP CONSTRAINT fk_slowmodeignoreduser_guildconfigs_guildconfigid;
|
||||
|
||||
ALTER TABLE streamrolesettings DROP CONSTRAINT fk_streamrolesettings_guildconfigs_guildconfigid;
|
||||
|
||||
ALTER TABLE unbantimer DROP CONSTRAINT fk_unbantimer_guildconfigs_guildconfigid;
|
||||
|
||||
ALTER TABLE unmutetimer DROP CONSTRAINT fk_unmutetimer_guildconfigs_guildconfigid;
|
||||
|
||||
ALTER TABLE unroletimer DROP CONSTRAINT fk_unroletimer_guildconfigs_guildconfigid;
|
||||
|
||||
ALTER TABLE vcroleinfo DROP CONSTRAINT fk_vcroleinfo_guildconfigs_guildconfigid;
|
||||
|
||||
ALTER TABLE xpsettings DROP CONSTRAINT fk_xpsettings_guildconfigs_guildconfigid;
|
||||
|
||||
DROP INDEX ix_xpsettings_guildconfigid;
|
||||
|
||||
DROP INDEX ix_vcroleinfo_guildconfigid;
|
||||
|
||||
DROP INDEX ix_unroletimer_guildconfigid;
|
||||
|
||||
DROP INDEX ix_unmutetimer_guildconfigid;
|
||||
|
||||
DROP INDEX ix_unbantimer_guildconfigid;
|
||||
|
||||
DROP INDEX ix_streamrolesettings_guildconfigid;
|
||||
|
||||
DROP INDEX ix_slowmodeignoreduser_guildconfigid;
|
||||
|
||||
DROP INDEX ix_slowmodeignoredrole_guildconfigid;
|
||||
|
||||
DROP INDEX ix_shopentry_guildconfigid;
|
||||
|
||||
DROP INDEX ix_muteduserid_guildconfigid;
|
||||
|
||||
DROP INDEX ix_gcchannelid_guildconfigid;
|
||||
|
||||
DROP INDEX ix_followedstream_guildconfigid;
|
||||
|
||||
ALTER TABLE feedsub DROP CONSTRAINT ak_feedsub_guildconfigid_url;
|
||||
|
||||
DROP INDEX ix_delmsgoncmdchannel_guildconfigid;
|
||||
|
||||
DROP INDEX ix_commandcooldown_guildconfigid;
|
||||
|
||||
DROP INDEX ix_commandalias_guildconfigid;
|
||||
|
||||
DROP INDEX ix_antispamsetting_guildconfigid;
|
||||
|
||||
DROP INDEX ix_antiraidsetting_guildconfigid;
|
||||
|
||||
DROP INDEX ix_antialtsetting_guildconfigid;
|
||||
|
||||
ALTER TABLE filterwordschannelid RENAME COLUMN guildconfigid TO guildfilterconfigid;
|
||||
|
||||
ALTER INDEX ix_filterwordschannelid_guildconfigid RENAME TO ix_filterwordschannelid_guildfilterconfigid;
|
||||
|
||||
ALTER TABLE filterlinkschannelid RENAME COLUMN guildconfigid TO guildfilterconfigid;
|
||||
|
||||
ALTER INDEX ix_filterlinkschannelid_guildconfigid RENAME TO ix_filterlinkschannelid_guildfilterconfigid;
|
||||
|
||||
ALTER TABLE filteredword RENAME COLUMN guildconfigid TO guildfilterconfigid;
|
||||
|
||||
ALTER INDEX ix_filteredword_guildconfigid RENAME TO ix_filteredword_guildfilterconfigid;
|
||||
|
||||
ALTER TABLE filterchannelid RENAME COLUMN guildconfigid TO guildfilterconfigid;
|
||||
|
||||
ALTER INDEX ix_filterchannelid_guildconfigid RENAME TO ix_filterchannelid_guildfilterconfigid;
|
||||
|
||||
ALTER TABLE xpsettings ADD guildid numeric(20,0) NOT NULL DEFAULT 0.0;
|
||||
|
||||
ALTER TABLE vcroleinfo ADD guildid numeric(20,0) NOT NULL DEFAULT 0.0;
|
||||
|
||||
ALTER TABLE unroletimer ADD guildid numeric(20,0) NOT NULL DEFAULT 0.0;
|
||||
|
||||
ALTER TABLE unmutetimer ADD guildid numeric(20,0) NOT NULL DEFAULT 0.0;
|
||||
|
||||
ALTER TABLE unbantimer ADD guildid numeric(20,0) NOT NULL DEFAULT 0.0;
|
||||
|
||||
ALTER TABLE streamrolesettings ADD guildid numeric(20,0) NOT NULL DEFAULT 0.0;
|
||||
|
||||
ALTER TABLE slowmodeignoreduser ADD guildid numeric(20,0) NOT NULL DEFAULT 0.0;
|
||||
|
||||
ALTER TABLE slowmodeignoredrole ADD guildid numeric(20,0) NOT NULL DEFAULT 0.0;
|
||||
|
||||
ALTER TABLE shopentry ADD guildid numeric(20,0) NOT NULL DEFAULT 0.0;
|
||||
|
||||
ALTER TABLE permissions ADD guildid numeric(20,0) NOT NULL DEFAULT 0.0;
|
||||
|
||||
ALTER TABLE muteduserid ADD guildid numeric(20,0) NOT NULL DEFAULT 0.0;
|
||||
|
||||
ALTER TABLE gcchannelid ADD guildid numeric(20,0) NOT NULL DEFAULT 0.0;
|
||||
|
||||
ALTER TABLE feedsub ALTER COLUMN url DROP NOT NULL;
|
||||
|
||||
ALTER TABLE feedsub ADD guildid numeric(20,0) NOT NULL DEFAULT 0.0;
|
||||
|
||||
ALTER TABLE delmsgoncmdchannel ADD guildid numeric(20,0) NOT NULL DEFAULT 0.0;
|
||||
|
||||
ALTER TABLE commandcooldown ADD guildid numeric(20,0) NOT NULL DEFAULT 0.0;
|
||||
|
||||
ALTER TABLE commandalias ADD guildid numeric(20,0) NOT NULL DEFAULT 0.0;
|
||||
|
||||
ALTER TABLE antispamsetting ADD guildid numeric(20,0) NOT NULL DEFAULT 0.0;
|
||||
|
||||
ALTER TABLE antiraidsetting ADD guildid numeric(20,0) NOT NULL DEFAULT 0.0;
|
||||
|
||||
ALTER TABLE antialtsetting ADD guildid numeric(20,0) NOT NULL DEFAULT 0.0;
|
||||
|
||||
CREATE TABLE guildfilterconfig (
|
||||
id integer GENERATED BY DEFAULT AS IDENTITY,
|
||||
guildid numeric(20,0) NOT NULL,
|
||||
filterinvites boolean NOT NULL,
|
||||
filterlinks boolean NOT NULL,
|
||||
filterwords boolean NOT NULL,
|
||||
CONSTRAINT pk_guildfilterconfig PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
insert into guildfilterconfig (Id, GuildId, FilterLinks, FilterInvites, FilterWords)
|
||||
select Id, GuildId, FilterLinks, FilterInvites, FilterWords
|
||||
from guildconfigs;
|
||||
|
||||
DELETE FROM XPSettings WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE XpSettings
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = XpSettings.GuildConfigId);
|
||||
|
||||
DELETE FROM StreamRoleSettings WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE StreamRoleSettings
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = StreamRoleSettings.GuildConfigId);
|
||||
|
||||
DELETE FROM FeedSub WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE FeedSub
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = FeedSub.GuildConfigId);
|
||||
|
||||
DELETE FROM DelMsgOnCmdChannel WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE DelMsgOnCmdChannel
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = DelMsgOnCmdChannel.GuildConfigId);
|
||||
|
||||
DELETE FROM AntiSpamSetting WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE AntiSpamSetting
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = AntiSpamSetting.GuildConfigId);
|
||||
|
||||
DELETE FROM AntiRaidSetting WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE AntiRaidSetting
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = AntiRaidSetting.GuildConfigId);
|
||||
|
||||
DELETE FROM AntiAltSetting WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE AntiAltSetting
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = AntiAltSetting.GuildConfigId);
|
||||
|
||||
DELETE FROM VcRoleInfo WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE VcRoleInfo
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = VcRoleInfo.GuildConfigId);
|
||||
|
||||
DELETE FROM UnroleTimer WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE UnroleTimer
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = UnroleTimer.GuildConfigId);
|
||||
|
||||
DELETE FROM UnmuteTimer WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE UnmuteTimer
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = UnmuteTimer.GuildConfigId);
|
||||
|
||||
DELETE FROM UnbanTimer WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE UnbanTimer
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = UnbanTimer.GuildConfigId);
|
||||
|
||||
DELETE FROM SlowmodeIgnoredUser WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE SlowmodeIgnoredUser
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = SlowmodeIgnoredUser.GuildConfigId);
|
||||
|
||||
DELETE FROM SlowmodeIgnoredRole WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE SlowmodeIgnoredRole
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = SlowmodeIgnoredRole.GuildConfigId);
|
||||
|
||||
DELETE FROM ShopEntry WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE ShopEntry
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = ShopEntry.GuildConfigId);
|
||||
|
||||
DELETE FROM Permissions WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE Permissions
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = Permissions.GuildConfigId);
|
||||
|
||||
DELETE FROM MutedUserId WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE MutedUserId
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = MutedUserId.GuildConfigId);
|
||||
|
||||
DELETE FROM GcChannelId WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE GcChannelId
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = GcChannelId.GuildConfigId);
|
||||
|
||||
DELETE FROM CommandCooldown WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE CommandCooldown
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = CommandCooldown.GuildConfigId);
|
||||
|
||||
DELETE FROM CommandAlias WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE CommandAlias
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = CommandAlias.GuildConfigId);
|
||||
|
||||
ALTER TABLE vcroleinfo DROP COLUMN guildconfigid;
|
||||
|
||||
ALTER TABLE unroletimer DROP COLUMN guildconfigid;
|
||||
|
||||
ALTER TABLE unmutetimer DROP COLUMN guildconfigid;
|
||||
|
||||
ALTER TABLE unbantimer DROP COLUMN guildconfigid;
|
||||
|
||||
ALTER TABLE slowmodeignoreduser DROP COLUMN guildconfigid;
|
||||
|
||||
ALTER TABLE slowmodeignoredrole DROP COLUMN guildconfigid;
|
||||
|
||||
ALTER TABLE shopentry DROP COLUMN guildconfigid;
|
||||
|
||||
ALTER TABLE muteduserid DROP COLUMN guildconfigid;
|
||||
|
||||
ALTER TABLE guildconfigs DROP COLUMN autodeleteselfassignedrolemessages;
|
||||
|
||||
ALTER TABLE guildconfigs DROP COLUMN exclusiveselfassignedroles;
|
||||
|
||||
ALTER TABLE guildconfigs DROP COLUMN filterinvites;
|
||||
|
||||
ALTER TABLE guildconfigs DROP COLUMN filterlinks;
|
||||
|
||||
ALTER TABLE guildconfigs DROP COLUMN filterwords;
|
||||
|
||||
ALTER TABLE gcchannelid DROP COLUMN guildconfigid;
|
||||
|
||||
ALTER TABLE followedstream DROP COLUMN dateadded;
|
||||
|
||||
ALTER TABLE followedstream DROP COLUMN guildconfigid;
|
||||
|
||||
ALTER TABLE filterchannelid DROP COLUMN dateadded;
|
||||
|
||||
ALTER TABLE commandcooldown DROP COLUMN guildconfigid;
|
||||
|
||||
ALTER TABLE commandalias DROP COLUMN guildconfigid;
|
||||
|
||||
CREATE UNIQUE INDEX ix_xpsettings_guildid ON xpsettings (guildid);
|
||||
|
||||
CREATE UNIQUE INDEX ix_xpcurrencyreward_level_xpsettingsid ON xpcurrencyreward (level, xpsettingsid);
|
||||
|
||||
CREATE UNIQUE INDEX ix_vcroleinfo_guildid_voicechannelid ON vcroleinfo (guildid, voicechannelid);
|
||||
|
||||
CREATE UNIQUE INDEX ix_unroletimer_guildid_userid ON unroletimer (guildid, userid);
|
||||
|
||||
CREATE UNIQUE INDEX ix_unmutetimer_guildid_userid ON unmutetimer (guildid, userid);
|
||||
|
||||
CREATE UNIQUE INDEX ix_unbantimer_guildid_userid ON unbantimer (guildid, userid);
|
||||
|
||||
CREATE UNIQUE INDEX ix_streamrolesettings_guildid ON streamrolesettings (guildid);
|
||||
|
||||
CREATE UNIQUE INDEX ix_slowmodeignoreduser_guildid_userid ON slowmodeignoreduser (guildid, userid);
|
||||
|
||||
CREATE UNIQUE INDEX ix_slowmodeignoredrole_guildid_roleid ON slowmodeignoredrole (guildid, roleid);
|
||||
|
||||
CREATE UNIQUE INDEX ix_shopentry_guildid_index ON shopentry (guildid, index);
|
||||
|
||||
CREATE INDEX ix_permissions_guildid ON permissions (guildid);
|
||||
|
||||
CREATE UNIQUE INDEX ix_muteduserid_guildid_userid ON muteduserid (guildid, userid);
|
||||
|
||||
CREATE UNIQUE INDEX ix_gcchannelid_guildid_channelid ON gcchannelid (guildid, channelid);
|
||||
|
||||
CREATE INDEX ix_followedstream_guildid_username_type ON followedstream (guildid, username, type);
|
||||
|
||||
CREATE UNIQUE INDEX ix_feedsub_guildid_url ON feedsub (guildid, url);
|
||||
|
||||
CREATE UNIQUE INDEX ix_delmsgoncmdchannel_guildid_channelid ON delmsgoncmdchannel (guildid, channelid);
|
||||
|
||||
CREATE UNIQUE INDEX ix_commandcooldown_guildid_commandname ON commandcooldown (guildid, commandname);
|
||||
|
||||
CREATE INDEX ix_commandalias_guildid ON commandalias (guildid);
|
||||
|
||||
CREATE UNIQUE INDEX ix_antispamsetting_guildid ON antispamsetting (guildid);
|
||||
|
||||
CREATE UNIQUE INDEX ix_antiraidsetting_guildid ON antiraidsetting (guildid);
|
||||
|
||||
CREATE UNIQUE INDEX ix_antialtsetting_guildid ON antialtsetting (guildid);
|
||||
|
||||
CREATE INDEX ix_guildfilterconfig_guildid ON guildfilterconfig (guildid);
|
||||
|
||||
ALTER TABLE excludeditem ADD CONSTRAINT fk_excludeditem_xpsettings_xpsettingsid FOREIGN KEY (xpsettingsid) REFERENCES xpsettings (id);
|
||||
|
||||
ALTER TABLE filterchannelid ADD CONSTRAINT fk_filterchannelid_guildfilterconfig_guildfilterconfigid FOREIGN KEY (guildfilterconfigid) REFERENCES guildfilterconfig (id);
|
||||
|
||||
ALTER TABLE filteredword ADD CONSTRAINT fk_filteredword_guildfilterconfig_guildfilterconfigid FOREIGN KEY (guildfilterconfigid) REFERENCES guildfilterconfig (id);
|
||||
|
||||
ALTER TABLE filterlinkschannelid ADD CONSTRAINT fk_filterlinkschannelid_guildfilterconfig_guildfilterconfigid FOREIGN KEY (guildfilterconfigid) REFERENCES guildfilterconfig (id);
|
||||
|
||||
ALTER TABLE filterwordschannelid ADD CONSTRAINT fk_filterwordschannelid_guildfilterconfig_guildfilterconfigid FOREIGN KEY (guildfilterconfigid) REFERENCES guildfilterconfig (id);
|
||||
|
||||
ALTER TABLE permissions ADD CONSTRAINT fk_permissions_guildconfigs_guildconfigid FOREIGN KEY (guildconfigid) REFERENCES guildconfigs (id);
|
||||
|
||||
INSERT INTO "__EFMigrationsHistory" (migrationid, productversion)
|
||||
VALUES ('20250126062816_cleanup', '8.0.8');
|
||||
|
||||
COMMIT;
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
762
src/EllieBot/Migrations/Sqlite/20250126062816_cleanup.sql
Normal file
762
src/EllieBot/Migrations/Sqlite/20250126062816_cleanup.sql
Normal file
|
@ -0,0 +1,762 @@
|
|||
BEGIN TRANSACTION;
|
||||
|
||||
DROP INDEX "IX_XpSettings_GuildConfigId";
|
||||
|
||||
DROP INDEX "IX_VcRoleInfo_GuildConfigId";
|
||||
|
||||
DROP INDEX "IX_UnroleTimer_GuildConfigId";
|
||||
|
||||
DROP INDEX "IX_UnmuteTimer_GuildConfigId";
|
||||
|
||||
DROP INDEX "IX_UnbanTimer_GuildConfigId";
|
||||
|
||||
DROP INDEX "IX_StreamRoleSettings_GuildConfigId";
|
||||
|
||||
DROP INDEX "IX_SlowmodeIgnoredUser_GuildConfigId";
|
||||
|
||||
DROP INDEX "IX_SlowmodeIgnoredRole_GuildConfigId";
|
||||
|
||||
DROP INDEX "IX_ShopEntry_GuildConfigId";
|
||||
|
||||
DROP INDEX "IX_MutedUserId_GuildConfigId";
|
||||
|
||||
DROP INDEX "IX_GCChannelId_GuildConfigId";
|
||||
|
||||
DROP INDEX "IX_FollowedStream_GuildConfigId";
|
||||
|
||||
DROP INDEX "IX_DelMsgOnCmdChannel_GuildConfigId";
|
||||
|
||||
DROP INDEX "IX_CommandCooldown_GuildConfigId";
|
||||
|
||||
DROP INDEX "IX_CommandAlias_GuildConfigId";
|
||||
|
||||
DROP INDEX "IX_AntiSpamSetting_GuildConfigId";
|
||||
|
||||
DROP INDEX "IX_AntiRaidSetting_GuildConfigId";
|
||||
|
||||
DROP INDEX "IX_AntiAltSetting_GuildConfigId";
|
||||
|
||||
ALTER TABLE "FilterWordsChannelId" RENAME COLUMN "GuildConfigId" TO "GuildFilterConfigId";
|
||||
|
||||
DROP INDEX "IX_FilterWordsChannelId_GuildConfigId";
|
||||
|
||||
CREATE INDEX "IX_FilterWordsChannelId_GuildFilterConfigId" ON "FilterWordsChannelId" ("GuildFilterConfigId");
|
||||
|
||||
ALTER TABLE "FilterLinksChannelId" RENAME COLUMN "GuildConfigId" TO "GuildFilterConfigId";
|
||||
|
||||
DROP INDEX "IX_FilterLinksChannelId_GuildConfigId";
|
||||
|
||||
CREATE INDEX "IX_FilterLinksChannelId_GuildFilterConfigId" ON "FilterLinksChannelId" ("GuildFilterConfigId");
|
||||
|
||||
ALTER TABLE "FilteredWord" RENAME COLUMN "GuildConfigId" TO "GuildFilterConfigId";
|
||||
|
||||
DROP INDEX "IX_FilteredWord_GuildConfigId";
|
||||
|
||||
CREATE INDEX "IX_FilteredWord_GuildFilterConfigId" ON "FilteredWord" ("GuildFilterConfigId");
|
||||
|
||||
ALTER TABLE "FilterChannelId" RENAME COLUMN "GuildConfigId" TO "GuildFilterConfigId";
|
||||
|
||||
DROP INDEX "IX_FilterChannelId_GuildConfigId";
|
||||
|
||||
CREATE INDEX "IX_FilterChannelId_GuildFilterConfigId" ON "FilterChannelId" ("GuildFilterConfigId");
|
||||
|
||||
ALTER TABLE "XpSettings" ADD "GuildId" INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
ALTER TABLE "VcRoleInfo" ADD "GuildId" INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
ALTER TABLE "UnroleTimer" ADD "GuildId" INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
ALTER TABLE "UnmuteTimer" ADD "GuildId" INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
ALTER TABLE "UnbanTimer" ADD "GuildId" INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
ALTER TABLE "StreamRoleSettings" ADD "GuildId" INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
ALTER TABLE "SlowmodeIgnoredUser" ADD "GuildId" INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
ALTER TABLE "SlowmodeIgnoredRole" ADD "GuildId" INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
ALTER TABLE "ShopEntry" ADD "GuildId" INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
ALTER TABLE "Permissions" ADD "GuildId" INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
ALTER TABLE "MutedUserId" ADD "GuildId" INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
ALTER TABLE "GCChannelId" ADD "GuildId" INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
ALTER TABLE "FeedSub" ADD "GuildId" INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
ALTER TABLE "DelMsgOnCmdChannel" ADD "GuildId" INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
ALTER TABLE "CommandCooldown" ADD "GuildId" INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
ALTER TABLE "CommandAlias" ADD "GuildId" INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
ALTER TABLE "AntiSpamSetting" ADD "GuildId" INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
ALTER TABLE "AntiRaidSetting" ADD "GuildId" INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
ALTER TABLE "AntiAltSetting" ADD "GuildId" INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
CREATE TABLE "GuildFilterConfig" (
|
||||
"Id" INTEGER NOT NULL CONSTRAINT "PK_GuildFilterConfig" PRIMARY KEY AUTOINCREMENT,
|
||||
"GuildId" INTEGER NOT NULL,
|
||||
"FilterInvites" INTEGER NOT NULL,
|
||||
"FilterLinks" INTEGER NOT NULL,
|
||||
"FilterWords" INTEGER NOT NULL
|
||||
);
|
||||
|
||||
insert into guildfilterconfig (Id, GuildId, FilterLinks, FilterInvites, FilterWords)
|
||||
select Id, GuildId, FilterLinks, FilterInvites, FilterWords
|
||||
from guildconfigs;
|
||||
|
||||
DELETE FROM XPSettings WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE XpSettings
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = XpSettings.GuildConfigId);
|
||||
|
||||
DELETE FROM StreamRoleSettings WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE StreamRoleSettings
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = StreamRoleSettings.GuildConfigId);
|
||||
|
||||
DELETE FROM FeedSub WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE FeedSub
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = FeedSub.GuildConfigId);
|
||||
|
||||
DELETE FROM DelMsgOnCmdChannel WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE DelMsgOnCmdChannel
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = DelMsgOnCmdChannel.GuildConfigId);
|
||||
|
||||
DELETE FROM AntiSpamSetting WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE AntiSpamSetting
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = AntiSpamSetting.GuildConfigId);
|
||||
|
||||
DELETE FROM AntiRaidSetting WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE AntiRaidSetting
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = AntiRaidSetting.GuildConfigId);
|
||||
|
||||
DELETE FROM AntiAltSetting WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE AntiAltSetting
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = AntiAltSetting.GuildConfigId);
|
||||
|
||||
DELETE FROM VcRoleInfo WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE VcRoleInfo
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = VcRoleInfo.GuildConfigId);
|
||||
|
||||
DELETE FROM UnroleTimer WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE UnroleTimer
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = UnroleTimer.GuildConfigId);
|
||||
|
||||
DELETE FROM UnmuteTimer WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE UnmuteTimer
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = UnmuteTimer.GuildConfigId);
|
||||
|
||||
DELETE FROM UnbanTimer WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE UnbanTimer
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = UnbanTimer.GuildConfigId);
|
||||
|
||||
DELETE FROM SlowmodeIgnoredUser WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE SlowmodeIgnoredUser
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = SlowmodeIgnoredUser.GuildConfigId);
|
||||
|
||||
DELETE FROM SlowmodeIgnoredRole WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE SlowmodeIgnoredRole
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = SlowmodeIgnoredRole.GuildConfigId);
|
||||
|
||||
DELETE FROM ShopEntry WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE ShopEntry
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = ShopEntry.GuildConfigId);
|
||||
|
||||
DELETE FROM Permissions WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE Permissions
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = Permissions.GuildConfigId);
|
||||
|
||||
DELETE FROM MutedUserId WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE MutedUserId
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = MutedUserId.GuildConfigId);
|
||||
|
||||
DELETE FROM GcChannelId WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE GcChannelId
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = GcChannelId.GuildConfigId);
|
||||
|
||||
DELETE FROM CommandCooldown WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE CommandCooldown
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = CommandCooldown.GuildConfigId);
|
||||
|
||||
DELETE FROM CommandAlias WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
|
||||
UPDATE CommandAlias
|
||||
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE GuildConfigs.Id = CommandAlias.GuildConfigId);
|
||||
|
||||
CREATE UNIQUE INDEX "IX_XpSettings_GuildId" ON "XpSettings" ("GuildId");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_XpCurrencyReward_Level_XpSettingsId" ON "XpCurrencyReward" ("Level", "XpSettingsId");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_VcRoleInfo_GuildId_VoiceChannelId" ON "VcRoleInfo" ("GuildId", "VoiceChannelId");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_UnroleTimer_GuildId_UserId" ON "UnroleTimer" ("GuildId", "UserId");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_UnmuteTimer_GuildId_UserId" ON "UnmuteTimer" ("GuildId", "UserId");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_UnbanTimer_GuildId_UserId" ON "UnbanTimer" ("GuildId", "UserId");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_StreamRoleSettings_GuildId" ON "StreamRoleSettings" ("GuildId");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_SlowmodeIgnoredUser_GuildId_UserId" ON "SlowmodeIgnoredUser" ("GuildId", "UserId");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_SlowmodeIgnoredRole_GuildId_RoleId" ON "SlowmodeIgnoredRole" ("GuildId", "RoleId");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_ShopEntry_GuildId_Index" ON "ShopEntry" ("GuildId", "Index");
|
||||
|
||||
CREATE INDEX "IX_Permissions_GuildId" ON "Permissions" ("GuildId");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_MutedUserId_GuildId_UserId" ON "MutedUserId" ("GuildId", "UserId");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_GCChannelId_GuildId_ChannelId" ON "GCChannelId" ("GuildId", "ChannelId");
|
||||
|
||||
CREATE INDEX "IX_FollowedStream_GuildId_Username_Type" ON "FollowedStream" ("GuildId", "Username", "Type");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_FeedSub_GuildId_Url" ON "FeedSub" ("GuildId", "Url");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_DelMsgOnCmdChannel_GuildId_ChannelId" ON "DelMsgOnCmdChannel" ("GuildId", "ChannelId");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_CommandCooldown_GuildId_CommandName" ON "CommandCooldown" ("GuildId", "CommandName");
|
||||
|
||||
CREATE INDEX "IX_CommandAlias_GuildId" ON "CommandAlias" ("GuildId");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_AntiSpamSetting_GuildId" ON "AntiSpamSetting" ("GuildId");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_AntiRaidSetting_GuildId" ON "AntiRaidSetting" ("GuildId");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_AntiAltSetting_GuildId" ON "AntiAltSetting" ("GuildId");
|
||||
|
||||
CREATE INDEX "IX_GuildFilterConfig_GuildId" ON "GuildFilterConfig" ("GuildId");
|
||||
|
||||
CREATE TABLE "ef_temp_AntiAltSetting" (
|
||||
"Id" INTEGER NOT NULL CONSTRAINT "PK_AntiAltSetting" PRIMARY KEY AUTOINCREMENT,
|
||||
"Action" INTEGER NOT NULL,
|
||||
"ActionDurationMinutes" INTEGER NOT NULL,
|
||||
"GuildConfigId" INTEGER NOT NULL,
|
||||
"GuildId" INTEGER NOT NULL,
|
||||
"MinAge" TEXT NOT NULL,
|
||||
"RoleId" INTEGER NULL
|
||||
);
|
||||
|
||||
INSERT INTO "ef_temp_AntiAltSetting" ("Id", "Action", "ActionDurationMinutes", "GuildConfigId", "GuildId", "MinAge", "RoleId")
|
||||
SELECT "Id", "Action", "ActionDurationMinutes", "GuildConfigId", "GuildId", "MinAge", "RoleId"
|
||||
FROM "AntiAltSetting";
|
||||
|
||||
CREATE TABLE "ef_temp_AntiRaidSetting" (
|
||||
"Id" INTEGER NOT NULL CONSTRAINT "PK_AntiRaidSetting" PRIMARY KEY AUTOINCREMENT,
|
||||
"Action" INTEGER NOT NULL,
|
||||
"DateAdded" TEXT NULL,
|
||||
"GuildConfigId" INTEGER NOT NULL,
|
||||
"GuildId" INTEGER NOT NULL,
|
||||
"PunishDuration" INTEGER NOT NULL,
|
||||
"Seconds" INTEGER NOT NULL,
|
||||
"UserThreshold" INTEGER NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO "ef_temp_AntiRaidSetting" ("Id", "Action", "DateAdded", "GuildConfigId", "GuildId", "PunishDuration", "Seconds", "UserThreshold")
|
||||
SELECT "Id", "Action", "DateAdded", "GuildConfigId", "GuildId", "PunishDuration", "Seconds", "UserThreshold"
|
||||
FROM "AntiRaidSetting";
|
||||
|
||||
CREATE TABLE "ef_temp_AntiSpamSetting" (
|
||||
"Id" INTEGER NOT NULL CONSTRAINT "PK_AntiSpamSetting" PRIMARY KEY AUTOINCREMENT,
|
||||
"Action" INTEGER NOT NULL,
|
||||
"DateAdded" TEXT NULL,
|
||||
"GuildConfigId" INTEGER NOT NULL,
|
||||
"GuildId" INTEGER NOT NULL,
|
||||
"MessageThreshold" INTEGER NOT NULL,
|
||||
"MuteTime" INTEGER NOT NULL,
|
||||
"RoleId" INTEGER NULL
|
||||
);
|
||||
|
||||
INSERT INTO "ef_temp_AntiSpamSetting" ("Id", "Action", "DateAdded", "GuildConfigId", "GuildId", "MessageThreshold", "MuteTime", "RoleId")
|
||||
SELECT "Id", "Action", "DateAdded", "GuildConfigId", "GuildId", "MessageThreshold", "MuteTime", "RoleId"
|
||||
FROM "AntiSpamSetting";
|
||||
|
||||
CREATE TABLE "ef_temp_CommandAlias" (
|
||||
"Id" INTEGER NOT NULL CONSTRAINT "PK_CommandAlias" PRIMARY KEY AUTOINCREMENT,
|
||||
"DateAdded" TEXT NULL,
|
||||
"GuildId" INTEGER NOT NULL,
|
||||
"Mapping" TEXT NULL,
|
||||
"Trigger" TEXT NULL
|
||||
);
|
||||
|
||||
INSERT INTO "ef_temp_CommandAlias" ("Id", "DateAdded", "GuildId", "Mapping", "Trigger")
|
||||
SELECT "Id", "DateAdded", "GuildId", "Mapping", "Trigger"
|
||||
FROM "CommandAlias";
|
||||
|
||||
CREATE TABLE "ef_temp_CommandCooldown" (
|
||||
"Id" INTEGER NOT NULL CONSTRAINT "PK_CommandCooldown" PRIMARY KEY AUTOINCREMENT,
|
||||
"CommandName" TEXT NULL,
|
||||
"DateAdded" TEXT NULL,
|
||||
"GuildId" INTEGER NOT NULL,
|
||||
"Seconds" INTEGER NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO "ef_temp_CommandCooldown" ("Id", "CommandName", "DateAdded", "GuildId", "Seconds")
|
||||
SELECT "Id", "CommandName", "DateAdded", "GuildId", "Seconds"
|
||||
FROM "CommandCooldown";
|
||||
|
||||
CREATE TABLE "ef_temp_DelMsgOnCmdChannel" (
|
||||
"Id" INTEGER NOT NULL CONSTRAINT "PK_DelMsgOnCmdChannel" PRIMARY KEY AUTOINCREMENT,
|
||||
"ChannelId" INTEGER NOT NULL,
|
||||
"DateAdded" TEXT NULL,
|
||||
"GuildConfigId" INTEGER NOT NULL,
|
||||
"GuildId" INTEGER NOT NULL,
|
||||
"State" INTEGER NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO "ef_temp_DelMsgOnCmdChannel" ("Id", "ChannelId", "DateAdded", "GuildConfigId", "GuildId", "State")
|
||||
SELECT "Id", "ChannelId", "DateAdded", "GuildConfigId", "GuildId", "State"
|
||||
FROM "DelMsgOnCmdChannel";
|
||||
|
||||
CREATE TABLE "ef_temp_ExcludedItem" (
|
||||
"Id" INTEGER NOT NULL CONSTRAINT "PK_ExcludedItem" PRIMARY KEY AUTOINCREMENT,
|
||||
"DateAdded" TEXT NULL,
|
||||
"ItemId" INTEGER NOT NULL,
|
||||
"ItemType" INTEGER NOT NULL,
|
||||
"XpSettingsId" INTEGER NULL,
|
||||
CONSTRAINT "FK_ExcludedItem_XpSettings_XpSettingsId" FOREIGN KEY ("XpSettingsId") REFERENCES "XpSettings" ("Id")
|
||||
);
|
||||
|
||||
INSERT INTO "ef_temp_ExcludedItem" ("Id", "DateAdded", "ItemId", "ItemType", "XpSettingsId")
|
||||
SELECT "Id", "DateAdded", "ItemId", "ItemType", "XpSettingsId"
|
||||
FROM "ExcludedItem";
|
||||
|
||||
CREATE TABLE "ef_temp_FeedSub" (
|
||||
"Id" INTEGER NOT NULL CONSTRAINT "PK_FeedSub" PRIMARY KEY AUTOINCREMENT,
|
||||
"ChannelId" INTEGER NOT NULL,
|
||||
"DateAdded" TEXT NULL,
|
||||
"GuildConfigId" INTEGER NOT NULL,
|
||||
"GuildId" INTEGER NOT NULL,
|
||||
"Message" TEXT NULL,
|
||||
"Url" TEXT NULL
|
||||
);
|
||||
|
||||
INSERT INTO "ef_temp_FeedSub" ("Id", "ChannelId", "DateAdded", "GuildConfigId", "GuildId", "Message", "Url")
|
||||
SELECT "Id", "ChannelId", "DateAdded", "GuildConfigId", "GuildId", "Message", "Url"
|
||||
FROM "FeedSub";
|
||||
|
||||
CREATE TABLE "ef_temp_FilterChannelId" (
|
||||
"Id" INTEGER NOT NULL CONSTRAINT "PK_FilterChannelId" PRIMARY KEY AUTOINCREMENT,
|
||||
"ChannelId" INTEGER NOT NULL,
|
||||
"GuildFilterConfigId" INTEGER NULL,
|
||||
CONSTRAINT "FK_FilterChannelId_GuildFilterConfig_GuildFilterConfigId" FOREIGN KEY ("GuildFilterConfigId") REFERENCES "GuildFilterConfig" ("Id")
|
||||
);
|
||||
|
||||
INSERT INTO "ef_temp_FilterChannelId" ("Id", "ChannelId", "GuildFilterConfigId")
|
||||
SELECT "Id", "ChannelId", "GuildFilterConfigId"
|
||||
FROM "FilterChannelId";
|
||||
|
||||
CREATE TABLE "ef_temp_FilteredWord" (
|
||||
"Id" INTEGER NOT NULL CONSTRAINT "PK_FilteredWord" PRIMARY KEY AUTOINCREMENT,
|
||||
"DateAdded" TEXT NULL,
|
||||
"GuildFilterConfigId" INTEGER NULL,
|
||||
"Word" TEXT NULL,
|
||||
CONSTRAINT "FK_FilteredWord_GuildFilterConfig_GuildFilterConfigId" FOREIGN KEY ("GuildFilterConfigId") REFERENCES "GuildFilterConfig" ("Id")
|
||||
);
|
||||
|
||||
INSERT INTO "ef_temp_FilteredWord" ("Id", "DateAdded", "GuildFilterConfigId", "Word")
|
||||
SELECT "Id", "DateAdded", "GuildFilterConfigId", "Word"
|
||||
FROM "FilteredWord";
|
||||
|
||||
CREATE TABLE "ef_temp_FilterLinksChannelId" (
|
||||
"Id" INTEGER NOT NULL CONSTRAINT "PK_FilterLinksChannelId" PRIMARY KEY AUTOINCREMENT,
|
||||
"ChannelId" INTEGER NOT NULL,
|
||||
"DateAdded" TEXT NULL,
|
||||
"GuildFilterConfigId" INTEGER NULL,
|
||||
CONSTRAINT "FK_FilterLinksChannelId_GuildFilterConfig_GuildFilterConfigId" FOREIGN KEY ("GuildFilterConfigId") REFERENCES "GuildFilterConfig" ("Id")
|
||||
);
|
||||
|
||||
INSERT INTO "ef_temp_FilterLinksChannelId" ("Id", "ChannelId", "DateAdded", "GuildFilterConfigId")
|
||||
SELECT "Id", "ChannelId", "DateAdded", "GuildFilterConfigId"
|
||||
FROM "FilterLinksChannelId";
|
||||
|
||||
CREATE TABLE "ef_temp_FilterWordsChannelId" (
|
||||
"Id" INTEGER NOT NULL CONSTRAINT "PK_FilterWordsChannelId" PRIMARY KEY AUTOINCREMENT,
|
||||
"ChannelId" INTEGER NOT NULL,
|
||||
"DateAdded" TEXT NULL,
|
||||
"GuildFilterConfigId" INTEGER NULL,
|
||||
CONSTRAINT "FK_FilterWordsChannelId_GuildFilterConfig_GuildFilterConfigId" FOREIGN KEY ("GuildFilterConfigId") REFERENCES "GuildFilterConfig" ("Id")
|
||||
);
|
||||
|
||||
INSERT INTO "ef_temp_FilterWordsChannelId" ("Id", "ChannelId", "DateAdded", "GuildFilterConfigId")
|
||||
SELECT "Id", "ChannelId", "DateAdded", "GuildFilterConfigId"
|
||||
FROM "FilterWordsChannelId";
|
||||
|
||||
CREATE TABLE "ef_temp_FollowedStream" (
|
||||
"Id" INTEGER NOT NULL CONSTRAINT "PK_FollowedStream" PRIMARY KEY AUTOINCREMENT,
|
||||
"ChannelId" INTEGER NOT NULL,
|
||||
"GuildId" INTEGER NOT NULL,
|
||||
"Message" TEXT NULL,
|
||||
"Type" INTEGER NOT NULL,
|
||||
"Username" TEXT NULL
|
||||
);
|
||||
|
||||
INSERT INTO "ef_temp_FollowedStream" ("Id", "ChannelId", "GuildId", "Message", "Type", "Username")
|
||||
SELECT "Id", "ChannelId", "GuildId", "Message", "Type", "Username"
|
||||
FROM "FollowedStream";
|
||||
|
||||
CREATE TABLE "ef_temp_GCChannelId" (
|
||||
"Id" INTEGER NOT NULL CONSTRAINT "PK_GCChannelId" PRIMARY KEY AUTOINCREMENT,
|
||||
"ChannelId" INTEGER NOT NULL,
|
||||
"DateAdded" TEXT NULL,
|
||||
"GuildId" INTEGER NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO "ef_temp_GCChannelId" ("Id", "ChannelId", "DateAdded", "GuildId")
|
||||
SELECT "Id", "ChannelId", "DateAdded", "GuildId"
|
||||
FROM "GCChannelId";
|
||||
|
||||
CREATE TABLE "ef_temp_MutedUserId" (
|
||||
"Id" INTEGER NOT NULL CONSTRAINT "PK_MutedUserId" PRIMARY KEY AUTOINCREMENT,
|
||||
"DateAdded" TEXT NULL,
|
||||
"GuildId" INTEGER NOT NULL,
|
||||
"UserId" INTEGER NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO "ef_temp_MutedUserId" ("Id", "DateAdded", "GuildId", "UserId")
|
||||
SELECT "Id", "DateAdded", "GuildId", "UserId"
|
||||
FROM "MutedUserId";
|
||||
|
||||
CREATE TABLE "ef_temp_Permissions" (
|
||||
"Id" INTEGER NOT NULL CONSTRAINT "PK_Permissions" PRIMARY KEY AUTOINCREMENT,
|
||||
"DateAdded" TEXT NULL,
|
||||
"GuildConfigId" INTEGER NULL,
|
||||
"GuildId" INTEGER NOT NULL,
|
||||
"Index" INTEGER NOT NULL,
|
||||
"IsCustomCommand" INTEGER NOT NULL,
|
||||
"PrimaryTarget" INTEGER NOT NULL,
|
||||
"PrimaryTargetId" INTEGER NOT NULL,
|
||||
"SecondaryTarget" INTEGER NOT NULL,
|
||||
"SecondaryTargetName" TEXT NULL,
|
||||
"State" INTEGER NOT NULL,
|
||||
CONSTRAINT "FK_Permissions_GuildConfigs_GuildConfigId" FOREIGN KEY ("GuildConfigId") REFERENCES "GuildConfigs" ("Id")
|
||||
);
|
||||
|
||||
INSERT INTO "ef_temp_Permissions" ("Id", "DateAdded", "GuildConfigId", "GuildId", "Index", "IsCustomCommand", "PrimaryTarget", "PrimaryTargetId", "SecondaryTarget", "SecondaryTargetName", "State")
|
||||
SELECT "Id", "DateAdded", "GuildConfigId", "GuildId", "Index", "IsCustomCommand", "PrimaryTarget", "PrimaryTargetId", "SecondaryTarget", "SecondaryTargetName", "State"
|
||||
FROM "Permissions";
|
||||
|
||||
CREATE TABLE "ef_temp_ShopEntry" (
|
||||
"Id" INTEGER NOT NULL CONSTRAINT "PK_ShopEntry" PRIMARY KEY AUTOINCREMENT,
|
||||
"AuthorId" INTEGER NOT NULL,
|
||||
"Command" TEXT NULL,
|
||||
"DateAdded" TEXT NULL,
|
||||
"GuildId" INTEGER NOT NULL,
|
||||
"Index" INTEGER NOT NULL,
|
||||
"Name" TEXT NULL,
|
||||
"Price" INTEGER NOT NULL,
|
||||
"RoleId" INTEGER NOT NULL,
|
||||
"RoleName" TEXT NULL,
|
||||
"RoleRequirement" INTEGER NULL,
|
||||
"Type" INTEGER NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO "ef_temp_ShopEntry" ("Id", "AuthorId", "Command", "DateAdded", "GuildId", "Index", "Name", "Price", "RoleId", "RoleName", "RoleRequirement", "Type")
|
||||
SELECT "Id", "AuthorId", "Command", "DateAdded", "GuildId", "Index", "Name", "Price", "RoleId", "RoleName", "RoleRequirement", "Type"
|
||||
FROM "ShopEntry";
|
||||
|
||||
CREATE TABLE "ef_temp_SlowmodeIgnoredRole" (
|
||||
"Id" INTEGER NOT NULL CONSTRAINT "PK_SlowmodeIgnoredRole" PRIMARY KEY AUTOINCREMENT,
|
||||
"DateAdded" TEXT NULL,
|
||||
"GuildId" INTEGER NOT NULL,
|
||||
"RoleId" INTEGER NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO "ef_temp_SlowmodeIgnoredRole" ("Id", "DateAdded", "GuildId", "RoleId")
|
||||
SELECT "Id", "DateAdded", "GuildId", "RoleId"
|
||||
FROM "SlowmodeIgnoredRole";
|
||||
|
||||
CREATE TABLE "ef_temp_SlowmodeIgnoredUser" (
|
||||
"Id" INTEGER NOT NULL CONSTRAINT "PK_SlowmodeIgnoredUser" PRIMARY KEY AUTOINCREMENT,
|
||||
"DateAdded" TEXT NULL,
|
||||
"GuildId" INTEGER NOT NULL,
|
||||
"UserId" INTEGER NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO "ef_temp_SlowmodeIgnoredUser" ("Id", "DateAdded", "GuildId", "UserId")
|
||||
SELECT "Id", "DateAdded", "GuildId", "UserId"
|
||||
FROM "SlowmodeIgnoredUser";
|
||||
|
||||
CREATE TABLE "ef_temp_StreamRoleSettings" (
|
||||
"Id" INTEGER NOT NULL CONSTRAINT "PK_StreamRoleSettings" PRIMARY KEY AUTOINCREMENT,
|
||||
"AddRoleId" INTEGER NOT NULL,
|
||||
"DateAdded" TEXT NULL,
|
||||
"Enabled" INTEGER NOT NULL,
|
||||
"FromRoleId" INTEGER NOT NULL,
|
||||
"GuildConfigId" INTEGER NOT NULL,
|
||||
"GuildId" INTEGER NOT NULL,
|
||||
"Keyword" TEXT NULL
|
||||
);
|
||||
|
||||
INSERT INTO "ef_temp_StreamRoleSettings" ("Id", "AddRoleId", "DateAdded", "Enabled", "FromRoleId", "GuildConfigId", "GuildId", "Keyword")
|
||||
SELECT "Id", "AddRoleId", "DateAdded", "Enabled", "FromRoleId", "GuildConfigId", "GuildId", "Keyword"
|
||||
FROM "StreamRoleSettings";
|
||||
|
||||
CREATE TABLE "ef_temp_UnbanTimer" (
|
||||
"Id" INTEGER NOT NULL CONSTRAINT "PK_UnbanTimer" PRIMARY KEY AUTOINCREMENT,
|
||||
"DateAdded" TEXT NULL,
|
||||
"GuildId" INTEGER NOT NULL,
|
||||
"UnbanAt" TEXT NOT NULL,
|
||||
"UserId" INTEGER NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO "ef_temp_UnbanTimer" ("Id", "DateAdded", "GuildId", "UnbanAt", "UserId")
|
||||
SELECT "Id", "DateAdded", "GuildId", "UnbanAt", "UserId"
|
||||
FROM "UnbanTimer";
|
||||
|
||||
CREATE TABLE "ef_temp_UnmuteTimer" (
|
||||
"Id" INTEGER NOT NULL CONSTRAINT "PK_UnmuteTimer" PRIMARY KEY AUTOINCREMENT,
|
||||
"DateAdded" TEXT NULL,
|
||||
"GuildId" INTEGER NOT NULL,
|
||||
"UnmuteAt" TEXT NOT NULL,
|
||||
"UserId" INTEGER NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO "ef_temp_UnmuteTimer" ("Id", "DateAdded", "GuildId", "UnmuteAt", "UserId")
|
||||
SELECT "Id", "DateAdded", "GuildId", "UnmuteAt", "UserId"
|
||||
FROM "UnmuteTimer";
|
||||
|
||||
CREATE TABLE "ef_temp_UnroleTimer" (
|
||||
"Id" INTEGER NOT NULL CONSTRAINT "PK_UnroleTimer" PRIMARY KEY AUTOINCREMENT,
|
||||
"DateAdded" TEXT NULL,
|
||||
"GuildId" INTEGER NOT NULL,
|
||||
"RoleId" INTEGER NOT NULL,
|
||||
"UnbanAt" TEXT NOT NULL,
|
||||
"UserId" INTEGER NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO "ef_temp_UnroleTimer" ("Id", "DateAdded", "GuildId", "RoleId", "UnbanAt", "UserId")
|
||||
SELECT "Id", "DateAdded", "GuildId", "RoleId", "UnbanAt", "UserId"
|
||||
FROM "UnroleTimer";
|
||||
|
||||
CREATE TABLE "ef_temp_VcRoleInfo" (
|
||||
"Id" INTEGER NOT NULL CONSTRAINT "PK_VcRoleInfo" PRIMARY KEY AUTOINCREMENT,
|
||||
"DateAdded" TEXT NULL,
|
||||
"GuildId" INTEGER NOT NULL,
|
||||
"RoleId" INTEGER NOT NULL,
|
||||
"VoiceChannelId" INTEGER NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO "ef_temp_VcRoleInfo" ("Id", "DateAdded", "GuildId", "RoleId", "VoiceChannelId")
|
||||
SELECT "Id", "DateAdded", "GuildId", "RoleId", "VoiceChannelId"
|
||||
FROM "VcRoleInfo";
|
||||
|
||||
CREATE TABLE "ef_temp_XpSettings" (
|
||||
"Id" INTEGER NOT NULL CONSTRAINT "PK_XpSettings" PRIMARY KEY AUTOINCREMENT,
|
||||
"DateAdded" TEXT NULL,
|
||||
"GuildConfigId" INTEGER NOT NULL,
|
||||
"GuildId" INTEGER NOT NULL,
|
||||
"ServerExcluded" INTEGER NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO "ef_temp_XpSettings" ("Id", "DateAdded", "GuildConfigId", "GuildId", "ServerExcluded")
|
||||
SELECT "Id", "DateAdded", "GuildConfigId", "GuildId", "ServerExcluded"
|
||||
FROM "XpSettings";
|
||||
|
||||
CREATE TABLE "ef_temp_GuildConfigs" (
|
||||
"Id" INTEGER NOT NULL CONSTRAINT "PK_GuildConfigs" PRIMARY KEY AUTOINCREMENT,
|
||||
"AutoAssignRoleIds" TEXT NULL,
|
||||
"CleverbotEnabled" INTEGER NOT NULL,
|
||||
"DateAdded" TEXT NULL,
|
||||
"DeleteMessageOnCommand" INTEGER NOT NULL,
|
||||
"DeleteStreamOnlineMessage" INTEGER NOT NULL,
|
||||
"DisableGlobalExpressions" INTEGER NOT NULL,
|
||||
"GameVoiceChannel" INTEGER NULL,
|
||||
"GuildId" INTEGER NOT NULL,
|
||||
"Locale" TEXT NULL,
|
||||
"MuteRoleName" TEXT NULL,
|
||||
"NotifyStreamOffline" INTEGER NOT NULL,
|
||||
"PermissionRole" TEXT NULL,
|
||||
"Prefix" TEXT NULL,
|
||||
"StickyRoles" INTEGER NOT NULL,
|
||||
"TimeZoneId" TEXT NULL,
|
||||
"VerboseErrors" INTEGER NOT NULL DEFAULT 1,
|
||||
"VerbosePermissions" INTEGER NOT NULL,
|
||||
"WarnExpireAction" INTEGER NOT NULL,
|
||||
"WarnExpireHours" INTEGER NOT NULL,
|
||||
"WarningsInitialized" INTEGER NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO "ef_temp_GuildConfigs" ("Id", "AutoAssignRoleIds", "CleverbotEnabled", "DateAdded", "DeleteMessageOnCommand", "DeleteStreamOnlineMessage", "DisableGlobalExpressions", "GameVoiceChannel", "GuildId", "Locale", "MuteRoleName", "NotifyStreamOffline", "PermissionRole", "Prefix", "StickyRoles", "TimeZoneId", "VerboseErrors", "VerbosePermissions", "WarnExpireAction", "WarnExpireHours", "WarningsInitialized")
|
||||
SELECT "Id", "AutoAssignRoleIds", "CleverbotEnabled", "DateAdded", "DeleteMessageOnCommand", "DeleteStreamOnlineMessage", "DisableGlobalExpressions", "GameVoiceChannel", "GuildId", "Locale", "MuteRoleName", "NotifyStreamOffline", "PermissionRole", "Prefix", "StickyRoles", "TimeZoneId", "VerboseErrors", "VerbosePermissions", "WarnExpireAction", "WarnExpireHours", "WarningsInitialized"
|
||||
FROM "GuildConfigs";
|
||||
|
||||
COMMIT;
|
||||
|
||||
PRAGMA foreign_keys = 0;
|
||||
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
DROP TABLE "AntiAltSetting";
|
||||
|
||||
ALTER TABLE "ef_temp_AntiAltSetting" RENAME TO "AntiAltSetting";
|
||||
|
||||
DROP TABLE "AntiRaidSetting";
|
||||
|
||||
ALTER TABLE "ef_temp_AntiRaidSetting" RENAME TO "AntiRaidSetting";
|
||||
|
||||
DROP TABLE "AntiSpamSetting";
|
||||
|
||||
ALTER TABLE "ef_temp_AntiSpamSetting" RENAME TO "AntiSpamSetting";
|
||||
|
||||
DROP TABLE "CommandAlias";
|
||||
|
||||
ALTER TABLE "ef_temp_CommandAlias" RENAME TO "CommandAlias";
|
||||
|
||||
DROP TABLE "CommandCooldown";
|
||||
|
||||
ALTER TABLE "ef_temp_CommandCooldown" RENAME TO "CommandCooldown";
|
||||
|
||||
DROP TABLE "DelMsgOnCmdChannel";
|
||||
|
||||
ALTER TABLE "ef_temp_DelMsgOnCmdChannel" RENAME TO "DelMsgOnCmdChannel";
|
||||
|
||||
DROP TABLE "ExcludedItem";
|
||||
|
||||
ALTER TABLE "ef_temp_ExcludedItem" RENAME TO "ExcludedItem";
|
||||
|
||||
DROP TABLE "FeedSub";
|
||||
|
||||
ALTER TABLE "ef_temp_FeedSub" RENAME TO "FeedSub";
|
||||
|
||||
DROP TABLE "FilterChannelId";
|
||||
|
||||
ALTER TABLE "ef_temp_FilterChannelId" RENAME TO "FilterChannelId";
|
||||
|
||||
DROP TABLE "FilteredWord";
|
||||
|
||||
ALTER TABLE "ef_temp_FilteredWord" RENAME TO "FilteredWord";
|
||||
|
||||
DROP TABLE "FilterLinksChannelId";
|
||||
|
||||
ALTER TABLE "ef_temp_FilterLinksChannelId" RENAME TO "FilterLinksChannelId";
|
||||
|
||||
DROP TABLE "FilterWordsChannelId";
|
||||
|
||||
ALTER TABLE "ef_temp_FilterWordsChannelId" RENAME TO "FilterWordsChannelId";
|
||||
|
||||
DROP TABLE "FollowedStream";
|
||||
|
||||
ALTER TABLE "ef_temp_FollowedStream" RENAME TO "FollowedStream";
|
||||
|
||||
DROP TABLE "GCChannelId";
|
||||
|
||||
ALTER TABLE "ef_temp_GCChannelId" RENAME TO "GCChannelId";
|
||||
|
||||
DROP TABLE "MutedUserId";
|
||||
|
||||
ALTER TABLE "ef_temp_MutedUserId" RENAME TO "MutedUserId";
|
||||
|
||||
DROP TABLE "Permissions";
|
||||
|
||||
ALTER TABLE "ef_temp_Permissions" RENAME TO "Permissions";
|
||||
|
||||
DROP TABLE "ShopEntry";
|
||||
|
||||
ALTER TABLE "ef_temp_ShopEntry" RENAME TO "ShopEntry";
|
||||
|
||||
DROP TABLE "SlowmodeIgnoredRole";
|
||||
|
||||
ALTER TABLE "ef_temp_SlowmodeIgnoredRole" RENAME TO "SlowmodeIgnoredRole";
|
||||
|
||||
DROP TABLE "SlowmodeIgnoredUser";
|
||||
|
||||
ALTER TABLE "ef_temp_SlowmodeIgnoredUser" RENAME TO "SlowmodeIgnoredUser";
|
||||
|
||||
DROP TABLE "StreamRoleSettings";
|
||||
|
||||
ALTER TABLE "ef_temp_StreamRoleSettings" RENAME TO "StreamRoleSettings";
|
||||
|
||||
DROP TABLE "UnbanTimer";
|
||||
|
||||
ALTER TABLE "ef_temp_UnbanTimer" RENAME TO "UnbanTimer";
|
||||
|
||||
DROP TABLE "UnmuteTimer";
|
||||
|
||||
ALTER TABLE "ef_temp_UnmuteTimer" RENAME TO "UnmuteTimer";
|
||||
|
||||
DROP TABLE "UnroleTimer";
|
||||
|
||||
ALTER TABLE "ef_temp_UnroleTimer" RENAME TO "UnroleTimer";
|
||||
|
||||
DROP TABLE "VcRoleInfo";
|
||||
|
||||
ALTER TABLE "ef_temp_VcRoleInfo" RENAME TO "VcRoleInfo";
|
||||
|
||||
DROP TABLE "XpSettings";
|
||||
|
||||
ALTER TABLE "ef_temp_XpSettings" RENAME TO "XpSettings";
|
||||
|
||||
DROP TABLE "GuildConfigs";
|
||||
|
||||
ALTER TABLE "ef_temp_GuildConfigs" RENAME TO "GuildConfigs";
|
||||
|
||||
COMMIT;
|
||||
|
||||
PRAGMA foreign_keys = 1;
|
||||
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
CREATE UNIQUE INDEX "IX_AntiAltSetting_GuildId" ON "AntiAltSetting" ("GuildId");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_AntiRaidSetting_GuildId" ON "AntiRaidSetting" ("GuildId");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_AntiSpamSetting_GuildId" ON "AntiSpamSetting" ("GuildId");
|
||||
|
||||
CREATE INDEX "IX_CommandAlias_GuildId" ON "CommandAlias" ("GuildId");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_CommandCooldown_GuildId_CommandName" ON "CommandCooldown" ("GuildId", "CommandName");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_DelMsgOnCmdChannel_GuildId_ChannelId" ON "DelMsgOnCmdChannel" ("GuildId", "ChannelId");
|
||||
|
||||
CREATE INDEX "IX_ExcludedItem_XpSettingsId" ON "ExcludedItem" ("XpSettingsId");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_FeedSub_GuildId_Url" ON "FeedSub" ("GuildId", "Url");
|
||||
|
||||
CREATE INDEX "IX_FilterChannelId_GuildFilterConfigId" ON "FilterChannelId" ("GuildFilterConfigId");
|
||||
|
||||
CREATE INDEX "IX_FilteredWord_GuildFilterConfigId" ON "FilteredWord" ("GuildFilterConfigId");
|
||||
|
||||
CREATE INDEX "IX_FilterLinksChannelId_GuildFilterConfigId" ON "FilterLinksChannelId" ("GuildFilterConfigId");
|
||||
|
||||
CREATE INDEX "IX_FilterWordsChannelId_GuildFilterConfigId" ON "FilterWordsChannelId" ("GuildFilterConfigId");
|
||||
|
||||
CREATE INDEX "IX_FollowedStream_GuildId_Username_Type" ON "FollowedStream" ("GuildId", "Username", "Type");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_GCChannelId_GuildId_ChannelId" ON "GCChannelId" ("GuildId", "ChannelId");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_MutedUserId_GuildId_UserId" ON "MutedUserId" ("GuildId", "UserId");
|
||||
|
||||
CREATE INDEX "IX_Permissions_GuildConfigId" ON "Permissions" ("GuildConfigId");
|
||||
|
||||
CREATE INDEX "IX_Permissions_GuildId" ON "Permissions" ("GuildId");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_ShopEntry_GuildId_Index" ON "ShopEntry" ("GuildId", "Index");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_SlowmodeIgnoredRole_GuildId_RoleId" ON "SlowmodeIgnoredRole" ("GuildId", "RoleId");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_SlowmodeIgnoredUser_GuildId_UserId" ON "SlowmodeIgnoredUser" ("GuildId", "UserId");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_StreamRoleSettings_GuildId" ON "StreamRoleSettings" ("GuildId");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_UnbanTimer_GuildId_UserId" ON "UnbanTimer" ("GuildId", "UserId");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_UnmuteTimer_GuildId_UserId" ON "UnmuteTimer" ("GuildId", "UserId");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_UnroleTimer_GuildId_UserId" ON "UnroleTimer" ("GuildId", "UserId");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_VcRoleInfo_GuildId_VoiceChannelId" ON "VcRoleInfo" ("GuildId", "VoiceChannelId");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_XpSettings_GuildId" ON "XpSettings" ("GuildId");
|
||||
|
||||
CREATE UNIQUE INDEX "IX_GuildConfigs_GuildId" ON "GuildConfigs" ("GuildId");
|
||||
|
||||
CREATE INDEX "IX_GuildConfigs_WarnExpireHours" ON "GuildConfigs" ("WarnExpireHours");
|
||||
|
||||
INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion")
|
||||
VALUES ('20250126062816_cleanup', '8.0.8');
|
||||
|
||||
COMMIT;
|
|
@ -11,7 +11,7 @@ using EllieBot.Db;
|
|||
namespace EllieBot.Migrations.Sqlite
|
||||
{
|
||||
[DbContext(typeof(SqliteContext))]
|
||||
[Migration("20250124023317_init")]
|
||||
[Migration("20250127062834_init")]
|
||||
partial class init
|
||||
{
|
||||
/// <inheritdoc />
|
||||
|
@ -35,6 +35,9 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.Property<int>("GuildConfigId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("GuildId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<TimeSpan>("MinAge")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
|
@ -43,7 +46,7 @@ namespace EllieBot.Migrations.Sqlite
|
|||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId")
|
||||
b.HasIndex("GuildId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("AntiAltSetting");
|
||||
|
@ -64,6 +67,9 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.Property<int>("GuildConfigId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("GuildId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("PunishDuration")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
|
@ -75,7 +81,7 @@ namespace EllieBot.Migrations.Sqlite
|
|||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId")
|
||||
b.HasIndex("GuildId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("AntiRaidSetting");
|
||||
|
@ -118,6 +124,9 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.Property<int>("GuildConfigId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("GuildId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("MessageThreshold")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
|
@ -129,7 +138,7 @@ namespace EllieBot.Migrations.Sqlite
|
|||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId")
|
||||
b.HasIndex("GuildId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("AntiSpamSetting");
|
||||
|
@ -461,7 +470,7 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
b.Property<ulong>("GuildId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Mapping")
|
||||
|
@ -472,7 +481,7 @@ namespace EllieBot.Migrations.Sqlite
|
|||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
b.HasIndex("GuildId");
|
||||
|
||||
b.ToTable("CommandAlias");
|
||||
});
|
||||
|
@ -489,7 +498,7 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
b.Property<ulong>("GuildId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Seconds")
|
||||
|
@ -497,7 +506,8 @@ namespace EllieBot.Migrations.Sqlite
|
|||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
b.HasIndex("GuildId", "CommandName")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("CommandCooldown");
|
||||
});
|
||||
|
@ -555,12 +565,16 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.Property<int>("GuildConfigId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("GuildId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("State")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
b.HasIndex("GuildId", "ChannelId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("DelMsgOnCmdChannel");
|
||||
});
|
||||
|
@ -689,16 +703,19 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.Property<int>("GuildConfigId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("GuildId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Message")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Url")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasAlternateKey("GuildConfigId", "Url");
|
||||
b.HasIndex("GuildId", "Url")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("FeedSub");
|
||||
});
|
||||
|
@ -712,15 +729,12 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.Property<ulong>("ChannelId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
b.Property<int?>("GuildFilterConfigId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
b.HasIndex("GuildFilterConfigId");
|
||||
|
||||
b.ToTable("FilterChannelId");
|
||||
});
|
||||
|
@ -737,12 +751,12 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
b.Property<int?>("GuildFilterConfigId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
b.HasIndex("GuildFilterConfigId");
|
||||
|
||||
b.ToTable("FilterLinksChannelId");
|
||||
});
|
||||
|
@ -759,12 +773,12 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
b.Property<int?>("GuildFilterConfigId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
b.HasIndex("GuildFilterConfigId");
|
||||
|
||||
b.ToTable("FilterWordsChannelId");
|
||||
});
|
||||
|
@ -778,7 +792,7 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
b.Property<int?>("GuildFilterConfigId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Word")
|
||||
|
@ -786,7 +800,7 @@ namespace EllieBot.Migrations.Sqlite
|
|||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
b.HasIndex("GuildFilterConfigId");
|
||||
|
||||
b.ToTable("FilteredWord");
|
||||
});
|
||||
|
@ -823,12 +837,6 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.Property<ulong>("ChannelId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("GuildId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
|
@ -843,7 +851,7 @@ namespace EllieBot.Migrations.Sqlite
|
|||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
b.HasIndex("GuildId", "Username", "Type");
|
||||
|
||||
b.ToTable("FollowedStream");
|
||||
});
|
||||
|
@ -860,12 +868,13 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
b.Property<ulong>("GuildId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
b.HasIndex("GuildId", "ChannelId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("GCChannelId");
|
||||
});
|
||||
|
@ -983,9 +992,6 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.Property<string>("AutoAssignRoleIds")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("AutoDeleteSelfAssignedRoleMessages")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("CleverbotEnabled")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
|
@ -1001,18 +1007,6 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.Property<bool>("DisableGlobalExpressions")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("ExclusiveSelfAssignedRoles")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("FilterInvites")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("FilterLinks")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("FilterWords")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong?>("GameVoiceChannel")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
|
@ -1067,6 +1061,31 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.ToTable("GuildConfigs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.GuildFilterConfig", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("FilterInvites")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("FilterLinks")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("FilterWords")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("GuildId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildId");
|
||||
|
||||
b.ToTable("GuildFilterConfig");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.HoneypotChannel", b =>
|
||||
{
|
||||
b.Property<ulong>("GuildId")
|
||||
|
@ -1276,7 +1295,7 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
b.Property<ulong>("GuildId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("UserId")
|
||||
|
@ -1284,7 +1303,8 @@ namespace EllieBot.Migrations.Sqlite
|
|||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
b.HasIndex("GuildId", "UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("MutedUserId");
|
||||
});
|
||||
|
@ -1424,6 +1444,9 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.Property<int?>("GuildConfigId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("GuildId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Index")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
|
@ -1449,6 +1472,8 @@ namespace EllieBot.Migrations.Sqlite
|
|||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.HasIndex("GuildId");
|
||||
|
||||
b.ToTable("Permissions");
|
||||
});
|
||||
|
||||
|
@ -1812,7 +1837,7 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
b.Property<ulong>("GuildId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Index")
|
||||
|
@ -1838,7 +1863,8 @@ namespace EllieBot.Migrations.Sqlite
|
|||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
b.HasIndex("GuildId", "Index")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("ShopEntry");
|
||||
});
|
||||
|
@ -1874,7 +1900,7 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
b.Property<ulong>("GuildId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("RoleId")
|
||||
|
@ -1882,7 +1908,8 @@ namespace EllieBot.Migrations.Sqlite
|
|||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
b.HasIndex("GuildId", "RoleId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("SlowmodeIgnoredRole");
|
||||
});
|
||||
|
@ -1896,7 +1923,7 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
b.Property<ulong>("GuildId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("UserId")
|
||||
|
@ -1904,7 +1931,8 @@ namespace EllieBot.Migrations.Sqlite
|
|||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
b.HasIndex("GuildId", "UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("SlowmodeIgnoredUser");
|
||||
});
|
||||
|
@ -2007,12 +2035,15 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.Property<int>("GuildConfigId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("GuildId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Keyword")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId")
|
||||
b.HasIndex("GuildId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("StreamRoleSettings");
|
||||
|
@ -2112,7 +2143,7 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
b.Property<ulong>("GuildId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("UnbanAt")
|
||||
|
@ -2123,7 +2154,8 @@ namespace EllieBot.Migrations.Sqlite
|
|||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
b.HasIndex("GuildId", "UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("UnbanTimer");
|
||||
});
|
||||
|
@ -2137,7 +2169,7 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
b.Property<ulong>("GuildId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("UnmuteAt")
|
||||
|
@ -2148,7 +2180,8 @@ namespace EllieBot.Migrations.Sqlite
|
|||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
b.HasIndex("GuildId", "UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("UnmuteTimer");
|
||||
});
|
||||
|
@ -2162,7 +2195,7 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
b.Property<ulong>("GuildId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("RoleId")
|
||||
|
@ -2176,7 +2209,8 @@ namespace EllieBot.Migrations.Sqlite
|
|||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
b.HasIndex("GuildId", "UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("UnroleTimer");
|
||||
});
|
||||
|
@ -2222,7 +2256,7 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("GuildConfigId")
|
||||
b.Property<ulong>("GuildId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("RoleId")
|
||||
|
@ -2233,7 +2267,8 @@ namespace EllieBot.Migrations.Sqlite
|
|||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
b.HasIndex("GuildId", "VoiceChannelId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("VcRoleInfo");
|
||||
});
|
||||
|
@ -2426,6 +2461,9 @@ namespace EllieBot.Migrations.Sqlite
|
|||
|
||||
b.HasIndex("XpSettingsId");
|
||||
|
||||
b.HasIndex("Level", "XpSettingsId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("XpCurrencyReward");
|
||||
});
|
||||
|
||||
|
@ -2470,12 +2508,15 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.Property<int>("GuildConfigId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("GuildId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("ServerExcluded")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId")
|
||||
b.HasIndex("GuildId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("XpSettings");
|
||||
|
@ -2646,24 +2687,6 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.ToTable("UserBetStats");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.AntiAltSetting", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.GuildConfig", null)
|
||||
.WithOne("AntiAltSetting")
|
||||
.HasForeignKey("EllieBot.Db.Models.AntiAltSetting", "GuildConfigId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.AntiRaidSetting", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.GuildConfig", null)
|
||||
.WithOne("AntiRaidSetting")
|
||||
.HasForeignKey("EllieBot.Db.Models.AntiRaidSetting", "GuildConfigId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.AntiSpamIgnore", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.AntiSpamSetting", null)
|
||||
|
@ -2672,15 +2695,6 @@ namespace EllieBot.Migrations.Sqlite
|
|||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.AntiSpamSetting", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.GuildConfig", null)
|
||||
.WithOne("AntiSpamSetting")
|
||||
.HasForeignKey("EllieBot.Db.Models.AntiSpamSetting", "GuildConfigId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.AutoTranslateUser", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.AutoTranslateChannel", "Channel")
|
||||
|
@ -2740,31 +2754,6 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.Navigation("Owner");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.CommandAlias", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.GuildConfig", null)
|
||||
.WithMany("CommandAliases")
|
||||
.HasForeignKey("GuildConfigId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.CommandCooldown", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.GuildConfig", null)
|
||||
.WithMany("CommandCooldowns")
|
||||
.HasForeignKey("GuildConfigId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.DelMsgOnCmdChannel", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.GuildConfig", null)
|
||||
.WithMany("DelMsgOnCmdChannels")
|
||||
.HasForeignKey("GuildConfigId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.DiscordUser", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.ClubInfo", "Club")
|
||||
|
@ -2777,73 +2766,37 @@ namespace EllieBot.Migrations.Sqlite
|
|||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.ExcludedItem", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.XpSettings", "XpSettings")
|
||||
b.HasOne("EllieBot.Db.Models.XpSettings", null)
|
||||
.WithMany("ExclusionList")
|
||||
.HasForeignKey("XpSettingsId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.Navigation("XpSettings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.FeedSub", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.GuildConfig", "GuildConfig")
|
||||
.WithMany("FeedSubs")
|
||||
.HasForeignKey("GuildConfigId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("GuildConfig");
|
||||
.HasForeignKey("XpSettingsId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.FilterChannelId", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.GuildConfig", null)
|
||||
b.HasOne("EllieBot.Db.Models.GuildFilterConfig", null)
|
||||
.WithMany("FilterInvitesChannelIds")
|
||||
.HasForeignKey("GuildConfigId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
.HasForeignKey("GuildFilterConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.FilterLinksChannelId", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.GuildConfig", null)
|
||||
b.HasOne("EllieBot.Db.Models.GuildFilterConfig", null)
|
||||
.WithMany("FilterLinksChannelIds")
|
||||
.HasForeignKey("GuildConfigId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
.HasForeignKey("GuildFilterConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.FilterWordsChannelId", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.GuildConfig", null)
|
||||
b.HasOne("EllieBot.Db.Models.GuildFilterConfig", null)
|
||||
.WithMany("FilterWordsChannelIds")
|
||||
.HasForeignKey("GuildConfigId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
.HasForeignKey("GuildFilterConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.FilteredWord", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.GuildConfig", null)
|
||||
b.HasOne("EllieBot.Db.Models.GuildFilterConfig", null)
|
||||
.WithMany("FilteredWords")
|
||||
.HasForeignKey("GuildConfigId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.FollowedStream", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.GuildConfig", null)
|
||||
.WithMany("FollowedStreams")
|
||||
.HasForeignKey("GuildConfigId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.GCChannelId", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.GuildConfig", "GuildConfig")
|
||||
.WithMany("GenerateCurrencyChannelIds")
|
||||
.HasForeignKey("GuildConfigId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.Navigation("GuildConfig");
|
||||
.HasForeignKey("GuildFilterConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.GiveawayUser", b =>
|
||||
|
@ -2866,20 +2819,11 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.Navigation("LogSetting");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.MutedUserId", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.GuildConfig", null)
|
||||
.WithMany("MutedUsers")
|
||||
.HasForeignKey("GuildConfigId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.Permissionv2", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.GuildConfig", null)
|
||||
.WithMany("Permissions")
|
||||
.HasForeignKey("GuildConfigId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.PlaylistSong", b =>
|
||||
|
@ -2899,14 +2843,6 @@ namespace EllieBot.Migrations.Sqlite
|
|||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.ShopEntry", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.GuildConfig", null)
|
||||
.WithMany("ShopEntries")
|
||||
.HasForeignKey("GuildConfigId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.ShopEntryItem", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.ShopEntry", null)
|
||||
|
@ -2915,22 +2851,6 @@ namespace EllieBot.Migrations.Sqlite
|
|||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.SlowmodeIgnoredRole", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.GuildConfig", null)
|
||||
.WithMany("SlowmodeIgnoredRoles")
|
||||
.HasForeignKey("GuildConfigId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.SlowmodeIgnoredUser", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.GuildConfig", null)
|
||||
.WithMany("SlowmodeIgnoredUsers")
|
||||
.HasForeignKey("GuildConfigId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.StreamRoleBlacklistedUser", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.StreamRoleSettings", "StreamRoleSettings")
|
||||
|
@ -2942,17 +2862,6 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.Navigation("StreamRoleSettings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.StreamRoleSettings", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.GuildConfig", "GuildConfig")
|
||||
.WithOne("StreamRole")
|
||||
.HasForeignKey("EllieBot.Db.Models.StreamRoleSettings", "GuildConfigId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("GuildConfig");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.StreamRoleWhitelistedUser", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.StreamRoleSettings", "StreamRoleSettings")
|
||||
|
@ -2972,38 +2881,6 @@ namespace EllieBot.Migrations.Sqlite
|
|||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.UnbanTimer", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.GuildConfig", null)
|
||||
.WithMany("UnbanTimer")
|
||||
.HasForeignKey("GuildConfigId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.UnmuteTimer", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.GuildConfig", null)
|
||||
.WithMany("UnmuteTimers")
|
||||
.HasForeignKey("GuildConfigId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.UnroleTimer", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.GuildConfig", null)
|
||||
.WithMany("UnroleTimer")
|
||||
.HasForeignKey("GuildConfigId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.VcRoleInfo", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.GuildConfig", null)
|
||||
.WithMany("VcRoleInfos")
|
||||
.HasForeignKey("GuildConfigId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.WaifuInfo", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.DiscordUser", "Affinity")
|
||||
|
@ -3061,35 +2938,20 @@ namespace EllieBot.Migrations.Sqlite
|
|||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.XpCurrencyReward", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.XpSettings", "XpSettings")
|
||||
b.HasOne("EllieBot.Db.Models.XpSettings", null)
|
||||
.WithMany("CurrencyRewards")
|
||||
.HasForeignKey("XpSettingsId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("XpSettings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.XpRoleReward", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.XpSettings", "XpSettings")
|
||||
b.HasOne("EllieBot.Db.Models.XpSettings", null)
|
||||
.WithMany("RoleRewards")
|
||||
.HasForeignKey("XpSettingsId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("XpSettings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.XpSettings", b =>
|
||||
{
|
||||
b.HasOne("EllieBot.Db.Models.GuildConfig", "GuildConfig")
|
||||
.WithOne("XpSettings")
|
||||
.HasForeignKey("EllieBot.Db.Models.XpSettings", "GuildConfigId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("GuildConfig");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.AntiSpamSetting", b =>
|
||||
|
@ -3123,20 +2985,11 @@ namespace EllieBot.Migrations.Sqlite
|
|||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.GuildConfig", b =>
|
||||
{
|
||||
b.Navigation("AntiAltSetting");
|
||||
|
||||
b.Navigation("AntiRaidSetting");
|
||||
|
||||
b.Navigation("AntiSpamSetting");
|
||||
|
||||
b.Navigation("CommandAliases");
|
||||
|
||||
b.Navigation("CommandCooldowns");
|
||||
|
||||
b.Navigation("DelMsgOnCmdChannels");
|
||||
|
||||
b.Navigation("FeedSubs");
|
||||
b.Navigation("Permissions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.GuildFilterConfig", b =>
|
||||
{
|
||||
b.Navigation("FilterInvitesChannelIds");
|
||||
|
||||
b.Navigation("FilterLinksChannelIds");
|
||||
|
@ -3144,32 +2997,6 @@ namespace EllieBot.Migrations.Sqlite
|
|||
b.Navigation("FilterWordsChannelIds");
|
||||
|
||||
b.Navigation("FilteredWords");
|
||||
|
||||
b.Navigation("FollowedStreams");
|
||||
|
||||
b.Navigation("GenerateCurrencyChannelIds");
|
||||
|
||||
b.Navigation("MutedUsers");
|
||||
|
||||
b.Navigation("Permissions");
|
||||
|
||||
b.Navigation("ShopEntries");
|
||||
|
||||
b.Navigation("SlowmodeIgnoredRoles");
|
||||
|
||||
b.Navigation("SlowmodeIgnoredUsers");
|
||||
|
||||
b.Navigation("StreamRole");
|
||||
|
||||
b.Navigation("UnbanTimer");
|
||||
|
||||
b.Navigation("UnmuteTimers");
|
||||
|
||||
b.Navigation("UnroleTimer");
|
||||
|
||||
b.Navigation("VcRoleInfos");
|
||||
|
||||
b.Navigation("XpSettings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EllieBot.Db.Models.LogSetting", b =>
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -94,7 +94,7 @@ public partial class Administration : EllieModule<AdministrationService>
|
|||
public async Task Delmsgoncmd(List _)
|
||||
{
|
||||
var guild = (SocketGuild)ctx.Guild;
|
||||
var (enabled, channels) = _service.GetDelMsgOnCmdData(ctx.Guild.Id);
|
||||
var (enabled, channels) = await _service.GetDelMsgOnCmdData(ctx.Guild.Id);
|
||||
|
||||
var embed = CreateEmbed()
|
||||
.WithOkColor()
|
||||
|
@ -124,14 +124,13 @@ public partial class Administration : EllieModule<AdministrationService>
|
|||
[Priority(1)]
|
||||
public async Task Delmsgoncmd(Server _ = Server.Server)
|
||||
{
|
||||
if (_service.ToggleDeleteMessageOnCommand(ctx.Guild.Id))
|
||||
var enabled = await _service.ToggleDeleteMessageOnCommand(ctx.Guild.Id);
|
||||
if (enabled)
|
||||
{
|
||||
_service.DeleteMessagesOnCommand.Add(ctx.Guild.Id);
|
||||
await Response().Confirm(strs.delmsg_on).SendAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
_service.DeleteMessagesOnCommand.TryRemove(ctx.Guild.Id);
|
||||
await Response().Confirm(strs.delmsg_off).SendAsync();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#nullable disable
|
||||
using LinqToDB;
|
||||
using LinqToDB.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using EllieBot.Db.Models;
|
||||
using EllieBot.Modules.Administration._common.results;
|
||||
|
@ -7,95 +9,130 @@ namespace EllieBot.Modules.Administration;
|
|||
|
||||
public class AdministrationService : IEService
|
||||
{
|
||||
public ConcurrentHashSet<ulong> DeleteMessagesOnCommand { get; }
|
||||
public ConcurrentDictionary<ulong, bool> DeleteMessagesOnCommandChannels { get; }
|
||||
private ConcurrentHashSet<ulong> deleteMessagesOnCommand;
|
||||
private ConcurrentDictionary<ulong, bool> delMsgOnCmdChannels;
|
||||
|
||||
private readonly DbService _db;
|
||||
private readonly IReplacementService _repSvc;
|
||||
private readonly ILogCommandService _logService;
|
||||
private readonly IHttpClientFactory _httpFactory;
|
||||
private readonly ShardData _shardData;
|
||||
private readonly CommandHandler _cmdHandler;
|
||||
|
||||
public AdministrationService(
|
||||
IBot bot,
|
||||
CommandHandler cmdHandler,
|
||||
DbService db,
|
||||
IReplacementService repSvc,
|
||||
ILogCommandService logService,
|
||||
IHttpClientFactory factory)
|
||||
IHttpClientFactory factory,
|
||||
ShardData shardData,
|
||||
CommandHandler cmdHandler)
|
||||
{
|
||||
_db = db;
|
||||
_shardData = shardData;
|
||||
_repSvc = repSvc;
|
||||
_logService = logService;
|
||||
_httpFactory = factory;
|
||||
|
||||
DeleteMessagesOnCommand = new(bot.AllGuildConfigs.Where(g => g.DeleteMessageOnCommand).Select(g => g.GuildId));
|
||||
|
||||
DeleteMessagesOnCommandChannels = new(bot.AllGuildConfigs.SelectMany(x => x.DelMsgOnCmdChannels)
|
||||
.ToDictionary(x => x.ChannelId, x => x.State)
|
||||
.ToConcurrent());
|
||||
|
||||
cmdHandler.CommandExecuted += DelMsgOnCmd_Handler;
|
||||
_cmdHandler = cmdHandler;
|
||||
}
|
||||
|
||||
public (bool DelMsgOnCmd, IEnumerable<DelMsgOnCmdChannel> channels) GetDelMsgOnCmdData(ulong guildId)
|
||||
public async Task ReadyAsync()
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
deleteMessagesOnCommand = new(await uow.GetTable<GuildConfig>()
|
||||
.Where(x => Queries.GuildOnShard(x.GuildId, _shardData.TotalShards, _shardData.ShardId) && x.DeleteMessageOnCommand)
|
||||
.Select(x => x.GuildId)
|
||||
.ToListAsyncLinqToDB());
|
||||
|
||||
delMsgOnCmdChannels = (await uow.GetTable<DelMsgOnCmdChannel>()
|
||||
.Where(x => deleteMessagesOnCommand.Contains(x.GuildId))
|
||||
.ToDictionaryAsyncLinqToDB(x => x.ChannelId, x => x.State))
|
||||
.ToConcurrent();
|
||||
|
||||
_cmdHandler.CommandExecuted += DelMsgOnCmd_Handler;
|
||||
}
|
||||
|
||||
public async Task<(bool DelMsgOnCmd, IEnumerable<DelMsgOnCmdChannel> channels)> GetDelMsgOnCmdData(ulong guildId)
|
||||
{
|
||||
using var uow = _db.GetDbContext();
|
||||
var conf = uow.GuildConfigsForId(guildId, set => set.Include(x => x.DelMsgOnCmdChannels));
|
||||
|
||||
return (conf.DeleteMessageOnCommand, conf.DelMsgOnCmdChannels);
|
||||
var conf = await uow.GetTable<GuildConfig>()
|
||||
.Where(x => x.GuildId == guildId)
|
||||
.Select(x => x.DeleteMessageOnCommand)
|
||||
.FirstOrDefaultAsyncLinqToDB();
|
||||
|
||||
var channels = await uow.GetTable<DelMsgOnCmdChannel>()
|
||||
.Where(x => x.GuildId == guildId)
|
||||
.ToListAsyncLinqToDB();
|
||||
|
||||
return (conf, channels);
|
||||
}
|
||||
|
||||
private Task DelMsgOnCmd_Handler(IUserMessage msg, CommandInfo cmd)
|
||||
{
|
||||
if (msg.Channel is not ITextChannel channel)
|
||||
return Task.CompletedTask;
|
||||
|
||||
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
//wat ?!
|
||||
if (DeleteMessagesOnCommandChannels.TryGetValue(channel.Id, out var state))
|
||||
if (delMsgOnCmdChannels.TryGetValue(channel.Id, out var state))
|
||||
{
|
||||
if (state && cmd.Name != "prune" && cmd.Name != "pick")
|
||||
{
|
||||
_logService.AddDeleteIgnore(msg.Id);
|
||||
try { await msg.DeleteAsync(); }
|
||||
try
|
||||
{ await msg.DeleteAsync(); }
|
||||
catch { }
|
||||
}
|
||||
//if state is false, that means do not do it
|
||||
}
|
||||
else if (DeleteMessagesOnCommand.Contains(channel.Guild.Id) && cmd.Name != "prune" && cmd.Name != "pick")
|
||||
else if (deleteMessagesOnCommand.Contains(channel.Guild.Id) && cmd.Name != "prune" && cmd.Name != "pick")
|
||||
{
|
||||
_logService.AddDeleteIgnore(msg.Id);
|
||||
try { await msg.DeleteAsync(); }
|
||||
try
|
||||
{ await msg.DeleteAsync(); }
|
||||
catch { }
|
||||
}
|
||||
});
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public bool ToggleDeleteMessageOnCommand(ulong guildId)
|
||||
public async Task<bool> ToggleDeleteMessageOnCommand(ulong guildId)
|
||||
{
|
||||
bool enabled;
|
||||
using var uow = _db.GetDbContext();
|
||||
var conf = uow.GuildConfigsForId(guildId, set => set);
|
||||
enabled = conf.DeleteMessageOnCommand = !conf.DeleteMessageOnCommand;
|
||||
|
||||
uow.SaveChanges();
|
||||
return enabled;
|
||||
var conf = await uow.GetTable<GuildConfig>()
|
||||
.Where(x => x.GuildId == guildId)
|
||||
.UpdateWithOutputAsync(x => new()
|
||||
{
|
||||
DeleteMessageOnCommand = !x.DeleteMessageOnCommand
|
||||
});
|
||||
|
||||
if (conf.Length == 0)
|
||||
return false;
|
||||
|
||||
var val = conf[0].Inserted.DeleteMessageOnCommand;
|
||||
|
||||
if (val)
|
||||
deleteMessagesOnCommand.Add(guildId);
|
||||
else
|
||||
deleteMessagesOnCommand.TryRemove(guildId);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
public async Task SetDelMsgOnCmdState(ulong guildId, ulong chId, Administration.State newState)
|
||||
{
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var conf = uow.GuildConfigsForId(guildId, set => set.Include(x => x.DelMsgOnCmdChannels));
|
||||
var old = await uow.GetTable<DelMsgOnCmdChannel>()
|
||||
.Where(x => x.GuildId == guildId && x.ChannelId == chId)
|
||||
.FirstOrDefaultAsyncLinqToDB();
|
||||
|
||||
var old = conf.DelMsgOnCmdChannels.FirstOrDefault(x => x.ChannelId == chId);
|
||||
if (newState == Administration.State.Inherit)
|
||||
{
|
||||
if (old is not null)
|
||||
{
|
||||
conf.DelMsgOnCmdChannels.Remove(old);
|
||||
uow.Remove(old);
|
||||
}
|
||||
}
|
||||
|
@ -103,15 +140,17 @@ public class AdministrationService : IEService
|
|||
{
|
||||
if (old is null)
|
||||
{
|
||||
old = new()
|
||||
old = new DelMsgOnCmdChannel
|
||||
{
|
||||
ChannelId = chId
|
||||
GuildId = guildId,
|
||||
ChannelId = chId,
|
||||
State = newState == Administration.State.Enable
|
||||
};
|
||||
conf.DelMsgOnCmdChannels.Add(old);
|
||||
uow.Add(old);
|
||||
}
|
||||
|
||||
old.State = newState == Administration.State.Enable;
|
||||
DeleteMessagesOnCommandChannels[chId] = newState == Administration.State.Enable;
|
||||
delMsgOnCmdChannels[chId] = newState == Administration.State.Enable;
|
||||
}
|
||||
|
||||
await uow.SaveChangesAsync();
|
||||
|
@ -121,9 +160,13 @@ public class AdministrationService : IEService
|
|||
{
|
||||
}
|
||||
else if (newState == Administration.State.Enable)
|
||||
DeleteMessagesOnCommandChannels[chId] = true;
|
||||
{
|
||||
delMsgOnCmdChannels[chId] = true;
|
||||
}
|
||||
else
|
||||
DeleteMessagesOnCommandChannels.TryRemove(chId, out _);
|
||||
{
|
||||
delMsgOnCmdChannels.TryRemove(chId, out _);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DeafenUsers(bool value, params IGuildUser[] users)
|
||||
|
@ -164,20 +207,22 @@ public class AdministrationService : IEService
|
|||
|
||||
public async Task<SetServerBannerResult> SetServerBannerAsync(IGuild guild, string img)
|
||||
{
|
||||
if (!IsValidUri(img)) return SetServerBannerResult.InvalidURL;
|
||||
|
||||
if (!IsValidUri(img))
|
||||
return SetServerBannerResult.InvalidURL;
|
||||
|
||||
var uri = new Uri(img);
|
||||
|
||||
using var http = _httpFactory.CreateClient();
|
||||
using var sr = await http.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead);
|
||||
|
||||
if (!sr.IsImage()) return SetServerBannerResult.InvalidFileType;
|
||||
|
||||
if (!sr.IsImage())
|
||||
return SetServerBannerResult.InvalidFileType;
|
||||
|
||||
if (sr.GetContentLength() > 8.Megabytes())
|
||||
{
|
||||
return SetServerBannerResult.Toolarge;
|
||||
}
|
||||
|
||||
|
||||
await using var imageStream = await sr.Content.ReadAsStreamAsync();
|
||||
|
||||
await guild.ModifyAsync(x => x.Banner = new Image(imageStream));
|
||||
|
@ -186,20 +231,22 @@ public class AdministrationService : IEService
|
|||
|
||||
public async Task<SetServerIconResult> SetServerIconAsync(IGuild guild, string img)
|
||||
{
|
||||
if (!IsValidUri(img)) return SetServerIconResult.InvalidURL;
|
||||
|
||||
if (!IsValidUri(img))
|
||||
return SetServerIconResult.InvalidURL;
|
||||
|
||||
var uri = new Uri(img);
|
||||
|
||||
using var http = _httpFactory.CreateClient();
|
||||
using var sr = await http.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead);
|
||||
|
||||
if (!sr.IsImage()) return SetServerIconResult.InvalidFileType;
|
||||
|
||||
|
||||
if (!sr.IsImage())
|
||||
return SetServerIconResult.InvalidFileType;
|
||||
|
||||
await using var imageStream = await sr.Content.ReadAsStreamAsync();
|
||||
|
||||
await guild.ModifyAsync(x => x.Icon = new Image(imageStream));
|
||||
return SetServerIconResult.Success;
|
||||
}
|
||||
|
||||
|
||||
private bool IsValidUri(string img) => !string.IsNullOrWhiteSpace(img) && Uri.IsWellFormedUriString(img, UriKind.Absolute);
|
||||
}
|
|
@ -3,6 +3,7 @@ using EllieBot.Db.Models;
|
|||
using System.Net;
|
||||
using System.Threading.Channels;
|
||||
using LinqToDB;
|
||||
using LinqToDB.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace EllieBot.Modules.Administration.Services;
|
||||
|
@ -11,9 +12,10 @@ public sealed class AutoAssignRoleService : IEService
|
|||
{
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly DbService _db;
|
||||
private readonly ShardData _shardData;
|
||||
|
||||
//guildid/roleid
|
||||
private readonly ConcurrentDictionary<ulong, IReadOnlyList<ulong>> _autoAssignableRoles;
|
||||
private ConcurrentDictionary<ulong, IReadOnlyList<ulong>> _autoAssignableRoles;
|
||||
|
||||
private readonly Channel<SocketGuildUser> _assignQueue = Channel.CreateBounded<SocketGuildUser>(
|
||||
new BoundedChannelOptions(100)
|
||||
|
@ -23,63 +25,78 @@ public sealed class AutoAssignRoleService : IEService
|
|||
SingleWriter = false
|
||||
});
|
||||
|
||||
public AutoAssignRoleService(DiscordSocketClient client, IBot bot, DbService db)
|
||||
public AutoAssignRoleService(
|
||||
DiscordSocketClient client,
|
||||
IBot bot,
|
||||
DbService db,
|
||||
ShardData shardData)
|
||||
{
|
||||
_client = client;
|
||||
_shardData = shardData;
|
||||
_db = db;
|
||||
}
|
||||
|
||||
_autoAssignableRoles = bot.AllGuildConfigs.Where(x => !string.IsNullOrWhiteSpace(x.AutoAssignRoleIds))
|
||||
.ToDictionary<GuildConfig, ulong, IReadOnlyList<ulong>>(k => k.GuildId,
|
||||
v => v.GetAutoAssignableRoles())
|
||||
.ToConcurrent();
|
||||
|
||||
_ = Task.Run(async () =>
|
||||
public async Task OnReadyAsync()
|
||||
{
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
while (true)
|
||||
_autoAssignableRoles = await uow.GetTable<GuildConfig>()
|
||||
.Where(x => Queries.GuildOnShard(x.GuildId,
|
||||
_shardData.TotalShards,
|
||||
_shardData.ShardId))
|
||||
.Where(x => x.AutoAssignRoleIds != null)
|
||||
.ToListAsyncLinqToDB()
|
||||
.Fmap(x => x
|
||||
.ToDictionary<GuildConfig, ulong, IReadOnlyList<ulong>>(
|
||||
k => k.GuildId,
|
||||
v => v.GetAutoAssignableRoles())
|
||||
.ToConcurrent());
|
||||
}
|
||||
|
||||
_client.UserJoined += OnClientOnUserJoined;
|
||||
_client.RoleDeleted += OnClientRoleDeleted;
|
||||
|
||||
while (true)
|
||||
{
|
||||
var user = await _assignQueue.Reader.ReadAsync();
|
||||
if (!_autoAssignableRoles.TryGetValue(user.Guild.Id, out var savedRoleIds))
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
var user = await _assignQueue.Reader.ReadAsync();
|
||||
if (!_autoAssignableRoles.TryGetValue(user.Guild.Id, out var savedRoleIds))
|
||||
continue;
|
||||
var roleIds = savedRoleIds.Select(roleId => user.Guild.GetRole(roleId))
|
||||
.Where(x => x is not null)
|
||||
.ToList();
|
||||
|
||||
try
|
||||
if (roleIds.Any())
|
||||
{
|
||||
var roleIds = savedRoleIds.Select(roleId => user.Guild.GetRole(roleId))
|
||||
.Where(x => x is not null)
|
||||
.ToList();
|
||||
|
||||
if (roleIds.Any())
|
||||
{
|
||||
await user.AddRolesAsync(roleIds);
|
||||
await Task.Delay(250);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Warning(
|
||||
"Disabled 'Auto assign role' feature on {GuildName} [{GuildId}] server the roles dont exist",
|
||||
user.Guild.Name,
|
||||
user.Guild.Id);
|
||||
|
||||
await DisableAarAsync(user.Guild.Id);
|
||||
}
|
||||
await user.AddRolesAsync(roleIds);
|
||||
await Task.Delay(250);
|
||||
}
|
||||
catch (HttpException ex) when (ex.HttpCode == HttpStatusCode.Forbidden)
|
||||
else
|
||||
{
|
||||
Log.Warning(
|
||||
"Disabled 'Auto assign role' feature on {GuildName} [{GuildId}] server because I don't have role management permissions",
|
||||
"Disabled 'Auto assign role' feature on {GuildName} [{GuildId}] server the roles dont exist",
|
||||
user.Guild.Name,
|
||||
user.Guild.Id);
|
||||
|
||||
await DisableAarAsync(user.Guild.Id);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Warning(ex, "Error in aar. Probably one of the roles doesn't exist");
|
||||
}
|
||||
}
|
||||
});
|
||||
catch (HttpException ex) when (ex.HttpCode == HttpStatusCode.Forbidden)
|
||||
{
|
||||
Log.Warning(
|
||||
"Disabled 'Auto assign role' feature on {GuildName} [{GuildId}] server because I don't have role management permissions",
|
||||
user.Guild.Name,
|
||||
user.Guild.Id);
|
||||
|
||||
_client.UserJoined += OnClientOnUserJoined;
|
||||
_client.RoleDeleted += OnClientRoleDeleted;
|
||||
await DisableAarAsync(user.Guild.Id);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Warning(ex, "Error in aar. Probably one of the roles doesn't exist");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task OnClientRoleDeleted(SocketRole role)
|
||||
|
@ -117,7 +134,8 @@ public sealed class AutoAssignRoleService : IEService
|
|||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
|
||||
await uow.Set<GuildConfig>().AsNoTracking()
|
||||
await uow.Set<GuildConfig>()
|
||||
.AsNoTracking()
|
||||
.Where(x => x.GuildId == guildId)
|
||||
.UpdateAsync(_ => new()
|
||||
{
|
||||
|
|
|
@ -42,7 +42,7 @@ public class AutoPublishService : IExecNoCommand, IReadyExecutor, IEService
|
|||
|
||||
await using var ctx = _db.GetDbContext();
|
||||
var items = await ctx.GetTable<AutoPublishChannel>()
|
||||
.Where(x => Linq2DbExpressions.GuildOnShard(x.GuildId, creds.TotalShards, _client.ShardId))
|
||||
.Where(x => Queries.GuildOnShard(x.GuildId, creds.TotalShards, _client.ShardId))
|
||||
.ToListAsyncLinqToDB();
|
||||
|
||||
_enabled = items
|
||||
|
|
|
@ -25,10 +25,11 @@ public partial class Administration
|
|||
var id = _service.ToggleGameVoiceChannel(ctx.Guild.Id, vch.Id);
|
||||
|
||||
if (id is null)
|
||||
{
|
||||
await Response().Confirm(strs.gvc_disabled).SendAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
_service.GameVoiceChannels.Add(vch.Id);
|
||||
await Response().Confirm(strs.gvc_enabled(Format.Bold(vch.Name))).SendAsync();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
#nullable disable
|
||||
using LinqToDB.EntityFrameworkCore;
|
||||
using EllieBot.Db.Models;
|
||||
|
||||
namespace EllieBot.Modules.Administration.Services;
|
||||
|
||||
public class GameVoiceChannelService : IEService
|
||||
{
|
||||
public ConcurrentHashSet<ulong> GameVoiceChannels { get; }
|
||||
private ConcurrentHashSet<ulong> _gameVoiceChannels = new();
|
||||
|
||||
private readonly DbService _db;
|
||||
private readonly DiscordSocketClient _client;
|
||||
|
@ -12,10 +15,16 @@ public class GameVoiceChannelService : IEService
|
|||
{
|
||||
_db = db;
|
||||
_client = client;
|
||||
}
|
||||
|
||||
GameVoiceChannels = new(bot.AllGuildConfigs
|
||||
.Where(gc => gc.GameVoiceChannel is not null)
|
||||
.Select(gc => gc.GameVoiceChannel!.Value));
|
||||
public async Task InitializeAsync()
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
_gameVoiceChannels = new(await uow.Set<GuildConfig>()
|
||||
.Where(gc => gc.GameVoiceChannel != null)
|
||||
.Select(gc => gc.GameVoiceChannel)
|
||||
.ToListAsyncLinqToDB()
|
||||
.Fmap(u => new ConcurrentHashSet<ulong>(u.Select(x => x.Value))));
|
||||
|
||||
_client.UserVoiceStateUpdated += OnUserVoiceStateUpdated;
|
||||
_client.PresenceUpdated += OnPresenceUpdate;
|
||||
|
@ -32,14 +41,14 @@ public class GameVoiceChannelService : IEService
|
|||
// if the user is in the voice channel and that voice channel is gvc
|
||||
|
||||
if (newUser.VoiceChannel is not { } vc
|
||||
|| !GameVoiceChannels.Contains(vc.Id))
|
||||
|| !_gameVoiceChannels.Contains(vc.Id))
|
||||
return;
|
||||
|
||||
//if the activity has changed, and is a playi1ng activity
|
||||
foreach (var activity in after.Activities)
|
||||
{
|
||||
if (activity is { Type: ActivityType.Playing })
|
||||
//trigger gvc
|
||||
//trigger gvc
|
||||
{
|
||||
if (await TriggerGvc(newUser, activity.Name))
|
||||
return;
|
||||
|
@ -58,18 +67,19 @@ public class GameVoiceChannelService : IEService
|
|||
{
|
||||
ulong? id;
|
||||
using var uow = _db.GetDbContext();
|
||||
var gc = uow.GuildConfigsForId(guildId, set => set);
|
||||
var gc = uow.GuildConfigsForId(guildId);
|
||||
|
||||
|
||||
if (gc.GameVoiceChannel == vchId)
|
||||
{
|
||||
GameVoiceChannels.TryRemove(vchId);
|
||||
_gameVoiceChannels.TryRemove(vchId);
|
||||
id = gc.GameVoiceChannel = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gc.GameVoiceChannel is not null)
|
||||
GameVoiceChannels.TryRemove(gc.GameVoiceChannel.Value);
|
||||
GameVoiceChannels.Add(vchId);
|
||||
_gameVoiceChannels.TryRemove(gc.GameVoiceChannel.Value);
|
||||
_gameVoiceChannels.Add(vchId);
|
||||
id = gc.GameVoiceChannel = vchId;
|
||||
}
|
||||
|
||||
|
@ -89,7 +99,7 @@ public class GameVoiceChannelService : IEService
|
|||
if (newState.VoiceChannel is null)
|
||||
return;
|
||||
|
||||
if (!GameVoiceChannels.Contains(newState.VoiceChannel.Id))
|
||||
if (!_gameVoiceChannels.Contains(newState.VoiceChannel.Id))
|
||||
return;
|
||||
|
||||
foreach (var game in gUser.Activities.Select(x => x.Name))
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#nullable disable
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using LinqToDB;
|
||||
using LinqToDB.EntityFrameworkCore;
|
||||
using EllieBot.Common.ModuleBehaviors;
|
||||
using EllieBot.Db.Models;
|
||||
|
||||
namespace EllieBot.Modules.Administration.Services;
|
||||
|
@ -11,7 +13,7 @@ public enum MuteType
|
|||
All
|
||||
}
|
||||
|
||||
public class MuteService : IEService
|
||||
public class MuteService : IEService, IReadyExecutor
|
||||
{
|
||||
public enum TimerType { Mute, Ban, AddRole }
|
||||
|
||||
|
@ -23,90 +25,23 @@ public class MuteService : IEService
|
|||
public event Action<IGuildUser, IUser, MuteType, string> UserMuted = delegate { };
|
||||
public event Action<IGuildUser, IUser, MuteType, string> UserUnmuted = delegate { };
|
||||
|
||||
public ConcurrentDictionary<ulong, string> GuildMuteRoles { get; }
|
||||
public ConcurrentDictionary<ulong, ConcurrentHashSet<ulong>> MutedUsers { get; }
|
||||
private ConcurrentDictionary<ulong, string> _guildMuteRoles = new();
|
||||
private ConcurrentDictionary<ulong, ConcurrentHashSet<ulong>> _mutedUsers = new();
|
||||
|
||||
public ConcurrentDictionary<ulong, ConcurrentDictionary<(ulong, TimerType), Timer>> UnTimers { get; } = new();
|
||||
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly DbService _db;
|
||||
private readonly IMessageSenderService _sender;
|
||||
private readonly ShardData _shardData;
|
||||
|
||||
public MuteService(DiscordSocketClient client, DbService db, IMessageSenderService sender)
|
||||
public MuteService(DiscordSocketClient client, DbService db, IMessageSenderService sender, ShardData shardData)
|
||||
{
|
||||
_client = client;
|
||||
_db = db;
|
||||
_sender = sender;
|
||||
_shardData = shardData;
|
||||
|
||||
using (var uow = db.GetDbContext())
|
||||
{
|
||||
var guildIds = client.Guilds.Select(x => x.Id).ToList();
|
||||
var configs = uow.Set<GuildConfig>()
|
||||
.AsNoTracking()
|
||||
.AsSplitQuery()
|
||||
.Include(x => x.MutedUsers)
|
||||
.Include(x => x.UnbanTimer)
|
||||
.Include(x => x.UnmuteTimers)
|
||||
.Include(x => x.UnroleTimer)
|
||||
.Where(x => guildIds.Contains(x.GuildId))
|
||||
.ToList();
|
||||
|
||||
GuildMuteRoles = configs.Where(c => !string.IsNullOrWhiteSpace(c.MuteRoleName))
|
||||
.ToDictionary(c => c.GuildId, c => c.MuteRoleName)
|
||||
.ToConcurrent();
|
||||
|
||||
MutedUsers = new(configs.ToDictionary(k => k.GuildId,
|
||||
v => new ConcurrentHashSet<ulong>(v.MutedUsers.Select(m => m.UserId))));
|
||||
|
||||
var max = TimeSpan.FromDays(49);
|
||||
|
||||
foreach (var conf in configs)
|
||||
{
|
||||
foreach (var x in conf.UnmuteTimers)
|
||||
{
|
||||
TimeSpan after;
|
||||
if (x.UnmuteAt - TimeSpan.FromMinutes(2) <= DateTime.UtcNow)
|
||||
after = TimeSpan.FromMinutes(2);
|
||||
else
|
||||
{
|
||||
var unmute = x.UnmuteAt - DateTime.UtcNow;
|
||||
after = unmute > max ? max : unmute;
|
||||
}
|
||||
|
||||
StartUn_Timer(conf.GuildId, x.UserId, after, TimerType.Mute);
|
||||
}
|
||||
|
||||
foreach (var x in conf.UnbanTimer)
|
||||
{
|
||||
TimeSpan after;
|
||||
if (x.UnbanAt - TimeSpan.FromMinutes(2) <= DateTime.UtcNow)
|
||||
after = TimeSpan.FromMinutes(2);
|
||||
else
|
||||
{
|
||||
var unban = x.UnbanAt - DateTime.UtcNow;
|
||||
after = unban > max ? max : unban;
|
||||
}
|
||||
|
||||
StartUn_Timer(conf.GuildId, x.UserId, after, TimerType.Ban);
|
||||
}
|
||||
|
||||
foreach (var x in conf.UnroleTimer)
|
||||
{
|
||||
TimeSpan after;
|
||||
if (x.UnbanAt - TimeSpan.FromMinutes(2) <= DateTime.UtcNow)
|
||||
after = TimeSpan.FromMinutes(2);
|
||||
else
|
||||
{
|
||||
var unban = x.UnbanAt - DateTime.UtcNow;
|
||||
after = unban > max ? max : unban;
|
||||
}
|
||||
|
||||
StartUn_Timer(conf.GuildId, x.UserId, after, TimerType.AddRole, x.RoleId);
|
||||
}
|
||||
}
|
||||
|
||||
_client.UserJoined += Client_UserJoined;
|
||||
}
|
||||
|
||||
UserMuted += OnUserMuted;
|
||||
UserUnmuted += OnUserUnmuted;
|
||||
|
@ -123,10 +58,10 @@ public class MuteService : IEService
|
|||
|
||||
_ = Task.Run(() => _sender.Response(user)
|
||||
.Embed(_sender.CreateEmbed(user?.GuildId)
|
||||
.WithDescription($"You've been muted in {user.Guild} server")
|
||||
.AddField("Mute Type", type.ToString())
|
||||
.AddField("Moderator", mod.ToString())
|
||||
.AddField("Reason", reason))
|
||||
.WithDescription($"You've been muted in {user.Guild} server")
|
||||
.AddField("Mute Type", type.ToString())
|
||||
.AddField("Moderator", mod.ToString())
|
||||
.AddField("Reason", reason))
|
||||
.SendAsync());
|
||||
}
|
||||
|
||||
|
@ -141,10 +76,10 @@ public class MuteService : IEService
|
|||
|
||||
_ = Task.Run(() => _sender.Response(user)
|
||||
.Embed(_sender.CreateEmbed(user.GuildId)
|
||||
.WithDescription($"You've been unmuted in {user.Guild} server")
|
||||
.AddField("Unmute Type", type.ToString())
|
||||
.AddField("Moderator", mod.ToString())
|
||||
.AddField("Reason", reason))
|
||||
.WithDescription($"You've been unmuted in {user.Guild} server")
|
||||
.AddField("Unmute Type", type.ToString())
|
||||
.AddField("Moderator", mod.ToString())
|
||||
.AddField("Reason", reason))
|
||||
.SendAsync());
|
||||
}
|
||||
|
||||
|
@ -152,7 +87,7 @@ public class MuteService : IEService
|
|||
{
|
||||
try
|
||||
{
|
||||
MutedUsers.TryGetValue(usr.Guild.Id, out var muted);
|
||||
_mutedUsers.TryGetValue(usr.Guild.Id, out var muted);
|
||||
|
||||
if (muted is null || !muted.Contains(usr.Id))
|
||||
return Task.CompletedTask;
|
||||
|
@ -169,9 +104,11 @@ public class MuteService : IEService
|
|||
public async Task SetMuteRoleAsync(ulong guildId, string name)
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
var config = uow.GuildConfigsForId(guildId, set => set);
|
||||
var config = uow.GetTable<GuildConfig>()
|
||||
.Where(x => x.GuildId == guildId)
|
||||
.FirstOrDefault();
|
||||
config.MuteRoleName = name;
|
||||
GuildMuteRoles.AddOrUpdate(guildId, name, (_, _) => name);
|
||||
_guildMuteRoles.AddOrUpdate(guildId, name, (_, _) => name);
|
||||
await uow.SaveChangesAsync();
|
||||
}
|
||||
|
||||
|
@ -183,7 +120,8 @@ public class MuteService : IEService
|
|||
{
|
||||
if (type == MuteType.All)
|
||||
{
|
||||
try { await usr.ModifyAsync(x => x.Mute = true); }
|
||||
try
|
||||
{ await usr.ModifyAsync(x => x.Mute = true); }
|
||||
catch { }
|
||||
|
||||
var muteRole = await GetMuteRole(usr.Guild);
|
||||
|
@ -192,16 +130,23 @@ public class MuteService : IEService
|
|||
StopTimer(usr.GuildId, usr.Id, TimerType.Mute);
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var config = uow.GuildConfigsForId(usr.Guild.Id,
|
||||
set => set.Include(gc => gc.MutedUsers).Include(gc => gc.UnmuteTimers));
|
||||
config.MutedUsers.Add(new()
|
||||
{
|
||||
UserId = usr.Id
|
||||
});
|
||||
if (MutedUsers.TryGetValue(usr.Guild.Id, out var muted))
|
||||
muted.Add(usr.Id);
|
||||
await uow.GetTable<MutedUserId>()
|
||||
.InsertOrUpdateAsync(() => new()
|
||||
{
|
||||
GuildId = usr.GuildId,
|
||||
UserId = usr.Id
|
||||
},
|
||||
(_) => new()
|
||||
{
|
||||
},
|
||||
() => new()
|
||||
{
|
||||
GuildId = usr.GuildId,
|
||||
UserId = usr.Id
|
||||
});
|
||||
|
||||
config.UnmuteTimers.RemoveWhere(x => x.UserId == usr.Id);
|
||||
if (_mutedUsers.TryGetValue(usr.Guild.Id, out var muted))
|
||||
muted.Add(usr.Id);
|
||||
|
||||
await uow.SaveChangesAsync();
|
||||
}
|
||||
|
@ -237,29 +182,26 @@ public class MuteService : IEService
|
|||
StopTimer(guildId, usrId, TimerType.Mute);
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var config = uow.GuildConfigsForId(guildId,
|
||||
set => set.Include(gc => gc.MutedUsers).Include(gc => gc.UnmuteTimers));
|
||||
var match = new MutedUserId
|
||||
{
|
||||
UserId = usrId
|
||||
};
|
||||
var toRemove = config.MutedUsers.FirstOrDefault(x => x.Equals(match));
|
||||
if (toRemove is not null)
|
||||
uow.Remove(toRemove);
|
||||
if (MutedUsers.TryGetValue(guildId, out var muted))
|
||||
await uow.GetTable<MutedUserId>()
|
||||
.Where(x => x.GuildId == guildId && x.UserId == usrId)
|
||||
.DeleteAsync();
|
||||
|
||||
await uow.GetTable<UnmuteTimer>()
|
||||
.Where(x => x.GuildId == guildId && x.UserId == usrId)
|
||||
.DeleteAsync();
|
||||
|
||||
if (_mutedUsers.TryGetValue(guildId, out var muted))
|
||||
muted.TryRemove(usrId);
|
||||
|
||||
config.UnmuteTimers.RemoveWhere(x => x.UserId == usrId);
|
||||
|
||||
await uow.SaveChangesAsync();
|
||||
}
|
||||
|
||||
if (usr is not null)
|
||||
{
|
||||
try { await usr.ModifyAsync(x => x.Mute = false); }
|
||||
try
|
||||
{ await usr.ModifyAsync(x => x.Mute = false); }
|
||||
catch { }
|
||||
|
||||
try { await usr.RemoveRoleAsync(await GetMuteRole(usr.Guild)); }
|
||||
try
|
||||
{ await usr.RemoveRoleAsync(await GetMuteRole(usr.Guild)); }
|
||||
catch
|
||||
{
|
||||
/*ignore*/
|
||||
|
@ -272,12 +214,9 @@ public class MuteService : IEService
|
|||
{
|
||||
if (usr is null)
|
||||
return;
|
||||
try
|
||||
{
|
||||
await usr.ModifyAsync(x => x.Mute = false);
|
||||
UserUnmuted(usr, mod, MuteType.Voice, reason);
|
||||
}
|
||||
catch { }
|
||||
|
||||
await usr.ModifyAsync(x => x.Mute = false);
|
||||
UserUnmuted(usr, mod, MuteType.Voice, reason);
|
||||
}
|
||||
else if (type == MuteType.Chat)
|
||||
{
|
||||
|
@ -292,15 +231,16 @@ public class MuteService : IEService
|
|||
{
|
||||
ArgumentNullException.ThrowIfNull(guild);
|
||||
|
||||
const string defaultMuteRoleName = "ellie-mute";
|
||||
const string defaultMuteRoleName = "nadeko-mute";
|
||||
|
||||
var muteRoleName = GuildMuteRoles.GetOrAdd(guild.Id, defaultMuteRoleName);
|
||||
var muteRoleName = _guildMuteRoles.GetOrAdd(guild.Id, defaultMuteRoleName);
|
||||
|
||||
var muteRole = guild.Roles.FirstOrDefault(r => r.Name == muteRoleName);
|
||||
if (muteRole is null)
|
||||
//if it doesn't exist, create it
|
||||
//if it doesn't exist, create it
|
||||
{
|
||||
try { muteRole = await guild.CreateRoleAsync(muteRoleName, isMentionable: false); }
|
||||
try
|
||||
{ muteRole = await guild.CreateRoleAsync(muteRoleName, isMentionable: false); }
|
||||
catch
|
||||
{
|
||||
//if creations fails, maybe the name is not correct, find default one, if doesn't work, create default one
|
||||
|
@ -340,13 +280,14 @@ public class MuteService : IEService
|
|||
await MuteUser(user, mod, muteType, reason); // mute the user. This will also remove any previous unmute timers
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var config = uow.GuildConfigsForId(user.GuildId, set => set.Include(x => x.UnmuteTimers));
|
||||
config.UnmuteTimers.Add(new()
|
||||
{
|
||||
UserId = user.Id,
|
||||
UnmuteAt = DateTime.UtcNow + after
|
||||
}); // add teh unmute timer to the database
|
||||
uow.SaveChanges();
|
||||
var unmuteAt = DateTime.UtcNow + after;
|
||||
await uow.GetTable<UnmuteTimer>()
|
||||
.InsertAsync(() => new()
|
||||
{
|
||||
GuildId = user.GuildId,
|
||||
UserId = user.Id,
|
||||
UnmuteAt = unmuteAt
|
||||
});
|
||||
}
|
||||
|
||||
StartUn_Timer(user.GuildId, user.Id, after, TimerType.Mute); // start the timer
|
||||
|
@ -362,39 +303,20 @@ public class MuteService : IEService
|
|||
await guild.AddBanAsync(userId, pruneDays, reason);
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var config = uow.GuildConfigsForId(guild.Id, set => set.Include(x => x.UnbanTimer));
|
||||
config.UnbanTimer.Add(new()
|
||||
{
|
||||
UserId = userId,
|
||||
UnbanAt = DateTime.UtcNow + after
|
||||
}); // add teh unmute timer to the database
|
||||
await uow.SaveChangesAsync();
|
||||
var unbanAt = DateTime.UtcNow + after;
|
||||
await uow.GetTable<UnbanTimer>()
|
||||
.InsertAsync(() => new()
|
||||
{
|
||||
GuildId = guild.Id,
|
||||
UserId = userId,
|
||||
UnbanAt = unbanAt
|
||||
});
|
||||
}
|
||||
|
||||
StartUn_Timer(guild.Id, userId, after, TimerType.Ban); // start the timer
|
||||
}
|
||||
|
||||
public async Task TimedRole(
|
||||
IGuildUser user,
|
||||
TimeSpan after,
|
||||
string reason,
|
||||
IRole role)
|
||||
{
|
||||
await user.AddRoleAsync(role);
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var config = uow.GuildConfigsForId(user.GuildId, set => set.Include(x => x.UnroleTimer));
|
||||
config.UnroleTimer.Add(new()
|
||||
{
|
||||
UserId = user.Id,
|
||||
UnbanAt = DateTime.UtcNow + after,
|
||||
RoleId = role.Id
|
||||
}); // add teh unmute timer to the database
|
||||
uow.SaveChanges();
|
||||
}
|
||||
|
||||
StartUn_Timer(user.GuildId, user.Id, after, TimerType.AddRole, role.Id); // start the timer
|
||||
}
|
||||
// todo unrole timers -> temprole
|
||||
|
||||
public void StartUn_Timer(
|
||||
ulong guildId,
|
||||
|
@ -408,56 +330,56 @@ public class MuteService : IEService
|
|||
|
||||
//unmute timer to be added
|
||||
var toAdd = new Timer(async _ =>
|
||||
{
|
||||
if (type == TimerType.Ban)
|
||||
{
|
||||
if (type == TimerType.Ban)
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
RemoveTimerFromDb(guildId, userId, type);
|
||||
StopTimer(guildId, userId, type);
|
||||
var guild = _client.GetGuild(guildId); // load the guild
|
||||
if (guild is not null)
|
||||
await guild.RemoveBanAsync(userId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Warning(ex, "Couldn't unban user {UserId} in guild {GuildId}", userId, guildId);
|
||||
}
|
||||
await RemoveTimerFromDb(guildId, userId, type);
|
||||
StopTimer(guildId, userId, type);
|
||||
var guild = _client.GetGuild(guildId); // load the guild
|
||||
if (guild is not null)
|
||||
await guild.RemoveBanAsync(userId);
|
||||
}
|
||||
else if (type == TimerType.AddRole)
|
||||
catch (Exception ex)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (roleId is null)
|
||||
return;
|
||||
Log.Warning(ex, "Couldn't unban user {UserId} in guild {GuildId}", userId, guildId);
|
||||
}
|
||||
}
|
||||
else if (type == TimerType.AddRole)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (roleId is null)
|
||||
return;
|
||||
|
||||
RemoveTimerFromDb(guildId, userId, type);
|
||||
StopTimer(guildId, userId, type);
|
||||
var guild = _client.GetGuild(guildId);
|
||||
var user = guild?.GetUser(userId);
|
||||
var role = guild?.GetRole(roleId.Value);
|
||||
if (guild is not null && user is not null && user.Roles.Contains(role))
|
||||
await user.RemoveRoleAsync(role);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Warning(ex, "Couldn't remove role from user {UserId} in guild {GuildId}", userId, guildId);
|
||||
}
|
||||
await RemoveTimerFromDb(guildId, userId, type);
|
||||
StopTimer(guildId, userId, type);
|
||||
var guild = _client.GetGuild(guildId);
|
||||
var user = guild?.GetUser(userId);
|
||||
var role = guild?.GetRole(roleId.Value);
|
||||
if (guild is not null && user is not null && user.Roles.Contains(role))
|
||||
await user.RemoveRoleAsync(role);
|
||||
}
|
||||
else
|
||||
catch (Exception ex)
|
||||
{
|
||||
try
|
||||
{
|
||||
// unmute the user, this will also remove the timer from the db
|
||||
await UnmuteUser(guildId, userId, _client.CurrentUser, reason: "Timed mute expired");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
RemoveTimerFromDb(guildId, userId, type); // if unmute errored, just remove unmute from db
|
||||
Log.Warning(ex, "Couldn't unmute user {UserId} in guild {GuildId}", userId, guildId);
|
||||
}
|
||||
Log.Warning(ex, "Couldn't remove role from user {UserId} in guild {GuildId}", userId, guildId);
|
||||
}
|
||||
},
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
// unmute the user, this will also remove the timer from the db
|
||||
await UnmuteUser(guildId, userId, _client.CurrentUser, reason: "Timed mute expired");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await RemoveTimerFromDb(guildId, userId, type); // if unmute errored, just remove unmute from db
|
||||
Log.Warning(ex, "Couldn't unmute user {UserId} in guild {GuildId}", userId, guildId);
|
||||
}
|
||||
}
|
||||
},
|
||||
null,
|
||||
after,
|
||||
Timeout.InfiniteTimeSpan);
|
||||
|
@ -481,23 +403,97 @@ public class MuteService : IEService
|
|||
removed.Change(Timeout.Infinite, Timeout.Infinite);
|
||||
}
|
||||
|
||||
private void RemoveTimerFromDb(ulong guildId, ulong userId, TimerType type)
|
||||
private async Task RemoveTimerFromDb(ulong guildId, ulong userId, TimerType type)
|
||||
{
|
||||
using var uow = _db.GetDbContext();
|
||||
object toDelete;
|
||||
if (type == TimerType.Mute)
|
||||
await using var ctx = _db.GetDbContext();
|
||||
}
|
||||
|
||||
|
||||
// todo update to new way of tracking expiries
|
||||
public async Task OnReadyAsync()
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
var configs = await uow.Set<GuildConfig>()
|
||||
.Where(x => Queries.GuildOnShard(x.GuildId, _shardData.TotalShards, _shardData.ShardId))
|
||||
.ToListAsyncLinqToDB();
|
||||
|
||||
_guildMuteRoles = configs.Where(c => !string.IsNullOrWhiteSpace(c.MuteRoleName))
|
||||
.ToDictionary(c => c.GuildId, c => c.MuteRoleName)
|
||||
.ToConcurrent();
|
||||
|
||||
_mutedUsers = await uow.GetTable<MutedUserId>()
|
||||
.Where(x => Queries.GuildOnShard(x.GuildId, _shardData.TotalShards, _shardData.ShardId))
|
||||
.ToListAsyncLinqToDB()
|
||||
.Fmap(x => x.GroupBy(x => x.GuildId)
|
||||
.ToDictionary(g => g.Key, g => new ConcurrentHashSet<ulong>(g.Select(x => x.UserId)))
|
||||
.ToConcurrent());
|
||||
|
||||
var max = TimeSpan.FromDays(49);
|
||||
|
||||
var unmuteTimers = await uow.GetTable<UnmuteTimer>()
|
||||
.Where(x => Queries.GuildOnShard(x.GuildId, _shardData.TotalShards, _shardData.ShardId))
|
||||
.ToListAsyncLinqToDB();
|
||||
|
||||
var unbanTimers = await uow.GetTable<UnbanTimer>()
|
||||
.Where(x => Queries.GuildOnShard(x.GuildId, _shardData.TotalShards, _shardData.ShardId))
|
||||
.ToListAsyncLinqToDB();
|
||||
|
||||
var unroleTimers = await uow.GetTable<UnroleTimer>()
|
||||
.Where(x => Queries.GuildOnShard(x.GuildId, _shardData.TotalShards, _shardData.ShardId))
|
||||
.ToListAsyncLinqToDB();
|
||||
|
||||
foreach (var conf in configs)
|
||||
{
|
||||
var config = uow.GuildConfigsForId(guildId, set => set.Include(x => x.UnmuteTimers));
|
||||
toDelete = config.UnmuteTimers.FirstOrDefault(x => x.UserId == userId);
|
||||
}
|
||||
else
|
||||
{
|
||||
var config = uow.GuildConfigsForId(guildId, set => set.Include(x => x.UnbanTimer));
|
||||
toDelete = config.UnbanTimer.FirstOrDefault(x => x.UserId == userId);
|
||||
foreach (var x in unmuteTimers)
|
||||
{
|
||||
TimeSpan after;
|
||||
if (x.UnmuteAt - TimeSpan.FromMinutes(2) <= DateTime.UtcNow)
|
||||
{
|
||||
after = TimeSpan.FromMinutes(2);
|
||||
}
|
||||
else
|
||||
{
|
||||
var unmute = x.UnmuteAt - DateTime.UtcNow;
|
||||
after = unmute > max ? max : unmute;
|
||||
}
|
||||
|
||||
StartUn_Timer(conf.GuildId, x.UserId, after, TimerType.Mute);
|
||||
}
|
||||
|
||||
foreach (var x in unbanTimers)
|
||||
{
|
||||
TimeSpan after;
|
||||
if (x.UnbanAt - TimeSpan.FromMinutes(2) <= DateTime.UtcNow)
|
||||
{
|
||||
after = TimeSpan.FromMinutes(2);
|
||||
}
|
||||
else
|
||||
{
|
||||
var unban = x.UnbanAt - DateTime.UtcNow;
|
||||
after = unban > max ? max : unban;
|
||||
}
|
||||
|
||||
StartUn_Timer(conf.GuildId, x.UserId, after, TimerType.Ban);
|
||||
}
|
||||
|
||||
foreach (var x in unroleTimers)
|
||||
{
|
||||
TimeSpan after;
|
||||
if (x.UnbanAt - TimeSpan.FromMinutes(2) <= DateTime.UtcNow)
|
||||
{
|
||||
after = TimeSpan.FromMinutes(2);
|
||||
}
|
||||
else
|
||||
{
|
||||
var unban = x.UnbanAt - DateTime.UtcNow;
|
||||
after = unban > max ? max : unban;
|
||||
}
|
||||
|
||||
StartUn_Timer(conf.GuildId, x.UserId, after, TimerType.AddRole, x.RoleId);
|
||||
}
|
||||
}
|
||||
|
||||
if (toDelete is not null)
|
||||
uow.Remove(toDelete);
|
||||
uow.SaveChanges();
|
||||
_client.UserJoined += Client_UserJoined;
|
||||
}
|
||||
}
|
|
@ -36,7 +36,7 @@ public sealed class NotifyService : IReadyExecutor, INotifySubscriber, IEService
|
|||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
_events = (await uow.GetTable<Notify>()
|
||||
.Where(x => Linq2DbExpressions.GuildOnShard(x.GuildId,
|
||||
.Where(x => Queries.GuildOnShard(x.GuildId,
|
||||
_creds.TotalShards,
|
||||
_client.ShardId))
|
||||
.ToListAsyncLinqToDB())
|
||||
|
@ -224,4 +224,4 @@ public sealed class NotifyService : IReadyExecutor, INotifySubscriber, IEService
|
|||
.Where(x => x.GuildId == guildId && x.Type == nType)
|
||||
.FirstOrDefaultAsyncLinqToDB();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,7 +15,7 @@ public partial class Administration
|
|||
[UserPerm(GuildPerm.Administrator)]
|
||||
public async Task AntiAlt()
|
||||
{
|
||||
if (await _service.TryStopAntiAlt(ctx.Guild.Id))
|
||||
if (await _service.TryStopAntiAltAsync(ctx.Guild.Id))
|
||||
{
|
||||
await Response().Confirm(strs.prot_disable("Anti-Alt")).SendAsync();
|
||||
return;
|
||||
|
@ -71,11 +71,15 @@ public partial class Administration
|
|||
[Cmd]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[UserPerm(GuildPerm.Administrator)]
|
||||
public Task AntiRaid()
|
||||
public async Task AntiRaid()
|
||||
{
|
||||
if (_service.TryStopAntiRaid(ctx.Guild.Id))
|
||||
return Response().Confirm(strs.prot_disable("Anti-Raid")).SendAsync();
|
||||
return Response().Pending(strs.protection_not_running("Anti-Raid")).SendAsync();
|
||||
if (await _service.TryStopAntiRaidAsync(ctx.Guild.Id))
|
||||
{
|
||||
await Response().Confirm(strs.prot_disable("Anti-Raid")).SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
await Response().Pending(strs.protection_not_running("Anti-Raid")).SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
|
@ -147,11 +151,15 @@ public partial class Administration
|
|||
[Cmd]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[UserPerm(GuildPerm.Administrator)]
|
||||
public Task AntiSpam()
|
||||
public async Task AntiSpam()
|
||||
{
|
||||
if (_service.TryStopAntiSpam(ctx.Guild.Id))
|
||||
return Response().Confirm(strs.prot_disable("Anti-Spam")).SendAsync();
|
||||
return Response().Pending(strs.protection_not_running("Anti-Spam")).SendAsync();
|
||||
if (await _service.TryStopAntiSpamAsync(ctx.Guild.Id))
|
||||
{
|
||||
await Response().Confirm(strs.prot_disable("Anti-Spam")).SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
await Response().Pending(strs.protection_not_running("Anti-Spam")).SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
#nullable disable
|
||||
using LinqToDB;
|
||||
using LinqToDB.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using EllieBot.Common.ModuleBehaviors;
|
||||
using EllieBot.Db.Models;
|
||||
using EllieBot.Migrations;
|
||||
using System.Threading.Channels;
|
||||
|
||||
namespace EllieBot.Modules.Administration.Services;
|
||||
|
||||
public class ProtectionService : IEService
|
||||
public class ProtectionService : IReadyExecutor, IEService
|
||||
{
|
||||
public event Func<PunishmentAction, ProtectionType, IGuildUser[], Task> OnAntiProtectionTriggered = delegate
|
||||
{
|
||||
|
@ -23,7 +27,7 @@ public class ProtectionService : IEService
|
|||
private readonly DbService _db;
|
||||
private readonly UserPunishService _punishService;
|
||||
private readonly INotifySubscriber _notifySub;
|
||||
|
||||
private readonly ShardData _shardData;
|
||||
private readonly Channel<PunishQueueItem> _punishUserQueue =
|
||||
Channel.CreateUnbounded<PunishQueueItem>(new()
|
||||
{
|
||||
|
@ -33,41 +37,23 @@ public class ProtectionService : IEService
|
|||
|
||||
public ProtectionService(
|
||||
DiscordSocketClient client,
|
||||
IBot bot,
|
||||
MuteService mute,
|
||||
DbService db,
|
||||
UserPunishService punishService,
|
||||
INotifySubscriber notifySub)
|
||||
INotifySubscriber notifySub,
|
||||
ShardData shardData)
|
||||
{
|
||||
_client = client;
|
||||
_mute = mute;
|
||||
_db = db;
|
||||
_punishService = punishService;
|
||||
_notifySub = notifySub;
|
||||
|
||||
var ids = client.GetGuildIds();
|
||||
using (var uow = db.GetDbContext())
|
||||
{
|
||||
var configs = uow.Set<GuildConfig>()
|
||||
.AsQueryable()
|
||||
.Include(x => x.AntiRaidSetting)
|
||||
.Include(x => x.AntiSpamSetting)
|
||||
.ThenInclude(x => x.IgnoredChannels)
|
||||
.Include(x => x.AntiAltSetting)
|
||||
.Where(x => ids.Contains(x.GuildId))
|
||||
.ToList();
|
||||
|
||||
foreach (var gc in configs)
|
||||
Initialize(gc);
|
||||
}
|
||||
_shardData = shardData;
|
||||
|
||||
_client.MessageReceived += HandleAntiSpam;
|
||||
_client.UserJoined += HandleUserJoined;
|
||||
|
||||
bot.JoinedGuild += _bot_JoinedGuild;
|
||||
_client.LeftGuild += _client_LeftGuild;
|
||||
|
||||
_ = Task.Run(RunQueue);
|
||||
}
|
||||
|
||||
private async Task RunQueue()
|
||||
|
@ -103,53 +89,13 @@ public class ProtectionService : IEService
|
|||
{
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
TryStopAntiRaid(guild.Id);
|
||||
TryStopAntiSpam(guild.Id);
|
||||
await TryStopAntiAlt(guild.Id);
|
||||
await TryStopAntiRaidAsync(guild.Id);
|
||||
await TryStopAntiSpamAsync(guild.Id);
|
||||
await TryStopAntiAltAsync(guild.Id);
|
||||
});
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Task _bot_JoinedGuild(GuildConfig gc)
|
||||
{
|
||||
using var uow = _db.GetDbContext();
|
||||
var gcWithData = uow.GuildConfigsForId(gc.GuildId,
|
||||
set => set.Include(x => x.AntiRaidSetting)
|
||||
.Include(x => x.AntiAltSetting)
|
||||
.Include(x => x.AntiSpamSetting)
|
||||
.ThenInclude(x => x.IgnoredChannels));
|
||||
|
||||
Initialize(gcWithData);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void Initialize(GuildConfig gc)
|
||||
{
|
||||
var raid = gc.AntiRaidSetting;
|
||||
var spam = gc.AntiSpamSetting;
|
||||
|
||||
if (raid is not null)
|
||||
{
|
||||
var raidStats = new AntiRaidStats
|
||||
{
|
||||
AntiRaidSettings = raid
|
||||
};
|
||||
_antiRaidGuilds[gc.GuildId] = raidStats;
|
||||
}
|
||||
|
||||
if (spam is not null)
|
||||
{
|
||||
_antiSpamGuilds[gc.GuildId] = new()
|
||||
{
|
||||
AntiSpamSettings = spam
|
||||
};
|
||||
}
|
||||
|
||||
var alt = gc.AntiAltSetting;
|
||||
if (alt is not null)
|
||||
_antiAltGuilds[gc.GuildId] = new(alt);
|
||||
}
|
||||
|
||||
private Task HandleUserJoined(SocketGuildUser user)
|
||||
{
|
||||
if (user.IsBot)
|
||||
|
@ -201,7 +147,8 @@ public class ProtectionService : IEService
|
|||
|
||||
await PunishUsers(settings.Action, ProtectionType.Raiding, settings.PunishDuration, null, users);
|
||||
await _notifySub.NotifyAsync(
|
||||
new ProtectionNotifyModel(user.Guild.Id, ProtectionType.Raiding, users[0].Id));
|
||||
new ProtectionNotifyModel(user.Guild.Id, ProtectionType.Raiding, users[0].Id)
|
||||
);
|
||||
}
|
||||
|
||||
await Task.Delay(1000 * stats.AntiRaidSettings.Seconds);
|
||||
|
@ -327,39 +274,36 @@ public class ProtectionService : IEService
|
|||
_antiRaidGuilds.AddOrUpdate(guildId, stats, (_, _) => stats);
|
||||
|
||||
await using var uow = _db.GetDbContext();
|
||||
var gc = uow.GuildConfigsForId(guildId, set => set.Include(x => x.AntiRaidSetting));
|
||||
|
||||
gc.AntiRaidSetting = stats.AntiRaidSettings;
|
||||
await uow.SaveChangesAsync();
|
||||
// todo finish this
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
public bool TryStopAntiRaid(ulong guildId)
|
||||
public async Task<bool> TryStopAntiRaidAsync(ulong guildId)
|
||||
{
|
||||
if (_antiRaidGuilds.TryRemove(guildId, out _))
|
||||
{
|
||||
using var uow = _db.GetDbContext();
|
||||
var gc = uow.GuildConfigsForId(guildId, set => set.Include(x => x.AntiRaidSetting));
|
||||
await uow.GetTable<AntiRaidSetting>()
|
||||
.Where(x => x.GuildId == guildId)
|
||||
.DeleteAsync();
|
||||
|
||||
gc.AntiRaidSetting = null;
|
||||
uow.SaveChanges();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryStopAntiSpam(ulong guildId)
|
||||
public async Task<bool> TryStopAntiSpamAsync(ulong guildId)
|
||||
{
|
||||
if (_antiSpamGuilds.TryRemove(guildId, out _))
|
||||
{
|
||||
using var uow = _db.GetDbContext();
|
||||
var gc = uow.GuildConfigsForId(guildId,
|
||||
set => set.Include(x => x.AntiSpamSetting).ThenInclude(x => x.IgnoredChannels));
|
||||
await uow.GetTable<AntiSpamSetting>()
|
||||
.Where(x => x.GuildId == guildId)
|
||||
.DeleteAsync();
|
||||
|
||||
gc.AntiSpamSetting = null;
|
||||
uow.SaveChanges();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -399,19 +343,26 @@ public class ProtectionService : IEService
|
|||
});
|
||||
|
||||
await using var uow = _db.GetDbContext();
|
||||
var gc = uow.GuildConfigsForId(guildId, set => set.Include(x => x.AntiSpamSetting));
|
||||
await uow.GetTable<AntiSpamSetting>()
|
||||
.InsertOrUpdateAsync(() => new()
|
||||
{
|
||||
GuildId = guildId,
|
||||
Action = stats.AntiSpamSettings.Action,
|
||||
MessageThreshold = stats.AntiSpamSettings.MessageThreshold,
|
||||
MuteTime = stats.AntiSpamSettings.MuteTime,
|
||||
RoleId = stats.AntiSpamSettings.RoleId
|
||||
}, (old) => new()
|
||||
{
|
||||
GuildId = guildId,
|
||||
Action = stats.AntiSpamSettings.Action,
|
||||
MessageThreshold = stats.AntiSpamSettings.MessageThreshold,
|
||||
MuteTime = stats.AntiSpamSettings.MuteTime,
|
||||
RoleId = stats.AntiSpamSettings.RoleId
|
||||
}, () => new()
|
||||
{
|
||||
GuildId = guildId
|
||||
});
|
||||
|
||||
if (gc.AntiSpamSetting is not null)
|
||||
{
|
||||
gc.AntiSpamSetting.Action = stats.AntiSpamSettings.Action;
|
||||
gc.AntiSpamSetting.MessageThreshold = stats.AntiSpamSettings.MessageThreshold;
|
||||
gc.AntiSpamSetting.MuteTime = stats.AntiSpamSettings.MuteTime;
|
||||
gc.AntiSpamSetting.RoleId = stats.AntiSpamSettings.RoleId;
|
||||
}
|
||||
else
|
||||
gc.AntiSpamSetting = stats.AntiSpamSettings;
|
||||
|
||||
await uow.SaveChangesAsync();
|
||||
return stats;
|
||||
}
|
||||
|
||||
|
@ -421,15 +372,16 @@ public class ProtectionService : IEService
|
|||
{
|
||||
ChannelId = channelId
|
||||
};
|
||||
bool added;
|
||||
await using var uow = _db.GetDbContext();
|
||||
var gc = uow.GuildConfigsForId(guildId,
|
||||
set => set.Include(x => x.AntiSpamSetting).ThenInclude(x => x.IgnoredChannels));
|
||||
var spam = gc.AntiSpamSetting;
|
||||
var spam = await uow.GetTable<AntiSpamSetting>()
|
||||
.Include(x => x.IgnoredChannels)
|
||||
.Where(x => x.GuildId == guildId)
|
||||
.FirstOrDefaultAsyncEF();
|
||||
if (spam is null)
|
||||
return null;
|
||||
|
||||
if (spam.IgnoredChannels.Add(obj)) // if adding to db is successful
|
||||
var added = false;
|
||||
if (!spam.IgnoredChannels.Any(x => x.ChannelId == channelId))
|
||||
{
|
||||
if (_antiSpamGuilds.TryGetValue(guildId, out var temp))
|
||||
temp.AntiSpamSettings.IgnoredChannels.Add(obj); // add to local cache
|
||||
|
@ -439,7 +391,9 @@ public class ProtectionService : IEService
|
|||
else
|
||||
{
|
||||
var toRemove = spam.IgnoredChannels.First(x => x.ChannelId == channelId);
|
||||
uow.Set<AntiSpamIgnore>().Remove(toRemove); // remove from db
|
||||
|
||||
uow.Set<AntiSpamIgnore>().Remove(toRemove);
|
||||
|
||||
if (_antiSpamGuilds.TryGetValue(guildId, out var temp))
|
||||
temp.AntiSpamSettings.IgnoredChannels.Remove(toRemove); // remove from local cache
|
||||
|
||||
|
@ -483,28 +437,83 @@ public class ProtectionService : IEService
|
|||
ulong? roleId = null)
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
var gc = uow.GuildConfigsForId(guildId, set => set.Include(x => x.AntiAltSetting));
|
||||
gc.AntiAltSetting = new()
|
||||
|
||||
await uow.GetTable<AntiAltSetting>()
|
||||
.InsertOrUpdateAsync(() => new()
|
||||
{
|
||||
GuildId = guildId,
|
||||
Action = action,
|
||||
ActionDurationMinutes = actionDurationMinutes,
|
||||
MinAge = TimeSpan.FromMinutes(minAgeMinutes),
|
||||
RoleId = roleId
|
||||
}, _ => new()
|
||||
{
|
||||
Action = action,
|
||||
ActionDurationMinutes = actionDurationMinutes,
|
||||
MinAge = TimeSpan.FromMinutes(minAgeMinutes),
|
||||
RoleId = roleId
|
||||
}, () => new()
|
||||
{
|
||||
GuildId = guildId
|
||||
});
|
||||
|
||||
_antiAltGuilds[guildId] = new(new()
|
||||
{
|
||||
GuildId = guildId,
|
||||
Action = action,
|
||||
ActionDurationMinutes = actionDurationMinutes,
|
||||
MinAge = TimeSpan.FromMinutes(minAgeMinutes),
|
||||
RoleId = roleId
|
||||
};
|
||||
|
||||
await uow.SaveChangesAsync();
|
||||
_antiAltGuilds[guildId] = new(gc.AntiAltSetting);
|
||||
});
|
||||
}
|
||||
|
||||
public async Task<bool> TryStopAntiAlt(ulong guildId)
|
||||
public async Task<bool> TryStopAntiAltAsync(ulong guildId)
|
||||
{
|
||||
if (!_antiAltGuilds.TryRemove(guildId, out _))
|
||||
return false;
|
||||
|
||||
await using var uow = _db.GetDbContext();
|
||||
var gc = uow.GuildConfigsForId(guildId, set => set.Include(x => x.AntiAltSetting));
|
||||
gc.AntiAltSetting = null;
|
||||
await uow.SaveChangesAsync();
|
||||
await uow.GetTable<AntiAltSetting>()
|
||||
.Where(x => x.GuildId == guildId)
|
||||
.DeleteAsync();
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task OnReadyAsync()
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
|
||||
var configs = await uow.GetTable<AntiAltSetting>()
|
||||
.Where(x => Queries.GuildOnShard(x.GuildId, _shardData.TotalShards, _shardData.ShardId))
|
||||
.ToListAsyncLinqToDB();
|
||||
|
||||
foreach (var config in configs)
|
||||
_antiAltGuilds[config.GuildId] = new(config);
|
||||
|
||||
var raidConfigs = await uow.GetTable<AntiRaidSetting>()
|
||||
.Where(x => Queries.GuildOnShard(x.GuildId, _shardData.TotalShards, _shardData.ShardId))
|
||||
.ToListAsyncLinqToDB();
|
||||
|
||||
foreach (var config in raidConfigs)
|
||||
{
|
||||
_antiRaidGuilds[config.GuildId] = new()
|
||||
{
|
||||
AntiRaidSettings = config,
|
||||
};
|
||||
}
|
||||
|
||||
var spamConfigs = await uow.GetTable<AntiSpamSetting>()
|
||||
.Where(x => Queries.GuildOnShard(x.GuildId, _shardData.TotalShards, _shardData.ShardId))
|
||||
.ToListAsyncLinqToDB();
|
||||
|
||||
foreach (var config in spamConfigs)
|
||||
{
|
||||
_antiSpamGuilds[config.GuildId] = new()
|
||||
{
|
||||
AntiSpamSettings = config,
|
||||
};
|
||||
}
|
||||
|
||||
await RunQueue();
|
||||
}
|
||||
}
|
|
@ -33,7 +33,7 @@ public sealed class ReactionRolesService : IReadyExecutor, IEService, IReactionR
|
|||
await using var uow = _db.GetDbContext();
|
||||
var reros = await uow.GetTable<ReactionRoleV2>()
|
||||
.Where(
|
||||
x => Linq2DbExpressions.GuildOnShard(x.GuildId, _creds.TotalShards, _client.ShardId))
|
||||
x => Queries.GuildOnShard(x.GuildId, _creds.TotalShards, _client.ShardId))
|
||||
.ToListAsyncLinqToDB();
|
||||
|
||||
foreach (var group in reros.GroupBy(x => x.MessageId))
|
||||
|
|
|
@ -221,7 +221,7 @@ public partial class Administration
|
|||
[RequireContext(ContextType.Guild)]
|
||||
[UserPerm(GuildPerm.Administrator)]
|
||||
[BotPerm(GuildPerm.ManageRoles)]
|
||||
public async Task TempRole(ParsedTimespan timespan, IUser user, [Leftover] IRole role)
|
||||
public async Task TempRole(ParsedTimespan timespan, IGuildUser user, [Leftover] IRole role)
|
||||
{
|
||||
if (!await CheckRoleHierarchy(role))
|
||||
{
|
||||
|
@ -231,6 +231,7 @@ public partial class Administration
|
|||
return;
|
||||
}
|
||||
|
||||
await user.AddRoleAsync(role);
|
||||
await _tempRoleService.AddTempRoleAsync(ctx.Guild.Id, role.Id, user.Id, timespan.Time);
|
||||
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ public sealed class StickyRolesService : IEService, IReadyExecutor
|
|||
_stickyRoles = (await ctx
|
||||
.Set<GuildConfig>()
|
||||
.ToLinqToDBTable()
|
||||
.Where(x => Linq2DbExpressions.GuildOnShard(x.GuildId,
|
||||
.Where(x => Queries.GuildOnShard(x.GuildId,
|
||||
_creds.TotalShards,
|
||||
_client.ShardId))
|
||||
.Where(x => x.StickyRoles)
|
||||
|
|
|
@ -72,7 +72,7 @@ public class TempRoleService : IReadyExecutor, IEService
|
|||
_tcs = new(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var latest = await _db.GetDbContext()
|
||||
.GetTable<TempRole>()
|
||||
.Where(x => Linq2DbExpressions.GuildOnShard(x.GuildId,
|
||||
.Where(x => Queries.GuildOnShard(x.GuildId,
|
||||
_creds.TotalShards,
|
||||
_client.ShardId))
|
||||
.OrderBy(x => x.ExpiresAt)
|
||||
|
@ -93,7 +93,7 @@ public class TempRoleService : IReadyExecutor, IEService
|
|||
|
||||
var deleted = await _db.GetDbContext()
|
||||
.GetTable<TempRole>()
|
||||
.Where(x => Linq2DbExpressions.GuildOnShard(x.GuildId,
|
||||
.Where(x => Queries.GuildOnShard(x.GuildId,
|
||||
_creds.TotalShards,
|
||||
_client.ShardId)
|
||||
&& x.ExpiresAt <= now)
|
||||
|
|
|
@ -216,7 +216,8 @@ public class SelfAssignedRolesService : IEService, IReadyExecutor
|
|||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
var guilds = await uow.GetTable<SarAutoDelete>()
|
||||
.Where(x => x.IsEnabled && Linq2DbExpressions.GuildOnShard(x.GuildId, _creds.TotalShards, _client.ShardId))
|
||||
.Where(x => x.IsEnabled
|
||||
&& Queries.GuildOnShard(x.GuildId, _creds.TotalShards, _client.ShardId))
|
||||
.Select(x => x.GuildId)
|
||||
.ToListAsyncLinqToDB();
|
||||
|
||||
|
@ -309,7 +310,6 @@ public sealed class SarAssignerService : IEService, IReadyExecutor
|
|||
{
|
||||
await _channel.Writer.WriteAsync(item);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public sealed class SarAssignerDataItem
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#nullable disable
|
||||
using LinqToDB.EntityFrameworkCore;
|
||||
using EllieBot.Db.Models;
|
||||
using EllieBot.Common.ModuleBehaviors;
|
||||
|
||||
|
@ -6,40 +7,30 @@ namespace EllieBot.Modules.Administration.Services;
|
|||
|
||||
public sealed class GuildTimezoneService : ITimezoneService, IReadyExecutor, IEService
|
||||
{
|
||||
private readonly ConcurrentDictionary<ulong, TimeZoneInfo> _timezones;
|
||||
private ConcurrentDictionary<ulong, TimeZoneInfo> _timezones;
|
||||
private readonly DbService _db;
|
||||
private readonly IReplacementPatternStore _repStore;
|
||||
private readonly ShardData _shardData;
|
||||
private readonly DiscordSocketClient _client;
|
||||
|
||||
public GuildTimezoneService(IBot bot, DbService db, IReplacementPatternStore repStore)
|
||||
public GuildTimezoneService(
|
||||
DbService db,
|
||||
IReplacementPatternStore repStore,
|
||||
ShardData shardData,
|
||||
DiscordSocketClient client)
|
||||
{
|
||||
_timezones = bot.AllGuildConfigs.Select(GetTimzezoneTuple)
|
||||
.Where(x => x.Timezone is not null)
|
||||
.ToDictionary(x => x.GuildId, x => x.Timezone)
|
||||
.ToConcurrent();
|
||||
|
||||
_db = db;
|
||||
_repStore = repStore;
|
||||
|
||||
bot.JoinedGuild += Bot_JoinedGuild;
|
||||
_shardData = shardData;
|
||||
_client = client;
|
||||
}
|
||||
|
||||
private Task Bot_JoinedGuild(GuildConfig arg)
|
||||
{
|
||||
var (guildId, tz) = GetTimzezoneTuple(arg);
|
||||
if (tz is not null)
|
||||
_timezones.TryAdd(guildId, tz);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private static (ulong GuildId, TimeZoneInfo Timezone) GetTimzezoneTuple(GuildConfig x)
|
||||
private static (ulong GuildId, TimeZoneInfo Timezone) GetTimezoneTuple(GuildConfig x)
|
||||
{
|
||||
TimeZoneInfo tz;
|
||||
try
|
||||
{
|
||||
if (x.TimeZoneId is null)
|
||||
tz = null;
|
||||
else
|
||||
tz = TimeZoneInfo.FindSystemTimeZoneById(x.TimeZoneId);
|
||||
tz = x.TimeZoneId is null ? null : TimeZoneInfo.FindSystemTimeZoneById(x.TimeZoneId);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -74,9 +65,18 @@ public sealed class GuildTimezoneService : ITimezoneService, IReadyExecutor, IES
|
|||
public TimeZoneInfo GetTimeZoneOrUtc(ulong? guildId)
|
||||
=> GetTimeZoneOrDefault(guildId) ?? TimeZoneInfo.Utc;
|
||||
|
||||
public Task OnReadyAsync()
|
||||
public async Task OnReadyAsync()
|
||||
{
|
||||
_repStore.Register("%server.time%",
|
||||
await using var uow = _db.GetDbContext();
|
||||
_timezones = await uow.GetTable<GuildConfig>()
|
||||
.Where(x => Queries.GuildOnShard(x.GuildId, _shardData.TotalShards, _shardData.ShardId))
|
||||
.ToListAsyncLinqToDB()
|
||||
.Fmap(x => x
|
||||
.Select(GetTimezoneTuple)
|
||||
.ToDictionary(x => x.GuildId, x => x.Timezone)
|
||||
.ToConcurrent());
|
||||
|
||||
await _repStore.Register("%server.time%",
|
||||
(IGuild g) =>
|
||||
{
|
||||
var to = TimeZoneInfo.Local;
|
||||
|
@ -88,7 +88,5 @@ public sealed class GuildTimezoneService : ITimezoneService, IReadyExecutor, IES
|
|||
return TimeZoneInfo.ConvertTime(DateTime.UtcNow, TimeZoneInfo.Utc, to).ToString("HH:mm ")
|
||||
+ to.StandardName.GetInitials();
|
||||
});
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
|
@ -16,6 +16,7 @@ public class UserPunishService : IEService, IReadyExecutor
|
|||
private readonly BotConfigService _bcs;
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly IReplacementService _repSvc;
|
||||
private readonly TempRoleService _tempRoleService;
|
||||
|
||||
public event Func<Warning, Task> OnUserWarned = static delegate { return Task.CompletedTask; };
|
||||
|
||||
|
@ -25,7 +26,8 @@ public class UserPunishService : IEService, IReadyExecutor
|
|||
BlacklistService blacklistService,
|
||||
BotConfigService bcs,
|
||||
DiscordSocketClient client,
|
||||
IReplacementService repSvc)
|
||||
IReplacementService repSvc,
|
||||
TempRoleService tempRoleService)
|
||||
{
|
||||
_mute = mute;
|
||||
_db = db;
|
||||
|
@ -33,6 +35,7 @@ public class UserPunishService : IEService, IReadyExecutor
|
|||
_bcs = bcs;
|
||||
_client = client;
|
||||
_repSvc = repSvc;
|
||||
_tempRoleService = tempRoleService;
|
||||
}
|
||||
|
||||
public async Task OnReadyAsync()
|
||||
|
@ -188,10 +191,14 @@ public class UserPunishService : IEService, IReadyExecutor
|
|||
var role = guild.GetRole(roleId.Value);
|
||||
if (role is not null)
|
||||
{
|
||||
if (minutes == 0)
|
||||
await user.AddRoleAsync(role);
|
||||
else
|
||||
await _mute.TimedRole(user, TimeSpan.FromMinutes(minutes), reason, role);
|
||||
await user.AddRoleAsync(role);
|
||||
if (minutes != 0)
|
||||
{
|
||||
await _tempRoleService.AddTempRoleAsync(guild.Id,
|
||||
role.Id,
|
||||
user.Id,
|
||||
TimeSpan.FromMinutes(minutes));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -233,7 +240,7 @@ public class UserPunishService : IEService, IReadyExecutor
|
|||
case PunishmentAction.RemoveRoles:
|
||||
return botUser.GuildPermissions.ManageRoles;
|
||||
case PunishmentAction.ChatMute:
|
||||
return botUser.GuildPermissions.ManageRoles; // adds ellie-mute role
|
||||
return botUser.GuildPermissions.ManageRoles; // adds nadeko-mute role
|
||||
case PunishmentAction.VoiceMute:
|
||||
return botUser.GuildPermissions.MuteMembers;
|
||||
case PunishmentAction.AddRole:
|
||||
|
|
|
@ -1,109 +1,95 @@
|
|||
#nullable disable
|
||||
using LinqToDB.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using EllieBot.Common.ModuleBehaviors;
|
||||
using EllieBot.Db.Models;
|
||||
|
||||
namespace EllieBot.Modules.Administration.Services;
|
||||
|
||||
public class VcRoleService : IEService
|
||||
public class VcRoleService : IEService, IReadyExecutor
|
||||
{
|
||||
public ConcurrentDictionary<ulong, ConcurrentDictionary<ulong, IRole>> VcRoles { get; }
|
||||
public ConcurrentDictionary<ulong, System.Collections.Concurrent.ConcurrentQueue<(bool, IGuildUser, IRole)>> ToAssign { get; }
|
||||
private readonly DbService _db;
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly IBot _bot;
|
||||
private readonly ShardData _shardData;
|
||||
|
||||
public VcRoleService(DiscordSocketClient client, IBot bot, DbService db)
|
||||
public VcRoleService(DiscordSocketClient client, IBot bot, DbService db, ShardData shardData)
|
||||
{
|
||||
_db = db;
|
||||
_client = client;
|
||||
_bot = bot;
|
||||
_shardData = shardData;
|
||||
|
||||
_client.UserVoiceStateUpdated += ClientOnUserVoiceStateUpdated;
|
||||
VcRoles = new();
|
||||
ToAssign = new();
|
||||
|
||||
using (var uow = db.GetDbContext())
|
||||
{
|
||||
var guildIds = client.Guilds.Select(x => x.Id).ToList();
|
||||
uow.Set<GuildConfig>()
|
||||
.AsQueryable()
|
||||
.Include(x => x.VcRoleInfos)
|
||||
.Where(x => guildIds.Contains(x.GuildId))
|
||||
.AsEnumerable()
|
||||
.Select(InitializeVcRole)
|
||||
.WhenAll();
|
||||
}
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
Task Selector(System.Collections.Concurrent.ConcurrentQueue<(bool, IGuildUser, IRole)> queue)
|
||||
{
|
||||
return Task.Run(async () =>
|
||||
{
|
||||
while (queue.TryDequeue(out var item))
|
||||
{
|
||||
var (add, user, role) = item;
|
||||
|
||||
try
|
||||
{
|
||||
if (add)
|
||||
{
|
||||
if (!user.RoleIds.Contains(role.Id))
|
||||
await user.AddRoleAsync(role);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (user.RoleIds.Contains(role.Id))
|
||||
await user.RemoveRoleAsync(role);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
await Task.Delay(250);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
await ToAssign.Values.Select(Selector).Append(Task.Delay(1000)).WhenAll();
|
||||
}
|
||||
});
|
||||
|
||||
_client.LeftGuild += _client_LeftGuild;
|
||||
bot.JoinedGuild += Bot_JoinedGuild;
|
||||
}
|
||||
|
||||
private Task Bot_JoinedGuild(GuildConfig arg)
|
||||
public async Task OnReadyAsync()
|
||||
{
|
||||
// includeall no longer loads vcrole
|
||||
// need to load new guildconfig with vc role included
|
||||
IEnumerable<IGrouping<ulong, VcRoleInfo>> vcRoles;
|
||||
using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var configWithVcRole = uow.GuildConfigsForId(arg.GuildId, set => set.Include(x => x.VcRoleInfos));
|
||||
_ = InitializeVcRole(configWithVcRole);
|
||||
vcRoles = await uow.GetTable<VcRoleInfo>()
|
||||
.AsQueryable()
|
||||
.Where(x => Queries.GuildOnShard(x.GuildId, _shardData.TotalShards, _shardData.ShardId))
|
||||
.ToListAsync()
|
||||
.Fmap(x => x.GroupBy(x => x.GuildId));
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
await vcRoles.Select(x => InitializeVcRole(x.Key, x.ToList())).WhenAll();
|
||||
|
||||
|
||||
_client.UserVoiceStateUpdated += ClientOnUserVoiceStateUpdated;
|
||||
|
||||
while (true)
|
||||
{
|
||||
Task Selector(System.Collections.Concurrent.ConcurrentQueue<(bool, IGuildUser, IRole)> queue)
|
||||
{
|
||||
return Task.Run(async () =>
|
||||
{
|
||||
while (queue.TryDequeue(out var item))
|
||||
{
|
||||
var (add, user, role) = item;
|
||||
|
||||
try
|
||||
{
|
||||
if (add)
|
||||
{
|
||||
if (!user.RoleIds.Contains(role.Id))
|
||||
await user.AddRoleAsync(role);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (user.RoleIds.Contains(role.Id))
|
||||
await user.RemoveRoleAsync(role);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
await Task.Delay(250);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
await ToAssign.Values.Select(Selector).Append(Task.Delay(1000)).WhenAll();
|
||||
}
|
||||
}
|
||||
|
||||
private Task _client_LeftGuild(SocketGuild arg)
|
||||
private async Task InitializeVcRole(ulong guildId, IReadOnlyList<VcRoleInfo> confs)
|
||||
{
|
||||
VcRoles.TryRemove(arg.Id, out _);
|
||||
ToAssign.TryRemove(arg.Id, out _);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task InitializeVcRole(GuildConfig gconf)
|
||||
{
|
||||
var g = _client.GetGuild(gconf.GuildId);
|
||||
var g = _client.GetGuild(guildId);
|
||||
if (g is null)
|
||||
return;
|
||||
|
||||
var infos = new ConcurrentDictionary<ulong, IRole>();
|
||||
var missingRoles = new List<VcRoleInfo>();
|
||||
VcRoles.AddOrUpdate(gconf.GuildId, infos, delegate { return infos; });
|
||||
foreach (var ri in gconf.VcRoleInfos)
|
||||
VcRoles.AddOrUpdate(guildId, infos, delegate
|
||||
{ return infos; });
|
||||
foreach (var ri in confs)
|
||||
{
|
||||
var role = g.GetRole(ri.RoleId);
|
||||
if (role is null)
|
||||
|
@ -120,7 +106,7 @@ public class VcRoleService : IEService
|
|||
await using var uow = _db.GetDbContext();
|
||||
uow.RemoveRange(missingRoles);
|
||||
await uow.SaveChangesAsync();
|
||||
|
||||
|
||||
Log.Warning("Removed {MissingRoleCount} missing roles from {ServiceName}",
|
||||
missingRoles.Count,
|
||||
nameof(VcRoleService));
|
||||
|
@ -135,11 +121,11 @@ public class VcRoleService : IEService
|
|||
|
||||
guildVcRoles.AddOrUpdate(vcId, role, (_, _) => role);
|
||||
using var uow = _db.GetDbContext();
|
||||
var conf = uow.GuildConfigsForId(guildId, set => set.Include(x => x.VcRoleInfos));
|
||||
var toDelete = conf.VcRoleInfos.FirstOrDefault(x => x.VoiceChannelId == vcId); // remove old one
|
||||
var toDelete = uow.Set<VcRoleInfo>()
|
||||
.FirstOrDefault(x => x.VoiceChannelId == vcId); // remove old one
|
||||
if (toDelete is not null)
|
||||
uow.Remove(toDelete);
|
||||
conf.VcRoleInfos.Add(new()
|
||||
uow.Set<VcRoleInfo>().Add(new()
|
||||
{
|
||||
VoiceChannelId = vcId,
|
||||
RoleId = role.Id
|
||||
|
@ -156,8 +142,7 @@ public class VcRoleService : IEService
|
|||
return false;
|
||||
|
||||
using var uow = _db.GetDbContext();
|
||||
var conf = uow.GuildConfigsForId(guildId, set => set.Include(x => x.VcRoleInfos));
|
||||
var toRemove = conf.VcRoleInfos.Where(x => x.VoiceChannelId == vcId).ToList();
|
||||
var toRemove = uow.Set<VcRoleInfo>().Where(x => x.VoiceChannelId == vcId).ToList();
|
||||
uow.RemoveRange(toRemove);
|
||||
uow.SaveChanges();
|
||||
|
||||
|
|
|
@ -77,6 +77,7 @@ public sealed class EllieExpressionsService : IExecOnMessage, IReadyExecutor
|
|||
private bool ready;
|
||||
private ConcurrentHashSet<ulong> _disabledGlobalExpressionGuilds;
|
||||
private readonly PermissionService _pc;
|
||||
private readonly ShardData _shardData;
|
||||
|
||||
public EllieExpressionsService(
|
||||
DbService db,
|
||||
|
@ -87,7 +88,8 @@ public sealed class EllieExpressionsService : IExecOnMessage, IReadyExecutor
|
|||
IMessageSenderService sender,
|
||||
IReplacementService repSvc,
|
||||
IPermissionChecker permChecker,
|
||||
PermissionService pc)
|
||||
PermissionService pc,
|
||||
ShardData shardData)
|
||||
{
|
||||
_db = db;
|
||||
_client = client;
|
||||
|
@ -98,6 +100,7 @@ public sealed class EllieExpressionsService : IExecOnMessage, IReadyExecutor
|
|||
_repSvc = repSvc;
|
||||
_permChecker = permChecker;
|
||||
_pc = pc;
|
||||
_shardData = shardData;
|
||||
_rng = new EllieRandom();
|
||||
|
||||
_pubSub.Sub(_exprsReloadedKey, OnExprsShouldReload);
|
||||
|
@ -105,26 +108,28 @@ public sealed class EllieExpressionsService : IExecOnMessage, IReadyExecutor
|
|||
pubSub.Sub(_gexprDeletedkey, OnGexprDeleted);
|
||||
pubSub.Sub(_gexprEditedKey, OnGexprEdited);
|
||||
|
||||
bot.JoinedGuild += OnJoinedGuild;
|
||||
_client.LeftGuild += OnLeftGuild;
|
||||
_client.JoinedGuild += OnJoinedGuild;
|
||||
}
|
||||
|
||||
private async Task ReloadInternal(IReadOnlyList<ulong> allGuildIds)
|
||||
private async Task ReloadInternal()
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
var guildItems = await uow.Set<EllieExpression>()
|
||||
var guildItems = await uow.GetTable<EllieExpression>()
|
||||
.AsNoTracking()
|
||||
.Where(x => allGuildIds.Contains(x.GuildId.Value))
|
||||
.ToListAsync();
|
||||
.Where(x => x.GuildId != null
|
||||
&& Queries.GuildOnShard(x.GuildId.Value,
|
||||
_shardData.TotalShards,
|
||||
_shardData.ShardId))
|
||||
.ToListAsyncLinqToDB();
|
||||
|
||||
newguildExpressions = guildItems.GroupBy(k => k.GuildId!.Value)
|
||||
.ToDictionary(g => g.Key,
|
||||
g => g.Select(x =>
|
||||
{
|
||||
x.Trigger = x.Trigger.Replace(MENTION_PH,
|
||||
_client.CurrentUser.Mention);
|
||||
return x;
|
||||
})
|
||||
{
|
||||
x.Trigger = x.Trigger.Replace(MENTION_PH,
|
||||
_client.CurrentUser.Mention);
|
||||
return x;
|
||||
})
|
||||
.ToArray())
|
||||
.ToConcurrent();
|
||||
|
||||
|
@ -635,10 +640,12 @@ public sealed class EllieExpressionsService : IExecOnMessage, IReadyExecutor
|
|||
#region Event Handlers
|
||||
|
||||
public async Task OnReadyAsync()
|
||||
=> await OnExprsShouldReload(true);
|
||||
{
|
||||
await OnExprsShouldReload(true);
|
||||
}
|
||||
|
||||
private ValueTask OnExprsShouldReload(bool _)
|
||||
=> new(ReloadInternal(_bot.GetCurrentGuildIds()));
|
||||
=> new(ReloadInternal());
|
||||
|
||||
private ValueTask OnGexprAdded(EllieExpression c)
|
||||
{
|
||||
|
@ -692,21 +699,13 @@ public sealed class EllieExpressionsService : IExecOnMessage, IReadyExecutor
|
|||
|
||||
#region Client Event Handlers
|
||||
|
||||
private Task OnLeftGuild(SocketGuild arg)
|
||||
private Task OnJoinedGuild(SocketGuild g)
|
||||
{
|
||||
newguildExpressions.TryRemove(arg.Id, out _);
|
||||
newguildExpressions[g.Id] = [];
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task OnJoinedGuild(GuildConfig gc)
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
var exprs = await uow.Set<EllieExpression>().AsNoTracking().Where(x => x.GuildId == gc.GuildId).ToArrayAsync();
|
||||
|
||||
newguildExpressions[gc.GuildId] = exprs;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Basic Operations
|
||||
|
|
|
@ -77,7 +77,7 @@ public partial class Gambling
|
|||
#endif
|
||||
public async Task GenCurrency()
|
||||
{
|
||||
var enabled = _service.ToggleCurrencyGeneration(ctx.Guild.Id, ctx.Channel.Id);
|
||||
var enabled = await _service.ToggleCurrencyGeneration(ctx.Guild.Id, ctx.Channel.Id);
|
||||
if (enabled)
|
||||
await Response().Confirm(strs.curgen_enabled).SendAsync();
|
||||
else
|
||||
|
@ -88,14 +88,14 @@ public partial class Gambling
|
|||
[RequireContext(ContextType.Guild)]
|
||||
[UserPerm(GuildPerm.ManageMessages)]
|
||||
[OwnerOnly]
|
||||
public Task GenCurList(int page = 1)
|
||||
public async Task GenCurList(int page = 1)
|
||||
{
|
||||
if (--page < 0)
|
||||
return Task.CompletedTask;
|
||||
return;
|
||||
|
||||
var enabledIn = _service.GetAllGeneratingChannels();
|
||||
var enabledIn = await _service.GetAllGeneratingChannels();
|
||||
|
||||
return Response()
|
||||
await Response()
|
||||
.Paginated()
|
||||
.Items(enabledIn.ToList())
|
||||
.PageSize(9)
|
||||
|
|
|
@ -15,7 +15,7 @@ using Image = SixLabors.ImageSharp.Image;
|
|||
|
||||
namespace EllieBot.Modules.Gambling.Services;
|
||||
|
||||
public class PlantPickService : IEService, IExecNoCommand
|
||||
public class PlantPickService : IEService, IExecNoCommand, IReadyExecutor
|
||||
{
|
||||
//channelId/last generation
|
||||
public ConcurrentDictionary<ulong, long> LastGenerations { get; } = new();
|
||||
|
@ -30,7 +30,7 @@ public class PlantPickService : IEService, IExecNoCommand
|
|||
private readonly GamblingConfigService _gss;
|
||||
private readonly GamblingService _gs;
|
||||
|
||||
private readonly ConcurrentHashSet<ulong> _generationChannels;
|
||||
private ConcurrentHashSet<ulong> _generationChannels;
|
||||
private readonly SemaphoreSlim _pickLock = new(1, 1);
|
||||
|
||||
public PlantPickService(
|
||||
|
@ -57,13 +57,6 @@ public class PlantPickService : IEService, IExecNoCommand
|
|||
|
||||
using var uow = db.GetDbContext();
|
||||
var guildIds = client.Guilds.Select(x => x.Id).ToList();
|
||||
var configs = uow.Set<GuildConfig>()
|
||||
.AsQueryable()
|
||||
.Include(x => x.GenerateCurrencyChannelIds)
|
||||
.Where(x => guildIds.Contains(x.GuildId))
|
||||
.ToList();
|
||||
|
||||
_generationChannels = new(configs.SelectMany(c => c.GenerateCurrencyChannelIds.Select(obj => obj.ChannelId)));
|
||||
}
|
||||
|
||||
public Task ExecOnNoCommandAsync(IGuild guild, IUserMessage msg)
|
||||
|
@ -72,41 +65,49 @@ public class PlantPickService : IEService, IExecNoCommand
|
|||
private string GetText(ulong gid, LocStr str)
|
||||
=> _strings.GetText(str, gid);
|
||||
|
||||
public bool ToggleCurrencyGeneration(ulong gid, ulong cid)
|
||||
public async Task<bool> ToggleCurrencyGeneration(ulong gid, ulong cid)
|
||||
{
|
||||
bool enabled;
|
||||
using var uow = _db.GetDbContext();
|
||||
var guildConfig = uow.GuildConfigsForId(gid, set => set.Include(gc => gc.GenerateCurrencyChannelIds));
|
||||
await using var uow = _db.GetDbContext();
|
||||
|
||||
var toAdd = new GCChannelId
|
||||
if (_generationChannels.Add(cid))
|
||||
{
|
||||
ChannelId = cid
|
||||
};
|
||||
if (!guildConfig.GenerateCurrencyChannelIds.Contains(toAdd))
|
||||
{
|
||||
guildConfig.GenerateCurrencyChannelIds.Add(toAdd);
|
||||
await uow.GetTable<GCChannelId>()
|
||||
.InsertOrUpdateAsync(() => new()
|
||||
{
|
||||
ChannelId = cid,
|
||||
GuildId = gid
|
||||
}, (x) => new()
|
||||
{
|
||||
ChannelId = cid,
|
||||
GuildId = gid
|
||||
}, () => new()
|
||||
{
|
||||
ChannelId = cid,
|
||||
GuildId = gid
|
||||
});
|
||||
|
||||
_generationChannels.Add(cid);
|
||||
enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var toDelete = guildConfig.GenerateCurrencyChannelIds.FirstOrDefault(x => x.Equals(toAdd));
|
||||
if (toDelete is not null)
|
||||
uow.Remove(toDelete);
|
||||
await uow.GetTable<GCChannelId>()
|
||||
.Where(x => x.ChannelId == cid && x.GuildId == gid)
|
||||
.DeleteAsync();
|
||||
|
||||
_generationChannels.TryRemove(cid);
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
uow.SaveChanges();
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public IEnumerable<GuildConfigExtensions.GeneratingChannel> GetAllGeneratingChannels()
|
||||
public async Task<IReadOnlyCollection<GCChannelId>> GetAllGeneratingChannels()
|
||||
{
|
||||
using var uow = _db.GetDbContext();
|
||||
var chs = uow.Set<GuildConfig>().GetGeneratingChannels();
|
||||
return chs;
|
||||
await using var uow = _db.GetDbContext();
|
||||
return await uow.GetTable<GCChannelId>()
|
||||
.ToListAsyncLinqToDB();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -412,4 +413,16 @@ public class PlantPickService : IEService, IExecNoCommand
|
|||
|
||||
return (totalDeletedAmount + amount, deleted.Select(x => x.MessageId).ToArray());
|
||||
}
|
||||
|
||||
public async Task OnReadyAsync()
|
||||
{
|
||||
|
||||
await using var uow = _db.GetDbContext();
|
||||
_generationChannels = (await uow.GetTable<GCChannelId>()
|
||||
.Select(x => x.ChannelId)
|
||||
.ToListAsyncLinqToDB())
|
||||
.ToHashSet()
|
||||
.ToConcurrentSet();
|
||||
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ using EllieBot.Modules.Gambling.Common;
|
|||
using EllieBot.Modules.Gambling.Services;
|
||||
using EllieBot.Db.Models;
|
||||
using EllieBot.Modules.Administration;
|
||||
using LinqToDB.EntityFrameworkCore;
|
||||
|
||||
namespace EllieBot.Modules.Gambling;
|
||||
|
||||
|
@ -30,25 +31,28 @@ public partial class Gambling
|
|||
|
||||
private readonly DbService _db;
|
||||
private readonly ICurrencyService _cs;
|
||||
private readonly EllieRandom _rng;
|
||||
|
||||
public ShopCommands(DbService db, ICurrencyService cs, GamblingConfigService gamblingConf)
|
||||
: base(gamblingConf)
|
||||
{
|
||||
_db = db;
|
||||
_cs = cs;
|
||||
_rng = new EllieRandom();
|
||||
}
|
||||
|
||||
private Task ShopInternalAsync(int page = 0)
|
||||
private async Task ShopInternalAsync(int page = 0)
|
||||
{
|
||||
if (page < 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(page));
|
||||
|
||||
using var uow = _db.GetDbContext();
|
||||
var entries = uow.GuildConfigsForId(ctx.Guild.Id,
|
||||
set => set.Include(x => x.ShopEntries).ThenInclude(x => x.Items))
|
||||
.ShopEntries.ToIndexed();
|
||||
await using var uow = _db.GetDbContext();
|
||||
var entries = await uow.Set<ShopEntry>()
|
||||
.Where(x => x.GuildId == ctx.Guild.Id)
|
||||
.Include(x => x.Items)
|
||||
.ToListAsyncEF();
|
||||
|
||||
return Response()
|
||||
await Response()
|
||||
.Paginated()
|
||||
.Items(entries.ToList())
|
||||
.PageSize(9)
|
||||
|
@ -92,13 +96,15 @@ public partial class Gambling
|
|||
ShopEntry entry;
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var config = uow.GuildConfigsForId(ctx.Guild.Id,
|
||||
set => set.Include(x => x.ShopEntries).ThenInclude(x => x.Items));
|
||||
var entries = new IndexedCollection<ShopEntry>(config.ShopEntries);
|
||||
entry = entries.ElementAtOrDefault(index);
|
||||
uow.SaveChanges();
|
||||
entry = await uow.Set<ShopEntry>()
|
||||
.Where(x => x.GuildId == ctx.Guild.Id)
|
||||
.Include(x => x.Items)
|
||||
.OrderBy(x => x.Id)
|
||||
.Skip(index)
|
||||
.FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
|
||||
if (entry is null)
|
||||
{
|
||||
await Response().Error(strs.shop_item_not_found).SendAsync();
|
||||
|
@ -174,7 +180,7 @@ public partial class Gambling
|
|||
return;
|
||||
}
|
||||
|
||||
var item = entry.Items.ToArray()[new EllieRandom().Next(0, entry.Items.Count)];
|
||||
var item = entry.Items.ToArray()[_rng.Next(0, entry.Items.Count)];
|
||||
|
||||
if (await _cs.RemoveAsync(ctx.User.Id, entry.Price, new("shop", "buy", entry.Type.ToString())))
|
||||
{
|
||||
|
@ -205,15 +211,15 @@ public partial class Gambling
|
|||
await _cs.AddAsync(ctx.User.Id, entry.Price, new("shop", "error-refund", entry.Name));
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var entries = new IndexedCollection<ShopEntry>(uow.GuildConfigsForId(ctx.Guild.Id,
|
||||
set => set.Include(x => x.ShopEntries)
|
||||
.ThenInclude(x => x.Items))
|
||||
.ShopEntries);
|
||||
var entries = new IndexedCollection<ShopEntry>(await uow.Set<ShopEntry>()
|
||||
.Where(x => x.GuildId == ctx.Guild.Id)
|
||||
.Include(x => x.Items)
|
||||
.ToListAsyncEF());
|
||||
entry = entries.ElementAtOrDefault(index);
|
||||
if (entry is not null)
|
||||
{
|
||||
if (entry.Items.Add(item))
|
||||
uow.SaveChanges();
|
||||
await uow.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -224,7 +230,9 @@ public partial class Gambling
|
|||
await Response().Confirm(strs.shop_item_purchase).SendAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
await Response().Error(strs.not_enough(CurrencySign)).SendAsync();
|
||||
}
|
||||
}
|
||||
else if (entry.Type == ShopEntryType.Command)
|
||||
{
|
||||
|
@ -253,7 +261,7 @@ public partial class Gambling
|
|||
.Replace("%you.username%", buyer.Username)
|
||||
.Replace("%you.name%", buyer.GlobalName ?? buyer.Username)
|
||||
.Replace("%you.nick%", buyer.DisplayName);
|
||||
|
||||
|
||||
var eb = CreateEmbed()
|
||||
.WithPendingColor()
|
||||
.WithTitle("Executing shop command")
|
||||
|
@ -328,15 +336,14 @@ public partial class Gambling
|
|||
};
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var entries = new IndexedCollection<ShopEntry>(uow.GuildConfigsForId(ctx.Guild.Id,
|
||||
set => set.Include(x => x.ShopEntries)
|
||||
.ThenInclude(x => x.Items))
|
||||
.ShopEntries)
|
||||
var entries = new IndexedCollection<ShopEntry>(await uow.Set<ShopEntry>()
|
||||
.Where(x => x.GuildId == ctx.Guild.Id)
|
||||
.Include(x => x.Items)
|
||||
.ToListAsyncEF())
|
||||
{
|
||||
entry
|
||||
};
|
||||
uow.GuildConfigsForId(ctx.Guild.Id, set => set).ShopEntries = entries;
|
||||
uow.SaveChanges();
|
||||
await uow.SaveChangesAsync();
|
||||
}
|
||||
|
||||
await Response().Embed(EntryToEmbed(entry).WithTitle(GetText(strs.shop_item_add))).SendAsync();
|
||||
|
@ -360,15 +367,16 @@ public partial class Gambling
|
|||
};
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var entries = new IndexedCollection<ShopEntry>(uow.GuildConfigsForId(ctx.Guild.Id,
|
||||
set => set.Include(x => x.ShopEntries)
|
||||
.ThenInclude(x => x.Items))
|
||||
.ShopEntries)
|
||||
{
|
||||
entry
|
||||
};
|
||||
uow.GuildConfigsForId(ctx.Guild.Id, set => set).ShopEntries = entries;
|
||||
uow.SaveChanges();
|
||||
var entries = await uow.Set<ShopEntry>()
|
||||
.Where(x => x.GuildId == ctx.Guild.Id)
|
||||
.ToListAsyncEF();
|
||||
|
||||
var indexed = new IndexedCollection<ShopEntry>(entries);
|
||||
indexed.Add(entry);
|
||||
|
||||
uow.Add(entry);
|
||||
await uow.SaveChangesAsync();
|
||||
|
||||
}
|
||||
|
||||
await Response().Embed(EntryToEmbed(entry).WithTitle(GetText(strs.shop_item_add))).SendAsync();
|
||||
|
@ -391,11 +399,13 @@ public partial class Gambling
|
|||
var added = false;
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var entries = new IndexedCollection<ShopEntry>(uow.GuildConfigsForId(ctx.Guild.Id,
|
||||
set => set.Include(x => x.ShopEntries)
|
||||
.ThenInclude(x => x.Items))
|
||||
.ShopEntries);
|
||||
entry = entries.ElementAtOrDefault(index);
|
||||
var entries = await uow.Set<ShopEntry>()
|
||||
.Where(x => x.GuildId == ctx.Guild.Id)
|
||||
.Include(x => x.Items)
|
||||
.ToListAsyncEF();
|
||||
|
||||
var indexed = new IndexedCollection<ShopEntry>(entries);
|
||||
entry = indexed.ElementAtOrDefault(index);
|
||||
if (entry is not null && (rightType = entry.Type == ShopEntryType.List))
|
||||
{
|
||||
if (entry.Items.Add(item))
|
||||
|
@ -427,10 +437,12 @@ public partial class Gambling
|
|||
ShopEntry removed;
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var config = uow.GuildConfigsForId(ctx.Guild.Id,
|
||||
set => set.Include(x => x.ShopEntries).ThenInclude(x => x.Items));
|
||||
var items = await uow.Set<ShopEntry>()
|
||||
.Where(x => x.GuildId == ctx.Guild.Id)
|
||||
.Include(x => x.Items)
|
||||
.ToListAsyncLinqToDB();
|
||||
|
||||
var entries = new IndexedCollection<ShopEntry>(config.ShopEntries);
|
||||
var entries = new IndexedCollection<ShopEntry>(items);
|
||||
removed = entries.ElementAtOrDefault(index);
|
||||
if (removed is not null)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#nullable disable
|
||||
using LinqToDB;
|
||||
using LinqToDB.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using EllieBot.Db.Models;
|
||||
|
||||
|
@ -11,11 +13,14 @@ public class ShopService : IShopService, IEService
|
|||
public ShopService(DbService db)
|
||||
=> _db = db;
|
||||
|
||||
private IndexedCollection<ShopEntry> GetEntriesInternal(DbContext uow, ulong guildId)
|
||||
=> uow.GuildConfigsForId(guildId,
|
||||
set => set.Include(x => x.ShopEntries)
|
||||
.ThenInclude(x => x.Items))
|
||||
.ShopEntries.ToIndexed();
|
||||
private async Task<IndexedCollection<ShopEntry>> GetEntriesInternal(DbContext uow, ulong guildId)
|
||||
{
|
||||
var items = await uow.GetTable<ShopEntry>()
|
||||
.Where(x => x.GuildId == guildId)
|
||||
.ToListAsyncLinqToDB();
|
||||
|
||||
return items.ToIndexed();
|
||||
}
|
||||
|
||||
public async Task<bool> ChangeEntryPriceAsync(ulong guildId, int index, int newPrice)
|
||||
{
|
||||
|
@ -23,32 +28,33 @@ public class ShopService : IShopService, IEService
|
|||
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(newPrice);
|
||||
|
||||
await using var uow = _db.GetDbContext();
|
||||
var entries = GetEntriesInternal(uow, guildId);
|
||||
|
||||
if (index >= entries.Count)
|
||||
return false;
|
||||
var changed = await uow.GetTable<ShopEntry>()
|
||||
.Where(x => x.GuildId == guildId && x.Index == index)
|
||||
.UpdateAsync(x => new ShopEntry()
|
||||
{
|
||||
Price = newPrice,
|
||||
});
|
||||
|
||||
entries[index].Price = newPrice;
|
||||
await uow.SaveChangesAsync();
|
||||
return true;
|
||||
return changed > 0;
|
||||
}
|
||||
|
||||
public async Task<bool> ChangeEntryNameAsync(ulong guildId, int index, string newName)
|
||||
{
|
||||
ArgumentOutOfRangeException.ThrowIfNegative(index);
|
||||
|
||||
|
||||
if (string.IsNullOrWhiteSpace(newName))
|
||||
throw new ArgumentNullException(nameof(newName));
|
||||
|
||||
await using var uow = _db.GetDbContext();
|
||||
var entries = GetEntriesInternal(uow, guildId);
|
||||
|
||||
if (index >= entries.Count)
|
||||
return false;
|
||||
|
||||
entries[index].Name = newName.TrimTo(100);
|
||||
await uow.SaveChangesAsync();
|
||||
return true;
|
||||
var changed = await uow.GetTable<ShopEntry>()
|
||||
.Where(x => x.GuildId == guildId && x.Index == index)
|
||||
.UpdateAsync(x => new ShopEntry()
|
||||
{
|
||||
Name = newName,
|
||||
});
|
||||
return changed > 0;
|
||||
}
|
||||
|
||||
public async Task<bool> SwapEntriesAsync(ulong guildId, int index1, int index2)
|
||||
|
@ -57,7 +63,7 @@ public class ShopService : IShopService, IEService
|
|||
ArgumentOutOfRangeException.ThrowIfNegative(index2);
|
||||
|
||||
await using var uow = _db.GetDbContext();
|
||||
var entries = GetEntriesInternal(uow, guildId);
|
||||
var entries = await GetEntriesInternal(uow, guildId);
|
||||
|
||||
if (index1 >= entries.Count || index2 >= entries.Count || index1 == index2)
|
||||
return false;
|
||||
|
@ -65,7 +71,14 @@ public class ShopService : IShopService, IEService
|
|||
entries[index1].Index = index2;
|
||||
entries[index2].Index = index1;
|
||||
|
||||
await uow.SaveChangesAsync();
|
||||
// todo fix swap
|
||||
await uow.GetTable<ShopEntry>()
|
||||
.Where(x => x.GuildId == guildId)
|
||||
.UpdateAsync(x => new ShopEntry()
|
||||
{
|
||||
Index = x.Index == index1 ? index2 : x.Index == index2 ? index1 : x.Index,
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -77,49 +90,38 @@ public class ShopService : IShopService, IEService
|
|||
await using var uow = _db.GetDbContext();
|
||||
var entries = GetEntriesInternal(uow, guildId);
|
||||
|
||||
if (fromIndex >= entries.Count || toIndex >= entries.Count || fromIndex == toIndex)
|
||||
return false;
|
||||
|
||||
var entry = entries[fromIndex];
|
||||
entries.RemoveAt(fromIndex);
|
||||
entries.Insert(toIndex, entry);
|
||||
|
||||
await uow.SaveChangesAsync();
|
||||
// todo move
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> SetItemRoleRequirementAsync(ulong guildId, int index, ulong? roleId)
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
var entries = GetEntriesInternal(uow, guildId);
|
||||
|
||||
if (index >= entries.Count)
|
||||
return false;
|
||||
|
||||
var entry = entries[index];
|
||||
|
||||
entry.RoleRequirement = roleId;
|
||||
|
||||
await uow.SaveChangesAsync();
|
||||
return true;
|
||||
var changes = await uow.GetTable<ShopEntry>()
|
||||
.Where(x => x.GuildId == guildId && x.Index == index)
|
||||
.UpdateAsync(x => new ShopEntry()
|
||||
{
|
||||
RoleRequirement = roleId,
|
||||
});
|
||||
return changes > 0;
|
||||
}
|
||||
|
||||
public async Task<ShopEntry> AddShopCommandAsync(ulong guildId, ulong userId, int price, string command)
|
||||
public async Task<ShopEntry> AddShopCommandAsync(
|
||||
ulong guildId,
|
||||
ulong userId,
|
||||
int price,
|
||||
string command)
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
|
||||
var entries = GetEntriesInternal(uow, guildId);
|
||||
var entry = new ShopEntry()
|
||||
{
|
||||
AuthorId = userId,
|
||||
Command = command,
|
||||
Type = ShopEntryType.Command,
|
||||
Price = price,
|
||||
};
|
||||
entries.Add(entry);
|
||||
uow.GuildConfigsForId(guildId, set => set).ShopEntries = entries;
|
||||
|
||||
await uow.SaveChangesAsync();
|
||||
var entry = await uow.GetTable<ShopEntry>()
|
||||
.InsertWithOutputAsync(() => new()
|
||||
{
|
||||
AuthorId = userId,
|
||||
Command = command,
|
||||
Type = ShopEntryType.Command,
|
||||
Price = price,
|
||||
});
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#nullable disable
|
||||
using LinqToDB;
|
||||
using LinqToDB.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using EllieBot.Common.ModuleBehaviors;
|
||||
using EllieBot.Db.Models;
|
||||
using EllieBot.Modules.Games.Common;
|
||||
|
@ -10,9 +11,9 @@ using EllieBot.Modules.Permissions;
|
|||
|
||||
namespace EllieBot.Modules.Games.Services;
|
||||
|
||||
public class ChatterBotService : IExecOnMessage
|
||||
public class ChatterBotService : IExecOnMessage, IReadyExecutor
|
||||
{
|
||||
private ConcurrentDictionary<ulong, Lazy<IChatterBotSession>> ChatterBotGuilds { get; }
|
||||
private ConcurrentDictionary<ulong, Lazy<IChatterBotSession>> _chatterBotGuilds;
|
||||
|
||||
public int Priority
|
||||
=> 1;
|
||||
|
@ -29,7 +30,6 @@ public class ChatterBotService : IExecOnMessage
|
|||
public ChatterBotService(
|
||||
DiscordSocketClient client,
|
||||
IPermissionChecker perms,
|
||||
IBot bot,
|
||||
IPatronageService ps,
|
||||
IHttpClientFactory factory,
|
||||
IBotCreds creds,
|
||||
|
@ -46,11 +46,6 @@ public class ChatterBotService : IExecOnMessage
|
|||
_perms = perms;
|
||||
_gcs = gcs;
|
||||
_ps = ps;
|
||||
|
||||
ChatterBotGuilds = new(bot.AllGuildConfigs
|
||||
.Where(gc => gc.CleverbotEnabled)
|
||||
.ToDictionary(gc => gc.GuildId,
|
||||
_ => new Lazy<IChatterBotSession>(() => CreateSession(), true)));
|
||||
}
|
||||
|
||||
public IChatterBotSession CreateSession()
|
||||
|
@ -86,25 +81,25 @@ public class ChatterBotService : IExecOnMessage
|
|||
|
||||
public IChatterBotSession GetOrCreateSession(ulong guildId)
|
||||
{
|
||||
if (ChatterBotGuilds.TryGetValue(guildId, out var lazyChatBot))
|
||||
if (_chatterBotGuilds.TryGetValue(guildId, out var lazyChatBot))
|
||||
return lazyChatBot.Value;
|
||||
|
||||
lazyChatBot = new(() => CreateSession(), true);
|
||||
ChatterBotGuilds.TryAdd(guildId, lazyChatBot);
|
||||
_chatterBotGuilds.TryAdd(guildId, lazyChatBot);
|
||||
return lazyChatBot.Value;
|
||||
}
|
||||
|
||||
public string PrepareMessage(IUserMessage msg)
|
||||
{
|
||||
var ellieId = _client.CurrentUser.Id;
|
||||
var normalMention = $"<@{ellieId}> ";
|
||||
var nickMention = $"<@!{ellieId}> ";
|
||||
var nadekoId = _client.CurrentUser.Id;
|
||||
var normalMention = $"<@{nadekoId}> ";
|
||||
var nickMention = $"<@!{nadekoId}> ";
|
||||
string message;
|
||||
if (msg.Content.StartsWith(normalMention, StringComparison.InvariantCulture))
|
||||
message = msg.Content[normalMention.Length..].Trim();
|
||||
else if (msg.Content.StartsWith(nickMention, StringComparison.InvariantCulture))
|
||||
message = msg.Content[nickMention.Length..].Trim();
|
||||
else if (msg.ReferencedMessage?.Author.Id == ellieId)
|
||||
else if (msg.ReferencedMessage?.Author.Id == nadekoId)
|
||||
message = msg.Content;
|
||||
else
|
||||
return null;
|
||||
|
@ -121,7 +116,7 @@ public class ChatterBotService : IExecOnMessage
|
|||
if (channel is null)
|
||||
return false;
|
||||
|
||||
if (!ChatterBotGuilds.TryGetValue(channel.Guild.Id, out var lazyChatBot))
|
||||
if (!_chatterBotGuilds.TryGetValue(channel.Guild.Id, out var lazyChatBot))
|
||||
return false;
|
||||
|
||||
var chatBot = lazyChatBot.Value;
|
||||
|
@ -205,7 +200,7 @@ public class ChatterBotService : IExecOnMessage
|
|||
|
||||
public async Task<bool> ToggleChatterBotAsync(ulong guildId)
|
||||
{
|
||||
if (ChatterBotGuilds.TryRemove(guildId, out _))
|
||||
if (_chatterBotGuilds.TryRemove(guildId, out _))
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
await uow.Set<GuildConfig>()
|
||||
|
@ -219,7 +214,7 @@ public class ChatterBotService : IExecOnMessage
|
|||
return false;
|
||||
}
|
||||
|
||||
ChatterBotGuilds.TryAdd(guildId, new(() => CreateSession(), true));
|
||||
_chatterBotGuilds.TryAdd(guildId, new(() => CreateSession(), true));
|
||||
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
|
@ -236,4 +231,16 @@ public class ChatterBotService : IExecOnMessage
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task OnReadyAsync()
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
_chatterBotGuilds = uow.GuildConfigs
|
||||
.AsNoTracking()
|
||||
.Where(gc => gc.CleverbotEnabled)
|
||||
.AsEnumerable()
|
||||
.ToDictionary(gc => gc.GuildId,
|
||||
_ => new Lazy<IChatterBotSession>(() => CreateSession(), true))
|
||||
.ToConcurrent();
|
||||
}
|
||||
}
|
|
@ -1,28 +1,28 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using LinqToDB;
|
||||
using LinqToDB.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using EllieBot.Common.ModuleBehaviors;
|
||||
using EllieBot.Db.Models;
|
||||
|
||||
namespace EllieBot.Modules.Permissions.Services;
|
||||
|
||||
public sealed class CmdCdService : IExecPreCommand, IReadyExecutor, IEService
|
||||
{
|
||||
private readonly DbService _db;
|
||||
private readonly ConcurrentDictionary<ulong, ConcurrentDictionary<string, int>> _settings = new();
|
||||
private ConcurrentDictionary<ulong, ConcurrentDictionary<string, int>> _settings = new();
|
||||
|
||||
private readonly ConcurrentDictionary<(ulong, string), ConcurrentDictionary<ulong, DateTime>> _activeCooldowns =
|
||||
new();
|
||||
|
||||
public int Priority => 0;
|
||||
public int Priority
|
||||
=> 0;
|
||||
|
||||
public CmdCdService(IBot bot, DbService db)
|
||||
private readonly ShardData _shardData;
|
||||
|
||||
public CmdCdService(DbService db, ShardData shardData)
|
||||
{
|
||||
_db = db;
|
||||
_settings = bot
|
||||
.AllGuildConfigs
|
||||
.ToDictionary(x => x.GuildId, x => x.CommandCooldowns
|
||||
.DistinctBy(x => x.CommandName.ToLowerInvariant())
|
||||
.ToDictionary(c => c.CommandName, c => c.Seconds)
|
||||
.ToConcurrent())
|
||||
.ToConcurrent();
|
||||
_shardData = shardData;
|
||||
}
|
||||
|
||||
public Task<bool> ExecPreCommandAsync(ICommandContext context, string moduleName, CommandInfo command)
|
||||
|
@ -32,7 +32,7 @@ public sealed class CmdCdService : IExecPreCommand, IReadyExecutor, IEService
|
|||
{
|
||||
if (guild is null)
|
||||
return Task.FromResult(false);
|
||||
|
||||
|
||||
if (!_settings.TryGetValue(guild.Id, out var cooldownSettings))
|
||||
return Task.FromResult(false);
|
||||
|
||||
|
@ -66,8 +66,23 @@ public sealed class CmdCdService : IExecPreCommand, IReadyExecutor, IEService
|
|||
|
||||
public async Task OnReadyAsync()
|
||||
{
|
||||
using var timer = new PeriodicTimer(TimeSpan.FromHours(1));
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
_settings = await uow.GetTable<CommandCooldown>()
|
||||
.Where(
|
||||
x => Queries.GuildOnShard(x.GuildId, _shardData.TotalShards, _shardData.ShardId))
|
||||
.ToListAsyncLinqToDB()
|
||||
.Fmap(cmdcds => cmdcds
|
||||
.GroupBy(x => x.GuildId)
|
||||
.ToDictionary(x => x.Key,
|
||||
x => x
|
||||
.DistinctBy(x => x.CommandName.ToLower())
|
||||
.ToDictionary(y => y.CommandName, y => y.Seconds)
|
||||
.ToConcurrent())
|
||||
.ToConcurrent());
|
||||
}
|
||||
|
||||
using var timer = new PeriodicTimer(TimeSpan.FromHours(1));
|
||||
while (await timer.WaitForNextTickAsync())
|
||||
{
|
||||
// once per hour delete expired entries
|
||||
|
@ -81,7 +96,7 @@ public sealed class CmdCdService : IExecPreCommand, IReadyExecutor, IEService
|
|||
_activeCooldowns.Remove((guildId, commandName), out _);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Cleanup(dict, cdSeconds);
|
||||
}
|
||||
}
|
||||
|
@ -96,20 +111,20 @@ public sealed class CmdCdService : IExecPreCommand, IReadyExecutor, IEService
|
|||
}
|
||||
}
|
||||
|
||||
public void ClearCooldowns(ulong guildId, string cmdName)
|
||||
public async Task ClearCooldowns(ulong guildId, string cmdName)
|
||||
{
|
||||
if (_settings.TryGetValue(guildId, out var dict))
|
||||
dict.TryRemove(cmdName, out _);
|
||||
|
||||
_activeCooldowns.TryRemove((guildId, cmdName), out _);
|
||||
|
||||
using var ctx = _db.GetDbContext();
|
||||
var gc = ctx.GuildConfigsForId(guildId, x => x.Include(x => x.CommandCooldowns));
|
||||
gc.CommandCooldowns.RemoveWhere(x => x.CommandName == cmdName);
|
||||
ctx.SaveChanges();
|
||||
|
||||
await using var ctx = _db.GetDbContext();
|
||||
await ctx.GetTable<CommandCooldown>()
|
||||
.Where(x => x.GuildId == guildId && x.CommandName == cmdName)
|
||||
.DeleteAsync();
|
||||
}
|
||||
|
||||
public void AddCooldown(ulong guildId, string name, int secs)
|
||||
public async Task AddCooldown(ulong guildId, string name, int secs)
|
||||
{
|
||||
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(secs);
|
||||
|
||||
|
@ -119,16 +134,24 @@ public sealed class CmdCdService : IExecPreCommand, IReadyExecutor, IEService
|
|||
// force cleanup
|
||||
if (_activeCooldowns.TryGetValue((guildId, name), out var dict))
|
||||
Cleanup(dict, secs);
|
||||
|
||||
using var ctx = _db.GetDbContext();
|
||||
var gc = ctx.GuildConfigsForId(guildId, x => x.Include(x => x.CommandCooldowns));
|
||||
gc.CommandCooldowns.RemoveWhere(x => x.CommandName == name);
|
||||
gc.CommandCooldowns.Add(new()
|
||||
{
|
||||
Seconds = secs,
|
||||
CommandName = name
|
||||
});
|
||||
ctx.SaveChanges();
|
||||
|
||||
await using var ctx = _db.GetDbContext();
|
||||
await ctx.GetTable<CommandCooldown>()
|
||||
.InsertOrUpdateAsync(() => new()
|
||||
{
|
||||
GuildId = guildId,
|
||||
CommandName = name,
|
||||
Seconds = secs
|
||||
},
|
||||
(old) => new()
|
||||
{
|
||||
Seconds = secs
|
||||
},
|
||||
() => new()
|
||||
{
|
||||
GuildId = guildId,
|
||||
CommandName = name,
|
||||
});
|
||||
}
|
||||
|
||||
public IReadOnlyCollection<(string CommandName, int Seconds)> GetCommandCooldowns(ulong guildId)
|
||||
|
|
|
@ -22,7 +22,6 @@ public partial class Permissions
|
|||
|
||||
private async Task CmdCooldownInternal(string cmdName, int secs)
|
||||
{
|
||||
var channel = (ITextChannel)ctx.Channel;
|
||||
if (secs is < 0 or > 3600)
|
||||
{
|
||||
await Response().Error(strs.invalid_second_param_between(0, 3600)).SendAsync();
|
||||
|
@ -30,34 +29,17 @@ public partial class Permissions
|
|||
}
|
||||
|
||||
var name = cmdName.ToLowerInvariant();
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var config = uow.GuildConfigsForId(channel.Guild.Id, set => set.Include(gc => gc.CommandCooldowns));
|
||||
|
||||
var toDelete = config.CommandCooldowns.FirstOrDefault(cc => cc.CommandName == name);
|
||||
if (toDelete is not null)
|
||||
uow.Set<CommandCooldown>().Remove(toDelete);
|
||||
if (secs != 0)
|
||||
{
|
||||
var cc = new CommandCooldown
|
||||
{
|
||||
CommandName = name,
|
||||
Seconds = secs
|
||||
};
|
||||
config.CommandCooldowns.Add(cc);
|
||||
_service.AddCooldown(channel.Guild.Id, name, secs);
|
||||
}
|
||||
|
||||
await uow.SaveChangesAsync();
|
||||
}
|
||||
await _service.AddCooldown(ctx.Guild.Id, name, secs);
|
||||
|
||||
if (secs == 0)
|
||||
{
|
||||
_service.ClearCooldowns(ctx.Guild.Id, cmdName);
|
||||
await _service.ClearCooldowns(ctx.Guild.Id, cmdName);
|
||||
await Response().Confirm(strs.cmdcd_cleared(Format.Bold(name))).SendAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
await Response().Confirm(strs.cmdcd_add(Format.Bold(name), Format.Bold(secs.ToString()))).SendAsync();
|
||||
}
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
|
|
|
@ -20,7 +20,7 @@ public partial class Permissions
|
|||
[UserPerm(GuildPerm.Administrator)]
|
||||
public async Task FwClear()
|
||||
{
|
||||
_service.ClearFilteredWords(ctx.Guild.Id);
|
||||
await _service.ClearFilteredWords(ctx.Guild.Id);
|
||||
await Response().Confirm(strs.fw_cleared).SendAsync();
|
||||
}
|
||||
|
||||
|
@ -71,22 +71,14 @@ public partial class Permissions
|
|||
{
|
||||
var channel = (ITextChannel)ctx.Channel;
|
||||
|
||||
bool enabled;
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var config = uow.GuildConfigsForId(channel.Guild.Id, set => set);
|
||||
enabled = config.FilterInvites = !config.FilterInvites;
|
||||
await uow.SaveChangesAsync();
|
||||
}
|
||||
var enabled = await _service.ToggleServerInviteFilteringAsync(channel.Guild.Id);
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
_service.InviteFilteringServers.Add(channel.Guild.Id);
|
||||
await Response().Confirm(strs.invite_filter_server_on).SendAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
_service.InviteFilteringServers.TryRemove(channel.Guild.Id);
|
||||
await Response().Confirm(strs.invite_filter_server_off).SendAsync();
|
||||
}
|
||||
}
|
||||
|
@ -97,32 +89,14 @@ public partial class Permissions
|
|||
{
|
||||
var channel = (ITextChannel)ctx.Channel;
|
||||
|
||||
FilterChannelId removed;
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var config = uow.GuildConfigsForId(channel.Guild.Id,
|
||||
set => set.Include(gc => gc.FilterInvitesChannelIds));
|
||||
var match = new FilterChannelId
|
||||
{
|
||||
ChannelId = channel.Id
|
||||
};
|
||||
removed = config.FilterInvitesChannelIds.FirstOrDefault(fc => fc.Equals(match));
|
||||
var enabled = await _service.ToggleChannelInviteFilteringAsync(channel.Guild.Id, channel.Id);
|
||||
|
||||
if (removed is null)
|
||||
config.FilterInvitesChannelIds.Add(match);
|
||||
else
|
||||
uow.Remove(removed);
|
||||
await uow.SaveChangesAsync();
|
||||
}
|
||||
|
||||
if (removed is null)
|
||||
if (enabled)
|
||||
{
|
||||
_service.InviteFilteringChannels.Add(channel.Id);
|
||||
await Response().Confirm(strs.invite_filter_channel_on).SendAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
_service.InviteFilteringChannels.TryRemove(channel.Id);
|
||||
await Response().Confirm(strs.invite_filter_channel_off).SendAsync();
|
||||
}
|
||||
}
|
||||
|
@ -133,22 +107,14 @@ public partial class Permissions
|
|||
{
|
||||
var channel = (ITextChannel)ctx.Channel;
|
||||
|
||||
bool enabled;
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var config = uow.GuildConfigsForId(channel.Guild.Id, set => set);
|
||||
enabled = config.FilterLinks = !config.FilterLinks;
|
||||
await uow.SaveChangesAsync();
|
||||
}
|
||||
var enabled = await _service.ToggleServerLinkFilteringAsync(channel.Guild.Id);
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
_service.LinkFilteringServers.Add(channel.Guild.Id);
|
||||
await Response().Confirm(strs.link_filter_server_on).SendAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
_service.LinkFilteringServers.TryRemove(channel.Guild.Id);
|
||||
await Response().Confirm(strs.link_filter_server_off).SendAsync();
|
||||
}
|
||||
}
|
||||
|
@ -159,32 +125,14 @@ public partial class Permissions
|
|||
{
|
||||
var channel = (ITextChannel)ctx.Channel;
|
||||
|
||||
FilterLinksChannelId removed;
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var config =
|
||||
uow.GuildConfigsForId(channel.Guild.Id, set => set.Include(gc => gc.FilterLinksChannelIds));
|
||||
var match = new FilterLinksChannelId
|
||||
{
|
||||
ChannelId = channel.Id
|
||||
};
|
||||
removed = config.FilterLinksChannelIds.FirstOrDefault(fc => fc.Equals(match));
|
||||
var enabled = await _service.ToggleChannelLinkFilteringAsync(channel.Guild.Id, channel.Id);
|
||||
|
||||
if (removed is null)
|
||||
config.FilterLinksChannelIds.Add(match);
|
||||
else
|
||||
uow.Remove(removed);
|
||||
await uow.SaveChangesAsync();
|
||||
}
|
||||
|
||||
if (removed is null)
|
||||
if (enabled)
|
||||
{
|
||||
_service.LinkFilteringChannels.Add(channel.Id);
|
||||
await Response().Confirm(strs.link_filter_channel_on).SendAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
_service.LinkFilteringChannels.TryRemove(channel.Id);
|
||||
await Response().Confirm(strs.link_filter_channel_off).SendAsync();
|
||||
}
|
||||
}
|
||||
|
@ -195,22 +143,14 @@ public partial class Permissions
|
|||
{
|
||||
var channel = (ITextChannel)ctx.Channel;
|
||||
|
||||
bool enabled;
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var config = uow.GuildConfigsForId(channel.Guild.Id, set => set);
|
||||
enabled = config.FilterWords = !config.FilterWords;
|
||||
await uow.SaveChangesAsync();
|
||||
}
|
||||
var enabled = await _service.ToggleServerWordFilteringAsync(channel.Guild.Id);
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
_service.WordFilteringServers.Add(channel.Guild.Id);
|
||||
await Response().Confirm(strs.word_filter_server_on).SendAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
_service.WordFilteringServers.TryRemove(channel.Guild.Id);
|
||||
await Response().Confirm(strs.word_filter_server_off).SendAsync();
|
||||
}
|
||||
}
|
||||
|
@ -221,32 +161,14 @@ public partial class Permissions
|
|||
{
|
||||
var channel = (ITextChannel)ctx.Channel;
|
||||
|
||||
FilterWordsChannelId removed;
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var config =
|
||||
uow.GuildConfigsForId(channel.Guild.Id, set => set.Include(gc => gc.FilterWordsChannelIds));
|
||||
var enabled = await _service.ToggleChannelWordFilteringAsync(channel.Guild.Id, channel.Id);
|
||||
|
||||
var match = new FilterWordsChannelId
|
||||
{
|
||||
ChannelId = channel.Id
|
||||
};
|
||||
removed = config.FilterWordsChannelIds.FirstOrDefault(fc => fc.Equals(match));
|
||||
if (removed is null)
|
||||
config.FilterWordsChannelIds.Add(match);
|
||||
else
|
||||
uow.Remove(removed);
|
||||
await uow.SaveChangesAsync();
|
||||
}
|
||||
|
||||
if (removed is null)
|
||||
if (enabled)
|
||||
{
|
||||
_service.WordFilteringChannels.Add(channel.Id);
|
||||
await Response().Confirm(strs.word_filter_channel_on).SendAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
_service.WordFilteringChannels.TryRemove(channel.Id);
|
||||
await Response().Confirm(strs.word_filter_channel_off).SendAsync();
|
||||
}
|
||||
}
|
||||
|
@ -255,44 +177,17 @@ public partial class Permissions
|
|||
[RequireContext(ContextType.Guild)]
|
||||
public async Task FilterWord([Leftover] string word)
|
||||
{
|
||||
var channel = (ITextChannel)ctx.Channel;
|
||||
|
||||
word = word?.Trim().ToLowerInvariant();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(word))
|
||||
return;
|
||||
|
||||
FilteredWord removed;
|
||||
await using (var uow = _db.GetDbContext())
|
||||
var enabled = await _service.ToggleFilteredWordAsync(ctx.Guild.Id, word);
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
var config = uow.GuildConfigsForId(channel.Guild.Id, set => set.Include(gc => gc.FilteredWords));
|
||||
|
||||
removed = config.FilteredWords.FirstOrDefault(fw => fw.Word.Trim().ToLowerInvariant() == word);
|
||||
|
||||
if (removed is null)
|
||||
{
|
||||
config.FilteredWords.Add(new()
|
||||
{
|
||||
Word = word
|
||||
});
|
||||
}
|
||||
else
|
||||
uow.Remove(removed);
|
||||
|
||||
await uow.SaveChangesAsync();
|
||||
}
|
||||
|
||||
var filteredWords =
|
||||
_service.ServerFilteredWords.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet<string>());
|
||||
|
||||
if (removed is null)
|
||||
{
|
||||
filteredWords.Add(word);
|
||||
await Response().Confirm(strs.filter_word_add(Format.Code(word))).SendAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
filteredWords.TryRemove(word);
|
||||
await Response().Confirm(strs.filter_word_remove(Format.Code(word))).SendAsync();
|
||||
}
|
||||
}
|
||||
|
@ -305,11 +200,7 @@ public partial class Permissions
|
|||
if (page < 0)
|
||||
return;
|
||||
|
||||
var channel = (ITextChannel)ctx.Channel;
|
||||
|
||||
_service.ServerFilteredWords.TryGetValue(channel.Guild.Id, out var fwHash);
|
||||
|
||||
var fws = fwHash.ToArray();
|
||||
var fws = _service.FilteredWordsForServer(ctx.Guild.Id);
|
||||
|
||||
await Response()
|
||||
.Paginated()
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
#nullable disable
|
||||
using LinqToDB;
|
||||
using LinqToDB.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using EllieBot.Common.ModuleBehaviors;
|
||||
using EllieBot.Db.Models;
|
||||
|
||||
namespace EllieBot.Modules.Permissions.Services;
|
||||
|
||||
public sealed class FilterService : IExecOnMessage
|
||||
public sealed class FilterService : IExecOnMessage, IReadyExecutor
|
||||
{
|
||||
public ConcurrentHashSet<ulong> InviteFilteringChannels { get; }
|
||||
public ConcurrentHashSet<ulong> InviteFilteringServers { get; }
|
||||
|
@ -23,40 +25,20 @@ public sealed class FilterService : IExecOnMessage
|
|||
=> int.MaxValue - 1;
|
||||
|
||||
private readonly DbService _db;
|
||||
private readonly ShardData _shardData;
|
||||
|
||||
public FilterService(DiscordSocketClient client, DbService db)
|
||||
public FilterService(DiscordSocketClient client, DbService db, ShardData shardData)
|
||||
{
|
||||
_db = db;
|
||||
_shardData = shardData;
|
||||
|
||||
using (var uow = db.GetDbContext())
|
||||
{
|
||||
var ids = client.GetGuildIds();
|
||||
var configs = uow.Set<GuildConfig>()
|
||||
.AsQueryable()
|
||||
.Include(x => x.FilteredWords)
|
||||
.Include(x => x.FilterLinksChannelIds)
|
||||
.Include(x => x.FilterWordsChannelIds)
|
||||
.Include(x => x.FilterInvitesChannelIds)
|
||||
.Where(gc => ids.Contains(gc.GuildId))
|
||||
.ToList();
|
||||
|
||||
InviteFilteringServers = new(configs.Where(gc => gc.FilterInvites).Select(gc => gc.GuildId));
|
||||
InviteFilteringChannels =
|
||||
new(configs.SelectMany(gc => gc.FilterInvitesChannelIds.Select(fci => fci.ChannelId)));
|
||||
|
||||
LinkFilteringServers = new(configs.Where(gc => gc.FilterLinks).Select(gc => gc.GuildId));
|
||||
LinkFilteringChannels =
|
||||
new(configs.SelectMany(gc => gc.FilterLinksChannelIds.Select(fci => fci.ChannelId)));
|
||||
|
||||
var dict = configs.ToDictionary(gc => gc.GuildId,
|
||||
gc => new ConcurrentHashSet<string>(gc.FilteredWords.Select(fw => fw.Word).Distinct()));
|
||||
|
||||
ServerFilteredWords = new(dict);
|
||||
|
||||
var serverFiltering = configs.Where(gc => gc.FilterWords);
|
||||
WordFilteringServers = new(serverFiltering.Select(gc => gc.GuildId));
|
||||
WordFilteringChannels =
|
||||
new(configs.SelectMany(gc => gc.FilterWordsChannelIds.Select(fwci => fwci.ChannelId)));
|
||||
.AsQueryable()
|
||||
.Where(gc => ids.Contains(gc.GuildId))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
client.MessageUpdated += (oldData, newMsg, channel) =>
|
||||
|
@ -74,6 +56,43 @@ public sealed class FilterService : IExecOnMessage
|
|||
};
|
||||
}
|
||||
|
||||
public async Task OnReadyAsync()
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
|
||||
var confs = await uow.GetTable<GuildFilterConfig>()
|
||||
.Where(x => Queries.GuildOnShard(x.GuildId, _shardData.TotalShards, _shardData.ShardId))
|
||||
.LoadWith(x => x.FilterInvitesChannelIds)
|
||||
.LoadWith(x => x.FilterWordsChannelIds)
|
||||
.LoadWith(x => x.FilterLinksChannelIds)
|
||||
.LoadWith(x => x.FilteredWords)
|
||||
.ToListAsyncLinqToDB();
|
||||
|
||||
foreach (var conf in confs)
|
||||
{
|
||||
foreach (var c in conf.FilterInvitesChannelIds)
|
||||
InviteFilteringChannels.Add(c.ChannelId);
|
||||
|
||||
foreach (var c in conf.FilterWordsChannelIds)
|
||||
WordFilteringChannels.Add(c.ChannelId);
|
||||
|
||||
foreach (var c in conf.FilterLinksChannelIds)
|
||||
LinkFilteringChannels.Add(c.ChannelId);
|
||||
|
||||
if (conf.FilterInvites)
|
||||
InviteFilteringServers.Add(conf.GuildId);
|
||||
|
||||
if (conf.FilterWords)
|
||||
WordFilteringServers.Add(conf.GuildId);
|
||||
|
||||
if (conf.FilterLinks)
|
||||
LinkFilteringServers.Add(conf.GuildId);
|
||||
|
||||
foreach (var word in conf.FilteredWords)
|
||||
ServerFilteredWords.GetOrAdd(conf.GuildId, new ConcurrentHashSet<string>()).Add(word.Word);
|
||||
}
|
||||
}
|
||||
|
||||
public ConcurrentHashSet<string> FilteredWordsForChannel(ulong channelId, ulong guildId)
|
||||
{
|
||||
var words = new ConcurrentHashSet<string>();
|
||||
|
@ -82,23 +101,24 @@ public sealed class FilterService : IExecOnMessage
|
|||
return words;
|
||||
}
|
||||
|
||||
public void ClearFilteredWords(ulong guildId)
|
||||
public async Task ClearFilteredWords(ulong guildId)
|
||||
{
|
||||
using var uow = _db.GetDbContext();
|
||||
var gc = uow.GuildConfigsForId(guildId,
|
||||
set => set.Include(x => x.FilteredWords).Include(x => x.FilterWordsChannelIds));
|
||||
await using var uow = _db.GetDbContext();
|
||||
var fc = uow.FilterConfigForId(guildId,
|
||||
set => set.Include(x => x.FilteredWords)
|
||||
.Include(x => x.FilterWordsChannelIds));
|
||||
|
||||
WordFilteringServers.TryRemove(guildId);
|
||||
ServerFilteredWords.TryRemove(guildId, out _);
|
||||
|
||||
foreach (var c in gc.FilterWordsChannelIds)
|
||||
foreach (var c in fc.FilterWordsChannelIds)
|
||||
WordFilteringChannels.TryRemove(c.ChannelId);
|
||||
|
||||
gc.FilterWords = false;
|
||||
gc.FilteredWords.Clear();
|
||||
gc.FilterWordsChannelIds.Clear();
|
||||
fc.FilterWords = false;
|
||||
fc.FilteredWords.Clear();
|
||||
fc.FilterWordsChannelIds.Clear();
|
||||
|
||||
uow.SaveChanges();
|
||||
await uow.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public ConcurrentHashSet<string> FilteredWordsForServer(ulong guildId)
|
||||
|
@ -170,7 +190,7 @@ public sealed class FilterService : IExecOnMessage
|
|||
// if user has manage messages perm, don't filter
|
||||
if (usrMsg.Channel is ITextChannel ch && usrMsg.Author is IGuildUser gu && gu.GetPermissions(ch).ManageMessages)
|
||||
return false;
|
||||
|
||||
|
||||
if ((InviteFilteringChannels.Contains(usrMsg.Channel.Id) || InviteFilteringServers.Contains(guild.Id))
|
||||
&& usrMsg.Content.IsDiscordInvite())
|
||||
{
|
||||
|
@ -206,7 +226,7 @@ public sealed class FilterService : IExecOnMessage
|
|||
// if user has manage messages perm, don't filter
|
||||
if (usrMsg.Channel is ITextChannel ch && usrMsg.Author is IGuildUser gu && gu.GetPermissions(ch).ManageMessages)
|
||||
return false;
|
||||
|
||||
|
||||
if ((LinkFilteringChannels.Contains(usrMsg.Channel.Id) || LinkFilteringServers.Contains(guild.Id))
|
||||
&& usrMsg.Content.TryGetUrlPath(out _))
|
||||
{
|
||||
|
@ -233,17 +253,162 @@ public sealed class FilterService : IExecOnMessage
|
|||
public async Task<ServerFilterSettings> GetFilterSettings(ulong guildId)
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
var gc = uow.GuildConfigsForId(guildId,
|
||||
set => set
|
||||
.Include(x => x.FilterInvitesChannelIds)
|
||||
.Include(x => x.FilterLinksChannelIds));
|
||||
|
||||
var conf = await uow.GetTable<GuildFilterConfig>()
|
||||
.Where(fi => fi.GuildId == guildId)
|
||||
.LoadWith(x => x.FilterInvitesChannelIds)
|
||||
.LoadWith(x => x.FilterLinksChannelIds)
|
||||
.FirstOrDefaultAsyncLinqToDB();
|
||||
|
||||
return new()
|
||||
{
|
||||
FilterInvitesChannels = gc.FilterInvitesChannelIds.Map(x => x.ChannelId),
|
||||
FilterLinksChannels = gc.FilterLinksChannelIds.Map(x => x.ChannelId),
|
||||
FilterInvitesEnabled = gc.FilterInvites,
|
||||
FilterLinksEnabled = gc.FilterLinks,
|
||||
FilterInvitesChannels = conf?.FilterInvitesChannelIds.Select(x => x.ChannelId).ToArray() ?? [],
|
||||
FilterLinksChannels = conf?.FilterLinksChannelIds.Select(x => x.ChannelId).ToArray() ?? [],
|
||||
FilterInvitesEnabled = false,
|
||||
FilterLinksEnabled = false,
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<bool> ToggleServerLinkFilteringAsync(ulong guildId)
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
|
||||
var fc = uow.FilterConfigForId(guildId);
|
||||
if (LinkFilteringServers.Add(guildId))
|
||||
{
|
||||
fc.FilterLinks = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fc.FilterLinks = false;
|
||||
}
|
||||
|
||||
await uow.SaveChangesAsync();
|
||||
return fc.FilterLinks;
|
||||
}
|
||||
|
||||
public async Task<bool> ToggleChannelLinkFilteringAsync(ulong guildId, ulong channelId)
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
|
||||
var fc = uow.FilterConfigForId(guildId, set => set.Include(x => x.FilterLinksChannelIds));
|
||||
|
||||
if (LinkFilteringChannels.Add(channelId))
|
||||
{
|
||||
fc.FilterLinksChannelIds.Add(new FilterLinksChannelId
|
||||
{
|
||||
ChannelId = channelId
|
||||
});
|
||||
|
||||
await uow.SaveChangesAsync();
|
||||
return true;
|
||||
}
|
||||
|
||||
LinkFilteringChannels.TryRemove(channelId);
|
||||
fc.FilterLinksChannelIds.RemoveWhere(x => x.ChannelId == channelId);
|
||||
await uow.SaveChangesAsync();
|
||||
return false;
|
||||
}
|
||||
|
||||
public async Task<bool> ToggleServerInviteFilteringAsync(ulong guildId)
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
var fc = uow.FilterConfigForId(guildId);
|
||||
|
||||
if (InviteFilteringServers.Add(guildId))
|
||||
{
|
||||
fc.FilterInvites = true;
|
||||
await uow.SaveChangesAsync();
|
||||
return true;
|
||||
}
|
||||
|
||||
fc.FilterInvites = false;
|
||||
await uow.SaveChangesAsync();
|
||||
return false;
|
||||
}
|
||||
|
||||
public async Task<bool> ToggleChannelInviteFilteringAsync(ulong guildId, ulong channelId)
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
var fc = uow.FilterConfigForId(guildId, set => set.Include(x => x.FilterInvitesChannelIds));
|
||||
|
||||
if (InviteFilteringChannels.Add(channelId))
|
||||
{
|
||||
fc.FilterInvitesChannelIds.Add(new FilterChannelId()
|
||||
{
|
||||
ChannelId = channelId
|
||||
});
|
||||
|
||||
await uow.SaveChangesAsync();
|
||||
return true;
|
||||
}
|
||||
|
||||
InviteFilteringChannels.TryRemove(channelId);
|
||||
fc.FilterInvitesChannelIds.RemoveWhere(x => x.ChannelId == channelId);
|
||||
await uow.SaveChangesAsync();
|
||||
return false;
|
||||
}
|
||||
|
||||
public async Task<bool> ToggleServerWordFilteringAsync(ulong guildId)
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
var fc = uow.FilterConfigForId(guildId);
|
||||
|
||||
if (WordFilteringServers.Add(guildId))
|
||||
{
|
||||
fc.FilterWords = true;
|
||||
await uow.SaveChangesAsync();
|
||||
return true;
|
||||
}
|
||||
|
||||
fc.FilterWords = false;
|
||||
await uow.SaveChangesAsync();
|
||||
return false;
|
||||
}
|
||||
|
||||
public async Task<bool> ToggleChannelWordFilteringAsync(ulong guildId, ulong channelId)
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
var fc = uow.FilterConfigForId(guildId, set => set.Include(x => x.FilterWordsChannelIds));
|
||||
|
||||
if (WordFilteringChannels.Add(channelId))
|
||||
{
|
||||
fc.FilterWordsChannelIds.Add(new FilterWordsChannelId()
|
||||
{
|
||||
ChannelId = channelId
|
||||
});
|
||||
|
||||
await uow.SaveChangesAsync();
|
||||
return true;
|
||||
}
|
||||
|
||||
WordFilteringChannels.TryRemove(channelId);
|
||||
fc.FilterWordsChannelIds.RemoveWhere(x => x.ChannelId == channelId);
|
||||
await uow.SaveChangesAsync();
|
||||
return false;
|
||||
}
|
||||
|
||||
public async Task<bool> ToggleFilteredWordAsync(ulong guildId, string word)
|
||||
{
|
||||
word = word?.Trim().ToLowerInvariant();
|
||||
|
||||
await using var uow = _db.GetDbContext();
|
||||
var fc = uow.FilterConfigForId(guildId, set => set.Include(x => x.FilteredWords));
|
||||
var sfw = ServerFilteredWords.GetOrAdd(guildId, []);
|
||||
if (sfw.Add(word))
|
||||
{
|
||||
fc.FilteredWords.Add(new FilteredWord()
|
||||
{
|
||||
Word = word
|
||||
});
|
||||
|
||||
await uow.SaveChangesAsync();
|
||||
}
|
||||
|
||||
sfw.TryRemove(word);
|
||||
fc.FilteredWords.RemoveWhere(x => x.Word == word);
|
||||
await uow.SaveChangesAsync();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -4,46 +4,52 @@ using CodeHollow.FeedReader.Feeds;
|
|||
using LinqToDB;
|
||||
using LinqToDB.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using EllieBot.Common.ModuleBehaviors;
|
||||
using EllieBot.Db.Models;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace EllieBot.Modules.Searches.Services;
|
||||
|
||||
public class FeedsService : IEService
|
||||
public class FeedsService : IEService, IReadyExecutor
|
||||
{
|
||||
private readonly DbService _db;
|
||||
private readonly ConcurrentDictionary<string, List<FeedSub>> _subs;
|
||||
private NonBlocking.ConcurrentDictionary<string, List<FeedSub>> _subs;
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly IMessageSenderService _sender;
|
||||
private readonly ShardData _shardData;
|
||||
|
||||
private readonly ConcurrentDictionary<string, DateTime> _lastPosts = new();
|
||||
private readonly NonBlocking.ConcurrentDictionary<string, DateTime> _lastPosts = new();
|
||||
private readonly Dictionary<string, uint> _errorCounters = new();
|
||||
|
||||
public FeedsService(
|
||||
IBot bot,
|
||||
DbService db,
|
||||
DiscordSocketClient client,
|
||||
IMessageSenderService sender)
|
||||
IMessageSenderService sender,
|
||||
ShardData shardData)
|
||||
{
|
||||
_db = db;
|
||||
|
||||
using (var uow = db.GetDbContext())
|
||||
{
|
||||
var guildConfigIds = bot.AllGuildConfigs.Select(x => x.Id).ToList();
|
||||
_subs = uow.Set<GuildConfig>()
|
||||
.AsQueryable()
|
||||
.Where(x => guildConfigIds.Contains(x.Id))
|
||||
.Include(x => x.FeedSubs)
|
||||
.ToList()
|
||||
.SelectMany(x => x.FeedSubs)
|
||||
.GroupBy(x => x.Url.ToLower())
|
||||
.ToDictionary(x => x.Key, x => x.ToList())
|
||||
.ToConcurrent();
|
||||
}
|
||||
|
||||
_client = client;
|
||||
_sender = sender;
|
||||
_shardData = shardData;
|
||||
}
|
||||
|
||||
_ = Task.Run(TrackFeeds);
|
||||
public async Task OnReadyAsync()
|
||||
{
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var subs = await uow.Set<FeedSub>()
|
||||
.AsQueryable()
|
||||
.Where(x => Queries.GuildOnShard(x.GuildId, _shardData.TotalShards, _shardData.ShardId))
|
||||
.ToListAsyncLinqToDB();
|
||||
_subs = subs
|
||||
.GroupBy(x => x.Url.ToLower())
|
||||
.ToDictionary(x => x.Key, x => x.ToList())
|
||||
.ToConcurrent();
|
||||
}
|
||||
|
||||
await TrackFeeds();
|
||||
}
|
||||
|
||||
private void ClearErrors(string url)
|
||||
|
@ -116,7 +122,7 @@ public class FeedsService : IEService
|
|||
if (items.Count > 2)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (items.Count == 0)
|
||||
continue;
|
||||
|
||||
|
@ -189,7 +195,7 @@ public class FeedsService : IEService
|
|||
|
||||
foreach (var val in kvp.Value)
|
||||
{
|
||||
var ch = _client.GetGuild(val.GuildConfig.GuildId).GetTextChannel(val.ChannelId);
|
||||
var ch = _client.GetGuild(val.GuildId).GetTextChannel(val.ChannelId);
|
||||
|
||||
if (ch is null)
|
||||
continue;
|
||||
|
@ -228,8 +234,10 @@ public class FeedsService : IEService
|
|||
public List<FeedSub> GetFeeds(ulong guildId)
|
||||
{
|
||||
using var uow = _db.GetDbContext();
|
||||
return uow.GuildConfigsForId(guildId, set => set.Include(x => x.FeedSubs))
|
||||
.FeedSubs.OrderBy(x => x.Id)
|
||||
|
||||
return uow.GetTable<FeedSub>()
|
||||
.Where(x => x.GuildId == guildId)
|
||||
.OrderBy(x => x.Id)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
|
@ -249,26 +257,21 @@ public class FeedsService : IEService
|
|||
};
|
||||
|
||||
using var uow = _db.GetDbContext();
|
||||
var gc = uow.GuildConfigsForId(guildId, set => set.Include(x => x.FeedSubs));
|
||||
var feeds = uow.GetTable<FeedSub>()
|
||||
.Where(x => x.GuildId == guildId)
|
||||
.ToArray();
|
||||
|
||||
if (gc.FeedSubs.Any(x => x.Url.ToLower() == fs.Url.ToLower()))
|
||||
if (feeds.Any(x => x.Url.ToLower() == fs.Url.ToLower()))
|
||||
return FeedAddResult.Duplicate;
|
||||
if (gc.FeedSubs.Count >= 10)
|
||||
if (feeds.Length >= 10)
|
||||
return FeedAddResult.LimitReached;
|
||||
|
||||
gc.FeedSubs.Add(fs);
|
||||
uow.Add(fs);
|
||||
uow.SaveChanges();
|
||||
//adding all, in case bot wasn't on this guild when it started
|
||||
foreach (var feed in gc.FeedSubs)
|
||||
{
|
||||
_subs.AddOrUpdate(feed.Url.ToLower(),
|
||||
[feed],
|
||||
(_, old) =>
|
||||
{
|
||||
old.Add(feed);
|
||||
return old;
|
||||
});
|
||||
}
|
||||
|
||||
_subs.AddOrUpdate(fs.Url.ToLower(),
|
||||
[fs],
|
||||
(_, old) => old.Append(fs).ToList());
|
||||
|
||||
return FeedAddResult.Success;
|
||||
}
|
||||
|
@ -279,19 +282,20 @@ public class FeedsService : IEService
|
|||
return false;
|
||||
|
||||
using var uow = _db.GetDbContext();
|
||||
var items = uow.GuildConfigsForId(guildId, set => set.Include(x => x.FeedSubs))
|
||||
.FeedSubs.OrderBy(x => x.Id)
|
||||
.ToList();
|
||||
var items = uow.Set<FeedSub>()
|
||||
.Where(x => x.GuildId == guildId)
|
||||
.OrderBy(x => x.Id)
|
||||
.ToList();
|
||||
|
||||
if (items.Count <= index)
|
||||
return false;
|
||||
|
||||
var toRemove = items[index];
|
||||
_subs.AddOrUpdate(toRemove.Url.ToLower(),
|
||||
[],
|
||||
(_, old) =>
|
||||
{
|
||||
old.Remove(toRemove);
|
||||
return old;
|
||||
return old.Where(x => x.Id != toRemove.Id).ToList();
|
||||
});
|
||||
uow.Remove(toRemove);
|
||||
uow.SaveChanges();
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
#nullable disable
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using EllieBot.Db.Models;
|
||||
using EllieBot.Modules.Searches.Services;
|
||||
|
||||
namespace EllieBot.Modules.Searches;
|
||||
|
@ -100,7 +98,7 @@ public partial class Searches
|
|||
[UserPerm(GuildPerm.ManageMessages)]
|
||||
public async Task StreamOffline()
|
||||
{
|
||||
var newValue = _service.ToggleStreamOffline(ctx.Guild.Id);
|
||||
var newValue = await _service.ToggleStreamOffline(ctx.Guild.Id);
|
||||
if (newValue)
|
||||
await Response().Confirm(strs.stream_off_enabled).SendAsync();
|
||||
else
|
||||
|
@ -112,7 +110,7 @@ public partial class Searches
|
|||
[UserPerm(GuildPerm.ManageMessages)]
|
||||
public async Task StreamOnlineDelete()
|
||||
{
|
||||
var newValue = _service.ToggleStreamOnlineDelete(ctx.Guild.Id);
|
||||
var newValue = await _service.ToggleStreamOnlineDelete(ctx.Guild.Id);
|
||||
if (newValue)
|
||||
await Response().Confirm(strs.stream_online_delete_enabled).SendAsync();
|
||||
else
|
||||
|
@ -151,7 +149,7 @@ public partial class Searches
|
|||
var canMentionEveryone = (ctx.User as IGuildUser)?.GuildPermissions.MentionEveryone ?? true;
|
||||
if (!canMentionEveryone)
|
||||
message = message?.SanitizeAllMentions();
|
||||
|
||||
|
||||
var count = _service.SetStreamMessageForAll(ctx.Guild.Id, message);
|
||||
|
||||
if (count == 0)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#nullable disable
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using LinqToDB;
|
||||
using LinqToDB.EntityFrameworkCore;
|
||||
using EllieBot.Common.ModuleBehaviors;
|
||||
using EllieBot.Db.Models;
|
||||
using EllieBot.Modules.Searches.Common;
|
||||
|
@ -17,16 +18,17 @@ public sealed class StreamNotificationService : IEService, IReadyExecutor
|
|||
|
||||
private readonly object _shardLock = new();
|
||||
|
||||
private readonly Dictionary<StreamDataKey, HashSet<ulong>> _trackCounter = new();
|
||||
private Dictionary<StreamDataKey, HashSet<ulong>> _trackCounter = new();
|
||||
|
||||
private readonly Dictionary<StreamDataKey, Dictionary<ulong, HashSet<FollowedStream>>> _shardTrackedStreams;
|
||||
private readonly ConcurrentHashSet<ulong> _offlineNotificationServers;
|
||||
private readonly ConcurrentHashSet<ulong> _deleteOnOfflineServers;
|
||||
private Dictionary<StreamDataKey, Dictionary<ulong, HashSet<FollowedStream>>> _shardTrackedStreams;
|
||||
private readonly ConcurrentHashSet<ulong> _offlineNotificationServers = [];
|
||||
private readonly ConcurrentHashSet<ulong> _deleteOnOfflineServers = [];
|
||||
|
||||
private readonly IPubSub _pubSub;
|
||||
private readonly IMessageSenderService _sender;
|
||||
private readonly SearchesConfigService _config;
|
||||
private readonly IReplacementService _repSvc;
|
||||
private readonly ShardData _shardData;
|
||||
|
||||
public TypedKey<List<StreamData>> StreamsOnlineKey { get; }
|
||||
public TypedKey<List<StreamData>> StreamsOfflineKey { get; }
|
||||
|
@ -46,10 +48,10 @@ public sealed class StreamNotificationService : IEService, IReadyExecutor
|
|||
IBotStrings strings,
|
||||
IBotCredsProvider creds,
|
||||
IHttpClientFactory httpFactory,
|
||||
IBot bot,
|
||||
IPubSub pubSub,
|
||||
IMessageSenderService sender,
|
||||
SearchesConfigService config,
|
||||
ShardData shardData,
|
||||
IReplacementService repSvc)
|
||||
{
|
||||
_db = db;
|
||||
|
@ -59,6 +61,7 @@ public sealed class StreamNotificationService : IEService, IReadyExecutor
|
|||
_sender = sender;
|
||||
_config = config;
|
||||
_repSvc = repSvc;
|
||||
_shardData = shardData;
|
||||
|
||||
_streamTracker = new(httpFactory, creds);
|
||||
|
||||
|
@ -68,56 +71,6 @@ public sealed class StreamNotificationService : IEService, IReadyExecutor
|
|||
_streamFollowKey = new("stream.follow");
|
||||
_streamUnfollowKey = new("stream.unfollow");
|
||||
|
||||
using (var uow = db.GetDbContext())
|
||||
{
|
||||
var ids = client.GetGuildIds();
|
||||
var guildConfigs = uow.Set<GuildConfig>()
|
||||
.AsQueryable()
|
||||
.Include(x => x.FollowedStreams)
|
||||
.Where(x => ids.Contains(x.GuildId))
|
||||
.ToList();
|
||||
|
||||
_offlineNotificationServers = new(guildConfigs
|
||||
.Where(gc => gc.NotifyStreamOffline)
|
||||
.Select(x => x.GuildId)
|
||||
.ToList());
|
||||
|
||||
_deleteOnOfflineServers = new(guildConfigs
|
||||
.Where(gc => gc.DeleteStreamOnlineMessage)
|
||||
.Select(x => x.GuildId)
|
||||
.ToList());
|
||||
|
||||
var followedStreams = guildConfigs.SelectMany(x => x.FollowedStreams).ToList();
|
||||
|
||||
_shardTrackedStreams = followedStreams.GroupBy(x => new
|
||||
{
|
||||
x.Type,
|
||||
Name = x.Username.ToLower()
|
||||
})
|
||||
.ToList()
|
||||
.ToDictionary(
|
||||
x => new StreamDataKey(x.Key.Type, x.Key.Name.ToLower()),
|
||||
x => x.GroupBy(y => y.GuildId)
|
||||
.ToDictionary(y => y.Key,
|
||||
y => y.AsEnumerable().ToHashSet()));
|
||||
|
||||
// shard 0 will keep track of when there are no more guilds which track a stream
|
||||
if (client.ShardId == 0)
|
||||
{
|
||||
var allFollowedStreams = uow.Set<FollowedStream>().AsQueryable().ToList();
|
||||
|
||||
foreach (var fs in allFollowedStreams)
|
||||
_streamTracker.AddLastData(fs.CreateKey(), null, false);
|
||||
|
||||
_trackCounter = allFollowedStreams.GroupBy(x => new
|
||||
{
|
||||
x.Type,
|
||||
Name = x.Username.ToLower()
|
||||
})
|
||||
.ToDictionary(x => new StreamDataKey(x.Key.Type, x.Key.Name),
|
||||
x => x.Select(fs => fs.GuildId).ToHashSet());
|
||||
}
|
||||
}
|
||||
|
||||
_pubSub.Sub(StreamsOfflineKey, HandleStreamsOffline);
|
||||
_pubSub.Sub(StreamsOnlineKey, HandleStreamsOnline);
|
||||
|
@ -134,15 +87,76 @@ public sealed class StreamNotificationService : IEService, IReadyExecutor
|
|||
_pubSub.Sub(_streamUnfollowKey, HandleUnfollowStream);
|
||||
}
|
||||
|
||||
bot.JoinedGuild += ClientOnJoinedGuild;
|
||||
client.JoinedGuild += ClientOnJoinedGuild;
|
||||
client.LeftGuild += ClientOnLeftGuild;
|
||||
}
|
||||
|
||||
private async Task InitStateAsync()
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
// todo check all guilds on shard for correct param order
|
||||
var notifyOffline = await uow.GetTable<GuildConfig>()
|
||||
.Where(gc => gc.NotifyStreamOffline)
|
||||
.Select(x => x.GuildId)
|
||||
.ToListAsyncLinqToDB();
|
||||
|
||||
foreach (var guildId in notifyOffline)
|
||||
_offlineNotificationServers.Add(guildId);
|
||||
|
||||
var deleteOnOffline = await uow.GetTable<GuildConfig>()
|
||||
.Where(gc => Queries.GuildOnShard(gc.GuildId,
|
||||
_shardData.TotalShards,
|
||||
_shardData.ShardId))
|
||||
.Where(gc => gc.DeleteStreamOnlineMessage)
|
||||
.Select(x => x.GuildId)
|
||||
.ToListAsyncLinqToDB();
|
||||
|
||||
foreach (var guildId in deleteOnOffline)
|
||||
_deleteOnOfflineServers.Add(guildId);
|
||||
|
||||
var followedStreams = await uow.GetTable<FollowedStream>()
|
||||
.Where(x => Queries.GuildOnShard(x.GuildId,
|
||||
_shardData.TotalShards,
|
||||
_shardData.ShardId))
|
||||
.ToListAsyncLinqToDB();
|
||||
|
||||
_shardTrackedStreams = followedStreams.GroupBy(x => new
|
||||
{
|
||||
x.Type,
|
||||
Name = x.Username.ToLower()
|
||||
})
|
||||
.ToList()
|
||||
.ToDictionary(
|
||||
x => new StreamDataKey(x.Key.Type, x.Key.Name.ToLower()),
|
||||
x => x.GroupBy(y => y.GuildId)
|
||||
.ToDictionary(y => y.Key,
|
||||
y => y.AsEnumerable().ToHashSet()));
|
||||
|
||||
// shard 0 will keep track of when there are no more guilds which track a stream
|
||||
if (_client.ShardId == 0)
|
||||
{
|
||||
var allFollowedStreams = uow.Set<FollowedStream>().AsQueryable().ToList();
|
||||
|
||||
foreach (var fs in allFollowedStreams)
|
||||
_streamTracker.AddLastData(fs.CreateKey(), null, false);
|
||||
|
||||
_trackCounter = allFollowedStreams.GroupBy(x => new
|
||||
{
|
||||
x.Type,
|
||||
Name = x.Username.ToLower()
|
||||
})
|
||||
.ToDictionary(x => new StreamDataKey(x.Key.Type, x.Key.Name),
|
||||
x => x.Select(fs => fs.GuildId).ToHashSet());
|
||||
}
|
||||
}
|
||||
|
||||
public async Task OnReadyAsync()
|
||||
{
|
||||
if (_client.ShardId != 0)
|
||||
return;
|
||||
|
||||
await InitStateAsync();
|
||||
|
||||
using var timer = new PeriodicTimer(TimeSpan.FromMinutes(30));
|
||||
while (await timer.WaitForNextTickAsync())
|
||||
{
|
||||
|
@ -198,7 +212,9 @@ public sealed class StreamNotificationService : IEService, IReadyExecutor
|
|||
{
|
||||
var key = info.Key;
|
||||
if (_trackCounter.ContainsKey(key))
|
||||
{
|
||||
_trackCounter[key].Add(info.GuildId);
|
||||
}
|
||||
else
|
||||
{
|
||||
_trackCounter[key] = [info.GuildId];
|
||||
|
@ -332,65 +348,67 @@ public sealed class StreamNotificationService : IEService, IReadyExecutor
|
|||
private Task OnStreamsOffline(List<StreamData> data)
|
||||
=> _pubSub.Pub(StreamsOfflineKey, data);
|
||||
|
||||
private Task ClientOnJoinedGuild(GuildConfig guildConfig)
|
||||
private async Task ClientOnJoinedGuild(SocketGuild guild)
|
||||
{
|
||||
using (var uow = _db.GetDbContext())
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var gc = uow.Set<GuildConfig>()
|
||||
.AsQueryable()
|
||||
.Include(x => x.FollowedStreams)
|
||||
.FirstOrDefault(x => x.GuildId == guildConfig.GuildId);
|
||||
var fs = await uow.Set<FollowedStream>()
|
||||
.Where(x => x.GuildId == guild.Id)
|
||||
.ToListAsyncLinqToDB();
|
||||
|
||||
if (gc is null)
|
||||
return Task.CompletedTask;
|
||||
var notifyOffline = await uow.GetTable<GuildConfig>()
|
||||
.Where(x => x.GuildId == guild.Id)
|
||||
.Select(x => x.NotifyStreamOffline)
|
||||
.FirstOrDefaultAsyncLinqToDB();
|
||||
|
||||
if (gc.NotifyStreamOffline)
|
||||
_offlineNotificationServers.Add(gc.GuildId);
|
||||
// todo hashset
|
||||
if (notifyOffline)
|
||||
_offlineNotificationServers.Add(guild.Id);
|
||||
|
||||
foreach (var followedStream in gc.FollowedStreams)
|
||||
foreach (var followedStream in fs)
|
||||
{
|
||||
var key = followedStream.CreateKey();
|
||||
var streams = GetLocalGuildStreams(key, gc.GuildId);
|
||||
var streams = GetLocalGuildStreams(key, guild.Id);
|
||||
streams.Add(followedStream);
|
||||
PublishFollowStream(followedStream);
|
||||
}
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Task ClientOnLeftGuild(SocketGuild guild)
|
||||
private async Task ClientOnLeftGuild(SocketGuild guild)
|
||||
{
|
||||
using (var uow = _db.GetDbContext())
|
||||
await using var uow = _db.GetDbContext();
|
||||
var followedStreams = await uow.Set<FollowedStream>()
|
||||
.Where(x => x.GuildId == guild.Id)
|
||||
.ToListAsyncLinqToDB();
|
||||
|
||||
_offlineNotificationServers.TryRemove(guild.Id);
|
||||
|
||||
foreach (var followedStream in followedStreams)
|
||||
{
|
||||
var gc = uow.GuildConfigsForId(guild.Id, set => set.Include(x => x.FollowedStreams));
|
||||
var streams = GetLocalGuildStreams(followedStream.CreateKey(), guild.Id);
|
||||
streams.Remove(followedStream);
|
||||
|
||||
_offlineNotificationServers.TryRemove(gc.GuildId);
|
||||
|
||||
foreach (var followedStream in gc.FollowedStreams)
|
||||
{
|
||||
var streams = GetLocalGuildStreams(followedStream.CreateKey(), guild.Id);
|
||||
streams.Remove(followedStream);
|
||||
|
||||
PublishUnfollowStream(followedStream);
|
||||
}
|
||||
await PublishUnfollowStream(followedStream);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public async Task<int> ClearAllStreams(ulong guildId)
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
var gc = uow.GuildConfigsForId(guildId, set => set.Include(x => x.FollowedStreams));
|
||||
uow.RemoveRange(gc.FollowedStreams);
|
||||
|
||||
foreach (var s in gc.FollowedStreams)
|
||||
var followedStreams = await uow.Set<FollowedStream>()
|
||||
.Where(x => x.GuildId == guildId)
|
||||
.ToListAsyncEF();
|
||||
|
||||
uow.RemoveRange(followedStreams);
|
||||
|
||||
foreach (var s in followedStreams)
|
||||
await PublishUnfollowStream(s);
|
||||
|
||||
uow.SaveChanges();
|
||||
await uow.SaveChangesAsync();
|
||||
|
||||
return gc.FollowedStreams.Count;
|
||||
return followedStreams.Count;
|
||||
}
|
||||
|
||||
public async Task<FollowedStream> UnfollowStreamAsync(ulong guildId, int index)
|
||||
|
@ -398,11 +416,11 @@ public sealed class StreamNotificationService : IEService, IReadyExecutor
|
|||
FollowedStream fs;
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var fss = uow.Set<FollowedStream>()
|
||||
.AsQueryable()
|
||||
.Where(x => x.GuildId == guildId)
|
||||
.OrderBy(x => x.Id)
|
||||
.ToList();
|
||||
var fss = await uow.Set<FollowedStream>()
|
||||
.AsQueryable()
|
||||
.Where(x => x.GuildId == guildId)
|
||||
.OrderBy(x => x.Id)
|
||||
.ToListAsyncEF();
|
||||
|
||||
// out of range
|
||||
if (fss.Count <= index)
|
||||
|
@ -454,7 +472,9 @@ public sealed class StreamNotificationService : IEService, IReadyExecutor
|
|||
FollowedStream fs;
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var gc = uow.GuildConfigsForId(guildId, set => set.Include(x => x.FollowedStreams));
|
||||
var followedStreams = await uow.Set<FollowedStream>()
|
||||
.Where(x => x.GuildId == guildId)
|
||||
.ToListAsyncEF();
|
||||
|
||||
// add it to the database
|
||||
fs = new()
|
||||
|
@ -467,10 +487,10 @@ public sealed class StreamNotificationService : IEService, IReadyExecutor
|
|||
|
||||
var config = _config.Data;
|
||||
if (config.FollowedStreams.MaxCount is not -1
|
||||
&& gc.FollowedStreams.Count >= config.FollowedStreams.MaxCount)
|
||||
&& followedStreams.Count >= config.FollowedStreams.MaxCount)
|
||||
return null;
|
||||
|
||||
gc.FollowedStreams.Add(fs);
|
||||
uow.Add(fs);
|
||||
await uow.SaveChangesAsync();
|
||||
|
||||
// add it to the local cache of tracked streams
|
||||
|
@ -529,13 +549,27 @@ public sealed class StreamNotificationService : IEService, IReadyExecutor
|
|||
private string GetText(ulong guildId, LocStr str)
|
||||
=> _strings.GetText(str, guildId);
|
||||
|
||||
public bool ToggleStreamOffline(ulong guildId)
|
||||
public async Task<bool> ToggleStreamOffline(ulong guildId)
|
||||
{
|
||||
bool newValue;
|
||||
using var uow = _db.GetDbContext();
|
||||
var gc = uow.GuildConfigsForId(guildId, set => set);
|
||||
newValue = gc.NotifyStreamOffline = !gc.NotifyStreamOffline;
|
||||
uow.SaveChanges();
|
||||
await using var uow = _db.GetDbContext();
|
||||
await uow.GetTable<GuildConfig>()
|
||||
.InsertOrUpdateAsync(() => new()
|
||||
{
|
||||
GuildId = guildId,
|
||||
},
|
||||
(old) => new()
|
||||
{
|
||||
NotifyStreamOffline = !old.NotifyStreamOffline
|
||||
},
|
||||
() => new()
|
||||
{
|
||||
GuildId = guildId
|
||||
});
|
||||
|
||||
var newValue = await uow.GetTable<GuildConfig>()
|
||||
.Where(x => x.GuildId == guildId)
|
||||
.Select(x => x.NotifyStreamOffline)
|
||||
.FirstOrDefaultAsyncLinqToDB();
|
||||
|
||||
if (newValue)
|
||||
_offlineNotificationServers.Add(guildId);
|
||||
|
@ -545,12 +579,27 @@ public sealed class StreamNotificationService : IEService, IReadyExecutor
|
|||
return newValue;
|
||||
}
|
||||
|
||||
public bool ToggleStreamOnlineDelete(ulong guildId)
|
||||
public async Task<bool> ToggleStreamOnlineDelete(ulong guildId)
|
||||
{
|
||||
using var uow = _db.GetDbContext();
|
||||
var gc = uow.GuildConfigsForId(guildId, set => set);
|
||||
var newValue = gc.DeleteStreamOnlineMessage = !gc.DeleteStreamOnlineMessage;
|
||||
uow.SaveChanges();
|
||||
await using var uow = _db.GetDbContext();
|
||||
await uow.GetTable<GuildConfig>()
|
||||
.InsertOrUpdateAsync(() => new()
|
||||
{
|
||||
GuildId = guildId,
|
||||
},
|
||||
(old) => new()
|
||||
{
|
||||
DeleteStreamOnlineMessage = !old.DeleteStreamOnlineMessage
|
||||
},
|
||||
() => new()
|
||||
{
|
||||
GuildId = guildId
|
||||
});
|
||||
|
||||
var newValue = await uow.GetTable<GuildConfig>()
|
||||
.Where(x => x.GuildId == guildId)
|
||||
.Select(x => x.DeleteStreamOnlineMessage)
|
||||
.FirstOrDefaultAsyncLinqToDB();
|
||||
|
||||
if (newValue)
|
||||
_deleteOnOfflineServers.Add(guildId);
|
||||
|
@ -650,13 +699,13 @@ public sealed class StreamNotificationService : IEService, IReadyExecutor
|
|||
|
||||
public async Task<List<FollowedStream>> GetAllStreamsAsync(SocketGuild guild)
|
||||
{
|
||||
var allStreams = new List<FollowedStream>();
|
||||
await using var uow = _db.GetDbContext();
|
||||
var all = uow.GuildConfigsForId(guild.Id, set => set.Include(gc => gc.FollowedStreams))
|
||||
.FollowedStreams
|
||||
.OrderBy(x => x.Id)
|
||||
.ToList();
|
||||
var all = await uow.Set<FollowedStream>()
|
||||
.Where(x => x.GuildId == guild.Id)
|
||||
.OrderBy(x => x.Id)
|
||||
.ToListAsyncEF();
|
||||
|
||||
var allStreams = new List<FollowedStream>();
|
||||
for (var index = all.Count - 1; index >= 0; index--)
|
||||
{
|
||||
var fs = all[index];
|
||||
|
|
|
@ -48,7 +48,7 @@ public sealed partial class FlagTranslateService : IReadyExecutor, IEService
|
|||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
_enabledChannels = (await uow.GetTable<FlagTranslateChannel>()
|
||||
.Where(x => Linq2DbExpressions.GuildOnShard(x.GuildId,
|
||||
.Where(x => Queries.GuildOnShard(x.GuildId,
|
||||
_creds.TotalShards,
|
||||
_client.ShardId))
|
||||
.Select(x => new
|
||||
|
|
|
@ -35,7 +35,9 @@ public sealed class TranslateService : ITranslateService, IExecNoCommand, IReady
|
|||
List<AutoTranslateChannel> cs;
|
||||
await using (var ctx = _db.GetDbContext())
|
||||
{
|
||||
var guilds = _bot.AllGuildConfigs.Select(x => x.GuildId).ToList();
|
||||
var guilds = await ctx.GetTable<GuildConfig>()
|
||||
.Select(x => x.GuildId)
|
||||
.ToListAsyncLinqToDB();
|
||||
cs = await ctx.Set<AutoTranslateChannel>().Include(x => x.Users)
|
||||
.Where(x => guilds.Contains(x.GuildId))
|
||||
.ToListAsyncEF();
|
||||
|
@ -106,8 +108,8 @@ public sealed class TranslateService : ITranslateService, IExecNoCommand, IReady
|
|||
{
|
||||
await using var ctx = _db.GetDbContext();
|
||||
|
||||
var old = await ctx.Set<AutoTranslateChannel>().ToLinqToDBTable()
|
||||
.FirstOrDefaultAsyncLinqToDB(x => x.ChannelId == channelId);
|
||||
var old = await ctx.Set<AutoTranslateChannel>()
|
||||
.FirstOrDefaultAsyncEF(x => x.ChannelId == channelId);
|
||||
|
||||
if (old is null)
|
||||
{
|
||||
|
|
|
@ -3,7 +3,7 @@ using EllieBot.Db.Models;
|
|||
|
||||
namespace EllieBot.Modules.Searches.Common;
|
||||
|
||||
public readonly struct StreamDataKey
|
||||
public readonly record struct StreamDataKey
|
||||
{
|
||||
public FollowedStream.FType Type { get; init; }
|
||||
public string Name { get; init; }
|
||||
|
|
|
@ -24,7 +24,7 @@ public partial class Utility
|
|||
[UserPerm(GuildPerm.Administrator)]
|
||||
public async Task AliasesClear()
|
||||
{
|
||||
var count = _service.ClearAliases(ctx.Guild.Id);
|
||||
var count = await _service.ClearAliases(ctx.Guild.Id);
|
||||
await Response().Confirm(strs.aliases_cleared(count)).SendAsync();
|
||||
}
|
||||
|
||||
|
@ -40,64 +40,17 @@ public partial class Utility
|
|||
|
||||
if (string.IsNullOrWhiteSpace(mapping))
|
||||
{
|
||||
if (!_service.AliasMaps.TryGetValue(ctx.Guild.Id, out var maps) || !maps.TryRemove(trigger, out _))
|
||||
if (!await _service.RemoveAliasAsync(ctx.Guild.Id, trigger))
|
||||
{
|
||||
await Response().Error(strs.alias_remove_fail(Format.Code(trigger))).SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var config = uow.GuildConfigsForId(ctx.Guild.Id, set => set.Include(x => x.CommandAliases));
|
||||
var tr = config.CommandAliases.FirstOrDefault(x => x.Trigger == trigger);
|
||||
if (tr is not null)
|
||||
uow.Set<CommandAlias>().Remove(tr);
|
||||
uow.SaveChanges();
|
||||
}
|
||||
|
||||
await Response().Confirm(strs.alias_removed(Format.Code(trigger))).SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
_service.AliasMaps.AddOrUpdate(ctx.Guild.Id,
|
||||
_ =>
|
||||
{
|
||||
using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var config = uow.GuildConfigsForId(ctx.Guild.Id, set => set.Include(x => x.CommandAliases));
|
||||
config.CommandAliases.Add(new()
|
||||
{
|
||||
Mapping = mapping,
|
||||
Trigger = trigger
|
||||
});
|
||||
uow.SaveChanges();
|
||||
}
|
||||
|
||||
return new(new Dictionary<string, string>
|
||||
{
|
||||
{ trigger.Trim().ToLowerInvariant(), mapping.ToLowerInvariant() }
|
||||
});
|
||||
},
|
||||
(_, map) =>
|
||||
{
|
||||
using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var config = uow.GuildConfigsForId(ctx.Guild.Id, set => set.Include(x => x.CommandAliases));
|
||||
var toAdd = new CommandAlias
|
||||
{
|
||||
Mapping = mapping,
|
||||
Trigger = trigger
|
||||
};
|
||||
var toRemove = config.CommandAliases.Where(x => x.Trigger == trigger).ToArray();
|
||||
if (toRemove.Any())
|
||||
uow.RemoveRange(toRemove);
|
||||
config.CommandAliases.Add(toAdd);
|
||||
uow.SaveChanges();
|
||||
}
|
||||
|
||||
map.AddOrUpdate(trigger, mapping, (_, _) => mapping);
|
||||
return map;
|
||||
});
|
||||
await _service.AddAliasAsync(ctx.Guild.Id, trigger, mapping);
|
||||
|
||||
await Response().Confirm(strs.alias_added(Format.Code(trigger), Format.Code(mapping))).SendAsync();
|
||||
}
|
||||
|
@ -112,13 +65,14 @@ public partial class Utility
|
|||
if (page < 0)
|
||||
return;
|
||||
|
||||
if (!_service.AliasMaps.TryGetValue(ctx.Guild.Id, out var maps) || !maps.Any())
|
||||
var aliases = await _service.GetAliasesAsync(ctx.Guild.Id);
|
||||
if (aliases is null || aliases.Count == 0)
|
||||
{
|
||||
await Response().Error(strs.aliases_none).SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
var arr = maps.ToArray();
|
||||
var arr = aliases.Select(x => (Trigger: x.Key, Mapping: x.Value)).ToArray();
|
||||
|
||||
await Response()
|
||||
.Paginated()
|
||||
|
@ -130,7 +84,7 @@ public partial class Utility
|
|||
return CreateEmbed()
|
||||
.WithOkColor()
|
||||
.WithTitle(GetText(strs.alias_list))
|
||||
.WithDescription(string.Join("\n", items.Select(x => $"`{x.Key}` => `{x.Value}`")));
|
||||
.WithDescription(string.Join("\n", items.Select(x => $"`{x.Trigger}` => `{x.Mapping}`")));
|
||||
})
|
||||
.SendAsync();
|
||||
}
|
||||
|
|
|
@ -1,54 +1,47 @@
|
|||
#nullable disable
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using LinqToDB;
|
||||
using LinqToDB.EntityFrameworkCore;
|
||||
using EllieBot.Common.ModuleBehaviors;
|
||||
using EllieBot.Db.Models;
|
||||
|
||||
namespace EllieBot.Modules.Utility.Services;
|
||||
|
||||
public class AliasService : IInputTransformer, IEService
|
||||
public class AliasService : IInputTransformer, IReadyExecutor, IEService
|
||||
{
|
||||
public ConcurrentDictionary<ulong, ConcurrentDictionary<string, string>> AliasMaps { get; } = new();
|
||||
private ConcurrentDictionary<ulong, ConcurrentDictionary<string, string>> _aliases = new();
|
||||
|
||||
private readonly DbService _db;
|
||||
private readonly IMessageSenderService _sender;
|
||||
private readonly ShardData _shardData;
|
||||
|
||||
public AliasService(
|
||||
DiscordSocketClient client,
|
||||
DbService db,
|
||||
IMessageSenderService sender)
|
||||
IMessageSenderService sender,
|
||||
ShardData shardData)
|
||||
{
|
||||
_sender = sender;
|
||||
_shardData = shardData;
|
||||
|
||||
using var uow = db.GetDbContext();
|
||||
var guildIds = client.Guilds.Select(x => x.Id).ToList();
|
||||
var configs = uow.Set<GuildConfig>()
|
||||
.Include(gc => gc.CommandAliases)
|
||||
.Where(x => guildIds.Contains(x.GuildId))
|
||||
.ToList();
|
||||
|
||||
AliasMaps = new(configs.ToDictionary(x => x.GuildId,
|
||||
x => new ConcurrentDictionary<string, string>(x.CommandAliases.DistinctBy(ca => ca.Trigger)
|
||||
.ToDictionary(ca => ca.Trigger, ca => ca.Mapping),
|
||||
StringComparer.OrdinalIgnoreCase)));
|
||||
|
||||
_db = db;
|
||||
}
|
||||
|
||||
public int ClearAliases(ulong guildId)
|
||||
public async Task<int> ClearAliases(ulong guildId)
|
||||
{
|
||||
AliasMaps.TryRemove(guildId, out _);
|
||||
_aliases.TryRemove(guildId, out _);
|
||||
|
||||
int count;
|
||||
using var uow = _db.GetDbContext();
|
||||
var gc = uow.GuildConfigsForId(guildId, set => set.Include(x => x.CommandAliases));
|
||||
count = gc.CommandAliases.Count;
|
||||
gc.CommandAliases.Clear();
|
||||
uow.SaveChanges();
|
||||
return count;
|
||||
await using var uow = _db.GetDbContext();
|
||||
|
||||
var deleted = await uow.GetTable<CommandAlias>()
|
||||
.Where(x => x.GuildId == guildId)
|
||||
.DeleteAsync();
|
||||
|
||||
return deleted;
|
||||
}
|
||||
|
||||
public async Task<string> TransformInput(
|
||||
IGuild guild,
|
||||
public async Task<string?> TransformInput(
|
||||
IGuild? guild,
|
||||
IMessageChannel channel,
|
||||
IUser user,
|
||||
string input)
|
||||
|
@ -56,39 +49,47 @@ public class AliasService : IInputTransformer, IEService
|
|||
if (guild is null || string.IsNullOrWhiteSpace(input))
|
||||
return null;
|
||||
|
||||
if (AliasMaps.TryGetValue(guild.Id, out var maps))
|
||||
if (_aliases.TryGetValue(guild.Id, out var maps))
|
||||
{
|
||||
string newInput = null;
|
||||
foreach (var (k, v) in maps)
|
||||
string? newInput = null;
|
||||
|
||||
if (maps.TryGetValue(input, out var alias))
|
||||
{
|
||||
if (string.Equals(input, k, StringComparison.OrdinalIgnoreCase))
|
||||
newInput = alias;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var (k, v) in maps)
|
||||
{
|
||||
newInput = v;
|
||||
if (string.Equals(input, k, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
newInput = v;
|
||||
}
|
||||
else if (input.StartsWith(k + ' ', StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (v.Contains("%target%"))
|
||||
newInput = v.Replace("%target%", input[k.Length..]);
|
||||
else
|
||||
newInput = v + ' ' + input[k.Length..];
|
||||
}
|
||||
}
|
||||
else if (input.StartsWith(k + ' ', StringComparison.OrdinalIgnoreCase))
|
||||
}
|
||||
|
||||
if (newInput is not null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (v.Contains("%target%"))
|
||||
newInput = v.Replace("%target%", input[k.Length..]);
|
||||
else
|
||||
newInput = v + ' ' + input[k.Length..];
|
||||
var toDelete = await _sender.Response(channel)
|
||||
.Confirm($"{input} => {newInput}")
|
||||
.SendAsync();
|
||||
toDelete.DeleteAfter(1.5f);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
if (newInput is not null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var toDelete = await _sender.Response(channel)
|
||||
.Confirm($"{input} => {newInput}")
|
||||
.SendAsync();
|
||||
toDelete.DeleteAfter(1.5f);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
return newInput;
|
||||
}
|
||||
return newInput;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -96,4 +97,71 @@ public class AliasService : IInputTransformer, IEService
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task OnReadyAsync()
|
||||
{
|
||||
await using var ctx = _db.GetDbContext();
|
||||
|
||||
var aliases = ctx.GetTable<CommandAlias>()
|
||||
.Where(x => Queries.GuildOnShard(x.GuildId,
|
||||
_shardData.TotalShards,
|
||||
_shardData.ShardId))
|
||||
.ToList();
|
||||
|
||||
_aliases = new();
|
||||
foreach (var alias in aliases)
|
||||
{
|
||||
_aliases.GetOrAdd(alias.GuildId, _ => new(StringComparer.OrdinalIgnoreCase))
|
||||
.TryAdd(alias.Trigger, alias.Mapping);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> RemoveAliasAsync(ulong guildId, string trigger)
|
||||
{
|
||||
await using var ctx = _db.GetDbContext();
|
||||
|
||||
var deleted = await ctx.GetTable<CommandAlias>()
|
||||
.Where(x => x.GuildId == guildId && x.Trigger == trigger)
|
||||
.DeleteAsync();
|
||||
|
||||
if (_aliases.TryGetValue(guildId, out var aliases))
|
||||
aliases.TryRemove(trigger, out _);
|
||||
|
||||
return deleted > 0;
|
||||
}
|
||||
|
||||
public async Task AddAliasAsync(ulong guildId, string trigger, string mapping)
|
||||
{
|
||||
await using var ctx = _db.GetDbContext();
|
||||
|
||||
await ctx.GetTable<CommandAlias>()
|
||||
.InsertOrUpdateAsync(() => new()
|
||||
{
|
||||
GuildId = guildId,
|
||||
Trigger = trigger,
|
||||
Mapping = mapping,
|
||||
},
|
||||
(old) => new()
|
||||
{
|
||||
Mapping = mapping
|
||||
},
|
||||
() => new()
|
||||
{
|
||||
GuildId = guildId,
|
||||
Trigger = trigger,
|
||||
});
|
||||
|
||||
var guildDict = _aliases.GetOrAdd(guildId, (_) => new());
|
||||
guildDict[trigger] = mapping;
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyDictionary<string, string>?> GetAliasesAsync(ulong guildId)
|
||||
{
|
||||
await Task.Yield();
|
||||
|
||||
if (_aliases.TryGetValue(guildId, out var aliases))
|
||||
return aliases;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -94,7 +94,7 @@ public sealed class GiveawayService : IEService, IReadyExecutor
|
|||
|
||||
var gas = await ctx
|
||||
.GetTable<GiveawayModel>()
|
||||
.Where(x => Linq2DbExpressions.GuildOnShard(x.GuildId, _creds.TotalShards, _client.ShardId))
|
||||
.Where(x => Queries.GuildOnShard(x.GuildId, _creds.TotalShards, _client.ShardId))
|
||||
.ToArrayAsync();
|
||||
|
||||
lock (_giveawayCache)
|
||||
|
|
|
@ -93,7 +93,7 @@ public class RemindService : IEService, IReadyExecutor, IRemindService
|
|||
await using var uow = _db.GetDbContext();
|
||||
var earliest = await uow.Set<Reminder>()
|
||||
.ToLinqToDBTable()
|
||||
.Where(x => Linq2DbExpressions.GuildOnShard(x.ServerId,
|
||||
.Where(x => Queries.GuildOnShard(x.ServerId,
|
||||
_creds.TotalShards,
|
||||
_client.ShardId))
|
||||
.OrderBy(x => x.When)
|
||||
|
@ -116,7 +116,7 @@ public class RemindService : IEService, IReadyExecutor, IRemindService
|
|||
|
||||
var reminders = await uow.Set<Reminder>()
|
||||
.ToLinqToDBTable()
|
||||
.Where(x => Linq2DbExpressions.GuildOnShard(x.ServerId,
|
||||
.Where(x => Queries.GuildOnShard(x.ServerId,
|
||||
_creds.TotalShards,
|
||||
_client.ShardId))
|
||||
.Where(x => x.When <= now)
|
||||
|
|
|
@ -3,6 +3,7 @@ using EllieBot.Modules.Utility.Common;
|
|||
using EllieBot.Modules.Utility.Common.Exceptions;
|
||||
using EllieBot.Db.Models;
|
||||
using System.Net;
|
||||
using LinqToDB.EntityFrameworkCore;
|
||||
|
||||
namespace EllieBot.Modules.Utility.Services;
|
||||
|
||||
|
@ -10,26 +11,19 @@ public class StreamRoleService : IReadyExecutor, IEService
|
|||
{
|
||||
private readonly DbService _db;
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly ConcurrentDictionary<ulong, StreamRoleSettings> _guildSettings;
|
||||
private readonly QueueRunner _queueRunner;
|
||||
private ConcurrentDictionary<ulong, StreamRoleSettings> _guildSettings = new();
|
||||
private QueueRunner _queueRunner;
|
||||
|
||||
public StreamRoleService(DiscordSocketClient client, DbService db, IBot bot)
|
||||
public StreamRoleService(DiscordSocketClient client, DbService db)
|
||||
{
|
||||
_db = db;
|
||||
_client = client;
|
||||
|
||||
_guildSettings = bot.AllGuildConfigs.ToDictionary(x => x.GuildId, x => x.StreamRole)
|
||||
.Where(x => x.Value is { Enabled: true })
|
||||
.ToConcurrent();
|
||||
|
||||
_client.PresenceUpdated += OnPresenceUpdate;
|
||||
|
||||
_queueRunner = new QueueRunner();
|
||||
}
|
||||
|
||||
private Task OnPresenceUpdate(SocketUser user, SocketPresence? oldPresence, SocketPresence? newPresence)
|
||||
{
|
||||
|
||||
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
if (oldPresence?.Activities?.Count != newPresence?.Activities?.Count)
|
||||
|
@ -49,8 +43,21 @@ public class StreamRoleService : IReadyExecutor, IEService
|
|||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task OnReadyAsync()
|
||||
=> Task.WhenAll(_client.Guilds.Select(RescanUsers).WhenAll(), _queueRunner.RunAsync());
|
||||
public async Task OnReadyAsync()
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
|
||||
_guildSettings = await uow.GetTable<StreamRoleSettings>()
|
||||
.Where(x => x.Enabled)
|
||||
.ToDictionaryAsyncLinqToDB(x => x.GuildId, x => x)
|
||||
.Fmap(x => x.ToConcurrent());
|
||||
|
||||
_client.PresenceUpdated += OnPresenceUpdate;
|
||||
|
||||
|
||||
|
||||
await Task.WhenAll(_client.Guilds.Select(RescanUsers).WhenAll(), _queueRunner.RunAsync());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds or removes a user from a blacklist or a whitelist in the specified guild.
|
||||
|
@ -73,7 +80,7 @@ public class StreamRoleService : IReadyExecutor, IEService
|
|||
var success = false;
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var streamRoleSettings = uow.GetStreamRoleSettings(guild.Id);
|
||||
var streamRoleSettings = await uow.GetOrCreateStreamRoleSettings(guild.Id);
|
||||
|
||||
if (listType == StreamRoleListType.Whitelist)
|
||||
{
|
||||
|
@ -93,7 +100,9 @@ public class StreamRoleService : IReadyExecutor, IEService
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
success = streamRoleSettings.Whitelist.Add(userObj);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -110,7 +119,9 @@ public class StreamRoleService : IReadyExecutor, IEService
|
|||
success = streamRoleSettings.Blacklist.Remove(toRemove);
|
||||
}
|
||||
else
|
||||
{
|
||||
success = streamRoleSettings.Blacklist.Add(userObj);
|
||||
}
|
||||
}
|
||||
|
||||
await uow.SaveChangesAsync();
|
||||
|
@ -134,7 +145,7 @@ public class StreamRoleService : IReadyExecutor, IEService
|
|||
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var streamRoleSettings = uow.GetStreamRoleSettings(guild.Id);
|
||||
var streamRoleSettings = await uow.GetOrCreateStreamRoleSettings(guild.Id);
|
||||
|
||||
streamRoleSettings.Keyword = keyword;
|
||||
UpdateCache(guild.Id, streamRoleSettings);
|
||||
|
@ -150,15 +161,15 @@ public class StreamRoleService : IReadyExecutor, IEService
|
|||
/// </summary>
|
||||
/// <param name="guildId">Guild Id</param>
|
||||
/// <returns>The keyword set</returns>
|
||||
public string GetKeyword(ulong guildId)
|
||||
public async Task<string> GetKeyword(ulong guildId)
|
||||
{
|
||||
if (_guildSettings.TryGetValue(guildId, out var outSetting))
|
||||
return outSetting.Keyword;
|
||||
|
||||
StreamRoleSettings setting;
|
||||
using (var uow = _db.GetDbContext())
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
setting = uow.GetStreamRoleSettings(guildId);
|
||||
setting = await uow.GetOrCreateStreamRoleSettings(guildId);
|
||||
}
|
||||
|
||||
UpdateCache(guildId, setting);
|
||||
|
@ -180,7 +191,7 @@ public class StreamRoleService : IReadyExecutor, IEService
|
|||
StreamRoleSettings setting;
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var streamRoleSettings = uow.GetStreamRoleSettings(fromRole.Guild.Id);
|
||||
var streamRoleSettings = await uow.GetOrCreateStreamRoleSettings(fromRole.Guild.Id);
|
||||
|
||||
streamRoleSettings.Enabled = true;
|
||||
streamRoleSettings.AddRoleId = addRole.Id;
|
||||
|
@ -207,7 +218,7 @@ public class StreamRoleService : IReadyExecutor, IEService
|
|||
{
|
||||
await using (var uow = _db.GetDbContext())
|
||||
{
|
||||
var streamRoleSettings = uow.GetStreamRoleSettings(guild.Id);
|
||||
var streamRoleSettings = await uow.GetOrCreateStreamRoleSettings(guild.Id);
|
||||
streamRoleSettings.Enabled = false;
|
||||
streamRoleSettings.AddRoleId = 0;
|
||||
streamRoleSettings.FromRoleId = 0;
|
||||
|
|
|
@ -699,7 +699,7 @@ public partial class Utility : EllieModule
|
|||
[UserPerm(GuildPerm.ManageMessages)]
|
||||
public async Task VerboseError(bool? newstate = null)
|
||||
{
|
||||
var state = _veService.ToggleVerboseErrors(ctx.Guild.Id, newstate);
|
||||
var state = await _veService.ToggleVerboseErrors(ctx.Guild.Id, newstate);
|
||||
|
||||
if (state)
|
||||
await Response().Confirm(strs.verbose_errors_enabled).SendAsync();
|
||||
|
|
|
@ -1,29 +1,31 @@
|
|||
#nullable disable
|
||||
using LinqToDB.EntityFrameworkCore;
|
||||
using EllieBot.Common.ModuleBehaviors;
|
||||
using EllieBot.Db.Models;
|
||||
|
||||
namespace EllieBot.Modules.Utility.Services;
|
||||
|
||||
public class VerboseErrorsService : IEService
|
||||
public class VerboseErrorsService : IReadyExecutor, IEService
|
||||
{
|
||||
private readonly ConcurrentHashSet<ulong> _guildsDisabled;
|
||||
private readonly ConcurrentHashSet<ulong> _guildsDisabled = [];
|
||||
private readonly DbService _db;
|
||||
private readonly CommandHandler _ch;
|
||||
private readonly ICommandsUtilityService _hs;
|
||||
private readonly IMessageSenderService _sender;
|
||||
private readonly ShardData _shardData;
|
||||
|
||||
public VerboseErrorsService(
|
||||
IBot bot,
|
||||
DbService db,
|
||||
CommandHandler ch,
|
||||
IMessageSenderService sender,
|
||||
ICommandsUtilityService hs)
|
||||
ICommandsUtilityService hs,
|
||||
ShardData shardData)
|
||||
{
|
||||
_db = db;
|
||||
_ch = ch;
|
||||
_hs = hs;
|
||||
_sender = sender;
|
||||
|
||||
_ch.CommandErrored += LogVerboseError;
|
||||
|
||||
_guildsDisabled = new(bot.AllGuildConfigs.Where(x => !x.VerboseErrors).Select(x => x.GuildId));
|
||||
_shardData = shardData;
|
||||
}
|
||||
|
||||
private async Task LogVerboseError(CommandInfo cmd, ITextChannel channel, string reason)
|
||||
|
@ -48,23 +50,37 @@ public class VerboseErrorsService : IEService
|
|||
}
|
||||
}
|
||||
|
||||
public bool ToggleVerboseErrors(ulong guildId, bool? maybeEnabled = null)
|
||||
public async Task<bool> ToggleVerboseErrors(ulong guildId, bool? maybeEnabled = null)
|
||||
{
|
||||
using var uow = _db.GetDbContext();
|
||||
var gc = uow.GuildConfigsForId(guildId, set => set);
|
||||
await using var ctx = _db.GetDbContext();
|
||||
|
||||
if (maybeEnabled is bool isEnabled) // set it
|
||||
gc.VerboseErrors = isEnabled;
|
||||
else // toggle it
|
||||
isEnabled = gc.VerboseErrors = !gc.VerboseErrors;
|
||||
|
||||
uow.SaveChanges();
|
||||
var isEnabled = ctx.GetTable<GuildConfig>()
|
||||
.Where(x => x.GuildId == guildId)
|
||||
.Select(x => x.VerboseErrors)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (isEnabled) // This doesn't need to be duplicated inside the using block
|
||||
{
|
||||
_guildsDisabled.TryRemove(guildId);
|
||||
}
|
||||
else
|
||||
{
|
||||
_guildsDisabled.Add(guildId);
|
||||
}
|
||||
|
||||
return isEnabled;
|
||||
}
|
||||
|
||||
public async Task OnReadyAsync()
|
||||
{
|
||||
await using var ctx = _db.GetDbContext();
|
||||
var disabledOn = ctx.GetTable<GuildConfig>()
|
||||
.Where(x => Queries.GuildOnShard(x.GuildId, _shardData.TotalShards, _shardData.ShardId) && !x.VerboseErrors)
|
||||
.Select(x => x.GuildId);
|
||||
|
||||
foreach (var guildId in disabledOn)
|
||||
_guildsDisabled.Add(guildId);
|
||||
|
||||
_ch.CommandErrored += LogVerboseError;
|
||||
}
|
||||
}
|
|
@ -56,7 +56,7 @@ public partial class Xp : EllieModule<XpService>
|
|||
[UserPerm(GuildPerm.Administrator)]
|
||||
public async Task XpExclude(Server _)
|
||||
{
|
||||
var ex = _service.ToggleExcludeServer(ctx.Guild.Id);
|
||||
var ex = await _service.ToggleExcludeServerAsync(ctx.Guild.Id);
|
||||
|
||||
if (ex)
|
||||
await Response().Confirm(strs.excluded(Format.Bold(ctx.Guild.ToString()))).SendAsync();
|
||||
|
@ -69,7 +69,7 @@ public partial class Xp : EllieModule<XpService>
|
|||
[RequireContext(ContextType.Guild)]
|
||||
public async Task XpExclude(Role _, [Leftover] IRole role)
|
||||
{
|
||||
var ex = _service.ToggleExcludeRole(ctx.Guild.Id, role.Id);
|
||||
var ex = await _service.ToggleExcludeRoleAsync(ctx.Guild.Id, role.Id);
|
||||
|
||||
if (ex)
|
||||
await Response().Confirm(strs.excluded(Format.Bold(role.ToString()))).SendAsync();
|
||||
|
@ -85,7 +85,7 @@ public partial class Xp : EllieModule<XpService>
|
|||
if (channel is null)
|
||||
channel = ctx.Channel;
|
||||
|
||||
var ex = _service.ToggleExcludeChannel(ctx.Guild.Id, channel.Id);
|
||||
var ex = await _service.ToggleExcludeChannelAsync(ctx.Guild.Id, channel.Id);
|
||||
|
||||
if (ex)
|
||||
await Response().Confirm(strs.excluded(Format.Bold(channel.ToString()))).SendAsync();
|
||||
|
@ -308,7 +308,7 @@ public partial class Xp : EllieModule<XpService>
|
|||
if (amount == 0)
|
||||
return;
|
||||
|
||||
_service.AddXp(userId, ctx.Guild.Id, amount);
|
||||
await _service.AddXpAsync(userId, ctx.Guild.Id, amount);
|
||||
var usr = ((SocketGuild)ctx.Guild).GetUser(userId)?.ToString() ?? userId.ToString();
|
||||
await Response().Confirm(strs.modified(Format.Bold(usr), Format.Bold(amount.ToString()))).SendAsync();
|
||||
}
|
||||
|
@ -455,7 +455,7 @@ public partial class Xp : EllieModule<XpService>
|
|||
if (!string.IsNullOrWhiteSpace(item.Desc))
|
||||
eb.AddField(GetText(strs.desc), item.Desc);
|
||||
|
||||
#if GLOBAL_ELLIE
|
||||
#if GLOBAL_NADEKO
|
||||
if (key == "default")
|
||||
eb.WithDescription(GetText(strs.xpshop_website));
|
||||
#endif
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue