From 53d56c950e2cb15981f927132a2b37e04e8a0ebc Mon Sep 17 00:00:00 2001 From: VDeltaGabriel Date: Thu, 30 Jul 2026 14:59:39 +0200 Subject: [PATCH 1/2] Migrated to gradle system mk. X and added publishing module --- build.gradle | 98 ++++++--- gradle.properties | 142 ++++++++----- gradle/boilerplate.gradle | 196 ------------------ gradle/codesign.gradle | 77 ------- gradle/corejar.gradle | 40 ---- gradle/docs/setup.txt | 140 ++++--------- gradle/ieaddon.gradle | 119 ----------- gradle/junit.gradle | 24 --- gradle/modworks.gradle | 34 --- gradle/scripts/cleanroom.gradle | 173 ++++++++++++++++ gradle/scripts/corejar.gradle | 59 ++++++ gradle/scripts/dependencies.gradle | 34 +++ gradle/scripts/helpers.gradle | 59 ++++++ gradle/scripts/ide.gradle | 32 +++ gradle/scripts/junit.gradle | 24 +++ gradle/scripts/lombok.gradle | 6 + gradle/scripts/modworks.gradle | 58 ++++++ gradle/scripts/publishing.gradle | 45 ++++ gradle/scripts/repositories.gradle | 32 +++ gradle/scripts/signing.gradle | 61 ++++++ gradle/scripts/spotless.gradle | 25 +++ gradle/tools/opti.sh | 15 +- gradle/wrapper/gradle-wrapper.properties | 2 +- settings.gradle | 34 +++ .../models/item/minecart/metal_barrel.json | 6 - .../immersiveintelligence_at.cfg | 0 src/main/resources/mcmod.info | 25 +-- src/main/resources/pack.mcmeta | 2 +- 28 files changed, 865 insertions(+), 697 deletions(-) delete mode 100644 gradle/boilerplate.gradle delete mode 100644 gradle/codesign.gradle delete mode 100644 gradle/corejar.gradle delete mode 100644 gradle/ieaddon.gradle delete mode 100644 gradle/junit.gradle delete mode 100644 gradle/modworks.gradle create mode 100644 gradle/scripts/cleanroom.gradle create mode 100644 gradle/scripts/corejar.gradle create mode 100644 gradle/scripts/dependencies.gradle create mode 100644 gradle/scripts/helpers.gradle create mode 100644 gradle/scripts/ide.gradle create mode 100644 gradle/scripts/junit.gradle create mode 100644 gradle/scripts/lombok.gradle create mode 100644 gradle/scripts/modworks.gradle create mode 100644 gradle/scripts/publishing.gradle create mode 100644 gradle/scripts/repositories.gradle create mode 100644 gradle/scripts/signing.gradle create mode 100644 gradle/scripts/spotless.gradle create mode 100644 settings.gradle delete mode 100644 src/main/resources/assets/immersiveintelligence/models/item/minecart/metal_barrel.json rename src/main/resources/{META-INF => }/immersiveintelligence_at.cfg (100%) diff --git a/build.gradle b/build.gradle index efa8b1353..6f1687bab 100644 --- a/build.gradle +++ b/build.gradle @@ -1,36 +1,80 @@ -//--- Boilerplate -buildscript { - repositories { - mavenCentral() - maven { - name = "forge" - url = "https://maven.minecraftforge.net/" - } - maven { - name = "iiMavenReleases" - url = uri("https://maven.iiteam.net/releases") - } - maven { - name = "sonatype" - url = "https://oss.sonatype.org/content/repositories/snapshots/" - } +/** + * Team Immersive Intelligence Mk. X Build System template. + */ +plugins { + id 'java' + id 'java-library' + id 'maven-publish' + id 'idea' + id 'org.jetbrains.gradle.plugin.idea-ext' version '1.4.1' + id 'com.gtnewhorizons.retrofuturagradle' version '2.0.2' + id 'com.diffplug.spotless' version '8.6.0' apply false +} +import org.jetbrains.gradle.ext.Gradle - } - dependencies { - classpath("com.anatawa12.forge:ForgeGradle:2.3-1.0.+") { - changing = true - } +// The ancient pact must be honoured as soon as the root build script is evaluated. +def mkxGradlephant = rootProject.file('gradle/docs/gradlephant.txt') +if (mkxGradlephant.isFile()) + logger.lifecycle('\n' + mkxGradlephant.getText('UTF-8')) +else + logger.warn('[Mk.X] Gradlephant banner missing: {}', mkxGradlephant) - classpath('xyz.vdeltagabriel:GradleUtils:2.1.0') - } +apply from: rootProject.file('gradle/scripts/helpers.gradle') + +mkxAssertProperties('mod_version', 'mod_group', 'mod_package', 'mod_id', 'mod_name') + +version = mkxString('mod_version') +group = mkxString('mod_group') + +base { + archivesName.set(mkxString('archives_base_name', mkxString('mod_id'))) } -// Apply boilerplate code -apply from: rootProject.file('gradle/boilerplate.gradle') +apply from: rootProject.file('gradle/scripts/cleanroom.gradle') + +def customGradle = rootProject.file('custom.gradle') +if (customGradle.exists()) { + logger.lifecycle('[Mk.X] applying local custom.gradle') + apply from: customGradle +} -//--- Dependencies +gradle.ext.mkxScriptSwitches.each { propertyName, scriptPath -> + mkxApplyScript(propertyName as String, scriptPath as String) +} -repositories { +if (mkxBool('ii_script_ide', false)) { + idea.project.settings.runConfigurations { + 'Setup Mod Workspace'(Gradle) { + taskNames = ['setupDecompWorkspace','mkxAfterSync'] + } + 'Run Client'(Gradle) { + taskNames = ['runClient -Dforge.logging.markers=REGISTRIES -Dforge.logging.console.level=debug'] + } + 'Run Client 2'(Gradle) { + taskNames = ['runClient -Dforge.logging.markers=REGISTRIES -Dforge.logging.console.level=debug --username=TestSubject'] + } + 'Run Server'(Gradle) { + taskNames = ['runServer'] + } + 'Build Mod Jar'(Gradle) { + taskNames = ['build'] + } + } } +tasks.register('mkxSetupDocs') { + group = 'help' + description = 'Prints gradle/docs/setup.txt.' + doLast { + def setupDocument = rootProject.file('gradle/docs/setup.txt') + if (!setupDocument.isFile()) + throw new GradleException("Mk. X setup document is missing: ${setupDocument}") + println setupDocument.getText('UTF-8') + } +} +tasks.named('build').configure { + doLast { + logger.lifecycle('[Mk.X] artifacts written to {}', layout.buildDirectory.dir('libs').get().asFile) + } +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 2ad2b667c..f2fdb0229 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,49 +1,97 @@ -# Sets default memory used for gradle commands. Can be overridden by user or command line properties. -# This is required to provide enough memory for the Minecraft decompilation process. -org.gradle.jvmargs=-Xmx3G -# Script definitions - DO NOT CHANGE -getOr= -logFile= -printDocs= -#MCMOD.INFO -mcmod_Name=Immersive Intelligence -mcmod_URL=https://www.curseforge.com/minecraft/mc-mods/immersive-intelligence -mcmod_Description=Adds new machines related to data, logistics, warfare and intelligence. -mcmod_Developer=Team Immersive Intelligence -mcmod_Contributors=Pabilo8,Carver,SchäferdCZ,Bastian,GabrielV -#Forge Data -modForge=1.12.2-14.23.5.2847 -modMappings=snapshot_20171003 -#Project Data -modVersion=0.3.1-dev5 -modGroup=pl.pabilo8 -modName=immersiveintelligence -# Private Team II Maven -#ii_MavenUser= -#ii_MavenToken= -# Boilerplate Script Settings -ii_useModworksPreprocessor=true -ii_useJUnit=true -ii_printSourceSets=true -ii_printOutputDir=true -# CoreJar Script Settings -ii_generateCoreJar=true -modATPath=immersiveintelligence_at.cfg -modASMPath=pl/pabilo8/immersiveintelligence/common/asm/** -modASMClass=pl.pabilo8.immersiveintelligence.common.asm.IILoadingPlugin -# Jar Signing -ii_enableSigning=true -timestamp_url= -ksalias= -keystore= -storepass= -keypass= -# II Maven -ii_authToIIMaven=false -iiMavenReleasesUsername= -iiMavenReleasesPassword -# Gradlephant Banner -ii_gradlephantTitle=A mod brought to you by Team II -ii_gradlephantLink=Check out our Github: https://github.com/Team-Immersive-Intelligence/ImmersiveIntelligence +# Gradle +org.gradle.jvmargs=-Xmx3G -Dfile.encoding=UTF-8 +org.gradle.parallel=true +org.gradle.caching=true + +# Minecraft / Forge / mappings +minecraft_version=1.12.2 +forge_version=14.23.5.2847 +mapping_channel=snapshot +mapping_version=20171004 +use_dependency_at_files=true +minecraft_username=Pabilo8 + +# Project identity +mod_version=0.3.1-dev5 +mod_group=pl.pabilo8 +mod_package=pl.pabilo8.immersiveintelligence +mod_id=immersiveintelligence +mod_name=Immersive Intelligence +mod_description=Adds new machines related to data, logistics, warfare and intelligence. +mod_url=https://github.com/Team-Immersive-Intelligence/ImmersiveIntelligence +mod_update_json= +mod_logo_path=assets/immersiveintelligence/logo.png +mod_authors=Pabilo8, GabrielV, Carver, SchäferdCZ, Bastian, Team Immersive Intelligence +mod_credits=Immersive Intelligence and Engineering Department communities. +archives_base_name=ImmersiveIntelligence + +# Access transformer support +use_access_transformer=true +access_transformer_locations=immersiveintelligence_at.cfg + +# Mk. X script switches +ii_script_repositories=true +ii_script_ide=true +ii_script_lombok=true +ii_script_modworks=true +ii_script_junit=true +ii_script_spotless=false +ii_script_dependencies=true +ii_script_corejar=true +ii_script_signing=true +ii_script_publishing=true + +# Modern Java syntax via Jabel. Bytecode is still emitted for Java 8. +ii_use_modern_java_syntax=true +ii_modern_java_language=21 + +generate_sources_jar=true +generate_javadocs_jar=false +show_testing_output=false + +# Team II Maven +ii_maven_url=https://maven.iiteam.net/releases +ii_auth_to_maven=true +# Available channels: releases, private, snapshots +ii_maven_channel=releases +ii_maven_username= +ii_maven_password= + +# Dependency versions +immersive_engineering_version=0.12-92-559 +jei_version=4.16.1.1013 +crafttweaker_version=1.12-4.1.20.698 +lombok_version=1.18.46 +junit_version=5.10.2 +minecraft_junit_version=1.5.1 +jmeasure_version=1.0.0 +modworks_version=1.1.3 +mockito_version=4.11.0 +mirage_version=2.0.3-rc3-SNAPSHOT +baubles_version=2518667 +cc_tweaked_version=1.89.2 +opencomputers_version=MC1.12.2-1.7.5.221 +tough_as_nails_version=2710969 +terrafirmacraft_version=3645502 +immersive_petroleum_version=3382321 +immersive_posts_version=2951672 +immersive_technology_version=3658279 +mysticalmechanics_version=3006392 +bwm_suite_version=5702821 +reauth_version=4408001 + +# Core-jar script settings +corejar_plugin_class=pl.pabilo8.immersiveintelligence.common.asm.IILoadingPlugin +corejar_include_patterns=pl/pabilo8/immersiveintelligence/common/asm/** +corejar_library_path=META-INF/libraries + +# Jar signing +ii_enable_signing=true +signing_storetype=pkcs12 +signing_alias= +signing_keystore= +signing_storepass= +signing_keypass= +signing_timestamp_url= diff --git a/gradle/boilerplate.gradle b/gradle/boilerplate.gradle deleted file mode 100644 index 601e8f692..000000000 --- a/gradle/boilerplate.gradle +++ /dev/null @@ -1,196 +0,0 @@ -//--- Gradle Dependencies - -apply plugin: "net.minecraftforge.gradle.forge" -apply plugin: 'idea' -apply plugin: 'gradleutils' - -//--- Script Utilties -project.getOr = { String envProp, projectProp -> System.getenv(envProp) ?: projectProp } -project.logFile = { LogLevel logLevel, String file -> logger.log(logLevel, new File('gradle/docs/' + file + '.txt').getText('UTF-8')) } -project.printDocs = { String file -> println(new File('gradle/docs/' + file + '.txt').getText('UTF-8')) } - -//--- Project SourceSets -sourceSets { - main - test -} - -idea { - project { - jdkName = '1.8' - languageLevel = '1.8' - } - module { - name file("./").name - outputDir = compileJava.destinationDir - testOutputDir = compileTestJava.destinationDir - } -} - -tasks.register('additionalIntellijSettings', Copy) { - from 'gradle/docs/idea/' - include "*" - into '.idea' -} -tasks.idea.dependsOn additionalIntellijSettings - -//--- Project Defaults -setVersion(modVersion) -setGroup(modGroup) -setArchivesBaseName(modName) - -//Ensures no compilation errors due to unrecognised unicode characters -compileJava.options.encoding = 'UTF-8' -tasks.withType(JavaCompile).configureEach { - options.encoding = 'UTF-8' -} - -//--- Settings -minecraft { - version = modForge - runDir = "run" - - replace "@VERSION@": modVersion - mappings = modMappings - useDepAts = true -} - -//--- Handling custom.gradle - -//To use personalized options when working with the mod create a file named custom.gradle -//The file is not sychronised with GitHub and can be used i.e. to store username and password -//Thanks to BluSunrize for the idea (taken from IE) - -// We have to put it **BEFORE** any other gradle files are parsed. -def customGradle = rootProject.file('custom.gradle') -if (customGradle.exists()) -{ - apply from: customGradle -} - -//--- Include the ModWorks Processor -if (ii_useModworksPreprocessor.asBoolean()) - apply from: rootProject.file("gradle/modworks.gradle") - -//--- Include Minecraft JUnit -if (ii_useJUnit.asBoolean()) - apply from: rootProject.file("gradle/junit.gradle") - -compileJava { - logFile(LogLevel.WARN, "gradlephant") - logger.log(LogLevel.WARN, ii_gradlephantTitle) - logger.log(LogLevel.WARN, ii_gradlephantLink + '\n') - - if (ii_printSourceSets.toBoolean()) - { - logger.log(LogLevel.WARN, 'SourceSets in Project: ') - sourceSets.each { srcSet -> - println "> [" + srcSet.name + "]" - print " - Sources: " + srcSet.allJava.srcDirs + "\n" - } - println "" - } - - println 'This mod uses Team II\'s Mod Setup Script, run [gradlew modSetupHelp].' - - if (ii_generateCoreJar == 'true') - { - println 'This mod will generate a [core jar] and place it inside its [main jar] during build.' - println 'For this, a valid fingerprint and configured keystore is needed.' - } - else - println 'This mod will not generate a [core jar] inside its [main jar]. Enable it in [gradle.properties] if needed.' - - if (ii_useModworksPreprocessor) - println 'This mod has ModWorks annotation processor enabled, check out https://github.com/Team-Immersive-Intelligence/ModworksProcessor for more information.' - if (ii_useJUnit) - println 'This mod has JUnit tests enabled, check out https://github.com/Team-Immersive-Intelligence/MinecraftJUnit for more information.' - -} - -//--- Generating Deobfed Jar -tasks.register('deobfJar', Jar) { - from sourceSets.main.output - classifier = 'deobf' - manifest { - attributes 'FMLAT': modATPath - attributes 'Maven-Artifact': modGroup + ':' + modName + ':' + modVersion - } -} - -artifacts { - archives deobfJar -} - -//--- Resource Processing - -processResources { - //this will ensure that this task is redone when the versions change. - inputs.property "version", modVersion - inputs.property "mcversion", project.minecraft.version - - //copy everything else except the mcmod.info and excluded files - //setDuplicatesStrategy('exclude') - - //replace stuff in mcmod.info - from(sourceSets.main.resources.srcDirs) { - exclude 'mcmod.info' - } - from(sourceSets.main.resources.srcDirs) { - include 'mcmod.info' - // replace properties - expand 'version': modVersion, 'mcversion': project.minecraft.version - } - - //Exclude GIMP images - exclude '**/*.xcf' - //Exclude batch - exclude '**/*.bat' - exclude '**/*.sh' - //Exclude template textures - exclude '**/*Template.png' - - //already excluded from gitignore, but still appear to be included in a locally built jar - exclude '**/desktop.ini' - exclude '**/Thumbs.db' - exclude '**/.DS_Store' -} - -processTestResources { - from(sourceSets.main.resources.srcDirs) { - include 'mcmod.info' - } into sourceSets.test.output.resourcesDir - println(sourceSets.test.output.resourcesDir) -} - -//--- Core Jar Generation -// Create a core jar, sign it and place it inside the main jar -if (ii_generateCoreJar == 'true') - apply from: rootProject.file('gradle/corejar.gradle') - -//--- IE Addon -apply from: rootProject.file('gradle/ieaddon.gradle') - -if (ii_enableSigning.asBoolean()) - apply from: rootProject.file('gradle/codesign.gradle') - -tasks.build.doLast() { - if (ii_printSourceSets.toBoolean()) - logger.log(LogLevel.WARN, 'Build Location: ' + file("./build/libs/").getPath()) -} - -if (ii_enableSigning.asBoolean()) -{ - tasks.build.finalizedBy() { - signMainJar - } -} - -//--- Help Function -tasks.register('modSetupDocs') { - group = "Help" - description = "Displays the Mod Build Script documentation" - doLast { - printDocs("setup") - } -} \ No newline at end of file diff --git a/gradle/codesign.gradle b/gradle/codesign.gradle deleted file mode 100644 index 665b9a650..000000000 --- a/gradle/codesign.gradle +++ /dev/null @@ -1,77 +0,0 @@ -apply plugin: 'signing' - -if (ii_generateCoreJar == 'true') -{ - tasks.register('signCoreJar') { - group 'signing' - - onlyIf { - hasKeyStore() - } - - outputs.upToDateWhen { false } - - dependsOn reobfCoreJar - - doLast { - def signdir = new File("$buildDir/libs") - signdir.mkdirs() - ant.signjar( - destDir: "${signdir.absolutePath}", - jar: 'build/libs/*-core.jar', - alias: project.ksalias ?: System.getenv("SIGN_ALIAS"), - storetype: "pkcs12", - keystore: project.keystore ?: System.getenv("SIGN_KEYSTORE"), - storepass: project.storepass ?: System.getenv("SIGN_STOREPASS"), - verbose: true, - preservelastmodified: "true", - tsaurl: project.timestamp_url ?: System.getenv("SIGN_TIMESTAMP") - ) - } - } - - tasks.coreJar.finalizedBy() { - signCoreJar - } -} - -tasks.register('signMainJar') { - group 'signing' - onlyIf { - hasKeyStore() - } - - outputs.upToDateWhen { false } - - dependsOn reobfJar - - doLast { - def signdir = new File("$buildDir/libs") - signdir.mkdirs() - ant.signjar( - destDir: "${signdir.absolutePath}", - jar: 'build/libs/*.jar', - alias: project.ksalias ?: System.getenv("SIGN_ALIAS"), - storetype: "pkcs12", - keystore: project.keystore ?: System.getenv("SIGN_KEYSTORE"), - storepass: project.storepass ?: System.getenv("SIGN_STOREPASS"), - verbose: true, - preservelastmodified: "true", - tsaurl: project.timestamp_url ?: System.getenv("SIGN_TIMESTAMP") - ) - } -} - -boolean hasKeyStore() -{ - if (!ii_enableSigning.asBoolean()) return false - def keystore = getOr("SIGNING_KEY_STORE_PATH", project.keystore) - if (keystore instanceof File) - { - return ((File) keystore).exists() - } - else - { - return !((String) keystore).isEmpty() - } -} \ No newline at end of file diff --git a/gradle/corejar.gradle b/gradle/corejar.gradle deleted file mode 100644 index 5ab1fde45..000000000 --- a/gradle/corejar.gradle +++ /dev/null @@ -1,40 +0,0 @@ -reobf { - coreJar { mappingType = 'SEARGE' } -} - -tasks.register('coreJar', Jar) { - // Copy all compiled files and resources from the source set to the JAR - // If you have additional source sets, add the same logic here - from(sourceSets.main.output) { - // Don't include the coremod in the main mod - // If you have more coremod-related packages that aren't nested in the main one, add exclusions for them - include modASMPath - } - manifest { - attributes "FMLCorePlugin": modASMClass - attributes 'Maven-Artifact': modGroup + ':' + modName + '-core:' + modVersion - } - // Add a classifier to the JAR ('-core' at the end of the file name) - // Distinguishes the mod JAR from the shipped one - classifier 'core' - group = 'build' -} - -def libPrefix = 'META-INF/libraries' - -jar { - dependsOn coreJar - - manifest { - attributes 'ContainedDeps': libPrefix + '/' + coreJar.archivePath.name - attributes "FMLAT": modATPath - attributes 'Maven-Artifact': modGroup + ':' + modName + ':' + modVersion - } - - exclude modASMPath - // Add the output of the mod JAR task to the main JAR for later extraction - from(coreJar.archivePath.absolutePath) { - include '*' // Due to the way Gradle's copy tasks work, we need this line for the JAR to get added - into libPrefix - } -} \ No newline at end of file diff --git a/gradle/docs/setup.txt b/gradle/docs/setup.txt index 0ec5bb866..d2003d836 100644 --- a/gradle/docs/setup.txt +++ b/gradle/docs/setup.txt @@ -1,102 +1,38 @@ --------------------------------------------------------------------------------------- - -Mk.4/5 Mod Setup Script -Made by Team Immersive Intelligence -Powered by ForgeGradle 2.3 fork by anatawa12 - --------------------------------------------------------------------------------------- - -1) ABOUT -This project uses a custom setup script structure. -The setup script is meant to be modular (to a degree) and consists of multiple scripts (modules) contained in the [gradle/] folder. -These are: - - Boilerplate [boilerplate.gradle] - the core module linking others together and storing the common mod construction code - - Modworks [modworks.gradle] - handling the ModWorks annotation processor and resource/code generator - - CoreJar [corejar.gradle] - handling the generation of a core jar, stored inside the main mod jar and code signing required to build it - - IE Addon [ieaddon.gradle] - handles mod dependencies required to build an Immersive Engineering addon mod - -The script offers compatibility with Intellij, which is the IDE preferred by Team II. -For other IDEs refrain to the standard gradle setup, with additions. - --------------------------------------------------------------------------------------- - -2) INTELLIJ SETUP -Import the project folder using [File>New...>Project from Existing Sources] -The project should automatically be recognised as a gradle project and load the scripts, if it didn't load them, do it manually by using [Gradle>Reload All Gradle Projects]. - -Navigate to [File>Settings>Build, Execution, Deployment>Build Tools>Gradle] and select 'Build and Run using' to [IntelliJ]. -Navigate to [File>Project Structure] and set SDK to a Java 8 (1.8) SDK. In Team II we use Amazon Corretto 8 both locally and on the GitHub Build Action. - -Run the [setupDecompWorkspace] Gradle task located in [forgegradle] category and proceed with the setup. -The task may error - in such case reload the gradle project and run the task again. - -Run the [genIntellijRuns] task to create Run Configurations. -When selecting a run configuration, set the Classpath (-cp) to [path].[ModName].Main - --------------------------------------------------------------------------------------- - -3) GRADLE.PROPERTIES -Below is a list of all properties, what are they used for and their possible values (if applicable) -Some properties can also be applied from - -General Properties - [modForge] - Forge Version - [modMappings] - MCP Mappings, used to give programmer-friendly names to the decompiled functions - - [modVersion] - Version of the mod, usually in format major-minor-patch, f.e. 1.2.3 - [modGroup] - - [modName] - - -Used in MCMOD.INFO file, which provides information about the mod to the in-game mod browser - [mcmod_Name], [mcmod_URL], [mcmod_Description], [mcmod_Developer], [mcmod_Contributors] - -Script settings - [ii_useModworksPreprocessor : true/false] - Whether the project should use the ModWorks Preprocessor (it's a compilation time only dependency (annotation processor) and not a lib required to run the jar) - [ii_printSourceSets : true/false] - Whether all source sets locations should be printed - [ii_printOutputDir : true/false] - Whether a link to the output directory [build/libs/] should be printed on finishing build, useful a for manually built jar - -CoreJar Script Settings - [ii_generateCoreJar : true/false] - whether a core jar should be - [modATPath] - Access Transformer name - [modASMPath] - - [modASMClass] - - -Jar Signing-Related properties. If keyStore is empty, the code will not be signed - [keyStore] - Relative or full path to the keystore file - [keyStoreAlias] - Keystore Username - [keyStorePass] - Keystore Password - [keyStoreKeyPass] - Keystore Key Password - [signSHA1] - SHA1 signature of the fingerprint - -Gradlephant Banner properties (the gradle elephant icon can be changed in [gradle/docs/gradlephant.txt]) - [ii_gradlephantTitle] - A mod brought to you by II Team - [ii_gradlephantLink] - A link to a project repository or homepage - --------------------------------------------------------------------------------------- - -4) CUSTOM.GRADLE -[custom.gradle] is a file ignored by the git repository, which can be used to apply special user configuration for the project. -An example could be: - project.setProperty("someSpecialProperty","value") - - Keep in mind that the property has to exist in [gradle.properties] as well. - -Or - sourceSets { - newly_added { - resources { - srcDir 'src/specific/folder' - } - } - } - To add a new source set (Check gradle documentation) - -Or, a more commonly used - runClient { - args("--username=Achroma11 --uuid=bebe01174cfb4d7d844d31823575368b") - } - So that running on client will start on a specific account (no password is needed for playing on offline mode) - -Settings such as Program Arguments or Environment Variables can also be applied in IntelliJ in Run Configurations - --------------------------------------------------------------------------------------- \ No newline at end of file +Team II Mk. X Build System +------------------------- + +Common tasks: + ./gradlew runClient + ./gradlew runServer + ./gradlew runObfClient + ./gradlew runObfServer + ./gradlew build + ./gradlew test + ./gradlew spotlessApply + +Project identity lives in gradle.properties: + mod_id, mod_name, mod_group, mod_package, mod_version + +Important build switches: + ii_script_repositories enable Team II / GTNH / Cleanroom / mod Maven repositories + ii_script_ide generate IntelliJ IDEA settings and Gradle run configurations + ii_script_lombok enable Lombok compileOnly and annotationProcessor dependencies + ii_script_modworks enable Team II Modworks processor and generated folders + ii_script_junit enable JUnit 5, MinecraftJUnit and JMeasure + ii_script_spotless enable Spotless formatting tasks + ii_script_ieaddon enable Immersive Engineering addon dependencies + ii_script_corejar build and embed a separate reobfuscated core jar + ii_script_signing sign reobfuscated jars using Ant signjar + ii_script_publishing publish jars to II Maven + +Modern Java syntax: + ii_use_modern_java_syntax=true enables Jabel and compiles modern Java syntax to Java 8 bytecode. + Keep this disabled unless the whole team uses a compatible Gradle/RFG toolchain. + +Signing: + Set ii_script_signing=true and ii_enable_signing=true, then provide either Gradle properties + or environment variables: SIGN_ALIAS, SIGN_KEYSTORE, SIGN_STOREPASS, SIGN_KEYPASS, SIGN_TIMESTAMP. + +Publishing: + Set ii_script_publishing=true and ii_auth_to_maven=true, then provide ii_maven_username + and ii_maven_password properties to authenticate into II Maven \ No newline at end of file diff --git a/gradle/ieaddon.gradle b/gradle/ieaddon.gradle deleted file mode 100644 index f4d86b5f7..000000000 --- a/gradle/ieaddon.gradle +++ /dev/null @@ -1,119 +0,0 @@ -dependencies { - // compile against the JEI API but do not include it at runtime - provided "mezz.jei:jei_1.12.2:4.16.1.1013:api" - - // use jei at runtime - runtimeOnly "mezz.jei:jei_1.12.2:4.16.1.1013" - - deobfCompile "team.chisel.ctm:CTM:MC1.12.2-1.0.2.31" - deobfCompile "blusunrize:ImmersiveEngineering:0.12-92-+" - - deobfCompile "CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.1.11.505" - //deobfCompile "com.mod-buildcraft:buildcraft:7.99.12" - - //Lighting mod formerly called Albedo - provided "com.elytradev:mirage:2.0.3-rc3-SNAPSHOT" -// compileOnly 'com.azanor:Baubles:1.12-1.5.2' - provided "curse.maven:baubles-227083:2518667" - - provided "org.squiddev:cc-tweaked-1.12.2:1.89.2" - provided "li.cil.oc:OpenComputers:MC1.12.2-1.7.5.221" - - //Download from curse maven - provided "curse.maven:tough-as-nails-246391:2710969" - provided "curse.maven:terrafirmacraft-302973:3645502" - deobfCompile "curse.maven:immersive-petroleum-268250:3382321" - deobfCompile "curse.maven:immersive-posts-314645:2951672" - deobfCompile "curse.maven:immersive-technology-359407:3658279" - deobfCompile "curse.maven:mysticalmechanics-300742:3006392" - deobfCompile "curse.maven:bwm-suite-246760:5702821" - - runtimeOnly "curse.maven:reauth-237701:4408001" - - if (ii_useJUnit) - { - testImplementation "blusunrize:ImmersiveEngineering:0.12-92-+" - testImplementation "org.squiddev:cc-tweaked-1.12.2:1.89.2" - testImplementation "li.cil.oc:OpenComputers:MC1.12.2-1.7.5.221" - testRuntimeOnly "com.elytradev:mirage:2.0.3-rc3-SNAPSHOT" - } -} - -repositories { - maven { - name = "iiMavenReleases" - url = uri("https://maven.iiteam.net") - if (ii_authToIIMaven.asBoolean()) - { - credentials { - username project.iiMavenReleasesUsername - password project.iiMavenReleasesPassword - } - authentication { - basic(BasicAuthentication) - } - } - } - - maven { // JEI & Tinkers - name 'DVS1 Maven FS' - url 'https://dvs1.progwml6.com/files/maven' - } - - maven { // CraftTweaker - name 'jared maven' - url 'https://maven.blamejared.com/' - } - - maven { // ModMaven, there is a bunch of stuff on there - name 'ModMaven' - url "https://modmaven.dev/" - } - - maven { // Mirage (Albedo) - url 'https://repo.elytradev.com/' - } - - maven { // CTM - name 'tterrag maven' - url "https://maven.tterrag.com/" - } - - maven { - name 'ComputerCraft Maven' - url 'https://squiddev.cc/maven/' - } - - maven { - name "OpenComputers" - url "https://maven.cil.li/" - } - - /*maven { // Baubles - name "MCModDev" - url "https://maven.mcmoddev.com/" - }*/ - - maven { //for Immersive Petroleum, Posts and Technology - name "CurseMaven" - url "https://www.cursemaven.com" - } - - - /* - maven { - name "BuildCraft" - url "https://mod-buildcraft.com/maven" - } - */ - - maven { - name "CurseForge" - url "https://minecraft.curseforge.com/api/maven/" - } - - maven { - name "Modrinth" - url = "https://api.modrinth.com/maven" - } -} \ No newline at end of file diff --git a/gradle/junit.gradle b/gradle/junit.gradle deleted file mode 100644 index 49fdba72f..000000000 --- a/gradle/junit.gradle +++ /dev/null @@ -1,24 +0,0 @@ -dependencies { - //Junit 5 - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2' - testImplementation 'org.junit.jupiter:junit-jupiter-params:5.8.2' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2' - testImplementation 'builtbroken.minecraftjunit:MinecraftJUnit:1.5.1' - - testImplementation 'io.hosuaby:inject-resources-junit-jupiter:0.3.2' - testImplementation 'org.reflections:reflections:0.10.2' - testImplementation 'net.iiteam:jmeasure:1.0.0' - - //Mockito - testImplementation 'org.mockito:mockito-inline:4.3.1' - testImplementation 'org.mockito:mockito-core:4.3.1' -} - -test { - useJUnitPlatform() - - maxHeapSize = '1G' - failFast = false - workingDir = './run_tests' - mkdir './run_tests' -} \ No newline at end of file diff --git a/gradle/modworks.gradle b/gradle/modworks.gradle deleted file mode 100644 index 3b311e501..000000000 --- a/gradle/modworks.gradle +++ /dev/null @@ -1,34 +0,0 @@ -def pathJavaGen = file('src/main/generated/java'); -def pathResourceGen = file('src/main/generated/resources'); - -sourceSets.main.java.srcDirs += ['src/main/generated/java'] -sourceSets.main.resources.srcDirs += ['src/main/generated/resources'] - -idea { - module { - sourceDirs += pathJavaGen - generatedSourceDirs += pathJavaGen - resourceDirs += pathResourceGen - generatedSourceDirs += pathResourceGen - } -} - -repositories { - maven { - url 'https://maven.iiteam.net/releases' - } -} - -dependencies { - annotationProcessor 'pl.pabilo8:ModworksProcessor:1.1.2' - compileOnly 'pl.pabilo8:ModworksProcessor:1.1.2' -} - -compileJava { - options.annotationProcessorGeneratedSourcesDirectory = project.file("src/main/generated") - options.compilerArgs.addAll([ - '-Amodworks.modid=' + modName, - '-Amodworks.resourcedir=' + 'resources', - '-Amodworks.javadir=' + 'java' - ]) -} \ No newline at end of file diff --git a/gradle/scripts/cleanroom.gradle b/gradle/scripts/cleanroom.gradle new file mode 100644 index 000000000..3b06173f3 --- /dev/null +++ b/gradle/scripts/cleanroom.gradle @@ -0,0 +1,173 @@ +repositories { + maven { + name = 'CleanroomMC Maven' + url = 'https://maven.cleanroommc.com' + } + mavenCentral() +} + +sourceSets { + main + test +} + +// Register the sources task before withSourcesJar() so Gradle publishes this +// implementation instead of creating its default allSource-based task. +// Java sources remain raw source files; resources come exclusively from the +// processResources output, after expansion, renaming and filtering. +def mkxSourcesJar = null +if (mkxBool('generate_sources_jar', true)) { + def processedResources = tasks.named('processResources') + mkxSourcesJar = tasks.register('sourcesJar', org.gradle.api.tasks.bundling.Jar) { + group = 'build' + description = 'Assembles Java sources and processed resources.' + archiveClassifier.set('sources') + dependsOn processedResources + from(sourceSets.main.allJava) + from(processedResources) + } +} + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(mkxBool('ii_use_modern_java_syntax') ? mkxInt('ii_modern_java_language', 16) : 8)) + vendor.set(JvmVendorSpec.AZUL) + } + if (mkxBool('generate_sources_jar', true)) + withSourcesJar() + if (mkxBool('generate_javadocs_jar', false)) + withJavadocJar() +} + +if (mkxSourcesJar != null) { + // withSourcesJar() reuses a pre-existing task but does not attach that task + // to assemble, so preserve the standard lifecycle relationship explicitly. + tasks.named('assemble').configure { + dependsOn mkxSourcesJar + } +} + +configurations { + runtimeOnlyNonPublishable { + description = 'Runtime-only dependencies used in development but not published.' + canBeConsumed = false + canBeResolved = false + } + devOnlyNonPublishable { + description = 'Development dependencies that should not be published.' + canBeConsumed = false + canBeResolved = false + } + compileOnly.extendsFrom(devOnlyNonPublishable) + runtimeOnlyNonPublishable.extendsFrom(devOnlyNonPublishable) + runtimeClasspath.extendsFrom(runtimeOnlyNonPublishable) + testRuntimeClasspath.extendsFrom(runtimeOnlyNonPublishable) +} + +minecraft { + mcVersion.set(mkxString('minecraft_version', '1.12.2')) + mcpMappingChannel.set(mkxString('mapping_channel', 'stable')) + mcpMappingVersion.set(mkxString('mapping_version', '39')) + useDependencyAccessTransformers.set(mkxBool('use_dependency_at_files', true)) + username.set(mkxString('minecraft_username', 'Developer')) + + injectedTags.put('MOD_ID', mkxString('mod_id')) + injectedTags.put('MOD_NAME', mkxString('mod_name')) + injectedTags.put('VERSION', project.version.toString()) + + extraRunJvmArguments.add('-ea:' + mkxString('mod_package')) +} + +if (mkxBool('ii_use_modern_java_syntax', false)) { + dependencies { + annotationProcessor 'com.github.bsideup.jabel:jabel-javac-plugin:1.0.1' + compileOnly('com.github.bsideup.jabel:jabel-javac-plugin:1.0.1') { transitive = false } + annotationProcessor 'net.java.dev.jna:jna-platform:5.13.0' + testAnnotationProcessor 'com.github.bsideup.jabel:jabel-javac-plugin:1.0.1' + testCompileOnly('com.github.bsideup.jabel:jabel-javac-plugin:1.0.1') { transitive = false } + patchedMinecraft 'me.eigenraven.java8unsupported:java-8-unsupported-shim:1.0.0' + } +} + +tasks.named('injectTags').configure { + outputClassName.set(mkxString('mod_package') + '.Tags') + onlyIf { + !tags.get().isEmpty() + } +} + +tasks.withType(JavaCompile).configureEach { + options.encoding = 'UTF-8' + if (mkxBool('ii_use_modern_java_syntax', false) && !(name in ['compileMcLauncherJava', 'compilePatchedMcJava'])) { + sourceCompatibility = mkxString('ii_modern_java_language', '16') + options.release.set(8) + javaCompiler.set(javaToolchains.compilerFor { + languageVersion.set(JavaLanguageVersion.of(mkxInt('ii_modern_java_language', 16))) + vendor.set(JvmVendorSpec.AZUL) + }) + } else { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } +} + +def mkxMcmodInfoValues = { + return [ + mod_id_json: mkxJsonString(mkxString('mod_id')), + mod_name_json: mkxJsonString(mkxString('mod_name')), + mod_version_json: mkxJsonString(project.version.toString()), + minecraft_version_json: mkxJsonString(mkxString('minecraft_version')), + mod_description_json: mkxJsonString(mkxString('mod_description')), + mod_url_json: mkxJsonString(mkxString('mod_url')), + mod_update_json_json: mkxJsonString(mkxString('mod_update_json')), + mod_logo_path_json: mkxJsonString(mkxString('mod_logo_path')), + mod_authors_json: mkxJsonStringList('mod_authors'), + mod_credits_json: mkxJsonString(mkxString('mod_credits')) + ] +} + +def mkxPackMetadataValues = { + return [ + pack_description_json: mkxJsonString(mkxString('mod_name') + ' resources') + ] +} + +processResources { + inputs.properties(mkxMcmodInfoValues()) + inputs.properties(mkxPackMetadataValues()) + + filesMatching('mcmod.info') { + expand(mkxMcmodInfoValues()) + } + + filesMatching('pack.mcmeta') { + expand(mkxPackMetadataValues()) + } + + if (mkxBool('use_access_transformer', false)) + rename '(.+_at.cfg)', 'META-INF/$1' + + exclude '**/*.xcf', '**/*.bat', '**/*.sh', '**/*Template.png' + exclude '**/desktop.ini', '**/Thumbs.db', '**/.DS_Store' +} + +if (mkxBool('use_access_transformer', false)) { + mkxList('access_transformer_locations').each { location -> + def atFile = file("src/main/resources/${location}") + if (!atFile.exists()) + throw new GradleException("Access transformer file does not exist: ${atFile}") + tasks.deobfuscateMergedJarToSrg.accessTransformerFiles.from(atFile) + tasks.srgifyBinpatchedJar.accessTransformerFiles.from(atFile) + } +} + +jar { + manifest { + def attributesMap = [ + 'Maven-Artifact': "${project.group}:${mkxString('mod_id')}:${project.version}" + ] + if (mkxBool('use_access_transformer', false)) + attributesMap['FMLAT'] = mkxList('access_transformer_locations').join(' ') + attributes(attributesMap) + } +} \ No newline at end of file diff --git a/gradle/scripts/corejar.gradle b/gradle/scripts/corejar.gradle new file mode 100644 index 000000000..b6597326c --- /dev/null +++ b/gradle/scripts/corejar.gradle @@ -0,0 +1,59 @@ +def corePatterns = mkxList('corejar_include_patterns') +def libPath = mkxString('corejar_library_path', 'META-INF/libraries') + +def corePluginClass = mkxString('corejar_plugin_class').trim() +if (corePatterns.isEmpty()) + throw new GradleException('ii_script_corejar is enabled, but corejar_include_patterns is empty.') +if (corePluginClass.isEmpty()) + throw new GradleException('ii_script_corejar is enabled, but corejar_plugin_class is empty.') + +/* + * Gradle 9 has two Jar types: + * - org.gradle.jvm.tasks.Jar is the new base task type; + * - org.gradle.api.tasks.bundling.Jar is a compatibility subclass. + * + * RFG 2.x uses the new JVM Jar type for both its automatic task lookup and + * ReobfuscatedJar. Use that type explicitly here to avoid narrowing the + * generated reobfCoreJar task to the incompatible compatibility subclass. + */ +def coreJar = tasks.register('coreJar', org.gradle.jvm.tasks.Jar) { + group = 'build' + description = 'Builds the development coremod jar before RFG reobfuscation.' + archiveBaseName.set(base.archivesName.map { it + '-core' }) + archiveClassifier.set('dev') + + from(sourceSets.main.output) { + include corePatterns + } + + manifest { + attributes( + 'FMLCorePlugin': corePluginClass, + 'Maven-Artifact': "${project.group}:${mkxString('mod_id')}-core:${project.version}" + ) + } +} + +/* + * RFG installs the reobf task rule. Requesting this provider after + * coreJar exists materialises a ReobfuscatedJar, which extends + * org.gradle.jvm.tasks.Jar. + */ +def reobfCoreJar = tasks.named('reobfCoreJar', org.gradle.jvm.tasks.Jar) +def reobfCoreArchive = reobfCoreJar.flatMap { it.archiveFile } + +tasks.named('jar', org.gradle.jvm.tasks.Jar).configure { + dependsOn reobfCoreJar + exclude corePatterns + + // Forge reads this manifest attribute from the outer mod jar. + doFirst { + manifest.attributes( + 'ContainedDeps': libPath + '/' + reobfCoreArchive.get().asFile.name + ) + } + + from(reobfCoreArchive) { + into libPath + } +} \ No newline at end of file diff --git a/gradle/scripts/dependencies.gradle b/gradle/scripts/dependencies.gradle new file mode 100644 index 000000000..74b2fdb12 --- /dev/null +++ b/gradle/scripts/dependencies.gradle @@ -0,0 +1,34 @@ +dependencies { + //Immersive Engineering addon baseline. + api rfg.deobf("blusunrize:ImmersiveEngineering:${mkxString('immersive_engineering_version')}") + + + //Common optional integrations for an IE addon template. + compileOnly rfg.deobf("mezz.jei:jei_1.12.2:${mkxString('jei_version')}:api") + runtimeOnlyNonPublishable rfg.deobf("mezz.jei:jei_1.12.2:${mkxString('jei_version')}") + compileOnly rfg.deobf("CraftTweaker2:CraftTweaker2-MC1120-Main:${mkxString('crafttweaker_version')}") + compileOnly 'com.google.code.findbugs:jsr305:3.0.1' + + compileOnly rfg.deobf("com.elytradev:mirage:${mkxString('mirage_version')}") + compileOnly rfg.deobf("curse.maven:baubles-227083:${mkxString('baubles_version')}") + + compileOnly rfg.deobf("org.squiddev:cc-tweaked-1.12.2:${mkxString('cc_tweaked_version')}") + compileOnly rfg.deobf("li.cil.oc:OpenComputers:${mkxString('opencomputers_version')}") + + compileOnly rfg.deobf("curse.maven:tough-as-nails-246391:${mkxString('tough_as_nails_version')}") + compileOnly rfg.deobf("curse.maven:terrafirmacraft-302973:${mkxString('terrafirmacraft_version')}") + compileOnly rfg.deobf("curse.maven:immersive-petroleum-268250:${mkxString('immersive_petroleum_version')}") + compileOnly rfg.deobf("curse.maven:immersive-posts-314645:${mkxString('immersive_posts_version')}") + compileOnly rfg.deobf("curse.maven:immersive-technology-359407:${mkxString('immersive_technology_version')}") + compileOnly rfg.deobf("curse.maven:mysticalmechanics-300742:${mkxString('mysticalmechanics_version')}") + compileOnly rfg.deobf("curse.maven:bwm-suite-246760:${mkxString('bwm_suite_version')}") + + runtimeOnly "curse.maven:reauth-237701:${mkxString('reauth_version')}" + + if (mkxBool('ii_script_junit', true)) { + testImplementation rfg.deobf("blusunrize:ImmersiveEngineering:${mkxString('immersive_engineering_version')}") + testImplementation rfg.deobf("org.squiddev:cc-tweaked-1.12.2:${mkxString('cc_tweaked_version')}") + testImplementation rfg.deobf("li.cil.oc:OpenComputers:${mkxString('opencomputers_version')}") + testRuntimeOnly rfg.deobf("com.elytradev:mirage:${mkxString('mirage_version')}") + } +} diff --git a/gradle/scripts/helpers.gradle b/gradle/scripts/helpers.gradle new file mode 100644 index 000000000..f29c62133 --- /dev/null +++ b/gradle/scripts/helpers.gradle @@ -0,0 +1,59 @@ +ext.mkxString = { String name, String defaultValue = '' -> + def value = project.findProperty(name) + return value == null ? defaultValue : value.toString() +} + +ext.mkxBool = { String name, boolean defaultValue = false -> + def value = project.findProperty(name) + if (value == null) + return defaultValue + return value.toString().trim().equalsIgnoreCase('true') +} + +ext.mkxInt = { String name, int defaultValue = 0 -> + def value = project.findProperty(name) + return value == null || value.toString().trim().isEmpty() ? defaultValue : value.toString().trim().toInteger() +} + +ext.mkxList = { String name, String separatorRegex = '[, ]+' -> + def value = mkxString(name, '') + if (value.trim().isEmpty()) + return [] + return value.split(separatorRegex).collect { it.trim() }.findAll { !it.isEmpty() } +} + +ext.mkxCommaList = { String name -> + def value = mkxString(name, '') + if (value.trim().isEmpty()) + return [] + return value.split(',').collect { it.trim() }.findAll { !it.isEmpty() } +} + +ext.mkxJsonString = { Object value -> + return groovy.json.JsonOutput.toJson(value == null ? '' : value.toString()) +} + +ext.mkxJsonStringList = { String name -> + return groovy.json.JsonOutput.toJson(mkxCommaList(name)) +} + +ext.mkxEnvOrProperty = { String envName, String propertyName -> + def envValue = System.getenv(envName) + return envValue == null || envValue.trim().isEmpty() ? mkxString(propertyName, '') : envValue +} + +ext.mkxAssertProperties = { String... names -> + names.each { name -> + if (mkxString(name, '').trim().isEmpty()) + throw new GradleException("Missing required Gradle property: ${name}") + } +} + +ext.mkxApplyScript = { String propertyName, String scriptPath -> + if (mkxBool(propertyName, false)) { + logger.lifecycle('[Mk.X] applying {}', scriptPath) + apply from: rootProject.file(scriptPath) + } else { + logger.lifecycle('[Mk.X] skipping {} ({})', scriptPath, propertyName) + } +} \ No newline at end of file diff --git a/gradle/scripts/ide.gradle b/gradle/scripts/ide.gradle new file mode 100644 index 000000000..a75a5a35a --- /dev/null +++ b/gradle/scripts/ide.gradle @@ -0,0 +1,32 @@ +tasks.register('mkxAfterSync') { + group = 'IDE' + description = 'Generates sources required immediately after an IntelliJ Gradle sync.' + dependsOn tasks.named('injectTags') +} + +idea { + module { + inheritOutputDirs = true + downloadJavadoc = true + downloadSources = true + } + project { + settings { + compiler.javac { + afterEvaluate { + javacAdditionalOptions = '-encoding UTF-8' + moduleJavacAdditionalOptions = [ + (project.name + '.main'): tasks.compileJava.options.compilerArgs.collect { '"' + it + '"' }.join(' ') + ] + } + } + taskTriggers { + afterSync 'mkxAfterSync' + } + } + } +} + +tasks.named('processIdeaSettings').configure { + dependsOn tasks.named('mkxAfterSync') +} \ No newline at end of file diff --git a/gradle/scripts/junit.gradle b/gradle/scripts/junit.gradle new file mode 100644 index 000000000..61173e313 --- /dev/null +++ b/gradle/scripts/junit.gradle @@ -0,0 +1,24 @@ +dependencies { + testImplementation platform("org.junit:junit-bom:${mkxString('junit_version')}") + testImplementation 'org.junit.jupiter:junit-jupiter' + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + testImplementation "builtbroken.minecraftjunit:MinecraftJUnit:${mkxString('minecraft_junit_version')}" + testImplementation "net.iiteam:jmeasure:${mkxString('jmeasure_version')}" + testImplementation "org.mockito:mockito-core:${mkxString('mockito_version')}" + testImplementation 'org.reflections:reflections:0.10.2' +} + +test { + useJUnitPlatform() + javaLauncher.set(javaToolchains.launcherFor { + languageVersion.set(JavaLanguageVersion.of(8)) + vendor.set(JvmVendorSpec.AZUL) + }) + maxHeapSize = '1G' + failFast = false + workingDir = './run_tests' + doFirst { mkdir './run_tests' } + if (mkxBool('show_testing_output', false)) { + testLogging { showStandardStreams = true } + } +} \ No newline at end of file diff --git a/gradle/scripts/lombok.gradle b/gradle/scripts/lombok.gradle new file mode 100644 index 000000000..29f384e26 --- /dev/null +++ b/gradle/scripts/lombok.gradle @@ -0,0 +1,6 @@ +dependencies { + compileOnly "org.projectlombok:lombok:${mkxString('lombok_version')}" + annotationProcessor "org.projectlombok:lombok:${mkxString('lombok_version')}" + testCompileOnly "org.projectlombok:lombok:${mkxString('lombok_version')}" + testAnnotationProcessor "org.projectlombok:lombok:${mkxString('lombok_version')}" +} \ No newline at end of file diff --git a/gradle/scripts/modworks.gradle b/gradle/scripts/modworks.gradle new file mode 100644 index 000000000..da9e4f786 --- /dev/null +++ b/gradle/scripts/modworks.gradle @@ -0,0 +1,58 @@ +def generatedRoot = file('src/main/generated') +def generatedJava = file('src/main/generated/java') +def generatedResources = file('src/main/generated/resources') + +sourceSets.main.java.srcDirs += [generatedJava] +sourceSets.main.resources.srcDirs += [generatedResources] + +idea { + module { + sourceDirs += generatedJava + generatedSourceDirs += generatedJava + resourceDirs += generatedResources + generatedSourceDirs += generatedResources + } +} + +dependencies { + annotationProcessor "pl.pabilo8:ModworksProcessor:${mkxString('modworks_version')}" + compileOnly "pl.pabilo8:ModworksProcessor:${mkxString('modworks_version')}" +} + +def compileJavaTask = tasks.named('compileJava', JavaCompile) + +compileJavaTask.configure { + //Modworks writes both the java/ and resources/ trees below SOURCE_OUTPUT. + //Therefore this must point to their common root, not to java/ directly. + options.generatedSourceOutputDirectory.set(generatedRoot) + options.compilerArgs.addAll([ + '-Amodworks.modid=' + mkxString('mod_id'), + '-Amodworks.resourcedir=resources', + '-Amodworks.javadir=java' + ]) +} + +//Both consumers read files produced by compileJava's annotation processors. +//Gradle 9 requires the producer-consumer relationship to be explicit because +//the generated directories are also registered as source-set directories. +tasks.named('processResources').configure { + dependsOn compileJavaTask +} + +if (mkxBool('generate_sources_jar', true)) { + tasks.named('sourcesJar').configure { + dependsOn compileJavaTask + } +} + +if (mkxBool('generate_javadocs_jar', false)) { + tasks.named('javadoc').configure { + dependsOn compileJavaTask + } +} + +tasks.register('cleanGeneratedModworks', Delete) { + group = 'build' + description = 'Deletes Modworks generated source/resource directories.' + delete generatedRoot +} \ No newline at end of file diff --git a/gradle/scripts/publishing.gradle b/gradle/scripts/publishing.gradle new file mode 100644 index 000000000..1f20671f4 --- /dev/null +++ b/gradle/scripts/publishing.gradle @@ -0,0 +1,45 @@ +publishing { + publications { + create("mavenJava", MavenPublication) { + artifactId = project.archives_base_name + from components.java + + pom { + name = mkxString('mod_name', 'IEAddon') + description = mkxString('mod_description', '') + url = mkxString('mod_url', 'https://github.com/Team-Immersive-Intelligence/ImmersiveIntelligence') + licenses { + license { + name = 'Team Immersive Intelligence License' + url = 'https://github.com/Team-Immersive-Intelligence/ImmersiveIntelligence/blob/dev/main/license.md' + } + } + developers { + developer { + id = 'teamii' + name = 'Team Immersive Intelligence' + } + } + scm { + connection = 'scm:git:git://github.com/Team-Immersive-Intelligence/ImmersiveIntelligence.git' + developerConnection = 'scm:git:ssh://github.com/Team-Immersive-Intelligence/ImmersiveIntelligence.git' + url = 'https://github.com/Team-Immersive-Intelligence/ImmersiveIntelligence' + } + } + } + } + + repositories { + maven { + name "TeamII_Maven" + url "https://maven.iiteam.net/${mkxString('ii_maven_channel', 'releases')}" + credentials { + username = mkxEnvOrProperty('II_MAVEN_USER', 'ii_maven_username') + password = mkxEnvOrProperty('II_MAVEN_PASSWORD', 'ii_maven_password') + } + authentication { + basic(BasicAuthentication) + } + } + } +} \ No newline at end of file diff --git a/gradle/scripts/repositories.gradle b/gradle/scripts/repositories.gradle new file mode 100644 index 000000000..21cd38bac --- /dev/null +++ b/gradle/scripts/repositories.gradle @@ -0,0 +1,32 @@ +repositories { + maven { + name = 'Team II Maven' + url = uri(mkxString('ii_maven_url', 'https://maven.iiteam.net/releases')) + if (mkxBool('ii_auth_to_maven', false)) { + credentials { + username = mkxEnvOrProperty('II_MAVEN_USER', 'ii_maven_username') + password = mkxEnvOrProperty('II_MAVEN_PASSWORD', 'ii_maven_password') + } + } + } + maven { name = 'GTNH Maven'; url = 'https://nexus.gtnewhorizons.com/repository/public/' } + maven { name = 'CleanroomMC Maven'; url = 'https://maven.cleanroommc.com' } + maven { name = 'BlameJared Maven'; url = 'https://maven.blamejared.com/' } + maven { name = 'DVS1 Maven'; url = 'https://dvs1.progwml6.com/files/maven/' } + maven { name = 'ModMaven'; url = 'https://modmaven.dev/' } + maven { name = 'tterrag Maven'; url = 'https://maven.tterrag.com/' } + maven { name = 'SpongePowered Maven'; url = 'https://repo.spongepowered.org/maven/' } + exclusiveContent { + forRepository { maven { name = 'CurseMaven'; url = 'https://www.cursemaven.com' } } + filter { includeGroup 'curse.maven' } + } + exclusiveContent { + forRepository { maven { name = 'Modrinth'; url = 'https://api.modrinth.com/maven' } } + filter { includeGroup 'maven.modrinth' } + } + maven { name = "ElytraDev Maven"; url = "https://repo.elytradev.com/" } + maven {name = "ComputerCraft Maven"; url = "https://maven.cil.li/" } + maven {name = "OpenComputers"; url = "https://squiddev.cc/maven/" } + mavenCentral() + mavenLocal() +} \ No newline at end of file diff --git a/gradle/scripts/signing.gradle b/gradle/scripts/signing.gradle new file mode 100644 index 000000000..d951de5e3 --- /dev/null +++ b/gradle/scripts/signing.gradle @@ -0,0 +1,61 @@ +def signingValue = { String envName, String propertyName -> mkxEnvOrProperty(envName, propertyName) } + +def hasSigningConfig = { + mkxBool('ii_enable_signing', false) + && !signingValue('SIGN_ALIAS', 'signing_alias').trim().isEmpty() + && !signingValue('SIGN_KEYSTORE', 'signing_keystore').trim().isEmpty() + && !signingValue('SIGN_STOREPASS', 'signing_storepass').trim().isEmpty() +} + +def signJar = { File jarFile -> + if (!jarFile.exists()) + throw new GradleException("Cannot sign missing jar: ${jarFile}") + + def args = [ + jar: jarFile.absolutePath, + alias: signingValue('SIGN_ALIAS', 'signing_alias'), + storetype: mkxString('signing_storetype', 'pkcs12'), + keystore: signingValue('SIGN_KEYSTORE', 'signing_keystore'), + storepass: signingValue('SIGN_STOREPASS', 'signing_storepass'), + verbose: true, + preservelastmodified: true + ] + def keypass = signingValue('SIGN_KEYPASS', 'signing_keypass') + if (!keypass.trim().isEmpty()) + args.keypass = keypass + def timestamp = signingValue('SIGN_TIMESTAMP', 'signing_timestamp_url') + if (!timestamp.trim().isEmpty()) + args.tsaurl = timestamp + + logger.lifecycle('[Mk.X] signing {}', jarFile.name) + ant.signjar(args) +} + +tasks.register('signMainJar') { + group = 'signing' + description = 'Signs the reobfuscated main mod jar.' + dependsOn tasks.named('reobfJar') + onlyIf { hasSigningConfig() } + doLast { + signJar(tasks.named('reobfJar', org.gradle.jvm.tasks.Jar).get().archiveFile.get().asFile) + } +} + +if (mkxBool('ii_script_corejar', false)) { + tasks.register('signCoreJar') { + group = 'signing' + description = 'Signs the reobfuscated core jar before embedding it.' + dependsOn tasks.named('reobfCoreJar', org.gradle.jvm.tasks.Jar) + onlyIf { hasSigningConfig() } + doLast { + signJar(tasks.named('reobfCoreJar', org.gradle.jvm.tasks.Jar).get().archiveFile.get().asFile) + } + } + tasks.named('jar').configure { + dependsOn tasks.named('signCoreJar') + } +} + +tasks.named('build').configure { + finalizedBy tasks.named('signMainJar') +} \ No newline at end of file diff --git a/gradle/scripts/spotless.gradle b/gradle/scripts/spotless.gradle new file mode 100644 index 000000000..7d0ade6c4 --- /dev/null +++ b/gradle/scripts/spotless.gradle @@ -0,0 +1,25 @@ +apply plugin: 'com.diffplug.spotless' + +spotless { + encoding 'UTF-8' + format 'misc', { + target '.gitignore', '*.md', '*.properties', 'gradle/**/*.properties' + trimTrailingWhitespace() + indentWithTabs() + endWithNewline() + } + groovyGradle { + target '*.gradle', 'gradle/**/*.gradle' + trimTrailingWhitespace() + indentWithTabs() + endWithNewline() + } + java { + target 'src/main/java/**/*.java', 'src/test/java/**/*.java' + trimTrailingWhitespace() + removeUnusedImports() + importOrder('java', 'javax', 'net.minecraft', 'net.minecraftforge', 'blusunrize', 'net.iiteam', '') + indentWithTabs() + endWithNewline() + } +} \ No newline at end of file diff --git a/gradle/tools/opti.sh b/gradle/tools/opti.sh index 7bd327c57..e4653de63 100644 --- a/gradle/tools/opti.sh +++ b/gradle/tools/opti.sh @@ -12,26 +12,19 @@ processAudio () { touch $1.tmp $LOC_FFMPEG -y -i $1 -f ogg -c:a libvorbis -b:a 120k $1.tmp & wait - if [ -s $1.tmp ] - then - rm $1 - mv $1.tmp $1 - else - echo "Cannot convert file, output is empty." - rm $1.tmp - return; - fi + rm $1 + mv $1.tmp $1 } while getopts "ia" arg; do case $arg in i) echo "Processing images..." - for f in $(find ./src/main/resources/assets/*/textures -name '*.png'); do chmod 644 "$f"; ./gradle/tools/oxipng "$f" --zc 9 -f 0-5 --nc --strip all; done + for f in $(find ./src/main/resources/assets/immersiveintelligence/textures -name '*.png'); do ./gradle/tools/oxipng $f --zc 9 -f 0-5 --nc --strip all; done ;; a) echo "Processing audio..." - for f in $(find ./src/main/resources/assets/*/sounds -name '*.ogg'); do processAudio $f; done + for f in $(find ./src/main/resources/assets/immersiveintelligence/sounds -name '*.ogg'); do processAudio $f; done ;; esac done \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index bcfa40cd1..f004c34c0 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 000000000..59531e47a --- /dev/null +++ b/settings.gradle @@ -0,0 +1,34 @@ +pluginManagement { + repositories { + maven { + name = 'GTNH Maven' + url = 'https://nexus.gtnewhorizons.com/repository/public/' + mavenContent { + includeGroup 'com.gtnewhorizons' + includeGroup 'com.gtnewhorizons.retrofuturagradle' + } + } + gradlePluginPortal() + mavenCentral() + mavenLocal() + } +} + +plugins { + id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0' +} + +rootProject.name = 'ImmersiveIntelligence' + +gradle.ext.mkxScriptSwitches = [ + 'ii_script_repositories': 'gradle/scripts/repositories.gradle', + 'ii_script_ide': 'gradle/scripts/ide.gradle', + 'ii_script_lombok': 'gradle/scripts/lombok.gradle', + 'ii_script_modworks': 'gradle/scripts/modworks.gradle', + 'ii_script_junit': 'gradle/scripts/junit.gradle', + 'ii_script_spotless': 'gradle/scripts/spotless.gradle', + 'ii_script_dependencies': 'gradle/scripts/dependencies.gradle', + 'ii_script_corejar': 'gradle/scripts/corejar.gradle', + 'ii_script_signing': 'gradle/scripts/signing.gradle', + 'ii_script_publishing': 'gradle/scripts/publishing.gradle' +] \ No newline at end of file diff --git a/src/main/resources/assets/immersiveintelligence/models/item/minecart/metal_barrel.json b/src/main/resources/assets/immersiveintelligence/models/item/minecart/metal_barrel.json deleted file mode 100644 index f6c79f641..000000000 --- a/src/main/resources/assets/immersiveintelligence/models/item/minecart/metal_barrel.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "immersiveintelligence:items/minecart/metal_barrel" - } -} \ No newline at end of file diff --git a/src/main/resources/META-INF/immersiveintelligence_at.cfg b/src/main/resources/immersiveintelligence_at.cfg similarity index 100% rename from src/main/resources/META-INF/immersiveintelligence_at.cfg rename to src/main/resources/immersiveintelligence_at.cfg diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info index 40b4557ee..0602c02b1 100644 --- a/src/main/resources/mcmod.info +++ b/src/main/resources/mcmod.info @@ -1,15 +1,16 @@ [ { - "modid": "immersiveintelligence", - "name": "Immersive Intelligence", - "description": "Adds new machines related to data, logistics, warfare and intelligence.", - "version": "${version}", - "mcversion": "${mcversion}", - "url": "https://www.curseforge.com/minecraft/mc-mods/immersive-intelligence", - "updateUrl": "", - "authorList": ["Pabilo8", "Carver", "Schaeferd-CZ", "Bastian", "VDeltaGabriel"], - "credits": "The II and IG community ^^", - "logoFile": "assets/immersiveintelligence/logo.png", - "screenshots": [] + "modid": ${mod_id_json}, + "name": ${mod_name_json}, + "description": ${mod_description_json}, + "version": ${mod_version_json}, + "mcversion": ${minecraft_version_json}, + "url": ${mod_url_json}, + "updateUrl": ${mod_update_json_json}, + "authorList": ${mod_authors_json}, + "credits": ${mod_credits_json}, + "logoFile": ${mod_logo_path_json}, + "screenshots": [], + "dependencies": ["immersiveengineering"] } -] +] \ No newline at end of file diff --git a/src/main/resources/pack.mcmeta b/src/main/resources/pack.mcmeta index 1f51e5833..a03257640 100644 --- a/src/main/resources/pack.mcmeta +++ b/src/main/resources/pack.mcmeta @@ -1,6 +1,6 @@ { "pack": { "pack_format": 3, - "description": "Resources used for Immersive Intelligence" + "description": ${pack_description_json} } } \ No newline at end of file From 05af934df1132b37a90f37e695202996f859f12a Mon Sep 17 00:00:00 2001 From: VDeltaGabriel Date: Fri, 31 Jul 2026 20:38:52 +0200 Subject: [PATCH 2/2] Javadoc generates and fixed ComputerCraft compat to support "legacy" version --- .github/workflows/pr.yml | 2 +- .github/workflows/push.yml | 2 +- .github/workflows/release_dev.yml | 2 +- gradle.properties | 3 +- gradle/scripts/dependencies.gradle | 1 + gradle/scripts/modworks.gradle | 7 +++ .../tileentity/TileEntityDataConnector.java | 14 +---- .../common/compat/ComputerCraftHelper.java | 54 +++++++++++++++++-- 8 files changed, 63 insertions(+), 22 deletions(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index dd378f9e2..95b8aef3c 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -42,7 +42,7 @@ jobs: uses: actions/setup-java@v4 with: distribution: corretto - java-version: 8 + java-version: 25 - name: Setup Gradle uses: gradle/gradle-build-action@v3 diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index cf5a21a12..e22e9c729 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -32,7 +32,7 @@ jobs: uses: actions/setup-java@v4 with: distribution: corretto - java-version: 8 + java-version: 25 - name: Setup Gradle uses: gradle/gradle-build-action@v3 diff --git a/.github/workflows/release_dev.yml b/.github/workflows/release_dev.yml index 15eb170dc..552f48386 100644 --- a/.github/workflows/release_dev.yml +++ b/.github/workflows/release_dev.yml @@ -24,7 +24,7 @@ jobs: uses: actions/setup-java@v4 with: distribution: corretto - java-version: 8 + java-version: 25 - name: Setup Gradle uses: gradle/gradle-build-action@v3 diff --git a/gradle.properties b/gradle.properties index f2fdb0229..ba60f76a7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -46,7 +46,7 @@ ii_use_modern_java_syntax=true ii_modern_java_language=21 generate_sources_jar=true -generate_javadocs_jar=false +generate_javadocs_jar=true show_testing_output=false # Team II Maven @@ -79,6 +79,7 @@ immersive_technology_version=3658279 mysticalmechanics_version=3006392 bwm_suite_version=5702821 reauth_version=4408001 +computercraft_version=1.80pr1 # Core-jar script settings corejar_plugin_class=pl.pabilo8.immersiveintelligence.common.asm.IILoadingPlugin diff --git a/gradle/scripts/dependencies.gradle b/gradle/scripts/dependencies.gradle index 74b2fdb12..e326acc5f 100644 --- a/gradle/scripts/dependencies.gradle +++ b/gradle/scripts/dependencies.gradle @@ -13,6 +13,7 @@ dependencies { compileOnly rfg.deobf("curse.maven:baubles-227083:${mkxString('baubles_version')}") compileOnly rfg.deobf("org.squiddev:cc-tweaked-1.12.2:${mkxString('cc_tweaked_version')}") + compileOnly rfg.deobf("dan200.computercraft:ComputerCraft:${mkxString('computercraft_version')}") compileOnly rfg.deobf("li.cil.oc:OpenComputers:${mkxString('opencomputers_version')}") compileOnly rfg.deobf("curse.maven:tough-as-nails-246391:${mkxString('tough_as_nails_version')}") diff --git a/gradle/scripts/modworks.gradle b/gradle/scripts/modworks.gradle index da9e4f786..48f4c7fa6 100644 --- a/gradle/scripts/modworks.gradle +++ b/gradle/scripts/modworks.gradle @@ -46,6 +46,13 @@ if (mkxBool('generate_sources_jar', true)) { } if (mkxBool('generate_javadocs_jar', false)) { + javadoc { + failOnError = false + options.source = '8' + options.addStringOption("tag", "updated:a:Updated:") + options.addStringOption("tag", "ii-approved:a:IIApproved:") + } + tasks.named('javadoc').configure { dependsOn compileJavaTask } diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/data_device/tileentity/TileEntityDataConnector.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/data_device/tileentity/TileEntityDataConnector.java index 5b1922e75..93ad7c7cb 100644 --- a/src/main/java/pl/pabilo8/immersiveintelligence/common/block/data_device/tileentity/TileEntityDataConnector.java +++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/block/data_device/tileentity/TileEntityDataConnector.java @@ -12,8 +12,6 @@ import blusunrize.immersiveengineering.common.blocks.IEBlockInterfaces.IHammerInteraction; import blusunrize.immersiveengineering.common.util.Utils; import com.google.common.annotations.VisibleForTesting; -import dan200.computercraft.api.peripheral.IPeripheral; -import dan200.computercraft.api.peripheral.IPeripheralTile; import net.minecraft.block.state.IBlockState; import net.minecraft.client.resources.I18n; import net.minecraft.entity.EntityLivingBase; @@ -45,10 +43,8 @@ * @author Pabilo8 (pabilo@iiteam.net) * @since 31.05.2019 */ -@Optional.Interface(iface = "dan200.computercraft.api.peripheral.IPeripheralTile", modid = "computercraft") public class TileEntityDataConnector extends TileEntityImmersiveConnectable implements - ITickable, IDirectionalTile, IHammerInteraction, IBlockBounds, IDataConnector, IOBJModelCallback, IAdvancedTextOverlay, - IPeripheralTile + ITickable, IDirectionalTile, IHammerInteraction, IBlockBounds, IDataConnector, IOBJModelCallback, IAdvancedTextOverlay { //--- OpenComputers / ComputerCraft compat ---// public DataPacket lastReceived = null; @@ -296,14 +292,6 @@ public String[] getOverlayText(EntityPlayer player, RayTraceResult mop) return null; } - @Nullable - @Override - @Optional.Method(modid = "computercraft") - public IPeripheral getPeripheral(@Nonnull EnumFacing facing) - { - return facing==this.facing?ComputerCraftHelper.createConnectorPeripheral(this): null; - } - @VisibleForTesting public void setColor(EnumDyeColor color) { diff --git a/src/main/java/pl/pabilo8/immersiveintelligence/common/compat/ComputerCraftHelper.java b/src/main/java/pl/pabilo8/immersiveintelligence/common/compat/ComputerCraftHelper.java index 87cb46713..ccc417356 100644 --- a/src/main/java/pl/pabilo8/immersiveintelligence/common/compat/ComputerCraftHelper.java +++ b/src/main/java/pl/pabilo8/immersiveintelligence/common/compat/ComputerCraftHelper.java @@ -1,10 +1,15 @@ package pl.pabilo8.immersiveintelligence.common.compat; -import dan200.computercraft.api.lua.ArgumentHelper; +import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.lua.ILuaContext; import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.peripheral.IComputerAccess; import dan200.computercraft.api.peripheral.IPeripheral; +import dan200.computercraft.api.peripheral.IPeripheralProvider; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; import net.minecraftforge.fml.common.Optional; import pl.pabilo8.immersiveintelligence.api.data.DataPacket; import pl.pabilo8.immersiveintelligence.api.data.DataVariable; @@ -28,10 +33,19 @@ public static DataConnectorPeripheral createConnectorPeripheral(TileEntityDataCo return new DataConnectorPeripheral(te); } + public static boolean isCCTweaked() { + try { + Class.forName("dan200.computercraft.api.peripheral.IPeripheralTile"); + return true; + } catch(ClassNotFoundException e) + { + return false; + } + } + @Override public void preInit() { - } @Override @@ -49,7 +63,7 @@ public void registerRecipes() @Override public void init() { - + ComputerCraftAPI.registerPeripheralProvider(new DataConnectorPeripheralProvider()); } @Override @@ -58,6 +72,23 @@ public void postInit() } + @Optional.Interface(iface = "dan200.computercraft.api.peripheral.IPeripheralProvider", modid = "computercraft") + public static class DataConnectorPeripheralProvider implements IPeripheralProvider + { + @Nullable + @Override + @Optional.Method(modid = "computercraft") + public IPeripheral getPeripheral(@Nonnull World world, @Nonnull BlockPos pos, @Nonnull EnumFacing facing) { + TileEntity tile = world.getTileEntity(pos); + if (tile != null && tile instanceof TileEntityDataConnector) + { + TileEntityDataConnector te = (TileEntityDataConnector)tile; + return facing==te.getFacing()?ComputerCraftHelper.createConnectorPeripheral(te): null; + } + return null; + } + } + @Optional.Interface(iface = "dan200.computercraft.api.peripheral.IPeripheral", modid = "computercraft") public static class DataConnectorPeripheral implements IPeripheral { @@ -99,13 +130,26 @@ public Object[] callMethod(@Nonnull IComputerAccess computer, @Nonnull ILuaConte DataPacket packet = new DataPacket(); if(args.length > 0) { - Map map = ArgumentHelper.optTable(args, 0, new HashMap<>()); + Map map; + if (ComputerCraftHelper.isCCTweaked()) + map = dan200.computercraft.api.lua.ArgumentHelper.optTable(args, 0, new HashMap<>()); + else + map = dan200.computercraft.core.apis.ArgumentHelper.optTable(args, 0, new HashMap<>()); + for(char c : DataPacket.VARIABLE_NAMES) if(map.containsKey(String.valueOf(c))) //parse into IDataType { Object o = map.get(String.valueOf(c)); DataType type; - switch(ArgumentHelper.getType(o)) + + String strType = ""; + if (ComputerCraftHelper.isCCTweaked()) + strType = dan200.computercraft.api.lua.ArgumentHelper.getType(o); + else + strType = dan200.computercraft.core.apis.ArgumentHelper.getType(o); + + + switch(strType) { default: case "string":