Cache some reflection

This commit is contained in:
libraryaddict 2022-11-29 19:58:34 +13:00
parent 55eb451765
commit 1eafa0f357
3 changed files with 58 additions and 63 deletions

View File

@ -1115,12 +1115,7 @@ public class DisguiseUtilities {
return;
}
// TODO Store reflection field
Set trackedPlayers = (Set) ReflectionManager.getNmsField("EntityTrackerEntry", "trackedPlayers").get(entityTrackerEntry);
// If the tracker exists. Remove himself from his tracker
trackedPlayers = (Set) new HashSet(trackedPlayers).clone(); // Copy before iterating to prevent
// ConcurrentModificationException
Set trackedPlayers = ReflectionManager.getClonedTrackedPlayers(entityTrackerEntry);
PacketContainer destroyPacket = getDestroyPacket(disguise.getEntity().getEntityId());
@ -1308,11 +1303,7 @@ public class DisguiseUtilities {
Object entityTrackerEntry = ReflectionManager.getEntityTrackerEntry(disguise.getEntity());
if (entityTrackerEntry != null) {
// TODO Store reflection field
Set trackedPlayers = (Set) ReflectionManager.getNmsField("EntityTrackerEntry", "trackedPlayers").get(entityTrackerEntry);
trackedPlayers = (Set) new HashSet(trackedPlayers).clone(); // Copy before iterating to prevent
// ConcurrentModificationException
for (Object p : trackedPlayers) {
for (Object p : ReflectionManager.getClonedTrackedPlayers(entityTrackerEntry)) {
Player player = (Player) ReflectionManager.getBukkitEntity(ReflectionManager.getPlayerFromPlayerConnection(p));
if (((TargetedDisguise) disguise).canSee(player)) {
@ -1699,18 +1690,10 @@ public class DisguiseUtilities {
return;
}
Set trackedPlayers = (Set) ReflectionManager.getNmsField("EntityTrackerEntry", "trackedPlayers").get(entityTrackerEntry);
Method clear = ReflectionManager.getNmsMethod("EntityTrackerEntry", NmsVersion.v1_14.isSupported() ? "a" : "clear",
ReflectionManager.getNmsClass("EntityPlayer"));
final Method updatePlayer = ReflectionManager.getNmsMethod("EntityTrackerEntry", NmsVersion.v1_14.isSupported() ? "b" : "updatePlayer",
ReflectionManager.getNmsClass("EntityPlayer"));
Set trackedPlayers = ReflectionManager.getClonedTrackedPlayers(entityTrackerEntry);
PacketContainer destroyPacket = getDestroyPacket(disguise.getEntity().getEntityId());
trackedPlayers = (Set) new HashSet(trackedPlayers).clone(); // Copy before iterating to prevent
// ConcurrentModificationException
for (final Object o : trackedPlayers) {
Object p = ReflectionManager.getPlayerFromPlayerConnection(o);
Player pl = (Player) ReflectionManager.getBukkitEntity(p);
@ -1719,13 +1702,13 @@ public class DisguiseUtilities {
continue;
}
clear.invoke(entityTrackerEntry, p);
ReflectionManager.clearEntityTracker(entityTrackerEntry, p);
ProtocolLibrary.getProtocolManager().sendServerPacket(pl, destroyPacket);
Bukkit.getScheduler().scheduleSyncDelayedTask(LibsDisguises.getInstance(), () -> {
try {
updatePlayer.invoke(entityTrackerEntry, p);
ReflectionManager.addEntityTracker(entityTrackerEntry, p);
} catch (Exception ex) {
ex.printStackTrace();
}
@ -1755,33 +1738,27 @@ public class DisguiseUtilities {
final Object entityTrackerEntry = ReflectionManager.getEntityTrackerEntry(entity);
if (entityTrackerEntry != null) {
Set trackedPlayers = (Set) ReflectionManager.getNmsField("EntityTrackerEntry", "trackedPlayers").get(entityTrackerEntry);
Set trackedPlayers = ReflectionManager.getClonedTrackedPlayers(entityTrackerEntry);
Method clear = ReflectionManager.getNmsMethod("EntityTrackerEntry", NmsVersion.v1_14.isSupported() ? "a" : "clear",
ReflectionManager.getNmsClass("EntityPlayer"));
final Method updatePlayer = ReflectionManager.getNmsMethod("EntityTrackerEntry", NmsVersion.v1_14.isSupported() ? "b" : "updatePlayer",
ReflectionManager.getNmsClass("EntityPlayer"));
trackedPlayers = (Set) new HashSet(trackedPlayers).clone(); // Copy before iterating to prevent
// ConcurrentModificationException
for (final Object o : trackedPlayers) {
Object p = ReflectionManager.getPlayerFromPlayerConnection(o);
Player player = (Player) ReflectionManager.getBukkitEntity(p);
if (player != entity) {
clear.invoke(entityTrackerEntry, p);
ProtocolLibrary.getProtocolManager().sendServerPacket(player, destroyPacket);
Bukkit.getScheduler().scheduleSyncDelayedTask(LibsDisguises.getInstance(), () -> {
try {
updatePlayer.invoke(entityTrackerEntry, p);
} catch (Exception ex) {
ex.printStackTrace();
}
}, 2);
if (player == entity) {
continue;
}
ReflectionManager.clearEntityTracker(entityTrackerEntry, p);
ProtocolLibrary.getProtocolManager().sendServerPacket(player, destroyPacket);
Bukkit.getScheduler().scheduleSyncDelayedTask(LibsDisguises.getInstance(), () -> {
try {
ReflectionManager.addEntityTracker(entityTrackerEntry, p);
} catch (Exception ex) {
ex.printStackTrace();
}
}, 2);
}
}
} catch (Exception ex) {
@ -1821,16 +1798,7 @@ public class DisguiseUtilities {
final Object entityTrackerEntry = ReflectionManager.getEntityTrackerEntry(disguise.getEntity());
if (entityTrackerEntry != null) {
Set trackedPlayers = (Set) ReflectionManager.getNmsField("EntityTrackerEntry", "trackedPlayers").get(entityTrackerEntry);
// TODO Store the fields
final Method clear = ReflectionManager.getNmsMethod("EntityTrackerEntry", NmsVersion.v1_14.isSupported() ? "a" : "clear",
ReflectionManager.getNmsClass("EntityPlayer"));
final Method updatePlayer = ReflectionManager.getNmsMethod("EntityTrackerEntry", NmsVersion.v1_14.isSupported() ? "b" : "updatePlayer",
ReflectionManager.getNmsClass("EntityPlayer"));
trackedPlayers = (Set) new HashSet(trackedPlayers).clone();
Set trackedPlayers = ReflectionManager.getClonedTrackedPlayers(entityTrackerEntry);
PacketContainer destroyPacket = getDestroyPacket(disguise.getEntity().getEntityId());
for (final Object o : trackedPlayers) {
@ -1838,13 +1806,13 @@ public class DisguiseUtilities {
Player player = (Player) ReflectionManager.getBukkitEntity(p);
if (disguise.getEntity() != player && disguise.canSee(player)) {
clear.invoke(entityTrackerEntry, p);
ReflectionManager.clearEntityTracker(entityTrackerEntry, p);
ProtocolLibrary.getProtocolManager().sendServerPacket(player, destroyPacket);
Bukkit.getScheduler().scheduleSyncDelayedTask(LibsDisguises.getInstance(), () -> {
try {
updatePlayer.invoke(entityTrackerEntry, p);
ReflectionManager.addEntityTracker(entityTrackerEntry, p);
} catch (Exception ex) {
ex.printStackTrace();
}
@ -1947,9 +1915,7 @@ public class DisguiseUtilities {
// TODO Store reflection fields
// If the tracker exists. Remove himself from his tracker
if (!isRunningPaper() || NmsVersion.v1_17.isSupported()) {
Object trackedPlayersObj = ReflectionManager.getNmsField("EntityTrackerEntry", "trackedPlayers").get(entityTrackerEntry);
((Set<Object>) trackedPlayersObj).remove(ReflectionManager.getPlayerConnectionOrPlayer(player));
ReflectionManager.getTrackedPlayers(entityTrackerEntry).remove(ReflectionManager.getPlayerConnectionOrPlayer(player));
} else {
((Map<Object, Object>) ReflectionManager.getNmsField("EntityTrackerEntry", "trackedPlayerMap").get(entityTrackerEntry)).remove(
ReflectionManager.getPlayerConnectionOrPlayer(player));
@ -2491,9 +2457,7 @@ public class DisguiseUtilities {
// Check for code differences in PaperSpigot vs Spigot
if (!isRunningPaper() || NmsVersion.v1_17.isSupported()) {
// Add himself to his own entity tracker
Object trackedPlayersObj = ReflectionManager.getNmsField("EntityTrackerEntry", "trackedPlayers").get(entityTrackerEntry);
((Set<Object>) trackedPlayersObj).add(ReflectionManager.getPlayerConnectionOrPlayer(player));
ReflectionManager.getTrackedPlayers(entityTrackerEntry).add(ReflectionManager.getPlayerConnectionOrPlayer(player));
} else {
Field field = ReflectionManager.getNmsField("EntityTrackerEntry", "trackedPlayerMap");
Object nmsEntity = ReflectionManager.getPlayerConnectionOrPlayer(player);

View File

@ -25,7 +25,7 @@ public class PacketListenerMain extends PacketAdapter {
@Override
public void onPacketSending(final PacketEvent event) {
if (event.isCancelled()) {
if (event.isCancelled() || event.isPlayerTemporary()) {
return;
}

View File

@ -13,6 +13,7 @@ import com.comphenix.protocol.wrappers.WrappedParticle;
import com.comphenix.protocol.wrappers.WrappedWatchableObject;
import com.comphenix.protocol.wrappers.nbt.NbtWrapper;
import com.mojang.authlib.GameProfile;
import lombok.SneakyThrows;
import me.libraryaddict.disguise.DisguiseConfig;
import me.libraryaddict.disguise.LibsDisguises;
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
@ -44,7 +45,6 @@ import me.libraryaddict.disguise.utilities.LibsPremium;
import me.libraryaddict.disguise.utilities.reflection.annotations.NmsAddedIn;
import me.libraryaddict.disguise.utilities.reflection.annotations.NmsRemovedIn;
import me.libraryaddict.disguise.utilities.sounds.SoundGroup;
import net.minecraft.world.entity.animal.FrogVariant;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Art;
@ -102,6 +102,7 @@ import java.lang.reflect.Modifier;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
@ -180,6 +181,9 @@ public class ReflectionManager {
private static Method incrementedInventoryStateId;
private static Field playerInventoryContainer;
private static ReflectionManagerAbstract nmsReflection;
private static Field trackedPlayers;
private static Method clearEntityTracker;
private static Method addEntityTracker;
public static void init() {
try {
@ -190,6 +194,12 @@ public class ReflectionManager {
nmsReflection = getReflectionManager(getVersion());
trackedPlayers = ReflectionManager.getNmsField("EntityTrackerEntry", "trackedPlayers");
clearEntityTracker = ReflectionManager.getNmsMethod("EntityTrackerEntry", NmsVersion.v1_14.isSupported() ? "a" : "clear",
ReflectionManager.getNmsClass("EntityPlayer"));
addEntityTracker = ReflectionManager.getNmsMethod("EntityTrackerEntry", NmsVersion.v1_14.isSupported() ? "b" : "updatePlayer",
ReflectionManager.getNmsClass("EntityPlayer"));
if (nmsReflection != null) {
return;
}
@ -1048,6 +1058,27 @@ public class ReflectionManager {
return getNmsField(getNmsClass(className), fieldName);
}
@SneakyThrows
public static Set getClonedTrackedPlayers(Object entityTrackerEntry) {
// Copy before iterating to prevent ConcurrentModificationException
return (Set) new HashSet(getTrackedPlayers(entityTrackerEntry)).clone();
}
@SneakyThrows
public static Set getTrackedPlayers(Object entityTrackerEntry) {
return (Set) trackedPlayers.get(entityTrackerEntry);
}
@SneakyThrows
public static void clearEntityTracker(Object tracker, Object player) {
clearEntityTracker.invoke(tracker, player);
}
@SneakyThrows
public static void addEntityTracker(Object tracker, Object player) {
addEntityTracker.invoke(tracker, player);
}
public static Object getNmsItem(ItemStack itemstack) {
if (nmsReflection != null) {
return nmsReflection.getNmsItem(itemstack);