holy shit I am the goat

This commit is contained in:
2026-02-28 22:40:27 +00:00
parent 940ab3535a
commit 2a27da1ab4
6 changed files with 145 additions and 104 deletions

View File

@@ -2,7 +2,7 @@ using Valour.Sdk.Models;
namespace Reactor.Commands;
public static class HelpComamnd
public static class HelpCommand
{
public static async Task Execute(Dictionary<long, Channel> channelCache, long channelId, String prefix, string memberPing)
{

View File

@@ -2,7 +2,7 @@ using Valour.Sdk.Models;
namespace Reactor.Commands;
public static class SourceComamnd
public static class SourceCommand
{
public static async Task Execute(Dictionary<long, Channel> channelCache, long channelId, string memberPing)
{

View File

@@ -1,122 +1,35 @@
using Valour.Sdk.Client;
using Valour.Sdk.Models;
using DotNetEnv;
using Valour.Shared.Models;
using Reactor.Commands;
using Reactor.Services;
namespace Reactor
{
public class Reactor
{
private ValourClient _client;
private Dictionary<long, Channel> _channelCache = new();
private HashSet<long> _initializedPlanets = new();
private string _prefix = "r.";
private readonly ValourClient _client;
private readonly Dictionary<long, Channel> _channelCache = new();
private readonly HashSet<long> _initializedPlanets = new();
private readonly string _prefix = "r.";
public Reactor(string token)
public Reactor()
{
Env.Load();
_client = new ValourClient("https://api.valour.gg/");
_client.SetupHttpClient();
InitializeBotAsync(token).GetAwaiter().GetResult();
}
//Initialize the bot.
private async Task InitializeBotAsync(string token)
public async Task StartAsync(string token)
{
if (string.IsNullOrWhiteSpace(token))
{
Console.WriteLine("TOKEN not set.");
return;
}
var loginResult = await _client.InitializeUser(token);
if (!loginResult.Success)
{
Console.WriteLine($"Login failed: {loginResult.Message}");
return;
}
Console.WriteLine($"Logged in as {_client.Me.Name} (ID: {_client.Me.Id})");
await InitializePlanetsAsync();
_client.PlanetService.JoinedPlanetsUpdated += async () =>
{
await InitializePlanetsAsync();
};
_client.MessageService.MessageReceived += async (msg) => await HandleMessageAsync(msg);
Console.WriteLine("Bot ready and listening...");
}
//Initalize the planets.
private async Task InitializePlanetsAsync()
{
foreach (var planet in _client.PlanetService.JoinedPlanets)
{
if (_initializedPlanets.Contains(planet.Id))
continue;
Console.WriteLine($"Initializing Planet: {planet.Name}");
await planet.EnsureReadyAsync();
await planet.FetchInitialDataAsync();
foreach (var channel in planet.Channels)
{
_channelCache[channel.Id] = channel;
if (channel.ChannelType == ChannelTypeEnum.PlanetChat)
{
await channel.OpenWithResult("Reactor");
Console.WriteLine($"Realtime opened for: {planet.Name} -> {channel.Name}");
await BotService.InitializeBotAsync(
token,
_client,
_channelCache,
_initializedPlanets,
_prefix
);
}
}
_initializedPlanets.Add(planet.Id);
}
}
//Message handler.
private async Task HandleMessageAsync(Message message)
{
if (message.AuthorUserId == _client.Me.Id) return;
string content = message.Content ?? "";
if (string.IsNullOrWhiteSpace(content)) return;
if (!content.StartsWith(_prefix)) return;
long channelId = message.ChannelId;
var member = await message.FetchAuthorMemberAsync();
string memberPing = member != null ? $"«@m-{member.Id}»" : "";
string withoutPrefix = content.Substring(_prefix.Length);
var parts = withoutPrefix.Split(' ', StringSplitOptions.RemoveEmptyEntries);
if (parts.Length == 0) return;
string command = parts[0].ToLower();
string[] args = parts[1..];
switch (command)
{
case "help":
await HelpComamnd.Execute(_channelCache, channelId, _prefix, memberPing);
break;
case "source":
await SourceComamnd.Execute(_channelCache, channelId, memberPing);
break;
}
}
}
//Because it required a main or something idk I hate C# :)
public class Program
{
public static async Task Main(string[] args)
@@ -131,7 +44,8 @@ namespace Reactor
return;
}
var bot = new Reactor(token);
var bot = new Reactor();
await bot.StartAsync(token);
await Task.Delay(Timeout.Infinite);
}

42
Services/BotService.cs Normal file
View File

@@ -0,0 +1,42 @@
using Valour.Sdk.Client;
using Valour.Sdk.Models;
namespace Reactor.Services
{
public static class BotService
{
public static async Task InitializeBotAsync(
string token,
ValourClient client,
Dictionary<long, Channel> channelCache,
HashSet<long> initializedPlanets,
string prefix)
{
if (string.IsNullOrWhiteSpace(token))
{
Console.WriteLine("TOKEN not set.");
return;
}
var loginResult = await client.InitializeUser(token);
if (!loginResult.Success)
{
Console.WriteLine($"Login failed: {loginResult.Message}");
return;
}
Console.WriteLine($"Logged in as {client.Me.Name} (ID: {client.Me.Id})");
await PlanetService.InitializePlanetsAsync(client, channelCache, initializedPlanets);
client.PlanetService.JoinedPlanetsUpdated += async () =>
{
await PlanetService.InitializePlanetsAsync(client, channelCache, initializedPlanets);
};
client.MessageService.MessageReceived += async (msg) => await MessageService.HandleMessageAsync(client, channelCache, msg, prefix);
Console.WriteLine("Bot ready and listening...");
}
}
}

View File

@@ -0,0 +1,46 @@
using Reactor.Commands;
using Valour.Sdk.Client;
using Valour.Sdk.Models;
namespace Reactor.Services
{
public static class MessageService
{
public static async Task HandleMessageAsync(
ValourClient client,
Dictionary<long, Channel> channelCache,
Message message,
string prefix)
{
if (message.AuthorUserId == client.Me.Id) return;
string content = message.Content ?? "";
if (string.IsNullOrWhiteSpace(content)) return;
if (!content.StartsWith(prefix)) return;
long channelId = message.ChannelId;
var member = await message.FetchAuthorMemberAsync();
string memberPing = member != null ? $"«@m-{member.Id}»" : "";
string withoutPrefix = content.Substring(prefix.Length);
var parts = withoutPrefix.Split(' ', StringSplitOptions.RemoveEmptyEntries);
if (parts.Length == 0) return;
string command = parts[0].ToLower();
string[] args = parts[1..];
switch (command)
{
case "help":
await HelpCommand.Execute(channelCache, channelId, prefix, memberPing);
break;
case "source":
await SourceCommand.Execute(channelCache, channelId, memberPing);
break;
}
}
}
}

39
Services/PlanetService.cs Normal file
View File

@@ -0,0 +1,39 @@
using Valour.Sdk.Client;
using Valour.Sdk.Models;
using Valour.Shared.Models;
namespace Reactor.Services
{
public static class PlanetService
{
public static async Task InitializePlanetsAsync(
ValourClient client,
Dictionary<long, Channel> channelCache,
HashSet<long> initializedPlanets)
{
foreach (var planet in client.PlanetService.JoinedPlanets)
{
if (initializedPlanets.Contains(planet.Id))
continue;
Console.WriteLine($"Initializing Planet: {planet.Name}");
await planet.EnsureReadyAsync();
await planet.FetchInitialDataAsync();
foreach (var channel in planet.Channels)
{
channelCache[channel.Id] = channel;
if (channel.ChannelType == ChannelTypeEnum.PlanetChat)
{
await channel.OpenWithResult("Reactor");
Console.WriteLine($"Realtime opened for: {planet.Name} -> {channel.Name}");
}
}
initializedPlanets.Add(planet.Id);
}
}
}
}