2016年8月13日 星期六

如何製作Spigot Plugin 第二章 第一個插件(三)

如何製作Spigot Plugin 第第一個插件()

往後的內容錯綜複雜,需要各種方法相互連結,後面的內容會越來越多,如果有沒介紹到的方法請告知,小弟可以在其他篇章內再做講解。

接下來的內容我們要介紹一下指令,問題是遊戲中要是指令太過於繁雜是非常不好的,尤其是指令使用名稱重複會出現許多問題,所以我們會教導各位圖形化介面,基本上有使用過箱子指令後都會覺得簡單又方便,並且讓玩家更能充分的掌握自己所能做的事,而不是呆呆的望著指令說明而不知所措,我們的架構很簡單就是利用箱子介面來完成簡單的傳送方法。



決定好箱子的內容我們就可以將我們的構想進行數位化,並且在遊戲中呈現出來,基本上是建立9格的箱子(0~8),並且在第一格(第一格為0)與第三格放入道具當作按鍵,道具上指示傳送位置。
Inventory
作出箱子可以使用[Bukkit.createInventory(箱子主人, 箱子格數(9的倍數最大54), 箱子的名稱)]來進行製作,不過箱子可不是指有儲存箱的介面,我們在製作時也可以設定箱子類型(InventoryType)
類型
說明
ANVIL
鐵砧介面。
BEACON
烽火台介面。
BREWING
釀造台介面。
CHEST
箱子介面。
CRAFTING
手工藝介面。
CREATIVE
創造模式的道具取得介面。
DISPENSER
發射器介面。
DROPPER
投擲器介面。
ENCHANTING
附魔台介面。
ENDER_CHEST
安德箱子介面。
FURNACE
熔爐介面。
HOPPER
漏斗介面。
MERCHANT
村民交易介面。
PLAYER
玩家的庫存介面。
WORKBENCH
工作台介面。
ItemStack
建立一個道具資料,在未放入箱子或人物庫存內都只是一筆資料,剛開始就需要指定道具類型(Material),由於道具類型破百個我們就不一一介紹了,直接建立起來的道具還可以利用參數來改變,例如羊毛的顏色等,參數的使用方法是[new ItemStack(道具類型, 道具數量, 參數(short)],建立起來的道具都是原始型態。
ItemMeta
原始的道具我們要先取出Meta而[ItemMeta]只是取出了基本層次,如書本,旗幟等,有更多近接的Meta可以進階段去修改,不過我們的按鈕只需要基本的顯示就可以了,我們先確認Meta可以為我們做哪些基本設置。
[setDisplayName(道具名稱)]在這裡我們可以修改道具預設的名稱。
[setLore(說明內容(List))]每個道具最好做簡單的敘述與簡介。
[addEnchant(附魔, 等級, 布林)]附魔可以增加道具的屬性,主要是附加在武器、工具、以及盔甲類。
[addItemFlags(ItemFlag)]系統本身還是會針對特殊的道具做說明標籤,使用這個方法可以隱藏這些系統標籤。



建立指令Class,由於我們不需要其他參數因此參數為0,而指令也只能由玩家開啟所以用[if]加以過濾以上兩種設定,避免由無法打開箱子的對象執行指令造成錯誤,接著我們使用[openInventory(Inventory)]讓執行的玩家開啟箱子介面。



如果空叫出一個箱子介面是不夠的,玩家們可能會在箱子內放置自己的物品,或者把已經準備好的「按鈕」帶走,當然最重要的是讓玩家觸發按下按鈕時所做的動作。

setCancelled(true)
取消點擊後的各種結果都會無效,不過當只限制部分區域時,游標上的道具還是可以放入限制區的空白格子,這部分需要做特殊處理,當然我們是做按鈕界面,限制全部的區域就不需要煩惱這部分。
InventoryAction
在這裡可以取得打開箱子後的部分動作,雖然我們已經截斷玩家所有的動作,但是後續的架構不允許點擊到介面外,加上沒點到按鈕也要加以排除。
動作
說明
CLONE_STACK
將點擊的最大數量道具移到游標上。
COLLECT_TO_CURSOR
道具可堆疊的最大數量移到游標上。
DROP_ALL_CURSOR
丟棄游標上所有道具。
DROP_ALL_SLOT
丟棄點擊位置內所有道具。
DROP_ONE_CURSOR
從光標丟棄一個道具。
DROP_ONE_SLOT
從點擊的位置上丟棄一個道具。
HOTBAR_MOVE_
AND_READD
將點擊的到具移到快捷欄,
並且將道具添加到玩家庫存。
HOTBAR_SWAP
點擊的道具和快捷欄進行交換。
MOVE_TO_OTHE_
INVENTORY
如果對向庫存有空間移動道具道該位置。
NOTHING
什麼都不會發生的點擊。
PICKUP_ALL
點擊位置內所有道具被移動到游標上。
PICKUP_HALF
點擊位置內一半道具被移動到游標上。
PICKUP_ONE
點擊位置內一個道具被移動到游標上。
PICKUP_SOME
點擊位置內一些道具被移動到游標上。
PLACE_ALL
游標上所有道具被移動到點擊的位置內。
PLACE_ONE
從游標中移動一個道具到點擊的位置內。
PLACE_SOME
游標上一些道具被移動到點擊的位置內。
SWAP_WITH_
CURSOR
游標上的道具與點擊的道具交換。
UNKNOWN
無法識別的點擊類型。
getSlot()
用這個方法可以在箱子、玩家庫存、快捷欄中取得位置(0~53,問題是打開介面也同時開啟這三個部分,所以我們採用[if]來限制區域,免得點到玩家庫存或快捷欄也能處發,如果取得的位置是[null] 會導致系統錯誤,在這之前要先排除玩家點擊在介面以外的地方,而點擊的位置就以道具代表按鈕引導玩家點擊。
teleport(Location)
玩家是[Entity]的一種,我們可以用這個方法瞬間移動實體到我們設定的位置上。
getSpawnLocation()
[World]中取得唯一的重生點位置,傳送玩家需要一個明確的位置,
getBedSpawnLocation()
[Player]中取得玩家放置床的位子,當然要睡過才能取得位置。



不用說我們還是要在Main Class內進行指令註冊,並加上啟動指令的代碼or名稱。



記得在插件資訊裡面加入指令訊息,不然是無法使用的,內容我們可以用[/help sp]查詢到,也方便讓使用的人了解指令訊息與操作。




在遊戲內執行指令,打開我們的箱子傳送介面,並點擊想傳送的位置進行傳送。由於傳送地點是以實質的[Location],所以當您傳送到世界的重生點時經常會埋進土裡,最好自行重新設定自己的世界重生點,床位的話比較簡單就在面對床的左下角,高度與擺放的位置相同。

2016年7月21日 星期四

如何製作Spigot Plugin 第二章 第一個插件(二)

如何製作Spigot Plugin 第第一個插件()

只在控制台上顯示文字是不是不過癮,我們可以更進一步讓玩家感受到,讓玩家登入遊戲時看到我們想表達的訊息。



在這裡我們採用事件(Event)來做觸發點,[PlayerJoinEvent]是一個經常使用到的事件,每個玩家進入遊戲一定會觸發的事件,而我們所做的是歡迎詞跟一些資訊的顯示,[Player]即是代表觸發該事件的玩家,我們可以從API中的方法取得各式各樣的玩家資訊。

服務器版本[Bukkit]內含有大量靜態(Static)的方法,未來我們經常會用到,其中[getBukkitVersion()]可以取的Bukkit的版本,而[getVersion()]則是取得Spigot的建構版本。
服務器玩家人數:基本上人數在登入服務器頁面就可以得知,不過也有部分服務器會隱藏該項訊息,我們採用的方法一樣也是[現有玩家人數/最大玩家數],最大玩家數是服務器的設定值,我們可以由[getMaxPlayers()]來取得,而現有玩家就是Online Players所已取得方式就是[getOnlinePlayers().size()]
玩家IP:既然是玩家IP自然我們要從[Player]內著手,在這裡我們利用[getAddress().getHostName()]取得玩家IP,當然我們也可以順手取得Port再加以完整的顯示。
Ping:在這裡我們無法從API中查獲,所以我們需要打開前下載的Spigot文件夾[Spigot-Server],當然您也可以用反編譯取得這就是NMS(net.minecraft.server)NMS是不穩定的除了版本號變更會需要再寫一次以支援新版外,有可能這個方法在新版就無法使用,所以開發插件我們會盡量避免NMS上的使用。在這裡我們轉型為[CraftPlayer]再由[getHandle().ping]取得該玩家的Ping值。
§?:在[String]內你看到我放入不少「§」符號,遊戲內文字也是有顏色,我們可以採用內建顏色對我們的文字上色,色碼表上對照所需的顏色,我們也可以運用[ChatColor]來作著色,這種方法可以明確的在編碼內告知著色內容問題是文字轉換還是會轉成符號,這樣在比較時很容易發生錯誤。



我們還需要為自己的事件進行註冊,讓服務器執行我們的製作辛()血,記得修改一下前面教學的內容創造自己的風格。




最後觀賞一下自己的作品,感受一下完成之後的喜悅~

2016年7月17日 星期日

如何製作Spigot Plugin 第二章 第一個插件(一)

如何製作Spigot Plugin 第第一個插件()

基本上我們的開發教學主要以最新版的Spigot為主,開發工具就不需要再多做教學必竟這不是重點,少說廢話我們直奔主題。



~上面的寫法不是必要的,不過使用得當可以在服務器中凸顯效果,不過有開過服務器的都知道服務器記錄檔是不會顯示顏色,只有在開啟的文字模式當下才有作用,如果覺得麻煩可以跳過這一部分。



接下來我們先建立所謂的Main Class,這部分跟獨立運作的Main Class有些不同,首先繼承[JavaPlugin.Class] 也就是Spigot的接口(可以想像這是個溝通的橋梁),開啟SpigotAPI檢查一下JavaPlugin內容,這裡我們需要重新定義方法來完成這個插件獨立的效果。

onLoad():當Spigot讀取資料時才會執行,可是這個方法不太常用到,必竟未完成讀取的資料呈現著不穩定的狀態,比如在尚未完成地圖載入時執行方塊的安置,這部分便會產生錯誤。
onEnable():在這裡啟動插件內所有需要運轉的內容是最好的,此時所有的插件、服務器地圖、資料也載入完畢,不過出現錯誤時插件會直接關閉,雖然不會關閉服務器,但是編輯的內容盡量以簡單為主,也有與其他插件衝突部分不過大多不是在這(大多數是指令名稱相同造成衝突)
onDisable():插件運用中可能會有需要儲存的部分,所以當服務器準備關閉時你會在這時後加入存檔的功能,不過在這裡不包含服務器過載、運算無線循環造成的死當。



雖然我們已經有Spigot接口並且執行一些程式碼,但是還需要有入場卷,這部分就像插件的身分證一樣。

name:插件名稱,有預設的設定檔會在同名的資料夾內。
mainMain Class的位置。
version:版本號,每次有變動最好加1號,這樣可以知道到底修改幾次。
description:簡單的敘述插件作用。




編譯後欣賞一下自己的作品,上面的圖有截斷過所以建議您立刻動手創出第一個插件吧!

2016年7月13日 星期三

Spigot 核心下載教學

Spigot 核心下載教學

有關於BUKKIT版權問題已經一陣子,大多數Bukkit 插件都已經轉成Spigot插件,其實Bukkit依然在開發而不是結束,Spigot其實是Bukkit其中的一個開發版本,當然版權問題依然是存在的所以我們不要自行發佈已經解碼的核心避免觸法,當然我在這提供的是怎樣下載也不會提供核心所以大家可以放心的看下去。



首先的第一步驟是下載GIT(git-scm.com),就算你看不懂英文麻煩點擊[Downloads for windows]基本上安裝也只要一直點擊[next]GIT是一個強大的專案助手想必您應該有修改後想反悔時去發現您已經無法回復當時的紀錄了,而GIT就是用來紀錄專案中各種變化建立變化節點,你隨時可以叫回任意節點,未來我們建立插件專案也會用到。



接下來第二步驟是下載BuildTools(www.spigotmc.org),目前這個解碼程式也是不斷更新,所以下載最新的版本就行了,不過在這我們是無法直接執行此檔來解開我們需要的核心檔,該檔案必須要在GIT環境下執行。



第三步驟,建立GIT環境,您一定會想安裝之後不是已經建立好了嗎?當然不是,每個GIT環境都是獨立的,我們先建立好資料夾接下來將下載的BuildTools.jar放進去,在程式集裡可以找到GIT GUI點擊執行,點擊連結文字[Create New Repository]選擇剛建立的資料夾開啟GIT專案介面,這個動作便完成將資料夾建立起GIT環境。



最後的步驟我們開啟文字模式,點擊[Git Bash]打開像是舊系統MS-DOS,好吧!有一部分的人可能只認識視窗介面不過這不是問題,我們只需要複製與貼上也可以輕鬆執行指令,不過在這裡記得打開網路,因為整個過程需要連線下載等,現在執行[java -jar BuildTools.jar]。




當整個程序跑出完成時間後你可以在資料夾發現核心craftbukkit以及spigot都出現在資料夾內,還包括NMSAPI也在裡面供我們查詢。

2016年3月11日 星期五

傳送與傳送騎士與他所騎的馬

傳送與傳送騎士與他所騎的馬

The Horse Go Home


基本上傳送指令是很方便的功能,當你在收刮戰利品,走廢墟走到頭很暈,挖礦挖滿身的鑽石最安全的方法就是傳送回家,問題是你騎著你的愛馬時,你可找不到優質的停車場讓你的愛馬不走失,尤其是屁孩當道的遊戲世界。


特色


就是可以騎馬傳送。

指令


/thgh:傳送到擺床的位置或是世界的重生點。

影片

作影片的時候是使用home當指令,怕衝突畢竟這種名稱滿街都是

下載


Thgh 0.1 只要有馬都可使用,連1.9也可以。


有人要我就發出來了

開源節流


@Overridepublic boolean onCommand(CommandSender commandSender,
                         org.bukkit.command.Command commandString s,
                         String[] strings) {
    // 遊戲中的玩家才能使用

    if (commandSender instanceof Player) {
        // 取得玩家

        Player player = (Player) commandSender;
        // 取得玩家擺床的位置
        Location location = player.getBedSpawnLocation();
        // 取得這個世界的重生點
        Location oLocation = player.getWorld().getSpawnLocation();
        // 判斷玩家是否騎馬
        if (player.isInsideVehicle() && player.getVehicle()
                instanceof Horse) {
            // 取得馬

            Horse horse = (Horse) player.getVehicle();
            // 檢查玩家有無擺床
            if (location == null ) {
                // 人下馬

                player.leaveVehicle();
                // 傳送馬
                horse.teleport(oLocation);
            }else {
                player.leaveVehicle();

                horse.teleport(location);
            }
            // 馬拉人上背

            horse.setPassenger(player);
            return true;
        else {
            // 沒騎馬直接傳送玩家

            if (location == null) {
                player.teleport(oLocation);

            else {
                player.teleport(location);

            }
        }
    }
    return false;}

2016年1月10日 星期日

文字格式

 文字格式


我們編輯插件之中最常用到的訊息顯示「 player.sendRawMessage("文字訊息")」,比如屬性上的顯示,不過不少人反應文字上的顯示排列經常歪七扭八的,這時候就需要善用 「String.format()」來解決問題,如文字所敘述是指「文字格式化」使用方法非常的多種,我們再這裡就教各位常用到的部份。


上圖很明顯因為劍術屬性多了一位數造成排版的錯位,經過文字格式化後能夠增強排版上的潤飾,也不會有錯位的問題,這部份份要先取決於大屬性的位數(個十百千萬),看一下0的數量位數就能知道最大屬性值,當然也可以隱藏起來。


其實這也是基礎中的基礎,詳情請翻閱課本(Java SE 6 技術手冊)第3章,插件寫多不是代表很厲害,我們要寫插件也要能寫出程度與細節,讓使用者能夠感受到我們的用心。