add quote commands and make it actually use mysql connection pooling oops
This commit is contained in:
parent
deb3d978e5
commit
67903be1dd
4 changed files with 69 additions and 16 deletions
|
@ -7,5 +7,6 @@ public class ChatlogQuery
|
||||||
public DateTime? FromTimestamp { get; set; }
|
public DateTime? FromTimestamp { get; set; }
|
||||||
public DateTime? ToTimestamp { get; set; }
|
public DateTime? ToTimestamp { get; set; }
|
||||||
public int? Count { get; set; }
|
public int? Count { get; set; }
|
||||||
|
public bool Random { get; set; }
|
||||||
public string? Regex { get; set; }
|
public string? Regex { get; set; }
|
||||||
}
|
}
|
|
@ -6,22 +6,21 @@ namespace EmperorPalpatine;
|
||||||
|
|
||||||
public class Database
|
public class Database
|
||||||
{
|
{
|
||||||
private MySqlConnection db;
|
private readonly string connstr;
|
||||||
|
|
||||||
public Database(ConfigDatabase config)
|
public Database(ConfigDatabase config)
|
||||||
{
|
{
|
||||||
var connstr = new MySqlConnectionStringBuilder
|
connstr = new MySqlConnectionStringBuilder
|
||||||
{
|
{
|
||||||
Server = config.Host,
|
Server = config.Host,
|
||||||
UserID = config.Username,
|
UserID = config.Username,
|
||||||
Password = config.Password,
|
Password = config.Password,
|
||||||
Database = config.Database,
|
Database = config.Database,
|
||||||
};
|
}.ToString();
|
||||||
db = new MySqlConnection(connstr.ToString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task InitAsync()
|
public async Task InitAsync()
|
||||||
{
|
{
|
||||||
|
await using var db = new MySqlConnection(connstr);
|
||||||
await db.OpenAsync();
|
await db.OpenAsync();
|
||||||
using var cmd = db.CreateCommand();
|
using var cmd = db.CreateCommand();
|
||||||
cmd.CommandText = """
|
cmd.CommandText = """
|
||||||
|
@ -46,6 +45,8 @@ public class Database
|
||||||
|
|
||||||
public async Task LogChatMessageAsync(string vm, string username, string message)
|
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();
|
await using var cmd = db.CreateCommand();
|
||||||
cmd.CommandText = "INSERT INTO chatlogs (vm, username, message) VALUES (@vm, @username, @message)";
|
cmd.CommandText = "INSERT INTO chatlogs (vm, username, message) VALUES (@vm, @username, @message)";
|
||||||
cmd.Parameters.AddWithValue("@vm", vm);
|
cmd.Parameters.AddWithValue("@vm", vm);
|
||||||
|
@ -56,6 +57,8 @@ public class Database
|
||||||
|
|
||||||
public async Task LogIPAsync(string vm, string username, IPAddress ip)
|
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();
|
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.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());
|
cmd.Parameters.AddWithValue("@ip", ip.GetAddressBytes());
|
||||||
|
@ -70,6 +73,8 @@ public class Database
|
||||||
|
|
||||||
public async Task<LoggedChatMessage[]> GetChatlogsAsync(ChatlogQuery q)
|
public async Task<LoggedChatMessage[]> GetChatlogsAsync(ChatlogQuery q)
|
||||||
{
|
{
|
||||||
|
await using var db = new MySqlConnection(connstr);
|
||||||
|
await db.OpenAsync();
|
||||||
await using var cmd = db.CreateCommand();
|
await using var cmd = db.CreateCommand();
|
||||||
cmd.CommandText = "SELECT * FROM chatlogs";
|
cmd.CommandText = "SELECT * FROM chatlogs";
|
||||||
List<string> where = new();
|
List<string> where = new();
|
||||||
|
@ -104,7 +109,7 @@ public class Database
|
||||||
}
|
}
|
||||||
if (q.Count != null)
|
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);
|
cmd.Parameters.AddWithValue("@count", q.Count);
|
||||||
}
|
}
|
||||||
await using var reader = await cmd.ExecuteReaderAsync();
|
await using var reader = await cmd.ExecuteReaderAsync();
|
||||||
|
@ -126,6 +131,8 @@ public class Database
|
||||||
|
|
||||||
public async Task<LoggedIP[]> GetIPFromUsernameAsync(string username)
|
public async Task<LoggedIP[]> GetIPFromUsernameAsync(string username)
|
||||||
{
|
{
|
||||||
|
await using var db = new MySqlConnection(connstr);
|
||||||
|
await db.OpenAsync();
|
||||||
await using var cmd = db.CreateCommand();
|
await using var cmd = db.CreateCommand();
|
||||||
cmd.CommandText = "SELECT * FROM iplog WHERE username = @username";
|
cmd.CommandText = "SELECT * FROM iplog WHERE username = @username";
|
||||||
cmd.Parameters.AddWithValue("@username", username);
|
cmd.Parameters.AddWithValue("@username", username);
|
||||||
|
@ -146,6 +153,8 @@ public class Database
|
||||||
|
|
||||||
public async Task<LoggedIP[]> GetUsernameFromIPAsync(IPAddress ip)
|
public async Task<LoggedIP[]> GetUsernameFromIPAsync(IPAddress ip)
|
||||||
{
|
{
|
||||||
|
await using var db = new MySqlConnection(connstr);
|
||||||
|
await db.OpenAsync();
|
||||||
await using var cmd = db.CreateCommand();
|
await using var cmd = db.CreateCommand();
|
||||||
cmd.CommandText = "SELECT * FROM iplog WHERE ip = @ip";
|
cmd.CommandText = "SELECT * FROM iplog WHERE ip = @ip";
|
||||||
cmd.Parameters.AddWithValue("@ip", ip.GetAddressBytes());
|
cmd.Parameters.AddWithValue("@ip", ip.GetAddressBytes());
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace EmperorPalpatine;
|
||||||
public class DiscordCommands : ApplicationCommandModule
|
public class DiscordCommands : ApplicationCommandModule
|
||||||
{
|
{
|
||||||
[SlashCommand("vm", "Get info from a VM")]
|
[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)) {
|
if (Program.VMs.All(v => v.Config.Name != VM)) {
|
||||||
await ctx.CreateResponseAsync("No VM by that name found.");
|
await ctx.CreateResponseAsync("No VM by that name found.");
|
||||||
return;
|
return;
|
||||||
|
@ -71,7 +71,7 @@ public class DiscordCommands : ApplicationCommandModule
|
||||||
|
|
||||||
[SlashCommand("ban", "Ban a user")]
|
[SlashCommand("ban", "Ban a user")]
|
||||||
public async Task Ban(InteractionContext ctx, [Option("username", "User to ban")] string username,
|
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)) {
|
if (Program.VMs.All(v => v.Config.Name != VM)) {
|
||||||
await ctx.CreateResponseAsync("No VM by that name found.");
|
await ctx.CreateResponseAsync("No VM by that name found.");
|
||||||
return;
|
return;
|
||||||
|
@ -94,7 +94,7 @@ public class DiscordCommands : ApplicationCommandModule
|
||||||
|
|
||||||
[SlashCommand("kick", "Kick a user")]
|
[SlashCommand("kick", "Kick a user")]
|
||||||
public async Task Kick(InteractionContext ctx, [Option("username", "User to kick")] string username,
|
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)) {
|
if (Program.VMs.All(v => v.Config.Name != VM)) {
|
||||||
await ctx.CreateResponseAsync("No VM by that name found.");
|
await ctx.CreateResponseAsync("No VM by that name found.");
|
||||||
return;
|
return;
|
||||||
|
@ -117,7 +117,7 @@ public class DiscordCommands : ApplicationCommandModule
|
||||||
|
|
||||||
[SlashCommand("reboot", "Reboot a VM")]
|
[SlashCommand("reboot", "Reboot a VM")]
|
||||||
public async Task Reboot(InteractionContext ctx,
|
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)) {
|
if (Program.VMs.All(v => v.Config.Name != VM)) {
|
||||||
await ctx.CreateResponseAsync("No VM by that name found.");
|
await ctx.CreateResponseAsync("No VM by that name found.");
|
||||||
|
@ -137,7 +137,7 @@ public class DiscordCommands : ApplicationCommandModule
|
||||||
|
|
||||||
[SlashCommand("restore", "Restore a VM")]
|
[SlashCommand("restore", "Restore a VM")]
|
||||||
public async Task Restore(InteractionContext ctx,
|
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)) {
|
if (Program.VMs.All(v => v.Config.Name != VM)) {
|
||||||
await ctx.CreateResponseAsync("No VM by that name found.");
|
await ctx.CreateResponseAsync("No VM by that name found.");
|
||||||
|
@ -196,14 +196,35 @@ public class DiscordCommands : ApplicationCommandModule
|
||||||
}
|
}
|
||||||
await ctx.EditResponseAsync(new DiscordWebhookBuilder().AddEmbeds(IPEmbeds));
|
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 class VMAutocompleteProvider : IAutocompleteProvider {
|
||||||
public async Task<IEnumerable<DiscordApplicationCommandOptionChoice>> Provider() {
|
|
||||||
var list = new List<DiscordApplicationCommandOptionChoice>();
|
public Task<IEnumerable<DiscordAutoCompleteChoice>> Provider(AutocompleteContext ctx)
|
||||||
|
{
|
||||||
|
var list = new List<DiscordAutoCompleteChoice>();
|
||||||
foreach (ConfigVM vm in Program.Config.VMs) {
|
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());
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -32,6 +32,28 @@ public class VM
|
||||||
this.cvm.ConnectionClosed += CvmOnConnectionClosed;
|
this.cvm.ConnectionClosed += CvmOnConnectionClosed;
|
||||||
this.cvm.UserRenamed += (_, e) => CheckUsername(e.User);
|
this.cvm.UserRenamed += (_, e) => CheckUsername(e.User);
|
||||||
this.cvm.UserJoined += (_, e) => CheckUsername(e);
|
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)
|
private void CvmOnConnectionClosed(object? sender, EventArgs e)
|
||||||
|
|
Loading…
Reference in a new issue