Permalink
Browse files

Change Minecraft reflection method to improve startup times

Despite only being used for sudo() right now, ClassDiscovery for the server jar adds up to 10 seconds to the startup time. The Bukkit convertor init also synchronizes during the ClassDiscovery process which may make things worse. This commit proposes that this extra time is not a necessary sacrifice and implements an alternative reflection method where needed.
  • Loading branch information...
PseudoKnight committed Oct 25, 2017
1 parent 7e4ebf4 commit 09845d3faaf16fffbee50543f89595c5d9120612
@@ -2,7 +2,6 @@
package com.laytonsmith.abstraction.bukkit.entities;
import com.laytonsmith.PureUtilities.ClassLoading.ClassDiscovery;
import com.laytonsmith.PureUtilities.Common.ReflectionUtils;
import com.laytonsmith.abstraction.MCCommandSender;
import com.laytonsmith.abstraction.MCEntity;
@@ -429,22 +428,23 @@ public MCEntity getSpectatorTarget() {
@Override
public void setTempOp(Boolean value) throws ClassNotFoundException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
Server server = Bukkit.getServer();
String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
Class serverClass = ClassDiscovery.getDefaultInstance().forFuzzyName("org.bukkit.craftbukkit.*", "CraftServer").loadClass();
Class serverClass = Class.forName("org.bukkit.craftbukkit." + version + ".CraftServer");
if (!server.getClass().isAssignableFrom(serverClass)) {
throw new IllegalStateException("Running server isn't CraftBukkit");
}
// Since 1.7.8
Class nmsMinecraftServerClass = ClassDiscovery.getDefaultInstance().forFuzzyName("net.minecraft.server.*", "MinecraftServer").loadClass();
Class nmsMinecraftServerClass = Class.forName("net.minecraft.server." + version + ".MinecraftServer");
/*n.m.s.MinecraftServer*/ Object nmsServer = ReflectionUtils.invokeMethod(nmsMinecraftServerClass, null, "getServer");
/*n.m.s.PlayerList*/ Object nmsPlayerList = ReflectionUtils.invokeMethod(nmsServer, "getPlayerList");
/*n.m.s.OpList*/ Object opSet = ReflectionUtils.get(ClassDiscovery.getDefaultInstance().forFuzzyName("net.minecraft.server.*", "PlayerList").loadClass(), nmsPlayerList, "operators");
/*n.m.s.OpList*/ Object opSet = ReflectionUtils.get(Class.forName("net.minecraft.server." + version + ".PlayerList"), nmsPlayerList, "operators");
//opSet.getClass().getSuperclass() == n.m.s.JsonList
Map/*<String, n.m.s.OpListEntry>*/ d = (Map)ReflectionUtils.get(opSet.getClass().getSuperclass(), opSet, "d");
if(value){
/*n.m.s.OpListEntry*/ Class nmsOpListEntry = ClassDiscovery.getDefaultInstance().forFuzzyName("net.minecraft.server.*", "OpListEntry").loadClass();
/*n.m.s.OpListEntry*/ Class nmsOpListEntry = Class.forName("net.minecraft.server." + version + ".OpListEntry");
Class nmsGameProfile;
try {
/*com.mojang.authlib.GameProfile*/ nmsGameProfile = Class.forName("com.mojang.authlib.GameProfile");
@@ -56,7 +56,6 @@
import com.laytonsmith.core.extensions.ExtensionManager;
import com.laytonsmith.core.profiler.Profiler;
import com.laytonsmith.persistence.PersistenceNetwork;
import org.bukkit.Server;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@@ -277,13 +276,10 @@ public void run() {
cdc.setLogger(Logger.getLogger(CommandHelperPlugin.class.getName()));
ClassDiscovery.getDefaultInstance().setClassDiscoveryCache(cdc);
ClassDiscovery.getDefaultInstance().addDiscoveryLocation(ClassDiscovery.GetClassContainer(CommandHelperPlugin.class));
ClassDiscovery.getDefaultInstance().addDiscoveryLocation(ClassDiscovery.GetClassContainer(Server.class));
StreamUtils.GetSystemOut().println("[CommandHelper] Running initial class discovery,"
+ " this will probably take a few seconds...");
myServer = StaticLayer.GetServer();
StreamUtils.GetSystemOut().println("[CommandHelper] Loading extensions in the background...");
loadingThread = new Thread("extensionloader") {
@Override
public void run() {
@@ -319,6 +315,7 @@ public void onEnable() {
Logger.getLogger(CommandHelperPlugin.class.getName()).log(Level.SEVERE, null, ex);
}
}
myServer = StaticLayer.GetServer();
BukkitMCEntityType.build();
BukkitMCBiomeType.build();
BukkitMCSound.build();
@@ -271,7 +271,7 @@ public final void reload(MCPlayer player, String[] settings, boolean firstLoad)
//Clear out the data source cache
DataSourceFactory.DisconnectAll();
PacketJumper.startup();
// PacketJumper.startup(); we're not using this yet
if (options.reloadExtensions()) {
ProfilePoint extensionManagerStartup = parent.profiler.start("Extension manager startup", LogLevel.VERBOSE);
@@ -2,9 +2,12 @@
package com.laytonsmith.core.packetjumper;
import com.laytonsmith.PureUtilities.ClassLoading.ClassDiscovery;
import com.laytonsmith.PureUtilities.Common.ReflectionUtils;
import com.laytonsmith.PureUtilities.Common.StreamUtils;
import com.laytonsmith.abstraction.MCPlayer;
import com.laytonsmith.core.constructs.Construct;
import org.bukkit.Bukkit;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
@@ -36,14 +39,17 @@ public void run() {
// } catch (IOException ex) {
// Logger.getLogger(PacketJumper.class.getName()).log(Level.SEVERE, null, ex);
// }
Class PacketClass = ClassDiscovery.getDefaultInstance().forFuzzyName("net\\.minecraft\\.server.*", "Packet").loadClass();
Set<Class> packets = ClassDiscovery.getDefaultInstance().loadClassesThatExtend(PacketClass);
for(Class packet : packets){
packetInfo.add(new PacketInfo(packet));
String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
try {
Class PacketClass = Class.forName("net.minecraft.server." + version + ".Packet");
Set<Class> packets = ReflectionUtils.getAllExtensions(PacketClass);
for (Class packet : packets) {
packetInfo.add(new PacketInfo(packet));
}
started = true;
} catch(ClassNotFoundException ex) {
StreamUtils.GetSystemOut().println("[CommandHelper] Failed to find Minecraft Packet classes.");
}
started = true;
}
}, "PacketJumperInitializer");
initializingThread.start();

0 comments on commit 09845d3

Please sign in to comment.