Skip to content

Commit 7ba8d1b

Browse files
authored
Refactor SpigotEntityIdProvider ID supplier logic
Refactor entity ID supplier detection logic to improve maintainability and clarity.
1 parent df6fe0f commit 7ba8d1b

File tree

1 file changed

+66
-33
lines changed

1 file changed

+66
-33
lines changed

platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/SpigotEntityIdProvider.java

Lines changed: 66 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
package me.tofaa.entitylib.spigot;
22

3-
import com.github.retrooper.packetevents.manager.server.ServerVersion;
4-
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
5-
import me.tofaa.entitylib.EntityIdProvider;
6-
import me.tofaa.entitylib.Platform;
7-
import org.bukkit.Bukkit;
8-
import org.bukkit.UnsafeValues;
9-
import org.bukkit.plugin.java.JavaPlugin;
10-
import org.jetbrains.annotations.NotNull;
11-
123
import java.lang.reflect.Field;
4+
import java.lang.reflect.Modifier;
135
import java.util.UUID;
146
import java.util.concurrent.atomic.AtomicInteger;
157
import java.util.function.Supplier;
168
import java.util.stream.Stream;
179

10+
import org.bukkit.Bukkit;
11+
import org.bukkit.UnsafeValues;
12+
import org.bukkit.plugin.java.JavaPlugin;
13+
import org.jetbrains.annotations.NotNull;
14+
15+
import com.github.retrooper.packetevents.manager.server.ServerVersion;
16+
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
17+
18+
import me.tofaa.entitylib.EntityIdProvider;
19+
import me.tofaa.entitylib.Platform;
20+
1821
/**
1922
* Internal {@link EntityIdProvider} for Spigot servers, handling version and platform differences.
2023
*/
@@ -63,37 +66,49 @@ private Supplier<Integer> detectIdSupplier() {
6366

6467
final Class<?> entityClass = getEntityClass();
6568
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_14)) {
66-
final Field entityAtomicField = getField(entityClass, "entityCount", "d", "c"); // Obfuscated names
67-
if (entityAtomicField == null) {
68-
throw new IllegalStateException("Could not find entity counter field");
69+
final Supplier<Integer> modernSupplier = resolveAtomicSupplier(entityClass);
70+
if (modernSupplier != null) {
71+
return modernSupplier;
6972
}
70-
try {
71-
entityAtomicField.setAccessible(true);
72-
final AtomicInteger counter = (AtomicInteger) entityAtomicField.get(null);
73-
return counter::incrementAndGet;
74-
} catch (final Exception exception) {
75-
throw new IllegalStateException("Failed to access entity counter", exception);
73+
}
74+
75+
return resolveLegacySupplier(entityClass);
76+
}
77+
78+
private Supplier<Integer> resolveAtomicSupplier(final Class<?> entityClass) {
79+
final Field entityAtomicField = getStaticFieldOfType(entityClass, AtomicInteger.class,
80+
"entityCount", "d", "c", "counter", "nextEntityId");
81+
if (entityAtomicField == null) {
82+
return null;
83+
}
84+
try {
85+
entityAtomicField.setAccessible(true);
86+
final Object fieldValue = entityAtomicField.get(null);
87+
if (!(fieldValue instanceof AtomicInteger)) {
88+
return null; // incompatible type, fall back to legacy strategy
7689
}
90+
final AtomicInteger counter = (AtomicInteger) fieldValue;
91+
return counter::incrementAndGet;
92+
} catch (final IllegalAccessException exception) {
93+
throw new IllegalStateException("Failed to access entity counter", exception);
7794
}
95+
}
7896

79-
final Field entityLegacyField = getField(entityClass, "entityCount");
97+
private Supplier<Integer> resolveLegacySupplier(final Class<?> entityClass) {
98+
final Field entityLegacyField = getStaticFieldOfType(entityClass, Integer.TYPE, "entityCount", "b");
8099
if (entityLegacyField == null) {
81100
throw new IllegalStateException("Could not find legacy entity counter field");
82101
}
83-
try {
84-
entityLegacyField.setAccessible(true);
85-
return () -> {
86-
try {
87-
final int entityId = entityLegacyField.getInt(null);
88-
entityLegacyField.setInt(null, entityId + 1);
89-
return entityId;
90-
} catch (final Exception exception) {
91-
throw new IllegalStateException("Failed to modify entity counter", exception);
92-
}
93-
};
94-
} catch (final Exception exception) {
95-
throw new IllegalStateException("Failed to access legacy entity counter", exception);
96-
}
102+
entityLegacyField.setAccessible(true);
103+
return () -> {
104+
try {
105+
final int entityId = entityLegacyField.getInt(null);
106+
entityLegacyField.setInt(null, entityId + 1);
107+
return entityId;
108+
} catch (final IllegalAccessException exception) {
109+
throw new IllegalStateException("Failed to modify entity counter", exception);
110+
}
111+
};
97112
}
98113

99114
/**
@@ -135,6 +150,24 @@ private static Field getField(final Class<?> clazz, final String... possibleName
135150
return null;
136151
}
137152

153+
private static Field getStaticFieldOfType(final Class<?> clazz, final Class<?> desiredType,
154+
final String... possibleNames) {
155+
for (final String name : possibleNames) {
156+
final Field field = getField(clazz, name);
157+
if (field != null && desiredType.isAssignableFrom(field.getType())
158+
&& Modifier.isStatic(field.getModifiers())) {
159+
return field;
160+
}
161+
}
162+
163+
for (final Field field : clazz.getDeclaredFields()) {
164+
if (Modifier.isStatic(field.getModifiers()) && desiredType.isAssignableFrom(field.getType())) {
165+
return field;
166+
}
167+
}
168+
return null;
169+
}
170+
138171
/**
139172
* Determines if the server environment is Paper by checking for Paper-specific classes.
140173
* @return true if Paper is detected.

0 commit comments

Comments
 (0)