This commit is contained in:
Brian Neumann-Fopiano
2026-08-01 22:39:09 -04:00
parent 324cf9e095
commit a8217b42e9
220 changed files with 10626 additions and 1661 deletions
@@ -41,6 +41,10 @@ public interface PlatformRegistries {
/**
* Resolves a block key, returning null instead of an air fallback when it does not resolve. Silent.
* <p>
* Unlike {@link #block(String)} this never consults the platform's compatibility layer. On Bukkit that layer only
* sees keys the underlying lookup could not answer at all, so an unregistered key resolves to air through
* {@link #block(String)} on every platform - the Bukkit-only legacy rewrite table cannot fork generation output.
*/
PlatformBlockState blockOrNull(String key);
@@ -109,6 +113,18 @@ public interface PlatformRegistries {
*/
List<String> blockTypeKeys();
/**
* Every entity key contributed by third-party content integrations rather than the vanilla entity registry -
* Bukkit item/mob plugins on the Bukkit side, registered custom-content providers on mod loaders. Feeds pack
* schema completion for custom mob types only; never the spawn path. Never null.
* <p>
* Defaults to empty so a platform with no integration surface needs no implementation, and so schema
* generation never has to reference a platform-specific service type directly.
*/
default List<String> specialEntityKeys() {
return List.of();
}
/**
* Every registered enchantment key. Never null.
*/
@@ -38,7 +38,10 @@ public final class IrisMessageCodec {
* Encodes {@code message} into a frame: type id as a varint, then the record's fields in declaration order.
* Never returns null.
*
* @throws IllegalStateException if the encoded form exceeds {@link IrisProtocol#MAX_FRAME_BYTES}
* @throws IllegalStateException if the encoded form exceeds {@link IrisProtocol#MAX_FRAME_BYTES}, or if a
* {@link IrisMessage.VisionMarkers} carries more than
* {@link IrisProtocol#MAX_VISION_MARKERS} entries (the decoder rejects such a
* frame, so producing one would only strand the payload)
*/
public static byte[] encode(IrisMessage message) {
IrisWireWriter writer = new IrisWireWriter();
@@ -106,6 +109,9 @@ public final class IrisMessageCodec {
writer.writeInt(visionMarkers.tileZ());
writer.writeInt(visionMarkers.zoomLevel());
List<IrisMessage.VisionMarkers.Marker> markers = visionMarkers.markers();
if (markers.size() > IrisProtocol.MAX_VISION_MARKERS) {
throw new IllegalStateException("marker count " + markers.size() + " exceeds " + IrisProtocol.MAX_VISION_MARKERS);
}
writer.writeVarInt(markers.size());
for (IrisMessage.VisionMarkers.Marker marker : markers) {
writer.writeInt(marker.blockX());
@@ -178,7 +184,10 @@ public final class IrisMessageCodec {
if (count < 0) {
throw new ProtocolException("negative marker count");
}
List<IrisMessage.VisionMarkers.Marker> markers = new ArrayList<>(Math.min(count, IrisProtocol.MAX_VISION_MARKERS));
if (count > IrisProtocol.MAX_VISION_MARKERS) {
throw new ProtocolException("marker count " + count + " exceeds " + IrisProtocol.MAX_VISION_MARKERS);
}
List<IrisMessage.VisionMarkers.Marker> markers = new ArrayList<>(count);
for (int index = 0; index < count; index++) {
markers.add(new IrisMessage.VisionMarkers.Marker(reader.readInt(), reader.readInt(), reader.readInt(), reader.readString()));
}
@@ -39,6 +39,17 @@ public final class IrisProtocol {
public static final int MAX_INBOUND_FRAMES_PER_SECOND = 32;
/** Vision tile requests accepted per client per second, tighter than the general frame budget because each one costs a render. */
public static final int MAX_VISION_TILE_REQUESTS_PER_SECOND = 8;
/**
* Cursor lookups accepted per client per second. Its own budget rather than a slice of
* {@link #MAX_INBOUND_FRAMES_PER_SECOND}: each lookup drives three engine column queries, so a client that
* spent its whole frame budget on cursors would cost 32 column resolves per second per player.
*/
public static final int MAX_CURSOR_INFO_REQUESTS_PER_SECOND = 4;
/**
* Largest absolute block coordinate a client may ask the generator about - the vanilla world border limit.
* Coordinates outside it are rejected rather than clamped so a spoofed frame is counted, not served.
*/
public static final int MAX_QUERY_BLOCK_COORDINATE = 29_999_999;
/** Fixed header size of a vision tile frame, subtracted when splitting a tile into chunks. */
public static final int VISION_TILE_HEADER_BYTES = 25;
/** Largest payload carried by one vision tile chunk. */