-
Notifications
You must be signed in to change notification settings - Fork 0
Packet Decorators
@shamoo/paper-packets is an unstable, Paper-only, exact-version boundary. It is generated for compatibility string protocol-1.21.8+paper.55+mache.2: Minecraft 1.21.8, Paper build 55, Mojang mappings, and Mache 2. The model contains 219 packet classes and 244 state/direction registrations with numeric IDs.
import {
OnPacketReceive,
OnPacketSend,
PacketHandler,
PACKETS,
} from '@shamoo/paper-packets';
import { Component, Context } from '@shamoo/decorators';| Decorator | Target | Argument | Purpose |
|---|---|---|---|
@PacketHandler(type) |
Method | Any generated PacketType<T>
|
Declares a handler for the packet descriptor without a compile-time direction restriction |
@OnPacketReceive(type) |
Method | A serverbound PacketType<T>
|
Declares inbound handling; TypeScript rejects a clientbound-only descriptor |
@OnPacketSend(type) |
Method | A clientbound PacketType<T>
|
Declares outbound handling; TypeScript rejects a serverbound-only descriptor |
Packet descriptors are keyed by fully qualified Java class name:
const keepAlive =
PACKETS['net.minecraft.network.protocol.game.ServerboundKeepAlivePacket'];
@Component()
export class PacketListener {
@OnPacketReceive(keepAlive)
public receive(
@Context() metadata: {
readonly direction: string;
readonly phase: string;
readonly protocolId: number;
readonly packetType: string;
},
): { readonly cancelled: boolean } {
console.info(metadata.phase, metadata.direction, metadata.packetType);
return { cancelled: false };
}
}The public decision model is pass, cancel, or replace; context declares direction, protocol state, connection identity/address, optional player, and a branded live handle. A packet may have multiple registrations across handshake, status, login, configuration, play, or common, so use registrations, not only the descriptor's first phase and direction fields.
All gates must pass:
-
Compiler gate: set
permissions.packets: trueinshamoo.config.json. Any@shamoo/paper-packetsimport without it fails withPERMISSION_REQUIRED. Packet imports are also rejected from Velocity reachability. -
Runtime operator gate: set
packets.enabled: truein Paper'splugins/ShamooRuntime/config.yml. -
Plugin allowlist gate: add the deployed descriptor plugin ID, not its npm scope, to
packets.allowed-plugins.
{
"permissions": {
"builtins": [],
"filesystem": { "read": [], "write": [] },
"network": false,
"workers": false,
"childProcess": false,
"nativeAddons": false,
"packets": true
}
}packets:
enabled: true
process-smoke: false
allowed-plugins:
- my-plugin
timeout-millis: 50
maximum-pending: 256The default Runtime configuration has packets disabled and an empty allowlist. The bridge enforces a positive timeout and bounded pending queue; backpressure failures do not silently pass packets.
The generated TypeScript API describes typed packet values, live handles, and replacement decisions, and the Java packet bridge implements exact-version pass/cancel/replacement behavior. The current bundled JavaScript host operation, however, subscribes each decorated packet handler to the broad packet stream without filtering on the decorator's PacketType. It sends only a copied metadata map containing direction, phase, protocol direction, protocol ID, and packet type. Filter packetType in the handler. The adapter interprets only { cancelled: true } as cancellation; it does not expose a live generated packet object or wire typed replacement from a decorator handler. Treat the richer TypeScript handler types as the intended host contract, not as proof that the current bundled adapter supplies those objects.
The broad createPaperHostApi().packet(...) path has the same data-only restriction. Packet processing is synchronous to the Netty ordering boundary, timeout-bounded, and security-sensitive. Test against the exact host build and provide a fail-safe decision.
Sources: TypeScript packet API, compiler permission check, and Runtime packet adapter.