Greasy Fork is available in English.

Chr_'s_Inventory_Helper

Steam库存批量出售

Instalează acest script?
Script sugerat de autor

Poate îți va plăcea șiAuto_Award_Profile.

Instalează acest script
// ==UserScript==
// @name         Chr_'s_Inventory_Helper
// @namespace    https://blog.chrxw.com
// @version      2.2
// @description  Steam库存批量出售
// @author       Chr_
// @include      /https://steamcommunity\.com/(id|profiles)/[^\/]+/inventory/?/
// @connect      steamcommunity.com
// @license      AGPL-3.0
// @icon         https://blog.chrxw.com/favicon.ico
// @grant        GM_setValue
// @grant        GM_getValue
// ==/UserScript==

let Vver = '2.2'; // 版本号
// 上面的开关
let VAutoR = false;// 定时刷新开关
let VTime = 30; // 定时刷新间隔
let VFailR = false;// 出错刷新开关
let VPanel = false;// 面板开关
// 面板的设置
let VName = '';// 物品名称
let VNMode = 'mc';// 匹配模式
let VPrice = 0;// 卖出价格
let VPMode = 'sq';// 价格模式
let VSMode = 'hl';// 皮肤磨损
let VTask = false;// 自动化开关
let VHash = '';// APPID
let VRun = false;// 终止任务
// 计时器
let Vart = -1;//自动刷新
let Vfrt = -1;//失败刷新
// 选项
const NameMode = { 'mc': '名称', 'lx': '类型', 'jj': '简介', 'qb': '全部' };
const PriceMode = { 'sq': '税前', 'sh': '税后' }; //TODO 'zd': '自动'
const SkinMode = { 'ry': '不过滤', 'zx': '崭新出厂', 'lm': '略有磨损', 'jj': '久经沙场', 'ps': '破损不堪', 'zh': '战痕累累', 'ym': '枪皮(有磨损)', 'wm': '非枪皮(无磨损)' };

(function () {
    'use strict';
    loadCFG();
    addPanel();
    checkifCSGO()
    checkSetting();
    if (VTask) {
        console.log('已开启自动任务,1秒后开始执行');
        window.location.hash = VHash;
        setTimeout(() => {
            runAutomatic();
        }, 1000);
    }
})();

