查看: 881|回復: 7

[分享] 製作GM管理工具

[複製鏈接]

3

主題

33

帖子

1533

金錢

妖魔鬥士

Rank: 6Rank: 6

威望
0
精華
0
貢獻
0
鑽石
0
閱讀權限
40
積分
1566
在線時間
7 小時
相冊
0
日誌
0
好友
0
發表於 2026-2-3 11:29 | 顯示全部樓層 |閱讀模式
購買主題 已有 4 人購買  本主題需向作者支付 200 金錢 才能瀏覽



上一篇︰武器新增攻擊施放技能
下一篇︰創完NPC 出現錯誤 不知道如何解決

2

主題

173

帖子

3400

金錢

暗殺軍王.史雷佛

Rank: 8Rank: 8

威望
0
精華
0
貢獻
0
鑽石
0
閱讀權限
45
積分
3573
在線時間
115 小時
相冊
0
日誌
0
好友
0
發表於 2026-2-3 15:43 | 顯示全部樓層
什麼東西,來瞧瞧看

回復 支持 反對

使用道具 舉報

0

主題

161

帖子

1650

金錢

妖魔鬥士

Rank: 6Rank: 6

威望
2
精華
0
貢獻
0
鑽石
0
閱讀權限
40
積分
1815
在線時間
71 小時
相冊
0
日誌
0
好友
1
發表於 2026-2-3 19:26 | 顯示全部樓層
不懂 來看看
觀摩一下



回復 支持 反對

使用道具 舉報

496

主題

4899

帖子

28萬

金錢

巴拉卡斯

Rank: 13Rank: 13Rank: 13Rank: 13

威望
5
精華
0
貢獻
0
鑽石
0
閱讀權限
75
積分
285458
在線時間
1007 小時
相冊
0
日誌
0
好友
0
發表於 2026-2-5 02:43 | 顯示全部樓層
感謝分享

回復

使用道具 舉報

3

主題

33

帖子

1533

金錢

妖魔鬥士

Rank: 6Rank: 6

威望
0
精華
0
貢獻
0
鑽石
0
閱讀權限
40
積分
1566
在線時間
7 小時
相冊
0
日誌
0
好友
0
 樓主| 發表於 2026-2-5 09:25 | 顯示全部樓層
20260205新增了給物品的功能

回復 支持 反對

使用道具 舉報

0

主題

53

帖子

614

金錢

妖魔

Rank: 4

威望
0
精華
0
貢獻
0
鑽石
0
閱讀權限
35
積分
667
在線時間
16 小時
相冊
0
日誌
0
好友
1
發表於 2026-2-12 20:59 | 顯示全部樓層
可以分享點畫面看看嗎?

回復 支持 反對

使用道具 舉報

496

主題

4899

帖子

28萬

金錢

巴拉卡斯

Rank: 13Rank: 13Rank: 13Rank: 13

威望
5
精華
0
貢獻
0
鑽石
0
閱讀權限
75
積分
285458
在線時間
1007 小時
相冊
0
日誌
0
好友
0
發表於 2026-2-14 08:20 | 顯示全部樓層
謝謝分享

[發帖際遇]: 野性覺醒 發帖時在路邊撿到 3 金錢,偷偷放進了口袋. 幸運榜 / 衰神榜
回復

使用道具 舉報

322

主題

1574

帖子

2萬

金錢

巴列斯

Rank: 10Rank: 10Rank: 10

威望
12
精華
0
貢獻
0
鑽石
0
閱讀權限
60
積分
24830
在線時間
1259 小時
相冊
0
日誌
0
好友
2

最佳新人

發表於 2026-3-1 19:24 | 顯示全部樓層
本帖最後由 天堂迷 於 2026-3-1 21:06 編輯

改一改都不會跑GM管理介面出來
用了好久還是查不出所以然
再麻煩大神看一下是什麼問題
核心改好都未報錯誤
模擬器開啟後也沒報錯誤
GM管理介面沒跑出來

