Add weekly rankings, spontaneous AI lines and BlueMap note markers
Weekly rankings (/ranking semanal [metrica]). On a server with three regulars an all-time board is decided by whoever started first and then stops being a contest. Subtracting a baseline taken at the start of the week makes it one again. Rotation is time-based and idempotent — the snapshot carries the timestamp it was taken at and is replaced only once a week has actually elapsed, so a server that restarts nightly does not reset the week every day. There is a test for exactly that. Players who did not move are dropped, since the point is who is playing this week; a player missing from the baseline counts their whole value, having joined during the week; a negative difference is dropped rather than shown, because statistics only go up and a negative means a stale baseline, not a result worth printing. Spontaneous AI lines (ia.comentar-eventos, ia.saudacao — both off by default). The persona comments on a run of deaths, and greets players as they join using their own numbers. Both are opt-in: a chatty AI nobody asked for is the fastest way to make players hate the feature. Budget is what makes this tolerable rather than obnoxious, and it is the piece worth reading. A player question is self-limiting — someone chose to spend it. A line the AI decides to make on its own is not, and it costs money every time, so three limits all have to pass: a gap between any two lines, a daily cap of its own separate from the /ia cap, and a per-subject cooldown so one unlucky player is not narrated all evening. allows() does not spend, so a caller that decides not to fire (nobody online, the model returned nothing) has burned nothing; saySomething spends up front rather than on success, because two events in the same tick would otherwise both pass allows() and fire together — the exact double-message the gap exists to prevent. The subject map drops expired entries on each spend, or a long-lived server would leak one entry per player who ever triggered a line. A death streak now decays: three deaths across an evening is not a streak, three in ten minutes is. Spontaneous lines are silent on failure — nobody asked for it, so nobody should see it fail. The five-minute sweep no longer hides behind the marcos toggle. It was a milestones-only task, so turning off marcos also silenced achievements and froze the weekly board; each of the three now checks its own module inside the body. BlueMap markers (notas.no-mapa, default on). Public notes already carry a world and coordinates and the server already runs BlueMap, so this joins the two. BlueMapBridge is the only class that touches BlueMap's API and every entry point catches NoClassDefFoundError as well as Exception — the failure mode of a missing optional dependency is a linkage error, not an exception — so a server without BlueMap logs one fine-level line and carries on. The dependency is 'provided' because BlueMap ships those classes itself; a second copy inside our jar would shadow them and break the real plugin, and preflight now fails if the scope is ever dropped. Markers are rebuilt rather than incrementally patched: BlueMap discards everything when it unloads and expects addons to re-create markers on its enable callback, and a full rebuild of a tiny list cannot drift out of sync the way a missed delete would. Notes are matched to the map that renders their world, or a Nether note would be drawn at the same numeric coordinates in the overworld, pointing at nothing. Note text is player-written and lands in a web page, so it is HTML-escaped — ampersand first, or the other replacements would be double-escaped. Private notes are never drawn, at any setting. 295 tests, up from 263. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016pEyCmrAYHBFgpYjwFxKxh
This commit is contained in:
+11
-4
@@ -47,13 +47,12 @@ else
|
||||
else
|
||||
bad "plugin.yml MISSING from jar — the plugin would not load at all"
|
||||
fi
|
||||
# Every command the code registers must exist in plugin.yml, or register()
|
||||
# logs a warning and the command silently does nothing in game.
|
||||
# Kept in step with Canalhandia.onEnable's register() list. A command that is
|
||||
# registered in code but absent here logs a warning at boot and then silently
|
||||
# does nothing in game, which is a hard failure to diagnose from inside.
|
||||
CMDS="canalhandia curiosidade adivinha enquete ranking reagir reacoes \
|
||||
palpite votar legal wow top f ia iap errado nota save"
|
||||
palpite votar legal wow top f ia iap errado nota save \
|
||||
recado recados mortes conquistas"
|
||||
missing=""
|
||||
for cmd in $CMDS; do
|
||||
unzip -p "$JAR" plugin.yml 2>/dev/null | grep -qE "^ ${cmd}:" || missing="$missing $cmd"
|
||||
@@ -65,13 +64,21 @@ else
|
||||
fi
|
||||
# Permissions the new features gate on. An undeclared Bukkit permission falls
|
||||
# back to op-only, which would silently stop normal players writing notes.
|
||||
for perm in canalhandia.nota canalhandia.nota.publica; do
|
||||
for perm in canalhandia.nota canalhandia.nota.publica canalhandia.recado; do
|
||||
if unzip -p "$JAR" plugin.yml 2>/dev/null | grep -q " ${perm}:"; then
|
||||
pass "permission ${perm} declared"
|
||||
else
|
||||
bad "permission ${perm} MISSING — would default to op-only"
|
||||
fi
|
||||
done
|
||||
# BlueMap's API is compile-only (provided scope): BlueMap ships those classes
|
||||
# itself, and a second copy inside this jar would shadow them and break the
|
||||
# real plugin. This check is the guard against someone dropping the scope.
|
||||
if unzip -l "$JAR" 2>/dev/null | grep -q "bluecolored"; then
|
||||
bad "BlueMap classes are BUNDLED in the jar — the dependency must stay 'provided'"
|
||||
else
|
||||
pass "BlueMap API not bundled (provided scope intact)"
|
||||
fi
|
||||
# config.yml ships defaults; a jar without it means saveDefaultConfig() writes
|
||||
# nothing and every setting silently falls back to the hardcoded default.
|
||||
if unzip -p "$JAR" config.yml >/dev/null 2>&1; then
|
||||
|
||||
Reference in New Issue
Block a user