- 欢迎来到Minecraft插件百科!
- 对百科编辑一脸懵逼?帮助:快速入门带您快速熟悉百科编辑!
- 因近日遭受攻击,百科现已限制编辑,有意编辑请加入插件百科企鹅群:223812289
WorldGuard
外文名 | WorldGuard |
插件类型 | Spigot / CraftBukkit |
最新版本 | 6.1.2 |
兼容服务端 | 1.10 |
源地址 | https://dev.bukkit.org/bukkit-plugins/worldguard/ |
WG是对服务器管理员,地图制作者,生存服务器等提供许多功能的一个插件。
- 在你创造区域后,只会允许有权限的玩家和一些插件去改变区域。
- 你可以在你的区域里设置一些标记,如(取消 凋零伤害 掉落伤害 等)
- 同时在特殊的世界的区域中你也可以改变一些标记,如(饱食度回复 生命值回复 PVP的开关 TNT 怪物伤害)
- 黑名单包括了玩家不能使用的物品和方块
- 可以记录服务器的统计和信息 (/wg report -p)
- 可以管理服务器的CPU(/wg profile -p)
- 增加例如停止所有火焰传播的指令 “STOP ALL FIRE SPREAD” .
- 可以与其他的Bukkit插件进行交♂易
- 保护与防止许多事件 (树长大 TNT爆炸 药水机器 等)
- 某些触发事件也可以修改 (门 拉杆 等)
- 开源,是Minecraft的最老的插件之一(比Bukkit还老)
- 启用你想要的特性!默认所有都是关闭的。你可以先安装WG,然后再配置它。
安装
WG需要一个能支持Bukkit API的Minecraft服务端及版本,如 CraftBukkit, MCPC+, Cauldron, 和 Spigot. 不支持官方的Minecraft服务器。
另一个需求是[WorldEdit]插件,一个非常轻量的地图编辑器,同样也是我们的作品,注意你不能使用Forge版本的WE,请使用插件版本。
由于[一个争论和随从法律的崩溃],你不能再下载官方Bukkit服务器了。供MC1.8+ 用户选择的服务端是 Spigot 。
如何安装
WG可以从[BukkitDev]下载。
如果你下载下来的文件是 .zip的话,解压它,你会找到一个WorldGurad.jar。否则,你会直接下载下来一个.jar文件
在你的服务器根目录下,如果没有plugins文件夹,创建之。
把jar文件放入plugins中
开启你的服务器,检查服务器日志,如果有错误,检查帮助页面。
配置
许多WG的特性都与配置相关(如药水,水中呼吸等模式)。每个配置选项都在这页列出了。
在你第一次运行WG的时候,主配置在plugins/WorldGuard/
- config.yml
每个世界都有特殊的配置文件
- worlds/world/config.yml
- worlds/world_nether/config.yml
- worlds/mining_world/config.yml
如果你打开了每个世界的配置文件,他们会是空的,如果你想要配置的话,你需要从主配置复制
示例:如何自定义世界配置 在主世界配置中,你可能把 block-creeper-block-damage 设置为true mobs: block-creeper-explosions: false block-creeper-block-damage: true block-wither-explosions: false 但你想在地狱世界把其设置为false 打开worlds/world_nether/config.yml 然后添加文本 mobs: block-creeper-block-damage: false 这一行会覆盖继承的true,表现为false
设置
这些是作为参考的顺序,并不是真正的顺序,你要现在config.yml找到它们
权限
建筑权限
worldguard.build.block.place.<material>
worldguard.build.block.remove.<material>
worldguard.build.block.interact.<material>
worldguard.build.entity.place.<type>
worldguard.build.entity.remove.<type>
worldguard.build.entity.interact.<type>
worldguard.build.entity.damage.<type>
worldguard.build.item.use.<material>
命令
黑名单
黑名单可以禁止玩家做一些事,这是一些情况:
禁止玩家挖金矿
当找到钻石时通知所有管理员
当放置附魔台时告诉玩家一些事
这是一个示例配置:
# Deny lava buckets [lavabucket] ignore-groups=admins,mods on-use=deny,tell message=Sorry, you can't use lava buckets! # Deny some ore [goldore,ironore] ignore-groups=admins on-break=deny,tell,notify # No TNT! [tnt] ignore-groups=admins on-place=deny,notify,kick
每个世界都会有配置文件
[*]worlds/world/blacklist.txt
[*]worlds/world_nether/blacklist.txt
[*]worlds/mining_world/blacklist.txt
这是格式
[a list of items/blocks to match] event to watch=what to do event to watch=what to do event to watch=what to do option=value
- 是注释行
可以使用ID和名字: [wood,brick,glass]
可以增加数据值: [wood:0]
多个数据值用;隔开 Multiple data values can be matched by separating each one with a semicolon (;): [wood:0;2;3]
也可以用范围: [wood:2-3]
可以用大于等于 小于等于 [wood:>=2,<=3]
你也可以这样: [wood:0;>=2,grass:1-2]
事件
on-break on-destroy-with on-place on-use on-interact on-drop on-acquire on-dispense
行动
deny allow notify log tell kick ban
选项
ignore-groups ignore-perms comment message
示例
[lavabucket,waterbucket,bucket] on-use=deny,tell [tnt] ignore-groups=admins on-place=deny,notify,kick [obsidian] ignore-groups=admins,obsidian on-place=deny,tell on-break=deny,tell
记录的参数: Console File Database
CONSOLE: 控制台
FILE 文件
%Y the year (YYYY)
%m the month (MM)
%d the day (DD)
%W the week of the year (00-52)
%H 24-hour time (HH)
%h 12-hour time (HH)
%i the minute (mm)
%s the second (ss)
%u the user’s name
%% translates to a single percent sign “%”
可用变量
数据库
示例
CREATE TABLE IF NOT EXISTS `blacklist_events` ( `id` int(11) NOT NULL AUTO_INCREMENT, `world` varchar(10) NOT NULL, `event` varchar(25) NOT NULL, `player` varchar(16) NOT NULL, `x` int(11) NOT NULL, `y` int(11) NOT NULL, `z` int(11) NOT NULL, `item` int(11) NOT NULL, `time` int(11) NOT NULL, `comment` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) );
区域
快速开始
选择区域
要创建一个区域,你要告诉WG你的区域范围。WE用于选范围。
区域可以是以下形状:
立方体
多边形
不支持圆!
基础指令
创建区域
使用这个指令创建区域 /region define:
/region define town
/rg和/region是相同的
/rg define town
新的区域默认为禁止玩家破坏方块,为使玩家可以建筑,为区域增加主人和成员,你可以为每个成员增加单独的权限。
所有玩家都可以成为主人或成员,下面是指令:
/rg addmember town Notch sk89q g:builders /rg addowner town sk89q /rg removemember town g:builders /rg removeowner town sk89q
更多请去区域命令页。
你在创建区域的同时也可以很简单的去增加成员:
/rg define town Notch sk89q g:builders
区域会自动保存,不需要保存指令。
示例:创建一个只有builders可以建筑的区域spawn
选择spawn的范围
创建一个叫做spawn的区域: /rg define spawn
增加建筑团队为成员: /rg addmember spawn g:builders
提示:区域会在一定间隔后自动保存,如果你想强制保存,使用/rg save
你可以这样删除区域: /rg remove town
列出区域消息 /rg info town
列出所有区域 /rg list
这样重新选择区域 /rg redefine town
更多请看区域命令
区域的配置
区域的重叠
区域可以互相重叠。
如果重叠的话,玩家必须拥有这些重叠区域的所有建筑权限才能在重叠区域建筑。
如果你想要一个区域覆盖另一个,使用继承。
如果你想要一个区域可以建筑,使用build权限。
如果区域不支持保护这个区域,使用 passthrough 权限。
示例:创建一个重叠于spawn的免费挖矿区域
选择出区域范围
创建区域: /rg define mine
允许破坏: /rg flag mine build allow
权限: 每个区域都有他们的权限,如PVP可以用pvp权限。
/rg flag town pvp deny
阅读区域权限来获取更多信息。
示例:做一个不能破坏方块[建筑者可以] 允许PVP的区域
选择区域范围
创建区域 /rg define arena
允许PVP /rg flag arena pvp allow
因为建筑师们不是区域的一员,所以他们不能建筑,甚至当他们是区域成员时也不行。
但你创建区域的原因是使用PVP权限,所以你可以使用 权限来允许。 /rg flag arena passthrough allow
常见情节 见常见情节页。
区域魔杖
区域魔杖列出当前位置的所有区域。它是一个MC物品,右键来检测。
默认的,这个物品是皮革,但可以在配置中更改。
要使用这个魔杖,需要 worldguard.region.wand 权限
区域标志
优先级与继承
在快速开始中提到,区域可以覆盖。如果要在覆盖的区域内建筑,需要有所有区域的权限。
但有了优先级不同。
优先级
每个区域默认的优先级是0,但它可以更改,大的数字意味着高的优先级。-2147483648 到 2147483647 都可以作为优先级的数字,但你也可以使用 -2, 10, 15, 100.
覆盖的区域中考虑优先级最高的那一个。
在区域中,使用优先级最高的那一个的权限。
使用优先级最高的标志。
这样改变优先级: /rg setpriority example 5
示例:创建一个pub区域,使pub组可以建筑。spawn中builders组已经可以建筑。
选择区域
创建区域: /rg define pub
设置优先级: /rg setpriority pub 10
在PVP区域中创建一个治疗区域。
选择区域
创建区域 /rg define heal
禁止PVP /rg flag heal pvp deny
优先级 /rg setpriority heal 10
继承
在上面说过,创建pub区域你是否想让pub组和builder组都可以建筑?
你可以把builder组加到成员里,但你也可以使用继承。
子区域继承父区域的成员、主人,没有设置的权限
这是为了方便:
大区域中的小区域
创建一个模板
每个区域至多有一个父区域。
使用这个指令: /rg setparent:
/rg setparent 子区域 父区域
移除父区域: /rg setparent 子区域
WG会自动检测继承。
例子:创建一个mall
/rg setparent plot1 mall
/rg setparent plot2 mall
/rg addowner mall g:mall_owners
/rg addowner plot1 sk89q
区域模板
之前提到,因为继承,所以父区域可以作为子区域的模板。
但你可能想要模板不是真正的区域,你不想保护这个区域,做到这个的方法之一是全局区域,使用-g来创建: /rg define -g plot_template
例子:
/rg define -g plot_template
/rg setparent plot1 plot_template
/rg setparent plot2 plot_template
/rg setparent plot_template mall
/rg flag mall chest-access allow
/rg flag plot_template chest-access deny
高优先级的父区域会覆盖子区域。
区域组和覆盖区域
你可能知道,标志可以只对于一些特殊的组有用。
/rg flag mall pvp -g nonmembers deny
当只有一个区域的时候,知道谁是成员谁是主人很清楚。但在覆盖区域中不这样:玩家只是其中一个区域的成员呢?
答案是否定的,玩家必须在标志设置的区域为成员。例如,让我们想象有两个组——
Spawn, 标志 pvp -g nonmembers deny ,没有成员 Market, 成员 “sk89q” sk89q不能PVP因为他不是spawn的一员。
当子区域继承父区域,成员和标志以及主人都会被继承,对于这个是不通用的。
例子:
Market, 标志 pvp -g nonmembers deny 无成员 Shop1, 成员 “sk89q,” 继承Market sk89q是成员吗?是,所以 sk89q 可以PVP
先前提到,父区域的优先级不能比子区域高,否则会覆盖子区域。
全局区域
全局区域是一个特殊的区域:
包括整个世界
有最低的优先级
有一些特殊功能
每个世界都有它的全局区域。但是除了你尝试配置它,全局区域不会创建。
例如,这样会自动创建全局区域。
/rg flag __global__ pvp deny
把全局区域当做一个一直在那儿的区域,在全局区域中的标志在该世界的区域中工作。
但,像普通区域一样,passthrough 区域标志必须设置为allow。把 passthrough 设置为 allow 会让区域成为一个没有保护的区域,所以只要没有区域防止破坏,玩家就可以建筑。
如果你把passthrough标志设置成了deny,会让区域像一个真正的区域一样,玩家必须是主人或成员才能建筑。因为全局区域包括整个世界,所以默认会禁止破坏。
因为全局区域的极低优先级,其他区域会直接覆盖全局区域的标志。
注意 passthrough标志与移动无关,它是建筑权限的缩写。
例子:没有区域的地方无法建筑
/rg flag __global__ passthrough deny
增加主人和成员会把passthrough打开。
建筑标志
建筑标志不能设置成allow,原因是会自动让区域的建筑标志都不工作。把标志设置为deny使它像其他区域一样,但也意味着不能破坏和放置方块。因为全局区域包含整个世界,所以整个世界都不能建筑。
警告: 不建议设置全局区域的build标志。如果你想保护世界,使用 passthrough 标志。如果你设置了全局区域的build标志,其他区域不会覆盖这个标志。
所以,如果你把全局区域的build设置为了deny,无论他们是区域的主人或成员,都不能建筑了。
默认覆盖
WE的标志有一些不同。如 exp-drop 标志如果没有区域设置的话,甚至是成员和主人都不能掉落经验。
如果你想要用把它设置为deny的方式覆盖 exp-drops 标志,使它可以运行,在全局区域上就不会工作。
如你尝试使用 /rg flag __global__ exp-drop -g nonmembers deny但这不会工作。当你指定不是成员时,会指定不是全局区域的成员。所以,如果你制作一个地皮区域,经验不会生成,因为地皮区域的成员不是全局区域的成员。
记住,即使全局区域的优先级是最低的,但区域不会继承,标志不会传播。
这样的话,推荐你创建一个模板区域。见优先级与继承。
区域认领
WG中可以使用区域认领系统。它像 /rg define 一样,但玩家必须有特殊的权限。
这里同时也需要WE来选择区域,所以你需要 worldedit.selection 权限。
玩家可以这样认领选中的区域: /rg claim region_name
当玩家输入指令后,会自动变成区域主人。这需要worldguard.region.claim权限。
规则:
最大的区域数量: 除非有 worldguard.region.unlimited 权限,玩家的区域数不能超过这个数量。
最大区域提及: 除非有 worldguard.region.unlimited 权限,不然体积不能超过配置。
预防覆盖:区域不能使用同名。
预防重叠:区域不能重叠于其他区域。
只能重叠自己的区域: 如果regions.claim-only-inside-existing-regions启用,只能重叠于自己的区域。
这时不支持多边形区域。
你也可以给予玩家其他指令的权限。
存储
区域数据可以这样存储:
YAML 不需要数据库 简单的更改,简单备份,快速读取
MYSQL 使用数据库 保存只更改一部分
注意:其他数据库,如PostgreSQL, SQL Server, SQLite不支持
切换存储:默认是YAML
在配置中 regions.sql.use 可以切换为MYSQL 这会禁用 YAML. 如果你切换至 MySQL, 数据表会自动生成, 当然要为 SQL 用户提供相应权限
警告 强烈建议在你更换数据库之前做备份。
如果你只是简单的切换数据库,你之前所有数据都会丢失。你可以使用你哥简单的指令来切换,你在切换之前和之后都可以使用。
To migrate data, use: /rg migratedb 之前 之后,如要把YAML换成MYSQL 使用 /rg migratedb yaml mysql
请确保目标数据库是空的。
在你更改的时候不要忘记备份。
YAML 在region.yml中,每个世界下都有。 可以使用/rg load来读取。
这是个示例:
regions: test: min: {x: 1730.0, y: 0.0, z: -169.0} max: {x: 1742.0, y: 255.0, z: -158.0} members: players: [bobby] unique-ids: [0ea8eca3-dbf6-47cc-9d1a-c64551ca975c] flags: {use: allow, greeting: Welcome!, pvp: allow, pvp-group: MEMBERS} owners: groups: [admins] type: cuboid priority: 4 __global__: members: {} flags: {} owners: {} type: global priority: 0
UUID经常使用
MySQL 只有一个服务器可以使用MYSQL 前缀可以更改 如果有错误发生会回档 默认WG只会记录更改 这个是讲解
Table Purpose region Region data, with shape, priority, and parent information. region_cuboid Data for cuboid regions, with bounds. region_poly2d Data for polygonal regions, with minimumum and maximum Y values. region_poly2d_point Individual rows for points of polygonal regions. region_flag Per-region flag data. region_players List of players on regions. region_groups List of groups on regions. world Normalizes worlds into a world ID. user Normalizes users into a user ID. group Normalizes groups into a group ID. Each user row will either have a UUID or name set.
不推荐在运行的服务器上修改MYSQL。经常会导致出错。
保护什么
保护是综合性的:
可以保护方块的破坏和放置,物品栏的打开,外部TNT的爆炸,外部重力方块的掉落,外部植物的生长,牌子的切换,作物的踩踏,画和展示框,红石触发机关,动物,喷溅药水和弹射物。
其实,WG也支持一些MOD物品的保护。
水和岩浆的流动在配置中默认禁止,可以打开。
如果你找到了破坏的方式,请汇报BUG。
例外 一些标志会自动为不是成员的人关闭
如物品掉落和物品拾取。
经验值也不允许掉落。
这些可以通过区域标志来移除。
但是漏斗不行。漏斗会自动吸取区域下部箱子的物品,所以不要把区域箱子放在下部。这不能被更改。
其实例外可以对每个区域都增加,也可以用触发白名单在全局区域开启。
例子:在保护的区域中允许任何人使用红石机关:
/rg flag __global__ use allow
例子:在spawn区域为所有不是成员的玩家锁定物品丢弃和拾取:
/rg flag spawn item-pickup -g nonmembers deny
/rg flag spawn item-drop -g nonmembers deny
例子:为所有地皮的不是成员的玩家锁定经验掉落
/rg flag mall_parent exp-drops -g nonmembers deny
这是错的 /rg flag __global__ exp-drops -g nonmembers deny
这因为区域没有继承全局区域。
方块和实体
一个WG保护区域的重要特性是控制方块和实体,玩家可以成为一个区域的成员,但WG把方块和实体也这样看待,它们也可以成员区域的成员之一。
但是方块和实体不能像玩家一样通过命令加入区域。一个外部的活塞的方块不能进入区域,这就是原因。这是因为那个方块像non-member组,同样的,一些东西也不能改变方块。在区域中的活塞可以推动方块的原因是它像区域的一个成员。
WG同时也尝试检测事件真正的触发器。如一个砂砾在一个被保护区域上空被放置,它会调入被保护区域。WG认为最后生成的方块是由于掉落的砂砾,掉落的砂砾是由于高出的方块砂砾,因为它在区域外,不是区域内的“成员”,所以就会被保护。
当build标志在区域中设置为了deny没有人可以建筑,活塞也不会工作,因为人们不可以建筑,活塞像成员一般,也不会工作。
其他MOD和插件的支持:
一些MOD增加了新的游戏物品,如方块,道具,实体,MOD们需要API。
通常的,BUkkit插件一般会遵循保护插件,但事实不总是这样。有些MOD的支持几乎少的可怜,这些MOD不会遵循其他MOD和插件的保护。
最优保护
要注意的东西
可以改变其他方块和实体的方块和实体
发射弹射物的东西
WG可以在更多方块和实体上去保护。保护会预防左键右键方块和实体。这通常是足够的,因为这是与大多数方块和实体进行交互的唯一方法。
但WG不能保护在客户端上打开GUI的方块和实体,因为他们发送和接收的东西与WG无关。
其实,WG本身有的行动也不能控制,如一些自定义方块和实体。因为MC本身的一些方块也会影响世界,如活塞,但Bukkit组或你正在使用的服务端的维护者注意到这改变了世界,所以WG可以保护它们。
但是MOD的方块和实体不同,所以WG有时不能保护这些。
一些MOD会为了某些效果而虚拟一个玩家。这些玩家的名字基本上都是以MOD名来命名。但是这个消息除了对于识别是哪个MOD造成的,也可以使WG来预防一些行为。
要让MOD在保护的区域中发挥作用,虚拟玩家有特殊权限,这个配置可以在fake-player-build-override修改,这样就不会预防MOD在保护区域中工作了。
弹射物[和一些魔法MOD中的弹射物效果]是作者目前主要关注的问题。这是因为MOD不会提示插件弹射物的发射。
WG有一个工作区 emit-block-use-at-feet 设置,这个设置可以允许你设置一些物品类型,这会假装改变玩家的脚底下的方块。这会防止玩家烧掉他们自己的物品,但玩家不能在区域中使用物品,但在保护区域外,这不会工作
解决方案 如果出问题的是一个Bukkit插件,联系它的作者以增加对于保护插件的支持。这也可以通过使用WG API来解决。
如果出问题的是一个MOD,那你只能联系发布者以获得支持。
修复选择的区域可以:
如果你确信的话,你可以忽略。
你也可以禁用出问题的物品。
常见情节
如何启用红石开关? /rg flag REGION_NAME use allow
/rg flag __global__ use allow
如何让玩家骑马和矿车?
/rg flag REGION_NAME ride allow
/rg flag __global__ ride allow
如何预防在野外建筑?
/rg flag __global__ passthrough deny
怎么让不是成员的玩家不能出去?
/rg addmember example_region sk89q
/rg flag example_region exit -g nonmembers deny
如何让不是成员的玩家只能从一边出去?
设置两个区域
一个与上面相同
一个在区域的一侧,覆盖掉标志。exit=allow.
如何不保护所有附魔台?
在配置中的 interaction-whitelist 设置,加入 enchantment table. 使用Material来获取正确的名字。
怎么允许挖但不会破坏方块?
把 block-break 标志设置为allow:
- /rg flag mining_area block-break allow
怎么只能破坏一些方块?
对不起,现在不支持。
地皮设置
怎么设置地皮?
你首先要阅读优先级和继承,然后根据例子来创建,
/rg define mall
/rg define shop_template -g
/rg define shop1
/rg define shop2
/rg define shop3
/rg setparent shop_template mall
/rg setparent shop1 shop_template
/rg setparent shop2 shop_template
/rg setparent shop3 shop_template
/rg flag mall use deny
/rg flag shop_template use allow
问题
为什么活塞不工作?
你设置建筑权限了吗?
/rg flag __global__ build
如果你想保护野外,使用这个
/rg flag __global__ passthrough deny
不支持用活塞把一个区域中的方块推到另一个区域中。
为什么其他MOD的一些物品被禁用了?
参阅保护什么页面
箱子保护
WG提供了一个基础的自带的箱子保护功能,只需使用特殊的格式。我们不建议新手使用这个部分因为它不是WG一个活跃的部分。此外,WG有特殊的方式使得没法用漏斗从箱子偷东西。
如果你对于这个箱子保护感兴趣的话,我们推荐你使用第三方插件,如 Lockette 和 LWC.
起步
箱子保护必须先在配置中启用。当它被禁用时,箱子保护不会激活,但可以使用牌子锁[这个也可以在配置内禁用]
只要箱子下放一个牌子,就会保护,这个牌子:
必须是个标示牌
必须在箱子下面 (双层箱子需要最少在一个下面)
在第一行写下[Lock]
第二行有玩家的名字
可以在下面2行写下其他玩家的名字
在第二行写下别人的名字是不允许的
注意
WG中的箱子保护不支持UUID
警告
因为1.8的改变,把其他版本的箱子锁升级到1.8会破坏所有牌子。[其实是会破坏带有 [ ] 的牌子]
WG API
开发者
{{{标题}}} |
---|
译者毕竟不是开发者,所以翻译见谅
WG API在5.X和6.X版本就有了,推荐6.X maven存储库: http://maven.sk89q.com/repo/ 人工制品: com.sk89q:worldguard:VERSION VERSION即为版本 下面是作者给的一些示例 <repositories> <repository> <id>sk89q-repo</id> <url>http://maven.sk89q.com/repo/</url> </repository> </repositories> <dependencies> <dependency> <groupId>com.sk89q</groupId> <artifactId>worldguard</artifactId> <version>VERSION</version> </dependency> </dependencies> repositories { mavenCentral() maven { url "http://maven.sk89q.com/repo/" } } dependencies { compile 'com.sk89q:worldguard:VERSION' }
name: My Plugin version: 1.0 description: This is my plugin! depend: [WorldGuard]
import com.sk89q.worldguard.bukkit.WorldGuardPlugin; import org.bukkit.plugin.Plugin; private WorldGuardPlugin getWorldGuard() { Plugin plugin = getServer().getPluginManager().getPlugin("WorldGuard"); // WorldGuard may not be loaded if (plugin == null || !(plugin instanceof WorldGuardPlugin)) { return null; // Maybe you want throw an exception instead } return (WorldGuardPlugin) plugin; } import com.sk89q.worldguard.bukkit.WGBukkit; WorldGuardPlugin plugin = WGBukkit.getPlugin(); class MyPlugin { public void onEnable() { ProtectedCuboidRegion region = new ProtectedCuboidRegion(...); } } class RegionHolder { private final ProtectedCuboidRegion region; public MyPlugin() { region = new ProtectedCuboidRegion(...); } } class MyPlugin { public void onEnable() { try { new RegionHolder(); } catch (NoClassDefFoundException e) { // Do something here } } } class MyPlugin { public void onEnable() { try { boolean result = SomeClass.staticMethod(); } catch (NoClassDefFoundException e) { // Do something here } } } 译者是个翻译官,开发什么的就免了。 有问题还是去问作者吧 这个我是没法解答了。 |
建筑检查
{{{标题}}} |
---|
boolean canBuild(Player player, Location loc); boolean canBuild(Player player, Block block); getWorldGuardPlugin().canBuild(player, block.getRelative(0, -1, 0)); |
区域构建
管理者
{{{标题}}} |
---|
RegionContainer container = getWorldGuard().getRegionContainer(); RegionManager regions = container.get(world); ProtectedRegion region = regions.getRegion("spawn"); RegionContainer container = getWorldGuard().getRegionContainer(); RegionManager regions = container.get(world); if (regions != null) { return regions.getRegion("spawn"); } else { // The world has no region support or region data failed to load } RegionContainer container = getWorldGuard().getRegionContainer(); RegionManager regions = container.get(world); regions.addRegion(region); regions.removeRegion("mall", RemovalStrategy.UNSET_PARENT_IN_CHILDREN); save() saveChanges() load() |
区域
{{{标题}}} |
---|
ProtectedRegion class 子class ProtectedCuboidRegion ProtectedPolygonalRegion GlobalProtectedRegion region.setPriority(100); mall.setParent(null); // No parent plot.setParent(mall); if (region instanceof ProtectedPolygonalRegion) { ProtectedPolygonalRegion polygon = (ProtectedPolygonalRegion) region; List<BlockVector2D> points = polygon.getPoints(); } DefaultDomain members = region.getMembers(); members.addPlayer("sk89q"); members.addPlayer(UUID.fromString("0ea8eca3-dbf6-47cc-9d1a-c64551ca975c")); members.addGroup("admins"); // Google's Guava library provides useful concurrency classes. // The following executor would be re-used in your plugin. ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool()); String[] input = new String[] { "sk89q", "g:admins" }; ProfileService profiles = getWorldGuard().getProfileService(); DomainInputResolver resolver = new DomainInputResolver(profiles, input); resolver.setLocatorPolicy(UserLocatorPolicy.UUID_AND_NAME); ListenableFuture<DefaultDomain> future = executor.submit(resolver); // Add a callback using Guava Futures.addCallback(future, new FutureCallback<DefaultDomain>() { @Override public void onSuccess(DefaultDomain result) { region.getOwners().addAll(result); } @Override public void onFailure(Throwable throwable) { // Do something about the error } }); DefaultFlag.BUILD DefaultFlag.PVP DefaultFlag.LEAF_DECAY DefaultFlag.LIGHTNING String message = region.getFlag(DefaultFlag.GREET_MESSAGE); player.sendMessage(message); region.setFlag(DefaultFlag.GREET_MESSAGE, "Hi there!"); RegionGroupFlag flag = DefaultFlag.PVP.getRegionGroupFlag(); region.setFlag(DefaultFlag.USE, StateFlag.State.ALLOW); region.setFlag(DefaultFlag.USE.getRegionGroupFlag(), RegionGroup.MEMBERS); BlockVector min = new BlockVector(-10, 5, -4); BlockVector max = new BlockVector(5, -8, 10); ProtectedRegion region = new ProtectedCuboidRegion("spawn", min, max); List<BlockVector2D> points = Lists.newArrayList(); // Call from Guava points.add(new BlockVector2D(3, 4, 5)); points.add(new BlockVector2D(0, 0, 0)); points.add(new BlockVector2D(19, 3, 4)); int minY = 0; int maxY = 54; ProtectedRegion region = new ProtectedPolygonalRegion("spawn", points, minY, maxY); ProtectedRegion region = new GlobalProtectedRegion("template"); region.contains(new Vector(20, 0, 30)); List<ProtectedRegion> candidates = Lists.newArrayList(); candidates.add(mall); candidates.add(hospital); List<ProtectedRegion> overlapping = spawn.getIntersectingRegions(candidates); isDirty() |
空间查询
{{{标题}}} |
---|
ApplicableRegionSet RegionQuery query = container.createQuery(); ApplicableRegionSet set = query.getApplicableRegions(location); Location loc = new Location(world, 10, 64, 100); RegionContainer container = getWorldGuard().getRegionContainer(); RegionQuery query = container.createQuery(); ApplicableRegionSet set = query.getApplicableRegions(loc); Vector position = new Vector(20, 10, 4); ApplicableRegionSet set = regions.getApplicableRegions(position); Location loc = new Location(world, 10, 64, 100); RegionContainer container = getWorldGuard().getRegionContainer(); RegionManager regions = container.get(loc.getWorld()); // Check to make sure that "regions" is not null ApplicableRegionSet set = regions.getApplicableRegions(BukkitUtil.toVector(loc)); Vector min = new Vector(0, 0, 0); Vector max = new Vector(10, 10, 10); ProtectedRegion test = new ProtectedCuboidRegion("dummy", min, max); ApplicableRegionSet set = regions.getApplicableRegions(test); List<ProtectedRegion> regions = Lists.newArrayList(); regions.add(spawn); regions.add(mall); regions.add(pub); ApplicableRegionSet set = new RegionResultSet(regions, null); // No global region for (ProtectedRegion region : set) { // Do something with each region } List<ProtectedRegion> region = Lists.newArrayList(set); |
计算权限
{{{标题}}} |
---|
queryAllValues(RegionAssociable, Flag) LocalPlayer localPlayer = getWorldGuard().wrapPlayer(player) Collection<String> greetings = set.queryAllValues(localPlayer, DefaultFlag.GREET_MESSAGE); LocalPlayer localPlayer = getWorldGuard().wrapPlayer(player) String greeting = set.queryValue(localPlayer, DefaultFlag.GREET_MESSAGE); LocalPlayer localPlayer = getWorldGuard().wrapPlayer(player) if (!set.testState(localPlayer, DefaultFlag.BUILD)) { event.setCancelled(true); } if (!set.testState(null, DefaultFlag.CREEPER_EXPLOSION)) { event.setCancelled(true); } LocalPlayer localPlayer = getWorldGuard().wrapPlayer(player) Location loc = new Location(world, 10, 64, 100); RegionContainer container = getWorldGuard().getRegionContainer(); RegionQuery query = container.createQuery(); // No need to bother: // ApplicableRegionSet set = query.getApplicableRegions(loc); // Just directly test the flag query.testState(loc, localPlayer, DefaultFlag.BUILD); testState(..., DefaultFlag.BUILD, your flags) List<ProtectedRegion> regions = Arrays.asList(spawnRegion, buildersClub); builderPlayer.getAssociation(regions) == Association.OWNER; Set deepInside = newHashSet(spawn, mall); Set inside = newHashSet(spawn); Set outside = newHashSet(); // Empty set // outside -> inside = BLOCKED new RegionOverlapAssociation(outside).getAssociation(inside) == NON_MEMBER // inside -> inside = ALLOWED new RegionOverlapAssociation(inside).getAssociation(inside) == MEMBER // inside -> deepInside = ALLOWED new RegionOverlapAssociation(inside).getAssociation(deepInside) == MEMBER // inside -> outside = ALLOWED new RegionOverlapAssociation(inside).getAssociation(outside) == MEMBER private RegionAssociable createRegionAssociable(Object cause) { if (cause instanceof Player) { return getWorldGuard().wrapPlayer((Player) cause); } else if (cause instanceof Entity) { RegionQuery query = getWorldGuard().getRegionContainer().createQuery(); return new DelayedRegionOverlapAssociation(query, ((Entity) cause).getLocation()); } else if (cause instanceof Block) { RegionQuery query = getWorldGuard().getRegionContainer().createQuery(); return new DelayedRegionOverlapAssociation(query, ((Block) cause).getLocation()); } else { return Associables.constant(Association.NON_MEMBER); } } @EventHandler public void onPlayerBucketFill(PlayerBucketFillEvent event) { Player player = event.getPlayer(); RegionAssociable associable = createRegionAssociable(getWorldGuard().wrapPlayer(player)); if (!set.testState(associable, /* flags here */)) { event.setCancelled(true); } } |
保护查询
{{{标题}}} |
---|
LocalPlayer localPlayer = getWorldGuard().wrapPlayer(player)
Location loc = new Location(world, 10, 64, 100); RegionContainer container = getWorldGuard().getRegionContainer(); RegionQuery query = container.createQuery(); if (!query.testState(loc, localPlayer, DefaultFlag.BUILD)) { // Can't build } |
区域事件
DisallowedPVPEvent 禁止PVP
从水桶服的一些物体
getWorldGuard().wrapPlayer(player);
BukkitUtil.toVector(location);
高级话题
事件的记录
漏斗式事件
Bukkit 在发生事件的时候通知插件,有许多所谓的事件,如
- Bucket fill
- Bucket empty
- Right click of an entity by a player
- Placement of a block by a player
- Digging of a block by a player
- Change of a block by an entity
- Piston push
- Push retract
但这些可以在MC中归于三类
- Items
- Blocks
- Entities
你可以关于这些做一些事
- Place them
- Break them
- Interact with them
- Damage them
为了简化事件,WG提供了以下方式
- Bucket fill → Interact with a block, Interact with an item
- Bucket empty → Interact with a block, Interact with an item
- Right click of an entity by a player → Interact with an entity
- Placement of a block by a player → Interact with a block
- Digging of a block by a player → Interact with a block
- Change of a block by an entity → Interact with a block
- Piston push → Interact with a block
- Push retract → Interact with a block
WG的部分,如区域保护,需要“interact with a block,” “interact with an entity,” 等 ,然后会检测方块 实体被触发。
检测触发
计算一些东西的另一方面是可以用简介的东西来完成这个复杂的事件。
例如,如果一个玩家对另一个玩家射箭,直接的触发器 -- 箭 -- 不是真正的触发器,玩家才是。
另一个例子是放置砂砾,它会掉落:最后掉在地上是因为(1)掉落实体,因为(2)砂砾方块被触发,(3)被玩家放置。
记住它是玩家导致的,其他例子可能是方块或实体。
但是,不可能总是检测正确。WG有时必须追踪事件链。
显示内部事件
这里只有一些有用的内部事件来检测。把它们放到服务器记录是可能的,允许你:
找出某些活动的黑名单
查看WG是否在操控活动
加入WG贡献组来查看它支持的内部事件
要使用这个模式,在命令行加入参数 -Dworldguard.debug.listener=true
提示: 这个特性最好在一个私人服务器上使用,不要在大型服务器使用,会刷屏。
可以在BAT文件启用
原来你的BAT是这样的
@ECHO OFF SET BINDIR=%~dp0 CD /D "%BINDIR%" "%ProgramFiles(x86)%\Java\jre7\bin\java.exe" -Xincgc -Xmx1G -jar craftbukkit.jar PAUSE You’d add -Dworldguard.debug.listener=true like so:
改为这样
@ECHO OFF SET BINDIR=%~dp0 CD /D "%BINDIR%" "%ProgramFiles(x86)%\Java\jre7\bin\java.exe" -Dworldguard.debug.listener=true -Xincgc -Xmx1G -jar craftbukkit.jar PAUSE
放在-jar之前的任意位置,在java.exe之后。
解释输出
让我们看看在区域上方放一个砂砾,你可以看到在控制台中:
* USE GRAVEL [Player{sk89q}] @world :BlockPlaceEvent * PLACE GRAVEL @0,99,0 [Player{sk89q}] :BlockPlaceEvent * SPAWN FALLING_BLOCK [Block{0,99,0}] @-0,99,0 :EntityChangeBlockEvent * PLACE GRAVEL @ [Block{0,99,0} | FallingSand] :EntityChangeBlockEvent [CANCELLED] * SPAWN DROPPED_ITEM [Block{0,99,0} | FallingSand] @-0,0,0 :EntityChangeBlockEvent
输出已经缩短并且有格式化
每行的语法是这样的
ACTION TYPE/LOCATION [CAUSES] @LOOCATION :BUKKIT-EVENT [CANCELLED?]
取消的事件被锁定?
讲解实例
首先,当砂砾被放置,会
* USE GRAVEL [Player{sk89q}] @world :BlockPlaceEvent
这是玩家放置,然后是真正的放置触发
* PLACE GRAVEL @0,99,0 [Player{sk89q}] :BlockPlaceEvent
因为砂砾被放在空气中,会掉落成实体——
* SPAWN FALLING_BLOCK [Block{0,99,0}] @-0,99,0 :EntityChangeBlockEvent
当砂砾落地时会尝试生成一个新的砂砾方块并移除实体——
* PLACE GRAVEL @ [Block{0,99,0} | FallingSand] :EntityChangeBlockEvent [CANCELLED]
因为掉落进了一保护区域,会生成一个掉落物——
* SPAWN DROPPED_ITEM [Block{0,99,0} | FallingSand] @-0,0,0 :EntityChangeBlockEvent
--全过程
普通问题
常规
为什么一个命令都不工作?
如果没有命令工作,可能是WG启动失败了。
请注意你的服务端是Bukkit或[其他兼容插件的服务器],在后台或游戏里使用/version来查看版本。
确保你安装了WE。
确保如果你下载的是zip文件,你已经解压。
确保你使用的是对应Minecraft版本的WG。
如果这些不能帮助你,你需要查看你的启动日志。
你可以打开latest.log来查看日志。
如果你还是不能发现问题,在获取帮助页面的汇报BUG链接中反馈。
WG多大了?
WG是2010.11被sk89q写出的,当时是个MOD,之后便有了插件的版本。
谁在发展WG
WG被许多人发展,WG的很多代码都是贡献代码,贡献者列表可以在Github找寻。
不能破坏
为什么玩家不能破坏方块?
全新的WG中的许多特性都是未启用的,所以这基本不可能是WG引起。
一个简单去找寻原因的方法是查看在你破坏方块时收到的信息。WG一般使用暗红和深红的颜色,和这样的消息“Hey! Sorry, but you can’t _____ here.”如果你没有收到信息,那就不是WG的锅。
如果不是一安装WG就这样的话,确保出生点保护没有启用。出生点保护会保护世界出生点以内的区域,若要取消,把 spawn-protection 改为0 [server.properties]。
同样确保你没有使用冒险模式。更新你的Bukkit/Spigot/Cauldron的版本。
如果这些步骤不行的话,WG中有一个简单的指令可以探测是什么插件阻止了这个事件的发生。使用 “testbreak” 和 “testplace” 来查看。
如果是WG造成的话:
使用区域魔杖来查看是否有区域保护了方块,如果有一些的话,可能你不知道,查看下一个问题。
检查是否启用了建筑权限,检查配置文件是否禁止了这个事件。
如果你不能解决问题,查看获取帮助页。
如果指令列出了另一个插件:
查看你是否关于那个插件要给予另外的权限。
如果什么都没有列出,查看上方的出生点保护设置,然后去获取帮助页。
在设置了区域之后,为什么都不能建筑?
使用区域魔杖,然后右键一个方块,去查看所有区域。使用/rg info来查看每个区域的信息。
确保合适所有区域的成员。
确保建筑权限没有禁止。
这里只有全局区域吗?
确保全局设置没有被禁用;确保M全局区域的穿过没有设置为禁用;确保全局区域没有成员和主人。
建筑没有锁定
为什么保护没有工作?但玩家没有收到消息?
你是OP,有完全权限,但玩家没有
你把一个区域的建筑和穿过权限设置成了allow
你把其他的一些权限设置成了allow
物品可能来自于MOD或第三方插件[见保护什么
WG并不会保护你特别说明的一些东西。这不是简单的方块破坏或放置的情况。请确保你在使用最新版本的WG,如果还是有BUG,做BUG反馈。
这是你Bukkit, Spigot, 或 Cauldron 版本中的BUG
如果你还不能解决问题,查看问题解决页面
为什么建筑控制不工作?玩家收到信息
如果WG锁定了一个事件,对于第三方插件来说也是可以解除锁定的,但是WG也发送了你不能XX的消息。
你可以使用testbreak和testplace指令来查看,如果在列表中发现ALLOW,就是那个插件造成的。
另一个原因是版本错误。如果还不能解决问题,查看问题帮助。
区域保护
为什么活塞不工作?
你可能把权限设置成deny了。查看 常见情节 节
关于区域保护我怎么XXXX
查看 常见情节 节
获取帮助
如果你有一个问题的话 [在论坛询问] [加入IRC] [在Twitter上联系sk89q]
如果你要汇报BUG的话 [在这里汇报]
译者注:全部都要翻墙
开源地址
你可以在[Github]找到资源代码。 WG是开源的,但贡献者必须遵守GNU Lesser General Public License v3。
链接
- [主页地址]
- [BukkitDev下载地址]
- [旧版WIKI]
地址
http://docs.enginehub.org/manual/worldguard/latest/regions/priorities/