chore(history): squash 59 commit(s) from 2026-09-23

- refactor(hud/weather/render): Scoreboard 931→240 + Rain 903→159 + UiMeshGeometry 956→99 (8.5.2)
- refactor(chams): Chams 985 → 129 + 4×≤195 (8.5.2)
- refactor(module): Module 1031 → 139 + 4×≤134 (8.5.2)
- refactor(tooltips): BetterTooltips 960 → 181 + 4×≤199 (8.5.2)
- refactor(clickgui): ClickGuiPickerState 970→166 + ModulesMenuScreen 966→145 (8.5.2)
- refactor(clickgui): CombatProtocolHeuristicsEditorState 932→79 + 4×≤192 (8.5.2)
- refactor(hud): CompactHudStatModel 894 → 125 + 4×≤175 (8.5.2)
- refactor(iris): ShaderPatchCompiler 843→66 + 4×≤174 (8.5.2)
- refactor(tab): CustomTabList 834→136 + 4×≤166 (8.5.2)
- refactor(relations): OnlineRelationPlayerPickerComponent 837→74 + 4×≤192 (8.5.2)
- refactor(hits): HitEffect 770→120 + 4×≤176 (8.5.2)
- refactor(predict): Predictions 815→150 + 4×≤195 (8.5.2)
- refactor(config): ConfigProfilesComponent 799→125 + 4×≤195 (8.5.2)
- refactor(sim): PlayerMovementSimulation 757→157 + 4×≤194 (8.5.2)
- refactor(predict): ProjectilePuncher 747→104 + 3×≤134 (8.5.2)
- refactor(crosshair): Crosshair 743→143 + 4×≤167 (8.5.2)
- refactor(mediaplayer): MediaPlayer 743→174 + 4×≤196 (8.5.2)
- refactor(hud): Itemizer 699→193 + Cooldowns 707→151 (8.5.2)
- refactor(hud): Potions 617→176 + 4×≤166 (8.5.2)
- refactor(hud): Admins 702→118 + 4×≤138 (8.5.2)
- refactor(hud): Keybinds 611→157 + 4×≤160 (8.5.2)
- refactor(hud): ModuleList 499→181 + 3×≤150 (8.5.2)
- refactor(hud): Radar 392→161 + 2×≤124 (8.5.2)
- refactor(hud): Fps 309→168 + 3×≤107 (8.5.2)
- refactor(hud): Memory 304→151 + 3×≤144 (8.5.2)
- refactor(hud): Tps 339→154 + 3×≤143 (8.5.2)
- refactor(hud): Ping 309→145 + 3×≤125 (8.5.2)
- refactor(hud): SpeedBps 334→156 + 3×≤142 (8.5.2)
- refactor(hud): GameTime 314→150 + 3×≤127 (8.5.2)
- refactor(hud): SystemTime 300→136 + 3×≤130 (8.5.2)
- refactor(hud): Coordinates 337→174 + 2×≤172 (8.5.2)
- refactor(hud): Armor 324→162 + 2×≤148 (8.5.2)
- refactor(hud): Inventory 476→153 + 3×≤181 (8.5.2)
- docs(todo): обновлён 8.5.2 — отмечены готовые гиганты (BetterButtons/InventorySwap/Svg/Темы/WorldParticles/Module/Chams и хвост)
- docs(api): папка combatant-client-26.2/docs + addons.md (API можно ломать при рефакторе)
- refactor(visuals): BlockHighlight 692→271 + 4×≤200 (8.5.2)
- refactor(mixins): GameRendererMixin 830→344 (хуки) + 4 хелпера (8.5.2)
- refactor(visuals): WorldParticles 821→260 + 6×≤200, режимы добиты (8.5.2)
- docs(todo): 8.5.2 — WorldParticles/GameRendererMixin/BlockHighlight отмечены ГОТОВО
- refactor(render): MeshBuilder 738→447 (фасад write-API) + 3 хелпера, FrameStats снесён (8.5.2)
- docs(todo): Фаза 10 — дизайн платформы (аккаунты/конфиги/аватарки), backlog RPC-чата
- docs(todo): Подсистема 3 — Аддоны 2.0 (скрипты/версии) + витрина аддонов + админка
- docs(todo): Подсистема 2 — RPC-чат/друзья/виджеты-телеметрия + рейт-лимиты, доп. правки Подсистемы 3
- chore: переименование combatant-client-26.2 -> mod, добавлены backend/ и frontend/
- docs(backend): implementation plan for accounts-service (Подсистема 1, часть 1)
- chore: пересоздать backend/frontend через cargo new и bun create vite + tailwind; убрать таблицу компонентов из TODO.md
- docs(backend): edition 2024 в плане вместо 2021
- chore: обновить версии до реально актуальных (проверено компиляцией)
- docs: правила платформы (лимит 250 строк, антипаттерны backend/frontend по итогам ресёрча) + frontend/ARCHITECTURE.md
- docs: добавить правило ≤4 файла на папку в правила платформы (backend/frontend)
- docs: commit messages in English from now on
- chore: gitignore .superpowers/ scratch directory
- docs: commit messages in English from now on (mod)
- feat(backend): scaffold accounts-service with health check
- chore(backend): remove target/ build artifacts from git, add gitignore
- chore: track docs/ in git (was accidentally gitignored, never committed)
- chore(backend): convert to Cargo workspace, plan full microservice layout
- feat(backend): accounts/avatars/device_links schema + migration
- feat(backend): argon2id password hashing
This commit is contained in:
loki5512344 2026-09-23 22:38:08 +02:00
parent ec10395511
commit 9d08fa910a
2239 changed files with 35265 additions and 28110 deletions

466
mod/build.gradle Normal file
View file

@ -0,0 +1,466 @@
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 {
// 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}"
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}"
}
// 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}"
// 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") ?: ""
}
}
}
}