Like Share Discussion Bookmark Smile

J.J. Huang   2021-10-27   天堂私服   瀏覽次數:

天堂私服 | GM指令分析 (創怪/創NPC)「L1J版」

章節用意

insert的指令,此指令用於創建特定的怪物、NPC、場景物件,主要用於地圖上的NPC放置,或是怪物的出生點設置。

核心版本

  • L1J-3.80c

前言

在開始分析前,請務必先將以下文章閱讀完畢。

分析

效果:創建怪物或NPC並寫入資料庫中的spawnlistspawnlist_npc資料表。
範例:

1
2
.insert mob ${npcid}
.insert npc ${npcid}
  • 1.分析資料表:

    • 先進入commands表,找到insert的指令。
    • class_nameL1InsertSpawn
  • 2.分析資料表:

    • 再進入npc表,這邊先分析一個impl欄位。
    • 先列出impl的清單。(下面兩個SQL語法效果一樣)
      1
      2
      SELECT DISTINCT impl FROM npc;
      SELECT impl FROM npc GROUP BY impl;
    • 資料分析,可以透過這些impl去抓取資料判斷對應的分類。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      SELECT * FROM npc WHERE impl = 'L1Scarecrow';
      SELECT * FROM npc WHERE impl = 'L1Monster';
      SELECT * FROM npc WHERE impl = 'L1Teleporter';
      SELECT * FROM npc WHERE impl = 'L1Merchant';
      SELECT * FROM npc WHERE impl = 'L1Housekeeper';
      SELECT * FROM npc WHERE impl = 'L1Dwarf';
      SELECT * FROM npc WHERE impl = 'L1Guard';
      SELECT * FROM npc WHERE impl = 'L1Npc';
      SELECT * FROM npc WHERE impl = 'L1Guardian';
      SELECT * FROM npc WHERE impl = 'L1Quest';
      SELECT * FROM npc WHERE impl = 'L1Board';
      SELECT * FROM npc WHERE impl = 'L1FieldObject';
      SELECT * FROM npc WHERE impl = 'L1Doll';
      SELECT * FROM npc WHERE impl = 'L1Furniture';
      SELECT * FROM npc WHERE impl = 'L1Effect';
      SELECT * FROM npc WHERE impl = '';
      SELECT * FROM npc WHERE impl = 'L1Tower';
      SELECT * FROM npc WHERE impl = 'L1Crown';
      SELECT * FROM npc WHERE impl = 'L1Door';
      SELECT * FROM npc WHERE impl = 'L1AuctionBoard';
      SELECT * FROM npc WHERE impl = 'L1Signboard';
      SELECT * FROM npc WHERE impl = 'L1DragonPortal';
      SELECT * FROM npc WHERE impl = 'L1Fish';
    • 這邊已經將資料取出,並去對應過後的對應表如下:
      • L1Scarecrow = 新手村的木頭人。
      • L1Monster = 怪物。
      • L1Teleporter = 競技場管理員、守門人、傳送師。(皆屬於傳送類型的NPC)
      • L1Merchant = 商人、強化師。(基本上為有金錢交易的NPC)
      • L1Housekeeper = 血盟小屋的女僕。
      • L1Dwarf = 侏儒倉庫、角色專屬侏儒倉庫。
      • L1Guard = 警衛、城堡守衛。
      • L1Npc = 沒什麼作用的NPC
      • L1Guardian = 潘、精靈、精靈女皇..等等。(妖精森林裡面的守護者)
      • L1Quest = 任務。(任務型的NPC)
      • L1Board = 佈告欄。
      • L1FieldObject = 火把、曙光、海音村莊的風車、奇岩的競技場的旗幟…等等。(各種地圖的物件)
      • L1Doll = 魔法娃娃。
      • L1Furniture = 家具。
      • L1Effect = 火牢、精準目標、冰矛圍籬、衝擊之暈、治癒能量風暴。(魔法效果)
      • `` = 純粹沒定義的。(垃圾資料?)
      • L1Tower = 守護者之塔。(攻城的守護者之塔)
      • L1Crown = 王冠。
      • L1Door = 門。(好像沒什麼定義)
      • L1AuctionBoard = 拍賣佈告欄。(血盟小屋的拍賣佈告欄)
      • L1Signboard = 招牌。(古魯丁各個商店前的招牌)
      • L1DragonPortal = 龍之副本的門。
      • L1Fish = 魚。(釣魚池裡面會動魚或影子)
    • 基本上上面分析這麼多種,主要大為分兩類L1Monster、非 L1Monster`。
  • 3.分析資料表:

    • 再進入npc表,
    • 再找到安塔瑞斯的編號 = 45682,用於待會創怪用。
      1
      SELECT * FROM `npc` WHERE `name` = '安塔瑞斯' AND impl = 'L1Monster';
    • 再騎士村商店的梅林的編號 = 70074,用於待會NPC用。
      1
      SELECT * FROM `npc` WHERE `name` = '梅林' AND impl = 'L1Merchant';
    • 多找一個釣魚池的魚兒的編號 = 81308來測試效果。
      1
      SELECT * FROM `npc` WHERE impl = 'L1Fish';
  • 2.指令的分析:

    • 啟動模擬器除錯模式,並啟動天堂遊戲登入。
    • 基本上都是在騎士村內執行以下指令。(同一個地方,後面好確認伺服器重啟後的效果)
    • 使用創怪的GM指令,參數為mob表示為怪物,並帶入45682 = 安塔瑞斯
      1
      .insert mob 45682
    • 人物稍微往下移動換個位置。
    • 使用創NPCGM指令,參數為npc表示為怪物,並帶入70074 = 梅林
      1
      .insert npc 70074
    • 人物再次稍微往下移動換個位置。
    • 使用創NPCGM指令,參數為npc表示為怪物,並帶入81308 = 釣魚池的魚兒
      1
      .insert npc 81308
    • 這時候可以將模擬器關閉做重啟。
    • 再次登入遊戲。
    • 這時候可以看到安塔瑞斯梅林釣魚池的魚兒依舊是在設定的出生位置。
  • 3.分析程式碼:

    • 透過搜尋L1InsertSpawn開啟程式碼。
      1
      src/l1j/server/server/command/executor/L1InsertSpawn.java
    • 45~53行,判斷輸入的參數並去取得typenpcid
    • 並判斷是否有找到npcid,如無則傳送數據回客戶端做顯示找不到符合條件的NPC。
    • 54~62行:
      • 第一個判斷type是否為mob
        • 進入後再次判斷該npcimpl是否為L1Monster
          • 如不為L1Monster,則傳送數據回客戶端做顯示指定的NPC不是L1Monster類型。
        • 如斷無誤,則使用SpawnTablestoreSpawn方法。
        • 該方法就是使用將相關對應的資料寫入到資料表spawnlist中。
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          INSERT INTO spawnlist 
          SET location =?,
          count =?,
          npc_templateid =?,
          group_id =?,
          locx =?,
          locy =?,
          randomx =?,
          randomy =?,
          heading =?,
          min_respawn_delay =?,
          max_respawn_delay =?,
          mapid =?
      • 第二個判斷type是否為npc
        • 則使用NpcSpawnTablestoreSpawn方法。
        • 該方法就是使用將相關對應的資料寫入到資料表spawnlist_npc中。
          1
          2
          3
          4
          5
          6
          7
          8
          INSERT INTO spawnlist_npc 
          SET location =?,
          count =?,
          npc_templateid =?,
          locx =?,
          locy =?,
          heading =?,
          mapid =?
    • 63行,使用L1SpawnUtilspawn方法,將對應的npc立刻創建出來。

      註:此部分已經有在GM指令分析 (召喚怪物)分析,這邊就不在特別分析。

    • 剩下的程式碼都滿基礎的就不特別說明。

結論

  • 資料表:

    • 資料表及欄位,可於上方分析中有說明。
  • 程式碼:

    • src/l1j/server/server/command/executor/L1InsertSpawn.java
      • 處理客戶端來的GM指令insert的處理。
    • src/l1j/server/server/datatables/NpcSpawnTable.java
      • storeSpawn產生NPC並寫入資料庫。
    • src/l1j/server/server/datatables/SpawnTable.java
      • storeSpawn產生怪物並寫入資料庫。

結語

到此基本上所有比較重要的GM指令都算是分析完成。
分析這些資料也是為了對核心內部的程式碼加以了解,方便在之後的修改或是其他的分析都有所幫助。

這邊的分析較為重要的是,NPCimpl分類,這些分類是真真實實對應到核心內的Class的實例;
例如:L1Fish = L1FishInstance。這些對應在慢慢分析整理後,可以對整個核心設計和架構可以有更全面的理解。

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

免責聲明

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