QuickBuy panel with hide/show toggle, remembered collapse, full cross-page quick buy (fixed search), supports qty > 1 purchases
目前為
// ==UserScript==
// @name QuickBuy
// @namespace Zega
// @version 1.41
// @description QuickBuy panel with hide/show toggle, remembered collapse, full cross-page quick buy (fixed search), supports qty > 1 purchases
// @match https://fairview.deadfrontier.com/onlinezombiemmo/index.php*
// @grant none
// ==/UserScript==
(function() {
'use strict';
// signal implant
window.BrowserImplant_QuickBuy = true;
// load any saved highlight settings
const highlightConfig = JSON.parse(localStorage.getItem('qb_highlightConfig') || '{}');
// define your buttons
const foodMedItems = [
{ label: 'Buy 1 Whiskey', search: 'Whiskey', qty: 1 },
{ label: 'Buy 2 Whiskey', search: 'Whiskey', qty: 2 },
{ label: 'Buy 1 Nerotonin 8B', search: 'Nerotonin 8B', qty: 1 },
{ label: 'Buy 2 Nerotonin 8B', search: 'Nerotonin 8B', qty: 2 },
{ label: 'Buy Energy Bar', search: 'Energy Bar', qty: 1 },
{ label: 'Buy Repair Kit', search: 'Repair Kit', qty: 1 }
];
const ammoItems = [
{ label: '14mm Stack (1200)', search: '14mm Rifle Bullets', qty: 1200 },
{ label: '12.7mm Stack (1200)', search: '12.7mm Rifle Bullets', qty: 1200 },
{ label: '9mm Stack (1200)', search: '9mm Rifle Bullets', qty: 1200 },
{ label: '.55 Stack (1600)', search: '.55 Handgun Bullets', qty: 1600 },
{ label: 'Biomass Stack (1000)', search: 'Biomass', qty: 1000 },
{ label: 'Energy Cell (1600)', search: 'Energy Cell', qty: 1600 },
{ label: 'Grenade Stack (400)', search: 'Grenades', qty: 400 },
{ label: 'Heavy Grenades (400)', search: 'Heavy Grenades', qty: 400 },
{ label: 'Gasoline (4546)', search: 'Gasoline', qty: 4546 },
{ label: '10 Gauge (800)', search: '10 Gauge Shells', qty: 800 },
{ label: '12 Gauge (800)', search: '12 Gauge Shells', qty: 800 },
{ label: '16 Gauge (800)', search: '16 Gauge Shells', qty: 800 },
{ label: '20 Gauge (800)', search: '20 Gauge Shells', qty: 800 }
];
// build and insert the toolbar
function createQuickBuyToolbar() {
const rightTd = document.querySelector("td.design2010[style*='right_margin.jpg']");
if (!rightTd) return console.warn('QuickBuy: right cell not found');
rightTd.style.position = 'relative';
const fieldset = document.createElement('fieldset');
fieldset.id = 'quickbuy-fieldset';
Object.assign(fieldset.style, {
position: 'absolute', top: '120px', left: '10px',
width: '420px', border: '1px solid #666',
padding: '8px 12px', background: 'rgba(0,0,0,0.35)',
borderRadius: '8px', boxShadow: '0 4px 12px rgba(0,0,0,0.6)',
zIndex: '10000'
});
const legend = document.createElement('legend');
legend.innerHTML = `<span style="color:#ffd700;">QuickBuys</span>
<button id="collapse-quickbuy" style="background:none;border:none;color:#ffd700;font-size:16px;cursor:pointer">[–]</button>`;
legend.style.padding = '0 6px';
legend.style.fontSize = '13px';
fieldset.appendChild(legend);
const container = document.createElement('div');
container.id = 'quickbuy-container';
fieldset.appendChild(container);
rightTd.appendChild(fieldset);
appendSection(container, 'Food / Medical', foodMedItems);
container.appendChild(Object.assign(document.createElement('hr'), {
style: 'border:0;border-top:1px solid #666;margin:8px 0;'
}));
appendSection(container, 'Ammo', ammoItems);
const collapseBtn = document.getElementById('collapse-quickbuy');
if (localStorage.getItem('quickbuyCollapsed') === 'true') {
container.style.display = 'none';
collapseBtn.textContent = '[+]';
}
collapseBtn.addEventListener('click', () => {
const hidden = container.style.display === 'none';
container.style.display = hidden ? 'block' : 'none';
collapseBtn.textContent = hidden ? '[–]' : '[+]';
localStorage.setItem('quickbuyCollapsed', hidden ? 'false' : 'true');
});
}
function appendSection(parent, title, items) {
const header = document.createElement('div');
header.textContent = title;
header.style.color = 'gold';
header.style.fontWeight = 'bold';
header.style.margin = title==='Ammo' ? '2px 0 4px' : '4px 0 2px';
parent.appendChild(header);
const grid = document.createElement('div');
grid.style.display = 'grid';
grid.style.gridTemplateColumns = 'repeat(2,200px)';
grid.style.gap = '8px';
items.forEach(item => grid.appendChild(createButton(item)));
parent.appendChild(grid);
}
function createButton(item) {
const btn = document.createElement('button');
btn.textContent = item.label;
Object.assign(btn.style, {
width: '200px',
height: '32px',
backgroundColor: highlightConfig[item.search]?.backgroundColor || '#222',
color: highlightConfig[item.search]?.color || 'gold',
border: '2px solid #555',
borderRadius: '8px',
cursor: 'pointer',
textAlign: 'center'
});
btn.addEventListener('contextmenu', e => {
e.preventDefault();
const key = item.search;
if (highlightConfig[key]?.backgroundColor === 'green') {
delete highlightConfig[key];
btn.style.backgroundColor = '#222';
btn.style.color = 'gold';
} else {
highlightConfig[key] = { backgroundColor: 'green', color: 'black' };
btn.style.backgroundColor = 'green';
btn.style.color = 'black';
}
localStorage.setItem('qb_highlightConfig', JSON.stringify(highlightConfig));
});
btn.addEventListener('click', () => quickBuy(item.search, item.qty));
return btn;
}
function quickBuy(term, qty) {
sessionStorage.setItem('quickBuy_pending', JSON.stringify({ term, qty }));
window.location.href = `${location.origin}${location.pathname}?page=35`;
}
function realClick(el) {
el.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true }));
}
function waitForYesClick(cb) {
const start = Date.now();
(function poll() {
const yes = Array.from(document.querySelectorAll('button'))
.find(b => b.innerText.trim().toLowerCase() === 'yes');
if (yes) {
realClick(yes);
cb && cb();
} else if (Date.now() - start < 5000) {
setTimeout(poll, 100);
}
})();
}
function purchaseMultiple(term, qty) {
let bought = 0;
(function buyNext() {
if (bought >= qty) return;
const items = Array.from(document.querySelectorAll('div.fakeItem'))
.filter(div => div.querySelector('.itemName')?.textContent.trim() === term);
if (!items.length) {
return setTimeout(buyNext, 200);
}
const btn = items[0].querySelector('button[data-action="buyItem"]');
if (!btn) {
return setTimeout(buyNext, 200);
}
realClick(btn);
waitForYesClick(() => {
bought++;
setTimeout(buyNext, 300);
});
})();
}
window.addEventListener('load', () => {
setTimeout(createQuickBuyToolbar, 500);
const pending = sessionStorage.getItem('quickBuy_pending');
if (pending && window.location.search.includes('page=35')) {
const { term, qty } = JSON.parse(pending);
sessionStorage.removeItem('quickBuy_pending');
const input = document.querySelector('#searchField');
const mk = document.querySelector('#makeSearch');
if (input && mk) {
input.value = term;
realClick(mk);
setTimeout(() => purchaseMultiple(term, qty), 500);
}
}
});
})();