Help with setting visibility
-
Hello. I'm currently trying to learn how to use nextgen's scriptAPI. I've created a simple module just to mess around and to learn it. Here is part of the code related to what I'm trying to do:
script.registerModule({ name: "TestFly", category: "Movement", description: "Fly module, made for learning purposes.", settings: { mode: Setting.choose({ name: "Mode", choices: ["Vanilla", "Hard", "Airwalk"], default: "Vanilla" }), speed: Setting.float({ name: "Speed", default: 1.0, range: [0.1, 5.0], }) } }, (mod) => {
I'm trying to make the "Speed" setting only visible when the vanilla mode is selected. Or I'm trying to make the Speed setting be within the mode setting only when Vanilla option is selected. In the default fly module the relevant settings are inside the mode setting and they change depending on which mode of fly is selected. Is this possible to do in nextgen's scriptapi? I couldn't find out how to do it in the documentation.
In short I'm asking how make settings within settings in the scriptapi.I also want to know if is it possible to add the "Toggle/ hold" setting in the scriptapi? This is the setting next to the bind button on some modules that makes the module only active when holding down the keybind.
-
Afaik, 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. -
But 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.
-
This might be possible actually I think, if you put it in the lambda near mod.on that might even work, will try later
-
@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}`) }) })
-
Also 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. -
By reading your post again I think I need to use ChoiceConfigurable. And I think that's definitely possible.
1/7