传奇私服自用脚本

自助挂机脚本

// ==UserScript==
// @name         传奇私服自用脚本
// @namespace    https://linux.do/u/io.oi/cq.auto.play
// @version      0.0.1
// @author       果农
// @description  自助挂机脚本
// @license      MIT
// @icon         https://www.google.com/s2/favicons?sz=64&domain=e-hai.one
// @match        http://chuanqi.proxy2world.com/play?*
// @match        https://cq.kubbo.cn/*
// @match        http://fuckgfw.me:23180/play?*
// @match        http://cq.eb.cx/*
// @grant        GM_addStyle
// @grant        none
// ==/UserScript==

((o) => {
    // 添加自定义样式到页面
    if (typeof GM_addStyle == "function") {
        GM_addStyle(o);
        return;
    }
    const t = document.createElement("style");
    (t.textContent = o), document.head.append(t);
})(
    " .control-panel{position:fixed;bottom:0;left:0;min-width:auto} "+
    " .control-panel .control-group{display:flex} " +
    " .control-panel div{background: #0f0f0f;} " +
    " .control-panel div label, .control-panel .control-group .button{color:#ece6cf;background-color:#084552;padding:.4rem;border:none;cursor:pointer;border-radius:.1rem} " +
    " .control-panel input[type=checkbox]{display: none;} "+
    " .control-panel .icon-label {display: inline-block; cursor: pointer;} " +
    " .control-panel .icon-label svg {width: 100%; height: 100%;} "
);

