4B
Client-mod API consolidation release — high-level Python interface, cleaner extension exports, and client/runtime hardening and readability improvements.
Changes
ClientMod Session-First API
- Consolidated extension entrypoints around
client_modfrombridge.extensions.client_mod. - Standardized per-player calls through
ClientModSession(cm = client_mod.session(player)) and methods likecm.command(...),cm.register_script(...),cm.raycast(...),cm.stream_audio_file(...), andcm.stream_audio_generator(...). - Exposed singleton decorators/registries for event and payload wiring:
client_mod.on_client_data,client_mod.on_permission_change,client_mod.register_request_data(...),client_mod.unregister_request_data(...). - Normalized exports in
bridge.extensionsto favor object-based API usage (ClientMod,ClientModSession,client_mod) over flat helper-only usage.
BridgeInstance and Event Routing Correctness
- Added script-only event bookkeeping via
BridgeInstance.scriptOnlySubscriptionssoBridgeInstance.hasSubscription(...),BridgeInstance.getSubscriptionNames(), and dispatch matching include script-local handlers. - Added
BridgeInstance.resolveInvokeResult(...)to correctly resolve nestedCompletableFuturereturns with timeout/error propagation into Python responses. - Corrected broadcast path in
BridgeInstanceto returnserver.broadcastMessage(...)behavior instead of log-only side effects. - Hardened material handling in
BridgeInstance(sendBlockChange) with explicitMaterial.matchMaterial(...)null checks beforeBukkit.createBlockData(...).
Serializer/Facade Guard Rails
- Added
BridgeSerializerinventory validation indeserialize(...)(sizemust be9..54and a multiple of9). - Removed implicit world mutation from
BridgeSerializerBlockdeserialization (no hiddenblock.setType(...)side effects). - Tightened boolean coercion in
BridgeSerializer.coerceArg(...)to explicitly parse"true"/"false"string inputs. - Added operation volume/bounds enforcement in
RegionFacade.pasteOperations(...)and stronger invalid block-data failure behavior inRegionFacade.parseBlockData(...). - Enforced protocol-version validation in
ClientModFrameCodec.decodeFrame(...).
Python Runtime Concurrency and Lifecycle Safety
- Added
BridgeConnectionlocking around_pending_syncand batching (_pending_sync_lock,_batch_lock) to avoid races between reader/caller threads. - Made
BridgeConnection.flush()atomically snapshot/clear_batch_messagesand_batch_futuresbefore sendingcall_batch. - Added atomic abort reporting:
server.atomic()now yields an int-like counter (with server.atomic() as num_failed:/async with ...) andserver.flush()returns the aborted-call count for the flushed batch. - Hardened disconnect/shutdown behavior in
BridgeConnectionso pending sync waits are finalized safely and loop stop is scheduled via_loop.call_soon(...). - Added proxy handle refcount synchronization in
wrappers.py(_handle_refcounts_lock) and deterministic LRU-like UUID cache helpers (_cache_get_player_uuid,_cache_set_player_uuid).
Extension Correctness and Recovery Paths
- Prevented duplicate updater loops by task dedupe/cancel logic in
ability.py,combat.py,quest.py,leaderboard.py,scheduler.py, andstate_machine.py. - Added malformed persistence recovery for JSON-backed extensions (
bank.py,levels.py,player_data.py,guild.py). - Fixed transactional currency flow in
trade.pyby checkingbank.withdraw(...)return values and refunding on partial failure. - Tightened parsing/validation across build and content tooling (
dungeon.py,schematic.py,mesh_display.py,image_display.py,loot_table.py,tab_list.py). - Improved client audio stream cleanup/failure surfacing in
client_mod.py(ffmpegstdout checks, producer error propagation, guaranteed stop infinally).
Docs, CI, and Packaging Follow-Through
- Reworked docs keying in
docs/build.pyto avoid basename collisions in output names, source maps, and search URLs. - Pinned
.github/workflows/deploy-pages.ymltool dependencies for reproducible docs deployments. - Added missing extension files to
src/main/resources/python/bridge/MANIFEST(loot_table.py,placeholder.py,scheduler.py,schematic.py,state_machine.py,tab_list.py). - Updated stubs to reflect API/type reality in
bridge/__init__.pyiandbridge/extensions/__init__.pyi. - Moved search index and git metadata from page files into seperate files. For faster loads and better SEO.
- Added
--productionflag, which converts all links to absolute links (/PyJavaBridge/world.htmlinstead of/world.html) for better SEO.