mirror of
https://github.com/architectury/architectury-loom.git
synced 2026-04-02 05:27:43 -05:00
Start work on porting 0.7.4 over
Signed-off-by: shedaniel <daniel@shedaniel.me>
This commit is contained in:
@@ -122,6 +122,16 @@ public interface LoomGradleExtension extends LoomGradleExtensionAPI {
|
||||
return getDependencyManager().getProvider(McpConfigProvider.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean isForgeAndOfficial() {
|
||||
return isForge() && getMcpConfigProvider().isOfficial();
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean isForgeAndNotOfficial() {
|
||||
return isForge() && !getMcpConfigProvider().isOfficial();
|
||||
}
|
||||
|
||||
default SrgProvider getSrgProvider() {
|
||||
return getDependencyManager().getProvider(SrgProvider.class);
|
||||
}
|
||||
|
||||
@@ -195,6 +195,10 @@ public interface LoomGradleExtensionAPI {
|
||||
return getPlatform().get() == ModPlatform.FORGE;
|
||||
}
|
||||
|
||||
boolean isForgeAndOfficial();
|
||||
|
||||
boolean isForgeAndNotOfficial();
|
||||
|
||||
boolean supportsInclude();
|
||||
|
||||
void setGenerateSrgTiny(Boolean generateSrgTiny);
|
||||
|
||||
@@ -83,8 +83,9 @@ public final class CompileConfiguration {
|
||||
extension.createLazyConfiguration(Constants.Configurations.FORGE_USERDEV).configure(configuration -> configuration.setTransitive(false));
|
||||
extension.createLazyConfiguration(Constants.Configurations.FORGE_INSTALLER).configure(configuration -> configuration.setTransitive(false));
|
||||
extension.createLazyConfiguration(Constants.Configurations.FORGE_UNIVERSAL).configure(configuration -> configuration.setTransitive(false));
|
||||
extension.createLazyConfiguration(Constants.Configurations.FORGE_DEPENDENCIES).configure(configuration -> configuration.setTransitive(false));
|
||||
extension.createLazyConfiguration(Constants.Configurations.FORGE_DEPENDENCIES);
|
||||
extension.createLazyConfiguration(Constants.Configurations.FORGE_NAMED).configure(configuration -> configuration.setTransitive(false));
|
||||
extension.createLazyConfiguration(Constants.Configurations.FORGE_EXTRA).configure(configuration -> configuration.setTransitive(false));
|
||||
extension.createLazyConfiguration(Constants.Configurations.MCP_CONFIG).configure(configuration -> configuration.setTransitive(false));
|
||||
|
||||
extendsFrom(Constants.Configurations.MINECRAFT_DEPENDENCIES, Constants.Configurations.FORGE_DEPENDENCIES, project);
|
||||
@@ -93,6 +94,10 @@ public final class CompileConfiguration {
|
||||
extendsFrom(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME, Constants.Configurations.FORGE_NAMED, project);
|
||||
extendsFrom(JavaPlugin.TEST_COMPILE_CLASSPATH_CONFIGURATION_NAME, Constants.Configurations.FORGE_NAMED, project);
|
||||
extendsFrom(JavaPlugin.TEST_RUNTIME_CLASSPATH_CONFIGURATION_NAME, Constants.Configurations.FORGE_NAMED, project);
|
||||
extendsFrom(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME, Constants.Configurations.FORGE_EXTRA, project);
|
||||
extendsFrom(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME, Constants.Configurations.FORGE_EXTRA, project);
|
||||
extendsFrom(JavaPlugin.TEST_COMPILE_CLASSPATH_CONFIGURATION_NAME, Constants.Configurations.FORGE_EXTRA, project);
|
||||
extendsFrom(JavaPlugin.TEST_RUNTIME_CLASSPATH_CONFIGURATION_NAME, Constants.Configurations.FORGE_EXTRA, project);
|
||||
}
|
||||
|
||||
if (extension.supportsInclude()) {
|
||||
|
||||
@@ -24,21 +24,15 @@
|
||||
|
||||
package net.fabricmc.loom.configuration.ide;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
@@ -132,23 +126,6 @@ public class RunConfig {
|
||||
|
||||
runConfig.mainClass = "net.fabricmc.devlaunchinjector.Main";
|
||||
runConfig.vmArgs = "-Dfabric.dli.config=" + encodeEscaped(extension.getFiles().getDevLauncherConfig().getAbsolutePath()) + " -Dfabric.dli.env=" + environment.toLowerCase();
|
||||
|
||||
if (extension.isForge()) {
|
||||
List<String> modClasses = new ArrayList<>();
|
||||
|
||||
for (Supplier<SourceSet> sourceSetSupplier : extension.getForgeLocalMods()) {
|
||||
SourceSet sourceSet = sourceSetSupplier.get();
|
||||
String sourceSetName = sourceSet.getName() + "_" + UUID.randomUUID().toString().replace("-", "").substring(0, 7);
|
||||
|
||||
Stream.concat(
|
||||
Stream.of(sourceSet.getOutput().getResourcesDir().getAbsolutePath()),
|
||||
StreamSupport.stream(sourceSet.getOutput().getClassesDirs().spliterator(), false)
|
||||
.map(File::getAbsolutePath)
|
||||
).map(s -> sourceSetName + "%%" + s).collect(Collectors.toCollection(() -> modClasses));
|
||||
}
|
||||
|
||||
runConfig.envVariables.put("MOD_CLASSES", String.join(File.pathSeparator, modClasses));
|
||||
}
|
||||
}
|
||||
|
||||
// Turns camelCase/PascalCase into Capital Case
|
||||
@@ -162,6 +139,7 @@ public class RunConfig {
|
||||
}
|
||||
|
||||
public static RunConfig runConfig(Project project, RunConfigSettings settings) {
|
||||
settings.evaluateNow();
|
||||
LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||
String name = settings.getName();
|
||||
|
||||
@@ -195,6 +173,7 @@ public class RunConfig {
|
||||
}
|
||||
|
||||
RunConfig runConfig = new RunConfig();
|
||||
runConfig.envVariables.putAll(settings.envVariables);
|
||||
runConfig.configName = configName;
|
||||
populate(project, extension, runConfig, environment);
|
||||
runConfig.ideaModuleName = getIdeaModuleName(project, sourceSet);
|
||||
|
||||
@@ -28,6 +28,7 @@ import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
@@ -36,6 +37,7 @@ import org.gradle.api.Named;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.plugins.JavaPluginConvention;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.util.Constants;
|
||||
@@ -96,6 +98,8 @@ public final class RunConfigSettings implements Named {
|
||||
|
||||
private final Project project;
|
||||
private final LoomGradleExtension extension;
|
||||
public final Map<String, String> envVariables = new HashMap<>();
|
||||
private List<Runnable> evaluateLater = new ArrayList<>();
|
||||
|
||||
public RunConfigSettings(Project project, String baseName) {
|
||||
this.baseName = baseName;
|
||||
@@ -107,6 +111,20 @@ public final class RunConfigSettings implements Named {
|
||||
runDir("run");
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public void evaluateLater(Runnable runnable) {
|
||||
this.evaluateLater.add(runnable);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public void evaluateNow() {
|
||||
for (Runnable runnable : this.evaluateLater) {
|
||||
runnable.run();
|
||||
}
|
||||
|
||||
this.evaluateLater.clear();
|
||||
}
|
||||
|
||||
public Project getProject() {
|
||||
return project;
|
||||
}
|
||||
|
||||
@@ -46,13 +46,13 @@ public class SetupIntelijRunConfigs {
|
||||
}
|
||||
|
||||
try {
|
||||
generate(project);
|
||||
generate(project, false);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Failed to generate run configs", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void generate(Project project) throws IOException {
|
||||
public static void generate(Project project, boolean override) throws IOException {
|
||||
Project rootProject = project.getRootProject();
|
||||
LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||
|
||||
@@ -82,6 +82,10 @@ public class SetupIntelijRunConfigs {
|
||||
File runConfigs = new File(runConfigsDir, name + projectPath + ".xml");
|
||||
String runConfigXml = config.fromDummy("idea_run_config_template.xml");
|
||||
|
||||
if (runConfigs.exists() && override) {
|
||||
runConfigs.delete();
|
||||
}
|
||||
|
||||
if (!runConfigs.exists()) {
|
||||
FileUtils.writeStringToFile(runConfigs, runConfigXml, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
@@ -33,11 +33,13 @@ import java.util.Map;
|
||||
|
||||
import org.gradle.api.Named;
|
||||
import org.gradle.api.Project;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
public class LaunchProviderSettings implements Named {
|
||||
private final String name;
|
||||
private List<Map.Entry<String, String>> properties = new ArrayList<>();
|
||||
private List<String> arguments = new ArrayList<>();
|
||||
private List<Runnable> evaluateLater = new ArrayList<>();
|
||||
|
||||
public LaunchProviderSettings(Project project, String name) {
|
||||
this.name = name;
|
||||
@@ -48,6 +50,20 @@ public class LaunchProviderSettings implements Named {
|
||||
return name;
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public void evaluateLater(Runnable runnable) {
|
||||
this.evaluateLater.add(runnable);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public void evaluateNow() {
|
||||
for (Runnable runnable : this.evaluateLater) {
|
||||
runnable.run();
|
||||
}
|
||||
|
||||
this.evaluateLater.clear();
|
||||
}
|
||||
|
||||
public void arg(String argument) {
|
||||
this.arguments.add(argument);
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ public class ModProcessor {
|
||||
|
||||
remapper.readClassPathAsync(mc);
|
||||
|
||||
if (extension.isForge()) {
|
||||
if (extension.isForgeAndNotOfficial()) {
|
||||
remapper.readClassPathAsync(mappedProvider.getForgeSrgJar().toPath());
|
||||
}
|
||||
|
||||
|
||||
@@ -60,31 +60,21 @@ public class LaunchProvider extends DependencyProvider {
|
||||
.property("log4j.configurationFile", getAllLog4JConfigFiles())
|
||||
|
||||
.property("client", "java.library.path", getExtension().getMinecraftProvider().nativesDir().getAbsolutePath())
|
||||
.property("client", "org.lwjgl.librarypath", getExtension().getMinecraftProvider().nativesDir().getAbsolutePath())
|
||||
.property("client", "org.lwjgl.librarypath", getExtension().getMinecraftProvider().nativesDir().getAbsolutePath());
|
||||
|
||||
.argument("client", "--assetIndex")
|
||||
.argument("client", getExtension().getMinecraftProvider().getVersionInfo().assetIndex().fabricId(getExtension().getMinecraftProvider().minecraftVersion()))
|
||||
.argument("client", "--assetsDir")
|
||||
.argument("client", new File(getDirectories().getUserCache(), "assets").getAbsolutePath());
|
||||
if (!getExtension().isForge()) {
|
||||
launchConfig
|
||||
.argument("client", "--assetIndex")
|
||||
.argument("client", getExtension().getMinecraftProvider().getVersionInfo().assetIndex().fabricId(getExtension().getMinecraftProvider().minecraftVersion()))
|
||||
.argument("client", "--assetsDir")
|
||||
.argument("client", new File(getDirectories().getUserCache(), "assets").getAbsolutePath());
|
||||
}
|
||||
|
||||
if (getExtension().isForge()) {
|
||||
launchConfig
|
||||
// Should match YarnNamingService.PATH_TO_MAPPINGS in forge-runtime
|
||||
.property("fabric.yarnWithSrg.path", getExtension().getMappingsProvider().tinyMappingsWithSrg.toAbsolutePath().toString())
|
||||
|
||||
.argument("--fml.mcVersion")
|
||||
.argument(getExtension().getMinecraftProvider().minecraftVersion())
|
||||
.argument("--fml.forgeVersion")
|
||||
.argument(getExtension().getForgeProvider().getVersion().getForgeVersion())
|
||||
|
||||
.argument("client", "--launchTarget")
|
||||
.argument("client", "fmluserdevclient")
|
||||
|
||||
.argument("server", "--launchTarget")
|
||||
.argument("server", "fmluserdevserver")
|
||||
|
||||
.argument("data", "--launchTarget")
|
||||
.argument("data", "fmluserdevdata")
|
||||
.argument("data", "--all")
|
||||
.argument("data", "--mod")
|
||||
.argument("data", String.join(",", getExtension().getDataGenMods()))
|
||||
@@ -109,7 +99,18 @@ public class LaunchProvider extends DependencyProvider {
|
||||
}
|
||||
}
|
||||
|
||||
addDependency(Constants.Dependencies.DEV_LAUNCH_INJECTOR + Constants.Dependencies.Versions.DEV_LAUNCH_INJECTOR, Constants.Configurations.LOOM_DEVELOPMENT_DEPENDENCIES);
|
||||
addDependency(Constants.Dependencies.TERMINAL_CONSOLE_APPENDER + Constants.Dependencies.Versions.TERMINAL_CONSOLE_APPENDER, Constants.Configurations.LOOM_DEVELOPMENT_DEPENDENCIES);
|
||||
addDependency(Constants.Dependencies.JETBRAINS_ANNOTATIONS + Constants.Dependencies.Versions.JETBRAINS_ANNOTATIONS, JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME);
|
||||
|
||||
if (getExtension().isForge()) {
|
||||
addDependency(Constants.Dependencies.FORGE_RUNTIME + Constants.Dependencies.Versions.FORGE_RUNTIME, Constants.Configurations.FORGE_EXTRA);
|
||||
addDependency(Constants.Dependencies.JAVAX_ANNOTATIONS + Constants.Dependencies.Versions.JAVAX_ANNOTATIONS, JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME);
|
||||
}
|
||||
|
||||
for (LaunchProviderSettings settings : getExtension().getLaunchConfigs()) {
|
||||
settings.evaluateNow();
|
||||
|
||||
for (String argument : settings.getArguments()) {
|
||||
launchConfig.argument(settings.getName(), argument);
|
||||
}
|
||||
@@ -129,16 +130,6 @@ public class LaunchProvider extends DependencyProvider {
|
||||
writeLog4jConfig();
|
||||
FileUtils.writeStringToFile(getDirectories().getDevLauncherConfig(), launchConfig.asString(), StandardCharsets.UTF_8);
|
||||
|
||||
addDependency(Constants.Dependencies.DEV_LAUNCH_INJECTOR + Constants.Dependencies.Versions.DEV_LAUNCH_INJECTOR, Constants.Configurations.LOOM_DEVELOPMENT_DEPENDENCIES);
|
||||
addDependency(Constants.Dependencies.TERMINAL_CONSOLE_APPENDER + Constants.Dependencies.Versions.TERMINAL_CONSOLE_APPENDER, Constants.Configurations.LOOM_DEVELOPMENT_DEPENDENCIES);
|
||||
addDependency(Constants.Dependencies.JETBRAINS_ANNOTATIONS + Constants.Dependencies.Versions.JETBRAINS_ANNOTATIONS, JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME);
|
||||
|
||||
if (getExtension().isForge()) {
|
||||
addDependency(Constants.Dependencies.FORGE_RUNTIME + Constants.Dependencies.Versions.FORGE_RUNTIME, JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME);
|
||||
addDependency(Constants.Dependencies.FORGE_RUNTIME + Constants.Dependencies.Versions.FORGE_RUNTIME, JavaPlugin.RUNTIME_ONLY_CONFIGURATION_NAME);
|
||||
addDependency(Constants.Dependencies.JAVAX_ANNOTATIONS + Constants.Dependencies.Versions.JAVAX_ANNOTATIONS, JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME);
|
||||
}
|
||||
|
||||
postPopulationScheduler.accept(this::writeRemapClassPath);
|
||||
}
|
||||
|
||||
@@ -178,7 +169,7 @@ public class LaunchProvider extends DependencyProvider {
|
||||
|
||||
remapClasspath.add(getExtension().getMinecraftMappedProvider().getIntermediaryJar());
|
||||
|
||||
if (getExtension().isForge()) {
|
||||
if (getExtension().isForgeAndNotOfficial()) {
|
||||
remapClasspath.add(getExtension().getMinecraftMappedProvider().getForgeIntermediaryJar());
|
||||
}
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ public class FieldMigratedMappingsProvider extends MappingsProviderImpl {
|
||||
|
||||
@Override
|
||||
protected String createMappingsIdentifier(String mappingsName, String version, String classifier) {
|
||||
return super.createMappingsIdentifier(mappingsName, version, classifier) + "-forge-" + getExtension().getPatchProvider().forgeVersion;
|
||||
return super.createMappingsIdentifier(mappingsName, version, classifier) + "-forge-" + getExtension().getForgeProvider().getVersion().getCombined();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -116,7 +116,7 @@ public class FieldMigratedMappingsProvider extends MappingsProviderImpl {
|
||||
if (getExtension().shouldGenerateSrgTiny()) {
|
||||
if (Files.notExists(rawTinyMappingsWithSrg) || isRefreshDeps()) {
|
||||
// Merge tiny mappings with srg
|
||||
SrgMerger.mergeSrg(getExtension().getSrgProvider().getSrg().toPath(), rawTinyMappings, rawTinyMappingsWithSrg, true);
|
||||
SrgMerger.mergeSrg(this::getMojmapSrgFileIfPossible, getRawSrgFile(), rawTinyMappings, rawTinyMappingsWithSrg, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,10 +55,13 @@ public class ForgeProvider extends DependencyProvider {
|
||||
}
|
||||
|
||||
public static final class ForgeVersion {
|
||||
private final String combined;
|
||||
private final String minecraftVersion;
|
||||
private final String forgeVersion;
|
||||
|
||||
public ForgeVersion(String combined) {
|
||||
this.combined = combined;
|
||||
|
||||
if (combined == null) {
|
||||
this.minecraftVersion = "NO_VERSION";
|
||||
this.forgeVersion = "NO_VERSION";
|
||||
@@ -76,6 +79,10 @@ public class ForgeProvider extends DependencyProvider {
|
||||
}
|
||||
}
|
||||
|
||||
public String getCombined() {
|
||||
return combined;
|
||||
}
|
||||
|
||||
public String getMinecraftVersion() {
|
||||
return minecraftVersion;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
package net.fabricmc.loom.configuration.providers.forge;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.net.URI;
|
||||
import java.nio.file.FileSystem;
|
||||
@@ -32,19 +33,46 @@ import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.artifacts.Dependency;
|
||||
import org.gradle.api.artifacts.ModuleDependency;
|
||||
import org.gradle.api.artifacts.transform.InputArtifact;
|
||||
import org.gradle.api.artifacts.transform.TransformAction;
|
||||
import org.gradle.api.artifacts.transform.TransformOutputs;
|
||||
import org.gradle.api.artifacts.transform.TransformParameters;
|
||||
import org.gradle.api.artifacts.type.ArtifactTypeDefinition;
|
||||
import org.gradle.api.attributes.Attribute;
|
||||
import org.gradle.api.file.FileSystemLocation;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
|
||||
import net.fabricmc.loom.configuration.DependencyProvider;
|
||||
import net.fabricmc.loom.configuration.ide.RunConfigSettings;
|
||||
import net.fabricmc.loom.configuration.launch.LaunchProviderSettings;
|
||||
import net.fabricmc.loom.util.Constants;
|
||||
import net.fabricmc.loom.util.DependencyDownloader;
|
||||
import net.fabricmc.loom.util.FileSystemUtil;
|
||||
|
||||
public class ForgeUserdevProvider extends DependencyProvider {
|
||||
private File userdevJar;
|
||||
private JsonObject json;
|
||||
private Consumer<Runnable> postPopulationScheduler;
|
||||
|
||||
public ForgeUserdevProvider(Project project) {
|
||||
super(project);
|
||||
@@ -52,6 +80,18 @@ public class ForgeUserdevProvider extends DependencyProvider {
|
||||
|
||||
@Override
|
||||
public void provide(DependencyInfo dependency, Consumer<Runnable> postPopulationScheduler) throws Exception {
|
||||
this.postPopulationScheduler = postPopulationScheduler;
|
||||
Attribute<Boolean> transformed = Attribute.of("architectury-loom-forge-dependencies-transformed", Boolean.class);
|
||||
|
||||
getProject().getDependencies().registerTransform(RemoveNameProvider.class, spec -> {
|
||||
spec.getFrom().attribute(transformed, false);
|
||||
spec.getTo().attribute(transformed, true);
|
||||
});
|
||||
|
||||
for (ArtifactTypeDefinition type : getProject().getDependencies().getArtifactTypes()) {
|
||||
type.getAttributes().attribute(transformed, false);
|
||||
}
|
||||
|
||||
userdevJar = new File(getDirectories().getProjectPersistentCache(), "forge-" + dependency.getDependency().getVersion() + "-userdev.jar");
|
||||
|
||||
Path configJson = getDirectories()
|
||||
@@ -68,8 +108,6 @@ public class ForgeUserdevProvider extends DependencyProvider {
|
||||
}
|
||||
}
|
||||
|
||||
JsonObject json;
|
||||
|
||||
try (Reader reader = Files.newBufferedReader(configJson)) {
|
||||
json = new Gson().fromJson(reader, JsonObject.class);
|
||||
}
|
||||
@@ -79,19 +117,199 @@ public class ForgeUserdevProvider extends DependencyProvider {
|
||||
addDependency(json.get("universal").getAsString(), Constants.Configurations.FORGE_UNIVERSAL);
|
||||
|
||||
for (JsonElement lib : json.get("libraries").getAsJsonArray()) {
|
||||
Dependency dep = null;
|
||||
|
||||
if (lib.getAsString().startsWith("org.spongepowered:mixin:")) {
|
||||
if (getExtension().isUseFabricMixin()) {
|
||||
addDependency("net.fabricmc:sponge-mixin:0.8.2+build.24", Constants.Configurations.FORGE_DEPENDENCIES);
|
||||
continue;
|
||||
dep = addDependency("net.fabricmc:sponge-mixin:0.8.2+build.24", Constants.Configurations.FORGE_DEPENDENCIES);
|
||||
}
|
||||
}
|
||||
|
||||
addDependency(lib.getAsString(), Constants.Configurations.FORGE_DEPENDENCIES);
|
||||
if (dep == null) {
|
||||
dep = addDependency(lib.getAsString(), Constants.Configurations.FORGE_DEPENDENCIES);
|
||||
}
|
||||
|
||||
if (lib.getAsString().split(":").length < 4) {
|
||||
((ModuleDependency) dep).attributes(attributes -> {
|
||||
attributes.attribute(transformed, true);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Read launch configs from the JSON too
|
||||
// TODO: Should I copy the patches from here as well?
|
||||
// That'd require me to run the "MCP environment" fully up to merging.
|
||||
for (Map.Entry<String, JsonElement> entry : json.getAsJsonObject("runs").entrySet()) {
|
||||
LaunchProviderSettings launchSettings = getExtension().getLaunchConfigs().findByName(entry.getKey());
|
||||
RunConfigSettings settings = getExtension().getRunConfigs().findByName(entry.getKey());
|
||||
JsonObject value = entry.getValue().getAsJsonObject();
|
||||
|
||||
if (launchSettings != null) {
|
||||
launchSettings.evaluateLater(() -> {
|
||||
if (value.has("args")) {
|
||||
launchSettings.arg(StreamSupport.stream(value.getAsJsonArray("args").spliterator(), false)
|
||||
.map(JsonElement::getAsString)
|
||||
.map(this::processTemplates)
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
if (value.has("props")) {
|
||||
for (Map.Entry<String, JsonElement> props : value.getAsJsonObject("props").entrySet()) {
|
||||
String string = processTemplates(props.getValue().getAsString());
|
||||
|
||||
launchSettings.property(props.getKey(), string);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (settings != null) {
|
||||
settings.evaluateLater(() -> {
|
||||
settings.defaultMainClass(value.getAsJsonPrimitive("main").getAsString());
|
||||
settings.vmArgs(StreamSupport.stream(value.getAsJsonArray("jvmArgs").spliterator(), false)
|
||||
.map(JsonElement::getAsString)
|
||||
.map(this::processTemplates)
|
||||
.collect(Collectors.toList()));
|
||||
for (Map.Entry<String, JsonElement> env : value.getAsJsonObject("env").entrySet()) {
|
||||
String string = processTemplates(env.getValue().getAsString());
|
||||
|
||||
settings.envVariables.put(env.getKey(), string);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class RemoveNameProvider implements TransformAction<TransformParameters.None> {
|
||||
@InputArtifact
|
||||
public abstract Provider<FileSystemLocation> getInput();
|
||||
|
||||
@Override
|
||||
public void transform(TransformOutputs outputs) {
|
||||
try {
|
||||
File input = getInput().get().getAsFile();
|
||||
//architectury-loom-forge-dependencies-transformed
|
||||
File output = outputs.file(input.getName() + "-alfd-transformed.jar");
|
||||
Files.copy(input.toPath(), output.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
|
||||
try (FileSystemUtil.FileSystemDelegate fs = FileSystemUtil.getJarFileSystem(output, false)) {
|
||||
Path path = fs.get().getPath("META-INF/services/cpw.mods.modlauncher.api.INameMappingService");
|
||||
Files.deleteIfExists(path);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String processTemplates(String string) {
|
||||
if (string.startsWith("{")) {
|
||||
String key = string.substring(1, string.length() - 1);
|
||||
|
||||
// TODO: Look into ways to not hardcode
|
||||
if (key.equals("runtime_classpath")) {
|
||||
string = runtimeClasspath().stream()
|
||||
.map(File::getAbsolutePath)
|
||||
.collect(Collectors.joining(File.pathSeparator));
|
||||
} else if (key.equals("minecraft_classpath")) {
|
||||
string = minecraftClasspath().stream()
|
||||
.map(File::getAbsolutePath)
|
||||
.collect(Collectors.joining(File.pathSeparator));
|
||||
} else if (key.equals("runtime_classpath_file")) {
|
||||
Path path = getDirectories().getProjectPersistentCache().toPath().resolve("forge_runtime_classpath.txt");
|
||||
|
||||
postPopulationScheduler.accept(() -> {
|
||||
try {
|
||||
Files.writeString(path, runtimeClasspath().stream()
|
||||
.map(File::getAbsolutePath)
|
||||
.collect(Collectors.joining("\n")),
|
||||
StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
|
||||
string = path.toAbsolutePath().toString();
|
||||
} else if (key.equals("minecraft_classpath_file")) {
|
||||
Path path = getDirectories().getProjectPersistentCache().toPath().resolve("forge_minecraft_classpath.txt");
|
||||
|
||||
postPopulationScheduler.accept(() -> {
|
||||
try {
|
||||
Files.writeString(path, minecraftClasspath().stream()
|
||||
.map(File::getAbsolutePath)
|
||||
.collect(Collectors.joining("\n")),
|
||||
StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
|
||||
string = path.toAbsolutePath().toString();
|
||||
} else if (key.equals("asset_index")) {
|
||||
string = getExtension().getMinecraftProvider().getVersionInfo().assetIndex().fabricId(getExtension().getMinecraftProvider().minecraftVersion());
|
||||
} else if (key.equals("assets_root")) {
|
||||
string = new File(getDirectories().getUserCache(), "assets").getAbsolutePath();
|
||||
} else if (key.equals("natives")) {
|
||||
string = getMinecraftProvider().nativesDir().getAbsolutePath();
|
||||
} else if (key.equals("source_roots")) {
|
||||
List<String> modClasses = new ArrayList<>();
|
||||
|
||||
for (Supplier<SourceSet> sourceSetSupplier : getExtension().getForgeLocalMods()) {
|
||||
SourceSet sourceSet = sourceSetSupplier.get();
|
||||
String sourceSetName = sourceSet.getName() + "_" + UUID.randomUUID().toString().replace("-", "").substring(0, 7);
|
||||
|
||||
Stream.concat(
|
||||
Stream.of(sourceSet.getOutput().getResourcesDir().getAbsolutePath()),
|
||||
StreamSupport.stream(sourceSet.getOutput().getClassesDirs().spliterator(), false)
|
||||
.map(File::getAbsolutePath)
|
||||
).map(s -> sourceSetName + "%%" + s).collect(Collectors.toCollection(() -> modClasses));
|
||||
}
|
||||
|
||||
string = String.join(File.pathSeparator, modClasses);
|
||||
} else if (json.has(key)) {
|
||||
JsonElement element = json.get(key);
|
||||
|
||||
if (element.isJsonArray()) {
|
||||
string = StreamSupport.stream(element.getAsJsonArray().spliterator(), false)
|
||||
.map(JsonElement::getAsString)
|
||||
.flatMap(str -> {
|
||||
if (str.contains(":")) {
|
||||
return DependencyDownloader.download(getProject(), str, false, false).getFiles().stream()
|
||||
.map(File::getAbsolutePath)
|
||||
.filter(dep -> !dep.contains("bootstraplauncher")); // TODO: Hack
|
||||
}
|
||||
|
||||
return Stream.of(str);
|
||||
})
|
||||
.collect(Collectors.joining(File.pathSeparator));
|
||||
} else {
|
||||
string = element.toString();
|
||||
}
|
||||
} else {
|
||||
getProject().getLogger().warn("Unrecognized template! " + string);
|
||||
}
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
private Set<File> runtimeClasspath() {
|
||||
// Should we actually include the runtime classpath here? Forge doesn't seem to be using this property anyways
|
||||
Set<File> mcLibs = DependencyDownloader.resolveFiles(getProject().getConfigurations().getByName(Constants.Configurations.FORGE_DEPENDENCIES), true);
|
||||
mcLibs.addAll(DependencyDownloader.resolveFiles(getProject().getConfigurations().getByName(Constants.Configurations.MINECRAFT_DEPENDENCIES), false));
|
||||
mcLibs.addAll(DependencyDownloader.resolveFiles(getProject().getConfigurations().getByName(Constants.Configurations.FORGE_EXTRA), false));
|
||||
mcLibs.addAll(DependencyDownloader.resolveFiles(getProject().getConfigurations().getByName(Constants.Configurations.MINECRAFT_NAMED), false));
|
||||
mcLibs.addAll(DependencyDownloader.resolveFiles(getProject().getConfigurations().getByName(Constants.Configurations.FORGE_NAMED), false));
|
||||
return mcLibs;
|
||||
}
|
||||
|
||||
private Set<File> minecraftClasspath() {
|
||||
Set<File> mcLibs = DependencyDownloader.resolveFiles(getProject().getConfigurations().getByName(Constants.Configurations.FORGE_DEPENDENCIES), true);
|
||||
mcLibs.addAll(DependencyDownloader.resolveFiles(getProject().getConfigurations().getByName(Constants.Configurations.MINECRAFT_DEPENDENCIES), false));
|
||||
mcLibs.addAll(DependencyDownloader.resolveFiles(getProject().getConfigurations().getByName(Constants.Configurations.FORGE_EXTRA), false));
|
||||
mcLibs.addAll(DependencyDownloader.resolveFiles(getProject().getConfigurations().getByName(Constants.Configurations.MINECRAFT_NAMED), false));
|
||||
mcLibs.addAll(DependencyDownloader.resolveFiles(getProject().getConfigurations().getByName(Constants.Configurations.FORGE_NAMED), false));
|
||||
return mcLibs;
|
||||
}
|
||||
|
||||
public File getUserdevJar() {
|
||||
|
||||
@@ -24,19 +24,33 @@
|
||||
|
||||
package net.fabricmc.loom.configuration.providers.forge;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.gradle.api.Project;
|
||||
import org.zeroturnaround.zip.ZipUtil;
|
||||
|
||||
import net.fabricmc.loom.configuration.DependencyProvider;
|
||||
import net.fabricmc.loom.util.Constants;
|
||||
import net.fabricmc.loom.util.FileSystemUtil;
|
||||
|
||||
public class McpConfigProvider extends DependencyProvider {
|
||||
private File mcp;
|
||||
private Path configJson;
|
||||
private Path mappings;
|
||||
private Boolean official;
|
||||
private String mappingsPath;
|
||||
|
||||
public McpConfigProvider(Project project) {
|
||||
super(project);
|
||||
@@ -46,25 +60,63 @@ public class McpConfigProvider extends DependencyProvider {
|
||||
public void provide(DependencyInfo dependency, Consumer<Runnable> postPopulationScheduler) throws Exception {
|
||||
init(dependency.getDependency().getVersion());
|
||||
|
||||
if (mcp.exists() && !isRefreshDeps()) {
|
||||
return; // No work for us to do here
|
||||
}
|
||||
|
||||
Path mcpZip = dependency.resolveFile().orElseThrow(() -> new RuntimeException("Could not resolve MCPConfig")).toPath();
|
||||
|
||||
if (!mcp.exists() || isRefreshDeps()) {
|
||||
if (!mcp.exists() || !Files.exists(configJson) || isRefreshDeps()) {
|
||||
Files.copy(mcpZip, mcp.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
|
||||
try (FileSystemUtil.FileSystemDelegate fs = FileSystemUtil.getJarFileSystem(mcp, false)) {
|
||||
Files.copy(fs.get().getPath("config.json"), configJson, StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
}
|
||||
|
||||
JsonObject json;
|
||||
|
||||
try (Reader reader = Files.newBufferedReader(configJson)) {
|
||||
json = new Gson().fromJson(reader, JsonObject.class);
|
||||
}
|
||||
|
||||
official = json.has("official") && json.getAsJsonPrimitive("official").getAsBoolean();
|
||||
mappingsPath = json.get("data").getAsJsonObject().get("mappings").getAsString();
|
||||
}
|
||||
|
||||
private void init(String version) throws IOException {
|
||||
File dir = getMinecraftProvider().dir("mcp/" + version);
|
||||
mcp = new File(dir, "mcp.zip");
|
||||
configJson = dir.toPath().resolve("mcp-config.json");
|
||||
mappings = dir.toPath().resolve("mcp-config-mappings.txt");
|
||||
|
||||
if (isRefreshDeps()) {
|
||||
Files.deleteIfExists(mappings);
|
||||
}
|
||||
}
|
||||
|
||||
private void init(String version) {
|
||||
mcp = new File(getDirectories().getUserCache(), "mcp-" + version + ".zip");
|
||||
public Path getMappings() {
|
||||
if (Files.notExists(mappings)) {
|
||||
if (!ZipUtil.handle(getMcp(), getMappingsPath(), (in, zipEntry) -> {
|
||||
try (BufferedWriter writer = Files.newBufferedWriter(mappings, StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) {
|
||||
IOUtils.copy(in, writer, StandardCharsets.UTF_8);
|
||||
}
|
||||
})) {
|
||||
throw new IllegalStateException("Failed to find mappings '" + getMappingsPath() + "' in " + getMcp().getAbsolutePath() + "!");
|
||||
}
|
||||
}
|
||||
|
||||
return mappings;
|
||||
}
|
||||
|
||||
public File getMcp() {
|
||||
return mcp;
|
||||
}
|
||||
|
||||
public boolean isOfficial() {
|
||||
return official;
|
||||
}
|
||||
|
||||
public String getMappingsPath() {
|
||||
return mappingsPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTargetConfig() {
|
||||
return Constants.Configurations.MCP_CONFIG;
|
||||
|
||||
@@ -29,7 +29,6 @@ import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.io.UncheckedIOException;
|
||||
@@ -55,47 +54,63 @@ import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.Manifest;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.base.Stopwatch;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.hash.Hashing;
|
||||
import com.google.common.io.ByteSource;
|
||||
import com.google.gson.JsonParser;
|
||||
import de.oceanlabs.mcp.mcinjector.adaptors.ParameterAnnotationFixer;
|
||||
import dev.architectury.mappingslayers.api.mutable.MutableClassDef;
|
||||
import dev.architectury.mappingslayers.api.mutable.MutableMethodDef;
|
||||
import dev.architectury.mappingslayers.api.mutable.MutableTinyTree;
|
||||
import dev.architectury.mappingslayers.api.utils.MappingsUtils;
|
||||
import dev.architectury.tinyremapper.InputTag;
|
||||
import dev.architectury.tinyremapper.OutputConsumerPath;
|
||||
import dev.architectury.tinyremapper.TinyRemapper;
|
||||
import net.minecraftforge.binarypatcher.ConsoleTool;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.output.NullOutputStream;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.file.FileCollection;
|
||||
import org.gradle.api.logging.LogLevel;
|
||||
import org.gradle.api.logging.Logger;
|
||||
import org.gradle.api.logging.configuration.ShowStacktrace;
|
||||
import org.gradle.api.plugins.JavaPluginConvention;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.Label;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.zeroturnaround.zip.ZipUtil;
|
||||
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.configuration.DependencyProvider;
|
||||
import net.fabricmc.loom.configuration.providers.MinecraftProvider;
|
||||
import net.fabricmc.loom.configuration.providers.MinecraftProviderImpl;
|
||||
import net.fabricmc.loom.configuration.providers.mappings.GradleMappingContext;
|
||||
import net.fabricmc.loom.configuration.providers.mappings.MappingNamespace;
|
||||
import net.fabricmc.loom.configuration.providers.mappings.mojmap.MojangMappingLayer;
|
||||
import net.fabricmc.loom.configuration.providers.mappings.mojmap.MojangMappingsSpec;
|
||||
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvider;
|
||||
import net.fabricmc.loom.util.Constants;
|
||||
import net.fabricmc.loom.util.DependencyDownloader;
|
||||
import net.fabricmc.loom.util.FileSystemUtil;
|
||||
import net.fabricmc.loom.util.MappingsProviderVerbose;
|
||||
import net.fabricmc.loom.util.ThreadingUtils;
|
||||
import net.fabricmc.loom.util.TinyRemapperMappingsHelper;
|
||||
import net.fabricmc.loom.util.function.FsPathConsumer;
|
||||
import net.fabricmc.loom.util.srg.InnerClassRemapper;
|
||||
import net.fabricmc.loom.util.srg.SpecialSourceExecutor;
|
||||
import net.fabricmc.loom.util.srg.Tsrg2Utils;
|
||||
import net.fabricmc.mapping.tree.TinyTree;
|
||||
import net.fabricmc.mappingio.MappingVisitor;
|
||||
|
||||
public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
private static final String LOOM_PATCH_VERSION_KEY = "Loom-Patch-Version";
|
||||
@@ -115,11 +130,14 @@ public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
// Step 5: Remap Patched AT & Forge to Official (global or project)
|
||||
private File minecraftMergedPatchedJar;
|
||||
private File forgeMergedJar;
|
||||
private File minecraftClientExtra;
|
||||
|
||||
private File projectAtHash;
|
||||
private Set<File> projectAts = new HashSet<>();
|
||||
private boolean atDirty = false;
|
||||
private boolean filesDirty = false;
|
||||
private Path mcpConfigMappings;
|
||||
private Path[] mergedMojangTsrg2Files;
|
||||
|
||||
public MinecraftPatchedProvider(Project project) {
|
||||
super(project);
|
||||
@@ -161,34 +179,29 @@ public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
MinecraftProviderImpl minecraftProvider = getExtension().getMinecraftProvider();
|
||||
PatchProvider patchProvider = getExtension().getPatchProvider();
|
||||
String minecraftVersion = minecraftProvider.minecraftVersion();
|
||||
String patchId = "forge-" + patchProvider.forgeVersion;
|
||||
|
||||
if (getExtension().isUseFabricMixin()) {
|
||||
patchId += "-fabric-mixin";
|
||||
}
|
||||
String patchId = "forge-" + getExtension().getForgeProvider().getVersion().getCombined();
|
||||
|
||||
minecraftProvider.setJarSuffix(patchId);
|
||||
|
||||
File globalCache = getDirectories().getUserCache();
|
||||
File globalCache = getMinecraftProvider().dir("forge/" + getExtension().getForgeProvider().getVersion().getCombined());
|
||||
File cache = usesProjectCache() ? getDirectories().getProjectPersistentCache() : globalCache;
|
||||
File globalDir = new File(globalCache, patchId);
|
||||
File projectDir = new File(cache, patchId);
|
||||
globalDir.mkdirs();
|
||||
File projectDir = new File(cache, "forge/" + getExtension().getForgeProvider().getVersion().getCombined());
|
||||
projectDir.mkdirs();
|
||||
|
||||
minecraftClientSrgJar = new File(globalCache, "minecraft-" + minecraftVersion + "-client-srg.jar");
|
||||
minecraftServerSrgJar = new File(globalCache, "minecraft-" + minecraftVersion + "-server-srg.jar");
|
||||
minecraftClientPatchedSrgJar = new File(globalDir, "client-srg-patched.jar");
|
||||
minecraftServerPatchedSrgJar = new File(globalDir, "server-srg-patched.jar");
|
||||
minecraftMergedPatchedSrgJar = new File(globalDir, "merged-srg-patched.jar");
|
||||
forgeMergedJar = new File(globalDir, "forge-official.jar");
|
||||
minecraftClientSrgJar = new File(globalCache, "minecraft-client-srg.jar");
|
||||
minecraftServerSrgJar = new File(globalCache, "minecraft-server-srg.jar");
|
||||
minecraftClientPatchedSrgJar = new File(globalCache, "client-srg-patched.jar");
|
||||
minecraftServerPatchedSrgJar = new File(globalCache, "server-srg-patched.jar");
|
||||
minecraftMergedPatchedSrgJar = new File(globalCache, "merged-srg-patched.jar");
|
||||
forgeMergedJar = getExtension().isForgeAndOfficial() ? null : new File(globalCache, "forge-official.jar");
|
||||
minecraftMergedPatchedSrgAtJar = new File(projectDir, "merged-srg-at-patched.jar");
|
||||
minecraftMergedPatchedJar = new File(projectDir, "merged-patched.jar");
|
||||
minecraftClientExtra = new File(globalCache, "forge-client-extra.jar");
|
||||
|
||||
if (isRefreshDeps() || Stream.of(getGlobalCaches()).anyMatch(Predicates.not(File::exists))
|
||||
if (isRefreshDeps() || Stream.of(getGlobalCaches()).anyMatch(((Predicate<File>) File::exists).negate())
|
||||
|| !isPatchedJarUpToDate(minecraftMergedPatchedJar)) {
|
||||
cleanAllCache();
|
||||
} else if (atDirty || Stream.of(getProjectCache()).anyMatch(Predicates.not(File::exists))) {
|
||||
} else if (atDirty || Stream.of(getProjectCache()).anyMatch(((Predicate<File>) File::exists).negate())) {
|
||||
cleanProjectCache();
|
||||
}
|
||||
}
|
||||
@@ -213,14 +226,21 @@ public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
}
|
||||
|
||||
private File[] getGlobalCaches() {
|
||||
return new File[] {
|
||||
File[] files = {
|
||||
minecraftClientSrgJar,
|
||||
minecraftServerSrgJar,
|
||||
minecraftClientPatchedSrgJar,
|
||||
minecraftServerPatchedSrgJar,
|
||||
minecraftMergedPatchedSrgJar,
|
||||
forgeMergedJar,
|
||||
minecraftClientExtra,
|
||||
};
|
||||
|
||||
if (forgeMergedJar != null) {
|
||||
Arrays.copyOf(files, files.length + 1);
|
||||
files[files.length - 1] = forgeMergedJar;
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
public void cleanProjectCache() {
|
||||
@@ -270,7 +290,7 @@ public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
accessTransformForge(getProject().getLogger());
|
||||
}
|
||||
|
||||
if (!forgeMergedJar.exists()) {
|
||||
if (forgeMergedJar != null && !forgeMergedJar.exists()) {
|
||||
this.dirty = true;
|
||||
}
|
||||
|
||||
@@ -278,10 +298,25 @@ public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
|
||||
if (dirty) {
|
||||
remapPatchedJar(input, getProject().getLogger());
|
||||
|
||||
if (getExtension().isForgeAndOfficial()) {
|
||||
fillClientExtraJar();
|
||||
}
|
||||
}
|
||||
|
||||
this.filesDirty = dirty;
|
||||
this.dirty = false;
|
||||
|
||||
if (getExtension().isForgeAndOfficial()) {
|
||||
addDependency(minecraftClientExtra, Constants.Configurations.FORGE_EXTRA);
|
||||
}
|
||||
}
|
||||
|
||||
private void fillClientExtraJar() throws IOException {
|
||||
Files.deleteIfExists(minecraftClientExtra.toPath());
|
||||
FileSystemUtil.getJarFileSystem(minecraftClientExtra, true).close();
|
||||
|
||||
copyNonClassFiles(getExtension().getMinecraftProvider().minecraftClientJar, minecraftClientExtra);
|
||||
}
|
||||
|
||||
private TinyRemapper buildRemapper(Path input) throws IOException {
|
||||
@@ -291,12 +326,16 @@ public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
.logger(getProject().getLogger()::lifecycle)
|
||||
.logUnknownInvokeDynamic(false)
|
||||
.withMappings(TinyRemapperMappingsHelper.create(mappingsWithSrg, "srg", "official", true))
|
||||
.withMappings(InnerClassRemapper.of(input, mappingsWithSrg, "srg", "official"))
|
||||
.withMappings(InnerClassRemapper.of(InnerClassRemapper.readClassNames(input), mappingsWithSrg, "srg", "official"))
|
||||
.renameInvalidLocals(true)
|
||||
.rebuildSourceFilenames(true)
|
||||
.fixPackageAccess(true)
|
||||
.build();
|
||||
|
||||
if (getProject().getGradle().getStartParameter().getLogLevel().compareTo(LogLevel.LIFECYCLE) < 0) {
|
||||
MappingsProviderVerbose.saveFile(remapper);
|
||||
}
|
||||
|
||||
remapper.readClassPath(libraries);
|
||||
remapper.prepareClasses();
|
||||
return remapper;
|
||||
@@ -309,41 +348,107 @@ public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
}
|
||||
|
||||
private void createSrgJars(Logger logger) throws Exception {
|
||||
McpConfigProvider mcpProvider = getExtension().getMcpConfigProvider();
|
||||
|
||||
MinecraftProviderImpl minecraftProvider = getExtension().getMinecraftProvider();
|
||||
String dep = getExtension().isForgeAndOfficial() ? Constants.Dependencies.VIGNETTE + Constants.Dependencies.Versions.VIGNETTE
|
||||
: Constants.Dependencies.SPECIAL_SOURCE + Constants.Dependencies.Versions.SPECIAL_SOURCE + ":shaded";
|
||||
FileCollection classpath = DependencyDownloader.download(getProject(), dep, true, true);
|
||||
produceSrgJar(getExtension().isForgeAndOfficial(), minecraftProvider.minecraftClientJar.toPath(), minecraftProvider.minecraftServerJar.toPath(), classpath);
|
||||
}
|
||||
|
||||
String[] mappingsPath = {null};
|
||||
|
||||
if (!ZipUtil.handle(mcpProvider.getMcp(), "config.json", (in, zipEntry) -> {
|
||||
mappingsPath[0] = JsonParser.parseReader(new InputStreamReader(in)).getAsJsonObject().get("data").getAsJsonObject().get("mappings").getAsString();
|
||||
})) {
|
||||
throw new IllegalStateException("Failed to find 'config.json' in " + mcpProvider.getMcp().getAbsolutePath() + "!");
|
||||
}
|
||||
|
||||
Path[] tmpSrg = {null};
|
||||
|
||||
if (!ZipUtil.handle(mcpProvider.getMcp(), mappingsPath[0], (in, zipEntry) -> {
|
||||
tmpSrg[0] = Files.createTempFile(null, null);
|
||||
|
||||
try (BufferedWriter writer = Files.newBufferedWriter(tmpSrg[0])) {
|
||||
IOUtils.copy(in, writer, StandardCharsets.UTF_8);
|
||||
}
|
||||
})) {
|
||||
throw new IllegalStateException("Failed to find mappings '" + mappingsPath[0] + "' in " + mcpProvider.getMcp().getAbsolutePath() + "!");
|
||||
}
|
||||
|
||||
String atDependency = Constants.Dependencies.SPECIAL_SOURCE + Constants.Dependencies.Versions.SPECIAL_SOURCE + ":shaded";
|
||||
// Do getFiles() to resolve it before multithreading it
|
||||
FileCollection classpath = getProject().files(DependencyDownloader.download(getProject(), atDependency).getFiles());
|
||||
private void produceSrgJar(boolean official, Path clientJar, Path serverJar, FileCollection classpath) throws IOException {
|
||||
Path tmpSrg = getToSrgMappings();
|
||||
Set<File> mcLibs = getProject().getConfigurations().getByName(Constants.Configurations.MINECRAFT_DEPENDENCIES).resolve();
|
||||
|
||||
ThreadingUtils.run(() -> {
|
||||
Files.copy(SpecialSourceExecutor.produceSrgJar(getProject(), "client", classpath, minecraftProvider.minecraftClientJar.toPath(), tmpSrg[0]), minecraftClientSrgJar.toPath());
|
||||
Files.copy(SpecialSourceExecutor.produceSrgJar(getProject(), "client", classpath, clientJar, tmpSrg), minecraftClientSrgJar.toPath());
|
||||
}, () -> {
|
||||
Files.copy(SpecialSourceExecutor.produceSrgJar(getProject(), "server", classpath, minecraftProvider.minecraftServerJar.toPath(), tmpSrg[0]), minecraftServerSrgJar.toPath());
|
||||
Files.copy(SpecialSourceExecutor.produceSrgJar(getProject(), "server", classpath, serverJar, tmpSrg), minecraftServerSrgJar.toPath());
|
||||
});
|
||||
}
|
||||
|
||||
private Path getToSrgMappings() throws IOException {
|
||||
if (getExtension().isForgeAndOfficial()) {
|
||||
return getMergedMojangTsrg2(true);
|
||||
} else {
|
||||
return getExtension().getMcpConfigProvider().getMappings();
|
||||
}
|
||||
}
|
||||
|
||||
private static void visitMojmap(MappingVisitor visitor, LoomGradleExtension extension) {
|
||||
GradleMappingContext context = new GradleMappingContext(extension.getForgeProvider().getProject(), "tmp-mojmap");
|
||||
|
||||
try {
|
||||
FileUtils.deleteDirectory(context.workingDirectory("/"));
|
||||
MojangMappingLayer layer = new MojangMappingsSpec(() -> true).createLayer(context);
|
||||
layer.visit(visitor);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
} finally {
|
||||
try {
|
||||
FileUtils.deleteDirectory(context.workingDirectory("/"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Path getMojmapTsrg(LoomGradleExtension extension) throws IOException {
|
||||
Path path = extension.getMinecraftProvider().dir("forge").toPath().resolve("mojmap.tsrg");
|
||||
|
||||
if (Files.notExists(path)) {
|
||||
try (BufferedWriter writer = Files.newBufferedWriter(path, StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) {
|
||||
Tsrg2Utils.writeTsrg(visitor -> visitMojmap(visitor, extension),
|
||||
MappingNamespace.NAMED.stringValue(), false, writer);
|
||||
}
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
public static Path getMojmapTsrg2(LoomGradleExtension extension) throws IOException {
|
||||
Path path = extension.getMinecraftProvider().dir("forge").toPath().resolve("mojmap.tsrg");
|
||||
|
||||
if (Files.notExists(path)) {
|
||||
try (BufferedWriter writer = Files.newBufferedWriter(path, StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) {
|
||||
Tsrg2Utils.writeTsrg2(visitor -> visitMojmap(visitor, extension), writer);
|
||||
}
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
public Path getMergedMojangTsrg2(boolean hasParameters) throws IOException {
|
||||
if (mergedMojangTsrg2Files == null) {
|
||||
Path out = Files.createTempFile("merged-mojang-tsrg2", null);
|
||||
Path outTrimmed = Files.createTempFile("merged-mojang-tsrg2-trimmed", null);
|
||||
net.minecraftforge.installertools.ConsoleTool.main(new String[]{
|
||||
"--task",
|
||||
"MERGE_MAPPING",
|
||||
"--left",
|
||||
getExtension().getMcpConfigProvider().getMappings().toAbsolutePath().toString(),
|
||||
"--right",
|
||||
getMojmapTsrg(getExtension()).toAbsolutePath().toString(),
|
||||
"--classes",
|
||||
"--output",
|
||||
out.toAbsolutePath().toString()
|
||||
});
|
||||
|
||||
MutableTinyTree mappings = MappingsUtils.deserializeFromTsrg2(FileUtils.readFileToString(out.toFile(), StandardCharsets.UTF_8));
|
||||
|
||||
for (MutableClassDef classDef : mappings.getClassesMutable()) {
|
||||
for (MutableMethodDef methodDef : classDef.getMethodsMutable()) {
|
||||
methodDef.getParametersMutable().clear();
|
||||
}
|
||||
}
|
||||
|
||||
Files.writeString(outTrimmed, MappingsUtils.serializeToTsrg2(mappings), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
|
||||
|
||||
mergedMojangTsrg2Files = new Path[]{out, outTrimmed};
|
||||
}
|
||||
|
||||
return mergedMojangTsrg2Files[hasParameters ? 0 : 1];
|
||||
}
|
||||
|
||||
private void fixParameterAnnotation(File jarFile) throws Exception {
|
||||
getProject().getLogger().info(":fixing parameter annotations for " + jarFile.getAbsolutePath());
|
||||
Stopwatch stopwatch = Stopwatch.createStarted();
|
||||
@@ -378,6 +483,60 @@ public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
getProject().getLogger().info(":fixing parameter annotations for " + jarFile.getAbsolutePath() + " in " + stopwatch);
|
||||
}
|
||||
|
||||
private void deleteParameterNames(File jarFile) throws Exception {
|
||||
getProject().getLogger().info(":deleting parameter names for " + jarFile.getAbsolutePath());
|
||||
Stopwatch stopwatch = Stopwatch.createStarted();
|
||||
|
||||
try (FileSystem fs = FileSystems.newFileSystem(new URI("jar:" + jarFile.toURI()), ImmutableMap.of("create", false))) {
|
||||
ThreadingUtils.TaskCompleter completer = ThreadingUtils.taskCompleter();
|
||||
Pattern vignetteParameters = Pattern.compile("p_\\d+_");
|
||||
|
||||
for (Path file : (Iterable<? extends Path>) Files.walk(fs.getPath("/"))::iterator) {
|
||||
if (!file.toString().endsWith(".class")) continue;
|
||||
|
||||
completer.add(() -> {
|
||||
byte[] bytes = Files.readAllBytes(file);
|
||||
ClassReader reader = new ClassReader(bytes);
|
||||
ClassWriter writer = new ClassWriter(0);
|
||||
|
||||
reader.accept(new ClassVisitor(Opcodes.ASM9, writer) {
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
|
||||
return new MethodVisitor(Opcodes.ASM9, super.visitMethod(access, name, descriptor, signature, exceptions)) {
|
||||
@Override
|
||||
public void visitParameter(String name, int access) {
|
||||
if (vignetteParameters.matcher(name).matches()) {
|
||||
super.visitParameter(null, access);
|
||||
} else {
|
||||
super.visitParameter(name, access);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitLocalVariable(String name, String descriptor, String signature, Label start, Label end, int index) {
|
||||
if (!vignetteParameters.matcher(name).matches()) {
|
||||
super.visitLocalVariable(name, descriptor, signature, start, end, index);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}, 0);
|
||||
|
||||
byte[] out = writer.toByteArray();
|
||||
|
||||
if (!Arrays.equals(bytes, out)) {
|
||||
Files.delete(file);
|
||||
Files.write(file, out);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
completer.complete();
|
||||
}
|
||||
|
||||
getProject().getLogger().info(":deleting parameter names for " + jarFile.getAbsolutePath() + " in " + stopwatch);
|
||||
}
|
||||
|
||||
private File getForgeJar() {
|
||||
return getExtension().getForgeUniversalProvider().getForge();
|
||||
}
|
||||
@@ -453,8 +612,10 @@ public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
spec.setClasspath(classpath);
|
||||
|
||||
// if running with INFO or DEBUG logging
|
||||
if (getProject().getGradle().getStartParameter().getLogLevel().compareTo(LogLevel.LIFECYCLE) < 0) {
|
||||
if (getProject().getGradle().getStartParameter().getShowStacktrace() != ShowStacktrace.INTERNAL_EXCEPTIONS
|
||||
|| getProject().getGradle().getStartParameter().getLogLevel().compareTo(LogLevel.LIFECYCLE) < 0) {
|
||||
spec.setStandardOutput(System.out);
|
||||
spec.setErrorOutput(System.err);
|
||||
} else {
|
||||
spec.setStandardOutput(NullOutputStream.NULL_OUTPUT_STREAM);
|
||||
spec.setErrorOutput(NullOutputStream.NULL_OUTPUT_STREAM);
|
||||
@@ -529,7 +690,12 @@ public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
|
||||
ThreadingUtils.run(Environment.values(), environment -> {
|
||||
copyMissingClasses(environment.srgJar.apply(this), environment.patchedSrgJar.apply(this));
|
||||
fixParameterAnnotation(environment.patchedSrgJar.apply(this));
|
||||
|
||||
if (getExtension().isForgeAndNotOfficial()) {
|
||||
fixParameterAnnotation(environment.patchedSrgJar.apply(this));
|
||||
} else {
|
||||
deleteParameterNames(environment.patchedSrgJar.apply(this));
|
||||
}
|
||||
});
|
||||
|
||||
logger.lifecycle(":patched jars in " + stopwatch.stop());
|
||||
@@ -565,9 +731,12 @@ public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
logger.lifecycle(":copying resources");
|
||||
|
||||
// Copy resources
|
||||
MinecraftProviderImpl minecraftProvider = getExtension().getMinecraftProvider();
|
||||
copyNonClassFiles(minecraftProvider.minecraftClientJar, minecraftMergedPatchedSrgJar);
|
||||
copyNonClassFiles(minecraftProvider.minecraftServerJar, minecraftMergedPatchedSrgJar);
|
||||
if (getExtension().isForgeAndNotOfficial()) {
|
||||
// Copy resources
|
||||
MinecraftProviderImpl minecraftProvider = getExtension().getMinecraftProvider();
|
||||
copyNonClassFiles(minecraftProvider.minecraftClientJar, minecraftMergedPatchedSrgJar);
|
||||
copyNonClassFiles(minecraftProvider.minecraftServerJar, minecraftMergedPatchedSrgJar);
|
||||
}
|
||||
}
|
||||
|
||||
private void walkFileSystems(File source, File target, Predicate<Path> filter, Function<FileSystem, Iterable<Path>> toWalk, FsPathConsumer action)
|
||||
@@ -576,6 +745,7 @@ public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
FileSystemUtil.FileSystemDelegate targetFs = FileSystemUtil.getJarFileSystem(target, false)) {
|
||||
for (Path sourceDir : toWalk.apply(sourceFs.get())) {
|
||||
Path dir = sourceDir.toAbsolutePath();
|
||||
if (!Files.exists(dir)) continue;
|
||||
Files.walk(dir)
|
||||
.filter(Files::isRegularFile)
|
||||
.filter(filter)
|
||||
@@ -616,9 +786,12 @@ public class MinecraftPatchedProvider extends DependencyProvider {
|
||||
}
|
||||
|
||||
private void copyNonClassFiles(File source, File target) throws IOException {
|
||||
Predicate<Path> filter = file -> {
|
||||
Predicate<Path> filter = getExtension().isForgeAndOfficial() ? file -> {
|
||||
String s = file.toString();
|
||||
return !s.endsWith(".class");
|
||||
} : file -> {
|
||||
String s = file.toString();
|
||||
return !s.endsWith(".class") || (s.startsWith("META-INF") && !s.startsWith("META-INF/services"));
|
||||
};
|
||||
|
||||
walkFileSystems(source, target, filter, this::copyReplacing);
|
||||
|
||||
@@ -43,7 +43,6 @@ import net.fabricmc.loom.util.Constants;
|
||||
public class PatchProvider extends DependencyProvider {
|
||||
public Path clientPatches;
|
||||
public Path serverPatches;
|
||||
public String forgeVersion;
|
||||
public Path projectCacheFolder;
|
||||
|
||||
public PatchProvider(Project project) {
|
||||
@@ -67,8 +66,7 @@ public class PatchProvider extends DependencyProvider {
|
||||
}
|
||||
|
||||
private void init(String forgeVersion) {
|
||||
this.forgeVersion = forgeVersion;
|
||||
projectCacheFolder = getDirectories().getProjectPersistentCache().toPath().resolve(forgeVersion);
|
||||
projectCacheFolder = getMinecraftProvider().dir("forge/" + forgeVersion).toPath();
|
||||
clientPatches = projectCacheFolder.resolve("patches-client.lzma");
|
||||
serverPatches = projectCacheFolder.resolve("patches-server.lzma");
|
||||
|
||||
|
||||
@@ -25,9 +25,7 @@
|
||||
package net.fabricmc.loom.configuration.providers.mappings;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.artifacts.Configuration;
|
||||
import org.gradle.api.logging.Logger;
|
||||
|
||||
@@ -35,8 +35,19 @@ import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import org.gradle.api.Action;
|
||||
import org.gradle.api.artifacts.Dependency;
|
||||
import org.gradle.api.artifacts.ExternalDependency;
|
||||
import org.gradle.api.artifacts.ExternalModuleDependency;
|
||||
import org.gradle.api.artifacts.ModuleIdentifier;
|
||||
import org.gradle.api.artifacts.ModuleVersionIdentifier;
|
||||
import org.gradle.api.artifacts.MutableVersionConstraint;
|
||||
import org.gradle.api.artifacts.SelfResolvingDependency;
|
||||
import org.gradle.api.artifacts.VersionConstraint;
|
||||
import org.gradle.api.internal.artifacts.DefaultModuleIdentifier;
|
||||
import org.gradle.api.internal.artifacts.ModuleVersionSelectorStrictSpec;
|
||||
import org.gradle.api.internal.artifacts.dependencies.AbstractModuleDependency;
|
||||
import org.gradle.api.internal.artifacts.dependencies.DefaultMutableVersionConstraint;
|
||||
import org.gradle.api.tasks.TaskDependency;
|
||||
import org.zeroturnaround.zip.ByteSource;
|
||||
import org.zeroturnaround.zip.ZipEntrySource;
|
||||
@@ -48,7 +59,7 @@ import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch;
|
||||
import net.fabricmc.mappingio.format.Tiny2Writer;
|
||||
import net.fabricmc.mappingio.tree.MemoryMappingTree;
|
||||
|
||||
public class LayeredMappingsDependency implements SelfResolvingDependency {
|
||||
public class LayeredMappingsDependency extends AbstractModuleDependency implements SelfResolvingDependency, ExternalModuleDependency {
|
||||
private static final String GROUP = "loom";
|
||||
private static final String MODULE = "mappings";
|
||||
|
||||
@@ -57,6 +68,7 @@ public class LayeredMappingsDependency implements SelfResolvingDependency {
|
||||
private final String version;
|
||||
|
||||
public LayeredMappingsDependency(MappingContext mappingContext, LayeredMappingSpec layeredMappingSpec, String version) {
|
||||
super(null);
|
||||
this.mappingContext = mappingContext;
|
||||
this.layeredMappingSpec = layeredMappingSpec;
|
||||
this.version = version;
|
||||
@@ -118,6 +130,21 @@ public class LayeredMappingsDependency implements SelfResolvingDependency {
|
||||
return version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VersionConstraint getVersionConstraint() {
|
||||
return new DefaultMutableVersionConstraint(getVersion());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matchesStrictly(ModuleVersionIdentifier identifier) {
|
||||
return new ModuleVersionSelectorStrictSpec(this).isSatisfiedBy(identifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModuleIdentifier getModule() {
|
||||
return DefaultModuleIdentifier.newId(GROUP, MODULE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contentEquals(Dependency dependency) {
|
||||
if (dependency instanceof LayeredMappingsDependency layeredMappingsDependency) {
|
||||
@@ -128,10 +155,34 @@ public class LayeredMappingsDependency implements SelfResolvingDependency {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dependency copy() {
|
||||
public boolean isChanging() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExternalModuleDependency setChanging(boolean b) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForce() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExternalDependency setForce(boolean b) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExternalModuleDependency copy() {
|
||||
return new LayeredMappingsDependency(mappingContext, layeredMappingSpec, version);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void version(Action<? super MutableVersionConstraint> action) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReason() {
|
||||
return null;
|
||||
|
||||
@@ -27,6 +27,7 @@ package net.fabricmc.loom.configuration.providers.mappings;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.FileSystem;
|
||||
@@ -151,7 +152,7 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings
|
||||
if (getExtension().shouldGenerateSrgTiny()) {
|
||||
if (Files.notExists(tinyMappingsWithSrg) || isRefreshDeps()) {
|
||||
// Merge tiny mappings with srg
|
||||
SrgMerger.mergeSrg(getExtension().getSrgProvider().getSrg().toPath(), tinyMappings, tinyMappingsWithSrg, true);
|
||||
SrgMerger.mergeSrg(this::getMojmapSrgFileIfPossible, getRawSrgFile(), tinyMappings, tinyMappingsWithSrg, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,7 +217,27 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings
|
||||
mappedProvider.provide(dependency, postPopulationScheduler);
|
||||
}
|
||||
|
||||
public void manipulateMappings(Path mappingsJar) throws IOException { }
|
||||
protected Path getRawSrgFile() throws IOException {
|
||||
LoomGradleExtension extension = getExtension();
|
||||
|
||||
if (extension.isForgeAndOfficial()) {
|
||||
return patchedProvider.getMergedMojangTsrg2(false);
|
||||
}
|
||||
|
||||
return extension.getSrgProvider().getSrg().toPath();
|
||||
}
|
||||
|
||||
protected Path getMojmapSrgFileIfPossible() {
|
||||
try {
|
||||
LoomGradleExtension extension = getExtension();
|
||||
return MinecraftPatchedProvider.getMojmapTsrg2(extension);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void manipulateMappings(Path mappingsJar) throws IOException {
|
||||
}
|
||||
|
||||
private String getMappingsClassifier(DependencyInfo dependency, boolean isV2) {
|
||||
String[] depStringSplit = dependency.getDepString().split(":");
|
||||
@@ -248,7 +269,8 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings
|
||||
}
|
||||
}
|
||||
|
||||
private void storeMappings(Project project, MinecraftProviderImpl minecraftProvider, Path yarnJar, Consumer<Runnable> postPopulationScheduler) throws IOException {
|
||||
private void storeMappings(Project project, MinecraftProviderImpl minecraftProvider, Path yarnJar, Consumer<Runnable> postPopulationScheduler)
|
||||
throws IOException {
|
||||
project.getLogger().info(":extracting " + yarnJar.getFileName());
|
||||
|
||||
if (isMCP(yarnJar)) {
|
||||
@@ -298,7 +320,7 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings
|
||||
provider.provide(DependencyInfo.create(getProject(), configuration.getDependencies().iterator().next(), configuration), postPopulationScheduler);
|
||||
}
|
||||
|
||||
Path srgPath = provider.getSrg().toPath();
|
||||
Path srgPath = getRawSrgFile();
|
||||
TinyFile file = new MCPReader(intermediaryTinyPath, srgPath).read(mcpJar);
|
||||
TinyV2Writer.write(file, tinyMappings);
|
||||
}
|
||||
@@ -426,20 +448,20 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings
|
||||
try {
|
||||
Command command = new CommandMergeTinyV2();
|
||||
runCommand(command, intermediaryMappings.toAbsolutePath().toString(),
|
||||
yarnMappings.toAbsolutePath().toString(),
|
||||
newMergedMappings.toAbsolutePath().toString(),
|
||||
"intermediary", "official");
|
||||
yarnMappings.toAbsolutePath().toString(),
|
||||
newMergedMappings.toAbsolutePath().toString(),
|
||||
"intermediary", "official");
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Could not merge mappings from " + intermediaryMappings.toString()
|
||||
+ " with mappings from " + yarnMappings, e);
|
||||
+ " with mappings from " + yarnMappings, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void suggestFieldNames(MinecraftProviderImpl minecraftProvider, Path oldMappings, Path newMappings) {
|
||||
Command command = new CommandProposeFieldNames();
|
||||
runCommand(command, minecraftProvider.getMergedJar().getAbsolutePath(),
|
||||
oldMappings.toAbsolutePath().toString(),
|
||||
newMappings.toAbsolutePath().toString());
|
||||
oldMappings.toAbsolutePath().toString(),
|
||||
newMappings.toAbsolutePath().toString());
|
||||
}
|
||||
|
||||
private void runCommand(Command command, String... args) {
|
||||
|
||||
@@ -101,7 +101,7 @@ public class MinecraftMappedProvider extends DependencyProvider {
|
||||
needToRemap = true;
|
||||
}
|
||||
|
||||
if (getExtension().isForge() && (!getForgeMappedJar().exists() || !getForgeIntermediaryJar().exists() || !getForgeSrgJar().exists() || isRefreshDeps() || isForgeAtDirty)) {
|
||||
if (getExtension().isForgeAndNotOfficial() && (!getForgeMappedJar().exists() || !getForgeIntermediaryJar().exists() || !getForgeSrgJar().exists() || isRefreshDeps() || isForgeAtDirty)) {
|
||||
needToRemap = true;
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ public class MinecraftMappedProvider extends DependencyProvider {
|
||||
minecraftSrgJar.delete();
|
||||
}
|
||||
|
||||
if (getExtension().isForge()) {
|
||||
if (getExtension().isForgeAndNotOfficial()) {
|
||||
if (getForgeMappedJar().exists()) {
|
||||
getForgeMappedJar().delete();
|
||||
}
|
||||
@@ -158,16 +158,18 @@ public class MinecraftMappedProvider extends DependencyProvider {
|
||||
|
||||
addDependencies(dependency, postPopulationScheduler);
|
||||
|
||||
if (getExtension().isForge()) {
|
||||
if (getExtension().isForgeAndNotOfficial()) {
|
||||
getProject().getRepositories().flatDir(repository -> repository.dir(new File(getJarDirectory(getDirectories().getUserCache(), "mapped"), "forge")));
|
||||
|
||||
getProject().getDependencies().add(Constants.Configurations.FORGE_NAMED,
|
||||
getProject().getDependencies().module("net.minecraftforge-loom:forge:" + getJarVersionString("mapped")));
|
||||
getProject().getDependencies().module("net.minecraftforge-loom:forge-mapped:" + getMinecraftProvider().minecraftVersion() + "/" + getExtension().getMappingsProvider().mappingsIdentifier() + "/forge"));
|
||||
}
|
||||
|
||||
if (getExtension().isForge()) {
|
||||
getProject().afterEvaluate(project -> {
|
||||
if (!OperatingSystem.isCIBuild()) {
|
||||
try {
|
||||
ForgeSourcesRemapper.addBaseForgeSources(project);
|
||||
ForgeSourcesRemapper.addBaseForgeSources(project, getExtension().isForgeAndOfficial());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -241,13 +243,13 @@ public class MinecraftMappedProvider extends DependencyProvider {
|
||||
forgeAssets.toFile().deleteOnExit();
|
||||
|
||||
Info vanilla = new Info(vanillaAssets, input, outputMapped, outputIntermediary, outputSrg);
|
||||
Info forge = getExtension().isForge() ? new Info(forgeAssets, inputForge, forgeOutputMapped, forgeOutputIntermediary, forgeOutputSrg) : null;
|
||||
Info forge = getExtension().isForgeAndNotOfficial() ? new Info(forgeAssets, inputForge, forgeOutputMapped, forgeOutputIntermediary, forgeOutputSrg) : null;
|
||||
|
||||
TinyRemapper remapper = remapperArray[0] = buildRemapper();
|
||||
|
||||
assetsOut(input, vanillaAssets);
|
||||
|
||||
if (getExtension().isForge()) {
|
||||
if (getExtension().isForgeAndNotOfficial()) {
|
||||
assetsOut(inputForge, forgeAssets);
|
||||
}
|
||||
|
||||
@@ -271,6 +273,8 @@ public class MinecraftMappedProvider extends DependencyProvider {
|
||||
}
|
||||
|
||||
public void remap(TinyRemapper remapper, Info vanilla, @Nullable Info forge, String fromM) throws IOException {
|
||||
Set<String> classNames = getExtension().isForge() ? InnerClassRemapper.readClassNames(vanilla.input) : null;
|
||||
|
||||
for (String toM : getExtension().isForge() ? Arrays.asList("intermediary", "srg", "named") : Arrays.asList("intermediary", "named")) {
|
||||
Path output = "named".equals(toM) ? vanilla.outputMapped : "srg".equals(toM) ? vanilla.outputSrg : vanilla.outputIntermediary;
|
||||
Path outputForge = forge == null ? null : "named".equals(toM) ? forge.outputMapped : "srg".equals(toM) ? forge.outputSrg : forge.outputIntermediary;
|
||||
@@ -285,7 +289,7 @@ public class MinecraftMappedProvider extends DependencyProvider {
|
||||
remapper.readInputs(forgeTag, forge.input);
|
||||
}
|
||||
|
||||
remapper.replaceMappings(getMappings(vanilla.input, fromM, toM));
|
||||
remapper.replaceMappings(getMappings(classNames, fromM, toM));
|
||||
OutputRemappingHandler.remap(remapper, vanilla.assets, output, null, vanillaTag);
|
||||
|
||||
if (forge != null) {
|
||||
@@ -325,13 +329,13 @@ public class MinecraftMappedProvider extends DependencyProvider {
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public Set<IMappingProvider> getMappings(@Nullable Path fromJar, String fromM, String toM) throws IOException {
|
||||
public Set<IMappingProvider> getMappings(@Nullable Set<String> fromClassNames, String fromM, String toM) throws IOException {
|
||||
Set<IMappingProvider> providers = new HashSet<>();
|
||||
providers.add(TinyRemapperMappingsHelper.create(getExtension().isForge() ? getExtension().getMappingsProvider().getMappingsWithSrg() : getExtension().getMappingsProvider().getMappings(), fromM, toM, true));
|
||||
|
||||
if (getExtension().isForge()) {
|
||||
if (fromJar != null) {
|
||||
providers.add(InnerClassRemapper.of(fromJar, getExtension().getMappingsProvider().getMappingsWithSrg(), fromM, toM));
|
||||
if (fromClassNames != null) {
|
||||
providers.add(InnerClassRemapper.of(fromClassNames, getExtension().getMappingsProvider().getMappingsWithSrg(), fromM, toM));
|
||||
}
|
||||
} else {
|
||||
providers.add(out -> JSR_TO_JETBRAINS.forEach(out::acceptClass));
|
||||
@@ -357,11 +361,16 @@ public class MinecraftMappedProvider extends DependencyProvider {
|
||||
minecraftMappedJar = new File(getExtension().getMappingsProvider().mappingsWorkingDir().toFile(), "minecraft-mapped.jar");
|
||||
inputJar = getExtension().isForge() ? mappingsProvider.patchedProvider.getMergedJar() : minecraftProvider.getMergedJar();
|
||||
|
||||
if (getExtension().isForge()) {
|
||||
if (getExtension().isForgeAndNotOfficial()) {
|
||||
inputForgeJar = mappingsProvider.patchedProvider.getForgeMergedJar();
|
||||
forgeIntermediaryJar = new File(getExtension().getMappingsProvider().mappingsWorkingDir().toFile(), "forge-intermediary.jar");
|
||||
forgeSrgJar = new File(getExtension().getMappingsProvider().mappingsWorkingDir().toFile(), "forge-srg.jar");
|
||||
forgeIntermediaryJar = new File(getExtension().getMappingsProvider().mappingsWorkingDir().toFile(), "forge/forge-intermediary.jar");
|
||||
forgeSrgJar = new File(getExtension().getMappingsProvider().mappingsWorkingDir().toFile(), "forge/forge-srg.jar");
|
||||
forgeMappedJar = new File(getExtension().getMappingsProvider().mappingsWorkingDir().toFile(), "forge/forge-mapped.jar");
|
||||
} else {
|
||||
inputForgeJar = null;
|
||||
forgeIntermediaryJar = null;
|
||||
forgeSrgJar = null;
|
||||
forgeMappedJar = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -58,8 +58,8 @@ import net.fabricmc.loom.util.ThreadingUtils;
|
||||
import net.fabricmc.lorenztiny.TinyMappingsReader;
|
||||
|
||||
public class ForgeSourcesRemapper {
|
||||
public static void addBaseForgeSources(Project project) throws IOException {
|
||||
Path sourcesJar = GenerateSourcesTask.getMappedJarFileWithSuffix(project, "-sources.jar", true).toPath();
|
||||
public static void addBaseForgeSources(Project project, boolean isOfficial) throws IOException {
|
||||
Path sourcesJar = GenerateSourcesTask.getMappedJarFileWithSuffix(project, "-sources.jar", !isOfficial).toPath();
|
||||
|
||||
if (!Files.exists(sourcesJar)) {
|
||||
addForgeSources(project, sourcesJar);
|
||||
@@ -185,7 +185,11 @@ public class ForgeSourcesRemapper {
|
||||
|
||||
// Distinct and add the srg jar at the top, so it gets prioritized
|
||||
mercury.getClassPath().add(0, extension.getMinecraftMappedProvider().getSrgJar().toPath());
|
||||
mercury.getClassPath().add(0, extension.getMinecraftMappedProvider().getForgeSrgJar().toPath());
|
||||
|
||||
if (extension.isForgeAndNotOfficial()) {
|
||||
mercury.getClassPath().add(0, extension.getMinecraftMappedProvider().getForgeSrgJar().toPath());
|
||||
}
|
||||
|
||||
List<Path> newClassPath = mercury.getClassPath().stream()
|
||||
.distinct()
|
||||
.filter(Files::isRegularFile)
|
||||
|
||||
@@ -366,6 +366,16 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA
|
||||
throw new RuntimeException("Yeah... something is really wrong");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForgeAndOfficial() {
|
||||
throw new RuntimeException("Yeah... something is really wrong");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForgeAndNotOfficial() {
|
||||
throw new RuntimeException("Yeah... something is really wrong");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getMinecraftVersion() {
|
||||
throw new RuntimeException("Yeah... something is really wrong");
|
||||
|
||||
@@ -160,6 +160,18 @@ public class MinecraftGradleExtension implements LoomGradleExtensionAPI {
|
||||
return parent.getPlatform();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForgeAndOfficial() {
|
||||
reportDeprecation();
|
||||
return parent.isForgeAndOfficial();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForgeAndNotOfficial() {
|
||||
reportDeprecation();
|
||||
return parent.isForgeAndNotOfficial();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsInclude() {
|
||||
reportDeprecation();
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
package net.fabricmc.loom.task;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import org.gradle.api.Project;
|
||||
@@ -33,6 +35,7 @@ import org.gradle.api.tasks.TaskContainer;
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.api.decompilers.LoomDecompiler;
|
||||
import net.fabricmc.loom.configuration.ide.RunConfigSettings;
|
||||
import net.fabricmc.loom.configuration.ide.SetupIntelijRunConfigs;
|
||||
import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl;
|
||||
import net.fabricmc.loom.decompilers.fernflower.FabricFernFlowerDecompiler;
|
||||
import net.fabricmc.loom.util.Constants;
|
||||
@@ -86,6 +89,19 @@ public final class LoomTasks {
|
||||
t.dependsOn("downloadAssets");
|
||||
t.setGroup(Constants.TaskGroup.IDE);
|
||||
});
|
||||
|
||||
tasks.register("genIntelliJRuns", AbstractLoomTask.class, t -> {
|
||||
t.setDescription("Generates IntelliJ IDEA launch configurations.");
|
||||
t.dependsOn("downloadAssets");
|
||||
t.setGroup("ide");
|
||||
t.doLast(task -> {
|
||||
try {
|
||||
SetupIntelijRunConfigs.generate(task.getProject(), true);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private static void registerRunTasks(TaskContainer tasks, Project project) {
|
||||
|
||||
@@ -187,9 +187,12 @@ public class MigrateMappingsTask extends AbstractLoomTask {
|
||||
|
||||
if (extension.isForge()) {
|
||||
mercury.getClassPath().add(minecraftMappedProvider.getSrgJar().toPath());
|
||||
mercury.getClassPath().add(minecraftMappedProvider.getForgeMappedJar().toPath());
|
||||
mercury.getClassPath().add(minecraftMappedProvider.getForgeIntermediaryJar().toPath());
|
||||
mercury.getClassPath().add(minecraftMappedProvider.getForgeSrgJar().toPath());
|
||||
|
||||
if (extension.isForgeAndNotOfficial()) {
|
||||
mercury.getClassPath().add(minecraftMappedProvider.getForgeMappedJar().toPath());
|
||||
mercury.getClassPath().add(minecraftMappedProvider.getForgeIntermediaryJar().toPath());
|
||||
mercury.getClassPath().add(minecraftMappedProvider.getForgeSrgJar().toPath());
|
||||
}
|
||||
}
|
||||
|
||||
mercury.getProcessors().add(MercuryRemapper.create(mappingSet));
|
||||
|
||||
@@ -79,6 +79,7 @@ public class Constants {
|
||||
public static final String FORGE_UNIVERSAL = "forgeUniversal";
|
||||
public static final String FORGE_DEPENDENCIES = "forgeDependencies";
|
||||
public static final String FORGE_NAMED = "forgeNamed";
|
||||
public static final String FORGE_EXTRA = "forgeExtra";
|
||||
public static final String MAPPING_CONSTANTS = "mappingsConstants";
|
||||
public static final String UNPICK_CLASSPATH = "unpick";
|
||||
|
||||
@@ -95,9 +96,10 @@ public class Constants {
|
||||
public static final String TERMINAL_CONSOLE_APPENDER = "net.minecrell:terminalconsoleappender:";
|
||||
public static final String JETBRAINS_ANNOTATIONS = "org.jetbrains:annotations:";
|
||||
public static final String JAVAX_ANNOTATIONS = "com.google.code.findbugs:jsr305:"; // I hate that I have to add these.
|
||||
public static final String FORGE_RUNTIME = "dev.architectury:architectury-loom-forge-runtime:";
|
||||
public static final String FORGE_RUNTIME = "dev.architectury:architectury-loom-runtime:";
|
||||
public static final String ACCESS_TRANSFORMERS = "net.minecraftforge:accesstransformers:";
|
||||
public static final String SPECIAL_SOURCE = "net.md-5:SpecialSource:";
|
||||
public static final String VIGNETTE = "net.minecraftforge.lex:vignette:";
|
||||
|
||||
private Dependencies() {
|
||||
}
|
||||
@@ -111,9 +113,10 @@ public class Constants {
|
||||
public static final String TERMINAL_CONSOLE_APPENDER = "1.2.0";
|
||||
public static final String JETBRAINS_ANNOTATIONS = "19.0.0";
|
||||
public static final String JAVAX_ANNOTATIONS = "3.0.2";
|
||||
public static final String FORGE_RUNTIME = "$LOOM_VERSION"; // replaced with current version at build time
|
||||
public static final String ACCESS_TRANSFORMERS = "2.2.0";
|
||||
public static final String FORGE_RUNTIME = "1.0.1";
|
||||
public static final String ACCESS_TRANSFORMERS = "3.0.1";
|
||||
public static final String SPECIAL_SOURCE = "1.8.3";
|
||||
public static final String VIGNETTE = "0.2.0.10";
|
||||
|
||||
private Versions() {
|
||||
}
|
||||
|
||||
@@ -24,7 +24,14 @@
|
||||
|
||||
package net.fabricmc.loom.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.artifacts.Configuration;
|
||||
import org.gradle.api.artifacts.Dependency;
|
||||
import org.gradle.api.artifacts.ModuleDependency;
|
||||
import org.gradle.api.file.FileCollection;
|
||||
|
||||
/**
|
||||
@@ -41,8 +48,40 @@ public final class DependencyDownloader {
|
||||
* @return the resolved files
|
||||
*/
|
||||
public static FileCollection download(Project project, String dependencyNotation) {
|
||||
var dependency = project.getDependencies().create(dependencyNotation);
|
||||
var config = project.getConfigurations().detachedConfiguration(dependency);
|
||||
return config.fileCollection(dep -> true);
|
||||
return download(project, dependencyNotation, true, false);
|
||||
}
|
||||
|
||||
public static FileCollection download(Project project, String dependencyNotation, boolean transitive, boolean resolve) {
|
||||
Dependency dependency = project.getDependencies().create(dependencyNotation);
|
||||
|
||||
if (dependency instanceof ModuleDependency) {
|
||||
((ModuleDependency) dependency).setTransitive(transitive);
|
||||
}
|
||||
|
||||
Configuration config = project.getConfigurations().detachedConfiguration(dependency);
|
||||
config.setTransitive(transitive);
|
||||
FileCollection files = config.fileCollection(dep -> true);
|
||||
|
||||
if (resolve) {
|
||||
files = project.files(files.getFiles());
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
private static Set<File> resolve(Configuration configuration, boolean transitive) {
|
||||
Configuration copy = configuration.copy();
|
||||
copy.setTransitive(transitive);
|
||||
Set<File> files = new LinkedHashSet<>(copy.resolve());
|
||||
|
||||
for (Configuration extendsForm : configuration.getExtendsFrom()) {
|
||||
files.addAll(resolve(extendsForm, transitive));
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
public static Set<File> resolveFiles(Configuration configuration, boolean transitive) {
|
||||
return resolve(configuration, transitive);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
package net.fabricmc.loom.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
|
||||
import dev.architectury.mappingslayers.api.mutable.MutableTinyMetadata;
|
||||
import dev.architectury.mappingslayers.api.mutable.MutableTinyTree;
|
||||
import dev.architectury.mappingslayers.api.utils.MappingsUtils;
|
||||
import dev.architectury.tinyremapper.IMappingProvider;
|
||||
import dev.architectury.tinyremapper.TinyRemapper;
|
||||
|
||||
public class MappingsProviderVerbose {
|
||||
public static void saveFile(TinyRemapper providers) throws IOException {
|
||||
try {
|
||||
Field field = TinyRemapper.class.getDeclaredField("mappingProviders");
|
||||
field.setAccessible(true);
|
||||
Set<IMappingProvider> mappingProviders = (Set<IMappingProvider>) field.get(providers);
|
||||
saveFile(mappingProviders);
|
||||
} catch (IllegalAccessException | NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void saveFile(Iterable<IMappingProvider> providers) throws IOException {
|
||||
MutableTinyTree tree = MappingsUtils.create(MutableTinyMetadata.create(2, 0, Arrays.asList("from", "to"), new HashMap<>()));
|
||||
|
||||
for (IMappingProvider provider : providers) {
|
||||
provider.load(new IMappingProvider.MappingAcceptor() {
|
||||
@Override
|
||||
public void acceptClass(String from, String to) {
|
||||
tree.getOrCreateClass(from).setName(1, to);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptMethod(IMappingProvider.Member from, String to) {
|
||||
tree.getOrCreateClass(from.owner).getOrCreateMethod(from.name, from.desc)
|
||||
.setName(1, to);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptMethodArg(IMappingProvider.Member from, int lvIndex, String to) {
|
||||
tree.getOrCreateClass(from.owner).getOrCreateMethod(from.name, from.desc)
|
||||
.getOrCreateParameter(lvIndex, "")
|
||||
.setName(1, to);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptMethodVar(IMappingProvider.Member from, int i, int i1, int i2, String s) {
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptField(IMappingProvider.Member from, String to) {
|
||||
tree.getOrCreateClass(from.owner).getOrCreateField(from.name, from.desc)
|
||||
.setName(1, to);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Path check = Files.createTempFile("CHECK", null);
|
||||
Files.writeString(check, MappingsUtils.serializeToString(tree), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
|
||||
System.out.println("Saved debug check mappings to " + check);
|
||||
}
|
||||
}
|
||||
@@ -27,11 +27,14 @@ package net.fabricmc.loom.util.srg;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import dev.architectury.tinyremapper.IMappingProvider;
|
||||
|
||||
import net.fabricmc.loom.util.FileSystemUtil;
|
||||
@@ -40,22 +43,16 @@ import net.fabricmc.mapping.tree.ClassDef;
|
||||
import net.fabricmc.mapping.tree.TinyTree;
|
||||
|
||||
public class InnerClassRemapper {
|
||||
public static IMappingProvider of(Path fromJar, TinyTree mappingsWithSrg, String from, String to) throws IOException {
|
||||
public static IMappingProvider of(Set<String> fromClassNames, TinyTree mappingsWithSrg, String from, String to) throws IOException {
|
||||
return sink -> {
|
||||
remapInnerClass(fromJar, mappingsWithSrg, from, to, sink::acceptClass);
|
||||
remapInnerClass(fromClassNames, mappingsWithSrg, from, to, sink::acceptClass);
|
||||
};
|
||||
}
|
||||
|
||||
private static void remapInnerClass(Path fromJar, TinyTree mappingsWithSrg, String from, String to, BiConsumer<String, String> action) {
|
||||
try (FileSystemDelegate system = FileSystemUtil.getJarFileSystem(fromJar, false)) {
|
||||
Map<String, String> availableClasses = mappingsWithSrg.getClasses().stream()
|
||||
.collect(Collectors.groupingBy(classDef -> classDef.getName(from),
|
||||
Collectors.<ClassDef, String>reducing(
|
||||
null,
|
||||
classDef -> classDef.getName(to),
|
||||
(first, last) -> last
|
||||
))
|
||||
);
|
||||
public static Set<String> readClassNames(Path jar) {
|
||||
Set<String> set = new HashSet<>();
|
||||
|
||||
try (FileSystemDelegate system = FileSystemUtil.getJarFileSystem(jar, false)) {
|
||||
Iterator<Path> iterator = Files.walk(system.get().getPath("/")).iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
@@ -65,21 +62,42 @@ public class InnerClassRemapper {
|
||||
|
||||
if (!Files.isDirectory(path) && name.contains("$") && name.endsWith(".class")) {
|
||||
String className = name.substring(0, name.length() - 6);
|
||||
|
||||
if (!availableClasses.containsKey(className)) {
|
||||
String parentName = className.substring(0, className.indexOf('$'));
|
||||
String childName = className.substring(className.indexOf('$') + 1);
|
||||
String remappedParentName = availableClasses.getOrDefault(parentName, parentName);
|
||||
String remappedName = remappedParentName + "$" + childName;
|
||||
|
||||
if (!className.equals(remappedName)) {
|
||||
action.accept(className, remappedName);
|
||||
}
|
||||
}
|
||||
set.add(className);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
private static void remapInnerClass(Set<String> classNames, TinyTree mappingsWithSrg, String from, String to, BiConsumer<String, String> action) {
|
||||
BiMap<String, String> availableClasses = HashBiMap.create(mappingsWithSrg.getClasses().stream()
|
||||
.collect(Collectors.groupingBy(classDef -> classDef.getName(from),
|
||||
Collectors.<ClassDef, String>reducing(
|
||||
null,
|
||||
classDef -> classDef.getName(to),
|
||||
(first, last) -> last
|
||||
))
|
||||
));
|
||||
|
||||
for (String className : classNames) {
|
||||
if (!availableClasses.containsKey(className)) {
|
||||
String parentName = className.substring(0, className.indexOf('$'));
|
||||
String childName = className.substring(className.indexOf('$') + 1);
|
||||
String remappedParentName = availableClasses.getOrDefault(parentName, parentName);
|
||||
String remappedName = remappedParentName + "$" + childName;
|
||||
|
||||
if (!className.equals(remappedName)) {
|
||||
if (availableClasses.containsValue(remappedName)) {
|
||||
// https://github.com/MinecraftForge/MinecraftForge/blob/b027a92dd287d6810a9fdae4d4b1e1432d7dc9cc/patches/minecraft/net/minecraft/Util.java.patch#L8
|
||||
action.accept(className, remappedName + "_UNBREAK");
|
||||
} else {
|
||||
action.accept(className, remappedName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ import org.apache.commons.io.output.NullOutputStream;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.file.FileCollection;
|
||||
import org.gradle.api.logging.LogLevel;
|
||||
import org.gradle.api.logging.configuration.ShowStacktrace;
|
||||
import org.zeroturnaround.zip.ZipUtil;
|
||||
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
@@ -87,8 +88,10 @@ public class SpecialSourceExecutor {
|
||||
spec.setMain("net.md_5.specialsource.SpecialSource");
|
||||
|
||||
// if running with INFO or DEBUG logging
|
||||
if (project.getGradle().getStartParameter().getLogLevel().compareTo(LogLevel.LIFECYCLE) < 0) {
|
||||
if (project.getGradle().getStartParameter().getShowStacktrace() != ShowStacktrace.INTERNAL_EXCEPTIONS
|
||||
|| project.getGradle().getStartParameter().getLogLevel().compareTo(LogLevel.LIFECYCLE) < 0) {
|
||||
spec.setStandardOutput(System.out);
|
||||
spec.setErrorOutput(System.err);
|
||||
} else {
|
||||
spec.setStandardOutput(NullOutputStream.NULL_OUTPUT_STREAM);
|
||||
spec.setErrorOutput(NullOutputStream.NULL_OUTPUT_STREAM);
|
||||
|
||||
@@ -27,15 +27,20 @@ package net.fabricmc.loom.util.srg;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import dev.architectury.mappingslayers.api.mutable.MutableClassDef;
|
||||
import dev.architectury.mappingslayers.api.mutable.MutableDescriptored;
|
||||
import dev.architectury.mappingslayers.api.mutable.MutableFieldDef;
|
||||
import dev.architectury.mappingslayers.api.mutable.MutableMethodDef;
|
||||
import dev.architectury.mappingslayers.api.mutable.MutableTinyTree;
|
||||
@@ -56,6 +61,7 @@ import net.fabricmc.mapping.tree.FieldDef;
|
||||
import net.fabricmc.mapping.tree.MethodDef;
|
||||
import net.fabricmc.mapping.tree.TinyMappingFactory;
|
||||
import net.fabricmc.mapping.tree.TinyTree;
|
||||
import net.fabricmc.mappingio.format.TsrgReader;
|
||||
import net.fabricmc.stitch.commands.tinyv2.TinyClass;
|
||||
import net.fabricmc.stitch.commands.tinyv2.TinyField;
|
||||
import net.fabricmc.stitch.commands.tinyv2.TinyFile;
|
||||
@@ -80,8 +86,9 @@ public final class SrgMerger {
|
||||
* @throws MappingException if the input tiny tree's default namespace is not 'official'
|
||||
* or if an element mentioned in the SRG file does not have tiny mappings
|
||||
*/
|
||||
public static void mergeSrg(Path srg, Path tiny, Path out, boolean lenient) throws IOException, MappingException {
|
||||
MappingSet arr = readSrg(srg);
|
||||
public static void mergeSrg(Supplier<Path> mojmap, Path srg, Path tiny, Path out, boolean lenient) throws IOException, MappingException {
|
||||
Map<String, List<MutableDescriptored>> addRegardlessSrgs = new HashMap<>();
|
||||
MappingSet arr = readSrg(srg, mojmap, addRegardlessSrgs);
|
||||
TinyTree foss;
|
||||
|
||||
try (BufferedReader reader = Files.newBufferedReader(tiny)) {
|
||||
@@ -100,19 +107,19 @@ public final class SrgMerger {
|
||||
List<TinyClass> classes = new ArrayList<>();
|
||||
|
||||
for (TopLevelClassMapping klass : arr.getTopLevelClassMappings()) {
|
||||
classToTiny(foss, namespaces, klass, classes::add, lenient);
|
||||
classToTiny(addRegardlessSrgs, foss, namespaces, klass, classes::add, lenient);
|
||||
}
|
||||
|
||||
TinyFile file = new TinyFile(header, classes);
|
||||
TinyV2Writer.write(file, out);
|
||||
}
|
||||
|
||||
private static MappingSet readSrg(Path srg) throws IOException {
|
||||
private static MappingSet readSrg(Path srg, Supplier<Path> mojmap, Map<String, List<MutableDescriptored>> addRegardlessSrgs) throws IOException {
|
||||
try (BufferedReader reader = Files.newBufferedReader(srg)) {
|
||||
String content = IOUtils.toString(reader);
|
||||
|
||||
if (content.startsWith("tsrg2")) {
|
||||
return readTsrg2(content);
|
||||
return readTsrg2(content, mojmap, addRegardlessSrgs);
|
||||
} else {
|
||||
try (TSrgReader srgReader = new TSrgReader(new StringReader(content))) {
|
||||
return srgReader.read();
|
||||
@@ -121,31 +128,45 @@ public final class SrgMerger {
|
||||
}
|
||||
}
|
||||
|
||||
private static MappingSet readTsrg2(String content) {
|
||||
MappingSet set = MappingSet.create();
|
||||
MutableTinyTree tree = MappingsUtils.deserializeFromTsrg2(content);
|
||||
int obfIndex = tree.getMetadata().index("obf");
|
||||
int srgIndex = tree.getMetadata().index("srg");
|
||||
private static MappingSet readTsrg2(String content, Supplier<Path> mojmap, Map<String, List<MutableDescriptored>> addRegardlessSrgs) throws IOException {
|
||||
MappingSet set;
|
||||
|
||||
for (MutableClassDef classDef : tree.getClassesMutable()) {
|
||||
ClassMapping<?, ?> classMapping = set.getOrCreateClassMapping(classDef.getName(obfIndex));
|
||||
classMapping.setDeobfuscatedName(classDef.getName(srgIndex));
|
||||
try (Tsrg2Utils.MappingsIO2LorenzWriter lorenzWriter = new Tsrg2Utils.MappingsIO2LorenzWriter(0, false)) {
|
||||
TsrgReader.read(new StringReader(content), lorenzWriter);
|
||||
set = lorenzWriter.read();
|
||||
MutableTinyTree mojmapTree = readTsrg2ToTinyTree(mojmap.get());
|
||||
|
||||
for (MutableFieldDef fieldDef : classDef.getFieldsMutable()) {
|
||||
FieldMapping fieldMapping = classMapping.getOrCreateFieldMapping(fieldDef.getName(obfIndex));
|
||||
fieldMapping.setDeobfuscatedName(fieldDef.getName(srgIndex));
|
||||
}
|
||||
for (MutableClassDef classDef : mojmapTree.getClassesMutable()) {
|
||||
for (MutableMethodDef methodDef : classDef.getMethodsMutable()) {
|
||||
String name = methodDef.getName(0);
|
||||
|
||||
for (MutableMethodDef methodDef : classDef.getMethodsMutable()) {
|
||||
MethodMapping methodMapping = classMapping.getOrCreateMethodMapping(methodDef.getName(obfIndex), methodDef.getDescriptor(obfIndex));
|
||||
methodMapping.setDeobfuscatedName(methodDef.getName(srgIndex));
|
||||
if (name.indexOf('<') != 0 && name.equals(methodDef.getName(1))) {
|
||||
addRegardlessSrgs.computeIfAbsent(classDef.getName(0), $ -> new ArrayList<>()).add(methodDef);
|
||||
}
|
||||
}
|
||||
|
||||
for (MutableFieldDef fieldDef : classDef.getFieldsMutable()) {
|
||||
if (fieldDef.getName(0).equals(fieldDef.getName(1))) {
|
||||
addRegardlessSrgs.computeIfAbsent(classDef.getName(0), $ -> new ArrayList<>()).add(fieldDef);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
private static void classToTiny(TinyTree foss, List<String> namespaces, ClassMapping<?, ?> klass, Consumer<TinyClass> classConsumer, boolean lenient) {
|
||||
private static MutableTinyTree readTsrg2ToTinyTree(Path path) throws IOException {
|
||||
MutableTinyTree tree;
|
||||
|
||||
try (BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
|
||||
tree = MappingsUtils.deserializeFromTsrg2(IOUtils.toString(reader));
|
||||
}
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
private static void classToTiny(Map<String, List<MutableDescriptored>> addRegardlessSrgs, TinyTree foss, List<String> namespaces, ClassMapping<?, ?> klass, Consumer<TinyClass> classConsumer, boolean lenient) {
|
||||
String obf = klass.getFullObfuscatedName();
|
||||
String srg = klass.getFullDeobfuscatedName();
|
||||
ClassDef classDef = foss.getDefaultNamespaceClassMap().get(obf);
|
||||
@@ -170,9 +191,17 @@ public final class SrgMerger {
|
||||
MethodDef def = CollectionUtil.find(
|
||||
classDef.getMethods(),
|
||||
m -> m.getName("official").equals(method.getObfuscatedName()) && m.getDescriptor("official").equals(method.getObfuscatedDescriptor())
|
||||
).orElse(nullOrThrow(lenient, () -> new MappingException("Missing method: " + method.getFullObfuscatedName() + " (srg: " + method.getFullDeobfuscatedName() + ")")));
|
||||
).orElse(null);
|
||||
|
||||
if (def == null) continue;
|
||||
if (def == null) {
|
||||
if (tryMatchRegardlessSrgs(addRegardlessSrgs, namespaces, obf, methods, method)) continue;
|
||||
|
||||
if (!lenient) {
|
||||
throw new MappingException("Missing method: " + method.getFullObfuscatedName() + " (srg: " + method.getFullDeobfuscatedName() + ")");
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
List<String> methodNames = CollectionUtil.map(
|
||||
namespaces,
|
||||
@@ -207,10 +236,36 @@ public final class SrgMerger {
|
||||
classConsumer.accept(tinyClass);
|
||||
|
||||
for (InnerClassMapping innerKlass : klass.getInnerClassMappings()) {
|
||||
classToTiny(foss, namespaces, innerKlass, classConsumer, lenient);
|
||||
classToTiny(addRegardlessSrgs, foss, namespaces, innerKlass, classConsumer, lenient);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean tryMatchRegardlessSrgs(Map<String, List<MutableDescriptored>> addRegardlessSrgs, List<String> namespaces, String obf,
|
||||
List<TinyMethod> methods, MethodMapping method) {
|
||||
List<MutableDescriptored> mutableDescriptoredList = addRegardlessSrgs.get(obf);
|
||||
|
||||
if (!method.getDeobfuscatedName().equals(method.getObfuscatedName())) {
|
||||
for (MutableDescriptored descriptored : MoreObjects.firstNonNull(mutableDescriptoredList, Collections.<MutableDescriptored>emptyList())) {
|
||||
if (descriptored.isMethod() && descriptored.getName(0).equals(method.getObfuscatedName()) && descriptored.getDescriptor(0).equals(method.getObfuscatedDescriptor())) {
|
||||
List<String> methodNames = CollectionUtil.map(
|
||||
namespaces,
|
||||
namespace -> "srg".equals(namespace) ? method.getDeobfuscatedName() : method.getObfuscatedName()
|
||||
);
|
||||
|
||||
methods.add(new TinyMethod(
|
||||
method.getObfuscatedDescriptor(), methodNames,
|
||||
/* parameters */ Collections.emptyList(),
|
||||
/* locals */ Collections.emptyList(),
|
||||
/* comments */ Collections.emptyList()
|
||||
));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static <T, X extends Exception> T nullOrThrow(boolean lenient, Supplier<X> exception) throws X {
|
||||
if (lenient) {
|
||||
|
||||
209
src/main/java/net/fabricmc/loom/util/srg/Tsrg2Utils.java
Normal file
209
src/main/java/net/fabricmc/loom/util/srg/Tsrg2Utils.java
Normal file
@@ -0,0 +1,209 @@
|
||||
package net.fabricmc.loom.util.srg;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import dev.architectury.mappingslayers.api.mutable.MutableClassDef;
|
||||
import dev.architectury.mappingslayers.api.mutable.MutableFieldDef;
|
||||
import dev.architectury.mappingslayers.api.mutable.MutableMethodDef;
|
||||
import dev.architectury.mappingslayers.api.mutable.MutableParameterDef;
|
||||
import dev.architectury.mappingslayers.api.mutable.MutableTinyMetadata;
|
||||
import dev.architectury.mappingslayers.api.mutable.MutableTinyTree;
|
||||
import dev.architectury.mappingslayers.api.utils.MappingsUtils;
|
||||
import org.cadixdev.lorenz.MappingSet;
|
||||
import org.cadixdev.lorenz.io.srg.tsrg.TSrgWriter;
|
||||
import org.cadixdev.lorenz.model.ClassMapping;
|
||||
import org.cadixdev.lorenz.model.MethodMapping;
|
||||
|
||||
import net.fabricmc.mappingio.MappingVisitor;
|
||||
import net.fabricmc.mappingio.MappingWriter;
|
||||
import net.fabricmc.mappingio.adapter.ForwardingMappingVisitor;
|
||||
import net.fabricmc.mappingio.format.TsrgReader;
|
||||
import net.fabricmc.mappingio.tree.MappingTree;
|
||||
import net.fabricmc.mappingio.tree.MemoryMappingTree;
|
||||
|
||||
public class Tsrg2Utils {
|
||||
public static void convert(Reader reader, Writer writer) throws IOException {
|
||||
writeTsrg(visitor -> {
|
||||
try {
|
||||
TsrgReader.read(reader, visitor);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}, "srg", false, writer);
|
||||
}
|
||||
|
||||
public static void writeTsrg(Consumer<MappingVisitor> visitorConsumer, String dstNamespace, boolean applyParameterMappings, Writer writer)
|
||||
throws IOException {
|
||||
MappingSet set;
|
||||
|
||||
try (MappingsIO2LorenzWriter lorenzWriter = new MappingsIO2LorenzWriter(dstNamespace, applyParameterMappings)) {
|
||||
visitorConsumer.accept(lorenzWriter);
|
||||
set = lorenzWriter.read();
|
||||
}
|
||||
|
||||
try (TSrgWriter w = new TSrgWriter(writer)) {
|
||||
w.write(set);
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeTsrg2(Consumer<MappingVisitor> visitorConsumer, Writer writer)
|
||||
throws IOException {
|
||||
MutableTinyTree tree;
|
||||
|
||||
try (MappingsIO2MappingsUtils w = new MappingsIO2MappingsUtils()) {
|
||||
visitorConsumer.accept(w);
|
||||
tree = w.read();
|
||||
}
|
||||
|
||||
writer.write(MappingsUtils.serializeToTsrg2(tree));
|
||||
}
|
||||
|
||||
// TODO Move this elsewhere
|
||||
public abstract static class MappingsIO2Others extends ForwardingMappingVisitor implements MappingWriter {
|
||||
public MappingsIO2Others() {
|
||||
super(new MemoryMappingTree());
|
||||
}
|
||||
|
||||
public MappingTree tree() {
|
||||
return (MappingTree) next;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
MappingTree tree = tree();
|
||||
List<String> names = new ArrayList<>();
|
||||
|
||||
for (MappingTree.ClassMapping aClass : tree.getClasses()) {
|
||||
names.add(aClass.getSrcName());
|
||||
}
|
||||
|
||||
for (String name : names) {
|
||||
tree.removeClass(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class MappingsIO2LorenzWriter extends MappingsIO2Others {
|
||||
private final Object dstNamespaceUnresolved;
|
||||
private int dstNamespace;
|
||||
private boolean applyParameterMappings;
|
||||
|
||||
public MappingsIO2LorenzWriter(int dstNamespace, boolean applyParameterMappings) {
|
||||
this.dstNamespaceUnresolved = dstNamespace;
|
||||
this.applyParameterMappings = applyParameterMappings;
|
||||
}
|
||||
|
||||
public MappingsIO2LorenzWriter(String dstNamespace, boolean applyParameterMappings) {
|
||||
this.dstNamespaceUnresolved = dstNamespace;
|
||||
this.applyParameterMappings = applyParameterMappings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNamespaces(String srcNamespace, List<String> dstNamespaces) throws IOException {
|
||||
super.visitNamespaces(srcNamespace, dstNamespaces);
|
||||
this.dstNamespace = dstNamespaceUnresolved instanceof Integer ? (Integer) dstNamespaceUnresolved : dstNamespaces.indexOf((String) dstNamespaceUnresolved);
|
||||
}
|
||||
|
||||
public MappingSet read() throws IOException {
|
||||
return this.read(MappingSet.create());
|
||||
}
|
||||
|
||||
public MappingSet read(final MappingSet mappings) throws IOException {
|
||||
MappingTree tree = tree();
|
||||
|
||||
for (MappingTree.ClassMapping aClass : tree.getClasses()) {
|
||||
ClassMapping<?, ?> lClass = mappings.getOrCreateClassMapping(aClass.getSrcName())
|
||||
.setDeobfuscatedName(aClass.getDstName(dstNamespace));
|
||||
|
||||
for (MappingTree.FieldMapping aField : aClass.getFields()) {
|
||||
String srcDesc = aField.getSrcDesc();
|
||||
|
||||
if (srcDesc == null || srcDesc.isEmpty()) {
|
||||
lClass.getOrCreateFieldMapping(aField.getSrcName())
|
||||
.setDeobfuscatedName(aField.getDstName(dstNamespace));
|
||||
} else {
|
||||
lClass.getOrCreateFieldMapping(aField.getSrcName(), srcDesc)
|
||||
.setDeobfuscatedName(aField.getDstName(dstNamespace));
|
||||
}
|
||||
}
|
||||
|
||||
for (MappingTree.MethodMapping aMethod : aClass.getMethods()) {
|
||||
MethodMapping lMethod = lClass.getOrCreateMethodMapping(aMethod.getSrcName(), aMethod.getSrcDesc())
|
||||
.setDeobfuscatedName(aMethod.getDstName(dstNamespace));
|
||||
|
||||
if (applyParameterMappings) {
|
||||
for (MappingTree.MethodArgMapping aArg : aMethod.getArgs()) {
|
||||
lMethod.getOrCreateParameterMapping(aArg.getLvIndex())
|
||||
.setDeobfuscatedName(aArg.getDstName(dstNamespace));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mappings;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MappingsIO2MappingsUtils extends MappingsIO2Others {
|
||||
public MutableTinyTree read() {
|
||||
MappingTree tree = tree();
|
||||
int dstNamesSize = tree.getDstNamespaces().size();
|
||||
List<String> namespaces = new ArrayList<>();
|
||||
namespaces.add(tree.getSrcNamespace());
|
||||
namespaces.addAll(tree.getDstNamespaces());
|
||||
Map<String, String> properties = new HashMap<>();
|
||||
|
||||
for (Map.Entry<String, String> entry : tree.getMetadata()) {
|
||||
properties.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
MutableTinyTree out = MappingsUtils.create(MutableTinyMetadata.create(2, 0, namespaces, properties));
|
||||
|
||||
for (MappingTree.ClassMapping aClass : tree.getClasses()) {
|
||||
MutableClassDef classDef = out.getOrCreateClass(aClass.getSrcName());
|
||||
classDef.setComment(aClass.getComment());
|
||||
|
||||
for (int i = 0; i < dstNamesSize; i++) {
|
||||
classDef.setName(i + 1, aClass.getDstName(i));
|
||||
}
|
||||
|
||||
for (MappingTree.MethodMapping aMethod : aClass.getMethods()) {
|
||||
MutableMethodDef methodDef = classDef.getOrCreateMethod(aMethod.getSrcName(), aMethod.getSrcDesc());
|
||||
methodDef.setComment(aMethod.getComment());
|
||||
|
||||
for (int i = 0; i < dstNamesSize; i++) {
|
||||
methodDef.setName(i + 1, aMethod.getDstName(i));
|
||||
}
|
||||
|
||||
for (MappingTree.MethodArgMapping aMethodArg : aMethod.getArgs()) {
|
||||
MutableParameterDef parameterDef = methodDef.getOrCreateParameter(aMethodArg.getLvIndex(), aMethodArg.getSrcName());
|
||||
parameterDef.setComment(aMethodArg.getComment());
|
||||
|
||||
for (int i = 0; i < dstNamesSize; i++) {
|
||||
parameterDef.setName(i + 1, aMethodArg.getDstName(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (MappingTree.FieldMapping aField : aClass.getFields()) {
|
||||
MutableFieldDef fieldDef = classDef.getOrCreateField(aField.getSrcName(), aField.getSrcDesc());
|
||||
fieldDef.setComment(aField.getComment());
|
||||
|
||||
for (int i = 0; i < dstNamesSize; i++) {
|
||||
fieldDef.setName(i + 1, aField.getDstName(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user