您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Overhaul of market UI and functionality.
// ==UserScript== // @name IdlePixel Market Overhaul // @namespace com.anwinity.idlepixel // @version 1.0.17 // @description Overhaul of market UI and functionality. // @author Anwinity // @license MIT // @match *://idle-pixel.com/login/play* // @grant none // @require https://gf.qytechs.cn/scripts/441206-idlepixel/code/IdlePixel+.js?anticache=20220905 // ==/UserScript== (function() { 'use strict'; const XP_PER = { stone: 0.1, copper: 1, iron: 5, silver: 10, gold: 20, promethium: 100, titanium: 300, bronze_bar: 5, iron_bar: 25, silver_bar: 50, gold_bar: 100, promethium_bar: 500, titanium_bar: 2000 }; const BONEMEAL_PER = { bones: 1, big_bones: 2, ice_bones: 3, ashes: 2 }; class MarketPlugin extends IdlePixelPlusPlugin { constructor() { super("market", { about: { name: GM_info.script.name, version: GM_info.script.version, author: GM_info.script.author, description: GM_info.script.description }, config: [ { id: "condensed", label: "Condensed UI", type: "boolean", default: true }, { id: "sortMethod", label: "Sort Method", type: "select", default: "default", options: [ {value: "default", label: "Default"}, {value: "timeDESC", label: "Time (Newest First)"}, {value: "timeASC", label: "Time (Newest Last)"}, {value: "priceASC", label: "Price (Cheapest First)"}, {value: "priceDESC", label: "Price (Cheapest Last)"}, ] }, { id: "highlightBest", label: "Highlight Best", type: "boolean", default: true }, { id: "autoMax", label: "Autofill Max Buy", type: "boolean", default: false }, ] }); this.lastBrowsedItem = "all"; this.lastCategoryFilter = "all"; } onConfigsChanged() { this.applyCondensed(this.getConfig("condensed")); } applyCondensed(condensed) { if(condensed) { $("#panel-player-market").addClass("condensed"); $("#modal-market-select-item").addClass("condensed"); } else { $("#panel-player-market").removeClass("condensed"); $("#modal-market-select-item").removeClass("condensed"); } } onLogin() { const self = this; $("head").append(` <style id="styles-market"> #market-table { margin-top: 0.5em !important; } #market-table tr.cheaper { background-color: rgb(50, 205, 50, 0.25); } #market-table tr.cheaper > td { background-color: rgb(50, 205, 50, 0.25); } #panel-player-market.condensed > center { display: flex; flex-direction: row; justify-content: center; } #panel-player-market.condensed div.player-market-slot-base { height: 400px; } #panel-player-market.condensed div.player-market-slot-base hr { margin-top: 2px; margin-bottom: 4px; } #panel-player-market.condensed div.player-market-slot-base br + #panel-player-market.condensed div.player-market-slot-base br { display: none; } #panel-player-market.condensed div.player-market-slot-base[id^="player-market-slot-occupied"] button { padding: 2px; } #panel-player-market.condensed #market-table th { padding: 2px 4px; } #panel-player-market.condensed #market-table td { padding: 2px 4px; } #modal-market-select-item.condensed #modal-market-select-item-section .select-item-tradables-catagory { margin: 6px 6px; padding: 6px 6px; } #modal-market-select-item.condensed #modal-market-select-item-section .select-item-tradables-catagory hr { margin-top: 2px; margin-bottom: 2px; } #market-category-filters { display: flex; flex-direction: row; justify-content: center; align-items: start; flex-wrap: wrap; margin: 0.25em; } #market-category-filters > button { display: inline-block; margin: 0.25em; } #market-category-filters > button.active { background-color: #74DBDB; } </style> `); // modal-market-configure-item-to-sell-amount const sellModal = $("#modal-market-configure-item-to-sell"); const sellAmountInput = sellModal.find("#modal-market-configure-item-to-sell-amount"); sellAmountInput.after(` <button type="button" onclick="IdlePixelPlus.plugins.market.applyOneAmountSell()">1</button> <button type="button" onclick="IdlePixelPlus.plugins.market.applyMaxAmountSell()">max</button> <button type="button" onclick="IdlePixelPlus.plugins.market.applyMaxAmountSell(true)">max-1</button> `); const sellPriceInput = sellModal.find("#modal-market-configure-item-to-sell-price-each").after(` <button type="button" onclick="IdlePixelPlus.plugins.market.applyMinPriceSell()">min</button> <button type="button" onclick="IdlePixelPlus.plugins.market.applyMidPriceSell()">mid</button> <button type="button" onclick="IdlePixelPlus.plugins.market.applyMaxPriceSell()">max</button> <br /><br /> Total: <span id="modal-market-configure-item-to-sell-total"></span> `); sellAmountInput.on("input change", () => this.applyTotalSell()); sellPriceInput.on("input change", () => this.applyTotalSell()); const buyModal = $("#modal-market-purchase-item"); const buyAmountInput = buyModal.find("#modal-market-purchase-item-amount-input"); buyAmountInput.after(` <button type="button" onclick="IdlePixelPlus.plugins.market.applyOneAmountBuy()">1</button> <button type="button" onclick="IdlePixelPlus.plugins.market.applyMaxAmountBuy()">max</button> <br /><br /> Total: <span id="modal-market-purchase-item-total"></span> <br /> Owned: <item-display data-format="number" data-key="coins"></item-display> `); buyAmountInput.on("input change", () => this.applyTotalBuy()); // wrap Market.browse_get_table to capture last selected const original_market_browse = Market.browse_get_table; Market.browse_get_table = function(item) { return self.browseGetTable(item) .always(() => { self.filterTable(); }); } $("#market-table").css("margin-top", "24px"); $("#market-table").parent().before(`<div id="market-category-filters"><div>`); // wrap Market.load_tradables to populate category filters const original_load_tradables = Market.load_tradables; Market.load_tradables = function(data) { original_load_tradables.apply(this, arguments); self.createFilterButtons(); } self.createFilterButtons(); $(`#panel-player-market button[onclick^="Market.clicks_browse_player_market_button"]`) .first() .after(`<button id="refresh-market-table-button" type="button" style="margin-left: 0.5em" onclick="IdlePixelPlus.plugins.market.refreshMarket(true);">Refresh</button>`); //$("button.market-remove-button").after('<br><br><br><button onclick="" class="market-rebrowse-button">Browse</button>'); this.onConfigsChanged(); } browseGetTable(item) { //console.log(`browseGetTable("${item}")`); const self = this; this.lastBrowsedItem = item; if(item != "all") { self.lastCategoryFilter = "all"; } if(item == "all") { $("#market-category-filters").show(); } else { $("#market-category-filters").hide(); } // A good chunk of this is taking directly from Market.browse_get_table hide_element("market-table"); show_element("market-loading"); let best = {}; let bestList = {}; return $.get(`../../market/browse/${item}/`).done(function(data) { const xpMultiplier = DonorShop.has_donor_active(IdlePixelPlus.getVar("donor_bonus_xp_timestamp")) ? 1.1 : 1; //console.log(data); data.forEach(datum => { const priceAfterTax = datum.market_item_price_each * 1.01; switch(datum.market_item_category) { case "bars": case "ores": { let perCoin = (priceAfterTax / (xpMultiplier*XP_PER[datum.market_item_name])); datum.perCoin = perCoin; datum.perCoinLabel = `${perCoin.toFixed(perCoin < 10 ? 2 : 1)} coins/xp`; if(!best[datum.market_item_category]) { best[datum.market_item_category] = perCoin; bestList[datum.market_item_category] = [datum]; } else { if(perCoin == best[datum.market_item_category]) { bestList[datum.market_item_category].push(datum); } else if(perCoin < best[datum.market_item_category]) { bestList[datum.market_item_category] = [datum]; best[datum.market_item_category] = perCoin; } } break; } case "logs": { let perCoin = (priceAfterTax / Cooking.getHeatPerLog(datum.market_item_name)); datum.perCoin = perCoin; datum.perCoinLabel = `${perCoin.toFixed(perCoin < 10 ? 2 : 1)} coins/heat`; if(!best[datum.market_item_category]) { best[datum.market_item_category] = perCoin; bestList[datum.market_item_category] = [datum]; } else { if(perCoin == best[datum.market_item_category]) { bestList[datum.market_item_category].push(datum); } else if(perCoin < best[datum.market_item_category]) { bestList[datum.market_item_category] = [datum]; best[datum.market_item_category] = perCoin; } } break; } case "raw_fish": case "cooked_fish":{ let perCoin = (priceAfterTax / Cooking.get_energy(datum.market_item_name)); datum.perCoin = perCoin; datum.perCoinLabel = `${perCoin.toFixed(perCoin < 10 ? 2 : 1)} coins/energy`; if(!best[datum.market_item_category]) { best[datum.market_item_category] = perCoin; bestList[datum.market_item_category] = [datum]; } else { if(perCoin == best[datum.market_item_category]) { bestList[datum.market_item_category].push(datum); } else if(perCoin < best[datum.market_item_category]) { bestList[datum.market_item_category] = [datum]; best[datum.market_item_category] = perCoin; } } break; } case "bones": { let perCoin = (priceAfterTax / BONEMEAL_PER[datum.market_item_name]); datum.perCoin = perCoin; datum.perCoinLabel = `${perCoin.toFixed(perCoin < 10 ? 2 : 1)} coins/bonemeal`; if(!best[datum.market_item_category]) { best[datum.market_item_category] = perCoin; bestList[datum.market_item_category] = [datum]; } else { if(perCoin == best[datum.market_item_category]) { bestList[datum.market_item_category].push(datum); } else if(perCoin < best[datum.market_item_category]) { bestList[datum.market_item_category] = [datum]; best[datum.market_item_category] = perCoin; } } break; } default: { datum.perCoin = Number.MAX_SAFE_INTEGER; datum.perCoinLabel = ""; break; } } }); Object.values(bestList).forEach(bestCatList => bestCatList.forEach(datum => datum.best=true)); const sortMethod = self.getConfig("sortMethod"); switch(sortMethod) { case "timeDESC": { data = data.sort((a, b) => b.market_item_post_timestamp - a.market_item_post_timestamp); break; } case "timeASC": { data = data.sort((a, b) => a.market_item_post_timestamp - b.market_item_post_timestamp); break; } case "priceASC": { data = data.sort((a, b) => { if(a.perCoin != b.perCoin && typeof a.perCoin==="number" && typeof b.perCoin==="number") { return a.perCoin - b.perCoin; } return a.market_item_price_each - b.market_item_price_each; }); // DEBUG //data.filter(x => x.market_item_category == "cooked_fish").forEach(d => { // console.log(`${d.market_item_name} ${d.perCoin} ${d.market_item_price_each}`); //}); // break; } case "priceDESC": { data = data.sort((a, b) => { if(a.perCoin != b.perCoin && typeof a.perCoin==="number" && typeof b.perCoin==="number") { return b.perCoin - a.perCoin; } return b.market_item_price_each - a.market_item_price_each; }); break; } } // console.log(data); let html = "<tr><th>ITEM</th><th></th><th>AMOUNT</th><th>PRICE EACH</th><th>CATEGORY</th><th>EXPIRES IN</th></tr>"; // in case you want to add any extra data to the table but still use this script if(typeof window.ModifyMarketDataHeader === "function") { html = window.ModifyMarketDataHeader(html); } data.forEach(datum => { let market_id = datum.market_id; let player_id = datum.player_id; let item_name = datum.market_item_name; let amount = datum.market_item_amount; let price_each = datum.market_item_price_each; let category = datum.market_item_category; let timestamp = datum.market_item_post_timestamp; let perCoinLabel = datum.perCoinLabel; let best = datum.best && self.getConfig("highlightBest"); let your_entry = ""; if(Items.getItem("player_id") == player_id) { your_entry = "<span class='color-grey font-small'><br /><br />(Your Item)</span>"; } let rowHtml = ""; rowHtml += `<tr onclick="Modals.market_purchase_item('${market_id}', '${item_name}', '${amount}', '${price_each}'); IdlePixelPlus.plugins.market.applyMaxAmountBuyIfConfigured();" class="hover${ best ? ' cheaper' : '' }">`; rowHtml += `<td>${Items.get_pretty_item_name(item_name)}${your_entry}</td>`; rowHtml += `<td><img src="https://d1xsc8x7nc5q8t.cloudfront.net/images/${item_name}.png" /></td>`; rowHtml += `<td>${amount}</td>`; rowHtml += `<td><img src="https://d1xsc8x7nc5q8t.cloudfront.net/images/coins.png" /> ${Market.get_price_after_tax(price_each)}`; if(perCoinLabel) { rowHtml += `<br /><span style="font-size: 80%; opacity: 0.8">${perCoinLabel}</span>`; } rowHtml += `</td>`; rowHtml += `<td>${category}</td>`; rowHtml += `<td>${Market._get_expire_time(timestamp)}</td>`; rowHtml += `</tr>`; // in case you want to add any extra data to the table but still use this script if(typeof window.ModifyMarketDataRow === "function") { rowHtml = window.ModifyMarketDataRow(datum, rowHtml); } html += rowHtml; }); document.getElementById("market-table").innerHTML = html; hide_element("market-loading"); show_element("market-table"); }); } createFilterButtons() { const filters = $("#market-category-filters"); filters.empty(); if(Market.tradables) { const categories = []; Market.tradables.forEach(tradable => { if(!categories.includes(tradable.category)) { categories.push(tradable.category); } }); filters.append(`<button data-category="all" onclick="IdlePixelPlus.plugins.market.filterTable('all')">All</button>`); categories.forEach(cat => { filters.append(`<button data-category="${cat}" onclick="IdlePixelPlus.plugins.market.filterTable('${cat}')">${cat.replace(/_/g, " ").replace(/(^|\s)\w/g, s => s.toUpperCase())}</button>`); }); } } filterTable(category) { if(category) { this.lastCategoryFilter = category; } else { category = this.lastCategoryFilter || "all"; } $("#market-category-filters button.active").removeClass("active"); $(`#market-category-filters button[data-category="${category}"]`).addClass("active"); const rows = $("#market-table tbody tr.hover"); if(category=="all") { rows.show(); } else { rows.each(function() { const row = $(this); const rowCategory = row.find("td:nth-child(5)").text(); if(category == rowCategory) { row.show(); } else { row.hide(); } }); } } refreshMarket(disableButtonForABit) { if(this.lastBrowsedItem) { Market.browse_get_table(this.lastBrowsedItem); if(disableButtonForABit) { // prevent spam clicking it $("#refresh-market-table-button").prop("disabled", true); setTimeout(() => { $("#refresh-market-table-button").prop("disabled", false); }, 700); } } } applyOneAmountBuy() { $("#modal-market-purchase-item #modal-market-purchase-item-amount-input").val(1); this.applyTotalBuy(); } applyMaxAmountBuyIfConfigured() { if(this.getConfig("autoMax")) { this.applyMaxAmountBuy(); } } applyMaxAmountBuy(minus1=false) { const coinsOwned = IdlePixelPlus.getVarOrDefault("coins", 0, "int"); const price = parseInt($("#modal-market-purchase-item #modal-market-purchase-item-price-each").val().replace(/[^\d]+/g, "")); const maxAffordable = Math.floor(coinsOwned / price); const maxAvailable = parseInt($("#modal-market-purchase-item #modal-market-purchase-item-amount-left").val().replace(/[^\d]+/g, "")); let max = Math.min(maxAffordable, maxAvailable); if(minus1) { max--; } if(max < 0) { max = 0; } $("#modal-market-purchase-item #modal-market-purchase-item-amount-input").val(max); this.applyTotalBuy(); } parseIntKMBT(s) { if(typeof s === "number") { return Math.floor(s); } s = s.toUpperCase().replace(/[^\dKMBT]+/, ""); if(s.endsWith("K")) { s = s.replace(/K$/, "000"); } else if(s.endsWith("M")) { s = s.replace(/M$/, "000000"); } else if(s.endsWith("B")) { s = s.replace(/B$/, "000000000"); } else if(s.endsWith("T")) { s = s.replace(/T$/, "000000000000"); } return parseInt(s); } applyTotalBuy() { const amount = this.parseIntKMBT($("#modal-market-purchase-item #modal-market-purchase-item-amount-input").val()); const price = this.parseIntKMBT($("#modal-market-purchase-item #modal-market-purchase-item-price-each").val().replace("Price each: ", "")); const total = amount*price; const totalElement = $("#modal-market-purchase-item-total"); if(isNaN(total)) { totalElement.text(""); } else { totalElement.text(total.toLocaleString()); const coinsOwned = IdlePixelPlus.getVarOrDefault("coins", 0, "int"); if(total > coinsOwned) { totalElement.css("color", "red"); } else { totalElement.css("color", ""); } } } currentItemSell() { return $("#modal-market-configure-item-to-sell").val(); } applyOneAmountSell() { const item = this.currentItemSell(); const owned = IdlePixelPlus.getVarOrDefault(item, 0, "int"); $("#modal-market-configure-item-to-sell-amount").val(Math.min(owned, 1)); this.applyTotalSell(); } applyMaxAmountSell(minus1=false) { const item = this.currentItemSell(); let max = IdlePixelPlus.getVarOrDefault(item, 0, "int"); if(minus1) { max--; } if(max < 0) { max = 0; } $("#modal-market-configure-item-to-sell-amount").val(max); this.applyTotalSell(); } applyMinPriceSell() { const min = parseInt($("#modal-market-configure-item-to-sell-label-lower-limit").text().replace(/[^\d]/g, "")); $("#modal-market-configure-item-to-sell-price-each").val(min); this.applyTotalSell(); } applyMidPriceSell() { const min = parseInt($("#modal-market-configure-item-to-sell-label-lower-limit").text().replace(/[^\d]/g, "")); const max = parseInt($("#modal-market-configure-item-to-sell-label-upper-limit").text().replace(/[^\d]/g, "")); const mid = Math.floor((min+max)/2); $("#modal-market-configure-item-to-sell-price-each").val(mid); this.applyTotalSell(); } applyMaxPriceSell() { const max = parseInt($("#modal-market-configure-item-to-sell-label-upper-limit").text().replace(/[^\d]/g, "")); $("#modal-market-configure-item-to-sell-price-each").val(max); this.applyTotalSell(); } applyTotalSell() { const amount = this.parseIntKMBT($("#modal-market-configure-item-to-sell-amount").val()); const price = this.parseIntKMBT($("#modal-market-configure-item-to-sell-price-each").val()); const total = amount*price; if(isNaN(total)) { $("#modal-market-configure-item-to-sell-total").text(""); } else { $("#modal-market-configure-item-to-sell-total").text(total.toLocaleString()); } // TODO total w/ tax } onVariableSet(key, valueBefore, valueAfter) { } } const plugin = new MarketPlugin(); IdlePixelPlus.registerPlugin(plugin); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址