Compare commits

..

4 commits

15 changed files with 105 additions and 67 deletions

View file

@ -2,6 +2,8 @@
Mostly based on [keepachangelog](https://keepachangelog.com/en/1.1.0/) except date format. a-c-f-r-o Mostly based on [keepachangelog](https://keepachangelog.com/en/1.1.0/) except date format. a-c-f-r-o
## Unreleased
### Added ### Added
- Added: Added a `'afk <msg>?` command which sets an afk message which will trigger whenever someone pings you - Added: Added a `'afk <msg>?` command which sets an afk message which will trigger whenever someone pings you

View file

@ -182,16 +182,6 @@ public static class GuildConfigExtensions
.SelectMany(gc => gc.FollowedStreams) .SelectMany(gc => gc.FollowedStreams)
.ToList(); .ToList();
public static void SetCleverbotEnabled(this DbSet<GuildConfig> configs, ulong id, bool cleverbotEnabled)
{
var conf = configs.FirstOrDefault(gc => gc.GuildId == id);
if (conf is null)
return;
conf.CleverbotEnabled = cleverbotEnabled;
}
public static XpSettings XpSettingsFor(this DbContext ctx, ulong guildId) public static XpSettings XpSettingsFor(this DbContext ctx, ulong guildId)
{ {
var gc = ctx.GuildConfigsForId(guildId, var gc = ctx.GuildConfigsForId(guildId,

View file

@ -65,23 +65,6 @@ public partial class Administration
await progressMsg.DeleteAsync(); await progressMsg.DeleteAsync();
} }
private async Task SendResult(PruneResult result)
{
switch (result)
{
case PruneResult.Success:
break;
case PruneResult.AlreadyRunning:
break;
case PruneResult.FeatureLimit:
await Response().Pending(strs.feature_limit_reached_owner).SendAsync();
break;
default:
throw new ArgumentOutOfRangeException(nameof(result), result, null);
}
}
// prune x // prune x
[Cmd] [Cmd]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
@ -218,5 +201,27 @@ public partial class Administration
await Response().Confirm(strs.prune_cancelled).SendAsync(); await Response().Confirm(strs.prune_cancelled).SendAsync();
} }
private async Task SendResult(PruneResult result)
{
switch (result)
{
case PruneResult.Success:
break;
case PruneResult.AlreadyRunning:
var msg = await Response().Pending(strs.prune_already_running).SendAsync();
msg.DeleteAfter(5);
break;
case PruneResult.FeatureLimit:
var msg2 = await Response().Pending(strs.feature_limit_reached_owner).SendAsync();
msg2.DeleteAfter(10);
break;
default:
Log.Error("Unhandled result received in prune: {Result}", result);
await Response().Error(strs.error_occured).SendAsync();
break;
}
}
} }
} }

View file

