在制作CraftBukkit和Spigot插件时,类似于一些技巧或窍门的东西
Minecraft的服务器MOD CraftBukkit·Spigot的插件
由于是在1.7版本之前创建的,所以方法可能有点过时。
虽然有些不算技巧,也有很少的数量,但如果能在某种程度上有所帮助就不错了(:3_ヽ)_
如果有错误、更好的方法或是有不明白的地方,请在评论中或通过Twitter回复告诉我。
当按下Tab键时,可以更改所显示的列表的名称。
从第一个开始不像是小技。
Player#setPlayerListName(nameString)
可以用于区分团队或权限。
它也可以将名称更改为完全不同的字符串,但请注意字符数限制为16个字符。
如果超过17个字符,则会抛出异常。
※如果要添加颜色,颜色部分会使用到2个字母。
ChatColor.RED + “Name”
↓
“§cName”
颜色代码 格式化代码

请在注册事件后最后调用它。
在其他插件可能会对块或物品进行更改时,在该插件处理完事件后,我希望执行我的插件处理,此类情况下。
只需将事件监听器注册的时机推迟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();
}

然后可以利用这个来创建各种功能。
比如,右击看板时,显示所选行上写的项目。
・简易定制物品
可以修改物品的名称或添加描述。
可以通过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);

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

应用
在非存储空间以外尝试使用。
将更改了项目名称的项目放置,并通过单击该项目来触发某些操作的用户界面。
即使在新建的存储空间中也会调用InventoryClickEvent,因此可以通过在那里取消事件并判断所点击的项目来实现(需要处理存储空间整理MOD)。
如果InventoryClickEvent#getSlotType()为SlotType.OUTSIDE(灰显的部分),则可以移动到下一页等。
在事件被调用时,注意判断项目是光标捕捉状态还是在槽中的状态。
InventoryClickEvent#getCursor()
InventoryClickEvent#getCurrentItem()
(╹◡╹)
我在檢索以前的資料時,原本以為只有大概6個可用的,但出乎意料地變得很長。
希望有些會對我有所幫助。