src/com/lineage/Server.java ↓↓↓↓↓↓
-----------------------------------------------------------------------------------------------------------------------
package com.lineage;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.logging.LogManager;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.PropertyConfigurator;

import com.lineage.commons.system.LanSecurityManager;
import com.lineage.config.Config;
import com.lineage.config.ConfigAlt;
import com.lineage.config.ConfigBad;
import com.lineage.config.ConfigBoxMsg;
import com.lineage.config.ConfigCharSetting;
import com.lineage.config.ConfigCreateMsg;
import com.lineage.config.ConfigDescs;
import com.lineage.config.ConfigIpCheck;
import com.lineage.config.ConfigKill;
import com.lineage.config.ConfigOther;
import com.lineage.config.ConfigRate;
import com.lineage.config.ConfigRecord;
import com.lineage.config.ConfigSQL;
import com.lineage.config.ConfigSkill;
import com.lineage.server.GameServer;

/**
* 服務器啟動
*/
public class Server {

        private static final String _log_prop = "./config/logging.properties";

        private static final String _log_4j = "./config/log4j.properties";

        private static final String _loginfo = "./loginfo";

        private static final String _back = "./back";

        /**
         * MAIN
         *
         * @param args
         * @throws Exception
         */
        public static void main(final String[] args) throws Exception {

                Calendar date = Calendar.getInstance();
                // 1=周日 7=周六
                System.out.println(">>>>" + date.get(Calendar.DAY_OF_WEEK));
                System.out.println(">>>>" + date.get(Calendar.HOUR_OF_DAY));

                // int i1 = 2;
                // int i2 = 16;
                // System.out.println("CONFIG 資料加載異常!" + (byte)(128) + " " +
                // (~(byte)(128)));
                // System.out.println("CONFIG 資料加載異常!" + (i1|=i2));
                // static

                // (>> 1: 除) (<< 1: 乘)
                // 1:2 2:4 3:8 4:16 5:32 6:64 7:128 8:256 9:512 10:1024
                // System.out.println(Integer.decode("0x42"));
                // System.getProperties().list(System.out);// 可用命令

                // 測試用核心
                try {
                        // 在核心啟動命令後面加上 test 可以用來作顯示測試
                        if (args[0.equalsIgnoreCase("test")) {
                                Config.DEBUG = true;
                        }

                } catch (final Exception e) {
                        // e.printStackTrace();
                }

                // 壓縮舊檔案
                final CompressFile bean = new CompressFile();
                try {
                        // 建立備份用資料夾
                        final File file = new File(_back);
                        if (!file.exists()) {
                                file.mkdir();
                        }

                        final String nowDate = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss")
                                        .format(new Date());
                        bean.zip(_loginfo, "./back/" + nowDate + ".zip");

                        final File loginfofile = new File(_loginfo);
                        final String[] loginfofileList = loginfofile.list();
                        for (final String fileName : loginfofileList) {
                                final File readfile = new File(_loginfo + "/" + fileName);
                                if (readfile.exists() && !readfile.isDirectory()) {
                                        readfile.delete();
                                }
                        }

                } catch (final IOException e) {
                        System.out.println("資料夾不存在: " + _back + " 已經自動建立!");
                }

                boolean error = false;

                try {
                        final InputStream is = new BufferedInputStream(new FileInputStream(
                                        _log_prop));
                        LogManager.getLogManager().readConfiguration(is);
                        is.close();

                } catch (final IOException e) {
                        System.out.println("檔案遺失: " + _log_prop);
                        error = true;
                }

                // 十進制轉二進制
                // System.out.println(Integer.toBinaryString(75) + "\n" +
                // Integer.toBinaryString(73));
                // System.out.println(Integer.toBinaryString(10) + "\n" +
                // Integer.toBinaryString(20));
                // System.out.println(Integer.toBinaryString(30) + "\n" +
                // Integer.toBinaryString(30));
                // 二進制轉十進制
                // System.out.println(Long.parseLong("00010", 2));
                // System.out.println(Long.parseLong("10000", 2));
                // System.out.println(Long.parseLong("10010", 2));

                try {
                        PropertyConfigurator.configure(_log_4j);

                } catch (final Exception e) {
                        System.out.println("檔案遺失: " + _log_4j);
                        System.exit(0);
                }

                try {
                        ConfigSkill.load();
                        Config.load();
                        ConfigAlt.load();
                        ConfigCharSetting.load();
                        ConfigOther.load();
                        ConfigRate.load();
                        ConfigSQL.load();
                        ConfigRecord.load();

                        ConfigDescs.load();
                        ConfigBad.load();
                        ConfigKill.load();
                        ConfigIpCheck.load();
                        ConfigBoxMsg.load();
                        ConfigCreateMsg.load();
                } catch (final Exception e) {
                        System.out.println("CONFIG 資料加載異常!" + e);
                        error = true;
                }

                System.out.println(_licence + "\n");
                final Log log = LogFactory.getLog(Server.class);

                // ManagementFactory.getMemoryMXBean().setVerbose(true);

                final String infoX = "\n\r##################################################"
                                + "\n\r       服務器 (核心版本:"
                                + Config.VER
                                + "/"
                                + Config.SRCVER
                                + ")"
                                + "\n\r##################################################";

                log.info(infoX);

                final File file = new File("./jar");
                final String[] fileNameList = file.list();

                for (final String fileName : fileNameList) {
                        final File readfile = new File(fileName);
                        if (!readfile.isDirectory()) {
                                log.info("加載引用JAR: " + fileName);
                        }
                }

                if (error) {
                        System.exit(0);
                }

                // log.info("訊息辨識(色彩涵義): [INFO]資訊");
                // log.debug("訊息辨識(色彩涵義): [DEBUG]除錯");
                // log.warn("訊息辨識(色彩涵義): [WARN]警告");
                // log.error("訊息辨識(色彩涵義): [ERROR]錯誤");
                // log.fatal("訊息辨識(色彩涵義): [FATAL]嚴重錯誤");

                // SQL讀取初始化
                DatabaseFactoryLogin.setDatabaseSettings();
                DatabaseFactory.setDatabaseSettings();

                DatabaseFactoryLogin.get();
                DatabaseFactory.get();

                // 安全管理器
                final LanSecurityManager securityManager = new LanSecurityManager();
                System.setSecurityManager(securityManager);
                log.info("加載 安全管理器: LanSecurityManager");

                final String osname = System.getProperties().getProperty("os.name");
                if (osname.lastIndexOf("Linux") != -1) {
                        Config.ISUBUNTU = true;
                }

                // 1. 先執行伺服器初始化
        GameServer.getInstance().initialize();
        
        // 2. 伺服器啟動完成後,開啟 GM 管理工具 UI
        new PackedTestUI();
    }

    // licence
    private static final String _licence = "Copyright (C) 2014 by DarkForce <[email protected]>\n";
}






src/com/lineage/PackedTestUI.java ↓↓↓↓↓↓
-----------------------------------------------------------------------------------------------------------------------
package com.lineage;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Collection;

import com.lineage.server.model.Instance.L1PcInstance;
import com.lineage.server.world.World;
import com.lineage.server.datatables.ItemTable;
import com.lineage.server.templates.L1Item;

// 引用指令區
import com.lineage.server.command.executor.L1AllBuff;
import com.lineage.server.command.executor.L1CreateItem;


public class PackedTestUI extends JFrame {
    // ==========================================
    // 基礎元件宣告
    // ==========================================
    private DefaultListModel<String> playerListModel = new DefaultListModel<>();
    private DefaultListModel<String> itemListModel = new DefaultListModel<>();
    private java.util.List<L1Item> allItemsBackup = new java.util.ArrayList<>();
    private JList<String> playerList;
    private JList<String> itemList;
    private JTextField txtSearch;
    private JTextField txtEnchantLevel;
    private JTextField txtAmount;

