七空幻音LOGO

七空幻音

Bukkit插件开发--使用PlaceHolderAPI2020-04-11 12:50:49

我本在MCBBS编程开发区写了这个教程

但是MCBBS的插入代码功能出了很多问题

现在我在这里再写一遍吧


近期看到有一些MCBBS坛友在询问PlaceHolderAPI的使用方法

包括如何注册PAPI变量和使用PAPI变量
的确,网上的一些教程已经过时
现在我根据 https://github.com/PlaceholderAPI/PlaceholderAPI/wiki

也即PlaceHolderAPI官方文档写一篇教程


零:添加前置


先按这个网站的方法,把PAPI作为前置插件

https://github.com/PlaceholderAPI/PlaceholderAPI/wiki/Hook-into-PlaceholderAPI#adding-placeholders-to-placeholderapi

比如说Maven,那就在POM.xml里面加上

<repositories>
        <repository>
            <id>placeholderapi</id>
            <url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
        </repository>
    </repositories>
    <dependencies>
        <dependency>
         <groupId>me.clip</groupId>
          <artifactId>placeholderapi</artifactId>
          <version>{VERSION}</version>
         <scope>provided</scope>
        </dependency>
    </dependencies>

其中{version}替换成自己使用的版本(目前的最新版是2.10.5
如果不使用maven而是普通javaproject,你可以按照导入自己bukkit核心的方法导入

抑或是gradle,那就在gradle.build里面加上

repositories {
    maven {
        url = 'https://repo.extendedclip.com/content/repositories/placeholderapi/'
    }
}dependencies {
    compileOnly 'me.clip:placeholderapi:{VERSION}'}

如何添加dependency不再多做说明了
接下来就是在plugin.yml当中添加依赖
比如说

depend: [PlaceholderAPI]

此处中括号在YAML里面表示的是列表,你也可以

depend: [xxxxxx, PlaceholderAPI]

来为自己的插件添加多个依赖(扯远了)

如果你的插件必须有它作为前置就使用前者

如果是可有可无的就使用软依赖

注意Placeholder不是PlaceHolder,大小写区分开


一、插件内使用PAPI变量

先看原文:

To use placeholders from other plugins in our own plugin, we simply have to use the setPlaceholders method.

 public void onEnable() { 
     if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
         /*
          * We register the EventListeneres here, when PlaceholderAPI is installed.             
          * Since all events are in the main class (this class), we simply use "this"
          * 说的是在主类注册的事件监听,因此使用了this
          * 如何注册事件监听不做讲解
          */
         Bukkit.getPluginManager().registerEvents(this, this);
     } else {            
         /*
          * 如果没有找到papi这个插件就直接报错
          */
         throw new RuntimeException("Could not find PlaceholderAPI!! Plugin can not work without it!");
     }
}    
   
@EventHandler(priority = EventPriority.HIGHEST)    
public void onJoin(PlayerJoinEvent event) {        
    String joinText = "%player_name% &ajoined the server! He/she is rank &f%vault_rank%";        
    // We parse the placeholders using "setPlaceholders"
    // 使用setPlaceholders方法
    joinText = PlaceholderAPI.setPlaceholders(event.getPlayer(), joinText);
    event.setJoinMessage(withPlaceholdersSet);
}

接下来仔细研究一下这一段代码
说的是你已经有了一段字符串,并且其中已经有PlaceHolder
比如 “你好,我是%player_name%
那么此时就使用setPlaceholders方法,把%player_name%换成玩家的名字
至于哪一些placeholder能被替换就取决于服务器有没有安装对应的papi扩展
这里不一定非要传入Player对象,同样也可以使用OfflinePlayer对象


二、插件内注册PAPI变量

需要在插件中使用一个独立的类来注册papi变量
看原文的实例
这段实例注册的是%someplugin_placeholder1%%someplugin_placeholder2%

/**
 * This class will be registered through the register-method in the plugins
 * onEnable-method.
 */
public class SomeExpansion extends PlaceholderExpansion {

    private Test plugin;

    /**
     * Since we register the expansion inside our own plugin, we can simply use
     * this method here to get an instance of our plugin.
     *
     * @param plugin The instance of our plugin.
     */
    public SomeExpansion(Test plugin) {
        this.plugin = plugin;
    }

    /*
	 *上面是使用构造函数传入插件主类实例
         *主类实例的传入方法很多
	 *这里不多作讲解了
     */
    /**
     * Because this is an internal class, you must override this method to let
     * PlaceholderAPI know to not unregister your expansion class when
     * PlaceholderAPI is reloaded
     *
	 * 这里指是不是要让papi扩展持久化
	 * 不持久化则使用reload指令之后你的变量就没了
	 *
     * @return true to persist through reloads
     */
    @Override
    public boolean persist() {
        return true;
    }

