Protocol2 min read
Node, Python & Rust
Protocol libraries for servers that are not written in Java.
For servers and proxies that are not written in Java, Teho ships protocol libraries for Node.js, Python and Rust. They speak exactly the same frames as the Java SDK, so you can use every feature without a plugin.
| Language | Package | Needs |
|---|---|---|
| Node.js | @tehoclient/server-api, with TypeScript types | Node 16+ |
| Python | teho-api | Python 3.8+ |
| Rust | teho-api crate, no dependencies | Rust 1.73+ |
Install
All three are hosted on Teho's own package repository, repo.tehoclient.dev, so there is nothing to sign up for. Package versions match the Java SDK.
npm install https://repo.tehoclient.dev/packages/npm/tehoclient-server-api-1.0.0.tgzpython -m pip install --no-index teho-api==1.0.0 --find-links https://repo.tehoclient.dev/packages/pypi/index.htmlIn requirements.txt, put --no-index and --find-links https://repo.tehoclient.dev/packages/pypi/index.html on separate lines above teho-api==1.0.0.
Add Teho's registry once, in .cargo/config.toml:
[registries.teho]
index = "sparse+https://repo.tehoclient.dev/packages/cargo/index/"Then depend on it from that registry:
[dependencies]
teho-api = { version = "1.0.0", registry = "teho" }What each library gives you
encodeanddecodefor all 108 framed messages and their nested types, with the same limits as the Java SDK: 32,000-byte frames, 1,024-byte strings (8,192 for grants and certificates) and capped list lengths.framesand aReassembler, which split messages over 32,000 bytes intoChunkframes and join them back: 4 MB per stream, at most 8 open streams, 30 seconds before a stream times out.welcome, which answers aHelloby enabling the capabilities both sides support.- A
Sessionthat runs the handshake, drops messages for capabilities the player did not enable, reassembles chunks and matches replies to requests.
Using a session
- Register the
teho:apiplugin channel with your server software. - Feed every incoming payload on that channel to
session.receive(frame). The session answersHellowithWelcomeby itself. - Send features with
session.send(...). Each frame you are handed goes out as one plugin message.
const teho = require('@tehoclient/server-api')
const session = new teho.Session({
serverName: 'Skyline',
send: (frame) => player.sendPluginMessage(teho.CHANNEL, frame),
})
player.onPluginMessage(teho.CHANNEL, (frame) => session.receive(frame))
session.send('Notify', { id: 'welcome', title: 'Welcome', body: 'Good luck!', accent: 0x4DA9FF, durationMs: 4000 })
const info = await session.request('InfoRequest', { fields: ['input'], reason: 'Matchmaking' })import teho_api as teho
session = teho.Session(lambda frame: player.send_plugin_message(teho.CHANNEL, frame), "Skyline")
def on_plugin_message(frame):
session.receive(frame)
session.send(teho.Timer(id="round", label="Round ends", mode=0, millis=120000))let mut session = teho_api::Session::new("Skyline");
let mut outbox = Vec::new();
session.receive(&frame, &mut outbox)?;
if let Some(frames) = session.send(teho_api::Cooldown {
id: "pearl".into(),
label: "Ender pearl".into(),
duration_ms: 15_000,
..Default::default()
})? {
outbox.extend(frames);
}Private capabilities
npc:1, statue:1, branding:1 and showcase:1 still need a private grant. Pass it as the grant option or field on the session, and the client checks it exactly as it does for the Java SDK.
One corpus, four languages
The message code is generated from teho_api.proto and the Java message classes, which hold the type ids and limits:
python generate.pyThe generator also writes a shared corpus with one populated frame per message. Java's LightweightCorpusTest and each library's own tests check that every implementation encodes the corpus to the same bytes.
cd node && npm testcd python && python -m unittest discover -s testscd rust && cargo test