Repository navigation
Pier 26.40.2
Added
-
A mod that is not a Pier mod can call a Pier mod's services.
pier_bridge_call,
pier_bridge_listandpier_bridge_abiare exported from the host, and
bindings/bridge/pier-bridge.his a header-only client that binds them. Until now the
registry was reachable only with aPierModHandlethe loader issues, and the only
exported symbol pointed the other way, so a permission manager whose value is being the
backend everyone shares was reachable only by mods that had already adopted Pier.The registry is unchanged:
api_service_callalready accepted a null handle and its
self-call check was already conditional on one. What a bridge caller lacks is identity,
which is a real limit and is documented as one -- a provider that grants anything on the
strength of the caller alone must not be reachable this way. Seedocs/guide/bridge.md. -
PlayerEditSignEventandPlayerOperatedItemFrameEventare raised. Both were
declared inALL_SYNTHETICand listed as names, and no hook in the tree produced
either, so a subscription succeeded and never fired. A protection mod gating on them
reported a refusal its own operator could see while the player edited the sign anyway.
Sign editing goes throughSignBlockActor::_playerCanUpdate, which is the engine's own
gate and is asked before the text is taken from the packet; the item-frame right click
goes throughItemFrameBlock::use. Both are inCANCELLABLEnow. -
Every player event with a position carries
block, and every one with a player
carriesitem. Injected by the enricher rather than by each hook, because the events
that need them are LeviLamina's own and have no hook here to extend. A consumer
subdividing a permission by what was touched had nowhere to get the answer: the payload
named the action and never the object.blockis the block at the event's coordinates
anditemis what the player held. Both are absent rather than empty when they cannot
be read, since a name invented here is indistinguishable from a real one and a rule
keyed on it fires on the wrong block. -
PlayerOpenContainerEventcarriescontainerandblock. The payload had only a
numericcontainerType, so a subscriber wanting to tell a chest from a dropper had to
carry its own copy of a network enum.containeris that enum as a word andblockis
the block's type name, which is empty rather than a placeholder when it cannot be read:
an invented name is indistinguishable from a real one, and a rule keyed on it fires on
the wrong block.
Fixed
PlayerRequestItemActionEventis declared observation-only. Nothing raises it and
there is no point at which it can be cancelled;is_cancellableansweredNone, which
a caller reads as "unknown" rather than "no". It now answersSome(false)with where to
block instead, which is what stops a protection mod from treating a subscription to it
as a working gate.
Changed
-
Translations are files again, not a generated C++ table.
packages/pier-support/src/LangShipped.inc,tools/embed-lang.pyand
tools/checks/lang_embedded.pyare gone. The host readsplugins/Pier/lang/<code>.lang
and nothing else is compiled in beyond the built-in English, so a language is a file an
operator drops in and edits rather than a table only a rebuild can change.The packaging half that made the table necessary is handled where it belongs: the
after_buildstep inxmake.luanamesen_US.langandzh_CN.langexplicitly and
fails the build when either is absent, sobin/Pier/lang/carries both and a release
cannot ship half-translated. A glob alone still succeeds on one file, which is the
shape that let the directory go missing before. -
lang/en_US.langis added and carries every key. It is what a translator copies and
what an operator edits;i18n_keys.pynow fails when it is missing a key, when either
shipped file is absent, or when a placeholder count disagrees with the English.
Fixed
-
The lang directory never reached an installed server, so every log was English.
loadLanguagesreadsgetModDir()/lang, modpacker packages the target and
manifest.jsonand nothing else, solang/sat in the repository and shipped in no
archive. Nothing reported it: a missing lang directory is not an error, and the one
line that would have said so only printed when keys loaded.The startup line now prints on every boot rather than only when a file was found, and
reports how many lines the active locale has rather than how many a file contributed.
Suppressing it when there is no file would leave exactly the gap this closed. -
PIER_SRV_PROTOCOL_VERSIONreported 2169 for BDS 1.26.40, which speaks 2168. The
row came from a published metadata table rather than from a server; the banner on a
real 1.26.40.8 readsProtocolVersion 2168. A consumer mapped the 2169 back through
its own table and announced the server as 1.26.45 — a confident wrong answer on a
clean boot, which is the failure the key was rewritten to stop producing. The 1.21.93
row went with it: it was taken from a save file'sNetworkVersiontag, which is the
same class of unchecked evidence. An unlisted version fails the key, and failing is
the correct outcome. 2168 covers 1.26.40 through 1.26.44 and 2169 is 1.26.45, but only
1.26.40 is listed — a range known second-hand is the evidence that produced the wrong
row in the first place. -
tools/checks/i18n_keys.pytruncated any English value containing{},. It cut
the value at the first},, which also matches a placeholder followed by a comma, so
... as id {}, registry id {}was read as having one placeholder. A correct
translation was then reported as having too many. It now collects the C++ string
literals properly.
Added
- Seven more log keys: the per-dimension boot lines an operator reads to answer "did my
world come up the way I wrote it" (dim.height.set,dim.registered,dim.ready,
dim.terrain.layers,dim.terrain.end), and the host's own ready line
(host.ready). The grid clause of the layers line is its own key rather than a
hardcoded tail, because a translation that cannot move that clause has to reorder the
sentence around it.
Added
-
Three events that used to need iListenAttentively are hooked here.
PlayerEditSignEvent,PlayerOperatedItemFrameEventand
PlayerRequestItemActionEventmoved fromALL_FROM_ILAtoALL_SYNTHETIC.Each closes a hole rather than adding a convenience. Placing a sign is a block place
and was covered; editing the text of one already there was neither a place nor an
interact. Taking an item out of a frame was covered byPlayerAttackItemFrameEvent;
rotating it was not. Opening an enchanting table is an interact and was covered;
everything after that arrives on the item-stack request path and was not.Taking them off another mod is deliberate. A protection feature that only works when a
third-party mod happens to be installed is not a protection feature, and the version
matrix was already BDS × LeviLamina without adding a third pin that this repository
cannot fix when it lags a BDS release.PlayerRequestItemActionEventreports only theCraft*action types, as anaction
word (craft/creative/anvil/grindstone/loom) rather than the engine's
enumerator number, which shifts when Mojang inserts a type. Take, place and swap are
not reported: several arrive per click, and a cross-mod dispatch on that path would
cost more than it protects.