Skip to content

Commit f40b253

Browse files
committed
fixes
1 parent fd855ed commit f40b253

59 files changed

Lines changed: 2155 additions & 516 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/main/java/com/comphenix/protocol/events/AbstractStructure.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,14 @@ public StructureModifier<PotionEffectType> getEffectTypes() {
845845
BukkitConverters.getEffectTypeConverter());
846846
}
847847

848+
/**
849+
* Retrieve a read/write structure for {@code Holder<DamageType>} fields.
850+
* @return A modifier for DamageType Holder fields.
851+
*/
852+
public StructureModifier<org.bukkit.damage.DamageType> getDamageTypes() {
853+
return getHolders(MinecraftReflection.getDamageTypeClass(), BukkitConverters.getDamageTypeConverter());
854+
}
855+
848856
/**
849857
* Retrieve a read/write structure for the SoundCategory enum in 1.9.
850858
* @return A modifier for SoundCategory enum fields.

src/main/java/com/comphenix/protocol/injector/EquivalentConstructor.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22

33
import com.comphenix.protocol.PacketType;
44
import com.comphenix.protocol.reflect.EquivalentConverter;
5+
import com.comphenix.protocol.reflect.FuzzyReflection;
56
import com.comphenix.protocol.reflect.accessors.Accessors;
67
import com.comphenix.protocol.reflect.accessors.ConstructorAccessor;
8+
import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract;
79
import com.comphenix.protocol.utility.Tuple;
810

11+
import java.lang.reflect.Constructor;
912
import java.util.ArrayList;
1013
import java.util.List;
1114

@@ -41,7 +44,10 @@ public Object create(Object... args) {
4144
for (int i = 0; i < converters.size(); i++) {
4245
params[i] = converters.get(i).first();
4346
}
44-
constructorAccessor = Accessors.getConstructorAccessor(packetType.getPacketClass(), params);
47+
48+
Constructor<?> ctor = FuzzyReflection.fromClass(packetType.getPacketClass(), true)
49+
.getConstructor(FuzzyMethodContract.newBuilder().parameterExactArray(params).build());
50+
constructorAccessor = Accessors.getConstructorAccessor(ctor);
4551
}
4652

4753
Object[] convertedArgs = new Object[args.length];

src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -928,6 +928,10 @@ public static Class<?> getMobEffectListClass() {
928928
return getMinecraftClass("world.effect.MobEffectList", "MobEffectList", "world.effect.MobEffect", "world.effect.MobEffects");
929929
}
930930

931+
public static Class<?> getDamageTypeClass() {
932+
return getMinecraftClass("world.damagesource.DamageType");
933+
}
934+
931935
public static Class<?> getSoundEffectClass() {
932936
return getNullableNMS("sounds.SoundEffect", "sounds.SoundEvent", "SoundEffect", "sounds.SoundEvents");
933937
}

src/main/java/com/comphenix/protocol/wrappers/AutoWrapper.java

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.google.common.base.Defaults;
2323
import com.google.common.base.Preconditions;
2424

25+
import java.lang.reflect.Constructor;
2526
import java.lang.reflect.Modifier;
2627
import java.util.Arrays;
2728
import java.util.HashMap;
@@ -165,12 +166,26 @@ private void computeNmsConstructorAccess() {
165166
nmsInstanceCreator = noArgs;
166167
nmsDefaultArgs = NO_ARGS;
167168
} else {
168-
// use the first constructor of the class
169-
nmsInstanceCreator = Accessors.getConstructorAccessor(nmsClass.getDeclaredConstructors()[0]);
170-
nmsDefaultArgs = Arrays
171-
.stream(nmsInstanceCreator.getConstructor().getParameterTypes())
172-
.map(type -> type.isPrimitive() ? Defaults.defaultValue(type) : null)
173-
.toArray(Object[]::new);
169+
// No no-arg constructor. For records (and most NMS data classes) the canonical
170+
// constructor has one parameter per non-static field; that's the one we want.
171+
// Other constructors (e.g. FriendlyByteBuf decoders) take a single network-buffer
172+
// argument and would call methods on it during construction, so they're unsafe to
173+
// invoke with default values.
174+
Constructor<?>[] ctors = nmsClass.getDeclaredConstructors();
175+
Constructor<?> chosen = ctors[0];
176+
for (int i = 1; i < ctors.length; i++) {
177+
if (ctors[i].getParameterCount() > chosen.getParameterCount()) {
178+
chosen = ctors[i];
179+
}
180+
}
181+
nmsInstanceCreator = Accessors.getConstructorAccessor(chosen);
182+
Class<?>[] paramTypes = chosen.getParameterTypes();
183+
nmsDefaultArgs = new Object[paramTypes.length];
184+
for (int i = 0; i < paramTypes.length; i++) {
185+
nmsDefaultArgs[i] = paramTypes[i].isPrimitive()
186+
? Defaults.defaultValue(paramTypes[i])
187+
: null;
188+
}
174189
}
175190
}
176191
}

src/main/java/com/comphenix/protocol/wrappers/BukkitConverters.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1428,6 +1428,47 @@ public PotionEffectType getSpecific(Object generic) {
14281428
});
14291429
}
14301430

1431+
private static MethodAccessor damageTypeToNms = null;
1432+
private static MethodAccessor damageTypeFromNms = null;
1433+
1434+
public static EquivalentConverter<org.bukkit.damage.DamageType> getDamageTypeConverter() {
1435+
return ignoreNull(new EquivalentConverter<org.bukkit.damage.DamageType>() {
1436+
1437+
@Override
1438+
public Class<org.bukkit.damage.DamageType> getSpecificType() {
1439+
return org.bukkit.damage.DamageType.class;
1440+
}
1441+
1442+
@Override
1443+
public Object getGeneric(org.bukkit.damage.DamageType specific) {
1444+
if (damageTypeToNms == null) {
1445+
Class<?> craftDamageType = getCraftBukkitClass("damage.CraftDamageType");
1446+
FuzzyReflection fuzzy = FuzzyReflection.fromClass(craftDamageType, false);
1447+
damageTypeToNms = Accessors.getMethodAccessor(fuzzy.getMethod(FuzzyMethodContract.newBuilder()
1448+
.parameterExactArray(org.bukkit.damage.DamageType.class)
1449+
.returnTypeExact(MinecraftReflection.getDamageTypeClass())
1450+
.requireModifier(Modifier.STATIC)
1451+
.build()));
1452+
}
1453+
return damageTypeToNms.invoke(null, specific);
1454+
}
1455+
1456+
@Override
1457+
public org.bukkit.damage.DamageType getSpecific(Object generic) {
1458+
if (damageTypeFromNms == null) {
1459+
Class<?> craftDamageType = getCraftBukkitClass("damage.CraftDamageType");
1460+
FuzzyReflection fuzzy = FuzzyReflection.fromClass(craftDamageType, false);
1461+
damageTypeFromNms = Accessors.getMethodAccessor(fuzzy.getMethod(FuzzyMethodContract.newBuilder()
1462+
.parameterExactArray(MinecraftReflection.getDamageTypeClass())
1463+
.returnTypeExact(org.bukkit.damage.DamageType.class)
1464+
.requireModifier(Modifier.STATIC)
1465+
.build()));
1466+
}
1467+
return (org.bukkit.damage.DamageType) damageTypeFromNms.invoke(null, generic);
1468+
}
1469+
});
1470+
}
1471+
14311472
private static Class<?> dimensionManager;
14321473
private static FauxEnumConverter<Dimension> dimensionConverter;
14331474
private static FauxEnumConverter<DimensionImpl> dimensionImplConverter;

0 commit comments

Comments
 (0)