diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..fd2792b --- /dev/null +++ b/.gitattributes @@ -0,0 +1,44 @@ +* text eol=lf + +*.[jJ][aA][rR] binary + +*.[pP][nN][gG] binary +*.[jJ][pP][gG] binary +*.[jJ][pP][eE][gG] binary +*.[gG][iI][fF] binary +*.[tT][iI][fF] binary +*.[tT][iI][fF][fF] binary +*.[iI][cC][oO] binary +*.[sS][vV][gG] text +*.[eE][pP][sS] binary +*.[xX][cC][fF] binary + +*.[kK][aA][rR] binary +*.[mM]4[aA] binary +*.[mM][iI][dD] binary +*.[mM][iI][dD][iI] binary +*.[mM][pP]3 binary +*.[oO][gG][gG] binary +*.[rR][aA] binary + +*.7[zZ] binary +*.[gG][zZ] binary +*.[tT][aA][rR] binary +*.[tT][gG][zZ] binary +*.[zZ][iI][pP] binary + +*.[tT][cC][nN] binary +*.[sS][oO] binary +*.[dD][lL][lL] binary +*.[dD][yY][lL][iI][bB] binary +*.[pP][sS][dD] binary +*.[tT][tT][fF] binary +*.[oO][tT][fF] binary + +*.[pP][aA][tT][cC][hH] -text + +*.[bB][aA][tT] text eol=crlf +*.[cC][mM][dD] text eol=crlf +*.[pP][sS]1 text eol=crlf + +*[aA][uU][tT][oO][gG][eE][nN][eE][rR][aA][tT][eE][dD]* binary diff --git a/addon.gradle b/addon.gradle index e901806..59f13fa 100644 --- a/addon.gradle +++ b/addon.gradle @@ -1,9 +1,12 @@ import minetweaker.tasks.RegisterZenClassesTask -task makeRegistry(type: RegisterZenClassesTask) { - inputDir = file("build/classes/java/main/") - outputDir = file("build/classes/java/main/") - className = "minetweaker.mc1710.MineTweakerRegistry" +def makeRegistryTask = tasks.register('makeRegistry', RegisterZenClassesTask) { + dependsOn("compileJava") + inputDir.set(file("build/classes/java/main/")) + outputDir.set(file("build/classes/java/main/")) + className.set("minetweaker.mc1710.MineTweakerRegistry") } -tasks.classes.dependsOn(makeRegistry) +tasks.named("classes").configure { + dependsOn(makeRegistryTask) +} diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index 2033a16..009ac24 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -1,9 +1,21 @@ -import javax.tools.ToolProvider +import java.io.File -apply plugin: 'java' +plugins { + id("java") +} + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(8)) + vendor.set(JvmVendorSpec.ADOPTIUM) + } +} //Make sure JAVA_HOME is set as an environment variable -ext.javaToolsJar = ((URLClassLoader) ToolProvider.getSystemToolClassLoader()).getURLs() +ext.javaToolsJar = files( + javaToolchains.compilerFor(java.toolchain).map { tc -> + new File(tc.executablePath.asFile.parentFile.parentFile, "lib/tools.jar") + }) repositories { @@ -11,7 +23,7 @@ repositories { } dependencies { - compile gradleApi() - compile 'org.ow2.asm:asm-debug-all:5.0.3' - compile files(javaToolsJar) + gradleApi() + implementation 'org.ow2.asm:asm-debug-all:5.0.3' + implementation files(javaToolsJar) } diff --git a/buildSrc/src/main/java/minetweaker/tasks/RegisterZenClassesTask.java b/buildSrc/src/main/java/minetweaker/tasks/RegisterZenClassesTask.java index f070162..d7d4f6f 100644 --- a/buildSrc/src/main/java/minetweaker/tasks/RegisterZenClassesTask.java +++ b/buildSrc/src/main/java/minetweaker/tasks/RegisterZenClassesTask.java @@ -11,8 +11,11 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.gradle.api.DefaultTask; +import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.provider.Property; import org.gradle.api.tasks.Input; import org.gradle.api.tasks.InputDirectory; +import org.gradle.api.tasks.Optional; import org.gradle.api.tasks.OutputDirectory; import org.gradle.api.tasks.TaskAction; import org.objectweb.asm.AnnotationVisitor; @@ -28,61 +31,60 @@ import org.objectweb.asm.Type; * @ZenExpansion annotation and generates a class with a single static * getClasses(List) method. Overrides existing files if they exist. * (handy for having a stub in the original source) - * + * * @author Stan Hebben */ -public class RegisterZenClassesTask extends DefaultTask { +public abstract class RegisterZenClassesTask extends DefaultTask { @InputDirectory - public File inputDir; - + public abstract DirectoryProperty getInputDir(); + @OutputDirectory - public File outputDir = null; - - public void setInputDir(File inputDir) { - this.inputDir = inputDir; - } - - public void setOutputDir(File inputDir) { - this.outputDir = inputDir; - } + @Optional + public abstract DirectoryProperty getOutputDir(); @Input - public String className; - + public abstract Property getClassName(); + + public RegisterZenClassesTask() { + getOutputDir().convention(getInputDir()); + } + @TaskAction public void doTask() { - if (outputDir == null) outputDir = inputDir; - - List classNames = new ArrayList(); - List onRegisterMethods = new ArrayList(); + final File inputDir = getInputDir().get().getAsFile(); + final File outputDir = getOutputDir().get().getAsFile(); + final String className = getClassName().get(); + + List classNames = new ArrayList<>(); + List onRegisterMethods = new ArrayList<>(); iterate(inputDir, null, classNames, onRegisterMethods); - + String fullClassName = className.replace('.', '/'); - + // generate class ClassWriter output = new ClassWriter(ClassWriter.COMPUTE_MAXS); output.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC, fullClassName, null, "java/lang/Object", null); - + MethodVisitor method = output.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "getClasses", "(Ljava/util/List;)V", null, null); method.visitCode(); - + for (String clsName : classNames) { method.visitVarInsn(Opcodes.ALOAD, 0); method.visitLdcInsn(Type.getType("L" + clsName + ";")); - method.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "add", "(Ljava/lang/Object;)Z"); + method.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "add", "(Ljava/lang/Object;)Z", true); } - + for (OnRegisterMethod onRegisterMethod : onRegisterMethods) { - method.visitMethodInsn(Opcodes.INVOKESTATIC, onRegisterMethod.className, onRegisterMethod.methodName, "()V"); + method.visitMethodInsn(Opcodes.INVOKESTATIC, onRegisterMethod.className, onRegisterMethod.methodName, "()V", false); } - + method.visitInsn(Opcodes.RETURN); - + method.visitMaxs(0, 0); method.visitEnd(); - + output.visitEnd(); - + // write output file File outputFile = new File(outputDir, fullClassName + ".class"); File outputFileDir = outputFile.getParentFile(); @@ -92,16 +94,14 @@ public class RegisterZenClassesTask extends DefaultTask { if (outputFile.exists()) { outputFile.delete(); } - - try { - FileOutputStream outputStream = new FileOutputStream(outputFile); + + try(FileOutputStream outputStream = new FileOutputStream(outputFile)) { outputStream.write(output.toByteArray()); - outputStream.close(); } catch (IOException ex) { Logger.getLogger(RegisterZenClassesTask.class.getName()).log(Level.SEVERE, null, ex); } } - + private void iterate(File dir, String pkg, List classNames, List onRegisterMethods) { for (File f : dir.listFiles()) { if (f.isDirectory()) { @@ -117,16 +117,15 @@ public class RegisterZenClassesTask extends DefaultTask { } } } - + private void processJavaClass(File cls, String pkg, List classNames, List onRegisterMethods) { - try { - InputStream input = new BufferedInputStream(new FileInputStream(cls)); - ClassReader reader = new ClassReader(input); - + try(InputStream input = new BufferedInputStream(new FileInputStream(cls))) { + ClassReader reader = new ClassReader(input); + AnnotationDetector detector = new AnnotationDetector(); reader.accept(detector, ClassReader.SKIP_CODE); input.close(); - + if (detector.isAnnotated) { classNames.add(pkg + "/" + cls.getName().substring(0, cls.getName().length() - 6)); } @@ -136,18 +135,18 @@ public class RegisterZenClassesTask extends DefaultTask { onRegisterMethod.name)); } } catch (IOException ex) { - + } } - + private static class AnnotationDetector extends ClassVisitor { private boolean isAnnotated = false; - private List onRegister = new ArrayList(); - + private List onRegister = new ArrayList<>(); + public AnnotationDetector() { - super(Opcodes.ASM4); + super(Opcodes.ASM5); } - + @Override public AnnotationVisitor visitAnnotation(String desc, boolean visible) { if (desc.equals("Lstanhebben/zenscript/annotations/ZenExpansion;")) { @@ -157,29 +156,29 @@ public class RegisterZenClassesTask extends DefaultTask { } else if (desc.equals("Lminetweaker/annotations/BracketHandler;")) { isAnnotated = true; } - + return super.visitAnnotation(desc, visible); } - + @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { return new MethodAnnotationDetector(this, name, desc); } } - + private static class MethodAnnotationDetector extends MethodVisitor { private final AnnotationDetector detector; private final String name; private final String desc; - + public MethodAnnotationDetector(AnnotationDetector detector, String name, String desc) { super(Opcodes.ASM4); - + this.detector = detector; this.name = name; this.desc = desc; } - + @Override public AnnotationVisitor visitAnnotation(String desc, boolean visible) { if (desc.equals("Lminetweaker/annotations/OnRegister;")) { @@ -189,15 +188,15 @@ public class RegisterZenClassesTask extends DefaultTask { throw new RuntimeException("OnRegister annotation must be used on a static method without arguments or return value"); } } - + return super.visitAnnotation(desc, visible); } } - + private static class OnRegisterMethod { private final String className; private final String methodName; - + public OnRegisterMethod(String className, String methodName) { this.className = className; this.methodName = methodName; diff --git a/gradle.properties b/gradle.properties index dfed8a4..5fc37bd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -21,16 +21,19 @@ forgeVersion = 10.13.4.1614 # Do you need to test how your custom blocks interacts with a player that is not the owner? -> leave name empty developmentEnvironmentUserName = Developer -# Define a source file of your project with: -# public static final String VERSION = "GRADLETOKEN_VERSION"; -# The string's content will be replaced with your mod's version when compiled. You should use this to specify your mod's -# version in @Mod([...], version = VERSION, [...]) -# Leave these properties empty to skip individual token replacements -replaceGradleTokenInFile = MineTweakerMod.java +# Generate a class with String fields for the mod id, name, version and group name named with the fields below +generateGradleTokenClass = gradleTokenModId = gradleTokenModName = gradleTokenVersion = gradleTokenGroupName = +# [DEPRECATED] +# Multiple source files can be defined here by providing a comma-seperated list: Class1.java,Class2.java,Class3.java +# public static final String VERSION = "GRADLETOKEN_VERSION"; +# The string's content will be replaced with your mod's version when compiled. You should use this to specify your mod's +# version in @Mod([...], version = VERSION, [...]) +# Leave these properties empty to skip individual token replacements +replaceGradleTokenInFile = # In case your mod provides an API for other mods to implement you may declare its package here. Otherwise, you can # leave this property empty. diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..01ea5f1 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,28 @@ + +pluginManagement { + repositories { + maven { + // RetroFuturaGradle + name "GTNH Maven" + url "http://jenkins.usrv.eu:8081/nexus/content/groups/public/" + allowInsecureProtocol = true + mavenContent { + includeGroup("com.gtnewhorizons.retrofuturagradle") + } + } + gradlePluginPortal() + mavenCentral() + mavenLocal() + } +} + +plugins { + id 'com.diffplug.blowdryerSetup' version '1.6.0' + id 'org.gradle.toolchains.foojay-resolver-convention' version '0.4.0' // Provides java toolchains +} + +blowdryerSetup { + repoSubfolder 'gtnhShared' + github('GTNewHorizons/ExampleMod1.7.10', 'tag', '0.2.0') + //devLocal '.' // Use this when testing config updates locally +}