First pass on "shareCaches".
This commit is contained in:
		
							parent
							
								
									2d7421d4ed
								
							
						
					
					
						commit
						32eb0bd3c8
					
				
					 9 changed files with 411 additions and 10 deletions
				
			
		|  | @ -24,6 +24,7 @@ | |||
| 
 | ||||
| package net.fabricmc.loom; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.util.HashSet; | ||||
| import java.util.Map; | ||||
| import java.util.Optional; | ||||
|  | @ -54,6 +55,8 @@ import net.fabricmc.loom.providers.MinecraftProvider; | |||
| import net.fabricmc.loom.providers.MappingsCache; | ||||
| import net.fabricmc.loom.task.RemapJarTask; | ||||
| import net.fabricmc.loom.task.RemapSourcesJarTask; | ||||
| import net.fabricmc.loom.task.shared.RemapAllJarsTask; | ||||
| import net.fabricmc.loom.task.shared.RemapAllSourcesTask; | ||||
| import net.fabricmc.loom.util.Constants; | ||||
| import net.fabricmc.loom.util.GroovyXmlUtil; | ||||
| import net.fabricmc.loom.util.LoomDependencyManager; | ||||
|  | @ -64,7 +67,9 @@ import net.fabricmc.loom.util.mixin.JavaApInvoker; | |||
| import net.fabricmc.loom.util.mixin.KaptApInvoker; | ||||
| import net.fabricmc.loom.util.mixin.ScalaApInvoker; | ||||
| import net.fabricmc.loom.util.FabricApiExtension; | ||||
| import net.fabricmc.loom.util.SourceRemapper; | ||||
| import net.fabricmc.loom.util.DownloadUtil; | ||||
| import net.fabricmc.loom.util.JarRemapper; | ||||
| 
 | ||||
| public class AbstractPlugin implements Plugin<Project> { | ||||
| 	protected Project project; | ||||
|  | @ -268,6 +273,48 @@ public class AbstractPlugin implements Plugin<Project> { | |||
| 					} | ||||
| 				} | ||||
| 
 | ||||
| 				SourceRemapper remapper = null; | ||||
| 				Task parentTask = project1.getTasks().getByName("build"); | ||||
| 
 | ||||
| 				if (extension.isShareCaches()) { | ||||
| 					Project rootProject = project.getRootProject(); | ||||
| 
 | ||||
| 					if (extension.isRootProject()) { | ||||
| 						SourceRemapper sourceRemapper = new SourceRemapper(rootProject, false); | ||||
| 						JarRemapper jarRemapper = new JarRemapper(); | ||||
| 
 | ||||
| 						remapJarTask.jarRemapper = jarRemapper; | ||||
| 
 | ||||
| 						rootProject.getTasks().register("remapAllSources", RemapAllSourcesTask.class, task -> { | ||||
| 							task.sourceRemapper = sourceRemapper; | ||||
| 							task.doLast(t -> sourceRemapper.remapAll()); | ||||
| 						}); | ||||
| 
 | ||||
| 						parentTask = rootProject.getTasks().getByName("remapAllSources"); | ||||
| 
 | ||||
| 						rootProject.getTasks().register("remapAllJars", RemapAllJarsTask.class, task -> { | ||||
| 							task.doLast(t -> { | ||||
| 								try { | ||||
| 									jarRemapper.remap(); | ||||
| 								} catch (IOException e) { | ||||
| 									throw new RuntimeException("Failed to remap jars", e); | ||||
| 								} | ||||
| 							}); | ||||
| 						}); | ||||
| 
 | ||||
| 						for (Project subProject : rootProject.getAllprojects()) { | ||||
| 							subProject.getTasks().getByName("build").dependsOn(parentTask); | ||||
| 							subProject.getTasks().getByName("build").dependsOn(rootProject.getTasks().getByName("remapAllJars")); | ||||
| 							rootProject.getTasks().getByName("remapAllJars").dependsOn(subProject.getTasks().getByName("remapJar")); | ||||
| 						} | ||||
| 					} else { | ||||
| 						parentTask = rootProject.getTasks().getByName("remapAllSources"); | ||||
| 						remapper = ((RemapAllSourcesTask) parentTask).sourceRemapper; | ||||
| 
 | ||||
| 						remapJarTask.jarRemapper = ((RemapJarTask) rootProject.getTasks().getByName("remapJar")).jarRemapper; | ||||
| 					} | ||||
| 				} | ||||
| 
 | ||||
