primo commit
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
/* 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();
|
||||
})();
|
||||
Reference in New Issue
Block a user