An unexpected error occurred trying to execute command /dynmap webregister
XiaoHuiHui233 opened this issue ยท 1 comments
Issue Description: When using command /dynmap webregister without op permission, it shows "An unexpected error occurred trying to execute that command"
- Dynmap Version: 3.2.1-531
- Server Version: fabric 1.17.1 with fabric loader 0.11,7 and fabric api 0.41.0
- Pastebin of Configuration.txt: https://pastebin.com/aCXi5JTw
- Server Host (if applicable): Selfhosted
- Pastebin of crashlogs or other relevant logs: Cannot invoke "org.dynmap.permissions.PermissionsHandler.hasPermission(String, String)" because "ph" is null
- Other Relevant Data/Screenshots: null
- Steps to Replicate: Just run /dynmap webregister without op permission
At first I thought it was a problem with my configuration, so I carefully checked the configuration.txt
file and found that there was no permission-related configuration. Then I saw permissions.yml.example
and thought it was because I did not configure permissions.yml
. So I renamed permissions.yml.example
to permissions.yml
, but the problem still exists.
Then I started looking through the source code. The first thing I saw is DynmapCore.processCommand()
:
1703 } else if(c.equals("webregister") && checkPlayerPermission(sender, "webregister")) {
1704 if(authmgr != null)
1705 return authmgr.processWebRegisterCommand(this, sender, player, args);
1706 else
1707 sender.sendMessage("Login support is not enabled");
1708 }
When recieved subcommand webregister
, it calls DynmapCore.checkPlayerPermission()
to check player's permission:
1724 public boolean checkPlayerPermission(DynmapCommandSender sender, String permission) {
1725 if (!(sender instanceof DynmapPlayer) || sender.isOp()) {
1726 return true;
1727 } else if (!sender.hasPrivilege(permission.toLowerCase())) {
1728 sender.sendMessage("You don't have permission to use this command!");
1729 return false;
1730 }
1731 return true;
1732 }
When command sender is a player and not op, it calls DynmapCommandSender.hasPrivilege()
which is an abstract method. In fabric 1.17.1, it was realized as org.dynmap.fabric_1_17_1.FabricPlayer.hasPrivilege()
:
177 @Override
178 public boolean hasPrivilege(String privid) {
179 if (player != null)
180 return plugin.hasPerm(player, privid);
181 return false;
182 }
Then if the player is not null, it calls org.dynmap.fabric_1_17_1.DynmapPlugin.hasPerm()
:
316 boolean hasPerm(PlayerEntity psender, String permission) {
317 PermissionsHandler ph = PermissionsHandler.getHandler();
318 if ((psender != null) && ph.hasPermission(psender.getName().getString(), permission)) {
319 return true;
320 }
321 return permissions.has(psender, permission);
322 }
Aha, here is the source of the error, ph
did not do a non-null check!
Originally, I still wanted to dig out why ph
is null. But in the end I found it does not seem to implement any PermissionsHandler
in fabric version.
I also found that method hasOfflinePermissions()
below method hasPerm()
also uses PermissionHandler
, but it has a non-null check, maybe forgot?
Yep - bug that crept into the Fabric implementation at some point (the other platforms handle it). The ph is only for a generic external permission handler, which is only set when another plugin registers as a dynmap permission handler - but by default, this is not the case (and the platform specific handler defaults (FilePermissions, OpPermissions) will always be present, but only if this check is in place to allow the fall through).
Fix should be in SNAPSHOT 601 or later (building as I post this)