开发者 API
开发者 API
Residence 的最新开发版提供了开发者 API,支持添加和处理自定义旗帜,以及一些自定义 Bukkit 事件的支持。我会在论坛帖子中为任何制作 Residence 附加组件的人提供额外帮助。如果你的插件需要 Residence 目前未提供的 API 功能,请在主论坛帖子中提出,我会尽量添加。下载文件可在下载页面找到。
添加自定义旗帜
我假设你熟悉 Bukkit,以及如何在编程项目中添加 .jar 文件作为库。我也假设你知道如何使用 Bukkit 的 Listener 类。
以下步骤以添加 "build" 旗帜为例。
第 1 步: 首先,将 Residence.jar 作为库添加到你的插件中。
第 2 步: 告诉 Residence "build" 是一个有效旗帜。可以通过 FlagPermissions 类实现:
第 3 步: 实际处理此旗帜。由于我们添加的是 "build" 旗帜,需要在 onBlockPlace() Bukkit 监听事件中添加代码。首先检查方块放置是否在领地内,通过尝试获取有效 ClaimedResidence 对象:
Location loc = event.getBlock().getLocation();
ClaimedResidence res = Residence.getResidenceManager().getByLoc(loc);
然后进行空值检查:
如果 res 为 null,说明该位置没有领地;否则获取到了领地,需要检查 "build" 旗帜是否允许。首先获取领地权限:
然后检查 build 是否被允许,如果不允许则取消事件:
String playerName = event.getPlayer().getName();
boolean defaultValue = true;
boolean hasPermission = perms.playerHas(playerName, "build", defaultValue);
if(!hasPermission)
event.setCancelled(true);
第 4 步(可选): 如果想让你的旗帜也成为有效的世界权限(可在整个世界设置,不仅限于领地内),当 res == null 时进行不同的检查。首先获取世界权限列表:
String worldName = event.getBlock().getWorld().getName();
FlagPermissions perms = Residence.getWorldPermisssions(worldName);
然后使用相同的 playerHas() 函数检查旗帜:
boolean hasPermission = perms.playerHas(playerName, "build", defaultValue);
if(!hasPermission)
event.setCancelled(true);
第 5 步(合并第 3 和第 4 步): 如果不关心位置是否在领地内,只想检查玩家是否被允许在特定位置执行操作,可以使用简化函数获取 FlagPermissions 对象:
如果该位置没有领地,将自动使用世界权限,将两个检查合二为一。
自定义 Bukkit 事件
有多个自定义 Bukkit 事件可供挂钩。使用时需要创建一个继承 Bukkit CustomEventListener 类的类,然后重写 onCustomEvent() 方法:
public class MyListener extends CustomEventListener {
@Override
public void onCustomEvent(Event event) {
// 处理事件
}
}
创建此类的实例,然后在插件主类中注册到 Bukkit:
getServer().getPluginManager().registerEvent(Event.Type.CUSTOM_EVENT, myListener, Priority.Normal, this);
现在可以捕获 Residence 事件,详见下一节。
Residence Bukkit 事件
以下是当前可捕获的 Residence 事件列表:
- ResidenceCommandEvent — 当玩家使用 Residence 注册的命令时触发。
- ResidenceFlagChangeEvent — 当领地旗帜被更改时触发。(可取消)
- ResidenceFlagCheckEvent — 当检查领地旗帜时触发。(可覆盖返回值)
- ResidenceOwnerChangeEvent — 当领地所有者变更时触发。
- ResidenceCreationEvent — 创建新领地时触发。(可取消)
- ResidenceSubzoneCreationEvent — 创建新子分区时触发。(可取消)
- ResidenceRenameEvent — 领地重命名时触发。
- ResidenceSizeChangeEvent — 领地调整大小时触发。
- ResidenceChatEvent — 玩家发送领地聊天消息时触发。
- ResidenceTPEvent — 玩家传送到领地时触发。
- ResidenceAreaAddEvent — 向领地添加新区域时触发。
- ResidenceAreaDeleteEvent — 删除领地区域时触发。
- ResidenceDeleteEvent — 删除领地时触发,可查询原因。(可取消)
- ResidenceRentEvent — 所有租赁相关事件触发,可查询原因。(可取消)后续会增加更多。
- ResidenceChangedEvent — 玩家更换领地时触发,包括子分区变化。
- ResidenceRaidEndEvent — 突袭事件结束时触发。
- ResidenceRaidPreStartEvent — 突袭实际开始前触发。
- ResidenceRaidStartEvent — 突袭开始时触发。
要确定 CustomEventListener 类中调用了哪个事件,需要使用 Java 的 instanceof 运算符并将每个事件转换为正确的类:
if(event instanceof ResidenceCommandEvent) {
ResidenceCommandEvent e = (ResidenceCommandEvent) event;
// 处理事件
} else if(event instanceof ResidenceFlagChangeEvent) {
ResidenceFlagChangeEvent e = (ResidenceFlagChangeEvent) event;
// 处理事件
}
以此类推。所有 Residence 事件都允许通过 getResidence() 方法访问对应的 ClaimedResidence 对象。
其他有用的 API 调用
Residence API 还有很多其他功能。每个 Residence 子系统都有一个"管理器",可通过主 Residence 类的静态方法访问:
// ResidenceManager — 管理和控制所有领地
ResidenceManager rmanager = Residence.getResidenceManager();
// SelectionManager — 控制创建领地的选择点
SelectionManager smanager = Residence.getSelectionManager();
// EconomyManager — 返回 Residence 挂钩的经济插件接口
EconomyInterface econ = Residence.getEconomyManager();
// ConfigManager — 持有配置文件中的配置设置
ConfigManager cmanager = Residence.getConfigManager();
// PermissionManager — 持有配置中的权限组以及任何权限插件的链接
PermissionManager pmanager = Residence.getPermissionManager();
// WorldFlagManager — 持有适用于整个世界的旗帜
WorldFlagManager wmanager = Residence.getWorldFlags();
还有更多,但这些是较重要的。
手动启用 Residence
如果你的插件名称首字母在 "R" 之前,你的插件可能在 Residence 之前启用。如果你需要立即使用 Residence 功能,这可能会有问题,因为 Residence 尚未完全初始化。为安全起见,可以包含代码检查 Residence 是否存在并已启用:
PluginManager pm = getServer().getPluginManager();
Plugin p = pm.getPlugin("Residence");
if(p!=null) {
if(!p.isEnabled()) {
System.out.println(" - Manually Enabling Residence!");
pm.enablePlugin(p);
}
} else {
System.out.println(" - Residence NOT Installed, DISABLED!");
this.setEnabled(false);
}
检查玩家是否可以放置方块:
ResidencePlayer rPlayer = Residence.getInstance().getPlayerManager().getResidencePlayer(attacker);
boolean canPlace = rPlayer.canPlaceBlock(Block block, boolean inform);
检查玩家是否可以破坏方块:
ResidencePlayer rPlayer = Residence.getInstance().getPlayerManager().getResidencePlayer(attacker);
boolean canBreak = rPlayer.canBreakBlock(Block block, boolean inform);
检查玩家是否可以伤害实体: