Skip to content

Team chat commands (!shop, !small, !large, !pos) + join/leave/AFK alerts#123

Open
Rathio12 wants to merge 7 commits into
Pronwan:betafrom
Rathio12:feature/team-chat-commands
Open

Team chat commands (!shop, !small, !large, !pos) + join/leave/AFK alerts#123
Rathio12 wants to merge 7 commits into
Pronwan:betafrom
Rathio12:feature/team-chat-commands

Conversation

@Rathio12

@Rathio12 Rathio12 commented Jun 14, 2026

Copy link
Copy Markdown

Summary

Adds team-chat commands, richer presence announcements, automatic Deep Sea tracking, persistent event logs, and a set of anti-spam / reliability fixes. Everything is built to be API-friendly — throttled sends, single/limited replies, no extra polling beyond a gentle background Deep Sea check. See CHANGELOG.md for the full breakdown. Rebased/merged on the current beta tip (includes the teammate-map-markers feature).

New chat commands

  • !shop <item> — searches the map's cached vending machines (no extra polling) and replies with the top 3 matches as separate, spaced messages, each grid: item → cost (stock). In-stock first, then cheapest; (+N more) overflow. Junk barter trades (priced in another item) are filtered out when real Scrap prices exist.
  • !small / !large — individual Small/Large Oil Rig crate timers (refactored !oilrig into a shared helper).
  • !pos <name> — a teammate's current grid (exact-then-partial match).
  • !afk — who's AFK and for how long (respects name abbreviation + 128-char limit).

Presence announcements (gated by the existing "Chat Announce" toggle)

  • Joined / left, with smart handling of your own team switches (you join someone → announce only you; people join your team → announce each; you leave / team dissolves → suppressed).
  • AFK ("X is now AFK for more than 5m") and back from AFK ("X came back from AFK, was AFK for 12m") — announced for any member, including yourself.
  • Came online appends offline duration; died appends how long they were alive (e.g. ":skull: X is dead @ G12, was alive for 1h 25m"). Alive/offline clocks survive going offline↔online and are tracked regardless of the announce toggle.
  • Multiple announcements are spaced ~2.5s apart.

