(() => { const FIREBASE_ENDPOINT = "https://bcrapi-default-rtdb.firebaseio.com"; const lastResults = {}; const updateLogs = []; // log hiện tại trên UI const allLogs = []; // lưu tất cả lịch sử kể cả khi clear // === Firebase helper === async function getFromFirebase(tableName) { try { const url = `${FIREBASE_ENDPOINT}/bcr/${tableName}.json`; const res = await fetch(url); return res.ok ? await res.json() : null; } catch { return null; } } async function saveToFirebase(table) { try { const payload = { table_name: table.table_name || "", cau: table.goodRoad || "", results: table.result || "" }; const curr = payload.results; if (!curr) return; const prevCache = lastResults[table.table_name] || ""; const prevFbData = await getFromFirebase(table.table_name); const prevFirebase = prevFbData?.results || ""; if (curr === prevCache || curr === prevFirebase) { safeLog(`⏩ Bỏ qua (trùng dữ liệu) ${table.table_name}`); return; } lastResults[table.table_name] = curr; const url = `${FIREBASE_ENDPOINT}/bcr/${table.table_name}.json`; const res = await fetch(url, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload) }); if (!res.ok) throw new Error(res.statusText); const log = { time: new Date().toLocaleTimeString(), table: table.table_name, old: prevFirebase || "(trống)", new: curr }; updateLogs.unshift(log); allLogs.unshift(log); if (updateLogs.length > 50) updateLogs.splice(50); renderMenu(); safeLog(`✅ Firebase (${table.table_name}): ${curr}`); } catch (err) { safeLog(`${table.table_name} lỗi Firebase: ${err.message}`); } } // === Menu === function renderMenu(showAll = false) { let menu = document.getElementById("firebase-update-menu"); if (!menu) { menu = document.createElement("div"); menu.id = "firebase-update-menu"; menu.style = ` position:fixed;top:10px;right:10px; background:rgba(0,0,0,0.85);color:#fff; padding:15px;border-radius:10px; z-index:999999;font-size:13px;font-family:monospace; max-height:90vh;overflow-y:auto;min-width:280px;`; document.body.appendChild(menu); } const logs = showAll ? allLogs : updateLogs; let html = `
🔥 Firebase Updates (FULL bàn + table_name)
`; html += ``; html += `
Lịch sử cập nhật (${logs.length}):
`; for (const log of logs) { html += `
[${log.time}] ${log.table}
Cũ: ${log.old}
Mới: ${log.new}
`; } menu.innerHTML = html; document.getElementById("toggleLogsBtn").onclick = () => renderMenu(!showAll); } // === Handle data === function handleData(data) { if (!data?.data) return; for (const table of data.data) { saveToFirebase(table); } } // === Hook XHR === const origOpen = XMLHttpRequest.prototype.open; const origSend = XMLHttpRequest.prototype.send; XMLHttpRequest.prototype.open = function (method, url, ...rest) { this._url = url; return origOpen.apply(this, [method, url, ...rest]); }; XMLHttpRequest.prototype.send = function (body) { this.addEventListener("load", function () { try { if (this._url.includes("/baccarat/getnewresult")) { let parsed; try { parsed = JSON.parse(this.responseText); } catch { parsed = null; } if (parsed) { safeLog("📥 Nhận response mới từ /baccarat/getnewresult"); handleData(parsed); } } } catch (e) { safeLog("❌ Hook error: " + e); } }); return origSend.apply(this, [body]); }; // === Spam check (polling) === setInterval(async () => { try { const res = await fetch("/baccarat/getnewresult", { method: "POST" }); if (res.ok) { const data = await res.json(); handleData(data); } } catch {} }, 5000); // check mỗi 5s // === Safe log (chặn spam getCase) === const origLog = console.log; function safeLog(...args) { const str = args.join(" "); if (str.startsWith("get Case:")) return; // chặn log spam origLog.apply(console, args); } console.log = safeLog; // === Auto clear console định kỳ === setInterval(() => { console.clear(); if (updateLogs.length > 20) updateLogs.splice(20); renderMenu(); safeLog("🧹 Đã clear console + giữ 20 log gần nhất (toàn bộ log lưu ở chế độ xem lịch sử)"); }, 3 * 60 * 1000); safeLog("🔥 Script chạy: Hook + Polling + Firebase (FULL bàn, thêm table_name, anti-spam, nút xem lịch sử)"); })();