Files
core-staff/docs/06_Operations.md
T
2026-05-26 00:59:39 -04:00

4.0 KiB

Operations

Smoke test after deploy

  1. /networkcore status - confirm "Database: ok" and "Network: connected".
  2. Connect a staff alt. Run /lookup <your-main>. You should see your own UUID and online status.
  3. Connect a non-staff alt. Have a staff member run /warn <alt> test. The alt receives a chat message; nothing crashes.
  4. /sc test from staff. Every other online staff member sees it. No non-staff sees it.
  5. Look in MySQL:
    SELECT * FROM staff_punishments ORDER BY issued_at DESC LIMIT 5;
    
    The warn should be the most recent row.

A staff member can't run staff commands

  1. Check what groups Hytale shows for them. There's no direct command for this in Staff; have them run /lookup <theirname> - if it works, they're staff. If it doesn't, the group is wrong.
  2. PermissionsModule.get().getGroupsForUser(uuid) is the source. Confirm the group name they're assigned matches one in permissions.staff_groups in config.json (case-sensitive).
  3. Group changes typically require the player to reconnect.

A ban isn't propagating

  1. On the issuing server: /networkcore servers - is the destination server in the list? If no, the destination isn't actually on the network.
  2. On the issuing server: confirm messagebus_published_total is incrementing in /metrics.
  3. On the destination server: confirm messagebus_received_total is incrementing. If it's rising but messagebus_rejected_total is also rising fast, you have an auth token mismatch.
  4. Confirm the destination server's network.auth_token matches the issuer's. Different tokens cause silent message drops.
  5. As a last resort: the destination server queries MySQL on connect via BanEnforcer. Have the target try to reconnect. If the ban still doesn't apply, the row may not actually be in the DB - check SELECT * FROM staff_punishments WHERE target_uuid = ?.

A muted player can still chat

  1. The mute might have expired. Check expires_at against now.
  2. MuteCache on the chat server might be stale. The cache loads on connect; if the mute was issued while the player was already online, the broadcast path is what populates the cache.
  3. If broadcasts aren't arriving, see the previous section.
  4. As a fallback, kick + rejoin the player. PlayerSeenTracker.onConnect calls loadMuteIntoCache which forces a fresh DB read.

players_seen.online is stuck at 1 after a crash

The plugin runs markServerOffline(serverId) in start(), which sets online=0 for all rows whose last_server_id matches this server. So a normal restart fixes it.

If you see online=1 for a player whose last_server_id belongs to a server that no longer exists (decommissioned, renamed): clear manually with UPDATE staff_players_seen SET online=0 WHERE last_server_id = 'old-server-id'.

Auditing

Recent actions taken by a moderator:

SELECT issued_at, type, target_name, reason
FROM staff_punishments
WHERE issued_by_name = 'StaffName'
ORDER BY issued_at DESC
LIMIT 50;

All actions in the last hour:

SELECT * FROM staff_punishments
WHERE issued_at > (UNIX_TIMESTAMP() * 1000) - 3600000
ORDER BY issued_at DESC;

Players who have been banned but later unbanned:

SELECT target_name, COUNT(*) AS unbanned_bans
FROM staff_punishments
WHERE type IN ('BAN', 'TEMPBAN') AND revoked_at IS NOT NULL
GROUP BY target_uuid, target_name
ORDER BY unbanned_bans DESC;

Things this plugin deliberately doesn't do

  • IP bans. Privacy implications and uncertainty about the Hytale auth model. Use the punishment system on UUIDs.
  • Appeals workflow. Staff just unban. There's no in-game appeal form. Build that externally if you want it.
  • Multiple active bans on the same player. The repository's "active ban" query returns the most recent one. Stacking is unsupported by design - it complicates logic without changing outcomes.
  • Per-world or per-server bans. Punishments are network-wide. If you need per-world, that's a different feature (likely a separate plugin built on top of this).