Attempt to remove arch and add AWToAt.java

This commit is contained in:
Cutiepie
2024-01-17 23:47:47 +06:00
parent fc62c78136
commit 9a8f14c7d3
14 changed files with 425 additions and 75 deletions
+3
View File
@@ -34,3 +34,6 @@ build.properties
# Sqlite databases
*.sqlite
# Don't add access transformers to git as it's dynamically generated
accesstransformer.cfg
+26 -11
View File
@@ -8,13 +8,18 @@ plugins {
id "io.github.pacifistmc.forgix" version "1.2.6"
// Manifold preprocessor
id "systems.manifold.manifold-gradle-plugin" version "0.0.2-alpha"
// id "systems.manifold.manifold-gradle-plugin" version "0.0.2-alpha"
// // Provides mc libraries to core
// id "org.spongepowered.gradle.vanilla" version '0.2.1-SNAPSHOT' apply false
// Architectury is used here only as a replacement for forge's own loom
id "dev.architectury.loom" version "1.4-SNAPSHOT" apply false
// id "dev.architectury.loom" version "1.4-SNAPSHOT" apply false
id "fabric-loom" version "1.4-SNAPSHOT" apply false
id 'net.minecraftforge.gradle' version '[6.0.16,6.2)' apply false
id 'org.spongepowered.mixin' version '0.7.+' apply false
id 'org.parchmentmc.librarian.forgegradle' version '1.+' apply false
}
/**
@@ -104,8 +109,8 @@ subprojects { p ->
// Apply plugins
apply plugin: "java"
apply plugin: "com.github.johnrengelman.shadow"
if (isMinecraftSubProject)
apply plugin: "systems.manifold.manifold-gradle-plugin"
// if (isMinecraftSubProject)
// apply plugin: "systems.manifold.manifold-gradle-plugin"
if (p == project(":core"))
apply plugin: "application"
// apply plugin: "org.spongepowered.gradle.vanilla" // Provides minecraft libraries
@@ -114,14 +119,20 @@ subprojects { p ->
if (
(findProject(":forge") && p == project(":forge")) ||
(findProject(":neoforge") && p == project(":neoforge"))
)
apply plugin: "dev.architectury.loom"
) {
// apply plugin: 'net.minecraftforge.gradle'
// apply plugin: 'org.spongepowered.mixin'
// apply plugin: 'org.parchmentmc.librarian.forgegradle'
/* The code below creates the access transformer file */
new AWToAT().remap(project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener"), accessWidenerVersion)
}
// Set the manifold version (may not be required tough)
manifold {
manifoldVersion = rootProject.manifold_version
}
// manifold {
// manifoldVersion = rootProject.manifold_version
// }
// set up custom configurations (configurations are a way to handle dependencies)
@@ -143,7 +154,7 @@ subprojects { p ->
// this should match shadowMe pretty closely
implementation.extendsFrom(forgeShadowMe)
shadowMe.extendsFrom(forgeShadowMe)
forgeRuntimeLibrary.extendsFrom(forgeShadowMe)
runtimeOnly.extendsFrom(forgeShadowMe)
if (isMinecraftSubProject && p != project(":common")) {
@@ -154,14 +165,18 @@ subprojects { p ->
runtimeClasspath.extendsFrom common
if (findProject(":forge"))
developmentForge.extendsFrom common
implementation.extendsFrom common
if (findProject(":neoforge"))
developmentNeoForge.extendsFrom common
implementation.extendsFrom common
compileClasspath.extendsFrom coreProjects
runtimeClasspath.extendsFrom coreProjects
if (findProject(":forge"))
developmentForge.extendsFrom coreProjects
implementation.extendsFrom coreProjects
if (findProject(":neoforge"))
developmentNeoForge.extendsFrom coreProjects
implementation.extendsFrom coreProjects
if (findProject(":fabricLike") && p != project(":fabricLike")) {
// Shadow fabricLike
@@ -615,7 +630,7 @@ allprojects { p ->
into p.file("build/resources/main")
}
tasks.withType(JavaCompile) {
compileJava {
if (isMinecraftSubProject) {
options.release = rootProject.java_version as Integer
options.compilerArgs += ["-Xplugin:Manifold"]
+239
View File
@@ -0,0 +1,239 @@
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
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;
public class AWToAT {
private static final Map<String, String> ACCESS_POINT_MAP = new HashMap<>();
static {
ACCESS_POINT_MAP.put("accessible", "public");
ACCESS_POINT_MAP.put("extendable", "public-f");
ACCESS_POINT_MAP.put("mutable", "public-f");
}
public String minecraftVersion;
public File remap(File file, String minecraftVersion) {
this.minecraftVersion = minecraftVersion.replace("_", ".");
File atFile = createATFile(file);
processFile(file, atFile);
return atFile;
}
private File createATFile(File file) {
File metaInf = new File(file.getParentFile(), "META-INF");
if (!metaInf.exists() && !metaInf.mkdir()) throw new RuntimeException("Error creating META-INF folder");
File atFile = new File(metaInf, "accesstransformer.cfg");
try {
atFile.createNewFile();
} catch (IOException e) {
throw new RuntimeException("Error creating new file", e);
}
return atFile;
}
private void processFile(File file, File atFile) {
/* Validates if we need to recreate the Access Transformer file if it's out of date */
// Get the hash of the file
String fileHash = getFileHash(file);
try (Scanner atScanner = new Scanner(atFile)) {
// Check if the AT file is up-to-date by comparing the hash of the file with the hash stored in the AT file
boolean hashFound = false;
while (atScanner.hasNextLine()) {
String line = atScanner.nextLine();
if (hashCheck(line, fileHash)) {
hashFound = true;
}
}
// If the AT file is up-to-date, print a message and return
if (hashFound) {
System.out.println("Access Transformer file is already up to date.");
return;
}
} catch (FileNotFoundException ignored) {
// If the AT file does not exist, continue
}
/* Creates the Access Transformer file */
// Opens a scanner for reading the Access Widener file and a writer for writing to the Access Transformer file
try (Scanner scanner = new Scanner(file); FileWriter writer = new FileWriter(atFile)) {
// Create an ExecutorService with a fixed thread pool size equal to the number of available processors
ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
// List to hold Future objects representing results of computation
List<Future<String>> futures = new ArrayList<>();
// Write the hash of the file to the AT file
writer.write("#DH_MAPPING_HASH:" + fileHash + "\n");
// Read each line from the file
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
// Skip lines starting with "accessWidener", "#" or blank lines
if (line.startsWith("accessWidener") || line.startsWith("#") || line.isBlank()) continue;
// Submit the line to the executor service for processing
// The processing is done by the processLine method
futures.add(executor.submit(() -> processLine(line.split(" "))));
}
// Write the results to the output file
// The results are obtained by calling the get method on each Future
for (Future<String> future : futures) {
writer.write(future.get());
}
// Shutdown the executor service to free up resources
executor.shutdown();
} catch (Exception e) {
throw new RuntimeException("Error reading or writing to file", e);
}
}
private String processLine(String[] fields) {
// fields[0] = access point like "accessible", "extendable", "mutable"
// fields[1] = type like "field", "method", "class"
// fields[2] = class name
// fields[3] = field/method name
// fields[4] = field/method descriptor
try {
// Store the original field/method name
String originalName = "";
// If there is a class name, replace the slashes with dots in the package name
if (fields.length > 2) fields[2] = fields[2].replace("/", ".");
// If there is a field/method name, store the original name and remap it to SRG
if (fields.length > 3) {
originalName = fields[3];
fields[3] = remapToSRG(fields[2], fields[3]);
}
StringBuilder line = new StringBuilder(ACCESS_POINT_MAP.getOrDefault(fields[0], "public")).append(" ");
switch (fields[1]) {
case "field":
line.append(fields[2]).append(" ").append(fields[3]).append(" #").append(originalName);
// It'll be like: access-point class-name field-name-SRG # field-name-Mojmap
// Eg: public net.minecraft.client.Minecraft f_90981_ # instance
break;
case "method":
line.append(fields[2]).append(" ").append(fields[3]).append(fields[4]).append(" #").append(originalName);
// It'll be like: access-point class-name method-name-SRG method-descriptor # method-name-Mojmap
// Eg: public net.minecraft.client.Minecraft m_172797_()Lnet/minecraft/client/Minecraft; # getInstance
break;
default:
line.append(fields[2]);
// It'll be like: access-point class-name
// Eg: public net.minecraft.client.Minecraft
break;
}
line.append("\n");
return line.toString();
} catch (Exception e) {
throw new RuntimeException("Error processing line", e);
}
}
private boolean hashCheck(String line, String fileHash) {
if (line.startsWith("#DH_MAPPING_HASH:")) {
String hash = line.substring(17);
return hash.equals(fileHash);
}
return false;
}
public String getFileHash(File file) {
try {
MessageDigest shaDigest = MessageDigest.getInstance("SHA-256");
try (InputStream fis = new FileInputStream(file)) {
byte[] byteArray = new byte[1024];
int bytesCount;
// Read file data and update in message digest
while ((bytesCount = fis.read(byteArray)) != -1) {
shaDigest.update(byteArray, 0, bytesCount);
}
}
byte[] bytes = shaDigest.digest();
// Convert byte array into signum representation
StringBuilder sb = new StringBuilder();
for (byte aByte : bytes) {
sb.append(Integer.toString((aByte & 0xff) + 0x100, 16).substring(1));
}
// Return complete hash
return sb.toString();
} catch (NoSuchAlgorithmException | IOException e) {
throw new RuntimeException(e);
}
}
// WARNING: BELOW LIES HIGHLY CURSED CODE AND MIGHT EVEN BE ILLEGAL
// Flag to track if there was an error in the GET request
boolean error = false;
/**
* This method returns a field or method name from Mojang mappings as SRG mappings.
* It makes a GET request to the Linkie API to fetch the SRG name.
*
* @param clazz The class name
* @param name The field or method name
* @return The SRG name
* @throws Exception If there is an error in the GET request or the SRG name is not found in the response
*/
private String remapToSRG(String clazz, String name) throws Exception {
// Encode the class and field/method name to be used in the URL
String query = URLEncoder.encode(clazz + "." + name, StandardCharsets.UTF_8);
// Construct the URL for the GET request
String urlString = "https://linkieapi.shedaniel.me/api/search?namespace=mojang&query=" + query + "&version=" + this.minecraftVersion + "&limit=1&allowClasses=false&allowFields=true&allowMethods=true&translate=mojang_srg";
URL url = new URI(urlString).toURL();
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
int responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuilder content = new StringBuilder();
// Read the response line by line
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
in.close();
conn.disconnect();
// Regex to find the SRG name in the response
Pattern pattern = Pattern.compile("\"l\"\\s*:\\s*\\{[^}]*\"i\"\\s*:\\s*\"([^\"]*)\"");
Matcher matcher = pattern.matcher(content.toString());
if (matcher.find()) return matcher.group(1);
else throw new Exception("Couldn't find the SRG mapping for name: " + name + "\nCould not find 'i' in 'l' object in the response"); // `i` is the SRG name which is stored in the `l` JSON object
} else {
if (error) {
// If there was an error in the GET request, and we already tried again, throw an exception
throw new Exception("The GET request failed");
}
// If there was an error in the GET request, wait 2.5 seconds and try again as we probably got rate limited
error = true;
Thread.sleep(2500);
return remapToSRG(clazz, name);
}
}
}
+8 -9
View File
@@ -1,6 +1,4 @@
plugins {
id "fabric-loom" version "1.4-SNAPSHOT"
}
apply plugin: "fabric-loom"
loom {
accessWidenerPath = project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener")
@@ -22,17 +20,12 @@ loom {
}
}
remapJar {
inputFile = shadowJar.archiveFile
dependsOn shadowJar
// classifier null
}
configurations {
// The addModJar basically embeds the mod to the built jar
addModJar
include.extendsFrom addModJar
modImplementation.extendsFrom addModJar
dummy
}
def addMod(path, enabled) {
@@ -114,6 +107,12 @@ dependencies {
}
}
remapJar {
inputFile = shadowJar.archiveFile
dependsOn shadowJar
// classifier null
}
task deleteResources(type: Delete) {
delete file("build/resources/main")
+134 -50
View File
@@ -1,15 +1,12 @@
plugins {
// Note: This is only needed for multi-loader projects
// The main architectury loom version is set at the start of the root build.gradle
id "architectury-plugin" version "3.4-SNAPSHOT"
}
apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'org.spongepowered.mixin'
sourceCompatibility = targetCompatibility = JavaVersion.VERSION_17
//sourceCompatibility = targetCompatibility = JavaVersion.VERSION_17
architectury {
platformSetupLoomIde()
forge()
}
//architectury {
// platformSetupLoomIde()
// forge()
//}
//loom {
// forge {
@@ -19,61 +16,138 @@ architectury {
// }
//}
loom {
silentMojangMappingsLicense() // Shut the licencing warning
accessWidenerPath = project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener")
//loom {
// silentMojangMappingsLicense() // Shut the licencing warning
// accessWidenerPath = project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener")
//
// forge {
// convertAccessWideners = true
// extraAccessWideners.add loom.accessWidenerPath.get().asFile.name
//
// mixinConfigs = [
// "DistantHorizons.forge.mixins.json"
// ]
// }
//
// // "runs" isn't required, but when we do need it then it can be useful
// runs {
// client {
// client()
// setConfigName("Forge Client")
// ideConfigGenerated(true)
// runDir("../run")
//// vmArgs("-XX:-OmitStackTraceInFastThrow", minecraftMemoryJavaArg)
// }
// server {
// server()
// setConfigName("Forge Server")
// ideConfigGenerated(true)
// runDir("../run")
// }
// }
//}
forge {
convertAccessWideners = true
extraAccessWideners.add loom.accessWidenerPath.get().asFile.name
mixinConfigs = [
"DistantHorizons.forge.mixins.json"
]
}
// "runs" isn't required, but when we do need it then it can be useful
minecraft {
mappings channel: 'official', version: minecraft_version
accessTransformer = project(":common").file('src/main/resources/META-INF/accesstransformer.cfg')
runs {
client {
client()
setConfigName("Forge Client")
ideConfigGenerated(true)
runDir("../run")
// vmArgs("-XX:-OmitStackTraceInFastThrow", minecraftMemoryJavaArg)
workingDirectory project.file('run')
ideaModule "${rootProject.name}.${project.name}.main"
taskName 'Client'
args "-mixins.config=${mod_name}.forge.mixins.json"
mods {
modClientRun {
source sourceSets.main
source project(":common").sourceSets.main
source project(":api").sourceSets.main
source project(":core").sourceSets.main
}
}
property 'forge.enabledGameTestNamespaces', mod_id
property 'forge.logging.console.level', 'debug'
properties 'mixin.env.remapRefMap': 'true'
property 'mixin.env.refMapRemappingFile', "${project.projectDir}/build/createSrgToMcp/output.srg"
}
server {
server()
setConfigName("Forge Server")
ideConfigGenerated(true)
runDir("../run")
workingDirectory project.file('run')
ideaModule "${rootProject.name}.${project.name}.main"
taskName 'Server'
args "-mixins.config=${mod_name}.forge.mixins.json"
mods {
modServerRun {
source sourceSets.main
source project(":common").sourceSets.main
source project(":api").sourceSets.main
source project(":core").sourceSets.main
}
}
property 'forge.logging.console.level', 'debug'
properties 'mixin.env.remapRefMap': 'true'
property 'mixin.env.refMapRemappingFile', "${project.projectDir}/build/createSrgToMcp/output.srg"
}
data {
workingDirectory project.file('run')
ideaModule "${rootProject.name}.${project.name}.main"
args '--mod', mod_id, '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/')
taskName 'Data'
args "-mixins.config=${mod_name}.forge.mixins.json"
mods {
modDataRun {
source sourceSets.main
source project(":common").sourceSets.main
source project(":api").sourceSets.main
source project(":core").sourceSets.main
}
}
property 'forge.logging.console.level', 'debug'
}
}
}
sourceSets.main.resources.srcDir 'src/generated/resources'
remapJar {
inputFile = shadowJar.archiveFile
dependsOn shadowJar
// classifier null
//remapJar {
// inputFile = shadowJar.archiveFile
// dependsOn shadowJar
//// classifier null
//}
shadowJar {
finalizedBy 'reobfShadowJar'
}
jar.dependsOn('shadowJar')
reobf {
shadowJar {}
}
minecraft.runs.all {
lazyToken('minecraft_classpath') {
// configurations.implementation.exclude group: 'org.jetbrains', module: 'annotations'
// configurations.implementation.copyRecursive().resolve().collect { it.absolutePath }.join(File.pathSeparator)
// configurations.runtimeLibrary.copyRecursive().resolve().collect { it.absolutePath }.join(File.pathSeparator)
}
}
def addMod(path, enabled) {
if (enabled == "2")
dependencies { implementation(path) }
// dependencies { implementation(path) }
dependencies { implementation(fg.deobf(path)) }
else if (enabled == "1")
dependencies { modCompileOnly(path) }
// dependencies { modCompileOnly(path) }
dependencies { compileOnly(fg.deobf(path)) }
}
dependencies {
minecraft "com.mojang:minecraft:${rootProject.minecraft_version}"
mappings loom.layered() {
// Mojmap mappings
officialMojangMappings()
// Parchment mappings (it adds parameter mappings & javadoc)
parchment("org.parchmentmc.data:parchment-${rootProject.parchment_version}@zip")
}
// minecraft "com.mojang:minecraft:${rootProject.minecraft_version}"
// mappings loom.layered() {
// // Mojmap mappings
// officialMojangMappings()
// // Parchment mappings (it adds parameter mappings & javadoc)
// parchment("org.parchmentmc.data:parchment-${rootProject.parchment_version}@zip")
// }
// Forge
forge "net.minecraftforge:forge:${rootProject.minecraft_version}-${rootProject.forge_version}"
minecraft "net.minecraftforge:forge:${rootProject.minecraft_version}-${rootProject.forge_version}"
// Architectury API
// if (minecraft_version == "1.16.5") {
@@ -89,12 +163,18 @@ dependencies {
addMod("curse.maven:TerraForged-363820:${rootProject.terraforged_version}", rootProject.enable_terraforged)
addMod("curse.maven:TerraFirmaCraft-302973:4616004", rootProject.enable_terrafirmacraft)
annotationProcessor "org.spongepowered:mixin:0.8.5:processor"
// if (System.getProperty("idea.sync.active") != "true") {
// annotationProcessor "org.spongepowered:mixin:0.8.4:processor"
// }
}
mixin {
add sourceSets.main, "${mod_name}-forge-refmap.json"
}
task deleteResources(type: Delete) {
delete file("build/resources/main")
}
@@ -108,10 +188,14 @@ processResources {
dependsOn(tasks.named('copyAllResources'))
}
tasks.named('runClient') {
dependsOn(tasks.named('copyAllResources'))
finalizedBy(deleteResources)
}
//processResources {
// dependsOn(tasks.named('copyAllResources'))
//}
//tasks.named('prepareClient') {
// dependsOn(tasks.named('copyAllResources'))
// finalizedBy(deleteResources)
//}
sourcesJar {
@@ -86,7 +86,7 @@ import java.util.List;
* @author James Seibel
* @version 8-15-2022
*/
@Mod(ModInfo.ID)
@Mod("distanthorizons") // TODO: Change it back to ModInfo.ID when forge works
public class ForgeMain implements LodForgeMethodCaller
{
private static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());
@@ -20,5 +20,6 @@
"client.MixinTextureUtil"
],
"server": [],
"plugin": "com.seibel.distanthorizons.forge.mixins.ForgeMixinPlugin"
"plugin": "com.seibel.distanthorizons.forge.mixins.ForgeMixinPlugin",
"refmap": "DistantHorizons-forge-refmap.json"
}
+1 -1
View File
@@ -29,5 +29,5 @@ issueTrackerURL = "${issues}"
mandatory = true # Forge syntax
type = "required" # Neoforge syntax
versionRange = "${compatible_forgemc_versions}" # Where we set what version of mc it is avalible for
ordering = "NONE"
ordering = "AFTER"
side = "BOTH"
+2
View File
@@ -2,9 +2,11 @@
org.gradle.jvmargs=-Xmx4096M
org.gradle.parallel=true
org.gradle.caching=true
fabric.loom.multiProjectOptimisation=true
# Mod Info
mod_name=DistantHorizons
mod_id=distanthorizons
mod_version=2.0.2-a-dev
api_version=1.1.0
maven_group=com.seibel.distanthorizons
+1 -1
View File
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
+4
View File
@@ -25,6 +25,10 @@ pluginManagement {
name "Sponge"
url "https://repo.spongepowered.org/repository/maven-public/"
}
maven {
name "ParchmentMC"
url "https://maven.parchmentmc.org"
}
mavenCentral()
gradlePluginPortal()
+1
View File
@@ -2,6 +2,7 @@
java_version=17
minecraft_version=1.20.1
parchment_version=1.20.1:2023.09.03
parchment_forge_version=1.20.1-2023.09.03
compatible_minecraft_versions=["1.20", "1.20.1"]
accessWidenerVersion=1_20
builds_for=fabric,forge
+1
View File
@@ -2,6 +2,7 @@
java_version=17
minecraft_version=1.20.2
parchment_version=1.20.1:2023.09.03
parchment_forge_version=1.20.1-2023.09.03
compatible_minecraft_versions=["1.20.2"]
accessWidenerVersion=1_20_2
builds_for=fabric,forge
+2 -1
View File
@@ -2,9 +2,10 @@
java_version=17
minecraft_version=1.20.4
parchment_version=1.20.2:2023.12.10
parchment_forge_version=1.20.2-2023.12.10
compatible_minecraft_versions=["1.20.3", "1.20.4"]
accessWidenerVersion=1_20_2
builds_for=fabric,forge,neoforge
builds_for=forge,fabric
# Fabric loader
fabric_loader_version=0.15.1