mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-10 17:28:27 -04:00
add: Added .honeypot command
fix: Fixed .betdraw not respecting max bet limit
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
using LinqToDB;
|
||||
using LinqToDB.EntityFrameworkCore;
|
||||
using NadekoBot.Common.ModuleBehaviors;
|
||||
using NadekoBot.Db.Models;
|
||||
using System.Threading.Channels;
|
||||
|
||||
namespace NadekoBot.Modules.Administration.Honeypot;
|
||||
|
||||
public sealed class HoneyPotService : IHoneyPotService, IReadyExecutor, IExecNoCommand, INService
|
||||
{
|
||||
private readonly DbService _db;
|
||||
private readonly CommandHandler _handler;
|
||||
|
||||
private ConcurrentHashSet<ulong> _channels = new();
|
||||
|
||||
private Channel<SocketGuildUser> _punishments = Channel.CreateBounded<SocketGuildUser>(
|
||||
new BoundedChannelOptions(100)
|
||||
{
|
||||
FullMode = BoundedChannelFullMode.DropOldest,
|
||||
SingleReader = true,
|
||||
SingleWriter = false,
|
||||
});
|
||||
|
||||
public HoneyPotService(DbService db, CommandHandler handler)
|
||||
{
|
||||
_db = db;
|
||||
_handler = handler;
|
||||
}
|
||||
|
||||
public async Task<bool> ToggleHoneypotChannel(ulong guildId, ulong channelId)
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
|
||||
var deleted = await uow.HoneyPotChannels
|
||||
.Where(x => x.GuildId == guildId)
|
||||
.DeleteWithOutputAsync();
|
||||
|
||||
if (deleted.Length > 0)
|
||||
{
|
||||
_channels.TryRemove(deleted[0].ChannelId);
|
||||
return false;
|
||||
}
|
||||
|
||||
await uow.HoneyPotChannels
|
||||
.ToLinqToDBTable()
|
||||
.InsertAsync(() => new HoneypotChannel
|
||||
{
|
||||
GuildId = guildId,
|
||||
ChannelId = channelId
|
||||
});
|
||||
|
||||
_channels.Add(channelId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task OnReadyAsync()
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
|
||||
var channels = await uow.HoneyPotChannels
|
||||
.Select(x => x.ChannelId)
|
||||
.ToListAsyncLinqToDB();
|
||||
|
||||
_channels = new(channels);
|
||||
|
||||
while (await _punishments.Reader.WaitToReadAsync())
|
||||
{
|
||||
while (_punishments.Reader.TryRead(out var user))
|
||||
{
|
||||
try
|
||||
{
|
||||
Log.Information("Honeypot caught user {User} [{UserId}]", user, user.Id);
|
||||
await user.BanAsync();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Warning(e, "Failed banning {User} due to {Error}", user, e.Message);
|
||||
}
|
||||
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task ExecOnNoCommandAsync(IGuild guild, IUserMessage msg)
|
||||
{
|
||||
if (_channels.Contains(msg.Channel.Id) && msg.Author is SocketGuildUser sgu)
|
||||
{
|
||||
if (!sgu.GuildPermissions.BanMembers)
|
||||
await _punishments.Writer.WriteAsync(sgu);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
using NadekoBot.Modules.Administration.Honeypot;
|
||||
|
||||
namespace NadekoBot.Modules.Administration;
|
||||
|
||||
public partial class Administration
|
||||
{
|
||||
[Group]
|
||||
public partial class HoneypotCommands : NadekoModule
|
||||
{
|
||||
private readonly IHoneyPotService _service;
|
||||
|
||||
public HoneypotCommands(IHoneyPotService service)
|
||||
=> _service = service;
|
||||
|
||||
[Cmd]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[RequireUserPermission(GuildPermission.Administrator)]
|
||||
[RequireBotPermission(GuildPermission.BanMembers)]
|
||||
public async Task Honeypot()
|
||||
{
|
||||
var enabled = await _service.ToggleHoneypotChannel(ctx.Guild.Id, ctx.Channel.Id);
|
||||
|
||||
if (enabled)
|
||||
await Response().Confirm(strs.honeypot_on).SendAsync();
|
||||
else
|
||||
await Response().Confirm(strs.honeypot_off).SendAsync();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
namespace NadekoBot.Modules.Administration.Honeypot;
|
||||
|
||||
public interface IHoneyPotService
|
||||
{
|
||||
public Task<bool> ToggleHoneypotChannel(ulong guildId, ulong channelId);
|
||||
}
|
@@ -17,7 +17,8 @@ public partial class Gambling
|
||||
private static readonly ConcurrentDictionary<IGuild, Deck> _allDecks = new();
|
||||
private readonly IImageCache _images;
|
||||
|
||||
public DrawCommands(IImageCache images, GamblingConfigService gcs) : base(gcs)
|
||||
public DrawCommands(IImageCache images, GamblingConfigService gcs)
|
||||
: base(gcs)
|
||||
=> _images = images;
|
||||
|
||||
private async Task InternalDraw(int count, ulong? guildId = null)
|
||||
@@ -56,8 +57,8 @@ public partial class Gambling
|
||||
i.Dispose();
|
||||
|
||||
var eb = _sender.CreateEmbed()
|
||||
.WithOkColor();
|
||||
|
||||
.WithOkColor();
|
||||
|
||||
var toSend = string.Empty;
|
||||
if (cardObjects.Count == 5)
|
||||
eb.AddField(GetText(strs.hand_value), Deck.GetHandValue(cardObjects), true);
|
||||
@@ -71,7 +72,7 @@ public partial class Gambling
|
||||
|
||||
if (count > 1)
|
||||
eb.AddField(GetText(strs.cards), count.ToString(), true);
|
||||
|
||||
|
||||
await using var imageStream = await img.ToStreamAsync();
|
||||
await ctx.Channel.SendFileAsync(imageStream,
|
||||
imgName,
|
||||
@@ -84,7 +85,7 @@ public partial class Gambling
|
||||
var cardBytes = await File.ReadAllBytesAsync($"data/images/cards/{cardName}.jpg");
|
||||
return Image.Load<Rgba32>(cardBytes);
|
||||
}
|
||||
|
||||
|
||||
private async Task<Image<Rgba32>> GetCardImageAsync(Deck.Card currentCard)
|
||||
{
|
||||
var cardName = currentCard.ToString().ToLowerInvariant().Replace(' ', '_');
|
||||
@@ -98,7 +99,7 @@ public partial class Gambling
|
||||
{
|
||||
if (num < 1)
|
||||
return;
|
||||
|
||||
|
||||
if (num > 10)
|
||||
num = 10;
|
||||
|
||||
@@ -110,7 +111,7 @@ public partial class Gambling
|
||||
{
|
||||
if (num < 1)
|
||||
return;
|
||||
|
||||
|
||||
if (num > 10)
|
||||
num = 10;
|
||||
|
||||
@@ -136,19 +137,29 @@ public partial class Gambling
|
||||
|
||||
[Cmd]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public Task BetDraw([OverrideTypeReader(typeof(BalanceTypeReader))] long amount, InputValueGuess val, InputColorGuess? col = null)
|
||||
public Task BetDraw(
|
||||
[OverrideTypeReader(typeof(BalanceTypeReader))]
|
||||
long amount,
|
||||
InputValueGuess val,
|
||||
InputColorGuess? col = null)
|
||||
=> BetDrawInternal(amount, val, col);
|
||||
|
||||
|
||||
[Cmd]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public Task BetDraw([OverrideTypeReader(typeof(BalanceTypeReader))] long amount, InputColorGuess col, InputValueGuess? val = null)
|
||||
public Task BetDraw(
|
||||
[OverrideTypeReader(typeof(BalanceTypeReader))]
|
||||
long amount,
|
||||
InputColorGuess col,
|
||||
InputValueGuess? val = null)
|
||||
=> BetDrawInternal(amount, val, col);
|
||||
|
||||
|
||||
public async Task BetDrawInternal(long amount, InputValueGuess? val, InputColorGuess? col)
|
||||
{
|
||||
if (amount <= 0)
|
||||
if (!await CheckBetMandatory(amount))
|
||||
{
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
var res = await _service.BetDrawAsync(ctx.User.Id,
|
||||
amount,
|
||||
(byte?)val,
|
||||
@@ -161,13 +172,13 @@ public partial class Gambling
|
||||
}
|
||||
|
||||
var eb = _sender.CreateEmbed()
|
||||
.WithOkColor()
|
||||
.WithAuthor(ctx.User)
|
||||
.WithDescription(result.Card.GetEmoji())
|
||||
.AddField(GetText(strs.guess), GetGuessInfo(val, col), true)
|
||||
.AddField(GetText(strs.card), GetCardInfo(result.Card), true)
|
||||
.AddField(GetText(strs.won), N((long)result.Won), false)
|
||||
.WithImageUrl("attachment://card.png");
|
||||
.WithOkColor()
|
||||
.WithAuthor(ctx.User)
|
||||
.WithDescription(result.Card.GetEmoji())
|
||||
.AddField(GetText(strs.guess), GetGuessInfo(val, col), true)
|
||||
.AddField(GetText(strs.card), GetCardInfo(result.Card), true)
|
||||
.AddField(GetText(strs.won), N((long)result.Won), false)
|
||||
.WithImageUrl("attachment://card.png");
|
||||
|
||||
using var img = await GetCardImageAsync(result.Card);
|
||||
await using var imgStream = await img.ToStreamAsync();
|
||||
@@ -189,9 +200,10 @@ public partial class Gambling
|
||||
InputColorGuess.Black => "B ⚫",
|
||||
_ => "❓"
|
||||
};
|
||||
|
||||
|
||||
return $"{val} / {col}";
|
||||
}
|
||||
|
||||
private string GetCardInfo(RegularCard card)
|
||||
{
|
||||
var val = (int)card.Value switch
|
||||
@@ -208,7 +220,7 @@ public partial class Gambling
|
||||
RegularSuit.Diamonds or RegularSuit.Hearts => "R 🔴",
|
||||
_ => "B ⚫"
|
||||
};
|
||||
|
||||
|
||||
return $"{val} / {col}";
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user