(function () {
    "use strict";
    const gameState = {
        // 自动挂机地图ID
        autoPlayMapId: 150,
        // 存储上一个BOSS的信息,用于判断是否为新BOSS
        lastBoss: {},
        // 是否正在寻路
        isFindedPath: false,
        // 是否在自动挂机状态
        autoPlayStatus: true,
        // 上一个地图ID
        lastMapId: 147,
        // 连续飞行次数
        flyCount: 0,
        // 是否是第一次连接
        isFirstConnected: true,
        // 是否是第一次运行
        isFirstRun: true,
        // 是否在黑白佬的服务器
        isInBlackWhite: window.location.hostname === "chuanqi.proxy2world.com",
        // 定时器和状态管理
        fireTimer: undefined,
        // 监控定时器
        watchTimer: undefined,
        // 是否附近有BOSS怪物
        nearHasBossMonster: false
    };
    window.gameState = gameState;

    const buttonColor = "#55b47d"; // 激活状态按钮颜色
    const buttonColor2 = "#084552"; // 未激活状态按钮颜色

    /**
     * 地图配置
     * @property {string} name - 地图名称
     * @property {number} flyId - 传送ID
     * @property {number} mapId - 地图ID
     * @property {boolean} dontautoplay - 是否禁用自动挂机
     * @property {Array} dangerArea - 危险区域坐标点(顺时针)
     * @property {Array} avoidMonsters - 需要躲避的怪物名称列表
     */
    const mapCfgs = {
        0: {
            // 这个适合任意地图挂机,仅实现无怪自动飞功能
            name: "无怪自动飞",
            flyId: 0,
            mapId: 0,
        },
        1: {
            name: "比奇",
            flyId: 3,
            mapId: 1,
            // 不开启挂机,只传送到当前地图
            dontautoplay: 1,
        },
        3: {
            name: "盟重",
            flyId: 14,
            mapId: 3,
            dontautoplay: 1,
        },
        9: {
            name: "封魔谷",
            flyId: 12,
            mapId: 9,
            // 忽略的坐标点,顺时针
            dangerArea: [
                [162, 60],
                [208, 95],
                [155, 130],
                [110, 100],
            ],
            // 不打的怪物名称,可以是全名,也可以只指定部分。如果检测到这些怪物就直接飞走
            avoidMonsters: ["麒麟"],
        },
        4: {
            name: "苍月",
            flyId: 16,
            mapId: 4,
            dangerArea: [
                [3, 130],
                [52, 103],
                [89, 135],
                [31, 168],
            ],
            avoidMonsters: ["麒麟", "魔龙"],
            notRecordBossInfo: true,
        },
        143: {
            name: "牛魔1层",
            flyId: 112,
            mapId: 143,
        },
        144: {
            name: "牛魔2层",
            flyId: 113,
            mapId: 144,
        },
        145: {
            name: "牛魔3层",
            flyId: 114,
            mapId: 145,
        },
        146: {
            name: "牛魔4层",
            flyId: 115,
            mapId: 146,
        },
        147: {
            name: "牛魔5层",
            flyId: 116,
            mapId: 147,
        },
        148: {
            name: "牛魔6层",
            flyId: 117,
            mapId: 148,
        },
        149: {
            name: "牛魔7层",
            // boss直接,配置参考 app.VlaoF.BossConfig,由 app.UyfaJ.ins().send_49_2 负责调用
            flyBossId: [9, 102],
            mapId: 149,
        },
        150: {
            name: "庄园",
            flyId: 118,
            mapId: 150,
            notFly: 1,
            // 挂机坐标点 38,33 40,31 42,29 44,27 46,25
            autoPlayArea: {
                x: 41,
                y: 30,
                scope: 3,
            },
            autoPlayInitPosition: {x: 40, y: 31, random: 3},
        },
        239: {
            name: "太行1层",
            flyId: 167,
            mapId: 239,
        },
        318: {
            name: "龙门1层",
            flyId: 218,
            mapId: 318,
        },
        347: {
            name: "沉默5层",
            flyId: 233,
            mapId: 347,
        },
        348: {
            name: "昏睡5层",
            flyId: 234,
            mapId: 348,
        },
        349: {
            name: "天池1层",
            flyId: 235,
            mapId: 349,
        },
    };

    /**
     * 一些app相关的函数以及数组
     * app.VlaoF.StdItems 这是一个数组,存放着所有的物品信息
     * app.VlaoF.RecyclingSettingConfig 这是一个数组,存放着所有的回收配置
     * app.GameMap.scenes.hook 这是一个数组,存放着当前地图的挂机点位
     *
     * app.ForgeMgr.ins().send_19_1 这是合成的api,经验瓶的itemCfg.Eid是3402
     * send_19_1(3402,1)
     *
     * 有龙的,捡取范围不生效可以自己改一下
     * app.PlayerRole.prototype.pickUpPetRange = function () { return 25; }
     */

    const gameHelper = {

        /**
         * 更新网页标题
         */
        updateDocumentTitle: function() {
            let player = app.NWRFmB.ins().getPayer;
            if(player && player.hasOwnProperty("_charName")) {
                document.title = player._charName + " - " + gameHelper.getCircleLv() + '转' + gameHelper.getLv() + '级' + '(' + app.MiOx.srvname + ')';
            }
        },

        /**
         * 整理包裹
         */
        sortBag: function() {
            app.ThgMu.ins().post_8_10();
        },

        /**
         * 替换玩家身上指定装备
         */
        replaceEquip: function(item) {
            // 包袱ID:0:药品,1:装备,2:材料;包袱中的所有物品存放于数组app.ThgMu.ins().bagItem[x]中
            // 先给包袱里的物品整理一下,这样就不用去找属性最好的那个了
            gameHelper.sortBag();
            // 获取当前的装备
            let itemId = gameHelper.checkAndConvertToItemId(item);
            if (itemId == 0) {
                return false;
            }
            // 检查一下包袱里有没有这个物品
            let itemInBag = gameHelper.getBagItemNum(itemId);
            if (!itemInBag) {
                // 没这玩意
                console.log('背包没有' + item + ', 无法替换');
                return false;
            }
            item = app.VlaoF.StdItems[itemId];
            let currentItem = app.caJqU.ins().getEquipsByPos(item.type - 1);
            if (currentItem['wItemId'] != itemId) {
                let currentItemName = app.VlaoF.StdItems[currentItem['wItemId']]['name'];
                console.log('将' + currentItemName + '替换为' + item['name']);
                return gameHelper.useItem(itemId, 1);
            } else {
                console.log('当前装备是' + item['name'] + ', 不需要替换');
                return true;
            }
        },

        /**
         * 检测是否是Boss
         */
        checkIsBoss: function(monsterName) {
            let checkNames = ["[神话]", "BOSS", "妖兽"];
            let isBoss = false;
            for (let i in checkNames) {
                if (monsterName.indexOf(checkNames[i]) >= 0) {
                    isBoss = true;
                    break;
                }
            }
            return isBoss;
        },

        /**
         * 获取指定背包中的物品列表
         *
         * @param {int} bagId 背包ID,0:药品,1:装备,2:材料
         * @param {int} showInConsole 是否在控制台输出,0:不输出,1:输出
         */
        getBagItems: function(bagId = 0, showInConsole = 0, onlytop = 0) {
            let items = app.ThgMu.ins().bagItem[bagId];
            let result = {};
            for(let i in items) {
                let itemId = items[i].wItemId;
                let itemName = app.VlaoF.StdItems[itemId]['name'];
                if(!result[itemId]) {
                    result[itemId] = {
                        id: itemId,
                        name: itemName,
                        count: 0,
                        itemlevel: app.VlaoF.StdItems[itemId]['itemlevel']?app.VlaoF.StdItems[itemId]['itemlevel']:0,
                    };
                }
                result[itemId].count += items[i].btCount;
            }
            let checkedItemLevel = [99, 117];
            // 以itemlevel和count从大到小排序
            // result = Object.values(result).sort((a, b) => {
            //     if(a['itemlevel'] == b['itemlevel']) {
            //         return b['count'] - a['count'];
            //     } else {
            //         return b['itemlevel'] - a['itemlevel'];
            //     }
            // })
            // 以 count 从大到小排序,如果 itemlevel 为 117,则在最前面
            result = Object.values(result).sort((a, b) => {
                let acount = a.count;
                let bcount = b.count;
                if(checkedItemLevel.indexOf(a['itemlevel']) >= 0) {
                    acount = acount * 1000000000;
                }
                if(checkedItemLevel.indexOf(b['itemlevel']) >= 0) {
                    bcount = bcount * 1000000000;
                }
                return bcount - acount;
            })
            if(showInConsole) {
                console.log('背包物品:' + (onlytop?'(只显示前'+onlytop+'个)':''));
                for(let i in result) {
                    if(onlytop && i >= onlytop) break;
                    let item = result[i];
                    if(checkedItemLevel.indexOf(item['itemlevel']) >= 0) {
                        gameHelper.redLog(item.name + ':'+ item.count);
                    } else {
                        console.log(item.name + ':'+ item.count);
                    }
                }
            }
            return result;
        },

        /**
         * 获取包裹中指定物品的数量
         *
         * @param {string} item 物品名称
         * @returns
         */
        getBagItemNum: function(item) {
            let itemId = gameHelper.checkAndConvertToItemId(item);
            if(!itemId) return 0;
            return app.ThgMu.ins().getItemCountById(itemId);
        },

        /**
         * 使用魔法
         *
         * @param {int} skillId
         */
        useMagic: function(skillId) {
            var player = app.NWRFmB.ins().getPayer;
            var skill = player.getUserSkill(skillId);
            if (player && skill && !skill.isDisable && egret.getTimer() > skill.dwResumeTick) {
                // 13: 瞬息移动,55:回城,56:盟重回城,57:比奇回城,58:随机
                var a = player.propSet.getAP_JOB();
                app.NGcJ.ins().s_5_2(skill.nSkillId, 0, player.currentX, player.currentY, player.dir, a);
            }
        },

        /**
         *
         * @param {int} key
         * @returns
         */
        appGetValue: function(key) {
            return app.NWRFmB.ins().getPayer.propSet.getValue(key)
        },

        /**
         * 转生等级
         * @returns
         */
        getCircleLv: function() {
            return app.NWRFmB.ins().getPayer.propSet.MzYki()
        },

        /**
         * 角色等级
         * @returns
         */
        getLv: function() {
            return app.NWRFmB.ins().getPayer.propSet.mBjV()
        },

        /**
         * 角色坐标
         * @returns
         */
        currentPosition: function() {
            let player = gameHelper.getPlayer();
            return { x: player.propSet.getX(), y: player.propSet.getY() }
        },

        /**
         * 多倍经验值
         * @returns
         */
        getmultipleExp: function() {
            return app.MathUtils.MakeLong64(gameHelper.appGetValue(app.nRDo.AP_MAX_EXP_L), gameHelper.appGetValue(app.nRDo.AP_MAX_EXP_H))
        },

        /**
         * 自动吃药
         * 药品使用有个冷却时间,这里默认延迟5s
         * @param {number} id - 物品ID
         * @param {number} count - 使用次数
         * @returns {Promise} 返回Promise用于处理完成后的操作
         */
        autoUseItem: function(id, count) {
            return new Promise((resolve) => {
                let usedCount = 0;
                const tmpTimer = setInterval(() => {
                    if (usedCount >= count) {
                        console.log(`自动使用${count}个${id}完成`);
                        clearInterval(tmpTimer);
                        resolve();
                        return;
                    }
                    gameHelper.useItem(id, 1);
                    usedCount++;
                }, 5000);
            });
        },

        /**
         * 使用物品
         * @param {number} id - 物品ID
         * @param {number} count - 使用次数
         * @returns {boolean} 返回是否使用成功
         */
        useItem: function(id, count) {
            let itemId = gameHelper.checkAndConvertToItemId(id);
            if(!itemId) {
                return false;
            }

            void 0 === count && (count = 1);
            //获取人物背包是否有物品
            const item = app.ThgMu.ins().getItemById(itemId);
            if (item) {
                // 使用物品,前提是 item 不等于空,使用数量小于 item 的 btCount,btCount 最大是一组物品的数量,不是背包的所有数量
                return app.pWFTj
                    .ins()
                    .useItem(
                        item.series,
                        itemId,
                        count === 1 || (count > 1 && count < item.btCount)
                            ? count
                            : item.btCount
                    );
            }
            return false;
        },

        /**
         * 添加指定类型的装备到自动回收列表中
         *
         * @param {int} typeId 回收类型
         * @param {int} itemlevel 回收物品等级
         * @param {string} itemName 装备名称
         */
        addToRecyclingList: function(typeId, itemlevel, itemName) {
            let recyCfg = app.VlaoF.RecyclingSettingConfig;
            // 如果没有指定levelId,则在所有装备中检索出装备的配置信息
            if (!itemlevel && itemName) {
                let hasFindItem = false;
                for (let i = 0; i < app.VlaoF.StdItems.length; i++) {
                    let item = app.VlaoF.StdItems[i];
                    if (item.name === itemName) {
                        hasFindItem = true;
                        if(item.hasOwnProperty("itemlevel")) {
                            itemlevel = item.itemlevel;
                            typeId = item.type;
                        }
                        break;
                    }
                }
                if (!hasFindItem) {
                    console.log("没有找到该装备");
                    return false;
                }
            }
            if(!itemlevel) {
                // 该装备不支持一键回收
                console.log("该装备不支持一键回收");
                return false;
            }
            // 查找最大的idx
            let maxIdx = 0;
            for (let i in recyCfg[typeId]) {
                let recyItem = recyCfg[typeId][i];
                if(recyItem.itemlevel == itemlevel) {
                    console.log('要添加的回收项目已经存在');
                    return recyItem;
                }
                if (recyItem.idx > maxIdx) {
                    maxIdx = recyItem.idx;
                }
            }
            maxIdx++;
            let item = {
                idx: maxIdx,
                id: typeId,
                tips: "一键回收" + itemName,
                Titletips: "一键回收" + itemName,
                value: 0,
                name: itemName,
                showQuality: 0,
                optionid: 32,
                itemlevel: itemlevel,
                title: "材料及药品",
                VipLV: 0,
            }
            app.VlaoF.RecyclingSettingConfig[typeId][maxIdx] = item;
            return item;
        },

        /**
         * 获取当前玩家信息
         *
         * @returns {Array}
         */
        getPlayer: function() {
            return app.NWRFmB.ins().getPayer;
        },

        /**
         * 获取商铺所有在售商品
         *
         * @returns {Array}
         */
        getAllShopItem: function(shopId)
        {
            //app.VlaoF.ShopConfig
            // 1为元宝商城,2为行会商城
            if(!shopId) {
                shopId = 1;
            }
            var shop = app.VlaoF.ShopConfig[shopId];
            for(var page in shop) {
                for(var item in shop[page]) {
                    let shopItem = shop[page][item]['shop'];
                    if(shopItem && shopItem.hasOwnProperty("id")) {
                        let itemId = shopItem['id'];
                        app.VlaoF.StdItems[itemId]['shopcfg'] = [page, item];
                    }
                }
            }
        },

        /**
         * 检查物品是否存在,如果不存在则转换为物品ID
         */
        checkAndConvertToItemId: function(item)
        {
            let itemId = 0;
            if(typeof item == 'number') {
                itemId = parseInt(item);
            } else {
                for(var stditem in app.VlaoF.StdItems) {
                    if(app.VlaoF.StdItems[stditem]['name'] == item) {
                        itemId = stditem;
                        break;
                    }
                }
            }
            if(itemId && !app.VlaoF.StdItems.hasOwnProperty(itemId)) {
                console.log('物品:' + item + '不存在');
                itemId = 0;
            }
            return parseInt(itemId);
        },

        /**
         * 购买物品
         */
        buyInShop: function(item, num)
        {
            let itemId = gameHelper.checkAndConvertToItemId(item);
            if(!itemId) return false;
            let itemName = app.VlaoF.StdItems[itemId]['name'];
            console.log('购买物品:' + itemName + ',数量:' + num);
            if(!app.VlaoF.StdItems[itemId]['shopcfg']) {
                gameHelper.getAllShopItem();
            }
            let shopCfg = app.VlaoF.StdItems[itemId]['shopcfg'];
            if(!shopCfg) return false;
            let [page, idx] = shopCfg;
            app.ShopMgr.ins().sendBuyShop(1, page, idx, app.ShopMgr.ins().npcCog, num);
        },

        /**
         * 解析洗炼属性
         *
         * @param {string} attr
         * @returns
         */
        parseRefineAttr: function(attr)
        {
            let currAttrs = {};
            let tmp = attr.split('|');
            for (let i = 0; i < tmp.length; i++) {
                // 将属性ID和属性值分离
                let [attrId, attrValue] = tmp[i].split(',');
                let attrName = '未知' + attrId;
                if(app.CrmPU.language_ATTROBJ.hasOwnProperty(attrId)) {
                    attrName = app.CrmPU.language_ATTROBJ[attrId];
                }
                // 将属性ID和属性值转换为数字类型
                currAttrs[attrId] = {attrName: attrName, attrId: parseInt(attrId), attrValue: parseInt(attrValue)};
            }
            return currAttrs;
        },

        /**
         * 检测洗炼属性
         */
        checkRefineAttr: function(currAttr, newAttr) {
            /**
             * 洗炼结果存放在 app.ForgeMgr.ins().refiningRuslt 中
             * 物品属性为使用|分隔的多组数据,每组数据格式为`a,b`,其中a为属性ID,b为属性值
             */
            // 解析洗炼结果
            let currAttrs = gameHelper.parseRefineAttr(currAttr);
            let newAttrs = gameHelper.parseRefineAttr(newAttr);
            // 要监控的属性ID,名称在 app.CrmPU.language_ATTROBJ 中
            let attrIds = [54, 136];
            console.log('原属性:', currAttrs, '新属性:', newAttrs);
            /**
             * TODO 此时系统并未替换,需要找到手动替换的注释方式,然后检查newAttrs中指定的attrId的值是否大于currAttrs中指定的attrId的值
             */
            try {
                for(let i in attrIds) {
                    let attrId = attrIds[i];
                    let currAttrValue = 0;
                    if(currAttrs.hasOwnProperty(attrId)) {
                        currAttrValue = currAttrs[attrId].attrValue;
                    }
                    if(newAttrs.hasOwnProperty(attrId) && newAttrs[attrId].attrValue >= currAttrValue) {
                        alert('洗炼成功,增加了' + (newAttrs[attrId].attrValue - currAttrValue) + '' + app.CrmPU.language_ATTROBJ[attrId]);
                    }
                }
            } catch(e) {
                console.log(e);
            }
        },

        /**
         * 检查掉落物数量
         *
         * @returns
         */
        checkDropCount: function() {
            const drops = app.NWRFmB.ins().dropList;
            let count = 0;
            for (var i in drops) {
                let item = drops[i];
                if(item.hasOwnProperty("nameTxt") && item.nameTxt['text'].indexOf("金牛") >= 0) {
                    count++;
                }
            }
            return count;
        },

        /**
         * 自动寻路
         *
         * @param {int} x
         * @param {int} y
         */
        pathFind: function(x, y) {
            var player = gameHelper.getPlayer();
            gameHelper.stopEdcwsp();
            player.pathFinding(x, y);
        },

        /**
         * 停止挂机
         */
        stopEdcwsp: function() {
            if (app.qTVCL.ins().isOpen) {
                app.qTVCL.ins().YFOmNj();
            }
        },

        /**
         * 检测并开启自动挂机
         */
        checkEdcwsp: function() {
            if(app.qTVCL.ins().isFinding) {
                stopWatchTimer();
                return false;
            }
            // 在不允许挂机的地图开启挂机功能
            app.GameMap.scenes.isHook = 1;
            if (!app.qTVCL.ins().isOpen) {
                app.qTVCL.ins().edcwsp();
                gameHelper.toast("开始挂机", "0x00ff60");
            }
        },

        /**
         * 检测怪物
         * @returns
         */
        checkMonster: function() {
            // 修复一下疗伤药回收的bug
            if(app.VlaoF.RecyclingSettingConfig[4].hasOwnProperty(401) && app.VlaoF.RecyclingSettingConfig[4][401]['itemlevel']!=401) {
                app.VlaoF.RecyclingSettingConfig[4][401]['itemlevel']=401;
            }
            if(gameHelper.getLv()<999) {
                // 检测一下5倍经验卷是否用完
                if(app.NWRFmB.ins().getPayer.propSet.getExpPower() < 40000) {
                    // 这玩意不用买,直接用
                    gameHelper.useItem("5倍挂机卷(大)", 1);
                }
                // 检测一下多倍经验瓶是否用完
                if (gameHelper.getmultipleExp() < 1000000) {
                    let itemId = gameHelper.checkAndConvertToItemId("多倍经验瓶");
                    if(itemId) {
                        let count = gameHelper.getBagItemNum("多倍经验瓶");
                        if(count<1000) {
                            // 先买100组,每组10个
                            gameHelper.buyInShop("多倍经验瓶", 100);
                        }
                        // 买完后等待2秒后使用
                        setTimeout(() => {
                            if(gameState.isInBlackWhite) {
                                gameHelper.useItem("多倍经验瓶", 200);
                            } else {
                                // 使用合成的方式使用药品,此方案是每次吃100个,需要吃10次
                                for(let i=0; i<10; i++) {
                                    app.ForgeMgr.ins().send_19_1(3402, 1)
                                }
                            }
                        }, 2000);
                    }
                }

            }
            // 检测一下活动
            if(app.OpenServerTreasureView.prototype.canLuckDraw()) {

            }
            let count = 0;
            const player = gameHelper.getPlayer();
            let mapId = app.GameMap.mapID;
            let mapName = app.GameMap.mapName;
            let mapCfg = {};
            if (mapCfgs.hasOwnProperty(mapId)) {
                mapCfg = mapCfgs[mapId];
            }
            let avoidMonsters = [];
            if (
                mapCfg.hasOwnProperty("avoidMonsters") &&
                !document.getElementById("dontCheckMonsters").checked
            ) {
                avoidMonsters = mapCfg["avoidMonsters"];
            }

            let hasBoss = false;
            const all = app.NWRFmB.ins().YUwhM();
            for (const a in all) {
                const monster = all[a];
                let monsterX = monster.propSet.propValueObj[1];
                let monsterY = monster.propSet.propValueObj[2];
                let monsterName = monster._charName;
                // 定义可见 app.ActorRace.Monster,0为玩家,1为怪物,2为NPC,等等
                if (monster.propSet.getRace() == 1) {
                    if (gameHelper.checkIsBoss(monsterName)) {
                        let monsterCfg = app.VlaoF.Monster[monster.propSet.getACTOR_ID()];
                        if (monsterCfg && 1 != monsterCfg.ascriptionopen) {
                            app.VlaoF.Monster[monster.propSet.getACTOR_ID()].ascriptionopen = 1;
                        }
                        hasBoss = true;
                        gameHelper.checkIsNewBoss(monsterX, monsterY, monsterName, mapId);
                    }
                    for (let i in avoidMonsters) {
                        if (monsterName.indexOf(avoidMonsters[i]) >= 0) {
                            let msg = `${mapName}的[${monsterX},${monsterY}]有"${monsterName}",闪人!`;
                            gameHelper.redLog(msg);
                            gameHelper.toast(msg, "0xff0000");
                            gameHelper.fly();
                        }
                    }
                    count++;
                }
            }
            if (
                document.getElementById("onlyFindBoss").checked &&
                !hasBoss && !gameState.nearHasBossMonster
            ) {
                return 0;
            }
            return count;
        },

        /**
         * 是否新boss怪物(名称中有神话,BOSS,妖兽等字样)
         * @param {int} monsterX 怪物的x坐标
         * @param {int} monsterY 怪物的y坐标
         * @param {string} monsterName 怪物名称
         */
        checkIsNewBoss: function(monsterX, monsterY, monsterName, mapId) {
            const radius = 20;
            if (gameState.lastBoss.hasOwnProperty("monsterName")) {
                // 检查名称是否重复
                if (gameState.lastBoss.monsterName == monsterName) {
                    // 检查坐标是否有重叠
                    let xDec = Math.abs(monsterX - gameState.lastBoss.monsterX);
                    let yDec = Math.abs(monsterY - gameState.lastBoss.monsterY);
                    if (xDec < radius && yDec < radius) {
                        return false;
                    }
                }
            }
            // 更新lastBoss信息
            gameState.lastBoss = {
                monsterName: monsterName,
                monsterX: monsterX,
                monsterY: monsterY,
            };
            let xy = "地图:" + mapId;
            let mapCfg = {};
            if (mapCfgs.hasOwnProperty(mapId)) {
                mapCfg = mapCfgs[mapId];
                xy = mapCfg["name"];
            }
            xy += "(" + monsterX + "," + monsterY + ")发现" + monsterName;
            // 输出当前时间
            if(mapCfg.hasOwnProperty('notRecordBossInfo') && mapCfg['notRecordBossInfo']) {
                return true;
            }
            gameHelper.redLog("时间:" + new Date().toLocaleString() + "," + xy);
            let bossRecord = localStorage.getItem("boss");
            if (bossRecord) {
                bossRecord = JSON.parse(bossRecord);
            } else {
                bossRecord = {};
            }
            let record = [ monsterName,monsterX, monsterY, new Date().toLocaleString()];
            let tmp = new Array();
            if (bossRecord.hasOwnProperty(mapId)) {
                tmp = bossRecord[mapId];
            }
            if (tmp.length >= 24) {
                tmp.pop();
            }
            tmp.unshift(record);
            bossRecord[mapId] = tmp;
            localStorage.setItem("boss", JSON.stringify(bossRecord));

            return true;
        },

        /**
         * 自动飞
         * @param {*} player
         */
        autoFly: function(player) {
            if (gameHelper.checkMonster() > 0) return false;
            const count = player.propSet.getFlyshoes();
            if (count<10) gameHelper.useItem(307, 99);
            // 飞之前再检查一次周围的怪物
            if (gameHelper.checkMonster() < 1 && gameHelper.checkDropCount() < 1 && count > 0) {
                // gameHelper.toast(`周围没有怪了,开始飞,飞鞋点数剩余:${count - 1}`);
                gameHelper.fly();
            } else {
                // 买点吧
                gameHelper.buyInShop('飞鞋', 99);
                gameHelper.toast(`飞鞋点数不足,请补充飞鞋点数`, "0xff0000");
            }
        },

        /**
         * 检查用户坐标是否在指定位置
         *
         * @param {int} x
         * @param {int} y
         * @param {int} scope
         * @returns boolean
         */
        checkUserPosition: function(x, y, scope) {
            let player = gameHelper.getPlayer();
            // 目标点可能有人或者有怪,所以只能指定一个可能的范围,只要到达这个范围即算是成功到达
            let startX = x - scope;
            let endX = x + scope;
            let startY = y - scope;
            let endY = y + scope;
            if (
                player.lastX >= startX &&
                player.lastX <= endX &&
                player.lastY >= startY &&
                player.lastY <= endY
            ) {
                // 在坐标范围
                return true;
            }
            console.log(
                "用户当前坐标(" +
                player.lastX +
                "," +
                player.lastY +
                ")不在指定位置(" +
                x +
                "," +
                y +
                ")"
            );
            if (!app.qTVCL.ins().isFinding) {
                // 开启寻路
                gameHelper.pathFind(x, y);
            } else {
                if (app.qTVCL.ins().isOpen) {
                    // 可能在寻路的过程中用户强制开始挂机,这时就不需要再寻路了
                    return true;
                }
                gameHelper.toast("正在前往挂机点(" + x + "," + y + ")");
            }
            return false;
        },

        /**
         * 检查是否需要飞行
         *
         * @param {array} rectangle
         * @returns boolean
         */
        checkNeedFly: function(rectangle) {
            let player = gameHelper.getPlayer();
            // 当前地图ID
            let currentMapId = app.GameMap.mapID;
            let currentMapName = app.GameMap.mapName;
            if(!mapCfgs.hasOwnProperty(currentMapId)) {
                // 为什么会有这种情况?
                rectangle = false;
            }

            // 处理自动挂机相关逻辑
            if (gameHelper.handleAutoplay()) {
                return;
            }

            // 如果开启了寻找BOSS,就不检查危险区域
            if(!document.getElementById("onlyFindBoss").checked && rectangle && rectangle.isInside(player.lastX, player.lastY)) {
                gameHelper.toast(
                    `人[${player.lastX},${player.lastY}],在[${currentMapName}]危险区域,开飞`,
                    "0xff0000"
                );
                gameHelper.fly();
                return;
            }

            // 检查是否需要飞行
            if (
                gameHelper.checkMonster() < 1 &&
                gameHelper.checkDropCount() < 1 &&
                !(currentMapId == gameState.autoPlayMapId && gameState.autoPlayStatus)
            ) {
                gameHelper.autoFly(player);
            }
        },

        /**
         * 处理自动挂机相关逻辑
         *
         * @param {string} playerName - 玩家名
         * @param {number} currentMapId - 当前地图ID
         * @returns {boolean} - 是否处理了自动挂机逻辑
         */
        handleAutoplay: function() {
            // 处理自动挂机相关逻辑
            const apConfig = new AutoPlayHelper(gameState.autoPlayMapId);
            apConfig.readInputFieldsAndSaveConfig();

            // 处理进入挂机地图逻辑
            if (apConfig.shouldEnterAutoPlayMap()) {
                apConfig.enterAutoPlayMap();
                return true;
            }

            // 处理离开挂机地图逻辑
            if (apConfig.shouldLeaveAutoPlayMap()) {
                apConfig.leaveAutoPlayMap();
                return true;
            }

            return false;
        },

        /**
         * 检查是否在指定地图
         *
         * @param {int} id
         * @returns boolean
         */
        inMap: function(id) {
            if (id < 1) return true;
            return app.GameMap.mapID == id;
        },

        fly: function() {
            gameState.lastBoss = {};
            let mapCfg = {};
            let selectMapId = document.getElementById("map-select").value;
            if (mapCfgs.hasOwnProperty(selectMapId)) {
                mapCfg = mapCfgs[selectMapId];
            }
            if (gameHelper.inMap(selectMapId)) {
                if (mapCfg.hasOwnProperty("notFly")) {
                    return false;
                }
            }
            gameHelper.useMagic(58);
            gameState.flyCount++;
        },

        fire: function() {
            // 14:火墙,12:雷电
            app.EhSWiR.m_clickSkillId = 14;
        },

        flyToNewMap: function(user, mapCfg) {
            // 换地图了,清除lastBoss信息
            gameState.lastBoss = {};
            gameState.flyCount = 0;

            if (mapCfg.hasOwnProperty("flyId")) {
                app.PKRX.ins().send_1_7(user, mapCfg["flyId"]);
            } else if (mapCfg.hasOwnProperty("flyBossId")) {
                let mapId = mapCfg["flyBossId"];
                app.UyfaJ.ins().send_49_2(mapId[0], mapId[1]);
            }
        },

        toast: function(message, color = "0xff7700") {
            console.log(message);
            app.uMEZy.ins().IrCm(`|C:${color}&T:${message}|`);
        },

        redLog: function(message) {
            console.log(`%c${message}`, "color: red");
        },
    }
    window.gameHelper = gameHelper;

    // 定义一个矩形类
    class Rectangle {
        constructor(vertices) {
            __publicField(this, "vertices");
            this.vertices = vertices;
        }

        crossProduct(x, y, z) {
            return (
                (z[1] - y[1]) * (y[0] - x[0]) - (z[0] - y[0]) * (y[1] - x[1])
            );
        }

        isOnSameSide(p1, p2, a, b) {
            const cp1 = this.crossProduct(a, b, p1);
            const cp2 = this.crossProduct(a, b, p2);
            return cp1 * cp2 >= 0;
        }

        isInside(x, y) {
            const [A, B, C, D] = this.vertices;
            const p = [x, y];
            return (
                this.isOnSameSide(p, A, B, C) &&
                this.isOnSameSide(p, B, C, D) &&
                this.isOnSameSide(p, C, D, A) &&
                this.isOnSameSide(p, D, A, B)
            );
        }
    }

    /**
     * 配置管理助手类
     */
    class ConfigHelper {
        /**
         * @param {string} configKey - 配置键名
         * @param {object} defaultConfig - 默认配置
         */
        constructor(configKey, defaultConfig = {}) {
            this.player = gameHelper.getPlayer()._charName;
            this.configKey = configKey;
            this.defaultConfig = defaultConfig;
            this.fullConfig = this.loadFullConfig();
        }

        /**
         * 加载完整配置
         * @private
         * @returns {object} 完整配置对象
         */
        loadFullConfig() {
            let fullConfig = localStorage.getItem(this.player);
            if (fullConfig) {
                try {
                    fullConfig = JSON.parse(fullConfig);
                } catch (e) {
                    console.error('配置解析错误:', e);
                    fullConfig = {};
                }

                if (typeof fullConfig !== "object") {
                    fullConfig = {};
                }
            } else {
                fullConfig = {};
            }

            if (!fullConfig.hasOwnProperty(this.configKey)) {
                fullConfig[this.configKey] = this.defaultConfig;
            }

            return fullConfig;
        }

        /**
         * 保存完整配置
         * @private
         */
        saveFullConfig() {
            localStorage.setItem(this.player, JSON.stringify(this.fullConfig));
        }

        /**
         * 加载配置
         * @public
         * @returns {object} 配置对象
         */
        load() {
            let config = this.fullConfig[this.configKey];
            return this.ensureConfigComplete(config);
        }

        /**
         * 保存配置
         * @public
         * @param {object} config - 要保存的配置
         */
        save(config) {
            this.fullConfig[this.configKey] = config;
            this.saveFullConfig();
        }

        /**
         * 确保配置完整性
         * @private
         * @param {object} config - 当前配置
         * @returns {object} 完整的配置
         */
        ensureConfigComplete(config) {
            for (const key in this.defaultConfig) {
                if (!config.hasOwnProperty(key)) {
                    config[key] = this.defaultConfig[key];
                }
            }
            return config;
        }

        /**
         * 更新配置中的特定字段
         * @param {string} key - 配置键
         * @param {any} value - 配置值
         */
        updateField(key, value) {
            let config = this.load();
            config[key] = value;
            this.save(config);
        }

        /**
         * 获取配置中的特定字段
         * @param {string} key - 配置键
         * @returns {any} 配置值
         */
        getField(key) {
            let config = this.load();
            return config[key];
        }
    }

    // 自动挂机配置管理类
    class AutoPlayHelper {
        constructor(mapId, player) {
            this.mapId = mapId;
            this.mapCfg = {};
            if (mapCfgs.hasOwnProperty(this.mapId)) {
                this.mapCfg = mapCfgs[this.mapId];
            }

            // 使用 ConfigHelper 来管理配置
            this.configHelper = new ConfigHelper('autoplay', {
                [this.mapId]: this.getDefaultConfig()
            });

            this.config = this.loadConfig();
        }

        loadConfig() {
            let config = this.configHelper.load();
            if (!config[this.mapId]) {
                config[this.mapId] = this.getDefaultConfig();
            }

            this.updateInputFields(config[this.mapId]);
            return config;
        }

        saveConfig() {
            this.configHelper.save(this.config);
        }

        /**
         * 获取默认配置
         *
         * @returns
         */
        getDefaultConfig() {
            // 从地图配置中获取默认位置
            let defaultPosition = [0, 0];
            if (
                this.mapCfg.hasOwnProperty("autoPlayInitPosition") &&
                this.mapCfg.autoPlayInitPosition
            ) {
                const {
                    x,
                    y,
                    random = 0,
                } = this.mapCfg.autoPlayInitPosition;
                const rand = random
                    ? Math.floor(Math.random() * random)
                    : 0;
                defaultPosition = [x + rand, y - rand];
            }

            return {
                position: defaultPosition,
                enterTime: "<0",
                autoPlay: false,
                scope: this.mapCfg.autoPlayArea?.scope || 3,
            };
        }

        /**
         * 更新输入框的值
         *
         * @param {object} config
         * @returns
         */
        updateInputFields(config) {
            if(!gameState.isFirstRun) {
                return;
            }
            gameState.isFirstRun = false;
            // 更新输入框的值
            const positionInput = document.getElementById("position");
            const enterTimeInput = document.getElementById("enterTime");
            const autoPlayCheckbox = document.getElementById("autoplayenabled");
            positionInput.value = config.position.join(",");
            enterTimeInput.value = config.enterTime;
            if(config.autoPlay) {
                autoPlayCheckbox.checked = config.autoPlay;
            }
        }

        /**
         * 保存配置
         *
         * @returns
         */
        readInputFieldsAndSaveConfig() {
            let position = document.getElementById("position").value;
            if (position) {
                // 从输入框中获取坐标
                let [x, y] = position.split(",").map((v) => parseInt(v));
                this.config[this.mapId].position = [x, y];
                mapCfgs[this.mapId]["autoPlayArea"] = {x: x, y: y, scope: 3};
            }
            let enterTime = document.getElementById("enterTime").value;
            if (enterTime) {
                // 从输入框中获取时间
                this.config[this.mapId].enterTime = enterTime;
            }
            let autoPlay = document.getElementById("autoplayenabled").checked;
            // 从输入框中获取自动挂机
            this.config[this.mapId].autoPlay = autoPlay;
            this.saveConfig();
        }

        /**
         * 检查当前时间是否在指定范围内
         * @param {string} timeId - 时间输入框的ID
         * @returns {boolean} - 是否在指定时间范围内
         */
        checkTimeScope(timeId, minute = -1) {
            // 获取当前的分钟
            if (minute < 0) minute = new Date().getMinutes();
            let time = document.getElementById(timeId).value;
            localStorage.setItem(timeId, time);
            // 如果没有输入,直接返回true
            if (!time) return true;

            try {
                // 替换表达式中的比较符号,使其成为有效的JavaScript表达式
                let expression = time
                    .replace(/([<>]=?)\s*(\d+)/g, "minute $1 $2") // 处理 >30, <50 这样的表达式
                    .replace(/(\d+)\s*([<>]=?)/g, "$1 $2 minute") // 处理反向的表达式
                    .replace(/&&/g, "&&") // 保持 && 运算符
                    .replace(/\|\|/g, "||"); // 保持 || 运算符

                // 使用eval执行表达式(在这种特定场景下使用eval是安全的,因为输入已经被严格处理)
                return eval(expression);
            } catch (e) {
                console.error("时间表达式格式错误:", time);
                return false;
            }
        }

        /**
         * 是否可以进入挂机地图
         *
         * @returns
         */
        shouldEnterAutoPlayMap() {
            return (
                document.getElementById("autoplayenabled").checked &&
                this.checkTimeScope("enterTime") &&
                app.GameMap.mapID != this.mapId
            );
        }

        /**
         * 进入挂机地图
         */
        enterAutoPlayMap() {
            gameHelper.replaceEquip('金牛手镯[炎]');
            gameHelper.autoUseItem(1006, 5);
            gameHelper.autoUseItem(1007, 5);
            gameState.lastMapId = app.GameMap.mapID;
            document.getElementById("map-select").value = this.mapId;
        }

        /**
         * 是否可以离开挂机地图
         * @returns
         */
        shouldLeaveAutoPlayMap() {
            return (
                app.GameMap.mapID == this.mapId &&
                document.getElementById("autoplayenabled").checked &&
                gameHelper.checkMonster() < 1 &&
                gameHelper.checkDropCount() < 1 &&
                !this.checkTimeScope("enterTime")
            );
        }

        /**
         * 离开挂机地图
         */
        leaveAutoPlayMap() {
            gameHelper.replaceEquip('大地之春');
            if (!mapCfgs.hasOwnProperty(gameState.lastMapId)) {
                gameState.lastMapId = 148;
            }
            gameHelper.toast("搞定,回" + mapCfgs[gameState.lastMapId]["name"]);
            document.getElementById("map-select").value = gameState.lastMapId;
        }
    }

    // 定义一个公共字段的函数
    var __defProp = Object.defineProperty;
    var __defNormalProp = (obj, key, value) =>
        key in obj
            ? __defProp(obj, key, {
                enumerable: true,
                configurable: true,
                writable: true,
                value,
            })
            : (obj[key] = value);
    var __publicField = (obj, key, value) =>
        __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);

    class Icons {}

    __publicField(
        Icons,
        "startIcon",
        '<svg class="icon" style="width: 1em;height: 1em;vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024"  xmlns="http://www.w3.org/2000/svg"><path d="M823.8 603.5l-501.2 336c-50.7 34-119.3 20.4-153.2-30.2-12.2-18.2-18.7-39.6-18.7-61.5v-672c0-61 49.5-110.4 110.4-110.4 21.9 0 43.3 6.5 61.5 18.7l501.1 336c50.7 34 64.2 102.6 30.2 153.2-7.8 11.9-18.1 22.2-30.1 30.2z m0 0"></path></svg>'
    );
    __publicField(
        Icons,
        "stopIcon",
        '<svg class="icon" style="width: 1em;height: 1em;vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M941.967463 109.714286v804.571428q0 14.857143-10.857143 25.714286t-25.714286 10.857143H100.824606q-14.857143 0-25.714286-10.857143t-10.857143-25.714286V109.714286q0-14.857143 10.857143-25.714286t25.714286-10.857143h804.571428q14.857143 0 25.714286 10.857143t10.857143 25.714286z"></path></svg>'
    );

    function createControlPanel(clicked) {
        const controlPanel = document.createElement("div");
        controlPanel.id = "control-panel";
        controlPanel.className = "control-panel";
        const mapOptions = Object.entries(mapCfgs)
            .map(([key, cfg]) => `<option value="${key}">${cfg.name}</option>`)
            .join("");
        controlPanel.innerHTML = `
        <div style="background: rgba(0,0,0, .5);color: #fff;" id="autoplaydiv">
      <div>不避怪<input id="dontCheckMonsters" type="checkbox" title="不避怪" value="1"><label for="dontCheckMonsters" class="icon-label"></label></div>
      <div>尽量找Boss<input id="onlyFindBoss" type="checkbox" title="只找Boss" value="1"><label for="onlyFindBoss" class="icon-label"></label></div>
      <div>坐标:<input type="text" class="text" id="position" title="自动挂机的坐标点" placeholder="41,30" style="width: 80px;background: #000;color:#fff;" value=""></div>
      <div>进入:<input type="text" class="text" id="enterTime" title="进入时间" placeholder="00 00" style="width: 80px;background: #000;color:#fff;" value=""></div>
      </div>
      <div class="control-group" id="autoplaycp">
      <button id="toggle" class="button" title="点击开始自动释放火墙">${Icons.startIcon}</button>
      <select id="map-select" class="select" title="选择地图">${mapOptions}</select>
      <div><input type="checkbox" id="autoplayenabled" title="自动挂机" value="1"><label for="autoplayenabled" class="icon-label"></label></div>
      <button id="random" class="button">${Icons.startIcon}</button>
  </div>`;
        // 添加复选框状态变化事件处理
        const checkboxes = controlPanel.querySelectorAll('input[type="checkbox"]');
        checkboxes.forEach(checkbox => {
            const label = checkbox.nextElementSibling;
            label.style.backgroundColor = checkbox.checked? buttonColor : buttonColor2;
            label.innerHTML = checkbox.checked? Icons.stopIcon : Icons.startIcon;
            checkbox.addEventListener('change', function() {
                label.style.backgroundColor = this.checked? buttonColor : buttonColor2;
                label.innerHTML = this.checked ? Icons.stopIcon : Icons.startIcon;
                let player = gameHelper.getPlayer();
                if(player && player.hasOwnProperty("_charName")) {
                    const apConfig = new AutoPlayHelper(gameState.autoPlayMapId);
                    apConfig.readInputFieldsAndSaveConfig();
                }
            });
        });
        const btns = Array.from(controlPanel.querySelectorAll("button"));
        for (const btn of btns) {
            btn.addEventListener("click", () => {
                clicked(btn);
            });
        }
        return controlPanel;
    }

    /**
     * 切换按钮状态
     *
     * @param {object} btn
     * @param {string} color
     * @param {string} icon
     * @returns
     */
    function toggleBtnStatus(btn, color, icon) {
        btn.style.backgroundColor = color;
        btn.innerHTML = icon;
    }

    /**
     * 停止挂机
     */
    function stopWatchTimer() {
        let btn = document.getElementById("random");
        if (gameState.watchTimer) {
            clearInterval(gameState.watchTimer);
        }
        gameState.watchTimer = void 0;
        toggleBtnStatus(btn, buttonColor2, Icons.startIcon);
        gameHelper.stopEdcwsp();
    }

    /**
     * 开始挂机
     *
     * @param {object} mapCfg
     * @returns
     */
    function startWatchTimer(mapCfg, btn) {
        // 自动回收这个只需要执行一次
        if (gameState.isInBlackWhite) {
            gameHelper.addToRecyclingList(1,114,'王者套装')
            gameHelper.addToRecyclingList(1,118,'天龙套装')
        }
        gameHelper.addToRecyclingList(4,82,'炼狱材料')
        if(app.qTVCL.ins().isFinding) {
            gameHelper.toast("正在寻路中,不允许开启自动挂机!");
            stopWatchTimer();
            return false;
        }
        if (!mapCfg || mapCfg.length < 1) {
            gameHelper.toast("暂不支持指定地图挂机");
            return false;
        }
        gameHelper.toast("4秒后开始挂机,请不要有任何操作");
        const player = gameHelper.getPlayer();
        gameState.watchTimer = setInterval(() => {
            gameHelper.updateDocumentTitle();
            let currentMapId = app.GameMap.mapID;
            let mapCfg = {};
            let selectMapId = document.getElementById("map-select").value;
            if (mapCfgs.hasOwnProperty(selectMapId)) {
                mapCfg = mapCfgs[selectMapId];
            } else {
                return false;
            }
            if(app.qTVCL.ins().isFinding) {
                gameHelper.toast("正在寻路中,不允许开启自动挂机!");
                return false;
            }
            if (gameHelper.inMap(selectMapId)) {
                if (mapCfg.hasOwnProperty("dontautoplay")) {
                    gameHelper.toast("该地图不允许自动挂机");
                    return false;
                }
                if (
                    mapCfg.hasOwnProperty("autoPlayArea") &&
                    !gameState.isFindedPath
                ) {
                    const tt = setInterval(() => {
                        if (
                            gameHelper.checkUserPosition(
                                mapCfg.autoPlayArea.x,
                                mapCfg.autoPlayArea.y,
                                mapCfg.autoPlayArea.scope
                            )
                        ) {
                            gameState.isFindedPath = true;
                            clearInterval(tt);
                        }
                    }, 1e3);
                }
                gameHelper.checkEdcwsp();
                let rectangle = false;
                if (mapCfg.hasOwnProperty("dangerArea")) {
                    rectangle = new Rectangle(mapCfg["dangerArea"]);
                }
                gameHelper.checkNeedFly(rectangle);
            } else {
                gameState.isFindedPath = false;
                gameHelper.toast("不在`" + mapCfg.name + "`,开始传送");
                gameHelper.flyToNewMap(player.recog, mapCfg);
                if (mapCfg.hasOwnProperty("dontautoplay")) {
                    stopWatchTimer();
                    return false;
                }
                const tt = setInterval(() => {
                    if (gameHelper.inMap(selectMapId)) {
                        gameHelper.checkEdcwsp();
                        clearInterval(tt);
                    }
                }, 2e3);
            }
        }, 4e3);
        toggleBtnStatus(btn, buttonColor, Icons.stopIcon);
    }

    window.addEventListener("load", () => {

        /**
         * 对原app功能进行hook
         */
        function hackApp() {
            alert("开始注入对app的功能修改");

            // 盒子批量兑换功能
            app.CommonGiftSelectWin.prototype.onClick = function (e) {
                switch (e.currentTarget) {
                    case this.rect:
                        app.mAYZL.ins().close(this);
                        break;
                    case this.receiveBtn:
                        console.log(this.userItemInfo.series);
                        console.log(this.curItemData.index);
                        if (!this.curItemData) return void app.uMEZy.ins().IrCm(app.CrmPU.language_Tips73);
                        if (!this.userItemInfo || !this.userItemInfo.series) {
                            return void app.uMEZy.ins().IrCm(app.CrmPU.language_Tips73);
                        }
                        // 背包最低空闲数量
                        var i = app.VlaoF.BagRemainConfig[10];
                        if (i) {
                            let usedCount = 0;
                            let count = 10;
                            // 如果当前页面有batch_count输入框,且输入的数量大于0,则使用输入的数量
                            const batchCountInput = document.getElementById("batch_count");
                            if (batchCountInput && batchCountInput.value > 0) {
                                count = parseInt(batchCountInput.value);
                            }
                            // 每隔50毫秒执行一次兑换操作
                            let tmpTimer = setInterval(() => {
                                if (usedCount >= count) {
                                    clearInterval(tmpTimer);
                                    return;
                                }
                                usedCount++;
                                // 检查背包是否已满
                                var n = app.ThgMu.ins().getBagCapacity(i.bagremain);
                                // 背包未满,则执行兑换操作;背包已满,则弹出提示并停止兑换。
                                if (n) {
                                    app.ThgMu.ins().send_8_8(this.userItemInfo.series, !0, this.curItemData.index);
                                } else {
                                    app.uMEZy.ins().IrCm(i.bagtips);
                                    clearInterval(tmpTimer);
                                    return;
                                }
                            }, 50);
                        }
                }
            }

            /**
             * 修复藏经阁的抽奖次数是当前最大可抽奖次数
             *
             * @param {object} t
             * @returns
             */
            app.OpenServerTreasureView.prototype.onClick = function (t) {
                switch (t.currentTarget) {
                    case this.receiveBtn:
                        this.onLuckDraw();
                        break;
                    case this.receiveBtn2:
                        var maxTimes = this.curDayMoney.Maxcount - this.chouNumber;
                        this.onLuckDraws(maxTimes);
                }
            };

            app.ForgeRefiningView.prototype.updatexxxxx = function(){
                var e = app.ForgeMgr.ins().refiningRuslt;
                console.log('update: 原属性:' + e.currAttr + ',新属性:' + e.newAttr);
                if (0 == e.errcode) {
                  (this.lbFail.visible = !1), this.refiningBind(e.currAttr);
                  var i = this.tabEq.selectedItem.item,
                    n = app.VlaoF.RefiningmaterialsConfig[i.wItemId],
                    s = this.refiningmaterialsGetData(n.consume);
                  this.costGoods.replaceAll(s),
                    e.replace
                      ? ((this.lbReplaceState.visible = !0), (this.btnReplace.visible = !1), this.refiningNewAttrBind(e.currAttr, e.currAttr))
                      : e.newAttr
                      ? ((i.refining = e.newAttr),
                        (this.lbFail.visible = !1),
                        (this.lbReplaceState.visible = !1),
                        (this.btnReplace.visible = !0),
                        this.refiningNewAttrBind(e.currAttr, e.newAttr),
                        app.uMEZy.ins().IrCm(app.CrmPU.language_Refining_Text6))
                      : ((this.lbFail.visible = !0), (this.lbReplaceState.visible = !1), (this.btnReplace.visible = !1), this.newAttrArr.removeAll(), app.uMEZy.ins().IrCm(app.CrmPU.language_Refining_Text5));
                }

            }

            /**
             * 圣物洗炼结果监控
             *
             * @param {object} e
             * @returns
             */
            app.SoldierSoulMgr.prototype.post_58_3 = function (e) {
                var i = e.readByte(),
                  n = (e.readByte(), e.readByte()),
                  replace = e.readByte(),
                  currAttr = e.readString(),
                  newAttr = e.readString();
                if (9 == i) {
                  var o = app.VlaoF.soulWpRefiningConfig[n];
                  o && o.limitMsg && app.uMEZy.ins().IrCm("|C:0xff7700&T:" + o.limitMsg + "|");
                }
                if(replace == 0) {
                    gameHelper.checkRefineAttr(currAttr, newAttr);
                }
                return {
                  errcode: i,
                  weaponID: n,
                  currAttr: currAttr,
                  newAttr: newAttr,
                  replace: replace,
                };
              }

            /**
             * 对装备洗炼结果的监控处理
             *
             * @param {object} t
             * @returns
             */
            app.ForgeMgr.prototype.post_19_4 = function (t) {
                var errcode = t.readByte(),
                    goodId = t.readNumber(),
                    replace = t.readByte(),
                    currAttr = t.readString(),
                    newAttr = t.readString();

                if(replace == 0) {
                    gameHelper.checkRefineAttr(currAttr, newAttr);
                }
                this.refiningRuslt = {
                    // 错误码,0 成功,1 失败
                    errcode: errcode,
                    // 物品ID
                    goodId: goodId,
                    // 物品原属性
                    currAttr: currAttr,
                    // 物品新属性
                    newAttr: newAttr,
                    // 是否替换
                    replace: replace,
                };
            }

            /**
             * 移除一些不需要的控制台输出
             *
             * @param {object} t
             * @returns
             */
            app.MainBottomNotice.prototype.Addnotice=function (t) {
                var e = t[1],
                  i = t[0];
                // console.log(e + " - " + i);
                1 == e
                  ? (this.noticeAry1.push(i), this.payNotice1())
                  : 2 == e
                  ? (this.noticeAry2.push(i), this.payNotice2())
                  : -1 == i.indexOf("银两") && (this.noticeAry.push(i), this.isShowNotice || this.payNotice());
            }

            /**
             * 修复拾取宠物的范围
             *
             * @returns
             */
            app.PlayerRole.prototype.pickUpPetRange = function () {
                var a = app.NWRFmB.ins().getPayer.propSet.getPickUpPet();
                var i = app.VlaoF.lootPetConfig;
                for (var n in i) for (var s in i[n]) if (+s == a) return (i[n][s].nDropPetLootDistance);
                return 0;
            };

            /**
             * 注入对周围怪物的检测
             *
             * @returns
             */
            app.qTVCL.ins().getNearestMonster_magicBOSS = function () {
                let checkNames = ["[神话]", "BOSS", "妖兽"];
                var e,
                    monster,
                    monsterName,
                    n,
                    s = app.NWRFmB.ins().YUwhM(),
                    a = app.NWRFmB.ins().getPayer,
                    r = Number.MAX_VALUE;
                gameState.nearHasBossMonster = false;
                for (var o in s) {
                    e = s[o];
                    monster = app.VlaoF.Monster[e.propSet.getACTOR_ID()];
                    if (!monster) continue;
                    monsterName = monster.name;
                    if (1 != monster.ascriptionopen) {
                        for (let i in checkNames) {
                            if (monsterName.indexOf(checkNames[i]) >= 0) {
                                app.VlaoF.Monster[e.propSet.getACTOR_ID()].ascriptionopen = 1;
                                monster.ascriptionopen = 1;
                                break;
                            }
                        }
                    }
                    var l = this.isRange(a.currentX, a.currentY, e.currentX, e.currentY);
                    if (l && e.propSet.getRace() == app.ActorRace.Monster && 1 == monster.ascriptionopen) {
                        let str = "  时间:" + new Date().toLocaleString() + "," + e.currentX + "," + e.currentY + "," + monsterName;
                        gameHelper.redLog(str);
                        gameState.nearHasBossMonster = true;
                        var h = app.MathUtils.getDistanceByObject(a, e);
                        r > h && ((r = h), (n = o));
                    }
                }
                return n;
            };
            // 注册(不可用)一个定时器,每秒执行一次 app.qTVCL.ins().getNearestMonster_magicBOSS
            gameState.watchTimer = setInterval(() => {
                app.qTVCL.ins().getNearestMonster_magicBOSS();
            }, 1000);
            egret.log=function(){return false;}
            /**
             * 服务器连接后的操作
             */
            app.ubnV.ins().KLsbd = function () {
                var i = new app.xAFLf();
                this.socket_.readBytes(i),
                    (i.position = 0),
                    (this._salt = i.readUnsignedShort()),
                    this.updateStatus(3);

                // 上面的代码不要动!!!!
                if (gameState.isFirstConnected) {
                    // 网页首次打开时连接上服务器后,执行下面的代码
                    gameState.isFirstConnected = false;
                } else {
                    // 计算进出挂机地图的时间范围,最多呆10分钟
                    let minute = new Date().getMinutes();
                    // 如果当前分钟小于2分钟或者大于50,则设置去处符为`||`否则设为`&&
                    let logicType = "&&";
                    if (minute < 1 || minute > 49) {
                        logicType = "||";
                    }
                    let minMinute = minute - 2;
                    if (minMinute < 0) minMinute += 60;
                    let maxMinute = minute + 10;
                    if (maxMinute >= 60) maxMinute -= 60;
                    let timeStr = `>${minMinute} ${logicType} <${maxMinute}`;
                    // document.getElementById("enterTime").value = timeStr;
                    let lastReboot = localStorage.getItem("lastReboot");
                    if (!lastReboot) {
                        lastReboot = [];
                    } else {
                        try {
                            lastReboot = JSON.parse(lastReboot);
                        } catch (error) {
                            lastReboot = [];
                        }
                    }
                    if (lastReboot.length > 10) {
                        lastReboot.shift();
                    }
                    lastReboot.push(new Date().toLocaleString());
                    localStorage.setItem("lastReboot", JSON.stringify(lastReboot));
                    console.log(
                        new Date().toLocaleString() +
                        "又TMD被人搞崩,还好又连上了"
                    );
                }
            };
        };
        const waitForAppLoaed = setInterval(() => {
            if (typeof egret !== "undefined" &&
                typeof app !== "undefined" &&
                app.hasOwnProperty("MainBottomNotice") &&
                app.hasOwnProperty("ubnV") &&
                app.hasOwnProperty("qTVCL") &&
                app.hasOwnProperty("PlayerRole") &&
                app.hasOwnProperty("MainBottomNotice") &&
                app.hasOwnProperty("VlaoF")
            ) {
                clearInterval(waitForAppLoaed);
                // 10秒后执行
                setTimeout(() => {
                    hackApp();
                }, 10000);
            }
        }, 100);

        const panel = createControlPanel((btn) => {
            const id = btn.getAttribute("id");
            let mapCfg = {};
            let selectMapId = document.getElementById("map-select").value;
            if (mapCfgs.hasOwnProperty(selectMapId)) {
                mapCfg = mapCfgs[selectMapId];
            }
            let player = gameHelper.getPlayer();
            if (!player || !player.hasOwnProperty("_charName")) {
                alert("请先进入游戏");
                return false;
            }
            gameHelper.updateDocumentTitle();
            switch (id) {
                case "toggle":
                    if (gameState.fireTimer) {
                        clearInterval(gameState.fireTimer);
                        gameState.fireTimer = void 0;
                        toggleBtnStatus(btn, buttonColor2, Icons.startIcon);
                    } else {
                        gameHelper.fire();
                        gameState.fireTimer = setInterval(() => {
                            gameHelper.fire();
                        }, 9e3);
                        toggleBtnStatus(btn, buttonColor, Icons.stopIcon);
                    }
                    break;
                case "random":
                    if (gameState.watchTimer) {
                        stopWatchTimer();
                    } else {
                        startWatchTimer(mapCfg, btn);
                    }
                    break;
            }
        });
        document.body.appendChild(panel);
        document.getElementById("autoplaycp").onmouseover = function() {if (!gameState.watchTimer) return false;let autoplayObj = document.getElementById("autoplaydiv");autoplayObj.style.display = "block";};
        setInterval(() => {
            document.getElementById("mainDiv").onmouseover = function() {let autoplayObj = document.getElementById("autoplaydiv");autoplayObj.style.display = "none";};
        }, 9e3);
    });
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址