Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions src/main/java/net/minecraftforge/gradle/FileUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package net.minecraftforge.gradle;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
Copy link
Copy Markdown
Member

@LexManos LexManos May 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

java.nio doesnt exist in java 6 Which is required to decompile the game correctly due to bugs in fernflower.
java.nio.file.Files was added in java 7
FG 1.2 works fine with this because it uses an updated Fernflower with stabilization

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm considering whether to upgrade compatibility to Java 7 or 8. Java 6 is practically obsolete.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are several other places that also mention the 1.7 API, but I don't know why they don't affect compilation.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They dont effect compilation because youre using the system java to compile. Which is probably java 8+

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm considering whether to upgrade compatibility to Java 7 or 8. Java 6 is practically obsolete.

Yes, there isnt even a distro for modern macs. Which is what im running into for mavenizer.

But its not possible to bump the required java version until the fernflower issues i stated are fixed.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tested it locally, and directly upgrading the version didn't reveal any bugs. I've even compiled and run the mod using my fixed FG. So I want to know what the problem is.

import java.util.Objects;

public class FileUtils {
public static String readString(File file) throws IOException {
return readString(file, StandardCharsets.UTF_8);
}

public static String readString(File file, Charset charset) throws IOException {
return new String(Files.readAllBytes(file.toPath()), charset);
}

public static void updateDate(File file) throws IOException {
if (!file.createNewFile() && !file.setLastModified(System.currentTimeMillis())) {
throw new IOException("Unable to update modification time of " + file);
}
}

public static String getFileExtension(String fullName) {
Objects.requireNonNull(fullName);
String fileName = new File(fullName).getName();
int dotIndex = fileName.lastIndexOf('.');
return (dotIndex == -1) ? "" : fileName.substring(dotIndex + 1);
}
}
149 changes: 126 additions & 23 deletions src/main/java/net/minecraftforge/gradle/common/BasePlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.List;
import java.util.function.Function;

import net.minecraftforge.gradle.FileLogListenner;
import net.minecraftforge.gradle.common.version.AssetIndex;
Expand All @@ -14,10 +18,13 @@
import net.minecraftforge.gradle.delayed.DelayedFile;
import net.minecraftforge.gradle.delayed.DelayedFileTree;
import net.minecraftforge.gradle.delayed.DelayedString;
import net.minecraftforge.gradle.json.MCVersionManifest;
import net.minecraftforge.gradle.json.version.VersionToString;
import net.minecraftforge.gradle.tasks.DownloadAssetsTask;
import net.minecraftforge.gradle.tasks.ObtainFernFlowerTask;
import net.minecraftforge.gradle.tasks.abstractutil.DownloadTask;

import net.minecraftforge.gradle.tasks.abstractutil.EtagDownloadTask;
import org.gradle.api.Action;
import org.gradle.api.DefaultTask;
import org.gradle.api.Plugin;
Expand Down Expand Up @@ -129,48 +136,144 @@ private void makeObtainTasks()
// download tasks
DownloadTask task;

EtagDownloadTask etagDlTask;
etagDlTask = makeTask("getVersionJsonIndex", EtagDownloadTask.class);
{
etagDlTask.setUri(delayedString(Constants.MC_JSON_INDEX_URL));
etagDlTask.setFile(delayedFile(Constants.VERSION_JSON_INDEX));
etagDlTask.setDieWithError(false);
}

etagDlTask = makeTask("getVersionJson", EtagDownloadTask.class);
{
class GetVersionJsonUrl extends DelayedString {
public GetVersionJsonUrl() {
super(BasePlugin.this.project, "");
}

@Override
public String call() {
try {
MCVersionManifest manifest = JsonFactory.loadMCVersionManifest(delayedFile(Constants.VERSION_JSON_INDEX).call());
MCVersionManifest.Version version = manifest.findVersion(delayedString("{MC_VERSION}").call());
return version.url;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
etagDlTask.dependsOn("getVersionJsonIndex");
etagDlTask.getInputs().file(delayedFile(Constants.VERSION_JSON_INDEX));
etagDlTask.setUri(new GetVersionJsonUrl());
etagDlTask.setFile(delayedFile(Constants.VERSION_JSON));
etagDlTask.setDieWithError(false);
//TODO: this is not necessary?
etagDlTask.doLast(new Action<Task>() { // normalizes to linux endings
@Override
public void execute(Task task) {
try {
File json = delayedFile(Constants.VERSION_JSON).call();
if (!json.exists())
return;

List<String> lines = Files.readAllLines(json.toPath());
StringBuilder buf = new StringBuilder();
for (String line : lines) {
buf.append(line).append('\n');
}
Files.write(json.toPath(), buf.toString().getBytes(StandardCharsets.UTF_8));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
});
}

class GetDataFromJson extends DelayedString {
private final VersionToString function;

public GetDataFromJson(VersionToString function) {
super(BasePlugin.this.project, "");
this.function = function;
}

@Override
public String call() {
try {
Version manifest = JsonFactory.loadVersion(delayedFile(Constants.VERSION_JSON).call());
return function.apply(manifest);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

task = makeTask("downloadClient", DownloadTask.class);
{
task.getInputs().file(delayedFile(Constants.VERSION_JSON));
task.dependsOn("getVersionJson");

task.setOutput(delayedFile(Constants.JAR_CLIENT_FRESH));
task.setUrl(delayedString(Constants.MC_JAR_URL));
task.setUrl(new GetDataFromJson(new VersionToString() {
@Override
public String apply(Version json) {
return json.downloads.client.url;
}
}));


}

task = makeTask("downloadServer", DownloadTask.class);
{
task.getInputs().file(delayedFile(Constants.VERSION_JSON));
task.dependsOn("getVersionJson");

task.setOutput(delayedFile(Constants.JAR_SERVER_FRESH));
task.setUrl(delayedString(Constants.MC_SERVER_URL));
task.setUrl(new GetDataFromJson(new VersionToString() {
@Override
public String apply(Version json) {
return json.downloads.server.url;
}
}));


}

ObtainFernFlowerTask mcpTask = makeTask("downloadMcpTools", ObtainFernFlowerTask.class);
{
mcpTask.setMcpUrl(delayedString(Constants.MCP_URL));
mcpTask.setFfJar(delayedFile(Constants.FERNFLOWER));
}
DownloadTask getAssetsIndex = makeTask("getAssetsIndex", DownloadTask.class);

etagDlTask = makeTask("getAssetsIndex", EtagDownloadTask.class);
{
getAssetsIndex.setUrl(delayedString(Constants.ASSETS_INDEX_URL));
getAssetsIndex.setOutput(delayedFile(Constants.ASSETS + "/indexes/{ASSET_INDEX}.json"));
getAssetsIndex.setDoesCache(false);
etagDlTask.getInputs().file(delayedFile(Constants.VERSION_JSON));
etagDlTask.dependsOn("getVersionJson");

getAssetsIndex.doLast(new Action<Task>() {
public void execute(Task task)
{
try
{
etagDlTask.setUrl(new GetDataFromJson(new VersionToString() {
@Override
public String apply(Version json) {
return json.assetIndex.url;
}
}));


etagDlTask.setFile(delayedFile(Constants.ASSETS + "/indexes/{ASSET_INDEX}.json"));
etagDlTask.setDieWithError(false);

etagDlTask.doLast(new Action<Task>() {
@Override
public void execute(Task task1) {
try {
parseAssetIndex();
} catch (JsonSyntaxException e) {
throw new RuntimeException(e);
} catch (JsonIOException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
catch (Exception e)
{
Throwables.propagate(e);
}
}
});

getAssetsIndex.getOutputs().upToDateWhen(new Closure<Boolean>(this, null) {
public Boolean call(Object... obj)
{
return false;
}
});
}
Expand Down
15 changes: 11 additions & 4 deletions src/main/java/net/minecraftforge/gradle/common/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ public String toString()
public static final OperatingSystem OPERATING_SYSTEM = getOs();
public static final SystemArch SYSTEM_ARCH = getArch();

public static final String HASH_FUNC = "MD5";
public static final String USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11";
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not run code formatters over existing code.
It makes your entire change set a pain to actually read/understand

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I formatted it on a whim, do I need to undo it?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, code changes should be actual changes not formatting. It makes it a pain to see what you actually changed.


// extension nam
public static final String EXT_NAME_MC = "minecraft";
public static final String EXT_NAME_JENKINS = "jenkins";
Expand All @@ -60,12 +63,13 @@ public String toString()
public static final Closure<Boolean> CALL_FALSE = new Closure<Boolean>(null){ public Boolean call(Object o){ return false; }};

// urls
public static final String MC_JAR_URL = "http://s3.amazonaws.com/Minecraft.Download/versions/{MC_VERSION}/{MC_VERSION}.jar";
public static final String MC_SERVER_URL = "http://s3.amazonaws.com/Minecraft.Download/versions/{MC_VERSION}/minecraft_server.{MC_VERSION}.jar";
public static final String MCP_URL = "http://files.minecraftforge.net/fernflower_temporary.zip";
public static final String ASSETS_URL = "http://resources.download.minecraft.net";
public static final String MC_JAR_URL = "https://s3.amazonaws.com/Minecraft.Download/versions/{MC_VERSION}/{MC_VERSION}.jar";
public static final String MC_SERVER_URL = "https://s3.amazonaws.com/Minecraft.Download/versions/{MC_VERSION}/minecraft_server.{MC_VERSION}.jar";
public static final String MCP_URL = "https://files.minecraftforge.net/fernflower_temporary.zip";
public static final String ASSETS_URL = "https://resources.download.minecraft.net";
public static final String LIBRARY_URL = "https://libraries.minecraft.net/";
public static final String ASSETS_INDEX_URL = "https://s3.amazonaws.com/Minecraft.Download/indexes/{ASSET_INDEX}.json";
public static final String MC_JSON_INDEX_URL = "https://piston-meta.mojang.com/mc/game/version_manifest.json";

public static final String LOG = ".gradle/gradle.log";
public static final String ASSETS_INDEX = "legacy";
Expand All @@ -77,6 +81,9 @@ public String toString()
public static final String FERNFLOWER = "{CACHE_DIR}/minecraft/fernflower.jar";
public static final String EXCEPTOR = "{CACHE_DIR}/minecraft/exceptor.jar";
public static final String ASSETS = "{CACHE_DIR}/minecraft/assets";
public static final String JSONS_DIR = "{CACHE_DIR}/minecraft/versionJsons";
public static final String VERSION_JSON_INDEX = JSONS_DIR + "/index.json";
public static final String VERSION_JSON = JSONS_DIR + "/{MC_VERSION}.json";

public static final String DEOBF_JAR = "{BUILD_DIR}/deobfuscated.jar";
public static final String DEOBF_BIN_JAR = "{BUILD_DIR}/deobfuscated-bin.jar";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.List;

import net.minecraftforge.gradle.common.Constants;
import net.minecraftforge.gradle.json.version.Downloads;

public class Version
{
Expand All @@ -19,6 +20,8 @@ public class Version
public String incompatibilityReason;
private String assets;
public List<OSRule> rules;
public Downloads downloads;
public Downloads.DownloadFileInfo assetIndex;

private List<Library> _libraries;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import com.google.gson.GsonBuilder;
import com.google.gson.JsonIOException;
import com.google.gson.JsonSyntaxException;
import net.minecraftforge.gradle.json.MCVersionManifest;

public class JsonFactory
{
Expand Down Expand Up @@ -43,4 +44,11 @@ public static AssetIndex loadAssetsIndex(File json) throws JsonSyntaxException,
reader.close();
return a;
}

public static MCVersionManifest loadMCVersionManifest(File json) throws JsonSyntaxException, JsonIOException, IOException {
FileReader reader = new FileReader(json);
MCVersionManifest a = GSON.fromJson(reader, MCVersionManifest.class);
reader.close();
return a;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package net.minecraftforge.gradle.json;

import java.util.Date;
import java.util.List;

// format of https://piston-meta.mojang.com/mc/game/version_manifest.json
public class MCVersionManifest {
public LatestInfo latest;
public List<Version> versions;

public Version findVersion(String versionId) {
for (Version v : versions) {
if (versionId.equals(v.id)) {
return v;
}
}
throw new IllegalArgumentException(versionId + " not found");
}

public static class LatestInfo {
public String release;
public String snapshot;
}

public static class Version {
public String id;
public String type;
public String url;
public Date time;
public Date releaseTime;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package net.minecraftforge.gradle.json.version;


public class Downloads {
public DownloadFileInfo client;
public DownloadFileInfo server;
public DownloadFileInfo windows_server;

public static class DownloadFileInfo {
public String sha1;
public long size;
public String url;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package net.minecraftforge.gradle.json.version;

import net.minecraftforge.gradle.common.version.Version;

public interface VersionToString {
String apply(Version version);
}
Loading