// 添加GUI
function addPanel() {
    function genMidButton(text, foo, id) {
        let a = document.createElement('a');
        let s = document.createElement('span');
        s.textContent = text;
        a.appendChild(s);
        a.addEventListener('click', foo);
        if (id) { a.id = id; }
        a.style.cssText = 'margin-right:15px;';
        a.className = 'btn_grey_black btn_medium'; //'btn_darkblue_white_innerfade btn_medium';
        return a;
    }
    function genSecond(ida, idi, value, tips, foo) {
        let a = document.createElement('a');
        let s = document.createElement('span');
        let s1 = document.createElement('span');
        let s2 = document.createElement('span');
        let i = genInput(idi, value, tips, true);
        a.id = ida;
        a.style.cssText = 'margin-right:15px;display:none';
        a.className = 'btn_grey_black btn_medium';
        s1.textContent = '每';
        s2.textContent = '秒';
        i.style.width = '40px';
        i.style.cssText += 'color:#000;background:#fff;vertical-align:inherit;';
        i.step = 1;
        i.min = 5;
        i.addEventListener('change', foo);
        a.appendChild(s);
        s.appendChild(s1);
        s.appendChild(i);
        s.appendChild(s2);
        return a;
    }
    function genButton(text, foo, id) {
        let b = document.createElement('button');
        b.textContent = text;
        b.style.verticalAlign = 'inherit';
        b.addEventListener('click', foo);
        if (id) { b.id = id; }
        return b;
    }
    function genDiv(cls, id) {
        let d = document.createElement('div');
        d.style.cssText = 'vertical-align:middle;';
        if (cls) { d.className = cls };
        if (id) { d.id = id };
        return d;
    }
    function genPanel(name, visiable) {
        let d = genDiv(name, name);
        d.style.cssText = 'background: rgba(58, 58, 58, 0.8);position: fixed;top: 50%;right: 0px;';
        d.style.cssText += 'text-align: center;transform: translate(0px, -50%);z-index: 100;';
        d.style.cssText += 'border: 1px solid rgb(83, 83, 83);padding: 5px;border-radius: 10px 0 0 10px;';
        d.style.cssText += 'transition:right 0.8s;right:-300px;'
        // d.style.display = visiable ? 'block' : 'none';
        return d;
    }
    function genLabel(text, bind) {
        let l = document.createElement('label');
        l.textContent = text;
        l.style.verticalAlign = 'inherit';
        if (bind) { l.setAttribute('for', bind); }
        return l;
    }
    function genA(text, url) {
        let a = document.createElement('a');
        a.textContent = text;
        a.href = url;
        return a;
    }
    function genInput(id, value, tips, number) {
        let i = document.createElement('input');
        i.id = id;
        i.style.cssText = 'border:none;border-radius:0;margin:0px 5px;width:60%;text-align:center;';
        i.style.cssText += 'color:#000;background:#fff;vertical-align:inherit;';
        if (value) { i.value = value; }
        if (tips) { i.placeholder = tips; }
        if (number) {
            i.type = 'number';
            i.step = 0.01;
            i.min = 0;
        }
        return i;
    }
    function genSelect(id, choose, choice) {
        let s = document.createElement('select');
        s.id = id;
        s.style.cssText = 'color:#000;background:#fff;border:none;border-radius:0;vertical-align:inherit;';
        for (k in choose) {
            s.options.add(new Option(choose[k], k));
        }
        s.value = choice;
        return s;
    }
    function genSpace() {
        let s = document.createElement('span');
        s.textContent = '    ';
        return s;
    }
    function genBr() {
        return document.createElement('br');
    }
    function genHr() {
        return document.createElement('hr');
    }
    document.getElementById('pagebtn_previous').addEventListener('click', cancelHighLight);
    document.getElementById('pagebtn_next').addEventListener('click', cancelHighLight);
    document.querySelectorAll('.games_list_tabs>a').forEach((obj) => {
        obj.addEventListener('click', cancelHighLight);
    })

    let lBtnArea = document.querySelector('.inventory_links');
    let btnAutoReload = genMidButton(bool2txt(VAutoR) + '定时刷新', autoReloadCtrl, 'btnAutoReload');
    let btnFailReload = genMidButton(bool2txt(VFailR) + '出错刷新', failReloadCtrl, 'btnFailReload');
    let btnReloadConf = genSecond('btnReloadConf', 'iptTiming', VTime, '30', reloadTimeCtrl);
    lBtnArea.insertBefore(btnReloadConf, lBtnArea.children[0]);
    lBtnArea.insertBefore(btnAutoReload, lBtnArea.children[0]);
    lBtnArea.insertBefore(btnFailReload, lBtnArea.children[0]);

    let rBtnArea = document.querySelector('.inventory_rightnav');
    let btnSwitch = genMidButton('面板', switchPanel, 'btnSwitch');
    rBtnArea.insertBefore(btnSwitch, rBtnArea.children[0])

    let panelFunc = genPanel('autoSell', false);
    document.body.appendChild(panelFunc);
    let lblTitle = genLabel('CIH - V' + Vver + ' - By ', null);
    let lblUrl = genA('Chr_', 'https://steamcommunity.com/id/Chr_');
    let lblFeed = genA('[反馈]', 'https://blog.chrxw.com/scripts.html');

    let divName = genDiv();
    let lblName = genLabel('名称:', 'lblName');
    let iptName = genInput('iptName', VName, ' *? 可作通配符', false);
    let selName = genSelect('selName', NameMode, VNMode);
    divName.style.marginBottom = '5px'
    divName.appendChild(lblName);
    divName.appendChild(iptName);
    divName.appendChild(selName);

    let divPrice = genDiv();
    let lblPrice = genLabel('定价:', 'lblPrice');
    let iptPrice = genInput('iptPrice', VPrice > 0 ? VPrice : ''.toString(), '卖出价格', true);
    let selPrice = genSelect('selPrice', PriceMode, VPMode);
    divPrice.style.marginBottom = '5px'
    divPrice.appendChild(lblPrice);
    divPrice.appendChild(iptPrice);
    divPrice.appendChild(selPrice);

    let divSkin = genDiv();
    let lblSkin = genLabel('磨损:', 'lblSkin');
    let selSkin = genSelect('selSkin', SkinMode, VSMode);
    divSkin.id = 'divSkin';
    divSkin.style.marginBottom = '5px'
    divSkin.appendChild(lblSkin);
    divSkin.appendChild(selSkin);

    let divAction = genDiv();
    divAction.style.marginBottom = '5px';
    let divAction2 = genDiv();
    // let lblAction = genLabel('模式:', 'lblAction');
    // let selAction = genSelect('selAction', { 'cs': '在市场出售', 'fj': '分解为宝珠' }, 'cs');
    let btnReload = genButton('重载库存', reloadInventory, 'btnTarget');
    let btnTarget = genButton('高亮匹配', enableHighLight, 'btnTarget');
    let btnFill = genButton('当前物品', autoFill, 'btnFill');
    // let btnTodo = genButton('自动价格', ()=>{alert('下个版本更新')}, 'btnTodo');
    let btnSetup = genButton('保存配置', setupGoal, 'btnSetup');
    let btnReset = genButton('重置配置', resetGoal, 'btnReset');

    divAction.appendChild(btnReload);
    divAction.appendChild(genSpace());
    divAction.appendChild(btnTarget);
    divAction.appendChild(genSpace());
    divAction.appendChild(btnFill);
    // divAction2.appendChild(btnTodo);
    // divAction2.appendChild(genSpace());
    divAction2.appendChild(btnSetup);
    divAction2.appendChild(genSpace());
    divAction2.appendChild(btnReset);

    let btnManual = genButton('出售当前页', runManual, 'btnManual');
    let btnAutomatic = genButton(bool2txt(VTask) + '自动运行', runAutomaticCtrl, 'btnAutomatic');

    panelFunc.appendChild(lblTitle);
    panelFunc.appendChild(lblUrl);
    panelFunc.appendChild(genSpace());
    panelFunc.appendChild(lblFeed);
    panelFunc.appendChild(genHr());

    panelFunc.appendChild(divName);
    // panelFunc.appendChild(genBr());
    panelFunc.appendChild(divPrice);
    // panelFunc.appendChild(genBr());
    panelFunc.appendChild(divSkin);
    // panelFunc.appendChild(genBr());
    panelFunc.appendChild(divAction);
    panelFunc.appendChild(divAction2);
    panelFunc.appendChild(genHr());
    panelFunc.appendChild(btnManual);
    panelFunc.appendChild(genSpace());
    panelFunc.appendChild(btnAutomatic);

    if (VFailR) { failReloadCtrl(); }
    if (VAutoR) { autoReloadCtrl(); }
    if (rBtnArea.children.length == 1) {
        btnSwitch.style.display = 'none';
    } else {
        if (VPanel) { switchPanel(); }
    }
}
// 出售当前页(单页)
function runManual() {
    let target = g_ActiveInventory.m_rgChildInventories == null ?
        g_ActiveInventory.m_rgItemElements :
        g_ActiveInventory.m_rgChildInventories[6].m_rgItemElements;
    let start = g_ActiveInventory.m_iCurrentPage * 25;
    let end = start + 25;
    let hashlist = [];//记录hash
    for (let i = start; i < end; i++) {
        if (target[i] == null) { continue; }//跳过无效元素
        let obj = target[i][0].rgItem;
        let desc = obj.description;
        if (desc.marketable == 0) { continue; }//跳过不可出售

        if (g_ActiveInventory.appid == 730) {//跳过磨损不匹配的项目
            if (VSMode != 'ry') {
                let ns = desc.descriptions;
                if (ns != undefined) {
                    let ms = checkSkin(ns[0].value);

                    if (
                        (VSMode == 'ym' && ms == '') ||
                        (VSMode == 'wm' && ms != '') ||
                        (VSMode != 'ym' && VSMode != 'wm' && ms != VSMode)
                    ) {
                        // console.log(ms);
                        continue;
                    }
                }
            }
        }

        if (VNMode == 'mc' || VNMode == 'qb') {
            let n = desc.name;
            if (isMatch(n.toLowerCase(), VName)) {
                hashlist.push(getHash(obj));
                continue;
            }
        }
        if (VNMode == 'lx' || VNMode == 'qb') {
            let n = desc.type;
            if (isMatch(n.toLowerCase(), VName)) {
                hashlist.push(getHash(obj));
                continue;
            }
        }
        if (VNMode == 'jj' || VNMode == 'qb') {
            let ns = desc.descriptions;
            if (ns != undefined) {
                for (let n of ns) {
                    if (isMatch(n.value.toLowerCase(), VName)) {
                        hashlist.push(getHash(obj));
                        break;
                    }
                }
            }
        }
    }
    VRun = true;
    if (hashlist.length == 0) {
        ShowAlertDialog('提示', '待出售物品列表为空');
    } else {
        autoSellFunc(hashlist);
    }
}
// 自动运行(前三页)
function runAutomatic() {
    let target = g_ActiveInventory.m_rgChildInventories == null ?
        g_ActiveInventory.m_rgItemElements :
        g_ActiveInventory.m_rgChildInventories[6].m_rgItemElements;
    let start = 0;
    let end = target.length;
    let hashlist = [];//记录hash
    for (let i = start; i < end; i++) {
        if (target[i] == null) { continue; }//跳过无效元素
        let obj = target[i][0].rgItem;
        let desc = obj.description;
        if (desc.marketable == 0) { continue; }//跳过不可出售

        if (g_ActiveInventory.appid == 730) {//跳过磨损不匹配的项目
            if (VSMode != 'ry') {
                let ns = desc.descriptions;
                if (ns != undefined) {
                    let ms = checkSkin(ns[0].value);

                    if (
                        (VSMode == 'ym' && ms == '') ||
                        (VSMode == 'wm' && ms != '') ||
                        (VSMode != 'ym' && VSMode != 'wm' && ms != VSMode)
                    ) {
                        // console.log(ms);
                        continue;
                    }
                }
            }
        }

        if (VNMode == 'mc' || VNMode == 'qb') {
            let n = desc.name;
            if (isMatch(n.toLowerCase(), VName)) {
                hashlist.push(getHash(obj));
                continue;
            }
        }
        if (VNMode == 'lx' || VNMode == 'qb') {
            let n = desc.type;
            if (isMatch(n.toLowerCase(), VName)) {
                hashlist.push(getHash(obj));
                continue;
            }
        }
        if (VNMode == 'jj' || VNMode == 'qb') {
            let ns = desc.descriptions;
            if (ns != undefined) {
                for (let n of ns) {
                    if (isMatch(n.value.toLowerCase(), VName)) {
                        hashlist.push(getHash(obj));
                        break;
                    }
                }
            }
        }
    }
    VRun = true;
    autoSellFunc(hashlist);
}
// 自动出售
function autoSellFunc(hashlist) {
    // console.log(hashlist);
    if (hashlist.length == 0) {
        console.log('待出售物品列表为空');
        // setTimeout(() => { window.location.reload(); }, 5000);
        VRun = false;
        return;
    }
    let i = 0;//当前操作的位置
    const max = 50; // 最大尝试次数
    let tries = 0; // 当前次数
    retry(waitLoad, 50);
    // 等待库存加载完全
    function waitLoad() {
        if (g_ActiveInventory.m_ActivePromise == null) {
            console.log('加载完毕');
            tries = 0;
            selectItem();
        } else {
            retry(waitLoad, 500);
        }
    }
    // 选择对象
    function selectItem() {
        let hash = hashlist[i++];
        if (hash != undefined) {
            window.location.hash = hash;
            retry(() => { // 稍微等一下
                SellCurrentSelection();
                tries = 0;
                retry(fillPrice, 50);
            }, 500);
        } else {
            console.log('列表执行完毕');
            VRun = false;
        }
    }
    // 填写价格
    function fillPrice() {
        let dialog = document.getElementById('market_sell_dialog');
        if (dialog != null && dialog.style.display != 'none') {
            let eula = document.getElementById('market_sell_dialog_accept_ssa');
            let sell = document.getElementById('market_sell_dialog_accept');
            if (eula != null && sell != null) {
                eula.checked = true;
                let price = null;
                if (VPMode == 'sq') {
                    price = document.getElementById('market_sell_buyercurrency_input');
                } else if (VPMode == 'sh') {
                    price = document.getElementById('market_sell_currency_input');
                } else {
                    throw 'VPMode有误';
                }
                price.value = VPrice;
                retry(() => { //等待响应完成
                    keyupSimulater(price);
                    retry(() => {
                        sell.click();
                        tries = 0;
                        retry(sellItem, 500);
                    });
                }, 200);
            } else {
                retry(fillPrice, 200);
            }
        } else {
            retry(fillPrice, 500);
        }
    }
    // 出售
    function sellItem() {
        let sell = document.getElementById('market_sell_dialog_ok');
        sell.click();
        retry(checkSuccess, 500)
    }
    // 判断上架是否成功
    function checkSuccess() {
        let dialog = document.getElementById('market_sell_dialog');
        let errmsg = document.getElementById('market_sell_dialog_error').textContent.trim();
        let succmsg = document.querySelector('.newmodal_header>div.title_text');
        let headertips = document.getElementById('market_headertip_itemsold');

        if (succmsg != null) { //上架成功,但是需要确认
            console.log('上架成功', succmsg.textContent);
            tries = 0;
            retry(closeModal, 200);
        } else if (dialog.style.display != 'none' && headertips.style.display != 'none') { //上架成功,但是无需确认
            if (succmsg != null) {
                console.log('上架成功', succmsg.textContent);
            } else {
                console.log('上架成功', headertips.textContent);
            }
            headertips.style.display = 'none';
            tries = 0;
            retry(closeModal, 200);
        } else if (dialog.style.display != 'none') {//上架失败,检查错误提示
            if (errmsg == '') {//等待响应
                retry(checkSuccess, 1000);
            } else if (errmsg.search('您已上架该物品并正等待确认') != -1 ||
                errmsg.search('You already have a listing for this item pending confirmation') != -1) {
                console.log('上架失败,当前物品正等待确认');
                tries = 0;
                retry(closeModal, 200);
            } else if (errmsg.search('您的物品在上架时出现问题') != -1 ||
                errmsg.search('There was a problem listing your item') != -1) {
                console.log('上架失败,重新尝试上架');
                retry(sellItem, 500);
            } else if (errmsg.search('直到前一个操作完成之前') != -1 ||
                errmsg.search('You cannot sell any items until your previous action completes') != -1) {
                console.log('上架失败,延长等待时间');
                retry(closeModal, 2000);
            } else {
                console.log('未知返回值', errmsg);
                tries = 0;
                retry(closeModal, 200);
            }
        } else {
            retry(checkSuccess, 1000);//其他情况
        }
    }
    // 关闭面板
    function closeModal() {
        let cs = document.querySelectorAll('.newmodal_close');
        if (cs != null) {
            cs.forEach((e) => { e.click(); })
        }
        tries = 0;
        retry(selectItem, 200);
    }
    // 自动重试
    function retry(foo, t) {
        console.log(foo.name);
        if (VRun) {
            if (tries++ <= max) {
                setTimeout(() => {
                    try {
                        foo();
                    } catch (e) {
                        console.error(e);
                    }
                }, t);
            } else {
                console.error('操作超时,等待页面刷新');
                VRun = false;
            }
        } else {
            console.error('手动终止自动任务');
        }
    }
    // 手动触发KeyUp
    function keyupSimulater(obj) {
        let e = new Event('keyup');
        obj.dispatchEvent(e);
    }
}
// 重载库存
function reloadInventory() {
    VRun = false;
    let appid = g_ActiveInventory.appid;
    let contextid = g_ActiveInventory.contextid;
    g_ActiveInventory.m_owner.ReloadInventory(appid, contextid);
}
// 获取Hash字符串
function getHash(obj) {
    return '#' + obj.appid.toString() + '_' + obj.contextid + '_' + obj.assetid;
}
// 通配符匹配
function isMatch(string, pattern) {
    let dp = [];
    for (let i = 0; i <= string.length; i++) {
        let child = [];
        for (let j = 0; j <= pattern.length; j++) {
            child.push(false);
        }
        dp.push(child);
    }
    dp[string.length][pattern.length] = true;
    for (let i = pattern.length - 1; i >= 0; i--) {
        if (pattern[i] != "*") {
            break;
        } else {
            dp[string.length][i] = true;
        }
    }
    for (let i = string.length - 1; i >= 0; i--) {
        for (let j = pattern.length - 1; j >= 0; j--) {
            if (string[i] == pattern[j] || pattern[j] == "?") {
                dp[i][j] = dp[i + 1][j + 1];
            } else if (pattern[j] == "*") {
                dp[i][j] = dp[i + 1][j] || dp[i][j + 1];
            } else {
                dp[i][j] = false;
            }
        }
    }
    return dp[0][0];
};
// 判断是否为CSGO,否则隐藏磨损筛选
function checkifCSGO() {
    let div = document.getElementById('divSkin');
    if (g_ActiveInventory.appid == 730) {
        div.style.display = '';
    } else {
        div.style.display = 'none';
    }
}
// 取消高亮
function cancelHighLight() {
    let div = document.getElementById('divSkin');
    if (g_ActiveInventory.appid == 730) {
        div.style.display = '';
    } else {
        div.style.display = 'none';
    }
    let target = g_ActiveInventory.m_rgChildInventories == null ?
        g_ActiveInventory.m_rgItemElements :
        g_ActiveInventory.m_rgChildInventories[6].m_rgItemElements;
    let start = g_ActiveInventory.m_iCurrentPage * 25;
    let end = start + 25;
    for (let i = start; i < end; i++) {
        if (target[i] != null) {
            let objstyle = target[i][0].children[0].style;
            objstyle.outlineStyle = 'none';
        }
    }
    checkifCSGO();
}
// 检查是否有子TAB
function checkSubChoose() {
    if (g_ActiveInventory.contextid == '0') {
        let choose = document.getElementById('contextselect_activecontext');
        ShowAlertDialog('错误', '请先选择子分类');
        choose.style.outline = '3px #f00 dashed';
        setTimeout(() => { choose.style.outline = ''; }, 5000);
        return true;
    } else {
        return false;
    }
}
// 判断磨损
function checkSkin(str) {
    switch (str) {
        case '外观: 崭新出厂':
        case 'Exterior: Factory New':
            return 'zx';
        case '外观: 略有磨损':
        case 'Exterior: Minimal Wear':
            return 'lm';
        case '外观: 久经沙场':
        case 'Exterior: Field-Tested':
            return 'jj';
        case '外观: 破损不堪':
        case 'Exterior: Well-Worn':
            return 'ps';
        case '外观: 战痕累累':
        case 'Exterior: Battle-Scarred':
            return 'zh';
        default:
            return '';
    }
}

