
NPE crashes the server when a player leave the server (Simple Fix xd)
einfachBlu opened this issue ยท 2 comments
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
- I have included a Fawe debugpaste.
- I am using the newest build from https://ci.athion.net/job/FastAsyncWorldEdit/ and the issue still persists.
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
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.
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