summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2026-08-30chore: add diagnostics report field to bug reportSho Sakuma
2026-08-30chore: bump paper/velocitySho Sakuma
2026-08-30docs: Add v1.4.0 docSho Sakuma
2026-08-30refactor(paper): let /lc dump name the folder instead of the fileSho Sakuma
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>
2026-08-30Merge branch 'main' into improve/debug-featureSho Sakuma
2026-08-30feat(velocity): let the proxy be debugged without a config fileSho Sakuma
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>
2026-08-30feat(paper): make the debug switch categorised, live and dumpableSho Sakuma
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>
2026-08-30feat(engine): give both platforms one debug switch to readSho Sakuma
"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>
2026-08-30Merge pull request #295 from m1sk9/fix/nightly-tagsSho Sakuma
fix: mark nightly builds with a `-nightly.<hash>` version and flatten CI artifacts
2026-08-30ci: publish the plugin JARs at the artifact rootSho Sakuma
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>
2026-08-30fix(build): give nightly builds a version of their ownSho Sakuma
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>
2026-08-30Merge pull request #294 from m1sk9/fix/pages-deploy-concurrencySho Sakuma
ci: let a newer Pages deploy supersede a stuck one
2026-08-30ci: let a newer Pages deploy supersede a stuck oneSho Sakuma
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>
2026-08-30Merge pull request #293 from m1sk9/feat/config-reloadSho Sakuma
feat: Add `/lc reload` command
2026-08-30docs(paper): say why the non-YamlException catch has no testSho Sakuma
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>
2026-08-30test(paper): cover the services reading the live message formatsSho Sakuma
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>
2026-08-30docs: add changelogSho Sakuma
2026-08-30chore: update japanese i18n settingsSho Sakuma
2026-08-30chore: fix `ParseOutcome` doc commentSho Sakuma
2026-08-30Merge branch 'main' into feat/config-reloadSho Sakuma
2026-08-29fix(deps): update dependency io.papermc.paper:paper-api to ↵renovate[bot]
v26.2.build.121-stable (#292) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-28fix(deps): update dependency io.papermc.paper:paper-api to ↵renovate[bot]
v26.2.build.120-stable (#291) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-27chore(deps): update dependency @biomejs/biome to v2.5.11 (#290)renovate[bot]
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-26fix(deps): update dependency com.velocitypowered:velocity-api to v4.1.1 (#289)renovate[bot]
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-26chore(deps): update cloudnode-pro/modrinth-publish digest to 203bc72renovate[bot]
2026-08-25fix(deps): update dependency io.papermc.paper:paper-api to ↵renovate[bot]
v26.2.build.119-stable (#287) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-25fix(deps): update dependency com.velocitypowered:velocity-api to v4.1.0 (#288)renovate[bot]
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-23fix(deps): update dependency io.papermc.paper:paper-api to ↵renovate[bot]
v26.2.build.116-stable (#286) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-22fix(deps): update dependency io.papermc.paper:paper-api to ↵renovate[bot]
v26.2.build.115-stable (#285) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-21chore(deps): update dependency @biomejs/biome to v2.5.10 (#284)renovate[bot]
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-20chore(deps): update dependency bun to v1.4.0 (#283)renovate[bot]
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-19chore(deps): update gradle to v9.7.1 (#282)renovate[bot]
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-18chore(deps): update dependency @biomejs/biome to v2.5.9 (#281)renovate[bot]
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-11chore(deps): update dependency @biomejs/biome to v2.5.8 (#279)renovate[bot]
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-11fix(deps): update dependency io.papermc.paper:paper-api to ↵renovate[bot]
v26.2.build.112-stable (#280) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-10refactor(paper): reword the /lc reload messages and mark the untranslated linesSho Sakuma
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.
2026-08-10feat(paper): report /lc reload as a single-line resultSho Sakuma
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.
2026-08-10feat(paper): add /lc reload to apply message formats without a restartSho Sakuma
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>
2026-08-08chore(deps): update plugin xyz.jpenilla.run-paper to v3.1.0 (#278)renovate[bot]
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-07fix(deps): update dependency io.papermc.paper:paper-api to ↵renovate[bot]
v26.2.build.111-stable (#277) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-07fix(deps): update dependency io.papermc.paper:paper-api to ↵renovate[bot]
v26.2.build.107-stable (#275) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-07fix(deps): update junit-framework monorepo to v6.1.3 (#276)renovate[bot]
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-07chore(deps): update gradle to v9.7.0 (#273)renovate[bot]
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-07fix(deps): update dependency io.papermc.paper:paper-api to ↵renovate[bot]
v26.2.build.105-stable (#274) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-07fix(deps): update dependency io.papermc.paper:paper-api to ↵renovate[bot]
v26.2.build.100-stable (#272) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-05fix(deps): update dependency io.papermc.paper:paper-api to ↵renovate[bot]
v26.2.build.98-stable (#271) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-05fix(deps): update dependency io.papermc.paper:paper-api to ↵renovate[bot]
v26.2.build.96-stable (#270) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-05fix(deps): update dependency io.papermc.paper:paper-api to ↵renovate[bot]
v26.2.build.93-stable (#269) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-05Merge pull request #268 from m1sk9/fix/download-and-compatibility-versionsSho Sakuma
fix: Show the actual plugin versions on the download and compatibility pages, and mark feature-short pairs
2026-08-05feat: warn where a pair connects but falls short of a featureSho Sakuma
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>