Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Method overloading support in script api #5242

Open
wants to merge 2 commits into
base: nextgen
Choose a base branch
from

Conversation

commandblock2
Copy link
Contributor

This pr fixes this issue, now corresponding method overloads can be automatically selected by arguments as shown below (Without using ReflectionUtil).

const script = registerScript({
  name: "IssueExample",
  version: "1.0.0",
  authors: ["Ajax"]
});

RenderLayer = Java.type("net.minecraft.client.render.RenderLayer")
SpectatorMenu = Java.type("net.minecraft.client.gui.hud.spectator.SpectatorMenu")
EnvironmentRemapper = Java.type("net.ccbluex.liquidbounce.utils.mappings.EnvironmentRemapper").INSTANCE
Color4b = Java.type("net.ccbluex.liquidbounce.render.engine.Color4b")

const CLOSE_TEXTURE = ReflectionUtil.getDeclaredField(SpectatorMenu.class, "CLOSE_TEXTURE")

script.registerModule({
  name: "IssueExample_drawGuiTexture",
  category: "Client",
  description: "Sausage"
}, (mod) => {

  mod.on("overlayRender", (event) => {
    if (!mc.player || !mc.world)
      return;

    // Should map to method_52706, but (probably) maps to method_52709
    // inb4 some smartass goes "oh this is because of null!1!", no
    event.context.drawGuiTexture(RenderLayer.getGuiTextured, CLOSE_TEXTURE, 0, 0, 16, 16, -1);    
  })
});

script.registerModule({
  name: "IssueExample_fill",
  category: "Client",
  description: "Sausage"
}, (mod) => {

  mod.on("overlayRender", (event) => {
    if (!mc.player || !mc.world)
      return;

    // Should map to method_25294, but (probably) maps to method_51737
    event.context.fill(100, 100, 200, 200, -1); // overload without z (default = 0)
    event.context.fill(50, 50, 150, 150, 1, Color4b.access$getBLUE$cp().alpha(128).toARGB()); // overload with z to be specified
    event.context.fill(150, 150, 250, 250, -1, Color4b.access$getGREEN$cp().alpha(128).toARGB());  
  })
});
method-overload-support.mp4

Comment on lines 107 to 108
for (final var overload : overloads)
methodsToRemap.add(getReflectionMethodFromSingleMethod(overload));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Brackets { ... }

@commandblock2 commandblock2 marked this pull request as draft January 10, 2025 17:49
@commandblock2
Copy link
Contributor Author

commandblock2 commented Jan 10, 2025

[01:47:47] [Render thread/ERROR]: Failed to remap field: length
java.lang.NoSuchFieldException: field
	at java.base/java.lang.Class.getDeclaredField(Class.java:2782) ~[?:?]
	at knot/com.oracle.truffle.host.HostClassDesc$Members.getField(HostClassDesc.java:716) ~[org_graalvm_truffle_truffle-api-24.0.2-995983b52bfdc5a1.jar:?]
	at knot/com.oracle.truffle.host.HostClassDesc$Members.remapFieldEntries(HostClassDesc.java:678) ~[org_graalvm_truffle_truffle-api-24.0.2-995983b52bfdc5a1.jar:?]
	at knot/com.oracle.truffle.host.HostClassDesc$Members.handler$cgi000$liquidbounce$remapClassDesc(HostClassDesc.java:603) ~[org_graalvm_truffle_truffle-api-24.0.2-995983b52bfdc5a1.jar:?]
...
[01:47:47] [Render thread/ERROR]: Failed to remap method: clone
java.lang.reflect.InvocationTargetException: null
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:118) ~[?:?]
	at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[?:?]
	at knot/com.oracle.truffle.host.HostClassDesc$Members.getReflectionMethodFromSingleMethod(HostClassDesc.java:665) ~[org_graalvm_truffle_truffle-api-24.0.2-995983b52bfdc5a1.jar:?]
	at knot/com.oracle.truffle.host.HostClassDesc$Members.remapMethodEntries(HostClassDesc.java:624) ~[org_graalvm_truffle_truffle-api-24.0.2-995983b52bfdc5a1.jar:?]
	at knot/com.oracle.truffle.host.HostClassDesc$Members.handler$cgi000$liquidbounce$remapClassDesc(HostClassDesc.java:606) ~[org_graalvm_truffle_truffle-api-24.0.2-995983

but actually this is just logging in a catch block,

        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 field: {}", key, e);
                continue;
            }

            if (remapped != null) {
                map.remove(key);
                map.put(remapped, value);
            }
        }

Produced by enabling the following script (copied and combined from documentation), note that the key settings are still not yet correct. But the output in chat appears to be working as intended though.

const script = registerScript({
    name: "MyScript",
    version: "1.0.0",
    authors: ["My Name"]
});

script.registerModule({
    name: "MyModule",
    category: "Misc",
    description: "An example module created with LiquidBounce's script API.",
    settings: {
        fastSwing: Setting.boolean({
            name: "FastSwing",
            default: true
        }),
        range: Setting.float({
            name: "Range",
            default: 3.0,
            range: [0.5, 8.0],
            suffix: "blocks"
        }),
        randomness: Setting.floatRange({
            name: "Randomness",
            default: [2.3, 7.8],
            range: [0.0, 10.0],
            suffix: "jitter"
        }),
        expand: Setting.int({
            name: "Expand",
            default: 4,
            range: [0, 10],
            suffix: "blocks"
        }),
        cps: Setting.intRange({
            name: "CPS",
            default: [4, 10],
            range: [0, 20],
            suffix: "cps"
        }),
        key: Setting.key({
            name: "Key",
            default: "key.keyboard.d"
        }),
        message: Setting.text({
            name: "Message",
            default: "This is a default message."
        }),
        messages: Setting.textArray({
            name: "Messages",
            default: ["This is a message", "This is another message"]
        }),
        animal: Setting.choose({
            name: "Animal",
            default: "Capybara",
            choices: ["Axolotl", "Capybara", "Snek"]
        })
    }
}, (mod) => {
    mod.on("enable", () => {
        Client.displayChatMessage(`FastSwing: ${mod.settings.fastSwing.value}`);
        Client.displayChatMessage(`Range: ${mod.settings.range.value}`);
        Client.displayChatMessage(`Randomness: ${mod.settings.randomness.value}`);
        Client.displayChatMessage(`Expand: ${mod.settings.expand.value}`);
        Client.displayChatMessage(`CPS: ${mod.settings.cps.value}`);
        Client.displayChatMessage(`Key: ${mod.settings.key.value}`);
        Client.displayChatMessage(`Message: ${mod.settings.message.value}`);
        Client.displayChatMessage(`Messages: ${mod.settings.messages.value}`);
        Client.displayChatMessage(`Animal: ${mod.settings.animal.value}`);

        mod.settings.fastSwing.value = false;
        mod.settings.range.value = 2.3;
        mod.settings.randomness.value = [2, 4.34];
        mod.settings.expand.value = 2;
        mod.settings.cps.value = [5, 12];
        mod.settings.key.value = "key.keyboard.a";
        mod.settings.message.value = "Axolotls are cool";
        mod.settings.messages.value = ["New message 1", "New message 2"];
        mod.settings.animal.value = "Axolotl";
    });
});

script.registerCommand({
    name: "addition",
    aliases: ["add"],
    parameters: [{
        name: "a",
        required: true,
        validate: ParameterValidator.integer
    },
    {
        name: "b",
        required: true,
        validate: ParameterValidator.integer
    }
    ],
    onExecute(arg1, arg2) {
        Client.displayChatMessage(`Result of ${arg1} + ${arg2} is ${arg1 + arg2}`);
    }
});


script.registerCommand({
    name: "description",
    parameters: [{
        name: "module",
        required: true,
        validate: ParameterValidator.module,
    }],
    onExecute(mod) {
        Client.displayChatMessage(`Description of module ${mod.name} is '${mod.description}'`);
    }
});

image

@commandblock2 commandblock2 marked this pull request as ready for review January 10, 2025 17:55
@commandblock2 commandblock2 marked this pull request as draft January 10, 2025 18:01
@commandblock2
Copy link
Contributor Author

commandblock2 commented Jan 10, 2025

This (intended behavior or not) is not introduced in this pr, and can be reproduced on previous build liquidbounce-fb4eeb4 too but with a slightly different stacktrace (this pr splits remapEntries for fields and methods).
Following is the one on old build

[02:04:39] [Render thread/ERROR]: Failed to remap: clone
java.lang.reflect.InvocationTargetException: null
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:118) ~[?:?]
	at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[?:?]
	at knot/com.oracle.truffle.host.HostClassDesc$Members.getMethod(HostClassDesc.java:620) ~[org_graalvm_truffle_truffle-api-24.0.2-995983b52bfdc5a1.jar:?]
	at knot/com.oracle.truffle.host.HostClassDesc$Members.remapEntries(HostClassDesc.java:599) ~[org_graalvm_truffle_truffle-api-24.0.2-995983b52bfdc5a1.jar:?]

@commandblock2 commandblock2 marked this pull request as ready for review January 10, 2025 18:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants