diff --git a/Commands/HelpCommand.cs b/Commands/HelpCommand.cs index 67e9486..ff4e71a 100644 --- a/Commands/HelpCommand.cs +++ b/Commands/HelpCommand.cs @@ -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 channelCache, long channelId, String prefix, string memberPing) { diff --git a/Commands/SourceCommand.cs b/Commands/SourceCommand.cs index 1b74bde..ee3847c 100644 --- a/Commands/SourceCommand.cs +++ b/Commands/SourceCommand.cs @@ -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 channelCache, long channelId, string memberPing) { diff --git a/Program.cs b/Program.cs index cc6b9af..1048304 100644 --- a/Program.cs +++ b/Program.cs @@ -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 _channelCache = new(); - private HashSet _initializedPlanets = new(); - private string _prefix = "r."; + private readonly ValourClient _client; + private readonly Dictionary _channelCache = new(); + private readonly HashSet _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..."); + await BotService.InitializeBotAsync( + token, + _client, + _channelCache, + _initializedPlanets, + _prefix + ); } - - //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}"); - } - } - - _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); } diff --git a/Services/BotService.cs b/Services/BotService.cs new file mode 100644 index 0000000..aea440b --- /dev/null +++ b/Services/BotService.cs @@ -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 channelCache, + HashSet 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..."); + } + } +} \ No newline at end of file diff --git a/Services/MessageService.cs b/Services/MessageService.cs new file mode 100644 index 0000000..c56af1a --- /dev/null +++ b/Services/MessageService.cs @@ -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 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; + } + } + } +} \ No newline at end of file diff --git a/Services/PlanetService.cs b/Services/PlanetService.cs new file mode 100644 index 0000000..08b1817 --- /dev/null +++ b/Services/PlanetService.cs @@ -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 channelCache, + HashSet 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); + } + } + } +} \ No newline at end of file