From 7a4e319c00262f54cfba69fbc1ca831583a2d568 Mon Sep 17 00:00:00 2001 From: awruff Date: Mon, 24 Aug 2026 12:28:29 -0400 Subject: [PATCH 01/14] closes #963 --- .../internal/mixin/events/Mixin_ChatReceiveEvent.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ChatReceiveEvent.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ChatReceiveEvent.java index bab5723c3..22d20786d 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ChatReceiveEvent.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ChatReceiveEvent.java @@ -76,10 +76,13 @@ public Component modifyMessage(Component message) { return false; } + ChatEvent.Receive event = new ChatEvent.Receive(adventure); + EventManager.INSTANCE.post(event); + + ocfg$chatEvent = event; + ocfg$nativeMessage = message; ocfg$postedMessage = adventure; - ocfg$chatEvent = new ChatEvent.Receive(adventure); - EventManager.INSTANCE.post(ocfg$chatEvent); - return ocfg$chatEvent.cancelled; + return event.cancelled; } /** From 84aa0bb23f2bb0230dd4d6b02f392aee52971523 Mon Sep 17 00:00:00 2001 From: awruff Date: Mon, 24 Aug 2026 12:28:36 -0400 Subject: [PATCH 02/14] closes #976 --- .../api/notifications/v1/NotificationToasts.kt | 6 ++++-- .../api/notifications/v1/NotificationsRenderer.kt | 3 ++- .../org/polyfrost/compose/render/RenderContext.kt | 14 +++++++++++++- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/modules/notifications/src/main/kotlin/org/polyfrost/oneconfig/api/notifications/v1/NotificationToasts.kt b/modules/notifications/src/main/kotlin/org/polyfrost/oneconfig/api/notifications/v1/NotificationToasts.kt index 65b4988bc..79691905a 100644 --- a/modules/notifications/src/main/kotlin/org/polyfrost/oneconfig/api/notifications/v1/NotificationToasts.kt +++ b/modules/notifications/src/main/kotlin/org/polyfrost/oneconfig/api/notifications/v1/NotificationToasts.kt @@ -68,7 +68,7 @@ private const val ICON_GAP = 12f private const val TITLE_SIZE = 14f private const val MESSAGE_SIZE = 12f -private const val ICON_RASTER_SCALE = 2 +private const val ICON_RASTER_SCALE = 2f internal sealed interface ToastHit { val notification: Notification @@ -84,6 +84,7 @@ private const val PROGRESS_LINGER_NANOS = 600_000_000L internal object ToastViewport { var width by mutableStateOf(0f) var height by mutableStateOf(0f) + var scale by mutableStateOf(1f) } @Composable @@ -240,7 +241,8 @@ private fun ToastIcon(notification: Notification, a: Float) { val dh = custom.height * s image(custom, x + (w - dw) / 2f, y + (h - dh) / 2f, dw, dh, Paint().also { it.setAlphaf(a) }) } else { - val img = SvgRasterizer.get(notification.type.iconName, (w * ICON_RASTER_SCALE).toInt()) + val pixelSize = Math.ceil((w * ToastViewport.scale * ICON_RASTER_SCALE).toDouble()).toInt() + val img = SvgRasterizer.get(notification.type.iconName, pixelSize) if (img != null) { val paint = Paint().also { it.colorFilter = ColorFilter.makeBlend(tint.argb, BlendMode.SRC_IN) } image(img, x, y, w, h, paint) diff --git a/modules/notifications/src/main/kotlin/org/polyfrost/oneconfig/api/notifications/v1/NotificationsRenderer.kt b/modules/notifications/src/main/kotlin/org/polyfrost/oneconfig/api/notifications/v1/NotificationsRenderer.kt index 1053f7264..3696b5314 100644 --- a/modules/notifications/src/main/kotlin/org/polyfrost/oneconfig/api/notifications/v1/NotificationsRenderer.kt +++ b/modules/notifications/src/main/kotlin/org/polyfrost/oneconfig/api/notifications/v1/NotificationsRenderer.kt @@ -38,7 +38,7 @@ import org.polyfrost.oneconfig.api.platform.v1.Platform object NotificationsRenderer { private val LOGGER = LogManager.getLogger("OneConfig/Notifications") - private const val BASE_SCALE = 0.4f + private const val BASE_SCALE = 0.5f @Volatile private var runtime: PolyComposeRuntime? = null @@ -61,6 +61,7 @@ object NotificationsRenderer { val viewHeight = screenHeight * guiScale / scale ToastViewport.width = viewWidth ToastViewport.height = viewHeight + ToastViewport.scale = scale val rt = runtime() rt.frame(viewWidth, viewHeight) diff --git a/modules/poly-compose/src/main/kotlin/org/polyfrost/compose/render/RenderContext.kt b/modules/poly-compose/src/main/kotlin/org/polyfrost/compose/render/RenderContext.kt index 45078482c..0b3d57d3a 100644 --- a/modules/poly-compose/src/main/kotlin/org/polyfrost/compose/render/RenderContext.kt +++ b/modules/poly-compose/src/main/kotlin/org/polyfrost/compose/render/RenderContext.kt @@ -67,11 +67,23 @@ class RenderContext(val canvas: Canvas) { } fun image(image: Image, x: Float, y: Float, w: Float, h: Float, paint: Paint) { - canvas.drawImageRect(image, Rect.makeXYWH(x, y, w, h), paint) + paint.isAntiAlias = true + canvas.drawImageRect( + image, + Rect.makeWH(image.width.toFloat(), image.height.toFloat()), + Rect.makeXYWH(x, y, w, h), + IMAGE_SAMPLING, + paint, + true, + ) } fun scale(sx: Float, sy: Float) = canvas.scale(sx, sy) fun clipRect(x: Float, y: Float, w: Float, h: Float) = canvas.clipRect(Rect.makeXYWH(x, y, w, h)) fun clipRRect(x: Float, y: Float, w: Float, h: Float, radius: Float) = canvas.clipRRect(RRect.makeXYWH(x, y, w, h, radius), true) + + private companion object { + private val IMAGE_SAMPLING: SamplingMode = FilterMipmap(FilterMode.LINEAR, MipmapMode.NONE) + } } From 66ef01584a1dcec8f2cede79ade2c90c76aa8b75 Mon Sep 17 00:00:00 2001 From: awruff Date: Mon, 24 Aug 2026 12:28:36 -0400 Subject: [PATCH 03/14] closes #956 --- .../internal/ui/components/Sidebar.kt | 28 ++----------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/modules/internal/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/components/Sidebar.kt b/modules/internal/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/components/Sidebar.kt index 3b5d3c353..9665bcfb7 100644 --- a/modules/internal/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/components/Sidebar.kt +++ b/modules/internal/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/components/Sidebar.kt @@ -66,7 +66,7 @@ fun Sidebar() { modifier = Modifier.fillMaxWidth().padding(bottom = 18.dp), horizontalAlignment = Alignment.CenterHorizontally ) { - TopOptionsSection(flipped = true) + TopOptionsSection() } } Account() @@ -98,8 +98,8 @@ private fun Branding() { } @Composable -private fun TopOptionsSection(flipped: Boolean = false) { - val editHud: @Composable () -> Unit = { +private fun TopOptionsSection() { + NavigationSection { NavigationEntry( "hud", "Edit HUD", @@ -107,28 +107,6 @@ private fun TopOptionsSection(flipped: Boolean = false) { HudManager.openEditor() } } - val globalSearch: @Composable () -> Unit = { - NavigationEntry( - "search", - "Global Search", - ) { - ShellState.globalSearchActive = true - if (ShellState.searchQuery.isBlank()) { - ShellState.searchQuery = "" - } - ShellState.showSearchField = true - ShellState.focusSearchField = true - } - } - NavigationSection { - if (flipped) { - globalSearch() - editHud() - } else { - editHud() - globalSearch() - } - } } @Composable From 8b35143412ae03384182d4502e4d344c50133e83 Mon Sep 17 00:00:00 2001 From: awruff Date: Mon, 24 Aug 2026 12:53:29 -0400 Subject: [PATCH 04/14] closes #997 --- .../oneconfig/internal/ui/hud/screens/HudDesignStudio.kt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/modules/internal/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/screens/HudDesignStudio.kt b/modules/internal/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/screens/HudDesignStudio.kt index fc8cc74e9..5abc8fb7f 100644 --- a/modules/internal/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/screens/HudDesignStudio.kt +++ b/modules/internal/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/screens/HudDesignStudio.kt @@ -188,6 +188,7 @@ private val snapGuideColor = Color(176, 47, 31) private const val CHROME_SETTINGS_PANEL = "settings-panel" private const val CHROME_LIBRARY = "library" private const val SIDE_CHROME_DIM_ALPHA = 0.45f +private const val LIBRARY_HOVER_HUD_ALPHA = 0.25f private data class SnapGuides(val vertical: Float?, val horizontal: Float?) { companion object { @@ -1565,6 +1566,12 @@ fun HudDesignStudio(onReturnToOneConfig: (() -> Unit)? = null) { label = "sideChromeAlpha" ) + val libraryAlpha by animateFloatAsState( + targetValue = if (hoveredHud != null) LIBRARY_HOVER_HUD_ALPHA else sideChromeAlpha, + animationSpec = tween(150), + label = "libraryAlpha" + ) + Box( modifier = Modifier .fillMaxSize() @@ -1988,7 +1995,7 @@ fun HudDesignStudio(onReturnToOneConfig: (() -> Unit)? = null) { Row( modifier = Modifier .chromeRegion(CHROME_LIBRARY) - .graphicsLayer { alpha = sideChromeAlpha } + .graphicsLayer { alpha = libraryAlpha } .safePointerEvent(PointerEventType.Press, PointerEventPass.Final) { event -> event.changes.forEach { if (!it.isConsumed) it.consume() } } From 87fcddd5fc3f6d109a1cb660642e9d0090a4edbd Mon Sep 17 00:00:00 2001 From: Saad Nadeem Date: Fri, 19 Jun 2026 16:20:43 -0400 Subject: [PATCH 05/14] feat(legacy): build setup --- bootstrap/ornithe.gradle.kts | 13 +++++ build.gradle.kts | 1 + buildSrc/build.gradle.kts | 3 ++ buildSrc/settings.gradle.kts | 3 ++ .../kotlin/oneconfig-bootstrap.gradle.kts | 26 +++++++--- ...neconfig-compose-bundle-publish.gradle.kts | 13 +---- .../main/kotlin/oneconfig-setup.gradle.kts | 21 ++++++-- gradle/common/1.8.9.versions.toml | 2 + gradle/ornithe.versions.toml | 12 +++++ gradle/ornithe/1.8.9.versions.toml | 5 ++ mappings/feather-overrides.tiny | 1 + minecraft/ornithe.gradle.kts | 48 +++++++++++++++++ minecraft/src/main/resources/ornithe.mod.json | 52 +++++++++++++++++++ .../oneconfig/test/mixin/MixinAuditTest.java | 4 ++ minecraft/src/test/resources/log4j2.xml | 1 + minecraft/stonecutter.gradle.kts | 3 +- settings.gradle.kts | 13 ++++- 17 files changed, 198 insertions(+), 23 deletions(-) create mode 100644 bootstrap/ornithe.gradle.kts create mode 100644 gradle/common/1.8.9.versions.toml create mode 100644 gradle/ornithe.versions.toml create mode 100644 gradle/ornithe/1.8.9.versions.toml create mode 100644 mappings/feather-overrides.tiny create mode 100644 minecraft/ornithe.gradle.kts create mode 100644 minecraft/src/main/resources/ornithe.mod.json create mode 100644 minecraft/src/test/resources/log4j2.xml diff --git a/bootstrap/ornithe.gradle.kts b/bootstrap/ornithe.gradle.kts new file mode 100644 index 000000000..1cf53d8a8 --- /dev/null +++ b/bootstrap/ornithe.gradle.kts @@ -0,0 +1,13 @@ +plugins { + id("net.fabricmc.fabric-loom-remap") + id("ploceus") + id("oneconfig-bootstrap") +} + +ploceus { + setIntermediaryGeneration(2) +} + +dependencies { + mappings(ploceus.featherMappings(versionedCatalog.versions["feather.build"].requiredVersion)) +} diff --git a/build.gradle.kts b/build.gradle.kts index 849bc8a2a..a0289d633 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,6 +3,7 @@ allprojects { repositories { mavenCentral() maven("https://maven.fabricmc.net/releases") + maven("https://maven.ornithemc.net/releases") } } diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 255033b76..0bb7991ee 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -7,6 +7,7 @@ repositories { mavenCentral() gradlePluginPortal() maven("https://maven.fabricmc.net/") + maven("https://maven.ornithemc.net/releases") maven("https://repo.polyfrost.org/releases") maven("https://maven.modmuss50.me/releases") } @@ -29,6 +30,8 @@ dependencies { implementation(plugin(fabric.plugins.loom)) implementation(plugin(fabric.plugins.loom.remap)) + implementation(plugin(ornithe.plugins.ploceus)) + implementation(plugin(neoforge.plugins.moddev)) implementation("dev.kikugie.stonecutter:dev.kikugie.stonecutter.gradle.plugin:0.9") diff --git a/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts index 1b7ed21a0..a3fff4ffd 100644 --- a/buildSrc/settings.gradle.kts +++ b/buildSrc/settings.gradle.kts @@ -9,6 +9,9 @@ dependencyResolutionManagement { create("neoforge") { from(files("../gradle/neoforge.versions.toml")) } + create("ornithe") { + from(files("../gradle/ornithe.versions.toml")) + } } } diff --git a/buildSrc/src/main/kotlin/oneconfig-bootstrap.gradle.kts b/buildSrc/src/main/kotlin/oneconfig-bootstrap.gradle.kts index 7d30dc493..9c85b1c8b 100644 --- a/buildSrc/src/main/kotlin/oneconfig-bootstrap.gradle.kts +++ b/buildSrc/src/main/kotlin/oneconfig-bootstrap.gradle.kts @@ -46,19 +46,19 @@ group = "${rootProject.group}.bootstrap" version = rootProject.version val node = project.name +val isOrnithe = node.endsWith("-ornithe") val platformPath = ":minecraft:$node" dependencies { "minecraft"("com.mojang:minecraft:${versionedCatalog.versions["minecraft"]}") } -evaluationDependsOn(platformPath) - -afterEvaluate { +gradle.projectsEvaluated { val platform = rootProject.project(platformPath) fun isExcluded(group: String?, name: String) = - (group == "net.fabricmc" && (name == "fabric-loader")) || group == "net.fabricmc.fabric-api" + (group == "net.fabricmc" && (name == "fabric-loader")) || group == "net.fabricmc.fabric-api" || + (isOrnithe && ((group == "io.github.moehreag" && name == "legacy-lwjgl3") || group == "net.ornithemc.osl-gen2")) val seen = HashSet() @@ -183,6 +183,15 @@ tasks.matching { it.name == "publishModrinth" }.configureEach { dependsOn(validateChangelog) } +if (!isOrnithe) { + tasks.publishMods.configure { + enabled = false + } + tasks.matching { it.name == "publishModrinth" }.configureEach { + enabled = false + } +} + publishMods { file = tasks.named(publishJarTaskName).flatMap { it.archiveFile } @@ -191,7 +200,7 @@ publishMods { changelog = changelogs type = STABLE - modLoaders.add("fabric") + modLoaders.add(if (isOrnithe) "ornithe" else "fabric") dryRun = modrinthId == null || modrinthToken == null @@ -202,7 +211,12 @@ publishMods { minecraftVersions.addAll(minecraftVersion) - requires("fabric-api") + if (isOrnithe) { + requires("osl") + requires("moehreag-legacy-lwjgl3") + } else { + requires("fabric-api") + } requires("fabric-language-kotlin") findProperty("publish.modrinth.compose-bundle") ?.toString() diff --git a/buildSrc/src/main/kotlin/oneconfig-compose-bundle-publish.gradle.kts b/buildSrc/src/main/kotlin/oneconfig-compose-bundle-publish.gradle.kts index b7ecffc15..a8ce4abcf 100644 --- a/buildSrc/src/main/kotlin/oneconfig-compose-bundle-publish.gradle.kts +++ b/buildSrc/src/main/kotlin/oneconfig-compose-bundle-publish.gradle.kts @@ -25,18 +25,7 @@ publishMods { projectId = modrinthId accessToken = modrinthToken.orEmpty() - minecraftVersions.addAll(listOf( - "1.21.1", - "1.21.4", - "1.21.5", - "1.21.8", - "1.21.10", - "1.21.11", - "26.1", - "26.1.1", - "26.1.2", - "26.2-rc-2" - )) + minecraftVersions.add("1.8.9") requires("fabric-language-kotlin") } diff --git a/buildSrc/src/main/kotlin/oneconfig-setup.gradle.kts b/buildSrc/src/main/kotlin/oneconfig-setup.gradle.kts index 181e1396f..cc6e6f71b 100644 --- a/buildSrc/src/main/kotlin/oneconfig-setup.gradle.kts +++ b/buildSrc/src/main/kotlin/oneconfig-setup.gradle.kts @@ -127,7 +127,7 @@ fun DependencyHandlerScope.handleApiDep( this.handleApiDep(project.provider { dependency }, isMod, transitive) } -if (loader != "fabric") { +if (loader == "neoforge") { configurations { val localRuntime = create("localRuntime") named("runtimeClasspath") { this.extendsFrom(localRuntime) } @@ -278,7 +278,7 @@ dependencies { val libsCatalog = rootProject.extensions.getByType().named("libs") when (loader) { - "fabric" -> "modRuntimeOnly"(libsCatalog.findLibrary("devauth-fabric").get()) + "fabric", "ornithe" -> "modRuntimeOnly"(libsCatalog.findLibrary("devauth-fabric").get()) "neoforge" -> "runtimeOnly"(libsCatalog.findLibrary("devauth-neoforge").get()) } @@ -378,6 +378,15 @@ afterEvaluate { } } +if (loader != "ornithe") { + tasks.withType().configureEach { + enabled = false + } + tasks.withType().configureEach { + enabled = false + } +} + tasks.withType() { val range = if (versionedCatalog.versions.has("minecraft.range")) { versionedCatalog.versions.get("minecraft.range").toString() @@ -395,9 +404,15 @@ tasks.withType() { this.inputs.properties(fabricProperties) - this.filesMatching("fabric.mod.json") { + this.filesMatching(if (loader == "ornithe") "ornithe.mod.json" else "fabric.mod.json") { expand(fabricProperties) } + if (loader == "ornithe") { + exclude("fabric.mod.json") + eachFile { if (path == "ornithe.mod.json") path = "fabric.mod.json" } + } else { + exclude("ornithe.mod.json") + } val mixinCompat = if (stonecutter.eval(stonecutter.current.version, ">= 26.1")) "JAVA_25" else "JAVA_21" this.inputs.property("mixin_compat", mixinCompat) diff --git a/gradle/common/1.8.9.versions.toml b/gradle/common/1.8.9.versions.toml new file mode 100644 index 000000000..f5046666c --- /dev/null +++ b/gradle/common/1.8.9.versions.toml @@ -0,0 +1,2 @@ +[versions] +minecraft = "1.8.9" diff --git a/gradle/ornithe.versions.toml b/gradle/ornithe.versions.toml new file mode 100644 index 000000000..e4c498cb4 --- /dev/null +++ b/gradle/ornithe.versions.toml @@ -0,0 +1,12 @@ +[versions] +loader = "0.19.3" +osl = "0.21.0-alpha.34" +feather_build = "1" +ploceus = "1.17.4" + +[libraries] +fabric-loader = { module = "net.fabricmc:fabric-loader", version.ref = "loader" } +fabric-loader-junit = { module = "net.fabricmc:fabric-loader-junit", version.ref = "loader" } + +[plugins] +ploceus = { id = "ploceus", version.ref = "ploceus" } diff --git a/gradle/ornithe/1.8.9.versions.toml b/gradle/ornithe/1.8.9.versions.toml new file mode 100644 index 000000000..db93cc67e --- /dev/null +++ b/gradle/ornithe/1.8.9.versions.toml @@ -0,0 +1,5 @@ +[versions] +legacy-lwjgl3 = "1.4.4" + +[libraries] +legacy-lwjgl3 = { module = "io.github.moehreag:legacy-lwjgl3", version.ref = "legacy-lwjgl3" } diff --git a/mappings/feather-overrides.tiny b/mappings/feather-overrides.tiny new file mode 100644 index 000000000..f92ab2ab7 --- /dev/null +++ b/mappings/feather-overrides.tiny @@ -0,0 +1 @@ +tiny 2 0 intermediary named diff --git a/minecraft/ornithe.gradle.kts b/minecraft/ornithe.gradle.kts new file mode 100644 index 000000000..def58e4a9 --- /dev/null +++ b/minecraft/ornithe.gradle.kts @@ -0,0 +1,48 @@ +plugins { + id("net.fabricmc.fabric-loom-remap") + id("ploceus") + `oneconfig-fabric` +} + +repositories { + exclusiveContent { + forRepository { mavenCentral() } + filter { includeGroup("org.lwjgl") } + } + + maven("https://maven.axolotlclient.com/releases") { + content { + includeGroup("io.github.moehreag") + includeGroup("io.github.moehreag.legacy-lwjgl3") + } + } +} + +ploceus { + setIntermediaryGeneration(2) +} + +loom { + accessWidenerPath.set(rootProject.file("minecraft/src/main/resources/oneconfigv1.classtweaker")) +} + +dependencies { + modImplementation(versionedCatalog["fabric-language-kotlin"]) + modImplementation(versionedCatalog["fabric-loader"]) + + mappings(loom.layered { + mappings(ploceus.featherMappings(versionedCatalog.versions["feather.build"].requiredVersion)) + mappings(rootProject.file("mappings/feather-overrides.tiny")) + }) + ploceus.dependOsl(versionedCatalog.versions["osl"].requiredVersion) + + configurations.configureEach { + exclude(group = "org.lwjgl.lwjgl") + } + + modApi(versionedCatalog["legacy-lwjgl3"]) { + exclude(group = "net.ornithemc.osl-gen2") + } + + api("com.mojang:brigadier:1.0.18") +} diff --git a/minecraft/src/main/resources/ornithe.mod.json b/minecraft/src/main/resources/ornithe.mod.json new file mode 100644 index 000000000..02535a424 --- /dev/null +++ b/minecraft/src/main/resources/ornithe.mod.json @@ -0,0 +1,52 @@ +{ + "schemaVersion": 1, + "id": "oneconfigv1", + "name": "OneConfig (Platform Module)", + "version": "${mod_version}", + "description": "Access all your mod settings in one place, with a sleek and intuitive interface.", + "authors": [ + "Polyfrost" + ], + "contact": { + "homepage": "https://polyfrost.org", + "sources": "https://github.com/Polyfrost/OneConfig", + "issues": "https://inv.wtf/polyfrost" + }, + "license": "LGPL-3.0", + "environment": "client", + "accessWidener": "oneconfigv1.classtweaker", + "mixins": [ + "mixins.oneconfigv1.init.json", + "mixins.oneconfigv1.json" + ], + "entrypoints": { + "client": [ + "org.polyfrost.oneconfig.internal.OneConfig" + ], + "modmenu": [ + { + "adapter": "kotlin", + "value": "org.polyfrost.oneconfig.internal.compat.ModMenuEntrypoint" + } + ], + "preLaunch": [ + "org.polyfrost.oneconfig.internal.SkikoDataPathPreLaunch" + ] + }, + "depends": { + "fabricloader": ">=0.18.0", + "minecraft": "${fabric_mc_version}", + "legacy-lwjgl3": ">=1.4.4", + "osl-core": ">=0.10.0-alpha.5", + "osl-resource-loader": ">=0.8.0-alpha.5", + "osl-localization": ">=0.1.1-alpha.3", + "osl-networking": ">=0.10.0-alpha.3", + "osl-text-components": ">=0.1.0-alpha.5" + }, + "custom": { + "modmenu": { + "parent": "oneconfig", + "badges": [ "library" ] + } + } +} diff --git a/minecraft/src/test/java/org/polyfrost/oneconfig/test/mixin/MixinAuditTest.java b/minecraft/src/test/java/org/polyfrost/oneconfig/test/mixin/MixinAuditTest.java index 9b133228a..e9d4bcf40 100644 --- a/minecraft/src/test/java/org/polyfrost/oneconfig/test/mixin/MixinAuditTest.java +++ b/minecraft/src/test/java/org/polyfrost/oneconfig/test/mixin/MixinAuditTest.java @@ -26,6 +26,7 @@ package org.polyfrost.oneconfig.test.mixin; +//? if > 1.8.9 import net.minecraft.SharedConstants; import net.minecraft.server.Bootstrap; import org.junit.jupiter.api.Assertions; @@ -79,8 +80,11 @@ static void setUpEnvironment() { "Error handler resolved to a different class than the test uses, failures would go unrecorded"); try { + //? if > 1.8.9 { SharedConstants.tryDetectVersion(); Bootstrap.bootStrap(); + //?} else + //Bootstrap.init(); } catch (Throwable t) { System.out.println("[mixin-audit] Minecraft bootstrap did not complete, continuing anyway:"); t.printStackTrace(System.out); diff --git a/minecraft/src/test/resources/log4j2.xml b/minecraft/src/test/resources/log4j2.xml new file mode 100644 index 000000000..e403921c1 --- /dev/null +++ b/minecraft/src/test/resources/log4j2.xml @@ -0,0 +1 @@ + diff --git a/minecraft/stonecutter.gradle.kts b/minecraft/stonecutter.gradle.kts index e5d3cf3a0..ab44a0a62 100644 --- a/minecraft/stonecutter.gradle.kts +++ b/minecraft/stonecutter.gradle.kts @@ -9,7 +9,8 @@ stonecutter { match( current.project.substringAfterLast("-"), "fabric", - "neoforge" + "neoforge", + "ornithe" ) val catalogue = rootProject.getForwardingVersionCatalog(current) diff --git a/settings.gradle.kts b/settings.gradle.kts index 84482934d..56fe8e2c4 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -44,9 +44,16 @@ val NEO_FORGE: ModLoader = object : ModLoader { override fun buildFile(version: String) = "neoforge.gradle.kts" } +val ORNITHE: ModLoader = object : ModLoader { + override val name: String = "ornithe" + override fun versionName(version: String) = "$version-ornithe" + override fun buildFile(version: String) = "ornithe.gradle.kts" +} + val versions = buildList { fun fabric(version: String) = add(version to listOf(FABRIC)) fun neoforge(version: String) = add(version to listOf(NEO_FORGE)) + fun ornithe(version: String) = add(version to listOf(ORNITHE)) fun both(version: String) { add(version to listOf(FABRIC)) } @@ -59,6 +66,7 @@ val versions = buildList { both("1.21.5") both("1.21.4") both("1.21.1") + ornithe("1.8.9") } stonecutter { @@ -73,7 +81,7 @@ stonecutter { // mirrors every Fabric node of the minecraft tree create("bootstrap") { versions.forEach { (version, loaders) -> - loaders.filter { it == FABRIC }.forEach { loader -> + loaders.filter { it == FABRIC || it == ORNITHE }.forEach { loader -> version(loader.versionName(version), version).buildscript = loader.buildFile(version) } } @@ -88,6 +96,9 @@ dependencyResolutionManagement { create("neoforge") { from(files(rootProject.projectDir.resolve("gradle/neoforge.versions.toml"))) } + create("ornithe") { + from(files(rootProject.projectDir.resolve("gradle/ornithe.versions.toml"))) + } versions.forEach { (version, loaders) -> val common = "common$version".replace(".", "") create(common) { From 16089990f7156bc150e74e559f5fc398ceb9d72b Mon Sep 17 00:00:00 2001 From: Saad Nadeem Date: Mon, 29 Jun 2026 17:18:33 -0400 Subject: [PATCH 06/14] feat(legacy): legacy compat helpers --- mappings/feather-overrides.tiny | 42 ++ .../blaze3d/platform/TextInputManager.java | 21 + .../legacy/FabricClientAudiences.java | 41 ++ .../internal/legacy/InputConstants.java | 421 +++++++++++++++ .../oneconfig/internal/legacy/KeyCodes.java | 162 ++++++ .../internal/legacy/NativeImage.java | 102 ++++ .../oneconfig/internal/legacy/PlayerSkin.java | 25 + .../internal/legacy/SimpleSoundInstance.java | 20 + .../internal/legacy/SoundEvents.java | 10 + .../oneconfig/internal/legacy/User.java | 23 + .../oneconfig/internal/legacy/Window.java | 51 ++ .../internal/legacy/chat/ChatFormatting.java | 63 +++ .../internal/legacy/chat/Component.java | 251 +++++++++ .../legacy/chat/ComponentContents.java | 15 + .../legacy/chat/FormattedCharSequence.java | 14 + .../legacy/chat/FormattedCharSink.java | 8 + .../internal/legacy/chat/FormattedText.java | 63 +++ .../legacy/chat/MutableComponent.java | 168 ++++++ .../legacy/chat/PlainTextContents.java | 40 ++ .../legacy/chat/StringDecomposer.java | 125 +++++ .../oneconfig/internal/legacy/chat/Style.java | 485 ++++++++++++++++++ .../legacy/chat/TranslatableContents.java | 181 +++++++ .../chat/TranslatableFormatException.java | 19 + .../oneconfig/internal/legacy/chat/Unit.java | 7 + .../ClientCommandRegistrationCallback.java | 57 ++ .../command/FabricClientCommandSource.java | 21 + .../legacy/compat/ClientPlayerCompat.java | 12 + .../legacy/compat/GameOptionsCompat.java | 23 + .../legacy/compat/HitResultCompat.java | 11 + .../legacy/compat/HttpTextureCompat.java | 15 + .../legacy/compat/KeyBindingCompat.java | 22 + .../legacy/compat/MinecraftCompat.java | 103 ++++ .../legacy/compat/SkinManagerCompat.java | 23 + .../legacy/compat/SoundInstanceCompat.java | 11 + .../main/resources/oneconfigv1.classtweaker | 13 + minecraft/stonecutter.gradle.kts | 177 ++++++- 36 files changed, 2843 insertions(+), 2 deletions(-) create mode 100644 minecraft/src/main/java/com/mojang/blaze3d/platform/TextInputManager.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/FabricClientAudiences.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/InputConstants.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/KeyCodes.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/NativeImage.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/PlayerSkin.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/SimpleSoundInstance.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/SoundEvents.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/User.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/Window.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/ChatFormatting.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/Component.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/ComponentContents.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/FormattedCharSequence.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/FormattedCharSink.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/FormattedText.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/MutableComponent.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/PlainTextContents.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/StringDecomposer.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/Style.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/TranslatableContents.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/TranslatableFormatException.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/Unit.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/command/ClientCommandRegistrationCallback.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/command/FabricClientCommandSource.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/ClientPlayerCompat.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/GameOptionsCompat.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/HitResultCompat.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/HttpTextureCompat.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/KeyBindingCompat.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/MinecraftCompat.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/SkinManagerCompat.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/SoundInstanceCompat.java create mode 100644 minecraft/src/main/resources/oneconfigv1.classtweaker diff --git a/mappings/feather-overrides.tiny b/mappings/feather-overrides.tiny index f92ab2ab7..c63061de3 100644 --- a/mappings/feather-overrides.tiny +++ b/mappings/feather-overrides.tiny @@ -1 +1,43 @@ tiny 2 0 intermediary named +c net/minecraft/unmapped/C_49122968 net/minecraft/text/Formatting + m ()Ljava/lang/String; m_85650466 serialize +c net/minecraft/unmapped/C_05113611 net/minecraft/unmapped/C_05113611 + m ()Z m_33616981 isSameThread +c net/minecraft/unmapped/C_70668269 net/minecraft/unmapped/C_70668269 + m ()Z m_33616981 isSameThread +c net/minecraft/client/Minecraft net/minecraft/client/Minecraft + f Lnet/minecraft/unmapped/C_24654288; f_81460813 hitResult + f Lnet/minecraft/unmapped/C_34399650; f_26407825 level + m (Lnet/minecraft/unmapped/C_85740840;)V m_52715402 setScreen + m ()Z m_33616981 isSameThread + m (Z)V m_77225877 continueAttack + m ()I m_53086118 getFramerateLimit + m ()Lnet/minecraft/unmapped/C_06196994; m_17688331 getMainRenderTarget + m ()V m_61857590 startUseItem +c net/minecraft/unmapped/C_23708450 net/minecraft/client/KeyMapping + m ()Z m_70603120 isDown +c net/minecraft/unmapped/C_76792751 net/minecraft/client/Options + f [Lnet/minecraft/unmapped/C_23708450; f_41636781 keyMappings + f Lnet/minecraft/unmapped/C_23708450; f_34423269 keyPlayerList +c net/minecraft/unmapped/C_85740840 net/minecraft/client/gui/screen/Screen + m ()Z m_94022149 isPauseScreen +c net/minecraft/unmapped/C_67960412 net/minecraft/client/gui/screens/LevelLoadingScreen +c net/minecraft/unmapped/C_36550219 net/minecraft/client/gui/screens/options/controls/KeyBindsList +c net/minecraft/unmapped/C_36550219$C_66337664 net/minecraft/client/gui/screens/options/controls/KeyBindsList$KeyEntry +c net/minecraft/unmapped/C_67645866 net/minecraft/client/gui/screens/options/controls/KeyBindsScreen + f Lnet/minecraft/unmapped/C_23708450; f_46607866 selectedKey +c net/minecraft/unmapped/C_34399650 net/minecraft/client/multiplayer/ClientLevel +c net/minecraft/unmapped/C_57778754 net/minecraft/client/player/LocalPlayer +c net/minecraft/unmapped/C_30593188 net/minecraft/world/scores/Objective +c net/minecraft/unmapped/C_97595263 net/minecraft/world/scores/PlayerTeam +c net/minecraft/unmapped/C_73166169 net/minecraft/world/scores/Scoreboard + m (Lnet/minecraft/unmapped/C_97595263;)V m_18544454 removePlayerTeam +c net/minecraft/server/MinecraftServer net/minecraft/server/MinecraftServer + m ()Z m_33616981 isSameThread +c net/minecraft/unmapped/C_82920792 net/minecraft/client/render/texture/TextureManager + m (Lnet/minecraft/unmapped/C_22168528;)Lnet/minecraft/unmapped/C_65241354; m_17123242 getTexture +c net/minecraft/unmapped/C_95503740 net/minecraft/client/sound/system/SoundManager + m (Lnet/minecraft/unmapped/C_28706180;F)V m_88002341 updateSourceVolume + m (Lnet/minecraft/unmapped/C_53396390;)Z m_92956382 isActive +c net/minecraft/unmapped/C_98888256 net/minecraft/item/Item + m ()Ljava/lang/String; m_27822537 getDescriptionId diff --git a/minecraft/src/main/java/com/mojang/blaze3d/platform/TextInputManager.java b/minecraft/src/main/java/com/mojang/blaze3d/platform/TextInputManager.java new file mode 100644 index 000000000..9aa7e953e --- /dev/null +++ b/minecraft/src/main/java/com/mojang/blaze3d/platform/TextInputManager.java @@ -0,0 +1,21 @@ +package com.mojang.blaze3d.platform; + +//? if = 1.8.9 { +/*import io.github.moehreag.legacylwjgl3.util.IMEManager; + +public final class TextInputManager { + private static final TextInputManager INSTANCE = new TextInputManager(); + + public static TextInputManager getInstance() { + return INSTANCE; + } + + public void startTextInput() { + IMEManager.getInstance().startTextInput(); + } + + public void stopTextInput() { + IMEManager.getInstance().stopTextInput(); + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/FabricClientAudiences.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/FabricClientAudiences.java new file mode 100644 index 000000000..b59e9a3df --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/FabricClientAudiences.java @@ -0,0 +1,41 @@ +package org.polyfrost.oneconfig.internal.legacy; + +//? if = 1.8.9 { +/*import net.kyori.adventure.audience.Audience; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; +import net.minecraft.client.Minecraft; +import net.minecraft.text.Text; + +public final class FabricClientAudiences { + private static final FabricClientAudiences INSTANCE = new FabricClientAudiences(); + private final Audience audience = new Audience() { + @Override + public void sendMessage(Component message) { + Minecraft.getInstance().gui.getChat().addMessage(toNative(message)); + } + }; + + private FabricClientAudiences() { + } + + public static FabricClientAudiences of() { + return INSTANCE; + } + + public Audience audience() { + return this.audience; + } + + public Text toNative(Component component) { + return Text.Serializer.fromJson(GsonComponentSerializer.gson().serialize(component)); + } + + public Component asAdventure(Text component) { + if (component instanceof net.minecraft.network.chat.Component) { + return ((net.minecraft.network.chat.Component) component).asComponent(); + } + return GsonComponentSerializer.gson().deserialize(Text.Serializer.toJson(component)); + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/InputConstants.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/InputConstants.java new file mode 100644 index 000000000..13057986c --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/InputConstants.java @@ -0,0 +1,421 @@ +package org.polyfrost.oneconfig.internal.legacy; + +//? if = 1.8.9 { +/*import com.google.common.base.Suppliers; +import com.google.common.collect.Maps; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; +import java.util.OptionalInt; +import java.util.function.BiFunction; +import com.google.common.base.Supplier; + +import net.minecraft.client.resources.language.I18n; +import org.lwjgl.glfw.GLFW; +import net.minecraft.network.chat.Component; + +public class InputConstants { + public static final int KEY_0 = 48; + public static final int KEY_1 = 49; + public static final int KEY_2 = 50; + public static final int KEY_3 = 51; + public static final int KEY_4 = 52; + public static final int KEY_5 = 53; + public static final int KEY_6 = 54; + public static final int KEY_7 = 55; + public static final int KEY_8 = 56; + public static final int KEY_9 = 57; + public static final int KEY_A = 65; + public static final int KEY_B = 66; + public static final int KEY_C = 67; + public static final int KEY_D = 68; + public static final int KEY_E = 69; + public static final int KEY_F = 70; + public static final int KEY_G = 71; + public static final int KEY_H = 72; + public static final int KEY_I = 73; + public static final int KEY_J = 74; + public static final int KEY_K = 75; + public static final int KEY_L = 76; + public static final int KEY_M = 77; + public static final int KEY_N = 78; + public static final int KEY_O = 79; + public static final int KEY_P = 80; + public static final int KEY_Q = 81; + public static final int KEY_R = 82; + public static final int KEY_S = 83; + public static final int KEY_T = 84; + public static final int KEY_U = 85; + public static final int KEY_V = 86; + public static final int KEY_W = 87; + public static final int KEY_X = 88; + public static final int KEY_Y = 89; + public static final int KEY_Z = 90; + public static final int KEY_F1 = 290; + public static final int KEY_F2 = 291; + public static final int KEY_F3 = 292; + public static final int KEY_F4 = 293; + public static final int KEY_F5 = 294; + public static final int KEY_F6 = 295; + public static final int KEY_F7 = 296; + public static final int KEY_F8 = 297; + public static final int KEY_F9 = 298; + public static final int KEY_F10 = 299; + public static final int KEY_F11 = 300; + public static final int KEY_F12 = 301; + public static final int KEY_F13 = 302; + public static final int KEY_F14 = 303; + public static final int KEY_F15 = 304; + public static final int KEY_F16 = 305; + public static final int KEY_F17 = 306; + public static final int KEY_F18 = 307; + public static final int KEY_F19 = 308; + public static final int KEY_F20 = 309; + public static final int KEY_F21 = 310; + public static final int KEY_F22 = 311; + public static final int KEY_F23 = 312; + public static final int KEY_F24 = 313; + public static final int KEY_F25 = 314; + public static final int KEY_NUMLOCK = 282; + public static final int KEY_NUMPAD0 = 320; + public static final int KEY_NUMPAD1 = 321; + public static final int KEY_NUMPAD2 = 322; + public static final int KEY_NUMPAD3 = 323; + public static final int KEY_NUMPAD4 = 324; + public static final int KEY_NUMPAD5 = 325; + public static final int KEY_NUMPAD6 = 326; + public static final int KEY_NUMPAD7 = 327; + public static final int KEY_NUMPAD8 = 328; + public static final int KEY_NUMPAD9 = 329; + public static final int KEY_NUMPADCOMMA = 330; + public static final int KEY_NUMPADENTER = 335; + public static final int KEY_NUMPADEQUALS = 336; + public static final int KEY_DOWN = 264; + public static final int KEY_LEFT = 263; + public static final int KEY_RIGHT = 262; + public static final int KEY_UP = 265; + public static final int KEY_ADD = 334; + public static final int KEY_APOSTROPHE = 39; + public static final int KEY_BACKSLASH = 92; + public static final int KEY_COMMA = 44; + public static final int KEY_EQUALS = 61; + public static final int KEY_GRAVE = 96; + public static final int KEY_LBRACKET = 91; + public static final int KEY_MINUS = 45; + public static final int KEY_MULTIPLY = 332; + public static final int KEY_PERIOD = 46; + public static final int KEY_RBRACKET = 93; + public static final int KEY_SEMICOLON = 59; + public static final int KEY_SLASH = 47; + public static final int KEY_SPACE = 32; + public static final int KEY_TAB = 258; + public static final int KEY_LALT = 342; + public static final int KEY_LCONTROL = 341; + public static final int KEY_LSHIFT = 340; + public static final int KEY_LSUPER = 343; + public static final int KEY_RALT = 346; + public static final int KEY_RCONTROL = 345; + public static final int KEY_RSHIFT = 344; + public static final int KEY_RSUPER = 347; + public static final int KEY_RETURN = 257; + public static final int KEY_ESCAPE = 256; + public static final int KEY_BACKSPACE = 259; + public static final int KEY_DELETE = 261; + public static final int KEY_END = 269; + public static final int KEY_HOME = 268; + public static final int KEY_INSERT = 260; + public static final int KEY_PAGEDOWN = 267; + public static final int KEY_PAGEUP = 266; + public static final int KEY_CAPSLOCK = 280; + public static final int KEY_PAUSE = 284; + public static final int KEY_SCROLLLOCK = 281; + public static final int KEY_PRINTSCREEN = 283; + public static final int PRESS = 1; + public static final int RELEASE = 0; + public static final int REPEAT = 2; + public static final int MOUSE_BUTTON_LEFT = 0; + public static final int MOUSE_BUTTON_RIGHT = 1; + public static final int MOUSE_BUTTON_MIDDLE = 2; + public static final int MOUSE_BUTTON_4 = 3; + public static final int MOUSE_BUTTON_5 = 4; + public static final int MOUSE_BUTTON_6 = 5; + public static final int MOUSE_BUTTON_7 = 6; + public static final int MOUSE_BUTTON_8 = 7; + public static final int MOD_SHIFT = 1; + public static final int MOD_CONTROL = 2; + public static final int MOD_ALT = 4; + public static final int MOD_SUPER = 8; + public static final int MOD_CAPS_LOCK = 16; + public static final int MOD_NUM_LOCK = 32; + public static final int CURSOR = 208897; + public static final int CURSOR_DISABLED = 212995; + public static final int CURSOR_NORMAL = 212993; + public static final InputConstants.Key UNKNOWN = InputConstants.Type.KEYSYM.getOrCreate(-1); + + public static InputConstants.Key getKey(final String name) { + if (InputConstants.Key.NAME_MAP.containsKey(name)) { + return (InputConstants.Key) InputConstants.Key.NAME_MAP.get(name); + } else { + for (InputConstants.Type type : InputConstants.Type.values()) { + if (name.startsWith(type.defaultPrefix)) { + String humanReadableValue = name.substring(type.defaultPrefix.length() + 1); + int intValue = Integer.parseInt(humanReadableValue); + if (type == InputConstants.Type.MOUSE) { + intValue--; + } + + return type.getOrCreate(intValue); + } + } + + throw new IllegalArgumentException("Unknown key name: " + name); + } + } + + public static final class Key { + private final String name; + private final InputConstants.Type type; + private final int value; + private final Supplier displayName; + private static final Map NAME_MAP = Maps.newHashMap(); + + private Key(final String name, final InputConstants.Type type, final int value) { + this.name = name; + this.type = type; + this.value = value; + this.displayName = Suppliers.memoize(() -> (Component) type.displayTextSupplier.apply(value, name)); + NAME_MAP.put(name, this); + } + + public InputConstants.Type getType() { + return this.type; + } + + public int getValue() { + return this.value; + } + + public String getName() { + return this.name; + } + + public Component getDisplayName() { + return (Component) this.displayName.get(); + } + + public OptionalInt getNumericKeyValue() { + if (this.value >= 48 && this.value <= 57) { + return OptionalInt.of(this.value - 48); + } else { + return this.value >= 320 && this.value <= 329 ? OptionalInt.of(this.value - 320) : OptionalInt.empty(); + } + } + + public boolean equals(final Object o) { + if (this == o) { + return true; + } else if (o != null && this.getClass() == o.getClass()) { + InputConstants.Key key = (InputConstants.Key) o; + return this.value == key.value && this.type == key.type; + } else { + return false; + } + } + + public int hashCode() { + return Objects.hash(new Object[]{this.type, this.value}); + } + + public String toString() { + return this.name; + } + } + + public static enum Type { + KEYSYM("key.keyboard", (value, name) -> { + if ("key.keyboard.unknown".equals(name)) { + return Component.translatable(name); + } else { + String systemName = GLFW.glfwGetKeyName(value, -1); + return systemName != null ? Component.literal(systemName.toUpperCase(Locale.ROOT)) : Component.translatable(name); + } + }), + SCANCODE("scancode", (value, name) -> { + String systemName = GLFW.glfwGetKeyName(-1, value); + return systemName != null ? Component.literal(systemName) : Component.translatable(name); + }), + MOUSE("key.mouse", (value, name) -> L10n.has(name) ? Component.translatable(name) : Component.translatable("key.mouse", value + 1)); + + private static final String KEY_KEYBOARD_UNKNOWN = "key.keyboard.unknown"; + private final Int2ObjectMap map = new Int2ObjectOpenHashMap<>(); + private final String defaultPrefix; + private final BiFunction displayTextSupplier; + + private static void addKey(final InputConstants.Type type, final String name, final int value) { + InputConstants.Key key = new InputConstants.Key(name, type, value); + type.map.put(value, key); + } + + private Type(final String defaultPrefix, final BiFunction displayTextSupplier) { + this.defaultPrefix = defaultPrefix; + this.displayTextSupplier = displayTextSupplier; + } + + public InputConstants.Key getOrCreate(final int value) { + return (InputConstants.Key) this.map.computeIfAbsent(value, intValue -> { + int humanReadableValue = intValue; + if (this == MOUSE) { + humanReadableValue = intValue + 1; + } + + String name = this.defaultPrefix + "." + humanReadableValue; + return new InputConstants.Key(name, this, intValue); + }); + } + + static { + addKey(KEYSYM, "key.keyboard.unknown", -1); + addKey(MOUSE, "key.mouse.left", 0); + addKey(MOUSE, "key.mouse.right", 1); + addKey(MOUSE, "key.mouse.middle", 2); + addKey(MOUSE, "key.mouse.4", 3); + addKey(MOUSE, "key.mouse.5", 4); + addKey(MOUSE, "key.mouse.6", 5); + addKey(MOUSE, "key.mouse.7", 6); + addKey(MOUSE, "key.mouse.8", 7); + addKey(KEYSYM, "key.keyboard.0", 48); + addKey(KEYSYM, "key.keyboard.1", 49); + addKey(KEYSYM, "key.keyboard.2", 50); + addKey(KEYSYM, "key.keyboard.3", 51); + addKey(KEYSYM, "key.keyboard.4", 52); + addKey(KEYSYM, "key.keyboard.5", 53); + addKey(KEYSYM, "key.keyboard.6", 54); + addKey(KEYSYM, "key.keyboard.7", 55); + addKey(KEYSYM, "key.keyboard.8", 56); + addKey(KEYSYM, "key.keyboard.9", 57); + addKey(KEYSYM, "key.keyboard.a", 65); + addKey(KEYSYM, "key.keyboard.b", 66); + addKey(KEYSYM, "key.keyboard.c", 67); + addKey(KEYSYM, "key.keyboard.d", 68); + addKey(KEYSYM, "key.keyboard.e", 69); + addKey(KEYSYM, "key.keyboard.f", 70); + addKey(KEYSYM, "key.keyboard.g", 71); + addKey(KEYSYM, "key.keyboard.h", 72); + addKey(KEYSYM, "key.keyboard.i", 73); + addKey(KEYSYM, "key.keyboard.j", 74); + addKey(KEYSYM, "key.keyboard.k", 75); + addKey(KEYSYM, "key.keyboard.l", 76); + addKey(KEYSYM, "key.keyboard.m", 77); + addKey(KEYSYM, "key.keyboard.n", 78); + addKey(KEYSYM, "key.keyboard.o", 79); + addKey(KEYSYM, "key.keyboard.p", 80); + addKey(KEYSYM, "key.keyboard.q", 81); + addKey(KEYSYM, "key.keyboard.r", 82); + addKey(KEYSYM, "key.keyboard.s", 83); + addKey(KEYSYM, "key.keyboard.t", 84); + addKey(KEYSYM, "key.keyboard.u", 85); + addKey(KEYSYM, "key.keyboard.v", 86); + addKey(KEYSYM, "key.keyboard.w", 87); + addKey(KEYSYM, "key.keyboard.x", 88); + addKey(KEYSYM, "key.keyboard.y", 89); + addKey(KEYSYM, "key.keyboard.z", 90); + addKey(KEYSYM, "key.keyboard.f1", 290); + addKey(KEYSYM, "key.keyboard.f2", 291); + addKey(KEYSYM, "key.keyboard.f3", 292); + addKey(KEYSYM, "key.keyboard.f4", 293); + addKey(KEYSYM, "key.keyboard.f5", 294); + addKey(KEYSYM, "key.keyboard.f6", 295); + addKey(KEYSYM, "key.keyboard.f7", 296); + addKey(KEYSYM, "key.keyboard.f8", 297); + addKey(KEYSYM, "key.keyboard.f9", 298); + addKey(KEYSYM, "key.keyboard.f10", 299); + addKey(KEYSYM, "key.keyboard.f11", 300); + addKey(KEYSYM, "key.keyboard.f12", 301); + addKey(KEYSYM, "key.keyboard.f13", 302); + addKey(KEYSYM, "key.keyboard.f14", 303); + addKey(KEYSYM, "key.keyboard.f15", 304); + addKey(KEYSYM, "key.keyboard.f16", 305); + addKey(KEYSYM, "key.keyboard.f17", 306); + addKey(KEYSYM, "key.keyboard.f18", 307); + addKey(KEYSYM, "key.keyboard.f19", 308); + addKey(KEYSYM, "key.keyboard.f20", 309); + addKey(KEYSYM, "key.keyboard.f21", 310); + addKey(KEYSYM, "key.keyboard.f22", 311); + addKey(KEYSYM, "key.keyboard.f23", 312); + addKey(KEYSYM, "key.keyboard.f24", 313); + addKey(KEYSYM, "key.keyboard.f25", 314); + addKey(KEYSYM, "key.keyboard.num.lock", 282); + addKey(KEYSYM, "key.keyboard.keypad.0", 320); + addKey(KEYSYM, "key.keyboard.keypad.1", 321); + addKey(KEYSYM, "key.keyboard.keypad.2", 322); + addKey(KEYSYM, "key.keyboard.keypad.3", 323); + addKey(KEYSYM, "key.keyboard.keypad.4", 324); + addKey(KEYSYM, "key.keyboard.keypad.5", 325); + addKey(KEYSYM, "key.keyboard.keypad.6", 326); + addKey(KEYSYM, "key.keyboard.keypad.7", 327); + addKey(KEYSYM, "key.keyboard.keypad.8", 328); + addKey(KEYSYM, "key.keyboard.keypad.9", 329); + addKey(KEYSYM, "key.keyboard.keypad.add", 334); + addKey(KEYSYM, "key.keyboard.keypad.decimal", 330); + addKey(KEYSYM, "key.keyboard.keypad.enter", 335); + addKey(KEYSYM, "key.keyboard.keypad.equal", 336); + addKey(KEYSYM, "key.keyboard.keypad.multiply", 332); + addKey(KEYSYM, "key.keyboard.keypad.divide", 331); + addKey(KEYSYM, "key.keyboard.keypad.subtract", 333); + addKey(KEYSYM, "key.keyboard.down", 264); + addKey(KEYSYM, "key.keyboard.left", 263); + addKey(KEYSYM, "key.keyboard.right", 262); + addKey(KEYSYM, "key.keyboard.up", 265); + addKey(KEYSYM, "key.keyboard.apostrophe", 39); + addKey(KEYSYM, "key.keyboard.backslash", 92); + addKey(KEYSYM, "key.keyboard.comma", 44); + addKey(KEYSYM, "key.keyboard.equal", 61); + addKey(KEYSYM, "key.keyboard.grave.accent", 96); + addKey(KEYSYM, "key.keyboard.left.bracket", 91); + addKey(KEYSYM, "key.keyboard.minus", 45); + addKey(KEYSYM, "key.keyboard.period", 46); + addKey(KEYSYM, "key.keyboard.right.bracket", 93); + addKey(KEYSYM, "key.keyboard.semicolon", 59); + addKey(KEYSYM, "key.keyboard.slash", 47); + addKey(KEYSYM, "key.keyboard.space", 32); + addKey(KEYSYM, "key.keyboard.tab", 258); + addKey(KEYSYM, "key.keyboard.left.alt", 342); + addKey(KEYSYM, "key.keyboard.left.control", 341); + addKey(KEYSYM, "key.keyboard.left.shift", 340); + addKey(KEYSYM, "key.keyboard.left.win", 343); + addKey(KEYSYM, "key.keyboard.right.alt", 346); + addKey(KEYSYM, "key.keyboard.right.control", 345); + addKey(KEYSYM, "key.keyboard.right.shift", 344); + addKey(KEYSYM, "key.keyboard.right.win", 347); + addKey(KEYSYM, "key.keyboard.enter", 257); + addKey(KEYSYM, "key.keyboard.escape", 256); + addKey(KEYSYM, "key.keyboard.backspace", 259); + addKey(KEYSYM, "key.keyboard.delete", 261); + addKey(KEYSYM, "key.keyboard.end", 269); + addKey(KEYSYM, "key.keyboard.home", 268); + addKey(KEYSYM, "key.keyboard.insert", 260); + addKey(KEYSYM, "key.keyboard.page.down", 267); + addKey(KEYSYM, "key.keyboard.page.up", 266); + addKey(KEYSYM, "key.keyboard.caps.lock", 280); + addKey(KEYSYM, "key.keyboard.pause", 284); + addKey(KEYSYM, "key.keyboard.scroll.lock", 281); + addKey(KEYSYM, "key.keyboard.menu", 348); + addKey(KEYSYM, "key.keyboard.print.screen", 283); + addKey(KEYSYM, "key.keyboard.world.1", 161); + addKey(KEYSYM, "key.keyboard.world.2", 162); + } + } + + @Retention(RetentionPolicy.CLASS) + @Target(ElementType.TYPE_USE) + public @interface Value { + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/KeyCodes.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/KeyCodes.java new file mode 100644 index 000000000..601134c4a --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/KeyCodes.java @@ -0,0 +1,162 @@ +package org.polyfrost.oneconfig.internal.legacy; + +//? if = 1.8.9 { +/*import org.lwjgl.glfw.GLFW; +import org.lwjgl.input.Keyboard; + +public final class KeyCodes { + private static final int[] GLFW2LWJGL = new int[GLFW.GLFW_KEY_MENU + 1]; + private static final int[] LWJGL2GLFW = new int[Keyboard.KEYBOARD_SIZE]; + + public static int toLegacy(int keyCode) { + return GLFW2LWJGL[keyCode]; + } + + public static int toLegacy(InputConstants.Key key) { + if (key == null || key.equals(InputConstants.UNKNOWN)) return 0; + if (key.getType() == InputConstants.Type.MOUSE) return key.getValue() - 100; + return GLFW2LWJGL[key.getValue()]; + } + + public static InputConstants.Key fromLegacy(int keyCode) { + if (keyCode == 0) return InputConstants.UNKNOWN; + if (keyCode < 0) return InputConstants.Type.MOUSE.getOrCreate(keyCode + 100); + int glfw = LWJGL2GLFW[keyCode]; + return glfw == 0 ? InputConstants.UNKNOWN : InputConstants.Type.KEYSYM.getOrCreate(glfw); + } + + static { + GLFW2LWJGL[0x00] = Keyboard.KEY_NONE; + GLFW2LWJGL[GLFW.GLFW_KEY_SPACE] = Keyboard.KEY_SPACE; + GLFW2LWJGL[GLFW.GLFW_KEY_APOSTROPHE] = Keyboard.KEY_APOSTROPHE; + GLFW2LWJGL[GLFW.GLFW_KEY_COMMA] = Keyboard.KEY_COMMA; + GLFW2LWJGL[GLFW.GLFW_KEY_MINUS] = Keyboard.KEY_MINUS; + GLFW2LWJGL[GLFW.GLFW_KEY_PERIOD] = Keyboard.KEY_PERIOD; + GLFW2LWJGL[GLFW.GLFW_KEY_SLASH] = Keyboard.KEY_SLASH; + GLFW2LWJGL[GLFW.GLFW_KEY_0] = Keyboard.KEY_0; + GLFW2LWJGL[GLFW.GLFW_KEY_1] = Keyboard.KEY_1; + GLFW2LWJGL[GLFW.GLFW_KEY_2] = Keyboard.KEY_2; + GLFW2LWJGL[GLFW.GLFW_KEY_3] = Keyboard.KEY_3; + GLFW2LWJGL[GLFW.GLFW_KEY_4] = Keyboard.KEY_4; + GLFW2LWJGL[GLFW.GLFW_KEY_5] = Keyboard.KEY_5; + GLFW2LWJGL[GLFW.GLFW_KEY_6] = Keyboard.KEY_6; + GLFW2LWJGL[GLFW.GLFW_KEY_7] = Keyboard.KEY_7; + GLFW2LWJGL[GLFW.GLFW_KEY_8] = Keyboard.KEY_8; + GLFW2LWJGL[GLFW.GLFW_KEY_9] = Keyboard.KEY_9; + GLFW2LWJGL[GLFW.GLFW_KEY_SEMICOLON] = Keyboard.KEY_SEMICOLON; + GLFW2LWJGL[GLFW.GLFW_KEY_EQUAL] = Keyboard.KEY_EQUALS; + GLFW2LWJGL[GLFW.GLFW_KEY_A] = Keyboard.KEY_A; + GLFW2LWJGL[GLFW.GLFW_KEY_B] = Keyboard.KEY_B; + GLFW2LWJGL[GLFW.GLFW_KEY_C] = Keyboard.KEY_C; + GLFW2LWJGL[GLFW.GLFW_KEY_D] = Keyboard.KEY_D; + GLFW2LWJGL[GLFW.GLFW_KEY_E] = Keyboard.KEY_E; + GLFW2LWJGL[GLFW.GLFW_KEY_F] = Keyboard.KEY_F; + GLFW2LWJGL[GLFW.GLFW_KEY_G] = Keyboard.KEY_G; + GLFW2LWJGL[GLFW.GLFW_KEY_H] = Keyboard.KEY_H; + GLFW2LWJGL[GLFW.GLFW_KEY_I] = Keyboard.KEY_I; + GLFW2LWJGL[GLFW.GLFW_KEY_J] = Keyboard.KEY_J; + GLFW2LWJGL[GLFW.GLFW_KEY_K] = Keyboard.KEY_K; + GLFW2LWJGL[GLFW.GLFW_KEY_L] = Keyboard.KEY_L; + GLFW2LWJGL[GLFW.GLFW_KEY_M] = Keyboard.KEY_M; + GLFW2LWJGL[GLFW.GLFW_KEY_N] = Keyboard.KEY_N; + GLFW2LWJGL[GLFW.GLFW_KEY_O] = Keyboard.KEY_O; + GLFW2LWJGL[GLFW.GLFW_KEY_P] = Keyboard.KEY_P; + GLFW2LWJGL[GLFW.GLFW_KEY_Q] = Keyboard.KEY_Q; + GLFW2LWJGL[GLFW.GLFW_KEY_R] = Keyboard.KEY_R; + GLFW2LWJGL[GLFW.GLFW_KEY_S] = Keyboard.KEY_S; + GLFW2LWJGL[GLFW.GLFW_KEY_T] = Keyboard.KEY_T; + GLFW2LWJGL[GLFW.GLFW_KEY_U] = Keyboard.KEY_U; + GLFW2LWJGL[GLFW.GLFW_KEY_V] = Keyboard.KEY_V; + GLFW2LWJGL[GLFW.GLFW_KEY_W] = Keyboard.KEY_W; + GLFW2LWJGL[GLFW.GLFW_KEY_X] = Keyboard.KEY_X; + GLFW2LWJGL[GLFW.GLFW_KEY_Y] = Keyboard.KEY_Y; + GLFW2LWJGL[GLFW.GLFW_KEY_Z] = Keyboard.KEY_Z; + GLFW2LWJGL[GLFW.GLFW_KEY_LEFT_BRACKET] = Keyboard.KEY_LBRACKET; + GLFW2LWJGL[GLFW.GLFW_KEY_BACKSLASH] = Keyboard.KEY_BACKSLASH; + GLFW2LWJGL[GLFW.GLFW_KEY_RIGHT_BRACKET] = Keyboard.KEY_RBRACKET; + GLFW2LWJGL[GLFW.GLFW_KEY_GRAVE_ACCENT] = Keyboard.KEY_GRAVE; + GLFW2LWJGL[GLFW.GLFW_KEY_WORLD_1] = Keyboard.KEY_WORLD_1; + GLFW2LWJGL[GLFW.GLFW_KEY_WORLD_2] = Keyboard.KEY_WORLD_2; + GLFW2LWJGL[GLFW.GLFW_KEY_ESCAPE] = Keyboard.KEY_ESCAPE; + GLFW2LWJGL[GLFW.GLFW_KEY_ENTER] = Keyboard.KEY_RETURN; + GLFW2LWJGL[GLFW.GLFW_KEY_TAB] = Keyboard.KEY_TAB; + GLFW2LWJGL[GLFW.GLFW_KEY_BACKSPACE] = Keyboard.KEY_BACK; + GLFW2LWJGL[GLFW.GLFW_KEY_INSERT] = Keyboard.KEY_INSERT; + GLFW2LWJGL[GLFW.GLFW_KEY_DELETE] = Keyboard.KEY_DELETE; + GLFW2LWJGL[GLFW.GLFW_KEY_RIGHT] = Keyboard.KEY_RIGHT; + GLFW2LWJGL[GLFW.GLFW_KEY_LEFT] = Keyboard.KEY_LEFT; + GLFW2LWJGL[GLFW.GLFW_KEY_DOWN] = Keyboard.KEY_DOWN; + GLFW2LWJGL[GLFW.GLFW_KEY_UP] = Keyboard.KEY_UP; + GLFW2LWJGL[GLFW.GLFW_KEY_PAGE_UP] = Keyboard.KEY_PRIOR; + GLFW2LWJGL[GLFW.GLFW_KEY_PAGE_DOWN] = Keyboard.KEY_NEXT; + GLFW2LWJGL[GLFW.GLFW_KEY_HOME] = Keyboard.KEY_HOME; + GLFW2LWJGL[GLFW.GLFW_KEY_END] = Keyboard.KEY_END; + GLFW2LWJGL[GLFW.GLFW_KEY_CAPS_LOCK] = Keyboard.KEY_CAPITAL; + GLFW2LWJGL[GLFW.GLFW_KEY_SCROLL_LOCK] = Keyboard.KEY_SCROLL; + GLFW2LWJGL[GLFW.GLFW_KEY_NUM_LOCK] = Keyboard.KEY_NUMLOCK; + GLFW2LWJGL[GLFW.GLFW_KEY_PRINT_SCREEN] = Keyboard.KEY_PRINT_SCREEN; + GLFW2LWJGL[GLFW.GLFW_KEY_PAUSE] = Keyboard.KEY_PAUSE; + GLFW2LWJGL[GLFW.GLFW_KEY_F1] = Keyboard.KEY_F1; + GLFW2LWJGL[GLFW.GLFW_KEY_F2] = Keyboard.KEY_F2; + GLFW2LWJGL[GLFW.GLFW_KEY_F3] = Keyboard.KEY_F3; + GLFW2LWJGL[GLFW.GLFW_KEY_F4] = Keyboard.KEY_F4; + GLFW2LWJGL[GLFW.GLFW_KEY_F5] = Keyboard.KEY_F5; + GLFW2LWJGL[GLFW.GLFW_KEY_F6] = Keyboard.KEY_F6; + GLFW2LWJGL[GLFW.GLFW_KEY_F7] = Keyboard.KEY_F7; + GLFW2LWJGL[GLFW.GLFW_KEY_F8] = Keyboard.KEY_F8; + GLFW2LWJGL[GLFW.GLFW_KEY_F9] = Keyboard.KEY_F9; + GLFW2LWJGL[GLFW.GLFW_KEY_F10] = Keyboard.KEY_F10; + GLFW2LWJGL[GLFW.GLFW_KEY_F11] = Keyboard.KEY_F11; + GLFW2LWJGL[GLFW.GLFW_KEY_F12] = Keyboard.KEY_F12; + GLFW2LWJGL[GLFW.GLFW_KEY_F13] = Keyboard.KEY_F13; + GLFW2LWJGL[GLFW.GLFW_KEY_F14] = Keyboard.KEY_F14; + GLFW2LWJGL[GLFW.GLFW_KEY_F15] = Keyboard.KEY_F15; + GLFW2LWJGL[GLFW.GLFW_KEY_F16] = Keyboard.KEY_F16; + GLFW2LWJGL[GLFW.GLFW_KEY_F17] = Keyboard.KEY_F17; + GLFW2LWJGL[GLFW.GLFW_KEY_F18] = Keyboard.KEY_F18; + GLFW2LWJGL[GLFW.GLFW_KEY_F19] = Keyboard.KEY_F19; + GLFW2LWJGL[GLFW.GLFW_KEY_F20] = Keyboard.KEY_F20; + GLFW2LWJGL[GLFW.GLFW_KEY_F21] = Keyboard.KEY_F21; + GLFW2LWJGL[GLFW.GLFW_KEY_F22] = Keyboard.KEY_F22; + GLFW2LWJGL[GLFW.GLFW_KEY_F23] = Keyboard.KEY_F23; + GLFW2LWJGL[GLFW.GLFW_KEY_F24] = Keyboard.KEY_F24; + GLFW2LWJGL[GLFW.GLFW_KEY_F25] = Keyboard.KEY_F25; + GLFW2LWJGL[GLFW.GLFW_KEY_KP_0] = Keyboard.KEY_NUMPAD0; + GLFW2LWJGL[GLFW.GLFW_KEY_KP_1] = Keyboard.KEY_NUMPAD1; + GLFW2LWJGL[GLFW.GLFW_KEY_KP_2] = Keyboard.KEY_NUMPAD2; + GLFW2LWJGL[GLFW.GLFW_KEY_KP_3] = Keyboard.KEY_NUMPAD3; + GLFW2LWJGL[GLFW.GLFW_KEY_KP_4] = Keyboard.KEY_NUMPAD4; + GLFW2LWJGL[GLFW.GLFW_KEY_KP_5] = Keyboard.KEY_NUMPAD5; + GLFW2LWJGL[GLFW.GLFW_KEY_KP_6] = Keyboard.KEY_NUMPAD6; + GLFW2LWJGL[GLFW.GLFW_KEY_KP_7] = Keyboard.KEY_NUMPAD7; + GLFW2LWJGL[GLFW.GLFW_KEY_KP_8] = Keyboard.KEY_NUMPAD8; + GLFW2LWJGL[GLFW.GLFW_KEY_KP_9] = Keyboard.KEY_NUMPAD9; + GLFW2LWJGL[GLFW.GLFW_KEY_KP_DECIMAL] = Keyboard.KEY_DECIMAL; + GLFW2LWJGL[GLFW.GLFW_KEY_KP_DIVIDE] = Keyboard.KEY_DIVIDE; + GLFW2LWJGL[GLFW.GLFW_KEY_KP_MULTIPLY] = Keyboard.KEY_MULTIPLY; + GLFW2LWJGL[GLFW.GLFW_KEY_KP_SUBTRACT] = Keyboard.KEY_SUBTRACT; + GLFW2LWJGL[GLFW.GLFW_KEY_KP_ADD] = Keyboard.KEY_ADD; + GLFW2LWJGL[GLFW.GLFW_KEY_KP_ENTER] = Keyboard.KEY_NUMPADENTER; + GLFW2LWJGL[GLFW.GLFW_KEY_KP_EQUAL] = Keyboard.KEY_NUMPADEQUALS; + GLFW2LWJGL[GLFW.GLFW_KEY_LEFT_SHIFT] = Keyboard.KEY_LSHIFT; + GLFW2LWJGL[GLFW.GLFW_KEY_LEFT_CONTROL] = Keyboard.KEY_LCONTROL; + GLFW2LWJGL[GLFW.GLFW_KEY_LEFT_ALT] = Keyboard.KEY_LMENU; + GLFW2LWJGL[GLFW.GLFW_KEY_LEFT_SUPER] = Keyboard.KEY_LMETA; + GLFW2LWJGL[GLFW.GLFW_KEY_RIGHT_SHIFT] = Keyboard.KEY_RSHIFT; + GLFW2LWJGL[GLFW.GLFW_KEY_RIGHT_CONTROL] = Keyboard.KEY_RCONTROL; + GLFW2LWJGL[GLFW.GLFW_KEY_RIGHT_ALT] = Keyboard.KEY_RMENU; + GLFW2LWJGL[GLFW.GLFW_KEY_RIGHT_SUPER] = Keyboard.KEY_RMETA; + GLFW2LWJGL[GLFW.GLFW_KEY_MENU] = Keyboard.KEY_APPS; + } + + static { + for (int glfw = 1; glfw < GLFW2LWJGL.length; glfw++) { + int legacy = GLFW2LWJGL[glfw]; + // Some GLFW keys alias the same LWJGL2 code, so only keep the first + if (legacy > 0 && LWJGL2GLFW[legacy] == 0) { + LWJGL2GLFW[legacy] = glfw; + } + } + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/NativeImage.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/NativeImage.java new file mode 100644 index 000000000..15fdeef01 --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/NativeImage.java @@ -0,0 +1,102 @@ +package org.polyfrost.oneconfig.internal.legacy; + +//? if = 1.8.9 { +/*import org.lwjgl.BufferUtils; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; + +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.awt.image.DataBufferInt; +import java.nio.IntBuffer; +import java.nio.file.Path; + +import javax.imageio.ImageIO; + +public class NativeImage implements AutoCloseable { + public final int width; + public final int height; + + private final BufferedImage image; + + public NativeImage(int width, int height, boolean useCalloc) { + this.width = width; + this.height = height; + this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + } + + public NativeImage(BufferedImage image) { + this(image.getWidth(), image.getHeight(), false); + + Graphics2D graphics = this.image.createGraphics(); + try { + graphics.drawImage(image, 0, 0, null); + } finally { + graphics.dispose(); + } + } + + public int getPixelRGBA(int x, int y) { + return swapRedBlue(image.getRGB(x, y)); + } + + public void setPixelRGBA(int x, int y, int color) { + image.setRGB(x, y, swapRedBlue(color)); + } + + private static int swapRedBlue(int color) { + return (color & 0xFF00FF00) | ((color & 0xFF) << 16) | ((color >>> 16) & 0xFF); + } + + public void writeToFile(Path path) throws java.io.IOException { + ImageIO.write(image, "png", path.toFile()); + } + + @Override + public void close() { + image.flush(); + } + + public void downloadTexture(int level, boolean forceOpaque) { + int count = width * height; + IntBuffer buffer = BufferUtils.createIntBuffer(count); + int previousAlignment = GL11.glGetInteger(GL11.GL_PACK_ALIGNMENT); + + try { + GL11.glPixelStorei(GL11.GL_PACK_ALIGNMENT, 1); + GL11.glGetTexImage( + GL11.GL_TEXTURE_2D, + level, + GL12.GL_BGRA, + GL12.GL_UNSIGNED_INT_8_8_8_8_REV, + buffer + ); + + int[] pixels = new int[count]; + buffer.get(pixels); + + if (forceOpaque) { + for (int i = 0; i < pixels.length; i++) { + pixels[i] |= 0xFF000000; + } + } + + image.setRGB(0, 0, width, height, pixels, 0, width); + } finally { + GL11.glPixelStorei(GL11.GL_PACK_ALIGNMENT, previousAlignment); + } + } + + public void flipY() { + int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData(); + int[] row = new int[width]; + + for (int y = 0; y < height / 2; y++) { + int opposite = height - 1 - y; + System.arraycopy(pixels, y * width, row, 0, width); + System.arraycopy(pixels, opposite * width, pixels, y * width, width); + System.arraycopy(row, 0, pixels, opposite * width, width); + } + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/PlayerSkin.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/PlayerSkin.java new file mode 100644 index 000000000..b0938cfcb --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/PlayerSkin.java @@ -0,0 +1,25 @@ +package org.polyfrost.oneconfig.internal.legacy; + +//? if = 1.8.9 { +/*import net.minecraft.resource.Identifier; + +public final class PlayerSkin { + private final Identifier texture; + + public PlayerSkin(Identifier texture) { + this.texture = texture; + } + + public PlayerSkin body() { + return this; + } + + public Identifier texture() { + return texture; + } + + public Identifier texturePath() { + return texture; + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/SimpleSoundInstance.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/SimpleSoundInstance.java new file mode 100644 index 000000000..03d642d9b --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/SimpleSoundInstance.java @@ -0,0 +1,20 @@ +package org.polyfrost.oneconfig.internal.legacy; + +//? if = 1.8.9 { +/*import net.minecraft.client.sound.instance.AbstractSoundInstance; +import net.minecraft.client.resources.sounds.SoundInstance; +import net.minecraft.resource.Identifier; + +public final class SimpleSoundInstance extends AbstractSoundInstance { + private SimpleSoundInstance(Identifier event, float pitch, float volume) { + super(event); + this.attenuation = SoundInstance.Attenuation.NONE; + this.pitch = pitch; + this.volume = volume; + } + + public static SimpleSoundInstance forUI(Identifier event, float pitch, float volume) { + return new SimpleSoundInstance(event, pitch, volume); + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/SoundEvents.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/SoundEvents.java new file mode 100644 index 000000000..2e6a1d9cf --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/SoundEvents.java @@ -0,0 +1,10 @@ +package org.polyfrost.oneconfig.internal.legacy; + +//? if = 1.8.9 { +/*import net.minecraft.resource.Identifier; + +public final class SoundEvents { + public static final Identifier UI_BUTTON_CLICK = new Identifier("gui.button.press"); + public static final Identifier NOTE_BLOCK_BASS = new Identifier("note.bass"); +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/User.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/User.java new file mode 100644 index 000000000..75410744b --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/User.java @@ -0,0 +1,23 @@ +package org.polyfrost.oneconfig.internal.legacy; + +//? if = 1.8.9 { +/*import com.mojang.authlib.GameProfile; + +import java.util.UUID; + +public final class User { + private final GameProfile profile; + + public User(GameProfile profile) { + this.profile = profile; + } + + public String getName() { + return profile.getName(); + } + + public UUID getProfileId() { + return profile.getId(); + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/Window.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/Window.java new file mode 100644 index 000000000..13cf240ab --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/Window.java @@ -0,0 +1,51 @@ +package org.polyfrost.oneconfig.internal.legacy; + +//? if = 1.8.9 { +/*import net.minecraft.client.Minecraft; +import org.lwjgl.opengl.Display; + +// We need this shim because Window#getWidth/getHeight return GUI-scaled dimensions in legacy but framebuffer dimensions in modern. +public final class Window { + private final net.minecraft.client.render.Window scaled; + + public Window(Minecraft minecraft) { + this.scaled = new net.minecraft.client.render.Window(minecraft); + } + + public long getWindow() { + return Display.getHandle(); + } + + public int getWidth() { + return Display.getWidth(); + } + + public int getHeight() { + return Display.getHeight(); + } + + public int getScreenWidth() { + return Display.getScreenWidth(); + } + + public int getScreenHeight() { + return Display.getScreenHeight(); + } + + public int getRefreshRate() { + return Display.getDisplayMode().getFrequency(); + } + + public int getGuiScaledWidth() { + return this.scaled.getWidth(); + } + + public int getGuiScaledHeight() { + return this.scaled.getHeight(); + } + + public int getGuiScale() { + return this.scaled.getScale(); + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/ChatFormatting.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/ChatFormatting.java new file mode 100644 index 000000000..3e94951ea --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/ChatFormatting.java @@ -0,0 +1,63 @@ +package org.polyfrost.oneconfig.internal.legacy.chat; + +//? if = 1.8.9 { +/*import java.util.regex.Pattern; +import org.jetbrains.annotations.Contract; +import org.jspecify.annotations.Nullable; + +public enum ChatFormatting { + BLACK('0'), + DARK_BLUE('1'), + DARK_GREEN('2'), + DARK_AQUA('3'), + DARK_RED('4'), + DARK_PURPLE('5'), + GOLD('6'), + GRAY('7'), + DARK_GRAY('8'), + BLUE('9'), + GREEN('a'), + AQUA('b'), + RED('c'), + LIGHT_PURPLE('d'), + YELLOW('e'), + WHITE('f'), + OBFUSCATED('k'), + BOLD('l'), + STRIKETHROUGH('m'), + UNDERLINE('n'), + ITALIC('o'), + RESET('r'); + + public static final char PREFIX_CODE = '§'; + private static final Pattern STRIP_FORMATTING_PATTERN = Pattern.compile("(?i)§[0-9A-FK-OR]"); + private final char code; + private final String toString; + + private ChatFormatting(final char code) { + this.code = code; + this.toString = "§" + String.valueOf(code); + } + + public String toString() { + return this.toString; + } + + @Contract("!null->!null;_->_") + public static @Nullable String stripFormatting(final @Nullable String input) { + return input == null ? null : STRIP_FORMATTING_PATTERN.matcher(input).replaceAll(""); + } + + public static @Nullable ChatFormatting getByCode(final char code) { + char sanitized = Character.toLowerCase(code); + + for(ChatFormatting format : values()) { + if (format.code == sanitized) { + return format; + } + } + + return null; + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/Component.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/Component.java new file mode 100644 index 000000000..9847d0ea8 --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/Component.java @@ -0,0 +1,251 @@ +package org.polyfrost.oneconfig.internal.legacy.chat; + +//? if = 1.8.9 { +/*import com.google.common.collect.Lists; +import com.mojang.brigadier.Message; +import java.net.URI; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import net.minecraft.resource.Identifier; +import net.minecraft.text.Text; +import net.minecraft.util.math.ChunkPos; +import net.kyori.adventure.text.format.TextDecoration; +import org.jspecify.annotations.Nullable; + +public interface Component extends Message, FormattedText, Text { + Style getStyle(); + + ComponentContents getContents(); + + @Override + default String getString() { + return FormattedText.super.getString(); + } + + default net.kyori.adventure.text.Component asComponent() { + net.kyori.adventure.text.Component result = net.kyori.adventure.text.Component.empty(); + for (Component part : this.toFlatList()) { + Style style = part.getStyle(); + net.kyori.adventure.text.format.Style.Builder adventureStyle = net.kyori.adventure.text.format.Style.style(); + Integer color = style.getRgbColor(); + if (color != null) { + adventureStyle.color(net.kyori.adventure.text.format.TextColor.color(color)); + } + adventureStyle.decoration(TextDecoration.BOLD, style.isBold()); + adventureStyle.decoration(TextDecoration.ITALIC, style.isItalic()); + adventureStyle.decoration(TextDecoration.UNDERLINED, style.isUnderlined()); + adventureStyle.decoration(TextDecoration.STRIKETHROUGH, style.isStrikethrough()); + adventureStyle.decoration(TextDecoration.OBFUSCATED, style.isObfuscated()); + if (style.getInsertion() != null) { + adventureStyle.insertion(style.getInsertion()); + } + result = result.append(net.kyori.adventure.text.Component.text(part.getString(), adventureStyle.build())); + } + return result; + } + + default String getString(final int limit) { + StringBuilder builder = new StringBuilder(); + this.visit(contents -> { + int remaining = limit - builder.length(); + if (remaining <= 0) { + return STOP_ITERATION; + } else { + builder.append(contents.length() <= remaining ? contents : contents.substring(0, remaining)); + return Optional.empty(); + } + }); + return builder.toString(); + } + + @Override + List getSiblings(); + + @Nullable + default String tryCollapseToString() { + return this.getContents() instanceof PlainTextContents text && this.getSiblings().isEmpty() && this.getStyle().isEmpty() ? text.text() : null; + } + + default MutableComponent plainCopy() { + return MutableComponent.create(this.getContents()); + } + + default MutableComponent copy() { + return new MutableComponent(this.getContents(), new ArrayList(this.getSiblings()), this.getStyle()); + } + + FormattedCharSequence getVisualOrderText(); + + @Override + default Optional visit(final FormattedText.StyledContentConsumer output, final Style parentStyle) { + Style selfStyle = this.getStyle().deepCopy().setParent(parentStyle); + Optional selfResult = this.getContents().visit(output, selfStyle); + if (selfResult.isPresent()) { + return selfResult; + } else { + for (Object sibling : this.getSiblings()) { + Optional result = ((Component) sibling).visit(output, selfStyle); + if (result.isPresent()) { + return result; + } + } + + return Optional.empty(); + } + } + + @Override + default Optional visit(final FormattedText.ContentConsumer output) { + Optional selfResult = this.getContents().visit(output); + if (selfResult.isPresent()) { + return selfResult; + } else { + for (Object sibling : this.getSiblings()) { + Optional result = ((Component) sibling).visit(output); + if (result.isPresent()) { + return result; + } + } + + return Optional.empty(); + } + } + + default List toFlatList() { + return this.toFlatList(new Style()); + } + + default List toFlatList(final Style rootStyle) { + List result = Lists.newArrayList(); + this.visit((style, contents) -> { + if (!contents.isEmpty()) { + result.add(literal(contents).withStyle(style)); + } + + return Optional.empty(); + }, rootStyle); + return result; + } + + default boolean contains(final Component other) { + if (this.equals(other)) { + return true; + } else { + List flat = this.toFlatList(); + List otherFlat = other.toFlatList(this.getStyle()); + return Collections.indexOfSubList(flat, otherFlat) != -1; + } + } + + static Component nullToEmpty(@Nullable final String text) { + return text != null ? literal(text) : empty(); + } + + static MutableComponent literal(final String text) { + return MutableComponent.create(PlainTextContents.create(text)); + } + + static MutableComponent fromLegacy(final String text) { + if (text.indexOf(ChatFormatting.PREFIX_CODE) < 0) { + return literal(text); + } + + MutableComponent result = empty(); + Style style = Style.EMPTY; + int start = 0; + + for (int i = 0; i < text.length() - 1; i++) { + if (text.charAt(i) != ChatFormatting.PREFIX_CODE) { + continue; + } + + ChatFormatting formatting = ChatFormatting.getByCode(text.charAt(i + 1)); + if (formatting == null) { + continue; + } + + if (start < i) { + result.append(literal(text.substring(start, i)).setStyle(style)); + } + + if (formatting == ChatFormatting.RESET) { + style = Style.EMPTY; + } else if (formatting.ordinal() <= ChatFormatting.WHITE.ordinal()) { + // Legacy color codes reset decorations before applying the new color. + style = Style.EMPTY.applyFormat(formatting); + } else { + style = style.applyFormat(formatting); + } + + i++; + start = i + 1; + } + + if (start < text.length()) { + result.append(literal(text.substring(start)).setStyle(style)); + } + + return result; + } + + static MutableComponent translatable(final String key) { + return MutableComponent.create(new TranslatableContents(key, null, TranslatableContents.NO_ARGS)); + } + + static MutableComponent translatable(final String key, final Object... args) { + return MutableComponent.create(new TranslatableContents(key, null, args)); + } + + static MutableComponent translatableEscape(final String key, final Object... args) { + for (int i = 0; i < args.length; i++) { + Object arg = args[i]; + if (!TranslatableContents.isAllowedPrimitiveArgument(arg) && !(arg instanceof Component)) { + args[i] = String.valueOf(arg); + } + } + + return translatable(key, args); + } + + static MutableComponent translatableWithFallback(final String key, @Nullable final String fallback) { + return MutableComponent.create(new TranslatableContents(key, fallback, TranslatableContents.NO_ARGS)); + } + + static MutableComponent translatableWithFallback(final String key, @Nullable final String fallback, final Object... args) { + return MutableComponent.create(new TranslatableContents(key, fallback, args)); + } + + static MutableComponent empty() { + return MutableComponent.create(PlainTextContents.EMPTY); + } + + static Component translationArg(final Date date) { + return literal(date.toString()); + } + + static Component translationArg(final Message message) { + return (Component)(message instanceof Component component ? component : literal(message.getString())); + } + + static Component translationArg(final UUID uuid) { + return literal(uuid.toString()); + } + + static Component translationArg(final Identifier id) { + return literal(id.toString()); + } + + static Component translationArg(final ChunkPos chunkPos) { + return literal(chunkPos.toString()); + } + + static Component translationArg(final URI uri) { + return literal(uri.toString()); + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/ComponentContents.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/ComponentContents.java new file mode 100644 index 000000000..199bdac17 --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/ComponentContents.java @@ -0,0 +1,15 @@ +package org.polyfrost.oneconfig.internal.legacy.chat; + +//? if = 1.8.9 { +/*import java.util.Optional; + +public interface ComponentContents { + default Optional visit(final FormattedText.StyledContentConsumer output, final Style currentStyle) { + return Optional.empty(); + } + + default Optional visit(final FormattedText.ContentConsumer output) { + return Optional.empty(); + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/FormattedCharSequence.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/FormattedCharSequence.java new file mode 100644 index 000000000..0b1471eec --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/FormattedCharSequence.java @@ -0,0 +1,14 @@ +package org.polyfrost.oneconfig.internal.legacy.chat; + +//? if = 1.8.9 { +/*@FunctionalInterface +public interface FormattedCharSequence { + FormattedCharSequence EMPTY = (output) -> true; + + boolean accept(final FormattedCharSink output); + + static FormattedCharSequence forward(final String plainText, final Style style) { + return plainText.isEmpty() ? EMPTY : (output) -> StringDecomposer.iterate(plainText, style, output); + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/FormattedCharSink.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/FormattedCharSink.java new file mode 100644 index 000000000..23d25c1ab --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/FormattedCharSink.java @@ -0,0 +1,8 @@ +package org.polyfrost.oneconfig.internal.legacy.chat; + +//? if = 1.8.9 { +/*@FunctionalInterface +public interface FormattedCharSink { + boolean accept(int position, Style style, int codepoint); +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/FormattedText.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/FormattedText.java new file mode 100644 index 000000000..e6c91c370 --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/FormattedText.java @@ -0,0 +1,63 @@ +package org.polyfrost.oneconfig.internal.legacy.chat; + +//? if = 1.8.9 { +/*import java.util.Optional; + +public interface FormattedText { + + private static Style applyTo(final Style style, final Style parentStyle) { + return style.deepCopy().setParent(parentStyle); + } + + Optional STOP_ITERATION = Optional.of(Unit.INSTANCE); + + Optional visit(final FormattedText.ContentConsumer output); + + Optional visit(final FormattedText.StyledContentConsumer output, final Style parentStyle); + + static FormattedText of(final String text) { + return new FormattedText() { + @Override + public Optional visit(final FormattedText.ContentConsumer output) { + return output.accept(text); + } + + @Override + public Optional visit(final FormattedText.StyledContentConsumer output, final Style parentStyle) { + return output.accept(parentStyle, text); + } + }; + } + + static FormattedText of(final String text, final Style style) { + return new FormattedText() { + @Override + public Optional visit(final FormattedText.ContentConsumer output) { + return output.accept(text); + } + + @Override + public Optional visit(final FormattedText.StyledContentConsumer output, final Style parentStyle) { + return output.accept(applyTo(style, parentStyle), text); + } + }; + } + + default String getString() { + StringBuilder builder = new StringBuilder(); + this.visit(contents -> { + builder.append(contents); + return Optional.empty(); + }); + return builder.toString(); + } + + interface ContentConsumer { + Optional accept(final String contents); + } + + interface StyledContentConsumer { + Optional accept(final Style style, final String contents); + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/MutableComponent.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/MutableComponent.java new file mode 100644 index 000000000..fdae13b92 --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/MutableComponent.java @@ -0,0 +1,168 @@ +package org.polyfrost.oneconfig.internal.legacy.chat; + +//? if = 1.8.9 { +/*import com.google.common.collect.Iterators; +import com.google.common.collect.Lists; +import java.util.Iterator; +import java.util.List; +import java.util.Optional; +import net.ornithemc.osl.text.impl.Locale; +import org.jspecify.annotations.Nullable; + +public final class MutableComponent implements Component { + private final ComponentContents contents; + private final List siblings; + private Style style; + private FormattedCharSequence visualOrderText = FormattedCharSequence.EMPTY; + @Nullable + private Locale decomposedWith; + + MutableComponent(final ComponentContents contents, final List siblings, final Style style) { + this.contents = contents; + this.siblings = siblings; + this.style = style; + } + + public static MutableComponent create(final ComponentContents contents) { + return new MutableComponent(contents, Lists.newArrayList(), new Style()); + } + + @Override + public ComponentContents getContents() { + return this.contents; + } + + @Override + public List getSiblings() { + return this.siblings; + } + + public MutableComponent setStyle(final Style style) { + this.style = style; + return this; + } + + @Override + public MutableComponent setStyle(final net.minecraft.text.Style style) { + this.style = Style.fromLegacy(style); + return this; + } + + @Override + public Style getStyle() { + return this.style; + } + + public MutableComponent append(final String text) { + return text.isEmpty() ? this : this.append(Component.literal(text)); + } + + public MutableComponent append(final Component component) { + this.siblings.add(component); + return this; + } + + @Override + public MutableComponent append(final net.minecraft.text.Text text) { + if (text instanceof Component component) { + return this.append(component); + } + + return this.append(Component.literal(text.getString()).setStyle(text.getStyle())); + } + + public MutableComponent withStyle(final Style patch) { + this.setStyle(patch.applyTo(this.getStyle())); + return this; + } + + public MutableComponent withStyle(final ChatFormatting format) { + this.setStyle(this.getStyle().applyFormat(format)); + return this; + } + + @Override + public FormattedCharSequence getVisualOrderText() { + Locale currentLocale = Locale.find(); + if (this.decomposedWith != currentLocale) { + this.visualOrderText = FormattedCharSequence.forward(this.getString(), this.getStyle()); + this.decomposedWith = currentLocale; + } + + return this.visualOrderText; + } + + @Override + public String getContent() { + StringBuilder builder = new StringBuilder(); + this.contents.visit(contents -> { + builder.append(contents); + return Optional.empty(); + }); + return builder.toString(); + } + + @Override + public String getFormattedString() { + StringBuilder builder = new StringBuilder(); + this.visit((style, contents) -> { + if (!contents.isEmpty()) { + builder.append(style.asString()).append(contents); + if (!style.isEmpty()) builder.append(ChatFormatting.RESET); + } + return Optional.empty(); + }, Style.EMPTY); + return builder.toString(); + } + + @Override + public Iterator iterator() { + return Iterators.concat( + Iterators.singletonIterator((net.minecraft.text.Text) this), + Iterators.concat(Iterators.transform( + (Iterator) (Iterator) this.siblings.iterator(), + net.minecraft.text.Text::iterator + )) + ); + } + + public boolean equals(final Object o) { + return this == o + ? true + : o instanceof MutableComponent that && this.contents.equals(that.contents) && this.style.equals(that.style) && this.siblings.equals(that.siblings); + } + + public int hashCode() { + int result = 1; + result = 31 * result + this.contents.hashCode(); + result = 31 * result + this.style.hashCode(); + return 31 * result + this.siblings.hashCode(); + } + + public String toString() { + StringBuilder result = new StringBuilder(this.contents.toString()); + boolean hasStyle = !this.style.isEmpty(); + boolean hasSiblings = !this.siblings.isEmpty(); + if (hasStyle || hasSiblings) { + result.append('['); + if (hasStyle) { + result.append("style="); + result.append(this.style); + } + + if (hasStyle && hasSiblings) { + result.append(", "); + } + + if (hasSiblings) { + result.append("siblings="); + result.append(this.siblings); + } + + result.append(']'); + } + + return result.toString(); + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/PlainTextContents.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/PlainTextContents.java new file mode 100644 index 000000000..0a89c5996 --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/PlainTextContents.java @@ -0,0 +1,40 @@ +package org.polyfrost.oneconfig.internal.legacy.chat; + +//? if = 1.8.9 { +/*import java.util.Optional; + +public interface PlainTextContents extends ComponentContents { + PlainTextContents EMPTY = new PlainTextContents() { + public String toString() { + return "empty"; + } + + @Override + public String text() { + return ""; + } + }; + + static PlainTextContents create(String text) { + return text.isEmpty() ? EMPTY : new LiteralContents(text); + } + + String text(); + + record LiteralContents(String text) implements PlainTextContents { + @Override + public Optional visit(FormattedText.ContentConsumer contentConsumer) { + return contentConsumer.accept(this.text); + } + + @Override + public Optional visit(FormattedText.StyledContentConsumer styledContentConsumer, Style style) { + return styledContentConsumer.accept(style, this.text); + } + + public String toString() { + return "literal{" + this.text + "}"; + } + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/StringDecomposer.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/StringDecomposer.java new file mode 100644 index 000000000..4aeb63c89 --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/StringDecomposer.java @@ -0,0 +1,125 @@ +package org.polyfrost.oneconfig.internal.legacy.chat; + +//? if = 1.8.9 { +/*public class StringDecomposer { + private static final char REPLACEMENT_CHAR = '�'; + + private static boolean feedChar(final Style style, final FormattedCharSink output, final int pos, final char ch) { + return Character.isSurrogate(ch) ? output.accept(pos, style, REPLACEMENT_CHAR) : output.accept(pos, style, ch); + } + + public static boolean iterate(final String string, final Style style, final FormattedCharSink output) { + int size = string.length(); + + for (int i = 0; i < size; i++) { + char ch = string.charAt(i); + if (Character.isHighSurrogate(ch)) { + if (i + 1 >= size) { + if (!output.accept(i, style, REPLACEMENT_CHAR)) { + return false; + } + break; + } + + char low = string.charAt(i + 1); + if (Character.isLowSurrogate(low)) { + if (!output.accept(i, style, Character.toCodePoint(ch, low))) { + return false; + } + + i++; + } else if (!output.accept(i, style, REPLACEMENT_CHAR)) { + return false; + } + } else if (!feedChar(style, output, i, ch)) { + return false; + } + } + + return true; + } + + public static boolean iterateBackwards(final String string, final Style style, final FormattedCharSink output) { + int size = string.length(); + + for (int i = size - 1; i >= 0; i--) { + char ch = string.charAt(i); + if (Character.isLowSurrogate(ch)) { + if (i - 1 < 0) { + if (!output.accept(0, style, REPLACEMENT_CHAR)) { + return false; + } + break; + } + + char high = string.charAt(i - 1); + if (Character.isHighSurrogate(high)) { + if (!output.accept(--i, style, Character.toCodePoint(high, ch))) { + return false; + } + } else if (!output.accept(i, style, REPLACEMENT_CHAR)) { + return false; + } + } else if (!feedChar(style, output, i, ch)) { + return false; + } + } + + return true; + } + + public static boolean iterateFormatted(final String string, final Style style, final FormattedCharSink output) { + return iterateFormatted(string, 0, style, output); + } + + public static boolean iterateFormatted(final String string, final int offset, final Style style, final FormattedCharSink output) { + return iterateFormatted(string, offset, style, style, output); + } + + public static boolean iterateFormatted( + final String string, final int offset, final Style currentStyle, final Style resetStyle, final FormattedCharSink output + ) { + int size = string.length(); + Style style = currentStyle; + + for (int i = offset; i < size; i++) { + char ch = string.charAt(i); + if (ch == 167) { + if (i + 1 >= size) { + break; + } + + char code = string.charAt(i + 1); + ChatFormatting formatting = ChatFormatting.getByCode(code); + if (formatting != null) { + style = formatting == ChatFormatting.RESET ? resetStyle : style.applyLegacyFormat(formatting); + } + + i++; + } else if (Character.isHighSurrogate(ch)) { + if (i + 1 >= size) { + if (!output.accept(i, style, REPLACEMENT_CHAR)) { + return false; + } + break; + } + + char low = string.charAt(i + 1); + if (Character.isLowSurrogate(low)) { + if (!output.accept(i, style, Character.toCodePoint(ch, low))) { + return false; + } + + i++; + } else if (!output.accept(i, style, REPLACEMENT_CHAR)) { + return false; + } + } else if (!feedChar(style, output, i, ch)) { + return false; + } + } + + return true; + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/Style.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/Style.java new file mode 100644 index 000000000..7f68c997e --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/Style.java @@ -0,0 +1,485 @@ +package org.polyfrost.oneconfig.internal.legacy.chat; + +//? if = 1.8.9 { +/*import java.util.Objects; + +public class Style extends net.minecraft.text.Style { + public static final Style EMPTY = new Style( + null, + null, + null, + null, + null, + null, + null, + null, + null + ); + + private final Style parent; + private final ChatFormatting color; + private final Integer rgbColor; + private final Boolean bold; + private final Boolean italic; + private final Boolean underlined; + private final Boolean strikethrough; + private final Boolean obfuscated; + private final String insertion; + + public Style() { + this(null, null, null, null, null, null, null, null, null); + } + + private Style( + final Style parent, + final ChatFormatting color, + final Integer rgbColor, + final Boolean bold, + final Boolean italic, + final Boolean underlined, + final Boolean strikethrough, + final Boolean obfuscated, + final String insertion + ) { + this.parent = parent; + this.color = color; + this.rgbColor = rgbColor; + this.bold = bold; + this.italic = italic; + this.underlined = underlined; + this.strikethrough = strikethrough; + this.obfuscated = obfuscated; + this.insertion = insertion; + } + + public Style applyTo(final Style base) { + if (this == EMPTY) { + return base; + } + + return new Style( + base.parent, + this.color != null ? this.color : base.color, + this.rgbColor != null ? this.rgbColor : base.rgbColor, + this.bold != null ? this.bold : base.bold, + this.italic != null ? this.italic : base.italic, + this.underlined != null ? this.underlined : base.underlined, + this.strikethrough != null ? this.strikethrough : base.strikethrough, + this.obfuscated != null ? this.obfuscated : base.obfuscated, + this.insertion != null ? this.insertion : base.insertion + ); + } + + public Style applyFormats(final ChatFormatting... formats) { + Style result = this; + + for (final ChatFormatting format : formats) { + result = result.applyFormat(format); + } + + return result; + } + + public Style applyFormat(final ChatFormatting format) { + if (format == ChatFormatting.RESET) { + return EMPTY; + } + + if (isColor(format)) { + return new Style( + this.parent, + format, + getColor(format), + this.bold, + this.italic, + this.underlined, + this.strikethrough, + this.obfuscated, + this.insertion + ); + } + + if (format == ChatFormatting.BOLD) { + return this.withBold(true); + } + + if (format == ChatFormatting.ITALIC) { + return this.withItalic(true); + } + + if (format == ChatFormatting.UNDERLINE) { + return this.withUnderlined(true); + } + + if (format == ChatFormatting.STRIKETHROUGH) { + return this.withStrikethrough(true); + } + + if (format == ChatFormatting.OBFUSCATED) { + return this.withObfuscated(true); + } + + return this; + } + + public Style applyLegacyFormat(final ChatFormatting format) { + ChatFormatting color = this.color; + Integer rgbColor = this.rgbColor; + Boolean bold = this.bold; + Boolean italic = this.italic; + Boolean underlined = this.underlined; + Boolean strikethrough = this.strikethrough; + Boolean obfuscated = this.obfuscated; + + switch (format) { + case OBFUSCATED: + obfuscated = true; + break; + case BOLD: + bold = true; + break; + case STRIKETHROUGH: + strikethrough = true; + break; + case UNDERLINE: + underlined = true; + break; + case ITALIC: + italic = true; + break; + case RESET: + return EMPTY; + default: + obfuscated = false; + bold = false; + italic = false; + underlined = false; + strikethrough = false; + color = format; + rgbColor = getColor(format); + } + + return new Style( + this.parent, + color, + rgbColor, + bold, + italic, + underlined, + strikethrough, + obfuscated, + this.insertion + ); + } + + public Style withColor(final int color) { + return new Style( + this.parent, + null, + color, + this.bold, + this.italic, + this.underlined, + this.strikethrough, + this.obfuscated, + this.insertion + ); + } + + public Style withColor(final ChatFormatting color) { + return new Style( + this.parent, + color, + getColor(color), + this.bold, + this.italic, + this.underlined, + this.strikethrough, + this.obfuscated, + this.insertion + ); + } + + public Style withBold(final Boolean bold) { + return new Style(this.parent, this.color, this.rgbColor, bold, this.italic, this.underlined, this.strikethrough, this.obfuscated, this.insertion); + } + + public Style withItalic(final Boolean italic) { + return new Style(this.parent, this.color, this.rgbColor, this.bold, italic, this.underlined, this.strikethrough, this.obfuscated, this.insertion); + } + + public Style withUnderlined(final Boolean underlined) { + return new Style(this.parent, this.color, this.rgbColor, this.bold, this.italic, underlined, this.strikethrough, this.obfuscated, this.insertion); + } + + public Style withStrikethrough(final Boolean strikethrough) { + return new Style(this.parent, this.color, this.rgbColor, this.bold, this.italic, this.underlined, strikethrough, this.obfuscated, this.insertion); + } + + public Style withObfuscated(final Boolean obfuscated) { + return new Style(this.parent, this.color, this.rgbColor, this.bold, this.italic, this.underlined, this.strikethrough, obfuscated, this.insertion); + } + + public Style withInsertion(final String insertion) { + return new Style(this.parent, this.color, this.rgbColor, this.bold, this.italic, this.underlined, this.strikethrough, this.obfuscated, insertion); + } + + public Style withoutShadow() { + return this; + } + + @Override + public Style setParent(final net.minecraft.text.Style parent) { + return new Style( + parent instanceof Style ? (Style) parent : fromLegacy(parent), + this.color, + this.rgbColor, + this.bold, + this.italic, + this.underlined, + this.strikethrough, + this.obfuscated, + this.insertion + ); + } + + @Override + public Style setColor(final net.minecraft.text.Formatting color) { + return this.withColor(fromLegacy(color)); + } + + @Override + public Style setBold(final Boolean bold) { + return this.withBold(bold); + } + + @Override + public Style setItalic(final Boolean italic) { + return this.withItalic(italic); + } + + @Override + public Style setUnderlined(final Boolean underlined) { + return this.withUnderlined(underlined); + } + + @Override + public Style setStrikethrough(final Boolean strikethrough) { + return this.withStrikethrough(strikethrough); + } + + @Override + public Style setObfuscated(final Boolean obfuscated) { + return this.withObfuscated(obfuscated); + } + + @Override + public Style setInsertion(final String insertion) { + return this.withInsertion(insertion); + } + + @Override + public Style copy() { + return this; + } + + @Override + public Style deepCopy() { + return this; + } + + @Override + public String asString() { + StringBuilder builder = new StringBuilder(); + + net.minecraft.text.Formatting color = this.getColor(); + if (color != null) builder.append(color); + + if (this.isBold()) builder.append(net.minecraft.text.Formatting.BOLD); + if (this.isItalic()) builder.append(net.minecraft.text.Formatting.ITALIC); + if (this.isUnderlined()) builder.append(net.minecraft.text.Formatting.UNDERLINE); + if (this.isStrikethrough()) builder.append(net.minecraft.text.Formatting.STRIKETHROUGH); + if (this.isObfuscated()) builder.append(net.minecraft.text.Formatting.OBFUSCATED); + + return builder.toString(); + } + + @Override + public boolean isEmpty() { + return this.parent == null + && this.color == null + && this.rgbColor == null + && this.bold == null + && this.italic == null + && this.underlined == null + && this.strikethrough == null + && this.obfuscated == null + && this.insertion == null; + } + + @Override + public net.minecraft.text.Formatting getColor() { + if (this.color != null) { + return toLegacy(this.color); + } + + return this.parent == null ? null : this.parent.getColor(); + } + + public Integer getRgbColor() { + if (this.rgbColor != null) { + return this.rgbColor; + } + + return this.parent == null ? null : this.parent.getRgbColor(); + } + + @Override + public boolean isBold() { + if (this.bold != null) { + return this.bold; + } + + return this.parent != null && this.parent.isBold(); + } + + @Override + public boolean isItalic() { + if (this.italic != null) { + return this.italic; + } + + return this.parent != null && this.parent.isItalic(); + } + + @Override + public boolean isUnderlined() { + if (this.underlined != null) { + return this.underlined; + } + + return this.parent != null && this.parent.isUnderlined(); + } + + @Override + public boolean isStrikethrough() { + if (this.strikethrough != null) { + return this.strikethrough; + } + + return this.parent != null && this.parent.isStrikethrough(); + } + + @Override + public boolean isObfuscated() { + if (this.obfuscated != null) { + return this.obfuscated; + } + + return this.parent != null && this.parent.isObfuscated(); + } + + @Override + public String getInsertion() { + if (this.insertion != null) { + return this.insertion; + } + + return this.parent == null ? null : this.parent.getInsertion(); + } + + public static Style fromLegacy(final net.minecraft.text.Style style) { + if (style == null) { + return EMPTY; + } + + if (style instanceof Style) { + return (Style) style; + } + + return EMPTY + .withColor(fromLegacy(style.getColor())) + .withBold(style.isBold() ? true : null) + .withItalic(style.isItalic() ? true : null) + .withUnderlined(style.isUnderlined() ? true : null) + .withStrikethrough(style.isStrikethrough() ? true : null) + .withObfuscated(style.isObfuscated() ? true : null) + .withInsertion(style.getInsertion()); + } + + private static boolean isColor(final ChatFormatting formatting) { + return formatting != null && formatting.ordinal() <= ChatFormatting.WHITE.ordinal(); + } + + private static Integer getColor(final ChatFormatting formatting) { + if (formatting == null) { + return null; + } + + return switch (formatting) { + case BLACK -> 0x000000; + case DARK_BLUE -> 0x0000AA; + case DARK_GREEN -> 0x00AA00; + case DARK_AQUA -> 0x00AAAA; + case DARK_RED -> 0xAA0000; + case DARK_PURPLE -> 0xAA00AA; + case GOLD -> 0xFFAA00; + case GRAY -> 0xAAAAAA; + case DARK_GRAY -> 0x555555; + case BLUE -> 0x5555FF; + case GREEN -> 0x55FF55; + case AQUA -> 0x55FFFF; + case RED -> 0xFF5555; + case LIGHT_PURPLE -> 0xFF55FF; + case YELLOW -> 0xFFFF55; + case WHITE -> 0xFFFFFF; + default -> null; + }; + } + + private static net.minecraft.text.Formatting toLegacy(final ChatFormatting formatting) { + return formatting == null ? null : net.minecraft.text.Formatting.valueOf(formatting.name()); + } + + private static ChatFormatting fromLegacy(final net.minecraft.text.Formatting formatting) { + return formatting == null ? null : ChatFormatting.valueOf(formatting.name()); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + + if (!(obj instanceof Style)) { + return false; + } + + final Style other = (Style) obj; + return Objects.equals(this.parent, other.parent) + && this.color == other.color + && Objects.equals(this.rgbColor, other.rgbColor) + && Objects.equals(this.bold, other.bold) + && Objects.equals(this.italic, other.italic) + && Objects.equals(this.underlined, other.underlined) + && Objects.equals(this.strikethrough, other.strikethrough) + && Objects.equals(this.obfuscated, other.obfuscated) + && Objects.equals(this.insertion, other.insertion); + } + + @Override + public int hashCode() { + return Objects.hash( + this.parent, + this.color, + this.rgbColor, + this.bold, + this.italic, + this.underlined, + this.strikethrough, + this.obfuscated, + this.insertion + ); + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/TranslatableContents.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/TranslatableContents.java new file mode 100644 index 000000000..3a1114c73 --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/TranslatableContents.java @@ -0,0 +1,181 @@ +package org.polyfrost.oneconfig.internal.legacy.chat; + +//? if = 1.8.9 { +/*import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableList.Builder; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Consumer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import net.ornithemc.osl.text.impl.Locale; +import org.jspecify.annotations.Nullable; + +public class TranslatableContents implements ComponentContents { + public static final Object[] NO_ARGS = new Object[0]; + private static final FormattedText TEXT_PERCENT = FormattedText.of("%"); + private static final FormattedText TEXT_NULL = FormattedText.of("null"); + private final String key; + @Nullable + private final String fallback; + private final Object[] args; + @Nullable + private Locale decomposedWith; + private List decomposedParts = ImmutableList.of(); + private static final Pattern FORMAT_PATTERN = Pattern.compile("%(?:(\\d+)\\$)?([A-Za-z%]|$)"); + + public static boolean isAllowedPrimitiveArgument(@Nullable final Object object) { + return object instanceof Number || object instanceof Boolean || object instanceof String; + } + + public TranslatableContents(final String key, @Nullable final String fallback, final Object[] args) { + this.key = key; + this.fallback = fallback; + this.args = args; + } + + private void decompose() { + Locale currentLocale = Locale.find(); + if (currentLocale != this.decomposedWith) { + this.decomposedWith = currentLocale; + String translated = currentLocale.get(this.key); + String format; + if (translated == null || translated.equals(this.key)) { + format = this.fallback != null ? this.fallback : this.key; + } else { + format = translated; + } + + try { + Builder parts = ImmutableList.builder(); + this.decomposeTemplate(format, parts::add); + this.decomposedParts = parts.build(); + } catch (TranslatableFormatException var4) { + this.decomposedParts = ImmutableList.of(FormattedText.of(format)); + } + } + } + + private void decomposeTemplate(final String template, final Consumer decomposedParts) { + Matcher matcher = FORMAT_PATTERN.matcher(template); + + try { + int replacementIndex = 0; + int current = 0; + + while (matcher.find(current)) { + int start = matcher.start(); + int end = matcher.end(); + if (start > current) { + String prefix = template.substring(current, start); + if (prefix.indexOf(37) != -1) { + throw new IllegalArgumentException(); + } + + decomposedParts.accept(FormattedText.of(prefix)); + } + + String formatType = matcher.group(2); + String formatString = template.substring(start, end); + if ("%".equals(formatType) && "%%".equals(formatString)) { + decomposedParts.accept(TEXT_PERCENT); + } else { + if (!"s".equals(formatType)) { + throw new TranslatableFormatException(this, "Unsupported format: '" + formatString + "'"); + } + + String possiblePositionIndex = matcher.group(1); + int index = possiblePositionIndex != null ? Integer.parseInt(possiblePositionIndex) - 1 : replacementIndex++; + decomposedParts.accept(this.getArgument(index)); + } + + current = end; + } + + if (current < template.length()) { + String tail = template.substring(current); + if (tail.indexOf(37) != -1) { + throw new IllegalArgumentException(); + } + + decomposedParts.accept(FormattedText.of(tail)); + } + } catch (IllegalArgumentException var12) { + throw new TranslatableFormatException(this, var12); + } + } + + private FormattedText getArgument(final int index) { + if (index >= 0 && index < this.args.length) { + Object arg = this.args[index]; + if (arg instanceof Component componentArg) { + return componentArg; + } else { + return arg == null ? TEXT_NULL : FormattedText.of(arg.toString()); + } + } else { + throw new TranslatableFormatException(this, index); + } + } + + @Override + public Optional visit(final FormattedText.StyledContentConsumer output, final Style currentStyle) { + this.decompose(); + + for (FormattedText part : this.decomposedParts) { + Optional result = part.visit(output, currentStyle); + if (result.isPresent()) { + return result; + } + } + + return Optional.empty(); + } + + @Override + public Optional visit(final FormattedText.ContentConsumer output) { + this.decompose(); + + for (FormattedText part : this.decomposedParts) { + Optional result = part.visit(output); + if (result.isPresent()) { + return result; + } + } + + return Optional.empty(); + } + + public boolean equals(final Object o) { + return this == o + ? true + : o instanceof TranslatableContents that + && Objects.equals(this.key, that.key) + && Objects.equals(this.fallback, that.fallback) + && Arrays.equals(this.args, that.args); + } + + public int hashCode() { + int result = Objects.hashCode(this.key); + result = 31 * result + Objects.hashCode(this.fallback); + return 31 * result + Arrays.hashCode(this.args); + } + + public String toString() { + return "translation{key='" + + this.key + + "'" + + (this.fallback != null ? ", fallback='" + this.fallback + "'" : "") + + ", args=" + + Arrays.toString(this.args) + + "}"; + } + + public String getKey() { + return this.key; + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/TranslatableFormatException.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/TranslatableFormatException.java new file mode 100644 index 000000000..07465c68e --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/TranslatableFormatException.java @@ -0,0 +1,19 @@ +package org.polyfrost.oneconfig.internal.legacy.chat; + +//? if = 1.8.9 { +/*import java.util.Locale; + +public class TranslatableFormatException extends IllegalArgumentException { + public TranslatableFormatException(final TranslatableContents component, final String message) { + super(String.format(Locale.ROOT, "Error parsing: %s: %s", component, message)); + } + + public TranslatableFormatException(final TranslatableContents component, final int index) { + super(String.format(Locale.ROOT, "Invalid index %d requested for %s", index, component)); + } + + public TranslatableFormatException(final TranslatableContents component, final Throwable t) { + super(String.format(Locale.ROOT, "Error while parsing: %s", component), t); + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/Unit.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/Unit.java new file mode 100644 index 000000000..cbbc099f0 --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/chat/Unit.java @@ -0,0 +1,7 @@ +package org.polyfrost.oneconfig.internal.legacy.chat; + +//? if = 1.8.9 { +/*public enum Unit { + INSTANCE +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/command/ClientCommandRegistrationCallback.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/command/ClientCommandRegistrationCallback.java new file mode 100644 index 000000000..abd3dfa5f --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/command/ClientCommandRegistrationCallback.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.polyfrost.oneconfig.internal.legacy.command; + +//? if = 1.8.9 { +/*import com.mojang.brigadier.CommandDispatcher; + +import java.util.ArrayList; +import java.util.List; + +/^* + * Callback for when client commands are registered to the dispatcher. + * + *

