add quote commands and make it actually use mysql connection pooling oops

This commit is contained in:
Elijah R 2024-04-03 15:50:24 -04:00
parent deb3d978e5
commit 67903be1dd
4 changed files with 69 additions and 16 deletions

View file

@ -7,5 +7,6 @@ public class ChatlogQuery
public DateTime? FromTimestamp { get; set; }
public DateTime? ToTimestamp { get; set; }
public int? Count { get; set; }
public bool Random { get; set; }
public string? Regex { get; set; }
}

View file

@ -6,22 +6,21 @@ namespace EmperorPalpatine;
public class Database
{
private MySqlConnection db;
private readonly string connstr;
public Database(ConfigDatabase config)
{
var connstr = new MySqlConnectionStringBuilder
connstr = new MySqlConnectionStringBuilder
{
Server = config.Host,
UserID = config.Username,
Password = config.Password,
Database = config.Database,
};
db = new MySqlConnection(connstr.ToString());
}.ToString();
}
public async Task InitAsync()
{
await using var db = new MySqlConnection(connstr);
await db.OpenAsync();
using var cmd = db.CreateCommand();
cmd.CommandText = """
@ -46,6 +45,8 @@ public class Database
public async Task LogChatMessageAsync(string vm, string username, string message)
{
await using var db = new MySqlConnection(connstr);
await db.OpenAsync();
await using var cmd = db.CreateCommand();
cmd.CommandText = "INSERT INTO chatlogs (vm, username, message) VALUES (@vm, @username, @message)";
cmd.Parameters.AddWithValue("@vm", vm);
@ -56,6 +57,8 @@ public class Database
public async Task LogIPAsync(string vm, string username, IPAddress ip)
{
await using var db = new MySqlConnection(connstr);
await db.OpenAsync();
await using var cmd = db.CreateCommand();
cmd.CommandText = "SELECT COUNT(ip) FROM iplog WHERE ip = @ip AND date >= DATE_SUB(NOW(), INTERVAL 1 HOUR) AND vm = @vm AND username = @username";
cmd.Parameters.AddWithValue("@ip", ip.GetAddressBytes());
@ -70,6 +73,8 @@ public class Database
public async Task<LoggedChatMessage[]> GetChatlogsAsync(ChatlogQuery q)
{
await using var db = new MySqlConnection(connstr);
await db.OpenAsync();
await using var cmd = db.CreateCommand();
cmd.CommandText = "SELECT * FROM chatlogs";
List<string> where = new();
@ -104,7 +109,7 @@ public class Database
}
if (q.Count != null)
{
cmd.CommandText += " ORDER BY date DESC LIMIT @count";
cmd.CommandText += $" ORDER BY {(q.Random ? "RAND()" : "date DESC")} LIMIT @count";
cmd.Parameters.AddWithValue("@count", q.Count);
}
await using var reader = await cmd.ExecuteReaderAsync();
@ -126,6 +131,8 @@ public class Database
public async Task<LoggedIP[]> GetIPFromUsernameAsync(string username)
{
await using var db = new MySqlConnection(connstr);
await db.OpenAsync();
await using var cmd = db.CreateCommand();
cmd.CommandText = "SELECT * FROM iplog WHERE username = @username";
cmd.Parameters.AddWithValue("@username", username);
@ -146,6 +153,8 @@ public class Database
public async Task<LoggedIP[]> GetUsernameFromIPAsync(IPAddress ip)
{
await using var db = new MySqlConnection(connstr);
await db.OpenAsync();
await using var cmd = db.CreateCommand();
cmd.CommandText = "SELECT * FROM iplog WHERE ip = @ip";
cmd.Parameters.AddWithValue("@ip", ip.GetAddressBytes());

View file

@ -9,7 +9,7 @@ namespace EmperorPalpatine;
public class DiscordCommands : ApplicationCommandModule
{
[SlashCommand("vm", "Get info from a VM")]
public async Task VM(InteractionContext ctx, [ChoiceProvider(typeof(VMAutocompleteProvider))] [Option("vm", "VM to get info from")] string VM) {
public async Task VM(InteractionContext ctx, [Autocomplete(typeof(VMAutocompleteProvider))] [Option("vm", "VM to get info from")] string VM) {
if (Program.VMs.All(v => v.Config.Name != VM)) {
await ctx.CreateResponseAsync("No VM by that name found.");
return;
@ -71,7 +71,7 @@ public class DiscordCommands : ApplicationCommandModule
[SlashCommand("ban", "Ban a user")]
public async Task Ban(InteractionContext ctx, [Option("username", "User to ban")] string username,
[Option("vm", "VM to ban from")] [ChoiceProvider(typeof(VMAutocompleteProvider))] string VM) {
[Option("vm", "VM to ban from")] [Autocomplete(typeof(VMAutocompleteProvider))] string VM) {
if (Program.VMs.All(v => v.Config.Name != VM)) {
await ctx.CreateResponseAsync("No VM by that name found.");
return;
@ -94,7 +94,7 @@ public class DiscordCommands : ApplicationCommandModule
[SlashCommand("kick", "Kick a user")]
public async Task Kick(InteractionContext ctx, [Option("username", "User to kick")] string username,
[Option("vm", "VM to kick from"), ChoiceProvider(typeof(VMAutocompleteProvider))] string VM) {
[Option("vm", "VM to kick from"), Autocomplete(typeof(VMAutocompleteProvider))] string VM) {
if (Program.VMs.All(v => v.Config.Name != VM)) {
await ctx.CreateResponseAsync("No VM by that name found.");
return;
@ -117,7 +117,7 @@ public class DiscordCommands : ApplicationCommandModule
[SlashCommand("reboot", "Reboot a VM")]
public async Task Reboot(InteractionContext ctx,
[Option("vm", "VM to reboot"), ChoiceProvider(typeof(VMAutocompleteProvider))] string VM)
[Option("vm", "VM to reboot"), Autocomplete(typeof(VMAutocompleteProvider))] string VM)
{
if (Program.VMs.All(v => v.Config.Name != VM)) {
await ctx.CreateResponseAsync("No VM by that name found.");
@ -137,7 +137,7 @@ public class DiscordCommands : ApplicationCommandModule
[SlashCommand("restore", "Restore a VM")]
public async Task Restore(InteractionContext ctx,
[Option("vm", "VM to restore"), ChoiceProvider(typeof(VMAutocompleteProvider))] string VM)
[Option("vm", "VM to restore"), Autocomplete(typeof(VMAutocompleteProvider))] string VM)
{
if (Program.VMs.All(v => v.Config.Name != VM)) {
await ctx.CreateResponseAsync("No VM by that name found.");
@ -196,14 +196,35 @@ public class DiscordCommands : ApplicationCommandModule
}
await ctx.EditResponseAsync(new DiscordWebhookBuilder().AddEmbeds(IPEmbeds));
}
[SlashCommand("quote", "Quote a user")]
public async Task Quote(InteractionContext ctx, [Option("username", "User to quote")] string username)
{
await ctx.DeferAsync();
var chat = await Program.Database.GetChatlogsAsync(new ChatlogQuery
{
Username = username,
Count = 1,
Random = true
});
if (chat.Length == 0)
{
await ctx.EditResponseAsync(new DiscordWebhookBuilder().WithContent($"@No messages found for {username}"));
return;
}
await ctx.EditResponseAsync(new DiscordWebhookBuilder().WithContent($"> {chat[0].Message}\n- {chat[0].Username}"));
}
}
public class VMAutocompleteProvider : IChoiceProvider {
public async Task<IEnumerable<DiscordApplicationCommandOptionChoice>> Provider() {
var list = new List<DiscordApplicationCommandOptionChoice>();
public class VMAutocompleteProvider : IAutocompleteProvider {
public Task<IEnumerable<DiscordAutoCompleteChoice>> Provider(AutocompleteContext ctx)
{
var list = new List<DiscordAutoCompleteChoice>();
foreach (ConfigVM vm in Program.Config.VMs) {
list.Add(new DiscordApplicationCommandOptionChoice(vm.Name, vm.Name));
list.Add(new DiscordAutoCompleteChoice(vm.Name, vm.Name));
}
return list.ToArray();
if (list.Count > 25) list.RemoveRange(24, list.Count - 25);
return Task.FromResult(list.AsEnumerable());
}
}

View file

@ -32,6 +32,28 @@ public class VM
this.cvm.ConnectionClosed += CvmOnConnectionClosed;
this.cvm.UserRenamed += (_, e) => CheckUsername(e.User);
this.cvm.UserJoined += (_, e) => CheckUsername(e);
this.cvm.RegisterCommand("+quote", QuoteCommand);
}
private async void QuoteCommand(string username, string[] args)
{
if (args.Length != 1)
{
await cvm.SendChat($"@{username} Usage: +quote <username>");
return;
}
var chat = await database.GetChatlogsAsync(new ChatlogQuery
{
Username = args[0],
Count = 1,
Random = true
});
if (chat.Length == 0)
{
await cvm.SendChat($"@{username} No messages found for {args[0]}");
return;
}
await cvm.SendXSSChat($"\"{chat[0].Message}\" - {chat[0].Username}");
}
private void CvmOnConnectionClosed(object? sender, EventArgs e)