@@ -225,11 +225,7 @@ private CommandTree(final @NonNull CommandManager<C> commandManager) {
225225 final PermissionResult permissionResult = this .determinePermissionResult (commandContext .sender (), root );
226226 if (permissionResult .denied ()) {
227227 return CompletableFutures .failedFuture (
228- new NoPermissionException (
229- permissionResult ,
230- commandContext .sender (),
231- this .getComponentChain (root )
232- )
228+ this .noPermissionOrSyntax (permissionResult , commandContext .sender (), root )
233229 );
234230 }
235231
@@ -328,11 +324,7 @@ private CommandTree(final @NonNull CommandManager<C> commandManager) {
328324 );
329325 if (check .denied ()) {
330326 return CompletableFutures .failedFuture (
331- new NoPermissionException (
332- check ,
333- commandContext .sender (),
334- this .getComponentChain (root )
335- )
327+ this .noPermissionOrSyntax (check , commandContext .sender (), root )
336328 );
337329 }
338330 return CompletableFuture .completedFuture (root .command ());
@@ -349,6 +341,72 @@ private CommandTree(final @NonNull CommandManager<C> commandManager) {
349341 });
350342 }
351343
344+ @ SuppressWarnings ({"unchecked" , "rawtypes" })
345+ private Exception noPermissionOrSyntax (
346+ final PermissionResult permissionResult ,
347+ final C sender ,
348+ final CommandNode <C > root
349+ ) {
350+ final boolean convert = this .commandManager .settings ().get (ManagerSetting .CONVERT_NO_PERMISSION_TO_SYNTAX_EXCEPTION );
351+ if (!convert ) {
352+ return new NoPermissionException (
353+ permissionResult ,
354+ sender ,
355+ this .getComponentChain (root )
356+ );
357+ }
358+
359+ if (this .childPermitted (root , sender )) {
360+ return new InvalidSyntaxException (
361+ this .commandManager .commandSyntaxFormatter ().apply (sender , (List ) this .getComponentChain (root ), root ),
362+ sender , this .getComponentChain (root )
363+ );
364+ }
365+
366+ final @ Nullable List <CommandNode <C >> parentChain = this .permittedParentChain (root , sender );
367+ if (parentChain != null ) {
368+ return new InvalidSyntaxException (
369+ this .commandManager .commandSyntaxFormatter ().apply (
370+ sender ,
371+ parentChain .stream ().map (CommandNode ::component )
372+ .filter (Objects ::nonNull ).collect (Collectors .toList ()),
373+ root
374+ ),
375+ sender , this .getComponentChain (root )
376+ );
377+ }
378+
379+ return new NoPermissionException (
380+ permissionResult ,
381+ sender ,
382+ this .getComponentChain (root )
383+ );
384+ }
385+
386+ private boolean childPermitted (CommandNode <C > node , C sender ) {
387+ if (this .determinePermissionResult (sender , node ).allowed ()) {
388+ return true ;
389+ }
390+ for (final CommandNode <C > child : node .children ()) {
391+ if (this .childPermitted (child , sender )) {
392+ return true ;
393+ }
394+ }
395+ return false ;
396+ }
397+
398+ private @ Nullable List <CommandNode <C >> permittedParentChain (CommandNode <C > node , C sender ) {
399+ final @ Nullable CommandNode <C > parent = node .parent ();
400+ if (parent != null ) {
401+ if (this .determinePermissionResult (sender , parent ).allowed ()) {
402+ return this .getChain (parent );
403+ } else {
404+ return this .permittedParentChain (parent , sender );
405+ }
406+ }
407+ return null ;
408+ }
409+
352410 private @ Nullable CompletableFuture <@ Nullable Command <C >> attemptParseUnambiguousChild (
353411 final @ NonNull List <@ NonNull CommandComponent <C >> parsedArguments ,
354412 final @ NonNull CommandContext <C > commandContext ,
@@ -380,11 +438,7 @@ private CommandTree(final @NonNull CommandManager<C> commandManager) {
380438 final PermissionResult childCheck = this .determinePermissionResult (sender , child );
381439 if (!commandInput .isEmpty () && childCheck .denied ()) {
382440 return CompletableFutures .failedFuture (
383- new NoPermissionException (
384- childCheck ,
385- sender ,
386- this .getComponentChain (child )
387- )
441+ this .noPermissionOrSyntax (childCheck , sender , child )
388442 );
389443 }
390444
@@ -447,11 +501,7 @@ private CommandTree(final @NonNull CommandManager<C> commandManager) {
447501 return CompletableFuture .completedFuture (command );
448502 }
449503 return CompletableFutures .failedFuture (
450- new NoPermissionException (
451- check ,
452- sender ,
453- this .getComponentChain (root )
454- )
504+ this .noPermissionOrSyntax (check , sender , root )
455505 );
456506 } else {
457507 // The child is not a leaf, but may have an intermediary executor, attempt to use it
@@ -476,11 +526,7 @@ private CommandTree(final @NonNull CommandManager<C> commandManager) {
476526 }
477527
478528 return CompletableFutures .failedFuture (
479- new NoPermissionException (
480- check ,
481- sender ,
482- this .getComponentChain (root )
483- )
529+ this .noPermissionOrSyntax (check , sender , root )
484530 );
485531 }
486532 }
0 commit comments