我的世界插件制作详细图文教程 教你制作强大的CraftBukkit插件
我的世界里有着各种不同的插件,这些插件能实现非常非常多的功能,以至于有些功能都难以置信,下面游戏园的小编就为大家解析一下我的世界怎么自己制作插件,那么到底我的世界插件制作都需要准备哪些呢?下面就请大家一起来看看吧!
序言
一、要想成功编写一个大型插件,你应准备好如下条件
充沛的精力,充足的时间,和坚持不懈的精神 —— 制作插件是一个既耗时又耗精力的事情,建议高中生不要参与进来,等毕业再来也不迟;
具有自主学习的能力 —— 一个大型插件需要多种知识的配合,比起忙碌的人,搜索引擎是你最好的朋友;
较高的英文水平 —— MC是外国人编写的,Bukkit也是外国人编写的,看英文更容易理解其本质,所以英语知识是必要的;
团队合作精神 —— 如果你拥有一个有同样爱好同样目标相互信赖的团队,效率将大大提高,插件质量也将更好,其它事情也是如此;
对计算机语言有较大兴趣,而不是一看代码就懵 —— 看一眼就腰酸背痛腿肚软,头昏脑胀胃筋挛,肯定是无法编写下去的;
注意运动,健康地进行插件编写这一活动 —— 长时间坐在电脑前对身体不好,而且还容易产生疲劳和厌倦感;
JAVA开发组件(JDK) —— 你做插件需要用到的最基本的工具,推荐再下载一个集成开发环境(IDE),下一章会说明安装方法;
综上所述,只要你有时间,有能力,就可以编个小插件,大型插件建议团队合作。而编写插件时,不要忘了保持自身良好的状态。
二、简略认识JAVA
JAVA,是一种可以撰写跨平台应用软件的面向对象的程序设计语言,以人认识世界的方式来设计编程的方式。
JAVA主要术语:
类:JAVA程序的基本组成成分,基于面向对象思想,一些具有相同特点的事物被抽象化成一个类;
对象(实例):从类中具体化(实例化)的具有该类特点的某一个事物;
句柄(引用,指针):你不能直接操作对象,因此你需要一个句柄来确定是哪个对象并操作。
构造器:一般需要调用构造器才能实例化出一个对象;
成员变量(属性):事物具有的特点被储存在属性里,可以被一个类所拥有,也可以被每一个单独对象所拥有;
函数(方法):你与事物之间的交互用方法来完成;
静态:属于类,也就是所有对象共同拥有的部分被称为静态成员。
非静态:属于每一个单独对象的部分被称为非静态成员(这个成员可能名称相同但内容不同)。
三、简略认识CraftBukkit插件成分
CB插件主要成分:
插件主类:一般与插件同名,作为插件的启动器,服务器启动时将首先执行插件主类里的方法,
所有插件功能最初都由此触发;
事件:游戏内数据的变化将引起事件,事件按其主要参与对象的主动和被动的行为特点分类;
监听器:按事件的类别分类,一个监听器可以监听一个或多个事件,通过事件的发生触发一些代码;
命令执行器:当玩家输入某一命令时(聊天时内容以“/”开头),由命令执行器执行该命令所触发的代码;
信息文件:plugin.yml,记录插件的主类位置,名称,以及版本等等,需要手动添加,缺少此文件插件将无法运行;
设置文件:CB为每个插件都配置了一个默认的设置文件(config.yml),你可以将插件的相关设定都放置在此文件中;
数据库:用来储存相关数据,虽然YAML文件同样能做到,但用数据库更安全更稳定(方便还真不敢说)。
四、为你的插件做个计划
你要做一个什么方面的插件;
你的插件能干什么;
你要如何使你的插件起作用;
你做这个插件后对服务器有什么好处;
如何能使你的插件达到小而精悍。
我的世界里有着各种不同的插件,这些插件能实现非常非常多的功能,以至于有些功能都难以置信,下面游戏园的小编就为大家解析一下我的世界怎么自己制作插件,那么到底我的世界插件制作都需要准备哪些呢?下面就请大家一起来看看吧!
序言
一、要想成功编写一个大型插件,你应准备好如下条件
充沛的精力,充足的时间,和坚持不懈的精神 —— 制作插件是一个既耗时又耗精力的事情,建议高中生不要参与进来,等毕业再来也不迟;
具有自主学习的能力 —— 一个大型插件需要多种知识的配合,比起忙碌的人,搜索引擎是你最好的朋友;
较高的英文水平 —— MC是外国人编写的,Bukkit也是外国人编写的,看英文更容易理解其本质,所以英语知识是必要的;
团队合作精神 —— 如果你拥有一个有同样爱好同样目标相互信赖的团队,效率将大大提高,插件质量也将更好,其它事情也是如此;
对计算机语言有较大兴趣,而不是一看代码就懵 —— 看一眼就腰酸背痛腿肚软,头昏脑胀胃筋挛,肯定是无法编写下去的;
注意运动,健康地进行插件编写这一活动 —— 长时间坐在电脑前对身体不好,而且还容易产生疲劳和厌倦感;
JAVA开发组件(JDK) —— 你做插件需要用到的最基本的工具,推荐再下载一个集成开发环境(IDE),下一章会说明安装方法;
综上所述,只要你有时间,有能力,就可以编个小插件,大型插件建议团队合作。而编写插件时,不要忘了保持自身良好的状态。
二、简略认识JAVA
JAVA,是一种可以撰写跨平台应用软件的面向对象的程序设计语言,以人认识世界的方式来设计编程的方式。
JAVA主要术语:
类:JAVA程序的基本组成成分,基于面向对象思想,一些具有相同特点的事物被抽象化成一个类;
对象(实例):从类中具体化(实例化)的具有该类特点的某一个事物;
句柄(引用,指针):你不能直接操作对象,因此你需要一个句柄来确定是哪个对象并操作。
构造器:一般需要调用构造器才能实例化出一个对象;
成员变量(属性):事物具有的特点被储存在属性里,可以被一个类所拥有,也可以被每一个单独对象所拥有;
函数(方法):你与事物之间的交互用方法来完成;
静态:属于类,也就是所有对象共同拥有的部分被称为静态成员。
非静态:属于每一个单独对象的部分被称为非静态成员(这个成员可能名称相同但内容不同)。
三、简略认识CraftBukkit插件成分
CB插件主要成分:
插件主类:一般与插件同名,作为插件的启动器,服务器启动时将首先执行插件主类里的方法,
所有插件功能最初都由此触发;
事件:游戏内数据的变化将引起事件,事件按其主要参与对象的主动和被动的行为特点分类;
监听器:按事件的类别分类,一个监听器可以监听一个或多个事件,通过事件的发生触发一些代码;
命令执行器:当玩家输入某一命令时(聊天时内容以“/”开头),由命令执行器执行该命令所触发的代码;
信息文件:plugin.yml,记录插件的主类位置,名称,以及版本等等,需要手动添加,缺少此文件插件将无法运行;
设置文件:CB为每个插件都配置了一个默认的设置文件(config.yml),你可以将插件的相关设定都放置在此文件中;
数据库:用来储存相关数据,虽然YAML文件同样能做到,但用数据库更安全更稳定(方便还真不敢说)。
四、为你的插件做个计划
你要做一个什么方面的插件;
你的插件能干什么;
你要如何使你的插件起作用;
你做这个插件后对服务器有什么好处;
如何能使你的插件达到小而精悍。
准备工作
一、了解IDE
这里的IDE指的是“Integrated Development Environment”,即“集成开发环境”。
本来,你想编写JAVA程序的话,只有用记事本,自己一个一个编,再用个命令提示符来执行相应命令,比如编译,打包等。
但如果你有了IDE,相当于给你配备了一个秘书,你不用考虑具体执行步骤,只要告诉秘书要做什么就行了。
举个栗子,如果你想重命名某一变量,如果没有IDE,你要一个一个查找并更改,但有了IDE,它会自动帮你找到所有指向同样地址的同名变量并重命名(重构)。
但如果只是想要学习JAVA语言的话最好脱离IDE,这样才能使你更有可能了解JAVA的本质。
二、下载&安装IDE
※ 说明:由于Netbeans官方提供中文版,而Eclipse不提供(有中文插件,但比Netbeans麻烦,因为Netbeans自带中文版)。
问题在编程过程中会不断出现,仅凭本帖是解决不了的,需要你自己去解决,而中文则有利于你理解并解决问题,
所以本系列只讲解如何用Netbeans制作CraftBukkit插件。
国外以Eclipse为主,如果你英语不成问题的话,推荐使用Eclipse,接轨国际。
下载Netbeans:
浏览 ,它会自动转换成你设置的所在地区的语言,然后按照图片点击下载:
或者WINDOWS平台中文版,你直接点击这个链接即可 点我下载 。
2.安装Netbeans(此安装教程适用于Windows系统):
3.设定你的项目储存位置:
首次使用会提醒你设置项目储存位置,推荐设定一个记得住的位置,
因为你可能需要查看源文件,不过忘记了也可以在选项里找到。
三、为制作插件做好铺垫
※ 注意:此部分路径及文件名必须使用中文!只有字符串“”内可用中文!(与文件编码有关)
新建一个项目:
给IDE添加Bukkit-API库:
首先下载 Bukkit API - 推荐版本 ;
打开Netbeans,并选择菜单栏中的“工具”;
点击“确定”完成添加。
给项目添加Bukkit-API库:
在IDE左上角“项目”中找到你刚才新建的项目
创建plugin.yml文件:
(若此处没发现该选项,点击“其他”,再选择“其他”类别即可找到)
之后在文件中输入
name: <插件名>
main: <包路径>.<主类>
version: <版本>
复制代码
注意空格
例如:
name: Essentials
main: com.earth2me.essentials.Essentials
version: 2.9.2
复制代码
四、注意事项:JAVA编程命名规则
※ 这个规则是为了增加JAVA编写出来的程序的兼容性与可读性,是一种惯例,不强制要求遵守。
包路径的命名规则:为保证不与其它程序或插件产生冲突,包名应该用你的域名或者邮箱倒过来作为包路径,应全部为小写(包路径对大小写不敏感)
例如:
com.github.<你的用户名>
或
com.gmail.<你的用户名>
后面的扩展路径则可以按用途命名
之后应以插件名结尾(因为你可能不只制作一个插件),
为了避免与服务端产生冲突,请不要使用以下路径:
- org.bukkit
- net.bukkit
- com.bukkit类名的命名规则:为增强可读性,应由无空格的多个单词连接而成,每个单词的首字母应大写(类名对大小写敏感)
例如:
NewClass
详细的命名规则可以到http://wenku.baidu.com/view/2e56f51a964bcf84b9d57b18.html中查看
第 贰 章:主 类
一、创建主类
主类,顾名思义,是你插件的核心类,该类在插件内首先被CB加载,然后由其中代码加载其它类。
这一节很简单,在你确定好插件的名字后,
在包的主要位置下新建一个类,重命名为“<你的插件名>”即可
(也可以用别的名字,为增强可读性,最好用插件名。IDE自动忽略后缀)。
你必须要做的是使这个类继承CB的JavaPlugin类,例如
Class <类名> extends JavaPlugin {
}
复制代码
若某一部分存在红色下划横线,表示无法识别该引用,点击该行最左侧的灯泡或者按Alt+回车完成导入(无法导入则说明不存在)。
二、加载与卸载
注:此处的卸载不同于卸载程序,只是在服务器中取消使用对应插件的功能。
JavaPlugin下有两个方法,在插件被加载和卸载时被调用,它们分别是:
onEnable() - 被加载时调用,onDisable() - 被卸载时调用;
它们看起来应该象这样:
public void onEnable(){
//代码
}
public void onDisable(){
//代码
}
复制代码
(IDE会提示你添加@Override,但可有可无)
三、用记录器输出文本
Logger即为记录器,相当于你服务端所使用的命令提示符窗口(实际上不是),
你使用它在控制台上输出消息,实用性比System.out.print()更好。
JavaPlugin下有一个getLogger()方法,用于获取该插件的记录器。
我认为你需要在你的插件被正常加载时显示对应消息,
所以你应该用它来显示一段文本,例如:
public void onEnable(){
getLogger().info("你的插件已被加载!");
}
public void onDisable(){
getLogger().info("你的插件已被卸载。");
}
复制代码
当你把以上三个步骤弄完后,你的主类看起来应该是这个样子:
package xxx.xxxxxxx.xxxxxx.xxxx;
import java.util.logging.Logger;
import org.bukkit.plugin.java.JavaPlugin;
public class <类名> extends JavaPlugin {
public void onEnable(){
getLogger().info("你的插件已被加载!");
}
public void onDisable(){
getLogger().info("你的插件已被卸载。");
}
}
复制代码
四、与Vault挂接
※ 无需权限、聊天、经济系统挂接的插件可以跳过此步骤
这个先搁置,等配置文件写完后再写这个
五、创建plugin.yml
在缺省包(包路径为空)下创建一个YAML文件,命名为plugin.yml。
以下内容必须含有,输入它们:
name: <你的插件名名>
main: <包路径>.<主类>
version: <插件版本号>
复制代码
例如:
name: MyPlugin
main: com.mydomain.myplugin.MyPlugin
version: 1.0
复制代码
由于包路径下主类的底层包名很可能为插件名,所以在main这一设置中见到插件名重复的情况很正常,这也可能是导致你出错的地方
详细设置见官方WIKI:http://wiki.bukkit.org/Plugin_YAML
第 叁 章:监听器
前言:
在1.1以前,监听器内的事件方法是以继承方式创建的,名称都是固定的(因为要覆盖),严格而繁琐;
1.1以后,CB作出较大改动,你仅需实现Listener接口,事件方法也变为依靠一个标记(EventHandler)来进行创建,自由且简便。
目前,你可以随意的创建一个监听器,方法也是任意的,只不过不要忘记标记“EventHandler”。
一、创建监听器
0.首先让我们来理解什么是监听器:
当一个玩家在游戏中做出各种行为时,你可能会需要对其控制,比如一名游客,你是不能让他去放置&破坏方块的。
这时你就需要用到监听器,对其进行判断,如果是游客就撤销该行为,如果不是则允许该行为。
1.新建一个类,名字任意(记住第壹章中只能使用英文的说明),但要求它实现“Listener”接口,它看起来应该象这样:
package xxx.xxxxxxx.xxxxxx.xxxx;
import org.bukkit.event.Listener;
public class MyListener implements Listener {
}
复制代码
2.创建一个方法,名字任意,变量为一个代表某一事件的类,我们以BlockBreakEvent事件为例,它看起来应该象这样:
public void aMethodName(BlockBreakEvent event) {
//代码
}
复制代码
3.添加EventHandler标记,你只要在方法上一行,输入“@EventHandler”即可,更改完后的方法代码应该象这样:
@EventHanlder
public void aMethodName(BlockBreakEvent event) {
//代码
}
复制代码
EventHandler 相关设置:
以优先级举例,把标记“@EventHandler”替换为如下内容:
@EventHandler(priority = EventPriority.LOW)
复制代码
另一项设置照葫芦画瓢即可,一起用则用逗号隔开。
事件方法的优先级将按如下顺序被调用
EventPriority.LOWEST
EventPriority.LOW
EventPriority.NORMAL
EventPriority.HIGH
EventPriority.HIGHEST
EventPriority.MONITOR
原理是,对于修改同一个数据,后被调用的方法 将会覆盖掉 先被调用的方法 所修改的数据,
所以,对于一个基础性的插件,比如仅仅阻止所有玩家 放置/破坏 方块的插件,对应事件方法应该采用最低优先级,
然后让其他功能性的插件来决定细节部分,比如让玩家可以 放置/破坏 草块和土块 的插件,只要将对应方法的优先级调高,判断是否为对应方块,再设置是否取消即可。
其实这两个插件可以整合为一个插件,但分开可以使事件间的组合更加自由,也使其它以你插件为基准的插件兼容性更好。
有一点需要注意,请不要使用Monitor优先级来修改结果,仅将这一优先级作为查看结果就好。
最后你的监听器看起来应该是这个样子
package xxx.xxxxxxx.xxxxxx.xxxx;
import org.bukkit.event.Listener;
public class MyListener implements Listener {
@EventHanlder
public void aMethodName(BlockBreakEvent event) {
//代码
}
}
复制代码
除了上面新建一个类作为事件监听器,你还可以在任何类中创建一个事件方法,只要记住2点:
(其实也就是把该类改造成一个监听器)
让该类实现 Listener 接口
给该事件方法添加 EventHandler 标记
二、注册监听器
你已经创建了一个监听器,然而现在它只能作为一个摆设而已,你需要在服务器中注册它来使它起作用,调用这个方法:
getServer().getPluginManager().registerEvents(Listener, Plugin);
复制代码
其中Listener处换为你实现该接口的类的对象(需要你自己去实例化),
Plugin则换成代表该插件的对象(在主类里的动态方法中用this关键字获得)。
之后你可以在任何地方来注册该监听器,只要你填入正确的对象(实际操作时是对象的引用)。
一般来说,是在插件加载时进行注册,下面是一个例子:
package xxx.xxxxxxx.xxxxxx.xxxx;
import java.util.logging.Logger;
import org.bukkit.plugin.java.JavaPlugin;
import xxx.xxxxx.xxxxx.xxxx.MyListener;
public class MyPlugin extends JavaPlugin {
public void onEnable(){
getServer().getPluginManager().registerEvents(new MyListener(), this);
getLogger().info("你的插件已被加载!");
}
public void onDisable(){
getLogger().info("你的插件已被卸载。");
}
}
复制代码
三、注销监听器
注销监听器有2种方式,一种是从单独事件中注销,另一种是从所有事件中注销。
无论是哪种方式,都可以指定某一监听器或插件来注销。
以BlockBreakEvent为例,单独事件注销方法如下:
BlockBreakEvent.getHandlerList().unregister(Listener);
BlockBreakEvent.getHandlerList().unregister(Plugin);
复制代码
从上到下分别是注销监听器中的该事件和插件中的该事件,
这样你就注销了对应对象中所有有关BlockBreakEvent的事件方法。
所有事件注销方法:
HandlerList.unregisterAll();
HandlerList.unregisterAll(Listener);
HandlerList.unregisterAll(Plugin);
复制代码
从上至下分别是注销所有事件,注销监听器中的所有事件,和注销插件中的所有事件。
这样你就把对应对象的所有事件全部注销了。
四、自制事件
自制事件很简单,你只需要记住以下2点即可。
1.在每个事件中都加入Handler相关内容;
在每个自制事件中都要加入1个属性、1个动态方法和1个静态方法:
private static final HandlerList handlers = new HandlerList();
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
复制代码
原因你可以在上一小节中找到。
我们假设这个事件是这样的:
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class CustomBlockEvent extends Event {
private static final HandlerList handlers = new HandlerList();
private Block block;
public CustomBlockEvent(Block block) {
this.block = block;
}
public String getBlock() {
return block;
}
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
}
复制代码
2.触发该事件的方法
首先你要实例化一个事件对象来确定它的属性的内容;
CustomBlockEvent event = new CustomBlockEvent(block);
复制代码
其中block代表某一方块的句柄。
之后触发该事件:
Bukkit.getServer().getPluginManager().callEvent(event);
复制代码
之后监听器该事件的监听器就会按优先级先后调用事件方法。
(Bukkit代表插件系统,可以获得对应服务器,这和你直接在插件中获得的服务器是相同的,性能差别也很小)
第 肆 章:命令执行器
前言:
1.命令通常与权限挂钩,权限将在后面章节讲,如果你想先了解,可以直接去浏览 第伍章:权限 (目前未完成)。
2.需要注意的是,命令除了建立一个命令执行器类,还要在plugin.yml中添加该命令,这样命令才能起作用,详情见该章。
一、onCommand() 方法简介
如你所知,前面讲的监听器只能在某一情况发生时才能被触发,而如果只通过一条命令(/xx xxx)来执行一系列代码,就要通过命令执行器。
命令执行器可以让玩家或控制台通过一个命令来执行一些动作,比如调整时间、天气等。
onCommand()方法必须总是返回一个波尔值(true or false),返回 true 不会有额外作用,
但如果在命令执行过程中返回 false 则会调用一个命令使用方法的说明(usage),说明在后面会提到。
所有的命令不仅需要在命令执行器中指定,还要添加到 plugin.yml 中,否则服务器将不会启用该命令。
(该方法的使用需要先实现 CommandExecutor接口,但插件主文件的接口即Plugin继承了该接口,所以可以直接使用,分离的执行器需要单独实现CommandExecutor接口)
它有4个局部变量,含义分别是:
CommandSender sender —— 命令发出者
Command cmd —— 所执行的命令
String label —— 所被使用的命令的其他形式,例如/j被用作/jump
String[] args —— 一个字符串数组,储存了命令的参数。例如/do a b,在方法中args[0]表示a,args[1]表示b
二、定义onCommand()方法
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args){
if(cmd.getName().equalsIgnoreCase("xxx")){ // 如果玩家输入 /xxx 则执行下面的代码
// 一些代码
// 如果命令成功执行则应该返回true,否则返回false
return true;
}
// 如果不是你所指的命令,需要返回false,如果它不能匹配任何一个命令,最终会提示“未知的命令”
return false;
}
复制代码
每当你进行命令编程时,总在方法结尾加上 return false,这是一个好的习惯。这样当命令错误时,会提示给命令发出者命令说明。
根据JAVA语法规则,当方法中返回一个值后,该方法将终止,所有之后的代码将不执行,此处需要注意。
此外,需要返回值的方法不能不返回一个值,这里IDE会帮助你检查返回逻辑问题。
.equalsIgnoreCase("xxx")的作用是忽略大小写,也就是当玩家输入/AbC与/aBc时会执行同一个命令
三、将命令添加到 plugin.yml
你需要将命令添加到 plugin.yml文件中来使命令起作用,你需要按下面的方式添加:
# 顶级键值,不缩进
commands:
# 命令的名字
basic:
# 命令描述,将会展示在/help中
description: This is a demo command.
# 命令使用方法,当命令被错误使用时将显示这个
usage: / [player]
# 权限,只对拥有该权限的人起作用
permission: .basic
# 不具有上面权限的玩家将被提示这条消息
permission-message: You don't have
复制代码
注意:
排版缩进法则:同一级的字符串前面需要有同样数量的空格,低级要比高级前面的空格多,相邻2级之间的空格数量一定,冒号后面不换行则要有一个空格。
此外,长空格将会引发错误,请使用普通空格。
四、创建安全的命令
有时候,需要考虑命令的安全性,为了使服务器不发生错误,对安全性的考虑是必要的。
大体上,需要注意以下几个方面:
发出者
作用对象
参数
举例说明,假定我们要创建一个"tpto"命令,该命令可以将发出者传送到被指定的玩家处
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if (cmd.getName().equalsIgnoreCase("tpto")) {
/* 显然,我们不能让控制台使用这个命令,因为控制台不是一个玩家,甚至连实体也算不上,无法传送。
* 但我们又无法通过权限来禁止控制台使用这个命令,因为控制台会忽视一切权限限制。
* 所以我们需要加入一个判断机制来确定发出者是玩家,然后才可以去传送他。
*/
if (sender instanceof Player) {
// 参数应该只有一个,也就是目标玩家,多了就没有意义了。
if (args.length != 1) {
sender.sendMessage("参数应该是单独的一个玩家名!");
} else {
Player player = (Player) sender;
// 下面这个方法可以获得玩家实例,如果玩家不在线则返回 null 。
Player target = Bukkit.getServer().getPlayer(args[0]);
/* 我们还应该检查目标玩家是否在线,如果不在线,当然是无法进行传送的,
* 而且还会抛出 NullPointerException 异常。
*/
if (target == null) {
sender.sendMessage("目标玩家不在线!");
} else {
player.teleport(target);
return true;
}
}
} else {
sender.sendMessage("控制台不能使用这个命令!");
}
}
return false;
}
复制代码
-
五、创建独立的命令执行器
这非常简单,你只需记住下面几点:
在主类下的 onEnable() 方法中添加一行注册方法 getCommand(String command).setExecutor(CommandExecutor commandexecutor);;
让新类实现 CommandExecutor 接口;
将onCommand() 方法移动到新类中;
下面的是例子:
假设插件主类类名是 MyPlugin ,命令执行器类名是 MyPluginCommandExecutor,命令名称是 xxx。
MyPlugin.java 中的方法:
@Override
public void onEnable() {
// ...
// 别忘了在 plugin.yml 添加这个命令,否则会抛出 NullPointerException 异常!
getCommand("xxx").setExecutor(new MyPluginCommandExecutor(this));
// ...
}
复制代码
MyPluginCommandExecutor.java :
public class MyPluginCommandExecutor implements CommandExecutor {
private MyPlugin plugin; // 用于调用主类中方法的句柄,不需要则可以去掉
public MyPluginCommandExecutor(MyPlugin plugin) {
this.plugin = plugin; // 给句柄添加引用
}
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
// 代码
}
}
复制代码
精品推荐
相关文章
更多+热门搜索
手游排行榜
- 最新排行
- 最热排行
- 评分最高
-
角色扮演 大小:164mb
-
其他游戏 大小:21.95MB
-
角色扮演 大小:273.37MB
-
角色扮演 大小:279.36MB
-
冒险解谜 大小:57.42MB
-
应用软件 大小:142.76 MB
-
飞行射击 大小:230MB
-
角色扮演 大小:305.2M
-
其他游戏 大小:3.81mb
-
其他游戏 大小:13.2MB