开发者 API

开发者 API

Residence 的最新开发版提供了开发者 API,支持添加和处理自定义旗帜,以及一些自定义 Bukkit 事件的支持。我会在论坛帖子中为任何制作 Residence 附加组件的人提供额外帮助。如果你的插件需要 Residence 目前未提供的 API 功能,请在主论坛帖子中提出,我会尽量添加。下载文件可在下载页面找到。

添加自定义旗帜

我假设你熟悉 Bukkit,以及如何在编程项目中添加 .jar 文件作为库。我也假设你知道如何使用 Bukkit 的 Listener 类。

以下步骤以添加 "build" 旗帜为例。

第 1 步: 首先,将 Residence.jar 作为库添加到你的插件中。

第 2 步: 告诉 Residence "build" 是一个有效旗帜。可以通过 FlagPermissions 类实现:

FlagPermissions.addFlag("build");

第 3 步: 实际处理此旗帜。由于我们添加的是 "build" 旗帜,需要在 onBlockPlace() Bukkit 监听事件中添加代码。首先检查方块放置是否在领地内,通过尝试获取有效 ClaimedResidence 对象:

Location loc = event.getBlock().getLocation();
ClaimedResidence res = Residence.getResidenceManager().getByLoc(loc);

然后进行空值检查:

if(res!=null)

如果 res 为 null,说明该位置没有领地;否则获取到了领地,需要检查 "build" 旗帜是否允许。首先获取领地权限:

ResidencePermissions perms = res.getPermisssions();

然后检查 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 对象:

Location loc = event.getBlock().getLocation();
FlagPermissions = Residence.getPermsByLoc(loc);

如果该位置没有领地,将自动使用世界权限,将两个检查合二为一。

自定义 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);

检查玩家是否可以伤害实体:

ResidencePlayer rPlayer = Residence.getInstance().getPlayerManager().getResidencePlayer(attacker);
boolean canDamage = rPlayer.canDamageEntity(Entity entity, boolean inform);