From 4f0ccb9464b9c8ceda2b210c240b461314eb64f1 Mon Sep 17 00:00:00 2001 From: Eveldee Date: Wed, 23 Nov 2022 22:36:56 +0100 Subject: [PATCH] [Raid] Move format code to another class --- Cocotte/Modules/Raids/PlayerRole.cs | 8 ++++ Cocotte/Modules/Raids/RaidFormatter.cs | 59 ++++++++++++++++++++++++++ Cocotte/Modules/Raids/RaidModule.cs | 47 ++++++-------------- Cocotte/Modules/Raids/RosterPlayer.cs | 31 ++------------ Cocotte/Options/RolesOptions.cs | 8 ++++ Cocotte/Program.cs | 4 ++ 6 files changed, 95 insertions(+), 62 deletions(-) create mode 100644 Cocotte/Modules/Raids/PlayerRole.cs create mode 100644 Cocotte/Modules/Raids/RaidFormatter.cs create mode 100644 Cocotte/Options/RolesOptions.cs diff --git a/Cocotte/Modules/Raids/PlayerRole.cs b/Cocotte/Modules/Raids/PlayerRole.cs new file mode 100644 index 0000000..543ab14 --- /dev/null +++ b/Cocotte/Modules/Raids/PlayerRole.cs @@ -0,0 +1,8 @@ +namespace Cocotte.Modules.Raids; + +public enum PlayerRole +{ + Dps, + Healer, + Tank +} \ No newline at end of file diff --git a/Cocotte/Modules/Raids/RaidFormatter.cs b/Cocotte/Modules/Raids/RaidFormatter.cs new file mode 100644 index 0000000..93ebb68 --- /dev/null +++ b/Cocotte/Modules/Raids/RaidFormatter.cs @@ -0,0 +1,59 @@ +using Cocotte.Options; +using Cocotte.Utils; +using Discord; + +namespace Cocotte.Modules.Raids; + +public class RaidFormatter +{ + private readonly RolesOptions _rolesOptions; + + public RaidFormatter(RolesOptions rolesOptions) + { + _rolesOptions = rolesOptions; + } + + private string RoleToEmote(PlayerRole role) => role switch + { + PlayerRole.Dps => _rolesOptions.DpsEmote, + PlayerRole.Tank => _rolesOptions.TankEmote, + PlayerRole.Healer => _rolesOptions.HealerEmote, + _ => ":question:" + }; + + public static string FcFormat(int fc) => fc switch + { + < 1_000 => $"{fc}", + _ => $"{fc/1000}k" + }; + + public string FormatRosterPlayer(RosterPlayer player) => player.Substitue switch + { + false => $"{RoleToEmote(player.Role)} {player.Name} ({FcFormat(player.Fc)} FC)", + true => $"*{RoleToEmote(player.Role)} {player.Name} ({FcFormat(player.Fc)} FC)*" + }; + + public EmbedBuilder RaidEmbed(Raid raid) + { + EmbedFieldBuilder RosterEmbed(int rosterNumber, IEnumerable players) + { + var rosterPlayers = players.ToList(); + var nonSubstitute = rosterPlayers.Where(p => !p.Substitue); + var substitute = rosterPlayers.Where(p => p.Substitue); + + var separatorLength = Math.Max(nonSubstitute.Select(p => p.Name.Length).Max(), substitute.Select(p => p.Name.Length).Max()); + separatorLength = (int) ((separatorLength + 13) * 0.49); // Don't ask why, it just works + + return new EmbedFieldBuilder() + .WithName($"Roster {rosterNumber}") + .WithValue($"{string.Join("\n", nonSubstitute.Select(FormatRosterPlayer))}\n{new string('━', separatorLength)}\n{string.Join("\n", substitute.Select(FormatRosterPlayer))}") + .WithIsInline(true); + } + + return new EmbedBuilder() + .WithColor(Colors.CocotteBlue) + .WithTitle(":crossed_swords: Raid") + .WithDescription($"**Date:** {TimestampTag.FromDateTime(raid.DateTime, TimestampTagStyles.LongDateTime)}") + .WithFields(raid.Rosters.Select(r => RosterEmbed(r.Key, r))); + } +} \ No newline at end of file diff --git a/Cocotte/Modules/Raids/RaidModule.cs b/Cocotte/Modules/Raids/RaidModule.cs index 00ba9c4..c235403 100644 --- a/Cocotte/Modules/Raids/RaidModule.cs +++ b/Cocotte/Modules/Raids/RaidModule.cs @@ -1,4 +1,5 @@ using System.Diagnostics.CodeAnalysis; +using Cocotte.Options; using Cocotte.Utils; using Discord; using Discord.Interactions; @@ -14,11 +15,13 @@ public class RaidModule : InteractionModuleBase { private readonly ILogger _logger; private readonly IRaidsRepository _raidsRepository; + private readonly RaidFormatter _raidFormatter; - public RaidModule(ILogger logger, IRaidsRepository raidsRepository) + public RaidModule(ILogger logger, IRaidsRepository raidsRepository, RaidFormatter raidFormatter) { _logger = logger; _raidsRepository = raidsRepository; + _raidFormatter = raidFormatter; } [EnabledInDm(false)] @@ -48,14 +51,14 @@ public class RaidModule : InteractionModuleBase // Build the raid message var raid = _raidsRepository[raidId]; - var embed = RaidEmbed(raid); var components = RaidComponents(raidId); + var embed = _raidFormatter.RaidEmbed(raid); await ModifyOriginalResponseAsync(m => { m.Content = ""; - m.Embed = embed.Build(); m.Components = components.Build(); + m.Embed = embed.Build(); }); } @@ -65,7 +68,7 @@ public class RaidModule : InteractionModuleBase if (!_raidsRepository.TryGetRaid(raidId, out var raid)) { await RespondAsync(ephemeral: true, embed: EmbedUtils.ErrorEmbed("This raid does not exist").Build()); - + return; } @@ -74,10 +77,10 @@ public class RaidModule : InteractionModuleBase if (!raid.AddPlayer(user.Id, user.DisplayName, PlayerRole.Dps, 10000)) { await RespondAsync(ephemeral: true, embed: EmbedUtils.InfoEmbed("You're already registered for this raid").Build()); - + return; } - + _logger.LogInformation("User {User} joined raid {Raid}", Context.User.Username, raid); await UpdateRaidRosterEmbed(raid); @@ -90,7 +93,7 @@ public class RaidModule : InteractionModuleBase if (!_raidsRepository.TryGetRaid(raidId, out var raid)) { await RespondAsync(ephemeral: true, embed: EmbedUtils.ErrorEmbed("This raid does not exist").Build()); - + return; } @@ -98,10 +101,10 @@ public class RaidModule : InteractionModuleBase if (!raid.RemovePlayer(user.Id)) { await RespondAsync(ephemeral: true, embed: EmbedUtils.WarningEmbed("You're not registered for this raid").Build()); - + return; } - + await UpdateRaidRosterEmbed(raid); await RespondAsync(ephemeral: true, embed: EmbedUtils.SuccessEmbed("Successfully left the raid").Build()); } @@ -112,34 +115,10 @@ public class RaidModule : InteractionModuleBase if (message is SocketUserMessage userMessage) { - await userMessage.ModifyAsync(m => m.Embed = RaidEmbed(raid).Build()); + await userMessage.ModifyAsync(m => m.Embed = _raidFormatter.RaidEmbed(raid).Build()); } } - private EmbedBuilder RaidEmbed(Raid raid) - { - EmbedFieldBuilder RosterEmbed(int rosterNumber, IEnumerable players) - { - var rosterPlayers = players.ToList(); - var nonSubstitute = rosterPlayers.Where(p => !p.Substitue); - var substitute = rosterPlayers.Where(p => p.Substitue); - - var separatorLength = Math.Max(nonSubstitute.Select(p => p.Name.Length).Max(), substitute.Select(p => p.Name.Length).Max()); - separatorLength = (int) ((separatorLength + 13) * 0.49); // Don't ask why, it just works - - return new EmbedFieldBuilder() - .WithName($"Roster {rosterNumber}") - .WithValue($"{string.Join("\n", nonSubstitute)}\n{new string('━', separatorLength)}\n{string.Join("\n", substitute)}") - .WithIsInline(true); - } - - return new EmbedBuilder() - .WithColor(Colors.CocotteBlue) - .WithTitle(":crossed_swords: Raid") - .WithDescription($"**Date:** {TimestampTag.FromDateTime(raid.DateTime, TimestampTagStyles.LongDateTime)}") - .WithFields(raid.Rosters.Select(r => RosterEmbed(r.Key, r))); - } - private ComponentBuilder RaidComponents(ulong raidId) { return new ComponentBuilder() diff --git a/Cocotte/Modules/Raids/RosterPlayer.cs b/Cocotte/Modules/Raids/RosterPlayer.cs index 7d120ea..983a57b 100644 --- a/Cocotte/Modules/Raids/RosterPlayer.cs +++ b/Cocotte/Modules/Raids/RosterPlayer.cs @@ -1,23 +1,11 @@ -namespace Cocotte.Modules.Raids; +using Cocotte.Options; + +namespace Cocotte.Modules.Raids; public record RosterPlayer(ulong Id, string Name, PlayerRole Role, int Fc, bool Substitue = false) { public int RosterNumber { get; set; } - private static string RoleToEmote(PlayerRole role) => role switch - { - PlayerRole.Dps => ":red_circle:", - PlayerRole.Tank => ":yellow_circle:", - PlayerRole.Healer => ":green_circle:", - _ => ":question:" - }; - - public static string FcFormat(int fc) => fc switch - { - < 1_000 => $"{fc}", - _ => $"{fc/1000}k" - }; - public override int GetHashCode() { return (int) (Id % int.MaxValue); @@ -27,17 +15,4 @@ public record RosterPlayer(ulong Id, string Name, PlayerRole Role, int Fc, bool { return other is not null && other.Id == Id; } - - public override string ToString() => Substitue switch - { - false => $"{RoleToEmote(Role)} {Name} ({FcFormat(Fc)} FC)", - true => $"*{RoleToEmote(Role)} {Name} ({FcFormat(Fc)} FC)*" - }; -} - -public enum PlayerRole -{ - Dps, - Healer, - Tank } \ No newline at end of file diff --git a/Cocotte/Options/RolesOptions.cs b/Cocotte/Options/RolesOptions.cs new file mode 100644 index 0000000..11afa9c --- /dev/null +++ b/Cocotte/Options/RolesOptions.cs @@ -0,0 +1,8 @@ +namespace Cocotte.Options; + +public class RolesOptions +{ + public string DpsEmote { get; set; } = ":red_circle:"; + public string TankEmote { get; set; } = ":yellow_circle:"; + public string HealerEmote { get; set; } = ":green_circle:"; +} \ No newline at end of file diff --git a/Cocotte/Program.cs b/Cocotte/Program.cs index 4b37408..479130f 100644 --- a/Cocotte/Program.cs +++ b/Cocotte/Program.cs @@ -34,6 +34,10 @@ IHost host = Host.CreateDefaultBuilder(args) // Data services.AddSingleton(); + services.AddSingleton(); + + // Raids + services.AddSingleton(); // Custom services.AddSingleton();