mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-04-23 16:39:22 +00:00
replace world load context injection with bytecode injections
This commit is contained in:
@@ -32,10 +32,8 @@ import com.volmit.iris.core.nms.v1X.NMSBinding1X;
|
||||
import com.volmit.iris.core.pregenerator.LazyPregenerator;
|
||||
import com.volmit.iris.core.service.StudioSVC;
|
||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||
import com.volmit.iris.core.tools.IrisWorldCreator;
|
||||
import com.volmit.iris.engine.EnginePanic;
|
||||
import com.volmit.iris.engine.object.IrisCompat;
|
||||
import com.volmit.iris.engine.object.IrisContextInjector;
|
||||
import com.volmit.iris.engine.object.IrisDimension;
|
||||
import com.volmit.iris.engine.object.IrisWorld;
|
||||
import com.volmit.iris.engine.platform.BukkitChunkGenerator;
|
||||
@@ -457,11 +455,9 @@ public class Iris extends VolmitPlugin implements Listener {
|
||||
services = new KMap<>();
|
||||
setupAudience();
|
||||
initialize("com.volmit.iris.core.service").forEach((i) -> services.put((Class<? extends IrisService>) i.getClass(), (IrisService) i));
|
||||
INMS.get();
|
||||
IO.delete(new File("iris"));
|
||||
compat = IrisCompat.configured(getDataFile("compat.json"));
|
||||
ServerConfigurator.configure();
|
||||
new IrisContextInjector();
|
||||
IrisSafeguard.IrisSafeguardSystem();
|
||||
getSender().setTag(getTag());
|
||||
IrisSafeguard.earlySplash();
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
package com.volmit.iris.core.nms;
|
||||
|
||||
import com.volmit.iris.core.nms.container.AutoClosing;
|
||||
import com.volmit.iris.core.nms.container.BiomeColor;
|
||||
import com.volmit.iris.core.nms.datapack.DataVersion;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
@@ -89,13 +88,10 @@ public interface INMSBinding {
|
||||
MCABiomeContainer newBiomeContainer(int min, int max);
|
||||
|
||||
default World createWorld(WorldCreator c) {
|
||||
if (missingDimensionTypes(true, true, true))
|
||||
if (missingDimensionTypes(c.environment()))
|
||||
throw new IllegalStateException("Missing dimenstion types to create world");
|
||||
|
||||
try (var ignored = injectLevelStems()) {
|
||||
ignored.storeContext();
|
||||
return c.createWorld();
|
||||
}
|
||||
return c.createWorld();
|
||||
}
|
||||
|
||||
int countCustomBiomes();
|
||||
@@ -130,13 +126,20 @@ public interface INMSBinding {
|
||||
|
||||
KList<String> getStructureKeys();
|
||||
|
||||
AutoClosing injectLevelStems();
|
||||
|
||||
default AutoClosing injectUncached(boolean overworld, boolean nether, boolean end) {
|
||||
return null;
|
||||
}
|
||||
KMap<String, World.Environment> getMainWorlds();
|
||||
|
||||
boolean missingDimensionTypes(boolean overworld, boolean nether, boolean end);
|
||||
|
||||
void removeCustomDimensions(World world);
|
||||
default boolean missingDimensionTypes(World.Environment env) {
|
||||
return switch (env) {
|
||||
case NORMAL -> missingDimensionTypes(true, false, false);
|
||||
case NETHER -> missingDimensionTypes(false, true, false);
|
||||
case THE_END -> missingDimensionTypes(false, false, true);
|
||||
default -> true;
|
||||
};
|
||||
}
|
||||
|
||||
default boolean injectBukkit() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,13 +121,8 @@ public class NMSBinding1X implements INMSBinding {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AutoClosing injectLevelStems() {
|
||||
return new AutoClosing(() -> {});
|
||||
}
|
||||
|
||||
@Override
|
||||
public AutoClosing injectUncached(boolean overworld, boolean nether, boolean end) {
|
||||
return injectLevelStems();
|
||||
public KMap<String, World.Environment> getMainWorlds() {
|
||||
return new KMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -135,11 +130,6 @@ public class NMSBinding1X implements INMSBinding {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeCustomDimensions(World world) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag serializeEntity(Entity location) {
|
||||
return null;
|
||||
|
||||
@@ -3,8 +3,12 @@ package com.volmit.iris.core.safeguard;
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.nms.INMS;
|
||||
import com.volmit.iris.core.nms.v1X.NMSBinding1X;
|
||||
import com.volmit.iris.engine.object.IrisContextInjector;
|
||||
import com.volmit.iris.util.agent.Agent;
|
||||
import com.volmit.iris.util.misc.ServerProperties;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import javax.tools.JavaCompiler;
|
||||
@@ -15,10 +19,8 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import static com.volmit.iris.Iris.getJavaVersion;
|
||||
import static com.volmit.iris.core.safeguard.IrisSafeguard.*;
|
||||
@@ -31,6 +33,8 @@ public class ServerBootSFG {
|
||||
public static boolean hasPrivileges = true;
|
||||
public static boolean unsuportedversion = false;
|
||||
public static boolean missingDimensionTypes = false;
|
||||
public static boolean missingAgent = false;
|
||||
public static boolean failedInjection = false;
|
||||
protected static boolean safeguardPassed;
|
||||
public static boolean passedserversoftware = true;
|
||||
protected static int count;
|
||||
@@ -112,10 +116,21 @@ public class ServerBootSFG {
|
||||
severityMedium++;
|
||||
}
|
||||
|
||||
if (IrisContextInjector.isMissingDimensionTypes()) {
|
||||
missingDimensionTypes = true;
|
||||
joiner.add("Missing Dimension Types");
|
||||
if (!Agent.install()) {
|
||||
missingAgent = true;
|
||||
joiner.add("Missing Java Agent");
|
||||
severityHigh++;
|
||||
} else {
|
||||
if (missingDimensionTypes()) {
|
||||
missingDimensionTypes = true;
|
||||
joiner.add("Missing Dimension Types");
|
||||
severityHigh++;
|
||||
}
|
||||
if (!INMS.get().injectBukkit()) {
|
||||
failedInjection = true;
|
||||
joiner.add("Failed Bukkit Injection");
|
||||
severityHigh++;
|
||||
}
|
||||
}
|
||||
|
||||
allIncompatibilities = joiner.toString();
|
||||
@@ -173,4 +188,31 @@ public class ServerBootSFG {
|
||||
return !path.isEmpty() && (new File(path, "javac").exists() || new File(path, "javac.exe").exists());
|
||||
}
|
||||
|
||||
private static boolean missingDimensionTypes() {
|
||||
var irisWorlds = irisWorlds();
|
||||
if (irisWorlds.isEmpty()) return false;
|
||||
|
||||
var worlds = INMS.get().getMainWorlds();
|
||||
worlds.keySet().removeIf(Predicate.not(irisWorlds::contains));
|
||||
|
||||
boolean overworld = worlds.containsValue(World.Environment.NORMAL) || worlds.containsValue(World.Environment.CUSTOM);
|
||||
boolean nether = worlds.containsValue(World.Environment.NETHER);
|
||||
boolean end = worlds.containsValue(World.Environment.THE_END);
|
||||
|
||||
if (overworld || nether || end)
|
||||
return INMS.get().missingDimensionTypes(overworld, nether, end);
|
||||
return false;
|
||||
}
|
||||
|
||||
private static List<String> irisWorlds() {
|
||||
var config = YamlConfiguration.loadConfiguration(ServerProperties.BUKKIT_YML);
|
||||
ConfigurationSection section = config.getConfigurationSection("worlds");
|
||||
if (section == null) return List.of();
|
||||
|
||||
return section.getKeys(false)
|
||||
.stream()
|
||||
.filter(k -> section.getString(k + ".generator", "").startsWith("Iris"))
|
||||
.toList();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -44,6 +44,11 @@ public class UtilsSFG {
|
||||
Iris.safeguard(C.RED + "- Required Iris dimension types were not loaded.");
|
||||
Iris.safeguard(C.RED + "- If this still happens after a restart please contact support.");
|
||||
}
|
||||
if (ServerBootSFG.missingAgent) {
|
||||
Iris.safeguard(C.RED + "Java Agent");
|
||||
Iris.safeguard(C.RED + "- Please enable dynamic agent loading by adding -XX:+EnableDynamicAgentLoading to your jvm arguments.");
|
||||
Iris.safeguard(C.RED + "- or add the jvm argument -javaagent:plugins/" + Iris.instance.getJarFile().getName());
|
||||
}
|
||||
if (!ServerBootSFG.passedserversoftware) {
|
||||
Iris.safeguard(C.YELLOW + "Unsupported Server Software");
|
||||
Iris.safeguard(C.YELLOW + "- Please consider using Paper or Purpur instead.");
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
package com.volmit.iris.engine.object;
|
||||
|
||||
import com.volmit.iris.core.nms.INMS;
|
||||
import com.volmit.iris.core.nms.container.AutoClosing;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.misc.ServerProperties;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.world.WorldInitEvent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.volmit.iris.Iris.instance;
|
||||
|
||||
public class IrisContextInjector implements Listener {
|
||||
@Getter
|
||||
private static boolean missingDimensionTypes = false;
|
||||
private AutoClosing autoClosing = null;
|
||||
|
||||
public IrisContextInjector() {
|
||||
if (!Bukkit.getWorlds().isEmpty()) return;
|
||||
|
||||
String levelName = ServerProperties.LEVEL_NAME;
|
||||
List<String> irisWorlds = irisWorlds();
|
||||
boolean overworld = irisWorlds.contains(levelName);
|
||||
boolean nether = irisWorlds.contains(levelName + "_nether");
|
||||
boolean end = irisWorlds.contains(levelName + "_end");
|
||||
|
||||
if (INMS.get().missingDimensionTypes(overworld, nether, end)) {
|
||||
missingDimensionTypes = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (overworld || nether || end) {
|
||||
autoClosing = INMS.get().injectUncached(overworld, nether, end);
|
||||
}
|
||||
|
||||
instance.registerListener(this);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void on(WorldInitEvent event) {
|
||||
if (autoClosing != null) {
|
||||
autoClosing.close();
|
||||
autoClosing = null;
|
||||
}
|
||||
instance.unregisterListener(this);
|
||||
}
|
||||
|
||||
private List<String> irisWorlds() {
|
||||
var config = YamlConfiguration.loadConfiguration(ServerProperties.BUKKIT_YML);
|
||||
ConfigurationSection section = config.getConfigurationSection("worlds");
|
||||
if (section == null) return List.of();
|
||||
|
||||
return section.getKeys(false)
|
||||
.stream()
|
||||
.filter(k -> section.getString(k + ".generator", "").startsWith("Iris"))
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
@@ -130,7 +130,6 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
|
||||
if (initialized || !world.name().equals(event.getWorld().getName()))
|
||||
return;
|
||||
AutoClosing.closeContext();
|
||||
INMS.get().removeCustomDimensions(event.getWorld());
|
||||
world.setRawWorldSeed(event.getWorld().getSeed());
|
||||
Engine engine = getEngine(event.getWorld());
|
||||
if (engine == null) {
|
||||
|
||||
41
core/src/main/java/com/volmit/iris/util/agent/Agent.java
Normal file
41
core/src/main/java/com/volmit/iris/util/agent/Agent.java
Normal file
@@ -0,0 +1,41 @@
|
||||
package com.volmit.iris.util.agent;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import net.bytebuddy.agent.ByteBuddyAgent;
|
||||
import net.bytebuddy.dynamic.loading.ClassReloadingStrategy;
|
||||
|
||||
import java.lang.instrument.Instrumentation;
|
||||
|
||||
public class Agent {
|
||||
private static final String NAME = "com.volmit.iris.util.agent.Installer";
|
||||
|
||||
public static ClassReloadingStrategy installed() {
|
||||
return ClassReloadingStrategy.of(getInstrumentation());
|
||||
}
|
||||
|
||||
public static Instrumentation getInstrumentation() {
|
||||
Instrumentation instrumentation = doGetInstrumentation();
|
||||
if (instrumentation == null) throw new IllegalStateException("The agent is not initialized or unavailable");
|
||||
return instrumentation;
|
||||
}
|
||||
|
||||
public static boolean install() {
|
||||
if (doGetInstrumentation() != null)
|
||||
return true;
|
||||
try {
|
||||
Iris.info("Installing Java Agent...");
|
||||
ByteBuddyAgent.attach(Iris.instance.getJarFile(), ByteBuddyAgent.ProcessProvider.ForCurrentVm.INSTANCE);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return doGetInstrumentation() != null;
|
||||
}
|
||||
|
||||
private static Instrumentation doGetInstrumentation() {
|
||||
try {
|
||||
return (Instrumentation) Class.forName(NAME, true, ClassLoader.getSystemClassLoader()).getMethod("getInstrumentation").invoke(null);
|
||||
} catch (Exception ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
29
core/src/main/java/com/volmit/iris/util/agent/Installer.java
Normal file
29
core/src/main/java/com/volmit/iris/util/agent/Installer.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package com.volmit.iris.util.agent;
|
||||
|
||||
import java.lang.instrument.Instrumentation;
|
||||
|
||||
public class Installer {
|
||||
private static volatile Instrumentation instrumentation;
|
||||
|
||||
public static Instrumentation getInstrumentation() {
|
||||
Instrumentation instrumentation = Installer.instrumentation;
|
||||
if (instrumentation == null) {
|
||||
throw new IllegalStateException("The agent is not loaded or this method is not called via the system class loader");
|
||||
}
|
||||
return instrumentation;
|
||||
}
|
||||
|
||||
public static void premain(String arguments, Instrumentation instrumentation) {
|
||||
doMain(instrumentation);
|
||||
}
|
||||
|
||||
public static void agentmain(String arguments, Instrumentation instrumentation) {
|
||||
doMain(instrumentation);
|
||||
}
|
||||
|
||||
private static synchronized void doMain(Instrumentation instrumentation) {
|
||||
if (Installer.instrumentation != null)
|
||||
return;
|
||||
Installer.instrumentation = instrumentation;
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,8 @@ libraries:
|
||||
- bsf:bsf:2.4.0
|
||||
- org.lz4:lz4-java:1.8.0
|
||||
- com.github.oshi:oshi-core:6.6.5
|
||||
- net.bytebuddy:byte-buddy:1.17.5
|
||||
- net.bytebuddy:byte-buddy-agent:1.17.5
|
||||
commands:
|
||||
iris:
|
||||
aliases: [ ir, irs ]
|
||||
|
||||
Reference in New Issue
Block a user