创建项目
根据 (Spigot开发笔记-1) 中的内容创建好项目。
插件功能蓝图
匠魂mod中有一个随着使用会强化自身的附属mod,初步就是实现一个这样的功能:工具使用可以增强自身。
那么接下来我们大致会需要以下知识点,接下来将一个一个来:
- 指令模块:提供工具的生成和测试操作
- 事件模块:监听挖掘等等事件进行后续功能实现
- 插件中间层:包括utils、自定义类、Spigot 上二次封装,方便进行解耦工作
实现思路
1. 指令模块
你可以执行下面的代码来注册一个 已存在于 plugin.yml
的指令:
public static void easyRegCommand(CommandExecutor executor, String name) {
pluginInstance.getCommand(name).setExecutor(executor);
}
在 plugin.yml
中这样写,就算注册了一个叫做 pic
的指令:
name: PowerItemCraft
version: '${project.version}'
main: nesb01t.poweritemcraft.PowerItemCraft
api-version: 1.14
commands:
pic:
description: This is main controller
usage: /pic
aliases:
- pi
- poweritemcraft
- poweritem
接下来是这个指令的简单实现,在一个合适的位置执行就可以注册指令了,一般是插件主类的 onEnable
中:
PowerItemCraft.easyRegCommand(new givePowerItem(), "pic");
public class givePowerItem implements CommandExecutor {
public static void givePowerItemToPlayer(String materialName, Player player) {
ItemStack poweritem = createNewItem(getMaterialByName(materialName));
player.getInventory().addItem(poweritem);
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
Player player = (Player) sender;
MessageUtils.sendPlayerMsg(player, String.valueOf(args.length));
if (args.length == 1) {
givePowerItemToPlayer(args[0], player);
}
return true;
}
}
2. 事件模块
和指令不同的是,您不需要再编写 plugin.yml
,除此之外大致相同,这是注册 Listener
的方法:
public static void easyRegEvent(Listener listener) {
pluginInstance.getServer().getPluginManager().registerEvents(listener, pluginInstance);
}
这是我其中的一个监听器类:
public class PowerItemBreakEvent implements Listener {
@EventHandler
public void onItemBreak(PlayerItemBreakEvent event) {
if (event.getBrokenItem().getItemMeta().getLore().isEmpty()) {
return;
}
Player player = event.getPlayer();
ItemStack item = event.getBrokenItem();
updateNewItem(player, item);
}
public void updateNewItem(Player player, ItemStack item) {
item.setDurability((short) 0);
ItemModifier.levelUp(item, player);
player.setItemInHand(item);
}
}
3. 插件中间层 🌟
3.1 主类的工作
这是插件设计的关键部分,在插件 PowerItemCraft
主类初始化时,进行了这样的操作:
- 获取插件实例并广播到整个包
- 新建了一个类
Core
用于初始化和维护整个插件的动态属性 - 在
Core
初始化时进行了事件和指令注册 - 完成初始化内容并在
console
中显示加载成功
3.2 如何解耦
诚然,可以只用 指令
和 事件
两个类完成整个插件的工作,例如:
- 通过
/pic 指令
获取 PowerItem 武器 - 通过
onDamage
事件监听武器使用,并随机给予经验,然后判断武器是否升级 - 如果升级则在
代码嵌套
中设置武器的外观提示,属性修改等等
但是这样就会遇到一个问题,在你的 onDamage.java
监听器中可能会出现长达500行甚至更多的代码。这并不酷,如果后期你想要增加新的功能,比如说增加 挖掘事件
增加经验的功能,你就需要把整坨代码复制过来然后改一部分,这时就会暴露出大量致命的问题,随着代码的迭代会逐渐加深问题的严重性。解决这个问题也很简单:
- 学习Java中实用简单的设计模式
- 多阅读优秀开源插件源码并学习插件结构
由于本人刚刚开始 Spigot 的开发学习,这里就不过多进行一个丑的献,如果您有兴趣可以阅读 PowerItemCraft 的源码,新冠放开初期我边学边做的一个物品插件
完整插件
由于篇幅限制,插件的完整源码存在我的 GitHub 上,这里就直接进行引用了,希望读到这里的开发者可以不吝赐教!