mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-20 07:24:16 +00:00
[VERY VERY VERY BAD IDEA]
This commit is contained in:
1 parent
f0e7fea13b
commit
2fa0853e42
892 files changed
+13482
-53554
No files matched your search
@@ -1,5 +0,0 @@
|
||||
public class Config {
|
||||
public int jvm = 25;
|
||||
public NMSBinding.Type type = NMSBinding.Type.DIRECT;
|
||||
public String version;
|
||||
}
|
||||
@@ -1,285 +0,0 @@
|
||||
import com.volmit.nmstools.NMSToolsExtension;
|
||||
import com.volmit.nmstools.NMSToolsPlugin;
|
||||
import io.papermc.paperweight.userdev.PaperweightUser;
|
||||
import io.papermc.paperweight.userdev.PaperweightUserDependenciesExtension;
|
||||
import io.papermc.paperweight.userdev.PaperweightUserExtension;
|
||||
import io.papermc.paperweight.userdev.attribute.Obfuscation;
|
||||
import org.gradle.api.Action;
|
||||
import org.gradle.api.DefaultTask;
|
||||
import org.gradle.api.GradleException;
|
||||
import org.gradle.api.Named;
|
||||
import org.gradle.api.Plugin;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.artifacts.Configuration;
|
||||
import org.gradle.api.attributes.Bundling;
|
||||
import org.gradle.api.attributes.Category;
|
||||
import org.gradle.api.attributes.LibraryElements;
|
||||
import org.gradle.api.attributes.Usage;
|
||||
import org.gradle.api.file.FileTree;
|
||||
import org.gradle.api.model.ObjectFactory;
|
||||
import org.gradle.api.plugins.JavaPluginExtension;
|
||||
import org.gradle.api.plugins.ExtraPropertiesExtension;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
import org.gradle.jvm.toolchain.JavaLanguageVersion;
|
||||
import org.gradle.jvm.toolchain.JavaToolchainService;
|
||||
import org.gradle.work.DisableCachingByDefault;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static io.papermc.paperweight.util.constants.ConstantsKt.REOBF_CONFIG;
|
||||
|
||||
public class NMSBinding implements Plugin<Project> {
|
||||
private static final String NEW_LINE = System.lineSeparator();
|
||||
private static final byte[] NEW_LINE_BYTES = NEW_LINE.getBytes(StandardCharsets.UTF_8);
|
||||
|
||||
@Override
|
||||
public void apply(Project target) {
|
||||
ExtraPropertiesExtension extra = target.getExtensions().getExtraProperties();
|
||||
Object configValue = extra.has("nms") ? extra.get("nms") : null;
|
||||
if (!(configValue instanceof Config)) {
|
||||
throw new GradleException("No NMS binding configuration found");
|
||||
}
|
||||
|
||||
Config config = (Config) configValue;
|
||||
int jvm = config.jvm;
|
||||
Type type = config.type;
|
||||
|
||||
if (type == Type.USER_DEV) {
|
||||
target.getPlugins().apply(PaperweightUser.class);
|
||||
|
||||
PaperweightUserDependenciesExtension dependenciesExtension =
|
||||
target.getDependencies().getExtensions().findByType(PaperweightUserDependenciesExtension.class);
|
||||
if (dependenciesExtension != null) {
|
||||
dependenciesExtension.paperDevBundle(config.version);
|
||||
}
|
||||
|
||||
JavaPluginExtension java = target.getExtensions().findByType(JavaPluginExtension.class);
|
||||
if (java == null) {
|
||||
throw new GradleException("Java plugin not found");
|
||||
}
|
||||
|
||||
java.getToolchain().getLanguageVersion().set(JavaLanguageVersion.of(jvm));
|
||||
JavaToolchainService javaToolchains = target.getExtensions().getByType(JavaToolchainService.class);
|
||||
target.getExtensions().configure(PaperweightUserExtension.class,
|
||||
extension -> extension.getJavaLauncher().set(javaToolchains.launcherFor(java.getToolchain())));
|
||||
} else {
|
||||
extra.set("nmsTools.useBuildTools", type == Type.BUILD_TOOLS);
|
||||
target.getPlugins().apply(NMSToolsPlugin.class);
|
||||
target.getExtensions().configure(NMSToolsExtension.class, extension -> {
|
||||
extension.getJvm().set(jvm);
|
||||
extension.getVersion().set(config.version);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
String outgoingArtifactTask = type == Type.USER_DEV ? "jar" : "remap";
|
||||
ObjectFactory objects = target.getObjects();
|
||||
Configuration reobfConfiguration = target.getConfigurations().findByName(REOBF_CONFIG);
|
||||
if (reobfConfiguration == null) {
|
||||
reobfConfiguration = target.getConfigurations().create(REOBF_CONFIG);
|
||||
}
|
||||
|
||||
target.getConfigurations().named(REOBF_CONFIG).configure(configuration -> {
|
||||
configuration.setCanBeConsumed(true);
|
||||
configuration.setCanBeResolved(false);
|
||||
configuration.getAttributes().attribute(Usage.USAGE_ATTRIBUTE, named(objects, Usage.class, Usage.JAVA_RUNTIME));
|
||||
configuration.getAttributes().attribute(Category.CATEGORY_ATTRIBUTE, named(objects, Category.class, Category.LIBRARY));
|
||||
configuration.getAttributes().attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, named(objects, LibraryElements.class, LibraryElements.JAR));
|
||||
configuration.getAttributes().attribute(Bundling.BUNDLING_ATTRIBUTE, named(objects, Bundling.class, Bundling.EXTERNAL));
|
||||
configuration.getAttributes().attribute(Obfuscation.Companion.getOBFUSCATION_ATTRIBUTE(), named(objects, Obfuscation.class, Obfuscation.OBFUSCATED));
|
||||
configuration.getOutgoing().artifact(target.getTasks().named(outgoingArtifactTask));
|
||||
});
|
||||
|
||||
int[] version = parseVersion(config.version);
|
||||
int major = version[0];
|
||||
int minor = version[1];
|
||||
if (major <= 20 && minor <= 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
target.getTasks().register("convert", ConversionTask.class, type);
|
||||
target.getTasks().named("compileJava").configure(task -> task.dependsOn("convert"));
|
||||
target.getRootProject().getTasks()
|
||||
.matching(task -> task.getName().equals("prepareKotlinBuildScriptModel"))
|
||||
.configureEach(task -> task.dependsOn(target.getPath() + ":convert"));
|
||||
}
|
||||
|
||||
public static void nmsBinding(Project project, Action<Config> action) {
|
||||
Config config = new Config();
|
||||
action.execute(config);
|
||||
project.getExtensions().getExtraProperties().set("nms", config);
|
||||
project.getPlugins().apply(NMSBinding.class);
|
||||
}
|
||||
|
||||
private static int[] parseVersion(String version) {
|
||||
String trimmed = version;
|
||||
int suffix = trimmed.indexOf('-');
|
||||
if (suffix >= 0) {
|
||||
trimmed = trimmed.substring(0, suffix);
|
||||
}
|
||||
|
||||
String[] parts = trimmed.split("\\.");
|
||||
if ("1".equals(parts[0])) {
|
||||
return new int[]{Integer.parseInt(parts[1]), Integer.parseInt(parts[2])};
|
||||
}
|
||||
return new int[]{Integer.parseInt(parts[0]), Integer.parseInt(parts[1])};
|
||||
}
|
||||
|
||||
private static <T extends Named> T named(ObjectFactory objects, Class<T> type, String name) {
|
||||
return objects.named(type, name);
|
||||
}
|
||||
|
||||
@DisableCachingByDefault
|
||||
public abstract static class ConversionTask extends DefaultTask {
|
||||
private final Pattern pattern;
|
||||
private final String replacement;
|
||||
|
||||
@Inject
|
||||
public ConversionTask(Type type) {
|
||||
setGroup("nms");
|
||||
getInputs().property("type", type);
|
||||
|
||||
JavaPluginExtension java = getProject().getExtensions().findByType(JavaPluginExtension.class);
|
||||
if (java == null) {
|
||||
throw new GradleException("Java plugin not found");
|
||||
}
|
||||
|
||||
Provider<FileTree> source = java.getSourceSets().named(SourceSet.MAIN_SOURCE_SET_NAME).map(SourceSet::getAllJava);
|
||||
getInputs().files(source);
|
||||
getOutputs().files(source);
|
||||
|
||||
if (type == Type.USER_DEV) {
|
||||
this.pattern = Pattern.compile("org\\.bukkit\\.craftbukkit\\." + getProject().getName());
|
||||
this.replacement = "org.bukkit.craftbukkit";
|
||||
} else {
|
||||
this.pattern = Pattern.compile("org\\.bukkit\\.craftbukkit\\.(?!" + getProject().getName() + ")");
|
||||
this.replacement = "org.bukkit.craftbukkit." + getProject().getName() + ".";
|
||||
}
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
public void process() {
|
||||
ExecutorService executor = Executors.newFixedThreadPool(16);
|
||||
try {
|
||||
Set<File> files = getInputs().getFiles().getFiles();
|
||||
List<Future<?>> futures = new ArrayList<>(files.size());
|
||||
for (File file : files) {
|
||||
if (!file.getName().endsWith(".java")) {
|
||||
continue;
|
||||
}
|
||||
futures.add(executor.submit(() -> processFile(file)));
|
||||
}
|
||||
|
||||
for (Future<?> future : futures) {
|
||||
future.get();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new RuntimeException(e);
|
||||
} catch (ExecutionException e) {
|
||||
throw new RuntimeException(e.getCause());
|
||||
} finally {
|
||||
executor.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
private void processFile(File file) {
|
||||
List<String> output = new ArrayList<>();
|
||||
boolean changed = false;
|
||||
|
||||
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (line.startsWith("package") || line.isBlank()) {
|
||||
output.add(line);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!line.startsWith("import")) {
|
||||
if (!changed) {
|
||||
return;
|
||||
}
|
||||
|
||||
output.add(line);
|
||||
continue;
|
||||
}
|
||||
|
||||
Matcher matcher = pattern.matcher(line);
|
||||
if (!matcher.find()) {
|
||||
output.add(line);
|
||||
continue;
|
||||
}
|
||||
|
||||
output.add(matcher.replaceAll(replacement));
|
||||
changed = true;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
if (!changed) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (hasTrailingNewLine(file)) {
|
||||
output.add("");
|
||||
}
|
||||
|
||||
try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
|
||||
for (int i = 0; i < output.size(); i++) {
|
||||
writer.append(output.get(i));
|
||||
if (i + 1 < output.size()) {
|
||||
writer.append(NEW_LINE);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasTrailingNewLine(File file) throws IOException {
|
||||
if (NEW_LINE_BYTES.length == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try (RandomAccessFile raf = new RandomAccessFile(file, "r")) {
|
||||
if (raf.length() < NEW_LINE_BYTES.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
byte[] bytes = new byte[NEW_LINE_BYTES.length];
|
||||
raf.seek(raf.length() - bytes.length);
|
||||
raf.readFully(bytes);
|
||||
return Arrays.equals(bytes, NEW_LINE_BYTES);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
USER_DEV,
|
||||
BUILD_TOOLS,
|
||||
DIRECT
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
import org.gradle.api.GradleException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HexFormat;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
public final class NativeRuntimeArtifacts {
|
||||
public static final String MANIFEST = "META-INF/iris/native-runtime.properties";
|
||||
private static final String GROUP = "com.github.VolmitSoftware.VolmLib";
|
||||
private static final String NATIVE = "art/arcane/volmlib/nativelib/";
|
||||
|
||||
private NativeRuntimeArtifacts() {
|
||||
}
|
||||
|
||||
public static void generate(Map<String, File> artifacts, String version, File output, File rules) throws IOException {
|
||||
List<String> manifest = new ArrayList<>();
|
||||
manifest.add("modules=" + String.join(",", artifacts.keySet()));
|
||||
manifest.add("repository=https://jitpack.io/");
|
||||
Set<String> retained = new TreeSet<>();
|
||||
for (Map.Entry<String, File> artifact : artifacts.entrySet()) {
|
||||
String module = artifact.getKey();
|
||||
manifest.add(module + ".coordinate=" + GROUP + ":" + module + ":" + version);
|
||||
manifest.add(module + ".sha256=" + digest(artifact.getValue()));
|
||||
try (JarFile jar = new JarFile(artifact.getValue())) {
|
||||
Enumeration<JarEntry> entries = jar.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
JarEntry entry = entries.nextElement();
|
||||
if (!entry.getName().endsWith(".class")) {
|
||||
continue;
|
||||
}
|
||||
try (InputStream input = jar.getInputStream(entry)) {
|
||||
for (String reference : ClassReferences.read(input.readAllBytes())) {
|
||||
if (reference.startsWith("art/arcane/volmlib/") && !implementation(reference)) {
|
||||
retained.add(reference);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File manifestFile = new File(output, MANIFEST);
|
||||
Files.createDirectories(manifestFile.toPath().getParent());
|
||||
Files.write(manifestFile.toPath(), manifest, StandardCharsets.UTF_8);
|
||||
Path runtimeRoots = output.toPath().resolve("META-INF/volmit/runtime-roots.list");
|
||||
Files.createDirectories(runtimeRoots.getParent());
|
||||
Files.write(runtimeRoots, retained, StandardCharsets.UTF_8);
|
||||
List<String> keep = new ArrayList<>();
|
||||
keep.add("-keep class art.arcane.volmlib.nativelib.** { *; }");
|
||||
for (String reference : retained) {
|
||||
keep.add("-keep class " + reference.replace('/', '.') + " { *; }");
|
||||
}
|
||||
Files.createDirectories(rules.toPath().getParent());
|
||||
Files.write(rules.toPath(), keep, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
public static void verify(File artifact, List<String> adapters, String version) throws IOException {
|
||||
try (JarFile jar = new JarFile(artifact)) {
|
||||
JarEntry entry = jar.getJarEntry(MANIFEST);
|
||||
if (entry == null) {
|
||||
throw new GradleException("Missing native runtime dependency manifest");
|
||||
}
|
||||
Properties manifest = new Properties();
|
||||
try (InputStream input = jar.getInputStream(entry)) {
|
||||
manifest.load(input);
|
||||
}
|
||||
Set<String> expected = new TreeSet<>();
|
||||
expected.add("native-common");
|
||||
for (String adapter : adapters) {
|
||||
expected.add("native-" + adapter);
|
||||
}
|
||||
Set<String> actual = new TreeSet<>(List.of(manifest.getProperty("modules", "").split(",")));
|
||||
if (!expected.equals(actual)) {
|
||||
throw new GradleException("Native dependency modules differ: " + actual + "; expected " + expected);
|
||||
}
|
||||
for (String module : expected) {
|
||||
String coordinate = GROUP + ":" + module + ":" + version;
|
||||
if (!coordinate.equals(manifest.getProperty(module + ".coordinate"))
|
||||
|| !manifest.getProperty(module + ".sha256", "").matches("[0-9a-f]{64}")) {
|
||||
throw new GradleException("Invalid native runtime dependency: " + module);
|
||||
}
|
||||
}
|
||||
Enumeration<JarEntry> entries = jar.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
String name = entries.nextElement().getName();
|
||||
if (name.endsWith(".class") && implementation(name)) {
|
||||
throw new GradleException("Native runtime implementation is bundled: " + name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean implementation(String name) {
|
||||
if (!name.startsWith(NATIVE)) {
|
||||
return false;
|
||||
}
|
||||
String relative = name.substring(NATIVE.length());
|
||||
return relative.startsWith("common/") || relative.startsWith("minecraft")
|
||||
|| relative.matches("v[0-9_]+R[0-9]+/.*");
|
||||
}
|
||||
|
||||
private static String digest(File file) throws IOException {
|
||||
try {
|
||||
return HexFormat.of().formatHex(MessageDigest.getInstance("SHA-256").digest(Files.readAllBytes(file.toPath())));
|
||||
} catch (NoSuchAlgorithmException exception) {
|
||||
throw new IllegalStateException(exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,8 +11,6 @@ public final class GenerationRevisionScope {
|
||||
"core/src/main/java",
|
||||
"spi/src/main/java",
|
||||
"adapters/bukkit/plugin/src/main/java",
|
||||
"adapters/bukkit/nms/v26_2_R1/src/main/java",
|
||||
"adapters/bukkit/nms/v26_3_R1/src/main/java",
|
||||
"adapters/minecraft-common/src/main/java",
|
||||
"adapters/modded-common/src/main/java",
|
||||
"adapters/client-common/src/main/java",
|
||||
@@ -31,8 +29,6 @@ public final class GenerationRevisionScope {
|
||||
"core/src/main/java/art/arcane/iris/world/safeguard/Diagnostic.java",
|
||||
"core/src/main/java/art/arcane/iris/world/safeguard/ValueWithDiagnostics.java",
|
||||
"core/src/main/java/art/arcane/iris/diagnostics/splash/IrisSplashRenderer.java",
|
||||
"adapters/bukkit/nms/v26_2_R1/src/main/java/art/arcane/iris/platform/bukkit/nms/v26_2_R1/NmsWorldLifecycle.java",
|
||||
"adapters/bukkit/nms/v26_3_R1/src/main/java/art/arcane/iris/platform/bukkit/nms/v26_3_R1/NmsWorldLifecycle.java",
|
||||
"adapters/bukkit/plugin/src/main/java/art/arcane/iris/command/CommandDeveloper.java",
|
||||
"adapters/bukkit/plugin/src/main/java/art/arcane/iris/command/CommandPregen.java",
|
||||
"adapters/bukkit/plugin/src/main/java/art/arcane/iris/command/CommandIris.java",
|
||||
|
||||
Reference in new issue
Block a user