Skip to content

NativeMethodAccess

youyihj edited this page Sep 22, 2024 · 2 revisions

Native Method Access

@since 1.19.0

A native method is a method whose implementation is provided by other programming languages.

You can directly access java native classes and methods in zenscript.

Import a native class

Besides the name of the native class, native. prefix is required.

import native.net.minecraft.world.World; to import net.minecraft.world.World class.

All public methods and fields are accessible by zenscript.

Conversion between Minecraft classes and CraftTweaker class

CraftTweaker has tons of classes, like IWorld, IPlayer and so on, which are basically wrappers of Minecraft classes. Native Minecraft classes are required for native methods, but in crafttweaker events and other zenscript api, only CraftTweaker wrappers are given. Thus, conversion between each other is necessary.

For (almost all) CraftTweaker classes, call native getter to convert it to mc classes.

For mc classes with the corresponding CraftTweaker class, call wrapper getter to convert it to CraftTweaker classes.

The conversion also be applied as caster, so as XXX is available, and conversion will be automatic when passing in a function or method.

Method remap

It is widely known that Minecraft is a commercial game, its code is obfuscated. MCP provides a mapping between obfuscated and human-readable names to ease the development of mods. ZenUtils downloads MCP version stable-39 to remap methods. Then MCP names are available in zenscript, ZenUtils translates them to mc obfuscated names to access mc methods.

Downloading may take a little while. By default, downloading will start and blocks the game loading until finished when you use native method by the first time. If you are certain you will use native methods, you can add #download_reobf_mapping preprocessor to start to download asynchronously when preinit.

Getter/Setter method

About getFoo() and setFoo(foo) java getter/setter method, zenscript foo getter/setter can be translated to them.

Iterable interface

For a java type Iterable<T> or any subclasses, you can iterate it, get its length and cast it to list.

Example:

val set = foo(); // foo returns Set<String>, Set is a subclass of Iterable.
val list = set as [string]; // casts it to string list
print(set.length); // gets its length
for s in set { // iterate it, the type of s variable is string
    print("a string:" ~ s);
}

Check Equals

== != operator are available to all native classes, it calls Objects.equals java method.

Downcast Note

Left unchecked cast is allowed to the crt class. But the native class is not, and requires right checked cast.

// crt
val entity as IEntity = event.entity;
if (entity instanceof IPlayer) {
    val player as IPlayer = entity;
}

// mc
val mcEntity as Entity = entity.native;
if (mcEntity instanceof Player) {
    val mcPlayer = entity as Player;
}

Example

import crafttweaker.event.PlayerLoggedInEvent;
import crafttweaker.player.IPlayer;
import native.net.minecraft.world.gen.ChunkProviderServer;
import native.net.minecraft.world.chunk.Chunk;
import native.net.minecraft.world.World;

// expansion method, syntax:
// https://docs.blamejared.com/1.12/en/AdvancedFunctions/Expansion_Methods
$expand World$loadedChunkCount() as int {
    val chunkProvider = this.chunkProvider;
    if (chunkProvider instanceof ChunkProviderServer) {
        // loadedChunks getter calls getLoadedChunks() method and returns Set<Chunk> 
        return (chunkProvider as ChunkProviderServer).loadedChunks.length;
    }
    return 0;
}

events.onPlayerLoggedIn(function(event as PlayerLoggedInEvent) {
    val player = event.player;
    if (event.player.world.remote) return;
    event.player.world.catenation()
        .sleep(10)
        .run(function(world, context) {
            print(world.native.loadedChunkCount() ~ " chunks loaded");
        })
        .start();
});

Sensitive Operations Blacklist

Not all native codes are exposed to zenscript, sensitive operations are blacklisted from being called or referenced.

It includes:

  • File IO
  • Network
  • Window
  • Multithreading
  • Mixin/ASM
  • Other language lib (scala kotlin groovy)
  • Java low-level code (java.lang, jdk., sun., ...)
Clone this wiki locally