mirror of
https://github.com/CCBlueX/LiquidBounce.git
synced 2025-09-07 02:18:32 +00:00
feat(ScriptAPI): Implement GraalJS JIT with call target remapping (#4368)
Improves ScriptAPI by enabling GraalJS JIT while addressing Minecraft's obfuscation. Previously, non-JIT mode allowed remapping; however, this new approach applies a call target remapping strategy, overcoming bugs with overloaded names. Also, GraalVM is now the default JDK on LiquidLauncher. --------- Co-authored-by: Senk Ju <18741573+SenkJu@users.noreply.github.com>
This commit is contained in:
12
.github/workflows/build.yml
vendored
12
.github/workflows/build.yml
vendored
@@ -19,8 +19,8 @@ jobs:
|
|||||||
- name: Setting up JDK 21
|
- name: Setting up JDK 21
|
||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: temurin
|
distribution: 'graalvm'
|
||||||
java-version: 21
|
java-version: '21'
|
||||||
|
|
||||||
- name: Grant permissions to src-theme
|
- name: Grant permissions to src-theme
|
||||||
run: sudo chmod -R 777 src-theme
|
run: sudo chmod -R 777 src-theme
|
||||||
@@ -50,7 +50,7 @@ jobs:
|
|||||||
cd zip
|
cd zip
|
||||||
zip -r liquidbounce.zip *
|
zip -r liquidbounce.zip *
|
||||||
md5sum liquidbounce.zip
|
md5sum liquidbounce.zip
|
||||||
curl --connect-timeout 30 -m 300 -X POST -F "artifact=@liquidbounce.zip" -H "Authorization: ${{ secrets.NIGHTLY_PASS }}" -F "gh_id=${{ github.event.head_commit.id }}" -F "gh_ref=${{ github.ref }}" -F "gh_message=${{ github.event.head_commit.message }}" -F "gh_timestamp=${{ github.event.head_commit.timestamp }}" -F "lb_version=$LB_VERSION" -F "mc_version=$MINECRAFT_VERSION" -F "subsystem=fabric" -F "jre_version=21" -F "fabric_loader_version=$LOADER_VERSION" -F "fabric_api_version=$FABRICAPI_VERSION" -F "kotlin_version=$KOTLIN_VERSION" -F "fabric_kotlin_version=$FABRIC_KOTLIN_VERSION" https://api.liquidbounce.net/api/v1/version/new
|
curl --connect-timeout 30 -m 300 -X POST -F "artifact=@liquidbounce.zip" -H "Authorization: ${{ secrets.NIGHTLY_PASS }}" -F "gh_id=${{ github.event.head_commit.id }}" -F "gh_ref=${{ github.ref }}" -F "gh_message=${{ github.event.head_commit.message }}" -F "gh_timestamp=${{ github.event.head_commit.timestamp }}" -F "lb_version=$LB_VERSION" -F "mc_version=$MINECRAFT_VERSION" -F "subsystem=fabric" -F "jre_version=21" -F "jre_distribution=graalvm" -F "fabric_loader_version=$LOADER_VERSION" -F "fabric_api_version=$FABRICAPI_VERSION" -F "kotlin_version=$KOTLIN_VERSION" -F "fabric_kotlin_version=$FABRIC_KOTLIN_VERSION" https://api.liquidbounce.net/api/v1/version/new
|
||||||
|
|
||||||
verify-pr:
|
verify-pr:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -62,10 +62,10 @@ jobs:
|
|||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
- name: Setting up JDK 21
|
- name: Setting up JDK 21
|
||||||
uses: actions/setup-java@v3
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: temurin
|
distribution: 'graalvm'
|
||||||
java-version: 21
|
java-version: '21'
|
||||||
|
|
||||||
- name: Grant permissions to src-theme
|
- name: Grant permissions to src-theme
|
||||||
run: sudo chmod -R 777 src-theme
|
run: sudo chmod -R 777 src-theme
|
||||||
|
241
build.gradle
241
build.gradle
@@ -20,41 +20,42 @@
|
|||||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id 'fabric-loom'
|
id "fabric-loom"
|
||||||
id 'org.jetbrains.kotlin.jvm'
|
id "org.jetbrains.kotlin.jvm"
|
||||||
id 'com.github.johnrengelman.shadow' version '8.1.1'
|
id "com.gorylenko.gradle-git-properties" version "2.4.2"
|
||||||
id 'com.gorylenko.gradle-git-properties' version '2.4.2'
|
|
||||||
id "io.gitlab.arturbosch.detekt" version "1.23.6"
|
id "io.gitlab.arturbosch.detekt" version "1.23.6"
|
||||||
id "com.github.node-gradle.node" version "7.1.0"
|
id "com.github.node-gradle.node" version "7.1.0"
|
||||||
id 'org.jetbrains.dokka' version '1.9.10'
|
id "org.jetbrains.dokka" version "1.9.10"
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_21
|
|
||||||
targetCompatibility = JavaVersion.VERSION_21
|
|
||||||
|
|
||||||
archivesBaseName = project.archives_base_name
|
archivesBaseName = project.archives_base_name
|
||||||
version = project.mod_version
|
version = project.mod_version
|
||||||
group = project.maven_group
|
group = project.maven_group
|
||||||
|
|
||||||
loom {
|
configurations {
|
||||||
accessWidenerPath = file('src/main/resources/liquidbounce.accesswidener')
|
includeDependency
|
||||||
|
includeModDependency
|
||||||
|
|
||||||
|
include.extendsFrom includeModDependency
|
||||||
|
modImplementation.extendsFrom includeModDependency
|
||||||
|
modCompileOnlyApi.extendsFrom includeModDependency
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
mavenLocal()
|
mavenLocal()
|
||||||
maven { url = 'https://maven.fabricmc.net/' }
|
maven { url = "https://maven.fabricmc.net/" }
|
||||||
maven {
|
maven {
|
||||||
name = 'Jitpack'
|
name = "Jitpack"
|
||||||
url = 'https://jitpack.io'
|
url = "https://jitpack.io"
|
||||||
}
|
}
|
||||||
maven {
|
maven {
|
||||||
name = 'TerraformersMC'
|
name = "TerraformersMC"
|
||||||
url = 'https://maven.terraformersmc.com/'
|
url = "https://maven.terraformersmc.com/"
|
||||||
}
|
}
|
||||||
maven {
|
maven {
|
||||||
name = 'ViaVersion'
|
name = "ViaVersion"
|
||||||
url = 'https://repo.viaversion.com/'
|
url = "https://repo.viaversion.com/"
|
||||||
}
|
}
|
||||||
maven {
|
maven {
|
||||||
name = "modrinth"
|
name = "modrinth"
|
||||||
@@ -70,83 +71,80 @@ repositories {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
loom {
|
||||||
testImplementation 'org.junit.jupiter:junit-jupiter:5.11.3'
|
accessWidenerPath = file("src/main/resources/liquidbounce.accesswidener")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
// Minecraft
|
// Minecraft
|
||||||
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
||||||
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
|
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
|
||||||
|
|
||||||
// Libraries (required mods)
|
// Fabric
|
||||||
|
|
||||||
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
||||||
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
||||||
modImplementation "net.fabricmc:fabric-language-kotlin:${project.fabric_kotlin_version}"
|
modImplementation "net.fabricmc:fabric-language-kotlin:${project.fabric_kotlin_version}"
|
||||||
|
|
||||||
implementation "net.fabricmc:tiny-mappings-parser:0.3.0+build.17"
|
|
||||||
|
|
||||||
// Recommended mods (on IDE)
|
// Recommended mods (on IDE)
|
||||||
modRuntimeOnly "com.terraformersmc:modmenu:${project.mod_menu_version}"
|
modRuntimeOnly "com.terraformersmc:modmenu:${project.mod_menu_version}"
|
||||||
modImplementation "maven.modrinth:sodium:${project.sodium_version}"
|
modImplementation "maven.modrinth:sodium:${project.sodium_version}"
|
||||||
modImplementation "de.florianmichael:ViaFabricPlus:${project.viafabricplus_version}"
|
modCompileOnly "de.florianmichael:ViaFabricPlus:${project.viafabricplus_version}"
|
||||||
|
|
||||||
// Tests
|
// Minecraft Authlib
|
||||||
// modImplementation 'com.github.superblaubeere27:tenacc:e3a7ada99a'
|
includeDependency ("com.github.CCBlueX:mc-authlib:${project.mc_authlib_version}") {
|
||||||
|
exclude group: "com.google.code.gson", module: "gson"
|
||||||
// fix nullable imports
|
exclude group: "org.apache.logging.log4j", module: "log4j-core"
|
||||||
implementation 'com.google.code.findbugs:jsr305:3.0.2'
|
exclude group: "org.apache.logging.log4j", module: "log4j-api"
|
||||||
|
exclude group: "org.apache.logging.log4j", module: "log4j-slf4j-impl"
|
||||||
// Client libraries
|
exclude group: "org.slf4j", module: "slf4j-api"
|
||||||
implementation("com.github.CCBlueX:mc-authlib:${project.mc_authlib_version}") {
|
exclude group: "com.mojang", module: "authlib"
|
||||||
exclude group: 'com.google.code.gson', module: 'gson'
|
|
||||||
exclude group: 'org.apache.logging.log4j', module: 'log4j-core'
|
|
||||||
exclude group: 'org.apache.logging.log4j', module: 'log4j-api'
|
|
||||||
exclude group: 'org.apache.logging.log4j', module: 'log4j-slf4j-impl'
|
|
||||||
exclude group: 'org.slf4j', module: 'slf4j-api'
|
|
||||||
exclude group: 'com.mojang', module: 'authlib'
|
|
||||||
}
|
}
|
||||||
implementation "com.github.CCBlueX:mcef:916f8c5f73"
|
|
||||||
implementation 'com.github.CCBlueX:netty-httpserver:2.1.0'
|
|
||||||
implementation "com.github.CCBlueX:DiscordIPC:-SNAPSHOT"
|
|
||||||
|
|
||||||
implementation 'org.graalvm.sdk:graal-sdk:23.0.5'
|
// JCEF Support
|
||||||
implementation 'org.graalvm.truffle:truffle-api:23.0.5'
|
includeModDependency "com.github.CCBlueX:mcef:1.1.5-1.21.1"
|
||||||
implementation 'org.graalvm.js:js:23.0.5'
|
includeDependency "org.apache.commons:commons-exec:1.3"
|
||||||
|
includeDependency ("com.github.CCBlueX:netty-httpserver:2.1.0") {
|
||||||
|
exclude group: "io.netty", module: "netty-all"
|
||||||
|
}
|
||||||
|
|
||||||
runtimeOnly 'org.graalvm.tools:profiler:23.0.5'
|
// Discord RPC Support
|
||||||
runtimeOnly 'org.graalvm.tools:chromeinspector:23.0.5'
|
includeDependency "com.github.CCBlueX:DiscordIPC:4.0.0"
|
||||||
|
|
||||||
// https://mvnrepository.com/artifact/io.netty/netty-codec
|
// ScriptAPI
|
||||||
implementation 'io.netty:netty-codec:4.1.82.Final'
|
includeDependency "net.fabricmc:tiny-mappings-parser:0.3.0+build.17"
|
||||||
// https://mvnrepository.com/artifact/io.netty/netty-codec-http
|
includeDependency "org.graalvm.polyglot:polyglot:24.0.2"
|
||||||
implementation 'io.netty:netty-codec-http:4.1.82.Final'
|
includeDependency "org.graalvm.polyglot:js-community:24.0.2"
|
||||||
// https://mvnrepository.com/artifact/io.netty/netty-handler-proxy
|
|
||||||
implementation 'io.netty:netty-handler-proxy:4.1.82.Final'
|
|
||||||
// https://mvnrepository.com/artifact/io.netty/netty-codec-socks
|
|
||||||
implementation 'io.netty:netty-codec-socks:4.1.82.Final'
|
|
||||||
|
|
||||||
implementation 'com.vdurmont:semver4j:3.1.0'
|
// SOCKS5 Proxy Support (to stay compatible with ViaFabricPlus)
|
||||||
implementation 'org.apache.tika:tika-core:3.0.0'
|
includeDependency "io.netty:netty-handler-proxy:4.1.114.Final"
|
||||||
|
|
||||||
implementation 'org.apache.commons:commons-exec:1.3'
|
// Update Checker
|
||||||
|
includeDependency "com.vdurmont:semver4j:3.1.0"
|
||||||
|
|
||||||
// Test libraries
|
// Test libraries
|
||||||
|
testImplementation "org.junit.jupiter:junit-jupiter:5.11.3"
|
||||||
|
testRuntimeOnly "org.junit.platform:junit-platform-launcher"
|
||||||
|
|
||||||
testImplementation 'org.junit.jupiter:junit-jupiter:5.11.3'
|
afterEvaluate {
|
||||||
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
|
configurations.includeDependency.incoming.resolutionResult.allDependencies.each {
|
||||||
|
dependencies.include(dependencies.implementation(dependencies.compileOnlyApi(it.requested.toString()) {
|
||||||
|
transitive = false
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
processResources {
|
processResources {
|
||||||
inputs.property 'version', project.version
|
inputs.property "version", project.version
|
||||||
|
|
||||||
inputs.property 'minecraft_version', minecraft_version
|
inputs.property "minecraft_version", minecraft_version
|
||||||
inputs.property 'fabric_version', fabric_version
|
inputs.property "fabric_version", fabric_version
|
||||||
inputs.property 'loader_version', loader_version
|
inputs.property "loader_version", loader_version
|
||||||
inputs.property 'min_loader_version', min_loader_version
|
inputs.property "min_loader_version", min_loader_version
|
||||||
inputs.property 'fabric_kotlin_version', fabric_kotlin_version
|
inputs.property "fabric_kotlin_version", fabric_kotlin_version
|
||||||
inputs.property 'viafabricplus_version', viafabricplus_version
|
inputs.property "viafabricplus_version", viafabricplus_version
|
||||||
|
|
||||||
filesMatching('fabric.mod.json') {
|
filesMatching("fabric.mod.json") {
|
||||||
expand([
|
expand([
|
||||||
version : project.version,
|
version : project.version,
|
||||||
minecraft_version : minecraft_version,
|
minecraft_version : minecraft_version,
|
||||||
@@ -161,60 +159,60 @@ processResources {
|
|||||||
|
|
||||||
// The following code will include the theme into the build
|
// The following code will include the theme into the build
|
||||||
|
|
||||||
tasks.register('npmInstallTheme', NpmTask) {
|
tasks.register("npmInstallTheme", NpmTask) {
|
||||||
workingDir = file('src-theme')
|
workingDir = file("src-theme")
|
||||||
args = ['i']
|
args = ["i"]
|
||||||
doLast {
|
doLast {
|
||||||
println 'Successfully installed dependencies for theme'
|
println "Successfully installed dependencies for theme"
|
||||||
}
|
}
|
||||||
|
|
||||||
inputs.files('src-theme/package.json', 'src-theme/package-lock.json')
|
inputs.files("src-theme/package.json", "src-theme/package-lock.json")
|
||||||
outputs.dir("src-theme/node_modules")
|
outputs.dir("src-theme/node_modules")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.register('buildTheme', NpmTask) {
|
tasks.register("buildTheme", NpmTask) {
|
||||||
dependsOn 'npmInstallTheme'
|
dependsOn "npmInstallTheme"
|
||||||
workingDir = file('src-theme')
|
workingDir = file("src-theme")
|
||||||
args = ['run', 'build']
|
args = ["run", "build"]
|
||||||
doLast {
|
doLast {
|
||||||
println 'Successfully build theme'
|
println "Successfully build theme"
|
||||||
}
|
}
|
||||||
|
|
||||||
inputs.files(
|
inputs.files(
|
||||||
'src-theme/package.json',
|
"src-theme/package.json",
|
||||||
'src-theme/package-lock.json',
|
"src-theme/package-lock.json",
|
||||||
'src-theme/bundle.cjs',
|
"src-theme/bundle.cjs",
|
||||||
'src-theme/rollup.config.js'
|
"src-theme/rollup.config.js"
|
||||||
)
|
)
|
||||||
inputs.dir("src-theme/src")
|
inputs.dir("src-theme/src")
|
||||||
outputs.dir('src-theme/dist')
|
outputs.dir("src-theme/dist")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.register('bundleTheme', NodeTask) {
|
tasks.register("bundleTheme", NodeTask) {
|
||||||
dependsOn 'buildTheme'
|
dependsOn "buildTheme"
|
||||||
workingDir = file('src-theme')
|
workingDir = file("src-theme")
|
||||||
script = file('src-theme/bundle.cjs')
|
script = file("src-theme/bundle.cjs")
|
||||||
doLast {
|
doLast {
|
||||||
println 'Successfully attached theme to build'
|
println "Successfully attached theme to build"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Incremental stuff
|
// Incremental stuff
|
||||||
inputs.files(
|
inputs.files(
|
||||||
'src-theme/package.json',
|
"src-theme/package.json",
|
||||||
'src-theme/package-lock.json',
|
"src-theme/package-lock.json",
|
||||||
'src-theme/bundle.cjs',
|
"src-theme/bundle.cjs",
|
||||||
'src-theme/rollup.config.js'
|
"src-theme/rollup.config.js"
|
||||||
)
|
)
|
||||||
inputs.dir("src-theme/src")
|
inputs.dir("src-theme/src")
|
||||||
inputs.dir("src-theme/public")
|
inputs.dir("src-theme/public")
|
||||||
inputs.dir("src-theme/dist")
|
inputs.dir("src-theme/dist")
|
||||||
outputs.files('src-theme/resources/assets/liquidbounce/default_theme.zip')
|
outputs.files("src-theme/resources/assets/liquidbounce/default_theme.zip")
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
main {
|
main {
|
||||||
resources {
|
resources {
|
||||||
srcDirs 'src-theme/resources'
|
srcDirs "src-theme/resources"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -229,7 +227,7 @@ tasks.withType(JavaCompile).configureEach {
|
|||||||
// this fixes some edge cases with special characters not displaying correctly
|
// this fixes some edge cases with special characters not displaying correctly
|
||||||
// see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html
|
// see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html
|
||||||
// If Javadoc is generated, this must be specified in that task too.
|
// If Javadoc is generated, this must be specified in that task too.
|
||||||
it.options.encoding = 'UTF-8'
|
it.options.encoding = "UTF-8"
|
||||||
|
|
||||||
// Minecraft 1.20.5 upwards uses Java 17.
|
// Minecraft 1.20.5 upwards uses Java 17.
|
||||||
it.options.release = 21
|
it.options.release = 21
|
||||||
@@ -237,6 +235,7 @@ tasks.withType(JavaCompile).configureEach {
|
|||||||
|
|
||||||
tasks.withType(Test).configureEach {
|
tasks.withType(Test).configureEach {
|
||||||
useJUnitPlatform()
|
useJUnitPlatform()
|
||||||
|
dependsOn(tasks.named("genSources"))
|
||||||
}
|
}
|
||||||
|
|
||||||
detekt {
|
detekt {
|
||||||
@@ -264,6 +263,9 @@ java {
|
|||||||
// if it is present.
|
// if it is present.
|
||||||
// If you remove this line, sources will not be generated.
|
// If you remove this line, sources will not be generated.
|
||||||
withSourcesJar()
|
withSourcesJar()
|
||||||
|
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_21
|
||||||
|
targetCompatibility = JavaVersion.VERSION_21
|
||||||
}
|
}
|
||||||
|
|
||||||
compileKotlin {
|
compileKotlin {
|
||||||
@@ -273,49 +275,22 @@ compileKotlin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shadowJar {
|
jar {
|
||||||
archiveClassifier.set('shadow')
|
// Rename the project"s license file to LICENSE_<project_name> to avoid conflicts
|
||||||
|
from("LICENSE") {
|
||||||
|
rename {
|
||||||
|
"${it}_${project.archives_base_name}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Natives are going to be downloaded from our cloud
|
from(configurations.mappings.collect { zipTree(it) }) {
|
||||||
exclude 'native-binaries/*'
|
include "mappings/mappings.tiny"
|
||||||
|
|
||||||
// META-INF/versions/20
|
|
||||||
exclude "META-INF/versions/20/**"
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
include(dependency('com.github.CCBlueX:mcef'))
|
|
||||||
include(dependency('com.github.CCBlueX:netty-httpserver'))
|
|
||||||
include(dependency('com.github.CCBlueX:mc-authlib'))
|
|
||||||
include(dependency('com.github.CCBlueX:DiscordIPC'))
|
|
||||||
include(dependency('com.thealtening.api:api'))
|
|
||||||
include(dependency('net.fabricmc:tiny-mappings-parser'))
|
|
||||||
include(dependency('org.graalvm.sdk:graal-sdk'))
|
|
||||||
include(dependency('org.graalvm.truffle:truffle-api'))
|
|
||||||
include(dependency('org.graalvm.js:js'))
|
|
||||||
include(dependency('io.netty:netty-codec'))
|
|
||||||
include(dependency('io.netty:netty-codec-http'))
|
|
||||||
include(dependency('io.netty:netty-handler-proxy'))
|
|
||||||
include(dependency('io.netty:netty-codec-socks'))
|
|
||||||
include(dependency('org.apache.commons:commons-exec'))
|
|
||||||
include(dependency('org.apache.tika:tika-core'))
|
|
||||||
include(dependency('com.vdurmont:semver4j'))
|
|
||||||
include(dependency('com.kohlschutter.junixsocket:junixsocket-common'))
|
|
||||||
include(dependency('com.kohlschutter.junixsocket:junixsocket-native-common'))
|
|
||||||
include(dependency('net.lenni0451:Reflect'))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jar {
|
tasks.register("copyZipInclude", Copy) {
|
||||||
from 'LICENSE'
|
from "zip_include/"
|
||||||
}
|
into "build/libs/zip"
|
||||||
|
|
||||||
remapJar {
|
|
||||||
inputFile = shadowJar.archiveFile
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.register('copyZipInclude', Copy) {
|
|
||||||
from 'zip_include/'
|
|
||||||
into 'build/libs/zip'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sourcesJar.dependsOn bundleTheme
|
sourcesJar.dependsOn bundleTheme
|
||||||
|
@@ -22,13 +22,13 @@ org.gradle.jvmargs=-Xms1024m -Xmx4096m
|
|||||||
# Check these on https://fabricmc.net/versions.html
|
# Check these on https://fabricmc.net/versions.html
|
||||||
minecraft_version=1.21.1
|
minecraft_version=1.21.1
|
||||||
yarn_mappings=1.21.1+build.3
|
yarn_mappings=1.21.1+build.3
|
||||||
loader_version=0.16.3
|
loader_version=0.16.9
|
||||||
min_loader_version=0.15.10
|
min_loader_version=0.15.10
|
||||||
|
|
||||||
# Fabric API
|
# Fabric API
|
||||||
fabric_version=0.102.1+1.21.1
|
fabric_version=0.107.0+1.21.1
|
||||||
# Loom
|
# Loom
|
||||||
loom_version=1.7-SNAPSHOT
|
loom_version=1.8-SNAPSHOT
|
||||||
# Mod Properties
|
# Mod Properties
|
||||||
mod_version=0.17.1
|
mod_version=0.17.1
|
||||||
maven_group=net.ccbluex
|
maven_group=net.ccbluex
|
||||||
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
@@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
pluginManagement {
|
pluginManagement {
|
||||||
repositories {
|
repositories {
|
||||||
jcenter()
|
|
||||||
maven {
|
maven {
|
||||||
name = 'Fabric'
|
name = 'Fabric'
|
||||||
url = 'https://maven.fabricmc.net/'
|
url = 'https://maven.fabricmc.net/'
|
||||||
@@ -33,5 +32,3 @@ pluginManagement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//include('mcef')
|
|
||||||
|
@@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of LiquidBounce (https://github.com/CCBlueX/LiquidBounce)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015 - 2024 CCBlueX
|
|
||||||
*
|
|
||||||
* LiquidBounce is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* LiquidBounce is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with LiquidBounce. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package net.ccbluex.liquidbounce.injection.mixins.graaljs;
|
|
||||||
|
|
||||||
import net.ccbluex.liquidbounce.utils.mappings.Remapper;
|
|
||||||
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.ModifyVariable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remaps class method and field names to their obfuscated counterparts.
|
|
||||||
*
|
|
||||||
* Initial code by lit
|
|
||||||
*/
|
|
||||||
@Mixin(targets = "com/oracle/truffle/host/HostClassDesc")
|
|
||||||
public abstract class MixinHostClassDesc {
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
public abstract Class<?> getType();
|
|
||||||
|
|
||||||
@ModifyVariable(method = "lookupField(Ljava/lang/String;)Lcom/oracle/truffle/host/HostFieldDesc;",
|
|
||||||
at = @At("HEAD"), argsOnly = true, index = 1, remap = false)
|
|
||||||
private String remapFieldName(String name) {
|
|
||||||
return Remapper.INSTANCE.remapField(getType(), name, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ModifyVariable(method = "lookupStaticField", at = @At("HEAD"), argsOnly = true, index = 1, remap = false)
|
|
||||||
private String remapStaticFieldName(String name) {
|
|
||||||
return Remapper.INSTANCE.remapField(getType(), name, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ModifyVariable(method = "lookupMethod(Ljava/lang/String;)Lcom/oracle/truffle/host/HostMethodDesc;",
|
|
||||||
at = @At("HEAD"), argsOnly = true, index = 1, remap = false)
|
|
||||||
private String remapMethodName(String name) {
|
|
||||||
return Remapper.INSTANCE.remapMethod(getType(), name, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ModifyVariable(method = "lookupStaticMethod", at = @At("HEAD"), argsOnly = true, index = 1, remap = false)
|
|
||||||
private String remapStaticMethodName(String name) {
|
|
||||||
return Remapper.INSTANCE.remapMethod(getType(), name, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,17 +0,0 @@
|
|||||||
package net.ccbluex.liquidbounce.injection.mixins.graaljs;
|
|
||||||
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Overwrite;
|
|
||||||
|
|
||||||
@Mixin(targets = "com/oracle/truffle/api/TruffleLanguage")
|
|
||||||
public class MixinTruffleLanguage {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Senk Ju
|
|
||||||
* @reason Prevent GraalVM from blocking multi threaded access to resources
|
|
||||||
*/
|
|
||||||
@Overwrite(remap = false)
|
|
||||||
protected boolean isThreadAccessAllowed(Thread thread, boolean singleThreaded) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -0,0 +1,140 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of LiquidBounce (https://github.com/CCBlueX/LiquidBounce)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 - 2024 CCBlueX
|
||||||
|
*
|
||||||
|
* LiquidBounce is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* LiquidBounce is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with LiquidBounce. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.ccbluex.liquidbounce.injection.mixins.truffle;
|
||||||
|
|
||||||
|
import net.ccbluex.liquidbounce.interfaces.MemberRetriever;
|
||||||
|
import net.ccbluex.liquidbounce.utils.client.ClientUtilsKt;
|
||||||
|
import net.ccbluex.liquidbounce.utils.mappings.EnvironmentRemapper;
|
||||||
|
import org.spongepowered.asm.mixin.*;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Member;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Pseudo
|
||||||
|
@Mixin(targets = "com/oracle/truffle/host/HostClassDesc$Members")
|
||||||
|
public abstract class MixinHostClassDesc {
|
||||||
|
|
||||||
|
@Shadow(remap = false)
|
||||||
|
@Final
|
||||||
|
Map<String, Object> methods;
|
||||||
|
|
||||||
|
@Shadow(remap = false)
|
||||||
|
@Final
|
||||||
|
Map<String, Object> fields;
|
||||||
|
|
||||||
|
@Shadow(remap = false)
|
||||||
|
@Final
|
||||||
|
Map<String, Object> staticFields;
|
||||||
|
|
||||||
|
@Shadow(remap = false)
|
||||||
|
@Final
|
||||||
|
Map<String, Object> staticMethods;
|
||||||
|
|
||||||
|
@Inject(method = "<init>", at = @At("RETURN"), remap = false)
|
||||||
|
private void remapClassDesc(CallbackInfo ci) {
|
||||||
|
remapEntries(methods, this::getMethod);
|
||||||
|
remapEntries(fields, this::getField);
|
||||||
|
remapEntries(staticFields, this::getField);
|
||||||
|
remapEntries(staticMethods, this::getMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private void remapEntries(Map<String, Object> map, MemberRetriever retriever) {
|
||||||
|
var entries = new HashMap<>(map).entrySet();
|
||||||
|
|
||||||
|
for (var entry : entries) {
|
||||||
|
String key = entry.getKey();
|
||||||
|
Object value = entry.getValue();
|
||||||
|
String remapped;
|
||||||
|
|
||||||
|
try {
|
||||||
|
Member member = retriever.getMember(value);
|
||||||
|
remapped = remapDescriptor(member);
|
||||||
|
} catch (ReflectiveOperationException e) {
|
||||||
|
ClientUtilsKt.getLogger().error("Failed to remap: {}", key, e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remapped != null) {
|
||||||
|
map.remove(key);
|
||||||
|
map.put(remapped, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private Member getMethod(Object o) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
||||||
|
try {
|
||||||
|
// If this works, it is likely a SingleMethod instance
|
||||||
|
Method descMethod = o.getClass().getDeclaredMethod("getReflectionMethod");
|
||||||
|
|
||||||
|
descMethod.setAccessible(true);
|
||||||
|
return (Member) descMethod.invoke(o);
|
||||||
|
} catch (NoSuchMethodException ignored) {
|
||||||
|
try {
|
||||||
|
var getOverloads = o.getClass().getDeclaredMethod("getOverloads");
|
||||||
|
var overloads = (Object[]) getOverloads.invoke(o);
|
||||||
|
|
||||||
|
return getMethod(overloads[0]);
|
||||||
|
} catch (NoSuchMethodException ignored2) {
|
||||||
|
ClientUtilsKt.getLogger().error("Unsupported method type: {}", o.getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private Member getField(Object o) throws IllegalAccessException, NoSuchFieldException {
|
||||||
|
var descField = o.getClass().getDeclaredField("field");
|
||||||
|
descField.setAccessible(true);
|
||||||
|
return (Member) descField.get(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private static String remapDescriptor(Member member) {
|
||||||
|
var name = member.getName();
|
||||||
|
|
||||||
|
String remapped;
|
||||||
|
if (member instanceof java.lang.reflect.Method) {
|
||||||
|
remapped = EnvironmentRemapper.INSTANCE.remapMethod(member.getDeclaringClass(), name);
|
||||||
|
} else if (member instanceof java.lang.reflect.Field) {
|
||||||
|
remapped = EnvironmentRemapper.INSTANCE.remapField(member.getDeclaringClass(), name);
|
||||||
|
} else {
|
||||||
|
ClientUtilsKt.getLogger().error("Unknown member type: {}", member.getClass().getName());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the name is the same, return the original field
|
||||||
|
if (name.equals(remapped)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClientUtilsKt.getLogger().debug("Remapped descriptor: {} in {} to {}", name, member.getDeclaringClass().getName(), remapped);
|
||||||
|
return remapped;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -17,24 +17,21 @@
|
|||||||
* along with LiquidBounce. If not, see <https://www.gnu.org/licenses/>.
|
* along with LiquidBounce. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.ccbluex.liquidbounce.injection.mixins.graaljs;
|
package net.ccbluex.liquidbounce.injection.mixins.truffle;
|
||||||
|
|
||||||
import net.ccbluex.liquidbounce.utils.mappings.Remapper;
|
import net.ccbluex.liquidbounce.utils.mappings.EnvironmentRemapper;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Pseudo;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||||
|
|
||||||
/**
|
@Pseudo
|
||||||
* Remaps class names to their obfuscated counterparts.
|
@Mixin(targets = "com/oracle/truffle/host/HostClassLoader", remap = false)
|
||||||
*
|
|
||||||
* Initial code by lit
|
|
||||||
*/
|
|
||||||
@Mixin(targets = "com/oracle/truffle/host/HostClassLoader")
|
|
||||||
public class MixinHostClassLoader {
|
public class MixinHostClassLoader {
|
||||||
|
|
||||||
@ModifyVariable(method = "findClass", at = @At("HEAD"), argsOnly = true, remap = false)
|
@ModifyVariable(method = "findClass", at = @At("HEAD"), argsOnly = true, remap = false)
|
||||||
private String remapClassName(String value) {
|
private String remapClassName(String value) {
|
||||||
return Remapper.INSTANCE.remapClassName(value);
|
return EnvironmentRemapper.INSTANCE.remapClassName(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@@ -19,19 +19,21 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.ccbluex.liquidbounce.injection.mixins.graaljs;
|
package net.ccbluex.liquidbounce.injection.mixins.truffle;
|
||||||
|
|
||||||
import net.ccbluex.liquidbounce.utils.mappings.Remapper;
|
import net.ccbluex.liquidbounce.utils.mappings.EnvironmentRemapper;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Pseudo;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||||
|
|
||||||
@Mixin(targets = "com/oracle/truffle/host/HostContext")
|
@Pseudo
|
||||||
|
@Mixin(targets = "com/oracle/truffle/host/HostContext", remap = false)
|
||||||
public class MixinHostContext {
|
public class MixinHostContext {
|
||||||
|
|
||||||
@ModifyVariable(method = "findClassImpl", at = @At("HEAD"), argsOnly = true, remap = false)
|
@ModifyVariable(method = "findClassImpl", at = @At("HEAD"), argsOnly = true, remap = false)
|
||||||
private String remapClassName(String value) {
|
private String remapClassName(String value) {
|
||||||
return Remapper.INSTANCE.remapClassName(value);
|
return EnvironmentRemapper.INSTANCE.remapClassName(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of LiquidBounce (https://github.com/CCBlueX/LiquidBounce)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 - 2024 CCBlueX
|
||||||
|
*
|
||||||
|
* LiquidBounce is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* LiquidBounce is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with LiquidBounce. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.ccbluex.liquidbounce.injection.mixins.truffle;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
import org.spongepowered.asm.mixin.Pseudo;
|
||||||
|
|
||||||
|
@Pseudo
|
||||||
|
@Mixin(targets = "com/oracle/truffle/api/TruffleLanguage", remap = false)
|
||||||
|
public class MixinTruffleLanguage {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Senk Ju
|
||||||
|
* @reason Prevent GraalVM from blocking multithreaded access to resources
|
||||||
|
*/
|
||||||
|
@Overwrite(remap = false)
|
||||||
|
protected boolean isThreadAccessAllowed(Thread thread, boolean singleThreaded) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of LiquidBounce (https://github.com/CCBlueX/LiquidBounce)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 - 2024 CCBlueX
|
||||||
|
*
|
||||||
|
* LiquidBounce is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* LiquidBounce is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with LiquidBounce. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.ccbluex.liquidbounce.interfaces;
|
||||||
|
|
||||||
|
import java.lang.reflect.Member;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface MemberRetriever {
|
||||||
|
Member getMember(Object o) throws ReflectiveOperationException;
|
||||||
|
}
|
@@ -62,7 +62,7 @@ import net.ccbluex.liquidbounce.utils.combat.CombatManager
|
|||||||
import net.ccbluex.liquidbounce.utils.combat.combatTargetsConfigurable
|
import net.ccbluex.liquidbounce.utils.combat.combatTargetsConfigurable
|
||||||
import net.ccbluex.liquidbounce.utils.input.InputTracker
|
import net.ccbluex.liquidbounce.utils.input.InputTracker
|
||||||
import net.ccbluex.liquidbounce.utils.inventory.InventoryManager
|
import net.ccbluex.liquidbounce.utils.inventory.InventoryManager
|
||||||
import net.ccbluex.liquidbounce.utils.mappings.Remapper
|
import net.ccbluex.liquidbounce.utils.mappings.EnvironmentRemapper
|
||||||
import net.ccbluex.liquidbounce.utils.render.WorldToScreen
|
import net.ccbluex.liquidbounce.utils.render.WorldToScreen
|
||||||
import net.minecraft.resource.ReloadableResourceManagerImpl
|
import net.minecraft.resource.ReloadableResourceManagerImpl
|
||||||
import net.minecraft.resource.ResourceManager
|
import net.minecraft.resource.ResourceManager
|
||||||
@@ -122,7 +122,7 @@ object LiquidBounce : Listenable {
|
|||||||
logger.debug("Loading from cloud: '$CLIENT_CLOUD'")
|
logger.debug("Loading from cloud: '$CLIENT_CLOUD'")
|
||||||
|
|
||||||
// Load mappings
|
// Load mappings
|
||||||
Remapper.load()
|
EnvironmentRemapper
|
||||||
|
|
||||||
// Load translations
|
// Load translations
|
||||||
LanguageManager.loadLanguages()
|
LanguageManager.loadLanguages()
|
||||||
|
@@ -18,13 +18,13 @@
|
|||||||
*/
|
*/
|
||||||
package net.ccbluex.liquidbounce.script.bindings.api
|
package net.ccbluex.liquidbounce.script.bindings.api
|
||||||
|
|
||||||
import net.ccbluex.liquidbounce.utils.mappings.Remapper
|
import net.ccbluex.liquidbounce.utils.mappings.EnvironmentRemapper
|
||||||
|
|
||||||
object JsReflectionUtil {
|
object JsReflectionUtil {
|
||||||
|
|
||||||
@JvmName("classByName")
|
@JvmName("classByName")
|
||||||
fun classByName(name: String): Class<*> = Class.forName(
|
fun classByName(name: String): Class<*> = Class.forName(
|
||||||
Remapper.remapClassName(name).replace('/', '.')
|
EnvironmentRemapper.remapClassName(name).replace('/', '.')
|
||||||
)
|
)
|
||||||
|
|
||||||
@JvmName("classByObject")
|
@JvmName("classByObject")
|
||||||
@@ -38,7 +38,7 @@ object JsReflectionUtil {
|
|||||||
|
|
||||||
@JvmName("newInstanceByName")
|
@JvmName("newInstanceByName")
|
||||||
fun newInstanceByName(name: String, vararg args: Any?): Any? =
|
fun newInstanceByName(name: String, vararg args: Any?): Any? =
|
||||||
Class.forName(Remapper.remapClassName(name).replace('/', '.'))
|
Class.forName(EnvironmentRemapper.remapClassName(name).replace('/', '.'))
|
||||||
.getDeclaredConstructor(*args.map { it!!::class.java }.toTypedArray()).apply {
|
.getDeclaredConstructor(*args.map { it!!::class.java }.toTypedArray()).apply {
|
||||||
isAccessible = true
|
isAccessible = true
|
||||||
}.newInstance(*args)
|
}.newInstance(*args)
|
||||||
@@ -50,35 +50,37 @@ object JsReflectionUtil {
|
|||||||
}.newInstance(*args)
|
}.newInstance(*args)
|
||||||
|
|
||||||
@JvmName("getField")
|
@JvmName("getField")
|
||||||
fun getField(obj: Any, name: String): Any? = obj::class.java.getDeclaredField(
|
fun getField(obj: Any, name: String): Any? = obj::class.java.fields
|
||||||
Remapper.remapField(obj::class.java, name, true)
|
.find { field ->
|
||||||
).apply {
|
field.name == EnvironmentRemapper.remapField(obj::class.java, name)
|
||||||
isAccessible = true
|
}?.apply {
|
||||||
}.get(obj)
|
isAccessible = true
|
||||||
|
}?.get(obj)
|
||||||
|
|
||||||
@JvmName("getStaticField")
|
@JvmName("getDeclaredField")
|
||||||
fun getStaticField(clazz: Class<*>, name: String): Any? = clazz.getDeclaredField(
|
fun getDeclaredField(clazz: Class<*>, name: String): Any? = clazz.declaredFields
|
||||||
Remapper.remapField(clazz, name, true)
|
.find { field ->
|
||||||
).apply {
|
field.name == EnvironmentRemapper.remapField(clazz, name)
|
||||||
isAccessible = true
|
}?.apply {
|
||||||
}.get(null)
|
isAccessible = true
|
||||||
|
}?.get(null)
|
||||||
|
|
||||||
@JvmName("invokeMethod")
|
@JvmName("invokeMethod")
|
||||||
fun invokeMethod(obj: Any, name: String, vararg args: Any?): Any? =
|
fun invokeMethod(obj: Any, name: String, vararg args: Any?): Any? =
|
||||||
obj::class.java.getDeclaredMethod(
|
obj::class.java.methods.find { method ->
|
||||||
Remapper.remapField(obj::class.java, name, true),
|
method.name == EnvironmentRemapper.remapMethod(obj::class.java, name) &&
|
||||||
*args.map { it!!::class.java }.toTypedArray()
|
method.parameterTypes.contentEquals(args.map { it!!::class.java }.toTypedArray())
|
||||||
).apply {
|
}?.apply {
|
||||||
isAccessible = true
|
isAccessible = true
|
||||||
}.invoke(obj, *args)
|
}?.invoke(obj, *args)
|
||||||
|
|
||||||
@JvmName("invokeStaticMethod")
|
@JvmName("invokeDeclaredMethod")
|
||||||
fun invokeStaticMethod(clazz: Class<*>, name: String, vararg args: Any?): Any? =
|
fun invokeDeclaredMethod(clazz: Class<*>, name: String, vararg args: Any?): Any? =
|
||||||
clazz.getDeclaredMethod(
|
clazz.declaredMethods.find { method ->
|
||||||
Remapper.remapField(clazz, name, true),
|
method.name == EnvironmentRemapper.remapMethod(clazz, name) &&
|
||||||
*args.map { it!!::class.java }.toTypedArray()
|
method.parameterTypes.contentEquals(args.map { it!!::class.java }.toTypedArray())
|
||||||
).apply {
|
}?.apply {
|
||||||
isAccessible = true
|
isAccessible = true
|
||||||
}.invoke(null, *args)
|
}?.invoke(null, *args)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,102 @@
|
|||||||
|
package net.ccbluex.liquidbounce.utils.mappings
|
||||||
|
|
||||||
|
import net.ccbluex.liquidbounce.utils.client.logger
|
||||||
|
import net.ccbluex.liquidbounce.utils.io.resource
|
||||||
|
import net.fabricmc.mappings.model.V2MappingsProvider
|
||||||
|
|
||||||
|
object EnvironmentRemapper {
|
||||||
|
|
||||||
|
private var mappings = runCatching {
|
||||||
|
V2MappingsProvider.readTinyMappings(resource("/mappings/mappings.tiny").bufferedReader())
|
||||||
|
}.onFailure {
|
||||||
|
logger.error("Unable to load mappings. Ignore this if you are using a development environment.", it)
|
||||||
|
}.getOrNull()
|
||||||
|
|
||||||
|
private var environment = runCatching {
|
||||||
|
probeEnvironment()
|
||||||
|
}.onFailure {
|
||||||
|
logger.error("Unable to probe environment. Please make sure you are using a valid environment.", it)
|
||||||
|
}.getOrNull()
|
||||||
|
|
||||||
|
private fun probeEnvironment(): String? {
|
||||||
|
val mappings = mappings ?: return null
|
||||||
|
|
||||||
|
val minecraftClassEntry = mappings.classEntries?.find { entry ->
|
||||||
|
entry?.get("named") == "net/minecraft/client/MinecraftClient"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minecraftClassEntry == null) {
|
||||||
|
logger.error("Unable to probe environment. Please make sure you are using a valid environment.")
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("Probing environment...")
|
||||||
|
return when {
|
||||||
|
isClassPresent(minecraftClassEntry.get("intermediary")?.toDotNotation()) -> {
|
||||||
|
logger.info("Intermediary environment detected.")
|
||||||
|
"intermediary"
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
logger.error("No matching environment detected. Please make sure you are using a valid environment.")
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isClassPresent(className: String?): Boolean {
|
||||||
|
return try {
|
||||||
|
Class.forName(className)
|
||||||
|
true
|
||||||
|
} catch (_: ClassNotFoundException) {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun remapClassName(clazz: String): String {
|
||||||
|
environment ?: return clazz
|
||||||
|
|
||||||
|
val className = clazz.toSlashNotation()
|
||||||
|
return mappings?.classEntries?.find {
|
||||||
|
it?.get("named") == className
|
||||||
|
}?.get(environment)?.toDotNotation() ?: clazz
|
||||||
|
}
|
||||||
|
|
||||||
|
fun remapField(clazz: Class<*>, name: String): String {
|
||||||
|
environment ?: return name
|
||||||
|
|
||||||
|
val clazzNames = getClassHierarchyNames(clazz)
|
||||||
|
|
||||||
|
return mappings?.fieldEntries?.find { entry ->
|
||||||
|
val intern = entry.get(environment)
|
||||||
|
clazzNames.contains(intern.owner) && intern.name == name
|
||||||
|
}?.get("named")?.name ?: name
|
||||||
|
}
|
||||||
|
|
||||||
|
fun remapMethod(clazz: Class<*>, name: String): String {
|
||||||
|
environment ?: return name
|
||||||
|
|
||||||
|
val clazzNames = getClassHierarchyNames(clazz)
|
||||||
|
|
||||||
|
return mappings?.methodEntries?.find { entry ->
|
||||||
|
val intern = entry.get(environment)
|
||||||
|
clazzNames.contains(intern.owner) && intern.name == name
|
||||||
|
}?.get("named")?.name ?: name
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getClassHierarchyNames(clazz: Class<*>): Set<String> {
|
||||||
|
val clazzNames = mutableSetOf(clazz.name.toSlashNotation())
|
||||||
|
var current = clazz
|
||||||
|
|
||||||
|
while (current.name != "java.lang.Object") {
|
||||||
|
current = current.superclass ?: break
|
||||||
|
clazzNames.add(current.name.toSlashNotation())
|
||||||
|
}
|
||||||
|
|
||||||
|
return clazzNames
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun String.toDotNotation(): String = replace('/', '.')
|
||||||
|
|
||||||
|
private fun String.toSlashNotation(): String = replace('.', '/')
|
||||||
|
|
||||||
|
}
|
@@ -1,145 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of LiquidBounce (https://github.com/CCBlueX/LiquidBounce)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015 - 2024 CCBlueX
|
|
||||||
*
|
|
||||||
* LiquidBounce is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* LiquidBounce is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with LiquidBounce. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package net.ccbluex.liquidbounce.utils.mappings
|
|
||||||
|
|
||||||
import net.ccbluex.liquidbounce.utils.client.logger
|
|
||||||
import net.ccbluex.liquidbounce.utils.io.resource
|
|
||||||
import net.fabricmc.mappings.Mappings
|
|
||||||
import net.fabricmc.mappings.model.V2MappingsProvider
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tiny mappings
|
|
||||||
*
|
|
||||||
* These are fabric mappings which are being exported when the jar is being built.
|
|
||||||
* It allows you to remap obfuscated environments into readable names.
|
|
||||||
*
|
|
||||||
* This is going to be used for ultralight-databind and our JS script engine.
|
|
||||||
*/
|
|
||||||
object Remapper {
|
|
||||||
|
|
||||||
var mappings: Mappings? = null
|
|
||||||
var environment: String? = null
|
|
||||||
|
|
||||||
fun load() {
|
|
||||||
runCatching {
|
|
||||||
mappings = V2MappingsProvider.readTinyMappings(resource("/mappings/mappings.tiny").bufferedReader())
|
|
||||||
}.onFailure {
|
|
||||||
logger.error("Unable to load mappings. Ignore this if you are using a development environment.", it)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Probe environment
|
|
||||||
runCatching {
|
|
||||||
probeEnvironment()
|
|
||||||
}.onFailure {
|
|
||||||
logger.error("Unable to probe environment. Please make sure you are using a valid environment.", it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun probeEnvironment() {
|
|
||||||
val minecraftEntry = mappings?.classEntries?.find {
|
|
||||||
it?.get("named") == "net/minecraft/client/MinecraftClient"
|
|
||||||
}
|
|
||||||
|
|
||||||
if (minecraftEntry == null) {
|
|
||||||
logger.error("Unable to probe environment. Please make sure you are using a valid environment.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val officialName = minecraftEntry.get("official")?.replace('/', '.')
|
|
||||||
val intermediaryName = minecraftEntry.get("intermediary")?.replace('/', '.')
|
|
||||||
|
|
||||||
logger.info("Probing environment... (official: $officialName, intermediary: $intermediaryName)")
|
|
||||||
|
|
||||||
try {
|
|
||||||
Class.forName(officialName)
|
|
||||||
this.environment = "official"
|
|
||||||
logger.info("Official environment detected.")
|
|
||||||
} catch (_: ClassNotFoundException) {
|
|
||||||
try {
|
|
||||||
Class.forName(intermediaryName)
|
|
||||||
this.environment = "intermediary"
|
|
||||||
logger.info("Intermediary environment detected.")
|
|
||||||
|
|
||||||
return
|
|
||||||
} catch (_: ClassNotFoundException) {
|
|
||||||
logger.error("No matching environment detected. Please make sure you are using a valid environment.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun remapClassName(clazz: String): String {
|
|
||||||
if (environment == null) {
|
|
||||||
return clazz
|
|
||||||
}
|
|
||||||
|
|
||||||
val className = clazz.replace('.', '/')
|
|
||||||
|
|
||||||
return mappings?.classEntries?.find {
|
|
||||||
it?.get("named") == className
|
|
||||||
}?.get(environment)?.replace('/', '.') ?: clazz
|
|
||||||
}
|
|
||||||
|
|
||||||
fun remapField(clazz: Class<*>, name: String, superClasses: Boolean): String {
|
|
||||||
if (environment == null) {
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
|
|
||||||
val classNames = mutableSetOf(clazz.name.replace('.', '/'))
|
|
||||||
|
|
||||||
if (superClasses) {
|
|
||||||
var current = clazz
|
|
||||||
while (current.name != "java.lang.Object") {
|
|
||||||
current = current.superclass
|
|
||||||
classNames.add(current.name.replace('.', '/'))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return mappings?.fieldEntries?.find {
|
|
||||||
val intern = it?.get(environment) ?: return@find false
|
|
||||||
val named = it.get("named") ?: return@find false
|
|
||||||
|
|
||||||
classNames.contains(intern.owner) && named.name == name
|
|
||||||
}?.get(environment)?.name ?: name
|
|
||||||
}
|
|
||||||
|
|
||||||
fun remapMethod(clazz: Class<*>, name: String, superClasses: Boolean): String {
|
|
||||||
if (environment == null) {
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
|
|
||||||
val classNames = mutableSetOf(clazz.name.replace('.', '/'))
|
|
||||||
|
|
||||||
if (superClasses) {
|
|
||||||
var current = clazz
|
|
||||||
while (current.name != "java.lang.Object") {
|
|
||||||
current = current.superclass
|
|
||||||
classNames.add(current.name.replace('.', '/'))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return mappings?.methodEntries?.find {
|
|
||||||
val intern = it?.get(environment) ?: return@find false
|
|
||||||
val named = it.get("named") ?: return@find false
|
|
||||||
|
|
||||||
classNames.contains(intern.owner) && named.name == name
|
|
||||||
}?.get(environment)?.name ?: name
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -6,10 +6,6 @@
|
|||||||
"priority": 1337,
|
"priority": 1337,
|
||||||
"mixinPriority": 1337,
|
"mixinPriority": 1337,
|
||||||
"client": [
|
"client": [
|
||||||
"graaljs.MixinHostClassDesc",
|
|
||||||
"graaljs.MixinHostClassLoader",
|
|
||||||
"graaljs.MixinHostContext",
|
|
||||||
"graaljs.MixinTruffleLanguage",
|
|
||||||
"minecraft.block.MixinAbstractBlock",
|
"minecraft.block.MixinAbstractBlock",
|
||||||
"minecraft.block.MixinBlock",
|
"minecraft.block.MixinBlock",
|
||||||
"minecraft.block.MixinBlockView",
|
"minecraft.block.MixinBlockView",
|
||||||
@@ -88,7 +84,6 @@
|
|||||||
"minecraft.render.MixinPostEffectPass",
|
"minecraft.render.MixinPostEffectPass",
|
||||||
"minecraft.render.MixinRenderTickCounter",
|
"minecraft.render.MixinRenderTickCounter",
|
||||||
"minecraft.render.MixinSignText",
|
"minecraft.render.MixinSignText",
|
||||||
"sodium.MixinSodiumBlockOcclusionCache",
|
|
||||||
"minecraft.render.MixinTextRenderer",
|
"minecraft.render.MixinTextRenderer",
|
||||||
"minecraft.render.MixinWorldRenderer",
|
"minecraft.render.MixinWorldRenderer",
|
||||||
"minecraft.render.entity.feature.MixinDeadmau5FeatureRenderer",
|
"minecraft.render.entity.feature.MixinDeadmau5FeatureRenderer",
|
||||||
@@ -96,7 +91,12 @@
|
|||||||
"minecraft.text.MixinChatHudLineVisible",
|
"minecraft.text.MixinChatHudLineVisible",
|
||||||
"minecraft.text.MixinTextColor",
|
"minecraft.text.MixinTextColor",
|
||||||
"minecraft.text.MixinTranslatableTextContent",
|
"minecraft.text.MixinTranslatableTextContent",
|
||||||
"sodium.MixinSodiumLightDataAccessMixin"
|
"sodium.MixinSodiumBlockOcclusionCache",
|
||||||
|
"sodium.MixinSodiumLightDataAccessMixin",
|
||||||
|
"truffle.MixinHostClassDesc",
|
||||||
|
"truffle.MixinHostClassLoader",
|
||||||
|
"truffle.MixinHostContext",
|
||||||
|
"truffle.MixinTruffleLanguage"
|
||||||
],
|
],
|
||||||
"server": [],
|
"server": [],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
|
Reference in New Issue
Block a user