By reading your post again I think I need to use ChoiceConfigurable. And I think that's definitely possible.
Supporters
Community members who have proven to be competent supporters.
Posts
-
Help with setting visibility9 days ago -
Help with setting visibility9 days agoAlso I am not sure about if we have to pass a object that implements all those functions to
Java.extend()
. But I think that's it for graaljs's type gymnastics, if you think this is necessary please open a issue at github. Ah just found that I forgot to use theReflectionUtils
xD. -
Help with setting visibility9 days ago@Soulplexis It's done. Although not supposed to be implemented this way but it can be.
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 ToggleableConfigurable_1 = __require("@minecraft-yarn-definitions/types/net/ccbluex/liquidbounce/config/types/ToggleableConfigurable"); /* eslint-enable unused-imports/no-unused-imports */ // DO NOT TOUCH ANYTHING ABOVE THIS LINE, also not sure why it didn't work const script = _embedded_1.registerScript.apply({ name: "example-script-api-hacking", version: "1.0.0", authors: ["commandblock2"] }); script.registerModule({ name: "example-typescript-module-script-api-hacking", description: "Ths is an minimal example module generated in ts but with a setting that's not supposed to be here", category: "Client", }, (mod) => { // Assuming you're in a JavaScript environment that supports Java.extend (like Nashorn or GraalVM) // @ts-expect-error const MyToggleableConfig = Java.extend(ToggleableConfigurable_1.ToggleableConfigurable, { // Implement abstract methods from ToggleableConfigurable and its parent classes // Required method implementations from EventListener interface parent: function () { return this.parent; // Return the parent passed in constructor }, children: function () { return []; // Return an array of child event listeners if any }, unregister: function () { // Implementation for unregistering this event listener }, // You can also override other methods like: enable: function () { // Custom enable logic // @ts-expect-error Java.super(this).enable(); // Call the parent method if needed }, disable: function () { // Custom disable logic // @ts-expect-error Java.super(this).disable(); // Call the parent method if needed } }); // Create an instance with required constructor parameters // constructor(parent: EventListener | null, name: string, enabled: boolean, aliases: string[]) const myConfig = new MyToggleableConfig(mod, "MyConfig", true, ["alias1", "alias2"]); const testBoolean = myConfig.boolean("testBoolean", false); _embedded_1.Client.displayChatMessage(testBoolean.toString()); // @ts-expect-error const field = mod.class.getDeclaredField("_values"); field.setAccessible(true); const valuesMap = field.get(mod); // @ts-expect-error valuesMap.put("MyConfig", mod.value(myConfig)); mod.on("enable", () => { _embedded_1.Client.displayChatMessage(`Hi, ${_embedded_1.mc.player}`); }); });
// 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 { Class } from "@minecraft-yarn-definitions/types/java/lang/Class"; import { ToggleableConfigurable } from "@minecraft-yarn-definitions/types/net/ccbluex/liquidbounce/config/types/ToggleableConfigurable"; import { ScriptModule } from "@minecraft-yarn-definitions/types/net/ccbluex/liquidbounce/script/bindings/features/ScriptModule"; /* eslint-enable unused-imports/no-unused-imports */ // DO NOT TOUCH ANYTHING ABOVE THIS LINE, also not sure why it didn't work const script = registerScript.apply({ name: "example-script-api-hacking", version: "1.0.0", authors: ["commandblock2"] }); script.registerModule({ name: "example-typescript-module-script-api-hacking", description: "Ths is an minimal example module generated in ts but with a setting that's not supposed to be here", category: "Client", }, (mod) => { // Assuming you're in a JavaScript environment that supports Java.extend (like Nashorn or GraalVM) // @ts-expect-error const MyToggleableConfig = Java.extend(ToggleableConfigurable, { // Implement abstract methods from ToggleableConfigurable and its parent classes // Required method implementations from EventListener interface parent: function () { return this.parent; // Return the parent passed in constructor }, children: function () { return []; // Return an array of child event listeners if any }, unregister: function () { // Implementation for unregistering this event listener }, // You can also override other methods like: enable: function () { // Custom enable logic // @ts-expect-error Java.super(this).enable(); // Call the parent method if needed }, disable: function () { // Custom disable logic // @ts-expect-error Java.super(this).disable(); // Call the parent method if needed } }); // Create an instance with required constructor parameters // constructor(parent: EventListener | null, name: string, enabled: boolean, aliases: string[]) const myConfig = new MyToggleableConfig(mod, "MyConfig", true, ["alias1", "alias2"]); const testBoolean = myConfig.boolean("testBoolean", false); Client.displayChatMessage(testBoolean.toString()); // @ts-expect-error const field = (mod.class as unknown as Class<ScriptModule>).getDeclaredField("_values"); field.setAccessible(true); const valuesMap = field.get(mod); // @ts-expect-error valuesMap.put("MyConfig", mod.value(myConfig)); mod.on("enable", () => { Client.displayChatMessage(`Hi, ${mc.player}`) }) })
-
Help with setting visibility10 days agoThis might be possible actually I think, if you put it in the lambda near mod.on that might even work, will try later
-
Help with setting visibility10 days agoBut on another thought, we could extend the value our self maybe and make the
ScriptToggleableConfigurable
our self within script? Maybe we could think about that.Also a bit of shameless self advertising, maybe try this typescript definition generator, could be a bit hard to setup and generate the definition yet.
-
Help with setting visibility10 days agoAfaik, it is not possible without significant change.
ScriptSetting
for now does not provide the togglableConfigurable value function yet. That's all they have right now.export class ScriptSetting extends Object { static INSTANCE: ScriptSetting; boolean(value: BooleanValue): Value<boolean>; choose(value: ChooseValue): ChooseListValue<NamedChoice>; float(value: FloatValue): RangedValue<number>; floatRange(value: FloatRangeValue): RangedValue<ClosedFloatingPointRange<number>>; int(value: IntValue): RangedValue<number>; intRange(value: IntRangeValue): RangedValue<number[]>; key(value: KeyValue): Value<InputUtil$Key>; text(value: TextView): Value<string>; textArray(value: TextArrayValue): Value<string[]>; }
even if you would construct a
ToggleableConfigurable
instance with the graal anonymous class/object syntax, theconstructor(parent: EventListener | null, name: string, enabled: boolean, aliases: string[])
would require aEventListener
, which is supplied bythis
in normal kotlin non-script modules. And thethis
in your script api corresponds to themod
in}, (mod) => {
in your last line given, which by design, is not possible to acquire.
However I do believe we could make a pr to the script api to make this possible, but I am not sure if a script is supposed to have such complex configuration. -
[GPLv3] transaction.js12 days agofunction __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); }
-
where is the liquidbounce folder in prism launcher13 days ago
-
[Script] PearlBlockThrow ?14 days agoThis is a somewhat faithful transplation of the original source code, which would not work on 1.8.x, this should desync your inventory too.
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"); /* eslint-enable unused-imports/no-unused-imports */ // DO NOT TOUCH ANYTHING ABOVE THIS LINE, also not sure why it didn't work const PlayerInteractItemC2SPacket_1 = __require("@minecraft-yarn-definitions/types/net/minecraft/network/packet/c2s/play/PlayerInteractItemC2SPacket"); const UpdateSelectedSlotC2SPacket_1 = __require("@minecraft-yarn-definitions/types/net/minecraft/network/packet/c2s/play/UpdateSelectedSlotC2SPacket"); const UpdateSelectedSlotS2CPacket_1 = __require("@minecraft-yarn-definitions/types/net/minecraft/network/packet/s2c/play/UpdateSelectedSlotS2CPacket"); const Items_1 = __require("@minecraft-yarn-definitions/types/net/minecraft/item/Items"); const Hand_1 = __require("@minecraft-yarn-definitions/types/net/minecraft/util/Hand"); const script = _embedded_1.registerScript.apply({ name: "no-pearl-use", version: "1.0.0", authors: ["commandblock2"] }); script.registerModule({ name: "no-pearl-use", description: "cancels ender pearl use", category: "Player", }, (mod) => { var slot = 0; mod.on("enable", () => { var _a, _b; slot = (_b = (_a = _embedded_1.mc.player) === null || _a === void 0 ? void 0 : _a.inventory.selectedSlot) !== null && _b !== void 0 ? _b : 0; }); mod.on("packet", (event) => { var _a; if (event.packet instanceof UpdateSelectedSlotS2CPacket_1.UpdateSelectedSlotS2CPacket) { slot = event.packet.slot(); } if (event.packet instanceof UpdateSelectedSlotC2SPacket_1.UpdateSelectedSlotC2SPacket) { slot = event.packet.selectedSlot; } if (event.packet instanceof PlayerInteractItemC2SPacket_1.PlayerInteractItemC2SPacket && ((_a = _embedded_1.mc.player) === null || _a === void 0 ? void 0 : _a.inventory.main[slot].item) == Items_1.Items.ENDER_PEARL) { // use reflection to set the hand to offhand const field = event.packet.class.getDeclaredField("hand"); field.setAccessible(true); field.set(event.packet, Hand_1.Hand.OFF_HAND); _embedded_1.Client.displayChatMessage(`§cPearl use changed to hand ${event.packet.hand}`); } }); });
original typescript code
// 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"; /* eslint-enable unused-imports/no-unused-imports */ // DO NOT TOUCH ANYTHING ABOVE THIS LINE, also not sure why it didn't work import { PlayerInteractItemC2SPacket } from "@minecraft-yarn-definitions/types/net/minecraft/network/packet/c2s/play/PlayerInteractItemC2SPacket"; import { UpdateSelectedSlotC2SPacket } from "@minecraft-yarn-definitions/types/net/minecraft/network/packet/c2s/play/UpdateSelectedSlotC2SPacket"; import { UpdateSelectedSlotS2CPacket } from "@minecraft-yarn-definitions/types/net/minecraft/network/packet/s2c/play/UpdateSelectedSlotS2CPacket"; import { Items } from "@minecraft-yarn-definitions/types/net/minecraft/item/Items"; import { Hand as MCHand } from "@minecraft-yarn-definitions/types/net/minecraft/util/Hand"; const script = registerScript.apply({ name: "no-pearl-use", version: "1.0.0", authors: ["commandblock2"] }); script.registerModule({ name: "no-pearl-use", description: "cancels ender pearl use", category: "Player", }, (mod) => { var slot = 0 mod.on("enable", () => { slot = mc.player?.inventory.selectedSlot ?? 0; }) mod.on("packet", (event) => { if (event.packet instanceof UpdateSelectedSlotS2CPacket) { slot = event.packet.slot(); } if (event.packet instanceof UpdateSelectedSlotC2SPacket) { slot = event.packet.selectedSlot; } if (event.packet instanceof PlayerInteractItemC2SPacket && mc.player?.inventory.main[slot].item == Items.ENDER_PEARL ) { // use reflection to set the hand to offhand const field = (event.packet as any).class.getDeclaredField("hand"); field.setAccessible(true); field.set(event.packet, MCHand.OFF_HAND); Client.displayChatMessage(`§cPearl use changed to hand ${event.packet.hand}`); } }) })
This will indeed cancel the usage of the pearl on 1.8.x protocols
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"); /* eslint-enable unused-imports/no-unused-imports */ // DO NOT TOUCH ANYTHING ABOVE THIS LINE, also not sure why it didn't work const PlayerInteractItemC2SPacket_1 = __require("@minecraft-yarn-definitions/types/net/minecraft/network/packet/c2s/play/PlayerInteractItemC2SPacket"); const UpdateSelectedSlotC2SPacket_1 = __require("@minecraft-yarn-definitions/types/net/minecraft/network/packet/c2s/play/UpdateSelectedSlotC2SPacket"); const UpdateSelectedSlotS2CPacket_1 = __require("@minecraft-yarn-definitions/types/net/minecraft/network/packet/s2c/play/UpdateSelectedSlotS2CPacket"); const Items_1 = __require("@minecraft-yarn-definitions/types/net/minecraft/item/Items"); const script = _embedded_1.registerScript.apply({ name: "no-pearl-use", version: "1.0.0", authors: ["commandblock2"] }); script.registerModule({ name: "no-pearl-use", description: "cancels ender pearl use", category: "Player", }, (mod) => { var slot = 0; mod.on("enable", () => { var _a, _b; slot = (_b = (_a = _embedded_1.mc.player) === null || _a === void 0 ? void 0 : _a.inventory.selectedSlot) !== null && _b !== void 0 ? _b : 0; }); mod.on("packet", (event) => { var _a; if (event.packet instanceof UpdateSelectedSlotS2CPacket_1.UpdateSelectedSlotS2CPacket) { slot = event.packet.slot(); } if (event.packet instanceof UpdateSelectedSlotC2SPacket_1.UpdateSelectedSlotC2SPacket) { slot = event.packet.selectedSlot; } if (event.packet instanceof PlayerInteractItemC2SPacket_1.PlayerInteractItemC2SPacket && ((_a = _embedded_1.mc.player) === null || _a === void 0 ? void 0 : _a.inventory.main[slot].item) == Items_1.Items.ENDER_PEARL) { event.cancelEvent(); } }); });
This will desync your inventory with the server anyway, but it is true that no end pearl will be thrown if you have one in your hand (unless u have a pearl in server side but not client side). Can be used as a example.
Later is the original ts file.// 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"; /* eslint-enable unused-imports/no-unused-imports */ // DO NOT TOUCH ANYTHING ABOVE THIS LINE, also not sure why it didn't work import { PlayerInteractItemC2SPacket } from "@minecraft-yarn-definitions/types/net/minecraft/network/packet/c2s/play/PlayerInteractItemC2SPacket"; import { UpdateSelectedSlotC2SPacket } from "@minecraft-yarn-definitions/types/net/minecraft/network/packet/c2s/play/UpdateSelectedSlotC2SPacket"; import { UpdateSelectedSlotS2CPacket } from "@minecraft-yarn-definitions/types/net/minecraft/network/packet/s2c/play/UpdateSelectedSlotS2CPacket"; import { Items } from "@minecraft-yarn-definitions/types/net/minecraft/item/Items"; const script = registerScript.apply({ name: "no-pearl-use", version: "1.0.0", authors: ["commandblock2"] }); script.registerModule({ name: "no-pearl-use", description: "cancels ender pearl use", category: "Player", }, (mod) => { var slot = 0 mod.on("enable", () => { slot = mc.player?.inventory.selectedSlot ?? 0; }) mod.on("packet", (event) => { if (event.packet instanceof UpdateSelectedSlotS2CPacket) { slot = event.packet.slot(); } if (event.packet instanceof UpdateSelectedSlotC2SPacket) { slot = event.packet.selectedSlot; } if (event.packet instanceof PlayerInteractItemC2SPacket && mc.player?.inventory.main[slot].item == Items.ENDER_PEARL ) { event.cancelEvent(); } }) })
-
who can write the script? noSlotChanger in the client LB for Nextgen14 days agoTrying with matrix on loyisa.cn with noslow mode set to None indeed will move your slot to other items. However just like I assumed previously simply ignoring the packet just won't do, you can never eat the food, even if you immediately send back a slot change. You might need something else to make a nolow mode for matrix. If you need to verify yourself, here is your script anyway.
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"); /* eslint-enable unused-imports/no-unused-imports */ // DO NOT TOUCH ANYTHING ABOVE THIS LINE, also not sure why it didn't work const UpdateSelectedSlotC2SPacket_1 = __require("@minecraft-yarn-definitions/types/net/minecraft/network/packet/c2s/play/UpdateSelectedSlotC2SPacket"); const UpdateSelectedSlotS2CPacket_1 = __require("@minecraft-yarn-definitions/types/net/minecraft/network/packet/s2c/play/UpdateSelectedSlotS2CPacket"); const script = _embedded_1.registerScript.apply({ name: "anti slot changing", version: "1.0.0", authors: ["commandblock2"] }); script.registerModule({ name: "anti-slot-changing", description: "like no rotate reset but for slots", category: "Exploit", settings: { resyncServerSide: _embedded_1.Setting.boolean({ name: "resync server side", default: true }) }, }, (mod) => { mod.on("packet", (event) => { var _a, _b, _c; if (event.packet instanceof UpdateSelectedSlotS2CPacket_1.UpdateSelectedSlotS2CPacket) { event.cancelEvent(); if (!mod.settings.resyncServerSide.get()) return; (_a = _embedded_1.mc.getNetworkHandler()) === null || _a === void 0 ? void 0 : _a.sendPacket(new UpdateSelectedSlotC2SPacket_1.UpdateSelectedSlotC2SPacket((_c = (_b = _embedded_1.mc.player) === null || _b === void 0 ? void 0 : _b.inventory.selectedSlot) !== null && _c !== void 0 ? _c : 0)); } }); });