[精讚] [會員登入]
510

【PaperMC - API】如何發送指令到伺服器內

How to sending or executing commands to server

分享此文連結 //n.sfs.tw/15879

分享連結 【PaperMC - API】如何發送指令到伺服器內@小編過路君子
(文章歡迎轉載,務必尊重版權註明連結來源)
2022-06-25 03:41:34 最後編修
2022-06-25 01:43:31 By 過路君子
 

哈囉大家好,這裡是吃了幾個小時錯誤的小編過路君子

外加吃了至少幾十幾百次的錯誤,慢慢嘗試才終於成功讓伺服器執行指令並且沒有任何錯誤被拋出!

 

 

小編基本上找了十幾篇的文章、論壇,基本上使用的場景都是只有單個檔案的狀況下。

換句話說,如果今天我們的專案使用上了 package 並且是要從外部的 class 去呼叫的話,那些論壇上的方式基本上不可以直接照搬,原因下面會提到。

 

這邊小邊就放出兩篇論壇的討論文章,基本上小編是從這兩篇慢慢地推導出來如何正確地從外部 class 去讓我們的伺服器執行指令(暱稱隨意排列),有興趣的人可以前往參考。

  1. fabio030, harry0198, ysl3000, escad & anikalinn. (2020, February 10). Error: Asynchronous Command Dispatch! Spigot. https://www.spigotmc.org/threads/error-asynchronous-command-dispatch.417150/
  2. s3ns3iw00, 24763, norska, zodiak & Drkmaster83. (2017, December 13). Dispatch Command. Spigot. https://www.spigotmc.org/threads/dispatch-command.290137/

 

那廢話不多說,我們開始吧,照慣例先丟上目錄結構吧:

(所有圖片點擊都可以放大、變高清)

 

小編這邊特別解釋 Editor.java 和 RemoteConsole.java 這兩個檔案。

Edirot.java 為插件的進入點,也就是說,onEnable() 等等事件是註冊在這個檔案內;RemoteConsole.java 則是外部 class 會去呼叫 dispatchCommand() 這個函式。

這兩個檔案都位在 package editor.passing.jinzan 下。

 

接下來就是一堆程式碼了,小編也不廢話了。

Editor.java

package editor.passing.jinzan; 

import java.lang.Runnable;
import org.bukkit.event.Listener;
import org.bukkit.plugin.java.JavaPlugin;
import editor.passing.jinzan.RemoteConsole;


public class Editor extends JavaPlugin implements Listener
{
	@Override 
	public void onEnable() 
	{
		// 註冊事件觸發器
		this.getServer().getPluginManager().registerEvents(this, this);

		// 實體化我們的虛擬控制台
		// 一定要將 this 傳入,待會我們會用到
		// this 的變數型態有包含 Interface org.bukkit.plugin.Plugin
		RemoteConsole remoteConsole = new RemoteConsole(this);
	}
}

RemoteConsole.java

package editor.passing.jinzan;

import org.bukkit.Bukkit;
import java.lang.Runnable;
import editor.passing.jinzan.Editor;
import org.bukkit.scheduler.BukkitRunnable;


class RemoteConsole
{
	private Editor plugin;
	
	public RemoteConsole(Editor plugin)
	{
		// 初始化
		this.plugin = plugin;
	}

	public dispatchCommand(String command)
	{
		// 請求伺服器將「執行我們的指令」的請求放入隊列中
		new BukkitRunnable()
		{
			@Override
			public void run()
			{
				// 請求伺服器執行我們的指令
				Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), command);
			}
		}.runTask(this.plugin);
	}
}

Bukkit.getServer().dispatchCommand(@NotNull Plugin plugin) 必須放在 BukkitRunnable 內才不會報錯且正常執行,否則會看到以下的錯誤:

