前往
大廳
主題

【Mineflayer】從零開始寫 Minecraft Bot-Ep.1 TypeScript 設定、第一支 Mineflayer 程式

酷可 | 2024-02-02 02:40:45 | 巴幣 0 | 人氣 290

上一次我們已經把寫程式的環境安裝好了,今天終於可以正式的來寫 Mineflayer 了,不過在正式開始之前,如果你是從 Ep.0 開始跟著我做的人,我們得先額外再多設置一些東西,讓我們的專案可以寫得更舒服。

TypeScript 設定

首先,我上次有提到,TS 的檔案沒有辦法直接執行,需要先經過編譯,變成 JS 檔之後,才能夠執行,除了我們需要執行兩次指令以外,加上每一個 TS 都會生成一個 JS 檔,萬一之後我們寫的檔案越來越多,一次生成的 JS 檔也會越來越多,因此,我們接下來要做兩件事情。

  • 只用一個指令執行 TS 檔:其實就是使用一條指令,讓我們在執行 JS 檔之前,先對 TS 檔進行編譯,如此一來,我們就不用在每次執行之前都還要編譯一次 TS 檔了。
  • 將生成的 JS 全部集中:修改 TS 的配置,讓生成的 JS 檔全部集中在一個資料夾裡面,如此一來,生成的 JS 檔就不會穿插在我們的 TS 檔裡面了。


我們先來完成第二點,集中 JS 檔的部分,如上圖先新增兩個資料夾,分別是 srcdist,src 是用來放我們 TS 檔的位置,dist 則是編譯後的 JS 檔的位置,這兩個名字只是一般寫程式的習慣而已,以後如果在其他地方看到 src 資料夾,裡面放的可能就會是該專案的原代碼。


接著打開 tsconfig.json 檔,利用 Ctrl + F 搜尋 rootDir,找到如上圖的設定,點擊該行後,按下 Ctrl + / 來將前面的 // 移除,或是手動刪除也可以,// 是註解的意思,不會讓後面的東西被電腦讀取到,就是寫給人看的備註,這在 JS 或 TS 當中也是一樣,詳細之後在談。

總之移除註解之後,將後方的 "./" 修改成 "./src",rootDir 是根目錄的意思,在這裡就是代表我們用來寫 TS 檔案的主要資料夾,而後方的值就是資料夾的路徑,原本的 ./ 是代表當前資料夾的意思,是一個相對位置,而 ./src 就是代表當前資料夾底下的 src 資料夾,也就是我們剛剛建立的 src 資料夾。


另外再搜尋 outDir,以同樣的方式,將後方的值改成 "./dist",outDir 是指輸出目錄,就是代表編譯後的 JS 檔要放置的位置,後面值的原理就跟剛剛的 rootDir 一樣,是一個資料夾路徑。


最後再搜尋 strict,將後方的 true 改成 false,這是指 TS 會不會非常嚴格的檢查我們寫的語法有沒有問題,建議把它關掉,不然之後可能會寫得很痛苦。


都設置完成以後,就將 app.ts 拖曳到 src 裡面,以後 app.ts 就是我們 TS 專案的進入點,不會再去改變它了,而上次生成的 app.js 可以先刪除,讓我們來測試一次剛剛設定的東西有沒有成功。