@ -26,21 +26,21 @@ public class PruneService : IEService
) )
{ {
ArgumentNullException.ThrowIfNull(channel, nameof(channel)); ArgumentNullException.ThrowIfNull(channel, nameof(channel));
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(amount);
var originalAmount = amount; var originalAmount = amount;
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(amount);
using var cancelSource = new CancellationTokenSource(); using var cancelSource = new CancellationTokenSource();
if (!_pruningGuilds.TryAdd(channel.GuildId, cancelSource)) if (!_pruningGuilds.TryAdd(channel.GuildId, cancelSource))
return PruneResult.AlreadyRunning; return PruneResult.AlreadyRunning;
try
{
if (!await _ps.LimitHitAsync(LimitedFeatureName.Prune, channel.Guild.OwnerId)) if (!await _ps.LimitHitAsync(LimitedFeatureName.Prune, channel.Guild.OwnerId))
{ {
return PruneResult.FeatureLimit; return PruneResult.FeatureLimit;
} }
try
{
var now = DateTime.UtcNow; var now = DateTime.UtcNow;
IMessage[] msgs; IMessage[] msgs;
IMessage lastMessage = null; IMessage lastMessage = null;

View file

@ -18,31 +18,18 @@ public partial class Games
[Cmd] [Cmd]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
[UserPerm(GuildPerm.ManageMessages)] [UserPerm(GuildPerm.ManageMessages)]
[NoPublicBot]
public async Task CleverBot() public async Task CleverBot()
{ {
var channel = (ITextChannel)ctx.Channel; var channel = (ITextChannel)ctx.Channel;
if (_service.ChatterBotGuilds.TryRemove(channel.Guild.Id, out _)) var newState = await _service.ToggleChatterBotAsync(ctx.Guild.Id);
{
await using (var uow = _db.GetDbContext())
{
uow.Set<GuildConfig>().SetCleverbotEnabled(ctx.Guild.Id, false);
await uow.SaveChangesAsync();
}
if (!newState)
{
await Response().Confirm(strs.chatbot_disabled).SendAsync(); await Response().Confirm(strs.chatbot_disabled).SendAsync();
return; return;
} }
_service.ChatterBotGuilds.TryAdd(channel.Guild.Id, new(() => _service.CreateSession(), true));
await using (var uow = _db.GetDbContext())
{
uow.Set<GuildConfig>().SetCleverbotEnabled(ctx.Guild.Id, true);
await uow.SaveChangesAsync();
}
await Response().Confirm(strs.chatbot_enabled).SendAsync(); await Response().Confirm(strs.chatbot_enabled).SendAsync();
} }
} }

View file

@ -1,5 +1,8 @@
#nullable disable #nullable disable
using LinqToDB;
using LinqToDB.EntityFrameworkCore;
using EllieBot.Common.ModuleBehaviors; using EllieBot.Common.ModuleBehaviors;
using EllieBot.Db.Models;
using EllieBot.Modules.Games.Common; using EllieBot.Modules.Games.Common;
using EllieBot.Modules.Games.Common.ChatterBot; using EllieBot.Modules.Games.Common.ChatterBot;
using EllieBot.Modules.Patronage; using EllieBot.Modules.Patronage;
@ -9,7 +12,7 @@ namespace EllieBot.Modules.Games.Services;
public class ChatterBotService : IExecOnMessage public class ChatterBotService : IExecOnMessage
{ {
public ConcurrentDictionary<ulong, Lazy<IChatterBotSession>> ChatterBotGuilds { get; } private ConcurrentDictionary<ulong, Lazy<IChatterBotSession>> ChatterBotGuilds { get; }
public int Priority public int Priority
=> 1; => 1;
@ -20,6 +23,7 @@ public class ChatterBotService : IExecOnMessage
private readonly IHttpClientFactory _httpFactory; private readonly IHttpClientFactory _httpFactory;
private readonly GamesConfigService _gcs; private readonly GamesConfigService _gcs;
private readonly IMessageSenderService _sender; private readonly IMessageSenderService _sender;
private readonly DbService _db;
public readonly IPatronageService _ps; public readonly IPatronageService _ps;
public ChatterBotService( public ChatterBotService(
@ -30,12 +34,14 @@ public class ChatterBotService : IExecOnMessage
IHttpClientFactory factory, IHttpClientFactory factory,
IBotCredentials creds, IBotCredentials creds,
GamesConfigService gcs, GamesConfigService gcs,
IMessageSenderService sender) IMessageSenderService sender,
DbService db)
{ {
_client = client; _client = client;
_perms = perms; _perms = perms;
_creds = creds; _creds = creds;
_sender = sender; _sender = sender;
_db = db;
_httpFactory = factory; _httpFactory = factory;
_perms = perms; _perms = perms;
_gcs = gcs; _gcs = gcs;
@ -196,4 +202,38 @@ public class ChatterBotService : IExecOnMessage
return false; return false;
} }
public async Task<bool> ToggleChatterBotAsync(ulong guildId)
{
if (ChatterBotGuilds.TryRemove(guildId, out _))
{
await using var uow = _db.GetDbContext();
await uow.Set<GuildConfig>()
.ToLinqToDBTable()
.Where(x => x.GuildId == guildId)
.UpdateAsync((gc) => new GuildConfig()
{
CleverbotEnabled = false
});
await uow.SaveChangesAsync();
return false;
}
ChatterBotGuilds.TryAdd(guildId, new(() => CreateSession(), true));
await using (var uow = _db.GetDbContext())
{
await uow.Set<GuildConfig>()
.ToLinqToDBTable()
.Where(x => x.GuildId == guildId)
.UpdateAsync((gc) => new GuildConfig()
{
CleverbotEnabled = true
});
await uow.SaveChangesAsync();
}
return true;
}
} }

View file

@ -1,4 +1,5 @@
using System.Text.Json.Serialization; #nullable disable
using System.Text.Json.Serialization;
namespace EllieBot.Modules.Games.Common.ChatterBot; namespace EllieBot.Modules.Games.Common.ChatterBot;

View file

@ -1,4 +1,5 @@
using System.Text.Json.Serialization; #nullable disable
using System.Text.Json.Serialization;
namespace EllieBot.Modules.Games.Common.ChatterBot; namespace EllieBot.Modules.Games.Common.ChatterBot;

View file

@ -1,4 +1,5 @@
using System.Text.Json.Serialization; #nullable disable
using System.Text.Json.Serialization;
namespace EllieBot.Modules.Games.Common.ChatterBot; namespace EllieBot.Modules.Games.Common.ChatterBot;

View file

@ -1,4 +1,5 @@
using System.Text.Json.Serialization; #nullable disable
using System.Text.Json.Serialization;
namespace EllieBot.Modules.Games.Common.ChatterBot; namespace EllieBot.Modules.Games.Common.ChatterBot;

View file

@ -1,4 +1,5 @@
using EllieBot.Modules.Searches.Common; #nullable disable
using EllieBot.Modules.Searches.Common;
using System.Net.Http.Json; using System.Net.Http.Json;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;

View file

@ -1,5 +1,5 @@
# DO NOT CHANGE # DO NOT CHANGE
version: 7 version: 9
# Bot token. Do not share with anyone ever -> https://discordapp.com/developers/applications/ # Bot token. Do not share with anyone ever -> https://discordapp.com/developers/applications/
token: "" token: ""
# List of Ids of the users who have bot owner permissions # List of Ids of the users who have bot owner permissions

View file

@ -57,18 +57,26 @@ raceAnimals:
# Which chatbot API should bot use. # Which chatbot API should bot use.
# 'cleverbot' - bot will use Cleverbot API. # 'cleverbot' - bot will use Cleverbot API.
# 'gpt' - bot will use GPT API # 'gpt' - bot will use GPT API
chatBot: Gpt chatBot: OpenAi
chatGpt: chatGpt:
# Url to any openai api compatible url.
# Make sure to modify the modelName appropriately
# DO NOT add /v1/chat/completions suffix to the url
apiUrl: https://api.openai.com
# Which GPT Model should bot use. # Which GPT Model should bot use.
# gpt35turbo - cheapest # gpt-3.5-turbo - cheapest
# gpt4o - more expensive, higher quality # gpt-4o - more expensive, higher quality
# #
modelName: Gpt35Turbo # If you are using another openai compatible api, you may use any of the models supported by that api
# How should the chat bot behave, what's its personality? (Usage of this counts towards the max tokens) modelName: gpt-3.5-turbo
# How should the chatbot behave, what's its personality?
# This will be sent as a system message.
# Usage of this counts towards the max tokens.
personalityPrompt: You are a chat bot willing to have a conversation with anyone about anything. personalityPrompt: You are a chat bot willing to have a conversation with anyone about anything.
# The maximum number of messages in a conversation that can be remembered. (This will increase the number of tokens used) # The maximum number of messages in a conversation that can be remembered.
# This will increase the number of tokens used.
chatHistory: 5 chatHistory: 5
# The maximum number of tokens to use per GPT API call # The maximum number of tokens to use per OpenAi API call
maxTokens: 100 maxTokens: 100
# The minimum number of tokens to use per GPT API call, such that chat history is removed to make room. # The minimum number of tokens to use per GPT API call, such that chat history is removed to make room.
minTokens: 30 minTokens: 30

View file

@ -1361,10 +1361,10 @@ flip:
desc: "The number of times the coin is flipped." desc: "The number of times the coin is flipped."
betflip: betflip:
desc: |- desc: |-
Bet to guess will the result be heads or tails. Bet on the coin flip.
Guessing awards you 1.95x the currency you've bet (rounded up). The result can be heads or tails.
Guessing correctly rewards you with 1.95x of the currency you've bet (rounded up).
Multiplier can be changed by the bot owner. Multiplier can be changed by the bot owner.
ex: ex:
- 5 heads - 5 heads
- 3 t - 3 t

View file

@ -38,6 +38,7 @@
"prune_cancelled": "Pruning was cancelled.", "prune_cancelled": "Pruning was cancelled.",
"prune_not_found": "No active prune was found on this server.", "prune_not_found": "No active prune was found on this server.",
"prune_progress": "Pruning... {0}/{1} messages deleted.", "prune_progress": "Pruning... {0}/{1} messages deleted.",
"prune_already_running": "A prune is already running on this server.",
"timeoutdm": "You have been timed out in {0} server.\nReason: {1}", "timeoutdm": "You have been timed out in {0} server.\nReason: {1}",
"timedout_user": "User Timed Out", "timedout_user": "User Timed Out",
"remove_roles_pl": "have had their roles removed", "remove_roles_pl": "have had their roles removed",