// 高亮匹配项
function enableHighLight() {
    if (checkSubChoose()) { return; }// 必须选择子TAB
    let target = g_ActiveInventory.m_rgItemElements;
    let pattern = document.getElementById('iptName').value.toLowerCase();
    // if (pattern == '') { pattern = '*'; }
    let mode = document.getElementById('selName').value;
    let skin = document.getElementById('selSkin').value;
    let start = g_ActiveInventory.m_iCurrentPage * 25;
    let end = start + 25;
    let matchlist = [];
    for (let i = start; i < end; i++) {
        if (target[i] != null) {
            let desc = target[i][0].rgItem.description;

            if (g_ActiveInventory.appid == 730) {//跳过磨损不匹配的项目
                if (skin != 'ry') {
                    let ns = desc.descriptions;
                    if (ns != undefined) {
                        let ms = checkSkin(ns[0].value);

                        if (
                            (skin == 'ym' && ms == '') ||
                            (skin == 'wm' && ms != '') ||
                            (skin != 'ym' && skin != 'wm' && ms != skin)
                        ) {
                            // console.log(ms);
                            continue;
                        }
                    }
                }
            }

            if (mode == 'mc' || mode == 'qb') {
                let n = desc.name;
                if (isMatch(n.toLowerCase(), pattern)) {
                    matchlist.push(i);
                    continue;
                }
            }
            if (mode == 'lx' || mode == 'qb') {
                let n = desc.type;
                if (isMatch(n.toLowerCase(), pattern)) {
                    matchlist.push(i);
                    continue;
                }
            }
            if (mode == 'jj' || mode == 'qb') {
                let ns = desc.descriptions;
                if (ns != undefined) {
                    for (let n of ns) {
                        if (isMatch(n.value.toLowerCase(), pattern)) {
                            matchlist.push(i);
                            break;
                        }
                    }
                }
            }
        }
    }
    for (let i = start; i < end; i++) { //高亮显示
        if (target[i] != null) {
            let obj = target[i][0];
            let objstyle = obj.children[0].style;
            if (matchlist.indexOf(i) != -1) {
                objstyle.outlineStyle = 'dashed';
                objstyle.outlineOffset = '-2px';
                if (obj.rgItem.description.marketable == 1) {
                    objstyle.outlineColor = '#FF9900'; //可交易
                } else {
                    objstyle.outlineColor = '#CCCCFF'; //不可交易
                }
            } else {
                objstyle.outlineStyle = 'none';
            }
        }
    }
}
// 按照当前物品填充设置
function autoFill() {
    let current = g_ActiveInventory.selectedItem;
    if (current) {
        let desc = current.description;
        let mode = document.getElementById('selName').value;
        let skin = document.getElementById('selSkin');
        let iptname = document.getElementById('iptName');
        let iptPrice = document.getElementById('iptPrice');
        iptname.value = '';

        if (g_ActiveInventory.appid == 730) { // 填充磨损设定
            if (skin != 'ry') {
                let ns = desc.descriptions;
                if (ns != undefined) {
                    let ms = checkSkin(ns[0].value);

                    if (ms != '') {
                        skin.value = ms;
                    } else {
                        skin.value = 'wm';
                    }
                }
            }
        }

        if (mode == 'mc' || mode == 'qb') { 
            iptname.value = desc.name;
        }
        else if (mode == 'lx') {
            iptname.value = desc.type;
        }
        else if (mode == 'jj') {
            let ns = desc.descriptions;
            if (ns != undefined) {
                for (let n of ns) {
                    if (n.value != '') {
                        iptname.value = n.value;
                        break;
                    } else {
                        iptname.value = '【该物品无简介】'
                    }
                }
            }
        }

        iptPrice.focus();
    } else {
        ShowAlertDialog('错误', '未选中物品');
    }
    console.log(current);
}

