Skip to content

Commit c76f987

Browse files
add max usages per command and catch register errors
1 parent 240d472 commit c76f987

1 file changed

Lines changed: 142 additions & 13 deletions

File tree

Code/FlagSystem/Flags/CustomCommandFlag.cs

Lines changed: 142 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,34 @@ This also applies to the server console.
149149
false,
150150
"-- onGlobalCooldownMessage \"This command is on cooldown! You can use this command in %time% seconds\""
151151
),
152+
new(
153+
"maxUses",
154+
"The maximum number of times a player can use this command.",
155+
args => AddMaxUses(args, false),
156+
false,
157+
"-- maxUses 5"
158+
),
159+
new(
160+
"onMaxUsesMessage",
161+
"Defines a message for when the player tries to run a command but has reached their maximum usage limit.",
162+
args => AddOnMaxUsesMessage(args, false),
163+
false,
164+
"-- onMaxUsesMessage \"You have already used this command 5 times!\""
165+
),
166+
new(
167+
"globalMaxUses",
168+
"The maximum number of times this command can be used globally.",
169+
args => AddMaxUses(args, true),
170+
false,
171+
"-- globalMaxUses 10"
172+
),
173+
new(
174+
"onGlobalMaxUsesMessage",
175+
"Defines a message for when the command has reached its global usage limit.",
176+
args => AddOnMaxUsesMessage(args, true),
177+
false,
178+
"-- onGlobalMaxUsesMessage \"This command has reached its global usage limit!\""
179+
),
152180
new(
153181
"arguments",
154182
"""
@@ -190,20 +218,33 @@ public override void OnParsingComplete()
190218

191219
foreach (var console in Command.ConsoleTypes.GetFlags())
192220
{
193-
switch (console)
221+
try
194222
{
195-
case ConsoleType.Player:
196-
QueryProcessor.DotCommandHandler.RegisterCommand(Command);
197-
continue;
198-
case ConsoleType.Server:
199-
Console.ConsoleCommandHandler.RegisterCommand(Command);
200-
continue;
201-
case ConsoleType.RemoteAdmin:
202-
CommandProcessor.RemoteAdminCommandHandler.RegisterCommand(Command);
203-
continue;
204-
case ConsoleType.None:
205-
default:
206-
throw new AndrzejFuckedUpException();
223+
switch (console)
224+
{
225+
case ConsoleType.Player:
226+
QueryProcessor.DotCommandHandler.RegisterCommand(Command);
227+
continue;
228+
case ConsoleType.Server:
229+
Console.ConsoleCommandHandler.RegisterCommand(Command);
230+
continue;
231+
case ConsoleType.RemoteAdmin:
232+
CommandProcessor.RemoteAdminCommandHandler.RegisterCommand(Command);
233+
continue;
234+
case ConsoleType.None:
235+
default:
236+
throw new AndrzejFuckedUpException();
237+
}
238+
}
239+
catch
240+
{
241+
ScriptCommands.TryGetValue(Command, out var flag);
242+
243+
Log.CompileError(
244+
flag?.ScriptName ?? "Unknown script",
245+
$"Failed to register command '{Command.Command}' for {console} console. " +
246+
$"Check if there isn't a command with the same name already registered."
247+
);
207248
}
208249
}
209250
}
@@ -282,6 +323,14 @@ public bool Execute(ArraySegment<string> arguments, ICommandSender sender, out s
282323
public DateTime? NextEligibleDateForGlobal;
283324
public string? OnGlobalCooldownMessage;
284325

326+
public int MaxUses = 0;
327+
public readonly Dictionary<Player, int> PlayerUses = [];
328+
public string? OnMaxUsesMessage;
329+
330+
public int GlobalMaxUses = 0;
331+
public int GlobalUses = 0;
332+
public string? OnGlobalMaxUsesMessage;
333+
285334
public string GetHelp(ArraySegment<string> arguments)
286335
{
287336
return $"Description: {Description}\n" +
@@ -300,6 +349,16 @@ public static Result RunAttachedScript(CustomCommand cmd, ScriptExecutor sender,
300349
return plrErr;
301350
}
302351

352+
if (cmd.GlobalMaxUses > 0 && cmd.GlobalUses >= cmd.GlobalMaxUses)
353+
{
354+
if (cmd.OnGlobalMaxUsesMessage is not null)
355+
{
356+
return cmd.OnGlobalMaxUsesMessage;
357+
}
358+
359+
return "This command has reached its global usage limit.";
360+
}
361+
303362
if (cmd.GlobalCooldown > TimeSpan.Zero)
304363
{
305364
if (cmd.NextEligibleDateForGlobal is { } nextEligibleDate
@@ -377,6 +436,12 @@ public static Result RunAttachedScript(CustomCommand cmd, ScriptExecutor sender,
377436
}
378437

379438
script.AddLocalVariable(new ReferenceVariable("command", new ReferenceValue<CustomCommand>(cmd)));
439+
440+
if (cmd.GlobalMaxUses > 0)
441+
{
442+
cmd.GlobalUses++;
443+
}
444+
380445
script.Run(RunReason.CustomCommand);
381446
return true;
382447
}
@@ -409,8 +474,27 @@ public static Result RunAttachedScript(CustomCommand cmd, ScriptExecutor sender,
409474
$"Required permissions: {cmd.NeededPermissions.JoinStrings(", ")}.";
410475
}
411476

477+
if (cmd.MaxUses > 0)
478+
{
479+
cmd.PlayerUses.TryGetValue(plr, out var uses);
480+
if (uses >= cmd.MaxUses)
481+
{
482+
if (cmd.OnMaxUsesMessage is not null)
483+
{
484+
return cmd.OnMaxUsesMessage;
485+
}
486+
487+
return "You have reached the maximum number of times you can use this command.";
488+
}
489+
}
490+
412491
if (cmd.PlayerCooldown <= TimeSpan.Zero)
413492
{
493+
if (cmd.MaxUses > 0)
494+
{
495+
cmd.PlayerUses.TryGetValue(plr, out var uses);
496+
cmd.PlayerUses[plr] = uses + 1;
497+
}
414498
return null;
415499
}
416500

@@ -430,6 +514,13 @@ public static Result RunAttachedScript(CustomCommand cmd, ScriptExecutor sender,
430514
}
431515

432516
cmd.NextEligibleDateForPlayer[plr] = DateTime.UtcNow + cmd.PlayerCooldown;
517+
518+
if (cmd.MaxUses > 0)
519+
{
520+
cmd.PlayerUses.TryGetValue(plr, out var uses);
521+
cmd.PlayerUses[plr] = uses + 1;
522+
}
523+
433524
return null;
434525
}
435526

@@ -552,4 +643,42 @@ private Result AddOnCooldownMessage(string[] args, bool isGlobal)
552643

553644
return true;
554645
}
646+
647+
private Result AddMaxUses(string[] args, bool isGlobal)
648+
{
649+
if (args.Length != 1)
650+
{
651+
return "Max uses requires exactly one integer value.";
652+
}
653+
654+
if (!int.TryParse(args[0], out var maxUses) || maxUses < 0)
655+
{
656+
return $"Value '{args[0]}' is not a valid positive integer.";
657+
}
658+
659+
if (isGlobal)
660+
{
661+
Command.GlobalMaxUses = maxUses;
662+
}
663+
else
664+
{
665+
Command.MaxUses = maxUses;
666+
}
667+
668+
return true;
669+
}
670+
671+
private Result AddOnMaxUsesMessage(string[] args, bool isGlobal)
672+
{
673+
if (isGlobal)
674+
{
675+
Command.OnGlobalMaxUsesMessage = args.JoinStrings(" ");
676+
}
677+
else
678+
{
679+
Command.OnMaxUsesMessage = args.JoinStrings(" ");
680+
}
681+
682+
return true;
683+
}
555684
}

0 commit comments

Comments
 (0)