primo commit
This commit is contained in:
@@ -0,0 +1,208 @@
|
||||
/* OGame Spy Auto-Importer — popup
|
||||
* Impostazioni piattaforma (IP/porta), toggle cattura/notifiche,
|
||||
* verifica connessione e import manuale di fallback.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const SETTINGS_KEY = 'settings';
|
||||
const DEFAULTS = { host: 'localhost', port: 8899, autoImport: true, notifications: true };
|
||||
|
||||
// Forme accettate per l'import manuale (come lato server)
|
||||
const TOKEN_RE = /^(cr|sr|rr|mr)-[a-z]{2}-\d{1,3}-[0-9a-f]{40}$/i;
|
||||
const RID_ONLY_RE = /^[0-9a-f]{40}$/i;
|
||||
|
||||
const refs = {
|
||||
host: document.getElementById('host'),
|
||||
port: document.getElementById('port'),
|
||||
targetUrl: document.getElementById('targetUrl'),
|
||||
btnCheck: document.getElementById('btnCheck'),
|
||||
statusDot: document.getElementById('statusDot'),
|
||||
statusText: document.getElementById('statusText'),
|
||||
autoImport: document.getElementById('autoImport'),
|
||||
notifications: document.getElementById('notifications'),
|
||||
btnImport: document.getElementById('btnImport'),
|
||||
importResult: document.getElementById('importResult'),
|
||||
lastImport: document.getElementById('lastImport'),
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------- utils
|
||||
|
||||
function loadSettings() {
|
||||
return new Promise((resolve) => {
|
||||
chrome.storage.local.get({ [SETTINGS_KEY]: DEFAULTS }, (d) => resolve({ ...DEFAULTS, ...(d[SETTINGS_KEY] || {}) }));
|
||||
});
|
||||
}
|
||||
|
||||
function saveSettings(cfg) {
|
||||
return new Promise((resolve) => {
|
||||
chrome.storage.local.set({ [SETTINGS_KEY]: cfg }, () => resolve());
|
||||
});
|
||||
}
|
||||
|
||||
function baseUrl(host, port) {
|
||||
return `http://${String(host || '').trim() || 'localhost'}:${port || 8899}`;
|
||||
}
|
||||
|
||||
function setStatus(cls, html) {
|
||||
refs.statusDot.className = 'dot ' + cls;
|
||||
refs.statusText.innerHTML = html;
|
||||
}
|
||||
|
||||
function renderLast(li) {
|
||||
if (!li) {
|
||||
refs.lastImport.textContent = 'Nessun import effettuato.';
|
||||
return;
|
||||
}
|
||||
if (li.ok) {
|
||||
refs.lastImport.innerHTML = `<span style="color:#6fdc8c">✓</span> ${esc(li.message)}`;
|
||||
} else {
|
||||
refs.lastImport.innerHTML = `<span style="color:#ff8a80">✗</span> ${esc(li.error)}`;
|
||||
}
|
||||
}
|
||||
|
||||
function esc(s) {
|
||||
const d = document.createElement('div');
|
||||
d.textContent = String(s == null ? '' : s);
|
||||
return d.innerHTML;
|
||||
}
|
||||
|
||||
function updateTarget() {
|
||||
refs.targetUrl.textContent = `${baseUrl(refs.host.value, refs.port.value)}/api/reports`;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------- server check
|
||||
|
||||
async function checkServer() {
|
||||
const host = refs.host.value.trim();
|
||||
const port = refs.port.value.trim();
|
||||
setStatus('wait', 'Verifica in corso…');
|
||||
try {
|
||||
const res = await fetch(`${baseUrl(host, port)}/api/bootstrap`, {
|
||||
signal: AbortSignal.timeout(5000),
|
||||
});
|
||||
const data = await res.json().catch(() => null);
|
||||
if (res.ok && data && data.ok) {
|
||||
const s = data.server || {};
|
||||
const universe = s.number ? `s${s.number}-${s.community || ''}` : (s.domain || '');
|
||||
setStatus('ok',
|
||||
`Connesso — <b>${esc(s.name || 'piattaforma')}</b>` +
|
||||
(universe ? `<small>${esc(universe)} · ${esc(s.galaxies || '?')} galassie</small>` : ''));
|
||||
return true;
|
||||
}
|
||||
setStatus('err', `Risposta del server: ${esc((data && data.error) || 'HTTP ' + res.status)}`);
|
||||
return false;
|
||||
} catch {
|
||||
setStatus('err', `Server non raggiungibile su ${esc(baseUrl(host, port))}.<br><small>Controlla IP/porta e che la piattaforma sia avviata.</small>`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------- import dalla clipboard
|
||||
|
||||
async function importFromClipboard() {
|
||||
let text;
|
||||
try {
|
||||
text = await navigator.clipboard.readText();
|
||||
} catch {
|
||||
refs.importResult.className = 'result err';
|
||||
refs.importResult.textContent = '✗ Impossibile leggere la clipboard.';
|
||||
return;
|
||||
}
|
||||
|
||||
const token = text.trim();
|
||||
refs.importResult.textContent = '';
|
||||
|
||||
if (!token) {
|
||||
refs.importResult.className = 'result err';
|
||||
refs.importResult.textContent = 'La clipboard è vuota. Copia un API string da OGame prima.';
|
||||
return;
|
||||
}
|
||||
if (!TOKEN_RE.test(token) && !RID_ONLY_RE.test(token)) {
|
||||
refs.importResult.className = 'result err';
|
||||
refs.importResult.textContent = 'Formato non riconosciuto. Atteso: sr-ar-170-<40 hex> o solo l\'id.';
|
||||
return;
|
||||
}
|
||||
|
||||
refs.btnImport.disabled = true;
|
||||
refs.btnImport.textContent = 'Importazione…';
|
||||
try {
|
||||
const r = await chrome.runtime.sendMessage({ type: 'importManual', token });
|
||||
if (r && r.ok) {
|
||||
refs.importResult.className = 'result ok';
|
||||
refs.importResult.textContent = (r.created ? '✓ Importato — ' : '✓ Già presente — ') + (r.message || '');
|
||||
} else {
|
||||
refs.importResult.className = 'result err';
|
||||
refs.importResult.textContent = '✗ ' + ((r && r.error) || 'Errore sconosciuto');
|
||||
}
|
||||
} catch {
|
||||
refs.importResult.className = 'result err';
|
||||
refs.importResult.textContent = '✗ Impossibile contattare il background. Ricarica l\'estensione.';
|
||||
} finally {
|
||||
refs.btnImport.disabled = false;
|
||||
refs.btnImport.textContent = 'Importa ora';
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------- init
|
||||
|
||||
async function init() {
|
||||
const cfg = await loadSettings();
|
||||
refs.host.value = cfg.host;
|
||||
refs.port.value = cfg.port;
|
||||
refs.autoImport.checked = cfg.autoImport !== false;
|
||||
refs.notifications.checked = cfg.notifications !== false;
|
||||
updateTarget();
|
||||
|
||||
// ultimo esito import (dal background)
|
||||
try {
|
||||
const st = await chrome.runtime.sendMessage({ type: 'getState' });
|
||||
if (st && st.ok) renderLast(st.lastImport);
|
||||
} catch { /* background non attivo: ignora */ }
|
||||
|
||||
// nessuna verifica automatica: la connessione si controlla solo col
|
||||
// pulsante "Verifica connessione"
|
||||
setStatus('', 'Premi “Verifica connessione” per testare il server');
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------- eventi
|
||||
|
||||
function onHostPortChanged() {
|
||||
updateTarget();
|
||||
// solo il pulsante "Verifica" interroga il server
|
||||
setStatus('', 'Impostazioni salvate — premi “Verifica connessione”');
|
||||
}
|
||||
|
||||
refs.host.addEventListener('change', async () => {
|
||||
const cfg = await loadSettings();
|
||||
await saveSettings({ ...cfg, host: refs.host.value.trim() || DEFAULTS.host });
|
||||
onHostPortChanged();
|
||||
});
|
||||
|
||||
refs.port.addEventListener('change', async () => {
|
||||
const cfg = await loadSettings();
|
||||
const p = parseInt(refs.port.value, 10);
|
||||
refs.port.value = (p >= 1 && p <= 65535) ? p : DEFAULTS.port;
|
||||
await saveSettings({ ...cfg, port: refs.port.value });
|
||||
onHostPortChanged();
|
||||
});
|
||||
|
||||
refs.autoImport.addEventListener('change', async () => {
|
||||
const cfg = await loadSettings();
|
||||
await saveSettings({ ...cfg, autoImport: refs.autoImport.checked });
|
||||
});
|
||||
|
||||
refs.notifications.addEventListener('change', async () => {
|
||||
const cfg = await loadSettings();
|
||||
await saveSettings({ ...cfg, notifications: refs.notifications.checked });
|
||||
});
|
||||
|
||||
refs.btnCheck.addEventListener('click', checkServer);
|
||||
refs.btnImport.addEventListener('click', importFromClipboard);
|
||||
|
||||
// aggiornamento live mentre il popup è aperto (es. import automatico in corso)
|
||||
chrome.storage.onChanged.addListener((changes, area) => {
|
||||
if (area !== 'local' || !changes.lastImport) return;
|
||||
renderLast(changes.lastImport.newValue);
|
||||
});
|
||||
|
||||
init();
|
||||
Reference in New Issue
Block a user