    public PackedTestUI() {
            // 視窗基礎設定
            setTitle("GM 管理工具 (模組化版本)");
            setSize(600, 350);
            getContentPane().setLayout(null);
            setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

            // ==========================================
            // 區塊 0:左側玩家清單 (共用)
            // ==========================================
            initPlayerListSection();

            // ==========================================
            // 區塊 1:AllBuff 功能區
            // ==========================================
            initAllBuffModule();

            // ==========================================
            // 區塊 2:AddItem 功能區
            // ==========================================
            initAddItemModule();

            // ==========================================
            // 初始化與顯示
            // ==========================================
            reloadPlayers();
            reloadItems();
           
            // 自動刷新玩家名單
            new Timer(5000, e -> reloadPlayers()).start();

            getContentPane().revalidate();
            getContentPane().repaint();
            setVisible(true);
    }

    /**
     * 【共用】初始化玩家列表
     */
    private void initPlayerListSection() {
            JLabel lblPlayer = new JLabel("線上角色");
            lblPlayer.setBounds(15, 10, 100, 15);
            getContentPane().add(lblPlayer);

            JScrollPane scrollPlayer = new JScrollPane();
            scrollPlayer.setBounds(15, 35, 120, 250);
            getContentPane().add(scrollPlayer);

            playerList = new JList<>(playerListModel);
            scrollPlayer.setViewportView(playerList);
    }

