From 1ad12096e293064a6d60fa26af3dff8099b2901c Mon Sep 17 00:00:00 2001 From: Isaac Date: Sun, 22 Sep 2024 22:24:45 -0700 Subject: [PATCH] Feat/unit tests (#17) * Add more unit tests * More unit tests * Update README * Cleanup * Final touches for now --- README.md | 16 +++++- lang/en.json | 6 ++- src/CS2/Commands/CoinflipCommand.cs | 11 ++-- src/CS2/Commands/Gang/BalanceCommand.cs | 4 +- src/CS2/Commands/Gang/CreateCommand.cs | 2 - src/CS2/Commands/Gang/DemoteCommand.cs | 12 ++--- src/CS2/Commands/Gang/DepositCommand.cs | 4 +- src/CS2/Commands/Gang/DisbandCommand.cs | 6 +-- src/CS2/Commands/Gang/DisplayCommand.cs | 47 ++++++++--------- src/CS2/Commands/Gang/DoorPolicyCommand.cs | 9 ++-- src/CS2/Commands/Gang/GangedPlayerCommand.cs | 4 +- src/CS2/Commands/Gang/InviteCommand.cs | 32 ++++++------ src/CS2/Commands/Gang/InvitesCommand.cs | 2 +- src/CS2/Commands/Gang/JoinCommand.cs | 3 +- src/CS2/Commands/Gang/KickCommand.cs | 10 ++-- src/CS2/Commands/Gang/LeaveCommand.cs | 4 +- src/CS2/Commands/Gang/PermissionCommand.cs | 22 ++++---- src/CS2/Commands/Gang/PromoteCommand.cs | 10 ++-- src/CS2/Commands/Gang/RankCommand.cs | 22 ++++---- src/CS2/Commands/Gang/SmokeColorCommand.cs | 10 ++-- src/CS2/Commands/Gang/TransferCommand.cs | 10 ++-- src/CS2/Commands/Menus/MembersMenu.cs | 2 +- src/CS2/Commands/Menus/OutgoingInvitesMenu.cs | 17 +++--- src/CS2/Gangs/CommandBasedMenuManager.cs | 9 +++- src/EcoRewards/PeriodicRewarder.cs | 6 +-- src/EcoRewards/RewardsCollection.cs | 2 + src/EcoRewards/RoundWinListener.cs | 9 +++- src/GangsAPI/MSG.cs | 5 +- .../AbstractDB/AbstractInstanceManager.cs | 1 - src/GangsImpl/SQLite/SQLiteGangManager.cs | 1 - .../Stats/Perk/Smoke/SmokeColorPerk.cs | 9 ++-- .../Stats/Perk/Smoke/SmokeListener.cs | 10 ++-- .../Services/Commands/Command/TestParent.cs | 21 -------- src/GangsTest/Commands/BalanceTests.cs | 20 ++----- .../Command => Commands}/FieldTests.cs | 2 +- src/GangsTest/Commands/Gang/BalanceTests.cs | 52 +++++++++++++++++++ src/GangsTest/Commands/Gang/CreateTests.cs | 2 - src/GangsTest/Commands/Gang/GangTests.cs | 5 +- src/GangsTest/Commands/Gang/InviteTests.cs | 1 - .../Commands/Command => Commands}/TestData.cs | 2 +- src/GangsTest/Commands/TestParent.cs | 14 +++++ src/GangsTest/GangTest.cs | 29 +++++++++++ 42 files changed, 281 insertions(+), 184 deletions(-) delete mode 100644 src/GangsTest/API/Services/Commands/Command/TestParent.cs rename src/GangsTest/{API/Services/Commands/Command => Commands}/FieldTests.cs (89%) create mode 100644 src/GangsTest/Commands/Gang/BalanceTests.cs rename src/GangsTest/{API/Services/Commands/Command => Commands}/TestData.cs (97%) create mode 100644 src/GangsTest/Commands/TestParent.cs create mode 100644 src/GangsTest/GangTest.cs diff --git a/README.md b/README.md index 058fa29..14fac54 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,17 @@ -![time spent](https://waka.msws.xyz/api/badge/msws/interval:all/project:Gangs?label=Dev%20Time) +# Gangs + +This plugin allows players to create gangs (guilds / clubs / teams) and invite other players to join said gang. +From there, players are able to obtain currency (internal / default name is credits) and use it to purchase perks for +their gang. +Some example perks are: + +- Colored Smokes +- Gang Chat +- Gang Name Displaying in Scoreboard / Chat + +There is currently no configuration support, and only a MySQL database format has been tested (though, in theory, an +SQLite database could work). + +![time spent](https://waka.msws.xyz/api/badge/msws/interval:all/project:Gangs?label=Dev%20Time) ![badge](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/MSWS/72f982ea80cb7dabb6e91f21d6594ba8/raw/code-coverage.json) [![CodeQL](https://github.com/edgegamers/Gangs/actions/workflows/codeql.yml/badge.svg)](https://github.com/edgegamers/Gangs/actions/workflows/codeql.yml) \ No newline at end of file diff --git a/lang/en.json b/lang/en.json index 1663901..5668647 100644 --- a/lang/en.json +++ b/lang/en.json @@ -42,7 +42,7 @@ "command.rank.rename_prompt": "%prefix%Please use %color.command%/gang rank rename {0} [new name]%color.default% to rename the rank.", "command.transfer.subordinate": "%prefix%You can only transfer ownership to someone with the \"%color.special%{0}%color.default%\" rank.", "command.coinflip.sent": "%prefix%You sent a coinflip request to %color.target%{0}%color.default% for %color.currency%{1} %currency%%s%.", - "command.coinflip.received": "%prefix%%color.target%{0}%color.default% sent you a coinflip request for %color.currency%{1} %currency%%s%.\n%prefix%Type %color.command%/coinflip accept%color.default% to accept.", + "command.coinflip.received": "%prefix%%color.target%{0}%color.default% sent you a coinflip request for %color.currency%{1} %currency%%s%.\n%prefix%Type %color.command%/coinflip yes%color.default% to accept.", "command.coinflip.rejected": "%prefix%%color.target%{0}%color.default% rejected your coinflip request.", "command.coinflip.result": "%prefix%%color.target%{0}%color.default% won a coinflip against %color.target%{1}%color.default% for %color.currency%{2} %currency%%s%.", "command.coinflip.cooldown": "%prefix%You must wait before sending another coinflip request to %color.target%{0}%color.default%.", @@ -104,5 +104,7 @@ "rank.promote.above_highest": "%prefix%You cannot promote %color.target%{0}%color.default% any further.", "rank.promote.success": "Promoted %color.target%{0}%color.default% to %color.special%{1}%color.default%.", "rank.cannot.owner": "%prefix%You cannot {0} as the owner, use %color.command%/gang transfer %color.default% to transfer ownership.", - "command.invite.doorpolicy": "%prefix%Your door policy must be set to invite-only to send invites." + "command.invite.doorpolicy": "%prefix%Your door policy must be set to invite-only to send invites.", + "menu.format.invitation": "%color.special%{0}%color.default% invited %color.target%{1}%color.default% on %color.emph%{2}%color.default%.", + "menu.format.request": "%color.target%{0}%color.default% requested to join on %color.emph%{1}%color.default%." } diff --git a/src/CS2/Commands/CoinflipCommand.cs b/src/CS2/Commands/CoinflipCommand.cs index 60a8640..16dc6e2 100644 --- a/src/CS2/Commands/CoinflipCommand.cs +++ b/src/CS2/Commands/CoinflipCommand.cs @@ -22,15 +22,16 @@ public class CoinflipCommand(IServiceProvider provider) : ICommand { provider.GetRequiredService(); public string Name => "css_coinflip"; - public string[] Aliases => ["coinflip", "cf"]; - public string[] Usage => ["accept", " "]; + public string[] Aliases => ["css_coinflip", "css_cf"]; + public string[] Usage => ["accept/yes", " "]; public async Task Execute(PlayerWrapper? executor, CommandInfoWrapper info) { if (executor == null) return CommandResult.PLAYER_ONLY; - if (info.ArgCount == 2 - && info[1].Equals("accept", StringComparison.OrdinalIgnoreCase)) - return await handleAccept(executor, info); + if (info.ArgCount == 2) + if (info[1].Equals("accept", StringComparison.OrdinalIgnoreCase) + || info[1].Equals("yes", StringComparison.OrdinalIgnoreCase)) + return await handleAccept(executor, info); if (info.ArgCount != 3) return CommandResult.PRINT_USAGE; var target = await targeter.GetSingleTarget(info[1], executor, locale); diff --git a/src/CS2/Commands/Gang/BalanceCommand.cs b/src/CS2/Commands/Gang/BalanceCommand.cs index c98ecf3..c91241f 100644 --- a/src/CS2/Commands/Gang/BalanceCommand.cs +++ b/src/CS2/Commands/Gang/BalanceCommand.cs @@ -24,11 +24,11 @@ public class BalanceCommand(IServiceProvider provider) ?? throw new GangNotFoundException(player.GangId.Value); if (!success) { - info.ReplySync(Localizer.Get(MSG.COMMAND_BALANCE_GANG_NONE, gang.Name)); + info.ReplySync(Locale.Get(MSG.COMMAND_BALANCE_GANG_NONE, gang.Name)); return CommandResult.SUCCESS; } - info.ReplySync(Localizer.Get(MSG.COMMAND_BALANCE_GANG, gang.Name, balance)); + info.ReplySync(Locale.Get(MSG.COMMAND_BALANCE_GANG, gang.Name, balance)); return CommandResult.SUCCESS; } } \ No newline at end of file diff --git a/src/CS2/Commands/Gang/CreateCommand.cs b/src/CS2/Commands/Gang/CreateCommand.cs index 87c603e..95b7e7a 100644 --- a/src/CS2/Commands/Gang/CreateCommand.cs +++ b/src/CS2/Commands/Gang/CreateCommand.cs @@ -10,7 +10,6 @@ using Microsoft.Extensions.Localization; namespace Commands.Gang; -// create [name] public class CreateCommand(IServiceProvider provider) : ICommand { private const int CREATION_COST = 500; @@ -29,7 +28,6 @@ public class CreateCommand(IServiceProvider provider) : ICommand { public async Task Execute(PlayerWrapper? executor, CommandInfoWrapper info) { if (executor == null) return CommandResult.PLAYER_ONLY; - if (info.ArgCount < 2) return CommandResult.PRINT_USAGE; var name = string.Join(' ', info.Args.Skip(1)); diff --git a/src/CS2/Commands/Gang/DemoteCommand.cs b/src/CS2/Commands/Gang/DemoteCommand.cs index 8483bed..c532d96 100644 --- a/src/CS2/Commands/Gang/DemoteCommand.cs +++ b/src/CS2/Commands/Gang/DemoteCommand.cs @@ -26,7 +26,7 @@ public class DemoteCommand(IServiceProvider provider) var (allowed, required) = await Ranks.CheckRank(player, Perm.DEMOTE_OTHERS); if (!allowed) { - info.ReplySync(Localizer.Get(MSG.GENERIC_NOPERM_RANK, required.Name)); + info.ReplySync(Locale.Get(MSG.GENERIC_NOPERM_RANK, required.Name)); return CommandResult.NO_PERMISSION; } @@ -40,7 +40,7 @@ public class DemoteCommand(IServiceProvider provider) var target = await Players.SearchPlayer(gang, query); if (target == null) { - info.ReplySync(Localizer.Get(MSG.GENERIC_PLAYER_NOT_FOUND, query)); + info.ReplySync(Locale.Get(MSG.GENERIC_PLAYER_NOT_FOUND, query)); return CommandResult.SUCCESS; } @@ -55,7 +55,7 @@ public class DemoteCommand(IServiceProvider provider) // Trying to demote below the lowest rank, they need to kick instead if (lower == null) { - info.ReplySync(Localizer.Get(MSG.RANK_DEMOTE_BELOW_LOWEST, + info.ReplySync(Locale.Get(MSG.RANK_DEMOTE_BELOW_LOWEST, target.Name ?? target.Steam.ToString())); return CommandResult.NO_PERMISSION; } @@ -64,11 +64,11 @@ public class DemoteCommand(IServiceProvider provider) // Can't demote someone with the same or higher rank if (higher == null) { // No higher rank, can't demote - info.ReplySync(Localizer.Get(MSG.RANK_CANNOT_OWNER, "demote yourself")); + info.ReplySync(Locale.Get(MSG.RANK_CANNOT_OWNER, "demote yourself")); return CommandResult.NO_PERMISSION; } - info.ReplySync(Localizer.Get(MSG.GENERIC_NOPERM_RANK, higher.Name)); + info.ReplySync(Locale.Get(MSG.GENERIC_NOPERM_RANK, higher.Name)); return CommandResult.NO_PERMISSION; } @@ -79,7 +79,7 @@ public class DemoteCommand(IServiceProvider provider) var gangChat = Provider.GetService(); if (gangChat != null) await gangChat.SendGangChat(player, gang, - Localizer.Get(MSG.RANK_DEMOTE_SUCCESS, + Locale.Get(MSG.RANK_DEMOTE_SUCCESS, target.Name ?? target.Steam.ToString(), lower.Name)); return CommandResult.SUCCESS; } diff --git a/src/CS2/Commands/Gang/DepositCommand.cs b/src/CS2/Commands/Gang/DepositCommand.cs index a17de8d..098dc67 100644 --- a/src/CS2/Commands/Gang/DepositCommand.cs +++ b/src/CS2/Commands/Gang/DepositCommand.cs @@ -22,12 +22,12 @@ public class DepositCommand(IServiceProvider provider) await Ranks.CheckRank(gangPlayer, Perm.BANK_DEPOSIT); if (!authorized) { - info.ReplySync(Localizer.Get(MSG.GENERIC_NOPERM, required.Name)); + info.ReplySync(Locale.Get(MSG.GENERIC_NOPERM, required.Name)); return CommandResult.SUCCESS; } if (!int.TryParse(info[1], out var amount) || amount <= 0) { - info.ReplySync(Localizer.Get(MSG.COMMAND_INVALID_PARAM, info[1], + info.ReplySync(Locale.Get(MSG.COMMAND_INVALID_PARAM, info[1], "a positive integer")); return CommandResult.SUCCESS; } diff --git a/src/CS2/Commands/Gang/DisbandCommand.cs b/src/CS2/Commands/Gang/DisbandCommand.cs index c22c87c..1e1ff5b 100644 --- a/src/CS2/Commands/Gang/DisbandCommand.cs +++ b/src/CS2/Commands/Gang/DisbandCommand.cs @@ -24,7 +24,7 @@ public class DisbandCommand(IServiceProvider provider) Perm.OWNER); if (!success) { - info.ReplySync(Localizer.Get(MSG.GENERIC_NOPERM_RANK, required.Name)); + info.ReplySync(Locale.Get(MSG.GENERIC_NOPERM_RANK, required.Name)); return CommandResult.SUCCESS; } @@ -32,7 +32,7 @@ public class DisbandCommand(IServiceProvider provider) throw new GangException("Passed rank check but not numerical check"); if (info.ArgCount == 1) { - info.ReplySync(Localizer.Get(MSG.COMMAND_GANG_DISBAND_WARN)); + info.ReplySync(Locale.Get(MSG.COMMAND_GANG_DISBAND_WARN)); return CommandResult.SUCCESS; } @@ -43,7 +43,7 @@ public class DisbandCommand(IServiceProvider provider) if (GangChat != null) await GangChat.SendGangChat(gang, - Localizer.Get(MSG.COMMAND_GANG_DISBANDED, + Locale.Get(MSG.COMMAND_GANG_DISBANDED, executor.Name ?? executor.Steam.ToString())); await Gangs.DeleteGang(player.GangId.Value); diff --git a/src/CS2/Commands/Gang/DisplayCommand.cs b/src/CS2/Commands/Gang/DisplayCommand.cs index 250ad87..ea08870 100644 --- a/src/CS2/Commands/Gang/DisplayCommand.cs +++ b/src/CS2/Commands/Gang/DisplayCommand.cs @@ -56,7 +56,7 @@ public class DisplayCommand(IServiceProvider provider) if (display == 0) { if (!await perk.HasChatDisplay(gang)) { if (!canBuy) { - info.ReplySync(Localizer.Get(MSG.GENERIC_NOPERM_RANK, required.Name)); + info.ReplySync(Locale.Get(MSG.GENERIC_NOPERM_RANK, required.Name)); return CommandResult.NO_PERMISSION; } @@ -70,7 +70,7 @@ public class DisplayCommand(IServiceProvider provider) if (gangChat == null) return CommandResult.SUCCESS; await gangChat.SendGangChat(player, gang, - Localizer.Get(MSG.PERK_PURCHASED, + Locale.Get(MSG.PERK_PURCHASED, player.Name ?? player.Steam.ToString(), "Display: Chat")); return CommandResult.SUCCESS; } @@ -80,34 +80,33 @@ public class DisplayCommand(IServiceProvider provider) ?? throw new GangException("Display setting not found"); var enabled = await displaySetting.IsChatEnabled(player.Steam); await displaySetting.SetChatEnabled(player.Steam, !enabled); - info.ReplySync(Localizer.Get(MSG.PERK_DISPLAY_CHAT, + info.ReplySync(Locale.Get(MSG.PERK_DISPLAY_CHAT, enabled ? ChatColors.Red + "disabled" : ChatColors.Green + "enabled")); await updateDisplay(executor, gang.Name, !enabled ? 1 : 0); return CommandResult.SUCCESS; } - if (!await perk.HasScoreboardDisplay(gang)) - if (!await perk.HasScoreboardDisplay(gang)) { - if (!canBuy) { - info.ReplySync(Localizer.Get(MSG.GENERIC_NOPERM_RANK, required.Name)); - return CommandResult.NO_PERMISSION; - } - - if (await eco.TryPurchase(executor, perk.ScoreboardCost, - item: "Scoreboard Display") < 0) - return CommandResult.SUCCESS; - - await perk.SetScoreboardDisplay(gang, true); - - var gangChat = Provider.GetService(); - if (gangChat == null) return CommandResult.SUCCESS; - - await gangChat.SendGangChat(player, gang, - Localizer.Get(MSG.PERK_PURCHASED, - player.Name ?? player.Steam.ToString(), "Display: Scoreboard")); - return CommandResult.SUCCESS; + if (!await perk.HasScoreboardDisplay(gang)) { + if (!canBuy) { + info.ReplySync(Locale.Get(MSG.GENERIC_NOPERM_RANK, required.Name)); + return CommandResult.NO_PERMISSION; } + if (await eco.TryPurchase(executor, perk.ScoreboardCost, + item: "Scoreboard Display") < 0) + return CommandResult.SUCCESS; + + await perk.SetScoreboardDisplay(gang, true); + + var gangChat = Provider.GetService(); + if (gangChat == null) return CommandResult.SUCCESS; + + await gangChat.SendGangChat(player, gang, + Locale.Get(MSG.PERK_PURCHASED, + player.Name ?? player.Steam.ToString(), "Display: Scoreboard")); + return CommandResult.SUCCESS; + } + // Toggle var scoreboardSetting = Provider.GetService() ?? throw new GangException("Display setting not found"); @@ -115,7 +114,7 @@ public class DisplayCommand(IServiceProvider provider) await scoreboardSetting.IsScoreboardEnabled(player.Steam); await scoreboardSetting.SetScoreboardEnabled(player.Steam, !scoreboardEnabled); - info.ReplySync(Localizer.Get(MSG.PERK_DISPLAY_SCOREBOARD, + info.ReplySync(Locale.Get(MSG.PERK_DISPLAY_SCOREBOARD, scoreboardEnabled ? ChatColors.Red + "disabled" : ChatColors.Green + "enabled")); diff --git a/src/CS2/Commands/Gang/DoorPolicyCommand.cs b/src/CS2/Commands/Gang/DoorPolicyCommand.cs index 96f71d6..9ff879a 100644 --- a/src/CS2/Commands/Gang/DoorPolicyCommand.cs +++ b/src/CS2/Commands/Gang/DoorPolicyCommand.cs @@ -42,7 +42,7 @@ public class DoorPolicyCommand(IServiceProvider provider) if (info.ArgCount == 2) { if (!int.TryParse(info.Args[1], out var selectedIndex)) { - info.ReplySync(Localizer.Get(MSG.COMMAND_INVALID_PARAM, info.Args[1], + info.ReplySync(Locale.Get(MSG.COMMAND_INVALID_PARAM, info.Args[1], "a number")); return CommandResult.SUCCESS; } @@ -51,21 +51,22 @@ public class DoorPolicyCommand(IServiceProvider provider) await ranks.CheckRank(player, Perm.MANAGE_INVITES); if (!success) { - info.ReplySync(Localizer.Get(MSG.GENERIC_NOPERM_RANK, required.Name)); + info.ReplySync(Locale.Get(MSG.GENERIC_NOPERM_RANK, required.Name)); return CommandResult.SUCCESS; } var gang = await gangs.GetGang(player.GangId.Value) ?? throw new GangNotFoundException(player.GangId.Value); - var selected = (DoorPolicy)selectedIndex; + var selected = + (DoorPolicy)(selectedIndex % Enum.GetValues().Length); await gangStats.SetForGang(player.GangId.Value, doorPolicyId, selected); var gangChat = Provider.GetService(); if (gangChat != null) await gangChat.SendGangChat(player, gang, - Localizer.Get(MSG.GANG_THING_SET, "Door Policy", + Locale.Get(MSG.GANG_THING_SET, "Door Policy", selected.ToString().ToTitleCase())); return CommandResult.SUCCESS; diff --git a/src/CS2/Commands/Gang/GangedPlayerCommand.cs b/src/CS2/Commands/Gang/GangedPlayerCommand.cs index b40898d..41a9491 100644 --- a/src/CS2/Commands/Gang/GangedPlayerCommand.cs +++ b/src/CS2/Commands/Gang/GangedPlayerCommand.cs @@ -36,7 +36,7 @@ public abstract class GangedPlayerCommand(IServiceProvider provider) protected readonly IGangStatManager GangStats = provider.GetRequiredService(); - protected readonly IStringLocalizer Localizer = + protected readonly IStringLocalizer Locale = provider.GetRequiredService(); protected readonly IMenuManager Menus = @@ -68,7 +68,7 @@ public abstract class GangedPlayerCommand(IServiceProvider provider) var gangPlayer = await Players.GetPlayer(executor.Steam) ?? throw new PlayerNotFoundException(executor.Steam); if (gangPlayer.GangId == null || gangPlayer.GangRank == null) { - info.ReplySync(Localizer.Get(MSG.NOT_IN_GANG)); + info.ReplySync(Locale.Get(MSG.NOT_IN_GANG)); return CommandResult.SUCCESS; } diff --git a/src/CS2/Commands/Gang/InviteCommand.cs b/src/CS2/Commands/Gang/InviteCommand.cs index 8062d59..dfd67ea 100644 --- a/src/CS2/Commands/Gang/InviteCommand.cs +++ b/src/CS2/Commands/Gang/InviteCommand.cs @@ -46,7 +46,7 @@ public class InviteCommand(IServiceProvider provider) if (!policySuccess) doorPolicy = DoorPolicy.INVITE_ONLY; if (doorPolicy != DoorPolicy.INVITE_ONLY) { - info.ReplySync(Localizer.Get(MSG.COMMAND_INVITE_DOORPOLICY)); + info.ReplySync(Locale.Get(MSG.COMMAND_INVITE_DOORPOLICY)); return CommandResult.ERROR; } @@ -57,7 +57,7 @@ public class InviteCommand(IServiceProvider provider) var capacity = await capacityPerk.GetCapacity(player.GangId.Value); var members = (await Players.GetMembers(player.GangId.Value)).Count(); if (members >= capacity) { - info.ReplySync(Localizer.Get(MSG.GANG_FULL, gang.Name)); + info.ReplySync(Locale.Get(MSG.GANG_FULL, gang.Name)); return CommandResult.ERROR; } } @@ -78,7 +78,7 @@ public class InviteCommand(IServiceProvider provider) Debug.Assert(player.GangId != null, "player.GangId != null"); var required = await Ranks.GetRankNeeded(player.GangId.Value, Perm.INVITE_OTHERS); - info.ReplySync(Localizer.Get(MSG.GENERIC_NOPERM_RANK, required.Name)); + info.ReplySync(Locale.Get(MSG.GENERIC_NOPERM_RANK, required.Name)); return CommandResult.NO_PERMISSION; } @@ -107,9 +107,9 @@ public class InviteCommand(IServiceProvider provider) if (invites.RemoveInvitation(steamId)) { Debug.Assert(player.GangId != null, "player.GangId != null"); await GangStats.SetForGang(player.GangId.Value, gangInviteId, invites); - info.ReplySync(Localizer.Get(MSG.COMMAND_INVITE_CANCELED, query)); + info.ReplySync(Locale.Get(MSG.COMMAND_INVITE_CANCELED, query)); } else { - info.ReplySync(Localizer.Get(MSG.COMMAND_INVITE_NOTFOUND, query)); + info.ReplySync(Locale.Get(MSG.COMMAND_INVITE_NOTFOUND, query)); } return steamId; @@ -122,10 +122,10 @@ public class InviteCommand(IServiceProvider provider) switch (invitedNames.Count) { case 0: - info.ReplySync(Localizer.Get(MSG.COMMAND_INVITE_NOTFOUND, query)); + info.ReplySync(Locale.Get(MSG.COMMAND_INVITE_NOTFOUND, query)); return null; case > 1: - info.ReplySync(Localizer.Get(MSG.COMMAND_INVITE_FOUNDMULTIPLE, query)); + info.ReplySync(Locale.Get(MSG.COMMAND_INVITE_FOUNDMULTIPLE, query)); return null; } @@ -133,7 +133,7 @@ public class InviteCommand(IServiceProvider provider) if (invites.RemoveInvitation(steamId)) { Debug.Assert(player.GangId != null, "player.GangId != null"); await GangStats.SetForGang(player.GangId.Value, gangInviteId, invites); - info.ReplySync(Localizer.Get(MSG.COMMAND_INVITE_CANCELED, name)); + info.ReplySync(Locale.Get(MSG.COMMAND_INVITE_CANCELED, name)); } else { throw new GangException( $"failed to remove invite which we found via {query}"); @@ -163,7 +163,7 @@ public class InviteCommand(IServiceProvider provider) if (info.ArgCount != 2) return CommandResult.PRINT_USAGE; if (invites.GetEntries().Count >= invites.MaxAmo) { - info.ReplySync(Localizer.Get(MSG.COMMAND_INVITE_MAXINVITES, + info.ReplySync(Locale.Get(MSG.COMMAND_INVITE_MAXINVITES, invites.MaxAmo)); return CommandResult.ERROR; } @@ -178,7 +178,7 @@ public class InviteCommand(IServiceProvider provider) PlayerWrapper executor) { if (info[1].All(char.IsDigit)) return ulong.Parse(info[1]); - return (await playerTargeter.GetSingleTarget(info[1], executor, Localizer)) + return (await playerTargeter.GetSingleTarget(info[1], executor, Locale)) ?.Steam; } @@ -187,12 +187,12 @@ public class InviteCommand(IServiceProvider provider) ulong steam) { var offlinePlayer = await Players.GetPlayer(steam, false); if (offlinePlayer == null) { - info.ReplySync(Localizer.Get(MSG.GENERIC_STEAM_NOT_FOUND, steam)); + info.ReplySync(Locale.Get(MSG.GENERIC_STEAM_NOT_FOUND, steam)); return CommandResult.SUCCESS; } if (invites.GetInvitedSteams().Contains(steam)) { - info.ReplySync(Localizer.Get(MSG.COMMAND_INVITE_ALREADY_INVITED, + info.ReplySync(Locale.Get(MSG.COMMAND_INVITE_ALREADY_INVITED, offlinePlayer.Name ?? offlinePlayer.Steam.ToString())); return CommandResult.SUCCESS; } @@ -201,7 +201,7 @@ public class InviteCommand(IServiceProvider provider) var msg = offlinePlayer.GangId == player.GangId ? MSG.COMMAND_INVITE_IN_YOUR_GANG : MSG.COMMAND_INVITE_ALREADY_IN_GANG; - info.ReplySync(Localizer.Get(msg, + info.ReplySync(Locale.Get(msg, offlinePlayer.Name ?? offlinePlayer.Steam.ToString())); return CommandResult.SUCCESS; } @@ -209,7 +209,7 @@ public class InviteCommand(IServiceProvider provider) Debug.Assert(player.GangId != null, "player.GangId != null"); var gangName = (await Gangs.GetGang(player.GangId.Value))?.Name; if (gangName == null) { - info.ReplySync(Localizer.Get(MSG.GENERIC_ERROR_INFO, + info.ReplySync(Locale.Get(MSG.GENERIC_ERROR_INFO, "Gang name not found")); return CommandResult.ERROR; } @@ -217,13 +217,13 @@ public class InviteCommand(IServiceProvider provider) invites.AddInvitation(executor.Steam, steam); await GangStats.SetForGang(player.GangId.Value, gangInviteId, invites); - info.ReplySync(Localizer.Get(MSG.COMMAND_INVITE_SUCCESS, + info.ReplySync(Locale.Get(MSG.COMMAND_INVITE_SUCCESS, offlinePlayer.Name ?? offlinePlayer.Steam.ToString(), gangName)); var onlinePlayer = await playerTargeter.GetSingleTarget(offlinePlayer.Steam.ToString()); - onlinePlayer?.PrintToChat(Localizer.Get(MSG.GANG_INVITED, + onlinePlayer?.PrintToChat(Locale.Get(MSG.GANG_INVITED, player.Name ?? player.Steam.ToString(), gangName)); return await addPendingInvitation(player, offlinePlayer.Steam); } diff --git a/src/CS2/Commands/Gang/InvitesCommand.cs b/src/CS2/Commands/Gang/InvitesCommand.cs index b29b160..71c0e4c 100644 --- a/src/CS2/Commands/Gang/InvitesCommand.cs +++ b/src/CS2/Commands/Gang/InvitesCommand.cs @@ -35,7 +35,7 @@ public class InvitesCommand(IServiceProvider provider) await Ranks.CheckRank(player, Perm.INVITE_OTHERS); if (!permitted) { - info.ReplySync(Localizer.Get(MSG.GENERIC_NOPERM_RANK, minimum.Name)); + info.ReplySync(Locale.Get(MSG.GENERIC_NOPERM_RANK, minimum.Name)); return CommandResult.NO_PERMISSION; } diff --git a/src/CS2/Commands/Gang/JoinCommand.cs b/src/CS2/Commands/Gang/JoinCommand.cs index f3169c0..9967f54 100644 --- a/src/CS2/Commands/Gang/JoinCommand.cs +++ b/src/CS2/Commands/Gang/JoinCommand.cs @@ -1,5 +1,4 @@ -using System.Text.Json.Serialization; -using GangsAPI; +using GangsAPI; using GangsAPI.Data; using GangsAPI.Data.Command; using GangsAPI.Data.Gang; diff --git a/src/CS2/Commands/Gang/KickCommand.cs b/src/CS2/Commands/Gang/KickCommand.cs index 824e9a8..c9789cf 100644 --- a/src/CS2/Commands/Gang/KickCommand.cs +++ b/src/CS2/Commands/Gang/KickCommand.cs @@ -38,7 +38,7 @@ public class KickCommand(IServiceProvider provider) var (allowed, required) = await ranks.CheckRank(player, Perm.KICK_OTHERS); if (!allowed) { - info.ReplySync(Localizer.Get(MSG.GENERIC_NOPERM_RANK, required.Name)); + info.ReplySync(Locale.Get(MSG.GENERIC_NOPERM_RANK, required.Name)); return CommandResult.NO_PERMISSION; } @@ -51,7 +51,7 @@ public class KickCommand(IServiceProvider provider) var target = await searchPlayer(gang, query); if (target == null) { - info.ReplySync(Localizer.Get(MSG.GENERIC_PLAYER_NOT_FOUND, query)); + info.ReplySync(Locale.Get(MSG.GENERIC_PLAYER_NOT_FOUND, query)); return CommandResult.SUCCESS; } @@ -61,12 +61,12 @@ public class KickCommand(IServiceProvider provider) var higherRank = await ranks.GetHigherRank(gang.GangId, targetRank.Rank); if (higherRank == null) { - info.ReplySync(Localizer.Get(MSG.RANK_CANNOT_OWNER, "kick yourself")); + info.ReplySync(Locale.Get(MSG.RANK_CANNOT_OWNER, "kick yourself")); return CommandResult.NO_PERMISSION; } if (targetRank.Rank <= executorRank.Rank) { - info.ReplySync(Localizer.Get(MSG.GENERIC_NOPERM_RANK, higherRank.Name)); + info.ReplySync(Locale.Get(MSG.GENERIC_NOPERM_RANK, higherRank.Name)); return CommandResult.NO_PERMISSION; } @@ -79,7 +79,7 @@ public class KickCommand(IServiceProvider provider) if (gangChat != null) await gangChat.SendGangChat(player, gang, - Localizer.Get(MSG.COMMAND_GANG_KICKED, + Locale.Get(MSG.COMMAND_GANG_KICKED, target.Name ?? target.Steam.ToString())); return CommandResult.SUCCESS; } diff --git a/src/CS2/Commands/Gang/LeaveCommand.cs b/src/CS2/Commands/Gang/LeaveCommand.cs index 7ef1d93..1af6bb2 100644 --- a/src/CS2/Commands/Gang/LeaveCommand.cs +++ b/src/CS2/Commands/Gang/LeaveCommand.cs @@ -20,13 +20,13 @@ public class LeaveCommand(IServiceProvider provider) Debug.Assert(player.GangRank != null, "player.GangRank != null"); if (player.GangRank.Value == 0) { - info.ReplySync(Localizer.Get(MSG.RANK_CANNOT_OWNER, "leave")); + info.ReplySync(Locale.Get(MSG.RANK_CANNOT_OWNER, "leave")); return CommandResult.SUCCESS; } if (GangChat != null) await GangChat.SendGangChat(player, gang, - Localizer.Get(MSG.COMMAND_LEAVE_LEFT, + Locale.Get(MSG.COMMAND_LEAVE_LEFT, player.Name ?? player.Steam.ToString())); player.GangId = null; diff --git a/src/CS2/Commands/Gang/PermissionCommand.cs b/src/CS2/Commands/Gang/PermissionCommand.cs index 3e2deb3..728b01a 100644 --- a/src/CS2/Commands/Gang/PermissionCommand.cs +++ b/src/CS2/Commands/Gang/PermissionCommand.cs @@ -54,7 +54,7 @@ public class PermissionCommand(IServiceProvider provider) ?? throw new GangNotFoundException(player.GangId.Value); if (!allowed) { - info.ReplySync(Localizer.Get(MSG.GENERIC_NOPERM_RANK, required.Name)); + info.ReplySync(Locale.Get(MSG.GENERIC_NOPERM_RANK, required.Name)); return CommandResult.NO_PERMISSION; } @@ -90,7 +90,7 @@ public class PermissionCommand(IServiceProvider provider) case 2: { var directEdit = await getRank(executor, player, info.Args[1]); if (directEdit == null) { - info.ReplySync(Localizer.Get(MSG.RANK_NOT_FOUND, info.Args[1])); + info.ReplySync(Locale.Get(MSG.RANK_NOT_FOUND, info.Args[1])); return CommandResult.SUCCESS; } @@ -106,12 +106,12 @@ public class PermissionCommand(IServiceProvider provider) var rank = await getRank(executor, player, info.Args[2]); if (rank == null) { - info.ReplySync(Localizer.Get(MSG.RANK_NOT_FOUND, info.Args[2])); + info.ReplySync(Locale.Get(MSG.RANK_NOT_FOUND, info.Args[2])); return CommandResult.SUCCESS; } if (rank.Rank <= executorRank.Rank) { - info.ReplySync(Localizer.Get(MSG.RANK_CANNOT_EDIT, rank.Name)); + info.ReplySync(Locale.Get(MSG.RANK_CANNOT_EDIT, rank.Name)); return CommandResult.SUCCESS; } @@ -123,14 +123,14 @@ public class PermissionCommand(IServiceProvider provider) if (int.TryParse(info.Args[3], out var permInt)) { permsChanging = (Perm)permInt; } else if (!Enum.TryParse(query, true, out permsChanging)) { - info.ReplySync(Localizer.Get(MSG.COMMAND_INVALID_PARAM, query, + info.ReplySync(Locale.Get(MSG.COMMAND_INVALID_PARAM, query, "rank or int")); return CommandResult.SUCCESS; } if (!executorRank.Permissions.HasFlag(permsChanging)) { var missing = permsChanging ^ executorRank.Permissions; - info.ReplySync(Localizer.Get(MSG.GENERIC_NOPERM_NODE, + info.ReplySync(Locale.Get(MSG.GENERIC_NOPERM_NODE, missing.Describe())); return CommandResult.NO_PERMISSION; } @@ -140,15 +140,15 @@ public class PermissionCommand(IServiceProvider provider) switch (info.Args[1].ToLower()) { case "grant": applicator = original => original | permsChanging; - msg = Localizer.Get(MSG.RANK_MODIFY_GRANT, permsChanging, rank.Name); + msg = Locale.Get(MSG.RANK_MODIFY_GRANT, permsChanging, rank.Name); break; case "revoke": applicator = original => original & permsChanging; - msg = Localizer.Get(MSG.RANK_MODIFY_REVOKE, permsChanging, rank.Name); + msg = Locale.Get(MSG.RANK_MODIFY_REVOKE, permsChanging, rank.Name); break; case "set": applicator = _ => permsChanging; - msg = Localizer.Get(MSG.RANK_MODIFY_SET, rank.Name, + msg = Locale.Get(MSG.RANK_MODIFY_SET, rank.Name, permsChanging.Describe()); break; default: @@ -160,7 +160,7 @@ public class PermissionCommand(IServiceProvider provider) var result = await ranks.UpdateRank(player.GangId.Value, rank); if (!result) { - executor.PrintToChat(Localizer.Get(MSG.GENERIC_ERROR)); + executor.PrintToChat(Locale.Get(MSG.GENERIC_ERROR)); return CommandResult.ERROR; } @@ -179,7 +179,7 @@ public class PermissionCommand(IServiceProvider provider) => r.Name.Equals(query, StringComparison.OrdinalIgnoreCase)); if (result == null) - wrapper.PrintToChat(Localizer.Get(MSG.RANK_NOT_FOUND, query)); + wrapper.PrintToChat(Locale.Get(MSG.RANK_NOT_FOUND, query)); return result; } diff --git a/src/CS2/Commands/Gang/PromoteCommand.cs b/src/CS2/Commands/Gang/PromoteCommand.cs index ff180b5..11c8420 100644 --- a/src/CS2/Commands/Gang/PromoteCommand.cs +++ b/src/CS2/Commands/Gang/PromoteCommand.cs @@ -39,7 +39,7 @@ public class PromoteCommand(IServiceProvider provider) await ranks.CheckRank(player, Perm.PROMOTE_OTHERS); if (!allowed) { - info.ReplySync(Localizer.Get(MSG.GENERIC_NOPERM_RANK, required.Name)); + info.ReplySync(Locale.Get(MSG.GENERIC_NOPERM_RANK, required.Name)); return CommandResult.NO_PERMISSION; } @@ -53,7 +53,7 @@ public class PromoteCommand(IServiceProvider provider) var target = await searchPlayer(gang, query); if (target == null) { - info.ReplySync(Localizer.Get(MSG.GENERIC_PLAYER_NOT_FOUND, query)); + info.ReplySync(Locale.Get(MSG.GENERIC_PLAYER_NOT_FOUND, query)); return CommandResult.SUCCESS; } @@ -63,14 +63,14 @@ public class PromoteCommand(IServiceProvider provider) var higher = await ranks.GetHigherRank(gang.GangId, targetRank.Rank); // Trying to promote above the highest rank if (higher == null) { - info.ReplySync(Localizer.Get(MSG.RANK_PROMOTE_ABOVE_HIGHEST, + info.ReplySync(Locale.Get(MSG.RANK_PROMOTE_ABOVE_HIGHEST, target.Name ?? target.Steam.ToString())); return CommandResult.NO_PERMISSION; } if (higher.Rank < executorRank.Rank) { // Can't promote to a rank higher than your own - info.ReplySync(Localizer.Get(MSG.GENERIC_NOPERM_RANK, higher.Name)); + info.ReplySync(Locale.Get(MSG.GENERIC_NOPERM_RANK, higher.Name)); return CommandResult.NO_PERMISSION; } @@ -81,7 +81,7 @@ public class PromoteCommand(IServiceProvider provider) var gangChat = Provider.GetService(); if (gangChat != null) await gangChat.SendGangChat(player, gang, - Localizer.Get(MSG.RANK_PROMOTE_SUCCESS, + Locale.Get(MSG.RANK_PROMOTE_SUCCESS, target.Name ?? target.Steam.ToString(), higher.Name)); return CommandResult.SUCCESS; } diff --git a/src/CS2/Commands/Gang/RankCommand.cs b/src/CS2/Commands/Gang/RankCommand.cs index d83beca..580bed8 100644 --- a/src/CS2/Commands/Gang/RankCommand.cs +++ b/src/CS2/Commands/Gang/RankCommand.cs @@ -38,7 +38,7 @@ public class RankCommand(IServiceProvider provider) ?? throw new RankNotFoundException(player); if (!int.TryParse(info[2], out var targetRank)) { - info.ReplySync(Localizer.Get(MSG.COMMAND_INVALID_PARAM, info[2], + info.ReplySync(Locale.Get(MSG.COMMAND_INVALID_PARAM, info[2], "an integer")); return CommandResult.INVALID_ARGS; } @@ -47,7 +47,7 @@ public class RankCommand(IServiceProvider provider) || !executorRank.Permissions.HasFlag(Perm.MANAGE_RANKS)) { var higher = await Ranks.GetHigherRank(gang.GangId, targetRank) ?? throw new RankNotFoundException(gang.GangId, targetRank); - info.ReplySync(Localizer.Get(MSG.GENERIC_NOPERM_RANK, higher.Name)); + info.ReplySync(Locale.Get(MSG.GENERIC_NOPERM_RANK, higher.Name)); return CommandResult.NO_PERMISSION; } @@ -71,18 +71,18 @@ public class RankCommand(IServiceProvider provider) var name = string.Join(' ', info.Args.Skip(3)); var existing = await Ranks.GetRank(gang.GangId, rank); if (existing != null) { - info.ReplySync(Localizer.Get(MSG.COMMAND_RANK_EXISTS, existing.Name)); + info.ReplySync(Locale.Get(MSG.COMMAND_RANK_EXISTS, existing.Name)); return CommandResult.ERROR; } var newRank = await Ranks.CreateRank(gang.GangId, name, rank, Perm.NONE); if (newRank == null) { - info.ReplySync(Localizer.Get(MSG.GENERIC_ERROR)); + info.ReplySync(Locale.Get(MSG.GENERIC_ERROR)); return CommandResult.ERROR; } await gangChat.SendGangChat(player, gang, - Localizer.Get(MSG.COMMAND_RANK_CREATED, newRank.Name)); + Locale.Get(MSG.COMMAND_RANK_CREATED, newRank.Name)); return CommandResult.SUCCESS; } @@ -91,7 +91,7 @@ public class RankCommand(IServiceProvider provider) var target = await Ranks.GetRank(gang.GangId, rank) ?? throw new RankNotFoundException(gang.GangId, rank); if (target.Rank == 0) { - info.ReplySync(Localizer.Get(MSG.COMMAND_RANK_CANNOT_DELETE, + info.ReplySync(Locale.Get(MSG.COMMAND_RANK_CANNOT_DELETE, target.Name)); return CommandResult.ERROR; } @@ -101,7 +101,7 @@ public class RankCommand(IServiceProvider provider) .ToList(); if (assigned.Count != 0) { - info.ReplySync(Localizer.Get(MSG.COMMAND_RANK_CANNOT_DELETE, + info.ReplySync(Locale.Get(MSG.COMMAND_RANK_CANNOT_DELETE, target.Name)); return CommandResult.SUCCESS; } @@ -109,12 +109,12 @@ public class RankCommand(IServiceProvider provider) var result = await Ranks.DeleteRank(gang.GangId, target, IRankManager.DeleteStrat.DEMOTE_FAIL); if (!result) { - info.ReplySync(Localizer.Get(MSG.GENERIC_ERROR)); + info.ReplySync(Locale.Get(MSG.GENERIC_ERROR)); return CommandResult.ERROR; } await gangChat.SendGangChat(player, gang, - Localizer.Get(MSG.COMMAND_RANK_DELETED, target.Name)); + Locale.Get(MSG.COMMAND_RANK_DELETED, target.Name)); return CommandResult.SUCCESS; } @@ -129,12 +129,12 @@ public class RankCommand(IServiceProvider provider) var result = await Ranks.UpdateRank(gang.GangId, target); if (!result) { - info.ReplySync(Localizer.Get(MSG.GENERIC_ERROR)); + info.ReplySync(Locale.Get(MSG.GENERIC_ERROR)); return CommandResult.ERROR; } await gangChat.SendGangChat(player, gang, - Localizer.Get(MSG.COMMAND_RANK_RENAMED, oldName, target.Name)); + Locale.Get(MSG.COMMAND_RANK_RENAMED, oldName, target.Name)); return CommandResult.SUCCESS; } } \ No newline at end of file diff --git a/src/CS2/Commands/Gang/SmokeColorCommand.cs b/src/CS2/Commands/Gang/SmokeColorCommand.cs index 27eeec0..ecefb3d 100644 --- a/src/CS2/Commands/Gang/SmokeColorCommand.cs +++ b/src/CS2/Commands/Gang/SmokeColorCommand.cs @@ -35,7 +35,7 @@ public class SmokeColorCommand(IServiceProvider provider) var query = string.Join('_', info.Args.Skip(1)).ToUpper(); if (!int.TryParse(info[1], out var colorInt) || colorInt < 0) { if (!Enum.TryParse(query, out color)) { - info.ReplySync(Localizer.Get(MSG.COMMAND_INVALID_PARAM, info[1], + info.ReplySync(Locale.Get(MSG.COMMAND_INVALID_PARAM, info[1], "a color")); return CommandResult.SUCCESS; } @@ -46,7 +46,7 @@ public class SmokeColorCommand(IServiceProvider provider) Perm.PURCHASE_PERKS); if (!canPurchase) { - info.ReplySync(Localizer.Get(MSG.GENERIC_NOPERM_RANK, minRank.Name)); + info.ReplySync(Locale.Get(MSG.GENERIC_NOPERM_RANK, minRank.Name)); return CommandResult.SUCCESS; } @@ -62,7 +62,7 @@ public class SmokeColorCommand(IServiceProvider provider) if (GangChat == null) return CommandResult.SUCCESS; await GangChat.SendGangChat(player, gang, - Localizer.Get(MSG.PERK_PURCHASED, color.ToString())); + Locale.Get(MSG.PERK_PURCHASED, color.ToString())); return CommandResult.SUCCESS; } @@ -71,7 +71,7 @@ public class SmokeColorCommand(IServiceProvider provider) var (canManage, required) = await Ranks.CheckRank(player, Perm.MANAGE_PERKS); if (!canManage) { - info.ReplySync(Localizer.Get(MSG.GENERIC_NOPERM_RANK, required.Name)); + info.ReplySync(Locale.Get(MSG.GENERIC_NOPERM_RANK, required.Name)); return CommandResult.SUCCESS; } @@ -81,7 +81,7 @@ public class SmokeColorCommand(IServiceProvider provider) if (GangChat == null) return CommandResult.SUCCESS; await GangChat.SendGangChat(player, gang, - Localizer.Get(MSG.GANG_THING_SET, "Smoke Color", + Locale.Get(MSG.GANG_THING_SET, "Smoke Color", color.ToString().ToTitleCase())); return CommandResult.SUCCESS; } diff --git a/src/CS2/Commands/Gang/TransferCommand.cs b/src/CS2/Commands/Gang/TransferCommand.cs index d4d3d8d..b2c15dc 100644 --- a/src/CS2/Commands/Gang/TransferCommand.cs +++ b/src/CS2/Commands/Gang/TransferCommand.cs @@ -26,7 +26,7 @@ public class TransferCommand(IServiceProvider provider) Perm.OWNER); if (!success) { - info.ReplySync(Localizer.Get(MSG.GENERIC_NOPERM_RANK, required.Name)); + info.ReplySync(Locale.Get(MSG.GENERIC_NOPERM_RANK, required.Name)); return CommandResult.SUCCESS; } @@ -38,7 +38,7 @@ public class TransferCommand(IServiceProvider provider) await Ranks.GetLowerRank(player.GangId.Value, player.GangRank.Value); if (immediatelyLower == null) { - info.ReplySync(Localizer.Get(MSG.GENERIC_ERROR_INFO, + info.ReplySync(Locale.Get(MSG.GENERIC_ERROR_INFO, "Could not find a lower rank")); return CommandResult.SUCCESS; } @@ -46,7 +46,7 @@ public class TransferCommand(IServiceProvider provider) var query = string.Join(' ', info.Args.Skip(1)); var target = await Players.SearchPlayer(player.GangId.Value, query); if (target == null) { - info.ReplySync(Localizer.Get(MSG.GENERIC_PLAYER_NOT_FOUND, query)); + info.ReplySync(Locale.Get(MSG.GENERIC_PLAYER_NOT_FOUND, query)); return CommandResult.SUCCESS; } @@ -54,7 +54,7 @@ public class TransferCommand(IServiceProvider provider) ?? throw new GangException("Target does not have a rank."); if (targetRank != immediatelyLower) { - info.ReplySync(Localizer.Get(MSG.COMMAND_TRANSFER_SUBORDINATE, + info.ReplySync(Locale.Get(MSG.COMMAND_TRANSFER_SUBORDINATE, immediatelyLower.Name)); return CommandResult.SUCCESS; } @@ -70,7 +70,7 @@ public class TransferCommand(IServiceProvider provider) if (GangChat != null) await GangChat.SendGangChat(gang, - Localizer.Get(MSG.GANG_TRANSFERRED, + Locale.Get(MSG.GANG_TRANSFERRED, executor.Name ?? executor.Steam.ToString(), target.Name ?? target.Steam.ToString())); diff --git a/src/CS2/Commands/Menus/MembersMenu.cs b/src/CS2/Commands/Menus/MembersMenu.cs index 89f4407..e179bd7 100644 --- a/src/CS2/Commands/Menus/MembersMenu.cs +++ b/src/CS2/Commands/Menus/MembersMenu.cs @@ -39,7 +39,7 @@ public class MembersMenu(IServiceProvider provider, IGang gang) (IGangPlayer, IGangRank) item) { var result = $"{ChatColors.Yellow}{index}. {ChatColors.Green}{item.Item2.Name}{ChatColors.Default}: {ChatColors.LightBlue}{item.Item1.Name}"; - if (index == 1) { result += $" {ChatColors.Red}({gang.Name})"; } + if (index == 1) result += $" {ChatColors.Red}({gang.Name})"; return Task.FromResult(result); } diff --git a/src/CS2/Commands/Menus/OutgoingInvitesMenu.cs b/src/CS2/Commands/Menus/OutgoingInvitesMenu.cs index 2ca1ba8..5e13c2f 100644 --- a/src/CS2/Commands/Menus/OutgoingInvitesMenu.cs +++ b/src/CS2/Commands/Menus/OutgoingInvitesMenu.cs @@ -1,5 +1,6 @@ using CounterStrikeSharp.API.Modules.Commands; using CounterStrikeSharp.API.Modules.Utils; +using GangsAPI; using GangsAPI.Data; using GangsAPI.Data.Gang; using GangsAPI.Extensions; @@ -48,20 +49,24 @@ public class OutgoingInvitesMenu : AbstractPagedMenu { return results; } - override protected Task HandleItemSelection(PlayerWrapper player, + override protected async Task HandleItemSelection(PlayerWrapper player, List items, int selectedIndex) { var entry = items[selectedIndex]; if (entry == null) { - Provider.GetRequiredService() + await Provider.GetRequiredService() .ProcessCommand(player, CommandCallingContext.Chat, "css_gang", "doorpolicy"); - return Task.CompletedTask; + return; } - Printer.Invoke(player, - $"Invitation sent to {entry.Value.Steam} by {entry.Value.Inviter} on {entry.Value.Date}"); - return Task.CompletedTask; + var inviterName = await players.GetPlayer(entry.Value.Inviter); + var invitedName = await players.GetPlayer(entry.Value.Steam); + + await Printer.Invoke(player, + Localizer.Get(MSG.MENU_FORMAT_INVITATION, + inviterName?.Name ?? entry.Value.Inviter.ToString(), + invitedName?.Name ?? entry.Value.Steam.ToString(), entry.Value.Date)); } override protected Task ShowPage(PlayerWrapper player, diff --git a/src/CS2/Gangs/CommandBasedMenuManager.cs b/src/CS2/Gangs/CommandBasedMenuManager.cs index 691f10a..0924462 100644 --- a/src/CS2/Gangs/CommandBasedMenuManager.cs +++ b/src/CS2/Gangs/CommandBasedMenuManager.cs @@ -1,4 +1,5 @@ using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Menu; using GangsAPI.Data; using GangsAPI.Data.Command; using GangsAPI.Services.Commands; @@ -24,9 +25,15 @@ public class CommandBasedMenuManager(Lazy provider) private HookResult AcceptInput(CCSPlayerController? player, int index) { if (player == null) return HookResult.Continue; + var wrapper = new PlayerWrapper(player); + if (MenuManager.GetActiveMenu(player) != null) { + // Avoid conflicts with CS#-based menus + CloseMenu(wrapper); + return HookResult.Continue; + } + var activeMenu = GetActiveMenu(player.SteamID); - var wrapper = new PlayerWrapper(player); Task.Run(() => activeMenu?.AcceptInput(wrapper, index)); return HookResult.Continue; } diff --git a/src/EcoRewards/PeriodicRewarder.cs b/src/EcoRewards/PeriodicRewarder.cs index bd92812..cf7ab92 100644 --- a/src/EcoRewards/PeriodicRewarder.cs +++ b/src/EcoRewards/PeriodicRewarder.cs @@ -1,5 +1,6 @@ using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Core.Attributes.Registration; using CounterStrikeSharp.API.Modules.Timers; using CounterStrikeSharp.API.Modules.Utils; using GangsAPI; @@ -19,10 +20,9 @@ public class PeriodicRewarder(IServiceProvider provider) : IPluginBehavior { .Select(p => new PlayerWrapper(p)) .ToList(); - if (players.Count < 5) return; + if (players.Count < RewardsCollection.MIN_PLAYERS) return; - foreach (var player in players) { - if (player.Player == null) continue; + foreach (var player in players.Where(p => p.Player != null)) { var reward = getReward(player); Task.Run( async () => await eco.Grant(player, reward, reason: "Playtime")); diff --git a/src/EcoRewards/RewardsCollection.cs b/src/EcoRewards/RewardsCollection.cs index 4f41cd2..ccaeb4a 100644 --- a/src/EcoRewards/RewardsCollection.cs +++ b/src/EcoRewards/RewardsCollection.cs @@ -4,6 +4,8 @@ using Microsoft.Extensions.DependencyInjection; namespace EcoRewards; public static class RewardsCollection { + public const int MIN_PLAYERS = 5; + public static void RegisterRewards(this IServiceCollection provider) { provider.AddPluginBehavior(); provider.AddPluginBehavior(); diff --git a/src/EcoRewards/RoundWinListener.cs b/src/EcoRewards/RoundWinListener.cs index 54137e7..aa62f60 100644 --- a/src/EcoRewards/RoundWinListener.cs +++ b/src/EcoRewards/RoundWinListener.cs @@ -25,12 +25,16 @@ public class RoundWinListener(IServiceProvider provider) : IPluginBehavior { if (DateTime.Now - roundStart < TimeSpan.FromMinutes(3)) return HookResult.Continue; + var allPlayers = Utilities.GetPlayers(); + if (allPlayers.Count < RewardsCollection.MIN_PLAYERS) + return HookResult.Continue; var winners = Utilities.GetPlayers() .Where(p => !p.IsBot && p.Team == (CsTeam)ev.Winner && p.PawnIsAlive) .Select(p => new PlayerWrapper(p)) .ToList(); if (winners.Count == 0) return HookResult.Continue; + const int toDistribute = 100; var each = (int)Math.Ceiling(toDistribute / (double)winners.Count); @@ -41,11 +45,14 @@ public class RoundWinListener(IServiceProvider provider) : IPluginBehavior { } [GameEventHandler] - public HookResult OnMVP(EventRoundMvp ev, GameEventInfo info) { + public HookResult OnMVP(EventRoundMvp ev, GameEventInfo _) { var player = ev.Userid; if (player == null || !player.IsValid || player.IsBot) return HookResult.Continue; + if (Utilities.GetPlayers().Count < RewardsCollection.MIN_PLAYERS) + return HookResult.Continue; + var mvp = new PlayerWrapper(player); Task.Run(async () => await eco.Grant(mvp, 20, reason: "MVP")); diff --git a/src/GangsAPI/MSG.cs b/src/GangsAPI/MSG.cs index c220c6a..681d634 100644 --- a/src/GangsAPI/MSG.cs +++ b/src/GangsAPI/MSG.cs @@ -109,7 +109,8 @@ public enum MSG { COMMAND_GANG_CREATE_INVALID, COMMAND_GANG_RESTRICTED, COMMAND_INVITE_DOORPOLICY, -} + MENU_FORMAT_INVITATION, + MENU_FORMAT_REQUEST, } public static class LocaleExtensions { public static string Key(this MSG msg) { @@ -227,6 +228,8 @@ public static class LocaleExtensions { MSG.COMMAND_GANG_CREATE_INVALID => "command.gang.create.invalid", MSG.COMMAND_GANG_RESTRICTED => "command.gang.create.restricted", MSG.COMMAND_INVITE_DOORPOLICY => "command.invite.doorpolicy", + MSG.MENU_FORMAT_INVITATION => "menu.format.invitation", + MSG.MENU_FORMAT_REQUEST => "menu.format.request", _ => throw new ArgumentOutOfRangeException(nameof(msg), msg, null) }; } diff --git a/src/GangsImpl/AbstractDB/AbstractInstanceManager.cs b/src/GangsImpl/AbstractDB/AbstractInstanceManager.cs index 9a75b1b..e52e4ec 100644 --- a/src/GangsImpl/AbstractDB/AbstractInstanceManager.cs +++ b/src/GangsImpl/AbstractDB/AbstractInstanceManager.cs @@ -1,6 +1,5 @@ using System.Data.Common; using System.Reflection; -using CounterStrikeSharp.API; using CounterStrikeSharp.API.Core; using Dapper; using GangsAPI.Extensions; diff --git a/src/GangsImpl/SQLite/SQLiteGangManager.cs b/src/GangsImpl/SQLite/SQLiteGangManager.cs index 92e61a2..0fa5fb5 100644 --- a/src/GangsImpl/SQLite/SQLiteGangManager.cs +++ b/src/GangsImpl/SQLite/SQLiteGangManager.cs @@ -1,5 +1,4 @@ using System.Data.Common; -using Dapper; using GenericDB; using Microsoft.Data.Sqlite; diff --git a/src/GangsImpl/Stats/Perk/Smoke/SmokeColorPerk.cs b/src/GangsImpl/Stats/Perk/Smoke/SmokeColorPerk.cs index 674ac79..2657f1a 100644 --- a/src/GangsImpl/Stats/Perk/Smoke/SmokeColorPerk.cs +++ b/src/GangsImpl/Stats/Perk/Smoke/SmokeColorPerk.cs @@ -8,16 +8,19 @@ namespace Stats.Perk.Smoke; public class SmokeColorPerk(IServiceProvider provider) : BasePerk(provider) { - public override string StatId => STAT_ID; - public override string Name => "Smoke Color"; public const string STAT_ID = "smoke_color"; private readonly IGangStatManager gangStats = provider.GetRequiredService(); + public override string StatId => STAT_ID; + public override string Name => "Smoke Color"; + public override string? Description => "Change the color of the smokes your gang throws!"; + public override SmokePerkData Value { get; set; } = new(); + public override Task GetCost(IGangPlayer player) { return Task.FromResult(null); } @@ -33,8 +36,6 @@ public class SmokeColorPerk(IServiceProvider provider) public override Task OnPurchase(IGangPlayer player) { return Task.CompletedTask; } - - public override SmokePerkData Value { get; set; } = new(); } public class SmokePerkData { diff --git a/src/GangsImpl/Stats/Perk/Smoke/SmokeListener.cs b/src/GangsImpl/Stats/Perk/Smoke/SmokeListener.cs index 7e02195..8a25451 100644 --- a/src/GangsImpl/Stats/Perk/Smoke/SmokeListener.cs +++ b/src/GangsImpl/Stats/Perk/Smoke/SmokeListener.cs @@ -11,17 +11,17 @@ using Microsoft.Extensions.DependencyInjection; namespace Stats.Perk.Smoke; public class SmokeListener(IServiceProvider provider) : IPluginBehavior { - private readonly Dictionary smokeColors = new(); - - private readonly IPlayerManager players = - provider.GetRequiredService(); - private readonly IGangManager gangs = provider.GetRequiredService(); private readonly IGangStatManager gangStats = provider.GetRequiredService(); + private readonly IPlayerManager players = + provider.GetRequiredService(); + + private readonly Dictionary smokeColors = new(); + public void Start(BasePlugin? plugin, bool hotReload) { plugin?.RegisterListener(OnEntitySpawned); } diff --git a/src/GangsTest/API/Services/Commands/Command/TestParent.cs b/src/GangsTest/API/Services/Commands/Command/TestParent.cs deleted file mode 100644 index 53afd59..0000000 --- a/src/GangsTest/API/Services/Commands/Command/TestParent.cs +++ /dev/null @@ -1,21 +0,0 @@ -using GangsAPI.Data; -using GangsAPI.Extensions; -using GangsAPI.Services.Commands; -using Microsoft.Extensions.DependencyInjection; - -namespace GangsTest.API.Services.Commands.Command; - -public abstract class TestParent { - protected readonly ICommand Command; - protected readonly ICommandManager Commands; - - protected readonly PlayerWrapper TestPlayer = - new(new Random().NextULong(), "Test Player"); - - protected TestParent(IServiceProvider provider, ICommand command) { - Commands = provider.GetRequiredService(); - Command = command; - Commands.RegisterCommand(command); - Commands.Start(); - } -} \ No newline at end of file diff --git a/src/GangsTest/Commands/BalanceTests.cs b/src/GangsTest/Commands/BalanceTests.cs index b89c169..300b313 100644 --- a/src/GangsTest/Commands/BalanceTests.cs +++ b/src/GangsTest/Commands/BalanceTests.cs @@ -2,10 +2,6 @@ using CounterStrikeSharp.API.Modules.Commands; using GangsAPI; using GangsAPI.Data.Command; -using GangsAPI.Services.Player; -using GangsTest.API.Services.Commands.Command; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Localization; using Stats.Stat; namespace GangsTest.Commands; @@ -14,29 +10,23 @@ public class BalanceTests(IServiceProvider provider) : TestParent(provider, new BalanceCommand(provider)) { private static readonly string STAT_ID = new BalanceStat().StatId; - private readonly IStringLocalizer locale = - provider.GetRequiredService(); - - private readonly IPlayerStatManager stats = - provider.GetRequiredService(); - [Fact] public async Task None() { Assert.Equal("css_balance", Command.Name); Assert.Equal(CommandResult.SUCCESS, await Commands.ProcessCommand(TestPlayer, CommandCallingContext.Console, Command.Name)); - Assert.Contains(locale.Get(MSG.COMMAND_BALANCE_NONE), + Assert.Contains(Locale.Get(MSG.COMMAND_BALANCE_NONE), TestPlayer.ConsoleOutput); } [Fact] public async Task One() { - await stats.SetForPlayer(TestPlayer.Steam, STAT_ID, 1); + await PlayerStats.SetForPlayer(TestPlayer.Steam, STAT_ID, 1); Assert.Equal(CommandResult.SUCCESS, await Commands.ProcessCommand(TestPlayer, CommandCallingContext.Console, Command.Name)); - Assert.Contains(locale.Get(MSG.COMMAND_BALANCE, 1), + Assert.Contains(Locale.Get(MSG.COMMAND_BALANCE, 1), TestPlayer.ConsoleOutput); } @@ -47,11 +37,11 @@ public class BalanceTests(IServiceProvider provider) : TestParent(provider, [InlineData(-1)] [InlineData(-1000)] public async Task Multiple(int bal) { - await stats.SetForPlayer(TestPlayer.Steam, STAT_ID, bal); + await PlayerStats.SetForPlayer(TestPlayer.Steam, STAT_ID, bal); Assert.Equal(CommandResult.SUCCESS, await Commands.ProcessCommand(TestPlayer, CommandCallingContext.Console, Command.Name)); - Assert.Contains(locale.Get(MSG.COMMAND_BALANCE, bal), + Assert.Contains(Locale.Get(MSG.COMMAND_BALANCE, bal), TestPlayer.ConsoleOutput); } } \ No newline at end of file diff --git a/src/GangsTest/API/Services/Commands/Command/FieldTests.cs b/src/GangsTest/Commands/FieldTests.cs similarity index 89% rename from src/GangsTest/API/Services/Commands/Command/FieldTests.cs rename to src/GangsTest/Commands/FieldTests.cs index dae3682..c9bf961 100644 --- a/src/GangsTest/API/Services/Commands/Command/FieldTests.cs +++ b/src/GangsTest/Commands/FieldTests.cs @@ -1,6 +1,6 @@ using GangsAPI.Services.Commands; -namespace GangsTest.API.Services.Commands.Command; +namespace GangsTest.Commands; public class FieldTests { [Theory] diff --git a/src/GangsTest/Commands/Gang/BalanceTests.cs b/src/GangsTest/Commands/Gang/BalanceTests.cs new file mode 100644 index 0000000..9aa4b49 --- /dev/null +++ b/src/GangsTest/Commands/Gang/BalanceTests.cs @@ -0,0 +1,52 @@ +using Commands.Gang; +using CounterStrikeSharp.API.Modules.Commands; +using GangsAPI; +using GangsAPI.Data.Command; +using GangsAPI.Services.Gang; +using Microsoft.Extensions.DependencyInjection; +using Stats.Stat; + +namespace GangsTest.Commands.Gang; + +public class BalanceTests(IServiceProvider provider) + : TestParent(provider, new BalanceCommand(provider)) { + private static readonly string STAT_ID = new BalanceStat().StatId; + + private readonly IGangManager gangs = + provider.GetRequiredService(); + + [Fact] + public async Task Balance_WithoutGang_PrintsNoGang() { + Assert.Equal(CommandResult.SUCCESS, + await Commands.ProcessCommand(TestPlayer, CommandCallingContext.Console, + Command.Name)); + Assert.Contains(Locale.Get(MSG.NOT_IN_GANG), TestPlayer.ConsoleOutput); + } + + [Fact] + public async Task Balance_WithoutCredits_PrintsNoCredits() { + await gangs.CreateGang("Test Gang", TestPlayer.Steam); + Assert.Equal(CommandResult.SUCCESS, + await Commands.ProcessCommand(TestPlayer, CommandCallingContext.Console, + Command.Name)); + Assert.Contains(Locale.Get(MSG.COMMAND_BALANCE_GANG_NONE, "Test Gang"), + TestPlayer.ConsoleOutput); + } + + [Theory] + [InlineData(2)] + [InlineData(5)] + [InlineData(10000)] + [InlineData(-1)] + [InlineData(-1000)] + public async Task Balance_WithCredits_PrintsExpected(int bal) { + var gang = await gangs.CreateGang("Test Gang", TestPlayer.Steam); + Assert.NotNull(gang); + await GangStats.SetForGang(gang, STAT_ID, bal); + Assert.Equal(CommandResult.SUCCESS, + await Commands.ProcessCommand(TestPlayer, CommandCallingContext.Console, + Command.Name)); + Assert.Contains(Locale.Get(MSG.COMMAND_BALANCE_GANG, "Test Gang", bal), + TestPlayer.ConsoleOutput); + } +} \ No newline at end of file diff --git a/src/GangsTest/Commands/Gang/CreateTests.cs b/src/GangsTest/Commands/Gang/CreateTests.cs index 53c1e65..d4a302d 100644 --- a/src/GangsTest/Commands/Gang/CreateTests.cs +++ b/src/GangsTest/Commands/Gang/CreateTests.cs @@ -1,11 +1,9 @@ using Commands.Gang; using CounterStrikeSharp.API.Modules.Commands; -using CounterStrikeSharp.API.Modules.Entities; using GangsAPI; using GangsAPI.Data; using GangsAPI.Data.Command; using GangsAPI.Services.Gang; -using GangsTest.API.Services.Commands.Command; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Localization; diff --git a/src/GangsTest/Commands/Gang/GangTests.cs b/src/GangsTest/Commands/Gang/GangTests.cs index 420bc53..64839e8 100644 --- a/src/GangsTest/Commands/Gang/GangTests.cs +++ b/src/GangsTest/Commands/Gang/GangTests.cs @@ -3,7 +3,6 @@ using CounterStrikeSharp.API.Modules.Commands; using GangsAPI.Data.Command; using GangsAPI.Services.Gang; using GangsAPI.Services.Menu; -using GangsTest.API.Services.Commands.Command; using Microsoft.Extensions.DependencyInjection; namespace GangsTest.Commands.Gang; @@ -27,8 +26,8 @@ public class GangTests(IServiceProvider provider) : TestParent(provider, [Fact] public async Task Gang_Test_Create() { Assert.Equal(CommandResult.SUCCESS, - await Commands.ProcessCommand(TestPlayer.WithFlags("@ego/dssilver"), CommandCallingContext.Chat, - Command.Name, "create", "foobar")); + await Commands.ProcessCommand(TestPlayer.WithFlags("@ego/dssilver"), + CommandCallingContext.Chat, Command.Name, "create", "foobar")); Assert.Single(await gangs.GetGangs()); } diff --git a/src/GangsTest/Commands/Gang/InviteTests.cs b/src/GangsTest/Commands/Gang/InviteTests.cs index 1422ae6..9e3e773 100644 --- a/src/GangsTest/Commands/Gang/InviteTests.cs +++ b/src/GangsTest/Commands/Gang/InviteTests.cs @@ -9,7 +9,6 @@ using GangsAPI.Services; using GangsAPI.Services.Gang; using GangsAPI.Services.Player; using GangsAPI.Services.Server; -using GangsTest.API.Services.Commands.Command; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Localization; using Stats.Stat.Gang; diff --git a/src/GangsTest/API/Services/Commands/Command/TestData.cs b/src/GangsTest/Commands/TestData.cs similarity index 97% rename from src/GangsTest/API/Services/Commands/Command/TestData.cs rename to src/GangsTest/Commands/TestData.cs index b597ae8..b43623d 100644 --- a/src/GangsTest/API/Services/Commands/Command/TestData.cs +++ b/src/GangsTest/Commands/TestData.cs @@ -5,7 +5,7 @@ using Microsoft.Extensions.DependencyInjection; using BalanceCommand = Commands.BalanceCommand; using StatsCommand = Commands.Gang.StatsCommand; -namespace GangsTest.API.Services.Commands.Command; +namespace GangsTest.Commands; public class TestData : TheoryData { private static readonly IServiceCollection services = new ServiceCollection(); diff --git a/src/GangsTest/Commands/TestParent.cs b/src/GangsTest/Commands/TestParent.cs new file mode 100644 index 0000000..07a67f2 --- /dev/null +++ b/src/GangsTest/Commands/TestParent.cs @@ -0,0 +1,14 @@ +using GangsAPI.Services.Commands; + +namespace GangsTest.Commands; + +public abstract class TestParent : GangTest { + protected readonly ICommand Command; + + protected TestParent(IServiceProvider provider, ICommand command) : + base(provider) { + Command = command; + Commands.RegisterCommand(command); + Commands.Start(); + } +} \ No newline at end of file diff --git a/src/GangsTest/GangTest.cs b/src/GangsTest/GangTest.cs new file mode 100644 index 0000000..005c26a --- /dev/null +++ b/src/GangsTest/GangTest.cs @@ -0,0 +1,29 @@ +using GangsAPI.Data; +using GangsAPI.Extensions; +using GangsAPI.Services.Commands; +using GangsAPI.Services.Gang; +using GangsAPI.Services.Player; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Localization; + +namespace GangsTest; + +public abstract class GangTest(IServiceProvider provider) { + protected readonly ICommandManager Commands = + provider.GetRequiredService(); + + protected readonly IGangManager Gangs = + provider.GetRequiredService(); + + protected readonly IGangStatManager GangStats = + provider.GetRequiredService(); + + protected readonly IStringLocalizer Locale = + provider.GetRequiredService(); + + protected readonly IPlayerStatManager PlayerStats = + provider.GetRequiredService(); + + protected readonly PlayerWrapper TestPlayer = + new(new Random().NextULong(), "Test Player"); +} \ No newline at end of file