mirror of
https://github.com/DeltaV-Station/Delta-v.git
synced 2026-10-02 00:57:26 +00:00
Authored-by: Vanessa <vanessalouwagie@gmail.com> Co-authored-by: Whisper <121047731+QuietlyWhisper@users.noreply.github.com>
146 lines
5.8 KiB
C#
146 lines
5.8 KiB
C#
using System.Reflection;
|
|
using Content.DiscordBot.Modules;
|
|
using Content.Server.Database;
|
|
using Discord.Commands;
|
|
using Discord.Interactions;
|
|
using Discord.WebSocket;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace Content.DiscordBot;
|
|
|
|
public sealed class CommandHandler(DiscordSocketClient client, CommandService commands, InteractionService interaction, PostgresServerDbContext db)
|
|
{
|
|
public async Task InstallCommandsAsync()
|
|
{
|
|
client.MessageReceived += HandleCommandAsync;
|
|
client.ButtonExecuted += HandleButtonAsync;
|
|
client.ModalSubmitted += HandleModalAsync;
|
|
|
|
await commands.AddModulesAsync(Assembly.GetEntryAssembly(), null);
|
|
|
|
interaction.AddModalInfo<LinkAccountModal>();
|
|
}
|
|
|
|
private async Task HandleCommandAsync(SocketMessage messageParam)
|
|
{
|
|
// Don't process the command if it was a system message
|
|
var message = messageParam as SocketUserMessage;
|
|
if (message == null)
|
|
return;
|
|
|
|
// Create a number to track where the prefix ends and the command begins
|
|
var argPos = 0;
|
|
|
|
// Determine if the message is a command based on the prefix and make sure no bots trigger commands
|
|
if (!(message.HasCharPrefix('!', ref argPos) ||
|
|
message.HasMentionPrefix(client.CurrentUser, ref argPos)) ||
|
|
message.Author.IsBot)
|
|
return;
|
|
|
|
// Create a WebSocket-based command context based on the message
|
|
var context = new SocketCommandContext(client, message);
|
|
|
|
// Execute the command with the command context we just
|
|
// created, along with the service provider for precondition checks.
|
|
await commands.ExecuteAsync(context, argPos, null);
|
|
}
|
|
|
|
private async Task HandleButtonAsync(SocketMessageComponent component)
|
|
{
|
|
switch (component.Data.CustomId)
|
|
{
|
|
case "link-ss14-account":
|
|
await component.RespondWithModalAsync<LinkAccountModal>("link-ss14-account");
|
|
break;
|
|
}
|
|
}
|
|
|
|
private async Task HandleModalAsync(SocketModal modal)
|
|
{
|
|
switch (modal.Data.CustomId)
|
|
{
|
|
case "link-ss14-account":
|
|
if (modal.GuildId is not { } guildId)
|
|
break;
|
|
|
|
var codeStr = modal.Data.Components.First(c => c.CustomId == "account_code").Value.Trim();
|
|
if (string.IsNullOrWhiteSpace(codeStr))
|
|
break;
|
|
|
|
await modal.DeferAsync(true);
|
|
if (!Guid.TryParse(codeStr, out var code))
|
|
{
|
|
await modal.FollowupAsync($"{codeStr} isn't a valid code! Get one in-game from the lobby at the top left of the screen.", ephemeral: true);
|
|
}
|
|
|
|
var author = modal.User;
|
|
var authorId = author.Id;
|
|
var discord = await db.DiscordAccounts
|
|
.Include(d => d.LinkedAccount)
|
|
.ThenInclude(l => l.Player)
|
|
.ThenInclude(p => p.Patron)
|
|
.FirstOrDefaultAsync(a => a.Id == authorId);
|
|
var codes = await db.DiscordLinkingCodes
|
|
.Include(l => l.Player)
|
|
.ThenInclude(player => player.Patron)
|
|
.FirstOrDefaultAsync(p => p.Code == code);
|
|
|
|
if (codes == null)
|
|
{
|
|
await modal.FollowupAsync($"No player found with code {codeStr}, join the game server and get another code before trying again, or ask for help in another channel.", ephemeral: true);
|
|
break;
|
|
}
|
|
|
|
if (codes.CreationTime < DateTime.UtcNow.Subtract(TimeSpan.FromDays(1)))
|
|
{
|
|
await modal.FollowupAsync($"Code {codeStr} were generated too long ago, join the game server and get another code before trying again.");
|
|
}
|
|
|
|
if (discord?.LinkedAccount is { } linked)
|
|
{
|
|
if (linked.Player.Patron is { } patron)
|
|
db.DeltaVPatrons.Remove(patron);
|
|
|
|
linked.Player.Patron = null;
|
|
db.DiscordLinkedAccounts.Remove(linked);
|
|
}
|
|
|
|
discord ??= db.DiscordAccounts.Add(new DiscordAccount { Id = authorId }).Entity;
|
|
discord.LinkedAccount = db.DiscordLinkedAccounts.Add(new DiscordLinkedAccount { Discord = discord }).Entity;
|
|
discord.LinkedAccount.Player = codes.Player;
|
|
|
|
var roles = client.GetGuild(guildId).GetUser(authorId).Roles.Select(r => r.Id).ToArray();
|
|
var tiers = await db.DeltaVPatronTiers
|
|
.Where(t => roles.Contains(t.DiscordRole))
|
|
.ToListAsync();
|
|
if (tiers.Count == 0)
|
|
{
|
|
discord.LinkedAccount.Player.Patron = null;
|
|
}
|
|
else
|
|
{
|
|
tiers.Sort((a, b) => a.Priority.CompareTo(b.Priority));
|
|
var tier = tiers[0];
|
|
discord.LinkedAccount.Player.Patron = db.DeltaVPatrons.Add(new DeltaVPatron { Tier = tier }).Entity;
|
|
discord.LinkedAccount.Player.Patron.Tier = tier;
|
|
}
|
|
|
|
db.DiscordLinkedAccountLogs.Add(new DiscordLinkedAccountLogs
|
|
{
|
|
Discord = discord,
|
|
Player = discord.LinkedAccount.Player,
|
|
});
|
|
|
|
db.ChangeTracker.DetectChanges();
|
|
await db.SaveChangesAsync();
|
|
|
|
var msg = $"Linked SS14 account with name {codes.Player.LastSeenUserName}";
|
|
if (codes.Player.Patron != null)
|
|
msg += $" and tier {codes.Player.Patron.Tier.Name}";
|
|
|
|
await modal.FollowupAsync(msg, ephemeral: true);
|
|
break;
|
|
}
|
|
}
|
|
}
|