权限节点
基本信息
| 属性 | 值 |
|---|---|
| 常量源文件 | src/main/java/serverutils/ServerUtilitiesPermissions.java:37-432 |
| 固定节点常量 | 69 个(:43-132) |
| 处理器 | serverutils.ranks.ServerUtilitiesPermissionHandler(enum 单例 INSTANCE) |
| 处理器安装 | ServerUtilitiesCommon preInit 中 PermissionAPI.setPermissionHandler(...),条件 ranks.enabled |
| 默认等级枚举 | serverutils.lib.util.permission.DefaultPermissionLevel(ALL / OP / NONE) |
| rank 可配置值 | 25 个 registerRankConfig 调用 |
| 自定义前缀 | 5 个显式 + 1 个事件扩展点 |
| 动态生成节点 | 每个方块 2 个、每个物品 1 个、每个排行榜 1 个 |
三层权限模型
| 层 | 载体 | 用途 |
|---|---|---|
| 原版 OP 等级 | CmdBase.Level |
服务端指令的粗粒度门槛(0 / 2 / 4) |
| 固定节点 | 本页 69 个常量 | 跨队伍、跨功能的细粒度判定 |
| Rank 图 | Ranks + 25 个 rank 配置值 |
玩家 → rank → 节点的完整解析 |
ServerUtilitiesPermissionHandler.hasPermission()(ServerUtilitiesPermissionHandler.java:41-66)的判定顺序:
- 客户端短路:若上下文有 world 且
isRemote,或FMLCommonHandler.getEffectiveSide() == CLIENT→ 只按DefaultPermissionLevel.ALL判定 - 补全 profile:
getId() == null时用EntityPlayer.func_146094_a(name)反查 UUID;名字也 null 则拒绝 - 查 rank 图,
ALLOW→ true,DENY→ false - 其余 → 委托
DefaultPermissionHandler
客户端短路是刻意的:防止客户端通过预测调用探测服务端权限配置。
固定节点分组(69 个)
按 ServerUtilitiesPermissions.java:43-132 的注释分节整理。
Display(1)
| 节点 | 常量 | 默认等级 |
|---|---|---|
serverutilities.display.admin_info |
DISPLAY_ADMIN_INFO |
OP |
Homes / Warps(10)
| 节点 | 常量 | 默认等级 |
|---|---|---|
serverutilities.homes.cross_dim |
HOMES_CROSS_DIM |
ALL |
serverutilities.homes.max |
HOMES_MAX |
rank 配置 |
serverutilities.homes.cooldown |
HOMES_COOLDOWN |
rank 配置 |
serverutilities.homes.warmup |
HOMES_WARMUP |
rank 配置 |
serverutilities.other_player.homes.list |
HOMES_LIST_OTHER |
OP |
serverutilities.other_player.homes.teleport |
HOMES_TELEPORT_OTHER |
OP |
serverutilities.warps.cross_dim |
WARPS_CROSS_DIM |
ALL |
serverutilities.warps.cooldown |
WARPS_COOLDOWN |
rank 配置 |
serverutilities.warps.warmup |
WARPS_WARMUP |
rank 配置 |
Back(9)
| 节点 | 常量 | 默认等级 |
|---|---|---|
serverutilities.back.home |
HOMES_BACK |
OP |
serverutilities.back.warp |
WARPS_BACK |
OP |
serverutilities.back.spawn |
SPAWN_BACK |
OP |
serverutilities.back.tpa |
TPA_BACK |
OP |
serverutilities.back.rtp |
RTP_BACK |
OP |
serverutilities.back.respawn |
RESPAWN_BACK |
ALL |
serverutilities.back.tp |
VANILLA_TP_BACK |
OP |
serverutilities.back.back |
BACK_BACK |
OP |
serverutilities.back.infinite |
INFINITE_BACK_USAGE |
ALL |
serverutilities.back.cooldown |
BACK_COOLDOWN |
rank 配置 |
serverutilities.back.warmup |
BACK_WARMUP |
rank 配置 |
Claims(13)
| 节点 | 常量 | 默认等级 |
|---|---|---|
serverutilities.other_player.claims.see_info |
CLAIMS_OTHER_SEE_INFO |
OP |
serverutilities.other_player.claims.claim |
CLAIMS_OTHER_CLAIM |
OP |
serverutilities.other_player.claims.unclaim |
CLAIMS_OTHER_UNCLAIM |
OP |
serverutilities.other_player.claims.load |
CLAIMS_OTHER_LOAD |
OP |
serverutilities.other_player.claims.unload |
CLAIMS_OTHER_UNLOAD |
OP |
serverutilities.claims.max_chunks |
CLAIMS_MAX_CHUNKS |
rank 配置 |
serverutilities.claims.block.edit. |
CLAIMS_BLOCK_EDIT_PREFIX |
前缀,OP |
serverutilities.claims.block.interact. |
CLAIMS_BLOCK_INTERACT_PREFIX |
前缀,OP |
serverutilities.claims.item. |
CLAIMS_ITEM_PREFIX |
前缀,ALL |
serverutilities.claims.bypass_limits |
CLAIMS_BYPASS_LIMITS |
NONE |
serverutilities.claims.attack_animals |
CLAIMS_ATTACK_ANIMALS |
OP |
serverutilities.claims.decay |
CLAIM_DECAY_TIMER |
rank 配置 |
CLAIMS_BYPASS_LIMITS 是全部 69 个常量中唯一默认等级为 NONE 的固定节点(ServerUtilitiesPermissions.java:183)—— 默认谁都没有,必须显式授予。
Chunkloader(3)
| 节点 | 常量 | 默认等级 |
|---|---|---|
serverutilities.chunkloader.max_chunks |
CHUNKLOADER_MAX_CHUNKS |
rank 配置 |
serverutilities.chunkloader.load_offline |
CHUNKLOADER_LOAD_OFFLINE |
ALL |
serverutilities.chunkloader.decay |
CHUNKLOAD_DECAY_TIMER |
rank 配置 |
Chat(11)
| 节点 | 常量 | 默认等级 |
|---|---|---|
serverutilities.chat.speak |
CHAT_SPEAK |
ALL |
serverutilities.chat.formatting |
CHAT_FORMATTING |
ALL |
serverutilities.chat.nickname.set |
CHAT_NICKNAME_SET |
OP |
serverutilities.chat.nickname.colors |
CHAT_NICKNAME_COLORS |
OP |
serverutilities.chat.name_format |
CHAT_NAME_FORMAT |
rank 配置 |
serverutilities.chat.text.color |
CHAT_TEXT_COLOR |
rank 配置 |
serverutilities.chat.text.bold |
CHAT_TEXT_BOLD |
未注册(见下) |
serverutilities.chat.text.italic |
CHAT_TEXT_ITALIC |
未注册 |
serverutilities.chat.text.underlined |
CHAT_TEXT_UNDERLINED |
未注册 |
serverutilities.chat.text.strikethrough |
CHAT_TEXT_STRIKETHROUGH |
未注册 |
serverutilities.chat.text.obfuscated |
CHAT_TEXT_OBFUSCATED |
未注册 |
Other / 管理面板 / 传送(17)
| 节点 | 常量 | 默认等级 |
|---|---|---|
admin_panel.serverutilities.crash_reports.view |
CRASH_REPORTS_VIEW |
OP |
admin_panel.serverutilities.crash_reports.delete |
CRASH_REPORTS_DELETE |
OP(需 VIEW) |
admin_panel.serverutilities.edit_world.gamerules |
EDIT_WORLD_GAMERULES |
OP |
serverutilities.admin_panel.ranks.view |
RANK_EDIT |
OP |
serverutilities.admin_panel.team.edit |
TEAM_EDIT |
OP |
serverutilities.bypass_player_limit |
BYPASS_PLAYER_LIMIT |
OP |
serverutilities.bypass_whitelist |
BYPASS_WHITELIST |
OP |
serverutilities.tpa.cooldown |
TPA_COOLDOWN |
rank 配置 |
serverutilities.spawn.cooldown |
SPAWN_COOLDOWN |
rank 配置 |
serverutilities.rtp.cooldown |
RTP_COOLDOWN |
rank 配置 |
serverutilities.tpa.warmup |
TPA_WARMUP |
rank 配置 |
serverutilities.spawn.warmup |
SPAWN_WARMUP |
rank 配置 |
serverutilities.rtp.warmup |
RTP_WARMUP |
rank 配置 |
serverutilities.tpa.cross_dim |
TPA_CROSS_DIM |
ALL |
serverutilities.spawn.cross_dim |
SPAWN_CROSS_DIM |
ALL |
serverutilities.rtp.cross_dim |
RTP_CROSS_DIM |
ALL |
serverutilities.afk.timer |
AFK_TIMER |
rank 配置 |
serverutilities.other_player.heal |
HEAL_OTHER |
OP |
serverutilities.vanish.see |
SEE_VANISH |
OP |
serverutilities.leaderboard. |
LEADERBOARD_PREFIX |
前缀,ALL |
serverutilities.journeymap.enable |
CLAIMS_JOURNEYMAP |
ALL |
serverutilities.journeymap.other |
CLAIMS_JOURNEYMAP_OTHER |
ALL |
bypass_player_limit 由 MixinNetHandlerLoginServer 提供(Mixins.BYPASS_PLAYER_LIMIT),bypass_whitelist 是配对节点。
Rank 可配置值(25 个)
ServerUtilitiesPermissions.registerConfigs()(:311-365)把 25 个节点注册为带类型的可继承值(ConfigInt / ConfigBoolean / ConfigString / ConfigTimer / ConfigEnum),而非开关。第一参数是「客户端/下限」定义,第二参数是「服务端默认」值。
| 节点 | 客户端定义 | 服务端默认 |
|---|---|---|
parent |
ConfigString("") + 正则 ^[a-z0-9\s,]*$ |
ConfigString("") |
default_player_rank |
ConfigBoolean(false) |
ConfigBoolean(false) |
default_op_rank |
ConfigBoolean(false) |
ConfigBoolean(false) |
power |
ConfigInt(0, 0, Integer.MAX_VALUE-1) |
ConfigInt(0) |
priority |
ConfigInt(0, 0, Integer.MAX_VALUE-1) |
ConfigInt(0) |
serverutilities.chat.name_format |
ConfigString("<{name}>") |
ConfigString("<&2{name}&r>") |
serverutilities.chat.text.color |
ConfigEnum(TextComponentParser.TEXT_FORMATTING_COLORS_NAME_MAP) |
— |
serverutilities.homes.max |
ConfigInt(1, 0, 30000) |
ConfigInt(100) |
serverutilities.homes.cooldown |
ConfigTimer(Ticks.MINUTE.x(5)) |
ConfigTimer(Ticks.NO_TICKS) |
serverutilities.warps.cooldown |
ConfigTimer(Ticks.MINUTE) |
ConfigTimer(Ticks.NO_TICKS) |
serverutilities.tpa.cooldown |
ConfigTimer(Ticks.MINUTE.x(3)) |
ConfigTimer(Ticks.NO_TICKS) |
serverutilities.spawn.cooldown |
ConfigTimer(Ticks.MINUTE) |
ConfigTimer(Ticks.NO_TICKS) |
serverutilities.back.cooldown |
ConfigTimer(Ticks.MINUTE.x(3)) |
ConfigTimer(Ticks.NO_TICKS) |
serverutilities.rtp.cooldown |
ConfigTimer(Ticks.MINUTE.x(10)) |
ConfigTimer(Ticks.NO_TICKS) |
serverutilities.homes.warmup |
ConfigTimer(Ticks.SECOND.x(5), Ticks.MINUTE.x(5)) |
ConfigTimer(Ticks.NO_TICKS) |
serverutilities.warps.warmup |
同上 | ConfigTimer(Ticks.NO_TICKS) |
serverutilities.tpa.warmup |
同上 | ConfigTimer(Ticks.NO_TICKS) |
serverutilities.spawn.warmup |
同上 | ConfigTimer(Ticks.NO_TICKS) |
serverutilities.back.warmup |
同上 | ConfigTimer(Ticks.NO_TICKS) |
serverutilities.rtp.warmup |
同上 | ConfigTimer(Ticks.NO_TICKS) |
serverutilities.claims.max_chunks |
ConfigInt(100, 0, 30000) |
ConfigInt(1000) |
serverutilities.chunkloader.max_chunks |
ConfigInt(50, 0, 30000) |
ConfigInt(64) |
serverutilities.afk.timer |
ConfigTimer(Ticks.NO_TICKS) |
— |
serverutilities.claims.decay |
ConfigTimer(Ticks.NO_TICKS, Ticks.DAY.x(365)) |
— |
serverutilities.chunkloader.decay |
ConfigTimer(Ticks.WEEK.x(2), Ticks.DAY.x(365)) |
ConfigTimer(Ticks.NO_TICKS) |
[!NOTE] 冷却/预热的服务端默认全是
NO_TICKS(无冷却),客户端定义里的 5 分钟/3 分钟等只是类型示例。这与commands-config中「客户端与服务端配置分离」的设计一致 —— 服务端才是权威。
ConfigTimer 的双参数形式是 (当前值, 上限),ConfigInt 的三参数形式是 (默认值, 下限, 上限)。
5 个聊天样式节点的例外
CHAT_TEXT_BOLD / ITALIC / UNDERLINED / STRIKETHROUGH / OBFUSCATED 这 5 个常量既没有 registerNode,也没有 registerRankConfig,但被真实读取:
// handlers/ServerUtilitiesServerEventHandler.java:157
if (Ranks.INSTANCE.getPermissionResult(player, ServerUtilitiesPermissions.CHAT_TEXT_BOLD, false)
== Event.Result.ALLOW) {
text.getChatStyle().setBold(true);
}
5 处分别在 :157、:162、:167、:172、:177(依次对应 bold / italic / underlined / strikethrough / obfuscated)。相邻的 CHAT_TEXT_COLOR 则确实注册为 rank 配置(:324),走 RankConfigAPI.get(player, ...) 取值。
getPermissionResult(ranks/Ranks.java:513-516)对查不到的节点返回 value.isNull() ? DEFAULT : ...,而 getPermission 最终落到 ServerUtilitiesPermissionHandler.getConfigValue()(:82-90),未命中 rank 时委托 DefaultRankConfigHandler。因此这 5 个节点的实际效果取决于 rank 图中是否存在同名条目 —— 本仓既不预注册默认等级,也不提供自动 GUI 条目。
这是「声明 ≠ 注册」的一个边界案例:代码在用它们,所以不能算死代码;但权限系统从未正式登记它们,/dump_permissions 与 Aurora 权限页也不会列出。已按事实记录,未做推断补全。
前缀机制
registerPrefixes()(:367-389)注册 5 个前缀,末尾 new CustomPermissionPrefixesRegistryEvent(CUSTOM_PERM_PREFIX::add).post() 允许外部模组追加:
| 前缀 | 默认等级 | 说明 |
|---|---|---|
command(Rank.NODE_COMMAND) |
OP | 指令权限;仅在 ranks.command_permissions 开启时有效,否则字符串失效 |
serverutilities.claims.block.edit. |
OP | 领地内可破坏/放置的方块 |
serverutilities.claims.block.interact. |
OP | 领地内可右键交互的方块 |
serverutilities.claims.item. |
ALL | 领地内可在空中右键使用的物品 |
serverutilities.leaderboard. |
ALL | 可查看的排行榜 |
动态生成的节点
registerPermissions()(:271-308)遍历游戏注册表生成海量节点,节点总数等于已注册方块 × 2 + 已注册物品 × 1 + 排行榜数:
| 循环 | 生成规则 | 数量 |
|---|---|---|
方块(:289-301) |
claims.block.edit.<id> 与 claims.block.interact.<id> |
方块数 × 2 |
物品(:303-308) |
claims.item.<id> |
物品数 |
<id> 由 formatId()(:395-403)生成:取注册名转小写并把 : 换成 .;取不到名字时回退为字面量 minecraft.air。
白名单/黑名单决定默认等级(这是本模组唯一的按方块差异化默认权限):
| 集合 | 判定条件 | 所在行 |
|---|---|---|
CLAIMS_BLOCK_EDIT_WHITELIST |
方块 id 以 .grave 或 .gravestone 结尾 |
:274-276 |
CLAIMS_BLOCK_INTERACT_WHITELIST |
instanceof BlockDoor / BlockWorkbench / BlockAnvil |
:278-280 |
CLAIMS_ITEM_BLACKLIST |
item instanceof ItemBucket |
:284-286 |
白名单内的默认 ALL、外的默认 OP(方块);黑名单内的默认 OP、外的默认 ALL(物品,即默认不屏蔽水桶)。
排行榜节点由 ServerUtilitiesLeaderboards.registerLeaderboard()(:213-219)在每次注册排行榜时动态创建,默认 ALL。节点名由 getLeaderboardNode()(:427-431)拼装:本模组内置排行榜不带域名前缀(serverutilities.leaderboard.<id>),外部模组注册的则带(serverutilities.leaderboard.<modid>.<id>)。
节点过滤
Ranks.getPermissionNodes()(Ranks.java:522-545)在枚举节点时会过滤掉前缀派生的平凡节点:若节点以某前缀开头、且其默认等级恰好等于该前缀的默认等级、且描述为空串,则不加入可授予列表。这样 serverutilities.claims.block.edit.minecraft.stone 这类成千上万的节点不会淹没管理员的 rank 编辑界面。
[!IMPORTANT] 本模组的权限体系完全不依赖原版 Forge 权限系统,而是自己实现
IPermissionHandler。原版canCommandSenderUseCommand只在ranks.command_permissions = false或 rank 未给出明确 ALLOW/DENY 时作为兜底。因此本仓中没有ForgePermissions/PermissionAPIPermission之类的注册代码(grep -rn "ForgePermissions" src/无匹配)。