This commit is contained in:
2026-05-26 23:20:08 -04:00
commit 4361d33ec3
56 changed files with 4508 additions and 0 deletions
+105
View File
@@ -0,0 +1,105 @@
# Commands
Every command is single-token-only (Hytale arg restriction). Multi-word inputs (DM bodies, guild chat lines, MOTDs longer than one word) use the **chat-target toggle** pattern: a command sets your chat mode, then your next chat message carries the body.
## Friends - `/friend`
| Subcommand | Args | Permission | Behavior |
|---|---|---|---|
| `/friend add <name>` | name | `networksocial.friend.use` | Send a friend request to an online player. Fails if recipient has `FRIEND_REQUEST` privacy set to `NOBODY` (or `FRIENDS` and you're not one already). |
| `/friend accept <name>` | sender name | `networksocial.friend.use` | Accept an incoming pending request. |
| `/friend reject <name>` | sender name | `networksocial.friend.use` | Reject an incoming pending request (no notification sent to sender). |
| `/friend remove <name>` | friend name | `networksocial.friend.use` | Remove someone from your friends list. Bidirectional. |
| `/friend list` | (none) | `networksocial.friend.use` | Show all accepted friends. |
| `/friend pending` | (none) | `networksocial.friend.use` | Show incoming + outgoing pending requests. |
Notes:
- `add`/`accept`/`reject`/`remove` need a username. If the target is online network-wide, `PlayerPresence` resolves them. If not, `accept`/`reject`/`remove` fall back to scanning your own friendship rows. `add` requires the target to be online.
## Guilds - `/guild`
| Subcommand | Args | Permission | Behavior |
|---|---|---|---|
| `/guild create <name>` | name | `networksocial.guild.create` | Create a new guild with you as owner. Seeds default ranks: Member / Officer / Owner. |
| `/guild disband` | (none) | `networksocial.guild.use` | Owner only. Deletes guild, ranks, members, and pending invites in one shot. |
| `/guild invite <name>` | invitee name | `networksocial.guild.use` | Requires `INVITE` permission on your rank. Sends an invite to an online player. Subject to their `GUILD_INVITE` privacy. |
| `/guild accept <guild>` | guild name | `networksocial.guild.use` | Accept a pending invite. You join at the guild's lowest-priority non-owner rank. |
| `/guild leave` | (none) | `networksocial.guild.use` | Leave your guild. Owners can't leave - use `/guild disband` instead. |
| `/guild kick <name>` | member name | `networksocial.guild.use` | Requires `KICK` permission, must outrank target by `priority`. Can't kick the owner. |
| `/guild promote <name> <rankId>` | name + rank | `networksocial.guild.use` | Requires `PROMOTE` permission, both source and destination ranks must be below yours. |
| `/guild demote <name> <rankId>` | name + rank | `networksocial.guild.use` | Same constraints, but uses `DEMOTE` permission. |
| `/guild motd <text>` | one-token text | `networksocial.guild.use` | Requires `MOTD` permission. Use `/guild chat` for multi-word MOTDs? No - MOTD is one token. For long MOTDs, edit via SQL or extend the plugin. |
| `/guild info` | (none) | `networksocial.guild.use` | Print your guild's name, owner, MOTD, and your rank. |
| `/guild roster` | (none) | `networksocial.guild.use` | List every member of your guild and their rank id. |
| `/guild ranks` | (none) | `networksocial.guild.use` | List every rank in your guild with id, name, priority, owner-flag, and bitmask permissions decoded. |
| `/guild chat` | (none) | `networksocial.guild.use` | Toggle guild-chat mode. While ON, your chat goes to your guild instead of public. Requires `CHAT` permission on your rank. |
### Guild permission bits
A rank's `permissions` is a bitmask of [`GuildPermission`](../src/main/java/net/kewwbec/social/model/GuildPermission.java):
| Bit | Name | What it allows |
|---|---|---|
| 1 | `INVITE` | `/guild invite` |
| 2 | `KICK` | `/guild kick` |
| 4 | `PROMOTE` | `/guild promote` |
| 8 | `DEMOTE` | `/guild demote` |
| 16 | `MOTD` | `/guild motd` |
| 32 | `MANAGE_RANKS` | Edit the rank ladder (no CLI in v1; service-only API) |
| 64 | `DISBAND` | (reserved; today only the owner can disband) |
| 128 | `CHAT` | `/guild chat` + guild chat send |
Default rank seeding on `/guild create`:
- **Member** (priority 10, perms = `CHAT`)
- **Officer** (priority 50, perms = `CHAT | INVITE | KICK | MOTD`)
- **Owner** (priority 100, all perms, `is_owner_rank=1`)
## Direct messages
| Command | Args | Permission | Behavior |
|---|---|---|---|
| `/msg <name>` | recipient name | `networksocial.dm.use` | Enter one-shot DM mode for the next chat message. Your next chat is delivered as a DM and your mode reverts to NORMAL. |
| `/r` | (none) | `networksocial.dm.use` | Enter DM mode targeting whoever DMed you last. Same one-shot behavior as `/msg`. |
| `/chat` | (none) | (none) | Clear any DM-mode / guild-chat-mode state so your chat is public again. |
Why one-shot DMs: Hytale args are single-token, so `/msg name body of message` is impossible. The toggle pattern is the same one Staff uses for `/sc`.
## Privacy - `/privacy`
| Subcommand | Args | Permission | Behavior |
|---|---|---|---|
| `/privacy show` | (none) | `networksocial.privacy.use` | Print your current DM / friend-request / guild-invite policies. |
| `/privacy set <key> <value>` | key + value | `networksocial.privacy.use` | Update one policy. `key` is `DM`, `FRIEND_REQUEST`, or `GUILD_INVITE`. `value` is `EVERYONE`, `FRIENDS`, or `NOBODY`. |
Privacy is enforced **at the sender's server**: when you `/friend add X`, your server calls `PrivacyService.canContact(you, X, FRIEND_REQUEST)` before publishing on the bus. If X has set their friend-request policy to NOBODY, the request never travels. Same for DM and guild-invite.
## Hub - `/social`
| Command | Args | Permission | Behavior |
|---|---|---|---|
| `/social` | (none) | (none) | Open the HyUI hub. Buttons go to Friends, Guild Roster, and Privacy Settings panels. |
See [07_UI.md](07_UI.md).
## Permissions index
```
networksocial.friend.use
networksocial.guild.use
networksocial.guild.create
networksocial.dm.use
networksocial.privacy.use
networksocial.admin # reserved for future server-side moderation tools
```
Each command checks one specific node via `requirePermission(...)` + `canGeneratePermission() = false`. We don't rely on Hytale's auto-generated permission names - those proved unreliable in practice. See [Ranks docs / Provider_Integration](../../Ranks/docs/05_Provider_Integration.md) for the broader rationale.
## Error/result responses
Every operation returns a `Result` enum from its service. Commands map these to user-facing chat text. The full set per service:
**FriendService.Result**: `OK`, `SELF`, `ALREADY_PENDING`, `ALREADY_FRIENDS`, `BLOCKED_BY_PRIVACY`, `LIMIT_REACHED`, `NO_REQUEST`, `DB_ERROR`.
**GuildService.Result**: `OK`, `NAME_INVALID`, `NAME_TAKEN`, `ALREADY_IN_GUILD`, `NOT_IN_GUILD`, `NOT_FOUND`, `NO_PERMISSION`, `SELF`, `BLOCKED_BY_PRIVACY`, `AT_CAPACITY`, `NO_INVITE`, `RANK_INVALID`, `OWNER_RANK_LOCKED`, `OWNER_ONLY`, `DB_ERROR`.
**DmRoutingService.Result**: `OK`, `SELF`, `TARGET_OFFLINE`, `BLOCKED_BY_PRIVACY`, `DB_ERROR`.