[02:05:08 FATAL]: Thread Thread-14 failed main thread check: command dispatch
java.lang.Throwable: null
    at org.spigotmc.AsyncCatcher.catchOp(AsyncCatcher.java:15) ~[paper-1.18.1.jar:git-Paper-187]
    at org.bukkit.craftbukkit.v1_18_R1.CraftServer.dispatchCommand(CraftServer.java:873) ~[paper-1.18.1.jar:git-Paper-187]
    at editor.passing.jinzan.RemoteConsole.<init>(RemoteConsole.java:37) ~[Paper_Plugin_7-1.5.9.jar:?]
    at editor.passing.jinzan.Editor$1.run(Editor.java:51) ~[Paper_Plugin_7-1.5.9.jar:?]
    at java.lang.Thread.run(Thread.java:833) ~[?:?]

 

剩下的事情就簡單了,只要呼叫 remoteConsole.dispatchCommand() 就可以直接執行我們的指令囉。

例如 remoteConsole.dispatchCommand("say hello")。

 

 

 

後記

這種寫法主要是要用於複合實做上使用,就是兩個不同的套件要協同執行的時候會用,因為對方套件內絕對不會有我們需要的 API,所以我們只好自己寫一個接口傳入對方的套件內,然後直接呼叫。

當然要直接暴力一點把整個 Editor 傳進對方的套件內也不是不可以啦,但是每次要呼叫指令就要玩一次 RemoteConsole.java,跟直接呼叫 remoteConsole.dispatchCommand() 在糾錯和除錯上級別差太多了。

END

你可能感興趣的文章

【Discord bot】(ERROR)await self.bot.wait_for() 大坑 今天真的是採到大坑,只找到解決方法,具體原因不明

【Minecraft】[CoreProtect|BungeeCord]如何重新命名世界或維度名稱 當只有一個伺服器的時候,問題往往處理起來非常簡單,但是一旦當伺服器成長至兩台以上,事情便開始有趣了起來

【自製-製作epub輔助工具】(Sigil) content產生器 能交給程式快速結束的地方就不要自己手動浪費時間了吧。

【Kali Linux】[history -c]如何清除歷史記錄 非bash環境會使history部分功能變的非法

【C++】一些好用的C++小功能 —— 貳 承襲上一篇的C++小功能,筆記下來以免自己以後忘記了。

【Wicket】[Header]如何讀取來自客戶端地檔頭和傳送自訂擋頭至客戶端 當需要設定檔頭或是讀取來自客戶端的檔頭時,這些程式碼就很好用

隨機好文

高捷少女:布拉格體驗㊦ 「各位想到盧卡站的乘客,請到我們左手邊排隊!」婕兒大聲地喊道。     「這孩子怎麼穿著地鐵站制服?童工嗎?」一位大嬸歪頭問道。

高捷少女:地下城的探險少女③ 過了十分鐘後,前方的天花板滴下一滴水珠,發出「噠」一聲響亮地落在石地上,讓大家嚇一跳。     「什麼嘛,只是水珠而已。」艾米撫著胸口噓了一聲。     忽然間,耐耐的臉色發白起來。「各位,你們看

高捷少女:地下城的探險少女(終)  小穹眨眨眼睛,然後說了出來。「其實,從剛剛開始,我就在想了……是在看過這本日記之後。」她拿出日記。「我想……我們尋找寶藏的想法,是不是真的正確的?」「怎麼說呢?」耐耐好奇地問。「這個埋藏寶藏的人,在

高捷少女:美麗島的守護者① 婕兒跟耐耐嚇得臉色發白。「耐耐,小穹有這方面的愛好喔?」婕兒小聲地說。耐耐默默的拿出筆記本,臉上浮現一層微笑:「這麼大的新聞,要趕快記下來!」

高捷少女:美麗島的守護者⑤  雖然暫時不用怕牠們了,可是一直躲在這裡終究不是辦法,小雅心想。她看看四周,這間更衣室沒有窗戶或後門,她不禁著急起來,不可能一直躲在這裡面,但從門出去只會被群貓圍攻而已。小雅低下頭苦思該怎麼辦,過了不