Closed Ghost-chu closed 3 years ago
Can you provide info on what the player did and what pet this occurred with?
Player get offline, so as far as I know, player just random disconnect and this is only what I found in console.
okay reproduce: summon your pet, then killed it
AttributeSupplier possibly null. (AttributeSupplier =AttributeProvider)
So I guess something wrong in there:
protected void replaceCraftAttributes() {
//TODO check this
Field craftAttributesField = ReflectionUtil.getField(LivingEntity.class, "craftAttributes");
CraftAttributeMap craftAttributes = new CraftAttributeMap(this.getAttributes());
ReflectionUtil.setFinalFieldValue(craftAttributesField, this, craftAttributes);
}
public static boolean setFinalFieldValue(@NonNull Field field, Object target, Object value) {
try {
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(target, value);
return true;
} catch (Throwable ignored) {
}
return false;
}
This method exceptions has been hidden, and I guess this is why I didn't see any error in console.
Good find, just edited it to print the StackTrace -> throws an error
Tested this some more - Seems to be a java 16 related.
How was this tested: Ran a 1.16.5 server with MyPet3.11-SNAPSHOT-B1642 on Java16: Same Error Ran the same server on Java 11: No error
Make a quick search on our local Minecraft forum, try this out: (Java 9+):
public static void grantAccess(Class<?> clazz){
Field theUnsafe = null;
try {
theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
Unsafe unsafe = (Unsafe) theUnsafe.get(null);
Field module = Class.class.getDeclaredField("module");
long offset = unsafe.objectFieldOffset(module);
unsafe.putObject(clazz, offset, Object.class.getModule());
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
}
like this:
public static boolean setFinalFieldValue(String fieldName, Object target, Object value) {
try {
Field field = getField(target.getClass(), fieldName);
if (field != null) {
FooBar.grantAccess(this);
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(target, value);
return true;
}
} catch (Throwable ignored) {
}
return false;
}
I didn't test it yet, trying to fix some maven issue.
Done in https://github.com/Jakllp/MyPet/commit/474496fd8ba5bf12738f0626552002dd7252acfb
If you wanna build the plugin yourself you can look at the BuildGuide
(Note: We are just not doing whatever it was doing to the modifier anymore...)
Hello! I'm writing a plugin that adds custom entity and I get the same exception message:
java.lang.NullPointerException: Cannot invoke "net.minecraft.world.entity.ai.attributes.AttributeProvider.a(java.util.function.Consumer, net.minecraft.world.entity.ai.attributes.AttributeBase)" because "this.d" is null
at net.minecraft.world.entity.ai.attributes.AttributeMap.lambda$getInstance$1(AttributeMap.java:50) ~[?:?]
at java.util.HashMap.computeIfAbsent(HashMap.java:1219) ~[?:?]
at net.minecraft.world.entity.ai.attributes.AttributeMap.getInstance(AttributeMap.java:49) ~[?:?]
...
How did you solve it?
See: https://github.com/Jakllp/MyPet/commit/474496fd8ba5bf12738f0626552002dd7252acfb
I had to change setFinalFieldValue() which is used to replace the craftAttributes-Field here
Thing is: I only needed to change it bc you don't need to modify the "modifiers" field in java 16+ anymore. You should check if you're replacing the craftAttributes first
Thanks for the answer!
I can't replace it because the plugin crashes at doing super(type, world)
.
I'm registering the entity by changing the value of an existing private static final
field in the EntityTypes
class (and it doesn't work without removing the final
field, I'm on MC 1.18.1 and Java 17).
In case you're talking about net.minecraft.world.entity.EntityType
: Take a look at how this plugin registers it's EntityTypes here
In case you're talking about org.bukkit.entity.EntityType
: That's an enum. Can't change that.
Is it possible to register custom entity (by replacing an existing one) without registering custom net.minecraft.world.entity.EntityTypes
?
maybe, idk