队伍系统
基本信息
| 属性 | 值 |
|---|---|
| 包 | com.gtnewhorizon.gtnhlib.teams(16 个类) |
| 源码 | src/main/java/com/gtnewhorizon/gtnhlib/teams/ |
| 指令根名 | GTNHLibConfig.teamCommandRoot(默认 gtnhteam) |
| 对外显示名 | GTNHLibConfig.teamSystemName(默认 GTNHTeams) |
| 开关 | GTNHLibConfig.enableTeamCommands(默认 true) |
| 存档目录 | <世界目录>/gtnhteams/(每个队伍 1 个 JSON) |
| 客户端 | 需 ModularUI 2(isMui2Loaded),否则只有指令 |
功能
GTNH 的多人队伍系统:角色、成员、邀请、合并、管理员指令。README 的 Teams 节:
Team management system with roles, membership, and admin commands. Register your own data on a team with
TeamDataRegistry. The library persists it to disk and syncs it to clients.
角色
TeamRole 枚举 3 级,从低到高:
| 枚举值 | 权限 |
|---|---|
MEMBER |
成员,最低级 |
OFFICER |
官员,可邀请 |
OWNER |
所有者,可改名/晋升/降级/发起合并/解散 |
权限约束(assets/gtnhlib/lang/en_US.lang 的 gtnhlib.chat.teams.help.* 与 teams.error.*):
gtnhteam promote|demote <player>— 仅 OWNERgtnhteam kick <player>— OWNER,或排名低于自己者gtnhteam rename <new name>/merge request <team>/disband— 仅 OWNERgtnhteam invite <player>— OWNER 或 OFFICER
指令
TeamCommand 与 TeamAdminCommand 在 serverAboutToStart 中条件注册(CommonProxy.java:125-128):
if (GTNHLibConfig.enableTeamCommands) {
TeamCommand.register();
TeamAdminCommand.register();
}
玩家指令(gtnhlib.chat.teams.message.usage):
help, gui, info, rename, invite, accept, deny, leave, promote, demote, kick, disband, merge <request|cancel|accept|deny>
管理员指令(gtnhlib.chat.teams.admin.message.usage):
help, info, rename, promote, demote, kick, merge, disband
gui 子命令在 ModularUI 2 未加载时报错(gtnhlib.chat.teams.error.mui2_not_loaded=MUI2 is required for Teams GUI.),见 ModularUI2 队伍 GUI。
关键安全约束
系统对"最后一个成员"的场景有明确的拒绝逻辑,全部有对应语言键:
| 约束 | 语言键 |
|---|---|
| 不能退出唯一成员的队伍 | teams.error.last_member_leave |
| 不能作为最后一个 OWNER 退出(其他成员还在时) | teams.error.last_owner_leave |
| 不能降级/解散自己作为唯一成员或最后一任 OWNER 的队伍 | teams.error.last_owner_demote、teams.error.last_owner_disband |
| 管理员不能强退最后一任 OWNER | teams.admin.error.kick_last_owner、teams.admin.error.demote_last_owner |
| 管理员不能强解散单人队伍 | teams.admin.error.cannot_disband_solo_team |
TeamManager.mergeTeams(Team surviving, Team consumed) 合并时会把 consumed 的成员与数据整体并入 surviving(TeamManager.java:119),并通过 transferTeamData(prevTeam, newTeam, playerId, reason) 触发 ITeamData 的迁移回调(TeamManager.java:148)。
持久化
TeamDataSaver 以 WorldEvent 驱动,不常驻内存:
| 事件 | 行为 |
|---|---|
WorldEvent.Load |
创建 INSTANCE,目录 <世界>/gtnhteams,立即 loadFromFiles()(:42-45) |
WorldEvent.Save |
saveToFiles()(:61-64) |
WorldEvent.Unload |
saveToFiles() 后实例失效(:50-53) |
loadFromFiles() 用 dir.listFiles((dir, name) -> name.endsWith(".json")) 枚举队伍文件(:75),即每个队伍一个 JSON 文件。
扩展点
| 接口/类 | 用途 |
|---|---|
ITeamData |
队伍自定义数据契约 |
TeamDataRegistry |
register(String key, Supplier<ITeamData> factory) 注册 |
INetworkTeamData |
需要经网络同步的数据 |
TeamDataTransferReason |
合并/改名等迁移原因 |
TeamDataRegistry 另有 construct(String key) 与 getRegisteredKeys() 两个静态方法(TeamDataRegistry.java:21、:28)。这是下游 mod 往队伍上挂持久化数据的主要入口,GTNHLib 负责落盘与同步。
数值
| 数值名 | 值 |
|---|---|
teams 包类数 |
16 |
| 角色数 | 3(MEMBER / OFFICER / OWNER) |
| 玩家子指令数 | 14 |
| 管理员子指令数 | 8 |
| 同步数据包 | 2(TeamInfoSync、TeamDataSync) |
| 存档格式 | 每队伍 1 个 .json |
gtnhlib.chat.teams.* 语言键 |
101(en_US.lang) |
gtnhlib.gui.teams.* 语言键 |
49(en_US.lang) |
交互
队伍数据同步经 网络处理器 的 2 个上行包完成。TeamManager 提供 9 个公开静态方法,包括 isTeamNameValid、getTeamByPlayer、getTeamByName、getTeamById、getOrCreateTeam、createTeam、mergeTeams、transferTeamData、forEachOnlineTeamMember。
相关条目
- ModularUI2 队伍 GUI -
gtnhteam gui的图形界面 - 网络处理器 - 队伍同步所用的 2 个数据包
- GTNHLib 主配置 -
enableTeamCommands、teamCommandRoot、teamSystemName