// 设置目标
function setupGoal() {
    if (checkSubChoose()) { return; } // 必须选择子TAB
    let name = document.getElementById('iptName').value.toLowerCase();
    let nmode = document.getElementById('selName').value;
    let price = Number(document.getElementById('iptPrice').value);
    let pmode = document.getElementById('selPrice').value;
    let smode = document.getElementById('selSkin').value;
    VRun = false;
    if (NameMode[nmode] != undefined &&
        PriceMode[pmode] != undefined &&
        SkinMode[smode] != undefined &&
        price == price && price > 0) {
        VName = name;
        VNMode = nmode;
        VPrice = Math.floor(price * 100) / 100;
        VPMode = pmode;
        VSMode = smode;
        VHash = '#' + g_ActiveInventory.appid.toString() + '_' + g_ActiveInventory.contextid.toString();
        saveCFG();
        ShowAlertDialog('成功', '设置保存成功,请选择运行模式。<br>【出售当前页】:按照设置自动出售当前页的物品(只执行一次)。<br>【自动运行】:按照设置自动出售前三页的物品(每次刷新后执行)。<br>【自动运行】需要配合【定时刷新】和【出错刷新】使用。');
    } else {
        ShowAlertDialog('错误', '价格填写有误。<br>价格必须是大于0的数字(支持整数和小数)。');
    }
    checkSetting();
}
// 重置目标
function resetGoal() {
    let name = document.getElementById('iptName');
    name.value = '';
    name.focus();
    document.getElementById('selName').value = 'mc';
    document.getElementById('iptPrice').value = '';
    document.getElementById('selPrice').value = 'sq';
    document.getElementById('selSkin').value = 'ry';
    VName = '';
    VNMode = 'mc';
    VPrice = 0;
    VPMode = 'sq';
    VSMode = 'hl';
    VHash = '';
    VRun = false;
    if (VTask) { runAutomaticCtrl(); }
    saveCFG();
    checkSetting();
}
// 检测设置是否正确
function checkSetting() {
    let btnManual = document.getElementById('btnManual');
    let btnAutomatic = document.getElementById('btnAutomatic');
    if (VPrice == VPrice && VPrice > 0) {
        btnAutomatic.disabled = false;
        btnManual.disabled = false;
    } else {
        btnAutomatic.disabled = true;
        btnManual.disabled = true;
    }
}
// 自动任务控制
function runAutomaticCtrl() {
    VTask = !VTask;
    document.getElementById('btnAutomatic').textContent = bool2txt(VTask) + '自动运行';
    saveCFG();
    if (VTask) {
        ShowAlertDialog('说明', '成功开启自动任务。<br>每次刷新页面后将会按照设置自动出售前三页的物品。<br>本功能需要配合【定时刷新】和【出错刷新】使用。');
    }
}
// 定时刷新控制
function autoReloadCtrl() {
    let btn = document.getElementById('btnReloadConf');
    VTime = readTime(30);
    if (Vart == -1) {
        btn.style.display = '';
        Vart = setInterval(() => {
            window.location.reload();
        }, VTime * 1000);
        console.log(`刷新时间${VTime}秒`);
    } else {
        clearInterval(Vart);
        Vart = -1;
    }
    VAutoR = Vart != -1;
    document.getElementById('btnAutoReload').children[0].textContent = bool2txt(VAutoR) + '定时刷新';
    saveCFG();
}
// 设置刷新时间
function reloadTimeCtrl() {
    VTime = readTime(30);
    if (VAutoR) {
        clearInterval(Vart);
        Vart = setInterval(() => {
            window.location.reload();
        }, VTime * 1000);
        console.log(`刷新时间${VTime}秒`);
    }
    saveCFG();
}
// 出错刷新控制
function failReloadCtrl() {
    if (Vfrt == -1) {
        Vfrt = setInterval(() => {
            console.log('checkfail');
            let err = document.querySelector('.inventory_load_error_header');
            if (err) { window.location.reload(); }
        }, 3000);
    } else {
        clearInterval(Vfrt);
        Vfrt = -1;
    }
    VFailR = Vfrt != -1;
    document.getElementById('btnFailReload').children[0].textContent = bool2txt(VFailR) + '出错刷新';
    saveCFG();
}
// 显示/隐藏面板
function switchPanel() {
    let p = document.getElementById('autoSell');
    let b = document.getElementById('btnSwitch');
    if (p.style.right == '-300px') {
        p.style.right = '0';
        b.className = 'btn_darkblue_white_innerfade btn_medium';
    } else {
        p.style.right = '-300px';
        b.className = 'btn_grey_black btn_medium';
    }
    VPanel = p.style.right != '-300px';
    saveCFG();
}
// 显示布尔
function bool2txt(bool) {
    return bool ? '√ ' : '× ';
}
// 文本转数字
function readTime(def) {
    let ipt = document.getElementById('iptTiming');
    let i = Number(ipt.value);
    if (i != i || i < 5) {
        return def;
    } else {
        return i;
    }
}
// 读取设置
function loadCFG() {
    let t = null;
    t = GM_getValue('VAutoR');
    VAutoR = Boolean(t);
    t = GM_getValue('VFailR');
    VFailR = Boolean(t);
    t = GM_getValue('VTime');
    VTime = t ? t : 30;
    t = GM_getValue('VPanel');
    VPanel = Boolean(t);
    t = GM_getValue('VName');
    VName = t ? t.toLowerCase() : '';
    t = GM_getValue('VNMode');
    if (NameMode[t] == undefined) { t = 'mc'; }
    VNMode = t;
    t = GM_getValue('VPrice');
    VPrice = t ? t : 0;
    t = GM_getValue('VPMode');
    if (PriceMode[t] == undefined) { t = 'sq'; }
    VPMode = t;
    t = GM_getValue('VSMode');
    if (SkinMode[t] == undefined) { t = 'ry'; }
    VSMode = t;
    t = GM_getValue('VTask');
    VTask = Boolean(t);
    t = GM_getValue('VHash');
    VHash = t ? t : '';
    if (VTask) { VPanel = true; }//开启自动任务后始终打开面板
    saveCFG();
}
// 保存设置
function saveCFG() {
    GM_setValue('VAutoR', VAutoR);
    GM_setValue('VTime', VTime);
    GM_setValue('VFailR', VFailR);
    GM_setValue('VPanel', VPanel);
    GM_setValue('VName', VName);
    GM_setValue('VNMode', VNMode);
    GM_setValue('VPrice', VPrice);
    GM_setValue('VPMode', VPMode);
    GM_setValue('VSMode', VSMode);
    GM_setValue('VTask', VTask);
    GM_setValue('VHash', VHash);
}