| 				try { | ||||
| 					AbstractArchiveTask sourcesTask = (AbstractArchiveTask) project1.getTasks().getByName("sourcesJar"); | ||||
| 
 | ||||
|  | @ -276,7 +323,12 @@ public class AbstractPlugin implements Plugin<Project> { | |||
| 					remapSourcesJarTask.setOutput(sourcesTask.getArchivePath()); | ||||
| 					remapSourcesJarTask.doLast(task -> project1.getArtifacts().add("archives", remapSourcesJarTask.getOutput())); | ||||
| 					remapSourcesJarTask.dependsOn(project1.getTasks().getByName("sourcesJar")); | ||||
| 					project1.getTasks().getByName("build").dependsOn(remapSourcesJarTask); | ||||
| 
 | ||||
| 					if (extension.isShareCaches()) { | ||||
| 						remapSourcesJarTask.setSourceRemapper(remapper); | ||||
| 					} | ||||
| 
 | ||||
| 					parentTask.dependsOn(remapSourcesJarTask); | ||||
| 				} catch (UnknownTaskException e) { | ||||
| 					// pass | ||||
| 				} | ||||
|  |  | |||
|  | @ -61,6 +61,7 @@ public class LoomGradleExtension { | |||
| 	public String customManifest = null; | ||||
| 	public File accessWidener = null; | ||||
| 	public Function<String, Object> intermediaryUrl = mcVer -> "https://maven.fabricmc.net/net/fabricmc/intermediary/" + mcVer + "/intermediary-" + mcVer + "-v2.jar"; | ||||
| 	public boolean shareCaches = false; | ||||
| 
 | ||||
| 	private List<Path> unmappedModsBuilt = new ArrayList<>(); | ||||
| 
 | ||||
|  | @ -338,4 +339,24 @@ public class LoomGradleExtension { | |||
| 		//Done like this to work around this possibly not being a java string... | ||||
| 		return s -> intermediaryUrl.apply(s).toString(); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean isRootProject() { | ||||
| 		return project.getRootProject() == project; | ||||
| 	} | ||||
| 
 | ||||
| 	public LoomGradleExtension getRootGradleExtension() { | ||||
| 		if (isRootProject()) { | ||||
| 			return this; | ||||
| 		} | ||||
| 
 | ||||
| 		return project.getRootProject().getExtensions().getByType(LoomGradleExtension.class); | ||||
| 	} | ||||
| 
 | ||||
| 	public LoomGradleExtension getSharedGradleExtension() { | ||||
| 		return isShareCaches() ? getRootGradleExtension() : this; | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean isShareCaches() { | ||||
| 		return shareCaches; | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -120,6 +120,10 @@ public class MinecraftProvider extends DependencyProvider { | |||
| 	private void downloadMcJson(boolean offline) throws IOException { | ||||
| 		File manifests = new File(getExtension().getUserCache(), "version_manifest.json"); | ||||
| 
 | ||||
| 		if (getExtension().isShareCaches() && !getExtension().isRootProject() && manifests.exists() && !isRefreshDeps()) { | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		if (offline) { | ||||
| 			if (manifests.exists()) { | ||||
| 				//If there is the manifests already we'll presume that's good enough | ||||
|  | @ -171,6 +175,10 @@ public class MinecraftProvider extends DependencyProvider { | |||
| 	} | ||||
| 
 | ||||
| 	private void downloadJars(Logger logger) throws IOException { | ||||
| 		if (getExtension().isShareCaches() && !getExtension().isRootProject() && minecraftClientJar.exists() && minecraftServerJar.exists() && !isRefreshDeps()) { | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		DownloadUtil.downloadIfChanged(new URL(versionInfo.downloads.get("client").url), minecraftClientJar, logger); | ||||
| 		DownloadUtil.downloadIfChanged(new URL(versionInfo.downloads.get("server").url), minecraftServerJar, logger); | ||||
| 	} | ||||
|  |  | |||
|  | @ -26,6 +26,7 @@ package net.fabricmc.loom.task; | |||
| 
 | ||||
| import java.io.File; | ||||
| import java.io.FileNotFoundException; | ||||
| import java.io.IOException; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
| import java.util.LinkedHashSet; | ||||
|  | @ -38,6 +39,7 @@ import org.gradle.api.tasks.Input; | |||
| import org.gradle.api.tasks.InputFile; | ||||
| import org.gradle.api.tasks.TaskAction; | ||||
| import org.gradle.jvm.tasks.Jar; | ||||
| import org.zeroturnaround.zip.ZipUtil; | ||||
| 
 | ||||
| import net.fabricmc.loom.LoomGradleExtension; | ||||
| import net.fabricmc.loom.providers.MappingsProvider; | ||||
|  | @ -46,6 +48,8 @@ import net.fabricmc.loom.util.MixinRefmapHelper; | |||
| import net.fabricmc.loom.util.NestedJars; | ||||
| import net.fabricmc.loom.util.TinyRemapperMappingsHelper; | ||||
| import net.fabricmc.loom.util.accesswidener.AccessWidenerJarProcessor; | ||||
| import net.fabricmc.loom.util.JarRemapper; | ||||
| import net.fabricmc.stitch.util.Pair; | ||||
| import net.fabricmc.tinyremapper.OutputConsumerPath; | ||||
| import net.fabricmc.tinyremapper.TinyRemapper; | ||||
| import net.fabricmc.tinyremapper.TinyUtils; | ||||
|  | @ -54,6 +58,7 @@ public class RemapJarTask extends Jar { | |||
| 	private RegularFileProperty input; | ||||
| 	private Property<Boolean> addNestedDependencies; | ||||
| 	private Property<Boolean> remapAccessWidener; | ||||
| 	public JarRemapper jarRemapper; | ||||
| 
 | ||||
| 	public RemapJarTask() { | ||||
| 		super(); | ||||
|  | @ -66,6 +71,14 @@ public class RemapJarTask extends Jar { | |||
| 
 | ||||
| 	@TaskAction | ||||
| 	public void doTask() throws Throwable { | ||||
| 		if (jarRemapper == null) { | ||||
| 			doSingleRemap(); | ||||
| 		} else { | ||||
| 			scheduleRemap(); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public void doSingleRemap() throws Throwable { | ||||
| 		Project project = getProject(); | ||||
| 		LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); | ||||
| 		Path input = this.getInput().getAsFile().get().toPath(); | ||||
|  | @ -150,6 +163,81 @@ public class RemapJarTask extends Jar { | |||
| 		}*/ | ||||
| 	} | ||||
| 
 | ||||
| 	public void scheduleRemap() throws Throwable { | ||||
| 		Project project = getProject(); | ||||
| 		LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); | ||||
| 		Path input = this.getInput().getAsFile().get().toPath(); | ||||
| 		Path output = this.getArchivePath().toPath(); | ||||
| 
 | ||||
| 		if (!Files.exists(input)) { | ||||
| 			throw new FileNotFoundException(input.toString()); | ||||
| 		} | ||||
| 
 | ||||
| 		MappingsProvider mappingsProvider = extension.getMappingsProvider(); | ||||
| 
 | ||||
| 		String fromM = "named"; | ||||
| 		String toM = "intermediary"; | ||||
| 
 | ||||
| 		if (extension.isRootProject()) { | ||||
| 			Set<File> classpathFiles = new LinkedHashSet<>( | ||||
| 					project.getConfigurations().getByName("compileClasspath").getFiles() | ||||
| 			); | ||||
| 
 | ||||
| 			Path[] classpath = classpathFiles.stream() | ||||
| 					.map(File::toPath) | ||||
| 					.filter(Files::exists) | ||||
| 					.toArray(Path[]::new); | ||||
| 
 | ||||
| 			jarRemapper.addToClasspath(classpath); | ||||
| 
 | ||||
| 			jarRemapper.addMappings(TinyRemapperMappingsHelper.create(mappingsProvider.getMappings(), fromM, toM, false)); | ||||
| 		} | ||||
| 
 | ||||
| 		File mixinMapFile = mappingsProvider.mappingsMixinExport; | ||||
| 		Path mixinMapPath = mixinMapFile.toPath(); | ||||
| 
 | ||||
| 		if (mixinMapFile.exists()) { | ||||
| 			jarRemapper.addMappings(TinyUtils.createTinyMappingProvider(mixinMapPath, fromM, toM)); | ||||
| 		} | ||||
| 
 | ||||
| 		jarRemapper.scheduleRemap(input, output) | ||||
| 				.supplyAccessWidener((remapData, remapper) -> { | ||||
| 					if (getRemapAccessWidener().getOrElse(false) && extension.accessWidener != null) { | ||||
| 						AccessWidenerJarProcessor accessWidenerJarProcessor = extension.getJarProcessorManager().getByType(AccessWidenerJarProcessor.class); | ||||
| 						byte[] data; | ||||
| 
 | ||||
| 						try { | ||||
| 							data = accessWidenerJarProcessor.getRemappedAccessWidener(remapper); | ||||
| 						} catch (IOException e) { | ||||
| 							throw new RuntimeException("Failed to remap access widener"); | ||||
| 						} | ||||
| 
 | ||||
| 						return Pair.of(accessWidenerJarProcessor.getAccessWidenerPath(remapData.output), data); | ||||
| 					} | ||||
| 
 | ||||
| 					return null; | ||||
| 				}) | ||||
| 				.complete((data, accessWidener) -> { | ||||
| 					if (!Files.exists(output)) { | ||||
| 						throw new RuntimeException("Failed to remap " + input + " to " + output + " - file missing!"); | ||||
| 					} | ||||
| 
 | ||||
| 					if (MixinRefmapHelper.addRefmapName(extension.getRefmapName(), extension.getMixinJsonVersion(), output)) { | ||||
| 						project.getLogger().debug("Transformed mixin reference maps in output JAR!"); | ||||
| 					} | ||||
| 
 | ||||
| 					if (getAddNestedDependencies().getOrElse(false)) { | ||||
| 						if (NestedJars.addNestedJars(project, output)) { | ||||
| 							project.getLogger().debug("Added nested jar paths to mod json"); | ||||
| 						} | ||||
| 					} | ||||
| 
 | ||||
| 					if (accessWidener != null) { | ||||
| 						ZipUtil.replaceEntry(data.output.toFile(), accessWidener.getLeft(), accessWidener.getRight()); | ||||
| 					} | ||||
| 				}); | ||||
| 	} | ||||
| 
 | ||||
| 	@InputFile | ||||
| 	public RegularFileProperty getInput() { | ||||
| 		return input; | ||||
|  |  | |||
|  | @ -28,6 +28,7 @@ import java.io.File; | |||
| 
 | ||||
| import org.gradle.api.tasks.Input; | ||||
| import org.gradle.api.tasks.InputFile; | ||||
| import org.gradle.api.tasks.Internal; | ||||
| import org.gradle.api.tasks.OutputFile; | ||||
| import org.gradle.api.tasks.TaskAction; | ||||
| 
 | ||||
|  | @ -37,10 +38,34 @@ public class RemapSourcesJarTask extends AbstractLoomTask { | |||
| 	private Object input; | ||||
| 	private Object output; | ||||
| 	private String direction = "intermediary"; | ||||
| 	private SourceRemapper sourceRemapper = null; | ||||
| 
 | ||||
| 	@TaskAction | ||||
| 	public void remap() throws Exception { | ||||
| 		if (sourceRemapper == null) { | ||||
| 			SourceRemapper.remapSources(getProject(), getInput(), getOutput(), direction.equals("named")); | ||||
| 		} else { | ||||
| 			sourceRemapper.scheduleRemapSources(getInput(), getOutput()); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public String getDirection() { | ||||
| 		return direction; | ||||
| 	} | ||||
| 
 | ||||
| 	public RemapSourcesJarTask setDirection(String direction) { | ||||
| 		this.direction = direction; | ||||
| 		return this; | ||||
| 	} | ||||
| 
 | ||||
| 	@Internal | ||||
| 	public SourceRemapper getSourceRemapper() { | ||||
| 		return sourceRemapper; | ||||
| 	} | ||||
| 
 | ||||
| 	public RemapSourcesJarTask setSourceRemapper(SourceRemapper sourceRemapper) { | ||||
| 		this.sourceRemapper = sourceRemapper; | ||||
| 		return this; | ||||
| 	} | ||||
| 
 | ||||
| 	@InputFile | ||||
|  |  | |||
|  | @ -0,0 +1,30 @@ | |||
| /* | ||||
|  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||
|  * | ||||
|  * Copyright (c) 2016, 2017, 2018 FabricMC | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in all | ||||
|  * copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|  * SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| package net.fabricmc.loom.task.shared; | ||||
| 
 | ||||
| import net.fabricmc.loom.task.AbstractLoomTask; | ||||
| 
 | ||||
| public class RemapAllJarsTask extends AbstractLoomTask { | ||||
| } | ||||
|  | @ -0,0 +1,32 @@ | |||
| /* | ||||
|  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||
|  * | ||||
|  * Copyright (c) 2016, 2017, 2018 FabricMC | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in all | ||||
|  * copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|  * SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| package net.fabricmc.loom.task.shared; | ||||
| 
 | ||||
| import net.fabricmc.loom.task.AbstractLoomTask; | ||||
| import net.fabricmc.loom.util.SourceRemapper; | ||||
| 
 | ||||
| public class RemapAllSourcesTask extends AbstractLoomTask { | ||||
| 	public SourceRemapper sourceRemapper; | ||||
| } | ||||
							
								
								
									
										141
									
								
								src/main/java/net/fabricmc/loom/util/JarRemapper.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								src/main/java/net/fabricmc/loom/util/JarRemapper.java
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,141 @@ | |||
| /* | ||||
|  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||
|  * | ||||
|  * Copyright (c) 2016, 2017, 2018 FabricMC | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in all | ||||
|  * copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|  * SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| package net.fabricmc.loom.util; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.nio.file.Path; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Arrays; | ||||
| import java.util.HashSet; | ||||
| import java.util.List; | ||||
| import java.util.Set; | ||||
| import java.util.function.BiConsumer; | ||||
| import java.util.function.BiFunction; | ||||
| 
 | ||||
| import org.objectweb.asm.commons.Remapper; | ||||
| 
 | ||||
| import net.fabricmc.stitch.util.Pair; | ||||
| import net.fabricmc.tinyremapper.IMappingProvider; | ||||
| import net.fabricmc.tinyremapper.InputTag; | ||||
| import net.fabricmc.tinyremapper.OutputConsumerPath; | ||||
| import net.fabricmc.tinyremapper.TinyRemapper; | ||||
| 
 | ||||
| public class JarRemapper { | ||||
| 	private final List<IMappingProvider> mappingProviders = new ArrayList<>(); | ||||
| 	private final Set<Path> classPath = new HashSet<>(); | ||||
| 	private final List<RemapData> remapData = new ArrayList<>(); | ||||
| 
 | ||||
| 	public void addMappings(IMappingProvider mappingProvider) { | ||||
| 		mappingProviders.add(mappingProvider); | ||||
| 	} | ||||
| 
 | ||||
| 	public void addToClasspath(Path... paths) { | ||||
| 		classPath.addAll(Arrays.asList(paths)); | ||||
| 	} | ||||
| 
 | ||||
| 	public RemapData scheduleRemap(Path input, Path output) { | ||||
| 		RemapData data = new RemapData(input, output); | ||||
| 		remapData.add(data); | ||||
| 		return data; | ||||
| 	} | ||||
| 
 | ||||
| 	public void remap() throws IOException { | ||||
| 		TinyRemapper.Builder remapperBuilder = TinyRemapper.newRemapper(); | ||||
| 		mappingProviders.forEach(remapperBuilder::withMappings); | ||||
| 
 | ||||
| 		TinyRemapper remapper = remapperBuilder.build(); | ||||
| 
 | ||||
| 		Path[] remapClasspath = classPath.stream() | ||||
| 				.filter(path -> | ||||
| 						remapData.stream().noneMatch(remapData -> remapData.input.equals(path)) | ||||
| 				) | ||||
| 				.toArray(Path[]::new); | ||||
| 
 | ||||
| 		remapper.readClassPathAsync(remapClasspath); | ||||
| 
 | ||||
| 		for (RemapData data : remapData) { | ||||
| 			InputTag tag = remapper.createInputTag(); | ||||
| 			data.tag = tag; | ||||
| 			remapper.readInputsAsync(tag, data.input); | ||||
| 		} | ||||
| 
 | ||||
| 		List<OutputConsumerPath> outputConsumers = new ArrayList<>(); | ||||
| 
 | ||||
| 		for (RemapData data : remapData) { | ||||
| 			OutputConsumerPath outputConsumer = new OutputConsumerPath.Builder(data.output).build(); | ||||
| 			outputConsumers.add(outputConsumer); | ||||
| 
 | ||||
| 			outputConsumer.addNonClassFiles(data.input); | ||||
| 
 | ||||
| 			data.processAccessWidener(remapper.getRemapper()); | ||||
| 			remapper.apply(outputConsumer, data.tag); | ||||
| 		} | ||||
| 
 | ||||
| 		remapper.finish(); | ||||
| 
 | ||||
| 		for (OutputConsumerPath outputConsumer : outputConsumers) { | ||||
| 			outputConsumer.close(); | ||||
| 		} | ||||
| 
 | ||||
| 		remapData.forEach(RemapData::complete); | ||||
| 	} | ||||
| 
 | ||||
| 	public static class RemapData { | ||||
| 		public final Path input; | ||||
| 		public final Path output; | ||||
| 		BiFunction<RemapData, Remapper, Pair<String, byte[]>> accesWidenerSupplier; | ||||
| 		BiConsumer<RemapData, Pair<String, byte[]>> onComplete; | ||||
| 
 | ||||
| 		private InputTag tag; | ||||
| 		private Pair<String, byte[]> accessWidener; | ||||
| 
 | ||||
| 		public RemapData(Path input, Path output) { | ||||
| 			this.input = input; | ||||
| 			this.output = output; | ||||
| 		} | ||||
| 
 | ||||
| 		public RemapData complete(BiConsumer<RemapData, Pair<String, byte[]>> onComplete) { | ||||
| 			this.onComplete = onComplete; | ||||
| 			return this; | ||||
| 		} | ||||
| 
 | ||||
| 		public RemapData supplyAccessWidener(BiFunction<RemapData, Remapper, Pair<String, byte[]>> beforeFinish) { | ||||
| 			this.accesWidenerSupplier = beforeFinish; | ||||
| 			return this; | ||||
| 		} | ||||
| 
 | ||||
| 		private void complete() { | ||||
| 			if (onComplete != null) { | ||||
| 				onComplete.accept(this, accessWidener); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		private void processAccessWidener(Remapper remapper) { | ||||
| 			if (accesWidenerSupplier != null) { | ||||
| 				accessWidener = accesWidenerSupplier.apply(this, remapper); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | @ -124,13 +124,7 @@ public class AccessWidenerJarProcessor implements JarProcessor { | |||
| 
 | ||||
| 	//Called when remapping the mod | ||||
| 	public void remapAccessWidener(Path modJarPath, Remapper asmRemapper) throws IOException { | ||||
| 		AccessWidenerRemapper remapper = new AccessWidenerRemapper(accessWidener, asmRemapper, "intermediary"); | ||||
| 		AccessWidener remapped = remapper.remap(); | ||||
| 
 | ||||
| 		StringWriter writer = new StringWriter(); | ||||
| 		remapped.write(writer); | ||||
| 		byte[] bytes = writer.toString().getBytes(); | ||||
| 		writer.close(); | ||||
| 		byte[] bytes = getRemappedAccessWidener(asmRemapper); | ||||
| 
 | ||||
| 		String path = getAccessWidenerPath(modJarPath); | ||||
| 
 | ||||
|  | @ -145,7 +139,17 @@ public class AccessWidenerJarProcessor implements JarProcessor { | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	private String getAccessWidenerPath(Path modJarPath) { | ||||
| 	public byte[] getRemappedAccessWidener(Remapper asmRemapper) throws IOException { | ||||
| 		AccessWidenerRemapper remapper = new AccessWidenerRemapper(accessWidener, asmRemapper, "intermediary"); | ||||
| 		AccessWidener remapped = remapper.remap(); | ||||
| 
 | ||||
| 		try (StringWriter writer = new StringWriter()) { | ||||
| 			remapped.write(writer); | ||||
| 			return writer.toString().getBytes(); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public String getAccessWidenerPath(Path modJarPath) { | ||||
| 		byte[] modJsonBytes = ZipUtil.unpackEntry(modJarPath.toFile(), "fabric.mod.json"); | ||||
| 
 | ||||
| 		if (modJsonBytes == null) { | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue