`module_rbac_permissions` 表
此表允许模块注册自己的 RBAC 权限,而不会与核心权限或其他模块的权限产生 ID 冲突。每个模块使用本地 ID(1、2、3...),该表会自动分配从 100000 开始的全局 ID。
有关系统概述,请参阅 RBAC。
表结构
| Field | Type | Attributes | Key | Null | Default | Extra | Comment |
|---|---|---|---|---|---|---|---|
| module | VARCHAR(255) | SIGNED | PRI | NO | 模块目录名称,例如 mod-cfbg | ||
| id | INT | UNSIGNED | PRI | NO | 模块本地权限 ID | ||
| global_id | INT | UNSIGNED | UNIQUE | NO | AUTO_INCREMENT | 自动分配的全局权限 ID | |
| name | VARCHAR(100) | SIGNED | NO | 权限名称 |
主键是由 (module, id) 组成的复合主键,可防止跨模块的 ID 冲突。global_id 列具有独立的 UNIQUE 索引,并从 100000 开始自动递增。
字段说明
模块目录名称(例如 mod-cfbg、mod-eluna)。该名称必须与 modules/ 下的模块目录名称一致。
模块本地权限 ID。每个模块自行管理从 1 开始的 ID 序列。由于主键包含模块名称,不同模块可以使用相同的本地 ID 而不会产生冲突。
由核心 RBAC 系统使用的自动分配的全局唯一权限 ID。AUTO_INCREMENT 从 100000 开始,以避免与核心权限 ID(1–924)冲突。模块绝不应手动设置此值——它由数据库在插入时分配。
权限的人类可读名称。按照惯例,命令权限使用 Command: .命令名 子命令 的格式。
在模块的 data/sql/db-auth/ 目录下创建一个 SQL 文件:
INSERT IGNORE INTO `module_rbac_permissions` (`module`, `id`, `name`) VALUES
('mod-example', 1, 'Command: .example hello'),
('mod-example', 2, 'Command: .example info');
使用 INSERT IGNORE 以确保 SQL 可以安全地重复执行。
在模块的 C++ 代码中,使用 AccountMgr 将本地 ID 转换为全局 ID:
#include "AccountMgr.h"
uint32 globalId = sAccountMgr->GetModulePermission("mod-example", 1);
如果在数据库中找不到该权限,则返回 0。
在定义命令时,将全局 ID 用作每个命令的权限:
static uint32 GetPermission(uint32 localId)
{
return sAccountMgr->GetModulePermission("mod-example", localId);
}
std::vector<ChatCommand> GetCommands() const override
{
static std::vector<ChatCommand> exampleCommandTable =
{
{ "hello", GetPermission(1), false, &HandleHelloCommand, "" },
{ "info", GetPermission(2), false, &HandleInfoCommand, "" },
};
static std::vector<ChatCommand> commandTable =
{
{ "example", SEC_PLAYER, false, nullptr, "", exampleCommandTable },
};
return commandTable;
}
模块权限需要先分配给角色或账号,之后才能被使用。
分配给角色 —— 通过 rbac_linked_permissions 将模块权限链接到命令角色。所有继承该角色的玩家都将获得访问权限:
-- 将 mod-example 的所有命令授予 GM 命令角色 (197)
INSERT IGNORE INTO `rbac_linked_permissions` (`id`, `linkedId`)
SELECT 197, `global_id`
FROM `module_rbac_permissions`
WHERE `module` = 'mod-example';
分配给特定账号 —— 插入到 rbac_account_permissions 中,或在游戏中使用 .rbac 命令:
-- 将 mod-example 的第一个命令授予所有服务器上的账号 5
INSERT INTO `rbac_account_permissions` (`accountId`, `permissionId`, `granted`, `realmId`)
SELECT 5, `global_id`, 1, -1
FROM `module_rbac_permissions`
WHERE `module` = 'mod-example' AND `id` = 1;
或者在游戏中,一旦你知道了全局 ID(例如 100001):
.rbac account grant 5 100001