.dev

Modules3 min read

Staff tools

X-Ray, ESP, freecam, inspector, action wheel and alerts that only work on your server.

staff:1Tier C · Privileged

Good for

  • X-Ray and ESP for moderators, only on your server
  • Anticheat alerts with one-key teleport
  • Inspect a player and act on them from a radial menu

Try it in game, no code

/tehoapi staff

Teho gives your moderators a full staff client that works only on your server: X-Ray, ESP, freecam, an inspector, an action wheel, alerts and more, with no hacked clients and no extra mods. Grants are per player. Each moderator accepts them once per server in a prompt that names your server, and can revoke them at any time.

Grant tools

The easy way is by permission in config.yml. From code:

Java
teho.staff().grant(StaffGrant.of(StaffTool.XRAY, StaffTool.PLAYER_ESP, StaffTool.FREECAM)
        .reason("Moderator")
        .build());

teho.staff().grant(StaffGrant.everything().reason("Senior moderator").radius(64).build());

teho.staff().revoke(StaffTool.FREECAM);
teho.staff().revokeAll();

A grant replaces the player's previous grant from your server. To add tools, start from granted().

StaffGrant.BuilderNotes
of(tools…), of(Collection), everything()Which tools.
reason(String)Shown in the consent prompt.
xray(XrayBlock…)Blocks X-Ray shows, such as XrayBlock.of("minecraft:diamond_ore", 0x5FE0DC). Defaults to common ores and spawners.
storage(XrayBlock…)Blocks storage ESP shows. Defaults to chests, shulkers, hoppers and similar.
entities(XrayBlock…)Entity types entity ESP shows.
radius(blocks)Scan radius from 8 to 128. Default 48.

Who has what

MethodReturns
granted()Tools you granted.
accepted()Tools the moderator accepted.
active()Tools switched on right now.
supported()Tools this client build can render.

TehoStaffToolEvent fires whenever a tool switches on or off, for example to vanish a moderator who enters freecam.

Tools

IdStaffToolWhat it does
xrayXRAYShows the configured ores, spawners and custom blocks through terrain.
storage_espSTORAGE_ESPOutlines chests, shulkers, hoppers and other storage.
player_espPLAYER_ESPPlayer outlines and info through walls, coloured by espColors.
nametagsNAMETAGSNametags through walls.
entity_espENTITY_ESPOutlines the configured entity types.
tracersTRACERSLines from the crosshair to tracked players.
fullbrightFULLBRIGHTFull brightness.
highlightsHIGHLIGHTSShows highlights your server sends.
lag_mapLAG_MAPChunk heat map of entities and tile entities.
trailsTRAILSDraws a player's recent movement.
inspectorINSPECTORLook at a player, block or entity for a card of facts and actions.
combat_overlayCOMBAT_OVERLAYCPS, best reach and hits above nearby players who are fighting.
spectateSPECTATEA follow camera locked to a player.
freecamFREECAMDetached camera. The moderator's body stays put.
action_wheelACTION_WHEELA radial menu of actions on whatever the moderator is looking at.
alertsALERTSAn alert feed in the HUD, with one-key teleport and spectate.
click_teleportCLICK_TELEPORTTeleport to the block the moderator clicks.

Highlights

Mark a player, a block or an area for every moderator with the highlights tool.

Java
teho.staff().highlight(Highlight.entity("vanished:" + mod.getUniqueId(), mod.getUniqueId())
        .label("Vanished")
        .color(0xB07CFF)
        .tracer(true)
        .build());

teho.staff().highlight(Highlight.area("claim-42", 100, 60, 100, 140, 90, 140)
        .label("Disputed claim")
        .style(Highlight.Style.BOTH)
        .lifetime(60_000)
        .build());

teho.staff().removeHighlights("claim-42");

Styles are OUTLINE, FILL and BOTH.

ESP colours

Java
teho.staff().espColors(Map.of(suspectId, 0xFF5555), Map.of(suspectId, "Flagged: Reach"));

Alerts

Push an alert into the feed of every moderator you send it to. Severities are INFO, WARN and HIGH.

Java
StaffAlert alert = StaffAlert.builder("ac-" + suspect.getUniqueId(), "Reach (VL 12)")
        .severity(StaffAlert.Severity.HIGH)
        .body("3.4 blocks on " + suspect.getName())
        .player(suspect.getUniqueId())
        .build();

TehoApi.get().players().stream()
        .filter(teho -> teho.staff().active().contains(StaffTool.ALERTS))
        .forEach(teho -> teho.staff().alert(alert));

With no code, point your anticheat at /tehoapi alert %player% high Reach_VL_%vl%.

Inspector cards

When a moderator inspects something, the built-in Bukkit kit answers with health, ping, game mode, first join and Teho Client for players, type, biome and contents for blocks, and type, health and age for entities. Answer TehoInspectEvent to add your own card:

Java
@EventHandler
public void onInspect(TehoInspectEvent event) {
    if (event.getTarget().kind() != Target.Kind.PLAYER) {
        return;
    }
    UUID id = event.getTarget().id();
    event.getResponder().reply(InspectCard.builder("Skyline profile")
            .subtitle(rankOf(id))
            .row("Alts", altsOf(id).size())
            .row("Warnings", warningsOf(id), 0xFFC24D)
            .action("history", "Punishment history")
            .action("ban", "Ban")
            .lifetime(10_000)
            .build());
}

Card actions arrive as TehoStaffActionEvent with the action id.

Action wheel

The wheel comes from staff.action-wheel in config. From code:

Java
teho.staff().actionWheel("Skyline staff", Arrays.asList(
        WheelAction.of("freeze", "Freeze", "ice", Target.Kind.PLAYER),
        WheelAction.of("history", "History", "book", Target.Kind.PLAYER).color(0xFFC24D),
        WheelAction.of("lagmap", "Lag map", "hopper", Target.Kind.NONE)));
Java
@EventHandler
public void onAction(TehoStaffActionEvent event) {
    if (event.getAction().equals("history")) {
        openHistory(event.getPlayer(), event.getTarget().id());
    }
}

Target stats, trails, spectate and lag map

Java
teho.staff().targetStats(suspectId, Arrays.asList(
        StatRow.of("CPS", 17, 0xFF5555),
        StatRow.of("Reach", "3.4")), 2000);

teho.staff().trail(suspectId, points, 0xFFC24D, "Last 5 minutes", "overworld", 30_000);

teho.staff().spectate(suspectId, 4);
teho.staff().stopSpectating();

teho.staff().lagMap("overworld", Arrays.asList(
        LagCell.of(12, -4, 92, "412 item frames"),
        LagCell.of(13, -4, 40, "88 hoppers")), 60_000);

Each trail point is an int[] of {x, y, z}.

Built in on Bukkit

With no code, the Bukkit plugin already provides the action wheel (freeze, spectate, teleport, inventory view, screenshot, mod check, path history, lag map, kick), inspector cards, freeze, screenshot and mod-check requests, movement trails, the combat overlay and the alert feed. See Commands.