    /**
     * 【模組化】AllBuff 功能
     */
    private void initAllBuffModule() {
            JButton btnAllBuff = new JButton("全能 Buff");
            btnAllBuff.setBounds(145, 35, 100, 30);
            btnAllBuff.addActionListener(e -> {
                    String selected = playerList.getSelectedValue();
                    if (selected == null) return;
                  
                    L1PcInstance target = World.get().getPlayer(selected);
                    if (target != null) {
                            // 執行 AllBuff
                            L1AllBuff.getInstance().execute(target, "allbuff", selected);
                            System.out.println("執行 AllBuff -> " + selected);
                    }
            });
            getContentPane().add(btnAllBuff);
    }

    /**
     * 【模組化】AddItem 功能
     */
    private void initAddItemModule() {
            // 1. 標題
            JLabel lblItem = new JLabel("物品清單  搜尋:");
            lblItem.setBounds(260, 10, 100, 15);
            getContentPane().add(lblItem);

            // 2. 物品選擇清單
            JScrollPane scrollItem = new JScrollPane();
            scrollItem.setBounds(260, 35, 250, 250);
            getContentPane().add(scrollItem);

            itemList = new JList<>(itemListModel);
            scrollItem.setViewportView(itemList);

            // 3. 執行按鈕
            JButton btnAddItem = new JButton("給予物品");
            btnAddItem.setBounds(145, 66, 100, 30);
            btnAddItem.addActionListener(e -> {
                    String selectedPlayer = playerList.getSelectedValue();
                    String selectedItem = itemList.getSelectedValue();
                  
                    if (selectedPlayer == null || selectedItem == null) {
                            JOptionPane.showMessageDialog(this, "請同時選取玩家與物品");
                            return;
                    }

                    L1PcInstance target = World.get().getPlayer(selectedPlayer);
                    if (target != null) {
                            int start = selectedItem.lastIndexOf("[") + 1;
                    int end = selectedItem.lastIndexOf("]");
                    String count = txtAmount.getText().trim();
                    String enchant = txtEnchantLevel.getText().trim();
                    String isId = "1"; // 1 為已鑑定
                    String itemId = selectedItem.substring(start, end);
                    
                    if (count.isEmpty()) count = "1";
                    if (enchant.isEmpty()) enchant = "0";
                    String commandArg = String.format("%s %s %s %s", itemId, count, enchant, isId);
                    
                    L1CreateItem.getInstance().execute(target, "item", commandArg);
                    System.out.println("給予物品 ID: " + itemId + " 數量: " + count + " -> " + selectedPlayer);
                    }
                  
            });
            getContentPane().add(btnAddItem);
           
            /*
             * txtSearch 搜尋框 精煉等級 數量
             */
            txtSearch = new JTextField();
            txtSearch.setBounds(354, 7, 96, 21);
            getContentPane().add(txtSearch);
            txtSearch.setColumns(10);
           
            JLabel lblNewLabel = new JLabel("精煉等級");
            lblNewLabel.setBounds(145, 98, 53, 21);
            getContentPane().add(lblNewLabel);
           
            JLabel lblNewLabel_1 = new JLabel("數量");
            lblNewLabel_1.setBounds(145, 149, 69, 21);
            getContentPane().add(lblNewLabel_1);
           
            txtEnchantLevel = new JTextField();
            txtEnchantLevel.setBounds(145, 118, 96, 21);
            getContentPane().add(txtEnchantLevel);
            txtEnchantLevel.setColumns(10);
           
            txtAmount = new JTextField();
            txtAmount.setBounds(145, 169, 96, 21);
            getContentPane().add(txtAmount);
            txtAmount.setColumns(10);
           
            txtSearch.addKeyListener(new java.awt.event.KeyAdapter() {
                @Override
                public void keyReleased(java.awt.event.KeyEvent e) {
                    // 使用者放開按鍵時即時過濾
                    filterItems(txtSearch.getText());
                }
            });
    }

    // ==========================================
    // 數據處理方法
    // ==========================================
   
    private void reloadPlayers() {
            playerListModel.clear();
            for (L1PcInstance pc : World.get().getAllPlayers()) {
                    playerListModel.addElement(pc.getName());
            }
    }
   
    private void reloadItems() {
            allItemsBackup.clear();
        try {
            ItemTable itemTable = ItemTable.get();
            String[] fields = {"_etcitems", "_weapons", "_armors"};

            for (String fieldName : fields) {
                try {
                    java.lang.reflect.Field field = ItemTable.class.getDeclaredField(fieldName);
                    field.setAccessible(true);
                    java.util.Map<?, L1Item> map = (java.util.Map<?, L1Item>) field.get(itemTable);
                    if (map != null) {
                        allItemsBackup.addAll(map.values());
                    }
                } catch (Exception e) {
                    System.out.println("跳過欄位: " + fieldName);
                }
            }
            
            // 初始顯示全部
            filterItems("");
            System.out.println("成功載入 " + allItemsBackup.size() + " 件物品");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
   
    private void filterItems(String key) {
        itemListModel.clear();
        String searchKey = key.toLowerCase().trim();
        
        for (L1Item item : allItemsBackup) {
            String itemName = item.getName();
            // 如果關鍵字是空的,或者名字包含關鍵字
            if (searchKey.isEmpty() || itemName.toLowerCase().contains(searchKey)) {
                // 建議加上 ID 方便區分同名的東西
                itemListModel.addElement(itemName + " [" + item.getItemId() + "]");
            }
        }
    }
}






回復 支持 反對

使用道具 舉報

您需要登錄後才可以回帖 登錄 | 註冊會員

本版積分規則

天堂私服列表

45客服

Archiver| 45天堂私服論壇   分享到微博! 分享到臉書! 分享到噗浪! 分享到維特! 分享到Google+! 分享到LINE!

45天堂私服發佈站 ©    天堂私服架設教學  提供最新天堂私服最新資訊

流量最高、品質最好、服務最優、玩家首選、最新天堂私服資訊,都在45天堂私服發佈站.    免責聲明

Sitetag
line客服聯繫
掃一掃二碼
Line客服聯繫
24H專人回覆
返回頂部 返回列表