Revert "Remove a bunch of stuff + update to support modlauncher"
This reverts commit 6b59f9c
			
			
This commit is contained in:
		
							parent
							
								
									337bb1392e
								
							
						
					
					
						commit
						88315e4ccf
					
				
					 21 changed files with 934 additions and 11 deletions
				
			
		
							
								
								
									
										14
									
								
								build.gradle
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								build.gradle
									
									
									
									
									
								
							|  | @ -32,6 +32,10 @@ repositories { | |||
| 		name = 'Forge' //For ModLauncher | ||||
| 		url = 'http://files.minecraftforge.net/maven/' | ||||
| 	} | ||||
|     maven { | ||||
|         name = 'SpongePowered' | ||||
|         url = 'http://repo.spongepowered.org/maven' | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| configurations { | ||||
|  | @ -59,7 +63,15 @@ dependencies { | |||
| 	shade 'net.sf.jopt-simple:jopt-simple:5.0.4' | ||||
| 	shade 'org.apache.logging.log4j:log4j-api:2.11.0' | ||||
| 	shade 'org.apache.logging.log4j:log4j-core:2.11.0' | ||||
| 	shade 'cpw.mods:modlauncher:0.1.0-rc.3' | ||||
| 
 | ||||
|     shade ('net.minecraft:launchwrapper:1.12') { | ||||
|         transitive = false | ||||
|     } | ||||
|      | ||||
|     shade('org.spongepowered:mixin:0.7.11-SNAPSHOT') { | ||||
|         exclude module: 'launchwrapper' | ||||
|         exclude module: 'guava' | ||||
|     } | ||||
| 	shade 'org.apache.commons:commons-lang3:3.5' | ||||
| 
 | ||||
| } | ||||
|  |  | |||
							
								
								
									
										
											BIN
										
									
								
								gradle/wrapper/gradle-wrapper.jar
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								gradle/wrapper/gradle-wrapper.jar
									
									
									
									
										vendored
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										3
									
								
								gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
								
							|  | @ -1,5 +1,6 @@ | |||
| #Mon May 14 11:21:37 BST 2018 | ||||
| distributionBase=GRADLE_USER_HOME | ||||
| distributionPath=wrapper/dists | ||||
| distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip | ||||
| zipStoreBase=GRADLE_USER_HOME | ||||
| zipStorePath=wrapper/dists | ||||
| distributionUrl=https\://services.gradle.org/distributions/gradle-4.7-all.zip | ||||
|  |  | |||
|  | @ -87,6 +87,36 @@ public class AbstractPlugin implements Plugin<Project> { | |||
| 		configureIDEs(); | ||||
| 		configureCompile(); | ||||
| 
 | ||||
| 		Map<Project, Set<Task>> taskMap = project.getAllTasks(true); | ||||
| 		for (Map.Entry<Project, Set<Task>> entry : taskMap.entrySet()) { | ||||
| 			Project project = entry.getKey(); | ||||
| 			Set<Task> taskSet = entry.getValue(); | ||||
| 			for (Task task : taskSet) { | ||||
| 				if (task instanceof JavaCompile | ||||
| 					&& !(task.getName().contains("Test")) && !(task.getName().contains("test"))) { | ||||
| 					JavaCompile javaCompileTask = (JavaCompile) task; | ||||
| 					javaCompileTask.doFirst(task1 -> { | ||||
| 						project.getLogger().lifecycle(":setting java compiler args"); | ||||
| 						try { | ||||
| 							javaCompileTask.getClasspath().add(target.files(this.getClass().getProtectionDomain().getCodeSource().getLocation())); | ||||
| 
 | ||||
| 							javaCompileTask.getOptions().getCompilerArgs().add("-AinMapFilePomfMojang=" + Constants.MAPPINGS_TINY.get(extension).getCanonicalPath()); | ||||
| 							javaCompileTask.getOptions().getCompilerArgs().add("-AoutMapFilePomfMojang=" + Constants.MAPPINGS_MIXIN_EXPORT.get(extension).getCanonicalPath()); | ||||
| 							if(extension.refmapName == null || extension.refmapName.isEmpty()){ | ||||
| 								project.getLogger().error("Could not find refmap definition, will be using default name: " + project.getName() + "-refmap.json"); | ||||
| 								extension.refmapName = project.getName() + "-refmap.json"; | ||||
| 							} | ||||
| 							javaCompileTask.getOptions().getCompilerArgs().add("-AoutRefMapFile=" + new File(javaCompileTask.getDestinationDir(), extension.refmapName).getCanonicalPath()); | ||||
| 							javaCompileTask.getOptions().getCompilerArgs().add("-AdefaultObfuscationEnv=pomf:mojang"); | ||||
| 						} catch (IOException e) { | ||||
| 							e.printStackTrace(); | ||||
| 						} | ||||
| 					}); | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
|  | @ -187,6 +217,11 @@ public class AbstractPlugin implements Plugin<Project> { | |||
| 				mavenArtifactRepository.setUrl("https://maven.modmuss50.me/"); | ||||
| 			}); | ||||
| 
 | ||||
| 			project1.getRepositories().maven(mavenArtifactRepository -> { | ||||
| 				mavenArtifactRepository.setName("SpongePowered"); | ||||
| 				mavenArtifactRepository.setUrl("http://repo.spongepowered.org/maven"); | ||||
| 			}); | ||||
| 
 | ||||
| 			project1.getRepositories().maven(mavenArtifactRepository -> { | ||||
| 				mavenArtifactRepository.setName("Mojang"); | ||||
| 				mavenArtifactRepository.setUrl("https://libraries.minecraft.net/"); | ||||
|  |  | |||
|  | @ -33,6 +33,7 @@ public class LoomGradleExtension { | |||
| 	public String runDir = "run"; | ||||
| 	public String omlVersion; | ||||
| 	public String pomfVersion; | ||||
| 	public String refmapName; | ||||
| 	public boolean skipPrebake = false; | ||||
| 	public boolean localMappings = false; | ||||
| 
 | ||||
|  |  | |||
|  | @ -0,0 +1,144 @@ | |||
| /* | ||||
|  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||
|  * | ||||
|  * Copyright (c) 2016 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.mixin; | ||||
| 
 | ||||
| import net.fabricmc.tinyremapper.TinyUtils; | ||||
| import org.spongepowered.asm.obfuscation.mapping.common.MappingField; | ||||
| import org.spongepowered.asm.obfuscation.mapping.common.MappingMethod; | ||||
| import org.spongepowered.tools.obfuscation.mapping.common.MappingProvider; | ||||
| 
 | ||||
| import javax.annotation.processing.Filer; | ||||
| import javax.annotation.processing.Messager; | ||||
| import java.io.BufferedReader; | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.nio.file.Files; | ||||
| 
 | ||||
| public class MixinMappingProviderTiny extends MappingProvider { | ||||
| 	private final String from, to; | ||||
| 
 | ||||
| 	public MixinMappingProviderTiny(Messager messager, Filer filer, String from, String to) { | ||||
| 		super(messager, filer); | ||||
| 		this.from = from; | ||||
| 		this.to = to; | ||||
| 	} | ||||
| 
 | ||||
| 	private static final String[] removeFirst(String[] src, int count) { | ||||
| 		if (count >= src.length) { | ||||
| 			return new String[0]; | ||||
| 		} else { | ||||
| 			String[] out = new String[src.length - count]; | ||||
| 			System.arraycopy(src, count, out, 0, out.length); | ||||
| 			return out; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public MappingMethod getMethodMapping(MappingMethod method) { | ||||
| 		System.out.println("processing " + method.getName() + method.getDesc()); | ||||
| 
 | ||||
| 		MappingMethod mapped = this.methodMap.get(method); | ||||
| 		if (mapped != null) | ||||
| 			return mapped; | ||||
| 
 | ||||
| 		try { | ||||
| 			Class c = this.getClass().getClassLoader().loadClass(method.getOwner().replace('/', '.')); | ||||
| 			if (c == null || c == Object.class) { | ||||
| 				return null; | ||||
| 			} | ||||
| 
 | ||||
| 			for (Class cc : c.getInterfaces()) { | ||||
| 				mapped = getMethodMapping(method.move(cc.getName().replace('.', '/'))); | ||||
| 				if (mapped != null) | ||||
| 					return mapped; | ||||
| 			} | ||||
| 
 | ||||
| 			if (c.getSuperclass() != null) { | ||||
| 				mapped = getMethodMapping(method.move(c.getSuperclass().getName().replace('.', '/'))); | ||||
| 				if (mapped != null) | ||||
| 					return mapped; | ||||
| 			} | ||||
| 
 | ||||
| 			return null; | ||||
| 		} catch (Exception e) { | ||||
| 			e.printStackTrace(); | ||||
| 			return null; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public MappingField getFieldMapping(MappingField field) { | ||||
| 		System.out.println("processing " + field.getOwner() + "/" + field.getName() + field.getDesc()); | ||||
| 
 | ||||
| 		MappingField mapped = this.fieldMap.get(field); | ||||
| 		if (mapped != null) | ||||
| 			return mapped; | ||||
| 
 | ||||
| 		try { | ||||
| 			Class c = this.getClass().getClassLoader().loadClass(field.getOwner().replace('/', '.')); | ||||
| 			if (c == null || c == Object.class) { | ||||
| 				return null; | ||||
| 			} | ||||
| 
 | ||||
| 			for (Class cc : c.getInterfaces()) { | ||||
| 				mapped = getFieldMapping(field.move(cc.getName().replace('.', '/'))); | ||||
| 				if (mapped != null) | ||||
| 					return mapped; | ||||
| 			} | ||||
| 
 | ||||
| 			if (c.getSuperclass() != null) { | ||||
| 				mapped = getFieldMapping(field.move(c.getSuperclass().getName().replace('.', '/'))); | ||||
| 				if (mapped != null) | ||||
| 					return mapped; | ||||
| 			} | ||||
| 
 | ||||
| 			return null; | ||||
| 		} catch (Exception e) { | ||||
| 			e.printStackTrace(); | ||||
| 			return null; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// TODO: Unify with tiny-remapper | ||||
| 
 | ||||
| 	@Override | ||||
| 	public void read(File input) throws IOException { | ||||
| 		BufferedReader reader = Files.newBufferedReader(input.toPath()); | ||||
| 
 | ||||
| 		TinyUtils.read(reader, from, to, (classFrom, classTo) -> { | ||||
| 			classMap.put(classFrom, classTo); | ||||
| 		}, (fieldFrom, fieldTo) -> { | ||||
| 			fieldMap.put( | ||||
| 				new MappingField(fieldFrom.owner, fieldFrom.name, fieldFrom.desc), | ||||
| 				new MappingField(fieldTo.owner, fieldTo.name, fieldTo.desc) | ||||
| 			); | ||||
| 		}, (methodFrom, methodTo) -> { | ||||
| 			methodMap.put( | ||||
| 				new MappingMethod(methodFrom.owner, methodFrom.name, methodFrom.desc), | ||||
| 				new MappingMethod(methodTo.owner, methodTo.name, methodTo.desc) | ||||
| 			); | ||||
| 		}); | ||||
| 	} | ||||
| } | ||||
|  | @ -0,0 +1,75 @@ | |||
| /* | ||||
|  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||
|  * | ||||
|  * Copyright (c) 2016 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.mixin; | ||||
| 
 | ||||
| import org.spongepowered.asm.obfuscation.mapping.common.MappingField; | ||||
| import org.spongepowered.asm.obfuscation.mapping.common.MappingMethod; | ||||
| import org.spongepowered.tools.obfuscation.ObfuscationType; | ||||
| import org.spongepowered.tools.obfuscation.mapping.IMappingConsumer; | ||||
| import org.spongepowered.tools.obfuscation.mapping.common.MappingWriter; | ||||
| 
 | ||||
| import javax.annotation.processing.Filer; | ||||
| import javax.annotation.processing.Messager; | ||||
| import java.io.IOException; | ||||
| import java.io.PrintWriter; | ||||
| 
 | ||||
| /** | ||||
|  * Created by asie on 10/9/16. | ||||
|  */ | ||||
| public class MixinMappingWriterTiny extends MappingWriter { | ||||
| 	public MixinMappingWriterTiny(Messager messager, Filer filer) { | ||||
| 		super(messager, filer); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public void write(String output, ObfuscationType type, IMappingConsumer.MappingSet<MappingField> fields, IMappingConsumer.MappingSet<MappingMethod> methods) { | ||||
| 		if (output != null) { | ||||
| 			PrintWriter writer = null; | ||||
| 
 | ||||
| 			try { | ||||
| 				String from = type.getKey().split(":")[0]; | ||||
| 				String to = type.getKey().split(":")[1]; | ||||
| 
 | ||||
| 				writer = this.openFileWriter(output, type + " output TinyMappings"); | ||||
| 				writer.println(String.format("v1\t%s\t%s", from, to)); | ||||
| 				for (IMappingConsumer.MappingSet.Pair<MappingField> pair : fields) { | ||||
| 					writer.println(String.format("FIELD\t%s\t%s\t%s\t%s", pair.from.getOwner(), pair.from.getDesc(), pair.from.getSimpleName(), pair.to.getSimpleName())); | ||||
| 				} | ||||
| 				for (IMappingConsumer.MappingSet.Pair<MappingMethod> pair : methods) { | ||||
| 					writer.println(String.format("METHOD\t%s\t%s\t%s\t%s", pair.from.getOwner(), pair.from.getDesc(), pair.from.getSimpleName(), pair.to.getSimpleName())); | ||||
| 				} | ||||
| 			} catch (IOException e) { | ||||
| 				e.printStackTrace(); | ||||
| 			} finally { | ||||
| 				if (writer != null) { | ||||
| 					try { | ||||
| 						writer.close(); | ||||
| 					} catch (Exception e) { | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | @ -0,0 +1,77 @@ | |||
| package net.fabricmc.loom.mixin; | ||||
| 
 | ||||
| import com.google.common.io.ByteStreams; | ||||
| import net.fabricmc.loom.task.ProcessModsTask; | ||||
| import net.fabricmc.loom.util.proccessing.MixinPrebaker; | ||||
| import org.spongepowered.asm.service.IClassBytecodeProvider; | ||||
| import org.spongepowered.asm.service.mojang.MixinServiceLaunchWrapper; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| import java.util.Set; | ||||
| import java.util.jar.JarFile; | ||||
| import java.util.zip.ZipEntry; | ||||
| 
 | ||||
| public class MixinServiceGradle extends MixinServiceLaunchWrapper implements IClassBytecodeProvider { | ||||
| 
 | ||||
| 	private static List<JarFile> jars = new ArrayList<>(); | ||||
| 
 | ||||
| 
 | ||||
| 	@Override | ||||
| 	public String getName() { | ||||
| 		return "OpenModLoaderGradle"; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public InputStream getResourceAsStream(String name) { | ||||
| 		if(MixinPrebaker.jarFileCache.containsKey(name)){ | ||||
| 			return MixinPrebaker.jarFileCache.get(name); | ||||
| 		} | ||||
| 		for(JarFile file : jars){ | ||||
| 			ZipEntry entry = file.getEntry(name); | ||||
| 			if(entry != null){ | ||||
| 				try { | ||||
| 					InputStream stream = file.getInputStream(entry); | ||||
| 					return stream; | ||||
| 				} catch (IOException e) { | ||||
| 					throw new RuntimeException("Failed to read mod file", e); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		return super.getResourceAsStream(name); | ||||
| 	} | ||||
| 
 | ||||
| 	public static void setupModFiles(Set<File> mods, File minecraft) throws IOException { | ||||
| 		jars.clear(); | ||||
| 		for(File mod : mods){ | ||||
| 			JarFile jarFile = new JarFile(mod); | ||||
| 			jars.add(jarFile); | ||||
| 		} | ||||
| 		jars.add(new JarFile(minecraft)); | ||||
| 	} | ||||
| 
 | ||||
| 	public static void addMCDeps(Set<File> deps, Object object) throws IOException { | ||||
| 		for(File mod : deps){ | ||||
| 			JarFile jarFile = new JarFile(mod); | ||||
| 			jars.add(jarFile); | ||||
| 			ProcessModsTask.addFile(mod, object); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public IClassBytecodeProvider getBytecodeProvider() { | ||||
| 		return this; | ||||
| 	} | ||||
| 
 | ||||
| 	public byte[] getClassBytes(String name, String transformedName) throws IOException { | ||||
| 		InputStream inputStream = getResourceAsStream(name.replace(".", "/") + ".class"); | ||||
| 		byte[] classBytes = ByteStreams.toByteArray(inputStream); | ||||
| 		if(classBytes == null){ | ||||
| 			return super.getClassBytes(name, transformedName); | ||||
| 		} | ||||
| 		return classBytes; | ||||
| 	} | ||||
| } | ||||
|  | @ -0,0 +1,51 @@ | |||
| /* | ||||
|  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||
|  * | ||||
|  * Copyright (c) 2016 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.mixin; | ||||
| 
 | ||||
| import org.spongepowered.tools.obfuscation.ObfuscationEnvironment; | ||||
| import org.spongepowered.tools.obfuscation.ObfuscationType; | ||||
| import org.spongepowered.tools.obfuscation.mapping.IMappingProvider; | ||||
| import org.spongepowered.tools.obfuscation.mapping.IMappingWriter; | ||||
| 
 | ||||
| import javax.annotation.processing.Filer; | ||||
| import javax.annotation.processing.Messager; | ||||
| 
 | ||||
| public class ObfuscationEnvironmentFabric extends ObfuscationEnvironment { | ||||
| 	protected ObfuscationEnvironmentFabric(ObfuscationType type) { | ||||
| 		super(type); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected IMappingProvider getMappingProvider(Messager messager, Filer filer) { | ||||
| 		String from = type.getKey().split(":")[0]; | ||||
| 		String to = type.getKey().split(":")[1]; | ||||
| 		return new MixinMappingProviderTiny(messager, filer, from, to); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected IMappingWriter getMappingWriter(Messager messager, Filer filer) { | ||||
| 		return new MixinMappingWriterTiny(messager, filer); | ||||
| 	} | ||||
| } | ||||
|  | @ -0,0 +1,75 @@ | |||
| /* | ||||
|  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||
|  * | ||||
|  * Copyright (c) 2016 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.mixin; | ||||
| 
 | ||||
| import com.google.common.collect.ImmutableSet; | ||||
| import org.apache.commons.lang3.StringUtils; | ||||
| import org.spongepowered.tools.obfuscation.service.IObfuscationService; | ||||
| import org.spongepowered.tools.obfuscation.service.ObfuscationTypeDescriptor; | ||||
| 
 | ||||
| import java.util.Collection; | ||||
| import java.util.Set; | ||||
| 
 | ||||
| public class ObfuscationServiceFabric implements IObfuscationService { | ||||
| 	public static final String IN_MAP_FILE = "inMapFile"; | ||||
| 	public static final String IN_MAP_EXTRA_FILES = "inMapExtraFiles"; | ||||
| 	public static final String OUT_MAP_FILE = "outMapFile"; | ||||
| 
 | ||||
| 	private String asSuffixed(String arg, String from, String to) { | ||||
| 		return arg + StringUtils.capitalize(from) + StringUtils.capitalize(to); | ||||
| 	} | ||||
| 
 | ||||
| 	private ObfuscationTypeDescriptor createObfuscationType(String from, String to) { | ||||
| 		return new ObfuscationTypeDescriptor( | ||||
| 			from + ":" + to, | ||||
| 			asSuffixed(ObfuscationServiceFabric.IN_MAP_FILE, from, to), | ||||
| 			asSuffixed(ObfuscationServiceFabric.IN_MAP_EXTRA_FILES, from, to), | ||||
| 			asSuffixed(ObfuscationServiceFabric.OUT_MAP_FILE, from, to), | ||||
| 			ObfuscationEnvironmentFabric.class | ||||
| 		); | ||||
| 	} | ||||
| 
 | ||||
| 	private void addSupportedOptions(ImmutableSet.Builder builder, String from, String to) { | ||||
| 		builder.add(asSuffixed(ObfuscationServiceFabric.IN_MAP_FILE, from, to)); | ||||
| 		builder.add(asSuffixed(ObfuscationServiceFabric.IN_MAP_EXTRA_FILES, from, to)); | ||||
| 		builder.add(asSuffixed(ObfuscationServiceFabric.OUT_MAP_FILE, from, to)); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public Set<String> getSupportedOptions() { | ||||
| 		ImmutableSet.Builder builder = new ImmutableSet.Builder(); | ||||
| 		addSupportedOptions(builder, "mojang", "pomf"); | ||||
| 		addSupportedOptions(builder, "pomf", "mojang"); | ||||
| 		return builder.build(); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public Collection<ObfuscationTypeDescriptor> getObfuscationTypes() { | ||||
| 		return ImmutableSet.of( | ||||
| 			createObfuscationType("mojang", "pomf"), | ||||
| 			createObfuscationType("pomf", "mojang") | ||||
| 		); | ||||
| 	} | ||||
| } | ||||
|  | @ -135,22 +135,22 @@ public class GenIdeaProjectTask extends DefaultTask { | |||
| 		} | ||||
| 
 | ||||
| 		IdeaRunConfig ideaClient = new IdeaRunConfig(); | ||||
| 		ideaClient.mainClass = "cpw.mods.modlauncher.Launcher"; | ||||
| 		ideaClient.mainClass = "net.minecraft.launchwrapper.Launch"; | ||||
| 		ideaClient.projectName = project.getName(); | ||||
| 		ideaClient.configName = "Minecraft Client"; | ||||
| 		ideaClient.runDir = "file://$PROJECT_DIR$/" + extension.runDir; | ||||
| 		ideaClient.vmArgs = "-Djava.library.path=" + Constants.MINECRAFT_NATIVES.get(extension).getAbsolutePath() + " -Doml.development=true"; | ||||
| 		ideaClient.programArgs = "--launchTarget oml --accessToken not_a_real_token --version " + extension.version + " --assetIndex " + version.assetIndex.id + " --assetsDir " + new File(extension.getUserCache(), "assets-" + extension.version).getAbsolutePath(); | ||||
| 		ideaClient.programArgs = "--tweakClass com.openmodloader.loader.launch.OpenClientTweaker --assetIndex " + version.assetIndex.id + " --assetsDir " + new File(extension.getUserCache(), "assets-" + extension.version).getAbsolutePath(); | ||||
| 
 | ||||
| 		runManager.appendChild(ideaClient.genRuns(runManager)); | ||||
| 
 | ||||
| 		IdeaRunConfig ideaServer = new IdeaRunConfig(); | ||||
| 		ideaServer.mainClass = "com.openmodloader.loader.launch.ServerLauncher"; | ||||
| 		ideaServer.mainClass = "net.minecraft.launchwrapper.Launch"; | ||||
| 		ideaServer.projectName = project.getName(); | ||||
| 		ideaServer.configName = "Minecraft Server"; | ||||
| 		ideaServer.runDir = "file://$PROJECT_DIR$/" + extension.runDir; | ||||
| 		ideaServer.vmArgs = "-Doml.development=true"; | ||||
| 		ideaServer.programArgs = ""; | ||||
| 		ideaServer.programArgs = "--tweakClass com.openmodloader.loader.launch.OpenServerTweaker"; | ||||
| 
 | ||||
| 		runManager.appendChild(ideaServer.genRuns(runManager)); | ||||
| 
 | ||||
|  |  | |||
|  | @ -49,7 +49,7 @@ public class MapJarsTask extends DefaultTask { | |||
| 	@TaskAction | ||||
| 	public void mapJars() throws IOException, MappingParseException { | ||||
| 		LoomGradleExtension extension = this.getProject().getExtensions().getByType(LoomGradleExtension.class); | ||||
| 		if (!Constants.MINECRAFT_MAPPED_JAR.get(extension).exists() || extension.localMappings) { | ||||
| 		if (!Constants.MINECRAFT_MAPPED_JAR.get(extension).exists() || extension.localMappings || true) { | ||||
| 			if(extension.localMappings && Constants.MINECRAFT_MAPPED_JAR.get(extension).exists()){ | ||||
| 				//Always remap the jar when using local mappings. | ||||
| 				Constants.MINECRAFT_MAPPED_JAR.get(extension).delete(); | ||||
|  |  | |||
|  | @ -26,6 +26,7 @@ package net.fabricmc.loom.task; | |||
| 
 | ||||
| import net.fabricmc.loom.LoomGradleExtension; | ||||
| import net.fabricmc.loom.util.Constants; | ||||
| import net.fabricmc.loom.util.proccessing.PreBakeMixins; | ||||
| import org.apache.commons.io.FileUtils; | ||||
| import org.gradle.api.DefaultTask; | ||||
| import org.gradle.api.artifacts.Configuration; | ||||
|  | @ -56,10 +57,11 @@ public class ProcessModsTask extends DefaultTask { | |||
| 			Constants.MINECRAFT_FINAL_JAR.get(extension).delete(); | ||||
| 		} | ||||
| 		if (mods.size() == 0 || extension.skipPrebake) { | ||||
| 			getProject().getLogger().lifecycle(":skipping mixin prebake"); | ||||
| 			FileUtils.copyFile(Constants.MINECRAFT_MERGED_JAR.get(extension), Constants.MINECRAFT_MIXED_JAR.get(extension)); | ||||
| 		} else { | ||||
| //			downloadRequiredDeps(extension); | ||||
| 			throw new UnsupportedOperationException("Mixin prebake isnt done yet"); | ||||
| 			downloadRequiredDeps(extension); | ||||
| 			new PreBakeMixins().proccess(getProject(), extension, mods); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -73,7 +73,7 @@ public class RunClientTask extends JavaExec { | |||
| 
 | ||||
| 		classpath(libs); | ||||
| 
 | ||||
| 		args("--launchTarget", "oml", "--accessToken", "NOT_A_TOKEN", "--version", extension.version, "--assetIndex", version.assetIndex.id, "--assetsDir", new File(extension.getUserCache(), "assets-" + extension.version).getAbsolutePath()); | ||||
| 		args("--tweakClass", "com.openmodloader.loader.launch.OpenClientTweaker", "--assetIndex", version.assetIndex.id, "--assetsDir", new File(extension.getUserCache(), "assets-" + extension.version).getAbsolutePath()); | ||||
| 
 | ||||
| 		setWorkingDir(new File(getProject().getRootDir(), "run")); | ||||
| 
 | ||||
|  |  | |||
|  | @ -65,6 +65,8 @@ public class RunServerTask extends JavaExec { | |||
| 		libs.add(Constants.MINECRAFT_FINAL_JAR.get(extension).getAbsolutePath()); | ||||
| 		classpath(libs); | ||||
| 
 | ||||
| 		args("--tweakClass", "com.openmodloader.loader.launch.OpenServerTweaker"); | ||||
| 
 | ||||
| 		setWorkingDir(new File(getProject().getRootDir(), "run")); | ||||
| 
 | ||||
| 		super.exec(); | ||||
|  | @ -72,7 +74,7 @@ public class RunServerTask extends JavaExec { | |||
| 
 | ||||
| 	@Override | ||||
| 	public String getMain() { | ||||
| 		return "com.openmodloader.loader.launch.ServerLauncher"; | ||||
| 		return "net.minecraft.launchwrapper.Launch"; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
|  |  | |||
|  | @ -57,6 +57,7 @@ public class Constants { | |||
| 	public static final IDelayed<File> MINECRAFT_LIBS = new DelayedFile(extension -> new File(extension.getUserCache(), extension.version + "-libs")); | ||||
| 	public static final IDelayed<File> MINECRAFT_NATIVES = new DelayedFile(extension -> new File(extension.getUserCache(), extension.version + "-natives")); | ||||
| 	public static final IDelayed<File> MINECRAFT_JSON = new DelayedFile(extension -> new File(extension.getUserCache(), extension.version + "-info.json")); | ||||
| 	public static final IDelayed<File> REF_MAP = new DelayedFile(extension -> new File(CACHE_FILES, "mixin-refmap.json")); | ||||
| 
 | ||||
| 	public static final IDelayed<File> VERSION_MANIFEST = new DelayedFile(extension -> new File(extension.getUserCache(), "version_manifest.json")); | ||||
| 
 | ||||
|  |  | |||
|  | @ -0,0 +1,75 @@ | |||
| package net.fabricmc.loom.util.proccessing; | ||||
| 
 | ||||
| import com.google.common.collect.BiMap; | ||||
| import com.google.common.collect.HashBiMap; | ||||
| import net.fabricmc.tinyremapper.TinyUtils; | ||||
| import org.objectweb.asm.commons.Remapper; | ||||
| import org.spongepowered.asm.mixin.extensibility.IRemapper; | ||||
| 
 | ||||
| import java.io.BufferedReader; | ||||
| import java.io.IOException; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| public class MixinDevRemapper implements IRemapper { | ||||
| 	private final BiMap<String, String> classMap = HashBiMap.create(); | ||||
| 	private final Map<TinyUtils.Mapping, TinyUtils.Mapping> fieldMap = new HashMap<>(); | ||||
| 	private final Map<TinyUtils.Mapping, TinyUtils.Mapping> methodMap = new HashMap<>(); | ||||
| 
 | ||||
| 	private final SimpleClassMapper classMapper = new SimpleClassMapper(classMap); | ||||
| 	private final SimpleClassMapper classUnmapper = new SimpleClassMapper(classMap.inverse()); | ||||
| 
 | ||||
| 	private static class SimpleClassMapper extends Remapper { | ||||
| 		final Map<String, String> classMap; | ||||
| 
 | ||||
| 		public SimpleClassMapper(Map<String, String> map) { | ||||
| 			this.classMap = map; | ||||
| 		} | ||||
| 
 | ||||
| 		public String map(String typeName) { | ||||
| 			return this.classMap.getOrDefault(typeName, typeName); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public void readMapping(BufferedReader reader, String fromM, String toM) throws IOException { | ||||
| 		TinyUtils.read(reader, fromM, toM, classMap::put, fieldMap::put, methodMap::put); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public String mapMethodName(String owner, String name, String desc) { | ||||
| 		TinyUtils.Mapping mapping = methodMap.get(new TinyUtils.Mapping(owner, name, desc)); | ||||
| 		return mapping != null ? mapping.name : name; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public String mapFieldName(String owner, String name, String desc) { | ||||
| 		TinyUtils.Mapping mapping = fieldMap.get(new TinyUtils.Mapping(owner, name, desc)); | ||||
| 		if(mapping == null){ | ||||
| 			//We try again using obfed names | ||||
| 			owner = unmap(owner); | ||||
| 			desc = unmapDesc(desc); | ||||
| 			mapping = fieldMap.get(new TinyUtils.Mapping(owner, name, desc)); | ||||
| 		} | ||||
| 		return mapping != null ? mapping.name : name; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public String map(String typeName) { | ||||
| 		return classMap.getOrDefault(typeName, typeName); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public String unmap(String typeName) { | ||||
| 		return classMap.inverse().getOrDefault(typeName, typeName); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public String mapDesc(String desc) { | ||||
| 		return classMapper.mapDesc(desc); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public String unmapDesc(String desc) { | ||||
| 		return classUnmapper.mapDesc(desc); | ||||
| 	} | ||||
| } | ||||
|  | @ -0,0 +1,317 @@ | |||
| /* | ||||
|  * Copyright 2016 FabricMC | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
| package net.fabricmc.loom.util.proccessing; | ||||
| 
 | ||||
| import com.google.common.base.Charsets; | ||||
| import com.google.common.base.Predicate; | ||||
| import com.google.common.io.ByteStreams; | ||||
| import com.google.gson.Gson; | ||||
| import com.google.gson.JsonArray; | ||||
| import com.google.gson.JsonObject; | ||||
| import net.fabricmc.loom.mixin.MixinServiceGradle; | ||||
| import net.minecraft.launchwrapper.Launch; | ||||
| import net.minecraft.launchwrapper.LaunchClassLoader; | ||||
| import org.gradle.api.Project; | ||||
| import org.objectweb.asm.*; | ||||
| import org.spongepowered.asm.launch.GlobalProperties; | ||||
| import org.spongepowered.asm.launch.MixinBootstrap; | ||||
| import org.spongepowered.asm.mixin.EnvironmentStateTweaker; | ||||
| import org.spongepowered.asm.mixin.MixinEnvironment; | ||||
| import org.spongepowered.asm.mixin.Mixins; | ||||
| import org.spongepowered.asm.mixin.transformer.MixinTransformer; | ||||
| import org.spongepowered.asm.service.MixinService; | ||||
| import org.spongepowered.asm.service.mojang.MixinServiceLaunchWrapper; | ||||
| 
 | ||||
| import javax.annotation.Nonnull; | ||||
| import java.io.*; | ||||
| import java.net.URLClassLoader; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.attribute.FileTime; | ||||
| import java.time.Instant; | ||||
| import java.util.*; | ||||
| import java.util.jar.JarEntry; | ||||
| import java.util.jar.JarFile; | ||||
| import java.util.jar.JarInputStream; | ||||
| import java.util.jar.JarOutputStream; | ||||
| import java.util.stream.Collectors; | ||||
| import java.util.zip.ZipEntry; | ||||
| 
 | ||||
| /** | ||||
|  * The purpose of this class is to provide an utility for baking mixins from | ||||
|  * mods into a JAR file at compile time to make accessing APIs provided by them | ||||
|  * more intuitive in development environment. | ||||
|  */ | ||||
| public class MixinPrebaker { | ||||
| 	private static class DesprinklingFieldVisitor extends FieldVisitor { | ||||
| 		public DesprinklingFieldVisitor(int api, FieldVisitor fv) { | ||||
| 			super(api, fv); | ||||
| 		} | ||||
| 
 | ||||
| 		@Override | ||||
| 		public AnnotationVisitor visitAnnotation(String desc, boolean visible) { | ||||
| 			if (isSprinkledAnnotation(desc)) { | ||||
| 				return null; | ||||
| 			} | ||||
| 			return super.visitAnnotation(desc, visible); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	private static class DesprinklingMethodVisitor extends MethodVisitor { | ||||
| 		public DesprinklingMethodVisitor(int api, MethodVisitor mv) { | ||||
| 			super(api, mv); | ||||
| 		} | ||||
| 
 | ||||
| 		@Override | ||||
| 		public AnnotationVisitor visitAnnotation(String desc, boolean visible) { | ||||
| 			if (isSprinkledAnnotation(desc)) { | ||||
| 				return null; | ||||
| 			} | ||||
| 			return super.visitAnnotation(desc, visible); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	private static class DesprinklingClassVisitor extends ClassVisitor { | ||||
| 		public DesprinklingClassVisitor(int api, ClassVisitor cv) { | ||||
| 			super(api, cv); | ||||
| 		} | ||||
| 
 | ||||
| 		@Override | ||||
| 		public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { | ||||
| 			return new DesprinklingFieldVisitor(Opcodes.ASM5, super.visitField(access, name, desc, signature, value)); | ||||
| 		} | ||||
| 
 | ||||
| 		@Override | ||||
| 		public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { | ||||
| 			return new DesprinklingMethodVisitor(Opcodes.ASM5, super.visitMethod(access, name, desc, signature, exceptions)); | ||||
| 		} | ||||
| 
 | ||||
| 		@Override | ||||
| 		public AnnotationVisitor visitAnnotation(String desc, boolean visible) { | ||||
| 			if (isSprinkledAnnotation(desc)) { | ||||
| 				return null; | ||||
| 			} | ||||
| 			return super.visitAnnotation(desc, visible); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	private static boolean isSprinkledAnnotation(String desc) { | ||||
| 		//System.out.println(desc); | ||||
| 		return desc.startsWith("Lorg/spongepowered/asm/mixin/transformer/meta"); | ||||
| 	} | ||||
| 
 | ||||
| 	// Term proposed by Mumfrey, don't blame me | ||||
| 	public static byte[] desprinkle(byte[] cls) { | ||||
| 		ClassReader reader = new ClassReader(cls); | ||||
| 		ClassWriter writer = new ClassWriter(0); | ||||
| 
 | ||||
| 		reader.accept(new DesprinklingClassVisitor(Opcodes.ASM5, writer), 0); | ||||
| 		return writer.toByteArray(); | ||||
| 	} | ||||
| 
 | ||||
| 	public static final String APPLIED_MIXIN_CONFIGS_FILENAME = ".oml-applied-mixin-configs"; | ||||
| 	public static final String MAPPINGS_FILENAME = ".oml-dev-mappings.tiny"; | ||||
| 
 | ||||
| 	public static Map<String, InputStream> jarFileCache = new HashMap<>(); | ||||
| 
 | ||||
| 	public static void main(String[] args, Project project) throws IOException { | ||||
| 		boolean hasMappingsFile = false; | ||||
| 
 | ||||
| 		if (args.length < 3) { | ||||
| 			System.out.println("usage: MixinPrebaker [-m mapping-file] <input-jar> <output-jar> <mod-jars...>"); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		File mappingsFile = null; | ||||
| 		int argOffset; | ||||
| 		for (argOffset = 0; argOffset < args.length; argOffset++) { | ||||
| 			if ("-m".equals(args[argOffset])) { | ||||
| 				hasMappingsFile = true; | ||||
| 				mappingsFile = new File(args[++argOffset]); | ||||
| 				//TODO this is prob what was handling the mixin remmapping, this may need to be added back | ||||
| 				//FabricMixinBootstrap.setMappingFile(); | ||||
| 			} else { | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 		Set<File> modFiles = new HashSet<>(); | ||||
| 		for (int i = argOffset + 2; i < args.length; i++) { | ||||
| 			modFiles.add(new File(args[i])); | ||||
| 		} | ||||
| 
 | ||||
| 		URLClassLoader ucl = (URLClassLoader) MixinPrebaker.class.getClassLoader(); | ||||
| 		Launch.classLoader = new LaunchClassLoader(ucl.getURLs()); | ||||
| 		Launch.blackboard = new HashMap<>(); | ||||
| 		Launch.blackboard.put(MixinServiceLaunchWrapper.BLACKBOARD_KEY_TWEAKS, Collections.emptyList()); | ||||
| 
 | ||||
| 		List<JsonObject> mods = findModInfo(modFiles); | ||||
| 		System.out.println("Found " + mods.size() + " mods"); | ||||
| 		List<String> mixins = new ArrayList<>(); | ||||
| 		for(JsonObject modObject : mods){ | ||||
| 			mixins.addAll(findMixins(modObject.getAsJsonArray("mixins"))); | ||||
| 			mixins.addAll(findMixins(modObject.getAsJsonArray("clientMixins"))); | ||||
| 			mixins.addAll(findMixins(modObject.getAsJsonArray("serverMixins"))); | ||||
| 		} | ||||
| 		System.out.println("Found " + mixins.size() + " mixins to pre bake"); | ||||
| 
 | ||||
| 		List<String> tweakers = new ArrayList<>(); | ||||
| 		tweakers.add("com.openmodloader.loader.launch.OpenTweaker"); | ||||
| 		GlobalProperties.put("TweakClasses", tweakers); | ||||
| 
 | ||||
| 		MixinBootstrap.init(); | ||||
| 		mixins.forEach(Mixins::addConfiguration); | ||||
| 
 | ||||
| 		MixinServiceGradle.setupModFiles(modFiles, new File(args[argOffset + 0])); | ||||
| 
 | ||||
| 
 | ||||
| 		EnvironmentStateTweaker tweaker = new EnvironmentStateTweaker(); | ||||
| 		tweaker.getLaunchArguments(); | ||||
| 		tweaker.injectIntoClassLoader(Launch.classLoader); | ||||
| 
 | ||||
| 		//MixinServiceGradle.addMCDeps(project.getConfigurations().getByName(Constants.CONFIG_MC_DEPENDENCIES).getFiles(), tweaker); | ||||
| 
 | ||||
| 		MixinEnvironment mixinEnvironment = MixinEnvironment.getDefaultEnvironment(); | ||||
| 
 | ||||
| 		System.out.println("Loading mappings: " + mappingsFile); | ||||
| 		InputStream mappingStream = new FileInputStream(mappingsFile); | ||||
| 		MixinDevRemapper devRemapper = new MixinDevRemapper(); | ||||
| 		devRemapper.readMapping(new BufferedReader(new InputStreamReader(mappingStream)), "pomf", "mojang"); | ||||
| 		mappingStream.close(); | ||||
| 		mixinEnvironment.getRemappers().add(devRemapper); | ||||
| 
 | ||||
| 		mixinEnvironment.setSide(MixinEnvironment.Side.CLIENT); //TODO have an all side? | ||||
| 
 | ||||
| 
 | ||||
| 		MixinTransformer mixinTransformer = GlobalProperties.get(GlobalProperties.Keys.TRANSFORMER); | ||||
| 		if(mixinTransformer == null){ | ||||
| 			MixinService.getService().beginPhase(); | ||||
| 			mixinTransformer = GlobalProperties.get(GlobalProperties.Keys.TRANSFORMER); | ||||
| 		} | ||||
| 		mixinTransformer.audit(mixinEnvironment); | ||||
| 
 | ||||
| 
 | ||||
| 		try { | ||||
| 			JarInputStream input = new JarInputStream(new FileInputStream(new File(args[argOffset + 0]))); | ||||
| 			JarOutputStream output = new JarOutputStream(new FileOutputStream(new File(args[argOffset + 1]))); | ||||
| 			JarEntry entry; | ||||
| 			while ((entry = input.getNextJarEntry()) != null) { | ||||
| 				if (entry.getName().equals(APPLIED_MIXIN_CONFIGS_FILENAME)) { | ||||
| 					continue; | ||||
| 				} | ||||
| 
 | ||||
| 				if (hasMappingsFile && entry.getName().equals(MAPPINGS_FILENAME)) { | ||||
| 					continue; | ||||
| 				} | ||||
| 
 | ||||
| 				if (entry.getName().endsWith(".class")) { | ||||
| 					byte[] classIn = ByteStreams.toByteArray(input); | ||||
| 					String className = entry.getName().substring(0, entry.getName().length() - 6).replace('/', '.'); | ||||
| 					byte[] classOut = mixinTransformer.transformClassBytes(className, className, classIn); | ||||
| 					if (classIn != classOut) { | ||||
| 						System.out.println("Transformed " + className); | ||||
| 						classOut = desprinkle(classOut); | ||||
| 					} | ||||
| 					JarEntry newEntry = new JarEntry(entry.getName()); | ||||
| 					newEntry.setComment(entry.getComment()); | ||||
| 					newEntry.setSize(classOut.length); | ||||
| 					newEntry.setLastModifiedTime(FileTime.from(Instant.now())); | ||||
| 					output.putNextEntry(newEntry); | ||||
| 					output.write(classOut); | ||||
| 				} else { | ||||
| 					output.putNextEntry(entry); | ||||
| 					ByteStreams.copy(input, output); | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			output.putNextEntry(new JarEntry(APPLIED_MIXIN_CONFIGS_FILENAME)); | ||||
| 			output.write(String.join("\n", mixins).getBytes(Charsets.UTF_8)); | ||||
| 
 | ||||
| 			if (hasMappingsFile) { | ||||
| 				output.putNextEntry(new JarEntry(MAPPINGS_FILENAME)); | ||||
| 				Files.copy(mappingsFile.toPath(), output); | ||||
| 			} | ||||
| 
 | ||||
| 			input.close(); | ||||
| 			output.close(); | ||||
| 		} catch (IOException e) { | ||||
| 			throw new RuntimeException(e); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	private static List<String> findMixins(JsonArray jsonArray){ | ||||
| 		if(jsonArray == null || jsonArray.size() == 0){ | ||||
| 			return Collections.emptyList(); | ||||
| 		} | ||||
| 		List<String> mixinList = new ArrayList<>(); | ||||
| 		for (int i = 0; i < jsonArray.size(); i++) { | ||||
| 			mixinList.add(jsonArray.get(i).getAsString()); | ||||
| 		} | ||||
| 		return mixinList; | ||||
| 	} | ||||
| 
 | ||||
| 	private static List<JsonObject> findModInfo(Set<File> mods){ | ||||
| 		List<JsonArray> modFiles = mods.stream().map(file -> { | ||||
| 			try { | ||||
| 				JarFile jar = new JarFile(file); | ||||
| 				return readModInfoFromJar(jar); | ||||
| 			} catch (IOException e) { | ||||
| 				throw new RuntimeException("Failed to mod " + file.getName(), e); | ||||
| 			} | ||||
| 		}).filter((Predicate<JsonArray>) Objects::nonNull).collect(Collectors.toList()); | ||||
| 
 | ||||
| 		List<JsonObject> containedMods = new ArrayList<>(); | ||||
| 		for(JsonArray modFile : modFiles){ | ||||
| 			for (int i = 0; i < modFile.size(); i++) { | ||||
| 				containedMods.add(modFile.get(i).getAsJsonObject()); | ||||
| 			} | ||||
| 		} | ||||
| 		return containedMods; | ||||
| 	} | ||||
| 
 | ||||
| 	private static JsonArray readModInfoFromJar(@Nonnull JarFile file) throws IOException { | ||||
| 		Gson gson = new Gson(); | ||||
| 		ZipEntry entry = file.getEntry("mod.json"); | ||||
| 		if (entry == null) | ||||
| 			return null; | ||||
| 
 | ||||
| 		InputStreamReader stream = new InputStreamReader(file.getInputStream(entry)); | ||||
| 		JsonArray jsonArray = gson.fromJson(stream, JsonArray.class); | ||||
| 		stream.close(); | ||||
| 
 | ||||
| 		List<String> mixins = new ArrayList<>(); | ||||
| 		for (int i = 0; i < jsonArray.size(); i++) { | ||||
| 			JsonObject modObject = jsonArray.get(i).getAsJsonObject(); | ||||
| 			mixins.addAll(findMixins(modObject.getAsJsonArray("mixins"))); | ||||
| 			mixins.addAll(findMixins(modObject.getAsJsonArray("clientMixins"))); | ||||
| 			mixins.addAll(findMixins(modObject.getAsJsonArray("serverMixins"))); | ||||
| 		} | ||||
| 
 | ||||
| 		System.out.println("Found: " + mixins.size() + " mixins in " + file.getName()); | ||||
| 
 | ||||
| 		mixins.forEach(s -> { | ||||
| 			ZipEntry entry1 = file.getEntry(s); | ||||
| 			try { | ||||
| 				jarFileCache.put(s, file.getInputStream(entry1)); | ||||
| 			} catch (IOException e) { | ||||
| 				throw new RuntimeException("Failed to load jar", e); | ||||
| 			} | ||||
| 		}); | ||||
| 		return jsonArray; | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
|  | @ -0,0 +1,53 @@ | |||
| /* | ||||
|  * This file is part of fabric-loom, licensed under the MIT License (MIT). | ||||
|  * | ||||
|  * Copyright (c) 2016 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.proccessing; | ||||
| 
 | ||||
| import net.fabricmc.loom.LoomGradleExtension; | ||||
| import net.fabricmc.loom.task.ProcessModsTask; | ||||
| import net.fabricmc.loom.util.Constants; | ||||
| import org.gradle.api.Project; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.util.List; | ||||
| 
 | ||||
| public class PreBakeMixins { | ||||
| 
 | ||||
| 	public void proccess(Project project, LoomGradleExtension extension, List<File> mods) throws IOException { | ||||
| 		project.getLogger().lifecycle(":Found " + mods.size() + " mods to prebake"); | ||||
| 		String[] args = new String[mods.size() + 4]; | ||||
| 		args[0] = "-m"; | ||||
| 		args[1] = Constants.MAPPINGS_TINY.get(extension).getAbsolutePath(); | ||||
| 		args[2] = Constants.MINECRAFT_MERGED_JAR.get(extension).getAbsolutePath(); | ||||
| 		args[3] = Constants.MINECRAFT_MIXED_JAR.get(extension).getAbsolutePath(); | ||||
| 		for (int i = 0; i < mods.size(); i++) { | ||||
| 			args[i + 4] = mods.get(i).getAbsolutePath(); | ||||
| 		} | ||||
| 		project.getLogger().lifecycle(":preBaking mixins"); | ||||
| 		ProcessModsTask.addFile(Constants.MINECRAFT_MIXED_JAR.get(extension), this); | ||||
| 		MixinPrebaker.main(args, project); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
|  | @ -0,0 +1 @@ | |||
| net.fabricmc.loom.mixin.MixinServiceGradle | ||||
|  | @ -0,0 +1 @@ | |||
| net.fabricmc.loom.mixin.ObfuscationServiceFabric | ||||
		Loading…
	
		Reference in a new issue