Dynmap-Forge/Fabric

Dynmap-Forge/Fabric

888k Downloads

An unexpected error occurred trying to execute command /dynmap webregister

XiaoHuiHui233 opened this issue ยท 1 comments

commented

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?

commented

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)