队伍系统

基本信息

属性 值
包 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> — 仅 OWNER
  • gtnhteam kick <player> — OWNER,或排名低于自己者
  • gtnhteam rename <new name> / merge request <team> / disband — 仅 OWNER
  • gtnhteam 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。

相关条目