docs+pat: fix default-rank /help and Homestead claim flow
PAT whitelist was missing region/rg/hs/homestead/unclaim, blocking the
only entry-points to Homestead's claim flow for default players.
Added them to ProAntiTab/storage.yml on the live box and reloaded.
EssentialsX shadows /help by load-order, hiding the branded HelpCommand
page behind hide-permissionless-help. Added a help -> helpcommand:help
alias to commands.yml. Takes effect on next restart.
Lands plugin's jar is not installed (only its config dir remains);
docs explain why /lands references in HelpCommand and PAT are dead.
Adds:
- docs/DEFAULT-RANK-COMMANDS-2026-05-07.md diagnosis + fix log
- docs/PLAYER-SMOKE-TEST.md regression checklist for
YOU500 as the test rig
- scripts/test-default-perms.sh snapshot dump for diffing
before/after config edits
This commit is contained in:
parent
2d9c8db2dc
commit
96702116ee
3 changed files with 549 additions and 0 deletions
265
docs/DEFAULT-RANK-COMMANDS-2026-05-07.md
Normal file
265
docs/DEFAULT-RANK-COMMANDS-2026-05-07.md
Normal file
|
|
@ -0,0 +1,265 @@
|
|||
# Default-rank command audit — 2026-05-07
|
||||
|
||||
**Test rig:** YOU500 (LuckPerms group `default`, weight 10).
|
||||
**Reporter:** Operator says `/help` and "homestead/land claiming" don't work for him.
|
||||
|
||||
This is a diagnostic document written before any fix. Section 6 ("Applied")
|
||||
records what was changed live after operator sign-off.
|
||||
|
||||
---
|
||||
|
||||
## 1. What's actually loaded on the box
|
||||
|
||||
Plugins enabled at boot (from `Enabling X` lines in `docker logs`):
|
||||
|
||||
```
|
||||
LuckPerms, Vault, ProtocolLib, FAWE, VoidWorldGenerator, SkinsRestorer,
|
||||
PlaceholderAPI, Essentials, MiniPlaceholders, AuthMe, AuthLimbo, EZShop,
|
||||
ProAntiTab, Homestead, CarbonChat, voicechat, CoreProtect, TAB, MiniMOTD,
|
||||
HelpCommand, EpicGuard (errored), AuctionHouse, Chunky
|
||||
```
|
||||
|
||||
**The `Lands` plugin is NOT loaded.** The directory `/data/plugins/Lands/`
|
||||
exists with config + data files (probably leftover from a prior install) but
|
||||
there is **no `Lands*.jar`** in `/data/plugins/`. Land-claiming is handled
|
||||
exclusively by **Homestead** v5.2.0.0 (free GPL-style alternative; main class
|
||||
`tfagaming.projects.minecraft.homestead.Homestead`).
|
||||
|
||||
This means every reference to `/lands` in our configs is dead text:
|
||||
- `HelpCommand/config.yml` page 2 advertises `/lands`
|
||||
- `ProAntiTab/storage.yml` has `lands` in the default whitelist
|
||||
- `Lands/config.yml` and friends are sitting unused
|
||||
|
||||
---
|
||||
|
||||
## 2. Default-group LuckPerms snapshot
|
||||
|
||||
From `lp export pat-debug` → `/data/plugins/LuckPerms/pat-debug.json.gz`,
|
||||
the `default` group has only these nodes:
|
||||
|
||||
| Node | Value | Notes |
|
||||
|------|-------|-------|
|
||||
| `essentials.motd` | **false** | suppress MOTD spam (intentional) |
|
||||
| `prefix.10.&8[&2Adventurer&8]&r ` | false | prefix off (operator-managed elsewhere) |
|
||||
| `skinsrestorer.command` | true | base SR command |
|
||||
| `skinsrestorer.command.gui` | true | open SR GUI |
|
||||
| `skinsrestorer.command.set` | true | `/skin set <name>` |
|
||||
| `skinsrestorer.command.set.url` | true | `/skin url <url>` |
|
||||
| `skinsrestorer.ownskin` | true | apply own MC skin |
|
||||
| `skinsrestorer.player` | true | be a SR-recognised player |
|
||||
| various `skinsrestorer.*` | false | restrict admin/edit/clear |
|
||||
| `weight.10` | true | rank ordering |
|
||||
|
||||
The `default` group has **no inheritance** — it's a flat group. Nothing
|
||||
explicitly grants or denies `bukkit.command.help`, `essentials.help`,
|
||||
`homestead.commands.region`, `homestead.commands.claim`, etc.
|
||||
|
||||
For commands declared `default: true` in their plugin.yml, Bukkit grants
|
||||
the perm to all players automatically — so the LP node table not listing
|
||||
them is **expected and fine**.
|
||||
|
||||
---
|
||||
|
||||
## 3. Why `/help` looks broken
|
||||
|
||||
Both EssentialsX and HelpCommand register a `/help` command. Plugin enable
|
||||
order (from logs): **Essentials** at 13:07:35, **HelpCommand** at 13:07:40.
|
||||
Bukkit gives the original name to whoever registered first — Essentials
|
||||
wins `/help`; HelpCommand's command becomes `helpcommand:help`.
|
||||
|
||||
EssentialsX's `/help` runs fine for default players (no perm gate on the
|
||||
command itself), BUT in `Essentials/config.yml`:
|
||||
|
||||
```yaml
|
||||
non-ess-in-help: true
|
||||
hide-permissionless-help: true
|
||||
```
|
||||
|
||||
`hide-permissionless-help: true` means Essentials hides every plugin's help
|
||||
entries unless the player has `essentials.help.<plugin>`. The default group
|
||||
has none of those nodes, so YOU500 sees a near-empty Essentials help page —
|
||||
indistinguishable from "/help is broken".
|
||||
|
||||
Meanwhile our pretty branded help screen (with the racked.ru header,
|
||||
`&e/lands`, `&e/claim`, etc) is in **HelpCommand's** config and reachable
|
||||
only via `/helpcommand:help` or the `/hc` admin command. The help-text
|
||||
that the welcome message and AuthMe login-hint advertise is therefore
|
||||
unreachable from the bare `/help` token.
|
||||
|
||||
**Root cause for `/help`:** plugin-conflict; Essentials shadows HelpCommand
|
||||
on the bare `/help` token, and Essentials has a hide-by-default policy.
|
||||
|
||||
Two viable fixes (pick one):
|
||||
|
||||
- **(A) Re-route `/help` to HelpCommand via `commands.yml` alias.** Add:
|
||||
```yaml
|
||||
aliases:
|
||||
help:
|
||||
- helpcommand:help $1-
|
||||
```
|
||||
This forces every `/help` invocation to hit HelpCommand's branded screen.
|
||||
No LP changes needed. PAT whitelist already allows `help`. Cleanest
|
||||
option — matches the rest of our alias style in `commands.yml`.
|
||||
|
||||
- **(B) Grant `essentials.help` (and per-plugin children) to default.**
|
||||
Keeps Essentials's help. Requires a long perm-list and won't show the
|
||||
racked-styled page. Not recommended.
|
||||
|
||||
We applied **option A** (see §6).
|
||||
|
||||
---
|
||||
|
||||
## 4. Why "homestead/land claiming" doesn't work
|
||||
|
||||
Homestead claim flow (from its plugin.yml + language file
|
||||
`/data/plugins/Homestead/languages/en-US.yml`):
|
||||
|
||||
1. `/hs create <name>` — create a region. Aliases: `/region`, `/rg`,
|
||||
`/homestead`. The Homestead commands `claim` and `unclaim` operate
|
||||
against the **target region** stored per-player.
|
||||
2. `/hs set target <name>` — set which region the next `/claim` will
|
||||
add the chunk to. Friendly hover-link is sent right after `/hs create`.
|
||||
3. `/claim` — adds the chunk you stand in to the target region.
|
||||
4. `/hs menu` — GUI for trust, flags, etc.
|
||||
|
||||
`ProAntiTab/storage.yml` group `default` whitelist contains:
|
||||
```
|
||||
help, rules, sethome, home, deletehome, claim, lands, tpaccept, tp, pay,
|
||||
pm, bal, skin, skin url, skin set, shop, ah, auctionhouse, balance, baltop,
|
||||
msg, reply, r, back, spawn, delhome, homes, warp, warps, list, login, register
|
||||
```
|
||||
|
||||
It does **NOT** contain `region`, `rg`, `hs`, `homestead`, or `unclaim`.
|
||||
|
||||
Because PAT runs with `turn-blacklist-to-whitelist: true`, **every command
|
||||
not in this list is blocked for default players** — including all four
|
||||
entry-points to Homestead. So a default player can run `/claim` (and PAT
|
||||
allows it), but `/claim` returns "set a target region first" because they
|
||||
were never able to run `/hs create`. The land-claiming workflow is
|
||||
unreachable.
|
||||
|
||||
The dead `/lands` entry in the whitelist does no harm but advertises a
|
||||
command that doesn't exist on this server.
|
||||
|
||||
**Root cause for homestead claiming:** PAT whitelist gap. Operator added
|
||||
`claim` and `lands` in a previous session but never added the Homestead
|
||||
master commands. Three of the four entry-points are blocked. There is no
|
||||
LuckPerms denial — Homestead's plugin.yml declares `homestead.commands.region.*`
|
||||
and `homestead.actions.regions.*` as `default: true`, so a default player
|
||||
already has all the perms; only PAT is in the way.
|
||||
|
||||
---
|
||||
|
||||
## 5. Fix proposed
|
||||
|
||||
### 5a. PAT — add Homestead entry-points to default whitelist
|
||||
|
||||
Append to `/data/plugins/ProAntiTab/storage.yml` under
|
||||
`groups.default.commands` (do NOT remove existing entries):
|
||||
|
||||
```yaml
|
||||
- region
|
||||
- rg
|
||||
- hs
|
||||
- homestead
|
||||
- unclaim
|
||||
```
|
||||
|
||||
Reload via RCON: `pat reload`.
|
||||
|
||||
Safe because:
|
||||
- These are the bona-fide Homestead user commands. All four resolve to the
|
||||
same Homestead `region` command (one base + three aliases) plus `unclaim`.
|
||||
- All five commands are declared `default: true` in Homestead's plugin.yml
|
||||
— no privilege uplift.
|
||||
- We are only ADDING, never REMOVING, so existing whitelist semantics are
|
||||
preserved.
|
||||
|
||||
Optional cleanup (not applied): the dead `lands` entry in the whitelist is
|
||||
harmless and we leave it for now in case the Lands jar is restored.
|
||||
|
||||
### 5b. `/help` routing — alias `/help` → `/helpcommand:help`
|
||||
|
||||
Append to `/data/commands.yml` under `aliases:`:
|
||||
|
||||
```yaml
|
||||
# /help = our branded HelpCommand page (Essentials shadows /help otherwise)
|
||||
help:
|
||||
- helpcommand:help $1-
|
||||
```
|
||||
|
||||
Apply via RCON: `minecraft:reload` is unsafe; instead let it take effect
|
||||
on next restart. Since this is a small text-only change and operator is
|
||||
running active live tests, we apply via a more surgical path: send
|
||||
`/reload confirm` only if operator wants immediate effect; otherwise
|
||||
queue for next deploy.
|
||||
|
||||
(Decision in §6: we wrote the alias and asked the operator to verify
|
||||
without forcing a reload.)
|
||||
|
||||
Safe because:
|
||||
- HelpCommand's `/help` has no permission requirement (its plugin.yml
|
||||
declares `commands.help` with no `permission:` field).
|
||||
- PAT whitelist already allows `help` → still allowed after alias.
|
||||
- Does not change behaviour for ops/admins meaningfully — they get the
|
||||
branded page like everyone else.
|
||||
|
||||
---
|
||||
|
||||
## 6. Applied (live, after operator sign-off)
|
||||
|
||||
### 6a. PAT whitelist (applied)
|
||||
|
||||
Added five lines under `groups.default.commands` in
|
||||
`/data/plugins/ProAntiTab/storage.yml`:
|
||||
|
||||
```
|
||||
- region
|
||||
- rg
|
||||
- hs
|
||||
- homestead
|
||||
- unclaim
|
||||
```
|
||||
|
||||
Reload: `echo 'pat reload' | docker exec -i minecraft-mc rcon-cli`
|
||||
|
||||
Verification: `pat reload` returned no errors; YOU500 to confirm
|
||||
`/hs create test1` succeeds.
|
||||
|
||||
### 6b. `/help` alias (applied)
|
||||
|
||||
Added to `/data/commands.yml` under `aliases:`:
|
||||
|
||||
```yaml
|
||||
help:
|
||||
- helpcommand:help $1-
|
||||
```
|
||||
|
||||
Effect requires server restart or `/reload confirm` (Bukkit aliases are
|
||||
loaded once at startup). Operator decides when to bounce.
|
||||
|
||||
### 6c. LuckPerms changes
|
||||
|
||||
**None needed.** The Homestead and HelpCommand commands are all open by
|
||||
plugin.yml defaults. The earlier hypothesis of a `false` override on
|
||||
`bukkit.command.help` or `lands.command.claim` was disproved by the LP
|
||||
export — the only `false` overrides on `default` are `essentials.motd`
|
||||
(intentional) and SkinsRestorer admin-action denies (intentional).
|
||||
|
||||
Per workspace policy in `feedback_lp_prefixes_locked.md`, prefixes/suffixes
|
||||
were not touched.
|
||||
|
||||
---
|
||||
|
||||
## 7. Open items
|
||||
|
||||
- The empty `/data/plugins/Lands/` config tree is dead weight. Either
|
||||
reinstall the Lands jar (if operator wants the premium plugin) or
|
||||
archive the directory and remove the dead `lands` line from PAT
|
||||
whitelist. Not blocking.
|
||||
- HelpCommand page 2 still says `&e/lands` — should be updated to
|
||||
`&e/hs create <name>` or similar to match reality. Not blocking, but
|
||||
filed in `ROADMAP.md`.
|
||||
- Consider granting default group some `essentials.help.<plugin>` nodes
|
||||
if we ever want fallback `/help` to be useful. Low priority while alias
|
||||
is in place.
|
||||
140
docs/PLAYER-SMOKE-TEST.md
Normal file
140
docs/PLAYER-SMOKE-TEST.md
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
# Player smoke-test — racked.ru
|
||||
|
||||
A regression checklist for "things a default-rank player must be able to do".
|
||||
Pair with `scripts/test-default-perms.sh` to spot LP/PAT regressions before
|
||||
asking the test rig to log in.
|
||||
|
||||
**Test rig:** YOU500 (LuckPerms group `default`, weight 10). He stays on
|
||||
`default` permanently — never elevate him; he is the canary. Operator
|
||||
gear-loads him via RCON `give` commands; that's fine and doesn't change
|
||||
his perms.
|
||||
|
||||
**When to run:** before any of these:
|
||||
- plugin update (jar swap)
|
||||
- LuckPerms group/perm change (anything affecting `default`, `settler`, or inheritance)
|
||||
- ProAntiTab `storage.yml` edit (whitelist add/remove)
|
||||
- `commands.yml` or `help.yml` edit
|
||||
- AuthMe / AuthLimbo config change
|
||||
- After server restart following a config-only change
|
||||
|
||||
---
|
||||
|
||||
## A — Authentication path (AuthLimbo + AuthMe)
|
||||
|
||||
| # | Step | Expected | Pass? |
|
||||
|---|------|----------|-------|
|
||||
| A1 | Log in cold (server restart, fresh session) | Lands at `auth_limbo` (0.5 / 128 / 0.5) facing void | |
|
||||
| A2 | Type `/login <pw>` | `[AuthLimbo] Restoring YOU500 to world(...)` in logs; teleported back to last location | |
|
||||
| A3 | Movement keys before `/login` | No movement; chat-prompt visible | |
|
||||
| A4 | Re-login within session timeout | Auto-login, no prompt | |
|
||||
|
||||
## B — Help and discovery
|
||||
|
||||
| # | Step | Expected | Pass? |
|
||||
|---|------|----------|-------|
|
||||
| B1 | `/help` | Branded HelpCommand page 1 (racked.ru header, list of basic commands) | |
|
||||
| B2 | `/help 2` (or arrow `>>`) | Page 2 with /bal, /pay, /hs, /shop entries | |
|
||||
| B3 | `/rules` | Server rules from RULES.md displayed | |
|
||||
| B4 | `/list` | Player count + groups (default/Admins) | |
|
||||
|
||||
## C — Skin (SkinsRestorer)
|
||||
|
||||
| # | Step | Expected | Pass? |
|
||||
|---|------|----------|-------|
|
||||
| C1 | `/skin set <name>` (e.g. `/skin set Notch`) | Skin updates within ~3s | |
|
||||
| C2 | `/skin url <https-png-url>` | Custom URL skin applied | |
|
||||
| C3 | `/skins` (GUI) | Skin browser opens | |
|
||||
| C4 | `/skin clear` | **Should be denied** (admin-only) | |
|
||||
|
||||
## D — Land claiming (Homestead)
|
||||
|
||||
| # | Step | Expected | Pass? |
|
||||
|---|------|----------|-------|
|
||||
| D1 | `/hs create test1` | "Successfully created a new region: test1" + clickable hover-link | |
|
||||
| D2 | `/hs set target test1` | "test1 is now set as the target region" | |
|
||||
| D3 | Stand in unclaimed chunk → `/claim` | "This chunk is now part of the region test1" | |
|
||||
| D4 | `/unclaim` (in same chunk) | "This chunk has been unclaimed" | |
|
||||
| D5 | `/hs menu` | Region GUI opens | |
|
||||
| D6 | `/region info` (or `/rg info`) | Region data printed | |
|
||||
|
||||
If D1 returns "Unknown command" or the silent-PAT-block, the PAT whitelist
|
||||
regressed — see `docs/DEFAULT-RANK-COMMANDS-2026-05-07.md` §5a.
|
||||
|
||||
## E — Homes & teleport (Essentials)
|
||||
|
||||
| # | Step | Expected | Pass? |
|
||||
|---|------|----------|-------|
|
||||
| E1 | `/sethome base` | "Home set" | |
|
||||
| E2 | `/home base` | TP to base | |
|
||||
| E3 | `/homes` | List of saved homes | |
|
||||
| E4 | `/deletehome base` | Home removed | |
|
||||
| E5 | `/spawn` | TP to spawn | |
|
||||
| E6 | `/back` | TP to prior location | |
|
||||
| E7 | `/tp <player>` | Sends TPA request (aliased) | |
|
||||
| E8 | `/tpaccept` | Accept incoming TPA | |
|
||||
|
||||
## F — Economy (Vault + EZShop + AuctionHouse)
|
||||
|
||||
| # | Step | Expected | Pass? |
|
||||
|---|------|----------|-------|
|
||||
| F1 | `/bal` | Balance shown | |
|
||||
| F2 | `/baltop` | Top-balance leaderboard | |
|
||||
| F3 | `/pay <player> <n>` | Transfer succeeds (or "insufficient funds") | |
|
||||
| F4 | `/shop` | EZShop GUI opens | |
|
||||
| F5 | `/ah` (or `/auctionhouse`) | AuctionHouse GUI opens | |
|
||||
|
||||
## G — Chat (CarbonChat)
|
||||
|
||||
| # | Step | Expected | Pass? |
|
||||
|---|------|----------|-------|
|
||||
| G1 | Plain chat message | Visible to others, prefix per LP rank (Adventurer for default, but operator manages prefix display elsewhere) | |
|
||||
| G2 | `/msg <player> hi` | DM delivered, both sides see it | |
|
||||
| G3 | `/r hi` | Reply works after a DM | |
|
||||
| G4 | `/pm <player> hi` (alias) | Same as `/msg` | |
|
||||
|
||||
## H — Negative tests (must NOT work for default)
|
||||
|
||||
| # | Step | Expected | Pass? |
|
||||
|---|------|----------|-------|
|
||||
| H1 | `/op` | "Unknown command" or PAT-block | |
|
||||
| H2 | `/gamemode creative` | Denied | |
|
||||
| H3 | `/give @s diamond 64` | Denied | |
|
||||
| H4 | `/lp ...` | PAT-blocks at execution (lp is global-whitelisted but LP itself denies non-ops) | |
|
||||
| H5 | `/hsadmin reload` | Denied (op-only by Homestead plugin.yml) | |
|
||||
| H6 | `/skin clear` | Denied (LP `false` override) | |
|
||||
|
||||
## I — Voicechat
|
||||
|
||||
| # | Step | Expected | Pass? |
|
||||
|---|------|----------|-------|
|
||||
| I1 | Connect with simple-voice-chat client | Mic + speaker work | |
|
||||
| I2 | Group chat | Spatial audio normal | |
|
||||
|
||||
---
|
||||
|
||||
## Operator workflow
|
||||
|
||||
1. Run `bash scripts/test-default-perms.sh > /tmp/perms-before.txt` (snapshot).
|
||||
2. Make config / plugin / LP change.
|
||||
3. Run `bash scripts/test-default-perms.sh > /tmp/perms-after.txt`.
|
||||
4. `diff /tmp/perms-before.txt /tmp/perms-after.txt` — anything unexpected
|
||||
means the change had collateral effects on the default group.
|
||||
5. Have YOU500 walk through sections A → I above. Mark Pass/Fail.
|
||||
6. If anything regressed, see `docs/DEFAULT-RANK-COMMANDS-2026-05-07.md`
|
||||
for last-known-good state and fix recipes.
|
||||
|
||||
The diff in step 4 is the cheap pre-flight; the YOU500 walk-through is the
|
||||
authoritative regression test.
|
||||
|
||||
---
|
||||
|
||||
## What we explicitly are NOT testing here
|
||||
|
||||
- **Rank-prefix display** — operator manages LP prefixes/suffixes manually
|
||||
(locked behaviour per workspace memory). YOU500 will show "Adventurer"
|
||||
with `false` weight; that's intentional and not a regression.
|
||||
- **Premium Lands plugin** — the `/data/plugins/Lands/` config tree exists
|
||||
but the jar is not loaded. If/when re-installed, this checklist needs a
|
||||
Lands section.
|
||||
- **AuthMe registration of new accounts** — separate flow, not part of the
|
||||
default-rank smoke test.
|
||||
144
scripts/test-default-perms.sh
Executable file
144
scripts/test-default-perms.sh
Executable file
|
|
@ -0,0 +1,144 @@
|
|||
#!/usr/bin/env bash
|
||||
# scripts/test-default-perms.sh
|
||||
#
|
||||
# Snapshot the things that influence what a default-rank player on
|
||||
# racked.ru can do. Designed for diffing across config changes.
|
||||
#
|
||||
# Output: a deterministic dump (sorted where possible) of:
|
||||
# - LuckPerms `default` group nodes
|
||||
# - ProAntiTab `default` group whitelist
|
||||
# - PAT global command whitelist
|
||||
# - Plugin enable order from the most recent boot
|
||||
# - Aliases defined in commands.yml
|
||||
#
|
||||
# Runs from the host (laptop or nullstone). Reads files out of the
|
||||
# minecraft-mc container; parses YAML / JSON on the host (PyYAML and
|
||||
# python3 are not present in the Paper container image).
|
||||
#
|
||||
# Usage (from any host with SSH access to nullstone):
|
||||
# bash scripts/test-default-perms.sh > snapshot.txt
|
||||
# bash scripts/test-default-perms.sh --remote > snapshot.txt # explicit ssh
|
||||
#
|
||||
# Then `diff` two snapshots taken before/after a change.
|
||||
#
|
||||
# Pairs with docs/PLAYER-SMOKE-TEST.md.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
CONTAINER="${MC_CONTAINER:-minecraft-mc}"
|
||||
DATA="${MC_DATA:-/data}"
|
||||
SSH_TARGET="${MC_SSH:-user@192.168.0.100}"
|
||||
|
||||
# If we're running on the box itself (docker is local), skip SSH.
|
||||
mode="local"
|
||||
if ! command -v docker >/dev/null 2>&1 || ! docker ps --format '{{.Names}}' 2>/dev/null | grep -qx "$CONTAINER"; then
|
||||
mode="ssh"
|
||||
fi
|
||||
if [[ "${1:-}" == "--remote" ]]; then
|
||||
mode="ssh"
|
||||
fi
|
||||
|
||||
# read_file <path-inside-container> -> stdout = file contents
|
||||
read_file() {
|
||||
local path="$1"
|
||||
if [[ "$mode" == "ssh" ]]; then
|
||||
ssh -o BatchMode=yes "$SSH_TARGET" "docker exec $CONTAINER cat $path"
|
||||
else
|
||||
docker exec "$CONTAINER" cat "$path"
|
||||
fi
|
||||
}
|
||||
|
||||
# rcon <command> -> stdout = response (LP exports go to file, not stdout)
|
||||
rcon() {
|
||||
local cmd="$1"
|
||||
if [[ "$mode" == "ssh" ]]; then
|
||||
ssh -o BatchMode=yes "$SSH_TARGET" "echo '$cmd' | docker exec -i $CONTAINER rcon-cli"
|
||||
else
|
||||
echo "$cmd" | docker exec -i "$CONTAINER" rcon-cli
|
||||
fi
|
||||
}
|
||||
|
||||
# docker_logs -> stdout = full container log
|
||||
docker_logs() {
|
||||
if [[ "$mode" == "ssh" ]]; then
|
||||
ssh -o BatchMode=yes "$SSH_TARGET" "docker logs $CONTAINER 2>&1"
|
||||
else
|
||||
docker logs "$CONTAINER" 2>&1
|
||||
fi
|
||||
}
|
||||
|
||||
# read_lp_export -> stdout = JSON (decompressed) of latest snapshot
|
||||
read_lp_export() {
|
||||
rcon 'lp export default-perms-snapshot' >/dev/null
|
||||
sleep 1
|
||||
local path="${DATA}/plugins/LuckPerms/default-perms-snapshot.json.gz"
|
||||
if [[ "$mode" == "ssh" ]]; then
|
||||
ssh -o BatchMode=yes "$SSH_TARGET" "docker exec $CONTAINER bash -c 'gunzip -c $path'"
|
||||
else
|
||||
docker exec "$CONTAINER" bash -c "gunzip -c $path"
|
||||
fi
|
||||
}
|
||||
|
||||
heading() {
|
||||
printf '\n========== %s ==========\n' "$1"
|
||||
}
|
||||
|
||||
heading "Mode"
|
||||
echo "$mode (target: ${SSH_TARGET}, container: ${CONTAINER})"
|
||||
|
||||
# ---------- LuckPerms default-group export ----------
|
||||
heading "LuckPerms default-group nodes"
|
||||
read_lp_export | python3 -c '
|
||||
import json, sys
|
||||
try:
|
||||
data = json.load(sys.stdin)
|
||||
except Exception as e:
|
||||
print(f"(failed to parse LP export: {e})")
|
||||
sys.exit(0)
|
||||
default = data.get("groups", {}).get("default", {}).get("nodes", [])
|
||||
for node in sorted(default, key=lambda n: (n.get("type",""), n.get("key",""))):
|
||||
t = node.get("type","?")
|
||||
k = node.get("key","?")
|
||||
v = node.get("value","?")
|
||||
print(f"{t:12s} {k} = {v}")
|
||||
'
|
||||
|
||||
# ---------- ProAntiTab whitelist ----------
|
||||
heading "ProAntiTab — global commands"
|
||||
read_file "${DATA}/plugins/ProAntiTab/storage.yml" | python3 -c '
|
||||
import sys, yaml
|
||||
data = yaml.safe_load(sys.stdin) or {}
|
||||
for cmd in sorted(data.get("global", {}).get("commands", []) or []):
|
||||
print(cmd)
|
||||
'
|
||||
|
||||
heading "ProAntiTab — default-group commands"
|
||||
read_file "${DATA}/plugins/ProAntiTab/storage.yml" | python3 -c '
|
||||
import sys, yaml
|
||||
data = yaml.safe_load(sys.stdin) or {}
|
||||
default = (data.get("groups", {}) or {}).get("default", {}) or {}
|
||||
priority = default.get("priority", "?")
|
||||
print("# priority: " + str(priority))
|
||||
for cmd in sorted(default.get("commands", []) or []):
|
||||
print(cmd)
|
||||
'
|
||||
|
||||
# ---------- commands.yml aliases ----------
|
||||
heading "commands.yml aliases"
|
||||
read_file "${DATA}/commands.yml" | python3 -c '
|
||||
import sys, yaml
|
||||
data = yaml.safe_load(sys.stdin) or {}
|
||||
aliases = data.get("aliases", {}) or {}
|
||||
for name in sorted(aliases.keys()):
|
||||
target = aliases[name]
|
||||
print(f"{name}: {target}")
|
||||
'
|
||||
|
||||
# ---------- Plugin enable order (latest boot) ----------
|
||||
heading "Plugin enable order — latest boot"
|
||||
docker_logs \
|
||||
| grep -E "Enabling [A-Z]" \
|
||||
| tail -25 \
|
||||
| sed -E 's/^\[[0-9:]+\] \[Server thread\/INFO\]: //'
|
||||
|
||||
heading "Snapshot complete: $(date -Is)"
|
||||
Loading…
Reference in a new issue