Rank 指令

基本信息

属性 值
根指令 /ranks
根类 serverutils.command.ranks.CmdRanks(extends CmdTreeBase)
根指令源码 src/main/java/serverutils/command/ranks/CmdRanks.java:8-19
子命令数 8 + 1 个自动生成的 help
注册 ServerUtilitiesCommands.java:90,受 commands.ranks 控制(默认开)
总开关 ranks.enabled(ServerUtilitiesConfig.java:434-437,默认 true)
指令权限覆写 ranks.command_permissions(ServerUtilitiesConfig.java:443-445,默认 true)

Rank 是一套独立于原版 OP 等级的权限体系。它接管 PermissionAPI 的处理器(ServerUtilitiesCommon.java preInit 中 PermissionAPI.setPermissionHandler(ServerUtilitiesPermissionHandler.INSTANCE)),使所有 serverutilities.* 节点改由 rank 图判定。

子命令表

子命令 类 权限 参数 作用
/ranks info CmdInfo ALL <rank> 查看 rank 详情
/ranks create CmdCreate OP <rank> 新建 rank
/ranks delete CmdDelete OP <rank> 删除 rank
/ranks add CmdAdd OP <rank> <父rank> 添加父 rank(继承)
/ranks remove CmdRemove OP <rank> <父rank> 移除父 rank
/ranks get_permission CmdGetPermission OP <rank> <节点> 读取 rank 的权限值
/ranks set_permission CmdSetPermission OP <rank> <节点> <值> 设置 rank 的权限值
/ranks help CmdTreeHelp — — 自动生成(new CmdTreeHelp(this))

CmdRanks 的 addSubcommand 顺序为 info, create, delete, add, remove, get_permission, set_permission, help(CmdRanks.java:11-18)。

/ranks info 与 /ranks delete 在 ranks.enabled = false 时报 feature_disabled_server(ranks/CmdInfo.java:46、ranks/CmdDelete.java:42、ranks/CmdSetPermission.java:70)。

Rank 名称规则

Ranks.isValidName(String)(src/main/java/serverutils/ranks/Ranks.java:56-58)要求同时满足 4 个条件:

条件 实现
非 null id != null
非空串 !id.isEmpty()
不等于保留字 none !id.equals("none")
匹配 ^[a-z0-9_]+$ RANK_NAME_PATTERN(Ranks.java:49)

与队伍 ID 的 isValidChar(允许 \|、不允许大写)不同,rank 名不允许竖线但同样不允许大写字母。

Rank 内建节点

serverutils.ranks.Rank(src/main/java/serverutils/ranks/Rank.java:26-32)定义 6 个保留节点名:

常量 字符串 说明
NODE_PARENT parent 父 rank 列表(逗号分隔)
NODE_DEFAULT_PLAYER default_player_rank 普通玩家的默认 rank
NODE_DEFAULT_OP default_op_rank OP 的默认 rank
NODE_PRIORITY priority 排序优先级
NODE_COMMAND command 指令权限前缀(见 权限节点)
NODE_POWER power 旧版权力值,已 @Deprecated(Rank.java:31)

这些节点的值在 ServerUtilitiesPermissions.registerConfigs() 中以 ConfigValue 形式注册(ServerUtilitiesPermissions.java:313-320):parent 为带正则 ^[a-z0-9\s,]*$ 的字符串,priority 为 0..Integer.MAX_VALUE-1 的整数,power 同样范围。

优先级计算

Rank.getPriority()(Rank.java:74-88)惰性计算并缓存(priority 初始 -1,clearCache() 复位):

  1. 读 power 与 priority 两个本地权限值,空串按 0 处理
  2. actualPriority = max(priority, power) —— 旧 power 值仍参与取最大值
  3. MathHelper.clamp_int(actualPriority, 0, Integer.MAX_VALUE - 1)

即 power 虽已废弃,但优先级上并未被完全忽略,只是被 priority 覆盖上限。

getParents()(Rank.java:104-118)把 parent 按 , 切分、逐个 trim(),过滤掉解析不到的与 isPlayer() 为真的 rank(玩家专属 rank 不能作为父级),再排序存入 LinkedHashSet。

权限判定链

ServerUtilitiesPermissionHandler.hasPermission()(src/main/java/serverutils/ranks/ServerUtilitiesPermissionHandler.java:41-66)的顺序:

  1. 客户端(有 world 且 isRemote,或 getEffectiveSide() == CLIENT)→ 只按 DefaultPermissionLevel.ALL 判定,即客户端只能看到「所有人都有」的节点
  2. profile.getId() == null 时用名字反查 UUID 补全 GameProfile;仍无名字则拒绝
  3. 查 Ranks.INSTANCE.getPermissionResult(profile, node, true):ALLOW → true,DENY → false
  4. 其余(default)→ 委托 DefaultPermissionHandler.INSTANCE.hasPermission(...)

因此 rank 体系是增量覆盖而非替换:ALLOW/DENY 显式决定,其余落到默认等级。

Ranks.isActive()(Ranks.java:51-54)要求三项同时成立:ranks.enabled 为真、INSTANCE != null、当前处理器确实是 ServerUtilitiesPermissionHandler.INSTANCE。

相关条目