To register some commands, you would register an event listener and implement the callback. + * + *

See {@link ClientCommands} for more details and an example. + ^/ +public interface ClientCommandRegistrationCallback { + Event EVENT = new Event(); + + /^* + * Called when registering client commands. + * + * @param dispatcher the command dispatcher to register commands to + * @param buildContext object exposing access to the game's holders + ^/ + void register(CommandDispatcher dispatcher, Object buildContext); + + final class Event { + private final List callbacks = new ArrayList<>(); + + public void register(ClientCommandRegistrationCallback callback) { + callbacks.add(callback); + } + + void invoke(CommandDispatcher dispatcher, Object buildContext) { + for (ClientCommandRegistrationCallback callback : callbacks) { + callback.register(dispatcher, buildContext); + } + } + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/command/FabricClientCommandSource.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/command/FabricClientCommandSource.java new file mode 100644 index 000000000..913e7cd0f --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/command/FabricClientCommandSource.java @@ -0,0 +1,21 @@ +package org.polyfrost.oneconfig.internal.legacy.command; + +//? if = 1.8.9 { +/*import net.minecraft.client.Minecraft; +import net.minecraft.ChatFormatting; +import net.minecraft.network.chat.Component; + +public interface FabricClientCommandSource { + default Minecraft getClient() { + return Minecraft.getInstance(); + } + + default void sendFeedback(Component message) { + getClient().gui.getChat().addMessage(message); + } + + default void sendError(Component message) { + sendFeedback(Component.empty().append(message).withStyle(ChatFormatting.RED)); + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/ClientPlayerCompat.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/ClientPlayerCompat.java new file mode 100644 index 000000000..534841a85 --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/ClientPlayerCompat.java @@ -0,0 +1,12 @@ +package org.polyfrost.oneconfig.internal.legacy.compat; + +//? if = 1.8.9 { +/*import net.minecraft.client.entity.living.player.ClientPlayerEntity; +import org.polyfrost.oneconfig.internal.legacy.PlayerSkin; + +public interface ClientPlayerCompat { + default PlayerSkin getSkin() { + return new PlayerSkin(((ClientPlayerEntity) (Object) this).getSkinTextureLocation()); + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/GameOptionsCompat.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/GameOptionsCompat.java new file mode 100644 index 000000000..a863406b8 --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/GameOptionsCompat.java @@ -0,0 +1,23 @@ +package org.polyfrost.oneconfig.internal.legacy.compat; + +//? if = 1.8.9 { +/*import net.minecraft.client.Options; +import net.minecraft.sounds.SoundSource; + +import java.util.Locale; +import java.util.function.Supplier; + +public interface GameOptionsCompat { + default float getSoundSourceVolume(SoundCategory source) { + return ((Options) (Object) this).getSoundCategoryVolume(source); + } + + default Supplier forceUnicodeFont() { + return () -> ((Options) (Object) this).forceUnicodeFont; + } + + default Supplier japaneseGlyphVariants() { + return () -> Locale.getDefault().getLanguage().equalsIgnoreCase("ja"); + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/HitResultCompat.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/HitResultCompat.java new file mode 100644 index 000000000..0c86b56fe --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/HitResultCompat.java @@ -0,0 +1,11 @@ +package org.polyfrost.oneconfig.internal.legacy.compat; + +//? if = 1.8.9 { +/*import net.minecraft.world.phys.HitResult; + +public interface HitResultCompat { + default HitResult.Type getType() { + return ((HitResult) (Object) this).type; + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/HttpTextureCompat.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/HttpTextureCompat.java new file mode 100644 index 000000000..5c588c573 --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/HttpTextureCompat.java @@ -0,0 +1,15 @@ +package org.polyfrost.oneconfig.internal.legacy.compat; + +//? if = 1.8.9 { +/*import net.minecraft.client.renderer.texture.DynamicTexture; +import com.mojang.blaze3d.platform.NativeImage; + +import java.awt.image.BufferedImage; + +public interface HttpTextureCompat { + default NativeImage getPixels() { + BufferedImage image = ((HttpTexture) (Object) this).image; + return image == null ? null : new NativeImage(image); + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/KeyBindingCompat.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/KeyBindingCompat.java new file mode 100644 index 000000000..caf077f0c --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/KeyBindingCompat.java @@ -0,0 +1,22 @@ +package org.polyfrost.oneconfig.internal.legacy.compat; + +//? if = 1.8.9 { +/*import com.mojang.blaze3d.platform.InputConstants; +import net.minecraft.client.KeyMapping; +import org.polyfrost.oneconfig.internal.legacy.KeyCodes; + +public interface KeyBindingCompat { + default String saveString() { + return KeyCodes.fromLegacy(((KeyMapping) (Object) this).getKeyCode()).getName(); + } + + default InputConstants.Key getDefaultKey() { + return KeyCodes.fromLegacy(((KeyMapping) (Object) this).getDefaultKeyCode()); + } + + default void setKey(InputConstants.Key key) { + ((KeyMapping) (Object) this).setKeyCode(KeyCodes.toLegacy(key)); + } + +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/MinecraftCompat.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/MinecraftCompat.java new file mode 100644 index 000000000..3a0d8db46 --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/MinecraftCompat.java @@ -0,0 +1,103 @@ +package org.polyfrost.oneconfig.internal.legacy.compat; + +//? if = 1.8.9 { +/*import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.Screen; +import com.mojang.blaze3d.platform.TextInputManager; +import com.mojang.authlib.GameProfile; +import net.minecraft.server.packs.resources.ResourceManager; +import org.lwjgl.opengl.Display; +import org.polyfrost.oneconfig.internal.legacy.User; +import org.polyfrost.oneconfig.internal.legacy.Window; + +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.FutureTask; +import java.util.function.Supplier; + +public interface MinecraftCompat { + default Window getWindow() { + return new Window((Minecraft) (Object) this); + } + + default boolean isWindowActive() { + return Display.isActive(); + } + + default TextInputManager textInputManager() { + return TextInputManager.getInstance(); + } + + default DebugOverlay getDebugOverlay() { + Minecraft minecraft = (Minecraft) (Object) this; + return () -> minecraft.options.debugEnabled; + } + + default GameProfile getGameProfile() { + return ((Minecraft) (Object) this).getSession().getProfile(); + } + + default User getUser() { + return new User(((Minecraft) (Object) this).getSession().getProfile()); + } + + default boolean isLocalServer() { + return ((Minecraft) (Object) this).isIntegratedServerRunning(); + } + + default int getFps() { + return Minecraft.getCurrentFps(); + } + + default CompletableFuture reloadResourcePacks() { + ((Minecraft) (Object) this).reloadResources(); + return CompletableFuture.completedFuture(null); + } + + default VanillaPackResources getVanillaPackResources() { + return path -> { + String joined = String.join("/", path); + ResourceManager resources = ResourceManager.client(); + return resources.hasResource(joined) ? () -> resources.getResource(joined) : null; + }; + } + + default void tell(Runnable task) { + Minecraft minecraft = (Minecraft) (Object) this; + FutureTask future = new FutureTask<>(task, null); + synchronized (minecraft.tasks) { + minecraft.tasks.add(future); + } + } + + default CompletableFuture submit(Supplier task) { + Minecraft minecraft = (Minecraft) (Object) this; + if (minecraft.isSameThread()) { + return CompletableFuture.completedFuture(task.get()); + } + + CompletableFuture future = new CompletableFuture<>(); + minecraft.executeTask(() -> { + try { + future.complete(task.get()); + } catch (Throwable throwable) { + future.completeExceptionally(throwable); + } + }); + return future; + } + + interface VanillaPackResources { + ResourceSupplier getRootResource(String... path); + } + + interface DebugOverlay { + boolean showDebugScreen(); + } + + interface ResourceSupplier { + InputStream get() throws IOException; + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/SkinManagerCompat.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/SkinManagerCompat.java new file mode 100644 index 000000000..f78fb7dc5 --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/SkinManagerCompat.java @@ -0,0 +1,23 @@ +package org.polyfrost.oneconfig.internal.legacy.compat; + +//? if = 1.8.9 { +/*import com.mojang.authlib.GameProfile; +import com.mojang.authlib.minecraft.MinecraftProfileTexture; +import net.minecraft.client.resource.skin.SkinManager; +import org.polyfrost.oneconfig.internal.legacy.PlayerSkin; + +import java.util.concurrent.CompletableFuture; + +public interface SkinManagerCompat { + default CompletableFuture getOrLoad(GameProfile profile) { + SkinManager manager = (SkinManager) (Object) this; + CompletableFuture future = new CompletableFuture<>(); + manager.register(profile, (type, location, texture) -> { + if (type == MinecraftProfileTexture.Type.SKIN) { + future.complete(new PlayerSkin(location)); + } + }, true); + return future; + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/SoundInstanceCompat.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/SoundInstanceCompat.java new file mode 100644 index 000000000..25080c9aa --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/compat/SoundInstanceCompat.java @@ -0,0 +1,11 @@ +package org.polyfrost.oneconfig.internal.legacy.compat; + +//? if = 1.8.9 { +/*import net.minecraft.client.resources.sounds.SoundInstance; + +public interface SoundInstanceCompat { + default SoundInstance getSound() { + return (SoundInstance) this; + } +} +*///?} diff --git a/minecraft/src/main/resources/oneconfigv1.classtweaker b/minecraft/src/main/resources/oneconfigv1.classtweaker new file mode 100644 index 000000000..ec6072e14 --- /dev/null +++ b/minecraft/src/main/resources/oneconfigv1.classtweaker @@ -0,0 +1,13 @@ +classTweaker v2 named + +accessible field net/minecraft/client/Minecraft tasks Ljava/util/Queue; +accessible field net/minecraft/client/render/texture/HttpTexture image Ljava/awt/image/BufferedImage; + +transitive-inject-interface net/minecraft/client/Minecraft org/polyfrost/oneconfig/internal/legacy/compat/MinecraftCompat +transitive-inject-interface net/minecraft/client/KeyMapping org/polyfrost/oneconfig/internal/legacy/compat/KeyBindingCompat +transitive-inject-interface net/minecraft/world/HitResult org/polyfrost/oneconfig/internal/legacy/compat/HitResultCompat +transitive-inject-interface net/minecraft/client/render/texture/HttpTexture org/polyfrost/oneconfig/internal/legacy/compat/HttpTextureCompat +transitive-inject-interface net/minecraft/client/sound/instance/SoundInstance org/polyfrost/oneconfig/internal/legacy/compat/SoundInstanceCompat +transitive-inject-interface net/minecraft/client/Options org/polyfrost/oneconfig/internal/legacy/compat/GameOptionsCompat +transitive-inject-interface net/minecraft/client/entity/living/player/ClientPlayerEntity org/polyfrost/oneconfig/internal/legacy/compat/ClientPlayerCompat +transitive-inject-interface net/minecraft/client/resource/skin/SkinManager org/polyfrost/oneconfig/internal/legacy/compat/SkinManagerCompat diff --git a/minecraft/stonecutter.gradle.kts b/minecraft/stonecutter.gradle.kts index ab44a0a62..15dc3097b 100644 --- a/minecraft/stonecutter.gradle.kts +++ b/minecraft/stonecutter.gradle.kts @@ -30,7 +30,7 @@ stonecutter { this["stella_compat"] = current.project.endsWith("-fabric") && catalogue.has("stella") this["apec_compat"] = current.project.endsWith("-fabric") && catalogue.has("apec") this["tr7zw_compat"] = true - this["wwaypoints_compat"] = true + this["wwaypoints_compat"] = current.project.endsWith("-fabric") this["cinnabar"] = catalogue.has("cinnabar") && rootProject.hasProperty("minecraft.vulkan") this["vulkanmod"] = current.project.endsWith("-fabric") && catalogue.has("vulkanmod") } @@ -51,16 +51,189 @@ stonecutter { string(eval(current.version, ">= 26.2"), "main_render_target") { replace("mainRenderTarget", "gameRenderer.mainRenderTarget()") } - string(eval(current.version, "< 1.21.11")) { + string(eval(current.version, "< 1.21.11", "> 1.8.9")) { replace( "import net.minecraft.resources.Identifier\n", "import net.minecraft.resources.ResourceLocation as Identifier\n", ) } + string(eval(current.version, "= 1.8.9")) { + replace( + "import net.minecraft.resources.Identifier\n", + "import net.minecraft.resource.Identifier\n", + ) + } string(eval(current.version, "< 1.21.2")) { replace("Minecraft.getInstance().schedule(", "Minecraft.getInstance().tell(") } + + string(eval(current.version, "= 1.8.9")) { + replace( + "com.mojang.blaze3d.platform.InputConstants", + "org.polyfrost.oneconfig.internal.legacy.InputConstants" + ) + replace( + "com.mojang.blaze3d.platform.NativeImage", + "org.polyfrost.oneconfig.internal.legacy.NativeImage" + ) + replace( + "net.kyori.adventure.platform.fabric.FabricClientAudiences", + "org.polyfrost.oneconfig.internal.legacy.FabricClientAudiences" + ) + replace( + "net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource", + "org.polyfrost.oneconfig.internal.legacy.command.FabricClientCommandSource" + ) + replace( + "net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback", + "org.polyfrost.oneconfig.internal.legacy.command.ClientCommandRegistrationCallback" + ) + replace( + "net.minecraft.client.resources.sounds.SimpleSoundInstance", + "org.polyfrost.oneconfig.internal.legacy.SimpleSoundInstance" + ) + replace( + "net.minecraft.sounds.SoundEvents", + "org.polyfrost.oneconfig.internal.legacy.SoundEvents" + ) + replace( + "net.minecraft.network.chat.Component", + "org.polyfrost.oneconfig.internal.legacy.chat.Component" + ) + replace( + "net.minecraft.network.chat.MutableComponent", + "org.polyfrost.oneconfig.internal.legacy.chat.MutableComponent" + ) + replace( + "net.minecraft.network.chat.Style", + "org.polyfrost.oneconfig.internal.legacy.chat.Style" + ) + replace( + "net.minecraft.ChatFormatting", + "org.polyfrost.oneconfig.internal.legacy.chat.ChatFormatting" + ) + replace( + "net.minecraft.network.chat.FormattedText", + "org.polyfrost.oneconfig.internal.legacy.chat.FormattedText" + ) + replace( + "net.minecraft.util.FormattedCharSequence", + "org.polyfrost.oneconfig.internal.legacy.chat.FormattedCharSequence" + ) + replace( + "net.minecraft.util.FormattedCharSink", + "org.polyfrost.oneconfig.internal.legacy.chat.FormattedCharSink" + ) + replace( + "net.minecraft.server.Bootstrap", + "net.minecraft.Bootstrap" + ) + replace( + "net.minecraft.client.gui.screens.Screen", + "net.minecraft.client.gui.screen.Screen" + ) + replace( + "net.minecraft.client.gui.screens.TitleScreen", + "net.minecraft.client.gui.screen.TitleScreen" + ) + replace( + "net.minecraft.client.gui.screens.ChatScreen", + "net.minecraft.client.gui.screen.ChatScreen" + ) + replace( + "com.mojang.blaze3d.pipeline.RenderTarget", + "net.minecraft.client.render.pipeline.RenderTarget" + ) + replace( + "net.minecraft.server.packs.repository.RepositorySource", + "net.ornithemc.osl.resource.loader.api.resource.repository.ResourcePackRepository" + ) + replace( + "net.minecraft.world.phys.HitResult", + "net.minecraft.world.HitResult" + ) + replace( + "import net.minecraft.network.protocol.Packet", + "import net.minecraft.network.packet.Packet" + ) + replace( + "net.minecraft.client.resources.sounds.SoundInstance", + "net.minecraft.client.sound.instance.SoundInstance" + ) + replace( + "net.minecraft.client.resources.sounds.AbstractTickableSoundInstance", + "net.minecraft.client.sound.instance.AbstractTickableSoundInstance" + ) + replace( + "net.minecraft.client.resources.language.I18n", + "net.ornithemc.osl.localization.api.L10n" + ) + replace( + "net.minecraft.client.sounds.SoundManager", + "net.minecraft.client.sound.system.SoundManager" + ) + replace( + "net.minecraft.client.sounds.SoundEngine", + "net.minecraft.client.sound.system.SoundEngine" + ) + replace( + "net.minecraft.sounds.SoundSource", + "net.minecraft.client.sound.SoundCategory" + ) + replace( + "net.minecraft.client.renderer.entity.LivingEntityRenderer", + "net.minecraft.client.render.entity.LivingEntityRenderer" + ) + replace( + "net.minecraft.world.entity.LivingEntity", + "net.minecraft.entity.living.LivingEntity" + ) + replace( + "net.minecraft.world.item", + "net.minecraft.item" + ) + replace( + "net.minecraft.server.packs.resources.PreparableReloadListener", + "net.ornithemc.osl.resource.loader.api.resource.reload.ResourceReloadListener" + ) + replace( + "net.minecraft.server.packs.resources.ReloadableResourceManager", + "net.ornithemc.osl.resource.loader.api.resource.manager.ReloadableResourceManager" + ) + replace( + "net.minecraft.server.packs.resources.ResourceManager", + "net.ornithemc.osl.resource.loader.api.resource.manager.ResourceManager" + ) + replace( + "net.minecraft.server.packs.resources.SimpleReloadInstance", + "net.ornithemc.osl.resource.loader.impl.resource.manager.SimpleReloadableResourceManager" + ) + replace( + "net.minecraft.core.Direction", + "net.minecraft.util.math.Direction" + ) + replace( + "net.minecraft.server.packs.resources.ReloadInstance", + "net.ornithemc.osl.resource.loader.api.resource.reload.ResourceReload" + ) + replace( + "net.minecraft.client.gui.components.DebugScreenOverlay", + "net.minecraft.client.gui.overlay.DebugOverlay" + ) + replace( + "net.minecraft.client.renderer.texture.AbstractTexture", + "net.minecraft.client.render.texture.Texture" + ) + replace( + "net.minecraft.client.renderer.texture.DynamicTexture", + "net.minecraft.client.render.texture.HttpTexture" + ) + replace( + "net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents", + "net.ornithemc.osl.networking.api.client.ClientConnectionEvents" + ) + } } } } From 31902839e027c7382a89ac7b9c2ac1936171c218 Mon Sep 17 00:00:00 2001 From: Saad Nadeem Date: Mon, 22 Jun 2026 00:30:42 -0400 Subject: [PATCH 07/14] feat(legacy): port services --- .../v1/internal/CompatibilityPlatformImpl.java | 8 +++++++- .../api/platform/v1/internal/I18nPlatformImpl.java | 6 ++++-- .../internal/ui/services/GLInterfaceFactory.kt | 10 +++++----- .../internal/ui/services/GLVulkanService.kt | 13 ++++++++++--- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/api/platform/v1/internal/CompatibilityPlatformImpl.java b/minecraft/src/main/java/org/polyfrost/oneconfig/api/platform/v1/internal/CompatibilityPlatformImpl.java index 2a2ed7c60..36704728a 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/api/platform/v1/internal/CompatibilityPlatformImpl.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/api/platform/v1/internal/CompatibilityPlatformImpl.java @@ -7,6 +7,7 @@ /*import net.kyori.adventure.platform.fabric.FabricClientAudiences; *///?} import net.kyori.adventure.text.Component; +//? if > 1.8.9 import net.minecraft.SharedConstants; import net.minecraft.client.Minecraft; import org.polyfrost.oneconfig.api.platform.v1.CompatibilityPlatform; @@ -32,7 +33,7 @@ public void displayChatMessage(Component text) { @Override public Set getMods() { - //? fabric { + //? fabric || ornithe { return FabricLoader.getInstance().getAllMods().stream() .map(mod -> { @@ -67,8 +68,11 @@ public boolean isDevelopment() { @Override public String version() { + //? if > 1.8.9 { //~ if >= 1.21.8 '.getName()' -> '.name()' return SharedConstants.getCurrentVersion().name(); + //?} else + //return FabricLoader.getInstance().getModContainer("minecraft").orElseThrow().getMetadata().getVersion().getFriendlyString(); } @Override @@ -77,6 +81,8 @@ public String loader() { return "fabric"; //? neoforge //return "neoforge"; + //? ornithe + //return "ornithe"; } @Override diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/api/platform/v1/internal/I18nPlatformImpl.java b/minecraft/src/main/java/org/polyfrost/oneconfig/api/platform/v1/internal/I18nPlatformImpl.java index 189f94e4e..7951a2987 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/api/platform/v1/internal/I18nPlatformImpl.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/api/platform/v1/internal/I18nPlatformImpl.java @@ -46,6 +46,7 @@ public Object translate(String key, String fallback, Object... args) { @Override public String translateString(String key, Object... args) { + //~ if = 1.8.9 'I18n.get(' -> 'L10n.get(' return I18n.get(key, args); } @@ -53,9 +54,10 @@ public String translateString(String key, Object... args) { public boolean hasTranslation(String key) { //? if >= 26.2 { return Language.getInstance().has(key); - //?} else { + //?} elif > 1.8.9 { /*return I18n.exists(key); - *///?} + *///?} else + //return L10n.has(key); } @Override diff --git a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/services/GLInterfaceFactory.kt b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/services/GLInterfaceFactory.kt index f645e713d..b6eb84e33 100644 --- a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/services/GLInterfaceFactory.kt +++ b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/services/GLInterfaceFactory.kt @@ -5,7 +5,7 @@ import org.jetbrains.skia.GLAssembledInterface import org.jetbrains.skia.makeGLWithInterface import org.lwjgl.opengl.GL import org.lwjgl.system.APIUtil -//? if >=26.1 +//? if >= 26.1 || = 1.8.9 import org.lwjgl.system.Callback import org.lwjgl.system.CallbackI import org.lwjgl.system.FunctionProvider @@ -14,7 +14,7 @@ import org.lwjgl.system.Pointer import org.lwjgl.system.libffi.FFICIF import org.lwjgl.system.libffi.LibFFI import org.slf4j.LoggerFactory -//? if >=26.1 +//? if >= 26.1 || = 1.8.9 import java.lang.invoke.MethodHandles internal object GLInterfaceFactory { @@ -60,9 +60,9 @@ internal object GLInterfaceFactory { @FunctionalInterface private fun interface GetProcCallbackI : CallbackI { - //? if >=26.1 + //? if >= 26.1 || = 1.8.9 { override fun getDescriptor(): Callback.Descriptor = DESCRIPTOR - //? if <26.1 + //?} else //override fun getCallInterface(): FFICIF = CALL_INTERFACE override fun callback(ret: Long, args: Long) { @@ -82,7 +82,7 @@ internal object GLInterfaceFactory { LibFFI.ffi_type_pointer, LibFFI.ffi_type_pointer, ) - //? if >= 26.3 { + //? if >= 26.3 || = 1.8.9 { /*private val DESCRIPTOR: Callback.Descriptor = Callback.Descriptor(GetProcCallbackI::class.java, MethodHandles.lookup(), CALL_INTERFACE) *///?} elif >= 26.1 private val DESCRIPTOR: Callback.Descriptor = Callback.Descriptor(MethodHandles.lookup(), CALL_INTERFACE) diff --git a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/services/GLVulkanService.kt b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/services/GLVulkanService.kt index 4d8484d5c..3305bf0fd 100644 --- a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/services/GLVulkanService.kt +++ b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/services/GLVulkanService.kt @@ -33,8 +33,10 @@ object GLVulkanService : VulkanService { //? } else //val frameBufferId = target.frameBufferId + //~ if = 1.8.9 '8' -> '0' + val stencilBits = 8 return BackendRenderTarget.makeGL( - width, height, 0, 8, frameBufferId, FramebufferFormat.GR_GL_RGBA8 + width, height, 0, stencilBits, frameBufferId, FramebufferFormat.GR_GL_RGBA8 ) } @@ -42,8 +44,10 @@ object GLVulkanService : VulkanService { width: Int, height: Int, vkImageHandle: Long, vkFormat: Int, vkQueueFamily: Int, ): BackendRenderTarget { + //~ if = 1.8.9 '8' -> '0' + val stencilBits = 8 return BackendRenderTarget.makeGL( - width, height, 0, 8, 0, FramebufferFormat.GR_GL_RGBA8 + width, height, 0, stencilBits, 0, FramebufferFormat.GR_GL_RGBA8 ) } @@ -57,7 +61,10 @@ object GLVulkanService : VulkanService { //? } else //val fboId = target.frameBufferId - return BackendRenderTarget.makeGL(width, height, 0, 8, fboId, FramebufferFormat.GR_GL_RGBA8) to + // 1.8.9 RenderTarget has no stencil attachment + //~ if = 1.8.9 '8' -> '0' + val stencilBits = 8 + return BackendRenderTarget.makeGL(width, height, 0, stencilBits, fboId, FramebufferFormat.GR_GL_RGBA8) to SurfaceColorFormat.RGBA_8888 } From 49b76a1efe9892300538626e5522c6e00645ba5a Mon Sep 17 00:00:00 2001 From: Saad Nadeem Date: Mon, 22 Jun 2026 00:30:42 -0400 Subject: [PATCH 08/14] feat(legacy): port compose and rendering --- .../internal/ui/SkiaOffscreenTarget.kt | 11 +- .../item/MinecraftItemCatalogService.kt | 62 +++++++- .../ui/compose/ComposeSceneContextImpl.kt | 36 ++++- .../internal/ui/compose/ComposeScreen.kt | 145 +++++++++++++++--- .../oneconfig/internal/ui/compose/SkiaCtx.kt | 62 +++++++- .../internal/ui/compose/SkiaFontRenderer.kt | 26 +++- .../ui/compose/impls/HudEditorUIScreen.kt | 7 + .../ui/compose/impls/OneConfigUIScreen.kt | 9 ++ .../ui/compose/opengl/StoredGLState.kt | 119 ++++++++++++++ .../internal/ui/hud/CompatOverlayRenderer.kt | 5 + .../internal/ui/hud/DebugOverlayOffscreen.kt | 58 +++++++ .../internal/ui/hud/LegacyHudOffscreen.kt | 13 +- .../internal/ui/hud/LegacyHudRenderer.kt | 20 ++- .../assets/oneconfig/font/legacy_default.json | 78 ++++++++++ 14 files changed, 604 insertions(+), 47 deletions(-) create mode 100644 minecraft/src/main/resources/assets/oneconfig/font/legacy_default.json diff --git a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/SkiaOffscreenTarget.kt b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/SkiaOffscreenTarget.kt index 7741254de..53bdf595d 100644 --- a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/SkiaOffscreenTarget.kt +++ b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/SkiaOffscreenTarget.kt @@ -1,6 +1,7 @@ package org.polyfrost.oneconfig.internal.ui import com.mojang.blaze3d.pipeline.RenderTarget +//? if > 1.8.9 import com.mojang.blaze3d.pipeline.TextureTarget import org.jetbrains.skia.BackendRenderTarget import org.jetbrains.skia.ColorSpace @@ -34,9 +35,10 @@ class SkiaOffscreenTarget { /*val rt = TextureTarget(null, w, h, true) *///?} else if >= 1.21.4 { /*val rt = TextureTarget(w, h, true) - *///?} else { + *///?} elif > 1.8.9 { /*val rt = TextureTarget(w, h, true, net.minecraft.client.Minecraft.ON_OSX) - *///?} + *///?} else + //val rt = RenderTarget(w, h, false) target = rt //? if < 1.21.5 //rt.setClearColor(0f, 0f, 0f, 0f) @@ -79,9 +81,10 @@ class SkiaOffscreenTarget { *///?} *///?} elif >= 1.21.4 { /*rt.clear() - *///?} else { + *///?} elif > 1.8.9 { /*rt.clear(net.minecraft.client.Minecraft.ON_OSX) - *///?} + *///?} else + //rt.clear() } fun destroy() { diff --git a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/components/item/MinecraftItemCatalogService.kt b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/components/item/MinecraftItemCatalogService.kt index b5fc8ae36..da6d0bd31 100644 --- a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/components/item/MinecraftItemCatalogService.kt +++ b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/components/item/MinecraftItemCatalogService.kt @@ -1,7 +1,13 @@ package org.polyfrost.oneconfig.internal.ui.components.item +//? if > 1.8.9 { import com.mojang.blaze3d.pipeline.TextureTarget import com.mojang.blaze3d.systems.RenderSystem +//?} else { +/*import com.mojang.blaze3d.pipeline.RenderTarget as TextureTarget +import net.minecraft.client.render.platform.GlStateManager +import org.lwjgl.opengl.GL11 +*///?} //? if >= 1.21.4 && < 1.21.8 //import com.mojang.blaze3d.ProjectionType //? if >= 1.21.8 { @@ -13,6 +19,7 @@ import com.mojang.blaze3d.buffers.BufferUsage //? if < 1.21.5 //import com.mojang.blaze3d.platform.NativeImage import net.minecraft.client.Minecraft +//? if > 1.8.9 { import net.minecraft.client.gui.GuiGraphicsExtractor //? if >= 1.21.8 import net.minecraft.client.gui.render.GuiRenderer @@ -24,9 +31,11 @@ import org.polyfrost.oneconfig.internal.mixin.render.GameRendererAccessor import org.polyfrost.oneconfig.internal.mixin.render.GameRendererAccessor *///? } import net.minecraft.core.registries.BuiltInRegistries +//?} import net.minecraft.network.chat.Component import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack +//? if > 1.8.9 import net.minecraft.world.item.Items import org.polyfrost.oneconfig.api.event.v1.EventManager import org.polyfrost.oneconfig.api.event.v1.events.ResourceFinishedLoading @@ -40,7 +49,7 @@ import kotlin.math.ceil import kotlin.math.floor import kotlin.math.min import kotlin.math.roundToInt -//? if < 1.21.8 +//? if < 1.21.8 && > 1.8.9 //import org.joml.Matrix4f class MinecraftItemCatalogService : ItemCatalogService { @@ -49,11 +58,19 @@ class MinecraftItemCatalogService : ItemCatalogService { private data class RenderBatch(val ids: List, val generation: Long) private val entries: List by lazy { + //? if > 1.8.9 { BuiltInRegistries.ITEM.mapNotNull { item -> if (item === Items.AIR) return@mapNotNull null val id = BuiltInRegistries.ITEM.getKey(item).toString() RegistryEntry(item, id) } + //?} else { + /*Item.REGISTRY.mapNotNull { item -> + val id = Item.REGISTRY.getKey(item)?.toString() ?: return@mapNotNull null + RegistryEntry(item, id) + } + *///?} + } private val entriesById: Map by lazy { entries.associateBy(RegistryEntry::id) } private val iconCache: MutableMap = Collections.synchronizedMap( @@ -77,7 +94,10 @@ class MinecraftItemCatalogService : ItemCatalogService { catalogCache?.let { return it } return synchronized(requestLock) { catalogCache ?: entries.map { entry -> + //? if > 1.8.9 { ItemDescriptor(entry.id, Component.translatable(entry.item.descriptionId).string) + //?} else + //ItemDescriptor(entry.id, entry.item.getName(ItemStack(entry.item))) }.also { catalogCache = it } } } @@ -188,9 +208,10 @@ class MinecraftItemCatalogService : ItemCatalogService { /*return TextureTarget(null, width, height, true) *///? } else if >= 1.21.4 { /*return TextureTarget(width, height, true).also { it.setClearColor(0f, 0f, 0f, 0f) } - *///? } else { + *///? } elif > 1.8.9 { /*return TextureTarget(width, height, true, Minecraft.ON_OSX).also { it.setClearColor(0f, 0f, 0f, 0f) } - *///? } + *///? } else + //return TextureTarget(width, height, true).also { it.setClearColor(0f, 0f, 0f, 0f) } } private fun renderItems( @@ -252,6 +273,7 @@ class MinecraftItemCatalogService : ItemCatalogService { return null *///? } else { /*val client = Minecraft.getInstance() + //? if > 1.8.9 val graphics = GuiGraphicsExtractor(client, client.renderBuffers().bufferSource()) val previousTarget = GuiTargetRedirect.target withGuiProjection(guiWidth, guiHeight) { @@ -260,8 +282,10 @@ class MinecraftItemCatalogService : ItemCatalogService { try { placements.forEach { placement -> val item = entriesById[placement.id]?.item ?: return@forEach + //~ if = 1.8.9 'graphics.renderFakeItem' -> 'client.itemRenderer.renderGuiItem' graphics.renderFakeItem(ItemStack(item), placement.x + ITEM_PADDING, placement.y + ITEM_PADDING) } + //? if > 1.8.9 graphics.flush() } finally { GuiTargetRedirect.target = previousTarget @@ -294,6 +318,7 @@ class MinecraftItemCatalogService : ItemCatalogService { //? if < 1.21.8 { /*private inline fun withGuiProjection(guiWidth: Int, guiHeight: Int, render: () -> Unit) { + //? if > 1.8.9 { RenderSystem.backupProjectionMatrix() val modelView = RenderSystem.getModelViewStack() modelView.pushMatrix() @@ -321,6 +346,27 @@ class MinecraftItemCatalogService : ItemCatalogService { //RenderSystem.applyModelViewMatrix() RenderSystem.restoreProjectionMatrix() } + //?} else { + /*val previousMatrixMode = GL11.glGetInteger(GL11.GL_MATRIX_MODE) + GL11.glMatrixMode(GL11.GL_PROJECTION) + GL11.glPushMatrix() + GL11.glLoadIdentity() + GL11.glOrtho(0.0, guiWidth.toDouble(), guiHeight.toDouble(), 0.0, 1000.0, 3000.0) + GL11.glMatrixMode(GL11.GL_MODELVIEW) + GL11.glPushMatrix() + GL11.glLoadIdentity() + GL11.glTranslatef(0f, 0f, -2000f) + + try { + render() + } finally { + GL11.glMatrixMode(GL11.GL_MODELVIEW) + GL11.glPopMatrix() + GL11.glMatrixMode(GL11.GL_PROJECTION) + GL11.glPopMatrix() + GL11.glMatrixMode(previousMatrixMode) + } + *///?} } *///? } @@ -335,9 +381,10 @@ class MinecraftItemCatalogService : ItemCatalogService { target.depthTexture?.let { encoder.clearDepthTexture(it, 1.0) } *///? } else if >= 1.21.4 { /*target.clear() - *///? } else { + *///? } elif > 1.8.9 { /*target.clear(Minecraft.ON_OSX) - *///? } + *///? } else + //target.clear() } private fun readTarget( @@ -445,8 +492,12 @@ class MinecraftItemCatalogService : ItemCatalogService { } //? } else { /*val image = NativeImage(target.width, target.height, false) + //? if > 1.8.9 { val previousTexture = RenderSystem.getShaderTexture(0) + //?} else + //val previousTexture = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D) try { + //~ if = 1.8.9 'RenderSystem' -> 'GlStateManager' RenderSystem.bindTexture(target.colorTextureId) image.downloadTexture(0, false) image.flipY() @@ -465,6 +516,7 @@ class MinecraftItemCatalogService : ItemCatalogService { } completeBatch(batch, icons) } finally { + //~ if = 1.8.9 'RenderSystem' -> 'GlStateManager' RenderSystem.bindTexture(previousTexture) image.close() closeRenderResource(renderResource) diff --git a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeSceneContextImpl.kt b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeSceneContextImpl.kt index d6f3a3c72..41d3f3028 100644 --- a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeSceneContextImpl.kt +++ b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeSceneContextImpl.kt @@ -11,17 +11,23 @@ import androidx.compose.ui.input.pointer.PointerIcon import androidx.compose.ui.input.pointer.PointerKeyboardModifiers import androidx.compose.ui.platform.PlatformContext import androidx.compose.ui.platform.PlatformScreenReader -//? if >= 26.1 +//? if >= 26.1 || = 1.8.9 import androidx.compose.ui.platform.PlatformTextInputMethodRequest import androidx.compose.ui.platform.WindowInfo import androidx.compose.ui.scene.ComposeSceneContext import androidx.compose.ui.unit.IntSize -//? if >= 26.1 +//? if >= 26.1 || = 1.8.9 import kotlinx.coroutines.awaitCancellation import net.minecraft.client.Minecraft import org.lwjgl.glfw.GLFW.* import org.polyfrost.oneconfig.api.platform.v1.Platform -//? if >= 26.1 +//? if = 1.8.9 { +/*import org.lwjgl.input.Keyboard +import org.lwjgl.sdl.SDLMouse.* +import org.lwjgl.sdl.SDLVideo.SDL_RaiseWindow +import org.polyfrost.oneconfig.internal.legacy.KeyCodes +*///?} +//? if >= 26.1 || = 1.8.9 import java.util.concurrent.atomic.AtomicInteger private class InputModeManagerImpl : InputModeManager { @@ -38,7 +44,10 @@ private class WindowInfoImpl : WindowInfo { ) private fun isKeyDown(glfwKey: Int): Boolean { + //? if > 1.8.9 { return glfwGetKey(Platform.compatibility().windowHandle(), glfwKey) == GLFW_PRESS + //?} else + //return Keyboard.isKeyDown(KeyCodes.toLegacy(glfwKey)) } override val keyboardModifiers: PointerKeyboardModifiers @@ -68,9 +77,15 @@ private class PlatformImpl : PlatformContext { override val screenReader: PlatformScreenReader = PlatformScreenReaderImpl() override val inputModeManager: InputModeManager = InputModeManagerImpl() + //? if > 1.8.9 { private val handCursor = glfwCreateStandardCursor(GLFW_HAND_CURSOR) private val textCursor = glfwCreateStandardCursor(GLFW_IBEAM_CURSOR) private val moveCursor = glfwCreateStandardCursor(GLFW_CROSSHAIR_CURSOR) + //?} else { + /*private val handCursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_POINTER) + private val textCursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_TEXT) + private val moveCursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_MOVE) + *///?} private val handle = Platform.compatibility().windowHandle() @@ -86,20 +101,33 @@ private class PlatformImpl : PlatformContext { } private fun applyPointerIcon(pointerIcon: PointerIcon) { + //? if > 1.8.9 { when (pointerIcon) { PointerIcon.Default -> glfwSetCursor(handle, 0L) PointerIcon.Hand -> glfwSetCursor(handle, handCursor) PointerIcon.Text -> glfwSetCursor(handle, textCursor) PointerIcon.Crosshair -> glfwSetCursor(handle, moveCursor) } + //?} else { + /*SDL_SetCursor(when (pointerIcon) { + PointerIcon.Default -> SDL_GetDefaultCursor() + PointerIcon.Hand -> handCursor + PointerIcon.Text -> textCursor + PointerIcon.Crosshair -> moveCursor + else -> SDL_GetDefaultCursor() + }) + *///?} } override fun requestFocus(): Boolean { + //? if > 1.8.9 { glfwFocusWindow(handle) + //?} else + //SDL_RaiseWindow(handle) return Minecraft.getInstance().isWindowActive } - //? if >= 26.1 { + //? if >= 26.1 || = 1.8.9 { private val textInputSessions = AtomicInteger() override suspend fun startInputMethod(request: PlatformTextInputMethodRequest): Nothing { diff --git a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeScreen.kt b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeScreen.kt index 3c32fd9fc..297e07abb 100644 --- a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeScreen.kt +++ b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeScreen.kt @@ -20,6 +20,7 @@ import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.IntSize import net.minecraft.client.Minecraft import org.polyfrost.oneconfig.utils.v1.ClipboardHelper +//? if > 1.8.9 import net.minecraft.client.gui.GuiGraphicsExtractor import net.minecraft.client.gui.screens.Screen //? >= 1.21.10 { @@ -27,7 +28,14 @@ import net.minecraft.client.input.CharacterEvent import net.minecraft.client.input.MouseButtonEvent import net.minecraft.client.input.KeyEvent as McKeyEvent //? } +//? if > 1.8.9 { import net.minecraft.network.chat.CommonComponents +//?} else { +/*import org.polyfrost.oneconfig.internal.legacy.KeyCodes +import org.lwjgl.input.Keyboard +import org.lwjgl.input.Mouse +import org.lwjgl.sdl.SDLVideo +*///?} import org.jetbrains.skia.FilterTileMode import org.jetbrains.skia.ImageFilter import org.jetbrains.skia.Paint @@ -93,6 +101,7 @@ private object SystemClipboard : androidx.compose.ui.platform.Clipboard { @OptIn(InternalComposeUiApi::class) abstract class ComposeScreen( protected val renderMode: RenderMode = RenderMode.ON_DEMAND, +//~ if = 1.8.9 '(CommonComponents.EMPTY)' -> '()' ) : Screen(CommonComponents.EMPTY) { enum class RenderMode { CONTINUOUS, @@ -252,6 +261,7 @@ abstract class ComposeScreen( private fun osUpscaleFactor(): Float { val handle = Platform.compatibility().windowHandle() + //? if > 1.8.9 { GLFW.glfwGetWindowContentScale(handle, contentScaleX, contentScaleY) val winCS = maxOf(contentScaleX[0], contentScaleY[0]).coerceAtLeast(1f) val mon = GLFW.glfwGetWindowMonitor(handle).takeIf { it != 0L } ?: GLFW.glfwGetPrimaryMonitor() @@ -259,6 +269,13 @@ abstract class ComposeScreen( GLFW.glfwGetMonitorContentScale(mon, monScaleX, monScaleY) val monCS = maxOf(monScaleX[0], monScaleY[0]).coerceAtLeast(1f) return (monCS / winCS).coerceAtLeast(1f) + //?} else { + /*val windowScale = SDLVideo.SDL_GetWindowDisplayScale(handle).coerceAtLeast(1f) + val display = SDLVideo.SDL_GetDisplayForWindow(handle) + if (display == 0) return 1f + val displayScale = SDLVideo.SDL_GetDisplayContentScale(display).coerceAtLeast(1f) + return (displayScale / windowScale).coerceAtLeast(1f) + *///?} } override fun init() { @@ -268,6 +285,9 @@ abstract class ComposeScreen( return } + //? if = 1.8.9 + //Keyboard.enableRepeatEvents(true) + sceneDirty = true lastPointer = null @@ -327,6 +347,7 @@ abstract class ComposeScreen( override fun isPauseScreen(): Boolean = false + //? if > 1.8.9 { //~ if >= 26.1 'renderBackground' -> 'extractBackground' override fun extractBackground(ctx: GuiGraphicsExtractor, mouseX: Int, mouseY: Int, tickDelta: Float) { if (client.level == null) { @@ -334,25 +355,33 @@ abstract class ComposeScreen( extractPanorama(ctx, tickDelta) } } + //?} private fun disposeScene() { SkiaCtx.clearComposeFrame() closeSceneQuietly() } + //? if > 1.8.9 { override fun onClose() { ComposeSceneContextImpl.resetPointerIcon() disposeScene() } + //?} override fun removed() { + //? if = 1.8.9 + //Keyboard.enableRepeatEvents(false) ComposeSceneContextImpl.resetPointerIcon() disposeScene() super.removed() } + //? if > 1.8.9 { //~ if >= 26.1 'render' -> 'extractRenderState' override fun extractRenderState(ctx: GuiGraphicsExtractor, mouseX: Int, mouseY: Int, tickDelta: Float) { + //?} else + //override fun render(mouseX: Int, mouseY: Int, tickDelta: Float) { if (Platform.screen().current() !== this) return if (scenePoisoned) { if (sceneRebuilds >= MAX_SCENE_REBUILDS) { @@ -393,10 +422,12 @@ abstract class ComposeScreen( withScene { it.invalidatePositionInWindow() } } + //? if > 1.8.9 { val debugOverlayOnTop = org.polyfrost.oneconfig.internal.ui.hud.DebugOverlayOffscreen.shouldSuppressVanilla() if (renderMode == RenderMode.ON_DEMAND && !sceneDirty && SkiaCtx.isDeferredComposeBackend && !debugOverlayOnTop) { if (SkiaCtx.blitComposeCached(ctx)) return } + //?} if (liveScene() == null) return @@ -428,52 +459,105 @@ abstract class ComposeScreen( val wasDirty = sceneDirty || renderMode == RenderMode.CONTINUOUS sceneDirty = false when { + //? if > 1.8.9 SkiaCtx.isDeferredComposeBackend -> SkiaCtx.drawComposeBlit(ctx, renderBlock) SkiaCtx.isVulkanMode -> SkiaCtx.queueDraw(renderBlock) // non-deferred Vulkan draws straight to the main RT else -> SkiaCtx.submitComposeFrame(wasDirty, renderBlock) // GL uses a cached FBO and re-renders only when dirty } } + //? if = 1.8.9 { + /*override fun handleMouse() { + val wheel = Mouse.getEventDWheel() + if (wheel != 0) { + mouseScrolled(wheel) + } + + super.handleMouse() + } + + override fun handleKeyboard() { + fun getModifiers(): Int { + var m = 0 + if (Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_RCONTROL)) m = m or GLFW.GLFW_MOD_CONTROL + if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT)) m = m or GLFW.GLFW_MOD_SHIFT + if (Keyboard.isKeyDown(Keyboard.KEY_LMENU) || Keyboard.isKeyDown(Keyboard.KEY_RMENU)) m = m or GLFW.GLFW_MOD_ALT + if (Keyboard.isKeyDown(Keyboard.KEY_LMETA) || Keyboard.isKeyDown(Keyboard.KEY_RMETA)) m = m or GLFW.GLFW_MOD_SUPER + return m + } + + val char = Keyboard.getEventCharacter() + val legacyKey = Keyboard.getEventKey() + val key = if (legacyKey > 0) KeyCodes.fromLegacy(legacyKey).value else -1 + val modifiers = getModifiers() + + if (Keyboard.getEventKeyState()) { + val keyHandled = if (key >= 0) keyPressed(key, modifiers) else false + val typedHandled = if (char != Keyboard.CHAR_NONE.toChar()) { + charTyped(char, modifiers) + } else false + + if (key >= 0 && !keyHandled && !typedHandled) { + super.keyPressed(char, legacyKey) + } + } else if (key >= 0) { + keyReleased(key, modifiers) + } + client.handleGuiKeyBindings() + } + *///?} + //? >= 1.21.10 { override fun mouseClicked(event: MouseButtonEvent, doubleClick: Boolean): Boolean { val button = event.button() - //? } else { + //?} elif > 1.8.9 { /*override fun mouseClicked(x: Double, y: Double, button: Int): Boolean { - *///? } + *///?} else + //override fun mouseClicked(x: Int, y: Int, button: Int) { if (handleMouseClicked(button)) { consumedButtons += button + //$ if > 1.8.9 'return true' else 'return' return true } sendMouseButtonEvent(PointerEventType.Press, button) - //? >= 1.21.10 { + //? if >= 1.21.10 { return super.mouseClicked(event, doubleClick) - //? } else { + //?} elif > 1.8.9 { /*return super.mouseClicked(x, y, button) - *///? } + *///?} else + //super.mouseClicked(x, y, button) } //? >= 1.21.10 { override fun mouseReleased(event: MouseButtonEvent): Boolean { val button = event.button() - //? } else { + //?} elif > 1.8.9 { /*override fun mouseReleased(x: Double, y: Double, button: Int): Boolean { - *///? } + *///?} else + //override fun mouseReleased(x: Int, y: Int, button: Int) { if (!consumedButtons.remove(button)) sendMouseButtonEvent(PointerEventType.Release, button) //? if >= 1.21.10 { return super.mouseReleased(event) - //?} else { + //?} elif > 1.8.9 { /*return super.mouseReleased(x, y, button) - *///?} + *///?} else + //super.mouseReleased(x, y, button) } protected open val scrollSpeed: Float get() = 1f + //? if > 1.8.9 { override fun mouseScrolled(x: Double, y: Double, scrollX: Double, scrollY: Double): Boolean { sendScrollEvent(scrollX, scrollY) return super.mouseScrolled(x, y, scrollX, scrollY) } + //?} else { + /*private fun mouseScrolled(scrollY: Int) { + sendScrollEvent(0.0, scrollY.toDouble()) + } + *///?} protected open fun handleMouseClicked(button: Int): Boolean = false @@ -499,6 +583,7 @@ abstract class ComposeScreen( it.sendPointerEvent( eventType = PointerEventType.Scroll, position = position, + //~ if = 1.8.9 '(-scrollX * scrollScale).toFloat()' -> '0f' scrollDelta = Offset((-scrollX * scrollScale).toFloat(), (-scrollY * scrollScale).toFloat()), ) } @@ -512,16 +597,20 @@ abstract class ComposeScreen( val modifiers = 0 //dropped from the event in 26.1 because glfw no longer passes them //? } else //val modifiers = event.modifiers - //? } else { + //?} elif > 1.8.9 { /*override fun charTyped(char: Char, modifiers: Int): Boolean { val codepoint = char.code - *///? } + *///?} else { + /*private fun charTyped(char: Char, modifiers: Int): Boolean { + val codepoint = char.code + *///?} val handled = sendCharacterEvent(char, codepoint, modifiers) - //? >= 1.21.10 { + //? if >= 1.21.10 { return handled || super.charTyped(event) - //? } else { + //?} elif > 1.8.9 { /*return handled || super.charTyped(char, modifiers) - *///? } + *///?} else + //return handled } fun Int.ctrlDown() = this and GLFW.GLFW_MOD_CONTROL != 0 @@ -538,30 +627,34 @@ abstract class ComposeScreen( override fun keyPressed(event: McKeyEvent): Boolean { val key = event.key val modifiers = event.modifiers - //?} else { + //?} elif > 1.8.9 { /*override fun keyPressed(key: Int, scanCode: Int, modifiers: Int): Boolean { - *///?} + *///?} else + //private fun keyPressed(key: Int, modifiers: Int): Boolean { val handled = dispatchKeyPressed(key, modifiers) //? if >= 1.21.10 { return handled || super.keyPressed(event) - //?} else { + //?} elif > 1.8.9 { /*return handled || super.keyPressed(key, scanCode, modifiers) - *///?} + *///?} else + //return handled } //? if >= 1.21.10 { override fun keyReleased(event: McKeyEvent): Boolean { val key = event.key val modifiers = event.modifiers - //?} else { + //?} elif > 1.8.9 { /*override fun keyReleased(key: Int, scanCode: Int, modifiers: Int): Boolean { - *///?} + *///?} else + //private fun keyReleased(key: Int, modifiers: Int): Boolean { val handled = if (consumedKeys.remove(key)) false else sendKeyReleasedEvent(key, modifiers) //? if >= 1.21.10 { return handled || super.keyReleased(event) - //?} else { + //?} elif > 1.8.9 { /*return handled || super.keyReleased(key, scanCode, modifiers) - *///?} + *///?} else + //return handled } private fun dispatchKeyPressed(key: Int, modifiers: Int): Boolean { @@ -722,8 +815,11 @@ abstract class ComposeScreen( private fun sceneDensity(): Float { val pixelRatio = Platform.screen().pixelRatio().takeIf { it > 0f } ?: 1f + //? if > 1.8.9 { GLFW.glfwGetWindowContentScale(Platform.compatibility().windowHandle(), contentScaleX, contentScaleY) val contentScale = maxOf(contentScaleX[0], contentScaleY[0]).coerceAtLeast(1f) + //?} else + //val contentScale = SDLVideo.SDL_GetWindowDisplayScale(Platform.compatibility().windowHandle()) return (contentScale / pixelRatio).coerceAtLeast(1f) } @@ -737,8 +833,13 @@ abstract class ComposeScreen( } protected fun pointerPosition(): Offset { + //? if > 1.8.9 { val mouse = client.mouseHandler return Offset(mouse.xpos().toFloat(), mouse.ypos().toFloat()) + //?} else { + /*val pixelRatio = Platform.screen().pixelRatio() + return Offset(Mouse.getX() / pixelRatio, (Platform.screen().viewportHeight() - Mouse.getY() - 1) / pixelRatio) + *///?} } private val dummyComponent by lazy { object : Component() {} } diff --git a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/SkiaCtx.kt b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/SkiaCtx.kt index 52e6346a2..1d172566c 100644 --- a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/SkiaCtx.kt +++ b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/SkiaCtx.kt @@ -1,9 +1,14 @@ package org.polyfrost.oneconfig.internal.ui.compose +import com.mojang.blaze3d.pipeline.RenderTarget +//? if > 1.8.9 import com.mojang.blaze3d.pipeline.TextureTarget import net.minecraft.client.Minecraft +//? if > 1.8.9 { import net.minecraft.client.gui.GuiGraphicsExtractor import net.minecraft.resources.Identifier +//?} else +//import net.minecraft.client.render.platform.GlStateManager import org.jetbrains.skia.BackendRenderTarget import org.jetbrains.skia.Color import org.jetbrains.skia.ColorSpace @@ -60,11 +65,11 @@ object SkiaCtx { private val gl = StoredGLState(330) - private var hudTarget: TextureTarget? = null + private var hudTarget: RenderTarget? = null private var hudSurface: Surface? = null private var hudBrt: BackendRenderTarget? = null - private var composeTarget: TextureTarget? = null + private var composeTarget: RenderTarget? = null private var composeSurface: Surface? = null private var composeBrt: BackendRenderTarget? = null @@ -155,7 +160,7 @@ object SkiaCtx { this.textureView = null } } - //? } else { + //?} elif > 1.8.9 { /*private val HUD_TEXTURE_LOC = net.minecraft.resources.ResourceLocation.fromNamespaceAndPath("oneconfig", "hud_skia") private val COMPOSE_TEXTURE_LOC = net.minecraft.resources.ResourceLocation.fromNamespaceAndPath("oneconfig", "compose_skia") private var hudTextureWrapper: HudGlTexture? = null @@ -282,6 +287,7 @@ object SkiaCtx { hudNeedsSamplingTransition = true } + //? if > 1.8.9 { @Volatile private var blurSnapshotRequested = false @@ -357,6 +363,7 @@ object SkiaCtx { } *///? } } + //?} @Volatile @JvmField @@ -376,6 +383,7 @@ object SkiaCtx { } *///? } + //? if > 1.8.9 { fun blitHud(guiGraphics: GuiGraphicsExtractor) { val rt = hudTarget ?: return val w = rt.width @@ -483,6 +491,41 @@ object SkiaCtx { guiGraphics.pose().popPose() *///? } } + //?} else { + /*fun blitHud() { + val rt = hudTarget ?: return + val w = rt.width + val h = rt.height + + gl.capture() + try { + GlStateManager.enableBlend() + GlStateManager.blendFuncSeparate( + GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, + GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA, + ) + if (hudNeedsSamplingTransition) { + vulkanService?.transitionOffscreenForSampling(rt) + hudNeedsSamplingTransition = false + hudRealIsGeneral = true + } + GL11.glMatrixMode(GL11.GL_PROJECTION) + GL11.glPushMatrix() + GL11.glMatrixMode(GL11.GL_MODELVIEW) + GL11.glPushMatrix() + try { + rt.draw(w, h, false) + } finally { + GL11.glMatrixMode(GL11.GL_MODELVIEW) + GL11.glPopMatrix() + GL11.glMatrixMode(GL11.GL_PROJECTION) + GL11.glPopMatrix() + } + } finally { + gl.restore() + } + } + *///?} fun draw() { if (!this::directContext.isInitialized) return @@ -636,9 +679,10 @@ object SkiaCtx { /*rt = TextureTarget(null, w, h, true) *///? } else if >= 1.21.4 { // rt = TextureTarget(w, h, true) - //? } else { + //?} elif > 1.8.9 { /*rt = TextureTarget(w, h, true, Minecraft.ON_OSX) - *///? } + *///?} else + //rt = RenderTarget(w, h, false) hudTarget = rt //? >= 1.21.5 { @@ -663,6 +707,7 @@ object SkiaCtx { hudBrt = brt hudSurface = Surface.makeFromBackendRenderTarget( directContext, brt, + //~ if = 1.8.9 'SurfaceOrigin.TOP_LEFT' -> 'SurfaceOrigin.BOTTOM_LEFT' SurfaceOrigin.TOP_LEFT, colorFmt, ColorSpace.sRGB, @@ -709,9 +754,10 @@ object SkiaCtx { /*TextureTarget(null, w, h, true) *///? } else if >= 1.21.4 { // TextureTarget(w, h, true) - //? } else { + //?} elif > 1.8.9 { /*TextureTarget(w, h, true, Minecraft.ON_OSX) - *///? } + *///?} else + //RenderTarget(w, h, false) } catch (e: Throwable) { onComposeAllocFailure(w, h, e) return null @@ -795,7 +841,7 @@ object SkiaCtx { if (existing != null && existing.width == w && existing.height == h) return existing glSurface?.close(); glBrt?.close() - //? if >= 26.1 { + //? if >= 26.1 || = 1.8.9 { //? if >= 26.2 { val target = client.gameRenderer.mainRenderTarget() //? } else { diff --git a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/SkiaFontRenderer.kt b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/SkiaFontRenderer.kt index f338e4e01..d234e415e 100644 --- a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/SkiaFontRenderer.kt +++ b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/SkiaFontRenderer.kt @@ -3,11 +3,16 @@ package org.polyfrost.oneconfig.internal.ui.compose import com.google.gson.JsonObject import com.google.gson.JsonParser import net.minecraft.client.Minecraft +//? if > 1.8.9 { import net.minecraft.resources.Identifier +//?} else { +/*import net.ornithemc.osl.core.api.util.NamespacedIdentifier as Identifier +import net.ornithemc.osl.core.api.util.NamespacedIdentifiers +*///?} import net.minecraft.server.packs.resources.PreparableReloadListener import net.minecraft.server.packs.resources.ReloadableResourceManager import net.minecraft.server.packs.resources.ResourceManager -//? < 1.21.4 +//? if < 1.21.4 && > 1.8.9 //import net.minecraft.util.profiling.ProfilerFiller import org.jetbrains.skia.* import org.jetbrains.skia.impl.RefCnt @@ -20,6 +25,7 @@ import java.util.concurrent.Executor import java.util.zip.ZipInputStream import kotlin.jvm.optionals.getOrNull +//~ if = 1.8.9 'PreparableReloadListener' -> 'ResourceReloadListener' object SkiaFontRenderer : PreparableReloadListener { private val LOGGER = LoggerFactory.getLogger("OneConfig/SkiaFontRenderer") @@ -70,6 +76,7 @@ object SkiaFontRenderer : PreparableReloadListener { private var lastLoadAttempt = 0L private const val RETRY_INTERVAL_MS = 200L + //~ if = 1.8.9 'minecraft:default' -> 'oneconfig:legacy_default' private const val ROOT_FONT = "minecraft:default" private val textPaint = Paint().apply { isAntiAlias = false } @@ -118,8 +125,10 @@ object SkiaFontRenderer : PreparableReloadListener { McFontQueue.measureWidth = { text, scale -> measureWidth(text) * scale } McFontQueue.measureHeight = { scale -> LINE_HEIGHT * scale } McFontQueue.renderer = ::draw + //~ if = 1.8.9 'Minecraft.getInstance().resourceManager' -> 'ResourceManager.client()' val resourceManager = Minecraft.getInstance().resourceManager if (resourceManager is ReloadableResourceManager) { + //~ if = 1.8.9 'registerReloadListener' -> 'addReloader' resourceManager.registerReloadListener(this) } ComposePreloader.preloadGpuWarmup() @@ -189,6 +198,7 @@ object SkiaFontRenderer : PreparableReloadListener { val now = System.currentTimeMillis() if (now - lastLoadAttempt < RETRY_INTERVAL_MS) return lastLoadAttempt = now + //~ if = 1.8.9 'Minecraft.getInstance().resourceManager' -> 'ResourceManager.client()' if (rebuild(Minecraft.getInstance().resourceManager)) loaded = true } @@ -462,6 +472,7 @@ object SkiaFontRenderer : PreparableReloadListener { private fun collectProviders(rm: ResourceManager, id: String, out: MutableList, visited: MutableSet, options: Int) { if (!visited.add(id)) return val (ns, path) = splitId(id) + //~ if = 1.8.9 'Identifier.fromNamespaceAndPath' -> 'NamespacedIdentifiers.from' for (bytes in readStack(rm, Identifier.fromNamespaceAndPath(ns, "font/$path.json"))) { val root = runCatching { JsonParser.parseString(String(bytes, Charsets.UTF_8)).asJsonObject }.getOrNull() ?: continue val providers = root.getAsJsonArray("providers") ?: continue @@ -591,6 +602,7 @@ object SkiaFontRenderer : PreparableReloadListener { private fun loadUnihex(rm: ResourceManager, provider: JsonObject, hex: HexAccumulator, claimed: MutableSet) { val hexRef = provider.get("hex_file")?.asString ?: return val (ns, path) = splitId(hexRef) + //~ if = 1.8.9 'Identifier.fromNamespaceAndPath' -> 'NamespacedIdentifiers.from' val zipBytes = read(rm, Identifier.fromNamespaceAndPath(ns, path)) ?: run { LOGGER.warn("unihex font provider references missing file {}", hexRef) return @@ -697,6 +709,7 @@ object SkiaFontRenderer : PreparableReloadListener { private fun loadBitmap(rm: ResourceManager, provider: JsonObject, out: MutableMap, atlasesOut: MutableList, claimed: MutableSet) { val fileRef = provider.get("file")?.asString ?: return val (ns, filePath) = splitId(fileRef) + //~ if = 1.8.9 'Identifier.fromNamespaceAndPath' -> 'NamespacedIdentifiers.from' val bytes = read(rm, Identifier.fromNamespaceAndPath(ns, "textures/$filePath")) ?: return if (!isPng(bytes)) return val image = Image.makeFromEncoded(bytes) @@ -757,6 +770,7 @@ object SkiaFontRenderer : PreparableReloadListener { bytes[0] == 0x89.toByte() && bytes[1] == 0x50.toByte() && bytes[2] == 0x4E.toByte() && bytes[3] == 0x47.toByte() + //? if > 1.8.9 { //? < 1.21.10 { /*override fun reload( preparationBarrier: PreparableReloadListener.PreparationBarrier?, @@ -794,4 +808,14 @@ object SkiaFontRenderer : PreparableReloadListener { } }, executor2) } + //?} else { + /*override fun resourcesReloaded(resourceManager: ResourceManager) { + if (rebuild(resourceManager)) { + loaded = true + } else { + loaded = false + lastLoadAttempt = 0L + } + } + *///?} } diff --git a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/impls/HudEditorUIScreen.kt b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/impls/HudEditorUIScreen.kt index 88e7caa2b..23351d86e 100644 --- a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/impls/HudEditorUIScreen.kt +++ b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/impls/HudEditorUIScreen.kt @@ -15,6 +15,7 @@ import androidx.compose.ui.Modifier import androidx.lifecycle.compose.LocalLifecycleOwner import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner import com.mojang.blaze3d.platform.InputConstants +//? if > 1.8.9 import net.minecraft.client.gui.GuiGraphicsExtractor import org.polyfrost.oneconfig.api.hud.v1.HudManager import org.polyfrost.oneconfig.api.platform.v1.Platform @@ -94,8 +95,11 @@ class HudEditorUIScreen : ComposeScreen() { return false } + //? if > 1.8.9 { //~ if >= 26.1 'render' -> 'extractRenderState' override fun extractRenderState(ctx: GuiGraphicsExtractor, mouseX: Int, mouseY: Int, tickDelta: Float) { + //?} else + //override fun render(mouseX: Int, mouseY: Int, tickDelta: Float) { // a screen drawn over this one may render it as its parent so skip that pass or it closes the screen above us if (Platform.screen().current() !== this) return if (closeRequested && System.currentTimeMillis() - closeRequestedAt >= closeAnimationMs) { @@ -111,8 +115,11 @@ class HudEditorUIScreen : ComposeScreen() { HudManager.prepare(sw, sh) } HudEditorViewport.update(Platform.screen().windowWidth(), Platform.screen().windowHeight()) + //? if > 1.8.9 { //~ if >= 26.1 'render' -> 'extractRenderState' super.extractRenderState(ctx, mouseX, mouseY, tickDelta) + //?} else + //super.render(mouseX, mouseY, tickDelta) } @Composable diff --git a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/impls/OneConfigUIScreen.kt b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/impls/OneConfigUIScreen.kt index 421319ae1..f609f342c 100644 --- a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/impls/OneConfigUIScreen.kt +++ b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/impls/OneConfigUIScreen.kt @@ -3,6 +3,7 @@ package org.polyfrost.oneconfig.internal.ui.compose.impls import androidx.compose.runtime.Composable import androidx.compose.ui.platform.LocalWindowInfo import com.mojang.blaze3d.platform.InputConstants +//? if > 1.8.9 import net.minecraft.client.gui.GuiGraphicsExtractor import org.lwjgl.glfw.GLFW import org.polyfrost.oneconfig.api.config.v1.ConfigManager @@ -258,8 +259,11 @@ class OneConfigUIScreen @JvmOverloads constructor( return false } + //? if > 1.8.9 { //~ if >= 26.1 'render' -> 'extractRenderState' override fun extractRenderState(ctx: GuiGraphicsExtractor, mouseX: Int, mouseY: Int, tickDelta: Float) { + //?} else + //override fun render(mouseX: Int, mouseY: Int, tickDelta: Float) { // tcdcommons-based screens like Better Statistics Screen render their parent by hand each frame // and that would queue a fullscreen blur which smears over the popup so bail unless we are current if (Platform.screen().current() !== this) return @@ -273,7 +277,9 @@ class OneConfigUIScreen @JvmOverloads constructor( //?} else { /*if (closeAnimationMs <= 0L) { SkiaCtx.discardComposeFrame() + //~ if = 1.8.9 '(ctx, tickDelta)' -> '(tickDelta)' OneConfig.render(ctx, tickDelta) + //~ if = 1.8.9 '(ctx)' -> '()' SkiaCtx.blitHud(ctx) } *///?} @@ -298,8 +304,11 @@ class OneConfigUIScreen @JvmOverloads constructor( //? } BlurRenderer.drawBlur(fullscreenBlurRadius()) } + //? if > 1.8.9 { //~ if >= 26.1 'render' -> 'extractRenderState' super.extractRenderState(ctx, mouseX, mouseY, tickDelta) + //?} else + //super.render(mouseX, mouseY, tickDelta) } private fun fullscreenBlurRadius(): Float { diff --git a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/opengl/StoredGLState.kt b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/opengl/StoredGLState.kt index 4801657ed..b4dc5ec6e 100644 --- a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/opengl/StoredGLState.kt +++ b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/opengl/StoredGLState.kt @@ -1,5 +1,6 @@ package org.polyfrost.oneconfig.internal.ui.compose.opengl +//? if > 1.8.9 { //? if >= 1.21.5 { import com.mojang.blaze3d.opengl.GlStateManager //? } else { @@ -7,18 +8,38 @@ import com.mojang.blaze3d.opengl.GlStateManager *///? } import org.lwjgl.opengl.GL import org.lwjgl.opengl.GL45.* +//?} else { +/*import net.minecraft.client.render.platform.GlStateManager +import org.lwjgl.opengl.GL11 +import org.lwjgl.opengl.GL12 +import org.lwjgl.opengl.GL13 +import org.lwjgl.opengl.GL14 +import org.lwjgl.opengl.GL15 +import org.lwjgl.opengl.GL20 +import org.lwjgl.opengl.GL30 +import org.lwjgl.opengl.GL33 +*///?} fun resyncTextureBindCache() { + //? if > 1.8.9 { for (unit in 0..7) { GlStateManager._activeTexture(GL_TEXTURE0 + unit) GlStateManager._bindTexture(0) } GlStateManager._activeTexture(GL_TEXTURE0) + //?} else { + /*for (unit in 0..7) { + GlStateManager.activeTexture(GL13.GL_TEXTURE0 + unit) + GlStateManager.bindTexture(0) + } + GlStateManager.activeTexture(GL13.GL_TEXTURE0) + *///?} } class StoredGLState(private val glVersion: Int) { private val props = StoredGLStateProps() + //? if > 1.8.9 { fun capture(): StoredGLState { with(props) { glGetIntegerv(GL_ACTIVE_TEXTURE, lastActiveTexture) @@ -212,4 +233,102 @@ class StoredGLState(private val glVersion: Int) { GlStateManager._depthMask(!mask) GlStateManager._depthMask(mask) } + //?} else { + /*private val isMacOS = System.getProperty("os.name").lowercase().contains("mac") + private var alphaTestEnabled = false + + fun capture() { + alphaTestEnabled = GL11.glIsEnabled(GL11.GL_ALPHA_TEST) + GL11.glPushClientAttrib(GL11.GL_CLIENT_ALL_ATTRIB_BITS) + GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS) + + with(props) { + if (!isMacOS) { + lastSampler[0] = GL11.glGetInteger(GL33.GL_SAMPLER_BINDING) + lastVertexArrayObject[0] = GL11.glGetInteger(GL30.GL_VERTEX_ARRAY_BINDING) + } + + lastEnableBlend = GL11.glIsEnabled(GL11.GL_BLEND) + + lastProgram[0] = GL11.glGetInteger(GL20.GL_CURRENT_PROGRAM) + lastActiveTexture[0] = GL11.glGetInteger(GL13.GL_ACTIVE_TEXTURE) + lastArrayBuffer[0] = GL11.glGetInteger(GL15.GL_ARRAY_BUFFER_BINDING) + + lastBlendSrcRgb[0] = GL11.glGetInteger(GL14.GL_BLEND_SRC_RGB) + lastBlendDstRgb[0] = GL11.glGetInteger(GL14.GL_BLEND_DST_RGB) + lastBlendSrcAlpha[0] = GL11.glGetInteger(GL14.GL_BLEND_SRC_ALPHA) + lastBlendDstAlpha[0] = GL11.glGetInteger(GL14.GL_BLEND_DST_ALPHA) + lastBlendEquationRgb[0] = GL11.glGetInteger(GL20.GL_BLEND_EQUATION_RGB) + lastBlendEquationAlpha[0] = GL11.glGetInteger(GL20.GL_BLEND_EQUATION_ALPHA) + + lastPackSwapBytes[0] = GL11.glGetInteger(GL11.GL_PACK_SWAP_BYTES) + lastPackLsbFirst[0] = GL11.glGetInteger(GL11.GL_PACK_LSB_FIRST) + lastPackRowLength[0] = GL11.glGetInteger(GL11.GL_PACK_ROW_LENGTH) + lastPackImageHeight[0] = GL11.glGetInteger(GL12.GL_PACK_IMAGE_HEIGHT) + lastPackSkipPixels[0] = GL11.glGetInteger(GL11.GL_PACK_SKIP_PIXELS) + lastPackSkipRows[0] = GL11.glGetInteger(GL11.GL_PACK_SKIP_ROWS) + lastPackSkipImages[0] = GL11.glGetInteger(GL12.GL_PACK_SKIP_IMAGES) + lastPackAlignment[0] = GL11.glGetInteger(GL11.GL_PACK_ALIGNMENT) + + lastUnpackSwapBytes[0] = GL11.glGetInteger(GL11.GL_UNPACK_SWAP_BYTES) + lastUnpackLsbFirst[0] = GL11.glGetInteger(GL11.GL_UNPACK_LSB_FIRST) + lastUnpackRowLength[0] = GL11.glGetInteger(GL11.GL_UNPACK_ROW_LENGTH) + lastUnpackImageHeight[0] = GL11.glGetInteger(GL12.GL_UNPACK_IMAGE_HEIGHT) + lastUnpackSkipPixels[0] = GL11.glGetInteger(GL11.GL_UNPACK_SKIP_PIXELS) + lastUnpackSkipRows[0] = GL11.glGetInteger(GL11.GL_UNPACK_SKIP_ROWS) + lastUnpackSkipImages[0] = GL11.glGetInteger(GL12.GL_UNPACK_SKIP_IMAGES) + lastUnpackAlignment[0] = GL11.glGetInteger(GL11.GL_UNPACK_ALIGNMENT) + } + } + + fun restore() { + GL11.glPopAttrib() + GL11.glPopClientAttrib() + if (alphaTestEnabled) GlStateManager.enableAlphaTest() else GlStateManager.disableAlphaTest() + + with(props) { + if (!isMacOS) { + for (unit in 0..7) { + GL33.glBindSampler(unit, 0) + } + GL33.glBindSampler(0, lastSampler[0]) + GL30.glBindVertexArray(lastVertexArrayObject[0]) + } + + if (lastEnableBlend) GlStateManager.enableBlend() else GlStateManager.disableBlend() + + GL20.glUseProgram(lastProgram[0]) + GL13.glActiveTexture(GL13.GL_TEXTURE0) + GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, lastArrayBuffer[0]) + + GL20.glBlendEquationSeparate(lastBlendEquationRgb[0], lastBlendEquationAlpha[0]) + GlStateManager.blendFuncSeparate( + lastBlendSrcRgb[0], + lastBlendDstRgb[0], + lastBlendSrcAlpha[0], + lastBlendDstAlpha[0], + ) + + GL11.glPixelStorei(GL11.GL_PACK_SWAP_BYTES, lastPackSwapBytes[0]) + GL11.glPixelStorei(GL11.GL_PACK_LSB_FIRST, lastPackLsbFirst[0]) + GL11.glPixelStorei(GL11.GL_PACK_ROW_LENGTH, lastPackRowLength[0]) + GL11.glPixelStorei(GL12.GL_PACK_IMAGE_HEIGHT, lastPackImageHeight[0]) + GL11.glPixelStorei(GL11.GL_PACK_SKIP_PIXELS, lastPackSkipPixels[0]) + GL11.glPixelStorei(GL11.GL_PACK_SKIP_ROWS, lastPackSkipRows[0]) + GL11.glPixelStorei(GL12.GL_PACK_SKIP_IMAGES, lastPackSkipImages[0]) + GL11.glPixelStorei(GL11.GL_PACK_ALIGNMENT, lastPackAlignment[0]) + + GL11.glPixelStorei(GL11.GL_UNPACK_SWAP_BYTES, lastUnpackSwapBytes[0]) + GL11.glPixelStorei(GL11.GL_UNPACK_LSB_FIRST, lastUnpackLsbFirst[0]) + GL11.glPixelStorei(GL11.GL_UNPACK_ROW_LENGTH, lastUnpackRowLength[0]) + GL11.glPixelStorei(GL12.GL_UNPACK_IMAGE_HEIGHT, lastUnpackImageHeight[0]) + GL11.glPixelStorei(GL11.GL_UNPACK_SKIP_PIXELS, lastUnpackSkipPixels[0]) + GL11.glPixelStorei(GL11.GL_UNPACK_SKIP_ROWS, lastUnpackSkipRows[0]) + GL11.glPixelStorei(GL12.GL_UNPACK_SKIP_IMAGES, lastUnpackSkipImages[0]) + GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, lastUnpackAlignment[0]) + + GL11.glShadeModel(GL11.GL_SMOOTH) + } + } + *///?} } diff --git a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/CompatOverlayRenderer.kt b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/CompatOverlayRenderer.kt index 03de80487..99cda4e51 100644 --- a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/CompatOverlayRenderer.kt +++ b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/CompatOverlayRenderer.kt @@ -1,5 +1,6 @@ package org.polyfrost.oneconfig.internal.ui.hud +//? if > 1.8.9 import net.minecraft.client.gui.GuiGraphicsExtractor import org.polyfrost.oneconfig.api.hud.v1.HudManager import org.polyfrost.oneconfig.internal.ui.compose.SkiaCtx @@ -8,9 +9,11 @@ import java.util.concurrent.CopyOnWriteArrayList object CompatOverlayRenderer { private val LOG = LoggerFactory.getLogger("OneConfig/CompatOverlayRenderer") + //~ if = 1.8.9 '<(GuiGraphicsExtractor)' -> '<()' private val hooks = CopyOnWriteArrayList<(GuiGraphicsExtractor) -> Unit>() @JvmStatic + //~ if = 1.8.9 'hook: (GuiGraphicsExtractor)' -> 'hook: ()' fun register(hook: (GuiGraphicsExtractor) -> Unit) { hooks.add(hook) } @@ -22,10 +25,12 @@ object CompatOverlayRenderer { fun oneConfigScreenOpen(): Boolean = HudManager.isEditing || SkiaCtx.suppressInGameHudRender @JvmStatic + //~ if = 1.8.9 '(ctx: GuiGraphicsExtractor)' -> '()' fun render(ctx: GuiGraphicsExtractor) { if (hooks.isEmpty()) return for (hook in hooks) { try { + //~ if = 1.8.9 'hook(ctx)' -> 'hook()' hook(ctx) } catch (t: Throwable) { LOG.debug("compat overlay hook failed", t) diff --git a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/DebugOverlayOffscreen.kt b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/DebugOverlayOffscreen.kt index 4a4eec1df..078628e50 100644 --- a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/DebugOverlayOffscreen.kt +++ b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/DebugOverlayOffscreen.kt @@ -1,6 +1,7 @@ package org.polyfrost.oneconfig.internal.ui.hud import com.mojang.blaze3d.pipeline.RenderTarget +//? if > 1.8.9 { import net.minecraft.client.Minecraft import net.minecraft.client.gui.GuiGraphicsExtractor //? if >= 26.1 { @@ -13,12 +14,18 @@ import org.polyfrost.oneconfig.internal.mixin.render.GameRendererAccessor import org.polyfrost.oneconfig.internal.mixin.render.GuiRendererAccessor *///? } import org.jetbrains.skia.Paint +//?} else { +/*import net.minecraft.client.Minecraft +import net.minecraft.client.render.Window +import net.minecraft.client.gui.components.DebugScreenOverlay +*///?} import org.polyfrost.oneconfig.api.platform.v1.Platform import org.polyfrost.oneconfig.internal.ui.SkiaOffscreenTarget import org.polyfrost.oneconfig.internal.ui.compose.ComposeScreen import org.polyfrost.oneconfig.internal.ui.compose.SkiaCtx import org.slf4j.LoggerFactory +//? if > 1.8.9 { /** * Minecraft draws the F3 debug overlay into the GUI while the OneConfig screen is open which puts it * *underneath* the Compose UI and inside the blur backdrop @@ -157,3 +164,54 @@ object DebugOverlayOffscreen { } } } +//?} else { +/*/** + * Minecraft draws the F3 debug overlay into the GUI while the OneConfig screen is open which puts it + * *underneath* the Compose UI and inside the blur backdrop + * + * The vanilla overlay is cancelled in Mixin_DebugOverlayAboveUi, then its overlay and window are stored + * here and replayed into the main target after Skia draws in Mixin_SkiaFrame + */ +object DebugOverlayOffscreen { + private val LOG = LoggerFactory.getLogger("OneConfig/DebugOverlayOffscreen") + private val client get() = Minecraft.getInstance() + + private var deferredOverlay: DebugOverlay? = null + private var deferredWindow: Window? = null + + @Volatile private var capturing = false + @Volatile private var failed = false + + private fun active(): Boolean = + !failed && SkiaCtx.isReady && Platform.screen().current() is ComposeScreen + + /** Called from the debug overlay mixin to hide the vanilla under-UI blurred copy */ + fun shouldSuppressVanilla(overlay: DebugOverlay, window: Window): Boolean { + if (capturing || !active()) return false + deferredOverlay = overlay + deferredWindow = window + return true + } + + fun render() { + val overlay = deferredOverlay ?: return + val window = deferredWindow ?: return + val rt = client.mainRenderTarget + deferredOverlay = null + deferredWindow = null + capturing = true + var bound = false + try { + rt.bindWrite(true) + bound = true + overlay.render(window) + } catch (t: Throwable) { + LOG.warn("Debug overlay replay failed; disabling", t) + failed = true + } finally { + if (bound) rt.unbindWrite() + capturing = false + } + } +} +*///?} diff --git a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/LegacyHudOffscreen.kt b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/LegacyHudOffscreen.kt index ceb98945c..f3003e593 100644 --- a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/LegacyHudOffscreen.kt +++ b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/LegacyHudOffscreen.kt @@ -2,6 +2,7 @@ package org.polyfrost.oneconfig.internal.ui.hud import com.mojang.blaze3d.pipeline.RenderTarget import net.minecraft.client.Minecraft +//? if > 1.8.9 import net.minecraft.client.gui.GuiGraphicsExtractor //? if >= 26.1 { import net.minecraft.client.renderer.state.gui.GuiRenderState @@ -107,7 +108,7 @@ object LegacyHudOffscreen { GuiTargetRedirect.target = null } } - *///?} else { + *///?} elif > 1.8.9 { /*private fun renderImmediateLegacy(rt: RenderTarget) { val graphics = GuiGraphicsExtractor(client, client.renderBuffers().bufferSource()) offscreen.clearTarget() @@ -121,6 +122,16 @@ object LegacyHudOffscreen { client.mainRenderTarget.bindWrite(true) } } + *///?} else { + /*private fun renderImmediateLegacy(rt: RenderTarget) { + offscreen.clearTarget() + rt.bindWrite(true) + try { + LegacyHudRenderer.renderLive() + } finally { + client.mainRenderTarget.bindWrite(true) + } + } *///?} fun drawInto(canvas: org.jetbrains.skia.Canvas) { diff --git a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/LegacyHudRenderer.kt b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/LegacyHudRenderer.kt index 029885d0f..3f17e20c9 100644 --- a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/LegacyHudRenderer.kt +++ b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/hud/LegacyHudRenderer.kt @@ -1,7 +1,10 @@ package org.polyfrost.oneconfig.internal.ui.hud import androidx.compose.runtime.snapshots.Snapshot +//? if > 1.8.9 { import net.minecraft.client.gui.GuiGraphicsExtractor +//?} else +//import net.minecraft.client.render.platform.GlStateManager import org.polyfrost.oneconfig.api.hud.v1.HudManager import org.polyfrost.oneconfig.api.hud.v1.LegacyHud @@ -32,11 +35,15 @@ object LegacyHudRenderer { ) } + //~ if = 1.8.9 '(graphics: GuiGraphicsExtractor)' -> '()' fun renderLive(graphics: GuiGraphicsExtractor) { + //~ if = 1.8.9 'renderLiveHuds(graphics)' -> 'renderLiveHuds()' renderLiveHuds(graphics) + //~ if = 1.8.9 '.render(graphics)' -> '.render()' if (CompatOverlayRenderer.oneConfigScreenOpen()) CompatOverlayRenderer.render(graphics) } + //~ if = 1.8.9 '(graphics: GuiGraphicsExtractor)' -> '()' private fun renderLiveHuds(graphics: GuiGraphicsExtractor) { frame.clear() for (hud in HudManager.activeInstances) { @@ -77,7 +84,7 @@ object LegacyHudRenderer { } finally { pose.popMatrix() } - //? } else { + //? } elif > 1.8.9 { /*val pose = graphics.pose() pose.pushPose() try { @@ -87,7 +94,16 @@ object LegacyHudRenderer { } finally { pose.popPose() } - *///? } + *///?} else { + /*GlStateManager.pushMatrix() + try { + GlStateManager.translatef(hud.x, hud.y, 0f) + if (hudScale != 1f) GlStateManager.scalef(hudScale, hudScale, 1f) + hud.render() + } finally { + GlStateManager.popMatrix() + } + *///?} } catch (e: Throwable) { reportFailure(hud, e) } diff --git a/minecraft/src/main/resources/assets/oneconfig/font/legacy_default.json b/minecraft/src/main/resources/assets/oneconfig/font/legacy_default.json new file mode 100644 index 000000000..7fdf97d48 --- /dev/null +++ b/minecraft/src/main/resources/assets/oneconfig/font/legacy_default.json @@ -0,0 +1,78 @@ +{ + "providers": [ + { + "type": "bitmap", + "file": "minecraft:font/nonlatin_european.png", + "ascent": 7, + "chars": [ + "\u00a1\u2030\u00ad\u00b7\u20b4\u2260\u00bf\u00d7\u00d8\u00de\u00df\u00f0\u00f8\u00fe\u0391\u0392", + "\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3", + "\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba", + "\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9\u0402", + "\u0405\u0406\u0408\u0409\u040a\u040b\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u041a", + "\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a", + "\u042b\u042c\u042d\u042e\u042f\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u043a\u043b", + "\u043c\u043d\u043e\u043f\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b", + "\u044c\u044d\u044e\u044f\u0454\u0455\u0456\u0458\u0459\u045a\u2013\u2014\u2018\u2019\u201c\u201d", + "\u201e\u2026\u204a\u2190\u2191\u2192\u2193\u21c4\uff0b\u018f\u0259\u025b\u026a\u04ae\u04af\u04e8", + "\u04e9\u02bb\u02cc\u037e\u0138\u1e9e\u00df\u20bd\u20ac\u0462\u0463\u0474\u0475\u0406\u0472\u0473", + "\u2070\u00b9\u00b3\u2074\u2075\u2076\u2077\u2078\u2079\u207a\u207b\u207c\u207d\u207e\u2071\u2122", + "\u0294\u0295\u29c8\u2694\u2620\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + ] + }, + { + "type": "bitmap", + "file": "minecraft:font/accented.png", + "height": 12, + "ascent": 10, + "chars": [ + "\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf", + "\u00d0\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u00d9\u00da\u00db\u00dc\u00dd\u00e0\u00e1\u00e2\u00e3", + "\u00e4\u00e5\u00e6\u00e7\u00ec\u00ed\u00ee\u00ef\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u00f9\u00fa", + "\u00fb\u00fc\u00fd\u00ff\u0100\u0101\u0102\u0103\u0104\u0105\u0106\u0107\u0108\u0109\u010a\u010b", + "\u010c\u010d\u010e\u010f\u0110\u0111\u0112\u0113\u0114\u0115\u0116\u0117\u0118\u0119\u011a\u011b", + "\u011c\u011d\u1e20\u1e21\u011e\u011f\u0120\u0121\u0122\u0123\u0124\u0125\u0126\u0127\u0128\u0129", + "\u012a\u012b\u012c\u012d\u012e\u012f\u0130\u0131\u0134\u0135\u0136\u0137\u0139\u013a\u013b\u013c", + "\u013d\u013e\u013f\u0140\u0141\u0142\u0143\u0144\u0145\u0146\u0147\u0148\u014a\u014b\u014c\u014d", + "\u014e\u014f\u0150\u0151\u0152\u0153\u0154\u0155\u0156\u0157\u0158\u0159\u015a\u015b\u015c\u015d", + "\u015e\u015f\u0160\u0161\u0162\u0163\u0164\u0165\u0166\u0167\u0168\u0169\u016a\u016b\u016c\u016d", + "\u016e\u016f\u0170\u0171\u0172\u0173\u0174\u0175\u0176\u0177\u0178\u0179\u017a\u017b\u017c\u017d", + "\u017e\u01fc\u01fd\u01fe\u01ff\u0218\u0219\u021a\u021b\u0386\u0388\u0389\u038a\u038c\u038e\u038f", + "\u0390\u03aa\u03ab\u03ac\u03ad\u03ae\u03af\u03b0\u03ca\u03cb\u03cc\u03cd\u03ce\u0400\u0401\u0403", + "\u0407\u040c\u040d\u040e\u0419\u0439\u0450\u0451\u0452\u0453\u0457\u045b\u045c\u045d\u045e\u045f", + "\u0490\u0491\u1e02\u1e03\u1e0a\u1e0b\u1e1e\u1e1f\u1e22\u1e23\u1e30\u1e31\u1e40\u1e41\u1e56\u1e57", + "\u1e60\u1e61\u1e6a\u1e6b\u1e80\u1e81\u1e82\u1e83\u1e84\u1e85\u1ef2\u1ef3\u00e8\u00e9\u00ea\u00eb", + "\u0149\u01e7\u01eb\u040f\u1e0d\u1e25\u1e5b\u1e6d\u1e92\u1eca\u1ecb\u1ecc\u1ecd\u1ee4\u1ee5\u2116", + "\u0207\u0194\u0263\u0283\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + ] + }, + { + "type": "bitmap", + "file": "minecraft:font/ascii.png", + "ascent": 7, + "chars": [ + "\u00c0\u00c1\u00c2\u00c8\u00ca\u00cb\u00cd\u00d3\u00d4\u00d5\u00da\u00df\u00e3\u00f5\u011f\u0130", + "\u0131\u0152\u0153\u015e\u015f\u0174\u0175\u017e\u0207\u0000\u0000\u0000\u0000\u0000\u0000\u0000", + "\u0020\u0021\"\u0023\u0024\u0025\u0026\u0027\u0028\u0029\u002a\u002b\u002c\u002d\u002e\u002f", + "\u0030\u0031\u0032\u0033\u0034\u0035\u0036\u0037\u0038\u0039\u003a\u003b\u003c\u003d\u003e\u003f", + "\u0040\u0041\u0042\u0043\u0044\u0045\u0046\u0047\u0048\u0049\u004a\u004b\u004c\u004d\u004e\u004f", + "\u0050\u0051\u0052\u0053\u0054\u0055\u0056\u0057\u0058\u0059\u005a\u005b\\\u005d\u005e\u005f", + "\u0060\u0061\u0062\u0063\u0064\u0065\u0066\u0067\u0068\u0069\u006a\u006b\u006c\u006d\u006e\u006f", + "\u0070\u0071\u0072\u0073\u0074\u0075\u0076\u0077\u0078\u0079\u007a\u007b\u007c\u007d\u007e\u0000", + "\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5", + "\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u0192", + "\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb", + "\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510", + "\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567", + "\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580", + "\u03b1\u03b2\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u2205\u2208\u2229", + "\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u0000" + ] + }, + { + "type": "legacy_unicode", + "sizes": "minecraft:font/glyph_sizes.bin", + "template": "minecraft:font/unicode_page_%s.png" + } + ] +} \ No newline at end of file From af30907610374048a485cb6f8675e6e06537f953 Mon Sep 17 00:00:00 2001 From: Saad Nadeem Date: Mon, 22 Jun 2026 01:22:43 -0400 Subject: [PATCH 09/14] feat(legacy): port mixins --- .../internal/OneConfigMixinInit.java | 6 ++-- .../internal/mixin/Mixin_PackRepository.java | 23 ++++++++++++ .../mixin/Mixin_SimpleReloadInstance.java | 4 +++ .../Mixin_FirmamentContentCapture.java | 2 ++ .../firmament/Mixin_FirmamentHudMeta.java | 2 ++ .../skyhanni/Mixin_SkyHanniRenderData.java | 2 ++ .../mixin/events/Mixin_ChatReceiveEvent.java | 35 ++++++++++++++----- .../mixin/events/Mixin_ChatSendEvent.java | 4 +++ .../mixin/events/Mixin_DebugOpenEvent.java | 9 ++++- .../events/Mixin_FramebufferRenderEvent.java | 14 ++++++-- .../mixin/events/Mixin_HudRenderEvent.java | 11 ++++-- .../events/Mixin_InitializationEvent.java | 1 + .../mixin/events/Mixin_KeyInputEvent.java | 28 +++++++++++++-- .../events/Mixin_ModernWindowFocusEvent.java | 30 ++++++++++++++-- .../mixin/events/Mixin_MouseInputEvent.java | 29 ++++++++++++++- .../mixin/events/Mixin_MusicDucking.java | 7 ++++ .../Mixin_PlayerInteractEvent_LeftAction.java | 4 +++ .../events/Mixin_ReceivePacketEvent.java | 1 + .../events/Mixin_RenderLivingEntityEvent.java | 24 +++++++++---- .../mixin/events/Mixin_ResizeEvent.java | 9 +++++ .../events/Mixin_ScreenOpenEvent_Fabric.java | 5 ++- .../mixin/events/Mixin_ServerJoinEvent.java | 4 +++ .../mixin/events/Mixin_WorldUnloadEvent.java | 3 ++ .../Mixin_ControllingComboDisplay.java | 8 +++++ .../mixin/skia/Mixin_DebugOverlayAboveUi.java | 6 ++++ .../internal/mixin/skia/Mixin_InitSkia.java | 1 + .../mixin/skia/Mixin_ScreenshotComposite.java | 2 ++ .../internal/mixin/skia/Mixin_SkiaFrame.java | 22 ++++++++++-- 28 files changed, 262 insertions(+), 34 deletions(-) diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/OneConfigMixinInit.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/OneConfigMixinInit.java index c4c1d2abf..33bb7fc33 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/OneConfigMixinInit.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/OneConfigMixinInit.java @@ -121,9 +121,11 @@ public List getMixins() { //? apec_compat //mixins.add("compat.apec.Mixin_ApecMenu"); + //? if > 1.8.9 { mixins.add("compat.skyhanni.Mixin_SkyHanniRenderData"); mixins.add("compat.firmament.Mixin_FirmamentHudMeta"); + //?} // Firmament has no stable release for 26.2 yet //? >= 1.21.8 && < 26.2 //mixins.add("compat.firmament.Mixin_FirmamentContentCapture"); @@ -156,7 +158,7 @@ public List getMixins() { //? if < 1.21.8 //mixins.add("skia.Mixin_MainTargetRedirect"); mixins.add("skia.Mixin_DebugOverlayAboveUi"); - //? < 26.1 { + //? if < 26.1 && > 1.8.9 { /*mixins.add("skia.Mixin_ScreenshotComposite"); *///? } mixins.add("skia.Mixin_InitSkiaFontRenderer"); @@ -164,7 +166,7 @@ public List getMixins() { //? if >= 1.21.10 { mixins.add("keybind.Mixin_KeybindCategoryLabel"); - //?} else + //?} elif > 1.8.9 //mixins.add("keybind.KeyMappingCategoryAccessor"); mixins.add("keybind.Mixin_OneConfigKeybindRebind"); diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/Mixin_PackRepository.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/Mixin_PackRepository.java index 2c1d7daf9..454c5ba0f 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/Mixin_PackRepository.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/Mixin_PackRepository.java @@ -26,8 +26,13 @@ package org.polyfrost.oneconfig.internal.mixin; +//? if > 1.8.9 { import net.minecraft.client.resources.ClientPackSource; import net.minecraft.server.packs.repository.PackRepository; +//?} else { +/*import net.ornithemc.osl.resource.loader.api.resource.ResourceType; +import net.ornithemc.osl.resource.loader.impl.resource.repository.SimpleResourcePackRepository; +*///?} import net.minecraft.server.packs.repository.RepositorySource; import org.polyfrost.oneconfig.internal.ui.sound.OneConfigSoundPackSource; import org.spongepowered.asm.mixin.Final; @@ -38,16 +43,26 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +//? if > 1.8.9 import java.util.LinkedHashSet; import java.util.Set; +//~ if = 1.8.9 'PackRepository' -> 'SimpleResourcePackRepository' @Mixin(PackRepository.class) public abstract class Mixin_PackRepository { @Mutable @Shadow @Final + //~ if = 1.8.9 'RepositorySource' -> 'ResourcePackRepository.Source' private Set sources; + //? if = 1.8.9 { + /*@Shadow + @Final + private ResourceType type; + *///?} + + //? if > 1.8.9 { @Inject(method = "", at = @At("TAIL")) private void oneconfig$addSoundPack(RepositorySource[] sources, CallbackInfo ci) { boolean isClientResources = false; @@ -63,4 +78,12 @@ public abstract class Mixin_PackRepository { combined.add(OneConfigSoundPackSource.INSTANCE); this.sources = combined; } + //?} else { + /*@Inject(method = "init", at = @At("TAIL")) + private void oneconfig$addSoundPack(CallbackInfo ci) { + if (this.type != ResourceType.CLIENT_ASSETS) return; + + this.sources.add(OneConfigSoundPackSource.INSTANCE); + } + *///?} } diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/Mixin_SimpleReloadInstance.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/Mixin_SimpleReloadInstance.java index b268e1e45..b1249c529 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/Mixin_SimpleReloadInstance.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/Mixin_SimpleReloadInstance.java @@ -9,11 +9,15 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +//~ if = 1.8.9 'SimpleReloadInstance' -> 'SimpleReloadableResourceManager' @Mixin(SimpleReloadInstance.class) public class Mixin_SimpleReloadInstance { + //~ if = 1.8.9 'create' -> 'startReload' @Inject(method = "create", at = @At("RETURN")) + //~ if = 1.8.9 'ReloadInstance' -> 'ResourceReload' private static void oneconfig$onResourceFinishedLoading(CallbackInfoReturnable cir) { + //~ if = 1.8.9 'done()' -> 'result()' cir.getReturnValue().done().whenComplete((result, throwable) -> { EventManager.INSTANCE.post(ResourceFinishedLoading.INSTANCE); }); diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/compat/firmament/Mixin_FirmamentContentCapture.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/compat/firmament/Mixin_FirmamentContentCapture.java index f0d8e6b4b..7a5d54998 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/compat/firmament/Mixin_FirmamentContentCapture.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/compat/firmament/Mixin_FirmamentContentCapture.java @@ -1,5 +1,6 @@ package org.polyfrost.oneconfig.internal.mixin.compat.firmament; +//? if > 1.8.9 { //~ gui_graphics import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphicsExtractor; @@ -68,3 +69,4 @@ public class Mixin_FirmamentContentCapture { } //? } } +//?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/compat/firmament/Mixin_FirmamentHudMeta.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/compat/firmament/Mixin_FirmamentHudMeta.java index f8ef1aaa1..0e8a850dc 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/compat/firmament/Mixin_FirmamentHudMeta.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/compat/firmament/Mixin_FirmamentHudMeta.java @@ -1,5 +1,6 @@ package org.polyfrost.oneconfig.internal.mixin.compat.firmament; +//? if > 1.8.9 { import org.polyfrost.oneconfig.internal.compat.FirmamentHudCompat; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Pseudo; @@ -16,3 +17,4 @@ public class Mixin_FirmamentHudMeta { FirmamentHudCompat.noteHudRendered(this); } } +//?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/compat/skyhanni/Mixin_SkyHanniRenderData.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/compat/skyhanni/Mixin_SkyHanniRenderData.java index 0469918a2..c40c0ce70 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/compat/skyhanni/Mixin_SkyHanniRenderData.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/compat/skyhanni/Mixin_SkyHanniRenderData.java @@ -1,5 +1,6 @@ package org.polyfrost.oneconfig.internal.mixin.compat.skyhanni; +//? if > 1.8.9 { import org.polyfrost.oneconfig.internal.compat.SkyHanniHudCompat; import org.polyfrost.oneconfig.internal.ui.hud.CompatOverlayRenderer; import org.spongepowered.asm.mixin.Mixin; @@ -20,3 +21,4 @@ public class Mixin_SkyHanniRenderData { } } } +//?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ChatReceiveEvent.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ChatReceiveEvent.java index 22d20786d..ccd264811 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ChatReceiveEvent.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ChatReceiveEvent.java @@ -8,12 +8,17 @@ //? if >= 26.1 { import net.minecraft.client.multiplayer.chat.GuiMessageSource; import net.minecraft.client.multiplayer.chat.GuiMessageTag; -//?} else { +//?} elif > 1.8.9 { /*import net.minecraft.client.GuiMessageTag; *///?} +//? if > 1.8.9 { import net.minecraft.client.gui.components.ChatComponent; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MessageSignature; +//?} else { +/*import net.minecraft.client.gui.chat.ChatGui; +import net.minecraft.text.Text; +*///?} import org.polyfrost.oneconfig.api.event.v1.EventManager; import org.polyfrost.oneconfig.api.event.v1.events.ChatEvent; import org.spongepowered.asm.mixin.Mixin; @@ -23,26 +28,30 @@ import org.spongepowered.asm.mixin.injection.ModifyVariable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +//~ if = 1.8.9 'ChatComponent' -> 'ChatGui' @Mixin(ChatComponent.class) public abstract class Mixin_ChatReceiveEvent { @Unique private ChatEvent.Receive ocfg$chatEvent; + //~ if = 1.8.9 'Component' -> 'Text' @Unique private Component ocfg$nativeMessage; @Unique private net.kyori.adventure.text.Component ocfg$postedMessage; @Inject( //? if >= 26.1 { method = "addMessage(Lnet/minecraft/network/chat/Component;Lnet/minecraft/network/chat/MessageSignature;Lnet/minecraft/client/multiplayer/chat/GuiMessageSource;Lnet/minecraft/client/multiplayer/chat/GuiMessageTag;)V", - //?} else { + //?} elif > 1.8.9 { /*method = "addMessage(Lnet/minecraft/network/chat/Component;Lnet/minecraft/network/chat/MessageSignature;Lnet/minecraft/client/GuiMessageTag;)V", - *///?} + *///?} else + //method = "addMessage(Lnet/minecraft/text/Text;I)V", at = @At("HEAD"), cancellable = true ) //? if >= 26.1 { public void chatReceiveCallback(Component message, MessageSignature signature, GuiMessageSource source, GuiMessageTag tag, CallbackInfo ci) { - //?} else { + //?} elif > 1.8.9 { /*public void chatReceiveCallback(Component message, MessageSignature signature, GuiMessageTag tag, CallbackInfo ci) { - *///?} + *///?} else + //private void chatReceiveCallback(Text message, int id, CallbackInfo ci) { if (ocfg$post(message)) { ci.cancel(); } @@ -51,18 +60,21 @@ public void chatReceiveCallback(Component message, MessageSignature signature, G @ModifyVariable( //? if >= 26.1 { method = "addMessage(Lnet/minecraft/network/chat/Component;Lnet/minecraft/network/chat/MessageSignature;Lnet/minecraft/client/multiplayer/chat/GuiMessageSource;Lnet/minecraft/client/multiplayer/chat/GuiMessageTag;)V", - //?} else { + //?} elif > 1.8.9 { /*method = "addMessage(Lnet/minecraft/network/chat/Component;Lnet/minecraft/network/chat/MessageSignature;Lnet/minecraft/client/GuiMessageTag;)V", - *///?} + *///?} else + //method = "addMessage(Lnet/minecraft/text/Text;I)V", at = @At("HEAD"), ordinal = 0, argsOnly = true ) + //~ if = 1.8.9 'Component' -> 'Text' public Component modifyMessage(Component message) { return ocfg$consume(message); } @Unique + //~ if = 1.8.9 'Component' -> 'Text' private boolean ocfg$post(Component message) { ocfg$chatEvent = null; ocfg$nativeMessage = message; @@ -90,9 +102,11 @@ public Component modifyMessage(Component message) { * pick up a stale event if the two HEAD injectors apply in the opposite order */ @Unique + //~ if = 1.8.9 'Component' -> 'Text' private Component ocfg$consume(Component message) { ChatEvent.Receive event = ocfg$chatEvent; net.kyori.adventure.text.Component posted = ocfg$postedMessage; + //~ if = 1.8.9 'Component' -> 'Text' Component original = ocfg$nativeMessage; ocfg$chatEvent = null; ocfg$postedMessage = null; @@ -115,15 +129,18 @@ public Component modifyMessage(Component message) { } @Unique + //~ if = 1.8.9 'Component component' -> 'Text text' private static net.kyori.adventure.text.Component ocfg$toAdventure(Component component) { //? if >=1.21.4 { return MinecraftClientAudiences.of().asAdventure(component); - //?} else { + //?} elif > 1.8.9 { /*return component.asComponent(); - *///?} + *///?} else + //return FabricClientAudiences.of().asAdventure(text); } @Unique + //~ if = 1.8.9 'static Component' -> 'static Text' private static Component ocfg$toNative(net.kyori.adventure.text.Component component) { //? if >=1.21.4 { return MinecraftClientAudiences.of().asNative(component); diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ChatSendEvent.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ChatSendEvent.java index 6e534d9da..e210c0671 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ChatSendEvent.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ChatSendEvent.java @@ -1,6 +1,9 @@ package org.polyfrost.oneconfig.internal.mixin.events; +//? if > 1.8.9 { import net.minecraft.client.multiplayer.ClientPacketListener; +//?} else +//import net.minecraft.client.player.LocalPlayer; import org.polyfrost.oneconfig.api.event.v1.EventManager; import org.polyfrost.oneconfig.api.event.v1.events.ChatEvent; import org.spongepowered.asm.mixin.Mixin; @@ -10,6 +13,7 @@ import org.spongepowered.asm.mixin.injection.ModifyVariable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +//~ if = 1.8.9 'ClientPacketListener' -> 'LocalPlayer' @Mixin(ClientPacketListener.class) public abstract class Mixin_ChatSendEvent { @Unique private ChatEvent.Send ocfg$chatEvent; diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_DebugOpenEvent.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_DebugOpenEvent.java index ee3b53e75..cc63333ea 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_DebugOpenEvent.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_DebugOpenEvent.java @@ -1,11 +1,14 @@ package org.polyfrost.oneconfig.internal.mixin.events; import net.minecraft.client.Minecraft; +//? if > 1.8.9 { //? < 1.21.10 { /*import net.minecraft.client.gui.components.DebugScreenOverlay; *///? } else { import net.minecraft.client.gui.components.debug.DebugScreenEntryList; //? } +//?} else +//import org.objectweb.asm.Opcodes; import org.polyfrost.oneconfig.api.event.v1.EventManager; import org.polyfrost.oneconfig.api.event.v1.events.HudEvent; import org.spongepowered.asm.mixin.Mixin; @@ -14,9 +17,13 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; //? < 1.21.10 { -/*@Mixin(DebugScreenOverlay.class) +/*//~ if = 1.8.9 'DebugScreenOverlay' -> 'Minecraft' +@Mixin(DebugScreenOverlay.class) public abstract class Mixin_DebugOpenEvent { + //? if > 1.8.9 { @Inject(method = "toggleOverlay", at = @At("TAIL")) + //?} else + //@Inject(method = "tick", at = @At(value = "FIELD", target = "Lnet/minecraft/client/Options;debugEnabled:Z", opcode = Opcodes.PUTFIELD, shift = At.Shift.AFTER)) private void onDebugOpen(CallbackInfo ci) { if (Minecraft.getInstance().getDebugOverlay().showDebugScreen()) { EventManager.INSTANCE.post(HudEvent.Debug.OPENED); diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_FramebufferRenderEvent.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_FramebufferRenderEvent.java index 91c123594..bf0461046 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_FramebufferRenderEvent.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_FramebufferRenderEvent.java @@ -11,31 +11,41 @@ @Mixin(Minecraft.class) public class Mixin_FramebufferRenderEvent { + //? if > 1.8.9 { //~ if >= 26.1 'runTick' -> 'renderFrame' @Inject(method = "renderFrame", at = @At(value = "INVOKE", + //?} else + //@Inject(method = "updateDisplay", at = @At(value = "INVOKE", //? if >= 26.2 { target = "Lcom/mojang/blaze3d/systems/GpuSurface;present()V" //?} elif 26.1 { /*target = "Lcom/mojang/blaze3d/systems/RenderSystem;flipFrame(Lcom/mojang/blaze3d/TracyFrameCapture;)V" *///?} elif >= 1.21.4 { /*target = "Lcom/mojang/blaze3d/platform/Window;updateDisplay(Lcom/mojang/blaze3d/TracyFrameCapture;)V" + *///?} elif > 1.8.9 { + /*target = "Lcom/mojang/blaze3d/platform/Window;updateDisplay()V" *///?} else - //target = "Lcom/mojang/blaze3d/platform/Window;updateDisplay()V" + //target = "Lorg/lwjgl/opengl/Display;update()V" )) private void preFramebufferRenderCallback(CallbackInfo ci) { EventManager.INSTANCE.post(FramebufferRenderEvent.Start.INSTANCE); } + //? if > 1.8.9 { //~ if >= 26.1 'runTick' -> 'renderFrame' @Inject(method = "renderFrame", at = @At(value = "INVOKE", + //?} else + //@Inject(method = "updateDisplay", at = @At(value = "INVOKE", //? if >= 26.2 { target = "Lcom/mojang/blaze3d/systems/GpuSurface;present()V", //?} elif 26.1 { /*target = "Lcom/mojang/blaze3d/systems/RenderSystem;flipFrame(Lcom/mojang/blaze3d/TracyFrameCapture;)V", *///?} elif >= 1.21.4 { /*target = "Lcom/mojang/blaze3d/platform/Window;updateDisplay(Lcom/mojang/blaze3d/TracyFrameCapture;)V", + *///?} elif > 1.8.9 { + /*target = "Lcom/mojang/blaze3d/platform/Window;updateDisplay()V", *///?} else - //target = "Lcom/mojang/blaze3d/platform/Window;updateDisplay()V", + //target = "Lorg/lwjgl/opengl/Display;update()V", shift = At.Shift.AFTER )) private void postFramebufferRenderCallback(CallbackInfo ci) { diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_HudRenderEvent.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_HudRenderEvent.java index e98773648..e9ba0efd7 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_HudRenderEvent.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_HudRenderEvent.java @@ -1,6 +1,7 @@ package org.polyfrost.oneconfig.internal.mixin.events; //~ gui_graphics +//? if > 1.8.9 { import net.minecraft.client.DeltaTracker; //? >= 26.2 { import net.minecraft.client.gui.Hud; @@ -8,6 +9,8 @@ /*import net.minecraft.client.gui.Gui; *///? } import net.minecraft.client.gui.GuiGraphicsExtractor; +//?} else +//import net.minecraft.client.gui.GameGui; import org.polyfrost.oneconfig.internal.OneConfig; import org.polyfrost.oneconfig.internal.ui.compose.SkiaCtx; import org.spongepowered.asm.mixin.Mixin; @@ -17,17 +20,21 @@ //? if >= 26.2 { @Mixin(Hud.class) -//? } else { +//?} elif > 1.8.9 { /*@Mixin(Gui.class) -*///? } +*///?} else +//@Mixin(GameGui.class) public class Mixin_HudRenderEvent { //~ if >= 26.1 'render' -> 'extractRenderState' @Inject(method = "extractRenderState", at = @At("TAIL")) + //~ if = 1.8.9 '(GuiGraphicsExtractor ctx, DeltaTracker deltaTracker' -> '(float partialTicks' private void renderHudCallback(GuiGraphicsExtractor ctx, DeltaTracker deltaTracker, CallbackInfo ci) { + //~ if = 1.8.9 '(ctx, deltaTracker.getRealtimeDeltaTicks())' -> '(partialTicks)' OneConfig.render(ctx, deltaTracker.getRealtimeDeltaTicks()); //~ if < 1.21.8 '.suppressInGameHudRender' -> '.shouldSuppressInGameHudRender()' if (!SkiaCtx.INSTANCE.suppressInGameHudRender) { + //~ if = 1.8.9 '(ctx)' -> '()' SkiaCtx.INSTANCE.blitHud(ctx); } } diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_InitializationEvent.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_InitializationEvent.java index 271f2d270..925e31d17 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_InitializationEvent.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_InitializationEvent.java @@ -11,6 +11,7 @@ @Mixin(Minecraft.class) public class Mixin_InitializationEvent { + //~ if = 1.8.9 '' -> 'init' @Inject(method = "", at = @At("RETURN")) private void completedInit(CallbackInfo ci) { EventManager.INSTANCE.post(InitializationEvent.INSTANCE); diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_KeyInputEvent.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_KeyInputEvent.java index a6cc5d606..ef4a3fdbc 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_KeyInputEvent.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_KeyInputEvent.java @@ -1,6 +1,12 @@ package org.polyfrost.oneconfig.internal.mixin.events; +//? if > 1.8.9 { import net.minecraft.client.KeyboardHandler; +//?} else { +/*import org.lwjgl.input.Keyboard; +import org.polyfrost.oneconfig.internal.legacy.KeyCodes; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +*///?} //? >= 1.21.10 { import net.minecraft.client.input.CharacterEvent; import net.minecraft.client.input.KeyEvent; @@ -15,6 +21,7 @@ import org.spongepowered.asm.mixin.injection.ModifyVariable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +//~ if = 1.8.9 'KeyboardHandler.class' -> 'Keyboard.class' @Mixin(KeyboardHandler.class) public class Mixin_KeyInputEvent { @@ -33,8 +40,7 @@ private void charCallback(long handle, CharacterEvent event, CallbackInfo ci) { EventManager.INSTANCE.post(new KeyInputEvent(0, (char) event.codepoint(), 1)); } - //? } else { - + //?} elif > 1.8.9 { /*@Inject(method = "keyPress", at = @At("HEAD")) private void keyCallback(long window, int key, int scancode, int action, int mods, CallbackInfo ci) { EventManager.INSTANCE.post(new KeyInputEvent(key, (char) 0, action)); @@ -47,5 +53,21 @@ private void charCallback(long window, int codepoint, int mods, CallbackInfo ci) } EventManager.INSTANCE.post(new KeyInputEvent(0, (char) codepoint, 1)); } - *///? } + *///?} else { + /*@Inject(method = "next", at = @At("RETURN"), remap = false) + private static void keyCallback(CallbackInfoReturnable cir) { + if (!cir.getReturnValue()) return; + + int keyCode = Keyboard.getEventKey(); + if (keyCode > 0) { + int action = Keyboard.isRepeatEvent() ? 2 : Keyboard.getEventKeyState() ? 1 : 0; + EventManager.INSTANCE.post(new KeyInputEvent(KeyCodes.fromLegacy(keyCode).getValue(), (char) 0, action)); + } + + char character = Keyboard.getEventCharacter(); + if (character != 0) { + EventManager.INSTANCE.post(new KeyInputEvent(0, character, 1)); + } + } + *///?} } diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ModernWindowFocusEvent.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ModernWindowFocusEvent.java index 7c40e97e3..12fd88a27 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ModernWindowFocusEvent.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ModernWindowFocusEvent.java @@ -34,10 +34,13 @@ import org.polyfrost.oneconfig.api.event.v1.EventManager; import org.polyfrost.oneconfig.api.event.v1.events.WindowFocusEvent; import org.spongepowered.asm.mixin.Mixin; +//? if = 1.8.9 +//import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - +//? if = 1.8.9 +//import org.objectweb.asm.Opcodes; //? if >= 26.1 { @Mixin(Window.class) @@ -48,7 +51,7 @@ private void onGameFocused(long window, boolean focused, CallbackInfo ci) { else EventManager.INSTANCE.post(WindowFocusEvent.Lost.INSTANCE); } } -//? } else { +//?} elif > 1.8.9 { /*@Mixin(Minecraft.class) public class Mixin_ModernWindowFocusEvent { @Inject(method = "setWindowActive", at = @At("HEAD")) @@ -57,4 +60,25 @@ private void onGameFocused(boolean focused, CallbackInfo ci) { else EventManager.INSTANCE.post(WindowFocusEvent.Lost.INSTANCE); } } -*///? } +*///?} else { +/*@Mixin(targets = "org.lwjgl.opengl.SDLDisplay", remap = false) +public class Mixin_ModernWindowFocusEvent { + @Shadow + private boolean focused; + + @Inject( + method = "update", + at = @At( + value = "FIELD", + target = "Lorg/lwjgl/opengl/SDLDisplay;focused:Z", + opcode = Opcodes.PUTFIELD, + shift = At.Shift.AFTER + ), + remap = false + ) + private void oneconfig$onFocusChanged(CallbackInfo ci) { + if (focused) EventManager.INSTANCE.post(WindowFocusEvent.Gained.INSTANCE); + else EventManager.INSTANCE.post(WindowFocusEvent.Lost.INSTANCE); + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_MouseInputEvent.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_MouseInputEvent.java index e19b881c8..6fe12bc22 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_MouseInputEvent.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_MouseInputEvent.java @@ -1,9 +1,15 @@ package org.polyfrost.oneconfig.internal.mixin.events; import net.minecraft.client.Minecraft; +//? if > 1.8.9 { import net.minecraft.client.MouseHandler; //? >= 1.21.10 import net.minecraft.client.input.MouseButtonInfo; +//?} else { +/*import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.Display; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +*///?} import org.polyfrost.oneconfig.api.event.v1.EventManager; import org.polyfrost.oneconfig.api.event.v1.events.MouseInputEvent; import org.spongepowered.asm.mixin.Mixin; @@ -11,7 +17,10 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +//? if > 1.8.9 { @Mixin(MouseHandler.class) +//?} else +//@Mixin(value = Mouse.class, remap = false) public class Mixin_MouseInputEvent { //? >= 1.21.10 { @Inject(method = "onButton", at = @At("HEAD")) @@ -30,7 +39,7 @@ private void mouseMoveCallback(long handle, double x, double y, CallbackInfo ci) } } - //? } else { + //?} elif > 1.8.9 { /*@Inject(method = "onPress", at = @At("HEAD")) private void mouseCallback(long handle, int button, int action, int mods, CallbackInfo ci) { EventManager.INSTANCE.post(new MouseInputEvent(button, action)); @@ -42,5 +51,23 @@ private void mouseMoveCallback(long handle, double x, double y, CallbackInfo ci) MouseInputEvent.Moved.post((float) x, (float) y); } } + *///?} else { + /*@Inject(method = "next", at = @At("RETURN"), remap = false) + private static void mouseCallback(CallbackInfoReturnable cir) { + if (!cir.getReturnValue()) return; + + int button = Mouse.getEventButton(); + if (button >= 0) { + EventManager.INSTANCE.post(new MouseInputEvent(button, Mouse.getEventButtonState() ? 1 : 0)); + return; + } + + if (Mouse.getEventDWheel() != 0 || Minecraft.getInstance().screen == null || Mouse.getEventDX() == 0 && Mouse.getEventDY() == 0) return; + + float scale = Display.getPixelScaleFactor(); + float x = Mouse.getEventX() / scale; + float y = Display.getScreenHeight() - Mouse.getEventY() / scale; + MouseInputEvent.Moved.post(x, y); + } *///? } } diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_MusicDucking.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_MusicDucking.java index 419844e87..f8b46a4b3 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_MusicDucking.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_MusicDucking.java @@ -2,6 +2,10 @@ import net.minecraft.client.sounds.SoundEngine; import net.minecraft.sounds.SoundSource; +//? if = 1.8.9 { +/*import net.minecraft.client.sound.Sound; +import net.minecraft.client.resources.sounds.SoundInstance; +*///?} import org.polyfrost.oneconfig.internal.ui.sound.UiSoundDucking; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -10,8 +14,11 @@ @Mixin(SoundEngine.class) public class Mixin_MusicDucking { + //~ if = 1.8.9 'calculateVolume(FLnet/minecraft/sounds/SoundSource;)F' -> 'getVolume(Lnet/minecraft/client/sound/instance/SoundInstance;Lnet/minecraft/client/sound/Sound;Lnet/minecraft/client/sound/SoundCategory;)F' @Inject(method = "calculateVolume(FLnet/minecraft/sounds/SoundSource;)F", at = @At("RETURN"), cancellable = true) + //~ if = 1.8.9 '(float volume, SoundSource source' -> '(SoundInstance instance, Sound sound, SoundCategory source' private void oneconfig$duckMusic(float volume, SoundSource source, CallbackInfoReturnable cir) { + //~ if = 1.8.9 'SoundSource.MUSIC' -> 'SoundCategory.MUSIC' if (source != SoundSource.MUSIC) return; float multiplier = UiSoundDucking.musicVolumeMultiplier(); if (multiplier < 1f) { diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_PlayerInteractEvent_LeftAction.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_PlayerInteractEvent_LeftAction.java index a62738e0c..e86fb88a4 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_PlayerInteractEvent_LeftAction.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_PlayerInteractEvent_LeftAction.java @@ -11,6 +11,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +//? if > 1.8.9 import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(Minecraft.class) @@ -22,10 +23,12 @@ public abstract class Mixin_PlayerInteractEvent_LeftAction { @Unique private PlayerInteractEvent ocfg$lastAttackEvent; @Inject( + //~ if = 1.8.9 'startAttack' -> 'doAttack' method = "startAttack", at = @At("HEAD"), cancellable = true ) + //~ if = 1.8.9 'CallbackInfoReturnable cir' -> 'CallbackInfo ci' private void onPlayerAttackCallback(CallbackInfoReturnable cir) { HitResult rayCastedObject = this.hitResult; PlayerInteractEvent.Type type = PlayerInteractEvent.Type.AIR; @@ -45,6 +48,7 @@ private void onPlayerAttackCallback(CallbackInfoReturnable cir) { ocfg$lastAttackEvent = new PlayerInteractEvent(this.player, PlayerInteractEvent.Action.LEFT, type); EventManager.INSTANCE.post(ocfg$lastAttackEvent); if (ocfg$lastAttackEvent.cancelled) { + //$ if > 1.8.9 'cir.cancel();' else 'ci.cancel();' cir.cancel(); } } diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ReceivePacketEvent.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ReceivePacketEvent.java index 3e9f22fed..f278b4cf4 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ReceivePacketEvent.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ReceivePacketEvent.java @@ -13,6 +13,7 @@ @Mixin(Connection.class) public class Mixin_ReceivePacketEvent { + //~ if = 1.8.9 'protocol/Packet' -> 'packet/Packet' @Inject(method = "channelRead0(Lio/netty/channel/ChannelHandlerContext;Lnet/minecraft/network/protocol/Packet;)V", at = @At("HEAD"), cancellable = true) private void packetReceiveCallback(ChannelHandlerContext ctx, Packet packet, CallbackInfo ci) { PacketEvent.Receive event = new PacketEvent.Receive(packet); diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_RenderLivingEntityEvent.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_RenderLivingEntityEvent.java index 9eab52b80..47886d0cf 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_RenderLivingEntityEvent.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_RenderLivingEntityEvent.java @@ -1,9 +1,11 @@ package org.polyfrost.oneconfig.internal.mixin.events; +//? if > 1.8.9 { import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.Minecraft; //? if < 1.21.9 //import net.minecraft.client.renderer.MultiBufferSource; +//?} import net.minecraft.client.renderer.entity.LivingEntityRenderer; //? if < 1.21.2 //import net.minecraft.world.entity.LivingEntity; @@ -30,8 +32,10 @@ public class Mixin_RenderLivingEntityEvent { method = "submit(Lnet/minecraft/client/renderer/entity/state/LivingEntityRenderState;Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/SubmitNodeCollector;Lnet/minecraft/client/renderer/state/level/CameraRenderState;)V", //? } >= 1.21.2 { /*method = "render(Lnet/minecraft/client/renderer/entity/state/LivingEntityRenderState;Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;I)V", - *///? } else - //method = "render(Lnet/minecraft/world/entity/LivingEntity;FFLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;I)V", + *///?} elif > 1.8.9 { + /*method = "render(Lnet/minecraft/world/entity/LivingEntity;FFLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;I)V", + *///?} else + //method = "render(Lnet/minecraft/entity/living/LivingEntity;DDDFF)V", at = @At("HEAD"), cancellable = true ) @@ -39,8 +43,10 @@ public class Mixin_RenderLivingEntityEvent { private void onPreEntityRenderCallback(LivingEntityRenderState entity, PoseStack matrixStack, SubmitNodeCollector renderQueue, CameraRenderState cameraState, CallbackInfo ci) { //?} elif >= 1.21.2 { /*private void onPreEntityRenderCallback(LivingEntityRenderState entity, PoseStack matrixStack, MultiBufferSource buffer, int packedLight, CallbackInfo ci) { - *///?} else { + *///?} elif > 1.8.9 { /*private void onPreEntityRenderCallback(LivingEntity entity, float entityYaw, float partialTicks, PoseStack matrixStack, MultiBufferSource buffer, int packedLight, CallbackInfo ci) { + *///?} else { + /*private void onPreEntityRenderCallback(LivingEntity entity, double x, double y, double z, float yaw, float partialTicks, CallbackInfo ci) { *///?} //? >= 1.21.2 { @@ -48,7 +54,7 @@ private void onPreEntityRenderCallback(LivingEntityRenderState entity, PoseStack double y = entity.y; double z = entity.z; float partialTicks = Minecraft.getInstance().getFrameTimeNs(); - //? } else { + //?} elif > 1.8.9 { /*double x = entity.getX(); double y = entity.getY(); double z = entity.getZ(); @@ -66,23 +72,27 @@ private void onPreEntityRenderCallback(LivingEntityRenderState entity, PoseStack method = "submit(Lnet/minecraft/client/renderer/entity/state/LivingEntityRenderState;Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/SubmitNodeCollector;Lnet/minecraft/client/renderer/state/level/CameraRenderState;)V", //? } >= 1.21.2 { /*method = "render(Lnet/minecraft/client/renderer/entity/state/LivingEntityRenderState;Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;I)V", + *///?} elif > 1.8.9 { + /*method = "render(Lnet/minecraft/world/entity/LivingEntity;FFLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;I)V", *///?} else - //method = "render(Lnet/minecraft/world/entity/LivingEntity;FFLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;I)V", + //method = "render(Lnet/minecraft/entity/living/LivingEntity;DDDFF)V", at = @At("TAIL") ) //? if >= 1.21.9 { private void onPostEntityRenderCallback(LivingEntityRenderState entity, PoseStack matrixStack, SubmitNodeCollector renderQueue, CameraRenderState cameraState, CallbackInfo ci) { //?} elif >= 1.21.2 { /*private void onPostEntityRenderCallback(LivingEntityRenderState entity, PoseStack matrixStack, MultiBufferSource buffer, int packedLight, CallbackInfo ci) { - *///?} else { + *///?} elif > 1.8.9 { /*private void onPostEntityRenderCallback(LivingEntity entity, float entityYaw, float partialTicks, PoseStack matrixStack, MultiBufferSource buffer, int packedLight, CallbackInfo ci) { + *///?} else { + /*private void onPostEntityRenderCallback(LivingEntity entity, double x, double y, double z, float yaw, float partialTicks, CallbackInfo ci) { *///?} //? >= 1.21.2 { double x = entity.x; double y = entity.y; double z = entity.z; float partialTicks = Minecraft.getInstance().getFrameTimeNs(); - //? } else { + //? } elif > 1.8.9 { /*double x = entity.getX(); double y = entity.getY(); double z = entity.getZ(); diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ResizeEvent.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ResizeEvent.java index c525332e3..1f808dfec 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ResizeEvent.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ResizeEvent.java @@ -1,7 +1,9 @@ package org.polyfrost.oneconfig.internal.mixin.events; +//? if > 1.8.9 { import org.polyfrost.oneconfig.api.platform.v1.Platform; import org.spongepowered.asm.mixin.Shadow; +//?} import net.minecraft.client.Minecraft; import org.polyfrost.oneconfig.api.event.v1.EventManager; import org.polyfrost.oneconfig.api.event.v1.events.ResizeEvent; @@ -13,6 +15,7 @@ @Mixin(Minecraft.class) public abstract class Mixin_ResizeEvent { + //? if > 1.8.9 { @Shadow public abstract com.mojang.blaze3d.platform.Window getWindow(); //~ if >= 26.1 'resizeDisplay' -> 'resizeGui' @@ -23,5 +26,11 @@ private void resizeCallback(CallbackInfo ci) { org.lwjgl.glfw.GLFW.glfwGetWindowSize(Platform.compatibility().windowHandle(), w, h); EventManager.INSTANCE.post(new ResizeEvent(w[0], h[0])); } + //?} else { + /*@Inject(method = "resize", at = @At("TAIL")) + private void resizeCallback(int width, int height, CallbackInfo ci) { + EventManager.INSTANCE.post(new ResizeEvent(width, height)); + } + *///?} } diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ScreenOpenEvent_Fabric.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ScreenOpenEvent_Fabric.java index c28ab45e5..a31b94a06 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ScreenOpenEvent_Fabric.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ScreenOpenEvent_Fabric.java @@ -1,6 +1,6 @@ package org.polyfrost.oneconfig.internal.mixin.events; -//? fabric { +//? fabric || ornithe { import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.Screen; import org.polyfrost.oneconfig.api.event.v1.EventManager; @@ -12,8 +12,11 @@ @Mixin(Minecraft.class) public class Mixin_ScreenOpenEvent_Fabric { + //? if > 1.8.9 { //~ if >= 26.2 'setScreen' -> 'setScreenAndShow' @Inject(method = "setScreenAndShow", at = @At("HEAD"), cancellable = true) + //?} else + //@Inject(method = "setScreen", at = @At("HEAD"), cancellable = true) private void screenOpenCallback(Screen screen, CallbackInfo ci) { ScreenOpenEvent event = new ScreenOpenEvent(screen); EventManager.INSTANCE.post(event); diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ServerJoinEvent.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ServerJoinEvent.java index dbeefbc00..7c0a74fa9 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ServerJoinEvent.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ServerJoinEvent.java @@ -1,6 +1,9 @@ package org.polyfrost.oneconfig.internal.mixin.events; +//? if > 1.8.9 { import net.minecraft.client.multiplayer.ClientPacketListener; +//?} else +//import net.minecraft.client.network.handler.ClientPlayNetworkHandler; import org.polyfrost.oneconfig.api.event.v1.EventManager; import org.polyfrost.oneconfig.api.event.v1.events.ServerJoinEvent; import org.spongepowered.asm.mixin.Mixin; @@ -8,6 +11,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +//~ if = 1.8.9 'ClientPacketListener' -> 'ClientPlayNetworkHandler' @Mixin(ClientPacketListener.class) public class Mixin_ServerJoinEvent { diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_WorldUnloadEvent.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_WorldUnloadEvent.java index 96ad215e3..2ac88cebc 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_WorldUnloadEvent.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_WorldUnloadEvent.java @@ -43,12 +43,14 @@ public class Mixin_WorldUnloadEvent { @Shadow public ClientLevel level; @Inject( + //~ if = 1.8.9 'setLevel' -> 'setWorld(Lnet/minecraft/client/multiplayer/ClientLevel;Ljava/lang/String;)V' method = "setLevel" , at = @At("HEAD")) private void onWorldUnloadCallback(CallbackInfo ci) { oneconfig$postWorldUnload(); } + //? if > 1.8.9 { //? if >= 1.21.11 { @Inject( method = "disconnect(Lnet/minecraft/client/gui/screens/Screen;ZZ)V" @@ -68,6 +70,7 @@ private void onDisconnectCallback(CallbackInfo ci) { private void onClearClientLevelCallback(CallbackInfo ci) { oneconfig$postWorldUnload(); } + //?} @Unique private void oneconfig$postWorldUnload() { diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/Mixin_ControllingComboDisplay.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/Mixin_ControllingComboDisplay.java index 1ae92c623..f99b1fc52 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/Mixin_ControllingComboDisplay.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/Mixin_ControllingComboDisplay.java @@ -1,5 +1,6 @@ package org.polyfrost.oneconfig.internal.mixin.keybind; +//? if > 1.8.9 { import net.minecraft.client.KeyMapping; import net.minecraft.client.gui.components.Button; import net.minecraft.network.chat.Component; @@ -38,3 +39,10 @@ public class Mixin_ControllingComboDisplay { if (combo != null && !combo.equals(btnChangeKeyBinding.getMessage())) btnChangeKeyBinding.setMessage(combo); } } +//?} else { +/*import net.minecraft.SharedConstants; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(SharedConstants.class) +public class Mixin_ControllingComboDisplay {} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/skia/Mixin_DebugOverlayAboveUi.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/skia/Mixin_DebugOverlayAboveUi.java index bbf5eaa42..1b77531cd 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/skia/Mixin_DebugOverlayAboveUi.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/skia/Mixin_DebugOverlayAboveUi.java @@ -1,7 +1,10 @@ package org.polyfrost.oneconfig.internal.mixin.skia; //~ gui_graphics +//? if > 1.8.9 { import net.minecraft.client.gui.GuiGraphicsExtractor; +//?} else +//import net.minecraft.client.render.Window; import net.minecraft.client.gui.components.DebugScreenOverlay; import org.polyfrost.oneconfig.internal.ui.hud.DebugOverlayOffscreen; import org.spongepowered.asm.mixin.Mixin; @@ -9,11 +12,14 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +//~ if = 1.8.9 'DebugScreenOverlay' -> 'DebugOverlay' @Mixin(DebugScreenOverlay.class) public class Mixin_DebugOverlayAboveUi { //~ if >= 26.1 'render' -> 'extractRenderState' @Inject(method = "extractRenderState", at = @At("HEAD"), cancellable = true) + //~ if = 1.8.9 'GuiGraphicsExtractor ctx' -> 'Window window' private void oneconfig$deferDebugOverlay(GuiGraphicsExtractor ctx, CallbackInfo ci) { + //~ if = 1.8.9 'shouldSuppressVanilla()' -> 'shouldSuppressVanilla((DebugOverlay) (Object) this, window)' if (DebugOverlayOffscreen.INSTANCE.shouldSuppressVanilla()) { ci.cancel(); } diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/skia/Mixin_InitSkia.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/skia/Mixin_InitSkia.java index 095c99d9a..7a97ab30e 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/skia/Mixin_InitSkia.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/skia/Mixin_InitSkia.java @@ -9,6 +9,7 @@ @Mixin(Minecraft.class) public class Mixin_InitSkia { + //~ if = 1.8.9 '' -> 'init' @Inject(method = "", at = @At("TAIL")) void impl$__init__(CallbackInfo ci) { SkiaCtx.INSTANCE.init(); diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/skia/Mixin_ScreenshotComposite.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/skia/Mixin_ScreenshotComposite.java index 65f9e635a..88bbc6d7d 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/skia/Mixin_ScreenshotComposite.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/skia/Mixin_ScreenshotComposite.java @@ -1,5 +1,6 @@ package org.polyfrost.oneconfig.internal.mixin.skia; +//? if > 1.8.9 { import com.mojang.blaze3d.pipeline.RenderTarget; import com.mojang.blaze3d.platform.NativeImage; import net.minecraft.client.Screenshot; @@ -33,3 +34,4 @@ public class Mixin_ScreenshotComposite { } *///? } } +//?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/skia/Mixin_SkiaFrame.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/skia/Mixin_SkiaFrame.java index 770622791..ddf6dd081 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/skia/Mixin_SkiaFrame.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/skia/Mixin_SkiaFrame.java @@ -1,15 +1,22 @@ package org.polyfrost.oneconfig.internal.mixin.skia; +//? if > 1.8.9 { import com.mojang.blaze3d.platform.Window; +import org.spongepowered.asm.mixin.Shadow; +//?} else { +/*import net.minecraft.client.Minecraft; +import org.polyfrost.oneconfig.internal.ui.hud.DebugOverlayOffscreen; +*///?} import org.polyfrost.oneconfig.internal.ui.compose.SkiaCtx; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +//~ if = 1.8.9 'Window' -> 'Minecraft' @Mixin(Window.class) public class Mixin_SkiaFrame { + //? if > 1.8.9 { @Shadow private int framebufferWidth; @@ -20,17 +27,26 @@ public class Mixin_SkiaFrame { void impl$onResize(CallbackInfo ci) { SkiaCtx.INSTANCE.recreateSurface(this.framebufferWidth, this.framebufferHeight); } + //?} else { + /*@Inject(method = "resize", at = @At("TAIL")) + void impl$onResize(int width, int height, CallbackInfo ci) { + SkiaCtx.INSTANCE.recreateSurface(width, height); + } + *///?} //? if < 26.1 { /*//? if >= 1.21.4 { @Inject(method = "updateDisplay(Lcom/mojang/blaze3d/TracyFrameCapture;)V", at = @At("HEAD")) - //?} else { + //?} elif > 1.8.9 { /^@Inject(method = "updateDisplay()V", at = @At("HEAD")) - ^///?} + ^///?} else + //@Inject(method = "runGame", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/pipeline/RenderTarget;draw(II)V")) void impl$onDraw(CallbackInfo ci) { if (!SkiaCtx.INSTANCE.isVulkanMode()) { SkiaCtx.INSTANCE.draw(); } + //? if = 1.8.9 + //DebugOverlayOffscreen.INSTANCE.render(); } *///? } } From 76dc5c816e04502a548b2e7d0ab8ffaabe99bb73 Mon Sep 17 00:00:00 2001 From: Saad Nadeem Date: Thu, 20 Aug 2026 17:55:37 -0400 Subject: [PATCH 10/14] feat(legacy): port oneconfig --- .../oneconfig/internal/OneConfig.java | 13 +++++++- .../internal/ui/PlayerHeadSkinAccess.java | 5 ++- .../internal/ui/PlayerHeadTextureAccess.java | 1 + .../ui/sound/OneConfigSoundPackSource.java | 32 +++++++++++++++++++ .../oneconfig/test/TestLegacyHud_Test.java | 12 +++++++ .../oneconfig/api/hud/v1/LegacyHud.kt | 2 ++ .../internal/compat/FirmamentHudCompat.kt | 2 ++ .../internal/compat/SkyHanniHudCompat.kt | 2 ++ .../internal/ui/sound/ExternalSounds.kt | 3 ++ .../internal/ui/sound/McUiSoundService.kt | 29 +++++++++++++++-- 10 files changed, 96 insertions(+), 5 deletions(-) diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/OneConfig.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/OneConfig.java index 6c3eaa32d..38ede23af 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/OneConfig.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/OneConfig.java @@ -31,10 +31,12 @@ import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; +//? if > 1.8.9 import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.screens.ChatScreen; import net.minecraft.client.gui.screens.TitleScreen; import net.minecraft.network.chat.Component; +//? if > 1.8.9 import net.minecraft.world.scores.DisplaySlot; import net.minecraft.world.scores.Scoreboard; import org.apache.logging.log4j.LogManager; @@ -75,7 +77,7 @@ //? neoforge //@net.neoforged.fml.common.Mod("oneconfigv1") public class OneConfig - //? fabric + //? fabric || ornithe implements net.fabricmc.api.ClientModInitializer { public static final OneConfig INSTANCE = new OneConfig(); private static final Logger LOGGER = LogManager.getLogger("OneConfig"); @@ -154,11 +156,16 @@ private static boolean isTabListVisible() { if (!minecraft.isLocalServer()) return true; Scoreboard scoreboard = minecraft.level.getScoreboard(); + //~ if = 1.8.9 'player.connection.getListedOnlinePlayers' -> 'getNetworkHandler().getOnlinePlayers' return minecraft.player.connection.getListedOnlinePlayers().size() > 1 + //~ if = 1.8.9 'DisplaySlot.LIST' -> '0' || scoreboard.getDisplayObjective(DisplaySlot.LIST) != null; } + //? if > 1.8.9 { public static void render(GuiGraphicsExtractor graphics, float partial) { + //?} else + //public static void render(float partial) { if (!SkiaCtx.INSTANCE.isReady()) { return; } @@ -185,10 +192,13 @@ public static void render(GuiGraphicsExtractor graphics, float partial) { //~ if < 1.21.8 '.suppressInGameHudRender' -> '.shouldSuppressInGameHudRender()' boolean hudRendersLive = !SkiaCtx.INSTANCE.suppressInGameHudRender; if (hudRendersLive || !org.polyfrost.oneconfig.internal.ui.hud.LegacyHudOffscreen.INSTANCE.render()) { + //~ if = 1.8.9 '(graphics)' -> '()' LegacyHudRenderer.INSTANCE.renderLive(graphics); } // records the F3 overlay offscreen so Skia can put it above the Compose UI instead of below the // blur and it must run every frame regardless of the HUD dirty gate + // 1.8.9 replays the overlay in Mixin_SkiaFrame after Skia finishes drawing instead + //? if > 1.8.9 org.polyfrost.oneconfig.internal.ui.hud.DebugOverlayOffscreen.INSTANCE.render(); if (HudManager.INSTANCE.beginFrame(sw, sh)) { SkiaCtx.INSTANCE.queueHudDraw(() -> { @@ -252,6 +262,7 @@ private static void registerEventHandlers() { MinecraftKeybindProfiles.init(); ConfigRegistry.INSTANCE.loadFrom(ConfigManager.active(), ConfigSource.OC); org.polyfrost.oneconfig.internal.ui.hud.BuiltinHudRegistrar.register(); + //? if > 1.8.9 org.polyfrost.oneconfig.internal.compat.FirmamentHudCompat.register(); //? if wwaypoints_compat org.polyfrost.oneconfig.internal.compat.WWaypointsCompat.register(); diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/ui/PlayerHeadSkinAccess.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/ui/PlayerHeadSkinAccess.java index 3221346d4..5e5362f81 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/ui/PlayerHeadSkinAccess.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/ui/PlayerHeadSkinAccess.java @@ -3,8 +3,11 @@ import com.mojang.authlib.GameProfile; import com.mojang.blaze3d.platform.NativeImage; import net.minecraft.client.Minecraft; +//? if > 1.8.9 { //~if >= 1.21.11 'ResourceLocation;' -> 'Identifier;' import net.minecraft.resources.Identifier; +//?} else +//import net.minecraft.resource.Identifier; import org.jetbrains.annotations.Nullable; import java.util.concurrent.TimeUnit; @@ -67,7 +70,7 @@ public static Supplier localPlayerHeadTask(Minecraft mc) { } } - //~if >= 1.21.11 'ResourceLocation' -> 'Identifier' + //~if >= 1.21.11 || = 1.8.9 'ResourceLocation' -> 'Identifier' private static @Nullable NativeImage extractHead(Minecraft mc, Identifier textureId) { NativeImage pixels = PlayerHeadTextureAccess.readPixels(mc.getTextureManager().getTexture(textureId)); if (pixels == null) { diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/ui/PlayerHeadTextureAccess.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/ui/PlayerHeadTextureAccess.java index 0f964ee10..fa624b34b 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/ui/PlayerHeadTextureAccess.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/ui/PlayerHeadTextureAccess.java @@ -12,6 +12,7 @@ private PlayerHeadTextureAccess() { *

* It must be consumed on the client thread before the calling task returns */ + //~ if = 1.8.9 'AbstractTexture' -> 'Texture' public static NativeImage readPixels(AbstractTexture texture) { if (texture == null) { return null; diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/ui/sound/OneConfigSoundPackSource.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/ui/sound/OneConfigSoundPackSource.java index d3e9ce4d0..d8055e466 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/ui/sound/OneConfigSoundPackSource.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/ui/sound/OneConfigSoundPackSource.java @@ -26,6 +26,7 @@ package org.polyfrost.oneconfig.internal.ui.sound; +//? if > 1.8.9 { import net.minecraft.network.chat.Component; import net.minecraft.server.packs.PackLocationInfo; import net.minecraft.server.packs.PackSelectionConfig; @@ -34,6 +35,12 @@ import net.minecraft.server.packs.repository.Pack; import net.minecraft.server.packs.repository.PackSource; import net.minecraft.server.packs.repository.RepositorySource; +//?} else { +/*import net.minecraft.server.packs.repository.RepositorySource; +import net.ornithemc.osl.resource.loader.api.resource.pack.PackPosition; +import net.ornithemc.osl.resource.loader.api.resource.repository.ResourcePackSummary; +import net.ornithemc.osl.resource.loader.impl.resource.pack.DirectoryResourcePack; +*///?} import java.nio.file.Files; import java.nio.file.Path; @@ -41,6 +48,7 @@ import java.util.Optional; import java.util.function.Consumer; +//~ if = 1.8.9 'RepositorySource' -> 'ResourcePackRepository.Source' public final class OneConfigSoundPackSource implements RepositorySource { public static final OneConfigSoundPackSource INSTANCE = new OneConfigSoundPackSource(); @@ -52,6 +60,7 @@ public final class OneConfigSoundPackSource implements RepositorySource { private OneConfigSoundPackSource() { } + //? if > 1.8.9 { @Override public void loadPacks(Consumer consumer) { if (!Files.isRegularFile(PACK_ROOT.resolve("pack.mcmeta"))) return; @@ -80,4 +89,27 @@ public net.minecraft.server.packs.PackResources openFull(PackLocationInfo info, consumer.accept(pack); } } + //?} else { + /*@Override + public void loadResourcePacks(Consumer consumer) { + if (!Files.isRegularFile(PACK_ROOT.resolve("pack.mcmeta"))) return; + + ResourcePackSummary summary = ResourcePackSummary.create( + PACK_ID, + true, + false, + PackPosition.BOTTOM, + () -> new DirectoryResourcePack(PACK_ROOT) { + @Override + public String getName() { + return "OneConfig Sounds"; + } + } + ); + + if (summary != null) { + consumer.accept(summary); + } + } + *///?} } diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/test/TestLegacyHud_Test.java b/minecraft/src/main/java/org/polyfrost/oneconfig/test/TestLegacyHud_Test.java index d221e89ef..e185915bc 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/test/TestLegacyHud_Test.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/test/TestLegacyHud_Test.java @@ -28,7 +28,12 @@ package org.polyfrost.oneconfig.test; import kotlin.Pair; +//? if > 1.8.9 { import net.minecraft.client.gui.GuiGraphicsExtractor; +//?} else { +/*import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiElement; +*///?} import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import org.jetbrains.annotations.NotNull; @@ -87,12 +92,19 @@ public boolean showByDefault() { } @Override + //? if > 1.8.9 { public void render(@NotNull GuiGraphicsExtractor graphics) { + //?} else + //public void render() { if (stack == null) stack = new ItemStack(Items.DIAMOND_SWORD); + //~ if = 1.8.9 'graphics.fill' -> 'GuiElement.fill' graphics.fill(0, 0, (int) W, (int) H, 0x80000000); + //? if > 1.8.9 { //~ if >= 26.1 'renderItem' -> 'item' graphics.item(stack, 2, 2); + //?} else + //Minecraft.getInstance().getItemRenderer().renderGuiItem(stack, 2, 2); } } diff --git a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/api/hud/v1/LegacyHud.kt b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/api/hud/v1/LegacyHud.kt index 1041bb98d..ded2e1313 100644 --- a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/api/hud/v1/LegacyHud.kt +++ b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/api/hud/v1/LegacyHud.kt @@ -1,6 +1,7 @@ package org.polyfrost.oneconfig.api.hud.v1 import androidx.compose.runtime.Composable +//? if > 1.8.9 import net.minecraft.client.gui.GuiGraphicsExtractor import org.jetbrains.annotations.ApiStatus @@ -10,6 +11,7 @@ abstract class LegacyHud(id: String, title: String, category: Category) : Hud(id abstract val width: Float abstract val height: Float + //~ if = 1.8.9 '(mcCtx: GuiGraphicsExtractor)' -> '()' abstract fun render(mcCtx: GuiGraphicsExtractor) // legacy HUDs are fixed-size and render through GuiGraphics rather than a Compose tree so diff --git a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/compat/FirmamentHudCompat.kt b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/compat/FirmamentHudCompat.kt index 9ad5fa528..a6bf68f65 100644 --- a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/compat/FirmamentHudCompat.kt +++ b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/compat/FirmamentHudCompat.kt @@ -29,6 +29,7 @@ package org.polyfrost.oneconfig.internal.compat +//? if > 1.8.9 { import net.minecraft.client.gui.GuiGraphicsExtractor import net.minecraft.network.chat.Component import org.joml.Vector2i @@ -392,3 +393,4 @@ object FirmamentHudCompat { } } } +//?} diff --git a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/compat/SkyHanniHudCompat.kt b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/compat/SkyHanniHudCompat.kt index dc9c779c3..c96c2aed0 100644 --- a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/compat/SkyHanniHudCompat.kt +++ b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/compat/SkyHanniHudCompat.kt @@ -1,5 +1,6 @@ package org.polyfrost.oneconfig.internal.compat +//? if > 1.8.9 { import net.minecraft.client.gui.GuiGraphicsExtractor import org.apache.logging.log4j.LogManager import org.polyfrost.oneconfig.api.config.v1.Property @@ -358,3 +359,4 @@ private class SkyHanniHudWrapper(private val internalName: String) : OneConfigHu override fun save() = SkyHanniHudCompat.flush() } +//?} diff --git a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/sound/ExternalSounds.kt b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/sound/ExternalSounds.kt index d4a4906bc..9305f3e2e 100644 --- a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/sound/ExternalSounds.kt +++ b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/sound/ExternalSounds.kt @@ -122,7 +122,10 @@ object ExternalSounds { } private const val PACK_META = + //? if > 1.8.9 { """{"pack":{"description":"OneConfig downloaded sounds","pack_format":64,"supported_formats":{"min_inclusive":0,"max_inclusive":2147483647},"min_format":0,"max_format":2147483647}}""" + //?} else + //"""{"pack":{"description":"OneConfig downloaded sounds","pack_format":1}}""" private fun sha1Of(path: Path): String { val digest = MessageDigest.getInstance("SHA-1") diff --git a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/sound/McUiSoundService.kt b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/sound/McUiSoundService.kt index 5acfcf505..59ad6b591 100644 --- a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/sound/McUiSoundService.kt +++ b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/sound/McUiSoundService.kt @@ -4,16 +4,20 @@ import net.minecraft.client.Minecraft import net.minecraft.client.resources.sounds.AbstractTickableSoundInstance import net.minecraft.client.resources.sounds.SimpleSoundInstance import net.minecraft.client.resources.sounds.SoundInstance +//? if > 1.8.9 { import net.minecraft.core.Holder -import net.minecraft.resources.Identifier import net.minecraft.sounds.SoundEvent +//?} +import net.minecraft.resources.Identifier import net.minecraft.sounds.SoundEvents import net.minecraft.sounds.SoundSource +//? if > 1.8.9 import net.minecraft.util.RandomSource import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicLong class McUiSoundService : UiSoundService { + //? if > 1.8.9 private val random = RandomSource.create() private val sliderTick = AtomicInteger(0) @@ -54,7 +58,10 @@ class McUiSoundService : UiSoundService { } private fun playModernSound(id: String, pitch: Float, volume: Float) { + //? if > 1.8.9 { val event = SoundEvent.createVariableRangeEvent(Identifier.fromNamespaceAndPath("oneconfig", id)) + //?} else + //val event = Identifier("oneconfig", id) mc.soundManager.play(SimpleSoundInstance.forUI(event, pitch, volume.coerceIn(0f, 1f))) } @@ -75,13 +82,16 @@ class McUiSoundService : UiSoundService { } } + //~ if = 1.8.9 'SoundEvent' -> 'Identifier' private fun playVanilla(event: SoundEvent, pitch: Float, volume: Float) { mc.soundManager.play(SimpleSoundInstance.forUI(event, pitch, volume.coerceIn(0f, 1f))) } + //? if > 1.8.9 { @Suppress("unused") private fun playVanilla(holder: Holder, pitch: Float, volume: Float) = playVanilla(holder.value(), pitch, volume) + //?} override fun startAmbience(theme: UiSoundTheme, volume: Float) { try { @@ -136,12 +146,16 @@ class McUiSoundService : UiSoundService { private fun playAmbienceInstance(theme: UiSoundTheme, targetVolume: Float): FadingLoopSoundInstance { val soundIds = ambienceSoundIds(theme) + //? if > 1.8.9 { val event = SoundEvent.createVariableRangeEvent(Identifier.fromNamespaceAndPath("oneconfig", nextAmbienceSoundId(theme, soundIds))) + //?} else + //val event = Identifier("oneconfig", nextAmbienceSoundId(theme, soundIds)) //? >= 1.21.6 { val source = SoundSource.UI - //? } else { + //?} elif > 1.8.9 { /*val source = SoundSource.MASTER *///? } + //~ if = 1.8.9 '(event, source,' -> '(event,' val instance = FadingLoopSoundInstance(event, source, targetVolume, theme, soundIds.size == 1) ambience = instance mc.soundManager.play(instance) @@ -215,7 +229,8 @@ class McUiSoundService : UiSoundService { //? } else if >= 1.21.10 { /*mc.soundManager.updateSourceVolume(SoundSource.MUSIC) *///? } else { - /*mc.soundManager.updateSourceVolume(SoundSource.MUSIC, mc.options.getSoundSourceVolume(SoundSource.MUSIC)) + /*//~ if = 1.8.9 'SoundSource' -> 'SoundCategory' + mc.soundManager.updateSourceVolume(SoundSource.MUSIC, mc.options.getSoundSourceVolume(SoundSource.MUSIC)) *///? } } catch (_: Throwable) { } @@ -232,11 +247,14 @@ class McUiSoundService : UiSoundService { } private inner class FadingLoopSoundInstance( + //~ if = 1.8.9 'SoundEvent' -> 'Identifier' event: SoundEvent, + //? if > 1.8.9 source: SoundSource, @Volatile var targetVolume: Float, val theme: UiSoundTheme, private val nativeLoop: Boolean, + //~ if = 1.8.9 '(event, source, random)' -> '(event)' ) : AbstractTickableSoundInstance(event, source, random) { @Volatile @@ -247,8 +265,12 @@ class McUiSoundService : UiSoundService { init { looping = nativeLoop + //? if > 1.8.9 { delay = 0 + //?} else + //period = 0 attenuation = SoundInstance.Attenuation.NONE + //? if > 1.8.9 relative = true volume = targetVolume pitch = 1f @@ -273,6 +295,7 @@ class McUiSoundService : UiSoundService { volume -= targetVolume / FADE_TICKS if (volume <= 0f) { volume = 0f + //$ if > 1.8.9 'stop()' else 'done = true' stop() } } From 506f7ba24ceea26cf83b9f64038a60616b7a59dd Mon Sep 17 00:00:00 2001 From: Saad Nadeem Date: Sun, 23 Aug 2026 20:45:46 -0400 Subject: [PATCH 11/14] feat(legacy): port commands --- .../internal/OneConfigMixinInit.java | 2 + .../command/ClientCommandInternals.java | 156 ++++++++++++++++++ .../command/Mixin_LegacyChatCompletion.java | 87 ++++++++++ .../mixin/events/Mixin_ChatSendEvent.java | 10 ++ .../events/Mixin_InitializationEvent.java | 4 + 5 files changed, 259 insertions(+) create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/command/ClientCommandInternals.java create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/command/Mixin_LegacyChatCompletion.java diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/OneConfigMixinInit.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/OneConfigMixinInit.java index 33bb7fc33..43ccc44d6 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/OneConfigMixinInit.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/OneConfigMixinInit.java @@ -65,6 +65,8 @@ public void acceptTargets(Set myTargets, Set otherTargets) { public List getMixins() { List mixins = new ArrayList<>(); + //? if = 1.8.9 + //mixins.add("command.Mixin_LegacyChatCompletion"); //? moul_compat { RelocatedMixins.INSTANCE.register(e -> { diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/command/ClientCommandInternals.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/command/ClientCommandInternals.java new file mode 100644 index 000000000..434caaf54 --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/command/ClientCommandInternals.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.polyfrost.oneconfig.internal.legacy.command; + +//? if = 1.8.9 { +/*import com.mojang.brigadier.AmbiguityConsumer; +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.exceptions.BuiltInExceptionProvider; +import com.mojang.brigadier.exceptions.CommandExceptionType; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.suggestion.Suggestion; +import com.mojang.brigadier.suggestion.Suggestions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import net.minecraft.network.chat.Component; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.Locale; +import java.util.concurrent.CompletableFuture; + +public final class ClientCommandInternals { + private static final Logger LOGGER = LoggerFactory.getLogger(ClientCommandInternals.class); + private static CommandDispatcher activeDispatcher; + + public static void initializeDispatcher() { + CommandDispatcher dispatcher = new CommandDispatcher<>(); + activeDispatcher = dispatcher; + ClientCommandRegistrationCallback.EVENT.invoke(dispatcher, null); + finalizeInit(); + } + + /^* + * Executes a client-sided command. Callers should ensure that this is only called + * on slash-prefixed messages and the slash needs to be removed before calling. + * + * @param command the command with slash removed + * @return true if the command should not be sent to the server, false otherwise + ^/ + public static boolean executeCommand(String command) { + FabricClientCommandSource source = new FabricClientCommandSource() {}; + + try { + // TODO: Check for server commands before executing. + // This requires parsing the command, checking if they match a server command + // and then executing the command with the parse results. + activeDispatcher.execute(command, source); + return true; + } catch (CommandSyntaxException e) { + boolean ignored = isIgnoredException(e.getType()); + + if (ignored) { + LOGGER.debug("Syntax exception for client-sided command '{}'", command, e); + return false; + } + + LOGGER.warn("Syntax exception for client-sided command '{}'", command, e); + source.sendError(getErrorMessage(e)); + return true; + } catch (Exception e) { + LOGGER.warn("Error while executing client-sided command '{}'", command, e); + source.sendError(Component.nullToEmpty(e.getMessage())); + return true; + } + } + + public static CompletableFuture getCompletions(String text) { + if (!text.startsWith("/")) { + return CompletableFuture.completedFuture(new String[0]); + } + + String command = text.substring(1); + FabricClientCommandSource source = new FabricClientCommandSource() { + }; + return activeDispatcher.getCompletionSuggestions(activeDispatcher.parse(command, source)) + .thenApply(suggestions -> convertSuggestions(activeDispatcher, source, command, suggestions)); + } + + public static String[] mergeSuggestions(String[] serverSuggestions, String[] clientSuggestions) { + if (clientSuggestions.length == 0) return serverSuggestions; + + LinkedHashMap merged = new LinkedHashMap<>(); + for (String suggestion : clientSuggestions) merged.put(suggestion.toLowerCase(Locale.ROOT), suggestion); + for (String suggestion : serverSuggestions) merged.putIfAbsent(suggestion.toLowerCase(Locale.ROOT), suggestion); + return merged.values().toArray(new String[0]); + } + + private static String[] convertSuggestions( + CommandDispatcher dispatcher, + FabricClientCommandSource source, + String command, + Suggestions suggestions + ) { + ArrayList converted = new ArrayList<>(); + int wordStart = command.lastIndexOf(' ') + 1; + boolean root = wordStart == 0; + for (Suggestion suggestion : suggestions.getList()) { + String applied = suggestion.apply(command); + // 1.8.9 can only replace the current word + if (!command.regionMatches(0, applied, 0, wordStart)) continue; + var child = dispatcher.getRoot().getChild(applied); + if (root && (child == null || !child.canUse(source))) continue; + + String replacement = root ? "/" + applied : applied.substring(wordStart); + if (replacement.indexOf(' ') < 0) converted.add(replacement); + } + return converted.toArray(new String[0]); + } + + /^* + * Tests whether a command syntax exception with the type + * should be ignored and the command sent to the server. + * + * @param type the exception type + * @return true if ignored, false otherwise + ^/ + private static boolean isIgnoredException(CommandExceptionType type) { + BuiltInExceptionProvider builtins = CommandSyntaxException.BUILT_IN_EXCEPTIONS; + + // Only ignore unknown commands and node parse exceptions. + // The argument-related dispatcher exceptions are not ignored because + // they will only happen if the user enters a correct command. + return type == builtins.dispatcherUnknownCommand() || type == builtins.dispatcherParseException(); + } + + private static Component getErrorMessage(CommandSyntaxException e) { + return Component.literal(e.getMessage()); + } + + /^* + * Runs final initialization tasks such as {@link CommandDispatcher#findAmbiguities(AmbiguityConsumer)} + * on the command dispatcher. + ^/ + public static void finalizeInit() { + // noinspection CodeBlock2Expr + activeDispatcher.findAmbiguities((parent, child, sibling, inputs) -> { + LOGGER.warn("Ambiguity between arguments {} and {} with inputs: {}", activeDispatcher.getPath(child), activeDispatcher.getPath(sibling), inputs); + }); + } + +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/command/Mixin_LegacyChatCompletion.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/command/Mixin_LegacyChatCompletion.java new file mode 100644 index 000000000..135d659bc --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/command/Mixin_LegacyChatCompletion.java @@ -0,0 +1,87 @@ +package org.polyfrost.oneconfig.internal.mixin.command; + +//? if = 1.8.9 { +/*import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.ChatScreen; +import net.minecraft.client.gui.widget.TextFieldWidget; +import org.jetbrains.annotations.Nullable; +import org.objectweb.asm.Opcodes; +import org.polyfrost.oneconfig.internal.legacy.command.ClientCommandInternals; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.ArrayDeque; +import java.util.concurrent.CompletableFuture; + +// Apply above default mixin priority +@Mixin(value = ChatScreen.class, priority = 1100) +public abstract class Mixin_LegacyChatCompletion { + @Shadow + private boolean completed; + + @Shadow + protected TextFieldWidget chatField; + + @Unique + @Nullable + private ArrayDeque> ocfg$clientSuggestions; + + @Unique + @Nullable + private ArrayDeque ocfg$suggestionInputs; + + @Unique + @Nullable + private ArrayDeque ocfg$suggestionRequests; + + @Unique + private int ocfg$suggestionRequest; + + @Inject( + method = "goThroughHistory(Ljava/lang/String;Ljava/lang/String;)V", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/client/gui/screen/ChatScreen;completed:Z", + opcode = Opcodes.PUTFIELD + ) + ) + private void ocfg$prepareClientSuggestions(String text, String cursor, CallbackInfo ci) { + if (ocfg$clientSuggestions == null) { + ocfg$clientSuggestions = new ArrayDeque<>(); + ocfg$suggestionInputs = new ArrayDeque<>(); + ocfg$suggestionRequests = new ArrayDeque<>(); + } + + ocfg$suggestionRequest++; + ocfg$clientSuggestions.addLast(ClientCommandInternals.getCompletions(text)); + ocfg$suggestionInputs.addLast(text); + ocfg$suggestionRequests.addLast(ocfg$suggestionRequest); + } + + @WrapMethod(method = "setMessageHistory") + private void ocfg$addClientSuggestions(String[] serverSuggestions, Operation original) { + if (ocfg$clientSuggestions == null || ocfg$clientSuggestions.isEmpty()) { + original.call((Object) serverSuggestions); + return; + } + + CompletableFuture future = ocfg$clientSuggestions.removeFirst(); + String input = ocfg$suggestionInputs.removeFirst(); + int request = ocfg$suggestionRequests.removeFirst(); + future.whenCompleteAsync((clientSuggestions, throwable) -> { + //noinspection ConstantValue + if (request != ocfg$suggestionRequest || !completed || Minecraft.getInstance().screen != (Object) this) return; + int cursor = chatField.getCursor(); + if (cursor != input.length() || !chatField.getText().startsWith(input)) return; + if (throwable != null) clientSuggestions = new String[0]; + original.call((Object) ClientCommandInternals.mergeSuggestions(serverSuggestions, clientSuggestions)); + }, Minecraft.getInstance()::executeTask); + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ChatSendEvent.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ChatSendEvent.java index e210c0671..f3851917d 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ChatSendEvent.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ChatSendEvent.java @@ -6,6 +6,8 @@ //import net.minecraft.client.player.LocalPlayer; import org.polyfrost.oneconfig.api.event.v1.EventManager; import org.polyfrost.oneconfig.api.event.v1.events.ChatEvent; +//? if = 1.8.9 +//import org.polyfrost.oneconfig.internal.legacy.command.ClientCommandInternals; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; @@ -29,7 +31,15 @@ public void chatCallback(String message, CallbackInfo ci) { if (ocfg$chatEvent.cancelled) { ci.cancel(); + return; } + + //? if = 1.8.9 { + /*String commandMessage = ocfg$chatEvent.message; + if (commandMessage.startsWith("/") && ClientCommandInternals.executeCommand(commandMessage.substring(1))) { + ci.cancel(); + } + *///?} } @ModifyVariable( diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_InitializationEvent.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_InitializationEvent.java index 925e31d17..ab5a2f571 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_InitializationEvent.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_InitializationEvent.java @@ -3,6 +3,8 @@ import net.minecraft.client.Minecraft; import org.polyfrost.oneconfig.api.event.v1.EventManager; import org.polyfrost.oneconfig.api.event.v1.events.InitializationEvent; +//? if = 1.8.9 +//import org.polyfrost.oneconfig.internal.legacy.command.ClientCommandInternals; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -15,6 +17,8 @@ public class Mixin_InitializationEvent { @Inject(method = "", at = @At("RETURN")) private void completedInit(CallbackInfo ci) { EventManager.INSTANCE.post(InitializationEvent.INSTANCE); + //? if = 1.8.9 + //ClientCommandInternals.initializeDispatcher(); } } From ff01a74fbda7494c110d94721e497b84ebcaa978 Mon Sep 17 00:00:00 2001 From: Saad Nadeem Date: Thu, 20 Aug 2026 21:22:59 -0400 Subject: [PATCH 12/14] feat(legacy): port keybinds --- .../internal/MinecraftKeybindBridgeImpl.java | 41 ++++++++++++++++++- .../mixin/keybind/KeyMappingAccessor.java | 8 ++++ .../keybind/KeyMappingCategoryAccessor.java | 2 +- .../keybind/KeyMappingRegistryAccessor.java | 6 +++ .../keybind/Mixin_KeyMappingResetDetect.java | 4 ++ .../keybind/Mixin_KeybindComboDisplay.java | 33 +++++++++++++++ .../keybind/Mixin_KeybindConflictDetect.java | 33 +++++++++++++++ .../keybind/Mixin_KeybindConflictScope.java | 1 + .../keybind/Mixin_OneConfigKeybindRebind.java | 34 +++++++++++++++ 9 files changed, 159 insertions(+), 3 deletions(-) diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/api/ui/v1/keybind/internal/MinecraftKeybindBridgeImpl.java b/minecraft/src/main/java/org/polyfrost/oneconfig/api/ui/v1/keybind/internal/MinecraftKeybindBridgeImpl.java index 6233c8538..6b2362da0 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/api/ui/v1/keybind/internal/MinecraftKeybindBridgeImpl.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/api/ui/v1/keybind/internal/MinecraftKeybindBridgeImpl.java @@ -14,17 +14,22 @@ import org.polyfrost.oneconfig.api.ui.v1.keybind.KeybindManager; import org.polyfrost.oneconfig.api.ui.v1.keybind.MinecraftKeybindBridge; import org.polyfrost.oneconfig.api.ui.v1.keybind.OneConfigKeybind; +//? if > 1.8.9 { import org.polyfrost.oneconfig.internal.mixin.keybind.KeyMappingAccessor; +//?} else +//import org.polyfrost.oneconfig.internal.legacy.KeyCodes; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; +//? if > 1.8.9 { +import java.util.HashMap; +import java.util.HashSet; import java.util.concurrent.ConcurrentHashMap; +//?} /** * Mirrors {@link OneConfigKeybind}s into Minecraft's native Controls menu @@ -65,8 +70,11 @@ public static String categoryLabel(Identifier id) { //?} else { /*private String categoryFor(String name) { String label = (name == null || name.isBlank()) ? "OneConfig" : name; + //? if > 1.8.9 { java.util.Map order = org.polyfrost.oneconfig.internal.mixin.keybind.KeyMappingCategoryAccessor.oneconfig$categorySortOrder(); if (!order.containsKey(label)) order.put(label, order.size()); + //?} else + //KeyMapping.getCategories().add(label); return label; } *///?} @@ -106,7 +114,10 @@ public synchronized void register(OneConfigKeybind bind) { KeyMapping mapping = detached( bind.getName(), type.getOrCreate(defSrc.getBoundCode()), + //? if > 1.8.9 { () -> new KeyMapping(bind.getName(), type, defSrc.getBoundCode(), categoryFor(bind.getCategory())) + //?} else + //() -> new KeyMapping(bind.getName(), KeyCodes.toLegacy(type.getOrCreate(defSrc.getBoundCode())), categoryFor(bind.getCategory())) ); applyKeyTo(mapping, bind); mappings.put(bind, mapping); @@ -132,6 +143,7 @@ private synchronized void syncOptionsArray() { @SuppressWarnings({"rawtypes", "unchecked"}) private static KeyMapping detached(String name, InputConstants.Key defaultKey, java.util.function.Supplier constructor) { + //? if > 1.8.9 { Map all; Map map; Object priorNamed; @@ -164,6 +176,23 @@ private static KeyMapping detached(String name, InputConstants.Key defaultKey, j LOGGER.warn("Failed to detach the mirror of '{}' from Minecraft's keybind registries", name, t); } return mapping; + //?} else { + /*List all; + try { + all = org.polyfrost.oneconfig.internal.mixin.keybind.KeyMappingRegistryAccessor.oneconfig$all(); + } catch (Throwable t) { + LOGGER.warn("Cannot reach Minecraft's keybind registries; OneConfig keybinds may shadow Minecraft ones", t); + return constructor.get(); + } + KeyMapping mapping = constructor.get(); + try { + all.remove(mapping); + KeyMapping.resetMapping(); + } catch (Throwable t) { + LOGGER.warn("Failed to detach the mirror of '{}' from Minecraft's keybind registries", name, t); + } + return mapping; + *///?} } private static String identity(OneConfigKeybind bind) { @@ -233,7 +262,10 @@ private long[] combo(KeyMapping mapping) { if (mouse != null) for (int m : mouse) set.add(MOUSE_TAG | m); set.add(MODS_TAG | (bind.getMods() & 0xFFL)); } else { + //? if > 1.8.9 { InputConstants.Key key = ((KeyMappingAccessor) mapping).oneconfig$getKey(); + //?} else + //InputConstants.Key key = KeyCodes.fromLegacy(mapping.getKeyCode()); int v = key.getValue(); if (v < 0) return null; set.add(key.getType() == InputConstants.Type.MOUSE ? (MOUSE_TAG | v) : (long) v); @@ -361,6 +393,8 @@ private void setKey(KeyMapping mapping, InputConstants.Key key) { internalSetKey = true; try { mapping.setKey(key); + //? if = 1.8.9 + //KeyMapping.resetMapping(); } finally { internalSetKey = false; } @@ -376,7 +410,10 @@ public void reconcile() { synchronized (this) { for (Map.Entry e : mappings.entrySet()) { OneConfigKeybind bind = e.getKey(); + //? if > 1.8.9 { InputConstants.Key actual = ((KeyMappingAccessor) e.getValue()).oneconfig$getKey(); + //?} else + //InputConstants.Key actual = KeyCodes.fromLegacy(e.getValue().getKeyCode()); int actualValue = actual.getValue(); boolean actualMouse = actual.getType() == InputConstants.Type.MOUSE; diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/KeyMappingAccessor.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/KeyMappingAccessor.java index 082be57d9..48bbab66c 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/KeyMappingAccessor.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/KeyMappingAccessor.java @@ -1,5 +1,6 @@ package org.polyfrost.oneconfig.internal.mixin.keybind; +//? if > 1.8.9 { import com.mojang.blaze3d.platform.InputConstants; import net.minecraft.client.KeyMapping; import org.spongepowered.asm.mixin.Mixin; @@ -10,3 +11,10 @@ public interface KeyMappingAccessor { @Accessor("key") InputConstants.Key oneconfig$getKey(); } +//?} else { +/*import net.minecraft.SharedConstants; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(SharedConstants.class) +public interface KeyMappingAccessor {} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/KeyMappingCategoryAccessor.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/KeyMappingCategoryAccessor.java index 8b22fa94b..53dafc60f 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/KeyMappingCategoryAccessor.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/KeyMappingCategoryAccessor.java @@ -1,6 +1,6 @@ package org.polyfrost.oneconfig.internal.mixin.keybind; -//? if <1.21.10 { +//? if < 1.21.10 && > 1.8.9 { /*import net.minecraft.client.KeyMapping; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/KeyMappingRegistryAccessor.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/KeyMappingRegistryAccessor.java index a054b78e0..f2de03db9 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/KeyMappingRegistryAccessor.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/KeyMappingRegistryAccessor.java @@ -4,19 +4,25 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; +//? if > 1.8.9 { import java.util.Map; +//?} else +//import java.util.List; @Mixin(KeyMapping.class) public interface KeyMappingRegistryAccessor { @SuppressWarnings("rawtypes") @Accessor("ALL") + //~ if = 1.8.9 'Map' -> 'List' static Map oneconfig$all() { throw new AssertionError(); } + //? if > 1.8.9 { @SuppressWarnings("rawtypes") @Accessor("MAP") static Map oneconfig$map() { throw new AssertionError(); } + //?} } diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/Mixin_KeyMappingResetDetect.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/Mixin_KeyMappingResetDetect.java index 70f99b984..906cfa1b3 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/Mixin_KeyMappingResetDetect.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/Mixin_KeyMappingResetDetect.java @@ -1,5 +1,6 @@ package org.polyfrost.oneconfig.internal.mixin.keybind; +//? if > 1.8.9 import com.mojang.blaze3d.platform.InputConstants; import net.minecraft.client.KeyMapping; import org.polyfrost.oneconfig.api.ui.v1.keybind.internal.MinecraftKeybindBridgeImpl; @@ -10,12 +11,15 @@ @Mixin(KeyMapping.class) public class Mixin_KeyMappingResetDetect { + //~ if = 1.8.9 'setKey' -> 'setKeyCode' @Inject(method = "setKey", at = @At("HEAD"), cancellable = true) + //~ if = 1.8.9 'InputConstants.Key key' -> 'int keyCode' private void oneconfig$restoreFullDefault(InputConstants.Key key, CallbackInfo ci) { MinecraftKeybindBridgeImpl bridge = MinecraftKeybindBridgeImpl.instance(); if (bridge == null || bridge.isInternalSetKey()) return; KeyMapping self = (KeyMapping) (Object) this; if (bridge.bindFor(self) == null) return; + //~ if = 1.8.9 '!key.equals(self.getDefaultKey())' -> 'keyCode != self.getDefaultKeyCode()' if (!key.equals(self.getDefaultKey())) return; if (bridge.menuReset(self)) ci.cancel(); } diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/Mixin_KeybindComboDisplay.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/Mixin_KeybindComboDisplay.java index bb1730d9e..25d43f9b6 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/Mixin_KeybindComboDisplay.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/Mixin_KeybindComboDisplay.java @@ -6,9 +6,15 @@ import org.polyfrost.oneconfig.api.ui.v1.keybind.internal.MinecraftKeybindBridgeImpl; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; +//? if > 1.8.9 { import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +//?} else { +/*import org.spongepowered.asm.mixin.Shadow; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +*///?} +//? if > 1.8.9 { @Mixin(KeyMapping.class) public class Mixin_KeybindComboDisplay { @Inject(method = "getTranslatedKeyMessage", at = @At("RETURN"), cancellable = true) @@ -28,3 +34,30 @@ public class Mixin_KeybindComboDisplay { if (decorated != null) cir.setReturnValue(decorated); } } +//?} else { +/*@Mixin(targets = "net.minecraft.client.gui.screens.options.controls.KeyBindsList$KeyEntry") +public class Mixin_KeybindComboDisplay { + @Shadow + private KeyMapping keyBinding; + + @ModifyExpressionValue( + method = "render", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/Options;getKeyName(I)Ljava/lang/String;" + ) + ) + private String oneconfig$showCombo(String original) { + MinecraftKeybindBridgeImpl bridge = MinecraftKeybindBridgeImpl.instance(); + if (bridge == null) return original; + KeyMapping self = this.keyBinding; + OneConfigKeybind bind = bridge.bindFor(self); + if (bind == null) return original; + // while recording show the live combo as keys are added + Component preview = bridge.previewFor(self); + if (preview != null) return preview.getFormattedString(); + Component decorated = MinecraftKeybindBridgeImpl.comboLabel(bind, Component.literal(original)); + return decorated != null ? decorated.getFormattedString() : original; + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/Mixin_KeybindConflictDetect.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/Mixin_KeybindConflictDetect.java index 1b674cd3b..7e3d0e831 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/Mixin_KeybindConflictDetect.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/Mixin_KeybindConflictDetect.java @@ -4,9 +4,19 @@ import org.polyfrost.oneconfig.api.ui.v1.keybind.internal.MinecraftKeybindBridgeImpl; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; +//? if > 1.8.9 { import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +//?} else { +/*import com.llamalad7.mixinextras.expression.Definition; +import com.llamalad7.mixinextras.expression.Expression; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.llamalad7.mixinextras.sugar.Local; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Shadow; +*///?} +//? if > 1.8.9 { @Mixin(KeyMapping.class) public class Mixin_KeybindConflictDetect { @Inject(method = "same", at = @At("HEAD"), cancellable = true) @@ -18,3 +28,26 @@ public class Mixin_KeybindConflictDetect { cir.setReturnValue(bridge.menuConflict(self, other)); } } +//?} else { +/*@Mixin(targets = "net.minecraft.client.gui.screens.options.controls.KeyBindsList$KeyEntry") +public class Mixin_KeybindConflictDetect { + @Final + @Shadow + private KeyMapping keyBinding; + + @Definition(id = "getKeyCode", method = "Lnet/minecraft/client/KeyMapping;getKeyCode()I") + @Definition( + id = "keyBinding", + field = "Lnet/minecraft/client/gui/screens/options/controls/KeyBindsList$KeyEntry;keyBinding:Lnet/minecraft/client/KeyMapping;" + ) + @Expression("?.getKeyCode() == this.keyBinding.getKeyCode()") + @ModifyExpressionValue(method = "render", at = @At("MIXINEXTRAS:EXPRESSION")) + private boolean oneconfig$conflict(boolean original, @Local KeyMapping other) { + MinecraftKeybindBridgeImpl bridge = MinecraftKeybindBridgeImpl.instance(); + if (bridge == null || (bridge.bindFor(this.keyBinding) == null && bridge.bindFor(other) == null)) { + return original; + } + return bridge.menuConflict(this.keyBinding, other); + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/Mixin_KeybindConflictScope.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/Mixin_KeybindConflictScope.java index 55ee56fdd..209bb9589 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/Mixin_KeybindConflictScope.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/Mixin_KeybindConflictScope.java @@ -12,6 +12,7 @@ @Mixin(targets = "net.minecraft.client.gui.screens.options.controls.KeyBindsList$KeyEntry") public class Mixin_KeybindConflictScope { @ModifyExpressionValue( + //~ if = 1.8.9 'refreshEntry' -> 'render' method = "refreshEntry", at = @At( value = "FIELD", diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/Mixin_OneConfigKeybindRebind.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/Mixin_OneConfigKeybindRebind.java index b8dcd3acc..b60a0de71 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/Mixin_OneConfigKeybindRebind.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/keybind/Mixin_OneConfigKeybindRebind.java @@ -1,7 +1,13 @@ package org.polyfrost.oneconfig.internal.mixin.keybind; import net.minecraft.client.KeyMapping; +//? if > 1.8.9 { import net.minecraft.client.gui.screens.options.controls.KeyBindsList; +//?} else { +/*import org.polyfrost.oneconfig.internal.legacy.KeyCodes; +import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; +*///?} import net.minecraft.client.gui.screens.options.controls.KeyBindsScreen; //? if >=1.21.10 { import net.minecraft.client.input.KeyEvent; @@ -17,6 +23,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +//? if > 1.8.9 import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.LinkedHashSet; @@ -24,6 +31,7 @@ @Mixin(KeyBindsScreen.class) public class Mixin_OneConfigKeybindRebind implements OneConfigKeybindRecorder { @Shadow public KeyMapping selectedKey; + //? if > 1.8.9 @Shadow private KeyBindsList keyBindsList; @Unique private final LinkedHashSet oneconfig$keys = new LinkedHashSet<>(); @@ -45,14 +53,26 @@ public class Mixin_OneConfigKeybindRebind implements OneConfigKeybindRecorder { } //?} else { /*@Inject(method = "keyPressed", at = @At("HEAD"), cancellable = true) + //? if > 1.8.9 { private void oneconfig$keyPressed(int keyCode, int scanCode, int modifiers, CallbackInfoReturnable cir) { + //?} else + //private void oneconfig$keyPressed(char keyChar, int keyCode, CallbackInfo ci) { if (!oneconfig$isOurs()) return; + //? if = 1.8.9 { + /^keyCode = KeyCodes.fromLegacy(keyCode).getValue(); + if (keyCode < 0) { + ci.cancel(); + return; + } + ^///?} if (keyCode == GLFW.GLFW_KEY_ESCAPE) { oneconfig$recordEscape(); + //$ if > 1.8.9 'cir.setReturnValue(true);' else 'ci.cancel();' cir.setReturnValue(true); return; } oneconfig$recordKey(keyCode); + //$ if > 1.8.9 'cir.setReturnValue(true);' else 'ci.cancel();' cir.setReturnValue(true); } *///?} @@ -66,9 +86,13 @@ public class Mixin_OneConfigKeybindRebind implements OneConfigKeybindRecorder { } //?} else { /*@Inject(method = "mouseClicked", at = @At("HEAD"), cancellable = true) + //? if > 1.8.9 { private void oneconfig$mouseClicked(double mouseX, double mouseY, int button, CallbackInfoReturnable cir) { + //?} else + //private void oneconfig$mouseClicked(int mouseX, int mouseY, int button, CallbackInfo ci) { if (!oneconfig$isOurs()) return; oneconfig$recordMouse(button); + //$ if > 1.8.9 'cir.setReturnValue(true);' else 'ci.cancel();' cir.setReturnValue(true); } *///?} @@ -80,7 +104,10 @@ public class Mixin_OneConfigKeybindRebind implements OneConfigKeybindRecorder { } //?} else { /*@Inject(method = "render", at = @At("HEAD")) + //? if > 1.8.9 { private void oneconfig$poll(CallbackInfo ci) { + //?} else + //private void oneconfig$poll(int mouseX, int mouseY, float tickDelta, CallbackInfo ci) { oneconfig$pollInputs(); } *///?} @@ -90,9 +117,14 @@ public class Mixin_OneConfigKeybindRebind implements OneConfigKeybindRecorder { MinecraftKeybindBridgeImpl bridge = MinecraftKeybindBridgeImpl.instance(); if (bridge != null) bridge.setActiveRebind(oneconfig$target != null ? oneconfig$target : this.selectedKey); if (!oneconfig$recording) return; + //? if > 1.8.9 { long window = Platform.compatibility().windowHandle(); for (int k : oneconfig$keys) if (GLFW.glfwGetKey(window, k) != GLFW.GLFW_RELEASE) return; for (int b : oneconfig$mouse) if (GLFW.glfwGetMouseButton(window, b) != GLFW.GLFW_RELEASE) return; + //?} else { + /*for (int k : oneconfig$keys) if (Keyboard.isKeyDown(KeyCodes.toLegacy(k))) return; + for (int b : oneconfig$mouse) if (Mouse.isButtonDown(b)) return; + *///?} oneconfig$commit(); } @@ -148,6 +180,7 @@ public class Mixin_OneConfigKeybindRebind implements OneConfigKeybindRecorder { MinecraftKeybindBridgeImpl bridge = MinecraftKeybindBridgeImpl.instance(); if (bridge == null || oneconfig$target == null) return; bridge.setPreview(oneconfig$target, oneconfig$toArray(oneconfig$keys), oneconfig$toArray(oneconfig$mouse)); + //? if > 1.8.9 if (this.keyBindsList != null) this.keyBindsList.resetMappingAndUpdateButtons(); } @@ -166,6 +199,7 @@ public class Mixin_OneConfigKeybindRebind implements OneConfigKeybindRecorder { @Unique private void oneconfig$finishSelection() { this.selectedKey = null; + //? if > 1.8.9 if (this.keyBindsList != null) this.keyBindsList.resetMappingAndUpdateButtons(); } From 9313ec55fb13693d5c30fd12878c9c916315e685 Mon Sep 17 00:00:00 2001 From: Saad Nadeem Date: Sat, 8 Aug 2026 06:23:35 -0400 Subject: [PATCH 13/14] feat(legacy): port hypixel mod api --- buildSrc/src/main/kotlin/oneconfig-bootstrap.gradle.kts | 7 ++++++- buildSrc/src/main/kotlin/oneconfig-setup.gradle.kts | 4 +++- minecraft/ornithe.gradle.kts | 1 + .../api/hypixel/v1/internal/HypixelApiInternalsImpl.java | 3 +++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/buildSrc/src/main/kotlin/oneconfig-bootstrap.gradle.kts b/buildSrc/src/main/kotlin/oneconfig-bootstrap.gradle.kts index 9c85b1c8b..03cf62c6c 100644 --- a/buildSrc/src/main/kotlin/oneconfig-bootstrap.gradle.kts +++ b/buildSrc/src/main/kotlin/oneconfig-bootstrap.gradle.kts @@ -16,6 +16,9 @@ repositories { maven("https://repo.hypixel.net/repository/Hypixel/") { content { includeGroupAndSubgroups("net.hypixel") } } + maven("https://maven.axolotlclient.com/releases") { + content { includeGroup("io.github.moehreag.hypixel") } + } maven("https://maven.deftu.dev/releases") { content { includeGroupAndSubgroups("dev.deftu") } } @@ -129,8 +132,10 @@ gradle.projectsEvaluated { val hypixelFabricMod = if (versionedCatalog.versions["minecraft"].requiredVersion.startsWith("26")) { "maven.modrinth:hypixel-mod-api:1.0.2+build.1+mc26.1" - } else { + } else if (versionedCatalog.versions["minecraft"].requiredVersion.startsWith("1.21")) { "maven.modrinth:hypixel-mod-api:1.0.1+build.1+mc1.21" + } else { + "org.polyfrost:mod-api-fabric:1.0.2+build.1+mc1.8.9" } (dependencies.add("include", hypixelFabricMod) as ExternalModuleDependency).isTransitive = false } diff --git a/buildSrc/src/main/kotlin/oneconfig-setup.gradle.kts b/buildSrc/src/main/kotlin/oneconfig-setup.gradle.kts index cc6e6f71b..06a463607 100644 --- a/buildSrc/src/main/kotlin/oneconfig-setup.gradle.kts +++ b/buildSrc/src/main/kotlin/oneconfig-setup.gradle.kts @@ -236,7 +236,7 @@ dependencies { handleApiDep(versionedCatalog.bundles["nightconfig"]) handleApiDep(versionedCatalog["snakeyaml"]) handleApiDep(versionedCatalog["java-objc-bridge"]) - val hypixelModApiVersion = if (stonecutter.eval(stonecutter.current.version, ">= 26.1")) "1.0.2" else "1.0.1" + val hypixelModApiVersion = if (stonecutter.eval(stonecutter.current.version, ">= 26.1") || loader == "ornithe") "1.0.2" else "1.0.1" handleApiDep("net.hypixel:mod-api:$hypixelModApiVersion") handleApiDep(versionedCatalog["hypixel-data"]) @@ -252,6 +252,8 @@ dependencies { } else { "modImplementation"(hypixelFabricMod) { isTransitive = false } } + } else if (loader == "ornithe") { + "modLocalRuntime"("org.polyfrost:mod-api-fabric:1.0.2+build.1+mc1.8.9") { isTransitive = false } } handleApiDep(versionedCatalog["mixin-squared"]) diff --git a/minecraft/ornithe.gradle.kts b/minecraft/ornithe.gradle.kts index def58e4a9..fb103a880 100644 --- a/minecraft/ornithe.gradle.kts +++ b/minecraft/ornithe.gradle.kts @@ -14,6 +14,7 @@ repositories { content { includeGroup("io.github.moehreag") includeGroup("io.github.moehreag.legacy-lwjgl3") + includeGroup("io.github.moehreag.hypixel") } } } diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/api/hypixel/v1/internal/HypixelApiInternalsImpl.java b/minecraft/src/main/java/org/polyfrost/oneconfig/api/hypixel/v1/internal/HypixelApiInternalsImpl.java index 244133dfb..6d245a299 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/api/hypixel/v1/internal/HypixelApiInternalsImpl.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/api/hypixel/v1/internal/HypixelApiInternalsImpl.java @@ -44,7 +44,10 @@ public final class HypixelApiInternalsImpl implements HypixelApiInternals { public HypixelApiInternalsImpl() { LOGGER.info("Registering Hypixel API hello/disconnect handlers"); HypixelModAPI.getInstance().createHandler(ClientboundHelloPacket.class, p -> onHypixel = true); + //? if > 1.8.9 { ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> onHypixel = false); + //?} else + //ClientConnectionEvents.DISCONNECT.register(context -> onHypixel = false); } @Override From 8cce1d2c199a5dd2eec712ffeff45b22b49088bc Mon Sep 17 00:00:00 2001 From: Saad Nadeem Date: Sat, 22 Aug 2026 01:20:07 -0400 Subject: [PATCH 14/14] feat(legacy): title panorama --- .../v1/internal/ScreenPlatformImpl.java | 9 +++- .../legacy/LegacyPanoramaTracker.java | 23 ++++++++++ .../events/Mixin_ScreenOpenEvent_Fabric.java | 4 ++ .../internal/ui/compose/ComposeScreen.kt | 42 ++++++++++++++++++- .../main/resources/oneconfigv1.classtweaker | 1 + 5 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/LegacyPanoramaTracker.java diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/api/platform/v1/internal/ScreenPlatformImpl.java b/minecraft/src/main/java/org/polyfrost/oneconfig/api/platform/v1/internal/ScreenPlatformImpl.java index 04c713ff2..398fd613c 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/api/platform/v1/internal/ScreenPlatformImpl.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/api/platform/v1/internal/ScreenPlatformImpl.java @@ -37,6 +37,8 @@ import org.polyfrost.oneconfig.internal.ui.compose.ComposeScreen; import org.polyfrost.oneconfig.internal.ui.compose.ComposeSupport; import org.polyfrost.oneconfig.internal.ui.compose.SkiaCtx; +//? if = 1.8.9 +//import org.polyfrost.oneconfig.internal.legacy.LegacyPanoramaTracker; public class ScreenPlatformImpl implements ScreenPlatform { @Override @@ -108,9 +110,14 @@ public void display(@Nullable Object screen, int frames) { // renderFrame and re-enters our renderFrame mixin giving a nested frame and a black flash if (frames < 1) Minecraft.getInstance().gui.setScreen((Screen) screen); else EventDelay.of(FramebufferRenderEvent.End.class, frames, () -> Minecraft.getInstance().gui.setScreen((Screen) screen)); - //?} else { + //?} elif > 1.8.9 { /*if (frames < 1) Minecraft.getInstance().setScreen((Screen) screen); else EventDelay.of(FramebufferRenderEvent.End.class, frames, () -> Minecraft.getInstance().setScreen((Screen) screen)); + *///?} else { + /*Object target = (screen == null && Minecraft.getInstance().level == null && current() instanceof ComposeScreen) + ? LegacyPanoramaTracker.current() : screen; + if (frames < 1) Minecraft.getInstance().setScreen((Screen) target); + else EventDelay.of(FramebufferRenderEvent.End.class, frames, () -> Minecraft.getInstance().setScreen((Screen) target)); *///?} } diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/LegacyPanoramaTracker.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/LegacyPanoramaTracker.java new file mode 100644 index 000000000..0dcd8045b --- /dev/null +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/legacy/LegacyPanoramaTracker.java @@ -0,0 +1,23 @@ +package org.polyfrost.oneconfig.internal.legacy; + +//? if = 1.8.9 { +/*import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.gui.screens.TitleScreen; + +public final class LegacyPanoramaTracker { + private static TitleScreen panorama; + + private LegacyPanoramaTracker() { + } + + public static void capture(Screen screen) { + if (screen instanceof TitleScreen) { + panorama = (TitleScreen) screen; + } + } + + public static TitleScreen current() { + return panorama; + } +} +*///?} diff --git a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ScreenOpenEvent_Fabric.java b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ScreenOpenEvent_Fabric.java index a31b94a06..14150989e 100644 --- a/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ScreenOpenEvent_Fabric.java +++ b/minecraft/src/main/java/org/polyfrost/oneconfig/internal/mixin/events/Mixin_ScreenOpenEvent_Fabric.java @@ -5,6 +5,8 @@ import net.minecraft.client.gui.screens.Screen; import org.polyfrost.oneconfig.api.event.v1.EventManager; import org.polyfrost.oneconfig.api.event.v1.events.ScreenOpenEvent; +//? if = 1.8.9 +//import org.polyfrost.oneconfig.internal.legacy.LegacyPanoramaTracker; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -18,6 +20,8 @@ public class Mixin_ScreenOpenEvent_Fabric { //?} else //@Inject(method = "setScreen", at = @At("HEAD"), cancellable = true) private void screenOpenCallback(Screen screen, CallbackInfo ci) { + //? if = 1.8.9 + //LegacyPanoramaTracker.capture(((Minecraft) (Object) this).screen); ScreenOpenEvent event = new ScreenOpenEvent(screen); EventManager.INSTANCE.post(event); if (event.cancelled) { diff --git a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeScreen.kt b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeScreen.kt index 297e07abb..b8f562935 100644 --- a/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeScreen.kt +++ b/minecraft/src/main/kotlin/org/polyfrost/oneconfig/internal/ui/compose/ComposeScreen.kt @@ -31,7 +31,11 @@ import net.minecraft.client.input.KeyEvent as McKeyEvent //? if > 1.8.9 { import net.minecraft.network.chat.CommonComponents //?} else { -/*import org.polyfrost.oneconfig.internal.legacy.KeyCodes +/*import net.minecraft.client.gui.screens.TitleScreen +import net.minecraft.client.render.platform.GlStateManager +import org.polyfrost.oneconfig.internal.legacy.KeyCodes +import org.polyfrost.oneconfig.internal.legacy.LegacyPanoramaTracker +import org.polyfrost.oneconfig.internal.ui.compose.opengl.StoredGLState import org.lwjgl.input.Keyboard import org.lwjgl.input.Mouse import org.lwjgl.sdl.SDLVideo @@ -103,6 +107,11 @@ abstract class ComposeScreen( protected val renderMode: RenderMode = RenderMode.ON_DEMAND, //~ if = 1.8.9 '(CommonComponents.EMPTY)' -> '()' ) : Screen(CommonComponents.EMPTY) { + //? if = 1.8.9 { + /*private val panorama = Platform.screen().current() as? TitleScreen ?: LegacyPanoramaTracker.current() + private val panoramaGlState = StoredGLState(330) + *///?} + enum class RenderMode { CONTINUOUS, @@ -288,6 +297,11 @@ abstract class ComposeScreen( //? if = 1.8.9 //Keyboard.enableRepeatEvents(true) + //? if = 1.8.9 { + /*panorama?.width = width + panorama?.height = height + *///?} + sceneDirty = true lastPointer = null @@ -342,9 +356,21 @@ abstract class ComposeScreen( //minecraft: Minecraft, width: Int, height: Int ) { + //? if = 1.8.9 { + /*this.width = width + this.height = height + panorama?.width = width + panorama?.height = height + *///?} syncSceneMetrics() } + //? if = 1.8.9 { + /*override fun tick() { + panorama?.tick() + } + *///?} + override fun isPauseScreen(): Boolean = false //? if > 1.8.9 { @@ -383,6 +409,20 @@ abstract class ComposeScreen( //?} else //override fun render(mouseX: Int, mouseY: Int, tickDelta: Float) { if (Platform.screen().current() !== this) return + //? if = 1.8.9 { + /*if (client.level == null && panorama != null) { + panoramaGlState.capture() + try { + GlStateManager.disableAlphaTest() + panorama.drawBackground(mouseX, mouseY, tickDelta) + GlStateManager.enableAlphaTest() + fillGradient(0, 0, width, height, -2130706433, 16777215) + fillGradient(0, 0, width, height, 0, Int.MIN_VALUE) + } finally { + panoramaGlState.restore() + } + } + *///?} if (scenePoisoned) { if (sceneRebuilds >= MAX_SCENE_REBUILDS) { LOGGER.error( diff --git a/minecraft/src/main/resources/oneconfigv1.classtweaker b/minecraft/src/main/resources/oneconfigv1.classtweaker index ec6072e14..9fd779001 100644 --- a/minecraft/src/main/resources/oneconfigv1.classtweaker +++ b/minecraft/src/main/resources/oneconfigv1.classtweaker @@ -2,6 +2,7 @@ classTweaker v2 named accessible field net/minecraft/client/Minecraft tasks Ljava/util/Queue; accessible field net/minecraft/client/render/texture/HttpTexture image Ljava/awt/image/BufferedImage; +accessible method net/minecraft/client/gui/screen/TitleScreen drawBackground (IIF)V transitive-inject-interface net/minecraft/client/Minecraft org/polyfrost/oneconfig/internal/legacy/compat/MinecraftCompat transitive-inject-interface net/minecraft/client/KeyMapping org/polyfrost/oneconfig/internal/legacy/compat/KeyBindingCompat