    /**
     * Because this is a internal class, this check is not needed and we can
     * simply return {@code true}
     *
	 * 不用管这个,直接return true就可以了
	 *
     * @return Always true since it's an internal class.
     */
    @Override
    public boolean canRegister() {
        return true;
    }

    /**
     * The name of the person who created this expansion should go here.
     * <br>For convienience do we return the author from the plugin.yml
     *
	 * papi扩展的作者,这里使用的是插件的作者
	 *
     * @return The name of the author as a String.
     */
    @Override
    public String getAuthor() {
        return plugin.getDescription().getAuthors().toString();
    }

    /**
     * The placeholder identifier should go here.
     * <br>This is what tells PlaceholderAPI to call our onRequest method to
     * obtain a value if a placeholder starts with our identifier.
     * <br>This must be unique and can not contain % or _
     *
	 * 对于%someplugin_placeholder1%,这里需要返回someplugin
	 *
     * @return The identifier in {@code %<identifier>_<value>%} as String.
     */
    @Override
    public String getIdentifier() {
        return "someplugin";
    }

    /**
     * This is the version of the expansion.
     * <br>You don't have to use numbers, since it is set as a String.
     *
     * For convienience do we return the version from the plugin.yml
     *
	 * papi扩展的版本,和plugin.yml当中版本的版本号规范是一样的
	 * 这边方便一点使用插件作者
	 * 
     * @return The version as a String.
     */
    @Override
    public String getVersion() {
        return plugin.getDescription().getVersion();
    }

    /**
     * This is the method called when a placeholder with our identifier is found
     * and needs a value.
     * <br>We specify the value identifier in this method.
     * <br>Since version 2.9.1 can you use OfflinePlayers in your requests.
     *
	 * 真正实现papi变量返回值的地方
	 * 
     * @param player A {@link org.bukkit.Player Player}.
     * @param identifier A String containing the identifier/value.
     *
     * @return possibly-null String of the requested identifier.
     */
    @Override
    public String onPlaceholderRequest(Player player, String identifier) {
        
        if (player == null) {
            return "";
        }

        // %someplugin_placeholder1%
		// 如果是%someplugin_placeholder1%,这里需要检测placeholder1
        if (identifier.equals("placeholder1")) {
            return plugin.getConfig().getString("placeholder1", "value doesnt exist");
        }

        // %someplugin_placeholder2%
        if (identifier.equals("placeholder2")) {
            return plugin.getConfig().getString("placeholder2", "value doesnt exist");
        }

        // We return null if an invalid placeholder (f.e. %someplugin_placeholder3%) 
        // was provided
		// 错误的papi后缀,比如说someplugin_placeholder666,并没有被我们所定义
        return null;
    }
}


注:onRequest方法不一定使用Player对象作为参数,同样可以OfflinePlayer
然后还需要在主类onEnable方法注册

public void onEnable(){        
// Small check to make sure that PlaceholderAPI is installed
    if(Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null){  
        new SomeExpansion(this).register();
    }
}

使用register方法来注册papi变量


需要注意的是比如我写了两个变量

%mtxz_state% %mtxz_attainments%

第一个标示符返回mtxz

第二个标示符则是你自己的后缀判断,比如state

这里不要重复加上mtxz_的前缀

还有papi变量尽量使用xxxx_xxxx的形式,不要随意改动

三、单独的PAPI扩展
(没有继承JavaPlugin的类,只有papi变量这一个功能)
这种变量不需要一些你自己插件所记录的独有内容
而只是返回一些玩家统计数据或是进行一些计算什么的
此时你可以直接写一个和上文一样的注册的类继承PlaceholderExpansion

然后构建成一个jar
放进papi的文件夹,即服务端的/plugins/PlaceholderAPI/expansions

四、云扩展
腐竹直接在服务器使用/papi ecloud download指令来下载

请看这里https://github.com/PlaceholderAPI/PlaceholderAPI/wiki/Expansion-cloud

本质上和三是一样的

只不过不需要腐竹自己下载jar再扔进目录

输入指令之后papi会搞定一切

注意这种方法对于版本号等参数的要求很严格

如果你要写这种扩展请仔细阅读原文


最后还是给一下莫老群的群号

942025944

进群能变强
   



0条评论登录后可见

详细图片
载入中...