Repository navigation
Ignore, message rate limit, AFK auto-reply and activity events (0.7.0) - #7
Merged
Merged
Conversation
….7.0)
- /f ignore <player>, /f unignore <player>, /f ignore (list): blocks private messages and friend
requests either way, silently ends a friendship (FriendRemovedEvent still fires) and drops pending
requests. Stored in a new friends_ignores table (created at startup). Works across proxies without a
new Redis event type: the acting proxy checks memory or the database, and the receiving proxy drops
messages from players its player ignores.
- private-messages.rate-limit (default 3 messages per 3 seconds, sliding window per sender): blocked
messages tell the sender how long to wait and never reach FriendMessageEvent.
- AFK auto-reply: a friend whose status is away still gets the message; the sender sees "I'm currently
AFK, and will answer when I am available." at most once every 5 minutes per friend.
- API: FriendsAPI.sendMessage (CompletableFuture<Result>, same rules and event as /msg),
Result.RATE_LIMITED and Result.IGNORED, PlayerActivityChangeEvent on Velocity and BungeeCord,
LastSeen.presence/line for emoji presence strings in other UIs ("🟢 Online", "⚫ Last seen 3 days ago").
- Config upgrades also add new keys inside existing sections (private-messages.rate-limit), following
the user's indentation and line endings, written atomically and through symbolic links.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Moderation and presence features on top of 0.6.0 (
/msg,/r,LastSeen,presence.ruleswere already there). Version 0.7.0.Messaging and moderation
/f ignore <player>,/f unignore <player>,/f ignore(list). Ignoring:FriendRemovedEventstill fires;/msg,/rand friend requests.Stored in a new
friends_ignorestable, created at startup. It needs no new Redis event type: the acting proxy checks memory or the database, and the receiving proxy drops messages from ignored players. So a network where some proxies are still on 0.6.0 keeps working.Rate limit:
private-messages.rate-limit(default 3 messages per 3 s, a sliding window per sender). Blocked messages tell the sender how long to wait and never reachFriendMessageEvent.AFK auto-reply: a friend whose status is away still gets the message. The sender sees "I'm currently AFK, and will answer when I am available. (auto-reply)" at most once every 5 minutes per friend.
The rate-limit and AFK cooldowns are kept in each online player's cached data and freed when they disconnect. This needs no cache library: both are bounded.
API
FriendsAPI.sendMessage(UUID, UUID, String)returnsCompletableFuture<Result>, like every other action, and follows the same rules as/msg(friends only, rate limit, ignore,FriendMessageEvent). It does not return a blockingboolean: that could deadlock on the Paper main thread, since Bukkit events are asynchronous.Result.RATE_LIMITEDandResult.IGNORED, added at the end of the enum so existing values keep their positions.PlayerActivityChangeEvent(player, oldActivity, newActivity)on Velocity and BungeeCord. It fires on the player's own proxy when they join, switch server or leave, and only if the activity changed. There is no Paper version: Paper never knows backend server names, so it would never fire.LastSeen.presence(...)/LastSeen.line(...)return"🟢 Online","⚫ Last seen 3 days ago"and"🟢 Bob — Playing BedWars Solo"for menus, websites and Discord. In-game chat keeps the coloured●, because 1.8 clients have no emoji font.Upgrading
private-messages.rate-limit), not just whole missing sections.key: value,key: {...}) are left alone.Test plan
./gradlew build: core 189 tests, SQLite 3.7.2 driver 44 (with the new moderation suite), Velocity 7, BungeeCord 8, Paper 8 (MockBukkit), strict javadoc,verifyBuilds(0.7.0)-Dfriends.mysql,-Dfriends.redis): 189 pass, 2 SQLite-only checks skippedtools/e2e), with the shared friend story extended (AFK reply, rate-limit burst, ignore/unignore): 14/14 scenarios on Paper 1.8.8 and 26.3, Folia 1.21.11, BungeeCord and Velocity (1.8.8 and 26.3 clients), the API probe (Paper 1.8.8, Paper 26.3, BungeeCord, Velocity), and BungeeCord + Velocity together on shared MySQL + Redisupgrade-paper/upgrade-velocityfrom 0.6.0 jars: friendships kept,rate-limitadded inside the user'sprivate-messagessection,/f ignoreworks on the old database🤖 Generated with Claude Code