Like Share Discussion Bookmark Smile

J.J. Huang   2021-09-17   天堂私服   瀏覽次數:

天堂私服 | GM指令的程式碼邏輯分析「L1J版」

章節用意

因後面的各個分析,過程中可能都需要使用到一些指令來產生怪物、物品、狀態…等等。所以這邊就先分析GM指令。
而在分析這些指令中所分析的程式碼,其實就可以將其應用在很多的地方。

例如:全輔助指令 → 全輔助藥水。

核心版本

  • L1J-TW_3.80c

分析

在開始分析前,要知道GM指令的指令使用方式,才方便開啟除錯(Debug)進行分析。
以下提供一個全輔助的指令使用allbuff ${角色名稱}

1
.allbuff 線上GM
  • 1.分析資料表:

    • 在茫茫的資料庫中,先觀察所有的表名,會發現一個commands的表名(commands = 命令/指令),點進去看資料如下圖。
    • 可見有三個欄位,分別為:
      • name:猜應該就是在遊戲內的指令名稱。
      • access_level:猜應該是使用指令的權限等級判斷。
      • class_name:就是會呼叫處理指令的Class的名稱。
    • 相信access_level欄位所對應的應該是accounts.access_level或是characters.access_level
    • 嘗試後確認為characters.access_level為主要的判斷。
  • 2.分析程式碼:

    • 根據猜測commands為表名,那透過此關鍵字去找尋程式碼,基本上也可以找到相對應的程式。
      1
      src/l1j/server/server/command/L1Commands.java
    • 開啟後分析程式碼,可以知道該SQL再根據name去取得資料庫資料。
    • 反向分析找尋呼叫的位置。
    • 在方法get上,按下右鍵並選擇Find Usages
    • 下方會彈出此所有使用此方法的清單。
    • 剛好只有一個地方,我們點擊將其開啟在工作區。
    • 這時候會開啟GMCommands.java
      1
      src/l1j/server/server/GMCommands.java
    • 63~66於資料庫取得指令,如nullreturn
    • 67~70判斷是用指令的角色是否有足夠權限使用此指令。
    • 72~76使用className去取得Class並執行方法execute

      註:className會判斷是否是完整路徑,如果不完整會補全l1j.server.server.command.executor.,詳細行為可見complementClassName方法。

    • 至此可以知道真時取得資料並判斷是否執行的程式碼位置就是在上述這些地方。
    • 繼續反向分析找尋呼叫的位置。
    • 在方法executeDatabaseCommand上,按下右鍵並選擇Find Usages
    • 剛好只有一個地方,我們點擊將其開啟在工作區。
    • 這時候還是在GMCommands.java,跳轉到97行程式碼。
    • 86~94在處理輸入來的指令,拆成指令與參數。
    • 97就是剛剛分析過的執行指令。
    • 98~100是將這次執行的指令存起來,也就是紀錄最後一次執行的指令。
    • 103~110就是判斷指令是否為r,如果是就執行最後一次執行的指令。

      註:如果你在最後一次執行.allbuff 線上GM,那下次還想執行一樣的指令,只需要打.r即可。

    • 繼續反向分析找尋呼叫的位置。
    • 在方法handleCommands上,按下右鍵並選擇Find Usages
    • 這次比較尷尬有四個地方,各別快速分析一下:
      • GMCommands內的121127都是在redo的方法內,可以斷定這是在使用.r指令的時後呼叫的。
      • C_chat分析程式碼和註解,就是在處理GM指令的入口點。
      • L1Favorite他是對應到GM指令的f或是書籤的這個指令。(該指令用途我沒使用不清楚)
    • 我們點擊C_chat將其在工作區。
      1
      src/l1j/server/server/clientpackets/C_Chat.java
    • 63判斷是否為一般聊天。

      註:該值需要了解客戶端的部分,此不特別說明。

    • 67~72處理GM指令,只要輸入的內容是.開頭,而且人物是GM或是終端的都會進入。
    • 繼續反向分析找尋呼叫的位置。
    • 在方法C_Chat上,按下右鍵並選擇Find Usages
    • 這次有兩個地方,直接都點過去看。
      1
      src/l1j/server/server/PacketHandler.java
    • PacketHandler會發現對應的是個OP_CODE
      • C_OPCODE_CHAT:請求使用一般聊天頻道
      • C_OPCODE_CHATGLOBAL:請求使用廣播聊天頻道

        註:我為什麼會知道對應的是客戶端的什麼行為?因為有註解有寫得很清楚。

    • 分析至此告一段落。

結論

根據不斷的分析,大致上可以理出一些東西。

  • 資料表:
    • commands.name指令名稱。
    • commands.access_level用於判斷指令權限的值。
    • commands.class_name對應要執行的class名稱。
  • 程式碼:
    • src/l1j/server/server/PacketHandler.java
      • 處理所有客戶端來的請求。
    • src/l1j/server/server/clientpackets/C_Chat.java
      • 處理客戶端發送過來的說話內容。
    • src/l1j/server/server/GMCommands.java
      • 處理GM指令的一些判斷和邏輯。
    • src/l1j/server/server/command/L1Commands.java
      • 對應資料庫commands所做的操作。

結語

其實在GM指令內,已經提供出很多的想法和程式碼範例。
這些只要稍加修改其實就可以達成很多有趣的遊戲內容。

原創文章真的不易,希望多多支持,感謝。
最後建議回顧一下首章天堂私服 | 天堂私服架設教學,了解其章結目錄,此處會不定時更新。

免責聲明

  • 本部落格文章中皆不提供任何所謂的遊戲「主程式」、「模擬器」、「登入器」…等等相關程式的下載點。
  • 本部落格文章中所見之遊戲主程式和服務器端程序均來自網路發佈,版本歸原作者所有
  • 本部落格文章為研究SQL資料庫與修改JAVA語法使用,非商業用途,亦無做營運事實等任何一切商業行為
  • 本部落格文章內容是為研究學習設計思想和原理為目的,絕沒有故意侵權或惡意抄襲、篡改其他遊戲內容