collabbot/CollabBot/DiscordCommands.cs
2024-10-17 10:02:56 -04:00

176 lines
7.3 KiB
C#

using System.Text.Json;
using System.Text.RegularExpressions;
using DSharpPlus.Entities;
using DSharpPlus.SlashCommands;
namespace CollabBot;
public class DiscordCommands : ApplicationCommandModule
{
[SlashCommand("vnc", "View insecure VNCs around the world!")]
public async Task VNC(InteractionContext ctx,
[Option("country", "If specified, a random VNC from this country")] string? country = null,
[Option("id", "If specified, a specific VNC by ID")] long? id = null)
{
await ctx.DeferAsync();
VNC vnc;
using var http = new HttpClient();
if (id != null)
{
Console.WriteLine($"Getting VNC ID {id} for {ctx.User.Username}");
try
{
var response = await http.GetStringAsync($"https://computernewb.com/vncresolver/api/scans/vnc/id/{id}");
vnc = JsonSerializer.Deserialize<VNC>(response);
}
catch (Exception ex)
{
await ctx.EditResponseAsync(new DiscordWebhookBuilder().WithContent($"Failed to fetch VNC data ({ex.Message}). Please ping an admin!"));
return;
}
}
else if (country != null)
{
Console.WriteLine($"Getting VNC from {country} for {ctx.User.Username}");
if (!Regex.IsMatch(country, "^[a-zA-Z]{2}$"))
{
await ctx.EditResponseAsync(new DiscordWebhookBuilder().WithContent(
"Country name must be ISO code (i.e. GB for England, US for United States)"));
return;
}
var response =
await http.GetStringAsync(
$"https://computernewb.com/vncresolver/api/scans/vnc/search?country={country}");
var results = JsonSerializer.Deserialize<VNCSearchResult>(response);
if (results == null || results.error != null)
{
await ctx.EditResponseAsync(new DiscordWebhookBuilder().WithContent(results != null
? results.error!
: "Failed to fetch VNC data (response was null, please ping an admin!)"));
}
if (results.count == 0)
{
await ctx.EditResponseAsync(new DiscordWebhookBuilder().WithContent(country.ToUpper() == "NK" ? "You wish lol" : "No VNCs from that country found."));
return;
}
var random = new Random().Next(results.count);
try
{
response = await http.GetStringAsync(
$"https://computernewb.com/vncresolver/api/scans/vnc/id/{results.result[random]}");
vnc = JsonSerializer.Deserialize<VNC>(response);
}
catch (Exception ex)
{
await ctx.EditResponseAsync(new DiscordWebhookBuilder().WithContent($"Failed to fetch VNC data ({ex.Message}). Please ping an admin!"));
return;
}
}
else
{
Console.WriteLine($"Getting random VNC for {ctx.User.Username}");
try
{
var response = await http.GetStringAsync("https://computernewb.com/vncresolver/api/scans/vnc/random");
vnc = JsonSerializer.Deserialize<VNC>(response);
}
catch (Exception ex)
{
await ctx.EditResponseAsync(new DiscordWebhookBuilder().WithContent($"Failed to fetch VNC data ({ex.Message}). Please ping an admin!"));
return;
}
}
if (vnc == null)
{
Console.WriteLine("Failed to fetch VNC data (response was null)");
await ctx.EditResponseAsync(new DiscordWebhookBuilder().WithContent("Failed to fetch VNC data (response was null, please ping an admin!)"));
return;
}
if (vnc.error != null)
{
Console.WriteLine($"Error: {vnc.error}");
await ctx.EditResponseAsync(new DiscordWebhookBuilder().WithContent(vnc.error));
return;
}
var embed = new DiscordEmbedBuilder()
.WithTitle($"VNC {vnc.id}").WithUrl($"https://computernewb.com/vncresolver/browse/#id/{vnc.id}")
.AddField("Address", $"{vnc.ip}:{vnc.port}")
.AddField("Location", $"{vnc.city}, {vnc.country} :flag_{vnc.country.ToLower()}:")
.AddField("ASN", vnc.asn)
.WithImageUrl($"https://computernewb.com/vncresolver/api/scans/vnc/screenshot/{vnc.id}.jpeg")
.WithFooter($"Added to database on {DateTime.UnixEpoch.AddMilliseconds(vnc.createdat):u}");
if (!String.IsNullOrEmpty(vnc.clientname)) embed.AddField("Client", vnc.clientname);
if (!String.IsNullOrEmpty(vnc.screenres)) embed.AddField("Screen Resolution", vnc.screenres);
if (!String.IsNullOrEmpty(vnc.hostname)) embed.AddField("Hostname", vnc.hostname);
await ctx.EditResponseAsync(new DiscordWebhookBuilder().AddEmbed(embed));
}
[SlashCommand("report", "Report a user for breaking the rules on the main VMs")]
public async Task ReportUser(InteractionContext ctx,
[Option("user", "Who is breaking the rules?")]
string user,
[Option("vm", "Which VM are they on?"), ChoiceProvider(typeof(VMChoiceProvider))]
string vm,
[Option("rule", "Which rule are they breaking?"), ChoiceProvider(typeof(RulesChoiceProvider))]
string rule,
[Option("reason", "What exactly are they doing?")]
string reason
)
{
await ctx.DeferAsync(true);
await Program.ReportChannel.SendMessageAsync($"<@&{Program.Config.ReportRole}>", new DiscordEmbedBuilder()
.WithTitle("User Reported")
.AddField("User", user)
.AddField("VM", vm)
.AddField("Rule", rule)
.AddField("Reason", reason)
.AddField("Reporter", $"{ctx.User.Mention} ({ctx.User.Username})")
.Build());
await ctx.EditResponseAsync(new DiscordWebhookBuilder().WithContent("Thank you for your report!"));
}
}
public abstract class DictChoiceProvider : ChoiceProvider
{
public abstract Dictionary<string,string> Options { get; }
public override Task<IEnumerable<DiscordApplicationCommandOptionChoice>> Provider()
{
return Task.FromResult(Options.Select(o => new DiscordApplicationCommandOptionChoice(o.Key, o.Value)));
}
}
public class RulesChoiceProvider : DictChoiceProvider
{
public override Dictionary<string, string> Options => new()
{
{ "R1. Don't break the law.", "R1" },
{ "R2. No running DoS/DDoS tools.", "R2"},
{ "R3. No spam distribution.", "R3"},
{ "R4. Do not abuse any exploits.", "R4" },
{ "R6. One vote per person.", "R6" },
{ "R7. No Remote Administration Tools.", "R7" },
{ "R8. No bypassing CollabNet.", "R8" },
{ "R9. No performing destructive actions constantly.", "R9" },
{ "R10. No Cryptomining", "R10" },
{ "NSFW Content on Main VMs", "NSFW" }
};
}
public class VMChoiceProvider : DictChoiceProvider
{
public override Dictionary<string, string> Options => new()
{
{ "VM0b0t", "VM0b0t" },
{ "VM1", "VM1" },
{ "VM2", "VM2" },
{ "VM3", "VM3" },
{ "VM4", "VM4" },
{ "VM5", "VM5" },
{ "VM6", "VM6" },
{ "VM7", "VM7" },
{ "VM8", "VM8" }
};
}