2023-03-15 21:52:13 +00:00
|
|
|
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
|
|
|
|
//
|
|
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
|
2022-11-17 09:26:57 +00:00
|
|
|
import cc.tweaked.gradle.CCTweakedExtension
|
2022-10-29 17:17:02 +00:00
|
|
|
import cc.tweaked.gradle.CCTweakedPlugin
|
2022-10-22 16:47:39 +00:00
|
|
|
import com.diffplug.gradle.spotless.FormatExtension
|
|
|
|
import com.diffplug.spotless.LineEnding
|
2022-11-09 18:58:31 +00:00
|
|
|
import net.ltgt.gradle.errorprone.CheckSeverity
|
|
|
|
import net.ltgt.gradle.errorprone.errorprone
|
2022-10-22 16:47:39 +00:00
|
|
|
import java.nio.charset.StandardCharsets
|
|
|
|
|
|
|
|
plugins {
|
2022-10-22 19:47:47 +00:00
|
|
|
`java-library`
|
2022-11-06 11:55:26 +00:00
|
|
|
idea
|
2022-10-22 16:47:39 +00:00
|
|
|
jacoco
|
2022-10-22 19:47:47 +00:00
|
|
|
checkstyle
|
2022-10-22 16:47:39 +00:00
|
|
|
id("com.diffplug.spotless")
|
2022-11-09 18:58:31 +00:00
|
|
|
id("net.ltgt.errorprone")
|
2022-10-22 16:47:39 +00:00
|
|
|
}
|
|
|
|
|
2022-11-04 21:41:59 +00:00
|
|
|
val modVersion: String by extra
|
|
|
|
val mcVersion: String by extra
|
|
|
|
|
|
|
|
group = "cc.tweaked"
|
|
|
|
version = modVersion
|
|
|
|
|
2022-11-17 09:26:57 +00:00
|
|
|
base.archivesName.convention("cc-tweaked-$mcVersion-${project.name}")
|
2022-11-04 21:41:59 +00:00
|
|
|
|
2022-10-22 19:47:47 +00:00
|
|
|
java {
|
|
|
|
toolchain {
|
2022-10-29 17:17:02 +00:00
|
|
|
languageVersion.set(CCTweakedPlugin.JAVA_VERSION)
|
2022-10-22 19:47:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
withSourcesJar()
|
|
|
|
}
|
|
|
|
|
|
|
|
repositories {
|
|
|
|
mavenCentral()
|
2023-07-02 11:21:03 +00:00
|
|
|
|
2024-06-26 17:07:56 +00:00
|
|
|
val mainMaven = maven("https://maven.squiddev.cc/mirror") {
|
2022-10-22 19:47:47 +00:00
|
|
|
name = "SquidDev"
|
2023-07-02 11:21:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
exclusiveContent {
|
|
|
|
forRepositories(mainMaven)
|
|
|
|
|
|
|
|
// Include the ForgeGradle repository if present. This requires that ForgeGradle is already present, which we
|
|
|
|
// enforce in our Forge overlay.
|
|
|
|
val fg =
|
|
|
|
project.extensions.findByType(net.minecraftforge.gradle.userdev.DependencyManagementExtension::class.java)
|
|
|
|
if (fg != null) forRepositories(fg.repository)
|
|
|
|
|
|
|
|
filter {
|
2022-10-22 19:47:47 +00:00
|
|
|
includeGroup("cc.tweaked")
|
|
|
|
// Things we mirror
|
2023-08-27 23:04:46 +00:00
|
|
|
includeGroup("commoble.morered")
|
2022-11-10 19:32:13 +00:00
|
|
|
includeGroup("dev.architectury")
|
2023-07-10 07:42:01 +00:00
|
|
|
includeGroup("dev.emi")
|
2022-10-22 19:47:47 +00:00
|
|
|
includeGroup("maven.modrinth")
|
2022-11-09 22:02:47 +00:00
|
|
|
includeGroup("me.shedaniel.cloth")
|
2023-07-10 07:42:01 +00:00
|
|
|
includeGroup("me.shedaniel")
|
2022-10-22 19:47:47 +00:00
|
|
|
includeGroup("mezz.jei")
|
2023-10-03 08:19:19 +00:00
|
|
|
includeGroup("org.teavm")
|
2022-11-20 13:00:43 +00:00
|
|
|
includeModule("com.terraformersmc", "modmenu")
|
2023-08-27 11:15:55 +00:00
|
|
|
includeModule("me.lucko", "fabric-permissions-api")
|
2022-10-22 19:47:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
dependencies {
|
|
|
|
val libs = project.extensions.getByType<VersionCatalogsExtension>().named("libs")
|
|
|
|
checkstyle(libs.findLibrary("checkstyle").get())
|
2022-11-09 18:58:31 +00:00
|
|
|
|
2023-12-19 18:12:21 +00:00
|
|
|
constraints {
|
|
|
|
checkstyle("org.codehaus.plexus:plexus-container-default:2.1.1") {
|
|
|
|
because("2.1.0 depends on deprecated Google collections module")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-09 18:58:31 +00:00
|
|
|
errorprone(libs.findLibrary("errorProne-core").get())
|
|
|
|
errorprone(libs.findLibrary("nullAway").get())
|
2022-10-22 19:47:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Configure default JavaCompile tasks with our arguments.
|
|
|
|
sourceSets.all {
|
|
|
|
tasks.named(compileJavaTaskName, JavaCompile::class.java) {
|
|
|
|
// Processing just gives us "No processor claimed any of these annotations", so skip that!
|
|
|
|
options.compilerArgs.addAll(listOf("-Xlint", "-Xlint:-processing"))
|
2022-11-09 18:58:31 +00:00
|
|
|
|
|
|
|
options.errorprone {
|
|
|
|
check("InvalidBlockTag", CheckSeverity.OFF) // Broken by @cc.xyz
|
|
|
|
check("InvalidParam", CheckSeverity.OFF) // Broken by records.
|
|
|
|
check("InlineMeSuggester", CheckSeverity.OFF) // Minecraft uses @Deprecated liberally
|
|
|
|
// Too many false positives right now. Maybe we need an indirection for it later on.
|
|
|
|
check("ReferenceEquality", CheckSeverity.OFF)
|
2024-04-28 17:32:19 +00:00
|
|
|
check("EnumOrdinal", CheckSeverity.OFF) // For now. We could replace most of these with EnumMap.
|
2022-11-09 18:58:31 +00:00
|
|
|
check("OperatorPrecedence", CheckSeverity.OFF) // For now.
|
|
|
|
check("NonOverridingEquals", CheckSeverity.OFF) // Peripheral.equals makes this hard to avoid
|
|
|
|
check("FutureReturnValueIgnored", CheckSeverity.OFF) // Too many false positives with Netty
|
|
|
|
|
|
|
|
check("NullAway", CheckSeverity.ERROR)
|
2023-10-03 08:19:19 +00:00
|
|
|
option(
|
|
|
|
"NullAway:AnnotatedPackages",
|
|
|
|
listOf("dan200.computercraft", "cc.tweaked", "net.fabricmc.fabric.api").joinToString(","),
|
|
|
|
)
|
2022-11-09 18:58:31 +00:00
|
|
|
option("NullAway:ExcludedFieldAnnotations", listOf("org.spongepowered.asm.mixin.Shadow").joinToString(","))
|
|
|
|
option("NullAway:CastToNonNullMethod", "dan200.computercraft.core.util.Nullability.assertNonNull")
|
|
|
|
option("NullAway:CheckOptionalEmptiness")
|
|
|
|
option("NullAway:AcknowledgeRestrictiveAnnotations")
|
Replace integer instance IDs with UUIDs
Here's a fun bug you can try at home:
- Create a new world
- Spawn in a pocket computer, turn it on, and place it in a chest.
- Reload the world - the pocket computer in the chest should now be
off.
- Spawn in a new pocket computer, and turn it on. The computer in chest
will also appear to be on!
This bug has been present since pocket computers were added (27th March,
2024).
When a pocket computer is added to a player's inventory, it is assigned
a unique *per-session* "instance id" , which is used to find the
associated computer. Note the "per-session" there - these ids will be
reused if you reload the world (or restart the server).
In the above bug, we see the following:
- The first pocket computer is assigned an instance id of 0.
- After reloading, the second pocket computer is assigned an instance
id of 0.
- If the first pocket computer was in our inventory, it'd be ticked and
assigned a new instance id. However, because it's in an inventory, it
keeps its old one.
- Both computers look up their client-side computer state and get the
same value, meaning the first pocket computer mirrors the second!
To fix this, we now ensure instance ids are entirely unique (not just
per-session). Rather than sequentially assigning an int, we now use a
random UUID (we probably could get away with a random long, but this
feels more idiomatic).
This has a couple of user-visible changes:
- /computercraft no longer lists instance ids outside of dumping an
individual computer.
- The @c[instance=...] selector uses UUIDs. We still use int instance
ids for the legacy selector, but that'll be removed in a later MC
version.
- Pocket computers now store a UUID rather than an int.
Related to this change (I made this change first, but then they got
kinda mixed up together), we now only create PocketComputerData when
receiving server data. This makes the code a little uglier in some
places (the data may now be null), but means we don't populate the
client-side pocket computer map with computers the server doesn't know
about.
2024-03-17 12:21:21 +00:00
|
|
|
|
|
|
|
excludedPaths = ".*/jmh_generated/.*"
|
2022-11-09 18:58:31 +00:00
|
|
|
}
|
2022-10-22 19:47:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-09 18:58:31 +00:00
|
|
|
tasks.compileTestJava {
|
|
|
|
options.errorprone {
|
|
|
|
check("NullAway", CheckSeverity.OFF)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-10-22 19:47:47 +00:00
|
|
|
tasks.withType(JavaCompile::class.java).configureEach {
|
|
|
|
options.encoding = "UTF-8"
|
|
|
|
}
|
|
|
|
|
2023-03-31 17:14:44 +00:00
|
|
|
tasks.processResources {
|
|
|
|
exclude("**/*.license")
|
2023-06-17 17:01:42 +00:00
|
|
|
exclude(".cache")
|
2023-03-31 17:14:44 +00:00
|
|
|
}
|
|
|
|
|
2022-11-08 16:43:27 +00:00
|
|
|
tasks.withType(AbstractArchiveTask::class.java).configureEach {
|
2022-11-04 21:41:59 +00:00
|
|
|
isPreserveFileTimestamps = false
|
2022-11-08 16:43:27 +00:00
|
|
|
isReproducibleFileOrder = true
|
2024-06-26 17:07:56 +00:00
|
|
|
filePermissions {}
|
|
|
|
dirPermissions {}
|
2022-11-08 16:43:27 +00:00
|
|
|
}
|
2022-11-04 21:41:59 +00:00
|
|
|
|
2022-11-08 16:43:27 +00:00
|
|
|
tasks.jar {
|
2022-11-04 21:41:59 +00:00
|
|
|
manifest {
|
|
|
|
attributes(
|
|
|
|
"Specification-Title" to "computercraft",
|
|
|
|
"Specification-Vendor" to "SquidDev",
|
|
|
|
"Specification-Version" to "1",
|
2022-11-17 09:26:57 +00:00
|
|
|
"Implementation-Title" to "cctweaked-${project.name}",
|
2022-11-04 21:41:59 +00:00
|
|
|
"Implementation-Version" to modVersion,
|
|
|
|
"Implementation-Vendor" to "SquidDev",
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
tasks.javadoc {
|
|
|
|
options {
|
|
|
|
val stdOptions = this as StandardJavadocDocletOptions
|
|
|
|
stdOptions.addBooleanOption("Xdoclint:all,-missing", true)
|
|
|
|
stdOptions.links("https://docs.oracle.com/en/java/javase/17/docs/api/")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-22 19:47:47 +00:00
|
|
|
tasks.test {
|
|
|
|
finalizedBy("jacocoTestReport")
|
|
|
|
|
|
|
|
useJUnitPlatform()
|
|
|
|
testLogging {
|
|
|
|
events("skipped", "failed")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
tasks.withType(JacocoReport::class.java).configureEach {
|
|
|
|
reports.xml.required.set(true)
|
|
|
|
reports.html.required.set(true)
|
|
|
|
}
|
|
|
|
|
2022-11-17 09:26:57 +00:00
|
|
|
project.plugins.withType(CCTweakedPlugin::class.java) {
|
|
|
|
// Set up jacoco to read from /all/ our source directories.
|
|
|
|
val cct = project.extensions.getByType<CCTweakedExtension>()
|
|
|
|
project.tasks.named("jacocoTestReport", JacocoReport::class.java) {
|
|
|
|
for (ref in cct.sourceSets.get()) sourceDirectories.from(ref.allSource.sourceDirectories)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-03 08:06:17 +00:00
|
|
|
tasks.register("checkstyle") {
|
|
|
|
description = "Run Checkstyle on all sources"
|
|
|
|
group = LifecycleBasePlugin.VERIFICATION_GROUP
|
|
|
|
dependsOn(tasks.withType(Checkstyle::class.java))
|
|
|
|
}
|
|
|
|
|
2022-10-22 16:47:39 +00:00
|
|
|
spotless {
|
|
|
|
encoding = StandardCharsets.UTF_8
|
|
|
|
lineEndings = LineEnding.UNIX
|
|
|
|
|
|
|
|
fun FormatExtension.defaults() {
|
|
|
|
endWithNewline()
|
|
|
|
trimTrailingWhitespace()
|
|
|
|
indentWithSpaces(4)
|
|
|
|
}
|
|
|
|
|
|
|
|
java {
|
|
|
|
defaults()
|
|
|
|
removeUnusedImports()
|
|
|
|
}
|
|
|
|
|
|
|
|
val ktlintConfig = mapOf(
|
2023-03-14 18:41:31 +00:00
|
|
|
"ktlint_standard_no-wildcard-imports" to "disabled",
|
2023-08-31 18:14:37 +00:00
|
|
|
"ktlint_standard_class-naming" to "disabled",
|
2023-12-19 18:12:21 +00:00
|
|
|
"ktlint_standard_function-naming" to "disabled",
|
2022-10-22 16:47:39 +00:00
|
|
|
"ij_kotlin_allow_trailing_comma" to "true",
|
|
|
|
"ij_kotlin_allow_trailing_comma_on_call_site" to "true",
|
|
|
|
)
|
|
|
|
|
|
|
|
kotlinGradle {
|
|
|
|
defaults()
|
|
|
|
ktlint().editorConfigOverride(ktlintConfig)
|
|
|
|
}
|
|
|
|
|
|
|
|
kotlin {
|
|
|
|
defaults()
|
|
|
|
ktlint().editorConfigOverride(ktlintConfig)
|
|
|
|
}
|
|
|
|
}
|
2022-11-06 11:55:26 +00:00
|
|
|
|
|
|
|
idea.module {
|
|
|
|
excludeDirs.addAll(project.files("run", "out", "logs").files)
|
|
|
|
|
|
|
|
// Force Gradle to write to inherit the output directory from the parent, instead of writing to out/xxx/classes.
|
|
|
|
// This is required for Loom, and we patch Forge's run configurations to work there.
|
|
|
|
// TODO: Submit a patch to Forge to support ProjectRootManager.
|
|
|
|
inheritOutputDirs = true
|
|
|
|
}
|