| Age | Commit message (Collapse) | Author |
|
|
|
|
|
|
|
The reply carried the report's path so the operator could find the file. But
`lunaticchat.command.lc.dump` can be granted to someone with no filesystem access
at all, and to them a path is not something they can act on - it only says how
the server is laid out. Relativising it against the server directory narrowed
that without removing it.
Naming the folder in the message says everything a reader can use, and leaves the
exact path to the server log, which only someone with that access can read
anyway. That also makes the reply a single message rather than a message plus a
component the language files could not translate.
Co-Authored-By: Claude <noreply@anthropic.com>
|
|
|
|
The proxy had three slf4j debug calls and no way to turn them on, so the
handshake internals were either missing or mixed into INFO for every backend.
The switch is read from the `lunaticchat.debug` system property, falling back to
the `LUNATICCHAT_DEBUG` environment variable, rather than from a new config file:
a file means a parser and a parser means a dependency, and platform-velocity
deliberately ships without so much as Ktor. The property wins so a proxy started
from a compose file can still be overridden for one run without editing it.
Paper's `debug` is deliberately not carried over the handshake. The proxy is
shared by every backend, so one Paper server's setting must not decide how much
the proxy logs for everyone else.
The compatibility check now reports both halves of the rule with their measured
values. "Protocol version incompatible" left the operator comparing two version
strings against a rule they could not see, and which half failed is the whole
answer when a rolling upgrade stops relaying. For the same reason the relay names
the servers it skipped and why: from the receiving server's log, "the message
never arrived" and "the message was never sent" look identical.
The lines that were unconditionally at INFO drop to their category, leaving only
the failure an operator has to act on.
Refs #228
Co-Authored-By: Claude <noreply@anthropic.com>
|
|
config.yml now accepts `debug: velocity,protocol` and a block with `enabled` and
`categories` beside the boolean it always took. Categories exist so that
instrumenting the chat path does not bury the handshake an operator is chasing
under one line per message.
The setting is read by inspecting the YAML node by hand rather than through a
data class, because one key has to accept both a scalar and a map and kaml picks
the input to build from the descriptor kind alone - a class descriptor rejects
`debug: true` before the serializer is ever called. An unknown category name is
collected rather than thrown: throwing would make ConfigManager prune the whole
`debug` key and switch off the categories the operator did spell correctly.
`debug` moves from RESTART_REQUIRED to applied, since a reload only has to
replace a DebugState. `/lc debug` switches a category for the running server and
deliberately does not write config.yml back - re-emitting a commented YAML
document from a parsed tree loses every comment and every bit of formatting the
operator put there, and a restart or `/lc reload` putting the file back in charge
is the safer default anyway.
`/lc dump` writes the report a bug report needs: versions, enabled features,
connection state and how full each store is. It carries no message text, player
name or UUID, because it exists to be pasted into a public issue by someone who
is not reading it first. Its reply names the file relative to the server
directory - the command can be granted to someone with no filesystem access, to
whom an absolute path discloses where the server is installed and nothing they
can act on.
The KtorSimpleLogger calls in ChannelMessageHandler and ChannelMessageLogger are
folded into the same logger, so there is one place that decides whether a
diagnostic line is printed.
Refs #228
Co-Authored-By: Claude <noreply@anthropic.com>
|
|
"Debug" had grown into three unconnected mechanisms: a boolean injected into
RomanjiConverter, a one-off configuration dump at startup, and KtorSimpleLogger
calls that Paper's stock log4j configuration never printed. Turning `debug: true`
on told an operator nothing about the Velocity handshake, which is what #228 is
actually about.
The vocabulary goes in engine because it is a contract before it is an
implementation: config.yml and the proxy's system property have to agree on what
`velocity,protocol` means, and a category added on one side must exist on the
other. Only the writing is left to the platforms.
The message is a lambda so that the chat path - instrumented once per message -
costs nothing while debugging is off. The `if (debugMode) logger.info("... $word")`
guards this replaces built their strings either way.
Both platform loggers write at INFO rather than at the level the content
deserves, because neither Paper's nor Velocity's stock logging configuration
prints anything below it, and asking operators to edit log4j before they can
answer a bug report is the friction this exists to remove.
Refs #228
Co-Authored-By: Claude <noreply@anthropic.com>
|
|
fix: mark nightly builds with a `-nightly.<hash>` version and flatten CI artifacts
|
|
Listing both platforms under one artifact made upload-artifact root the
archive at the workspace, so downloading it yielded nested
platform-*/build/libs directories instead of the JARs themselves.
Co-Authored-By: Claude <noreply@anthropic.com>
|
|
A nightly JAR was named after the bare release version, so a build from
main and the release of the same base version were indistinguishable in
the JAR file name, /plugins and bug reports; only build-info.properties
knew the difference, and Velocity does not even ship that file.
The x script tried to express this with -Pversion, but each module
assigns its own version from paperVersion/velocityVersion, so the
override never took effect.
Co-Authored-By: Claude <noreply@anthropic.com>
|
|
ci: let a newer Pages deploy supersede a stuck one
|
|
A deploy_dokka job queued on 2026-08-07 never progressed and, because the
"pages" concurrency group refused to cancel in-progress deployments, it held
the group for 23 days. Every later main-branch run piled up behind it and was
cancelled after 14-52h, so main CI never reported. Discarding a superseded
docs deploy costs nothing -- the newer run publishes newer docs anyway -- and
the job timeout keeps a hung deploy from repeating the stall.
Co-Authored-By: Claude <noreply@anthropic.com>
|
|
feat: Add `/lc reload` command
|
|
It shows up as an uncovered line on every patch that touches parse(),
and the next reader would otherwise have to rediscover that no config.yml
can reach it.
Co-Authored-By: Claude <noreply@anthropic.com>
|
|
Swapping LunaticChatConfiguration for MessageFormatHolder pulled
ChannelMessageHandler and CrossServerChatManager into the patch as
uncovered, because neither class had ever had a unit test: nothing
guarded the claim that /lc reload reaches channel chat and cross-server
chat without a restart.
Both now assert that a format replaced at runtime applies to the next
message, alongside the delivery rules they already relied on. The
reloader gains the read failure that carries no message, so the reason
it reports is known not to come out empty.
Co-Authored-By: Claude <noreply@anthropic.com>
|
|
|
|
|
|
|
|
|
|
v26.2.build.121-stable (#292)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
|
|
v26.2.build.120-stable (#291)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
|
|
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
|
|
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
|
|
|
|
v26.2.build.119-stable (#287)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
|
|
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
|
|
v26.2.build.116-stable (#286)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
|
|
v26.2.build.115-stable (#285)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
|
|
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
|
|
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
|
|
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
|
|
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
|
|
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
|
|
v26.2.build.112-stable (#280)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
|
|
The Japanese wording was revised in place: the messages now say "the
configuration file" rather than naming config.yml at the operator, and they
follow the punctuation this file already used for in-game text. English is
brought in line with that wording, keeping its own trailing periods, which
the rest of en.yml uses on every full sentence.
The three failure headings now carry a comment saying what is printed
beneath them and why those lines are never translated. A translator has no
way to see that from the file alone, and the two reasons it cannot change
are both easy to undo by accident: the text comes from the YAML parser, so a
parser update would silently age any translation kept here, and it cannot be
passed as a placeholder because a reason holding braces of its own is broken
by the next substitution and then coloured as if the braces were ours.
|
|
The reply listed every setting that had moved and every setting that still
needed a restart, as dotted keys. That buried the one bit that changes what
the operator does next - whether they have to restart - under names they had
just typed themselves and did not need read back to them.
The detail is not lost: which settings moved was already written to the
server log on every reload, which is the better home for it anyway, since a
format change can be dated there long after the chat line has scrolled away.
A pending restart now outranks "nothing changed" even when nothing could be
applied. Reporting no change to someone who did edit the file would send
them hunting for a typo they had not made.
The failure path still names each unreadable setting and the reason it was
rejected, because that is a list the operator cannot reconstruct and needs
in order to fix the file.
|
|
Changing a message format meant taking the server down, because config.yml
was read once in onEnable and every consumer held the value it was built
with. Operators tune these formats far more often than anything else in the
file, and a restart is a disproportionate price for a colour code.
Only messageFormat is applied. The rest of config.yml settles things once,
at startup - which services exist, which commands and listeners are
registered, which files are opened - and none of that can be redone while
the server runs: Paper registers commands only through its COMMANDS
lifecycle event, Bukkit cannot unregister a listener, and the conversion
cache saver keeps no task handle to cancel. Rebuilding the services would
leave the old ones still wired up, so a changed setting the server cannot
pick up is reported back as needing a restart rather than silently ignored.
MessageFormatHolder is deliberately narrower than LunaticChatConfiguration:
taking it says the value is live, taking the configuration says it was
frozen at startup. A holder over the whole tree would hold a configuration
matching no version of the file, since only messageFormat is ever swapped.
Reload reads config.yml more strictly than startup does, because it has an
option startup does not - leaving the running configuration alone. Startup
falls a single unreadable setting back to its default so the server can come
up; reload refuses the file, names every unreadable setting at once, and
keeps what the server already had. A document holding no settings is refused
for the same reason: it cannot be told apart from a config.yml caught
halfway through being written, and resetting every format over that is worse
than doing nothing.
Closes #266
Co-Authored-By: Claude <noreply@anthropic.com>
|
|
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
|
|
v26.2.build.111-stable (#277)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
|
|
v26.2.build.107-stable (#275)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
|
|
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
|
|
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
|
|
v26.2.build.105-stable (#274)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
|
|
v26.2.build.100-stable (#272)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
|
|
v26.2.build.98-stable (#271)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
|
|
v26.2.build.96-stable (#270)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
|
|
v26.2.build.93-stable (#269)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
|
|
fix: Show the actual plugin versions on the download and compatibility pages, and mark feature-short pairs
|
|
The matrix marked every accepted pair with a plain tick, which reads as
"everything works". It does not. ProtocolVersion bumps PATCH for sub-channels a
peer can safely ignore, so Paper 1.3.0 (protocol 1.0.1) against Velocity 1.1.0
(1.0.0) completes the handshake and then silently drops cross-server direct
messages — the very feature that PATCH was bumped for. An operator reading the
tick had no way to learn that, and the pages around it repeated the claim.
The handshake is settled by MAJOR and MINOR alone, so any difference left once a
pair is accepted is a feature the newer end offers and the older will never
answer. Those pairs now carry a warning that says which end lags. Naming the
feature would take a protocol-version-to-feature table on the website, which
would drift from the protocol it describes, so the warning stays general and
leaves the reader one hop from the compatibility page.
The handshake verdict keeps the three checks that mirror Velocity's gate, with
the new one layered after them, so the mirror stays honest. isCompatible now
holds for a degraded pair, which does connect.
Cells are built once per pair in a computed instead of recomputing on each of the
template's reads, which a third state would otherwise have multiplied.
Co-Authored-By: Claude <noreply@anthropic.com>
|