@@ -226,11 +226,7 @@ private CommandTree(final @NonNull CommandManager<C> commandManager) {
226226 final PermissionResult permissionResult = this .determinePermissionResult (commandContext .sender (), root );
227227 if (permissionResult .denied ()) {
228228 return CompletableFutures .failedFuture (
229- new NoPermissionException (
230- permissionResult ,
231- commandContext .sender (),
232- this .getComponentChain (root )
233- )
229+ this .noPermissionOrSyntax (permissionResult , commandContext .sender (), root )
234230 );
235231 }
236232
@@ -329,11 +325,7 @@ private CommandTree(final @NonNull CommandManager<C> commandManager) {
329325 );
330326 if (check .denied ()) {
331327 return CompletableFutures .failedFuture (
332- new NoPermissionException (
333- check ,
334- commandContext .sender (),
335- this .getComponentChain (root )
336- )
328+ this .noPermissionOrSyntax (check , commandContext .sender (), root )
337329 );
338330 }
339331 return CompletableFuture .completedFuture (root .command ());
@@ -350,6 +342,72 @@ private CommandTree(final @NonNull CommandManager<C> commandManager) {
350342 });
351343 }
352344
345+ @ SuppressWarnings ({"unchecked" , "rawtypes" })
346+ private Exception noPermissionOrSyntax (
347+ final PermissionResult permissionResult ,
348+ final C sender ,
349+ final CommandNode <C > root
350+ ) {
351+ final boolean convert = this .commandManager .settings ().get (ManagerSetting .CONVERT_NO_PERMISSION_TO_SYNTAX_EXCEPTION );
352+ if (!convert ) {
353+ return new NoPermissionException (
354+ permissionResult ,
355+ sender ,
356+ this .getComponentChain (root )
357+ );
358+ }
359+
360+ if (this .childPermitted (root , sender )) {
361+ return new InvalidSyntaxException (
362+ this .commandManager .commandSyntaxFormatter ().apply (sender , (List ) this .getComponentChain (root ), root ),
363+ sender , this .getComponentChain (root )
364+ );
365+ }
366+
367+ final @ Nullable List <CommandNode <C >> parentChain = this .permittedParentChain (root , sender );
368+ if (parentChain != null ) {
369+ return new InvalidSyntaxException (
370+ this .commandManager .commandSyntaxFormatter ().apply (
371+ sender ,
372+ parentChain .stream ().map (CommandNode ::component )
373+ .filter (Objects ::nonNull ).collect (Collectors .toList ()),
374+ root
375+ ),
376+ sender , this .getComponentChain (root )
377+ );
378+ }
379+
380+ return new NoPermissionException (
381+ permissionResult ,
382+ sender ,
383+ this .getComponentChain (root )
384+ );
385+ }
386+
387+ private boolean childPermitted (CommandNode <C > node , C sender ) {
388+ if (this .determinePermissionResult (sender , node ).allowed ()) {
389+ return true ;
390+ }
391+ for (final CommandNode <C > child : node .children ()) {
392+ if (this .childPermitted (child , sender )) {
393+ return true ;
394+ }
395+ }
396+ return false ;
397+ }
398+
399+ private @ Nullable List <CommandNode <C >> permittedParentChain (CommandNode <C > node , C sender ) {
400+ final @ Nullable CommandNode <C > parent = node .parent ();
401+ if (parent != null ) {
402+ if (this .determinePermissionResult (sender , parent ).allowed ()) {
403+ return this .getChain (parent );
404+ } else {
405+ return this .permittedParentChain (parent , sender );
406+ }
407+ }
408+ return null ;
409+ }
410+
353411 private @ Nullable CompletableFuture <@ Nullable Command <C >> attemptParseUnambiguousChild (
354412 final @ NonNull List <@ NonNull CommandComponent <C >> parsedArguments ,
355413 final @ NonNull CommandContext <C > commandContext ,
@@ -381,11 +439,7 @@ private CommandTree(final @NonNull CommandManager<C> commandManager) {
381439 final PermissionResult childCheck = this .determinePermissionResult (sender , child );
382440 if (!commandInput .isEmpty () && childCheck .denied ()) {
383441 return CompletableFutures .failedFuture (
384- new NoPermissionException (
385- childCheck ,
386- sender ,
387- this .getComponentChain (child )
388- )
442+ this .noPermissionOrSyntax (childCheck , sender , child )
389443 );
390444 }
391445
@@ -448,11 +502,7 @@ private CommandTree(final @NonNull CommandManager<C> commandManager) {
448502 return CompletableFuture .completedFuture (command );
449503 }
450504 return CompletableFutures .failedFuture (
451- new NoPermissionException (
452- check ,
453- sender ,
454- this .getComponentChain (root )
455- )
505+ this .noPermissionOrSyntax (check , sender , root )
456506 );
457507 } else {
458508 // The child is not a leaf, but may have an intermediary executor, attempt to use it
@@ -477,11 +527,7 @@ private CommandTree(final @NonNull CommandManager<C> commandManager) {
477527 }
478528
479529 return CompletableFutures .failedFuture (
480- new NoPermissionException (
481- check ,
482- sender ,
483- this .getComponentChain (root )
484- )
530+ this .noPermissionOrSyntax (check , sender , root )
485531 );
486532 }
487533 }
0 commit comments