在制作CraftBukkit和Spigot插件时,类似于一些技巧或窍门的东西

Minecraft的服务器MOD CraftBukkit·Spigot的插件
由于是在1.7版本之前创建的,所以方法可能有点过时。
虽然有些不算技巧,也有很少的数量,但如果能在某种程度上有所帮助就不错了(:3_ヽ)_
如果有错误、更好的方法或是有不明白的地方,请在评论中或通过Twitter回复告诉我。

当按下Tab键时,可以更改所显示的列表的名称。

从第一个开始不像是小技。
Player#setPlayerListName(nameString)
可以用于区分团队或权限。
它也可以将名称更改为完全不同的字符串,但请注意字符数限制为16个字符。
如果超过17个字符,则会抛出异常。

※如果要添加颜色,颜色部分会使用到2个字母。
ChatColor.RED + “Name”
  ↓
“§cName”

颜色代码 格式化代码

ListNameChange.jpg

请在注册事件后最后调用它。

在其他插件可能会对块或物品进行更改时,在该插件处理完事件后,我希望执行我的插件处理,此类情况下。

只需将事件监听器注册的时机推迟PluginManager#registerEvents().

只是在设定的EventPriority中成为最后一个而已,所以并不是以EventPriority.NORMAL设置在EventPriority.MONITOR之后被调用。

有很多方法,但先只列出调度器的。
可能更可靠的是创建初始化命令,可以在任意时间执行。
BukkitScheduler#scheduleSyncDelayedTask(plugin,task,delay)。

Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, () -> {
    Bukkit.getServer().getPluginManager().registerEvents(plugin, listener);
}, 200);

第三个参数是Tick。

在输入命令时,使用Tab键可以实现自动补全。

这个也不是小技巧的感觉。
如果准备了/test hoge, /test piyo等命令,
在输入/test后按下Tab键,聊天框会显示hoge, piyo,第一个被选中并输入到输入框中,再次按下Tab键可以循环显示正在被选中的候选项,
输入/test h并按下Tab键,输入框会自动补全剩下的oge。

在实现了TabCompleter的类中,重写onTabComplete()方法以使用它。
由于JavaPlugin已经实现了该功能,所以可以直接在主类中编写。
如果要通过JavaPlugin#getCommand(commandString).setExecutor(commandExecutor)在命令的不同类中进行处理,则需要在实现了CommandExecutor的类中也实现TabCompleter。

我之前写的两个命令补全选项

public class Main extends JavaPlugin {
    @Override
    public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
        if (!command.getName().equalsIgnoreCase("test")) return super.onTabComplete(sender, command, alias, args);
        if (args.length == 1) {
            if (args[0].length() == 0) { // /testまで
                return Arrays.asList("hoge", "piyo");
            } else {
                //入力されている文字列と先頭一致
                if ("hoge".startsWith(args[0])) {
                    return Collections.singletonList("hoge");
                } else if ("piyo".startsWith(args[0])) {
                    return Collections.singletonList("piyo");
                }
            }
        }
        //JavaPlugin#onTabComplete()を呼び出す
        return super.onTabComplete(sender, command, alias, args);
    }
}

更新看板上的文字

看板非常有用。
可以显示玩家的登录信息,通过点击板子进行一些操作。
Sign(牌子)
SignChangeEvent(牌子改变事件)
尽管下面的示例使用了PlayerInteractEvent,但如果能够获取板子方块,我认为也可以直接从世界中指定坐标并获取。

@EventHandler
public void onSignChange(SignChangeEvent event) {
    String[] lines = event.getLines();//全行取得
    String line = event.getLine(0);//引数は[0-3]

    event.setLine(0, "0行目です");//行に文字列をセット

    //SignChangeEventではイベントに値をセットするのでupdate不要
}

@EventHandler //看板ブロックを右クリック
public void onSignClick(PlayerInteractEvent event) {
    if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return;
    Block clickedBlock = event.getClickedBlock();
    Material material = clickedBlock.getType();
    if (material == Material.SIGN_POST || material == Material.WALL_SIGN) {
        Sign sign = (Sign) clickedBlock.getState();

        String[] lines = sign.getLines();//全行取得
        String line = sign.getLine(0);//引数は[0-3]

        sign.setLine(0, "0行目です");//行に文字列をセット

        sign.update(); //Signを直接変更する場合はこれで更新完了
        //updateを忘れると反映されないので注意
    }
}