Deep Sea

  • Auto-detected in the background (60s poll on connect) — no need to enable the Shops layer. Skips when full shop polling is active and backs off under API pressure; also keeps the shop cache fresh so !shop works without the layer.
  • Direction reported reliably as West (always spawns off the west edge; precise direction isn't readable from the API) and shown in the alert: "Deep Sea event is up (West)".

Persistent event logs (%LOCALAPPDATA%\RustPlusDesk\logs\)

  • timeline.log — append-only, crash-safe history of every event (presence, AFK, death, oil rig, cargo, heli, vendor, deep sea).
  • events.json — latest state per type (per server, overwritten), loaded on startup to rehydrate the "X ago" timers after a restart. Guards: states from before the server's last wipe (RustMapsWipeTime) or older than ~15h are ignored; past that age commands say "Haven't seen X in a while" instead of a misleading "28h ago".

Anti-spam / reliability

  • Global send throttle — min 1.5s gap between any two team-chat sends so bursts don't hammer the API (isolated messages still send instantly).
  • Alarm spam cooldown — an alarm firing >3× in a row (each within 2 min) mutes its team-chat + Discord alerts for 10 min (per-alarm); popup/audio still fire.
  • Discord webhook forwarding uses a serialized, rate-limited queue honoring Retry-After (was a fresh HttpClient per message with no rate handling).
  • Emoji-tolerant delivery confirmation — Rust rewrites :shortcode: emoji to glyphs in its echo, which broke the send-confirm match and caused duplicate re-sends; both sides are normalized now.
  • Instant command responses — removed an artificial pre-send delay.

Other

  • Configurable AFK threshold (per-server, default 5 min, range 1–60), with a selector in the Chat Commands panel.
  • In-game emoji shortcodes on alerts: :skull: (death), :wave: (join/leave), :vending.machine: (shop).
  • New strings in Resources.resx + en-US; alert templates editable in the Custom Alerts window.

Builds clean (Release, 0 errors). No changes to existing polling cadence; all additions are opt-in via the chat-commands / chat-announce toggles.

@Rathio12 Rathio12 force-pushed the feature/team-chat-commands branch 8 times, most recently from 51fc946 to b0a3c33 Compare June 14, 2026 21:58
… alert

- !shop <item>: search map vending machines; single chat reply (anti-flood,
  reads cached shop data, no extra API polling)
- !small / !large: individual oil rig crate timers
- !pos <name>: report a teammate's grid
- Announce team join / leave and AFK-after-5min (gated by Chat Announce toggle)
- Vanilla emoji shortcodes: 💀 death, 👋 join/leave, :vending.machine: shop alerts
- Fix: emoji-tolerant chat delivery confirmation (no failed-confirm waits / duplicate sends)
- Instant command responses (removed artificial pre-send delay)
- New renameable command rows in the Chat Commands panel; alerts editable in Custom Alerts
@Rathio12 Rathio12 force-pushed the feature/team-chat-commands branch from b0a3c33 to 684a115 Compare June 14, 2026 22:02
Rathio12 added 4 commits June 15, 2026 04:57
…oding

- AFK alerts now announce for any team member (including yourself); the
  alert was previously hard-skipped for the local account, so going AFK
  yourself produced no message.
- !shop now replies with the top 3 matches as separate, spaced messages and
  filters out junk barter trades (non-Scrap currency) that ranked as
  "cheapest" because 1 < 25 across different currencies. Multi-item queries
  (e.g. "clone") no longer mislabel every grid as the first item.
- !afk respects the name-abbreviation setting and caps its reply at the
  128-char team-chat limit so long AFK lists no longer fail to send.
- Discord webhook forwarding now uses a serialized, rate-limited queue
  (shared HttpClient, min gap between posts, honors 429 Retry-After) instead
  of a fresh HttpClient per message with no rate handling.
- Offline-duration tracking is no longer coupled to the Chat Alerts toggle,
  so the "(was offline X)" suffix is correct even if alerts were enabled
  only after the player went offline.
When a teammate dies, the death message now reports how long they were
alive (e.g. ":skull: X died @ G12 was alive for 1h 25m").

- New AliveSince field on TeamMemberVM: set on respawn, seeded when a
  player is first seen alive, and cleared on death.
- Survives going offline/online (sleeping is not dying) and is tracked
  regardless of the Chat Alerts toggle, so the duration stays accurate.
- New "AlertPlayerAliveDuration" string ("was alive for {0}") added to
  Resources.resx and the en-US resources.
Persistence (survives app crashes/restarts), written regardless of the
Chat Alerts toggle:
- timeline.log: append-only, crash-safe history of every event (offline/
  online, AFK/back, death/respawn, oil rig, cargo, heli, vendor, deep sea).
- events.json: latest state per event type, keyed per server and overwritten
  as new events arrive; loaded on startup. On reconnect it rehydrates the
  "X ago" timers for cargo/heli/vendor/deep sea so those commands still
  answer correctly after a restart. New EventStateService handles this.

Reworded in-game presence messages (defaults; still editable in Custom Alerts):
- Death: ":skull: X is dead @ G12, was alive for 1h 25m"
- AFK: "X is now AFK for more than 5m"
- Back from AFK: "X came back from AFK, was AFK for 12m"
@Rathio12 Rathio12 force-pushed the feature/team-chat-commands branch from 2ff8113 to a90d207 Compare June 15, 2026 14:04
Rathio12 added 2 commits June 15, 2026 20:32
- Global outgoing-send throttle: minimum 1.5s gap between any two team-chat
  sends so bursts of alerts/commands don't hammer the Rust+ API. Isolated
  messages still send instantly; only back-to-back ones wait.
- Alarm spam cooldown: if a Smart Alarm fires more than 3 times in a row
  (each within 2 min of the last), its team-chat and Discord raid alerts are
  muted for 10 minutes (per-alarm). Popup/audio still fire.
- Event-state restore guards: ignore persisted states from before the
  server's last wipe (RustMapsWipeTime) and anything older than ~15h. Past
  that age, !cargo/!heli/!vendor/!deepsea say "Haven't seen X in a while"
  instead of a misleading "28h ago".
- !deepsea reports "enable Shops to track it" when shop polling is off,
  instead of blindly claiming it's not up.
- Background Deep Sea poll (every 60s, started on connect) tracks the event
  without needing the Shops layer enabled. Skips when full shop polling is
  already active and backs off under API pressure; also refreshes the shop
  cache so !shop works too.
- Deep Sea direction is now reported reliably as West (it always spawns off
  the west edge; the real direction can't be read from the API) and is shown
  in the alert, e.g. "Deep Sea event is up (West)". The old edge-based guess
  tested Y first and could wrongly say North/South.
- Removed the obsolete "enable Shops" guard from !deepsea now that it's
  auto-tracked.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant