Automatically opens packs, watches ads, and selects the best 10 cards for daily raid battles on wikigacha.com
// ==UserScript==
// @name Wikigacha Auto Player
// @description Automatically opens packs, watches ads, and selects the best 10 cards for daily raid battles on wikigacha.com
// @match https://wikigacha.com/*
// @grant none
// @run-at document-start
// @version 0.0.1.20260322204210
// @namespace https://greasyfork.org/users/1583423
// ==/UserScript==
(function () {
'use strict';
// Inject alert override directly into page context
const script = document.createElement('script');
script.textContent = `
window.alert = function(msg) {
console.log('[Wikigacha] Alert suppressed:', msg);
};
window.confirm = function() { return true; };
`;
(document.head || document.documentElement).appendChild(script);
script.remove();
const INTERVAL = 300;
const SCAN_RARITIES = ['LR', 'UR'];
function findButtonByText(text) {
return [...document.querySelectorAll('button')].find(
b => b.textContent.trim().toLowerCase() === text.toLowerCase()
);
}
function tryOpenPack() {
const pack = document.querySelector('img[alt="Wiki Pack"]');
if (pack) {
pack.closest('button, div[role="button"], div')?.click() || pack.click();
return true;
}
const tapBtn = [...document.querySelectorAll('*')].find(
el => el.textContent.trim() === '▲ TAP TO OPEN ▲'
);
if (tapBtn) { tapBtn.click(); return true; }
return false;
}
function tryWatchAd() {
const adBtn = [...document.querySelectorAll('span')].find(
s => s.textContent.trim() === '📺 Watch Ad to Refill'
);
if (adBtn) { adBtn.closest('button')?.click() || adBtn.click(); return true; }
return false;
}
function tryCloseAd() {
const closeBtn = findButtonByText('Close Ad');
if (closeBtn) { closeBtn.click(); return true; }
return false;
}
function tryBackToPacks() {
const backBtn = findButtonByText('BACK TO PACKS');
if (backBtn) { backBtn.click(); return true; }
return false;
}
function tryRecoverFromError() {
const collectionBtn = [...document.querySelectorAll('button')].find(
b => b.textContent.trim() === 'Collection'
);
if (collectionBtn) {
collectionBtn.click();
setTimeout(() => {
const packsBtn = [...document.querySelectorAll('button')].find(
b => b.textContent.trim() === 'Packs'
);
if (packsBtn) packsBtn.click();
}, 1500);
return true;
}
return false;
}
// ── RAID AUTO-SELECT ────────────────────────────────────────────────
let raidRunning = false;
async function sleep(ms) {
return new Promise(r => setTimeout(r, ms));
}
function getRowsFromPage() {
return [...document.querySelectorAll('tbody tr')].map(row => {
const cells = row.querySelectorAll('td');
if (cells.length < 6) return null;
const rarity = cells[2]?.textContent.trim();
const atk = parseInt(cells[4]?.textContent.trim().replace(/,/g, ''), 10) || 0;
const def = parseInt(cells[5]?.textContent.trim().replace(/,/g, ''), 10) || 0;
const plusBtn = cells[0]?.querySelector('button:last-child');
return { rarity, atk, def, total: atk + def, plusBtn };
}).filter(Boolean);
}
async function collectAllCards() {
let allCards = [];
// Reset to page 1
while (true) {
const prevBtn = [...document.querySelectorAll('button')].find(b => b.textContent.trim() === 'Prev');
if (!prevBtn || prevBtn.disabled) break;
prevBtn.click();
await sleep(600);
}
while (true) {
await sleep(500);
const rows = getRowsFromPage();
let hitLowerRarity = false;
for (const row of rows) {
if (!SCAN_RARITIES.includes(row.rarity)) {
hitLowerRarity = true;
break;
}
allCards.push(row);
}
if (hitLowerRarity) {
console.log(`[Wikigacha] Hit lower rarity, stopping scan with ${allCards.length} cards`);
break;
}
const nextBtn = [...document.querySelectorAll('button')].find(b => b.textContent.trim() === 'Next');
if (!nextBtn || nextBtn.disabled) break;
nextBtn.click();
}
return allCards;
}
async function autoSelectBestRaid() {
if (raidRunning) return;
raidRunning = true;
console.log('[Wikigacha] Starting raid auto-select...');
// Reset any existing selection first
const resetBtn = findButtonByText('Reset');
if (resetBtn) { resetBtn.click(); await sleep(400); }
const allCards = await collectAllCards();
console.log(`[Wikigacha] Scraped ${allCards.length} LR/UR cards`);
// Sort by ATK+DEF descending, pick top 10 with available + button
const top10 = allCards
.filter(c => c.plusBtn && !c.plusBtn.disabled)
.sort((a, b) => b.total - a.total)
.slice(0, 10);
console.log('[Wikigacha] Top 10 by ATK+DEF:', top10.map(c => `${c.rarity} ${c.total}`));
// Reset to page 1 again to start clicking
while (true) {
const prevBtn = [...document.querySelectorAll('button')].find(b => b.textContent.trim() === 'Prev');
if (!prevBtn || prevBtn.disabled) break;
prevBtn.click();
await sleep(600);
}
// Click + for each top 10 card by matching stats page by page
let remaining = [...top10];
while (remaining.length > 0) {
await sleep(500);
const rows = getRowsFromPage();
for (const row of rows) {
const match = remaining.findIndex(
c => c.atk === row.atk && c.def === row.def && row.plusBtn && !row.plusBtn.disabled
);
if (match !== -1) {
row.plusBtn.click();
remaining.splice(match, 1);
await sleep(150);
}
}
if (remaining.length === 0) break;
// Stop paginating once we're past LR/UR
const rows2 = getRowsFromPage();
const hitLower = rows2.some(r => !SCAN_RARITIES.includes(r.rarity));
if (hitLower) break;
const nextBtn = [...document.querySelectorAll('button')].find(b => b.textContent.trim() === 'Next');
if (!nextBtn || nextBtn.disabled) break;
nextBtn.click();
}
console.log('[Wikigacha] Raid selection done!');
raidRunning = false;
}
function injectRaidButton() {
if (document.getElementById('wg-raid-btn')) return;
const target = [...document.querySelectorAll('button')].find(b => b.textContent.trim() === 'Back to Raid Top');
if (!target) return;
const btn = document.createElement('button');
btn.id = 'wg-raid-btn';
btn.textContent = '⚔️ Auto-Select Best 10';
btn.style.cssText = `
margin-left: 8px;
padding: 4px 14px;
border-radius: 9999px;
border: 1px solid #22d3ee;
background: rgba(8,145,178,0.2);
color: #cffafe;
font-size: 13px;
cursor: pointer;
`;
btn.addEventListener('click', autoSelectBestRaid);
target.parentElement.appendChild(btn);
}
// ── MAIN LOOP ────────────────────────────────────────────────────────
let stuckCounter = 0;
window.addEventListener('load', () => {
setInterval(() => {
injectRaidButton();
if (raidRunning) return;
if (tryCloseAd()) { stuckCounter = 0; return; }
if (tryBackToPacks()) { stuckCounter = 0; return; }
if (tryWatchAd()) { stuckCounter = 0; return; }
if (tryOpenPack()) { stuckCounter = 0; return; }
stuckCounter++;
if (stuckCounter >= 5) {
const onPackPage = !!document.querySelector('img[alt="Wiki Pack"]') ||
[...document.querySelectorAll('span')].some(s => s.textContent.trim() === '📺 Watch Ad to Refill');
if (onPackPage) {
console.log('[Wikigacha] Stuck on pack page, attempting recovery...');
tryRecoverFromError();
}
stuckCounter = 0;
}
}, INTERVAL);
});
})();