Important for new members!
All future posts from members with a reputation of less than 1 will be queued for manual review to prevent forum spam. We will review your posts as soon as possible!
The autoblock bypass issue in LiquidBounce Nextgen has been a major concern within the Chinese user community. We strongly urge the development team to prioritize fixing this critical Block problem, as it severely compromises the PvP experience. Currently, many players consistently lose battles on PvP servers when facing opponents using well-known hacked clients that exploit this flaw.
Successfully resolving this Block issue would be a significant breakthrough for the project - especially considering this problem has persisted since the legacy versions and remained unfixed even before development was discontinued."
I am trying to run Legacy so I can play 1.8.9 on my macOS, on Mac15.0. Nextgen works fine but when Legacy has been providing me with the below error:
libc++abi: terminating due to uncaught exception of type NSException
An error occured:
Process exited with non-zero exit code: 7900.
Any help would be amazing.
ScriptAPI v1 compatibility
This script re-introduces the compatibility layer for ScriptAPI v1, which was removed in LiquidBounce b83, while adding a few tweaks.
Only works on LiquidBounce legacy, NOT LiquidBounce nextgen.
NEVER contact LiquidBounce staff about errors while using legacy scripts!
For help and support, contact me on Discord: ayyyax.
For updates to script, visit my repository.
How to install
Download the provided zip file.
Extract it into your LiquidBouce-1.8.9 folder
Insert your favourite legacy scripts in scriptapi-v1/scripts
Warnings
Some scripts will simply not work. If that happens, try and contact me to sort out the issue.
LiquidBounce will take longer to start up while using this script.
I have no idea how to write scripts, so this is really bad, but it kinda works lol
Tested and confirmed working scripts
fancyderp.js by SoulPlexis
autoeat.js by SoulPlexis
DOWNLOAD - NEVER CONTACT LIQUIDBOUNCE STAFF ABOUT ERRORS WHEN USING LEGACY SCRIPTS
function __require(path) {
if (path.startsWith("@embedded")) {
return globalThis
}
if (path.startsWith("@minecraft-yarn-definitions/types/")) {
return {
[path.substring(path.lastIndexOf("/") + 1)]: Java.type(path
.replaceAll("@minecraft-yarn-definitions/types/", "")
.replaceAll("/", ".")
)
}
}
return require(path);
}
var exports = {}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
// imports
/* eslint-disable unused-imports/no-unused-imports */
const _embedded_1 = __require("@embedded");
const CommonPingS2CPacket_1 = __require("@minecraft-yarn-definitions/types/net/minecraft/network/packet/s2c/common/CommonPingS2CPacket");
// Global variables for storing transaction data
const transactionQueue = [];
const MAX_QUEUE_SIZE = 100;
// Global statistics
let totalTransactions = 0;
let lastReportTime = 0;
const REPORT_INTERVAL = 5000; // Report every 5 seconds
const PARAMETER_FREQUENCY = {};
const script = _embedded_1.registerScript.apply({
name: "transactions",
version: "1.0.0",
authors: ["commandblock2"]
});
script.registerModule({
name: "transactions",
description: "Logs transactions packets for anticheat detection",
category: "Client",
settings: {
reportInterval: _embedded_1.Setting.int({
name: "ReportInterval",
default: 5,
range: [1, 60],
suffix: "seconds"
}),
showParameters: _embedded_1.Setting.boolean({
name: "ShowParameters",
default: true
}),
logToChat: _embedded_1.Setting.boolean({
name: "LogToChat",
default: true
}),
verbose: _embedded_1.Setting.boolean({
name: "Verbose",
default: false
})
}
}, (mod) => {
mod.on("enable", () => {
// Reset statistics
totalTransactions = 0;
lastReportTime = Date.now();
// Clear the queue
transactionQueue.length = 0;
// Reset parameter frequency
for (const key in PARAMETER_FREQUENCY) {
delete PARAMETER_FREQUENCY[key];
}
_embedded_1.Client.displayChatMessage("§a[Transactions] Monitoring started. Use .txstats to see statistics.");
});
mod.on("disable", () => {
_embedded_1.Client.displayChatMessage("§c[Transactions] Monitoring stopped.");
});
mod.on("packet", (event) => {
if (event.packet instanceof CommonPingS2CPacket_1.CommonPingS2CPacket) {
const parameter = event.packet.getParameter();
const timestamp = Date.now();
if (mod.settings.verbose.getValue()) {
_embedded_1.Client.displayChatMessage(`§a[Transactions] Received parameter: ${parameter}`);
}
// Add to queue
transactionQueue.push({ timestamp, parameter });
// Keep queue size limited
if (transactionQueue.length > MAX_QUEUE_SIZE) {
transactionQueue.shift();
}
// Update statistics
totalTransactions++;
PARAMETER_FREQUENCY[parameter] = (PARAMETER_FREQUENCY[parameter] || 0) + 1;
// Check if it's time to report
const currentTime = Date.now();
const reportIntervalMs = mod.settings.reportInterval.getValue() * 1000;
if (mod.settings.logToChat.getValue() && currentTime - lastReportTime >= reportIntervalMs) {
reportStatistics();
lastReportTime = currentTime;
}
}
});
// Function to report statistics
function reportStatistics() {
if (transactionQueue.length === 0) {
return;
}
const packetsPerSecond = calculatePacketsPerSecond();
_embedded_1.Client.displayChatMessage(`§e[Transactions] §fRate: §a${packetsPerSecond.toFixed(2)} §fpackets/sec | Total: §a${totalTransactions}`);
if (mod.settings.showParameters.getValue()) {
const topParameters = getTopParameters(8);
if (topParameters.length > 0) {
_embedded_1.Client.displayChatMessage(`§e[Transactions] §fTop parameters: ${topParameters.map(p => `§a${p.parameter}§f(${p.count})`).join(", ")}`);
}
}
}
// Calculate packets per second based on queue data
function calculatePacketsPerSecond() {
if (transactionQueue.length < 2) {
return 0;
}
const oldestTimestamp = transactionQueue[0].timestamp;
const newestTimestamp = transactionQueue[transactionQueue.length - 1].timestamp;
const timeSpanSeconds = (newestTimestamp - oldestTimestamp) / 1000;
return timeSpanSeconds > 0 ? transactionQueue.length / timeSpanSeconds : 0;
}
// Get top N most frequent parameters
function getTopParameters(n) {
return Object.entries(PARAMETER_FREQUENCY)
.map(([parameter, count]) => ({ parameter: parseInt(parameter), count }))
.sort((a, b) => b.count - a.count)
.slice(0, n);
}
});
// Register a command to view transaction statistics
script.registerCommand({
name: "txstats",
aliases: ["transactionstats"],
parameters: [{
name: "action",
required: false,
validate: _embedded_1.ParameterValidator.string
}],
onExecute(action) {
if (action === "clear") {
// Clear statistics
totalTransactions = 0;
transactionQueue.length = 0;
for (const key in PARAMETER_FREQUENCY) {
delete PARAMETER_FREQUENCY[key];
}
_embedded_1.Client.displayChatMessage("§a[Transactions] Statistics cleared.");
return;
}
if (transactionQueue.length === 0) {
_embedded_1.Client.displayChatMessage("§c[Transactions] No transaction data available.");
return;
}
// Display basic statistics
const packetsPerSecond = calculatePacketsPerSecond();
_embedded_1.Client.displayChatMessage(`§e[Transactions] §fStatistics:`);
_embedded_1.Client.displayChatMessage(`§fTotal transactions: §a${totalTransactions}`);
_embedded_1.Client.displayChatMessage(`§fCurrent rate: §a${packetsPerSecond.toFixed(2)} §fpackets/sec`);
// Display queue info
_embedded_1.Client.displayChatMessage(`§fQueue size: §a${transactionQueue.length}/${MAX_QUEUE_SIZE}`);
// Display top 5 parameters
const topParameters = getTopParameters(5);
if (topParameters.length > 0) {
_embedded_1.Client.displayChatMessage(`§fTop 5 parameters:`);
topParameters.forEach((p, index) => {
_embedded_1.Client.displayChatMessage(`§f ${index + 1}. Parameter §a${p.parameter}§f: ${p.count} occurrences (${(p.count / totalTransactions * 100).toFixed(1)}%)`);
});
}
// Display time range
if (transactionQueue.length >= 2) {
const oldestTimestamp = transactionQueue[0].timestamp;
const newestTimestamp = transactionQueue[transactionQueue.length - 1].timestamp;
const timeSpanSeconds = (newestTimestamp - oldestTimestamp) / 1000;
_embedded_1.Client.displayChatMessage(`§fTime span: §a${timeSpanSeconds.toFixed(2)} §fseconds`);
}
}
});
// Helper functions for command execution
function calculatePacketsPerSecond() {
if (transactionQueue.length < 2) {
return 0;
}
const oldestTimestamp = transactionQueue[0].timestamp;
const newestTimestamp = transactionQueue[transactionQueue.length - 1].timestamp;
const timeSpanSeconds = (newestTimestamp - oldestTimestamp) / 1000;
return timeSpanSeconds > 0 ? transactionQueue.length / timeSpanSeconds : 0;
}
function getTopParameters(n) {
return Object.entries(PARAMETER_FREQUENCY)
.map(([parameter, count]) => ({ parameter: parseInt(parameter), count }))
.sort((a, b) => b.count - a.count)
.slice(0, n);
}
Note that LiquidBounce cannot run typescript, at least as of now.
// imports
/* eslint-disable unused-imports/no-unused-imports */
import {
Setting,
Vec3i,
Vec3d,
MathHelper,
BlockPos,
Hand,
RotationAxis,
mc,
Client,
RotationUtil,
ItemUtil,
NetworkUtil,
InteractionUtil,
BlockUtil,
MovementUtil,
ReflectionUtil,
ParameterValidator,
UnsafeThread,
registerScript
} from "@embedded";
import { CommonPingS2CPacket } from "@minecraft-yarn-definitions/types/net/minecraft/network/packet/s2c/common/CommonPingS2CPacket";
/* eslint-enable unused-imports/no-unused-imports */
// DO NOT TOUCH ANYTHING ABOVE THIS LINE
// Define the TransactionEntry interface for storing packet data
interface TransactionEntry {
timestamp: number;
parameter: number;
}
// Global variables for storing transaction data
const transactionQueue: TransactionEntry[] = [];
const MAX_QUEUE_SIZE = 100;
// Global statistics
let totalTransactions = 0;
let lastReportTime = 0;
const PARAMETER_FREQUENCY: { [key: number]: number } = {};
const script = registerScript.apply({
name: "transactions",
version: "1.0.0",
authors: ["commandblock2"]
});
script.registerModule({
name: "transactions",
description: "Logs transactions packets for anticheat detection",
category: "Client",
settings: {
reportInterval: Setting.int({
name: "ReportInterval",
default: 5,
range: [1, 60],
suffix: "seconds"
}),
showParameters: Setting.boolean({
name: "ShowParameters",
default: true
}),
logToChat: Setting.boolean({
name: "LogToChat",
default: true
}),
verbose: Setting.boolean({
name: "Verbose",
default: false
})
}
}, (mod) => {
mod.on("enable", () => {
// Reset statistics
totalTransactions = 0;
lastReportTime = Date.now();
// Clear the queue
transactionQueue.length = 0;
// Reset parameter frequency
for (const key in PARAMETER_FREQUENCY) {
delete PARAMETER_FREQUENCY[key];
}
Client.displayChatMessage("§a[Transactions] Monitoring started. Use .txstats to see statistics.");
});
mod.on("disable", () => {
Client.displayChatMessage("§c[Transactions] Monitoring stopped.");
});
mod.on("packet", (event) => {
if (event.packet instanceof CommonPingS2CPacket) {
const parameter = event.packet.getParameter();
const timestamp = Date.now();
if (mod.settings.verbose.getValue()) {
Client.displayChatMessage(`§a[Transactions] Received parameter: ${parameter}`);
}
// Add to queue
transactionQueue.push({ timestamp, parameter });
// Keep queue size limited
if (transactionQueue.length > MAX_QUEUE_SIZE) {
transactionQueue.shift();
}
// Update statistics
totalTransactions++;
PARAMETER_FREQUENCY[parameter] = (PARAMETER_FREQUENCY[parameter] || 0) + 1;
// Check if it's time to report
const currentTime = Date.now();
const reportIntervalMs = mod.settings.reportInterval.getValue() * 1000;
if (mod.settings.logToChat.getValue() && currentTime - lastReportTime >= reportIntervalMs) {
reportStatistics();
lastReportTime = currentTime;
}
}
});
// Function to report statistics
function reportStatistics() {
if (transactionQueue.length === 0) {
return;
}
const packetsPerSecond = calculatePacketsPerSecond();
Client.displayChatMessage(`§e[Transactions] §fRate: §a${packetsPerSecond.toFixed(2)} §fpackets/sec | Total: §a${totalTransactions}`);
if (mod.settings.showParameters.getValue()) {
const topParameters = getTopParameters(8);
if (topParameters.length > 0) {
Client.displayChatMessage(`§e[Transactions] §fTop parameters: ${topParameters.map(p => `§a${p.parameter}§f(${p.count})`).join(", ")}`);
}
}
}
// Calculate packets per second based on queue data
function calculatePacketsPerSecond(): number {
if (transactionQueue.length < 2) {
return 0;
}
const oldestTimestamp = transactionQueue[0].timestamp;
const newestTimestamp = transactionQueue[transactionQueue.length - 1].timestamp;
const timeSpanSeconds = (newestTimestamp - oldestTimestamp) / 1000;
return timeSpanSeconds > 0 ? transactionQueue.length / timeSpanSeconds : 0;
}
// Get top N most frequent parameters
function getTopParameters(n: number): { parameter: number, count: number }[] {
return Object.entries(PARAMETER_FREQUENCY)
.map(([parameter, count]) => ({ parameter: parseInt(parameter), count }))
.sort((a, b) => b.count - a.count)
.slice(0, n);
}
});
// Register a command to view transaction statistics
script.registerCommand({
name: "txstats",
aliases: ["transactionstats"],
parameters: [{
name: "action",
required: false,
validate: ParameterValidator.string
}],
onExecute(action: string) {
if (action === "clear") {
// Clear statistics
totalTransactions = 0;
transactionQueue.length = 0;
for (const key in PARAMETER_FREQUENCY) {
delete PARAMETER_FREQUENCY[key];
}
Client.displayChatMessage("§a[Transactions] Statistics cleared.");
return;
}
if (transactionQueue.length === 0) {
Client.displayChatMessage("§c[Transactions] No transaction data available.");
return;
}
// Display basic statistics
const packetsPerSecond = calculatePacketsPerSecond();
Client.displayChatMessage(`§e[Transactions] §fStatistics:`);
Client.displayChatMessage(`§fTotal transactions: §a${totalTransactions}`);
Client.displayChatMessage(`§fCurrent rate: §a${packetsPerSecond.toFixed(2)} §fpackets/sec`);
// Display queue info
Client.displayChatMessage(`§fQueue size: §a${transactionQueue.length}/${MAX_QUEUE_SIZE}`);
// Display top 5 parameters
const topParameters = getTopParameters(5);
if (topParameters.length > 0) {
Client.displayChatMessage(`§fTop 5 parameters:`);
topParameters.forEach((p, index) => {
Client.displayChatMessage(`§f ${index + 1}. Parameter §a${p.parameter}§f: ${p.count} occurrences (${(p.count / totalTransactions * 100).toFixed(1)}%)`);
});
}
// Display time range
if (transactionQueue.length >= 2) {
const oldestTimestamp = transactionQueue[0].timestamp;
const newestTimestamp = transactionQueue[transactionQueue.length - 1].timestamp;
const timeSpanSeconds = (newestTimestamp - oldestTimestamp) / 1000;
Client.displayChatMessage(`§fTime span: §a${timeSpanSeconds.toFixed(2)} §fseconds`);
}
}
});
// Helper functions for command execution
function calculatePacketsPerSecond(): number {
if (transactionQueue.length < 2) {
return 0;
}
const oldestTimestamp = transactionQueue[0].timestamp;
const newestTimestamp = transactionQueue[transactionQueue.length - 1].timestamp;
const timeSpanSeconds = (newestTimestamp - oldestTimestamp) / 1000;
return timeSpanSeconds > 0 ? transactionQueue.length / timeSpanSeconds : 0;
}
function getTopParameters(n: number): { parameter: number, count: number }[] {
return Object.entries(PARAMETER_FREQUENCY)
.map(([parameter, count]) => ({ parameter: parseInt(parameter), count }))
.sort((a, b) => b.count - a.count)
.slice(0, n);
}
I truly appreciate that this client has remained free and open-source, which is excellent and has given rise to many forks. However, I wonder if there has been consideration to develop an injectable client? I understand that technical expertise varies, but could we attempt to explore this path?
Take the example of CCBlueX/liquidbounce_lite, which uses DLL injection via Rust. While undoubtedly challenging (potentially taking at least two years to mature), could such an approach eventually become viable? Additionally, would an executable (EXE) based solution be worth exploring as an alternative?
Following repo means
demo
https://github.com/commandblock2/minecraft-LBNG-types.
[image: 1743439569889-9094e21e-c6b5-4f3b-b562-92cd701ba7e3-image-resized.png]
minecraft-LBNG-types
DISCLAIMER: Use this at your own risk!!! This is an unofficial project not endorsed by Mojang or fabric developers. This repo does NOT
contains any generated minecraft type definitions by itself
redistribute the game itself
guarentee the correctness of the generated definition
This repo contains
instruction and scripts for creating typescript definitions
for Minecraft (with mods*)
for LiquidBounce NextGen
for everything inside of the jvm
typescript definitions for embedded context of LiquidBounce NextGen scriptAPI
a set of manually maintained patches to make the script api work properly
a set of examples LiquidBounce NextGen script using typescript
a compiler script that will compile all the .ts files into .js files that could run in graaljs (LiquidBounce NextGen runtime) with watch mode
some prompt files to use on LLMs, specifically for claude + continue.dev vscode extension, at .continue/prompts.
Note: the mods are only limited to those presented at the development environment of LiquidBounce NextGen.
When writing your script in typescript, expect inconsistencies with script API in js, but please report them to this repo if you can
Instruction (subject to change)
Adjust the order flexibly to your needs.
Generating the typescript definitions
Setup development environment for Liquidbounce NextGen
Clone LBNG, run git checkout 451cb31e9bf093fe07f9b28202bc2471921ea13d (for version 0.29.0 release) and launch with gradle ./gradlew runClient without intellij idea(recommened because of the sheer amount of memory it takes to generate the definition).
Place the LBNG-script/ts-defgen.js in your script folder for LiquidBounce
Build or download the latest released ts-generator jar from github, place it in your script folder as well.
Do a .script reload in your client, this should load the ts-defgen.js
Run the .ts-defgen command
See messages from chat and wait for around a few minute or more or less depending on your setup, this may take a while and also nearly 7GB of additional RAM (other than your intellij idea plus the what Minecraft needs in it's original state, causes OOM for me a lot of times xD).
Now you can find a types-gen folder in your script folder, this contains the generated typescript definitions.
.
├── ts-defgen.js
├── ts-generator-1.1.1.jar
└── types-gen
└── minecraft-yarn-definitions
├── package.json
├── tsconfig.json
└── types
├── ai
├── com
├── _COROUTINE
├── de
├── io
├── it
├── java
├── javax
├── jdk
├── joptsimple
├── kotlin
├── kotlinx
├── net
├── okhttp3
├── okio
├── org
├── oshi
└── sun
├── ... other scripts.js
Writing scripts with TypeScript Support
Run npm install in this directory.
copy the generated folder types-gen to generated-modules folder in the root of your project.
Run the script apply-patch with npm run apply-patches
Run npm install file:./generated-modules/types-gen/minecraft-yarn-definitions/ --no-save, no-save for now, not sure if I should do this.
Open the template.ts file and try start writing your script, you should see TypeScript type hints for all the classes that are available. vscode will automatically generate working imports, but you should not touch the import statement with @embedded namespace.
Run the script compile with npm like step 4 or npm run watch
Corresponding javascript file is generated in the dist directory, you can link this dist directory to your scripts directory in LB.
Contribution and TODOs
If you know how to better organize this project (architecture), please feel free to submit a PR.
If you find errors on generated definitions about Minecraft classes or LiquidBounce classes, please file your tick at ts-generator.
If you find a un-intended behavior in the ts-defgen.js, compile script or manually maintained definitions(TODO), please file an issue here.
License
This project is licensed under the GNU General Public license, see LICENSE for more information.
[image: 1738500020404-vscode-file___vscode-app_opt_vscodium_resources_app_out_vs_code_electron-sandbox_workbench_workbench.html-cropped.png]
Please fix the forgegradle problem and support for Scriptapi1 in b74
I'm really bored. Countless scripts can't be used. Countless problems and scripts need to be updated. This is a community, but it doesn't mean we need to work for free. Even if I write a tool that can convert api1 scripts into api2 scripts with one click, there are still a lot of error correction steps. Who doesn't want to use the latest version of liquidbond? But we can't give up our work, so please fix the forgegradle problem and support for Scriptapi1 in b74
-
-
-
-
General Discussion
A place to talk about anything related to LiquidBounce
-
Suggestions
Think something is missing? Let us know!
-
Bug Reports
Found a bug? Report it here!
-
Chinese
A place for our Chinese community
-
Off-Topic
Talk about anything you like (as long as you follow the rules)!