elliebot/src/Ellie.Bot.Common/Services/Impl/BlacklistService.cs
2023-07-15 22:25:21 +12:00

136 lines
No EOL
3.8 KiB
C#

#nullable disable
using LinqToDB;
using LinqToDB.EntityFrameworkCore;
using Ellie.Common.ModuleBehaviors;
using Ellie.Db;
using Ellie.Db.Models;
using Ellie.Services.Database.Models;
namespace Ellie.Modules.Permissions.Services;
public sealed class BlacklistService : IExecOnMessage
{
public int Priority
=> int.MaxValue;
private readonly DbService _db;
private readonly IPubSub _pubSub;
private readonly IBotCredentials _creds;
private IReadOnlyList<BlacklistEntry> blacklist;
private readonly TypedKey<BlacklistEntry[]> _blPubKey = new("blacklist.reload");
public BlacklistService(DbService db, IPubSub pubSub, IBotCredentials creds)
{
_db = db;
_pubSub = pubSub;
_creds = creds;
Reload(false);
_pubSub.Sub(_blPubKey, OnReload);
}
private ValueTask OnReload(BlacklistEntry[] newBlacklist)
{
blacklist = newBlacklist;
return default;
}
public Task<bool> ExecOnMessageAsync(IGuild guild, IUserMessage usrMsg)
{
foreach (var bl in blacklist)
{
if (guild is not null && bl.Type == BlacklistType.Server && bl.ItemId == guild.Id)
{
Log.Information("Blocked input from blacklisted guild: {GuildName} [{GuildId}]", guild.Name, guild.Id);
return Task.FromResult(true);
}
if (bl.Type == BlacklistType.Channel && bl.ItemId == usrMsg.Channel.Id)
{
Log.Information("Blocked input from blacklisted channel: {ChannelName} [{ChannelId}]",
usrMsg.Channel.Name,
usrMsg.Channel.Id);
return Task.FromResult(true);
}
if (bl.Type == BlacklistType.User && bl.ItemId == usrMsg.Author.Id)
{
Log.Information("Blocked input from blacklisted user: {UserName} [{UserId}]",
usrMsg.Author.ToString(),
usrMsg.Author.Id);
return Task.FromResult(true);
}
}
return Task.FromResult(false);
}
public IReadOnlyList<BlacklistEntry> GetBlacklist()
=> blacklist;
public void Reload(bool publish = true)
{
using var uow = _db.GetDbContext();
var toPublish = uow.GetTable<BlacklistEntry>().ToArray();
blacklist = toPublish;
if (publish)
_pubSub.Pub(_blPubKey, toPublish);
}
public async Task Blacklist(BlacklistType type, ulong id)
{
if (_creds.OwnerIds.Contains(id))
return;
await using var uow = _db.GetDbContext();
await uow
.GetTable<BlacklistEntry>()
.InsertAsync(() => new()
{
ItemId = id,
Type = type,
});
Reload();
}
public async Task UnBlacklist(BlacklistType type, ulong id)
{
await using var uow = _db.GetDbContext();
await uow.GetTable<BlacklistEntry>()
.Where(bi => bi.ItemId == id && bi.Type == type)
.DeleteAsync();
Reload();
}
public void BlacklistUsers(IReadOnlyCollection<ulong> toBlacklist)
{
using (var uow = _db.GetDbContext())
{
var bc = uow.Set<BlacklistEntry>();
bc.AddRange(toBlacklist.Select(x => new BlacklistEntry
{
ItemId = x,
Type = BlacklistType.User
}));
// todo check if blacklist works and removes currency
uow.GetTable<DiscordUser>()
.UpdateAsync(x => toBlacklist.Contains(x.UserId),
_ => new()
{
CurrencyAmount = 0
});
uow.SaveChanges();
}
Reload();
}
}