打開你的終端機,還記得嗎?按下 Ctrl + `,再次輸入 tsc 來編譯我們的 TS 檔,編譯完成後,應該就會看到 JS 檔被生成在 dist 資料夾裡面了,是不是變得比較整齊了一些呢?

其實 dist 資料夾可以不用預先建立,只要在 tsconfig.json 中設定 outDir,當我們使用 tsc 編譯 TS 檔的時候,它就會自動幫我們建立 dist 資料夾並將 JS 檔放在裡面,不過為了教學方便理解,我還是事先建立好。


接下來我們就要回去處理第一點,只用一個指令執行 TS 檔,讓我們打開 package.json 檔,找到其中有個叫做 scripts 的設定,我們要來新增兩個腳本,在 test 的尾巴後面按下 Enter 換行,如上圖新增一個名為 build 的腳本,並且在值的欄位寫上 tsc,也就是我們編譯 TS 檔的指令,記得要用 "" 包起來,後面的值也是一樣。

完成後再新增一行,名稱為 start,值的部分寫上 npm run build && node ./dist/app.js,它的用途就是先執行一次剛剛的 build,也就是編譯 TS 檔,然後再執行 node 去執行編譯後的 JS 檔。

如此一來,當我們在終端機輸入 npm start 時,系統就會自動編譯 TS 並執行 JS 檔,讓我們來試試看。


怎麼樣,是不是方便多了呢?在這裡可能有些人會注意到,明明都是 npm 執行某個腳本,為什麼執行 build 前面要加上 run,執行 start 時卻不用,因為 start 是 npm 預設的腳本名稱,當我們執行 npm start 時,系統會預設我們是要執行 npm run start,讓我們可以省略 run 參數,而 build 是我們自訂的腳本名稱,所以需要加上 run 來告訴 npm 我們是要執行它。

VS Code 套件安裝


最後,讓我們點擊左邊功能欄的第五個頁面 Extensions(擴充),我們可以在這裡安裝一些擴充功能,來輔助我們撰寫程式,我用 VS Code 寫程式的經驗其實也不久,對套件其實也不太熟悉,總之你可以在上方的欄位搜尋 Prettier 找到如上圖的第三個「Prettier - Code formatter」,或是輸入 TypeScript 找到一些跟 TS 有關的套件,如「JavaScript and TypeScript Nightly」,簡單的說這些套件的功能主要都是幫我們格式化我們的程式碼,讓它看起來比較整齊一點,並將程式碼的各個部分用不同的顏色標示清楚,方便我們閱讀,還有可以自動幫我們 import 一些東西,這個實際上寫的時候就知道了。

其他還有像是 ESLint、IntelliCode 等,例如 IntelliCode 是一個 AI 輔助套件,甚至也有讓 VS Code 變成繁體中文的語言套件「Chinese (Traditional) Language Pack for Visual Studio Code」,有需要的可以自己去搜尋看看有沒有你需要的套件可以安裝,如果不想要搞得太複雜,就像我一樣裝上圖中的那些就好了。

第一支 Mineflayer 程式

要開始寫一個新的程式,或使用新的函示庫以前,第一件事情就是到官網上去看看範例,因此讓我們回到 Mineflayer 的官方 GitHub 上面去看看。


我們可以在介紹頁面找到如上圖的範例程式,什麼都不用說,直接點擊右上角的複製按鈕,貼到我們的 app.ts 裡面去看看。


如果你在這個時候使用 npm start,執行的話,沒有意外應該會出錯,並在最後出現一條訊息,主要有兩個原因,讓我來解釋一下。

  • 第一點是上面那些看起來很複雜的各種錯誤,這個部分不是程式有錯,單純是因為沒有一個世界可以讓 Bot 加入而已,所以你只要 打開你的 Minecraft進入單人遊戲,使用 ESC在區網上公開,並將 連接埠號碼 設定成 25565(這是 Bot 連線時預設使用的),提供一個可以讓 Bot 加入的世界就可以了。
  • 第二點是因為該 Bot 使用的帳號是 Microsoft 帳號,也就是微軟帳號,它提示了「First time signing in. Please authenticate now:」,意思是因為是第一次登入,所以需要進行驗證,而下一行提供了驗證網址以及驗證碼,如果你在之後遇到了這個問題,只要點擊網址,並登入你的 Microsoft 帳號就好了,當然要記得是 Bot 使用的帳號。

如果你只是想要在單人測試看看 Bot 的效果,那麼可以考慮把範例中 'microsoft' 的部分改成 'offline',也就是離線狀態,這樣 Bot 就不會進行帳號驗證、登入,可以直接加入你的世界,當然這樣也就沒辦法加入多人伺服器。

至此,我們得先了解一件事情,我們本系列的目標是寫一個可以應用於 廢土伺服器 的 Minecraft Bot,也就是說要加入多人伺服器,而要加入多人伺服器就得要有帳號,並非是我們隨便寫一個程式就可以讓 Bot 加入到伺服器中,除非伺服器沒有開啟正版驗證,也就是說伺服器中的每一個 Bot 都代表著一個 MC 帳號,如果你自己只有一個 MC 帳號,但想要多一個 Bot 來幫你做事的話,那麼首先你應該做的事情是再去買一個 MC 帳號,並且讓你的 Bot 使用這個新帳號來進行登入,或是讓 Bot 直接使用你的帳號登入也可以,但這樣你就看不到 Bot 在遊戲內的身影了。

我們接下來的教學都是以有兩隻帳號為前提去進行的,一隻帳號作為 Bot 使用,而主要帳號在遊戲中向 Bot 下達指令,當然就算只有一隻帳號,還是可以在單人進行練習,只是環境不一樣,可能會導致我們的程式碼在某些細節處理上也不太一樣。


接下來讓我一一的解釋範例中的程式都在做什麼,首先如上圖,除了中文註解以外,我稍微改掉了第一行的程式,這是我們在寫 TS 的習慣,比起原本 JS 的 require(),在 TS 中我們一般會使用 import ... from 來引用其他檔案、函示庫,但用途不變,目的都是為了將 mineflayer 這個函示庫裡面的功能,被儲存在一個 叫做 mineflayer 的變數之中,看起來似乎有點饒舌,之後就會懂了。

接著範例中使用了 mineflayer 裡面的 createBot 功能來創造一個 Bot,並且我們可以賦予一些參數:

  • host:伺服器位址,localhost 代表的是你自己電腦的位址,因此我們在單人伺服器公開至區網時,Bot 才有辦法連線到我們的單人世界,之後我們要連線到廢土伺服器的時候,這裡就是要改成廢土伺服器的 IP 位址「mcfallout.net」。
  • username:這裡得根據 auth 的設定來判斷,如果 auth 是設定成 microsoft,那麼這個欄位代表的就是 microsoft 帳號的信箱,否則若是 mojang、offline 的話,這裡代表的就是 Bot 的玩家 ID。
  • auth:身分驗證的方式,由於 MC 最早就是由 Mojang 產生的,只是後來被微軟給收購了,因此有兩種登入方式,當然自從微軟強制要求早期的 Mojang 帳號轉移成微軟帳號,到現在也停止了對 Mojang 帳號轉移的支援,因此現在能夠進入多人伺服器的驗證方法應該也只剩下 microsoft 了,mojang 就跟 offline 應該是一樣的效果。
  • port:伺服器連接埠,預設為 25565,這主要應該是用在單人世界,或是一些私人伺服器使用的,多人伺服器一般不太會需要設定連接埠。
  • version:Bot 的版本,有設定的話,Bot 會使用該版本的遊戲進入伺服器,否則會自動根據伺服器版本而定,在某些時候還滿有用的。
  • password:Bot 帳號的密碼,記得如果你在寫一些開源專案,或是打算把寫完的程式發給別人使用時,千萬不要把自己的密碼寫在這裡,除非你想把你的 MC 帳號送給別人ˊˇˋ

以上只是範例程式中提到的,實際上還有其他東西可以設定,但我們暫時不深入那麼多,總之利用 mineflayer.createBot() 產生出來的 Bot,我們要將它儲存在一個叫做 bot 的變數裡面,這樣我們之後才可以針對這個 Bot 做一些事情。


接下來如上圖,bot 就是我們剛剛定義的變數,也就是代表我們的機器人,而 on 是為了讓 Bot 接收一些事件,至於是什麼事件呢?是一個叫做 chat 的事件,簡單的說,當有玩家在遊戲中的聊天欄上面發送訊息,Bot 就會接收到,而且會有兩個參數:

  • username:發送訊息的玩家 ID。
  • message:發送的訊息內容。

if 是如果的意思,用來讓我們在程式中進行一些判斷,如圖中判斷的是「發送訊息的玩家 ID,等於 Bot 自己的 ID」,也就是說話的對象是 Bot 自己,那麼就會執行後方的 return。

至於為什麼要這樣檢查呢?先讓我們看看下一行,同樣是 bot 開頭,代表 Bot 又要做什麼事情了,後面接上 chat 就可以讓 Bot 在遊戲中發送訊息,就跟我們按 T 發送訊息一樣,後面 () 內的,就是訊息的內容,不過這裡是一個變數。

回到那個 if,為什麼要檢查說話的人是不是 Bot 自己呢?因為 Bot 連自己發送的訊息都會接收到,發現了嗎?我總結下這一段程式的功能:

  1. 讓 Bot 接收一個 chat 事件,也就是有人在遊戲聊天欄發送訊息的事件,該事件會包含 username(發送對象 ID)、message(訊息內容)兩個參數,並執行接下來的工作。
  2. 檢查發送對象 ID 是不是跟 Bot 自己的 ID 一樣,如果是的話就 return(結束工作),不然就繼續往下執行。
  3. 讓 Bot 說出剛剛接收到的 message(訊息內容)。

如果少了第 2 點,會發生什麼事情呢?

玩家說話→Bot 接收到→Bot 說出重複內容→Bot 接收到→Bot 說出重複內容→Bot 接收到......

這樣 Bot 就會永無止盡的重複發送一樣的訊息,到時候你的電腦就會卡住,然後大爆炸,世界就毀滅了,好啦沒這麼誇張,總之第 2 點的檢查,就是為了避免這種事情的發生。


接下來是同樣的原理,讓 Bot 接收某個事件,只是這次接收了兩種事件,分別是 kicked、error,前者是當 Bot 被伺服器踢出時會接收到,而後者是當 Bot 出現錯誤時會接收到,在這裡 Bot 接收到這兩個事件的時候,都會做同一件事情——console.log。

還記得嗎?我們在上一篇有提到這條程式的功能,是在下方的終端機輸出訊息,這兩個事件在發生時,都會傳出其原因,而直接在後面塞入這段程式,就是直接讓原因被輸出到終端機上面的簡寫,因此當 Bot 被踢出或出錯時,就會在終端機顯示原因。

到此為止,針對範例的講解就已經結束了,你可以嘗試開啟你的 MC 進入單人世界,並將遊戲使用連接埠 25565 公開至區網,把 Bot 登入設定裡的 auth 刪掉或改成 offline,並在終端機輸入 npm start 來執行這段程式,這樣你就可以看到 Bot 加入到你的單人世界了。


結語

今天首先針對了在 VS Code 中,撰寫 TypeScript 的部分進行了一些設定,讓我們在檔案的管理、操作上會比較方便,並且簡單介紹了 Mineflayer 官方範例的程式碼內容。

到目前為止都是以讓沒接觸過程式設計的人也能大概看懂的出發點來介紹的,所以針對很多部分進行了不少補充,但老實說我也不清楚沒寫過程式的人能不能真的看懂,再加上這樣的話文章可能會變得過於冗長,因此我可能會考慮把關於 TS 基礎語法的部分獨立出來,讓這裡能夠更專注於 Mineflayer 本身的使用上,

另外由於巴哈的文章編輯並沒有支援展示程式碼,只能用表格模擬,而這個教學肯定會有不少程式碼的展示,所以我也考慮是否要將文章改到 iT邦上面,只是我覺得對於 Minecraft 以及廢土伺服器這個主題,巴哈可能更適合,而且 iT邦的文章不能置中,圖片會超醜,或是程式碼在文章內可能會用圖片展示,而實際程式碼的部分我就放到 GitHub 上面,這樣你們才有地方可以複製。(但老實說我寫程式到現在還沒認真用過 GitHub)

創作回應

Enkidu
有問題想問大佬 可以幫我看一下私訊嗎
2024-03-23 07:13:04

更多創作