Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
259 changes: 259 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@ import com.gtnewhorizons.retrofuturagradle.mcp.InjectTagsTask
import org.jetbrains.changelog.Changelog
import org.jetbrains.gradle.ext.Gradle

import com.gtnewhorizons.retrofuturagradle.MinecraftExtension
import com.gtnewhorizons.retrofuturagradle.mcp.MCPTasks
import com.gtnewhorizons.retrofuturagradle.minecraft.MinecraftTasks
import com.gtnewhorizons.retrofuturagradle.minecraft.RunMinecraftTask
import com.gtnewhorizons.retrofuturagradle.util.Distribution
import de.undercouch.gradle.tasks.download.DownloadExtension
import org.apache.commons.io.FileUtils

import javax.inject.Inject

plugins {
id 'java'
id 'java-library'
Expand All @@ -11,6 +21,7 @@ plugins {
id 'com.matthewprenger.cursegradle' version '1.4.0' apply false
id 'com.modrinth.minotaur' version '2.+' apply false
id 'org.jetbrains.changelog' version '2.5.0'
id 'de.undercouch.download' version '5.6.0' apply false
}

apply from: 'gradle/scripts/helpers.gradle'
Expand Down Expand Up @@ -63,6 +74,22 @@ java {

configurations {
embed
create("runtimeOnlyNonPublishable") {
description = "Runtime only dependencies that are not published alongside the jar"
canBeConsumed = false
canBeResolved = false
}
create("devOnlyNonPublishable") {
description = "Runtime and compiletime dependencies that are not published alongside the jar (compileOnly + runtimeOnlyNonPublishable)"
canBeConsumed = false
canBeResolved = false
}

compileOnly.extendsFrom(devOnlyNonPublishable)
runtimeOnlyNonPublishable.extendsFrom(devOnlyNonPublishable)
runtimeClasspath.extendsFrom(runtimeOnlyNonPublishable)
testRuntimeClasspath.extendsFrom(runtimeOnlyNonPublishable)

implementation.extendsFrom(embed)
}

Expand Down Expand Up @@ -230,9 +257,29 @@ idea {
"1. Run Client"(Gradle) {
taskNames = ["runClient"]
}
if (propertyBool('enable_java17_run_tasks')) {
'1a. Run Hotswap Client (Java 17)'(Gradle) {
taskNames = ['runClient17']
envs=[HOTSWAP:"true"]
}
'1b. Run Hotswap Client (Java 21)'(Gradle) {
taskNames = ['runClient21']
envs=[HOTSWAP:"true"]
}
}
"2. Run Server"(Gradle) {
taskNames = ["runServer"]
}
if (propertyBool('enable_java17_run_tasks')) {
'2a. Run Hotswap Server (Java 17)'(Gradle) {
taskNames = ['runServer17']
envs=[HOTSWAP:"true"]
}
'2b. Run Hotswap Server (Java 21)'(Gradle) {
taskNames = ['runServer21']
envs=[HOTSWAP:"true"]
}
}
"3. Run Obfuscated Client"(Gradle) {
taskNames = ["runObfClient"]
}
Expand Down Expand Up @@ -354,3 +401,215 @@ idea.project.settings {

apply from: 'gradle/scripts/publishing.gradle'
apply from: 'gradle/scripts/extra.gradle'


if (propertyBool('enable_java17_run_tasks')) {

apply plugin: 'de.undercouch.download'

ext.java17Toolchain = (JavaToolchainSpec spec) -> {
spec.languageVersion.set(JavaLanguageVersion.of(17))
spec.vendor.set(JvmVendorSpec.matching("jetbrains"))
}
ext.java21Toolchain = (JavaToolchainSpec spec) -> {
spec.languageVersion.set(JavaLanguageVersion.of(21))
spec.vendor.set(JvmVendorSpec.matching("jetbrains"))
}

ext.java17DependenciesCfg = configurations.create("java17Dependencies") {
extendsFrom(configurations.getByName("runtimeClasspath")) // Ensure consistent transitive dependency resolution
canBeConsumed = false
}
ext.java17PatchDependenciesCfg = configurations.create("java17PatchDependencies") {
canBeConsumed = false
}

dependencies {
if (propertyString('mod_id') != 'lwjgl3ify') {
java17Dependencies("io.github.twilightflower:lwjgl3ify:1.0.1")
java17PatchDependencies("io.github.twilightflower:lwjgl3ify:1.0.1:forgePatches") {
transitive = false
}
}
}

ext.java17JvmArgs = [
"-Dfile.encoding=UTF-8",
"-Djava.system.class.loader=com.gtnewhorizons.retrofuturabootstrap.RfbSystemClassLoader",
"-Djava.security.manager=allow",
"--add-opens", "java.base/jdk.internal.loader=ALL-UNNAMED",
"--add-opens", "java.base/java.net=ALL-UNNAMED",
"--add-opens", "java.base/java.nio=ALL-UNNAMED",
"--add-opens", "java.base/java.io=ALL-UNNAMED",
"--add-opens", "java.base/java.lang=ALL-UNNAMED",
"--add-opens", "java.base/java.lang.reflect=ALL-UNNAMED",
"--add-opens", "java.base/java.text=ALL-UNNAMED",
"--add-opens", "java.base/java.util=ALL-UNNAMED",
"--add-opens", "java.base/jdk.internal.reflect=ALL-UNNAMED",
"--add-opens", "java.base/sun.nio.ch=ALL-UNNAMED",
"--add-opens", "jdk.naming.dns/com.sun.jndi.dns=ALL-UNNAMED,java.naming",
"--add-opens", "java.desktop/sun.awt=ALL-UNNAMED",
"--add-opens", "java.desktop/sun.awt.image=ALL-UNNAMED",
"--add-opens", "java.desktop/com.sun.imageio.plugins.png=ALL-UNNAMED",
"--add-opens", "jdk.dynalink/jdk.dynalink.beans=ALL-UNNAMED",
"--add-opens", "java.sql.rowset/javax.sql.rowset.serial=ALL-UNNAMED"
]

ext.hotswapJvmArgs = [
// DCEVM advanced hot reload
"-XX:+AllowEnhancedClassRedefinition",
"-XX:HotswapAgent=fatjar"
]

ext.setupHotswapAgent17 = tasks.register("setupHotswapAgent17", SetupHotswapAgentTask, t -> {
t.setTargetForToolchain(java17Toolchain)
})

ext.setupHotswapAgent21 = tasks.register("setupHotswapAgent21", SetupHotswapAgentTask, t -> {
t.setTargetForToolchain(java21Toolchain)
})

def runClient17Task = tasks.register("runClient17", RunHotswappableMinecraftTask, Distribution.CLIENT, "runClient")
runClient17Task.configure {
dependsOn(setupHotswapAgent17)
setup(project)
javaLauncher = project.javaToolchains.launcherFor(project.java17Toolchain)
}

def runServer17Task = tasks.register("runServer17", RunHotswappableMinecraftTask, Distribution.DEDICATED_SERVER, "runServer")
runServer17Task.configure {
dependsOn(setupHotswapAgent17)
setup(project)
javaLauncher = project.javaToolchains.launcherFor(project.java17Toolchain)
}

def runClient21Task = tasks.register("runClient21", RunHotswappableMinecraftTask, Distribution.CLIENT, "runClient")
runClient21Task.configure {
dependsOn(setupHotswapAgent21)
setup(project)
javaLauncher = project.javaToolchains.launcherFor(project.java21Toolchain)
}

def runServer21Task = tasks.register("runServer21", RunHotswappableMinecraftTask, Distribution.DEDICATED_SERVER, "runServer")
runServer21Task.configure {
dependsOn(setupHotswapAgent21)
setup(project)
javaLauncher = project.javaToolchains.launcherFor(project.java21Toolchain)
}
}

abstract class RunHotswappableMinecraftTask extends RunMinecraftTask {

// IntelliJ doesn't seem to allow pre-set commandline arguments, so we also support an env variable
private boolean enableHotswap = Boolean.valueOf(System.getenv("HOTSWAP"))

public final Distribution side
public final String superTask

@Input
boolean getEnableHotswap() {
return enableHotswap
}

@Option(option = "hotswap", description = "Enables HotSwapAgent for enhanced class reloading under a debugger")
boolean setEnableHotswap(boolean enable) {
enableHotswap = enable
}

@Inject
RunHotswappableMinecraftTask(Distribution side, String superTask, org.gradle.api.invocation.Gradle gradle) {
super(side, gradle)

this.side = side
this.superTask = superTask
setGroup("Modded Minecraft")
setDescription("Runs the modded " + side.name().toLowerCase(Locale.ROOT) + " using modern Java and lwjgl3ify")
this.getLwjglVersion().set(3)
}

void setup(Project project) {
final MinecraftExtension minecraft = project.getExtensions().getByType(MinecraftExtension.class)
final MCPTasks mcpTasks = project.getExtensions().getByType(MCPTasks.class)
final MinecraftTasks mcTasks = project.getExtensions().getByType(MinecraftTasks.class)

this.getExtraJvmArgs().addAll((List<String>) project.property("java17JvmArgs"))
if (getEnableHotswap()) {
this.getExtraJvmArgs().addAll((List<String>) project.property("hotswapJvmArgs"))
}

this.classpath(project.property("java17PatchDependenciesCfg"))
this.classpath(mcpTasks.getTaskPackageMcLauncher())
this.classpath(mcpTasks.getTaskPackagePatchedMc())
this.classpath(mcpTasks.getPatchedConfiguration())
this.classpath(project.getTasks().named("jar"))
this.classpath(project.property("java17DependenciesCfg"))

super.setup(project)

dependsOn(
mcpTasks.getLauncherSources().getClassesTaskName(),
mcTasks.getTaskDownloadVanillaAssets(),
mcpTasks.getTaskPackagePatchedMc(),
"jar"
)

getMainClass().set((side == Distribution.CLIENT) ? "GradleStart" : "GradleStartServer")
getUsername().set(minecraft.getUsername())
getUserUUID().set(minecraft.getUserUUID())
if (side == Distribution.DEDICATED_SERVER) {
getExtraArgs().add("nogui")
}

systemProperty("gradlestart.bouncerClient", "com.gtnewhorizons.retrofuturabootstrap.Main")
systemProperty("gradlestart.bouncerServer", "com.gtnewhorizons.retrofuturabootstrap.Main")

if (project.use_mixins.toBoolean()) {
this.extraJvmArgs.addAll(project.provider(() -> {
def mixinCfg = project.configurations.detachedConfiguration(project.dependencies.create(project.mixinProviderSpec))
mixinCfg.canBeConsumed = false
mixinCfg.canBeResolved = true
mixinCfg.transitive = false
enableHotswap ? ["-javaagent:" + mixinCfg.singleFile.absolutePath] : []
}))
}
}
}

abstract class SetupHotswapAgentTask extends DefaultTask {

@OutputFile
abstract RegularFileProperty getTargetFile()

void setTargetForToolchain(Action<JavaToolchainSpec> spec) {
getTargetFile().set(project.javaToolchains.launcherFor(spec).map {
it.metadata.installationPath.file("lib/hotswap/hotswap-agent.jar")
})
}

@Inject
SetupHotswapAgentTask() {
setGroup("GT Buildscript")
setDescription("Installs a recent version of HotSwapAgent into the Java runtime directory")
onlyIf("Run only if not already installed", t -> !((SetupHotswapAgentTask) t).getTargetFile().getAsFile().get().exists())
}

@TaskAction
void installHSA() {
final String url = 'https://github.com/HotswapProjects/HotswapAgent/releases/download/RELEASE-2.0.3/hotswap-agent-2.0.3.jar'
final File target = getTargetFile().getAsFile().get()
final File parent = target.getParentFile()
FileUtils.forceMkdir(parent)
final DownloadExtension download = getProject().getExtensions().findByType(DownloadExtension.class)
download.run(ds -> {
try {
ds.src(url)
} catch (MalformedURLException e) {
throw new RuntimeException(e)
}
ds.dest(target)
ds.overwrite(false)
ds.tempAndMove(true)
})
}
}

1 change: 1 addition & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ org.gradle.caching = true

# Source Options
use_modern_java_syntax = false
enable_java17_run_tasks = true

# Compilation Options
generate_sources_jar = true
Expand Down
37 changes: 27 additions & 10 deletions gradle/scripts/dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,26 @@ repositories {
metadataSources { artifact() }
}

maven {
name = 'BlameJared Maven'
url = 'https://maven.blamejared.com'
}
maven {
name = 'GTCEu Maven'
url = 'https://maven.gtceu.com'
}

mavenLocal() // Must be last for caching to work
}

/**
* NOT DEPENDENCIES:
* - runtimeOnly: not required at all for the mod, added for developer convenience to run targets
* OPTIONAL DEPENDENCIES:
* - compileOnly: will not be included in developer run targets
* - devOnlyNonPublishable: will be included in developer run targets
* REQUIRED DEPENDENCIES:
* - implementation: mods or other jars that are required to be installed alongside this mod
*/
dependencies {
// Include StripLatestForgeRequirements by default for the dev env
runtimeOnly 'com.cleanroommc:strip-latest-forge-requirements:1.0'
Expand All @@ -45,28 +62,28 @@ dependencies {
// ---- Required dependencies ----

// AE2 Extended Life (AE2-UEL)
implementation rfg.deobf("curse.maven:ae2-extended-life-570458:5378163")
implementation rfg.deobf("curse.maven:ae2-extended-life-570458:6302098")

// Baubles (required by AE2)
implementation rfg.deobf("curse.maven:baubles-227083:2518667")

// ---- Optional: JEI ----
implementation rfg.deobf("curse.maven:jei-238222:4538010")
devOnlyNonPublishable 'mezz.jei:jei_1.12.2:4.16.1.302'

// ---- Optional: AE2WUT (Wireless Universal Terminal) ----
implementation rfg.deobf("curse.maven:ae2uel-wireless-universal-terminal-1196988:7366371")
devOnlyNonPublishable rfg.deobf("curse.maven:ae2uel-wireless-universal-terminal-1196988:7366371")

// ---- Optional: Thaumic Energistics ----
implementation rfg.deobf("curse.maven:thaumcraft-223628:2629023")
implementation rfg.deobf("curse.maven:thaumic-energistics-223666:2915506")
devOnlyNonPublishable rfg.deobf("curse.maven:thaumcraft-223628:2629023")
devOnlyNonPublishable rfg.deobf("curse.maven:thaumic-energistics-223666:2915506")

// ---- Optional: CrazyAE ----
implementation rfg.deobf("curse.maven:crazyae-1111042:6840104")
devOnlyNonPublishable rfg.deobf("curse.maven:crazyae-1111042:6840104")

// ---- Optional: ECO AE Extension ----
implementation "curse.maven:modularmachinery-community-edition-817377:7372951"
implementation "curse.maven:geckolib-388172:4020277"
implementation ':Nova-Engineering-ECO-AE-Extension-1.2.0@jar'
compileOnly "curse.maven:modularmachinery-community-edition-817377:7372951"
compileOnly "curse.maven:geckolib-388172:4020277"
compileOnly ':Nova-Engineering-ECO-AE-Extension-1.2.0@jar'

// ---- Test dependencies ----
// JUnit 4 via the Vintage engine on JUnit Platform
Expand Down
11 changes: 11 additions & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,21 @@ pluginManagement {
}
}

buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath group: 'commons-io', name: 'commons-io', version: '2.21.0'
}
}

plugins {
// Automatic toolchain provisioning
id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0'
}

// Different repo name from mod name
rootProject.name = 'cell-terminal'


Loading