98 lines
3.3 KiB
JavaScript
98 lines
3.3 KiB
JavaScript
/* OGame Spy Auto-Importer — content script (isolated world)
|
|
*
|
|
* Esegue SOLO sulle pagine OGame (vedi manifest: *.ogame.gameforge.com).
|
|
*
|
|
* NON legge la clipboard (impossibile da content script: vale il permesso
|
|
* della pagina, non quello dell'estensione). Intercetta invece il token nel
|
|
* momento in cui viene copiato, tramite due sorgenti:
|
|
* 1) evento DOM 'copy' → Ctrl+C, tasto destro, execCommand('copy')
|
|
* 2) messaggio dal MAIN world → navigator.clipboard.writeText() (pulsante API)
|
|
*
|
|
* Il token intercettato viene inviato UNA volta al background che lo importa.
|
|
* Se il background è occupato o non ancora pronto, si concede un solo retry.
|
|
*/
|
|
'use strict';
|
|
|
|
// Stessa forma accettata dal server (ricerca dentro il testo copiato)
|
|
const TOKEN_SEARCH_RE = /(cr|sr|rr|mr)-[a-z]{2}-\d{1,3}-[0-9a-f]{40}/i;
|
|
const OGame_HOST_RE = /(^|\.)ogame\.gameforge\.com$/i;
|
|
const CHANNEL = 'ogame-spy-importer';
|
|
const RETRY_MS = 1500;
|
|
|
|
let autoImport = true;
|
|
const done = new Set(); // token già inviati con esito definitivo
|
|
const retried = new Set(); // token che hanno già usato il loro unico retry
|
|
let inflight = null; // token attualmente in invio
|
|
|
|
function isOgame() {
|
|
return OGame_HOST_RE.test(window.location.hostname);
|
|
}
|
|
|
|
function extractToken(text) {
|
|
if (!text || typeof text !== 'string') return null;
|
|
const m = text.match(TOKEN_SEARCH_RE);
|
|
return m ? m[0].toLowerCase() : null;
|
|
}
|
|
|
|
async function loadSettings() {
|
|
const d = await chrome.storage.local.get({ settings: undefined });
|
|
autoImport = !d.settings || d.settings.autoImport !== false;
|
|
}
|
|
|
|
async function sendCapture(token) {
|
|
try {
|
|
const r = await chrome.runtime.sendMessage({ type: 'capture', token });
|
|
return (r && r.status) || 'error';
|
|
} catch {
|
|
return 'unreachable'; // background non ancora pronto
|
|
}
|
|
}
|
|
|
|
async function handleToken(token) {
|
|
if (!token || !isOgame() || !autoImport) return;
|
|
|
|
// già gestito (o in corso): niente doppioni se scattano entrambe le sorgenti
|
|
if (done.has(token) || inflight === token) return;
|
|
|
|
inflight = token;
|
|
const status = await sendCapture(token);
|
|
inflight = null;
|
|
|
|
// 'busy'/'unreachable' = il background non ha risposto: un solo retry.
|
|
if (status === 'busy' || status === 'unreachable') {
|
|
if (!retried.has(token)) {
|
|
retried.add(token);
|
|
setTimeout(() => handleToken(token), RETRY_MS);
|
|
}
|
|
return;
|
|
}
|
|
// Esito definitivo: 'ok'/'dup'/'known' importato o già noto,
|
|
// 'error' fallito (il background ha già mostrato la notifica d'errore).
|
|
done.add(token);
|
|
}
|
|
|
|
// ---- sorgente 1: evento 'copy' (Ctrl+C, tasto destro, execCommand) ----
|
|
document.addEventListener('copy', (e) => {
|
|
try {
|
|
const text = e.clipboardData && e.clipboardData.getData('text');
|
|
const token = extractToken(text);
|
|
if (token) handleToken(token);
|
|
} catch (_) { /* noop */ }
|
|
}, true);
|
|
|
|
// ---- sorgente 2: writeText della pagina (main world → postMessage) ----
|
|
window.addEventListener('message', (e) => {
|
|
if (e.source !== window || !e.data || e.data.__ogameSpyImporter !== CHANNEL) return;
|
|
const token = extractToken(e.data.text);
|
|
if (token) handleToken(token);
|
|
});
|
|
|
|
chrome.storage.onChanged.addListener((changes, area) => {
|
|
if (area !== 'local' || !changes.settings) return;
|
|
autoImport = changes.settings.newValue.autoImport !== false;
|
|
});
|
|
|
|
(async function init() {
|
|
await loadSettings();
|
|
})();
|