1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-11-02 06:32:59 +00:00

Merge branch 'mc-1.20.x' into mc-1.21.x

Oh, I'm sure I missed something here. This was a nasty merge, has the
docs have changed so much in each version.
This commit is contained in:
Jonathan Coates
2025-01-11 17:53:53 +00:00
61 changed files with 1009 additions and 491 deletions

View File

@@ -3,7 +3,7 @@
// SPDX-License-Identifier: MPL-2.0
import cc.tweaked.gradle.*
import net.neoforged.gradle.dsl.common.runs.run.Run
import net.neoforged.moddevgradle.dsl.RunModel
plugins {
id("cc-tweaked.forge")
@@ -19,106 +19,122 @@ cct {
allProjects.forEach { externalSources(it) }
}
sourceSets {
main {
resources.srcDir("src/generated/resources")
}
testMod { runs { modIdentifier = "cctest" } }
testFixtures { runs { modIdentifier = "cctest" } }
}
minecraft {
accessTransformers {
file("src/main/resources/META-INF/accesstransformer.cfg")
}
}
runs {
configureEach {
systemProperty("forge.logging.markers", "REGISTRIES")
systemProperty("forge.logging.console.level", "debug")
neoForge {
val computercraft by mods.registering {
cct.sourceDirectories.get().forEach {
if (it.classes) modSources.add("computercraft", it.sourceSet)
}
dependencies {
runtime(configurations["minecraftLibrary"])
if (it.classes) sourceSet(it.sourceSet)
}
}
val client by registering {
workingDirectory(file("run"))
}
val server by registering {
workingDirectory(file("run/server"))
argument("--nogui")
}
val data by registering {
workingDirectory(file("run"))
arguments.addAll(
"--mod", "computercraft", "--all",
"--output", layout.buildDirectory.dir("generatedResources").getAbsolutePath(),
"--existing", project(":common").file("src/main/resources/").absolutePath,
"--existing", file("src/main/resources/").absolutePath,
)
modSources.add("computercraft", sourceSets.datagen.get())
}
fun Run.configureForGameTest() {
gameTest()
systemProperty("cctest.sources", project(":common").file("src/testMod/resources/data/cctest").absolutePath)
modSource(sourceSets.testMod.get())
modSource(sourceSets.testFixtures.get())
modSources.add("cctest", project(":core").sourceSets.testFixtures.get())
jvmArgument("-ea")
dependencies {
runtime(configurations["testMinecraftLibrary"])
val computercraftDatagen by mods.registering {
cct.sourceDirectories.get().forEach {
if (it.classes) sourceSet(it.sourceSet)
}
sourceSet(sourceSets.datagen.get())
}
val gameTestServer by registering {
workingDirectory(file("run/testServer"))
configureForGameTest()
val testMod by mods.registering {
sourceSet(sourceSets.testMod.get())
sourceSet(sourceSets.testFixtures.get())
sourceSet(project(":core").sourceSets["testFixtures"])
}
val gameTestClient by registering {
configure(runTypes.named("client"))
val exampleMod by mods.registering {
sourceSet(sourceSets.examples.get())
}
workingDirectory(file("run/testClient"))
configureForGameTest()
runs {
configureEach {
ideName = "Forge - ${name.capitalise()}"
systemProperty("forge.logging.markers", "REGISTRIES")
systemProperty("forge.logging.console.level", "debug")
loadedMods.add(computercraft)
}
systemProperties("cctest.tags", "client,common")
register("client") {
client()
}
register("server") {
server()
gameDirectory = file("run/server")
programArgument("--nogui")
}
fun RunModel.configureForData(mod: String, sourceSet: SourceSet) {
data()
gameDirectory = file("run/run${name.capitalise()}")
programArguments.addAll(
"--mod", mod, "--all",
"--output",
layout.buildDirectory.dir(sourceSet.getTaskName("generateResources", null))
.getAbsolutePath(),
"--existing", project.project(":common").file("src/${sourceSet.name}/resources/").absolutePath,
"--existing", project.file("src/${sourceSet.name}/resources/").absolutePath,
)
}
register("data") {
configureForData("computercraft", sourceSets.main.get())
loadedMods = listOf(computercraftDatagen.get())
}
fun RunModel.configureForGameTest() {
systemProperty(
"cctest.sources",
project.project(":common").file("src/testMod/resources/data/cctest").absolutePath,
)
programArgument("--mixin.config=computercraft-gametest.mixins.json")
loadedMods.add(testMod)
jvmArgument("-ea")
}
register("testClient") {
client()
gameDirectory = file("run/testClient")
configureForGameTest()
systemProperty("cctest.tags", "client,common")
}
register("gametest") {
type = "gameTestServer"
configureForGameTest()
systemProperty("forge.logging.console.level", "info")
systemProperty(
"cctest.gametest-report",
layout.buildDirectory.dir("test-results/runGametest.xml").getAbsolutePath(),
)
gameDirectory = file("run/gametest")
}
register("exampleClient") {
client()
loadedMods.add(exampleMod.get())
}
register("exampleData") {
configureForData("examplemod", sourceSets.examples.get())
loadedMods.add(exampleMod.get())
}
}
}
configurations {
val minecraftEmbed by registering {
isCanBeResolved = false
isCanBeConsumed = false
}
named("jarJar") { extendsFrom(minecraftEmbed.get()) }
additionalRuntimeClasspath { extendsFrom(jarJar.get()) }
val minecraftLibrary by registering {
isCanBeResolved = true
isCanBeConsumed = false
extendsFrom(minecraftEmbed.get())
}
runtimeOnly { extendsFrom(minecraftLibrary.get()) }
val testMinecraftLibrary by registering {
val testAdditionalRuntimeClasspath by registering {
isCanBeResolved = true
isCanBeConsumed = false
// Prevent ending up with multiple versions of libraries on the classpath.
shouldResolveConsistentlyWith(minecraftLibrary.get())
shouldResolveConsistentlyWith(additionalRuntimeClasspath.get())
}
for (testConfig in listOf("testClientAdditionalRuntimeClasspath", "gametestAdditionalRuntimeClasspath")) {
named(testConfig) { extendsFrom(testAdditionalRuntimeClasspath.get()) }
}
register("testWithIris") {
@@ -136,21 +152,18 @@ dependencies {
runtimeOnly(libs.bundles.externalMods.forge.runtime) { cct.exclude(this) }
compileOnly(variantOf(libs.create.forge) { classifier("slim") }) { isTransitive = false }
implementation("net.neoforged:neoforge:${libs.versions.neoForge.get()}")
// Depend on our other projects.
api(commonClasses(project(":forge-api"))) { cct.exclude(this) }
clientApi(clientClasses(project(":forge-api"))) { cct.exclude(this) }
implementation(project(":core")) { cct.exclude(this) }
"minecraftEmbed"(libs.cobalt)
"minecraftEmbed"(libs.jzlib)
jarJar(libs.cobalt)
jarJar(libs.jzlib)
// We don't jar-in-jar our additional netty dependencies (see the tasks.jarJar configuration), but still want them
// on the legacy classpath.
"minecraftLibrary"(libs.netty.http)
"minecraftLibrary"(libs.netty.socks)
"minecraftLibrary"(libs.netty.proxy)
additionalRuntimeClasspath(libs.netty.http) { isTransitive = false }
additionalRuntimeClasspath(libs.netty.socks) { isTransitive = false }
additionalRuntimeClasspath(libs.netty.proxy) { isTransitive = false }
testFixturesApi(libs.bundles.test)
testFixturesApi(libs.bundles.kotlin)
@@ -163,8 +176,8 @@ dependencies {
testModImplementation(testFixtures(project(":forge")))
// Ensure our test fixture dependencies are on the classpath
"testMinecraftLibrary"(libs.bundles.kotlin)
"testMinecraftLibrary"(libs.bundles.test)
"testAdditionalRuntimeClasspath"(libs.bundles.kotlin)
"testAdditionalRuntimeClasspath"(libs.bundles.test)
testFixturesImplementation(testFixtures(project(":core")))
@@ -178,15 +191,12 @@ tasks.processResources {
inputs.property("modVersion", modVersion)
inputs.property("neoVersion", libs.versions.neoForge.get())
filesMatching("META-INF/neoforge.mods.toml") {
filesMatching("META-INF/mods.toml") {
expand(mapOf("neoVersion" to libs.versions.neoForge.get(), "file" to mapOf("jarVersion" to modVersion)))
}
}
tasks.jar {
archiveClassifier.set("slim")
duplicatesStrategy = DuplicatesStrategy.FAIL
// Include all classes from other projects except core.
val coreSources = project(":core").sourceSets["main"]
for (source in cct.sourceDirectories.get()) {
@@ -203,42 +213,28 @@ tasks.sourcesJar {
for (source in cct.sourceDirectories.get()) from(source.sourceSet.allSource)
}
tasks.jarJar {
archiveClassifier.set("")
}
tasks.assemble { dependsOn("jarJar") }
// Check tasks
tasks.test {
systemProperty("cct.test-files", layout.buildDirectory.dir("tmp/testFiles").getAbsolutePath())
}
val runGametest by tasks.registering(JavaExec::class) {
group = LifecycleBasePlugin.VERIFICATION_GROUP
description = "Runs tests on a temporary Minecraft instance."
dependsOn("cleanRunGametest")
val runGametest = tasks.named<JavaExec>("runGametest") {
usesService(MinecraftRunnerService.get(gradle))
copyFromTask("runGameTestServer")
systemProperty("forge.logging.console.level", "info")
systemProperty("cctest.gametest-report", layout.buildDirectory.dir("test-results/$name.xml").getAbsolutePath())
}
cct.jacoco(runGametest)
tasks.check { dependsOn(runGametest) }
val runGametestClient by tasks.registering(ClientJavaExec::class) {
description = "Runs client-side gametests with no mods"
copyFrom("runGameTestClient")
copyFromForge("runTestClient")
tags("client")
}
cct.jacoco(runGametestClient)
val runGametestClientWithIris by tasks.registering(ClientJavaExec::class) {
description = "Runs client-side gametests with Iris"
copyFrom("runGameTestClient")
copyFromForge("runGameTestClient")
tags("iris")
classpath += configurations["testWithIris"]
@@ -256,20 +252,15 @@ tasks.register("checkClient") {
// Upload tasks
modPublishing {
output.set(tasks.jarJar)
output.set(tasks.jar)
}
// Don't publish the slim jar
for (cfg in listOf(configurations.apiElements, configurations.runtimeElements)) {
cfg.configure { artifacts.removeIf { it.classifier == "slim" } }
}
tasks.withType(GenerateModuleMetadata::class).configureEach { isEnabled = false }
publishing {
publications {
named("maven", MavenPublication::class) {
mavenDependencies {
cct.configureExcludes(this)
exclude(libs.jei.forge.get())
}
}
}

View File

@@ -0,0 +1,41 @@
package com.example.examplemod;
import com.example.examplemod.peripheral.BrewingStandPeripheral;
import dan200.computercraft.api.peripheral.PeripheralCapability;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.fml.common.Mod;
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent;
import net.neoforged.neoforge.registries.RegisterEvent;
/**
* The main entry point for the Forge version of our example mod.
*/
@Mod(ExampleMod.MOD_ID)
public class ForgeExampleMod {
public ForgeExampleMod(IEventBus modBus) {
// Register our turtle upgrade. If writing a Forge-only mod, you'd normally use DeferredRegister instead.
// However, this is an easy way to implement this in a multi-loader-compatible manner.
// @start region=turtle_upgrades
modBus.addListener((RegisterEvent event) -> {
event.register(
ITurtleUpgrade.typeRegistry(),
ResourceLocation.fromNamespaceAndPath(ExampleMod.MOD_ID, "example_turtle_upgrade"),
() -> ExampleMod.EXAMPLE_TURTLE_UPGRADE
);
});
// @end region=turtle_upgrades
modBus.addListener((FMLCommonSetupEvent event) -> ExampleMod.registerComputerCraft());
// @start region=peripherals
modBus.addListener((RegisterCapabilitiesEvent event) -> {
event.registerBlockEntity(PeripheralCapability.get(), BlockEntityType.BREWING_STAND, (b, d) -> new BrewingStandPeripheral(b));
});
// @end region=peripherals
}
}

View File

@@ -0,0 +1,20 @@
package com.example.examplemod;
import dan200.computercraft.api.client.turtle.RegisterTurtleModellersEvent;
import dan200.computercraft.api.client.turtle.TurtleUpgradeModeller;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
/**
* The client-side entry point for the Forge version of our example mod.
*/
@EventBusSubscriber(modid = ExampleMod.MOD_ID, value = Dist.CLIENT, bus = EventBusSubscriber.Bus.MOD)
public class ForgeExampleModClient {
// @start region=turtle_modellers
@SubscribeEvent
public static void onRegisterTurtleModellers(RegisterTurtleModellersEvent event) {
event.register(ExampleMod.EXAMPLE_TURTLE_UPGRADE, TurtleUpgradeModeller.flatItem());
}
// @end region=turtle_modellers
}

View File

@@ -0,0 +1,31 @@
package com.example.examplemod;
import com.example.examplemod.data.TurtleUpgradeProvider;
import net.minecraft.core.HolderLookup;
import net.minecraft.data.DataGenerator;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.common.data.DatapackBuiltinEntriesProvider;
import net.neoforged.neoforge.data.event.GatherDataEvent;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
/**
* Data generators for the Forge version of our example mod.
*/
@EventBusSubscriber(bus = EventBusSubscriber.Bus.MOD)
public class ForgeExampleModDataGenerator {
@SubscribeEvent
public static void gather(GatherDataEvent event) {
var pack = event.getGenerator().getVanillaPack(true);
addTurtleUpgrades(pack, event.getLookupProvider());
}
// @start region=turtle_upgrades
private static void addTurtleUpgrades(DataGenerator.PackGenerator pack, CompletableFuture<HolderLookup.Provider> registries) {
var fullRegistryPatch = TurtleUpgradeProvider.makeUpgradeRegistry(registries);
pack.addProvider(o -> new DatapackBuiltinEntriesProvider(o, fullRegistryPatch, Set.of(ExampleMod.MOD_ID)));
}
// @end region=turtle_upgrades
}

View File

@@ -0,0 +1,14 @@
modLoader="javafml"
loaderVersion="[1,)"
license="CC0-1.0"
[[mods]]
modId="examplemod"
version="1.0.0"
[[dependencies.examplemod]]
modId="computercraft"
mandatory=true
versionRange="[1.0,)"
ordering="AFTER"
side="BOTH"

View File

@@ -0,0 +1,6 @@
{
"pack": {
"pack_format": 15,
"description": "Example Mod"
}
}