天堂私服 | GM指令分析/修改 (金幣)「L1J版」
章節用意
adena的指令,給GM使用給予自己增加金幣,或許可以套用物品上,用於節日活動開啟特定物品贈送金幣。
核心版本
- L1J-3.80c
分析
在開始分析前,要知道GM指令的指令效果與使用方式,才方便開啟除錯(Debug)進行分析。
效果:產生金幣。
範例:
1 | .adena ${金幣數量} |
1.分析資料表:
- 先進入
commands表,找到adena的指令。 class_name是L1Adena。
- 先進入
2.分析程式碼:
- 透過搜尋
L1Adena開啟程式碼。1
src/l1j/server/server/command/executor/L1Adena.java

- 登入遊戲稍微確認一下目前物品欄內的物品和數量。

- 使用除錯模式,斷點在
38行。 38~39行單純取得指令所帶的金幣數量參數,放於count變數中。41行可以特別分析一下pc.getInventory()。- 使用評估表達式
Evaluate Expression來分析。 - 可發現物品欄的物件是
L1PcInventory.class。
- 而
_owner是L1PcInstance.class;這個之前就分析過此為客戶端的完整資料。
_items可以發現數量與人物物品欄內的數量一致,將其展開並點開其中一個的_item。- 這邊可以發現
_item是L1Weapon,說明是武器的物品,裡面的_name是歐西斯匕首。
- 接著在方法
storeItem上,按下Ctrl+ 左鍵。 - 會直接跳轉到該方法位置。
1
src/l1j/server/server/model/L1PcInventory.java
- 設定斷點在
142繼續分析。 142~148行,是在判斷數量是否大於0、物品資料是否合法存在。150行,40312物品查看資料庫後可以發現是旅館鑰匙;這一段判斷就先不分析。160行,是判斷該物品是否是可堆疊的物品。163~166行,判斷該物品是否已經在物品欄內存在,如果不存在則直接新增,168行,物品已存在的狀態,會將數量相加,並更新物品資訊。- 最後
Return該新增的物品L1ItemInstance資訊。註:部分程式碼沒有特別分析到,可自行深入分析。

- 回到
L1Adena。 42~44行,根據Return回來的L1ItemInstance資訊,可以做一些判斷或是組合回傳回客戶端的數據。
- 透過搜尋
修改
目前指令只有針對自己,希望將此指令修改程可以指定玩家做查詢。
以下是修改後所使用的指令方式:
1 | .desc me|${玩家名稱} ${金幣數量} |
- 修改前
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void execute(L1PcInstance pc, String cmdName, String arg) {
try {
StringTokenizer stringtokenizer = new StringTokenizer(arg);
int count = Integer.parseInt(stringtokenizer.nextToken());
L1ItemInstance adena = pc.getInventory().storeItem(L1ItemId.ADENA, count);
if (adena != null) {
pc.sendPackets(new S_SystemMessage((new StringBuilder()).append(count).append(" 金幣產生。").toString()));
}
}
catch (Exception e) {
pc.sendPackets(new S_SystemMessage((new StringBuilder()).append("請輸入 .adena 數量||.金幣 數量。").toString()));
}
} - 修改後
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public void execute(L1PcInstance pc, String cmdName, String arg) {
try {
StringTokenizer stringtokenizer = new StringTokenizer(arg);
String char_name = stringtokenizer.nextToken();
int count = Integer.parseInt(stringtokenizer.nextToken());
L1PcInstance target = null;
if (char_name.equalsIgnoreCase("me")) {
target = pc;
}
else {
target = L1World.getInstance().getPlayer(char_name);
}
if (target == null) {
pc.sendPackets(new S_ServerMessage(73, char_name));
return;
}
L1ItemInstance adena = target.getInventory().storeItem(L1ItemId.ADENA, count);
if (adena != null) {
pc.sendPackets(new S_SystemMessage((new StringBuilder()).append("贈與 ").append(target.getName()).append(" ").append(count).append(" 金幣。").toString()));
}
}
catch (Exception e) {
pc.sendPackets(new S_SystemMessage((new StringBuilder()).append("請輸入 .adena 玩家名稱|me 數量。").toString()));
}
} - 修改後儲存,啟動模擬器。
- 啟動天堂登入遊戲,登入
GM帳號與另一個帳號。 GM使用指令贈與另一位玩家金幣,該玩家金幣確實已經增加。
結論
- 程式碼:
src/l1j/server/server/command/executor/L1Adena.java- 處理客戶端來的
GM指令desc的處理。
- 處理客戶端來的
src/l1j/server/server/model/L1PcInventory.java- 物品欄的相關資訊與方法。
結語
雖然文章的一些修改,非常簡單,但是建議一定要自己動手做做看。
原創文章真的不易,希望多多支持,感謝。
最後建議回顧一下首章天堂私服 | 天堂私服架設教學,了解其章節目錄。
免責聲明
- 本部落格文章中皆不提供任何所謂的遊戲「主程式」、「模擬器」、「登入器」…等等相關程式的下載點。
- 本部落格文章中所見之遊戲主程式和服務器端程序均來自網路發佈,版本歸原作者所有。
- 本部落格文章為研究SQL資料庫與修改JAVA語法使用,並非商業用途,亦無做營運事實等任何一切商業行為。
- 本部落格文章內容是為研究學習設計思想和原理為目的,絕沒有故意侵權或惡意抄襲、篡改其他遊戲內容!
