FastAsyncWorldEdit

FastAsyncWorldEdit

245k Downloads

NPE crashes the server when a player leave the server (Simple Fix xd)

einfachBlu opened this issue ยท 2 comments

commented

Server Implementation

Paper

Server Version

1.21

Describe the bug

[19:05:35 ERROR]: Could not pass event PlayerQuitEvent to FastAsyncWorldEdit v2.12.1-SNAPSHOT-952;d959778
java.lang.NullPointerException: Cannot invoke "org.bukkit.permissions.PermissibleBase.removeAttachment(org.bukkit.permissions.PermissionAttachment)" because "this.perm" is null
at org.bukkit.craftbukkit.entity.CraftHumanEntity.removeAttachment(CraftHumanEntity.java:270) ~[paper-1.21.1.jar:1.21.1-131-84281ce]
at FastAsyncWorldEdit-Bukkit-2.12.1-SNAPSHOT-952.jar/com.fastasyncworldedit.bukkit.BukkitPermissionAttachmentManager.removeAttachment(BukkitPermissionAttachmentManager.java:41) ~[FastAsyncWorldEdit-Bukkit-2.12.1-SNAPSHOT-952.jar:?]
at FastAsyncWorldEdit-Bukkit-2.12.1-SNAPSHOT-952.jar/com.sk89q.worldedit.bukkit.BukkitPlayer.unregister(BukkitPlayer.java:454) ~[FastAsyncWorldEdit-Bukkit-2.12.1-SNAPSHOT-952.jar:?]
at FastAsyncWorldEdit-Bukkit-2.12.1-SNAPSHOT-952.jar/com.fastasyncworldedit.bukkit.FaweBukkit.onPlayerQuit(FaweBukkit.java:276) ~[FastAsyncWorldEdit-Bukkit-2.12.1-SNAPSHOT-952.jar:?]
at com.destroystokyo.paper.event.executor.asm.generated.GeneratedEventExecutor41.execute(Unknown Source) ~[?:?]
at org.bukkit.plugin.EventExecutor$2.execute(EventExecutor.java:77) ~[paper-mojangapi-1.21.1-R0.1-SNAPSHOT.jar:?]
at co.aikar.timings.TimedEventExecutor.execute(TimedEventExecutor.java:80) ~[paper-mojangapi-1.21.1-R0.1-SNAPSHOT.jar:1.21.1-131-84281ce]
at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:70) ~[paper-mojangapi-1.21.1-R0.1-SNAPSHOT.jar:?]
at io.papermc.paper.plugin.manager.PaperEventManager.callEvent(PaperEventManager.java:54) ~[paper-1.21.1.jar:1.21.1-131-84281ce]
at io.papermc.paper.plugin.manager.PaperPluginManagerImpl.callEvent(PaperPluginManagerImpl.java:131) ~[paper-1.21.1.jar:1.21.1-131-84281ce]
at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:628) ~[paper-mojangapi-1.21.1-R0.1-SNAPSHOT.jar:?]
at net.minecraft.server.players.PlayerList.remove(PlayerList.java:605) ~[paper-1.21.1.jar:1.21.1-131-84281ce]
at net.minecraft.server.players.PlayerList.remove(PlayerList.java:590) ~[paper-1.21.1.jar:1.21.1-131-84281ce]
at net.minecraft.server.network.ServerGamePacketListenerImpl.removePlayerFromWorld(ServerGamePacketListenerImpl.java:2107) ~[paper-1.21.1.jar:1.21.1-131-84281ce]
at net.minecraft.server.network.ServerGamePacketListenerImpl.onDisconnect(ServerGamePacketListenerImpl.java:2087) ~[paper-1.21.1.jar:1.21.1-131-84281ce]
at net.minecraft.server.network.ServerGamePacketListenerImpl.onDisconnect(ServerGamePacketListenerImpl.java:2074) ~[paper-1.21.1.jar:1.21.1-131-84281ce]
at net.minecraft.network.Connection.handleDisconnection(Connection.java:910) ~[paper-1.21.1.jar:1.21.1-131-84281ce]
at net.minecraft.server.network.ServerConnectionListener.tick(ServerConnectionListener.java:268) ~[paper-1.21.1.jar:1.21.1-131-84281ce]
at net.minecraft.server.MinecraftServer.tickChildren(MinecraftServer.java:1821) ~[paper-1.21.1.jar:1.21.1-131-84281ce]
at net.minecraft.server.dedicated.DedicatedServer.tickChildren(DedicatedServer.java:473) ~[paper-1.21.1.jar:1.21.1-131-84281ce]
at net.minecraft.server.MinecraftServer.tickServer(MinecraftServer.java:1596) ~[paper-1.21.1.jar:1.21.1-131-84281ce]
at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:1302) ~[paper-1.21.1.jar:1.21.1-131-84281ce]
at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:329) ~[paper-1.21.1.jar:1.21.1-131-84281ce]
at java.base/java.lang.Thread.run(Unknown Source) ~[?:?

To Reproduce

create a simple plugin that injects a custom PermissionBase into the player:

called in PlayerLoginEvent:

replaceBase(player, new PermissionBase(player))

public PermissionBase replaceBase(Player player, PermissionBase permissionBase) {
try {
var craftHumanEntityClass = Class.forName("org.bukkit.craftbukkit.entity.CraftHumanEntity");
var field = craftHumanEntityClass.getDeclaredField("perm");
field.setAccessible(true);
field.set(player, permissionBase);
return permissionBase;
} catch (Exception e) {
e.printStackTrace();
}

return null;

}

// My Custom Permission Base Class
public class PermissionBase extends PermissibleBase {

private Map<String, Boolean> customPermissions = new HashMap<>();

public PermissionBase(ServerOperator opable) {
super(opable);
}

@OverRide
public boolean hasPermission(@NotNull String permission) {
if (this.customPermissions == null) {
return false;
}

if (this.customPermissions.containsKey(permission)) {
  return this.customPermissions.get(permission);
}

// Check if the permission is a wildcard permission
for (var entry : this.customPermissions.entrySet()) {
  var isStarPermission = entry.getKey().endsWith("*");
  if (!isStarPermission) {
    continue;
  }

  var permissionStart = entry.getKey().substring(0, entry.getKey().length() - 1);

  if (permission.startsWith(permissionStart)) {
    return entry.getValue();
  }
}

return false;

}

@OverRide
public boolean hasPermission(Permission permission) {
return this.hasPermission(permission.getName());
}

public void setPermission(String permission, boolean value) {
this.customPermissions.put(permission, value);
}

public void clearCustomPermissions() {
this.customPermissions.clear();
}
}

Expected behaviour

it should not crash on PlayerQuitEvent, might be just a quick if statement to prevent the crash

Screenshots / Videos

No response

Error log (if applicable)

https://paste.gg/p/anonymous/c089c7de53884b7c89beef65701f8bd4

Fawe Debugpaste

https://athion.net/ISPaster/paste/view/9e023fe162a44e97ab661caec09d1d14

Fawe Version

FastAsyncWorldEdit version 2.12.1-SNAPSHOT-952;d959778

Checklist

Anything else?

this bug report thing is so big that i even thought of just cancelling the bug report. Make it easier for users to report bugs

commented

That's something on your end, which you did wrong. The PermissibleBase field in the CraftHumanEntity is seemingly null, which it can't be by default. The Server nor the API handles possible nullability of that field and expects it to be not null, so nothing wrong with FAWE here. We just use the API as exposed by the server, in the intended way.

commented

Additional Info:

the error happens when i set the field to null. But with the same thing above i get the following issue:

java.lang.IllegalArgumentException: Given attachment is not part of Permissible object CraftPlayer{name=einfachBlu}
at org.bukkit.permissions.PermissibleBase.removeAttachment(PermissibleBase.java:160) ~[paper-mojangapi-1.21.1-R0.1-SNAPSHOT.jar:?]
at org.bukkit.craftbukkit.entity.CraftHumanEntity.removeAttachment(CraftHumanEntity.java:270) ~[paper-1.21.1.jar:1.21.1-131-84281ce]

    I assume it is because i replace the permission base and you are trying to remove an attachment while there is no attachment