Friend
概览
Friend 为每位玩家提供一个好友列表。玩家发送请求,对方接受或拒绝,已接受的好友可以互相查看在线状态并传送到彼此身边。所有功能都可以通过 /friend 命令、TypeWriter 动作和事实,以及你在网页面板中自行设计的菜单来使用。
好友关系按玩家 UUID 存储,因此在更改名称后依然有效。列表保存在单个 Friend Artifact 中。当安装了 MySQL 桥接并启用 Redis 时,请求、好友关系和在线状态会在服务器网络的所有服务器之间共享,/friend tp 还可以把玩家送到其好友所在的服务器。
菜单是一个 GUI 菜单:你在网页面板中构建其布局,并将某些物品标记为 Friend 按钮。好友头颅本身由扩展放置。
功能
- 好友请求 — 通过命令、动作条目或菜单点击来发送、接受、拒绝和删除好友。
- 请求开关 — 每位玩家都可以用
/friend toggle关闭收到的请求。 - 好友菜单 — 一个条目包含所有界面(好友、请求、标签页),带有玩家头颅、分页和空槽位填充物。
- 传送到好友 — 在同一服务器内,或在服务器网络中通过代理传送到好友所在的服务器。
- 在线状态 — 本地玩家,以及启用 Redis 时同一分组内其他服务器上的玩家。
- 剧情钩子 — 一个表示“该玩家是否为好友”的事实,以及一个表示“有多少好友在线”的事实。
- 占位符 — 数量、列表、按索引取得的名称以及好友所在的服务器,可用于任何 MiniMessage 文本。
- 管理工具 — 使用
/friend admin列出、查看,并强制建立或解除任何人的好友关系。
安装
- 安装负责绘制菜单的 GUI 扩展。
- 可选,用于多台服务器:安装 MySQL 扩展并在其配置中启用 Redis(或 Valkey),每台服务器使用相同的
redis.group-id。参见跨服务器行为。 - 将 Friend 的 JAR 放入
plugins/Typewriter/extensions/并重启服务器。 - 在静态页面上创建一个 Friend Artifact 条目并发布。没有它,任何内容都不会被保存。
权限 friend.use 和 friend.tp 默认授予所有人,friend.admin 默认授予管理员。
快速上手
构建一个由 /friend 打开的好友菜单:
- 在 TypeWriter 网页面板中,打开一个**静态(static)**页面,添加一个 Friend Artifact。将
artifactId保持为friend_data。 - 打开一个页面,添加一个 Friend Menu 条目。命令
/friend会打开找到的第一个 Friend Menu,因此通常只需要一个。 - 设置
inventoryTitle、inventoryRows和guiType,然后在layoutPool中构建布局,并将mainLayoutId指向根布局。有关布局和框架,请参阅 GUI 指南。 - 放置你的装饰物和按钮。在物品上,于
buttonType中选择一个 Friend 值,例如用于计数器的FRIEND_STATUS、用于请求开关的FRIEND_SETTINGS_TOGGLE_REQUESTS,或用于关闭菜单的NAV_CLOSE。 - 声明各个界面:在
views中为每个界面添加一项,然后在friendListViewIds中列出显示好友的 id,在requestListViewIds中列出显示收到请求的 id。 - 使用
contentX、contentY、contentColumns和contentRows设置玩家头颅出现的位置。 - 发布,然后在游戏中运行
/friend。
若要通过任务、NPC 或物品打开菜单,请将 Friend Menu 条目链接到另一个条目的 triggers 中,或将其作为动作运行。
使用 Is Friend 事实,并将 targetName 设为某个玩家名称,然后在条件中使用该事实(值为 1 表示是好友)。对于随活跃好友列表而变化的奖励,请使用 Online Friends Count。
工作原理
每位玩家的数据会在该玩家在服务器上在线时加载,并在后台保存到构件中。每次更改也会发布到社交消息总线上,因此持有另一位玩家的服务器同样会应用它。
菜单
Friend Menu 条目是一个 GUI 菜单,包含三个 Friend 特有的部分。
玩家头颅。 在 friendListViewIds 中声明的界面上,每位好友都是一个玩家头颅,在线好友排在前面。左键点击传送到该好友,右键点击删除该好友。在 requestListViewIds 中声明的界面上,左键点击接受请求,右键点击拒绝请求。头颅填充一个从 contentX 和 contentY 开始、大小为 contentColumns 乘 contentRows 个槽位的网格。空闲的格子显示 emptySlotItem。
按钮。 buttonType 为下列值之一的物品会在渲染时被替换:
buttonType | 玩家看到或执行的内容 |
|---|---|
FRIEND_STATUS | 在线、离线和好友总数。 |
FRIEND_LIST | 好友总数,列表为空时显示“没有好友”。 |
FRIEND_REQUESTS | 待处理请求的数量。至少有一个时,点击会打开 requests 视图。 |
FRIEND_SETTINGS_TOGGLE_REQUESTS | 点击开启或关闭收到的请求。 |
FRIEND_ONLINE_HEADER、FRIEND_OFFLINE_HEADER | 装饰性的分区标题。 |
PAGE_NAV | 翻页箭头。左键点击前进,右键点击后退,名称显示页码计数。一页足够时会隐藏。 |
NAV_BACK、NAV_CLOSE | 返回上一个菜单,关闭菜单。 |
FRIEND_ADD、FRIEND_REMOVE、FRIEND_ACCEPT、FRIEND_DECLINE、FRIEND_TP、FRIEND_MSG、FRIEND_PLAYER_SLOT | 带有固定名称和 lore 的展示物品,本身没有动作。 |
编辑器提供的其他值(NAV_PREV、NAV_NEXT、PENDING_REQUESTS、FRIEND_SLOT、REQUEST_ACCEPT、REQUEST_DECLINE)会保持你配置的样子。
槽位命令。 物品可以运行以 friend 开头的命令:friend open [view]、friend page next|prev|<number>、friend tp <name>、friend remove <name>、friend accept <name>、friend decline <name>、friend toggle、friend add <name>。它们以点击的玩家身份运行,无需 %player%。
内置的菜单文本(默认标题 “Amis”、按钮名称和头颅 lore)为法语。可通过你在布局中设置的物品名称和 lore,以及 inventoryTitle 来覆盖它们。命令发送的聊天消息为英语。
跨服务器行为
Friend 在单台服务器上无需任何其他插件即可工作。在服务器网络中,请安装 MySQL 并启用 Redis 或 Valkey,然后为网络中的每台服务器设置相同的 redis.group-id 和不同的 redis.server-name。没有 group-id 时,社交消息总线保持静默,每台服务器只能看到自己的更改。
连接桥接后:
- 请求、新的好友关系、删除以及请求开关都会发送到其他服务器;
- 当 Redis 知道某位好友位于哪台服务器时,该好友会被视为在线;
- 对位于另一台服务器上的好友使用
/friend tp,会请求代理将你连接到该服务器(代理必须能理解btc:bridge通道)。你会到达该服务器,而不是好友所在的位置。
构件遵循当前启用的存储:当 MySQL 配置中的 mysql.enabled 为 true 时,Friend Artifact 存储在共享数据库中,因此每台服务器读取的都是同一份好友列表。
命令
所有命令都需要 friend.use。别名:/friends、/f、/amis。不带参数的命令会打开第一个 Friend Menu,如果不存在则不输出任何内容。
| 命令 | 说明 |
|---|---|
/friend | 打开好友菜单。 |
/friend add <player> | 发送好友请求。 |
/friend accept <player> | 接受一个待处理的请求。 |
/friend decline <player> | 拒绝一个待处理的请求。 |
/friend remove <player> | 删除一位好友。 |
/friend list | 在聊天中输出你的好友及其在线状态。 |
/friend toggle | 开启或关闭收到的好友请求。 |
/friend tp <player> | 传送到一位好友(同时需要 friend.tp)。 |
/friend admin list <player> | 列出某位在线玩家的好友(需要 friend.admin)。 |
/friend admin requests <player> | 列出某位在线玩家的待处理请求。 |
/friend admin add <player> <player> | 让两位在线玩家成为好友,无需请求步骤。 |
/friend admin remove <player> <friend> | 从某位在线玩家的列表中移除一位好友。 |
权限
| 权限 | 默认 | 授予 |
|---|---|---|
friend.use | 所有人 | 所有 /friend 命令。菜单点击会执行相同的动作,但不会检查该权限。 |
friend.tp | 所有人 | /friend tp。在菜单中点击头颅会直接执行传送,并且不会检查此权限。 |
friend.admin | 管理员 | /friend admin 命令。 |
占位符
这些是 MiniPlaceholders 标签,在 MiniMessage 文本中写作 <friend_count>。布尔值返回 1 或 0。
| 占位符 | 返回 |
|---|---|
<friend_count> | 该玩家的好友数量。 |
<friend_online_count> | 在此服务器上在线的好友数量。 |
<friend_online_network_count> | 已知在该分组内任意服务器上在线的好友数量。 |
<friend_requests_count> | 待处理请求的数量。 |
<friend_requests_enabled> | 允许收到请求时为 1。 |
<friend_list> | 以逗号分隔的好友名称。 |
<friend_online_list> | 在此服务器上在线的好友名称。 |
<friend_name:index> | 该位置的好友名称,从 0 开始。 |
<friend_online_name:index> | 该位置的在线好友名称,从 0 开始。 |
<friend_is_friend:name> | 当指定名称的玩家是好友时为 1。 |
<friend_server:name> | 指定名称的玩家在线所在的服务器,未知时为空。 |
条目
8 个条目,由扩展源码生成。
动作5
- Accept Friend RequestAccept a friend request
- Friend MenuFriend Menu
- Remove FriendRemove a friend
- Send Friend RequestSend a friend request
- Teleport to FriendTeleport to a friend
事实2
- Is FriendCheck if player is Friend
- Online Friends CountNumber of online friends
构件1
- Friend ArtifactFriend Data Artifact
故障排查
重启后好友消失。 没有发布 Friend Artifact,因此数据只存在于内存中。请在静态页面上添加该构件并发布。
/friend 没有任何反应。 该命令会打开第一个 Friend Menu 条目,没有时保持静默。请创建并发布一个 Friend Menu。诸如 /friend list 之类的子命令在没有菜单时也能工作。
请求已发送,但对方始终没有收到。 发送请求时,接收者必须在网络中的某台服务器上在线。发给离线玩家的请求不会被保留,而发送者仍会被告知请求已发送。在多台服务器上,请检查 redis.group-id 在所有地方是否设置为相同的值,否则请求无法跨服务器传递。
在第二台服务器上好友列表为空。 每台服务器都需要相同的 redis.group-id、唯一的 redis.server-name,并且 mysql.enabled 必须为 true,这样构件才能通过数据库共享。请检查 MySQL 扩展的日志中是否有 Redis 连接错误。
头颅网格为空或只显示填充物品。 当前界面未在 friendListViewIds 或 requestListViewIds 中列出。当菜单声明了 views 时,只有其中列出的 id 才会显示头颅。没有 views 时,请将 view 设为 friends 或 requests。
在另一台服务器上传送到好友没有任何作用。 代理必须处理 btc:bridge 通道,并且 Redis 在线状态必须正常工作。没有网络连接时,/friend tp 仅在好友位于同一服务器时才有效。