应用?

当玩家在使用滚轮操作时,可以检测到所选槽位(不知道具体叫什么名字)的选择变化,(也可通过数字键调用)。
从此事件中可以获取到变化前后的槽位编号,从而判断玩家是向上滚动还是向下滚动,可以用于上下选择项的变更等情况。

滚动检测不仅适用于标牌,也适用于其他场合,但它是应用于标牌更改的一种扩展,因此我在此附上相应的代码(:3_ヽ)_

当玩家将光标(位于屏幕中央的十字)对准标牌并滚动时,标牌上的文字会更改。
已经安置好的标牌中已经包含了字符串:
ChatColor.GREEN + “物品0”
“物品1”
“物品2”
“物品3”

private int currentLine = 0;

@EventHandler
public void onScrolling(PlayerItemHeldEvent event){
    //プレイヤーの向いている方向にあるブロックを取得
    Block block = event.getPlayer().getTargetBlock((Set<Material>) null, 5);
    Material material = block.getType();
    if (material == Material.SIGN_POST || material == Material.WALL_SIGN) {
        Sign sign = (Sign) block.getState();
        //変更後、変更前のスロット番号取得
        //手持ちスロットの番号は[0-8]
        int slotIndex = event.getNewSlot() - event.getPreviousSlot();
        if(slotIndex == -1 || slotIndex == 8){
            //up
            selectLine(sign, true);
        }else if(slotIndex == 1 || slotIndex == -8){
            //down
            selectLine(sign, false);
        }
    }
}

private void selectLine(Sign sign, boolean scrollUp) {
    if (scrollUp && currentLine == 0) {//0行目状態で上スクロール取消
        return;
    }
    if (!scrollUp && currentLine == 3) {//3行目状態で下スクロール取消
        return;
    }
    String line = sign.getLine(currentLine);
    line = line.substring(2);//先頭の色コード削除
    sign.setLine(currentLine, line);
    if (scrollUp) {
        currentLine--;
    } else {
        currentLine++;
    }
    line = sign.getLine(currentLine);
    line = ChatColor.GREEN + line;//先頭に色コード追加
    sign.setLine(currentLine, line);
    sign.update();
}
scrollSign.jpg

然后可以利用这个来创建各种功能。
比如,右击看板时,显示所选行上写的项目。

・简易定制物品

可以修改物品的名称或添加描述。
可以通过ItemStack#getItemMeta()方法获取到的ItemMeta来修改物品的名称等。

ItemStack itemStack = new ItemStack(Material.BREAD);
ItemMeta itemMeta = itemStack.getItemMeta();
//アイテム名をセット
itemMeta.setDisplayName("焼きたてのパン");
List<String> lore = Arrays.asList(ChatColor.RESET + "とても良い香りがする", ChatColor.RESET + "120円");
//説明文をセット
itemMeta.setLore(lore);
//ItemMetaをセットしないと反映されない。
itemStack.setItemMeta(itemMeta);
2015-12-03_23.32.48.png

创建清单

当需要创建额外的存储空间,如手提箱或背包时,
服务器~#createInventory()
Inventory inventory = Bukkit.getServer().createInventory(null, 9 * row, “背包”)
第二个参数一定是9的倍数。
该方法创建的InventoryType默认为CHEST。
要让玩家打开新创建的存储空间,需要将创建的Inventory作为参数传递给HumanEntity~#openInventory()。
请注意,一旦传递,它将立即打开。

createInventory.jpg

应用

在非存储空间以外尝试使用。
将更改了项目名称的项目放置,并通过单击该项目来触发某些操作的用户界面。
即使在新建的存储空间中也会调用InventoryClickEvent,因此可以通过在那里取消事件并判断所点击的项目来实现(需要处理存储空间整理MOD)。
如果InventoryClickEvent#getSlotType()为SlotType.OUTSIDE(灰显的部分),则可以移动到下一页等。
在事件被调用时,注意判断项目是光标捕捉状态还是在槽中的状态。
InventoryClickEvent#getCursor()
InventoryClickEvent#getCurrentItem()

(╹◡╹)

我在檢索以前的資料時,原本以為只有大概6個可用的,但出乎意料地變得很長。
希望有些會對我有所幫助。

bannerAds