.dev

Developers3 min read

The Java API

TehoApi, TehoPlayer and how sends, futures and listeners behave.

The Java API is the dev.tehoclient.api package. It is platform-neutral: every adapter implements it, so the same code runs on Paper, a proxy, Minestom or a modded server. Platform helpers such as BukkitTeho only translate platform types.

Getting the API

Java
TehoApi api = TehoApi.get();

TehoApi.get() throws IllegalStateException when the Teho API is not running on this server. If Teho support is optional for your plugin, use TehoApi.find(), which returns an Optional<TehoApi>.

MethodReturns
player(UUID)Optional<TehoPlayer>, empty unless the player finished the handshake.
players()Every Teho player online.
isTeho(UUID)Whether player(uuid) is present.
addListener(TehoListener) / removeListenerPlatform-neutral callbacks, see Events.
assets()The asset store.
npcs(), statues(), branding(), rewards()Private modules for approved servers.

TehoPlayer

A TehoPlayer is one player's session on your server. It hangs one API off each feature.

Java
TehoPlayer teho = api.player(uuid).orElseThrow();
teho.notify(notification);
teho.waypoints().set(waypoint);
teho.hud().timer(timer);
teho.staff().grant(grant);
AccessorModuleCapability
notify(…), dismiss(id)Notificationsnotify:1
waypoints()Waypointswaypoint:1
modules()Module rulesmodules:1
hud()HUDhud:1
staff()Staff toolsstaff:1
suspect()Suspect toolssuspect:1
world()World visualsworld:1
players()Players & teamsplayers:1
keybinds()Keybindskeybind:1
camera()Cameracamera:1
audio()Audioaudio:1
social()Socialsocial:1
ui()Server UIui:1
info()Client infoinfo:1
verify()Verified clientsassert:1, attest:1
pack()Resource packspack:1
clips()Highlight clipsclips:1
broadcast()Broadcastbroadcast:1
showcase()Private modulesshowcase:1

It also tells you about the session:

MethodReturns
uniqueId(), name()Who the player is.
clientVersion(), minecraftVersion(), platform(), protocol()What they sent in Hello.
advertised(), capabilities(), supports(id)What the client offered and what was agreed.
session()The session id. A new one means the client cleared all server state.
privileges(), privilegeError()Private capabilities your grant unlocked, or why it was refused.
verifiedServer()Whether your server presented a valid verified-server certificate.
reset()Clears everything your server applied on this client.

How calls behave

Sends return boolean. true means the frame was queued. false means the player did not negotiate the capability, or you turned the feature off in config.yml. It never throws for an unsupported feature.

Builders validate early. Ids are required, and limits such as a sidebar's 32 rows or a hologram's 16 lines throw IllegalArgumentException in build(), so you find mistakes in development instead of in a player's log.

Requests return CompletableFuture. Anything that waits for the client, such as screenshots, client info, proofs and clips, completes when the reply arrives. Players can decline, so always check granted() or valid().

Java
teho.info().request("Matchmaking", ClientInfo.Field.INPUT, ClientInfo.Field.PERFORMANCE)
        .thenAccept(info -> {
            if (info.has(ClientInfo.Field.INPUT) && info.input() == ClientInfo.Input.CONTROLLER) {
                queue.joinControllerPool(teho.uniqueId());
            }
        });

A future completes on whichever thread delivered the client's reply, and that differs between platforms. Schedule back onto the thread that owns the world or player before you change game state.

State is remembered. Rules, staff grants, waypoints, cooldowns, timers and other state are kept per player in the SDK and re-sent after a re-handshake, so you only set them once.

Colours

Methods that take rgb ignore the top byte. Methods that take argb treat a value with a zero alpha byte as opaque, so 0x4DA9FF and 0xFF4DA9FF mean the same thing, and you only need the alpha byte for translucent colours such as 0x804DA9FF.

Item ids

Wherever an item is accepted, such as cooldown icons, bars or holograms, a bare id gets the minecraft: namespace, so "ender_pearl" and "minecraft:ender_pearl" are equivalent.

A listener without platform events

TehoListener has a default no-op method for every callback, so implement only what you need. It is handy in shared code that runs on more than one platform.

Java
TehoApi.get().addListener(new TehoListener() {
    @Override
    public void onReady(TehoPlayer player) {
        player.hud().timer(Timer.stopwatch("session", "Session", 0));
    }

    @Override
    public void onKey(TehoPlayer player, String keybind, boolean pressed, long heldMs) {
        if (pressed && keybind.equals("party")) {
            openPartyMenu(player);
        }
    }
});