• 欢迎来到Minecraft插件百科!
  • 对百科编辑一脸懵逼?帮助:快速入门带您快速熟悉百科编辑!
  • 因近日遭受攻击,百科现已限制编辑,有意编辑请加入插件百科企鹅群:223812289

“LuckPerms”的版本间的差异

来自Minecraft插件百科
跳转至: 导航搜索
路线 (/lp track <track> ...)
 
(未显示4个用户的20个中间版本)
第1行: 第1行:
 +
{{急需改进|页面冗长,需要拆分子页面}}
 +
{{Plugin Infobox
 +
|外文名    = LuckPerms
 +
|图片      =
 +
|作者      = Luck
 +
|插件类型  = Spigot / CraftBukkit / Sponge
 +
|最新版本  = 4.0.18(Bukkit) / 4.0.60(Sponge)
 +
|兼容服务端 = 1.7, 1.8, 1.9, 1.10, 1.11, 1.12
 +
|前置插件  =
 +
|源地址    = [https://www.spigotmc.org/resources/luckperms-an-advanced-permissions-plugin.28140/ SpigotMC]<br>[https://ore.spongepowered.org/Luck/LuckPerms SpongePowered]
 +
}}
 +
'''LuckPerms'''是一款由Luck开发的权限插件。
 +
 +
== 引言 ==
 +
 
欢迎来到 LuckPerms wiki。这里你将会找到本插件的完整的使用文档,包括了安装、设置、配置和如何高效的使用 LuckPerms。
 
欢迎来到 LuckPerms wiki。这里你将会找到本插件的完整的使用文档,包括了安装、设置、配置和如何高效的使用 LuckPerms。
  
第2,056行: 第2,071行:
 
-----
 
-----
  
=== 日志 (/lp log ...) ===
+
===== 日志 (/lp log ...) =====
  
  
第2,138行: 第2,153行:
 
-----
 
-----
  
= 指令权限 =
+
==== 指令权限 ====
  
 
'''注意''': 你可以使用通配符 * '''All commands''' - luckperms.'' '' '''All user commands''' - luckperms.user.'' '' '''All group commands''' - luckperms.group.'' '' '''All track commands''' - luckperms.track.'' '' '''All log commands''' - luckperms.log.*
 
'''注意''': 你可以使用通配符 * '''All commands''' - luckperms.'' '' '''All user commands''' - luckperms.user.'' '' '''All group commands''' - luckperms.group.'' '' '''All track commands''' - luckperms.track.'' '' '''All log commands''' - luckperms.log.*
  
=== 基础 ===
+
===== 基础 =====
  
 
* luckperms.sync
 
* luckperms.sync
第2,161行: 第2,176行:
 
* luckperms.listtracks
 
* luckperms.listtracks
  
=== 用户 ===
+
===== 用户 =====
  
 
* luckperms.user.info
 
* luckperms.user.info
第2,199行: 第2,214行:
 
* luckperms.user.clear
 
* luckperms.user.clear
  
=== 组 ===
+
===== 组 =====
  
 
* luckperms.group.info
 
* luckperms.group.info
第2,238行: 第2,253行:
 
* luckperms.group.clone
 
* luckperms.group.clone
  
=== 路线 ===
+
===== 路线 =====
  
 
* luckperms.track.info
 
* luckperms.track.info
第2,248行: 第2,263行:
 
* luckperms.track.clone
 
* luckperms.track.clone
  
=== 日志 ===
+
===== 日志 =====
  
 
* luckperms.log.recent
 
* luckperms.log.recent
第2,257行: 第2,272行:
 
* luckperms.log.grouphistory
 
* luckperms.log.grouphistory
 
* luckperms.log.trackhistory
 
* luckperms.log.trackhistory
 +
 +
===从其他插件迁移数据===
 +
LuckPerms 有内置的支持其他的权限插件轻松迁移到 LuckPerms 的功能。
 +
 +
==== 开始之前 ====
 +
 +
需要注意的是这个系统还不是那么的完美,在绝大多数情况下,它在转变数据时相当不错,但是不是所有的数据都是相同的,并且有时我可能没有考虑这么多。
 +
 +
LuckPerms 有和其他权限插件相同的地方,但是有些部分从根本上不同,有些迁移运用了一些技巧。
 +
 +
另外,让插件迁移你的所有的数据意味着你没有机会学习任何一个 LuckPerms 命令,这可能会是一个麻烦的地方,如果你是从 PermissionsEx 或者 GroupManager 迁移来的数据,你应该看看 [https://github.com/PluginsCDTribe/LuckPerms/wiki/GM-&-PEX-Command-Equivalents GM PEX 的等同命令]
 +
 +
如果你使用了老版本的权限插件,或者你根本不喜欢的,现在可能是一个机会来重新构建清理,顺便学习 LuckPerms 的命令!
 +
 +
不?!就喜欢你现在的权限插件?让我们来迁移。
 +
 +
==== 目前支持的插件 ====
 +
 +
{|
 +
! Bukkit / Spigot
 +
! BungeeCord
 +
! Sponge
 +
|-
 +
| GroupManager
 +
| BungeePerms
 +
| PermissionsEx
 +
|-
 +
| PermissionsEx
 +
|
 +
 +
| PermissionManager
 +
|-
 +
| zPermissions
 +
|
 +
 +
|
 +
 +
|-
 +
| PowerfulPerms
 +
|
 +
 +
|
 +
 +
|-
 +
| bPermissions
 +
|
 +
 +
|
 +
 +
|}
 +
 +
==== 怎么做 ===
 +
 +
迁移的处理很简单,但是每个平台可能有不同。
 +
 +
# 将 LuckPerms jar 文件放入你的服务器文件夹。
 +
# 保证两个权限插件的文件夹在同一个文件夹里(现在还不要卸载)
 +
# 开启服务器,你可以在活跃的服务器来进行这个操作,但是我建议在没有人的服务器上进行。
 +
 +
'''运行一下命令: <code>lp migration &lt;插件名&gt;</code>'''
 +
 +
有些插件需要你填写额外的选项/标签,如果需要,你会在迁移之前被通知。
 +
 +
接着只需要让 LuckPerms 处理剩下的事了!你将会被提示迁移进度,完成时也会被提示。
 +
 +
当处理完成,停止服务器,移除其他权限插件的 jar,再次开启你的服务器。
 +
 +
控制台的输出一定是冗长繁杂的,以 &quot;(LP) LOG&quot; 开头的命令都可以忽略,但是栈堆信息不应该忽略(一般表示出现了什么问题)。如果你的迁移输出含有栈堆信息,请反馈给我,更多的信息在这一个页面的底部。
 +
 +
===== PowerfulPerms =====
 +
 +
处理 PowerfulPerms 的过程更加复杂。
 +
 +
玩家的信息只有在加入服务器时才被加载,插件 API 没有方法一次性获得所有的玩家的数据。
 +
 +
这意味着我们在导入数据时,我们必须得查询 PowerfulPerms MySQL 表来获得所有玩家的信息。
 +
 +
命令使用将会不同。
 +
 +
<code>/luckperms migration powerfulperms [address] [database] [username] [password] [db table]</code>
 +
 +
解释: * address = MySQL 服务器的 IP 地址,比如 127.0.0.1:3306 * database = PowerfulPerms 插件使用的数据库的名称 * username = SQL 服务器登入需要的用户名 * password = SQL 服务器登入需要的密码 * db table = 存储玩家数据的表名(尽管我们只关注 UUID 列表)
 +
 +
默认的表名,据我所知,是 &quot;players&quot;,但是如果你添加了表名的前缀,你需要添加他们。
 +
 +
比如如果我的表的前缀是 &quot;pp_&quot;,那么 db table = &quot;pp_players&quot;(不需要引号)
 +
 +
比如: <code>/luckperms migration powerfulperms 127.0.0.1:3306 minecraft root passw0rd players</code>
 +
 +
==== 错误 ====
 +
 +
如果这个命令不存在,请检查这个插件是否正确加载。
 +
 +
如果处理没有完成,并且打印了错误消息,请在 GitHub 提交 issue 或者 [https://github.com/PluginsCDTribe/LuckPerms/wiki#cant-find-something 在这里联系我],我将尽力尽可能快的回复你。
 +
 +
===GM&PEX对应等效指令===
 +
我编写这部分WIKI内容的目的是为了帮助用户们适应从GM/PEX到LuckPerm的转变, 这里我制作了一份对应等效指令的表格,方便用户随时查阅。
 +
 +
==== Group Manager ====
 +
 +
{|
 +
! Group Manager 命令
 +
! LuckPerms 命令
 +
|-
 +
| manuadd &lt;玩家&gt; &lt;组&gt;
 +
| lp user &lt;玩家&gt; parent set &lt;组&gt;
 +
|-
 +
| manudel &lt;玩家&gt;
 +
| lp user &lt;玩家&gt; clear
 +
|-
 +
| manuaddsub &lt;玩家&gt; &lt;组&gt;
 +
| lp user &lt;玩家&gt; parent add &lt;组&gt;
 +
|-
 +
| manudelsub &lt;玩家&gt; &lt;组&gt;
 +
| lp user &lt;玩家&gt; parent remove &lt;组&gt;
 +
|-
 +
| manpromote &lt;玩家&gt; &lt;组&gt;
 +
| lp user &lt;玩家&gt; promote &lt;track&gt;
 +
|-
 +
| mandemote &lt;玩家&gt; &lt;组&gt;
 +
| lp user &lt;玩家&gt; demote &lt;track&gt;
 +
|-
 +
| manwhois &lt;玩家&gt;
 +
| lp user &lt;玩家&gt; info
 +
|-
 +
| manuaddp &lt;玩家&gt; &lt;权限&gt;
 +
| lp user &lt;玩家&gt; permission set &lt;权限&gt; true
 +
|-
 +
| manudelp &lt;玩家&gt; &lt;权限&gt;
 +
| lp user &lt;玩家&gt; permission unset &lt;权限&gt;
 +
|-
 +
| manulistp &lt;玩家&gt;
 +
| lp user &lt;玩家&gt; permission info
 +
|-
 +
| manucheckp &lt;玩家&gt; &lt;权限&gt;
 +
| lp user &lt;玩家&gt; haspermission &lt;权限&gt;
 +
|-
 +
| manuaddv &lt;玩家&gt; prefix &lt;值&gt;
 +
| lp user &lt;玩家&gt; meta addprefix &lt;优先级&gt; &lt;值&gt;
 +
|-
 +
| manuaddv &lt;玩家&gt; suffix &lt;值&gt;
 +
| lp user &lt;玩家&gt; meta addsuffix &lt;优先级&gt; &lt;值&gt;
 +
|-
 +
| manuaddv &lt;玩家&gt; &lt;变量&gt; &lt;值&gt;
 +
| lp user &lt;玩家&gt; meta set &lt;变量&gt; &lt;值&gt;
 +
|-
 +
| manudelv &lt;玩家&gt; &lt;变量&gt;
 +
| lp user &lt;玩家&gt; meta unset &lt;变量&gt;
 +
|-
 +
| manulistv &lt;玩家&gt;
 +
| lp user &lt;玩家&gt; meta info
 +
|-
 +
|
 +
 +
|
 +
 +
|-
 +
| mangadd &lt;组&gt;
 +
| lp creategroup &lt;组&gt;
 +
|-
 +
| mangdel &lt;组&gt;
 +
| lp deletegroup &lt;组&gt;
 +
|-
 +
| mangaddi &lt;组1&gt; &lt;组2&gt;
 +
| lp group &lt;组1&gt; parent add &lt;组2&gt;
 +
|-
 +
| mangdeli &lt;组1&gt; &lt;组2&gt;
 +
| lp group &lt;组1&gt; parent remove &lt;组2&gt;
 +
|-
 +
| listgroups
 +
| lp listgroups
 +
|-
 +
| mangaddp &lt;组&gt; &lt;权限&gt;
 +
| lp group &lt;组&gt; permission set &lt;权限&gt; true
 +
|-
 +
| mangdelp &lt;组&gt; &lt;权限&gt;
 +
| lp group &lt;组&gt; permission unset &lt;权限&gt;
 +
|-
 +
| manglistp &lt;组&gt;
 +
| lp group &lt;组&gt; permission info
 +
|-
 +
| mangcheckp &lt;组&gt; &lt;权限&gt;
 +
| lp group &lt;组&gt; haspermission &lt;权限&gt;
 +
|-
 +
| mangaddv &lt;玩家&gt; prefix &lt;值&gt;
 +
| lp group &lt;组&gt; meta addprefix &lt;优先级&gt; &lt;值&gt;
 +
|-
 +
| mangaddv &lt;玩家&gt; suffix &lt;值&gt;
 +
| lp group &lt;组&gt; meta addsuffix &lt;优先级&gt; &lt;值&gt;
 +
|-
 +
| mangaddv &lt;玩家&gt; &lt;变量&gt; &lt;值&gt;
 +
| lp group &lt;组&gt; meta set &lt;变量&gt; &lt;值&gt;
 +
|-
 +
| mangdelv &lt;玩家&gt; &lt;变量&gt;
 +
| lp group &lt;组&gt; meta unset &lt;变量&gt;
 +
|-
 +
| manglistv &lt;玩家&gt;
 +
| lp group &lt;组&gt; meta info
 +
|-
 +
|
 +
 +
|
 +
 +
|-
 +
| mansave
 +
| lp sync
 +
|-
 +
| manload
 +
| lp sync
 +
|}
 +
 +
==== PermissionsEx ====
 +
 +
{|
 +
!width="44%"| PermissionsEx 命令
 +
!width="55%"| LuckPerms 命令
 +
|-
 +
| pex
 +
| lp
 +
|-
 +
| pex reload
 +
| lp sync
 +
|-
 +
| pex toggle debug
 +
| lp verbose true
 +
|-
 +
| pex user &lt;用户&gt; check &lt;权限&gt;
 +
| lp user &lt;用户&gt; haspermission &lt;权限&gt;
 +
|-
 +
| pex backend
 +
| lp info
 +
|-
 +
| pex import &lt;backend&gt;
 +
| lp export &lt;file&gt; / lp import &lt;file&gt;
 +
|-
 +
| pex set default group &lt;组&gt;
 +
| (in the config file)
 +
|-
 +
|
 +
 +
|
 +
 +
|-
 +
| pex user &lt;用户&gt; list
 +
| lp user &lt;用户&gt; permission info
 +
|-
 +
| pex user &lt;用户&gt; prefix
 +
| lp user &lt;用户&gt; meta info
 +
|-
 +
| pex user &lt;用户&gt; prefix &lt;前缀&gt;
 +
| lp user &lt;用户&gt; meta addprefix &lt;优先级&gt; &lt;前缀&gt;
 +
|-
 +
| pex user &lt;用户&gt; suffix
 +
| lp user &lt;用户&gt; meta info
 +
|-
 +
| pex user &lt;用户&gt; suffix &lt;后缀&gt;
 +
| lp user &lt;用户&gt; meta addsuffix &lt;优先级&gt; &lt;后缀&gt;
 +
|-
 +
| pex user &lt;用户&gt; delete
 +
| lp user &lt;用户&gt; clear
 +
|-
 +
| pex user &lt;用户&gt; add &lt;权限&gt; &lt;世界&gt;
 +
| lp user &lt;用户&gt; permission set &lt;权限&gt; true global &lt;世界&gt;
 +
|-
 +
| pex user &lt;用户&gt; remove &lt;权限&gt; &lt;世界&gt;
 +
| lp user &lt;用户&gt; permission unset &lt;权限&gt; global &lt;世界&gt;
 +
|-
 +
| pex user &lt;用户&gt; timed add &lt;权限&gt; &lt;时间&gt; &lt;世界&gt;
 +
| lp user &lt;用户&gt; permission settemp &lt;权限&gt; true &lt;时间&gt; global &lt;世界&gt;
 +
|-
 +
| pex user &lt;用户&gt; timed remove &lt;权限&gt; &lt;时间&gt; &lt;世界&gt;
 +
| lp user &lt;用户&gt; permission settemp &lt;权限&gt; true &lt;时间&gt; global &lt;世界&gt;
 +
|-
 +
| pex user &lt;用户&gt; set &lt;option&gt; &lt;值&gt; &lt;世界&gt;
 +
| lp user &lt;用户&gt; meta set &lt;option&gt; &lt;值&gt; global &lt;世界&gt;
 +
|-
 +
|
 +
 +
|
 +
 +
|-
 +
| pex user &lt;用户&gt; group list
 +
| lp user &lt;用户&gt; parent info
 +
|-
 +
| pex user &lt;用户&gt; group add &lt;组&gt; &lt;世界&gt;
 +
| lp user &lt;用户&gt; parent add &lt;组&gt; global &lt;世界&gt;
 +
|-
 +
| pex user &lt;用户&gt; group add &lt;组&gt; &lt;世界&gt; &lt;时间&gt;
 +
| lp user &lt;用户&gt; parent addtemp &lt;组&gt; &lt;时间&gt; global &lt;世界&gt;
 +
|-
 +
| pex user &lt;用户&gt; group set &lt;组&gt;
 +
| lp user &lt;用户&gt; parent set &lt;组&gt;
 +
|-
 +
| pex user &lt;用户&gt; group remove &lt;组&gt; &lt;世界&gt;
 +
| lp user &lt;用户&gt; parent remove &lt;组&gt; global &lt;世界&gt;
 +
|-
 +
| pex groups list
 +
| lp listgroups
 +
|-
 +
| pex group &lt;组&gt; list
 +
| lp group &lt;组&gt; permission info
 +
|-
 +
| pex group &lt;组&gt; prefix
 +
| lp group &lt;组&gt; meta info
 +
|-
 +
| pex group &lt;组&gt; prefix &lt;前缀&gt;
 +
| lp group &lt;组&gt; meta addprefix &lt;优先级&gt; &lt;前缀&gt;
 +
|-
 +
| pex group &lt;组&gt; suffix
 +
| lp group &lt;组&gt; meta info
 +
|-
 +
| pex group &lt;组&gt; suffix &lt;后缀&gt;
 +
| lp group &lt;组&gt; meta addsuffix &lt;优先级&gt; &lt;后缀&gt;
 +
|-
 +
| pex group &lt;组&gt; create
 +
| lp creategroup &lt;组&gt;
 +
|-
 +
| pex group &lt;组&gt; delete
 +
| lp deletegroup &lt;组&gt;
 +
|-
 +
| pex group &lt;组&gt; parents list
 +
| lp group &lt;组&gt; parent info
 +
|-
 +
| pex group &lt;组&gt; parents set &lt;parents&gt;
 +
| lp group &lt;组&gt; parent add &lt;parent&gt;
 +
|-
 +
| pex group &lt;组&gt; add &lt;权限&gt; &lt;世界&gt;
 +
| lp group &lt;组&gt; permission set &lt;权限&gt; true global &lt;世界&gt;
 +
|-
 +
| pex group &lt;组&gt; remove &lt;权限&gt; &lt;世界&gt;
 +
| lp group &lt;组&gt; permission unset &lt;权限&gt; global &lt;世界&gt;
 +
|-
 +
| pex group &lt;组&gt; timed add &lt;权限&gt; &lt;时间&gt; &lt;世界&gt;
 +
| lp group &lt;组&gt; permission settemp &lt;权限&gt; true &lt;时间&gt; global &lt;世界&gt;
 +
|-
 +
| pex group &lt;组&gt; timed remove &lt;权限&gt; &lt;时间&gt; &lt;世界&gt;
 +
| lp group &lt;组&gt; permission settemp &lt;权限&gt; true &lt;时间&gt; global &lt;世界&gt;
 +
|-
 +
| pex group &lt;组&gt; set &lt;option&gt; &lt;值&gt; &lt;世界&gt;
 +
| lp group &lt;组&gt; meta set &lt;option&gt; &lt;值&gt; global &lt;世界&gt;
 +
|-
 +
|
 +
 +
|
 +
 +
|-
 +
| pex group &lt;组&gt; user add &lt;用户&gt;
 +
| lp user &lt;用户&gt; parent add &lt;组&gt;
 +
|-
 +
| pex group &lt;组&gt; user remove &lt;用户&gt;
 +
| lp user &lt;用户&gt; parent remove &lt;组&gt;
 +
|-
 +
| pex promote &lt;用户&gt; &lt;ladder&gt;
 +
| lp user &lt;用户&gt; promote &lt;ladder&gt;
 +
|-
 +
| pex demote &lt;用户&gt; &lt;ladder&gt;
 +
| lp user &lt;用户&gt; demote &lt;ladder&gt;
 +
|}
 +
 +
===常见问题===
 +
 +
这些是我经常被问到的问题,我很高兴你在直接问我之前看了这些问题。
 +
 +
==== 我在用 EssentialsChat 然后它不工作了 ====
 +
 +
请确保你在使用最新版的 [https://ci.drtshock.net/job/essentialsx/ EssentialsX] 并且你安装了 [https://dev.bukkit.org/bukkit-plugins/vault/ Vault]。EssentialsX 的 X 是很重要的,老的版本不会工作。
 +
 +
==== 我在哪里安装 LuckPerms 呢? ====
 +
 +
如果你在运行很多的服务器,你应该将 LuckPerms 放入每个服务器的 plugins 文件夹。
 +
 +
如果你想使用 BungeeCord 来应用权限,你需要将 LuckPermsBungee.jar 放入 BungeeCord 插件文件夹。
 +
 +
如果你选择只在 BungeeCord 安装 LuckPerms,他将不会影响任何 Spigot/Sponge 服务器的权限检查,如果你想要使用 LuckPerms,你必须将 LuckPerms 安装在这些服务器。
 +
 +
==== 我可以只在 BungeeCord 安装 LuckPerms 吗? ====
 +
 +
在 BungeeCord 上的权限系统是完全独立于 Spigot/Sponge 服务器的。
 +
 +
如果你想让 Spigot/Sponge 的权限检查被 LuckPerms 处理的话,在每个 Spigot/Sponge 服务器都安装 LuckPerms。
 +
 +
如果你想让 BungeeCord 服务器的权限检查被 LuckPerms 处理,在 BungeeCord 服务器安装 LuckPerms。
 +
 +
你可以'''只'''在 BungeeCord 安装 LuckPerms,但是 Spigot/Sponge 服务器的权限检查将不会被 LuckPerms 处理。
 +
 +
==== 我应该怎样在多个服务器中同步权限呢? ====
 +
 +
将每个 LuckPerms 连接到同一个 MySQL/MongoDB 服务器,你可以使用 /luckperms sync 来从数据库获得最后的权限更新。你也可以 [https://github.com/PluginsCDTribe/LuckPerms/wiki/Instant-Update-Propagation#messaging-services 建立一个通讯服务] 来立刻在你的服务器之间同步更改。
 +
 +
==== LuckPerms 不能连接到我的 Redis 服务器 ====
 +
 +
检查以下是否正常:
 +
 +
* 你正在使用正确的地址和端口
 +
* 你的密码是正确的
 +
* 没有防火墙规则阻拦了连接
 +
* Redis 服务器正在运行
 +
 +
==== LuckPerms 不能连接到我的 MySQL 服务器 ====
 +
 +
检查以下是否正常:
 +
 +
* 你正在使用正确的地址和端口
 +
* 你使用了正确的用户名 / 密码
 +
* 数据库存在并且用户可以访问
 +
* 该服务器在线并且接受连接
 +
* 没有防火墙规则阻拦了连接
 +
* MySQL 正确绑定了端口,并且安装 LuckPerms 的服务器可以访问
 +
* 检查 MySQL 的连接限制没有超过,默认 LuckPerms 会使用 10 个连接,如果你有过多的插件连接了同一个服务器,你需要增加这个限制。
 +
 +
如果你得到了 <code>Communications link failure</code> 的错误,或者由于超时导致的错误,那么上面的有一条是不正常的。
 +
 +
给玩家 LuckPerms 表的权限,使用
 +
 +
<source lang="sql">GRANT ALL PRIVILEGES ON [databasename].* TO '[username]'@'[ipaddress]';</source>
 +
记得替换 [ ] 里的东西。
 +
 +
比如:
 +
 +
<source lang="sql">GRANT ALL PRIVILEGES ON luckperms.* TO 'luck'@'%';</source>
 +
接着当你完成这个更改后,使用
 +
 +
<source lang="sql">FLUSH PRIVILEGES;</source>
 +
 +
==特性==
 +
===权限检查系统(Verbose)===
 +
你曾经经历过想要找到某条命令或某种特性的使用权限,但找不到作者提供的帮助文档这种情况吗?
 +
 +
可能作者提供的帮助文档过期了,或是内含的信息不正确。可能你想要修复玩家没有正确权限的问题,或是仅仅是对插件所检查的权限感兴趣……
 +
 +
权限检查系统能够让你监视一段时间内的权限检查操作!😄
 +
 +
==== 如何使用本系统 ====
 +
 +
指令的使用方法如下:
 +
 +
<code>/lp verbose &lt;on|record|off|paste&gt; [filter]</code>
 +
 +
第一个参数会启用/禁用本系统,第二个参数设置权限筛选器。
 +
 +
{|
 +
! 选项
 +
! 描述
 +
|-
 +
| <code>on</code>
 +
| 启用本系统,并且在设置的筛选权限被检查时会发消息提示您。
 +
|-
 +
| <code>record</code>
 +
| 与“on”的作用相同,但是您的聊天框不会收到提醒。
 +
|-
 +
| <code>off</code>
 +
| 会禁用本系统,清除内存中所有的存储记忆。
 +
|-
 +
| <code>paste</code>
 +
| 与“off”的作用相同,但是会将最先的500个结果上传到一个网页上,然后提供给你一个链接。
 +
|}
 +
 +
==== 筛选器 ====
 +
 +
筛选器是用来匹配权限节点的工具,它会过滤掉你不需要的权限。它可以筛选玩家名,或更高级的东西。
 +
 +
筛选器输入的字符能够匹配所有带有该字符的权限的开头,或是玩家的全名。
 +
 +
你可以使用 <code>&amp;</code> (表示 和), <code>|</code> (表示 或), 和 <code>!</code> (表示 非)来设置筛选文本,输入时也支持使用小括号 <code>(  )</code> 。
 +
 +
===== 一些使用示例 =====
 +
 +
* <code>Luck &amp; (essentials | worldedit)</code> —— 会匹配玩家“Luck”的所有以“essentials”或“worldedit”开头的权限检查
 +
* <code>Luck &amp; !anticheat</code> —— 会匹配玩家“Luck”所有不以“anticheat”为开头的权限检查
 +
* <code>anticheat &amp; !anticheat.check</code> —— 会匹配所有玩家以“anticheat”开头,但不是 &quot;anticheat.check&quot; 权限的权限检查
 +
 +
==== 示例 ====
 +
 +
我使用了指令 <code>/lp verbose record Luck &amp; minecraft</code>,这打开了权限检查系统,然后会检查 &quot;Luck&quot; 玩家所有以 &quot;minecraft&quot; 开头的权限。
 +
 +
然后我使用了 <code>/help</code> 命令(来让服务器对我进行权限检查),然后我输入了 <code>/lp verbose paste</code>。
 +
 +
然后插件就会将检查的结果上传,然后返回了这个链接。[https://git.io/vDUba <code>https://git.io/vDUba</code>]
 +
 +
如果你点开这个链接看看的话,你会看到检查的结果的。 😄
 +
 +
在Metadata数据信息下面,你会看到一些有关于检查的数据。
 +
 +
你可以注意到 <code>Count: 58 / 72</code>,这就是说在这段检查期间,共检查了72条权限,其中58条符合你设定的筛选器。
 +
 +
那些满足筛选器的检查结果已经列出来了。
 +
 +
=== 大量编辑 ===
 +
LuckPerms 提供了一个命令来帮助执行大量的权限编辑,这个命令应该小心使用,因为很容易破坏你的所有信息。
 +
 +
在执行这个命令之前做一个备份可能是个明智的选择,或者是给你的数据库做个备份,或者使用 export 命令。
 +
 +
命令的设计基于 SQL 格式,这意味着命令可以直接转换为一条 SQL 查询语句,或者在 YAML 或者 JSON 文本编辑。那些对 SQL 语句有经验的人可能会发现在数据库服务器直接写入查询比使用命令更简单。
 +
 +
这些命令'''只能在控制台使用'''。这是因为这些命令可能会对你的服务器造成极大的伤害。在执行之前,你会被要求输入一个确认码,用于防止 &quot;sudo&quot; 来通过这些命令获得权限。
 +
 +
命令用法如下...
 +
 +
<code>/lp bulkupdate &lt;data type&gt; &lt;action&gt; [action field] [action value] [constraint...]</code>
 +
 +
一开始有点令人害怕,我知道,拆开来看...
 +
 +
{|
 +
! 参数
 +
! 描述
 +
|-
 +
| <code>data type</code>
 +
| 更改的数据 (可以是 &quot;all&quot;, &quot;users&quot; 或者 &quot;groups&quot;)
 +
|-
 +
| <code>action</code>
 +
| 对数据执行的操作 (可以是 &quot;update&quot; 或者 &quot;delete&quot;)
 +
|-
 +
| <code>action field</code>
 +
| 只可用于 update 操作 (可以是 &quot;permission&quot;, &quot;server&quot; 或 &quot;world&quot;)
 +
|-
 +
| <code>action value</code>
 +
| 替换的值,只可用于 update 操作
 +
|-
 +
| <code>constraint</code>
 +
| update 的约束
 +
|}
 +
 +
<code>data type</code> 是最简单的,只是简单的告诉了 LuckPerms 这个操作应该影响什么数据。
 +
 +
<code>action</code> 是对数据执行的操作。可以是 &quot;update&quot; 或 &quot;delete&quot;。delete 就是简单的删除满足约束的所有的记录。Update 将会将原来的值替换为新的值。
 +
 +
<code>action field</code> 和 <code>action value</code> 参数是可选的,因为只对 update 有效。field 是用来更新的东西,而 value 是用来替换的东西。
 +
 +
<code>constraints</code> 参数与 update 的限制有关,只有权限(或者条目)匹配约束才会被影响。
 +
 +
==== 约束 ====
 +
 +
约束分为 3 部分,<code>field</code>, <code>comparison</code> 和 <code>value</code>。
 +
 +
可用的 <code>fields</code> 是 <code>permission</code>, <code>server</code> 和 <code>world</code>。权限就只是存储在文件中的权限节点(记住甚至组的关系和前缀都是存储在前缀的)。server 和 world 与 permission 应用的世界和服务器有关。如果权限没有他们的值,那么就是全局。
 +
 +
<code>value</code> 部分的约束是需要的 field,用于比较。
 +
 +
有四种比较的方式。
 +
 +
{|
 +
! 比较符号
 +
! 比较的名称
 +
! 描述
 +
|-
 +
| <code>==</code>
 +
| 等于
 +
| 两个值相同(忽略大小写)
 +
|-
 +
| <code>!=</code>
 +
| 不等于
 +
| 两个值不相同(忽略大小写)
 +
|-
 +
| <code>~~</code>
 +
| 相似
 +
| 两个值相似,与SQL的 <code>LIKE</code> 关键字相同
 +
|-
 +
| <code>!~</code>
 +
| 不相似
 +
| 两个值不相似,与SQL的 <code>LIKE</code> 关键字相同
 +
|}
 +
 +
更多的有关相似的信息可以在[https://www.w3schools.com/sql/sql_like.asp 这里]和[https://www.tutorialspoint.com/sql/sql-like-clause.htm 这里]找到。
 +
 +
基础的大概是这样的: * <code>%</code> - 百分号代表 0 到多个字符 * <code>_</code> - 下划线代表一个字符
 +
 +
===== 一些示例 =====
 +
 +
* <code>server ~~ hub_</code> 匹配 &quot;hub1&quot;, &quot;hub2&quot;, &quot;hub3&quot; 等
 +
* <code>permission !~ group.%</code> 匹配任何不以 group 开头的权限
 +
* <code>world == nether</code> 匹配世界名为 nether
 +
 +
当在命令中使用约束,必须使用 <code>&quot; &quot;</code> 引号包围。
 +
 +
==== 命令示例 ====
 +
 +
<code>/lp bulkupdate all update permission group.mod &quot;permission == group.moderator&quot;</code>
 +
 +
更新所有的条目,替换所有的 &quot;group.moderator&quot; 为 &quot;group.mod&quot;(效率重命名)。
 +
 +
<code>/lp bulkupdate user delete &quot;server ~~ hub%&quot; &quot;world == nether&quot;</code>
 +
 +
删除任何分配给以 &quot;hub&quot; 开头的服务器,并且世界是 &quot;nether&quot; 的玩家的权限。
 +
 +
<code>/lp bulkupdate all delete &quot;permission == essentials.fly&quot;</code>
 +
 +
删除所有 &quot;essentials.fly&quot; 的权限
 +
 +
<code>/lp bulkupdate all update server global &quot;server == factions&quot;</code>
 +
 +
更改所有服务器 &quot;factions&quot; 条目为 &quot;global&quot;。
 +
 +
希望你理解了这个意思,如果你不确定如何构建一个你想要应用的命令,请随意使用 Wiki 主界面的联系方式联系我。
 +
 +
=== 即时更新权限变更 ===
 +
 +
==== 介绍 ====
 +
 +
如果你在群组服务器上运行LuckPerms的话,有时你会遇到这样的问题——你在一个服务器上做下了更改,但是这更改不会“传播”到你网络中的其他服务器中。
 +
 +
这一页就是教你怎么修复这个问题的。
 +
 +
当然,如果你只有一个服务器运行LuckPerms插件,或是你的服务器不使用普通的储存方法(连接到一个相同的数据库)的话,你不需要看这些。
 +
 +
==== 同步间隔 ====
 +
 +
你能够设置同步间隔,这会执行能够不断重复获得存储系统内的数据的任务。
 +
 +
本选项默认的值是 '''-1''' (也就是说默认是禁用的)
 +
 +
<pre class="yml">data:
 +
 +
  ...
 +
 +
#此选项控制 LuckPerms 多长时间进行一次同步任务。
 +
 +
#同步任务将会刷新存储中的所有信息,保证插件使用的是最新的数据。
 +
 +
#这个选项默认关闭,因为大多数的用户都是不需要这个功能的,但是如果你使用远程存储,又没有设置信息服务,那么你可能将其设置为像 3 这样的数值。
 +
 +
#设置为 -1 来完全停用这个任务。
 +
  sync-minutes: -1</pre>
 +
你能够将这个值改成你想要的。
 +
 +
==== 监视文件 ====
 +
 +
如果你使用以文件为基础的存储类型的话(JSON或YAML),LuckPerms能够监视那些数据文件的更改,然后自动检测是否做出了改变。
 +
 +
<pre class="yml">#当使用基于文件的存储系统,LuckPerms将会监视数据文件的变化,并在文件变化被检测到的时候自动规划更新数据、
 +
 +
#如果不想让这个发生,那么将此选项设置为 false。
 +
watch-files: true</pre>
 +
这也就是说你只要更改一个数据文件就好了,然后按下保存按钮,然后你的更改就会被应用到整个群组服中了。
 +
 +
==== /lp sync ====
 +
 +
<code>/lp sync</code> 命令能够强制让插件执行一次上述提到的更新任务。
 +
 +
能够从数据库或文件读取最新的数据信息。
 +
 +
这个命令对于使用文件储存来说也是很有用的,因为它能够请求更新。
 +
 +
==== 信息传递服务 ====
 +
 +
在更改设定之后,你可以使用 <code>/lp networksync</code> 命令来让群组服中所有其他服务器应用更改。
 +
 +
==== 当前支持 ====
 +
 +
{|
 +
! 服务
 +
! 描述
 +
|-
 +
| Bungee
 +
| 使用插件所提供的信息传递隧道来在你的BungeeCord网络中传递更改
 +
|-
 +
| Lilypad
 +
| 使用 LilyPad 的连接子服系统来在你的LilyPad网络中传递更改
 +
|-
 +
| Redis
 +
| 使用 Redis Pub Sub 来在所有连接的服务器中传递更改
 +
|}
 +
 +
===== Bungee =====
 +
 +
<pre class="yml">messaging-service: bungee</pre>
 +
你必须在你的代理服务器上安装LuckPerms插件,然后将上述的设置在所有配置文件中都启用。本选项不支持跨BungeeCord代理服务器传递信息,在这种情况下你应该使用Redis群组服。
 +
 +
===== LilyPad =====
 +
 +
<pre class="yml">messaging-service: lilypad</pre>
 +
你需要在你的服务器上安装 <code>LilyPad-Connect</code> 插件。
 +
 +
===== Redis =====
 +
 +
<pre class="yml">messaging-service: redis
 +
 +
# Settings for Redis.
 +
# Port 6379 is used by default; set address to &quot;host:port&quot; if differs
 +
redis:
 +
  enabled: true
 +
  address: localhost
 +
  password: ''</pre>
 +
你需要按照你服务器的实际情况来设置你的Redis群组服相关设置,然后在redis小节填写你的服务器的地址和密码。
 +
 +
请确保你的防火墙设置设置地恰当,来防止你的Redis群组服拒绝访问。
 +
 +
=== 切换存储 & 备份 ===
 +
==== 如何做 ====
 +
 +
切换存储是很简单的。
 +
 +
# 第一,运行 <code>/luckperms export &lt;file&gt;</code>
 +
# 接着,完全停止你的服务器
 +
# 编辑你的配置文件,更改存储类型
 +
# 开启你的服务器,等待数据存储的初始化
 +
# 接着,使用 <code>/luckperms import &lt;file&gt;</code>
 +
# 所有的数据已经迁移到新的数据存储中了
 +
 +
<file> 是你想用来存储/加载的文件的名称,文件位于 LuckPerms 的数据文件夹里。你可以任意命名,只要在 import 命令中正确填写。
 +
 +
==== 备份 ====
 +
 +
你可以使用这个特性来备份所有你的 LuckPerms 的数据,只需要运行 export 命令,将文件保存到一个安全的地方。
 +
 +
==== 这是怎么工作的? ====
 +
 +
export 命令将所有的数据转换为一串命令,处理后将会重建你的安装,import 命令只是将每个命令运行一遍,这意味着你可以只导出/导入一小部分数据,你删掉不需要的一部分就可以了。
 +
 +
=== 权限组路线 ===
 +
 +
虽然其他一些插件也提供了一些相似的功能,LuckPerms 插件拥有它自己独特的权限组路线系统。
 +
 +
请将“权限组路线”试做一种“梯子”或“晋升路线”。
 +
 +
==== 示例 1 ====
 +
 +
我创建了一个叫做“staff”的权限组路线,这权限树包括以下组:
 +
 +
'''default :arrow_right: helper :arrow_right: mod :arrow_right: admin'''
 +
 +
然后我就能使用权限组路线来为玩家升级或降级。
 +
 +
例如,玩家“Notch”在helper权限组里,我想将他升到“mod”组,我需要运行
 +
 +
<code>/luckperms user Notch promote staff</code>
 +
 +
==== 示例 2 ====
 +
 +
我又为赞助商新建了一个权限组路线,包括以下组:
 +
 +
'''default :arrow_right: iron :arrow_right: gold :arrow_right: diamond'''
 +
 +
当玩家购买了“权限组提升”这类的东西时,我能使用权限组路线为玩家晋升权限等级。
 +
 +
<code>/luckperms user Luck promote donator</code>
 +
 +
要想让玩家在某条权限组路线中降级的话,请使用降级命令。
 +
 +
==== 创建权限组路线 ====
 +
 +
请运行 <code>/luckperms createtrack &lt;name&gt;</code> 命令,然后使用 <code>/luckperms track &lt;name&gt; append &lt;group&gt;</code> 来将权限组加入路线中。
 +
 +
帮助编辑路线的命令也还有几条,你可以在命令使用页面找到。
 +
 +
=== 前缀,后缀与元数据 ===
 +
这教程包括如何使用LuckPerms插件设置和管理玩家的前缀,后缀以及元数据。
 +
 +
如果你已经对这些概念很熟悉了,或是只想查看本插件如何实现更改,你应该阅读[https://github.com/lucko/LuckPerms/wiki/Command-Usage#meta---lp-user-user-meta---lp-group-group-meta- 命令使用] 页面的 “section” 小节。
 +
 +
==== 关键术语 ====
 +
 +
===== 前缀/后缀 =====
 +
 +
Minecraft服务器上的前缀和后缀代指你聊天用户名前后的文本。
 +
 +
举个例子,在下列的聊天中:
 +
 +
<pre>[Admin] Luck the great: Hello!</pre>
 +
玩家的前缀是<code>&quot;[Admin] &quot;</code>部分,玩家的后缀是<code>&quot; the great&quot;</code>部分。
 +
 +
===== 元数据 =====
 +
 +
有时元数据指“选项”或“变量”,元数据是跟权限组有关的额外数据部分。与权限不同的是,元数据分成两部分,一部分是“关键字”,另一部分是“值”。
 +
 +
关键字就是元数据的名字,值就是关键字所代表的数据。
 +
 +
举个例子,我的用户有下列的元数据,这元数据代表我最多能设置5个家,然后我的用户名应该是蓝色的。
 +
 +
<pre>max-homes = 5
 +
username-color: blue</pre>
 +
==== 是谁提供了对这些的支持? ====
 +
 +
一般来说,提供服务器管理权限的插件就有能够让你设置,管理和储存玩家的前缀,后缀和元数据的功能,这对于LuckPerms插件来说也一样。、
 +
 +
有时,提供这些设置的权限插件也能够直接在游戏中应用这些值。但是这对于LuckPerms来说不是它能做到的任务,你需要安装另一款额外的插件来在游戏聊天中应用,关于这点我们稍后详述。
 +
 +
==== 前缀/后缀/元数据是怎么存储的 ====
 +
 +
LuckPerms 插件将前缀和后缀转换成权限节点来存储。你可能会注意到当你给一位用户或一个权限组添加权限的恶化,他们的权限信息中会多出一条跟你设置的值相同的权限数据。为什么要这样做呢?好的,从编程的角度来说,让所有东西都储存在一个地方,用相同的格式,这样做更简单。这也意味着你能够简单的更改前缀和后缀,就像你改权限的方式一样。
 +
 +
前缀和后缀分成了两部分 * '''Weight''' —— 这是决定着前缀和后缀优先级的数值,较大的数代表着较大的优先级。 * '''Value''' —— 这是真正的前缀的值。
 +
 +
例如一个叫做 &quot;[Admin] &quot; 的前缀,优先级设置为100,转换成权限就是: <code>&quot;prefix.100.[Admin] &quot;</code>。
 +
 +
对于元数据来说所使用的系统也相似,元数据组合 <code>favourite-color = red</code> ,转换成权限就是:<code>&quot;meta.favourite-color.red&quot;</code>.
 +
 +
==== 前缀和后缀的优先级是怎么工作的 ====
 +
 +
前缀和后缀和权限一样,也能够继承。这意味着LuckPerms插件需要决定,当需要显示前缀或后缀时,真正为玩家显示哪一个。
 +
 +
当另外一款插件请求玩家的前缀或后缀时,LuckPerms插件会: * 收集玩家的所有前缀与后缀,包括继承的 * 根据他们的优先级来进行分类,高的优先级数值代表高的优先级 * 然后决定出最高优先级的前缀或后缀来为玩家展示
 +
 +
如果发现了两个相同优先级的前缀或后缀的话,最接近于用户的那一个会被使用,接近的意思就是插件在搜索继承数据时最先找到的那一个。
 +
 +
==== 我怎么为玩家设置前缀或后缀 ====
 +
 +
举个例子,如果我想让admin权限组的玩家拥有 &quot;&amp;c[Admin] &quot; 前缀,在mod权限组的玩家拥有 &quot;&amp;d[Mod] &quot; 前缀的话,我需要运行:
 +
 +
* /lp creategroup admin
 +
* /lp creategroup mod
 +
* /lp group admin parent add mod
 +
* /lp group admin meta addprefix 100 &quot;&amp;c[Admin] &quot;
 +
* /lp group mod meta addprefix 90 &quot;&amp;d[Mod] &quot;
 +
 +
然后如果我决定想要将admin用户组的称号改为使用 &quot;&amp;4&quot; 这个颜色代码的话,要想删除之前设定的值,我需要运行: * /lp group admin meta removeprefix 100
 +
 +
这会将所有设定给admin权限组的,优先级为100的前缀全部移除,然后我就能重新设置新的前缀值了。
 +
 +
对于临时设定用户前缀或后缀的方法和增加临时权限或临时权限组的方法差不多。
 +
 +
所有的权限使用方法可以在[https://github.com/lucko/LuckPerms/wiki/Command-Usage#meta---lp-user-user-meta---lp-group-group-meta- '''权限使用页面''']找到。增加和移除元数据的方法也列在了那里。
 +
 +
==== 我怎么查看一位玩家或一个用户组所有的前缀或后缀 ====
 +
 +
解决前缀或后缀相关问题最简单的方式就是使用info命令。
 +
 +
举个例子: <code>/lp user Luck meta info</code>。这会将用户所有的前缀,后缀和元数据,以及继承的相关信息列举出来。
 +
 +
按照优先级来排序,所以你就能很清楚的看到目前应用的值是哪一个。
 +
 +
另外一条有趣的命令就是玩家的全局信息命令: <code>/lp user Luck info</code>。
 +
 +
如果玩家在服务器上在线的话,这会直接给你展示所提供给要读取LuckPerms信息的插件的前缀或后缀。
 +
 +
==== 展示前缀和后缀 ====
 +
 +
就像早些时候提到的那样,LuckPerms插件不会为你处理任何的聊天格式相关信息。
 +
 +
你需要安装额外的插件来做到这个。
 +
 +
下面为你列出了一些推荐的聊天管理插件。
 +
 +
===== Bukkit/Spigot =====
 +
 +
LuckPerms 目前已经支持'''所有'''能够从 [https://dev.bukkit.org/projects/vault Vault] 插件读取信息的聊天管理插件了。
 +
 +
你需要在你的服务器上安装Vault来让其工作。
 +
 +
如果你发现某款插件所获取的数据不正确的话,请确保 <code>/vault-info</code> 插件输出的信息展示的数据是从LuckPerms插件处读取的。
 +
 +
一些较为受欢迎的,且支持Vault的聊天管理插件包括: * [https://ci.drtshock.net/job/EssentialsX/ EssentialsXChat] —— 原来的Essentials插件的升级复刻版本。(“X” 是很重要的!) * [https://dev.bukkit.org/projects/chatex ChatEx] * [https://www.spigotmc.org/resources/deluxechat.1277/ DeluxeChat] —— 你能够使用Vault或LuckPerms所提供的Placeholder变量。 * [https://www.spigotmc.org/resources/10258/ ChatControl] —— 也支持其他选项的设置来帮助管理聊天。
 +
 +
列举出所有可用的插件没有任何意义,再说一遍,所有支持Vault的聊天管理插件都支持LuckPerms!
 +
 +
===== BungeeCord ======
 +
 +
* [https://github.com/lucko/gChat gChat] (我写的 :wink:)
 +
* [https://www.spigotmc.org/resources/multichat.26204/ MultiChat]
 +
* [https://www.spigotmc.org/resources/bungee-chat.12592/ BungeeChat]
 +
 +
===== Sponge =====
 +
 +
* [http://nucleuspowered.org/ Nucleus] —— 就像是“Essentials”一样的插件,包括 [http://nucleuspowered.org/docs/modules/chat.html 聊天管理模块].
 +
 +
 +
=== 前缀与后缀的堆叠 ===
 +
==== 这个功能能做什么? ====
 +
 +
“元数据堆叠”特性能够让你在玩家聊天中同时展示多个前缀或后缀。
 +
 +
你仍需要安装聊天管理类型的插件。
 +
 +
==== 它怎么工作? ====
 +
 +
当聊天管理类插件请求要获取玩家的前缀或后缀时,取代返回玩家最高优先级的称号,LuckPerms能够应用一些你设定的规则来一起输出多个前缀或后缀。
 +
 +
默认的设置看起来是这样:
 +
 +
<pre class="yml">meta-formatting:
 +
  prefix:
 +
    format:
 +
      - &quot;highest&quot;
 +
    start-spacer: &quot;&quot;
 +
    middle-spacer: &quot; &quot;
 +
    end-spacer: &quot;&quot;
 +
  suffix:
 +
    format:
 +
      - &quot;highest&quot;
 +
    start-spacer: &quot;&quot;
 +
    middle-spacer: &quot; &quot;
 +
    end-spacer: &quot;&quot;</pre>
 +
这些当前配置意味着,当请求前缀或后缀的时候,会返回最高优先级的那一个。
 +
 +
==== 我怎么增加其他元素? ====
 +
 +
当前支持以下元素。
 +
 +
{|
 +
! 元素
 +
! 描述
 +
|-
 +
| <code>highest</code>
 +
| 从玩家拥有或继承的数据中选择最高优先级的值
 +
|-
 +
| <code>lowest</code>
 +
| 和上面的工作原理相同,但是它会选择最低优先级的值
 +
|-
 +
| <code>highest_own</code>
 +
| 选择最高优先级的值,但不支持继承来的值
 +
|-
 +
| <code>lowest_own</code>
 +
| 和上面的工作原理相同,但是它会选择最低优先级的值
 +
|-
 +
| <code>highest_on_track_&lt;track&gt;</code>
 +
| 选择继承于给予的权限组路线中的权限组所提供的最高优先级的值
 +
|-
 +
| <code>lowest_on_track_&lt;track&gt;</code>
 +
| 和上面的工作原理相同,但是它会选择最低优先级的值
 +
|-
 +
| <code>highest_not_on_track_&lt;track&gt;</code>
 +
| 选择不继承于给予的权限组路线中的权限组所提供的最高优先级的值
 +
|-
 +
| <code>lowest_not_on_track_&lt;track&gt;</code>
 +
| 和上面的工作原理相同,但是它会选择最低优先级的值
 +
|}
 +
 +
==== 一个示例 ====
 +
 +
例如,在一个监狱服务器中,你可能有3种类型的权限组,一种是玩家“gameplay”权限组,一种是赞助商权限组,一种是管理员权限组。
 +
 +
如果玩家在三个组中,我想要展示三个前缀,举个例子: <code>[Mine C] [Donor] [Admin] Luck: hi!</code>.
 +
 +
但是如果玩家不在管理员权限组中,我想展示: <code>[Mine C] [Donor] Luck: hi</code>.
 +
 +
使用堆叠系统这些都可以实现。每个堆叠中的“元素”都需要添加到格式节内。
 +
 +
<pre class="yml">prefix:
 +
  format:
 +
    - &quot;highest_on_track_prison&quot;
 +
    - &quot;highest_on_track_donor&quot;
 +
    - &quot;highest_on_track_staff&quot;
 +
  start-spacer: &quot;&quot;
 +
  middle-spacer: &quot; &quot;
 +
  end-spacer: &quot;&quot;</pre>
 +
如果玩家在该元素中没有对应的值的话,它就会被堆叠系统自动无视。
 +
 +
你可以控制每个元素在开头,中间和结尾的分隔符,举个例子:
 +
 +
<code>yml  prefix:    format:      - &quot;highest_on_track_prison&quot;      - &quot;highest_on_track_donor&quot;      - &quot;highest_on_track_staff&quot;    start-spacer: &quot;★ &quot;    middle-spacer: &quot; | &quot;    end-spacer: &quot; &quot;</code>
 +
 +
... 这样的聊天结果会是: <code>★ [Mine C] | [Donor] | [Admin] Luck: hi</code>.
 +
 +
显然你可以使用你的聊天管理插件来改变这些值,那些插件也会提供相似的选项。
 +
 +
=== 高级设置 ===
 +
==== 简介 ====
 +
 +
LuckPerm总体来说虽然是相对简单的.. 你可以利用插件的一些特点与内部规则来制定一个适合你服务器情况的高等权限系统!
 +
 +
==== 分服务器权限&分世界权限 ====
 +
 +
LuckPerm本来是针对群组服的情况来工作的, 但是你可以自定义一些只在特定子服/特定世界才生效的权限。
 +
 +
===== 配置中一些重要的选项说明 ====
 +
 +
<pre class="yml"># The name of the server, used for server specific permissions. Set to 'global' to disable.
 +
server: global</pre>
 +
该项为设置服务器的名称,如果要想设置特定服务器的权限,则需要通过修改server项来命名服务器。 如果你愿意,同一个群组服是可以一起使用相同的服务器名的。
 +
 +
<pre class="yml"># If users on this server should have their global permissions/groups applied.
 +
include-global: true</pre>
 +
include-global选项也是非常重要的。
 +
 +
LuckPerm有两种体现方式,一是特定服务器的权限,二则是直接应用全局权限设置。
 +
 +
如果这个选项被设置为 false,只有指定在此服务器的权限才会被应用。
 +
 +
如果上方的 &quot;server&quot; 选项设置为 global,请不要将其设置为 '''false'''。更多的有关服务器指定的权限可以在这里找到。 通过编辑更改这两个选项,你可以灵活的为每个服务器的权限组/权限做出意想不到的配合效果
 +
 +
==== 示例 ====
 +
 +
===== 示例 1 =====
 +
 +
<pre class="yml">server: global
 +
include-global: true</pre>
 +
* /luckperms user Luck set minecraft.command.gamemode true '''将应用'''
 +
* /luckperms user Luck set minecraft.command.gamemode true factions '''不应用'''
 +
 +
===== 示例 2 =====
 +
 +
<pre class="yml">server: lobby
 +
include-global: true</pre>
 +
* /luckperms user Luck set minecraft.command.gamemode true '''将应用'''
 +
* /luckperms user Luck set minecraft.command.gamemode true lobby '''将应用'''
 +
 +
===== 示例 3 =====
 +
 +
<pre class="yml">server: bungeecord
 +
include-global: false</pre>
 +
* /luckperms user Luck set minecraft.command.gamemode true '''不应用'''
 +
* /luckperms user Luck set bungeecord.command.alert true bungeecord '''将应用'''
 +
 +
===== 示例 4 =====
 +
 +
<pre class="yml">server: global
 +
include-global: false</pre>
 +
'''没有任何权限将会应用!'''
 +
 +
如果没有设置服务器名字(server项设置为global)且全局设置未开启(include-global项设置为flase), 将不会有任何权限可以应用到服务器上!
 +
 +
==== 权限计算 ====
 +
 +
===== 权限是根据优先级进行计算的,如下所示 =====
 +
 +
* '''服务器特定的权限是会覆盖通用/全局权限设置的'''
 +
 +
例如:有一个玩家,我们姑且叫他海螺,他拥有一个全局的“fly.use”(允许飞行)权限, 然后在“factions”这个服务器上,取消了“fly.use”权限,服务器的特定权限设置将会覆盖全局设置。 即,这个海螺在“factions”服务器上是无法使用“fly.use”权限的,他就不能够上天了, 前提是海螺现在正在“factions”服务器上。
 +
 +
* '''世界特定的权限也是会覆盖通用/全局权限设置的'''
 +
 +
例如:上文我们说的玩家“海螺”,他现在任然有一个全局的“fly.use”权限, 然后在“world_nether”(地狱)世界,取消了“fly.use”权限,世界的特定权限设置将会覆盖全局设置。 即,这个海螺在地狱就无法上天了(只要海螺在地狱世界)。
 +
 +
* '''临时权限将会覆盖非临时权限'''
 +
 +
例如:如果玩家海螺本来关闭了一个权限“test.node”, 以此为基础,服务器给海螺设置新的临时权限“test.node”, 海螺的临时权限则会覆盖本身关闭的权限,即海螺会在特定时间(临时权限)获得“test.node”权限。
 +
 +
* '''如果同时有两个节点相同、但时长不同的临时权限,时间较长的会覆盖时间较短的'''
 +
* '''更加具体的通配符权限将覆盖不具体的通配符权限'''
 +
 +
例如:一个用户拥有权限“luckperms.''”并且设置为true,但是“luckperms.user.''”权限却设置为false, 那么所有玩家的权限都将被设置为false! 因为尽管“luckperm.''”有更加通用的通配符,但是他没有“luckperms.user.''”具体。
 +
 +
* '''继承权限将由对象自己的权限来重写'''
 +
 +
例如:一个玩家是默认权限组的成员,默认权限组有“some.thing.perm”权限, 但是这个玩家又被以用户形式给予了权限“some.thing.perm”, 继承而来的权限将会被玩家自己的权限给覆盖。
 +
 +
==== 临时权限 ====
 +
 +
临时权限每间隔3s会检查一遍,检查临时权限的时限是否到期, 不论同步间隔设置的怎么样,这个检查都会照常工作,这意味着你可以安全的设置临时权限在几秒后过期, 他们将会在时限到期时被删除。
 +
 +
==== 速记权限 ====
 +
 +
LuckPerms有他自己的速记权限系统,在这一点上,它非常类似PermissionsEx, 它允许你使用速记格式来设置权限。
 +
 +
===== 示例 =====
 +
 +
====== 示例 1 ======
 +
 +
使用LuckPerm的允许节点来作为例子,比如说,你想让一个用户组与用户权限设置/取消允许节点,
 +
 +
如果没有速记,你就必须键入下面四个节点。
 +
 +
<pre>luckperms.user.setpermission
 +
luckperms.user.unsetpermission
 +
luckperms.group.setpermission
 +
luckperms.group.unsetpermission</pre>
 +
但是,你要是使用速记,你就可以应用以下节点:
 +
 +
<code>luckperms.(user|group).(setpermission|unsetpermission)</code>
 +
 +
你可以使用括号来让一个节点成为一个速记的权限组,然后用 <code>|</code> 来分隔他们
 +
 +
====== 示例 2 ======
 +
 +
你可以使用“-”来创建字符范围,如果没有使用速记,则必须键入以下四个节点:
 +
 +
<pre>coolkits.kit.a
 +
coolkits.kit.b
 +
coolkits.kit.c
 +
coolkits.kit.d</pre>
 +
然而,使用了速记方法,你只需应用下面的节点:
 +
 +
<code>coolkits.kit.(a-d)</code>
 +
 +
====== 示例 3 ======
 +
 +
你可以使用“-”来创建字符范围,如果没有使用速记,则必须键入以下四个节点:
 +
 +
<pre>prisonmines.teleport.1
 +
prisonmines.teleport.2
 +
prisonmines.teleport.3
 +
prisonmines.teleport.4</pre>
 +
不过,你只要使用速记方法,这一切都会变得简单许多!你只需要应用下面的节点:
 +
 +
<code>prisonmines.teleport.(1-4)</code>
 +
 +
==== 正则表达式 ====
 +
 +
LuckPerms支持使用正则表达式来定义权限节点与服务器/世界的名字, 当使用正则表达式的时候,必须添加前缀“R=”。 所以LuckPerm才会知道将它是作为正则表达式来输出,而不是作为普通的字符串来输出。
 +
 +
例如:你希望玩家可以创建两个组与权限系(tracks),通常只需要添加两个权限节点。 然而使用正则表达式,你只需要添加一个权限节点 <code>luckperms\.create.*</code> 。 记住,转为任何字符,例如一个点,都将作为一个节点被系统解析。
 +
 +
=== 默认组 ===
 +
 +
我在 LuckPerms 里处理默认和默认组的方法可能是整个插件里最不受喜爱的特性了。最新我做了一些添加/调整,做了一些替代的特性,允许最大程度的控制像其他权限插件的方法,希望这会成为插件最好的方面,而不是最差的方面。
 +
 +
==== 从何开始 ====
 +
 +
这是我的想法。
 +
 +
你的服务器的用户可以分为两种。
 +
 +
# 基础玩家
 +
# 加入不同的组的玩家,或者有他们特别权限的玩家。
 +
 +
你不希望浪费宝贵的硬盘空间来存储第一种玩家,你只希望存储你的职员,或者有特殊等级的玩家。平凡的&quot;成员&quot;就只是平凡,没有必要存储他们的信息。
 +
 +
下一个问题是如何确定一个用户是&quot;平凡的&quot;或不是,想象一下情景。
 +
 +
# 默认的组设置为&quot;默认&quot;,当玩家加入,他们被设置为&quot;默认&quot;,并被保存。
 +
# 过了一会儿,你想将默认的组更改为&quot;成员&quot;。
 +
# 接着你的老的成员全部在&quot;默认&quot;组里,剩下的人都在&quot;成员&quot;,这不好。
 +
 +
甚至我们没有&quot;平凡&quot;的用户,这个问题依然会出现。
 +
 +
# 默认组设置为&quot;默认&quot;
 +
# 你想给 &quot;Notch&quot; 一个特殊的 &quot;essentials.fly&quot; 权限,Notch 的权限被保存,标记为&quot;默认组&quot;的成员,有特殊的飞行权限。
 +
# 接着你编辑了默认的组,所有的&quot;平凡的&quot;成员全部进入了新的组,但是 Notch 还是默认组的。
 +
 +
因为这个原因,我让默认的组不可配置,这让所有对我的事情都简单了 10 倍,这意味着我可以写有效率的存储系统,并且不用担心一些稀有的情况下服务器的管理员更改了默认组,但是,我知道这对一些人很反感。
 +
 +
这对一些等级插件也有问题,如果你想要一个&quot;主&quot;组,并且分离&quot;升级&quot;组,你需要多于一个的默认组。
 +
 +
这里是你的选项。
 +
 +
==== 继续使用默认组,但是只是更改显示名 ====
 +
 +
我非常推荐这个做法,因为你继续使用默认组。
 +
 +
如果你只是想简单的更改默认组的显示名,(比如在 Vault),我推荐你配置一个 <code>group-name-rewrite</code> 规则,通过添加这些到你的 <code>config.yml</code>/<code>luckperms.conf</code> 来实现。
 +
 +
<pre class="yml"># Rewrites group names. The underlying name of the group does not change, just the output in commands / placeholders / Vault.
 +
group-name-rewrite:
 +
  default: Member</pre>
 +
你也可以使用这个:https://github.com/lucko/LuckPerms/wiki/Primary-Groups
 +
 +
==== 配置继承 ====
 +
 +
这个选项意味着所有的用户都还在&quot;默认&quot;的组里,但是这个默认组作为父组,这样他就可以将配置继承给不同的组。
 +
 +
<pre>/luckperms creategroup member
 +
/luckperms group default parents add member</pre>
 +
 +
==== 配置默认分配 ====
 +
 +
如果你有更多的特殊需要,你可以使用这个选项,但是,这将否定我们在这个页面的第一节讨论的存储空间规划,所有的用户都会被存储,无论是&quot;平凡的&quot;成员还是不是。
 +
 +
===== 注意:查看 Default Assignments 章节 =====
 +
 +
接下来的规则将会创建一个不同的默认的组。
 +
 +
<pre class="yml">default-assignments:
 +
  my-defaults-rule:
 +
    if:
 +
      has-true: &lt;group.default&gt;
 +
    take:
 +
      - group.default
 +
    give:
 +
      - group.member
 +
    set-primary-group: member</pre>
 +
放入以后,每次玩家登入时,插件会检测这个玩家是不是&quot;默认&quot;组的成员,如果是,插件将会把玩家从&quot;默认&quot;组移除,将他们添加至&quot;成员&quot;组,将他们的主组也设置为&quot;成员&quot;组。
 +
 +
这个系统非常强力,允许你配置按你自己的需求而定的默认组,记住你可以将玩家添加至不止一个的&quot;默认&quot;组。
 +
 +
== 开发者 ==
 +
=== 开发者 API ===
 +
==== 简介 ====
 +
 +
LuckPerms API 允许你更改大量的插件内部编程,并且能够轻松地将 LuckPerms 深度集成到你的插件和系统里。
 +
 +
大多数的其他的权限要么没有 API,要么有很差的 API,或者是有很差的文档的 API,而且里面的方法和类可能随机在不同版本里消失或是移动。Vault 项目就是一个很好的接口,并且是将大量插件一次性集成的很好的方法,可惜他的功能实在是太少了。
 +
 +
LuckPerms 遵循 Semantic 版本控制,也就是意味着一个不向后兼容的新的 API 出现时,主版本会增加这个 API,你可以放心你的集成不会因为版本的不同而崩溃,主要的版本是保持不变的。
 +
 +
==== 如何在项目里使用 API ====
 +
 +
LuckPerms 的 API 包是 [https://github.com/lucko/LuckPerms/tree/master/api/src/main/java/me/lucko/luckperms <code>me.lucko.luckperms.api</code>]
 +
 +
我的 Nexus 服务器可以在这里找到 https://nexus.lucko.me/,你在你的构建脚本里需要的仓库在 https://repo.lucko.me/
 +
 +
==== 其他有用的链接 ====
 +
 +
* [https://luckperms.lucko.me/javadocs/ JavaDocs]
 +
* [https://ci.lucko.me/job/LuckPerms/ CI Server]
 +
 +
==== Maven ====
 +
 +
<source lang="xml"><repositories>
 +
    <repository>
 +
        <id>luck-repo</id>
 +
        <url>https://repo.lucko.me/</url>
 +
    </repository>
 +
</repositories>
 +
 +
<dependencies>
 +
    <dependency>
 +
        <groupId>me.lucko.luckperms</groupId>
 +
        <artifactId>luckperms-api</artifactId>
 +
        <version>3.2</version>
 +
        <scope>provided</scope>
 +
    </dependency>
 +
</dependencies></source>
 +
==== Gradle ====
 +
 +
<pre class="gradle">repositories {
 +
    maven {
 +
        name &quot;luck-repo&quot;
 +
        url &quot;https://repo.lucko.me/&quot;
 +
    }
 +
}
 +
 +
dependencies {
 +
    compile (&quot;me.lucko.luckperms:luckperms-api:3.2&quot;)
 +
}</pre>
 +
==== 使用指南 ====
 +
 +
使用 API,你需要获得 LuckPermsApi 接口的实例,这可以通过几个方法完成。
 +
 +
<source lang="java">// 所有平台 (抛出 IllegalStateException 如果 API 没有被加载)
 +
final LuckPermsApi api = LuckPerms.getApi();
 +
 +
// 或者可选的
 +
Optional<LuckPermsApi> provider = LuckPerms.getApiSafe();
 +
if (provider.isPresent()) {
 +
    final LuckPermsApi api = provider.get();
 +
}
 +
 +
// Bukkit/Spigot
 +
ServicesManager manager = Bukkit.getServicesManager();
 +
if (manager.isProvidedFor(LuckPermsApi.class)) {
 +
    final LuckPermsApi api = manager.getRegistration(LuckPermsApi.class).getProvider();
 +
}
 +
 +
// Sponge
 +
Optional<LuckPermsApi> provider = Sponge.getServiceManager().provide(LuckPermsApi.class);
 +
if (provider.isPresent()) {
 +
    final LuckPermsApi api = provider.get();
 +
}</source>
 +
===== 线程安全的警告 =====
 +
 +
所有 LuckPerms 内部,包括 API 都是线程安全的,你可以在异步线程任意调用 API 而不用担心发生错误。
 +
 +
但是,请注意一些操作,(尤其是存储类)是阻塞的。[https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html CompletableFuture] 就是用于这种情况:防止由于较差的处理导致的增加的错误,当出现 IO 时主线程等待处理完成。注意在添加 Callback 时指定正确的处理器。
 +
 +
===== 我想将 LuckPerms 作为依赖项 =====
 +
 +
在 Bukkit/Bungee,你需要在你的 plugin.yml 添加以下信息
 +
 +
<pre class="yml">depend: [LuckPerms]</pre>
 +
在 Sponge, 在你的插件声明添加这些。
 +
 +
<source lang="java">@Plugin(
 +
        id = "myplugin",
 +
        dependencies = {
 +
                @Dependency(id = "luckperms")
 +
        }
 +
)
 +
public class MyPlugin {
 +
    ...
 +
}</source>
 +
===== 事件 =====
 +
 +
LuckPerms 有一个完整的读写API,也有一个事件监听系统。由于插件的多平台的原因,我们使用了内部的事件系统,而不是每个平台已经使用的事件系统(举个例子,Bukkit Event API)。这意味着简单的注册你的平台的监听器将不会生效。
 +
 +
所有的事件都是'''异步触发'''的。这意味着不应该在监听器里交互或者调用任何不是线程安全的方法。
 +
 +
值得注意的是,大多数的 Bukkit/Sponge 都不是线程安全的,并且只应该使用主服务器线程来交互。你应该使用调度器来访问 LuckPerms 的监听器。
 +
 +
===== 我怎样才能监听一个事件 =====
 +
 +
所有的事件接口都可以在 [https://github.com/lucko/LuckPerms/tree/master/api/src/main/java/me/lucko/luckperms/api/event me.lucko.luckperms.api.event] 包里找到,它们都继承了 [https://github.com/lucko/LuckPerms/blob/master/api/src/main/java/me/lucko/luckperms/api/event/LuckPermsEvent.java LuckPermsEvent] 类。
 +
 +
监听事件应该获得 [https://github.com/lucko/LuckPerms/blob/master/api/src/main/java/me/lucko/luckperms/api/event/EventBus.java EventBus] 实例,使用 [https://github.com/lucko/LuckPerms/blob/master/api/src/main/java/me/lucko/luckperms/api/LuckPermsApi.java#L68 LuckPermsApi#getEventBus]即可。
 +
 +
为你的监听器创建另一个类常常是个好想法,这是一个你可以用来参考的类。
 +
 +
<source lang="java">package me.lucko.test;
 +
 +
import me.lucko.luckperms.api.event.EventBus;
 +
import me.lucko.luckperms.api.event.log.LogPublishEvent;
 +
import me.lucko.luckperms.api.event.user.UserLoadEvent;
 +
import me.lucko.luckperms.api.event.user.track.UserPromoteEvent;
 +
 +
public class TestListener {
 +
    private final MyPlugin plugin;
 +
 +
    public TestListener(MyPlugin plugin, LuckPermsApi api) {
 +
        this.plugin = plugin;
 +
 +
        EventBus eventBus = api.getEventBus();
 +
 +
        // use a lambda
 +
        eventBus.subscribe(LogPublishEvent.class, e -> e.getCancellationState().set(true));
 +
        eventBus.subscribe(UserLoadEvent.class, e -> {
 +
            System.out.println("User " + e.getUser().getName() + " was loaded!");
 +
            if (e.getUser().hasPermission("some.perm", true)) {
 +
                // Do something
 +
            }
 +
        });
 +
 +
        // use a method reference
 +
        eventBus.subscribe(UserPromoteEvent.class, this::onUserPromote);
 +
    }
 +
 +
    private void onUserPromote(UserPromoteEvent event) {
 +
        Bukkit.getScheduler().runTask(plugin, () -> {
 +
            Bukkit.broadcastMessage(event.getUser().getName() + " was promoted to" + event.getGroupTo().get() + "!");
 +
 +
            Player player = Bukkit.getPlayer(event.getUser().getUuid());
 +
            if (player != null) {
 +
                player.sendMessage("Congrats!");
 +
            }
 +
        });
 +
    }
 +
 +
}</source>
 +
[https://github.com/lucko/LuckPerms/blob/master/api/src/main/java/me/lucko/luckperms/api/event/EventBus.java#L43 EventBus#subscribe] 返回一个 [https://github.com/lucko/LuckPerms/blob/master/api/src/main/java/me/lucko/luckperms/api/event/EventHandler.java EventHander] 实例,可以用来在插件停止的时候取消注册监听器。
 +
 +
==== 示例用法 ====
 +
 +
下面就是一些简短的实例,使用了一些基本的 API 功能。
 +
 +
===== 获得玩家的组 =====
 +
 +
如果你只是想找到一个玩家的组,我非常建议你使用以下的方法(你甚至不需要使用 API)。
 +
 +
<source lang="java">public static String getPlayerGroup(Player player, List<String> possibleGroups) {
 +
    for (String group : possibleGroups) {
 +
        if (player.hasPermission("group." + group)) {
 +
            return group;
 +
        }
 +
    }
 +
    return null;
 +
}</source>
 +
记住将你的组排列为优先级的顺序(比如组长在前,成员在后)。
 +
 +
===== 为一个玩家添加权限 =====
 +
 +
<source lang="java">LuckPermsApi api = null; // See above for how to get the API instance.
 +
 +
Optional<User> user = api.getUserSafe(uuid);
 +
if (!user.isPresent()) {
 +
    return false; // The user isn't loaded in memory.
 +
}
 +
 +
// Build the permission node we want to set
 +
Node node = api.getNodeFactory().newBuilder(permission).setValue(true).build();
 +
 +
// Set the permission, and return true if the user didn't already have it set.
 +
try {
 +
    user.get().setPermission(node);
 +
 +
    // Now we need to save the user back to the storage
 +
    api.getStorage().saveUser(u);
 +
 +
    return true;
 +
} catch (ObjectAlreadyHasException e) {
 +
    return false;
 +
}</source>
 +
===== 为(可能的)离线玩家添加权限 =====
 +
 +
CompletionStage API 可以用来轻松交互插件的存储,查看[https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletionStage.html 这里] 和 [https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html 这里] 来查看这两个类的详细信息。
 +
 +
<source lang="java">LuckPermsApi api = null; // See above for how to get the API instance.
 +
 +
// load the user in from storage. we can specify "null" for their username,
 +
// since it's unknown to us.
 +
api.getStorage().loadUser(uuid, "null").thenComposeAsync(success -> {
 +
    // loading the user failed, return straight away
 +
    if (!success) {
 +
        return CompletableFuture.completedFuture(false);
 +
    }
 +
   
 +
    // get the user instance, they're now loaded in memory.
 +
    User user = api.getUser(uuid);
 +
 +
    // Build the permission node we want to set
 +
    Node node = api.getNodeFactory().newBuilder(permission).setValue(true).build();
 +
 +
    // Set the permission, and return true if the user didn't already have it set.
 +
    try {
 +
        user.setPermission(node);
 +
       
 +
        // now we've set the permission, but still need to save the user data
 +
        // back to the storage.
 +
       
 +
        // first save the user
 +
        return api.getStorage().saveUser(user)
 +
                .thenCompose(b -> {
 +
                    // then cleanup their user instance so we don't create
 +
                    // a memory leak.
 +
                    api.cleanupUser(user);
 +
                    return CompletableFuture.completedFuture(b);
 +
                });
 +
       
 +
    } catch (ObjectAlreadyHasException e) {
 +
        return CompletableFuture.completedFuture(false);
 +
    }
 +
   
 +
}, api.getStorage().getAsyncExecutor());</source>
 +
===== 获得玩家的前缀 =====
 +
 +
LuckPerms 有一个(复杂的)缓存系统,用于非常快速的权限/信息查询。这些类都在 API 里,并且可以在可能的地方使用。
 +
 +
<source lang="java">LuckPermsApi api = null; // See above for how to get the API instance.
 +
 +
// Get the user, or null if they're not loaded.
 +
User user = api.getUserSafe(uuid).orElse(null);
 +
if (user == null) {
 +
    return Optional.empty(); // The user isn't loaded. :(
 +
}
 +
 +
// Now get the users "Contexts". This is basically just data about the players current state.
 +
// Don't worry about it too much, just know we need it to get their cached data.
 +
Contexts contexts = api.getContextForUser(user).orElse(null);
 +
if (contexts == null) {
 +
    return Optional.empty();
 +
}
 +
 +
// Ah, now we're making progress. We can use the Contexts to get the users "MetaData". This is their cached meta data.
 +
MetaData metaData = user.getCachedData().getMetaData(contexts);
 +
 +
// MetaData#getPrefix returns null if they have no prefix.
 +
return metaData.getPrefix();</source>
 +
===== 获得玩家请求的权限 =====
 +
 +
我们也可以使用这个缓存系统来获得一个包含用户权限的 Map 实例,包含了基础的权限查询。
 +
 +
<source lang="java">// All retrieved in the same way as shown above.
 +
User user;
 +
Contexts contexts;
 +
 +
PermissionData permissionData = user.getCachedData().getPermissionData(contexts);
 +
Map<String, Boolean> data = permissionData.getImmutableBacking();</source>
 +
===== 寻找权限 =====
 +
 +
你可以使用 Java 8 的流轻松过滤并返回一个用户请求的权限
 +
 +
<source lang="java">public boolean hasPermissionStartingWith(UUID uuid, String startingWith) {
 +
    // Get the user, if they're online.
 +
    Optional<User> user = api.getUserSafe(uuid);
 +
 +
    // If they're online, perform the check, otherwise, return false.
 +
    return user.map(u -> u.getPermissions().stream()
 +
            .filter(Node::getValue)
 +
            .filter(Node::isPermanent)
 +
            .filter(n -> !n.isServerSpecific())
 +
            .filter(n -> !n.isWorldSpecific())
 +
            .anyMatch(n -> n.getPermission().startsWith(startingWith))
 +
    ).orElse(false);
 +
}</source>
 +
===== 创建新的组并分配权限 =====
 +
 +
这个方法不是阻塞的,所以可以安全的在主线程调用,一旦操作完成,回调会异步运行。
 +
 +
<source lang="java">api.getStorage().createAndLoadGroup("my-new-group").thenAcceptAsync(success -> {
 +
    if (!success) {
 +
        return;
 +
    }
 +
 +
    Group group = api.getGroup("my-new-group");
 +
    if (group == null) {
 +
        return;
 +
    }
 +
 +
    Node permission = api.buildNode("test.permission").build();
 +
 +
    try {
 +
        group.setPermission(permission);
 +
    } catch (ObjectAlreadyHasException ignored) {}
 +
 +
    // Now save the group back to storage
 +
    api.getStorage().saveGroup(group);
 +
}, api.getStorage().getAsyncExecutor());</source>
 +
==== 版本控制 ====
 +
 +
在 2.0 版本里,LuckPerms 遵循了 Semantic 版本控制。
 +
 +
唯一不同的是 patch 号不包含在任何地方,除了 pom,并且每次构建都会计算,基于上次提交后的提交数量。(每个新的小版本都会创建新的标签)
 +
 +
这意味着 API 版本不再有 patch 号(在 patch 里没有 API 的变化),API 版本会是 x.y,每个不同的 LuckPerms 构建都会遵循 x.y.z。
 +
 +
===== 变更日志 =====
 +
 +
* 版本 2.x 保持了几个月的稳定,没有任何向后不兼容的变更,但是在之后的版本里很多的方法变为弃用状态,并且事件 API 的确应该重写一遍。
 +
* 版本 3.x 包含了以下的向后不兼容的变化。 https://gist.github.com/PluginsCDTribe/fdf6ae4b2d9e466d8103dd9c68e5db9e
 +
 +
== 其他 ==
 +
=== 语言文件 ===
 +
LuckPerms 插件中所有的消息(包括颜色和格式代码)都能够修改。(似乎合情合理)
 +
 +
将下面的文件之一下载然后存储到LuckPerms的文件夹中,然后命名为 '''&quot;lang.yml&quot;'''。
 +
 +
将文件中的消息文本改成你喜欢的样子,然后重启你的服务器就好了。
 +
 +
==== 语言文件 ====
 +
 +
* [https://github.com/lucko/LuckPerms/blob/master/.locale/en_US.yml '''en_US''' - 英语]
 +
* [https://github.com/lucko/LuckPerms/blob/master/.locale/es_ES.yml '''es_ES''' - 西班牙语]
 +
* [https://github.com/lucko/LuckPerms/blob/master/.locale/ru_RU.yml '''ru_RU''' - 俄语]
 +
* [https://github.com/lucko/LuckPerms/blob/master/.locale/zh-CN.yml '''zh-CN''' - 简体中文]
 +
* [https://github.com/lucko/LuckPerms/blob/master/.locale/pl_PL.yml '''pl_PL''' - 波兰语]
 +
 +
==== 为翻译做贡献 ====
 +
 +
如果你翻译了语言文件,然后提交回工程的话,我(和其他使用本插件的人)会很高兴的,因为其他使用者会受益。
 +
 +
上面的 &quot;en_US&quot; 语言文件应作为翻译的标准,你只能修改文本消息的值,关键字应保留原样。
 +
 +
==== 附:简体中文语言文件 ====
 +
<pre>
 +
# LuckPerms Language File
 +
# Locale: zh-CN (Simplified Chinese)
 +
# Author: EuropeJing
 +
 +
prefix: "&7&l[&b&lL&3&lP&7&l] &c"
 +
log-info: "&7&l[&bL&3P&7&l] &3{0}"
 +
log-warn: "&7&l[&bLuck&3Perms&7&l] &c[警告] {0}"
 +
log-error: "&7&l[&bLuck&3Perms&7&l] &4[错误] {0}"
 +
empty: "{0}"
 +
player-online: "&a在线"
 +
player-offline: "&c离线"
 +
loading-error: "无法加载权限数据,请稍后再试."
 +
op-disabled: "&b此服务器上禁用了vanilla OP系统."
 +
op-disabled-sponge: "&2服务器管理员状态在安装权限插件时无效,请直接编辑用户数据."
 +
log: "&3日志 &3&l> {0}"
 +
export-log: "&3输出 &3&l> &f{0}"
 +
export-log-progress: "&3输出 &3&l> &7{0}"
 +
migration-log: "&3移动 &7[&3{0}&7] &3&l> &f{1}"
 +
migration-log-progress: "&3移动 &7[&3{0}&7] &3&l> &7{1}"
 +
command-not-recognised: "命令未被识别."
 +
command-no-permission: "你没有权限使用这个命令!"
 +
already-haspermission: "{0}已经有这个权限!"
 +
does-not-havepermission: "{0}没有这个命令的权限."
 +
already-has-temp-permission: "{0}已经设置此临时权限!"
 +
does-not-have-temp-permission: "{0}没有设置此临时权限."
 +
user-not-found: "&b找不到用户."
 +
user-not-online: "&b用户&a{0}&b不在线."
 +
user-no-data: "&b没有加载用户&a{0}&b任何数据."
 +
user-save-success: "&7(保存用户数据到文件)"
 +
user-save-error: "保存用户数据时出错."
 +
user-create-fail: "创建新用户时出错."
 +
group-not-found: "&b找不到组."
 +
group-save-success: "&7(保存组数据到文件)"
 +
group-save-error: "保存组数据时出错."
 +
track-not-found: "&b无法找到轨道."
 +
track-save-success: "&7(保存轨道到文件)"
 +
track-save-error: "保存轨道时出错."
 +
user-invalid-entry: "&d{0}&c不是有效的用户名/uuid."
 +
group-invalid-entry: "组名只能包含字母数字字符."
 +
track-invalid-entry: "轨道名称只能包含字母数字字符."
 +
server-invalid-entry: "服务器名称只能包含字母数字字符."
 +
use-inherit-command: "使用'parent add'和'parent remove'命令,而不是指定节点."
 +
verbose-invalid-filter: "&c无效的详细过滤器: &f{0}"
 +
verbose-on: "&b所有权限的详细输出设置为&a开&b."
 +
verbose-on-query: "&b将匹配过滤器:&f{0}&b的权限详细输出设置为&a开&b."
 +
verbose-off: "&b所有权限的详细输出设置为&c关&b."
 +
verbose-recording-on: "&b所有权限的详细记录设置为&a开&b."
 +
verbose-recording-on-query: "&b将匹配过滤器:&f{0}&b的权限详细记录设置为&a开&b."
 +
verbose-recording-upload-start: "&b详细记录被禁用. 正在上传结果..."
 +
verbose-recording-url: "&a详细结果的网址:"
 +
tree-upload-start: "&b生成权限树..."
 +
tree-empty: "&a无法生成树,没有找到结果."
 +
tree-url: "&a权限树网址:"
 +
search-searching: "&a使用&b{0}&a搜索用户和组..."
 +
search-searching-members: "&a正在搜索继承自&b{0}&a的用户和组..."
 +
search-result: "&a从&b{1}&a用户和&b{2}&a组找到&b{0}&a个条目."
 +
search-showing-users: "&b显示用户条目:"
 +
search-showing-groups: "&b显示组条目:"
 +
search-showing-users-with-page: "&b显示用户条目: {0}"
 +
search-showing-groups-with-page: "&b显示组条目: {0}"
 +
check-result: "&a用户&b{0}&a获得允许&b{1}&a权限的检查结果&a: &f{2}"
 +
create-success: "&b{0}&a成功创建."
 +
delete-success: "&b{0}&a成功删除."
 +
rename-success: "&b{0}&a成功被重命名为&b{1}&a."
 +
clone-success: "&b{0}&a被成功地复制到了&b{1}&a."
 +
already-inherits: "{0}已经继承'{1}'."
 +
does-not-inherit: "{0}已不继承'{1}'."
 +
already-temp-inherits: "{0}已临时继承'{1}'."
 +
does-not-temp-inherit: "{0}不会临时继承'{1}'."
 +
track-already-contains: "轨道{0}已经包含组'{1}'."
 +
track-does-not-contain: "轨道{0}不包含组'{1}'."
 +
track-ambiguous-call: "指定的用户是此轨道上多个组的成员,无法确定他们的位置."
 +
group-already-exists: "该组已存在!"
 +
group-does-not-exist: "组不存在!"
 +
group-load-error: "发生意外错误,组未加载."
 +
groups-load-error: "发生意外错误,无法加载所有组."
 +
track-already-exists: "轨道已存在!"
 +
track-does-not-exist: "轨道不存在!"
 +
track-load-error: "发生意外错误. 轨道未加载."
 +
tracks-load-error: "出现意外错误,无法加载所有轨道."
 +
track-empty: "轨道不能使用,因为它是空的或只包含一个组."
 +
update-task-request: "&b更新任务计划."
 +
update-task-complete: "&a更新任务完成."
 +
update-task-complete-network: "&a更新任务完成,现在尝试推送到其他服务器."
 +
update-task-push-success: "&a其他服务器通过&b{0}成功通知."
 +
update-task-push-failure: "&c将更改推送到其他服务器时出错."
 +
update-task-push-failure-not-setup: "&c将更改推送到其他服务器时出错,未配置消息传递服务."
 +
reload-config-success: "&a重新加载配置文件. &7(一些选项将仅在服务器重新启动后才应用.)"
 +
info: >
 +
  {PREFIX}&2运行 &bLuckPerms v{0}&2 by &bLuck&2.\n
 +
  {PREFIX}&f-  &3平台: &f{1}\n
 +
  {PREFIX}&f-  &3存储方式: &f{2}\n
 +
  {PREFIX}&f-  &3服务器名称: &f{3}\n
 +
  {PREFIX}&f-  &3同步间隔: &a{4} &f分钟\n
 +
  {PREFIX}&f-  &3消息服务: &f{5}\n
 +
  {PREFIX}&f-  &b统计:\n
 +
  {PREFIX}&f-    &3在线玩家: &a{6}\n
 +
  {PREFIX}&f-    &3加载用户: &a{7}\n
 +
  {PREFIX}&f-    &3加载组: &a{8}\n
 +
  {PREFIX}&f-    &3加载轨道: &a{9}\n
 +
  {PREFIX}&f-    &3日志大小: &a{10}\n
 +
  {PREFIX}&f-    &3UUID缓存大小: &a{11}\n
 +
  {PREFIX}&f-    &3翻译加载: &a{12}\n
 +
  {PREFIX}&f-    &3预处理环境: &a{13}\n
 +
  {PREFIX}&f-    &3环境计算器: &a{14}\n
 +
  {PREFIX}&f-    &3唯一权限: &a{15}\n
 +
  {PREFIX}&f-  &b配置:\n
 +
  {PREFIX}&f-    &3使用服务器UUIDs: {16}\n
 +
  {PREFIX}&f-    &b权限计算:\n
 +
  {PREFIX}&f-        &3包括全部: {17}\n
 +
  {PREFIX}&f-        &3包括全部世界: {18}\n
 +
  {PREFIX}&f-        &3应用全部组: {19}\n
 +
  {PREFIX}&f-        &3应用全部世界组: {20}\n
 +
  {PREFIX}&f-        &3应用通配符: {21}\n
 +
  {PREFIX}&f-        &3应用正则表达式: {22}\n
 +
  {PREFIX}&f-        &3应用速记: {23}
 +
create-group-error: "创建组时出错."
 +
delete-group-error: "删除组时出错."
 +
delete-group-error-default: "您不能删除默认组."
 +
groups-list: "&aGroups: {0}"
 +
create-track-error: "创建轨道时出错."
 +
delete-track-error: "删除轨道时出错."
 +
tracks-list: "&a轨道: {0}"
 +
listnodes: "&b{0}的节点:"
 +
listnodes-with-page: "&b{0}的节点:  {1}"
 +
listnodes-temp: >
 +
  &b{0}的临时节点:\n
 +
  {1}
 +
listparents: >
 +
  &b{0}的父组:\n
 +
  {1}
 +
listparents-temp: >
 +
  &b{0}的临时父组:\n
 +
  {1}
 +
listgroups: >
 +
  &b{0}的组:\n
 +
  {1}
 +
listgroups-temp: >
 +
  &b{0}的临时组:\n
 +
  {1}
 +
list-tracks: >
 +
  &b{0}的轨道:\n
 +
  {1}
 +
list-tracks-empty: "{0}不在任何轨道上."
 +
context-pair-inline: "&3{0}=&b{1}"
 +
context-pair--global-inline: "&e全局"
 +
context-pair-end: "&a."
 +
context-pair-sep: "&a, "
 +
context-pair: "&8(&7{0}=&f{1}&8)"
 +
check-permission: "&b在环境&b{3}&b中,&b{0}&b的权限&b{1}&b被设置为&b{2}&b."
 +
check-permission-inherited: "&b{0}&a在环境&b{3}&a中的&b{1}&a被设置为&b{2}&a,继承自&b{4}&a."
 +
setpermission-success: "&a在&b{3}&a中为&b{2}&a设置&b{0}&a为&b{1}&a."
 +
setpermission-temp-success: "&a在环境&b{4}&a将&b{0}&a的&b{2}&a设为&b{1}&a,持续时间&b{3}&a."
 +
unsetpermission-success: "&a在环境&b{2}&a中取消&b{1}&a的&b{0}&a."
 +
unset-temp-permission-success: "&a在环境&b{2}&a中取消设置&b{1}&a的临时许可&b{0}&a."
 +
set-inherit-success: "&b{0}&a现在在环境&b{2}&a中继承&b{1}&a的权限&a."
 +
set-temp-inherit-success: "&b{0}&a现在在环境&b{3}&a中继承&b{1}&a的权限,持续时间&b{2}&a."
 +
set-parent-success: "&b{0}&a现有的父组被清除,现在只在&b{2}&a中继承&b{1}&a."
 +
unset-inherit-success: "&b{0}&a不再继承环境&b{2}&a中的&b{1}&a权限."
 +
unset-temp-inherit-success: "&b{0}&a在环境{2}中不再临时从&b{1}&a继承权限."
 +
clear-success: "&b{0}&a的权限被清除. (&b{1}&a节点被删除.)"
 +
clear-success-singular: "&b{0}&a的权限被清除. (&b{1}&a节点已被删除.)"
 +
parent-clear-success: "&b{0}&a的组被清除. (&b{1}&a节点被删除.)"
 +
parent-clear-success-singular: "&b{0}&a的组被清除. (&b{1}&a节点已被删除.)"
 +
meta-clear-success: "&b{0}&a的父组被清除. (&b{1}&a节点被删除.)"
 +
meta-clear-success-singular: "已经清除了这个&b{0}&a的元数据. (&b{1}&a节点已被删除.)"
 +
illegal-date-error: "无法解析日期'{0}'."
 +
past-date-error: "您不能设定一个过去的日期!"
 +
chat-meta-prefix-header: "&b{0}的前缀"
 +
chat-meta-suffix-header: "&b{0}的后缀"
 +
meta-header: "&b{0}的元信息"
 +
chat-meta-entry: "&b-> {0} &f- &f\"{1}&f\" &8(&7继承自&a{2}&8)"
 +
chat-meta-entry-with-context: "&b-> {0} &f- &f\"{1}&f\" &8(&7继承自&a{2}&8){3}"
 +
meta-entry: "&b-> &a{0} &f= &f\"{1}&f\" &8(&7继承自&a{2}&8)"
 +
meta-entry-with-context: "&b-> &a{0} &f= &f\"{1}&f\" &8(&7继承自&a{2}&8){3}"
 +
chat-meta-prefix-none: "&b{0}没有前缀."
 +
chat-meta-suffix-none: "&b{0}没有后缀."
 +
meta-none: "&b{0}没有元信息."
 +
meta-invalid-priority: "优先级'{0}'无效. 应该是一个数字."
 +
already-has-chat-meta: "{0}已经设置了{1}."
 +
does-not-have-chat-meta: "{0}没有设置{1}."
 +
add-chatmeta-success: "&b{0}&a在环境&b{4}&a中将优先级&b{3}&a设置为 {1} &f\"{2}&f\"."
 +
add-temp-chatmeta-success: "&b{0}&a在环境&b{5}&a中,设置为优先级&b{3}&a的{1} &f\"{2}&f\"&a,持续时间为&b{4}&a."
 +
remove-chatmeta-success: "&b{0}&a在&b{3}&a中删除了优先级&b{3}&a的{1} &f\"{2}&f\"&a."
 +
bulk-remove-chatmeta-success: "&b{0}&a had all {1}es at priority &b{3}&a removed in context {4}&a."
 +
remove-temp-chatmeta-success: "&b{0}&a在环境&b{4}&a中删除了优先级&b{3}&a的临时{1} &f\"{2}&f\"&a."
 +
bulk-remove-temp-chatmeta-success: "&b{0}&a在环境&b{4}&a中移除了优先级&b{3}&a的所有临时&b{1}&a.."
 +
already-has-meta: "{0}已经有了这个元信息集."
 +
set-meta-success: "将环境&b{3}&a中的&b{2}&a的键&f\"{0}&f\"&a的元信息设置为&f\"{1}&f\"&a."
 +
set-meta-temp-success: "&a在环境&b{4}&a中将&b{2}&a的键&f\"{0}&f\"&a的值设置为&f\"{1}&f\"&a,持续时间为&b{3}&a."
 +
unset-meta-success: "&a在环境{2}中取消设置&b{1}&a的键&f\"{0}&f\"&a的元信息."
 +
unset-meta-temp-success: "&a在环境{2}中取消设置&b{1}&a的键&f\"{0}&f\"&a的临时元信息."
 +
bulk-update-invalid-data-type: "Invalid type. Was expecting 'all', 'users' or 'groups'."
 +
bulk-update-invalid-constraint: "无效的约束&4{0}&c.约束的格式应该是'&f<field> <comparison operator> <value>&c'."
 +
bulk-update-invalid-comparison: "比较运算符无效'&4{0}&c'. 应该以下之一: &f==  !=  ~~  ~!"
 +
bulk-update-queued: "&a批量更新操作已排队.&7(&f{0}&7)"
 +
bulk-update-confirm: "&a运行&b/{0} bulkupdate &a确认{1}执行更新."
 +
bulk-update-unknown-id: "&a使用id&b{0}&a的操作不存在或已过期."
 +
bulk-update-starting: "&a运行批量更新."
 +
bulk-update-success: "&b量更新已成功完成."
 +
bulk-update-failure: "&cBulk update failed. Check the console for errors."
 +
bulk-change-type-error: "类型无效. 应该是 'server' 或 'world'."
 +
bulk-change-success: "&a应用批量更改成功. {0}记录已更改."
 +
user-info-general: >
 +
  {PREFIX}&b&l> &bUser Info: &f{0}\n
 +
  {PREFIX}&f- &3UUID: &f{1}\n
 +
  {PREFIX}&f- &3状态: {2}\n
 +
  {PREFIX}&f- &3主组: &f{3}\n
 +
  {PREFIX}&f- &a统计:\n
 +
  {PREFIX}&f-    &3权限: &a{4}\n
 +
  {PREFIX}&f-    &3临时权限: &a{5}\n
 +
  {PREFIX}&f-    &3前缀: &a{6}\n
 +
  {PREFIX}&f-    &3后缀: &a{7}\n
 +
  {PREFIX}&f-    &3元信息: &a{8}
 +
user-info-data: >
 +
  {PREFIX}&f- &aCached Data:\n
 +
  {PREFIX}&f-    &3具有环境数据: {0}\n
 +
  {PREFIX}&f-    &3当前环境: {1}\n
 +
  {PREFIX}&f-    &3当前前缀: {2}\n
 +
  {PREFIX}&f-    &3当前后缀: {3}
 +
info-parent-header: "&f- &a父组:"
 +
info-temp-parent-header: "&f- &a临时父组:"
 +
user-getuuid: "&b{0}&b的UUID是&b{1}&b."
 +
user-removegroup-error-primary: "您不能从其主组中删除用户."
 +
user-primarygroup-success: "&b{0}&的主组已设为&b{1}&a."
 +
user-primarygroup-warn-option: "&c警告:此服务器&7({0})&c使用的主组计算方法可能无法反映此更改."
 +
user-primarygroup-error-alreadyhas: "用户已将此组设置为其主组."
 +
user-primarygroup-error-notmember: "&b{0}&a已经不是&b{1}&a的成员,现在添加它们."
 +
user-track-error-not-contain-group: "指定的用户尚未在此轨道上的任何组中."
 +
user-track-added-to-first: "&b{0}&a不在此轨道上的任何组中, 因此在环境&b{2}&a中将其添加到第一组&b{2}&a."
 +
user-promote-success: "&a在环境&b{3}&a中将用户沿轨道&b{0}&a从&b{1}&a提升到&b{2}&a."
 +
user-promote-error-endoftrack: "已达到轨道&4{0}&c的结尾,所以无法提升用户."
 +
user-promote-error-malformed: >
 +
  {PREFIX}轨道上的下一个组{0}不存在. 无法提升用户.\n
 +
  {PREFIX}创建组,或将其从轨道中删除,然后重试.
 +
user-demote-success: "&a在环境&b{3}&a中将用户沿轨道&b{0}&a从&b{1}&a转移到&b{2}&a."
 +
user-demote-endoftrack: "已达到轨道&4{0}&c的结尾,所以&4{1}&c已从&4{2}&c中移除."
 +
user-demote-error-malformed: >
 +
  {PREFIX}轨道上的上一组{0}不存在.无法降级用户.\n
 +
  {PREFIX}创建组,或将其从轨道中删除,然后重试.
 +
user-showpos: >
 +
  &a显示&b{0}&a在轨道&b{1}&a的位置.\n
 +
  {2}
 +
group-info-general: >
 +
  {PREFIX}&b&l> &b组信息: &f{0}\n
 +
  {PREFIX}&f- &3显示名称: &f{1}\n
 +
  {PREFIX}&f- &3权重: &f{2}\n
 +
  {PREFIX}&f- &a统计:\n
 +
  {PREFIX}&f-    &3权限: &a{3}\n
 +
  {PREFIX}&f-    &3临时权限: &a{4}\n
 +
  {PREFIX}&f-    &3前缀: &a{5}\n
 +
  {PREFIX}&f-    &3后缀: &a{6}\n
 +
  {PREFIX}&f-    &3元信息: &a{7}
 +
group-set-weight: "&a将组&b{1}&a的权重设置为&b{0}&a."
 +
track-info: >
 +
  {PREFIX}&b&l> &b显示轨道: &f{0}\n
 +
  {PREFIX}&f- &7路径: &f{1}
 +
track-clear: "&b{0}&a's groups track was cleared."
 +
track-append-success: "&a组&b{0}&a已成功添加到轨道&b{1}&a."
 +
track-insert-success: "&a组&b{0}&a已成功插入轨道&b{1}&a的&b{2}&a位置."
 +
track-insert-error-number: "没有预期的数量,而是收到: {0}"
 +
track-insert-error-invalid-pos: "无法插入位置{0}. 索引超出范围."
 +
track-remove-success: "&aGroup &b{0}&a已成功从轨道&b{1}&a移除."
 +
log-load-error: "日志无法加载."
 +
log-invalid-page: "页码无效."
 +
log-invalid-page-range: "页码无效,请输入1和{0}之间的值."
 +
log-no-entries: "&b没有日志条目显示."
 +
log-entry: "&b#{0} -> &8(&7{1} ago&8) {2}"
 +
log-notify-toggle-on: "&a启用&b记录输出."
 +
log-notify-toggle-off: "&c禁用&b记录输出."
 +
log-notify-already-on: "您已经收到通知."
 +
log-notify-already-off: "您目前没有收到通知."
 +
log-notify-unknown: "状态未知.输入 \"on\" 或者 \"off\"."
 +
log-search-header: "&a显示最近的查询操作&b{0} &a(page &f{1}&a of &f{2}&a)"
 +
log-recent-header: "&a显示最近操作 (page &f{0}&a of &f{1}&a)"
 +
log-recent-by-header: "&a显示&b{0}&a的最近操作 (page &f{1}&a of &f{2}&a)"
 +
log-history-user-header: "&a显示用户的历史记录&b{0} &a(page &f{1}&a of &f{2}&a)"
 +
log-history-group-header: "&a显示组的历史记录 &b{0} &a(page &f{1}&a of &f{2}&a)"
 +
log-history-track-header: "&a显示轨道的历史记录 &b{0} &a(page &f{1}&a of &f{2}&a)"
 +
log-export-already-exists: "错误: 文件{0}已经存在."
 +
log-export-not-writable: "错误: 文件{0}不可写."
 +
log-export-empty: "日志为空,因此无法导出."
 +
log-export-failure: "写入文件时出现意外错误."
 +
log-export-success: "&a成功导出日志&b{0}&a."
 +
import-already-running: "另一个导入过程已经在运行,请等待完成,然后重试."
 +
export-already-running: "另一个导出过程已经在运行,请等待完成,然后重试."
 +
import-log-doesnt-exist: "错误: 文件{0}不存在."
 +
import-log-not-readable: "错误: 文件{0}不可读."
 +
import-log-failure: "从日志文件读取时发生意外错误."
 +
import-progress: "&b(导入) &b-> &f百分之{0}完成 &7- &b{1}&f/&b{2} &f完成 &c{3}&f错误."
 +
import-progress-sin: "&b(导入) &b-> &f百分之{0}完成 &7- &b{1}&f/&b{2} &f完成 &c{3}&f错误."
 +
import-start: "&b(导入) &b-> &f开始导入过程."
 +
import-end-complete: "&b(导入) &a&l已完成 &7- 用了 &b{0} &7秒 - &7没有错误."
 +
import-end-complete-err: "&b(导入) &a&l已完成 &7- 用了 &b{0} &7秒 - &c{1}错误."
 +
import-end-complete-err-sin: "&b(导入) &a&l已完成 &7- 用了 &b{0} &7秒 - &c{1}错误."
 +
import-end-error-header: >
 +
  {PREFIX}&b(导入) &7------------> &f显示错误 #&b{0} &7<------------\n
 +
  {PREFIX}&b(导入) &f执行时: &3Command #{1}\n
 +
  {PREFIX}&b(导入) &f命令: &7{2}\n
 +
  {PREFIX}&b(导入) &f类型: &3{3}\n
 +
  {PREFIX}&b(导入) &f输出:
 +
import-end-error-content: "&b(导入) &b-> &c{0}"
 +
import-end-error-footer: "&b(导入) &7<------------------------------------------>"
 +
</pre>
 +
 +
=== PlaceholderAPI ===
 +
 +
在 extended_clip 的 [https://www.spigotmc.org/resources/placeholderapi.6245/ PlaceholderAPI] 插件中,LuckPerms 也注册了一些变量(Placeholders)。
 +
 +
LuckPerms 插件所使用的标识符是 '''luckperms'''。
 +
 +
==== 使用 ====
 +
 +
要想使用变量的话,你需要运行下列命令。 这些命令的作用就是安装 LuckPerms 的变量扩展,安装后你就可以使用下面列举出的变量了。
 +
 +
<code>/papi ecloud download LuckPerms</code>
 +
 +
<code>/papi reload</code>
 +
 +
请记住使用这些指令你需要OP权限(或者你也可以选择在控制台中运行这些指令)
 +
 +
同时请注意,如果你想得到玩家的前缀或后缀数据,——如果你在服务器上安装了Vault插件和Vault的变量扩展的话,你也可以使用 Vault 插件所提供的变量。
 +
 +
==== Placeholders ====
 +
 +
<code>%luckperms_group_name%</code>
 +
 +
'''使用说明:''' 返回玩家当前所在组的名字<br />
 +
'''使用示例:''' n/a
 +
 +
 +
-----
 +
 +
<code>%luckperms_context_&lt;context key&gt;%</code>
 +
 +
'''使用说明:''' 返回给定内容关键字的值,如果内容没有值的话会返回空 '''使用示例:''' %luckperms_context_server%
 +
 +
 +
-----
 +
 +
<code>%luckperms_groups%</code>
 +
 +
'''使用说明:''' 返回服务器上的权限组列表,用逗号分割 '''使用示例:''' n/a
 +
 +
 +
-----
 +
 +
<code>%luckperms_has_permission_&lt;permission&gt;%</code>
 +
 +
'''使用说明:''' 检查玩家是否直接拥有该权限,不会检查通配符或继承的权限 '''使用示例:''' %luckperms_has_permission_essentials.ban%
 +
 +
 +
-----
 +
 +
<code>%luckperms_check_permission_&lt;permission&gt;%</code>
 +
 +
'''使用说明:''' 检查玩家是否拥有指定权限,这个变量工作的方式和正常插件的检查方式没有区别 '''使用示例:''' %luckperms_check_permission_some.cool.permission%
 +
 +
 +
-----
 +
 +
<code>%luckperms_in_group_&lt;group&gt;%</code>
 +
 +
'''使用说明:''' 返回玩家是否为给定组的成员,不包括继承组 '''使用示例:''' %luckperms_in_group_admin%
 +
 +
 +
-----
 +
 +
<code>%luckperms_inherits_group_&lt;group&gt;%</code>
 +
 +
'''使用说明:''' 返回玩家是否在给定组或继承给定组 '''使用示例:''' %luckperms_inherits_group_vip%
 +
 +
 +
-----
 +
 +
<code>%luckperms_on_track_&lt;track&gt;%</code>
 +
 +
'''使用说明:''' 返回玩家的权限组是否在给定权限组树上 '''使用示例:''' %luckperms_on_track_staff%
 +
 +
 +
-----
 +
 +
<code>%luckperms_has_groups_on_track_&lt;track&gt;%</code>
 +
 +
'''使用说明:''' 检查玩家是否继承给定权限组树中的任何一个组 '''使用示例:''' %luckperms_on_track_donor%
 +
 +
 +
-----
 +
 +
<code>%luckperms_highest_group_by_weight%</code>
 +
 +
'''使用说明:''' 返回玩家所在权限组树种的最高级权限组 '''使用示例:''' n/a
 +
 +
 +
-----
 +
 +
<code>%luckperms_lowest_group_by_weight%</code>
 +
 +
'''使用说明:''' 返回玩家所在权限组树种的最低级权限组 '''使用示例:''' n/a
 +
 +
 +
-----
 +
 +
<code>%luckperms_first_group_on_tracks_&lt;tracks&gt;%</code>
 +
 +
'''使用说明:''' 返回玩家在给定权限组树上所在的第一个组,权限组树会返回一组用逗号分隔的权限组名,权限组树中的每一个权限组都正序排列。 '''使用示例:''' %luckperms_first_group_on_tracks_staff,donor%
 +
 +
 +
-----
 +
 +
<code>%luckperms_last_group_on_tracks_&lt;tracks&gt;%</code>
 +
 +
'''使用说明:''' 返回玩家在给定权限组树上所在的最后一个组,权限组树会返回一组用逗号分隔的权限组名,权限组树中的每一个权限组都倒序排列。 '''使用示例:''' %luckperms_last_group_on_tracks_staff,donor%
 +
 +
 +
-----
 +
 +
<code>%luckperms_expiry_time_&lt;permission&gt;%</code>
 +
 +
'''使用说明:''' 获得玩家拥有的临时权限剩余的时间,如果玩家没有该权限的话会返回空 '''使用示例:''' %luckperms_expiry_time_essentials.fly%
 +
 +
 +
-----
 +
 +
<code>%luckperms_group_expiry_time_&lt;group name&gt;%</code>
 +
 +
'''使用说明:''' 获得玩家拥有的临时权限组所剩余的时间,如果玩家不在该权限组的话会返回空 '''使用示例:''' %luckperms_group_expiry_time_vip%
 +
 +
 +
-----
 +
 +
<code>%luckperms_prefix%</code>
 +
 +
'''使用说明:''' 返回玩家的前缀,使用Vault所提供的变量所输出的结果可能会更精确,这一项不会被Vault的配置设置影响 '''使用示例:''' n/a
 +
 +
 +
-----
 +
 +
<code>%luckperms_suffix%</code>
 +
 +
'''使用说明:''' 返回玩家的后缀,使用Vault所提供的变量所输出的结果可能会更精确,这一项不会被Vault的配置设置影响 '''使用示例:''' n/a
 +
 +
 +
-----
 +
 +
<code>%luckperms_meta_&lt;meta key&gt;%</code>
 +
 +
'''使用说明:''' 返回与指定Meta关键字联系的值 '''使用示例:''' %luckperms_meta_some-key%
 +
 +
 +
-----
 +
[[分类:Spigot插件]][[分类:CraftBukkit插件]][[分类:Sponge插件]]
 +
[[Category:管理]][[Category:安全]]

2021年8月16日 (一) 00:28的最新版本

Commons-emblem-issue.png
Minecraft插件百科提醒您,此条目或需要大幅度整改,建议新用户不要模仿此条目格式建立新条目。

原因在于:

  • 页面冗长,需要拆分子页面
若您清楚改善现状的方法,可以尝试帮忙改进
LuckPerms
外文名LuckPerms
作者Luck
插件类型Spigot / CraftBukkit / Sponge
最新版本4.0.18(Bukkit) / 4.0.60(Sponge)
兼容服务端1.7, 1.8, 1.9, 1.10, 1.11, 1.12
源地址SpigotMC
SpongePowered

LuckPerms是一款由Luck开发的权限插件。

目录

引言

欢迎来到 LuckPerms wiki。这里你将会找到本插件的完整的使用文档,包括了安装、设置、配置和如何高效的使用 LuckPerms。

从何开始?

如果您从未使用过任意权限插件,我推荐你从头开始看。

基础都在[使用教程]页面。

完整的命令使用在[命令使用]页面。

什么也没找到?

如果你有更多的问题是这篇Wiki没有解决的,你可以通过以下几种方式联系我。

  • [Discord 服务器] (就算我不在,也有很多人帮助你!)
  • 在 irc.esper.net 我是 "Luck",我也在 irc.spi.gt 和 chat.freenode.net
  • 在 SpigotMC 和 Sponge 论坛我是 "Luck"
  • 在[GitHub]提交一个 issue (如果你要提交一个BUG,这是最好的方式)

一些有用的链接

为什么选择LuckPerms?

这是另外一款全新的权限插件?

是的,我认为LuckPerm相比其他权限插件还有很大的发展空间。

LuckPerm是一款先进、高等的权限插件,仅仅以快速稳定可靠灵活多变的特点,

便可以替代现有的许多权限插件,例如PermissionsEX、GroupManagerX、z/bPermissions、BungeePerms等主流权限插件。

LuckPerms这个插件的计划,本来是围绕着两个主要特点来制作的:高性能、强大且广泛的功能,

填补其他同类插件的功能缺陷、并且建立在同类现有功能上更进一步的优化功能。

LuckPerms还包括了非常广泛的API支持,这是为开发人员的添加的,

并且,luckperms还兼容各式各类Minecraft服务器软件&支持多种数据存储的选择。

我已经使用某插件很长一段时间了,它对我的帮助很大,我也很熟悉它了,为什么我要更换它而选择LuckPerm呢?

现在主流的权限插件大多数都是老牌插件了,并且都是在Bukkit早期就被创造出来了。

虽然,这可能意味着它们非常的稳定可靠,但通常也意味着它们被原作者抛弃,并且一般不会再有任何更新、修复,

但LuckPerm却任然是一个需要成长、需要磨砺的插件!

我会尽力及时查看并回复所有的bug报告、问题,以及可实现的新功能建议

你说的不错,但是我更加偏爱某插件,因为仅凭它就完成了我需要的一切

这没关系,我完全理解你的这种心态,我并不是想要说你**必须**用LuckPerm来作为你服务器的权限插件。

当然还有更多适合你服务器权限插件,但是LuckPerm确实是个很棒的选择,不是么?

来吧兄弟,告诉我,我为什么要使用LuckPerm?

LuckPerm能做很多事情,至少单在技术层面,LuckPerm就胜过大部分同类插件。

我认为这不取决于我制作插件的水平,而是取决于我在LuckPerm上面花费的精力与时间。

LuckPerm是我在2016年开始准备编写的插件,但因为Bukkit变得流行起来,许多同一时期的插件都变成了老牌稳定插件,

不过,这也为我编写LuckPerm提供的很好的参考帮助,因为我可以避免其它同类插件的缺陷,

并且明白它们哪些地方做的特别出色,我可以在其基础之上进一步优化,使那部分功能变得更加引人瞩目。

记着,如果你对LuckPerm技术性方面的内容感兴趣,我推荐你从[命令使用]部分开始阅读

或者看看wiki列出的其他部分内容,在本节的其余部分,我会将阅读重点放到LuckPerm一些全新的特色功能上面。

这些内容是你不太可能从其他插件中找到的,专属luckPerm的特色功能!

Verbose(权限查看系统)

LuckPerm有一套完整的权限查看系统,是的,它叫做[verbose]。

他可以实时监视并检测其他插件所需的权限,就像下面示例的动态图那样:【图片过大 请去wiki页面查看】

你也可以把录像上传到网上,方便查看、分析和阅读:

[https://git.io/vQitM]

权限树系统

LuckPerm允许你在服务器所有已知权限上建立编写"权限树"。

权限树上的数据是由你所有的插件在服务器注册的权限构成的。

随着你服务器运营时间的增长,因为服务器添加了许多插件,它们都会注册权限,这些数据都会被纳入权限树中。

这是个清真的例子 [https://git.io/vQiti]。 你看到的权限树的颜色,代表了你的玩家是否拥有对应的权限,这一机制很方便的让你查阅到服务器的相应权限。

这还是那个清真的例子 [[1]]

指令界面&TAB补全

LuckPerm的指令系统被我设计的尽可能便捷、易用、人性化,

这样一来,你除了查阅LuckPerm的[大量相关帮助文档],还可以在游戏中查看指令用法、以及指令列表。

Luck-1.png

LuckPerm的所有指令皆可使用TAB补全功能,这就意味着,你可以通过输入更少的指令来完成你的工作!

这是不是在一定程度极大地提高了你的工作效率呢?就像下面那样:

AnnualYoungKoi-size restricted.gif

网站编辑器

除了使用指令来编辑服务器权限相关,LuckPerm还提供了更加便捷的编辑方式,

你可以使用Web网站编辑器来对服务器的权限数据进行快速更改,

任何人都能够使用网站编辑器,不论你使用了哪种存储方式!

网站编辑功能非常容易使用,且易于上手

【图片过大 请去wiki页面查看】

行为记录仪

为了防止服务器中出现心存不轨的管理员,想要私自给自己添加权限,

LuckPerm详细的记录了服务器各类权限的微小变化,

你可以通过行为记录仪来搜索每个人的详细操作。

Luck-2.png

你也可以查看所有东西的详细历史。

安装

安装

初始设置

1. 下载适合你平台的 `LuckPerms-???-x.x.x.jar` 文件。你可以点这里查看最新的版本。

2. 打开你的 Mod 或插件所在路径,这路径通常要么是 `/server/plugins/` ,要么是 `/server/mods/`。

然后把 LuckPerms 的 jar 文件放入文件夹中。

3. 请完全关闭你的服务器,然后再打开,这会生成默认配置。

4. 完全关闭你的服务器,打开配置文件。配置文件的位置在 `/plugins/LuckPerms/config.yml` 或 `/config/luckperms/luckperms.conf`。

5. 请浏览配置文件,然后根据你的服务器修改设置,尤其是请注意存储相关设置。

6. 再次开启你的服务器。

你可以更改配置文件中的很多内容,文件有很细节化的注释,每个设置的作用注释中都解释的很清楚。

需求

LuckPerms 插件只有一个环境需求。

  • Java 8

没错,唯一需求就是你必须使用 Java 8,LuckPerms 插件在旧版本的Java上不会工作。

到目前为止很多服务器提供商都已经升级到Java 8了,但是如果你的服务器提供商没有升级的话,请温和地和他们谈谈,让他们去升级。

如果你是自己租主机开服的话,你应该对你还没有升级Java感到羞愧!

升级的过程是很简单的,如果你想升级的话网上也有大量的教程。

使用过期的软件肯定不是好的:)

Bukkit版本过旧

如果你收到了类似于 "NoSuchMethod" 或 "ClassNotFound" 这类错误的话,十有八九就是你在使用较旧的Bukkit版本。

在将它作为错误报告给我之前,请尝试使用"Development Builds"(构建版本)下载页面的"Bukkit-Legacy"(Bukkit-旧版)版本。

切换存储类型

LuckPerms 插件所使用的默认数据存储类型是 H2 数据库

所有的数据都会储存在LuckPerms插件目录下的 `luckperms.db.mv.db` 文件之中。

(插件目录为 `/plugins/LuckPerms/` 或 `/luckperms/`)

这个数据格式普通的文本编辑器是**不能读取**的。

如果你想要手动阅读/编辑LuckPerms插件的数据的话,你就需要切换到**YAML或JSON**存储格式,更改 `config.yml` 文件中的配置选项就好了。

更多相关于存储类型的有关信息请阅读[下一节]

选择存储类型

LuckPerms 插件带有很多存储数据的方式,你可以从中选择。

存储类型选项可以在 `config.yml` 或 `luckperms.conf` 文件中修改。

# Which storage method the plugin should use.
# Currently supported: mysql, postgresql, sqlite, h2, json, yaml, mongodb
# Fill out connection info below if you're using MySQL, PostgreSQL or MongoDB
storage-method: h2

请记住如果你想改变存储类型的话,你的数据不会自动转移到新的存储库中。

要想手动在数据存储方式间转移数据的话,请查看这里来获得更多信息。

可用的选项都列在了下面。

H2 / SQLite

默认的存储类型是 H2

这两种文件类型都是以SQL数据库为基础的。

所有的数据都会存储在LuckPerms插件目录下的一个文件之中。

和YAML和JSON方式的不同之处在于,这个文件不能用文本编辑器打开。

你必须使用插件提供的命令才能编辑或查看数据。

如果你选择使用 H2 数据库的话(默认设置),所有的数据都会储存在 `luckperms-h2.mv.db` 文件中。

SQLite 类型所提供的存储文件是 `luckperms-sqlite.db`。

要想使用这两种类型中的一种,请将配置设置为:

storage-method: h2
# or
storage-method: sqlite

JSON / YAML

JSON 和 YAML 存储类型会将数据存储在可读可编辑的文本文件中。YAML 类型所提供的文件扩展名为 `.yml` ,JSON类型所提供的文件扩展名为 `.json`。

这两种类型的存储格式很相似,只是在一些句法上不同。

示例 YAML 文件

uuid: c1d60c50-70b5-4722-8057-87767557e50d
name: Luck
primary-group: default
permissions:
- group.default:
    value: true
- test.permission:
    value: true
    server: factions
- other.test.permission:
    value: false

示例 JSON 文件

{
  "uuid": "c1d60c50-70b5-4722-8057-87767557e50d",
  "name": "Luck",
  "primaryGroup": "default",
  "permissions": [
    {
      "group.default": {
        "value": true
      }
    },
    {
      "test.permission": {
        "value": true,
        "server": "factions"
      }
    },
    {
      "other.test.permission": {
        "value": false,
        "server": "test"
      }
    }
  ]
}

要想使用这两种类型中的一种,请将配置设置为:

storage-method: yaml
# or
storage-method: json

MySQL / PostgreSQL

储存在 MySQL 类型和 PostgreSQL 类型中的数据格式上与上文提及的 H2/SQLite 类型相同,但是数据是储存在远程服务器上的。

这意味着你可以跨服分享相同的数据。

你需要在配置文件中输入你数据库服务器的地址,端口,数据库名,用户名和密码。

这种类型推荐要存储大量数据的用户,或是想要搭建群组服务器的用户所使用。

如果你已经在运行群组服务器,并且想要在子服务器之间同步数据的话,你就必须选择这种类型了。

格式布局示例在这里

要想使用这两种选项中的一种,请将配置设置为:

storage-method: mysql
# or
storage-method: postgresql

MongoDB

LuckPerms 也支持 MongoDB 类型的存储,它也是一种远程数据库,在有些方面上和 MySQL 相似。

这种类型也只会被一小部分的用户所使用。

要想使用这种类型的存储,请将配置设置为:

storage-method: mongodb

使用教程

这篇教程是为之前从来没有使用过权限管理插件的人所准备的。

如果你已经很熟悉权限管理等相关概念了的话,我认为你应该就能够理解命令中的东西了。

这样我就推荐你去阅读命令和权限页面,这样更加“直奔主题”,你也能够更容易理解插件的工作方法。

如果你正在努力想弄明白权限管理相关概念的话,这篇教程就是你起步的最佳地方:)


关键术语

权限

在你的服务器上会有大量的**特性,命令和一些新功能**。

这其中的一些特性是服务器自带的,另一些是由“插件”所添加的。

与这些特性相联系的大多数行为都是由权限所控制的,因此你可以控制哪些用户可以使用你指定的特性或权限。

    • 权限仅仅是个字符串**,并且使用英文的句号(半角 → . ←)分成几部分。

举个例子, “minecraft.command.ban” 就是原版 /ban 命令所使用的权限。

显然我们不想让所有用户都能执行这个命令,所以我们只给我们信任的玩家这个权限。

代表特定行为的使用许可的字符串,我们就称之为权限,它又名“权限节点”,简称“权限”。

权限组

代替单独为每个用户设置权限,我们可以将**权限捆绑为一组**,然后直接将这一组**给予玩家**。

举个例子,在我设置的“admin”权限组中,我可能会添加使用ban和unban指令的权限,然后将玩家加入admin权限组中。

这意味着他们能够获得“admin”权限组所设置的所有权限和他们自身被设置的权限。

继承

用户和权限组能够**互相继承权限**。

举个例子,默认地,所有的用户都会从“default”权限组继承权限。

你可以为你自己的服务器设置你自己的权限组与继承方式,或是制作你自己独特的系统。

举个例子,我设置了三个权限组, “default”, “moderator” 和 “admin”。

我想让“moderator”权限组从“default”权限组继承所有权限,“admin”权限组从“moderator”权限组继承所有权限。

起步

如果你还没有将LuckPerms插件安装在你的服务器上的话,我们推荐你先阅读安装有关的教程。

然后,请确保你在继续之前已经阅读了选择数据存储类型的有关章节。

虽然你在后期也能实现数据之间的转移,但第一次就将他们弄对位置是更好的。

给予修改权限的全部权限

你想做的第一件事情就是给你本插件的所有权限。

当本插件首次安装后,没有人能够使用LuckPerms插件的有关命令。

要想做到这个的话,你需要在服务器控制台输入 `/luckperms user Luck permission set luckperms.* true` 。

当然,请把我的名字换成你自己的(不用担心,这条命令的使用方法之后会详细讲解)

这应该就是运行的结果:

LPUsage1.png

实际上,这条命令起的效果,就是给了 `Luck` 用户 `luckperms.*` 权限。(或者说,为用户设置权限为 true)

你可能已经注意到了我们刚才在权限字符串的末端使用的 `*` 字符了。

这个字符叫做通配符,它会给玩家**所有**以 "luckperms" 为开头的权限。

创建第一个权限组

我们可以使用创建权限组命令来创建一个新的权限组。

让我们创建一个叫做“admin”的权限组,然后给它附加一条权限吧。

首先,运行 `/luckperms creategroup admin` 命令。

这会创建一个叫做“admin”的空权限组。

LPUsage2.png

接下来,我们想为“admin”权限组增加一条权限。

用来修改权限组的命令是 `/luckperms group <group>`

如果你执行这条命令的话,它会为你显示所有可用的子命令。

LPUsage3.png

你可能注意到了第一个子命令是“info”命令。它只会列举出一些权限组相关的信息。

我们可以运行 `/luckperms group admin info` 来查看新建立的“admin”权限组的一些信息。

LPUsage4.png

接下来就是“permission”命令。这能够帮助你修改权限组的权限。

再一次,使用 `/luckperms group admin permission` 命令会列出所有可用的子命令。

LPUsage5.png

再一次,我们看到了更多我们可以执行的命令。

第一个就是另一个 "info" 子命令。

因为它是“permission”子命令下的又一子命令,它就会显示某一权限组所拥有的所有权限。

下面的命令是“set”子命令。

你还记得吗,之前我们使用相似的指令来给玩家 "luckperms.*" 权限。这里它也相同

只需要不加参数运行该命令就可以返回该命令的使用方法。举个例子:

LPUsage6.png

举个例子,我想给我的“admin”用户组 "minecraft.command.ban" 权限。

因此我可以输入 `/luckperms group admin permission set minecraft.command.ban true`

LPUsage7.png

这条命令就会给予 `admin` 用户组 `minecraft.command.ban permission` 权限。

末端的true控制我们设置的权限的启用与否。

你可以将权限的启用与否设置为 `true` 或 `false` 。

为用户或权限组将权限设置为 true 能够让他们拥有该权限,设置为 false 即该权限无效。(指定他们没有该权限)

如果晚些时候我决定不再让“admin”用户组拥有这个权限了,我可以使用 unset 命令来移除该权限的设定。

输入 `/luckperms group admin permission unset minecraft.command.ban`

LPUsage8.png

将玩家加入到权限组中

将用户加入到权限组中需要使用 "parent" 命令。(在我们的命令使用页我们经常用“permission”替换“parent”)

举个例子,把我自己加入“admin”权限组中,我需要使用 `/luckperms user Luck parent add admin`

LPUsage9.png

这条命令会将用户 `Luck` 加入到 `admin` 权限组中。

这意味着任何“admin”权限组所拥有的权限我现在也继承下来了。

让一个权限组继承另一个权限组

就像用户能够继承一样,权限组也能够继承另一个权限组。

举个例子,想想下面这种情况的设置方法。(有些权限仅仅是为了演示而编造出来的)

Admin Mod Default
minecraft.command.ban minecraft.command.mute minecraft.command.say
minecraft.command.pardon minecraft.command.unmute minecraft.command.me
some.cool.admin.perm some.cool.mod.perm
someplugin.vanish |

我想让“admin”权限组中的用户拥有“mod”和“default”权限组的权限,同时“mod”权限组中的用户拥有“default”权限组中的权限。要想实现这个的话,我可以设置用户组之间的相互继承。

`/luckperms group admin parent add mod` 命令会让“admin”权限组继承所有“mod”权限组中的权限。

然后要想让“mod”继承“default”,同样的道理,我可以输入 `/luckperms group mod parent add default`。

LPUsage10.png

继承是可递归的,所以这样以后“admin”权限组就不仅仅继承了“mod”权限组,还继承了“default”权限组。

这意味着“admin”权限组中的玩家拥有“mod”**和**“default”两权限组中的权限了。

在“admin”组的一位用户因此拥有 `minecraft.command.ban`,`minecraft.command.mute` *和* `minecraft.command.say` 权限。

移除继承权限组

要想移除权限组间的继承关系只需要输入一个类似的命令就好了。

要想让我自己不再继承“admin”权限组,我只要输入 `/luckperms user Luck parent remove admin` 就好了。

LPUsage11.png

配置

不同平台的 LuckPerms 的配置文件可以在这里找到。

平台 位置
Bukkit/Spigot /plugins/LuckPerms/config.yml
BungeeCord /plugins/LuckPerms/config.yml
Sponge /config/luckperms/luckperms.conf

请注意配置文件不能在有新配置的时候自动添加,如果文件中没有找到任何东西,我们将使用默认选项。

索引

基础

权限计算

基础

server

服务器的名称,用于制定服务器的权限。

如果设置为 "global" 这个设置将会被忽略,更多关于服务器指定的权限可以在这里找到。

示例
server: global

include-global

这个服务器的玩家是否应该应用他们的全局权限。(没有指定服务器的权限)

如果这个选项被设置为 false,只有指定在此服务器的权限才会被应用。如果上方的 "server" 选项设置为 global,请不要将其设置为 false。更多的有关服务器指定的权限可以在这里找到。

示例
include-global: true

include-global-world

与上方的选项相似,只是这个选项用于世界的设定。如果设置为 false,只有指定了世界的权限才会被应用至玩家。任何没有指定世界的权限都不会被应用。

示例
include-global-world: true

apply-global-groups

这个选项与 "include-global" 选项类似,但是此选项更改了组的继承设定。

当计算玩家的权限时,插件将会给继承树设定范围,递归解析组成员关系。如果这个设置设置为 false,如果一个组没有被应用,那么它的父组都不会被计算,继承查询将会在此终止。

这意味着就算一个玩家没有在一个特定服务器直接继承一个组,如果这个组通过了一个没有指定服务器的组继承,这个组将不会被应用。

举个例子,当设置为 false,使用以下设置:

用户 "Luck" 继承自全局组 "admin",admin 继承自某服务器的 "default" 组。

尽管 Luck 在指定服务器上继承了默认组,它将不会被应用,因为继承查询在 admin 停止。admin 的父组将不被考虑。

示例
apply-global-groups: true

apply-global-world-groups

与上面的选项相似,但是这个选项用于世界的设定。如果设置为 false,只有指定了世界的组才会被分配,给用户解析。任何没有指定世界的组都不会被应用。

示例
apply-global-world-groups: true

use-server-uuids

如果使用服务器的UUID,或者根据之前的连接的用户名来查询,那么这个设定应该使用 true,除非你很确定你在做什么。

一般的,当这个选项设置为 true 时,当玩家登入时,LuckPerms 将会使用服务器提供的用户名/UUID来标识玩家。这个在大多数的服务器都是适用的。

当设置为 false,LuckPerms 将会检查玩家是否曾经在服务器登录过,如果找到了一个玩家,那么之前映射的UUID将会被使用,否则将会回到默认的使用服务器的UUID的方法。

在离线模式(破解版)的服务器,玩家的UUID基于他们的用户名创建。

重要

如果你在运行一个 BungeeCord 服务器,你必须开启 IP forward 设置,这将让服务器使用正确的UUID。

Spigot Sponge. SpongeForge 推荐使用 HexaCord, 这是一个 BungeeCord 分支,支持 Forge 的 IP forwarding。

如果你的 BungeeCord 代理运行于离线模式并且你使用了 Spigot,你也应该像下方一样开启 IP forwarding,但是推荐你安装 Paper 并设置 paper.yml 中的 bungee-online-mode: false

如果还有什么原因导致了你无法设置 Ip forwarding,你可能需要将其设置为 false,请确保这样做之前你知道这样做的后果。

示例
use-server-uuids: true

log-notify

当任何权限被修改后是否向玩家发送长的提醒。提醒将只发送给拥有正确权限的用户。

提醒可以在游戏中使用 /lp log notify off 临时关闭。

示例
log-notify: true

world-rewrite

允许你给发送的世界设置别名,别名附加于真正的世界名,递归应用。

示例
world-rewrite:
  world_nether: world
  world_the_end: world

group-name-rewrite

允许你设置组名的别名。它们是纯粹的显示名称,实际上的名称不会改变,只有命令/信息的输出会改变。

示例
group-name-rewrite:
  default: Member

temporary-add-behaviour

控制临时的权限/父类/元数据,默认是 deny

  • accumulate - 任何添加的节点将被添加
  • replace - 临时的节点持续的最长的时间,其他的节点将被忽略
  • deny - 如果你试图添加一个重复的临时节点命令将被拒绝
示例
temporary-add-behaviour: deny

primary-group-calculation

LuckPerms 如何决定用户的主组,Bukkit/Bungee 默认的是 stored,Sponge 默认的是 parents-by-weight

  • stored - 使用存储的记录在文件/数据库的数据
  • parents-by-weight - 使用用户权重最高的父组
  • all-parents-by-weight - 像上面的一样,但是计算所有的继承,包括直接继承和间接继承
示例
primary-group-calculation: stored

权限计算


apply-wildcards

插件是否应用带有通配符的权限。

如果插件的作者没有提供他们自己的通配符权限,那么开启这个选项将会让 LuckPerms 转换它们。Bukkit 尤其不认同这种做法,但是它们在管理员中间适用的相当普遍。在 Sponge,这个选项控制 "node.part.*" 类型的通配符是否生效。

示例
apply-wildcards: true

apply-regex

插件是否转换正则表达式权限。

如果设置为 true,LuckPerms 将会检测任何正则表达式权限,正则表达式权限节点以 "r=" 开头,返回所有匹配这个节点的请求。如果你没有任何正则表达式权限的设置,开启这个将没有任何性能的影响。这个特点的更多信息可以在这里找到。

示例
apply-regex: true

apply-shorthand

是否允许GLOB风格的速记权限。

更多这个特性的信息可以在这里找到。

示例
apply-shorthand: true

apply-bukkit-child-permissions

插件是否应用Bukkit子权限。

插件的作者可以给他们的插件定义自定义权限结构,如果设置为 true,LuckPerms 将会使用他们。

这个选项是默认启用的,因为这是一个基础的Bukkit特性,大多数的服务器管理员都需要,但是如果你不希望使用这个系统,它将可以被安全关闭。

示例
apply-bukkit-child-permissions: true

apply-bukkit-default-permissions

插件是否应该应用Bukkit的默认权限。

插件作者可以给所有的用户默认权限,或者设置应该/不应该给OP玩家。如果这个设置为 false,LuckPerms将会忽略这些默认权限。

这个选项是默认启用的,因为这是一个基础的Bukkit特性,大多数的服务器管理员都需要,但是如果你不希望使用这个系统,它将可以被安全关闭。

示例
apply-bukkit-default-permissions: true

apply-bukkit-attachment-permissions

插件是否应该应用Bukkit的附加权限。

服务器的其他插件可以添加它们自身的"权限附加"到玩家,这允许大量的玩家附加权限持续到回话结束,或者被移除。如果这个设置被设置为 false,LuckPerms 在考虑玩家是否有某一特定的权限时,将不会包括这些附加的权限。

你在开启这个选项后可能会见到一个小的性能提升,关闭 OP 系统后,这个系统可以非常有效的阻止恶意插件给玩家任意权限的尝试。

这个选项是默认启用的,因为这是一个基础的Bukkit特性,大多数的服务器管理员都需要,但是如果你不希望使用这个系统,它将可以被安全关闭。

示例
apply-bukkit-attachment-permissions: true

apply-bungee-config-permissions

插件是否应用 BungeeCord config.yml 里设置的权限和组。

如果设置为 false,LuckPerms 将会忽略这些值。

这个是默认关闭的,因为所有的权限都应该通过 LuckPerms 来设置,这样他们可以在游戏中查看和编辑。

示例
apply-bungee-config-permissions: false

apply-sponge-implicit-wildcards

插件是否解析并应用Sponge的通配符集成系统的权限。

如果一个玩家获得了 example,那么他将自动获得 example.function 权限,example.anotherexample.deeper.nesting 等。

如果这个选项被设置为 false,系统将不会被应用。

这个选项是默认启用的,因为这是一个基础的Sponge特性,大多数的服务器管理员都需要,但是如果你不希望使用这个系统,它将可以被安全关闭。

示例
apply-sponge-implicit-wildcards=true

apply-sponge-default-subjects

插件是否应用Sponge的默认权限。

插件将会授予玩家一组默认权限,如果设置为 false,那么插件将在考虑玩家是否拥有某权限时忽略这一组权限。

这个选项是默认启用的,因为这是一个基础的Sponge特性,大多数的服务器管理员都需要,但是如果你不希望使用这个系统,它将可以被安全关闭。

示例
apply-sponge-default-subjects=true

Server Operator / Vault (Bukkit version only)


enable-ops

是否使用原版的OP系统。

如果设置为 false,所有玩家都不是 op,op/deop 命令将被禁止。

示例
enable-ops: true

auto-op

如果设置为 true,任何拥有 "luckperms.autoop" 权限的玩家将会自动设置为服务器OP。

这个权限可以被继承,或者设置在特定的服务器/世界,临时的等等。另外,设置此选项为 true 将会强制上方的选项 "enable-ops" 为 false。所有的用户都将被 deop 直到他们有了这个权限节点,并且 op/deop 命令将被禁止。

有一点需要注意的是,自动OP检测只有在玩家进入服务器和切换世界时生效,这意味着,简单的移除他们的权限并不会自动去除玩家的OP,玩家必须重新登陆才能使其生效。

推荐使用这个选项而不是简单的分配一个 "*" 权限。

示例
auto-op: false

commands-allow-op

OP玩家是否有权限使用 LuckPerms 指令。

设置为 false 将只允许有命令指定的权限的玩家使用。

示例
commands-allow-op: true

use-vault-server

下方的 vault-server 选项是否应该使用。

当这个选项设置为 false 时,"server" 值用于 Vault 操作。

示例
use-vault-server: false

vault-server

Vault 操作中使用的服务器名称。

如果你不想让 Vault 操作为特定服务器,将其设置为 "global"。

只有当 use-vault-server 设置为 true 时生效。

示例
vault-server: global

vault-include-global

玩家组接受元数据时是否考虑全局权限。

示例
vault-include-global: true

vault-ignore-world

Vault 操作是否应该忽略提供的世界参数。

默认情况下,如果没有提供世界参数,权限将会设置在玩家当前的世界。(Vault 的设计给满分)。设置为 true 来更改这项操作的结果。

示例
vault-ignore-world: false

vault-debug

LuckPerms 是否应当在一个插件使用了 Vault 的功能后打印 debug 信息。

示例
vault-debug: false

Storage


storage-method

插件应该使用哪个存储方法。

查看这里查看支持的所有类型。

接受mysql, mariadb, postgresql, sqlite, h2, json, yaml, mongodb

如果你的 MySQL 支持,那么 mariadb 选项比 mysql 更好,h2 当然也比 sqlite 更好。

示例
storage-method: h2

watch-files

当使用基于文件的存储系统,LuckPerms将会监视数据文件的变化,并在文件变化被检测到的时候自动规划更新数据、

如果不想让这个发生,那么将此选项设置为 false。

示例
watch-files: true

split-storage

分离存储允许你为不用的数据类型使用不同的存储选项。

不同类型的数据有: * user - 关于用户的数据,包含权限、父组和元数据 * group - 关于组的数据,包括了组权限、继承组和元数据 * track - 关于轨道的数据(或者说是梯子) * uuid - LuckPerms 适用的 uuid <-- --> username 缓存,当 /lp user 使用的是用户名而不是 UUID * log - LuckPerms 存储的日志 允许的数据类型在上方列出

示例
split-storage:
  enabled: true
  methods:
    user: mariadb
    group: yaml
    track: yaml
    uuid: mariadb
    log: mariadb

data

此选项用于指定数据库的存储凭据。

  • address - 数据库的地址,如果使用默认的端口可以不填写,如果使用了特定端口,请使用 host:port
  • database - LuckPerms 应该使用的数据库
  • username - 使用的用户名
  • password - 使用的密码,留空则不使用验证
示例
data:
  address: localhost
  database: minecraft
  username: root
  password: ''

pool-size

MySQL 连接池大小。

默认为 10,应该适合大部分服务器。只有你清楚你在干什么再更改这项设置。

查看这里了解更多关于连接池大小的信息。

示例
data:
  pool-size: 10 # The size of the MySQL connection pool.

sync-minutes

此选项控制 LuckPerms 多长时间进行一次同步任务。

同步任务将会刷新存储中的所有信息,保证插件使用的是最新的数据。

这个选项默认关闭,因为大多数的用户都是不需要这个功能的,但是如果你使用远程存储,又没有设置信息服务,那么你可能将其设置为像 3 这样的数值。

设置为 -1 来完全停用这个任务。

示例
data:
  sync-minutes: 3

messaging-service

设置信息服务。

如果开启并且正确配置了,LuckPerms 可以使用消息系统来通知其他连接的服务器更改。使用命令 /luckperms networksync 来推送更改,使用这个服务不会存储数据,只是用于消息平台。

如果你决定开启这个功能,你应该设置 "sync-minutes" 为 -1,因为没有必要将数据推至数据库。

可用的选项:

  • bungee - 使用插件的 messaging channel。必须在所有的子服务器开启才能使用,并且要在 Bungee 安装 LuckPerms。
  • lilypad - 使用 LilyPad 的 pub sub 来推送更改。你需要安装 LilyPad-Connect 插件。
  • redis - 使用 Redis 的 pub sub 来推送更改。
  • none - 啥都没有!
示例
messaging-service: none

auto-push-updates

LuckPerms 是否应该在命令执行后自动推送更改。

示例
auto-push-updates: true

redis

Redis的设定。

  • address - redis 使用的地址,默认使用默认端口(6379),如果你有特定的端口,请使用 host:port
  • password - 使用 Redis 需要的密码。留空则不使用验证。
示例
redis:
  enabled: true
  address: localhost
  password: 'passw0rd'

命令使用

当输入无效的参数时,命令的使用方法将会打印在控制台/聊天中,简单的输入 /lp 或者 /lpb 会显示当前用户的权限能够使用的所有命令。

如果输入命令后返回的只有插件版本,那么你没有权限使用任何插件,你需要使用服务器控制台来给自己使用 LuckPerms 命令的权限

别名

每个平台的可用的别名都列在下方,每个命令的效果都是一样的,所以你可以选择自己喜欢的来使用。

Bukkit / Sponge BungeeCord
/luckperms /luckpermsbungee
/perms /bperms
/permissions /bpermissions
/perm /bperm
/lp /lpb

重要 在BungeeCord上命令有所不同,这可以让你选择命令使用的地方,如果命令全部相同,那么你就没有机会控制你的子服务器了。

如果你在使用 Bukkit/Spigot,作为默认,所有是OP的玩家都有使用LuckPerms命令的权限,你可以在配置文件中更改这项选项。

什么是上下文(Context)

参数 context 在LuckPerms中使用频率很高,他的意义对大多数的用户可能不是那么显而易见。

Context,在常识中,意味着环境,某个权限,父组,前缀后缀抑或是元数据。

上下文分为两部分,键和值。LuckPerms提供了默认的两种上下文,服务器和世界上下文,但是可能服务器的其他的插件提供更多可用的上下文,用户的"金钱"上下文可以在使用用户命令时找到。

举个例子,如果我想要在特定的世界设定我的权限,我就会使用世界上下文,解释的更详细些,我们假设这个世界叫做"nether",我在命令中使用的上下文就将是world=nether

当在命令中使用时,上下文 "key" 和 "value" 使用 = 分隔,你可以指定任意多的上下文,但是请记住所有的上下文都应该指定玩家相关的来应用权限之类的东西。

最终,举个例子,我想将 "luckperms.info" 权限在 "nether" 世界设置为 true,只有在 "factions" 服务器有效,命令将会是:

/luckperms user Luck permission set luckperms.info true server=factions world=nether.

这就是用来接收上下文的命令的相同的格式。

最终,给老用户的一些提醒,在命令的最后添加两个额外的 [服务器] [世界] 参数仍然被支持!

概览

= 参数键值:

  • <必需> - 运行指令时你 必需 指定这个参数
  • [可选] - 如果没有指定将会使用默认

如果你想在参数中添加空格,你必须像这样 " " 使用引号把参数包起来。

下方使用的别名 (/lp) 可以使用上方介绍的别名中的任意一个替换。

基础
用户 (/lp user <user> ...)
组 (/lp group <group> ...)
权限 (/lp user <user> permission ... | /lp group <group> permission ...)
继承 (/lp user <user> parent ... | /lp group <group> parent ...)
元数据 (/lp user <user> meta ... | /lp group <group> meta ...)
轨道 (/lp track <track> ...)
日志 (/lp log ...)

命令细节

基础

/lp

权限: n/a
基础的 LuckPerms 命令。将会打印用户有权限使用的所有的命令,包含每个命令的基础信息,和接受的参数。



/lp sync

权限: luckperms.sync
刷新所有加载的数据,如果存储中有变化,那么这个命令将会将服务器的信息添加存储中的更改。



/lp info

权限: luckperms.info
列出 LuckPerms 的一些信息/数据,包括 debug 输出,统计,设置和配置中的一些重要的值。



/lp verbose

权限: luckperms.verbose
参数:

  • <on|record|off|paste> - 启用或禁用日志,或者粘贴日志输出 * [filter] - 排序输出使用的过滤器

控制 LuckPerms 日志输出系统,这允许你坚挺所有对玩家的权限检查,当插件检查了玩家的权限,检查会被 verbose handler 处理。

如果你的过滤器匹配了权限检查,你就会被通知。

on 将会启用这个系统,并且当过滤器匹配时在聊天栏向你发送警告。record 会做相同的事,但是不会向你发送聊天中的警告。off 将会关闭这个系统,paste 将会把前 3500 个结果上传到 GitHub 的 pastebin,并向你提供链接。

过滤器用来匹配玩家检查到的权限的开头,你可以使用 &(与)和 |(或)符号,或者用 ! 来否定一个匹配。( ) 也是支持的。

例子:

  • Luck & (essentials | worldedit) - 匹配每个检查 Luck 的以 "essentials" 或 "worldedit" 开头的权限。 * !Luck & !anticheat - 匹配每个对不是 Luck 的玩家的对以不是 "anticheat" 开头的权限的检查。 * anticheat & !anticheat.check - matches any checks starting with "anticheat" but not starting with "anticheat.check"

更多的信息可以在这里找到。



/lp tree

权限: luckperms.tree
参数:

  • [selection] - 树的根 (指定 . 包含所有的权限) * [max level] - 最多返回多少子分支 (换句话说,树的宽度) * [player] - 检查的在线玩家的名称

生成注册在服务器的权限的树来查看,树由服务器中的插件的数据提供而构建,当插件检查权限时这棵树将会扩大。

所有的参数都是可选的。默认的选择是 . (只是一个点,代表所有),默认的最大等级是 5

选择允许你只生成树的一部分,比如,选择 luckperms.user 将只会返回树中以 luckperms.user 开头的分支。

Max level 允许你定义最多包括的子分支,举个例子,如果你设置最大等级为 2,"luckperms.user" 将会被返回,但是 "luckperms.user.info" 将不会被显示。



/lp search

权限: luckperms.search
参数:

  • <permission> - 搜索的权限

搜索所有用户/组的特定权限,返回分页的所有条目的列表。



/lp check

权限: luckperms.check
参数:

  • <user> - 检查的玩家 * <permission> - 检查的权限

执行一个普通的对在线玩家的权限检查,返回结果,这个检查与其他插件的权限检查的结果相同。



/lp networksync

权限: luckperms.sync
刷新所有存储提供的缓存数据,接着(如果提供了的话)使用消息服务来请求连接的其他的服务器并请求所有服务器同步。



/lp import

权限: luckperms.import
参数:

  • <file> - 导入的文件

从文件导入 LuckPerms 的数据,文件必须是一列命令,以 "/luckperms" 开头,这个文件可以使用 export 命令生成,文件必须在插件的目录下。



/lp export

权限: luckperms.export
参数:

  • <file> - 导出的文件

将 LuckPerms 的数据导出到一个文件,这个文件也可以作为一个备份,或者在 LuckPerms 的安装之间转移数据。这个文件可以使用 import 命令重新导入,生成的文件在插件的目录下。



/lp reloadconfig

权限: luckperms.reloadconfig
重载配置文件的部分值。不是所有的条目都会被这个命令重载,有些需要一次完全的服务器重启才能生效(比如存储的设置)。



/lp bulkupdate

权限: 仅控制台
允许你执行一次对所有权限数据的块编辑。详细的指南可以在这里找到。



/lp migration

权限: luckperms.migration
迁移系统使用的主命令。允许你从其他的权限插件导入权限数据,更多的关于这个特性的信息可以在这里找到。



/lp creategroup

权限: luckperms.creategroup
参数:

  • <name> - 组的名称

创建一个新的组。



/lp deletegroup

权限: luckperms.deletegroup
参数:

  • <name> - 组的名称

永久的删除一个组。



/lp listgroups

权限: luckperms.listgroups
显示当前的所有的组。



/lp createtrack

权限: luckperms.createtrack
参数:

  • <name> - 路线名称

创建新的路线。



/lp deletetrack

权限: luckperms.deletetrack
参数:

  • <name> - 路线的名称

永久删除一个路线。



/lp listtracks

权限: luckperms.listtracks
显示当前所有的路线。



用户 (/lp user <user> ...)

/lp user <user> info

权限: luckperms.user.info
显示一个用户的信息,包括用户名,主组,继承组,和当前的上下文。



/lp user <user> editor

权限: luckperms.user.editor
开启编辑指定的用户的权限的网页接口,当更改保存后,你将会收到一条命令,使用后使更改生效。



/lp user <user> switchprimarygroup

权限: luckperms.user.switchprimarygroup
参数:

  • <group> - 切换的组

这个命令允许你更改用户的主组,如果他们还不是这个组的成员,他们将被添加到新的组。这不应该作为 "parent set" 命令的替代,他们的现有的主组将不会被移除,而是作为继承组(一个用户可以有多个继承组)。

如果 primary-group-calculation 选项被设置为不是 "stored" 的其他东西,你应该使用 parent add(#lp-usergroup-usergroup-parent-add) 或者 parent set(#lp-usergroup-usergroup-parent-set) 命令而不是这个命令。



/lp user <user> promote

权限: luckperms.user.promote
参数:

  • <track> - 升级遵循的路线 * [context...] - 升级使用的上下文

这个命令将会沿着一条路线提升玩家,命令会检查玩家在给出的上下文里是否在这个路线上,如果用户没有在这条路线,他们将会被加入这条路线的第一个组,如果玩家在这条路线上的不止一个组,命令将会执行失败。在其他情况下,玩家将会被成功提升,并将会被从现有的组移除。如果路线动作影响了用户的主组,他们也会被更新。



/lp user <user> demote

权限: luckperms.user.demote
参数:

  • <track> - 降级的遵循的路线 * [context...] - 降级使用的上下文

这个命令将会沿着一条路线降级玩家,命令会检查玩家在给出的上下文里是否在这个路线上,如果用户没有在这条路线,或者玩家在这条路线上的不止一个组,命令将会执行失败。在其他情况下,玩家将会被成功降级,并将会被从现有的组移除。如果路线动作影响了用户的主组,他们也会被更新。



/lp user <user> showtracks

权限: luckperms.user.showtracks
显示玩家当前所在的全部路线。



/lp user <user> clear

权限: luckperms.user.clear
参数:

  • [context...] - 用于过滤的上下文

清除玩家的权限,继承组和元数据。



组 (/lp group <group> ...)

/lp group <group> info

权限: luckperms.group.info
显示一个组的信息。



/lp group <group> editor

权限: luckperms.group.editor
开启编辑指定的组的权限的网页接口,当更改保存后,你将会收到一条命令,使用后使更改生效。



/lp group <group> listmembers

权限: luckperms.group.listmembers
参数:

  • [page] - 查看的页数

显示直接继承这个组的用户/组



/lp group <group> setweight

权限: luckperms.group.setweight
参数:

  • <weight> - 设置的权重

设置组的权重值,这决定了决定用户的权限的顺序。越大的值代表越高的权重。



/lp group <group> showtracks

权限: luckperms.group.showtracks
显示一个组所在的所有的路线。



/lp group <group> clear

权限: luckperms.group.clear
参数:

  • [context...] - 用于过滤的上下文

清除组的权限,继承组和元数据。



/lp group <group> rename

权限: luckperms.group.rename
参数:

  • <new name> - 组的新的名称

更改组的名称,注意任何组的成员都不会知道这个变更,他们还将在原来的旧组的组名。如果你希望更新这些状态,你应该使用块变更特性来更新存在的条目。



/lp group <group> clone

权限: luckperms.group.clone
参数:

  • <new name> - 复制的名称

创建一个组的不同名称的拷贝。



权限 (/lp user <user> permission ... | /lp group <group> permission ...)

/lp user/group <user|group> permission info

权限: luckperms.user.permission.info 或 luckperms.group.permission.info
显示一个用户/组拥有的所有的权限。



/lp user/group <user|group> permission set

权限: luckperms.user.permission.set or luckperms.group.permission.set
参数:

  • <node> - 设置的权限节点 * <true|false> - 设置权限的值 * [context...] - 设置权限的上下文

设置(或给予)某个用户/组一个权限,提供 false 值将会否定这个权限。



/lp user/group <user|group> permission unset

权限: luckperms.user.permission.unset or luckperms.group.permission.unset
参数:

  • <node> - 取消设置的权限节点 * [context...] - 取消设置权限的上下文

取消设置一个用户或组的权限节点。



/lp user/group <user|group> permission settemp

权限: luckperms.user.permission.settemp or luckperms.group.permission.settemp
参数:

  • <node> - 设置的权限节点 * <true|false> - 设置的权限的值 * <duration> - 权限过期的时间 * [context...] - 权限设置的上下文

给一个玩家/组设置临时权限,提供 false 值将会否定这个权限。持续时间应为时间段或者一个标准的 Unix 时间戳,比如 "3d13h45m" 将会设置权限在 3 天, 13 小时 45 分钟后过期。"1482694200" 会设置过期时间为 7:30PM 于 25th December 2016。



/lp user/group <user|group> permission unsettemp

权限: luckperms.user.permission.unsettemp or luckperms.group.permission.unsettemp
参数:

  • <node> - 取消设置的权限节点 * [context...] - 取消设置权限的上下文

取消设置一个用户或组的临时权限节点。



/lp user/group <user|group> permission check

权限: luckperms.user.permission.check or luckperms.group.permission.check
参数:

  • <node> - 检查的权限节点 * [context...] - 检查的权限节点的上下文

检查一个组或者玩家有特定的权限



/lp user/group <user|group> permission checkinherits

权限: luckperms.user.permission.checkinherits or luckperms.group.permission.checkinherits
参数:

  • <node> - 检查的权限节点 * [context...] - 检查的权限节点的上下文

检查一个组或者玩家继承了特定的权限,如果是,从哪里继承的。



继承组 (/lp user <user> parent ... | /lp group <group> parent ...)

/lp user/group <user|group> parent info

权限: luckperms.user.parent.info or luckperms.group.parent.info
显示一个用户/组的继承的组



/lp user/group <user|group> parent set

权限: luckperms.user.parent.set or luckperms.group.parent.set
参数:

  • <group> - 设置的组 * [context...] - 设置的组的上下文

设置一个用户/组的继承组,不像是 "parent add" 命令,这个命令将会清空所有已经存在的组。"add" 命令只会简单的将组添加到已经存在的组里,如果命令执行时没有上下文环境,这个插件也会更新玩家的主组。



/lp user/group <user|group> parent add

权限: luckperms.user.parent.add or luckperms.group.parent.add
参数:

  • <group> - 添加的组 * [context...] - 添加的组用的上下文

添加一个集成组到一个玩家/组,不像是 "parent set" 命令,这个命令只会将组添加进已经存在的组的列表。没有已经存在的继承组会被移除,用户的主组也不会被影响。



/lp user/group <user|group> parent remove

权限: luckperms.user.parent.remove or luckperms.group.parent.remove
参数:

  • <group> - 移除的组 * [context...] - 移除的组的上下文

移除一个用户/组的继承组。



/lp user/group <user|group> parent settrack

权限: luckperms.user.parent.settrack or luckperms.group.parent.settrack
参数:

  • <track> - 设置的路线 * <group> - 设置的组,或者这个路线的组的相对位置 * [context...] - 设置的组的上下文

设置用户/组在给出的路线的位置,这个跟 set 命令相同,除了这个将会清除在指定的路线上已经存在的组,其他继承组不会被影响。



/lp user/group <user|group> parent addtemp

权限: luckperms.user.parent.addtemp or luckperms.group.parent.addtemp
参数:

  • <group> - 添加的组 * <duration> - 组的过期时间 * [context...] - 添加组的上下文

给一个玩家/组添加临时继承组。持续时间应为时间段或者一个标准的 Unix 时间戳,比如 "3d13h45m" 将会设置权限在 3 天, 13 小时 45 分钟后过期。"1482694200" 会设置过期时间为 7:30PM 于 25th December 2016。



/lp user/group <user|group> parent removetemp

权限: luckperms.user.parent.removetemp or luckperms.group.parent.removetemp
参数:

  • <group> - 移除的组 * [context...] - 移除的组的上下文

移除一个用户/组的临时继承组。



/lp user/group <user|group> parent clear

权限: luckperms.user.parent.clear or luckperms.group.parent.clear
参数:

  • [context...] - 用于过滤的上下文

移除所有继承组。



/lp user/group <user|group> parent cleartrack

权限: luckperms.user.parent.cleartrack or luckperms.group.parent.cleartrack
参数:

  • <track> - 移除的路线 * [context...] - 用于过滤的上下文

移除指定路线的玩家/组的所有继承组。



元数据 (/lp user <user> meta ... | /lp group <group> meta ...)

/lp user/group <user|group> meta info

权限: luckperms.user.meta.info or luckperms.group.meta.info
显示用户/组的继承元数据,前缀和后缀。



/lp user/group <user|group> meta set

权限: luckperms.user.meta.set or luckperms.group.meta.set
参数:

  • <key> - 设置的键值 * <value> - 设置的键值的值 * [context...] - 设置的元数据的上下文

设置用户/组的键值对元数据,这些值可以用于读取并且可以通过其他使用 Vault 或者 Sponge Permissions API 的插件更改。



/lp user/group <user|group> meta unset

权限: luckperms.user.meta.unset or luckperms.group.meta.unset
参数:

  • <key> - 取消设置的键 * [context...] - 取消设置的元数据的上下文

取消设置一个用户或组的元数据键值。



/lp user/group <user|group> meta settemp

权限: luckperms.user.meta.settemp or luckperms.group.meta.settemp
参数:

  • <key> - 设置的键值 * <value> - 设置的键的值 * <duration> - 元数据过期的时间 * [context...] - 设置的元数据的上下文

给一个玩家/组设置临时元数据键值,提供 false 值将会否定这个权限。持续时间应为时间段或者一个标准的 Unix 时间戳,比如 "3d13h45m" 将会设置权限在 3 天, 13 小时 45 分钟后过期。"1482694200" 会设置过期时间为 7:30PM 于 25th December 2016。



/lp user/group <user|group> meta unsettemp

权限: luckperms.user.meta.unsettemp or luckperms.group.meta.unsettemp
参数:

  • <key> - 取消设置的键 * [context...] - 取消设置的元数据的上下文

取消设置一个用户或组的临时元数据。



/lp user/group <user|group> meta addprefix

权限: luckperms.user.meta.addprefix or luckperms.group.meta.addprefix
参数:

  • <priority> - 添加前缀的优先度 * <prefix> - 实际的前缀字符串 * [context...] - 添加前缀的上下文

给一个玩家/组设置前缀,使用 " " 来添加空格。



/lp user/group <user|group> meta addsuffix

权限: luckperms.user.meta.addsuffix or luckperms.group.meta.addsuffix
参数:

  • <priority> - 添加后缀的优先度 * <suffix> - 实际的后缀字符串 * [context...] - 添加后缀的上下文

给一个玩家/组设置后缀,使用 " " 来添加空格。



/lp user/group <user|group> meta removeprefix

权限: luckperms.user.meta.removeprefix or luckperms.group.meta.removeprefix
参数:

  • <priority> - 移除前缀的优先度 * <prefix> - 实际的前缀字符串 * [context...] - 添加前缀的上下文

给一个玩家/组移除前缀,使用 " " 来添加空格。



/lp user/group <user|group> meta removesuffix

权限: luckperms.user.meta.removesuffix or luckperms.group.meta.removesuffix
参数:

  • <priority> - 移除后缀的优先度 * <suffix> - 实际的后缀字符串 * [context...] - 添加后缀的上下文

给一个玩家/组移除后缀,使用 " " 来添加空格。



/lp user/group <user|group> meta addtempprefix

权限: luckperms.user.meta.addtempprefix or luckperms.group.meta.addtempprefix
参数:

  • <priority> - 添加前缀的优先度 * <prefix> - 实际的前缀字符串 * <duration> - 前缀过期的时间 * [context...] - 添加前缀的上下文

给一个玩家/组设置临时前缀,提供 false 值将会否定这个权限。持续时间应为时间段或者一个标准的 Unix 时间戳,比如 "3d13h45m" 将会设置权限在 3 天, 13 小时 45 分钟后过期。"1482694200" 会设置过期时间为 7:30PM 于 25th December 2016。



/lp user/group <user|group> meta addtempsuffix

权限: luckperms.user.meta.addtempsuffix or luckperms.group.meta.addtempsuffix
参数:

  • <priority> - 添加后缀的优先度 * <suffix> - 实际的后缀字符串 * <duration> - 后缀过期的时间 * [context...] - 添加后缀的上下文

给一个玩家/组设置临时后缀,提供 false 值将会否定这个权限。持续时间应为时间段或者一个标准的 Unix 时间戳,比如 "3d13h45m" 将会设置权限在 3 天, 13 小时 45 分钟后过期。"1482694200" 会设置过期时间为 7:30PM 于 25th December 2016。



/lp user/group <user|group> meta removetempprefix

权限: luckperms.user.meta.removetempprefix or luckperms.group.meta.removetempprefix
参数:

  • <priority> - 移除前缀的优先度 * <prefix> - 实际的前缀字符串 * [context...] - 添加前缀的上下文

给一个玩家/组移除临时前缀,使用 " " 来添加空格。



/lp user/group <user|group> meta removetempsuffix

权限: luckperms.user.meta.removetempsuffix or luckperms.group.meta.removetempsuffix
参数:

  • <priority> - 移除后缀的优先度 * <suffix> - 实际的后缀字符串 * [context...] - 添加后缀的上下文

给一个玩家/组移除临时后前缀,使用 " " 来添加空格。



/lp user/group <user|group> meta clear

权限: luckperms.user.meta.clear or luckperms.group.meta.clear
参数:

  • [context...] - 用于过滤的上下文

移除所有的元数据,前后缀。



路线 (/lp track <track> ...)

/lp track <track> info

权限: luckperms.track.info
显示路线中的组。



/lp track <track> append

权限: luckperms.track.info
参数:

  • <group> - 添加的组

在路线结尾追加一个组。



/lp track <track> insert

权限: luckperms.track.insert
参数:

  • <group> - 插入的组 * <position> - 插入的组的位置

在指定的路线的位置插入一个组,为 1 的位置将会是路径的开始。



/lp track <track> remove

权限: luckperms.track.remove
参数:

  • <group> - 移除的组

从路线移除一个组。



/lp track <track> clear

权限: luckperms.track.clear
移除路线中的所有的组。



/lp track <track> rename

权限: luckperms.track.rename
参数:

  • <new name> - 路线的新名称

更改路线的名称。



/lp track <track> clone

权限: luckperms.track.clone
参数:

  • <new name> - 拷贝的名称

创建路线的不同名称的拷贝。



日志 (/lp log ...)

/lp log recent

权限: luckperms.log.recent
参数:

  • [user] - 用于过滤的名称、UUID * [page] - 查看的页数

显示最近的动作。



/lp log search

权限: luckperms.log.search
参数:

  • <query> - 查询的查询 * [page] - 查看的页数

搜索匹配查询的所有日志条目。



/lp log notify

权限: luckperms.log.notify
参数:

  • [on|off] - 是否开启

开关向发送者发送提醒的功能。



/lp log export

权限: luckperms.log.export
参数:

  • <file> - the file to export to

将日志导出为一列命令,可以被 "/lp import" 命令识别,这个特性应该尽量不使用,推荐使用 "/lp export" 命令。



/lp log userhistory

权限: luckperms.log.userhistory
参数:

  • <user> - 搜索的玩家 * [page] - 查看的页数

搜索有关给出玩家的日志。



/lp log grouphistory

权限: luckperms.log.grouphistory
参数:

  • <group> - 搜索的组 * [page] - 查看的页数

搜索有关给出组的日志。



/lp log trackhistory

权限: luckperms.log.trackhistory
参数:

  • <track> - 搜索的路线 * [page] - 查看的页数

搜索有关给出路线的日志。



指令权限

注意: 你可以使用通配符 * All commands - luckperms. All user commands - luckperms.user. All group commands - luckperms.group. All track commands - luckperms.track. All log commands - luckperms.log.*

基础
  • luckperms.sync
  • luckperms.info
  • luckperms.verbose
  • luckperms.tree
  • luckperms.search
  • luckperms.check
  • luckperms.import
  • luckperms.export
  • luckperms.reloadconfig
  • luckperms.migration
  • luckperms.creategroup
  • luckperms.deletegroup
  • luckperms.listgroups
  • luckperms.createtrack
  • luckperms.deletetrack
  • luckperms.listtracks
用户
  • luckperms.user.info
  • luckperms.user.permission.info
  • luckperms.user.permission.set
  • luckperms.user.permission.unset
  • luckperms.user.permission.settemp
  • luckperms.user.permission.unsettemp
  • luckperms.user.permission.check
  • luckperms.user.permission.checkinherits
  • luckperms.user.parent.info
  • luckperms.user.parent.set
  • luckperms.user.parent.add
  • luckperms.user.parent.remove
  • luckperms.user.parent.addtemp
  • luckperms.user.parent.removetemp
  • luckperms.user.parent.clear
  • luckperms.user.meta.info
  • luckperms.user.meta.set
  • luckperms.user.meta.unset
  • luckperms.user.meta.settemp
  • luckperms.user.meta.unsettemp
  • luckperms.user.meta.addprefix
  • luckperms.user.meta.addsuffix
  • luckperms.user.meta.removeprefix
  • luckperms.user.meta.removesuffix
  • luckperms.user.meta.addtempprefix
  • luckperms.user.meta.addtempsuffix
  • luckperms.user.meta.removetempprefix
  • luckperms.user.meta.removetempsuffix
  • luckperms.user.meta.clear
  • luckperms.user.editor
  • luckperms.user.switchprimarygroup
  • luckperms.user.showtracks
  • luckperms.user.promote
  • luckperms.user.demote
  • luckperms.user.clear
  • luckperms.group.info
  • luckperms.group.permission.info
  • luckperms.group.permission.set
  • luckperms.group.permission.unset
  • luckperms.group.permission.settemp
  • luckperms.group.permission.unsettemp
  • luckperms.group.permission.check
  • luckperms.group.permission.checkinherits
  • luckperms.group.parent.info
  • luckperms.group.parent.set
  • luckperms.group.parent.add
  • luckperms.group.parent.remove
  • luckperms.group.parent.addtemp
  • luckperms.group.parent.removetemp
  • luckperms.group.parent.clear
  • luckperms.group.meta.info
  • luckperms.group.meta.set
  • luckperms.group.meta.unset
  • luckperms.group.meta.settemp
  • luckperms.group.meta.unsettemp
  • luckperms.group.meta.addprefix
  • luckperms.group.meta.addsuffix
  • luckperms.group.meta.removeprefix
  • luckperms.group.meta.removesuffix
  • luckperms.group.meta.addtempprefix
  • luckperms.group.meta.addtempsuffix
  • luckperms.group.meta.removetempprefix
  • luckperms.group.meta.removetempsuffix
  • luckperms.group.meta.clear
  • luckperms.group.editor
  • luckperms.group.listmembers
  • luckperms.group.showtracks
  • luckperms.group.setweight
  • luckperms.group.clear
  • luckperms.group.rename
  • luckperms.group.clone
路线
  • luckperms.track.info
  • luckperms.track.append
  • luckperms.track.insert
  • luckperms.track.remove
  • luckperms.track.clear
  • luckperms.track.rename
  • luckperms.track.clone
日志
  • luckperms.log.recent
  • luckperms.log.search
  • luckperms.log.notify
  • luckperms.log.export
  • luckperms.log.userhistory
  • luckperms.log.grouphistory
  • luckperms.log.trackhistory

从其他插件迁移数据

LuckPerms 有内置的支持其他的权限插件轻松迁移到 LuckPerms 的功能。

开始之前

需要注意的是这个系统还不是那么的完美,在绝大多数情况下,它在转变数据时相当不错,但是不是所有的数据都是相同的,并且有时我可能没有考虑这么多。

LuckPerms 有和其他权限插件相同的地方,但是有些部分从根本上不同,有些迁移运用了一些技巧。

另外,让插件迁移你的所有的数据意味着你没有机会学习任何一个 LuckPerms 命令,这可能会是一个麻烦的地方,如果你是从 PermissionsEx 或者 GroupManager 迁移来的数据,你应该看看 GM PEX 的等同命令

如果你使用了老版本的权限插件,或者你根本不喜欢的,现在可能是一个机会来重新构建清理,顺便学习 LuckPerms 的命令!

不?!就喜欢你现在的权限插件?让我们来迁移。

目前支持的插件

Bukkit / Spigot BungeeCord Sponge
GroupManager BungeePerms PermissionsEx
PermissionsEx PermissionManager
zPermissions
PowerfulPerms
bPermissions

= 怎么做

迁移的处理很简单,但是每个平台可能有不同。

  1. 将 LuckPerms jar 文件放入你的服务器文件夹。
  2. 保证两个权限插件的文件夹在同一个文件夹里(现在还不要卸载)
  3. 开启服务器,你可以在活跃的服务器来进行这个操作,但是我建议在没有人的服务器上进行。

运行一下命令: lp migration <插件名>

有些插件需要你填写额外的选项/标签,如果需要,你会在迁移之前被通知。

接着只需要让 LuckPerms 处理剩下的事了!你将会被提示迁移进度,完成时也会被提示。

当处理完成,停止服务器,移除其他权限插件的 jar,再次开启你的服务器。

控制台的输出一定是冗长繁杂的,以 "(LP) LOG" 开头的命令都可以忽略,但是栈堆信息不应该忽略(一般表示出现了什么问题)。如果你的迁移输出含有栈堆信息,请反馈给我,更多的信息在这一个页面的底部。

PowerfulPerms

处理 PowerfulPerms 的过程更加复杂。

玩家的信息只有在加入服务器时才被加载,插件 API 没有方法一次性获得所有的玩家的数据。

这意味着我们在导入数据时,我们必须得查询 PowerfulPerms MySQL 表来获得所有玩家的信息。

命令使用将会不同。

/luckperms migration powerfulperms [address] [database] [username] [password] [db table]

解释: * address = MySQL 服务器的 IP 地址,比如 127.0.0.1:3306 * database = PowerfulPerms 插件使用的数据库的名称 * username = SQL 服务器登入需要的用户名 * password = SQL 服务器登入需要的密码 * db table = 存储玩家数据的表名(尽管我们只关注 UUID 列表)

默认的表名,据我所知,是 "players",但是如果你添加了表名的前缀,你需要添加他们。

比如如果我的表的前缀是 "pp_",那么 db table = "pp_players"(不需要引号)

比如: /luckperms migration powerfulperms 127.0.0.1:3306 minecraft root passw0rd players

错误

如果这个命令不存在,请检查这个插件是否正确加载。

如果处理没有完成,并且打印了错误消息,请在 GitHub 提交 issue 或者 在这里联系我,我将尽力尽可能快的回复你。

GM&PEX对应等效指令

我编写这部分WIKI内容的目的是为了帮助用户们适应从GM/PEX到LuckPerm的转变, 这里我制作了一份对应等效指令的表格,方便用户随时查阅。

Group Manager

Group Manager 命令 LuckPerms 命令
manuadd <玩家> <组> lp user <玩家> parent set <组>
manudel <玩家> lp user <玩家> clear
manuaddsub <玩家> <组> lp user <玩家> parent add <组>
manudelsub <玩家> <组> lp user <玩家> parent remove <组>
manpromote <玩家> <组> lp user <玩家> promote <track>
mandemote <玩家> <组> lp user <玩家> demote <track>
manwhois <玩家> lp user <玩家> info
manuaddp <玩家> <权限> lp user <玩家> permission set <权限> true
manudelp <玩家> <权限> lp user <玩家> permission unset <权限>
manulistp <玩家> lp user <玩家> permission info
manucheckp <玩家> <权限> lp user <玩家> haspermission <权限>
manuaddv <玩家> prefix <值> lp user <玩家> meta addprefix <优先级> <值>
manuaddv <玩家> suffix <值> lp user <玩家> meta addsuffix <优先级> <值>
manuaddv <玩家> <变量> <值> lp user <玩家> meta set <变量> <值>
manudelv <玩家> <变量> lp user <玩家> meta unset <变量>
manulistv <玩家> lp user <玩家> meta info
mangadd <组> lp creategroup <组>
mangdel <组> lp deletegroup <组>
mangaddi <组1> <组2> lp group <组1> parent add <组2>
mangdeli <组1> <组2> lp group <组1> parent remove <组2>
listgroups lp listgroups
mangaddp <组> <权限> lp group <组> permission set <权限> true
mangdelp <组> <权限> lp group <组> permission unset <权限>
manglistp <组> lp group <组> permission info
mangcheckp <组> <权限> lp group <组> haspermission <权限>
mangaddv <玩家> prefix <值> lp group <组> meta addprefix <优先级> <值>
mangaddv <玩家> suffix <值> lp group <组> meta addsuffix <优先级> <值>
mangaddv <玩家> <变量> <值> lp group <组> meta set <变量> <值>
mangdelv <玩家> <变量> lp group <组> meta unset <变量>
manglistv <玩家> lp group <组> meta info
mansave lp sync
manload lp sync

PermissionsEx

PermissionsEx 命令 LuckPerms 命令
pex lp
pex reload lp sync
pex toggle debug lp verbose true
pex user <用户> check <权限> lp user <用户> haspermission <权限>
pex backend lp info
pex import <backend> lp export <file> / lp import <file>
pex set default group <组> (in the config file)
pex user <用户> list lp user <用户> permission info
pex user <用户> prefix lp user <用户> meta info
pex user <用户> prefix <前缀> lp user <用户> meta addprefix <优先级> <前缀>
pex user <用户> suffix lp user <用户> meta info
pex user <用户> suffix <后缀> lp user <用户> meta addsuffix <优先级> <后缀>
pex user <用户> delete lp user <用户> clear
pex user <用户> add <权限> <世界> lp user <用户> permission set <权限> true global <世界>
pex user <用户> remove <权限> <世界> lp user <用户> permission unset <权限> global <世界>
pex user <用户> timed add <权限> <时间> <世界> lp user <用户> permission settemp <权限> true <时间> global <世界>
pex user <用户> timed remove <权限> <时间> <世界> lp user <用户> permission settemp <权限> true <时间> global <世界>
pex user <用户> set <option> <值> <世界> lp user <用户> meta set <option> <值> global <世界>
pex user <用户> group list lp user <用户> parent info
pex user <用户> group add <组> <世界> lp user <用户> parent add <组> global <世界>
pex user <用户> group add <组> <世界> <时间> lp user <用户> parent addtemp <组> <时间> global <世界>
pex user <用户> group set <组> lp user <用户> parent set <组>
pex user <用户> group remove <组> <世界> lp user <用户> parent remove <组> global <世界>
pex groups list lp listgroups
pex group <组> list lp group <组> permission info
pex group <组> prefix lp group <组> meta info
pex group <组> prefix <前缀> lp group <组> meta addprefix <优先级> <前缀>
pex group <组> suffix lp group <组> meta info
pex group <组> suffix <后缀> lp group <组> meta addsuffix <优先级> <后缀>
pex group <组> create lp creategroup <组>
pex group <组> delete lp deletegroup <组>
pex group <组> parents list lp group <组> parent info
pex group <组> parents set <parents> lp group <组> parent add <parent>
pex group <组> add <权限> <世界> lp group <组> permission set <权限> true global <世界>
pex group <组> remove <权限> <世界> lp group <组> permission unset <权限> global <世界>
pex group <组> timed add <权限> <时间> <世界> lp group <组> permission settemp <权限> true <时间> global <世界>
pex group <组> timed remove <权限> <时间> <世界> lp group <组> permission settemp <权限> true <时间> global <世界>
pex group <组> set <option> <值> <世界> lp group <组> meta set <option> <值> global <世界>
pex group <组> user add <用户> lp user <用户> parent add <组>
pex group <组> user remove <用户> lp user <用户> parent remove <组>
pex promote <用户> <ladder> lp user <用户> promote <ladder>
pex demote <用户> <ladder> lp user <用户> demote <ladder>

常见问题

这些是我经常被问到的问题,我很高兴你在直接问我之前看了这些问题。

我在用 EssentialsChat 然后它不工作了

请确保你在使用最新版的 EssentialsX 并且你安装了 Vault。EssentialsX 的 X 是很重要的,老的版本不会工作。

我在哪里安装 LuckPerms 呢?

如果你在运行很多的服务器,你应该将 LuckPerms 放入每个服务器的 plugins 文件夹。

如果你想使用 BungeeCord 来应用权限,你需要将 LuckPermsBungee.jar 放入 BungeeCord 插件文件夹。

如果你选择只在 BungeeCord 安装 LuckPerms,他将不会影响任何 Spigot/Sponge 服务器的权限检查,如果你想要使用 LuckPerms,你必须将 LuckPerms 安装在这些服务器。

我可以只在 BungeeCord 安装 LuckPerms 吗?

在 BungeeCord 上的权限系统是完全独立于 Spigot/Sponge 服务器的。

如果你想让 Spigot/Sponge 的权限检查被 LuckPerms 处理的话,在每个 Spigot/Sponge 服务器都安装 LuckPerms。

如果你想让 BungeeCord 服务器的权限检查被 LuckPerms 处理,在 BungeeCord 服务器安装 LuckPerms。

你可以在 BungeeCord 安装 LuckPerms,但是 Spigot/Sponge 服务器的权限检查将不会被 LuckPerms 处理。

我应该怎样在多个服务器中同步权限呢?

将每个 LuckPerms 连接到同一个 MySQL/MongoDB 服务器,你可以使用 /luckperms sync 来从数据库获得最后的权限更新。你也可以 建立一个通讯服务 来立刻在你的服务器之间同步更改。

LuckPerms 不能连接到我的 Redis 服务器

检查以下是否正常:

  • 你正在使用正确的地址和端口
  • 你的密码是正确的
  • 没有防火墙规则阻拦了连接
  • Redis 服务器正在运行

LuckPerms 不能连接到我的 MySQL 服务器

检查以下是否正常:

  • 你正在使用正确的地址和端口
  • 你使用了正确的用户名 / 密码
  • 数据库存在并且用户可以访问
  • 该服务器在线并且接受连接
  • 没有防火墙规则阻拦了连接
  • MySQL 正确绑定了端口,并且安装 LuckPerms 的服务器可以访问
  • 检查 MySQL 的连接限制没有超过,默认 LuckPerms 会使用 10 个连接,如果你有过多的插件连接了同一个服务器,你需要增加这个限制。

如果你得到了 Communications link failure 的错误,或者由于超时导致的错误,那么上面的有一条是不正常的。

给玩家 LuckPerms 表的权限,使用

GRANT ALL PRIVILEGES ON [databasename].* TO '[username]'@'[ipaddress]';

记得替换 [ ] 里的东西。

比如:

GRANT ALL PRIVILEGES ON luckperms.* TO 'luck'@'%';

接着当你完成这个更改后,使用

FLUSH PRIVILEGES;

特性

权限检查系统(Verbose)

你曾经经历过想要找到某条命令或某种特性的使用权限,但找不到作者提供的帮助文档这种情况吗?

可能作者提供的帮助文档过期了,或是内含的信息不正确。可能你想要修复玩家没有正确权限的问题,或是仅仅是对插件所检查的权限感兴趣……

权限检查系统能够让你监视一段时间内的权限检查操作!😄

如何使用本系统

指令的使用方法如下:

/lp verbose <on|record|off|paste> [filter]

第一个参数会启用/禁用本系统,第二个参数设置权限筛选器。

选项 描述
on 启用本系统,并且在设置的筛选权限被检查时会发消息提示您。
record 与“on”的作用相同,但是您的聊天框不会收到提醒。
off 会禁用本系统,清除内存中所有的存储记忆。
paste 与“off”的作用相同,但是会将最先的500个结果上传到一个网页上,然后提供给你一个链接。

筛选器

筛选器是用来匹配权限节点的工具,它会过滤掉你不需要的权限。它可以筛选玩家名,或更高级的东西。

筛选器输入的字符能够匹配所有带有该字符的权限的开头,或是玩家的全名。

你可以使用 & (表示 和), | (表示 或), 和 ! (表示 非)来设置筛选文本,输入时也支持使用小括号 ( )

一些使用示例
  • Luck & (essentials | worldedit) —— 会匹配玩家“Luck”的所有以“essentials”或“worldedit”开头的权限检查
  • Luck & !anticheat —— 会匹配玩家“Luck”所有不以“anticheat”为开头的权限检查
  • anticheat & !anticheat.check —— 会匹配所有玩家以“anticheat”开头,但不是 "anticheat.check" 权限的权限检查

示例

我使用了指令 /lp verbose record Luck & minecraft,这打开了权限检查系统,然后会检查 "Luck" 玩家所有以 "minecraft" 开头的权限。

然后我使用了 /help 命令(来让服务器对我进行权限检查),然后我输入了 /lp verbose paste

然后插件就会将检查的结果上传,然后返回了这个链接。https://git.io/vDUba

如果你点开这个链接看看的话,你会看到检查的结果的。 😄

在Metadata数据信息下面,你会看到一些有关于检查的数据。

你可以注意到 Count: 58 / 72,这就是说在这段检查期间,共检查了72条权限,其中58条符合你设定的筛选器。

那些满足筛选器的检查结果已经列出来了。

大量编辑

LuckPerms 提供了一个命令来帮助执行大量的权限编辑,这个命令应该小心使用,因为很容易破坏你的所有信息。

在执行这个命令之前做一个备份可能是个明智的选择,或者是给你的数据库做个备份,或者使用 export 命令。

命令的设计基于 SQL 格式,这意味着命令可以直接转换为一条 SQL 查询语句,或者在 YAML 或者 JSON 文本编辑。那些对 SQL 语句有经验的人可能会发现在数据库服务器直接写入查询比使用命令更简单。

这些命令只能在控制台使用。这是因为这些命令可能会对你的服务器造成极大的伤害。在执行之前,你会被要求输入一个确认码,用于防止 "sudo" 来通过这些命令获得权限。

命令用法如下...

/lp bulkupdate <data type> <action> [action field] [action value] [constraint...]

一开始有点令人害怕,我知道,拆开来看...

参数 描述
data type 更改的数据 (可以是 "all", "users" 或者 "groups")
action 对数据执行的操作 (可以是 "update" 或者 "delete")
action field 只可用于 update 操作 (可以是 "permission", "server" 或 "world")
action value 替换的值,只可用于 update 操作
constraint update 的约束

data type 是最简单的,只是简单的告诉了 LuckPerms 这个操作应该影响什么数据。

action 是对数据执行的操作。可以是 "update" 或 "delete"。delete 就是简单的删除满足约束的所有的记录。Update 将会将原来的值替换为新的值。

action fieldaction value 参数是可选的,因为只对 update 有效。field 是用来更新的东西,而 value 是用来替换的东西。

constraints 参数与 update 的限制有关,只有权限(或者条目)匹配约束才会被影响。

约束

约束分为 3 部分,field, comparisonvalue

可用的 fieldspermission, serverworld。权限就只是存储在文件中的权限节点(记住甚至组的关系和前缀都是存储在前缀的)。server 和 world 与 permission 应用的世界和服务器有关。如果权限没有他们的值,那么就是全局。

value 部分的约束是需要的 field,用于比较。

有四种比较的方式。

比较符号 比较的名称 描述
== 等于 两个值相同(忽略大小写)
!= 不等于 两个值不相同(忽略大小写)
~~ 相似 两个值相似,与SQL的 LIKE 关键字相同
!~ 不相似 两个值不相似,与SQL的 LIKE 关键字相同

更多的有关相似的信息可以在这里这里找到。

基础的大概是这样的: * % - 百分号代表 0 到多个字符 * _ - 下划线代表一个字符

一些示例
  • server ~~ hub_ 匹配 "hub1", "hub2", "hub3" 等
  • permission !~ group.% 匹配任何不以 group 开头的权限
  • world == nether 匹配世界名为 nether

当在命令中使用约束,必须使用 " " 引号包围。

命令示例

/lp bulkupdate all update permission group.mod "permission == group.moderator"

更新所有的条目,替换所有的 "group.moderator" 为 "group.mod"(效率重命名)。

/lp bulkupdate user delete "server ~~ hub%" "world == nether"

删除任何分配给以 "hub" 开头的服务器,并且世界是 "nether" 的玩家的权限。

/lp bulkupdate all delete "permission == essentials.fly"

删除所有 "essentials.fly" 的权限

/lp bulkupdate all update server global "server == factions"

更改所有服务器 "factions" 条目为 "global"。

希望你理解了这个意思,如果你不确定如何构建一个你想要应用的命令,请随意使用 Wiki 主界面的联系方式联系我。

即时更新权限变更

介绍

如果你在群组服务器上运行LuckPerms的话,有时你会遇到这样的问题——你在一个服务器上做下了更改,但是这更改不会“传播”到你网络中的其他服务器中。

这一页就是教你怎么修复这个问题的。

当然,如果你只有一个服务器运行LuckPerms插件,或是你的服务器不使用普通的储存方法(连接到一个相同的数据库)的话,你不需要看这些。

同步间隔

你能够设置同步间隔,这会执行能够不断重复获得存储系统内的数据的任务。

本选项默认的值是 -1 (也就是说默认是禁用的)

data:

  ...

#此选项控制 LuckPerms 多长时间进行一次同步任务。

#同步任务将会刷新存储中的所有信息,保证插件使用的是最新的数据。

#这个选项默认关闭,因为大多数的用户都是不需要这个功能的,但是如果你使用远程存储,又没有设置信息服务,那么你可能将其设置为像 3 这样的数值。

#设置为 -1 来完全停用这个任务。
  sync-minutes: -1

你能够将这个值改成你想要的。

监视文件

如果你使用以文件为基础的存储类型的话(JSON或YAML),LuckPerms能够监视那些数据文件的更改,然后自动检测是否做出了改变。

#当使用基于文件的存储系统,LuckPerms将会监视数据文件的变化,并在文件变化被检测到的时候自动规划更新数据、

#如果不想让这个发生,那么将此选项设置为 false。
watch-files: true

这也就是说你只要更改一个数据文件就好了,然后按下保存按钮,然后你的更改就会被应用到整个群组服中了。

/lp sync

/lp sync 命令能够强制让插件执行一次上述提到的更新任务。

能够从数据库或文件读取最新的数据信息。

这个命令对于使用文件储存来说也是很有用的,因为它能够请求更新。

信息传递服务

在更改设定之后,你可以使用 /lp networksync 命令来让群组服中所有其他服务器应用更改。

当前支持

服务 描述
Bungee 使用插件所提供的信息传递隧道来在你的BungeeCord网络中传递更改
Lilypad 使用 LilyPad 的连接子服系统来在你的LilyPad网络中传递更改
Redis 使用 Redis Pub Sub 来在所有连接的服务器中传递更改
Bungee
messaging-service: bungee

你必须在你的代理服务器上安装LuckPerms插件,然后将上述的设置在所有配置文件中都启用。本选项不支持跨BungeeCord代理服务器传递信息,在这种情况下你应该使用Redis群组服。

LilyPad
messaging-service: lilypad

你需要在你的服务器上安装 LilyPad-Connect 插件。

Redis
messaging-service: redis

# Settings for Redis.
# Port 6379 is used by default; set address to "host:port" if differs
redis:
  enabled: true
  address: localhost
  password: ''

你需要按照你服务器的实际情况来设置你的Redis群组服相关设置,然后在redis小节填写你的服务器的地址和密码。

请确保你的防火墙设置设置地恰当,来防止你的Redis群组服拒绝访问。

切换存储 & 备份

如何做

切换存储是很简单的。

  1. 第一,运行 /luckperms export <file>
  2. 接着,完全停止你的服务器
  3. 编辑你的配置文件,更改存储类型
  4. 开启你的服务器,等待数据存储的初始化
  5. 接着,使用 /luckperms import <file>
  6. 所有的数据已经迁移到新的数据存储中了

<file> 是你想用来存储/加载的文件的名称,文件位于 LuckPerms 的数据文件夹里。你可以任意命名,只要在 import 命令中正确填写。

备份

你可以使用这个特性来备份所有你的 LuckPerms 的数据,只需要运行 export 命令,将文件保存到一个安全的地方。

这是怎么工作的?

export 命令将所有的数据转换为一串命令,处理后将会重建你的安装,import 命令只是将每个命令运行一遍,这意味着你可以只导出/导入一小部分数据,你删掉不需要的一部分就可以了。

权限组路线

虽然其他一些插件也提供了一些相似的功能,LuckPerms 插件拥有它自己独特的权限组路线系统。

请将“权限组路线”试做一种“梯子”或“晋升路线”。

示例 1

我创建了一个叫做“staff”的权限组路线,这权限树包括以下组:

default :arrow_right: helper :arrow_right: mod :arrow_right: admin

然后我就能使用权限组路线来为玩家升级或降级。

例如,玩家“Notch”在helper权限组里,我想将他升到“mod”组,我需要运行

/luckperms user Notch promote staff

示例 2

我又为赞助商新建了一个权限组路线,包括以下组:

default :arrow_right: iron :arrow_right: gold :arrow_right: diamond

当玩家购买了“权限组提升”这类的东西时,我能使用权限组路线为玩家晋升权限等级。

/luckperms user Luck promote donator

要想让玩家在某条权限组路线中降级的话,请使用降级命令。

创建权限组路线

请运行 /luckperms createtrack <name> 命令,然后使用 /luckperms track <name> append <group> 来将权限组加入路线中。

帮助编辑路线的命令也还有几条,你可以在命令使用页面找到。

前缀,后缀与元数据

这教程包括如何使用LuckPerms插件设置和管理玩家的前缀,后缀以及元数据。

如果你已经对这些概念很熟悉了,或是只想查看本插件如何实现更改,你应该阅读命令使用 页面的 “section” 小节。

关键术语

前缀/后缀

Minecraft服务器上的前缀和后缀代指你聊天用户名前后的文本。

举个例子,在下列的聊天中:

[Admin] Luck the great: Hello!

玩家的前缀是"[Admin] "部分,玩家的后缀是" the great"部分。

元数据

有时元数据指“选项”或“变量”,元数据是跟权限组有关的额外数据部分。与权限不同的是,元数据分成两部分,一部分是“关键字”,另一部分是“值”。

关键字就是元数据的名字,值就是关键字所代表的数据。

举个例子,我的用户有下列的元数据,这元数据代表我最多能设置5个家,然后我的用户名应该是蓝色的。

max-homes = 5
username-color: blue

是谁提供了对这些的支持?

一般来说,提供服务器管理权限的插件就有能够让你设置,管理和储存玩家的前缀,后缀和元数据的功能,这对于LuckPerms插件来说也一样。、

有时,提供这些设置的权限插件也能够直接在游戏中应用这些值。但是这对于LuckPerms来说不是它能做到的任务,你需要安装另一款额外的插件来在游戏聊天中应用,关于这点我们稍后详述。

前缀/后缀/元数据是怎么存储的

LuckPerms 插件将前缀和后缀转换成权限节点来存储。你可能会注意到当你给一位用户或一个权限组添加权限的恶化,他们的权限信息中会多出一条跟你设置的值相同的权限数据。为什么要这样做呢?好的,从编程的角度来说,让所有东西都储存在一个地方,用相同的格式,这样做更简单。这也意味着你能够简单的更改前缀和后缀,就像你改权限的方式一样。

前缀和后缀分成了两部分 * Weight —— 这是决定着前缀和后缀优先级的数值,较大的数代表着较大的优先级。 * Value —— 这是真正的前缀的值。

例如一个叫做 "[Admin] " 的前缀,优先级设置为100,转换成权限就是: "prefix.100.[Admin] "

对于元数据来说所使用的系统也相似,元数据组合 favourite-color = red ,转换成权限就是:"meta.favourite-color.red".

前缀和后缀的优先级是怎么工作的

前缀和后缀和权限一样,也能够继承。这意味着LuckPerms插件需要决定,当需要显示前缀或后缀时,真正为玩家显示哪一个。

当另外一款插件请求玩家的前缀或后缀时,LuckPerms插件会: * 收集玩家的所有前缀与后缀,包括继承的 * 根据他们的优先级来进行分类,高的优先级数值代表高的优先级 * 然后决定出最高优先级的前缀或后缀来为玩家展示

如果发现了两个相同优先级的前缀或后缀的话,最接近于用户的那一个会被使用,接近的意思就是插件在搜索继承数据时最先找到的那一个。

我怎么为玩家设置前缀或后缀

举个例子,如果我想让admin权限组的玩家拥有 "&c[Admin] " 前缀,在mod权限组的玩家拥有 "&d[Mod] " 前缀的话,我需要运行:

  • /lp creategroup admin
  • /lp creategroup mod
  • /lp group admin parent add mod
  • /lp group admin meta addprefix 100 "&c[Admin] "
  • /lp group mod meta addprefix 90 "&d[Mod] "

然后如果我决定想要将admin用户组的称号改为使用 "&4" 这个颜色代码的话,要想删除之前设定的值,我需要运行: * /lp group admin meta removeprefix 100

这会将所有设定给admin权限组的,优先级为100的前缀全部移除,然后我就能重新设置新的前缀值了。

对于临时设定用户前缀或后缀的方法和增加临时权限或临时权限组的方法差不多。

所有的权限使用方法可以在权限使用页面找到。增加和移除元数据的方法也列在了那里。

我怎么查看一位玩家或一个用户组所有的前缀或后缀

解决前缀或后缀相关问题最简单的方式就是使用info命令。

举个例子: /lp user Luck meta info。这会将用户所有的前缀,后缀和元数据,以及继承的相关信息列举出来。

按照优先级来排序,所以你就能很清楚的看到目前应用的值是哪一个。

另外一条有趣的命令就是玩家的全局信息命令: /lp user Luck info

如果玩家在服务器上在线的话,这会直接给你展示所提供给要读取LuckPerms信息的插件的前缀或后缀。

展示前缀和后缀

就像早些时候提到的那样,LuckPerms插件不会为你处理任何的聊天格式相关信息。

你需要安装额外的插件来做到这个。

下面为你列出了一些推荐的聊天管理插件。

Bukkit/Spigot

LuckPerms 目前已经支持所有能够从 Vault 插件读取信息的聊天管理插件了。

你需要在你的服务器上安装Vault来让其工作。

如果你发现某款插件所获取的数据不正确的话,请确保 /vault-info 插件输出的信息展示的数据是从LuckPerms插件处读取的。

一些较为受欢迎的,且支持Vault的聊天管理插件包括: * EssentialsXChat —— 原来的Essentials插件的升级复刻版本。(“X” 是很重要的!) * ChatEx * DeluxeChat —— 你能够使用Vault或LuckPerms所提供的Placeholder变量。 * ChatControl —— 也支持其他选项的设置来帮助管理聊天。

列举出所有可用的插件没有任何意义,再说一遍,所有支持Vault的聊天管理插件都支持LuckPerms!

BungeeCord =
Sponge


前缀与后缀的堆叠

这个功能能做什么?

“元数据堆叠”特性能够让你在玩家聊天中同时展示多个前缀或后缀。

你仍需要安装聊天管理类型的插件。

它怎么工作?

当聊天管理类插件请求要获取玩家的前缀或后缀时,取代返回玩家最高优先级的称号,LuckPerms能够应用一些你设定的规则来一起输出多个前缀或后缀。

默认的设置看起来是这样:

meta-formatting:
  prefix:
    format:
      - "highest"
    start-spacer: ""
    middle-spacer: " "
    end-spacer: ""
  suffix:
    format:
      - "highest"
    start-spacer: ""
    middle-spacer: " "
    end-spacer: ""

这些当前配置意味着,当请求前缀或后缀的时候,会返回最高优先级的那一个。

我怎么增加其他元素?

当前支持以下元素。

元素 描述
highest 从玩家拥有或继承的数据中选择最高优先级的值
lowest 和上面的工作原理相同,但是它会选择最低优先级的值
highest_own 选择最高优先级的值,但不支持继承来的值
lowest_own 和上面的工作原理相同,但是它会选择最低优先级的值
highest_on_track_<track> 选择继承于给予的权限组路线中的权限组所提供的最高优先级的值
lowest_on_track_<track> 和上面的工作原理相同,但是它会选择最低优先级的值
highest_not_on_track_<track> 选择不继承于给予的权限组路线中的权限组所提供的最高优先级的值
lowest_not_on_track_<track> 和上面的工作原理相同,但是它会选择最低优先级的值

一个示例

例如,在一个监狱服务器中,你可能有3种类型的权限组,一种是玩家“gameplay”权限组,一种是赞助商权限组,一种是管理员权限组。

如果玩家在三个组中,我想要展示三个前缀,举个例子: [Mine C] [Donor] [Admin] Luck: hi!.

但是如果玩家不在管理员权限组中,我想展示: [Mine C] [Donor] Luck: hi.

使用堆叠系统这些都可以实现。每个堆叠中的“元素”都需要添加到格式节内。

prefix:
  format:
    - "highest_on_track_prison"
    - "highest_on_track_donor"
    - "highest_on_track_staff"
  start-spacer: ""
  middle-spacer: " "
  end-spacer: ""

如果玩家在该元素中没有对应的值的话,它就会被堆叠系统自动无视。

你可以控制每个元素在开头,中间和结尾的分隔符,举个例子:

yml prefix: format: - "highest_on_track_prison" - "highest_on_track_donor" - "highest_on_track_staff" start-spacer: "★ " middle-spacer: " | " end-spacer: " "

... 这样的聊天结果会是: ★ [Mine C] | [Donor] | [Admin] Luck: hi.

显然你可以使用你的聊天管理插件来改变这些值,那些插件也会提供相似的选项。

高级设置

简介

LuckPerm总体来说虽然是相对简单的.. 你可以利用插件的一些特点与内部规则来制定一个适合你服务器情况的高等权限系统!

分服务器权限&分世界权限

LuckPerm本来是针对群组服的情况来工作的, 但是你可以自定义一些只在特定子服/特定世界才生效的权限。

= 配置中一些重要的选项说明

# The name of the server, used for server specific permissions. Set to 'global' to disable.
server: global

该项为设置服务器的名称,如果要想设置特定服务器的权限,则需要通过修改server项来命名服务器。 如果你愿意,同一个群组服是可以一起使用相同的服务器名的。

# If users on this server should have their global permissions/groups applied.
include-global: true

include-global选项也是非常重要的。

LuckPerm有两种体现方式,一是特定服务器的权限,二则是直接应用全局权限设置。

如果这个选项被设置为 false,只有指定在此服务器的权限才会被应用。

如果上方的 "server" 选项设置为 global,请不要将其设置为 false。更多的有关服务器指定的权限可以在这里找到。 通过编辑更改这两个选项,你可以灵活的为每个服务器的权限组/权限做出意想不到的配合效果

示例

示例 1
server: global
include-global: true
  • /luckperms user Luck set minecraft.command.gamemode true 将应用
  • /luckperms user Luck set minecraft.command.gamemode true factions 不应用
示例 2
server: lobby
include-global: true
  • /luckperms user Luck set minecraft.command.gamemode true 将应用
  • /luckperms user Luck set minecraft.command.gamemode true lobby 将应用
示例 3
server: bungeecord
include-global: false
  • /luckperms user Luck set minecraft.command.gamemode true 不应用
  • /luckperms user Luck set bungeecord.command.alert true bungeecord 将应用
示例 4
server: global
include-global: false

没有任何权限将会应用!

如果没有设置服务器名字(server项设置为global)且全局设置未开启(include-global项设置为flase), 将不会有任何权限可以应用到服务器上!

权限计算

权限是根据优先级进行计算的,如下所示
  • 服务器特定的权限是会覆盖通用/全局权限设置的

例如:有一个玩家,我们姑且叫他海螺,他拥有一个全局的“fly.use”(允许飞行)权限, 然后在“factions”这个服务器上,取消了“fly.use”权限,服务器的特定权限设置将会覆盖全局设置。 即,这个海螺在“factions”服务器上是无法使用“fly.use”权限的,他就不能够上天了, 前提是海螺现在正在“factions”服务器上。

  • 世界特定的权限也是会覆盖通用/全局权限设置的

例如:上文我们说的玩家“海螺”,他现在任然有一个全局的“fly.use”权限, 然后在“world_nether”(地狱)世界,取消了“fly.use”权限,世界的特定权限设置将会覆盖全局设置。 即,这个海螺在地狱就无法上天了(只要海螺在地狱世界)。

  • 临时权限将会覆盖非临时权限

例如:如果玩家海螺本来关闭了一个权限“test.node”, 以此为基础,服务器给海螺设置新的临时权限“test.node”, 海螺的临时权限则会覆盖本身关闭的权限,即海螺会在特定时间(临时权限)获得“test.node”权限。

  • 如果同时有两个节点相同、但时长不同的临时权限,时间较长的会覆盖时间较短的
  • 更加具体的通配符权限将覆盖不具体的通配符权限

例如:一个用户拥有权限“luckperms.”并且设置为true,但是“luckperms.user.”权限却设置为false, 那么所有玩家的权限都将被设置为false! 因为尽管“luckperm.”有更加通用的通配符,但是他没有“luckperms.user.”具体。

  • 继承权限将由对象自己的权限来重写

例如:一个玩家是默认权限组的成员,默认权限组有“some.thing.perm”权限, 但是这个玩家又被以用户形式给予了权限“some.thing.perm”, 继承而来的权限将会被玩家自己的权限给覆盖。

临时权限

临时权限每间隔3s会检查一遍,检查临时权限的时限是否到期, 不论同步间隔设置的怎么样,这个检查都会照常工作,这意味着你可以安全的设置临时权限在几秒后过期, 他们将会在时限到期时被删除。

速记权限

LuckPerms有他自己的速记权限系统,在这一点上,它非常类似PermissionsEx, 它允许你使用速记格式来设置权限。

示例
示例 1

使用LuckPerm的允许节点来作为例子,比如说,你想让一个用户组与用户权限设置/取消允许节点,

如果没有速记,你就必须键入下面四个节点。

luckperms.user.setpermission
luckperms.user.unsetpermission
luckperms.group.setpermission
luckperms.group.unsetpermission

但是,你要是使用速记,你就可以应用以下节点:

luckperms.(user|group).(setpermission|unsetpermission)

你可以使用括号来让一个节点成为一个速记的权限组,然后用 | 来分隔他们

示例 2

你可以使用“-”来创建字符范围,如果没有使用速记,则必须键入以下四个节点:

coolkits.kit.a
coolkits.kit.b
coolkits.kit.c
coolkits.kit.d

然而,使用了速记方法,你只需应用下面的节点:

coolkits.kit.(a-d)

示例 3

你可以使用“-”来创建字符范围,如果没有使用速记,则必须键入以下四个节点:

prisonmines.teleport.1
prisonmines.teleport.2
prisonmines.teleport.3
prisonmines.teleport.4

不过,你只要使用速记方法,这一切都会变得简单许多!你只需要应用下面的节点:

prisonmines.teleport.(1-4)

正则表达式

LuckPerms支持使用正则表达式来定义权限节点与服务器/世界的名字, 当使用正则表达式的时候,必须添加前缀“R=”。 所以LuckPerm才会知道将它是作为正则表达式来输出,而不是作为普通的字符串来输出。

例如:你希望玩家可以创建两个组与权限系(tracks),通常只需要添加两个权限节点。 然而使用正则表达式,你只需要添加一个权限节点 luckperms\.create.* 。 记住,转为任何字符,例如一个点,都将作为一个节点被系统解析。

默认组

我在 LuckPerms 里处理默认和默认组的方法可能是整个插件里最不受喜爱的特性了。最新我做了一些添加/调整,做了一些替代的特性,允许最大程度的控制像其他权限插件的方法,希望这会成为插件最好的方面,而不是最差的方面。

从何开始

这是我的想法。

你的服务器的用户可以分为两种。

  1. 基础玩家
  2. 加入不同的组的玩家,或者有他们特别权限的玩家。

你不希望浪费宝贵的硬盘空间来存储第一种玩家,你只希望存储你的职员,或者有特殊等级的玩家。平凡的"成员"就只是平凡,没有必要存储他们的信息。

下一个问题是如何确定一个用户是"平凡的"或不是,想象一下情景。

  1. 默认的组设置为"默认",当玩家加入,他们被设置为"默认",并被保存。
  2. 过了一会儿,你想将默认的组更改为"成员"。
  3. 接着你的老的成员全部在"默认"组里,剩下的人都在"成员",这不好。

甚至我们没有"平凡"的用户,这个问题依然会出现。

  1. 默认组设置为"默认"
  2. 你想给 "Notch" 一个特殊的 "essentials.fly" 权限,Notch 的权限被保存,标记为"默认组"的成员,有特殊的飞行权限。
  3. 接着你编辑了默认的组,所有的"平凡的"成员全部进入了新的组,但是 Notch 还是默认组的。

因为这个原因,我让默认的组不可配置,这让所有对我的事情都简单了 10 倍,这意味着我可以写有效率的存储系统,并且不用担心一些稀有的情况下服务器的管理员更改了默认组,但是,我知道这对一些人很反感。

这对一些等级插件也有问题,如果你想要一个"主"组,并且分离"升级"组,你需要多于一个的默认组。

这里是你的选项。

继续使用默认组,但是只是更改显示名

我非常推荐这个做法,因为你继续使用默认组。

如果你只是想简单的更改默认组的显示名,(比如在 Vault),我推荐你配置一个 group-name-rewrite 规则,通过添加这些到你的 config.yml/luckperms.conf 来实现。

# Rewrites group names. The underlying name of the group does not change, just the output in commands / placeholders / Vault.
group-name-rewrite:
  default: Member

你也可以使用这个:https://github.com/lucko/LuckPerms/wiki/Primary-Groups

配置继承

这个选项意味着所有的用户都还在"默认"的组里,但是这个默认组作为父组,这样他就可以将配置继承给不同的组。

/luckperms creategroup member
/luckperms group default parents add member

配置默认分配

如果你有更多的特殊需要,你可以使用这个选项,但是,这将否定我们在这个页面的第一节讨论的存储空间规划,所有的用户都会被存储,无论是"平凡的"成员还是不是。

注意:查看 Default Assignments 章节

接下来的规则将会创建一个不同的默认的组。

default-assignments:
  my-defaults-rule:
    if:
      has-true: <group.default>
    take:
      - group.default
    give:
      - group.member
    set-primary-group: member

放入以后,每次玩家登入时,插件会检测这个玩家是不是"默认"组的成员,如果是,插件将会把玩家从"默认"组移除,将他们添加至"成员"组,将他们的主组也设置为"成员"组。

这个系统非常强力,允许你配置按你自己的需求而定的默认组,记住你可以将玩家添加至不止一个的"默认"组。

开发者

开发者 API

简介

LuckPerms API 允许你更改大量的插件内部编程,并且能够轻松地将 LuckPerms 深度集成到你的插件和系统里。

大多数的其他的权限要么没有 API,要么有很差的 API,或者是有很差的文档的 API,而且里面的方法和类可能随机在不同版本里消失或是移动。Vault 项目就是一个很好的接口,并且是将大量插件一次性集成的很好的方法,可惜他的功能实在是太少了。

LuckPerms 遵循 Semantic 版本控制,也就是意味着一个不向后兼容的新的 API 出现时,主版本会增加这个 API,你可以放心你的集成不会因为版本的不同而崩溃,主要的版本是保持不变的。

如何在项目里使用 API

LuckPerms 的 API 包是 me.lucko.luckperms.api

我的 Nexus 服务器可以在这里找到 https://nexus.lucko.me/,你在你的构建脚本里需要的仓库在 https://repo.lucko.me/

其他有用的链接

Maven

<repositories>
    <repository>
        <id>luck-repo</id>
        <url>https://repo.lucko.me/</url>
    </repository>
</repositories>

<dependencies>
    <dependency>
        <groupId>me.lucko.luckperms</groupId>
        <artifactId>luckperms-api</artifactId>
        <version>3.2</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

Gradle

repositories {
    maven {
        name "luck-repo"
        url "https://repo.lucko.me/"
    }
}

dependencies {
    compile ("me.lucko.luckperms:luckperms-api:3.2")
}

使用指南

使用 API,你需要获得 LuckPermsApi 接口的实例,这可以通过几个方法完成。

// 所有平台 (抛出 IllegalStateException 如果 API 没有被加载)
final LuckPermsApi api = LuckPerms.getApi();

// 或者可选的
Optional<LuckPermsApi> provider = LuckPerms.getApiSafe();
if (provider.isPresent()) {
    final LuckPermsApi api = provider.get();
}

// Bukkit/Spigot
ServicesManager manager = Bukkit.getServicesManager();
if (manager.isProvidedFor(LuckPermsApi.class)) {
    final LuckPermsApi api = manager.getRegistration(LuckPermsApi.class).getProvider();
}

// Sponge
Optional<LuckPermsApi> provider = Sponge.getServiceManager().provide(LuckPermsApi.class);
if (provider.isPresent()) {
    final LuckPermsApi api = provider.get();
}
线程安全的警告

所有 LuckPerms 内部,包括 API 都是线程安全的,你可以在异步线程任意调用 API 而不用担心发生错误。

但是,请注意一些操作,(尤其是存储类)是阻塞的。CompletableFuture 就是用于这种情况:防止由于较差的处理导致的增加的错误,当出现 IO 时主线程等待处理完成。注意在添加 Callback 时指定正确的处理器。

我想将 LuckPerms 作为依赖项

在 Bukkit/Bungee,你需要在你的 plugin.yml 添加以下信息

depend: [LuckPerms]

在 Sponge, 在你的插件声明添加这些。

@Plugin(
        id = "myplugin",
        dependencies = {
                @Dependency(id = "luckperms")
        }
)
public class MyPlugin {
    ...
}
事件

LuckPerms 有一个完整的读写API,也有一个事件监听系统。由于插件的多平台的原因,我们使用了内部的事件系统,而不是每个平台已经使用的事件系统(举个例子,Bukkit Event API)。这意味着简单的注册你的平台的监听器将不会生效。

所有的事件都是异步触发的。这意味着不应该在监听器里交互或者调用任何不是线程安全的方法。

值得注意的是,大多数的 Bukkit/Sponge 都不是线程安全的,并且只应该使用主服务器线程来交互。你应该使用调度器来访问 LuckPerms 的监听器。

我怎样才能监听一个事件

所有的事件接口都可以在 me.lucko.luckperms.api.event 包里找到,它们都继承了 LuckPermsEvent 类。

监听事件应该获得 EventBus 实例,使用 LuckPermsApi#getEventBus即可。

为你的监听器创建另一个类常常是个好想法,这是一个你可以用来参考的类。

package me.lucko.test;

import me.lucko.luckperms.api.event.EventBus;
import me.lucko.luckperms.api.event.log.LogPublishEvent;
import me.lucko.luckperms.api.event.user.UserLoadEvent;
import me.lucko.luckperms.api.event.user.track.UserPromoteEvent;

public class TestListener {
    private final MyPlugin plugin;

    public TestListener(MyPlugin plugin, LuckPermsApi api) {
        this.plugin = plugin;

        EventBus eventBus = api.getEventBus();

        // use a lambda
        eventBus.subscribe(LogPublishEvent.class, e -> e.getCancellationState().set(true));
        eventBus.subscribe(UserLoadEvent.class, e -> {
            System.out.println("User " + e.getUser().getName() + " was loaded!");
            if (e.getUser().hasPermission("some.perm", true)) {
                // Do something
            }
        });

        // use a method reference
        eventBus.subscribe(UserPromoteEvent.class, this::onUserPromote);
    }

    private void onUserPromote(UserPromoteEvent event) {
        Bukkit.getScheduler().runTask(plugin, () -> {
            Bukkit.broadcastMessage(event.getUser().getName() + " was promoted to" + event.getGroupTo().get() + "!");

            Player player = Bukkit.getPlayer(event.getUser().getUuid());
            if (player != null) {
                player.sendMessage("Congrats!");
            }
        });
    }

}

EventBus#subscribe 返回一个 EventHander 实例,可以用来在插件停止的时候取消注册监听器。

示例用法

下面就是一些简短的实例,使用了一些基本的 API 功能。

获得玩家的组

如果你只是想找到一个玩家的组,我非常建议你使用以下的方法(你甚至不需要使用 API)。

public static String getPlayerGroup(Player player, List<String> possibleGroups) {
    for (String group : possibleGroups) {
        if (player.hasPermission("group." + group)) {
            return group;
        }
    }
    return null;
}

记住将你的组排列为优先级的顺序(比如组长在前,成员在后)。

为一个玩家添加权限
LuckPermsApi api = null; // See above for how to get the API instance.

Optional<User> user = api.getUserSafe(uuid);
if (!user.isPresent()) {
    return false; // The user isn't loaded in memory.
}

// Build the permission node we want to set
Node node = api.getNodeFactory().newBuilder(permission).setValue(true).build();

// Set the permission, and return true if the user didn't already have it set.
try {
    user.get().setPermission(node);

    // Now we need to save the user back to the storage
    api.getStorage().saveUser(u);

    return true;
} catch (ObjectAlreadyHasException e) {
    return false;
}
为(可能的)离线玩家添加权限

CompletionStage API 可以用来轻松交互插件的存储,查看这里这里 来查看这两个类的详细信息。

LuckPermsApi api = null; // See above for how to get the API instance.

// load the user in from storage. we can specify "null" for their username,
// since it's unknown to us.
api.getStorage().loadUser(uuid, "null").thenComposeAsync(success -> {
    // loading the user failed, return straight away
    if (!success) {
        return CompletableFuture.completedFuture(false);
    }
    
    // get the user instance, they're now loaded in memory.
    User user = api.getUser(uuid);

    // Build the permission node we want to set
    Node node = api.getNodeFactory().newBuilder(permission).setValue(true).build();

    // Set the permission, and return true if the user didn't already have it set.
    try {
        user.setPermission(node);
        
        // now we've set the permission, but still need to save the user data
        // back to the storage.
        
        // first save the user
        return api.getStorage().saveUser(user)
                .thenCompose(b -> {
                    // then cleanup their user instance so we don't create
                    // a memory leak.
                    api.cleanupUser(user);
                    return CompletableFuture.completedFuture(b);
                });
        
    } catch (ObjectAlreadyHasException e) {
        return CompletableFuture.completedFuture(false);
    }
    
}, api.getStorage().getAsyncExecutor());
获得玩家的前缀

LuckPerms 有一个(复杂的)缓存系统,用于非常快速的权限/信息查询。这些类都在 API 里,并且可以在可能的地方使用。

LuckPermsApi api = null; // See above for how to get the API instance.

// Get the user, or null if they're not loaded.
User user = api.getUserSafe(uuid).orElse(null);
if (user == null) {
    return Optional.empty(); // The user isn't loaded. :(
}

// Now get the users "Contexts". This is basically just data about the players current state.
// Don't worry about it too much, just know we need it to get their cached data.
Contexts contexts = api.getContextForUser(user).orElse(null);
if (contexts == null) {
    return Optional.empty();
}

// Ah, now we're making progress. We can use the Contexts to get the users "MetaData". This is their cached meta data.
MetaData metaData = user.getCachedData().getMetaData(contexts);

// MetaData#getPrefix returns null if they have no prefix.
return metaData.getPrefix();
获得玩家请求的权限

我们也可以使用这个缓存系统来获得一个包含用户权限的 Map 实例,包含了基础的权限查询。

// All retrieved in the same way as shown above.
User user;
Contexts contexts;

PermissionData permissionData = user.getCachedData().getPermissionData(contexts);
Map<String, Boolean> data = permissionData.getImmutableBacking();
寻找权限

你可以使用 Java 8 的流轻松过滤并返回一个用户请求的权限

public boolean hasPermissionStartingWith(UUID uuid, String startingWith) {
    // Get the user, if they're online.
    Optional<User> user = api.getUserSafe(uuid);

    // If they're online, perform the check, otherwise, return false.
    return user.map(u -> u.getPermissions().stream()
            .filter(Node::getValue)
            .filter(Node::isPermanent)
            .filter(n -> !n.isServerSpecific())
            .filter(n -> !n.isWorldSpecific())
            .anyMatch(n -> n.getPermission().startsWith(startingWith))
    ).orElse(false);
}
创建新的组并分配权限

这个方法不是阻塞的,所以可以安全的在主线程调用,一旦操作完成,回调会异步运行。

api.getStorage().createAndLoadGroup("my-new-group").thenAcceptAsync(success -> {
    if (!success) {
        return;
    }

    Group group = api.getGroup("my-new-group");
    if (group == null) {
        return;
    }

    Node permission = api.buildNode("test.permission").build();

    try {
        group.setPermission(permission);
    } catch (ObjectAlreadyHasException ignored) {}

    // Now save the group back to storage
    api.getStorage().saveGroup(group);
}, api.getStorage().getAsyncExecutor());

版本控制

在 2.0 版本里,LuckPerms 遵循了 Semantic 版本控制。

唯一不同的是 patch 号不包含在任何地方,除了 pom,并且每次构建都会计算,基于上次提交后的提交数量。(每个新的小版本都会创建新的标签)

这意味着 API 版本不再有 patch 号(在 patch 里没有 API 的变化),API 版本会是 x.y,每个不同的 LuckPerms 构建都会遵循 x.y.z。

变更日志

其他

语言文件

LuckPerms 插件中所有的消息(包括颜色和格式代码)都能够修改。(似乎合情合理)

将下面的文件之一下载然后存储到LuckPerms的文件夹中,然后命名为 "lang.yml"

将文件中的消息文本改成你喜欢的样子,然后重启你的服务器就好了。

语言文件

为翻译做贡献

如果你翻译了语言文件,然后提交回工程的话,我(和其他使用本插件的人)会很高兴的,因为其他使用者会受益。

上面的 "en_US" 语言文件应作为翻译的标准,你只能修改文本消息的值,关键字应保留原样。

附:简体中文语言文件

# LuckPerms Language File
# Locale: zh-CN (Simplified Chinese)
# Author: EuropeJing

prefix: "&7&l[&b&lL&3&lP&7&l] &c"
log-info: "&7&l[&bL&3P&7&l] &3{0}"
log-warn: "&7&l[&bLuck&3Perms&7&l] &c[警告] {0}"
log-error: "&7&l[&bLuck&3Perms&7&l] &4[错误] {0}"
empty: "{0}"
player-online: "&a在线"
player-offline: "&c离线"
loading-error: "无法加载权限数据,请稍后再试."
op-disabled: "&b此服务器上禁用了vanilla OP系统."
op-disabled-sponge: "&2服务器管理员状态在安装权限插件时无效,请直接编辑用户数据."
log: "&3日志 &3&l> {0}"
export-log: "&3输出 &3&l> &f{0}"
export-log-progress: "&3输出 &3&l> &7{0}"
migration-log: "&3移动 &7[&3{0}&7] &3&l> &f{1}"
migration-log-progress: "&3移动 &7[&3{0}&7] &3&l> &7{1}"
command-not-recognised: "命令未被识别."
command-no-permission: "你没有权限使用这个命令!"
already-haspermission: "{0}已经有这个权限!"
does-not-havepermission: "{0}没有这个命令的权限."
already-has-temp-permission: "{0}已经设置此临时权限!"
does-not-have-temp-permission: "{0}没有设置此临时权限."
user-not-found: "&b找不到用户."
user-not-online: "&b用户&a{0}&b不在线."
user-no-data: "&b没有加载用户&a{0}&b任何数据."
user-save-success: "&7(保存用户数据到文件)"
user-save-error: "保存用户数据时出错."
user-create-fail: "创建新用户时出错."
group-not-found: "&b找不到组."
group-save-success: "&7(保存组数据到文件)"
group-save-error: "保存组数据时出错."
track-not-found: "&b无法找到轨道."
track-save-success: "&7(保存轨道到文件)"
track-save-error: "保存轨道时出错."
user-invalid-entry: "&d{0}&c不是有效的用户名/uuid."
group-invalid-entry: "组名只能包含字母数字字符."
track-invalid-entry: "轨道名称只能包含字母数字字符."
server-invalid-entry: "服务器名称只能包含字母数字字符."
use-inherit-command: "使用'parent add'和'parent remove'命令,而不是指定节点."
verbose-invalid-filter: "&c无效的详细过滤器: &f{0}"
verbose-on: "&b所有权限的详细输出设置为&a开&b."
verbose-on-query: "&b将匹配过滤器:&f{0}&b的权限详细输出设置为&a开&b."
verbose-off: "&b所有权限的详细输出设置为&c关&b."
verbose-recording-on: "&b所有权限的详细记录设置为&a开&b."
verbose-recording-on-query: "&b将匹配过滤器:&f{0}&b的权限详细记录设置为&a开&b."
verbose-recording-upload-start: "&b详细记录被禁用. 正在上传结果..."
verbose-recording-url: "&a详细结果的网址:"
tree-upload-start: "&b生成权限树..."
tree-empty: "&a无法生成树,没有找到结果."
tree-url: "&a权限树网址:"
search-searching: "&a使用&b{0}&a搜索用户和组..."
search-searching-members: "&a正在搜索继承自&b{0}&a的用户和组..."
search-result: "&a从&b{1}&a用户和&b{2}&a组找到&b{0}&a个条目."
search-showing-users: "&b显示用户条目:"
search-showing-groups: "&b显示组条目:"
search-showing-users-with-page: "&b显示用户条目: {0}"
search-showing-groups-with-page: "&b显示组条目: {0}"
check-result: "&a用户&b{0}&a获得允许&b{1}&a权限的检查结果&a: &f{2}"
create-success: "&b{0}&a成功创建."
delete-success: "&b{0}&a成功删除."
rename-success: "&b{0}&a成功被重命名为&b{1}&a."
clone-success: "&b{0}&a被成功地复制到了&b{1}&a."
already-inherits: "{0}已经继承'{1}'."
does-not-inherit: "{0}已不继承'{1}'."
already-temp-inherits: "{0}已临时继承'{1}'."
does-not-temp-inherit: "{0}不会临时继承'{1}'."
track-already-contains: "轨道{0}已经包含组'{1}'."
track-does-not-contain: "轨道{0}不包含组'{1}'."
track-ambiguous-call: "指定的用户是此轨道上多个组的成员,无法确定他们的位置."
group-already-exists: "该组已存在!"
group-does-not-exist: "组不存在!"
group-load-error: "发生意外错误,组未加载."
groups-load-error: "发生意外错误,无法加载所有组."
track-already-exists: "轨道已存在!"
track-does-not-exist: "轨道不存在!"
track-load-error: "发生意外错误. 轨道未加载."
tracks-load-error: "出现意外错误,无法加载所有轨道."
track-empty: "轨道不能使用,因为它是空的或只包含一个组."
update-task-request: "&b更新任务计划."
update-task-complete: "&a更新任务完成."
update-task-complete-network: "&a更新任务完成,现在尝试推送到其他服务器."
update-task-push-success: "&a其他服务器通过&b{0}成功通知."
update-task-push-failure: "&c将更改推送到其他服务器时出错."
update-task-push-failure-not-setup: "&c将更改推送到其他服务器时出错,未配置消息传递服务."
reload-config-success: "&a重新加载配置文件. &7(一些选项将仅在服务器重新启动后才应用.)"
info: >
  {PREFIX}&2运行 &bLuckPerms v{0}&2 by &bLuck&2.\n
  {PREFIX}&f-  &3平台: &f{1}\n
  {PREFIX}&f-  &3存储方式: &f{2}\n
  {PREFIX}&f-  &3服务器名称: &f{3}\n
  {PREFIX}&f-  &3同步间隔: &a{4} &f分钟\n
  {PREFIX}&f-  &3消息服务: &f{5}\n
  {PREFIX}&f-  &b统计:\n
  {PREFIX}&f-     &3在线玩家: &a{6}\n
  {PREFIX}&f-     &3加载用户: &a{7}\n
  {PREFIX}&f-     &3加载组: &a{8}\n
  {PREFIX}&f-     &3加载轨道: &a{9}\n
  {PREFIX}&f-     &3日志大小: &a{10}\n
  {PREFIX}&f-     &3UUID缓存大小: &a{11}\n
  {PREFIX}&f-     &3翻译加载: &a{12}\n
  {PREFIX}&f-     &3预处理环境: &a{13}\n
  {PREFIX}&f-     &3环境计算器: &a{14}\n
  {PREFIX}&f-     &3唯一权限: &a{15}\n
  {PREFIX}&f-  &b配置:\n
  {PREFIX}&f-     &3使用服务器UUIDs: {16}\n
  {PREFIX}&f-     &b权限计算:\n
  {PREFIX}&f-        &3包括全部: {17}\n
  {PREFIX}&f-        &3包括全部世界: {18}\n
  {PREFIX}&f-        &3应用全部组: {19}\n
  {PREFIX}&f-        &3应用全部世界组: {20}\n
  {PREFIX}&f-        &3应用通配符: {21}\n
  {PREFIX}&f-        &3应用正则表达式: {22}\n
  {PREFIX}&f-        &3应用速记: {23}
create-group-error: "创建组时出错."
delete-group-error: "删除组时出错."
delete-group-error-default: "您不能删除默认组."
groups-list: "&aGroups: {0}"
create-track-error: "创建轨道时出错."
delete-track-error: "删除轨道时出错."
tracks-list: "&a轨道: {0}"
listnodes: "&b{0}的节点:"
listnodes-with-page: "&b{0}的节点:  {1}"
listnodes-temp: >
  &b{0}的临时节点:\n
  {1}
listparents: >
  &b{0}的父组:\n
  {1}
listparents-temp: >
  &b{0}的临时父组:\n
  {1}
listgroups: >
  &b{0}的组:\n
  {1}
listgroups-temp: >
  &b{0}的临时组:\n
  {1}
list-tracks: >
  &b{0}的轨道:\n
  {1}
list-tracks-empty: "{0}不在任何轨道上."
context-pair-inline: "&3{0}=&b{1}"
context-pair--global-inline: "&e全局"
context-pair-end: "&a."
context-pair-sep: "&a, "
context-pair: "&8(&7{0}=&f{1}&8)"
check-permission: "&b在环境&b{3}&b中,&b{0}&b的权限&b{1}&b被设置为&b{2}&b."
check-permission-inherited: "&b{0}&a在环境&b{3}&a中的&b{1}&a被设置为&b{2}&a,继承自&b{4}&a."
setpermission-success: "&a在&b{3}&a中为&b{2}&a设置&b{0}&a为&b{1}&a."
setpermission-temp-success: "&a在环境&b{4}&a将&b{0}&a的&b{2}&a设为&b{1}&a,持续时间&b{3}&a."
unsetpermission-success: "&a在环境&b{2}&a中取消&b{1}&a的&b{0}&a."
unset-temp-permission-success: "&a在环境&b{2}&a中取消设置&b{1}&a的临时许可&b{0}&a."
set-inherit-success: "&b{0}&a现在在环境&b{2}&a中继承&b{1}&a的权限&a."
set-temp-inherit-success: "&b{0}&a现在在环境&b{3}&a中继承&b{1}&a的权限,持续时间&b{2}&a."
set-parent-success: "&b{0}&a现有的父组被清除,现在只在&b{2}&a中继承&b{1}&a."
unset-inherit-success: "&b{0}&a不再继承环境&b{2}&a中的&b{1}&a权限."
unset-temp-inherit-success: "&b{0}&a在环境{2}中不再临时从&b{1}&a继承权限."
clear-success: "&b{0}&a的权限被清除. (&b{1}&a节点被删除.)"
clear-success-singular: "&b{0}&a的权限被清除. (&b{1}&a节点已被删除.)"
parent-clear-success: "&b{0}&a的组被清除. (&b{1}&a节点被删除.)"
parent-clear-success-singular: "&b{0}&a的组被清除. (&b{1}&a节点已被删除.)"
meta-clear-success: "&b{0}&a的父组被清除. (&b{1}&a节点被删除.)"
meta-clear-success-singular: "已经清除了这个&b{0}&a的元数据. (&b{1}&a节点已被删除.)"
illegal-date-error: "无法解析日期'{0}'."
past-date-error: "您不能设定一个过去的日期!"
chat-meta-prefix-header: "&b{0}的前缀"
chat-meta-suffix-header: "&b{0}的后缀"
meta-header: "&b{0}的元信息"
chat-meta-entry: "&b-> {0} &f- &f\"{1}&f\" &8(&7继承自&a{2}&8)"
chat-meta-entry-with-context: "&b-> {0} &f- &f\"{1}&f\" &8(&7继承自&a{2}&8){3}"
meta-entry: "&b-> &a{0} &f= &f\"{1}&f\" &8(&7继承自&a{2}&8)"
meta-entry-with-context: "&b-> &a{0} &f= &f\"{1}&f\" &8(&7继承自&a{2}&8){3}"
chat-meta-prefix-none: "&b{0}没有前缀."
chat-meta-suffix-none: "&b{0}没有后缀."
meta-none: "&b{0}没有元信息."
meta-invalid-priority: "优先级'{0}'无效. 应该是一个数字."
already-has-chat-meta: "{0}已经设置了{1}."
does-not-have-chat-meta: "{0}没有设置{1}."
add-chatmeta-success: "&b{0}&a在环境&b{4}&a中将优先级&b{3}&a设置为 {1} &f\"{2}&f\"."
add-temp-chatmeta-success: "&b{0}&a在环境&b{5}&a中,设置为优先级&b{3}&a的{1} &f\"{2}&f\"&a,持续时间为&b{4}&a."
remove-chatmeta-success: "&b{0}&a在&b{3}&a中删除了优先级&b{3}&a的{1} &f\"{2}&f\"&a."
bulk-remove-chatmeta-success: "&b{0}&a had all {1}es at priority &b{3}&a removed in context {4}&a."
remove-temp-chatmeta-success: "&b{0}&a在环境&b{4}&a中删除了优先级&b{3}&a的临时{1} &f\"{2}&f\"&a."
bulk-remove-temp-chatmeta-success: "&b{0}&a在环境&b{4}&a中移除了优先级&b{3}&a的所有临时&b{1}&a.."
already-has-meta: "{0}已经有了这个元信息集."
set-meta-success: "将环境&b{3}&a中的&b{2}&a的键&f\"{0}&f\"&a的元信息设置为&f\"{1}&f\"&a."
set-meta-temp-success: "&a在环境&b{4}&a中将&b{2}&a的键&f\"{0}&f\"&a的值设置为&f\"{1}&f\"&a,持续时间为&b{3}&a."
unset-meta-success: "&a在环境{2}中取消设置&b{1}&a的键&f\"{0}&f\"&a的元信息."
unset-meta-temp-success: "&a在环境{2}中取消设置&b{1}&a的键&f\"{0}&f\"&a的临时元信息."
bulk-update-invalid-data-type: "Invalid type. Was expecting 'all', 'users' or 'groups'."
bulk-update-invalid-constraint: "无效的约束&4{0}&c.约束的格式应该是'&f<field> <comparison operator> <value>&c'."
bulk-update-invalid-comparison: "比较运算符无效'&4{0}&c'. 应该以下之一: &f==  !=  ~~  ~!"
bulk-update-queued: "&a批量更新操作已排队.&7(&f{0}&7)"
bulk-update-confirm: "&a运行&b/{0} bulkupdate &a确认{1}执行更新."
bulk-update-unknown-id: "&a使用id&b{0}&a的操作不存在或已过期."
bulk-update-starting: "&a运行批量更新."
bulk-update-success: "&b量更新已成功完成."
bulk-update-failure: "&cBulk update failed. Check the console for errors."
bulk-change-type-error: "类型无效. 应该是 'server' 或 'world'."
bulk-change-success: "&a应用批量更改成功. {0}记录已更改."
user-info-general: >
  {PREFIX}&b&l> &bUser Info: &f{0}\n
  {PREFIX}&f- &3UUID: &f{1}\n
  {PREFIX}&f- &3状态: {2}\n
  {PREFIX}&f- &3主组: &f{3}\n
  {PREFIX}&f- &a统计:\n
  {PREFIX}&f-    &3权限: &a{4}\n
  {PREFIX}&f-    &3临时权限: &a{5}\n
  {PREFIX}&f-    &3前缀: &a{6}\n
  {PREFIX}&f-    &3后缀: &a{7}\n
  {PREFIX}&f-    &3元信息: &a{8}
user-info-data: >
  {PREFIX}&f- &aCached Data:\n
  {PREFIX}&f-    &3具有环境数据: {0}\n
  {PREFIX}&f-    &3当前环境: {1}\n
  {PREFIX}&f-    &3当前前缀: {2}\n
  {PREFIX}&f-    &3当前后缀: {3}
info-parent-header: "&f- &a父组:"
info-temp-parent-header: "&f- &a临时父组:"
user-getuuid: "&b{0}&b的UUID是&b{1}&b."
user-removegroup-error-primary: "您不能从其主组中删除用户."
user-primarygroup-success: "&b{0}&的主组已设为&b{1}&a."
user-primarygroup-warn-option: "&c警告:此服务器&7({0})&c使用的主组计算方法可能无法反映此更改."
user-primarygroup-error-alreadyhas: "用户已将此组设置为其主组."
user-primarygroup-error-notmember: "&b{0}&a已经不是&b{1}&a的成员,现在添加它们."
user-track-error-not-contain-group: "指定的用户尚未在此轨道上的任何组中."
user-track-added-to-first: "&b{0}&a不在此轨道上的任何组中, 因此在环境&b{2}&a中将其添加到第一组&b{2}&a."
user-promote-success: "&a在环境&b{3}&a中将用户沿轨道&b{0}&a从&b{1}&a提升到&b{2}&a."
user-promote-error-endoftrack: "已达到轨道&4{0}&c的结尾,所以无法提升用户."
user-promote-error-malformed: >
  {PREFIX}轨道上的下一个组{0}不存在. 无法提升用户.\n
  {PREFIX}创建组,或将其从轨道中删除,然后重试.
user-demote-success: "&a在环境&b{3}&a中将用户沿轨道&b{0}&a从&b{1}&a转移到&b{2}&a."
user-demote-endoftrack: "已达到轨道&4{0}&c的结尾,所以&4{1}&c已从&4{2}&c中移除."
user-demote-error-malformed: >
  {PREFIX}轨道上的上一组{0}不存在.无法降级用户.\n
  {PREFIX}创建组,或将其从轨道中删除,然后重试.
user-showpos: >
  &a显示&b{0}&a在轨道&b{1}&a的位置.\n
  {2}
group-info-general: >
  {PREFIX}&b&l> &b组信息: &f{0}\n
  {PREFIX}&f- &3显示名称: &f{1}\n
  {PREFIX}&f- &3权重: &f{2}\n
  {PREFIX}&f- &a统计:\n
  {PREFIX}&f-    &3权限: &a{3}\n
  {PREFIX}&f-    &3临时权限: &a{4}\n
  {PREFIX}&f-    &3前缀: &a{5}\n
  {PREFIX}&f-    &3后缀: &a{6}\n
  {PREFIX}&f-    &3元信息: &a{7}
group-set-weight: "&a将组&b{1}&a的权重设置为&b{0}&a."
track-info: >
  {PREFIX}&b&l> &b显示轨道: &f{0}\n
  {PREFIX}&f- &7路径: &f{1}
track-clear: "&b{0}&a's groups track was cleared."
track-append-success: "&a组&b{0}&a已成功添加到轨道&b{1}&a."
track-insert-success: "&a组&b{0}&a已成功插入轨道&b{1}&a的&b{2}&a位置."
track-insert-error-number: "没有预期的数量,而是收到: {0}"
track-insert-error-invalid-pos: "无法插入位置{0}. 索引超出范围."
track-remove-success: "&aGroup &b{0}&a已成功从轨道&b{1}&a移除."
log-load-error: "日志无法加载."
log-invalid-page: "页码无效."
log-invalid-page-range: "页码无效,请输入1和{0}之间的值."
log-no-entries: "&b没有日志条目显示."
log-entry: "&b#{0} -> &8(&7{1} ago&8) {2}"
log-notify-toggle-on: "&a启用&b记录输出."
log-notify-toggle-off: "&c禁用&b记录输出."
log-notify-already-on: "您已经收到通知."
log-notify-already-off: "您目前没有收到通知."
log-notify-unknown: "状态未知.输入 \"on\" 或者 \"off\"."
log-search-header: "&a显示最近的查询操作&b{0} &a(page &f{1}&a of &f{2}&a)"
log-recent-header: "&a显示最近操作 (page &f{0}&a of &f{1}&a)"
log-recent-by-header: "&a显示&b{0}&a的最近操作 (page &f{1}&a of &f{2}&a)"
log-history-user-header: "&a显示用户的历史记录&b{0} &a(page &f{1}&a of &f{2}&a)"
log-history-group-header: "&a显示组的历史记录 &b{0} &a(page &f{1}&a of &f{2}&a)"
log-history-track-header: "&a显示轨道的历史记录 &b{0} &a(page &f{1}&a of &f{2}&a)"
log-export-already-exists: "错误: 文件{0}已经存在."
log-export-not-writable: "错误: 文件{0}不可写."
log-export-empty: "日志为空,因此无法导出."
log-export-failure: "写入文件时出现意外错误."
log-export-success: "&a成功导出日志&b{0}&a."
import-already-running: "另一个导入过程已经在运行,请等待完成,然后重试."
export-already-running: "另一个导出过程已经在运行,请等待完成,然后重试."
import-log-doesnt-exist: "错误: 文件{0}不存在."
import-log-not-readable: "错误: 文件{0}不可读."
import-log-failure: "从日志文件读取时发生意外错误."
import-progress: "&b(导入) &b-> &f百分之{0}完成 &7- &b{1}&f/&b{2} &f完成 &c{3}&f错误."
import-progress-sin: "&b(导入) &b-> &f百分之{0}完成 &7- &b{1}&f/&b{2} &f完成 &c{3}&f错误."
import-start: "&b(导入) &b-> &f开始导入过程."
import-end-complete: "&b(导入) &a&l已完成 &7- 用了 &b{0} &7秒 - &7没有错误."
import-end-complete-err: "&b(导入) &a&l已完成 &7- 用了 &b{0} &7秒 - &c{1}错误."
import-end-complete-err-sin: "&b(导入) &a&l已完成 &7- 用了 &b{0} &7秒 - &c{1}错误."
import-end-error-header: >
  {PREFIX}&b(导入) &7------------> &f显示错误 #&b{0} &7<------------\n
  {PREFIX}&b(导入) &f执行时: &3Command #{1}\n
  {PREFIX}&b(导入) &f命令: &7{2}\n
  {PREFIX}&b(导入) &f类型: &3{3}\n
  {PREFIX}&b(导入) &f输出:
import-end-error-content: "&b(导入) &b-> &c{0}"
import-end-error-footer: "&b(导入) &7<------------------------------------------>"

PlaceholderAPI

在 extended_clip 的 PlaceholderAPI 插件中,LuckPerms 也注册了一些变量(Placeholders)。

LuckPerms 插件所使用的标识符是 luckperms

使用

要想使用变量的话,你需要运行下列命令。 这些命令的作用就是安装 LuckPerms 的变量扩展,安装后你就可以使用下面列举出的变量了。

/papi ecloud download LuckPerms 
/papi reload 

请记住使用这些指令你需要OP权限(或者你也可以选择在控制台中运行这些指令)

同时请注意,如果你想得到玩家的前缀或后缀数据,——如果你在服务器上安装了Vault插件和Vault的变量扩展的话,你也可以使用 Vault 插件所提供的变量。

Placeholders

%luckperms_group_name%

使用说明: 返回玩家当前所在组的名字
使用示例: n/a



%luckperms_context_<context key>%

使用说明: 返回给定内容关键字的值,如果内容没有值的话会返回空 使用示例: %luckperms_context_server%



%luckperms_groups%

使用说明: 返回服务器上的权限组列表,用逗号分割 使用示例: n/a



%luckperms_has_permission_<permission>%

使用说明: 检查玩家是否直接拥有该权限,不会检查通配符或继承的权限 使用示例: %luckperms_has_permission_essentials.ban%



%luckperms_check_permission_<permission>%

使用说明: 检查玩家是否拥有指定权限,这个变量工作的方式和正常插件的检查方式没有区别 使用示例: %luckperms_check_permission_some.cool.permission%



%luckperms_in_group_<group>%

使用说明: 返回玩家是否为给定组的成员,不包括继承组 使用示例: %luckperms_in_group_admin%



%luckperms_inherits_group_<group>%

使用说明: 返回玩家是否在给定组或继承给定组 使用示例: %luckperms_inherits_group_vip%



%luckperms_on_track_<track>%

使用说明: 返回玩家的权限组是否在给定权限组树上 使用示例: %luckperms_on_track_staff%



%luckperms_has_groups_on_track_<track>%

使用说明: 检查玩家是否继承给定权限组树中的任何一个组 使用示例: %luckperms_on_track_donor%



%luckperms_highest_group_by_weight%

使用说明: 返回玩家所在权限组树种的最高级权限组 使用示例: n/a



%luckperms_lowest_group_by_weight%

使用说明: 返回玩家所在权限组树种的最低级权限组 使用示例: n/a



%luckperms_first_group_on_tracks_<tracks>%

使用说明: 返回玩家在给定权限组树上所在的第一个组,权限组树会返回一组用逗号分隔的权限组名,权限组树中的每一个权限组都正序排列。 使用示例: %luckperms_first_group_on_tracks_staff,donor%



%luckperms_last_group_on_tracks_<tracks>%

使用说明: 返回玩家在给定权限组树上所在的最后一个组,权限组树会返回一组用逗号分隔的权限组名,权限组树中的每一个权限组都倒序排列。 使用示例: %luckperms_last_group_on_tracks_staff,donor%



%luckperms_expiry_time_<permission>%

使用说明: 获得玩家拥有的临时权限剩余的时间,如果玩家没有该权限的话会返回空 使用示例: %luckperms_expiry_time_essentials.fly%



%luckperms_group_expiry_time_<group name>%

使用说明: 获得玩家拥有的临时权限组所剩余的时间,如果玩家不在该权限组的话会返回空 使用示例: %luckperms_group_expiry_time_vip%



%luckperms_prefix%

使用说明: 返回玩家的前缀,使用Vault所提供的变量所输出的结果可能会更精确,这一项不会被Vault的配置设置影响 使用示例: n/a



%luckperms_suffix%

使用说明: 返回玩家的后缀,使用Vault所提供的变量所输出的结果可能会更精确,这一项不会被Vault的配置设置影响 使用示例: n/a



%luckperms_meta_<meta key>%

使用说明: 返回与指定Meta关键字联系的值 使用示例: %luckperms_meta_some-key%