Repository navigation
Private messages, last-seen display and server-based presence (0.6.0) - #6
Merged
Merged
Conversation
…6.0)
Private messages: /msg <friend> <message> (/tell, /w, /whisper) and /r (/reply),
friends only, network-wide. A cancellable FriendMessageEvent (Bukkit, Velocity,
BungeeCord) fires first: cancel it to own the messaging layer, or rewrite the text.
Messages go straight to Redis (not behind the SQL queue) and are never stored.
Player text is never parsed; section signs and control characters are stripped.
private-messages.enabled: false leaves the commands to another plugin.
Last seen: LastSeen (API) words times ("Last seen 17 minutes ago"); /f list
shows "● Bob — Playing BedWars Solo" / "● Bob — Last seen 3 days ago", and
/msg to an offline friend says when they were last seen.
Presence: presence.rules map backend server-name regexes to a generic
PlayerActivity (game, mode). Evaluated on join and server switch, carried by
the existing Presence / Event.Updated through Redis (published only when it
changed), exposed as FriendsAPI.getActivity. Bad rules are skipped with a
warning. No party logic: that belongs to Parties & Chill.
Upgrades: no schema change; missing config.yml sections are appended with
their comments; older proxies ignore the new Presence field. New e2e
scenarios upgrade-paper / upgrade-velocity run the previous release, then this
build on the same data.
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.
What
Three social features, on Velocity, BungeeCord and Paper (one shared core), API 0.6.0.
1. Private messages
/msg <friend> <message>(also/tell,/w,/whisper) and/r <message>(also/reply). Friends only, network-wide; the recipient must be online and not appearing offline.From [VIP] Bob: hi/To Bob: hi; clicking one starts a reply.FriendMessageEvent(Bukkit, Velocity, BungeeCord) fires before delivery. If a plugin cancels it, Friends delivers nothing, echoes nothing and leaves both players'/rtarget unchanged, so an external chat plugin can own the messaging layer.setMessagelets a filter rewrite the text.&codes);§and control characters are stripped.private-messages.enabled: falsekeeps/msgand/runregistered, for networks that have their own.2. Last seen
LastSeen(API, Java 8):LastSeen.format(friend.getLastSeen())gives "Last seen 17 minutes ago" ("just now", "3 days ago", …), for other plugins' menus and scoreboards./f list:/msgto an offline friend replies "Bob is offline. (Last seen 3 days ago)".3. Server-based presence
presence.rulesin config.yml: each server-name regex maps to a genericPlayerActivity(game, mode). The regex must match the whole name, case is ignored, the first match wins, andmodeis optional.Presence/Event.Updatedthrough the Redis presence hash, so there are no new keys, and nothing is published if nothing changed.FriendsAPI.getActivity(UUID)returns anOptional<PlayerActivity>.Upgrading from 0.5.0
config.ymlsections are added to the end of the existing file with their comments; nothing the server owner wrote is touched./msgand its aliases are new. On Paper they are registered when the plugin starts, not through plugin.yml: a plugin that declares/msgin its plugin.yml (e.g. Essentials) keeps it, and Friends logs that its own is/friends:msg. On both proxies, Friends replaces an existing/msgand logs it. I checked this in the BungeeCord API and Velocity proxy bytecode:Map.put, thenremoveChildByName+addChild./msgto a player on a proxy that isn't upgraded yet is lost. This is written in the README.Decisions taken with the maintainer
●(U+25CF) instead of the emoji 🟢/⚫. I couldn't confirm 🟢 (outside the Basic Multilingual Plane) renders on 1.8 clients.PlayerActivityis read-only, likeFriendandFriendRequest, with no setters: one shared object is synchronised across proxies, so a setter would change what every proxy sees.Tests
src/teststays out of git): 149 core, 7 Paper (MockBukkit), 5 Velocity, 6 BungeeCord, all passing. They also pass with-Dfriends.mysqland-Dfriends.redisagainst a throwaway MySQL 8.0 and redis-server. They cover:LastSeenboundaries, config upgrade/msgand/r: not friends, offline, appearing offline, cancelled, rewritten, re-checked after the event listeners, text injectiontools/e2e, all passing): Paper 1.8.8 and 26.3, Folia 1.21.11, Velocity and BungeeCord with 1.8.8 and 26.3 players, the API probe on 4 platforms,mixed(BungeeCord + Velocity on MySQL + Redis: Alice on BungeeCord sees Bob's activity from Velocity, and/msg↔/rgo through Redis), plus the newupgrade-paper/upgrade-velocity(the 0.5.0 jar first, then this build on the same data: friendship and nickname kept, config extended,/wworking)./msg,/telland/wtake over vanilla's on both real Paper versions../gradlew build(includingverifyBuilds, Java 8 bytecode, Javadoc lint) passes.Not included (easy to add if wanted)
Offline mail, ignore lists, social spy, a message rate limit, an activity-change event, and an API method to send a message.
🤖 Generated with Claude Code