ChatTriggers Framework

repository·master·Indexed 41 days ago

https://github.com/chattriggers/chattriggers

A JavaScript-based framework for Minecraft that enables live scripting and client-side modifications through an event-driven system of Triggers. Built on Rhino, it supports ES6+ features, including optional chaining, nullish coalescing, and decorators. The framework provides APIs for custom in-game commands, image rendering, and chat message manipulation, with a sandboxed module system introduced in version 1.0.0.

Tokens
13.1K
Snippets
42
Records
67
Agent score
51%

What's inside ChatTriggers

  1. What is ChatTriggers and how does it work?

    master

    ChatTriggers is a Minecraft framework for live scripting and client modification using JavaScript. It provides libraries, wrappers, and objects to simplify modding.

    Key technical details:

    • Engine: Built on Rhino using Java 8.
    • Compatibility: Supports most Rhino methods and some ES6 features.
    • Core Concept: Everything is based around Triggers, which act as event listeners. Triggers can respond to various Minecraft events, such as chat messages or rendering overlays.
    • Advanced Access: While wrappers are provided, you can still access exposed Minecraft methods and variables directly if you have knowledge of FML mappings.
  2. How to use Triggers for event listening

    master

    Triggers are the fundamental building block of ChatTriggers. You use the register function to listen for specific events.

    Common patterns include:

    • Chat Triggers: Run code when a specific chat pattern is matched. You can use .setCriteria() to define the pattern and access captured groups.
    • Render Triggers: Run code during specific rendering phases (e.g., renderCrosshair).

    Note: You can use cancel(event) within a trigger to prevent the original Minecraft event from proceeding.

    // Example: A chat trigger that intercepts a message and re-chats it
    register("chat", function(name, message, event) {
      cancel(event);
      ChatLib.chat(name + ": " + message);
    }).setCriteria("<${name}> ${message}");
    
    // Example: A render trigger that draws a small rectangle at the center of the screen
    register("renderCrosshair", function(event) {
      cancel(event);
      Renderer.drawRect(
        0x50ffffff,
        Renderer.screen.getWidth() / 2 - 1,
        Renderer.screen.getHeight() / 2 - 1,
        2, 2
      );
    });
  3. Use ES7+ features in ChatTriggers (Rhino)

    master

    The custom Rhino engine supports several modern JavaScript features:

    Exponentiation Operator (**)

    Replaces Math.pow. Note: if the first argument is negative, you must use parentheses to avoid syntax errors.

    print((-5) ** 2); // '25'

    Array and Object features

    • Array.prototype.includes(object)
    • Array.prototype.lastItem / lastIndex
    • Object.values(object) / Object.entries(object)
    • Object.getOwnPropertyDescriptors(object)
    • Object Rest/Spread (ES9):
      const { a, ...rest } = { a: 1, b: 2, c: 3 }; // rest === { b: 2, c: 3 }
      const o = { a: 1, ...spread };

    Advanced Operators

    • Optional Chaining (?.): Safely access nested properties.
    • Nullish Coalescing (??): Returns the right-hand side if the left-hand side is null or undefined.
    • Throw Expressions: throw can now be used inside expressions (e.g., in function parameters or with ??).
    • Pipeline Operator (|>): Inlines multiple chained function calls.
      const result = a |> f3 |> f2 |> f1;
  4. Use Class Fields and Decorators in Rhino

    master

    ChatTriggers' Rhino engine supports modern class syntax and decorators.

    Class Fields

    Supports public, private (using #), and static fields.

    class Foo {
        x = 5;
        #y = 10; // private
        static z = 15;
    }

    Built-in Decorators

    • @wrap(fn): Runs before class creation. The function receives the target (method or class) and returns a new version of it.
    • @register(fn): Runs after class creation. The function receives the target (class or prototype) and the key (for public elements).
    • @initialize(fn): Runs inside the constructor during instantiation. The function receives (target, key, value).

    User-Defined Decorators (UDDs)

    Custom decorators can be defined using the decorator keyword and must consist of other decorators.

    class Foo {
        @wrap(method => () => method() * 2)
        x() {
            return 6;
        }
    }
    
    print((new Foo).x()); // '12'
  5. Migrate modules from 0.18.4 to 1.0.0

    master
    ChatTriggers 1.0.0 introduced a new JavaScript engine (Rhino) and a completely reworked module engine. Modules built for 0.18.4 (Nashorn) are not compatible with 1.0.0. The primary architectural change is the introduction of sandboxing: in 1.0.0, each module has its own top-level scope. Global variables declared in one module or file are no longer accessible in another.
  6. Use ES6 modules to share data between files in 1.0.0

    master

    Because modules are now sandboxed in 1.0.0, you must use ES6 import and export syntax to share functions, variables, or classes between files.

    To export a function from lib.js:

    export { add };

    To import it in main.js:

    import { add } from './lib';

    You can also import using the module name: import { add } from '<MyModuleName>/lib'.

    /* lib.js */
    function add(num1, num2) {
        return num1 + num2;
    }
    
    // Export the function so that any other module can use it
    export { add };
    
    /* main.js */
    // import the function
    import { add } from './lib'; // note that you could also import from '<MyModuleName>/lib'
     
    print(add(4, 9)); // prints '13'
  7. Understand ChatTrigger Arguments

    master

    When a ChatTrigger is fired, the arguments passed to your callback function depend on your setChatCriteria configuration.

    1. Captured Variables: Any values captured via ${variableName} in your criteria string are passed as arguments in the order they appear.
    2. The Chat Event: The ClientChatReceivedEvent object is always passed as the last argument in the list.
    3. The Raw Message: If you use placeholders, the captured strings are passed. If you do not use placeholders, the arguments list will primarily contain the event.

    Note: The first argument in the underlying implementation is the raw chat message string, and the second is the ClientChatReceivedEvent.

  8. Reference of ChatTriggers API changes in 1.0.0

    master

    The following built-in libraries and methods have changed or been added in version 1.0.0:

    • Removed: XMLHttpRequest (use the request module instead).
    • Commands: ChatLib.command now includes an optional parameter to trigger other client-side commands.
    • Message: Added Message#getFormattedText and Message#getUnformattedText.
    • Tessellator:
      • Added Tessellator.getRenderPos(x, y, z).
      • Changed parameter order for Tessellator.drawString:
        • Old: (text, x, y, z, renderBlackBox, partialTicks, scale, color, increase)
        • New: (text, x, y, z, color, renderBlackBox, scale, increase)
    • Renderer: Added Renderer.getRenderManager.
    • World/Client: Moved World.showTitle to Client.showTitle.
    • Inventory: Changed parameter order for Inventory#click:
      • Old: (slot, button, shift)
      • New: (slot, shift, button)
    • New Triggers: registerRenderArmor.
  9. Reference of miscellaneous Rhino functions and properties

    master

    The following additional functions and properties are available in the custom Rhino build:

    Math & Conversion

    • Math.signBit(number), Math.clamp(value, min, max)
    • Math.DEG_PER_RAD, Math.RAD_PER_DEG
    • Math.degrees(number), Math.radians(number)
    • Math.fscale(value, min1, max1, min2, max2), Math.scale(value, min1, max1, min2, max2)

    Set & Map Operations

    • Set.prototype.intersection(set), union(set), difference(set), symmetricDifference(set), isDisjointFrom(set), isSubsetOf(set), isSupersetOf(set), addAll(...items), deleteAll(...items), every(fn), filter(fn), find(fn), join(string), map(fn), reduce(fn, initialValue), some(fn)
    • Map.prototype.upsert(key, insertFn, updateFn), merge(map), reduce(fn, initialValue), mapKeys(fn), mapValues(fn), keyBy(set, keyFn), groupBy(set, groupFn)
    • Map.prototype.deleteAll(...keys), Map.prototype.every(fn), Map.prototype.filter(fn), Map.prototype.find(fn), Map.prototype.findKey(fn), Map.prototype.includes(obj), Map.prototype.keyOf(obj)

    WeakMap/WeakSet

    • WeakMap.prototype.upsert(...), deleteAll(...keys)
    • WeakSet.prototype.addAll(...items), deleteAll(...items)
  10. Instantiate a BlockType

    master

    A BlockType is an immutable wrapper around a Minecraft block definition. It represents the concept of a block (e.g., 'Stone') rather than a specific instance of a block at a specific coordinate in the world. To interact with a specific block in the world, use withBlockPos(blockPos) to create a Block object.

    You can instantiate a BlockType using several different methods:

    • By Name: Using the registry name (e.g., minecraft:planks).
    • By ID: Using the integer block ID.
    • From an Item: Using an existing Item object.
    • From another BlockType: Using a copy constructor.
    // By registry name
    const stoneType = new BlockType("minecraft:stone");
    
    // By ID
    const stoneTypeById = new BlockType(1);
    
    // From an Item
    const item = ...; // some Item object
    const stoneTypeFromItem = new BlockType(item);
    
    // Convert to a specific block instance at a position
    const blockAtPos = stoneType.withBlockPos(new BlockPos(0, 64, 0));
  11. Control Minecraft connection and GUI state

    master

    The Client companion object provides several methods to control the game's connection and interface state:

    • Client.connect(ip: String): Connects to a server at the specified IP address.
    • Client.disconnect(): Disconnects from the current server/world and returns to the main menu.
    • Client.isInChat(): Returns true if the chat GUI is currently open.
    • Client.isInTab(): Returns true if the player list (Tab GUI) is currently open.
    • Client.isInGui(): Returns true if any GUI screen is currently open.
    • Client.getChatGUI(): Returns the GuiNewChat object.
    • Client.getTabGui(): Returns the GuiPlayerTabOverlay object.
  12. Get Item metadata and properties

    master

    Use the following methods to retrieve information about an Item:

    • getStackSize(): Returns the current quantity in the stack.
    • setStackSize(size): Sets the quantity in the stack.
    • getName(): Returns the item's display name (e.g., "Oak Wood Planks").
    • getUnlocalizedName(): Returns the unlocalized name (e.g., "tile.wood").
    • getRegistryName(): Returns the full registry name (e.g., "minecraft:planks").
    • getID(): Returns the integer ID of the item.
    • getMetadata(): Returns the item's metadata.
    • getLore(): Returns a list of strings representing the item's lore lines.