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