Merge pull request #18 from edgegamers/dev

Feat/unit tests (#17)
This commit is contained in:
Isaac
2024-09-22 22:27:56 -07:00
committed by GitHub
42 changed files with 281 additions and 184 deletions

View File

@@ -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)

View File

@@ -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 <player>%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%."
}

View File

@@ -22,15 +22,16 @@ public class CoinflipCommand(IServiceProvider provider) : ICommand {
provider.GetRequiredService<IPlayerTargeter>();
public string Name => "css_coinflip";
public string[] Aliases => ["coinflip", "cf"];
public string[] Usage => ["accept", "<player> <amount>"];
public string[] Aliases => ["css_coinflip", "css_cf"];
public string[] Usage => ["accept/yes", "<player> <amount>"];
public async Task<CommandResult> 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);

View File

@@ -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;
}
}

View File

@@ -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<CommandResult> 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));

View File

@@ -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<IGangChatPerk>();
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;
}

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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<IGangChatPerk>();
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<IGangChatPerk>();
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<IDisplaySetting>()
?? 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"));

View File

@@ -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<DoorPolicy>().Length);
await gangStats.SetForGang(player.GangId.Value, doorPolicyId, selected);
var gangChat = Provider.GetService<IGangChatPerk>();
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;

View File

@@ -36,7 +36,7 @@ public abstract class GangedPlayerCommand(IServiceProvider provider)
protected readonly IGangStatManager GangStats =
provider.GetRequiredService<IGangStatManager>();
protected readonly IStringLocalizer Localizer =
protected readonly IStringLocalizer Locale =
provider.GetRequiredService<IStringLocalizer>();
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;
}

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -1,5 +1,4 @@
using System.Text.Json.Serialization;
using GangsAPI;
using GangsAPI;
using GangsAPI.Data;
using GangsAPI.Data.Command;
using GangsAPI.Data.Gang;

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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<IGangChatPerk>();
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;
}

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -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()));

View File

@@ -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);
}

View File

@@ -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<InvitationEntry?> {
return results;
}
override protected Task HandleItemSelection(PlayerWrapper player,
override protected async Task HandleItemSelection(PlayerWrapper player,
List<InvitationEntry?> items, int selectedIndex) {
var entry = items[selectedIndex];
if (entry == null) {
Provider.GetRequiredService<ICommandManager>()
await Provider.GetRequiredService<ICommandManager>()
.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,

View File

@@ -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<ICommandManager> 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;
}

View File

@@ -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"));

View File

@@ -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<RoundWinListener>();
provider.AddPluginBehavior<PeriodicRewarder>();

View File

@@ -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"));

View File

@@ -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)
};
}

View File

@@ -1,6 +1,5 @@
using System.Data.Common;
using System.Reflection;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using Dapper;
using GangsAPI.Extensions;

View File

@@ -1,5 +1,4 @@
using System.Data.Common;
using Dapper;
using GenericDB;
using Microsoft.Data.Sqlite;

View File

@@ -8,16 +8,19 @@ namespace Stats.Perk.Smoke;
public class SmokeColorPerk(IServiceProvider provider)
: BasePerk<SmokePerkData>(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<IGangStatManager>();
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<int?> GetCost(IGangPlayer player) {
return Task.FromResult<int?>(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 {

View File

@@ -11,17 +11,17 @@ using Microsoft.Extensions.DependencyInjection;
namespace Stats.Perk.Smoke;
public class SmokeListener(IServiceProvider provider) : IPluginBehavior {
private readonly Dictionary<ulong, Color> smokeColors = new();
private readonly IPlayerManager players =
provider.GetRequiredService<IPlayerManager>();
private readonly IGangManager gangs =
provider.GetRequiredService<IGangManager>();
private readonly IGangStatManager gangStats =
provider.GetRequiredService<IGangStatManager>();
private readonly IPlayerManager players =
provider.GetRequiredService<IPlayerManager>();
private readonly Dictionary<ulong, Color> smokeColors = new();
public void Start(BasePlugin? plugin, bool hotReload) {
plugin?.RegisterListener<Listeners.OnEntitySpawned>(OnEntitySpawned);
}

View File

@@ -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<ICommandManager>();
Command = command;
Commands.RegisterCommand(command);
Commands.Start();
}
}

View File

@@ -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<IStringLocalizer>();
private readonly IPlayerStatManager stats =
provider.GetRequiredService<IPlayerStatManager>();
[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);
}
}

View File

@@ -1,6 +1,6 @@
using GangsAPI.Services.Commands;
namespace GangsTest.API.Services.Commands.Command;
namespace GangsTest.Commands;
public class FieldTests {
[Theory]

View File

@@ -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<IGangManager>();
[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);
}
}

View File

@@ -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;

View File

@@ -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());
}

View File

@@ -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;

View File

@@ -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<ICommand> {
private static readonly IServiceCollection services = new ServiceCollection();

View File

@@ -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();
}
}

29
src/GangsTest/GangTest.cs Normal file
View File

@@ -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<ICommandManager>();
protected readonly IGangManager Gangs =
provider.GetRequiredService<IGangManager>();
protected readonly IGangStatManager GangStats =
provider.GetRequiredService<IGangStatManager>();
protected readonly IStringLocalizer Locale =
provider.GetRequiredService<IStringLocalizer>();
protected readonly IPlayerStatManager PlayerStats =
provider.GetRequiredService<IPlayerStatManager>();
protected readonly PlayerWrapper TestPlayer =
new(new Random().NextULong(), "Test Player");
}