mirror of
https://github.com/CCBlueX/LiquidBounce.git
synced 2025-09-06 09:46:38 +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
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 21
|
||||
distribution: 'graalvm'
|
||||
java-version: '21'
|
||||
|
||||
- name: Grant permissions to src-theme
|
||||
run: sudo chmod -R 777 src-theme
|
||||
@@ -50,7 +50,7 @@ jobs:
|
||||
cd zip
|
||||
zip -r 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:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -62,10 +62,10 @@ jobs:
|
||||
submodules: recursive
|
||||
|
||||
- name: Setting up JDK 21
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 21
|
||||
distribution: 'graalvm'
|
||||
java-version: '21'
|
||||
|
||||
- name: Grant permissions to 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
|
||||
|
||||
plugins {
|
||||
id 'fabric-loom'
|
||||
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 "fabric-loom"
|
||||
id "org.jetbrains.kotlin.jvm"
|
||||
id "com.gorylenko.gradle-git-properties" version "2.4.2"
|
||||
id "io.gitlab.arturbosch.detekt" version "1.23.6"
|
||||
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
|
||||
version = project.mod_version
|
||||
group = project.maven_group
|
||||
|
||||
loom {
|
||||
accessWidenerPath = file('src/main/resources/liquidbounce.accesswidener')
|
||||
configurations {
|
||||
includeDependency
|
||||
includeModDependency
|
||||
|
||||
include.extendsFrom includeModDependency
|
||||
modImplementation.extendsFrom includeModDependency
|
||||
modCompileOnlyApi.extendsFrom includeModDependency
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
maven { url = 'https://maven.fabricmc.net/' }
|
||||
maven { url = "https://maven.fabricmc.net/" }
|
||||
maven {
|
||||
name = 'Jitpack'
|
||||
url = 'https://jitpack.io'
|
||||
name = "Jitpack"
|
||||
url = "https://jitpack.io"
|
||||
}
|
||||
maven {
|
||||
name = 'TerraformersMC'
|
||||
url = 'https://maven.terraformersmc.com/'
|
||||
name = "TerraformersMC"
|
||||
url = "https://maven.terraformersmc.com/"
|
||||
}
|
||||
maven {
|
||||
name = 'ViaVersion'
|
||||
url = 'https://repo.viaversion.com/'
|
||||
name = "ViaVersion"
|
||||
url = "https://repo.viaversion.com/"
|
||||
}
|
||||
maven {
|
||||
name = "modrinth"
|
||||
@@ -70,83 +71,80 @@ repositories {
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter:5.11.3'
|
||||
loom {
|
||||
accessWidenerPath = file("src/main/resources/liquidbounce.accesswidener")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// Minecraft
|
||||
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
||||
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
|
||||
|
||||
// Libraries (required mods)
|
||||
|
||||
// Fabric
|
||||
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
||||
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_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)
|
||||
modRuntimeOnly "com.terraformersmc:modmenu:${project.mod_menu_version}"
|
||||
modImplementation "maven.modrinth:sodium:${project.sodium_version}"
|
||||
modImplementation "de.florianmichael:ViaFabricPlus:${project.viafabricplus_version}"
|
||||
modCompileOnly "de.florianmichael:ViaFabricPlus:${project.viafabricplus_version}"
|
||||
|
||||
// Tests
|
||||
// modImplementation 'com.github.superblaubeere27:tenacc:e3a7ada99a'
|
||||
|
||||
// fix nullable imports
|
||||
implementation 'com.google.code.findbugs:jsr305:3.0.2'
|
||||
|
||||
// Client libraries
|
||||
implementation("com.github.CCBlueX:mc-authlib:${project.mc_authlib_version}") {
|
||||
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'
|
||||
// Minecraft Authlib
|
||||
includeDependency ("com.github.CCBlueX:mc-authlib:${project.mc_authlib_version}") {
|
||||
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'
|
||||
implementation 'org.graalvm.truffle:truffle-api:23.0.5'
|
||||
implementation 'org.graalvm.js:js:23.0.5'
|
||||
// JCEF Support
|
||||
includeModDependency "com.github.CCBlueX:mcef:1.1.5-1.21.1"
|
||||
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'
|
||||
runtimeOnly 'org.graalvm.tools:chromeinspector:23.0.5'
|
||||
// Discord RPC Support
|
||||
includeDependency "com.github.CCBlueX:DiscordIPC:4.0.0"
|
||||
|
||||
// https://mvnrepository.com/artifact/io.netty/netty-codec
|
||||
implementation 'io.netty:netty-codec:4.1.82.Final'
|
||||
// https://mvnrepository.com/artifact/io.netty/netty-codec-http
|
||||
implementation 'io.netty:netty-codec-http:4.1.82.Final'
|
||||
// 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'
|
||||
// ScriptAPI
|
||||
includeDependency "net.fabricmc:tiny-mappings-parser:0.3.0+build.17"
|
||||
includeDependency "org.graalvm.polyglot:polyglot:24.0.2"
|
||||
includeDependency "org.graalvm.polyglot:js-community:24.0.2"
|
||||
|
||||
implementation 'com.vdurmont:semver4j:3.1.0'
|
||||
implementation 'org.apache.tika:tika-core:3.0.0'
|
||||
// SOCKS5 Proxy Support (to stay compatible with ViaFabricPlus)
|
||||
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
|
||||
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'
|
||||
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
|
||||
afterEvaluate {
|
||||
configurations.includeDependency.incoming.resolutionResult.allDependencies.each {
|
||||
dependencies.include(dependencies.implementation(dependencies.compileOnlyApi(it.requested.toString()) {
|
||||
transitive = false
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
processResources {
|
||||
inputs.property 'version', project.version
|
||||
inputs.property "version", project.version
|
||||
|
||||
inputs.property 'minecraft_version', minecraft_version
|
||||
inputs.property 'fabric_version', fabric_version
|
||||
inputs.property 'loader_version', loader_version
|
||||
inputs.property 'min_loader_version', min_loader_version
|
||||
inputs.property 'fabric_kotlin_version', fabric_kotlin_version
|
||||
inputs.property 'viafabricplus_version', viafabricplus_version
|
||||
inputs.property "minecraft_version", minecraft_version
|
||||
inputs.property "fabric_version", fabric_version
|
||||
inputs.property "loader_version", loader_version
|
||||
inputs.property "min_loader_version", min_loader_version
|
||||
inputs.property "fabric_kotlin_version", fabric_kotlin_version
|
||||
inputs.property "viafabricplus_version", viafabricplus_version
|
||||
|
||||
filesMatching('fabric.mod.json') {
|
||||
filesMatching("fabric.mod.json") {
|
||||
expand([
|
||||
version : project.version,
|
||||
minecraft_version : minecraft_version,
|
||||
@@ -161,60 +159,60 @@ processResources {
|
||||
|
||||
// The following code will include the theme into the build
|
||||
|
||||
tasks.register('npmInstallTheme', NpmTask) {
|
||||
workingDir = file('src-theme')
|
||||
args = ['i']
|
||||
tasks.register("npmInstallTheme", NpmTask) {
|
||||
workingDir = file("src-theme")
|
||||
args = ["i"]
|
||||
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")
|
||||
}
|
||||
|
||||
tasks.register('buildTheme', NpmTask) {
|
||||
dependsOn 'npmInstallTheme'
|
||||
workingDir = file('src-theme')
|
||||
args = ['run', 'build']
|
||||
tasks.register("buildTheme", NpmTask) {
|
||||
dependsOn "npmInstallTheme"
|
||||
workingDir = file("src-theme")
|
||||
args = ["run", "build"]
|
||||
doLast {
|
||||
println 'Successfully build theme'
|
||||
println "Successfully build theme"
|
||||
}
|
||||
|
||||
inputs.files(
|
||||
'src-theme/package.json',
|
||||
'src-theme/package-lock.json',
|
||||
'src-theme/bundle.cjs',
|
||||
'src-theme/rollup.config.js'
|
||||
"src-theme/package.json",
|
||||
"src-theme/package-lock.json",
|
||||
"src-theme/bundle.cjs",
|
||||
"src-theme/rollup.config.js"
|
||||
)
|
||||
inputs.dir("src-theme/src")
|
||||
outputs.dir('src-theme/dist')
|
||||
outputs.dir("src-theme/dist")
|
||||
}
|
||||
|
||||
tasks.register('bundleTheme', NodeTask) {
|
||||
dependsOn 'buildTheme'
|
||||
workingDir = file('src-theme')
|
||||
script = file('src-theme/bundle.cjs')
|
||||
tasks.register("bundleTheme", NodeTask) {
|
||||
dependsOn "buildTheme"
|
||||
workingDir = file("src-theme")
|
||||
script = file("src-theme/bundle.cjs")
|
||||
doLast {
|
||||
println 'Successfully attached theme to build'
|
||||
println "Successfully attached theme to build"
|
||||
}
|
||||
|
||||
// Incremental stuff
|
||||
inputs.files(
|
||||
'src-theme/package.json',
|
||||
'src-theme/package-lock.json',
|
||||
'src-theme/bundle.cjs',
|
||||
'src-theme/rollup.config.js'
|
||||
"src-theme/package.json",
|
||||
"src-theme/package-lock.json",
|
||||
"src-theme/bundle.cjs",
|
||||
"src-theme/rollup.config.js"
|
||||
)
|
||||
inputs.dir("src-theme/src")
|
||||
inputs.dir("src-theme/public")
|
||||
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 {
|
||||
main {
|
||||
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
|
||||
// see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html
|
||||
// If Javadoc is generated, this must be specified in that task too.
|
||||
it.options.encoding = 'UTF-8'
|
||||
it.options.encoding = "UTF-8"
|
||||
|
||||
// Minecraft 1.20.5 upwards uses Java 17.
|
||||
it.options.release = 21
|
||||
@@ -237,6 +235,7 @@ tasks.withType(JavaCompile).configureEach {
|
||||
|
||||
tasks.withType(Test).configureEach {
|
||||
useJUnitPlatform()
|
||||
dependsOn(tasks.named("genSources"))
|
||||
}
|
||||
|
||||
detekt {
|
||||
@@ -264,6 +263,9 @@ java {
|
||||
// if it is present.
|
||||
// If you remove this line, sources will not be generated.
|
||||
withSourcesJar()
|
||||
|
||||
sourceCompatibility = JavaVersion.VERSION_21
|
||||
targetCompatibility = JavaVersion.VERSION_21
|
||||
}
|
||||
|
||||
compileKotlin {
|
||||
@@ -273,49 +275,22 @@ compileKotlin {
|
||||
}
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
archiveClassifier.set('shadow')
|
||||
jar {
|
||||
// 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
|
||||
exclude 'native-binaries/*'
|
||||
|
||||
// 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'))
|
||||
from(configurations.mappings.collect { zipTree(it) }) {
|
||||
include "mappings/mappings.tiny"
|
||||
}
|
||||
}
|
||||
|
||||
jar {
|
||||
from 'LICENSE'
|
||||
}
|
||||
|
||||
remapJar {
|
||||
inputFile = shadowJar.archiveFile
|
||||
}
|
||||
|
||||
tasks.register('copyZipInclude', Copy) {
|
||||
from 'zip_include/'
|
||||
into 'build/libs/zip'
|
||||
tasks.register("copyZipInclude", Copy) {
|
||||
from "zip_include/"
|
||||
into "build/libs/zip"
|
||||
}
|
||||
|
||||
sourcesJar.dependsOn bundleTheme
|
||||
|
@@ -22,13 +22,13 @@ org.gradle.jvmargs=-Xms1024m -Xmx4096m
|
||||
# Check these on https://fabricmc.net/versions.html
|
||||
minecraft_version=1.21.1
|
||||
yarn_mappings=1.21.1+build.3
|
||||
loader_version=0.16.3
|
||||
loader_version=0.16.9
|
||||
min_loader_version=0.15.10
|
||||
|
||||
# Fabric API
|
||||
fabric_version=0.102.1+1.21.1
|
||||
fabric_version=0.107.0+1.21.1
|
||||
# Loom
|
||||
loom_version=1.7-SNAPSHOT
|
||||
loom_version=1.8-SNAPSHOT
|
||||
# Mod Properties
|
||||
mod_version=0.17.1
|
||||
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
|
||||
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
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
@@ -19,7 +19,6 @@
|
||||
|
||||
pluginManagement {
|
||||
repositories {
|
||||
jcenter()
|
||||
maven {
|
||||
name = 'Fabric'
|
||||
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/>.
|
||||
*/
|
||||
|
||||
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.Pseudo;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||
|
||||
/**
|
||||
* Remaps class names to their obfuscated counterparts.
|
||||
*
|
||||
* Initial code by lit
|
||||
*/
|
||||
@Mixin(targets = "com/oracle/truffle/host/HostClassLoader")
|
||||
@Pseudo
|
||||
@Mixin(targets = "com/oracle/truffle/host/HostClassLoader", remap = false)
|
||||
public class MixinHostClassLoader {
|
||||
|
||||
@ModifyVariable(method = "findClass", at = @At("HEAD"), argsOnly = true, remap = false)
|
||||
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.Pseudo;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
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 {
|
||||
|
||||
@ModifyVariable(method = "findClassImpl", at = @At("HEAD"), argsOnly = true, remap = false)
|
||||
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.input.InputTracker
|
||||
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.minecraft.resource.ReloadableResourceManagerImpl
|
||||
import net.minecraft.resource.ResourceManager
|
||||
@@ -122,7 +122,7 @@ object LiquidBounce : Listenable {
|
||||
logger.debug("Loading from cloud: '$CLIENT_CLOUD'")
|
||||
|
||||
// Load mappings
|
||||
Remapper.load()
|
||||
EnvironmentRemapper
|
||||
|
||||
// Load translations
|
||||
LanguageManager.loadLanguages()
|
||||
|
@@ -18,13 +18,13 @@
|
||||
*/
|
||||
package net.ccbluex.liquidbounce.script.bindings.api
|
||||
|
||||
import net.ccbluex.liquidbounce.utils.mappings.Remapper
|
||||
import net.ccbluex.liquidbounce.utils.mappings.EnvironmentRemapper
|
||||
|
||||
object JsReflectionUtil {
|
||||
|
||||
@JvmName("classByName")
|
||||
fun classByName(name: String): Class<*> = Class.forName(
|
||||
Remapper.remapClassName(name).replace('/', '.')
|
||||
EnvironmentRemapper.remapClassName(name).replace('/', '.')
|
||||
)
|
||||
|
||||
@JvmName("classByObject")
|
||||
@@ -38,7 +38,7 @@ object JsReflectionUtil {
|
||||
|
||||
@JvmName("newInstanceByName")
|
||||
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 {
|
||||
isAccessible = true
|
||||
}.newInstance(*args)
|
||||
@@ -50,35 +50,37 @@ object JsReflectionUtil {
|
||||
}.newInstance(*args)
|
||||
|
||||
@JvmName("getField")
|
||||
fun getField(obj: Any, name: String): Any? = obj::class.java.getDeclaredField(
|
||||
Remapper.remapField(obj::class.java, name, true)
|
||||
).apply {
|
||||
isAccessible = true
|
||||
}.get(obj)
|
||||
fun getField(obj: Any, name: String): Any? = obj::class.java.fields
|
||||
.find { field ->
|
||||
field.name == EnvironmentRemapper.remapField(obj::class.java, name)
|
||||
}?.apply {
|
||||
isAccessible = true
|
||||
}?.get(obj)
|
||||
|
||||
@JvmName("getStaticField")
|
||||
fun getStaticField(clazz: Class<*>, name: String): Any? = clazz.getDeclaredField(
|
||||
Remapper.remapField(clazz, name, true)
|
||||
).apply {
|
||||
isAccessible = true
|
||||
}.get(null)
|
||||
@JvmName("getDeclaredField")
|
||||
fun getDeclaredField(clazz: Class<*>, name: String): Any? = clazz.declaredFields
|
||||
.find { field ->
|
||||
field.name == EnvironmentRemapper.remapField(clazz, name)
|
||||
}?.apply {
|
||||
isAccessible = true
|
||||
}?.get(null)
|
||||
|
||||
@JvmName("invokeMethod")
|
||||
fun invokeMethod(obj: Any, name: String, vararg args: Any?): Any? =
|
||||
obj::class.java.getDeclaredMethod(
|
||||
Remapper.remapField(obj::class.java, name, true),
|
||||
*args.map { it!!::class.java }.toTypedArray()
|
||||
).apply {
|
||||
obj::class.java.methods.find { method ->
|
||||
method.name == EnvironmentRemapper.remapMethod(obj::class.java, name) &&
|
||||
method.parameterTypes.contentEquals(args.map { it!!::class.java }.toTypedArray())
|
||||
}?.apply {
|
||||
isAccessible = true
|
||||
}.invoke(obj, *args)
|
||||
}?.invoke(obj, *args)
|
||||
|
||||
@JvmName("invokeStaticMethod")
|
||||
fun invokeStaticMethod(clazz: Class<*>, name: String, vararg args: Any?): Any? =
|
||||
clazz.getDeclaredMethod(
|
||||
Remapper.remapField(clazz, name, true),
|
||||
*args.map { it!!::class.java }.toTypedArray()
|
||||
).apply {
|
||||
@JvmName("invokeDeclaredMethod")
|
||||
fun invokeDeclaredMethod(clazz: Class<*>, name: String, vararg args: Any?): Any? =
|
||||
clazz.declaredMethods.find { method ->
|
||||
method.name == EnvironmentRemapper.remapMethod(clazz, name) &&
|
||||
method.parameterTypes.contentEquals(args.map { it!!::class.java }.toTypedArray())
|
||||
}?.apply {
|
||||
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,
|
||||
"mixinPriority": 1337,
|
||||
"client": [
|
||||
"graaljs.MixinHostClassDesc",
|
||||
"graaljs.MixinHostClassLoader",
|
||||
"graaljs.MixinHostContext",
|
||||
"graaljs.MixinTruffleLanguage",
|
||||
"minecraft.block.MixinAbstractBlock",
|
||||
"minecraft.block.MixinBlock",
|
||||
"minecraft.block.MixinBlockView",
|
||||
@@ -88,7 +84,6 @@
|
||||
"minecraft.render.MixinPostEffectPass",
|
||||
"minecraft.render.MixinRenderTickCounter",
|
||||
"minecraft.render.MixinSignText",
|
||||
"sodium.MixinSodiumBlockOcclusionCache",
|
||||
"minecraft.render.MixinTextRenderer",
|
||||
"minecraft.render.MixinWorldRenderer",
|
||||
"minecraft.render.entity.feature.MixinDeadmau5FeatureRenderer",
|
||||
@@ -96,7 +91,12 @@
|
||||
"minecraft.text.MixinChatHudLineVisible",
|
||||
"minecraft.text.MixinTextColor",
|
||||
"minecraft.text.MixinTranslatableTextContent",
|
||||
"sodium.MixinSodiumLightDataAccessMixin"
|
||||
"sodium.MixinSodiumBlockOcclusionCache",
|
||||
"sodium.MixinSodiumLightDataAccessMixin",
|
||||
"truffle.MixinHostClassDesc",
|
||||
"truffle.MixinHostClassLoader",
|
||||
"truffle.MixinHostContext",
|
||||
"truffle.MixinTruffleLanguage"
|
||||
],
|
||||
"server": [],
|
||||
"injectors": {
|
||||
|
Reference in New Issue
Block a user