Frontend: - replace the i18next stack with a small typed i18n module - hero clouds removed, llms.txt, HUD widget ARIA fixes and tests Mod: - TargetESP constellation mode; tracker and colors extracted - JumpCircles: 7 new shapes, shared animation and color pipeline - KillEffect blood mode with Burst/Fountain/Ring/Spray styles - main menu: menuLayout setting (orbs/hero) and hero screen - Simple Voice Chat soft integration: VoiceChat module and HUD panel - renderer/quick: static Draw facade with glass outline - vanilla chat: Baritone-style autocomplete popup for the % command prefix
480 lines
18 KiB
Groovy
480 lines
18 KiB
Groovy
plugins {
|
||
id 'net.fabricmc.fabric-loom' version '1.17.12'
|
||
id 'maven-publish'
|
||
id 'pmd'
|
||
id 'checkstyle'
|
||
id 'com.github.spotbugs' version '6.5.11'
|
||
}
|
||
|
||
repositories {
|
||
mavenCentral()
|
||
maven {
|
||
url = 'https://maven.fabricmc.net/'
|
||
}
|
||
exclusiveContent {
|
||
forRepository {
|
||
maven {
|
||
name = "Modrinth"
|
||
url = "https://api.modrinth.com/maven"
|
||
}
|
||
}
|
||
filter {
|
||
includeGroup "maven.modrinth"
|
||
}
|
||
}
|
||
maven {
|
||
// ViaFabricPlus / ViaVersion
|
||
url = 'https://repo.viaversion.com/everything'
|
||
}
|
||
maven {
|
||
// ViaBedrock snapshots (dependency of ViaFabricPlus)
|
||
url = 'https://repo.opencollab.dev/maven-snapshots/'
|
||
}
|
||
maven {
|
||
// ViaBedrock snapshots (alt repo used by Via* stack)
|
||
url = 'https://maven.lenni0451.net/snapshots'
|
||
}
|
||
maven {
|
||
// Simple Voice Chat API (optional compat)
|
||
url = 'https://maven.maxhenkel.de/repository/public'
|
||
}
|
||
maven {
|
||
// JitPack (for com.github.* artifacts like CubeConverter)
|
||
url = 'https://jitpack.io'
|
||
}
|
||
maven {
|
||
url = uri("$rootDir/local-maven")
|
||
}
|
||
}
|
||
|
||
version = project.mod_version
|
||
group = project.maven_group
|
||
|
||
base {
|
||
archivesName = project.archives_base_name
|
||
}
|
||
|
||
def lovisualVulkanDebugEnabled = providers.gradleProperty("lovisualVulkanDebug")
|
||
.map { it.toBoolean() }
|
||
.orElse(false)
|
||
def lovisualDevTaskRequested = gradle.startParameter.taskNames.any { it == "buildDev" || it.endsWith(":buildDev") }
|
||
def lovisualDevEnabled = providers.gradleProperty("lovisualDev")
|
||
.orElse(providers.gradleProperty("dev"))
|
||
.orElse(providers.gradleProperty("devBuild"))
|
||
.orElse(lovisualDevTaskRequested ? "true" : "false")
|
||
.map { it.toBoolean() }
|
||
.orElse(false)
|
||
def svgMsdfGeneratedResources = layout.buildDirectory.dir("generated/resources/svgMsdf")
|
||
def javetNativeGeneratedResources = layout.buildDirectory.dir("generated/resources/javetNatives")
|
||
def javetVersion = "5.0.9"
|
||
def targetJavaVersion = 25
|
||
|
||
sourceSets {
|
||
main {
|
||
resources.srcDir(svgMsdfGeneratedResources)
|
||
}
|
||
svgMsdfTool {
|
||
java.srcDir("src/svgMsdfTool/java")
|
||
compileClasspath += sourceSets.main.output.classesDirs + sourceSets.main.compileClasspath
|
||
runtimeClasspath += output + compileClasspath
|
||
}
|
||
dev {
|
||
java.srcDir("src/dev/java")
|
||
resources.srcDir("src/dev/resources")
|
||
compileClasspath += sourceSets.main.output + sourceSets.main.compileClasspath
|
||
runtimeClasspath += output + compileClasspath
|
||
}
|
||
vulkanDebug {
|
||
java.srcDir("src/vulkanDebug/java")
|
||
resources.srcDir("src/vulkanDebug/resources")
|
||
compileClasspath += sourceSets.main.output + sourceSets.main.compileClasspath
|
||
runtimeClasspath += output + compileClasspath
|
||
}
|
||
}
|
||
|
||
configurations {
|
||
bundledLibrary
|
||
javetNativeBundle
|
||
compileOnly.extendsFrom bundledLibrary
|
||
runtimeOnly.extendsFrom bundledLibrary
|
||
devImplementation.extendsFrom implementation
|
||
devCompileOnly.extendsFrom compileOnly
|
||
devAnnotationProcessor.extendsFrom annotationProcessor
|
||
vulkanDebugImplementation.extendsFrom implementation
|
||
vulkanDebugCompileOnly.extendsFrom compileOnly
|
||
vulkanDebugAnnotationProcessor.extendsFrom annotationProcessor
|
||
}
|
||
|
||
loom {
|
||
mods {
|
||
"lovisual" {
|
||
sourceSet sourceSets.main
|
||
if (lovisualDevEnabled.get()) {
|
||
sourceSet sourceSets.dev
|
||
}
|
||
if (lovisualVulkanDebugEnabled.get()) {
|
||
sourceSet sourceSets.vulkanDebug
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
dependencies {
|
||
compileOnly 'org.projectlombok:lombok:1.18.46'
|
||
annotationProcessor 'org.projectlombok:lombok:1.18.46'
|
||
testCompileOnly 'org.projectlombok:lombok:1.18.46'
|
||
testAnnotationProcessor 'org.projectlombok:lombok:1.18.46'
|
||
testImplementation platform('org.junit:junit-bom:5.14.4')
|
||
testImplementation 'org.junit.jupiter:junit-jupiter'
|
||
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
|
||
devCompileOnly 'org.projectlombok:lombok:1.18.46'
|
||
devAnnotationProcessor 'org.projectlombok:lombok:1.18.46'
|
||
vulkanDebugCompileOnly 'org.projectlombok:lombok:1.18.46'
|
||
vulkanDebugAnnotationProcessor 'org.projectlombok:lombok:1.18.46'
|
||
|
||
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
||
implementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
||
// Loader 0.19.4 ships MixinExtras 0.5.4, which crashes on @Redirect(at) arrays with this Mixin; 0.5.5 handles them.
|
||
implementation "io.github.llamalad7:mixinextras-fabric:${project.mixinextras_version}"
|
||
include "io.github.llamalad7:mixinextras-fabric:${project.mixinextras_version}"
|
||
implementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
||
|
||
|
||
// Renderer targets. Sodium is required; Iris stays optional but available in dev runtime.
|
||
compileOnly "maven.modrinth:sodium:${project.sodium_version}"
|
||
compileOnly "maven.modrinth:iris:${project.iris_version}"
|
||
compileOnly "maven.modrinth:immediatelyfast:${project.immediatelyfast_version}"
|
||
if (providers.gradleProperty("withOptionalModRuntime").map { it.toBoolean() }.orElse(false).get()) {
|
||
runtimeOnly "maven.modrinth:sodium:${project.sodium_version}"
|
||
runtimeOnly "maven.modrinth:iris:${project.iris_version}"
|
||
runtimeOnly "maven.modrinth:immediatelyfast:${project.immediatelyfast_version}"
|
||
}
|
||
|
||
// Dev-only Xaero API for optional triangulator waypoint compat.
|
||
// Pulled from Modrinth Maven so IDE sources/classes follow the selected MC version.
|
||
compileOnly "maven.modrinth:xaeros-minimap:${project.xaero_minimap_version}"
|
||
compileOnly "maven.modrinth:xaeros-world-map:${project.xaero_worldmap_version}"
|
||
|
||
// ViaFabricPlus (optional)
|
||
compileOnly "com.viaversion:viafabricplus-api:${project.viafabricplus_version}"
|
||
if (providers.gradleProperty("withViaFabricPlusRuntime").map { it.toBoolean() }.orElse(false).get()) {
|
||
// Dev/runtime only (not bundled) to test locally.
|
||
runtimeOnly "com.viaversion:viafabricplus:${project.viafabricplus_version}"
|
||
}
|
||
|
||
// Simple Voice Chat (optional): client plugin API for speaking indicators; the mod provides it at runtime.
|
||
compileOnly "de.maxhenkel.voicechat:voicechat-api:${project.voicechat_api_version}"
|
||
|
||
// Entity Culling (optional): typed compile-time API for shader ESP visibility compat.
|
||
compileOnly "maven.modrinth:entityculling:${project.entityculling_version}"
|
||
|
||
bundledLibrary "de.marhali:json5-java:3.0.0"
|
||
|
||
// Linux MPRIS backend for the built-in media session service.
|
||
bundledLibrary "com.github.hypfvieh:dbus-java-core:4.3.1"
|
||
bundledLibrary "com.github.hypfvieh:dbus-java-transport-native-unixsocket:4.3.1"
|
||
|
||
// Provided by Minecraft runtime; keep it out of the bundled jar.
|
||
compileOnly 'com.google.code.gson:gson:2.14.0'
|
||
|
||
// Provided by Minecraft/Fabric runtime; do not shade it into the mod jar.
|
||
compileOnly 'org.slf4j:slf4j-api:2.0.17'
|
||
|
||
bundledLibrary 'io.github.classgraph:classgraph:4.8.192'
|
||
|
||
// Javet core only. Native V8 binaries are copied into resources/javet/natives.
|
||
bundledLibrary "com.caoccao.javet:javet:${javetVersion}"
|
||
|
||
// LuaJ: scripted hand/item poses for HoldMyItems (MIT, pure Java interpreter).
|
||
bundledLibrary "org.luaj:luaj-jse:3.0.1"
|
||
testImplementation "org.luaj:luaj-jse:3.0.1"
|
||
|
||
// Javet in minimal V8 mode only: no Node runtime and no ARM native payloads.
|
||
// ARM builds can be added later behind a separate opt-in distribution profile.
|
||
javetNativeBundle "com.caoccao.javet:javet-v8-windows-x86_64:${javetVersion}"
|
||
javetNativeBundle "com.caoccao.javet:javet-v8-linux-x86_64:${javetVersion}"
|
||
javetNativeBundle "com.caoccao.javet:javet-v8-macos-x86_64:${javetVersion}"
|
||
|
||
}
|
||
|
||
tasks.named('test') {
|
||
useJUnitPlatform()
|
||
}
|
||
|
||
tasks.register("validateIrisPatches", JavaExec) {
|
||
group = "verification"
|
||
description = "Compiles bundled Iris patch manifests against a shaderpack zip without modifying it."
|
||
dependsOn classes
|
||
classpath = sourceSets.main.runtimeClasspath
|
||
mainClass = "dev.loki.lovisual.render.iris.patch.ShaderPatchCompilerCli"
|
||
doFirst {
|
||
if (!project.hasProperty("shaderpack")) {
|
||
throw new GradleException("Pass -Pshaderpack=<path-to-shaderpack.zip>")
|
||
}
|
||
args project.property("shaderpack")
|
||
}
|
||
}
|
||
|
||
tasks.register("generateSvgMsdf", Exec) {
|
||
group = "render assets"
|
||
description = "Generates MTSDF texture assets for tintable SVG icons."
|
||
dependsOn tasks.named("compileSvgMsdfToolJava")
|
||
|
||
def inputDir = file("src/main/resources/assets/lovisual/svg")
|
||
def outputDir = svgMsdfGeneratedResources.map { it.dir("assets/lovisual/svg/msdf") }
|
||
def script = file("tools/msdf/GenerateSvgMsdf.ps1")
|
||
def preprocessorClasspath = sourceSets.svgMsdfTool.output.classesDirs.asPath +
|
||
File.pathSeparator + sourceSets.main.output.classesDirs.asPath +
|
||
File.pathSeparator + sourceSets.main.compileClasspath.asPath
|
||
def generatorJava = javaToolchains.launcherFor {
|
||
languageVersion = JavaLanguageVersion.of(targetJavaVersion)
|
||
}
|
||
inputs.files(fileTree(inputDir) {
|
||
include "**/*.svg"
|
||
exclude "msdf/**"
|
||
})
|
||
inputs.file(script)
|
||
outputs.dir(outputDir)
|
||
onlyIf {
|
||
if (!script.isFile()) {
|
||
logger.warn("SVG MSDF generator missing: ${script}")
|
||
return false
|
||
}
|
||
if (!org.gradle.internal.os.OperatingSystem.current().isWindows()) {
|
||
logger.warn("SVG MSDF generation requires Windows (PowerShell); skipping on ${org.gradle.internal.os.OperatingSystem.current().getFamilyName()}")
|
||
return false
|
||
}
|
||
return true
|
||
}
|
||
doFirst {
|
||
outputDir.get().asFile.mkdirs()
|
||
}
|
||
commandLine "powershell",
|
||
"-NoProfile",
|
||
"-ExecutionPolicy", "Bypass",
|
||
"-File", script.absolutePath,
|
||
"-InputRoot", inputDir.path,
|
||
"-OutRoot", outputDir.get().asFile.path,
|
||
"-PreprocessorClasspath", preprocessorClasspath,
|
||
"-JavaExe", generatorJava.get().executablePath.asFile.absolutePath
|
||
}
|
||
|
||
|
||
tasks.register("unpackJavetNatives", Copy) {
|
||
group = "runtime assets"
|
||
description = "Copies bundled Javet V8 native binaries into generated resources."
|
||
into javetNativeGeneratedResources.map { it.dir("javet/natives") }
|
||
from({ configurations.javetNativeBundle.collect { zipTree(it) } }) {
|
||
include "**/*.dll", "**/*.so", "**/*.dylib"
|
||
eachFile { details ->
|
||
details.path = details.name
|
||
}
|
||
includeEmptyDirs = false
|
||
}
|
||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||
}
|
||
|
||
tasks.register("syncJavetNatives", Copy) {
|
||
group = "runtime assets"
|
||
description = "Copies Javet V8 native binaries into src/main/resources/javet/natives for committing/debugging."
|
||
into file("src/main/resources/javet/natives")
|
||
from({ configurations.javetNativeBundle.collect { zipTree(it) } }) {
|
||
include "**/*.dll", "**/*.so", "**/*.dylib"
|
||
eachFile { details ->
|
||
details.path = details.name
|
||
}
|
||
includeEmptyDirs = false
|
||
}
|
||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||
}
|
||
|
||
processResources {
|
||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||
dependsOn tasks.named("generateSvgMsdf")
|
||
dependsOn tasks.named("unpackJavetNatives")
|
||
from(javetNativeGeneratedResources)
|
||
inputs.property "version", project.version
|
||
inputs.property "minecraft_version", project.minecraft_version
|
||
inputs.property "lovisual_dev", lovisualDevEnabled.get()
|
||
inputs.property "lovisual_vulkan_debug", lovisualVulkanDebugEnabled.get()
|
||
filteringCharset "UTF-8"
|
||
|
||
filesMatching("fabric.mod.json") {
|
||
expand "version": project.version,
|
||
"minecraft_version": project.minecraft_version,
|
||
"loader_version": project.loader_version
|
||
}
|
||
|
||
doLast {
|
||
if (!lovisualDevEnabled.get() && !lovisualVulkanDebugEnabled.get()) return
|
||
def metadataFile = new File(destinationDir, "fabric.mod.json")
|
||
def metadata = new groovy.json.JsonSlurper().parse(metadataFile)
|
||
def mixins = metadata.mixins instanceof java.util.Collection
|
||
? new ArrayList(metadata.mixins)
|
||
: new ArrayList()
|
||
if (lovisualDevEnabled.get() && !mixins.contains("lovisual-dev.mixins.json")) {
|
||
mixins.add("lovisual-dev.mixins.json")
|
||
}
|
||
if (!mixins.contains("lovisual-vulkan-debug.mixins.json")) {
|
||
if (lovisualVulkanDebugEnabled.get()) {
|
||
mixins.add("lovisual-vulkan-debug.mixins.json")
|
||
}
|
||
}
|
||
metadata.mixins = mixins
|
||
metadataFile.setText(
|
||
groovy.json.JsonOutput.prettyPrint(groovy.json.JsonOutput.toJson(metadata)) + System.lineSeparator(),
|
||
"UTF-8"
|
||
)
|
||
}
|
||
}
|
||
|
||
tasks.named("processDevResources") {
|
||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||
}
|
||
|
||
tasks.withType(JavaCompile).configureEach {
|
||
// ensure that the encoding is set to UTF-8, no matter what the system default is
|
||
// this fixes some edge cases with special characters not displaying correctly
|
||
// see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html
|
||
// If Javadoc is generated, this must be specified in that task too.
|
||
it.options.encoding = "UTF-8"
|
||
if (targetJavaVersion >= 10 || JavaVersion.current().isJava10Compatible()) {
|
||
it.options.release.set(targetJavaVersion)
|
||
}
|
||
}
|
||
|
||
tasks.named("compileDevJava").configure { enabled = lovisualDevEnabled.get() }
|
||
tasks.named("processDevResources").configure { enabled = lovisualDevEnabled.get() }
|
||
tasks.named("compileVulkanDebugJava").configure { enabled = lovisualVulkanDebugEnabled.get() }
|
||
tasks.named("processVulkanDebugResources").configure { enabled = lovisualVulkanDebugEnabled.get() }
|
||
|
||
java {
|
||
def javaVersion = JavaVersion.toVersion(targetJavaVersion)
|
||
if (JavaVersion.current() < javaVersion) {
|
||
toolchain.languageVersion = JavaLanguageVersion.of(targetJavaVersion)
|
||
}
|
||
// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
|
||
// if it is present.
|
||
// If you remove this line, sources will not be generated.
|
||
withSourcesJar()
|
||
}
|
||
|
||
pmd {
|
||
toolVersion = '7.27.0'
|
||
ruleSetFiles = files("config/pmd/ruleset.xml")
|
||
ruleSets = []
|
||
ignoreFailures = true
|
||
consoleOutput = true
|
||
sourceSets = [sourceSets.main]
|
||
}
|
||
|
||
checkstyle {
|
||
toolVersion = '14.1.0'
|
||
configFile = file("config/checkstyle/checkstyle.xml")
|
||
ignoreFailures = true
|
||
showViolations = true
|
||
sourceSets = [sourceSets.main]
|
||
}
|
||
|
||
spotbugs {
|
||
toolVersion = '4.10.3'
|
||
ignoreFailures = true
|
||
showProgress = true
|
||
}
|
||
|
||
spotbugsMain {
|
||
reports {
|
||
html.required = true
|
||
xml.required = false
|
||
}
|
||
}
|
||
|
||
tasks.withType(com.github.spotbugs.snom.SpotBugsTask).configureEach {
|
||
if (it.name != "spotbugsMain") {
|
||
it.enabled = false
|
||
}
|
||
}
|
||
|
||
tasks.register("checkFolderLimit") {
|
||
group = "verification"
|
||
description = "Проверяет правило ≤4 файла на папку (проектное)"
|
||
doLast {
|
||
def base = file("src/main/java")
|
||
def bad = []
|
||
base.eachDirRecurse { dir ->
|
||
def files = dir.listFiles({ f -> f.name.endsWith(".java") } as FileFilter)
|
||
def count = files != null ? files.length : 0
|
||
if (count > 4) bad << "${dir} : ${count}"
|
||
}
|
||
if (!bad.isEmpty()) {
|
||
logger.warn("Папок >4 файлов:\n" + bad.join("\n"))
|
||
if (!project.hasProperty("ignoreFolderLimit")) {
|
||
throw new GradleException("Правило ≤4 файла/папку нарушено:\n" + bad.join("\n") + "\nИсправь разбивкой на подпапки")
|
||
}
|
||
} else {
|
||
logger.lifecycle("checkFolderLimit: OK (0 папок >4)")
|
||
}
|
||
}
|
||
}
|
||
check.dependsOn("checkFolderLimit")
|
||
|
||
tasks.matching { it.name == "sourcesJar" }.configureEach {
|
||
dependsOn tasks.named("generateSvgMsdf")
|
||
exclude("javet/natives/**")
|
||
}
|
||
|
||
jar {
|
||
manifest {
|
||
attributes("Multi-Release": "true")
|
||
}
|
||
|
||
from("LICENSE") {
|
||
rename { "${it}_${project.archives_base_name}" }
|
||
}
|
||
from {
|
||
configurations.bundledLibrary.collect { it.isDirectory() ? it : zipTree(it) }
|
||
}
|
||
exclude "com/google/gson/**"
|
||
exclude "org/slf4j/**"
|
||
exclude "META-INF/*.RSA", "META-INF/*.SF", "META-INF/*.DSA"
|
||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||
|
||
if (lovisualDevEnabled.get()) {
|
||
dependsOn tasks.named("compileDevJava"), tasks.named("processDevResources")
|
||
from(sourceSets.dev.output)
|
||
}
|
||
if (lovisualVulkanDebugEnabled.get()) {
|
||
dependsOn tasks.named("compileVulkanDebugJava"), tasks.named("processVulkanDebugResources")
|
||
from(sourceSets.vulkanDebug.output)
|
||
}
|
||
}
|
||
|
||
// Gradle cannot accept an arbitrary global `--dev` flag for the built-in `build` task
|
||
// from build.gradle itself. Use this alias or `-PlovisualDev=true`.
|
||
tasks.register("buildDev") {
|
||
group = "build"
|
||
description = "Builds LoVisual with development source set and dev metadata enabled."
|
||
dependsOn "build"
|
||
}
|
||
|
||
// configure the maven publication
|
||
publishing {
|
||
publications {
|
||
create("mavenJava", MavenPublication) {
|
||
artifactId = project.archives_base_name
|
||
from components.java
|
||
}
|
||
}
|
||
|
||
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
|
||
repositories {
|
||
maven {
|
||
name = "GitHubPackages"
|
||
url = uri("https://maven.pkg.github.com/loki5512344/lovisual-client")
|
||
credentials {
|
||
username = findProperty("gpr.user") ?: System.getenv("GITHUB_ACTOR") ?: ""
|
||
password = findProperty("gpr.key") ?: System.getenv("GITHUB_TOKEN") ?: System.getenv("GH_TOKEN") ?: ""
|
||
}
|
||
}
|
||
}
|
||
}
|