ClientAuthProbe

Client-only half of the AuthGate: computes the session-derived authorization decision from live client state, on the client thread, every client tick, and publishes it to AuthGate's volatile. Touching Minecraft here keeps that link out of AuthGate, which loads on a dedicated server; there Lane.pump never takes the client branch, so this object is never reached.

Rides the client-lane heartbeat, which fires every tick regardless of active evals, so the gate stays fresh even when idle.

The client-known op level can read 0 for an instant right after connecting, which merely denies for that instant and self-heals on the next tick.

Types

Link copied to clipboard
private class LazyProbe(val build: () -> (Any) -> Boolean)

A reflective probe resolved at most once. get answers null until Mappings.namesResolvable: before that, every mojmap name is a guaranteed miss, and probing anyway burns 2-3 thrown exceptions per client tick — for the whole session if the mapping load failed. A resolution FAILURE is cached as a re-throw; past that point the mapping table and the runtime classes are both fixed, so the miss is permanent.

Properties

Link copied to clipboard
Link copied to clipboard

WorldData's single-player "Allow Cheats" flag. The getter was renamed getAllowCommands() (<1.20.5) -> isAllowCommands() (>=1.20.5) — inside the 1.20 jar's own version range, so no compile-time choice spans it. Resolving the live method at runtime lets ONE jar span the rename.

Link copied to clipboard

Client player's "permission level >= 3" — the COMMANDS_ADMIN tier that gates commands/cheats. Two shapes, because the 26.1 permission rework left no single compiled name spanning the range:

Link copied to clipboard

One-shot latch for the probe-failure log. observe runs ~20x/s, so a deterministic failure would otherwise emit a stack trace every client tick.

Link copied to clipboard

Same, for the unresolved path — which compute reaches without throwing.

Functions

Link copied to clipboard
private fun compute(mc: Minecraft): AuthGate.Decision
Link copied to clipboard
fun observe(self: Any?)

Compute + publish the gate. self is the Minecraft from the client-lane heartbeat.

Link copied to clipboard
private inline fun probeCall(block: () -> Boolean): Result<Boolean>

One reflective probe step. Unwraps InvocationTargetException so the reflected method's OWN throwable is what gets logged — the wrapper carries no diagnosis.

Link copied to clipboard

Still a denial — this is the authorization gate — but named: names WERE resolvable, or LazyProbe.get would have returned null, so what doesn't match is the runtime's shape, not the mapping table.