- 欢迎来到Minecraft插件百科!
- 对百科编辑一脸懵逼?帮助:快速入门带您快速熟悉百科编辑!
- 因近日遭受攻击,百科现已限制编辑,有意编辑请加入插件百科企鹅群:223812289
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找到它们
设置项 | 默认值 | 介绍 |
---|---|---|
op-permissions | TRUE | 是否给予OP插件的所有权限,甚至是插件没有给OP的权限 |
summary-on-start | TRUE | 是否在服务器开启时显示每个世界的设置,如果你有多个世界的话,建议关闭 |
auto-invincible | FALSE | 是否在玩家登入时自动给予无敌权限 |
auto-invincible-group | FALSE | 给予玩家无敌组的权限 |
auto-no-drowning-group | FALSE | 在登入时是否给予玩家水下呼吸的权限 |
use-player-move-event | TRUE | 消耗更多的CPU来检测玩家移动,这些需要在治疗,饮食,喂动物,和一些其他权限使用 |
use-player-teleports | TRUE | 示例 是否在传送时考虑玩家的移动状态,传送事件不会因为玩家传送而必然发生,只是在可能的时候。 |
host-keys | XXXXX | 玩家必须从哪些域名进入服务器,见热键。 |
热键
Frequently in the past, Minecraft had failures in its login code where players could login to a server as any player, including administrators and moderators. Between 2010 and 2013, exploits of this nature were made public five times, frequently leading to thousands of servers being hacked.
The host keys feature was added to WorldGuard as an extra barrier to impersonation. It works because an extra piece of information, not known by Mojang, has to be sent from the client during login to a server. Even if an attacker were able to break Minecraft’s login system and join as a moderator, because the attacker’s game would lack this piece of information, the server could detect impersonation.
Note Security breaches of this nature are less common these days. How It Works When a player connects to a server with an address, say play.example.com, Minecraft will tell the server that the player connected with that address. A moderator could connect to a special, secret secretmod.play.example.com address, and the server could easily check whether the address used by the moderator started with secretmod.
The host keys feature allows you to configure an an accepted address for certain players. If a player on the list connects with an incorrect address, he or she is kicked immediately.
Configuration Setup is done using the Configuration:
host-keys:
your_username: bagels.play.example.com moderator1_name: manoverboard.play.example.com
Note Host keys do not support UUIDs yet. DNS Configuration To make this work, you have to make bagels.play.example.com and manoverboard.play.example.com point to your server. However, you should not add specific records for the domains that you use, because this allows attackers to easily figure out the secret domains.
Rather, it is recommended that you setup “wildcard addresses.” An example of a wildcard address may be *.play.example.com, which would mean that any prefix would work (aa.play.example.com, ab.play.example.com, ac.play.example.com, etc.).
Tip If you don’t have a domain name or can’t set a wildcard address, you can use xip.io. Alternatives An alternative to host keys, although not provided by WorldGuard, is to use some sort of login command that takes a password.
权限
建筑权限
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 权限
区域权限
优先级与继承
全局区域
区域认领
存储
保护什么
常见情节
箱子保护
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/