// ==UserScript==
// @name TSOlastBreath
// @namespace TSOlastBreath
// @description Allow run TSO in old client
// @author Sin aka Brutus
// @version 2.8
// @grant none
// @match https://www.thesettlersonline.com.br/*
// @match https://www.thesettlersonline.com/*
// @match https://www.thesettlersonline.net/*
// @match https://www.thesettlersonline.fr/*
// @match https://www.thesettlersonline.cz/*
// @match https://www.diesiedleronline.de/*
// @match https://www.thesettlersonline.gr/*
// @match https://www.thesettlersonline.it/*
// @match https://www.juego-thesettlersonline.com/*
// @match https://www.thesettlersonline.nl/*
// @match https://www.thesettlersonline.pl/*
// @match https://www.thesettlersonline.ro/*
// @match https://www.thesettlersonline.ru/*
// @match https://www.thesettlersonline.es/*
// @match https://www.tsotesting.com/en/*
// ==/UserScript==

(() => {
 'use strict';

 const MENU = '#menu ul';
 const LOGOUT = '.jsInstance-logout';
 const CLIENT_URL = 'https://sammlerworld.de/files/client.swf';

 // Alles nach diesem Datum gilt als "neu" => rot
 const NEW_FROM_DATE = new Date('2026-10-01T00:00:00Z');

 // Genau dieses Datum gilt als korrekt/tatsächlich => grün
 const EXPECTED_CLIENT_DATE = 'Tue, 13 Oct 2026 00:00:00 GMT';

 const mk = (text, href, id, cls, title, img) => {
 const li = document.createElement('li');
 li.className = cls;

 const a = document.createElement('a');
 a.id = id;
 a.href = href;
 a.title = title;

 if (img) {
 a.appendChild(Object.assign(document.createElement('img'), {
 src: img,
 width: 16,
 height: 16,
 alt: ''
 }));
 }

 a.appendChild(document.createTextNode(text));
 li.appendChild(document.createElement('span'));
 li.appendChild(a);
 return li;
 };

 const get = (re, src) => (src.match(re) || [])[1] || null;

 const addStyle = () => {
 const style = document.createElement('style');
 style.textContent = `
.new-client a {
 color: red !important;
 font-weight: bold !important;
 }
.valid-client a {
 color: green !important;
 font-weight: bold !important;
 }
 `;
 document.head.appendChild(style);
 };

 const formatDate = (dateString) => {
 if (!dateString) return 'unbekannt';

 const d = new Date(dateString);
 if (Number.isNaN(d.getTime())) return 'unbekannt';

 return d.toLocaleDateString('de-DE', {
 day: '2-digit',
 month: '2-digit',
 year: 'numeric'
 });
 };

 async function getLastModified(url) {
 try {
 let r = await fetch(url, {
 method: 'HEAD',
 cache: 'no-store'
 });

 if (!r.ok || !r.headers.get('last-modified')) {
 r = await fetch(url, {
 method: 'GET',
 cache: 'no-store'
 });
 }

 if (!r.ok) return null;
 return r.headers.get('last-modified');
 } catch (e) {
 console.error('Last-Modified Prüfung fehlgeschlagen:', url, e);
 return null;
 }
 }

 async function startClient(origin) {
 try {
 const playNow = get(/playNowforwardUrl\s*=\s*"([^"]+)";/, document.body.innerHTML);
 if (!playNow) return alert('Fehler: playNowforwardUrl nicht gefunden');

 const res = await fetch(origin + playNow, {
 credentials: 'include',
 redirect: 'manual'
 });

 const tso = get(/return "(lang.*)"/, await res.text());
 if (!tso) return alert('Fehler: Client-Daten nicht gefunden');

 location.href = `tso://${tso}&baseUri=${encodeURIComponent(origin)}`;
 } catch (e) {
 console.error(e);
 alert('Fehler beim Starten des Clients');
 }
 }

 const init = async () => {
 if (!document.querySelector(LOGOUT) || !document.querySelector(MENU)) return;

 addStyle();

 const menu = document.querySelector(MENU);
 const currentDateRaw = await getLastModified(CLIENT_URL);
 const currentDate = currentDateRaw ? new Date(currentDateRaw) : null;

 const currentDateText = formatDate(currentDateRaw);
 const expectedDateText = formatDate(EXPECTED_CLIENT_DATE);

 const isNewClient = currentDate && !Number.isNaN(currentDate.getTime()) && currentDate > NEW_FROM_DATE;
 const isExpectedClient = currentDateText !== 'unbekannt' && currentDateText === expectedDateText;

 let cssClass = 'sub';
 if (isExpectedClient) {
 cssClass = 'sub valid-client';
 } else if (isNewClient) {
 cssClass = 'sub new-client';
 }

 const swfText = currentDateRaw === null
 ? ' Neue client.swf (Datum unbekannt) '
 : ` Neue client.swf (${currentDateText}) `;

 const swfTitle = currentDateRaw === null
 ? 'Neue client.swf - Datum unbekannt'
 : isExpectedClient
 ? `client.swf hat das erwartete Datum (${currentDateText})`
 : isNewClient
 ? `Neue client.swf vom ${currentDateText}`
 : `client.swf vom ${currentDateText}`;

 menu.append(
 mk(
 ' Spiele mit Client ',
 '#',
 'clplay',
 'promotion first',
 'Spielen Sie mit dem DSO-Client',
 'https://tso-pl-ssl.cdn.ubi.com/sites/default/themes/siedler/images/community/news/forward.png'
 ),
 mk(
 swfText,
 CLIENT_URL,
 'clswf',
 cssClass,
 swfTitle,
 'https://forum.thesettlersonline.pl/images/settlers/statusicon/thread_lock-16.png'
 ),
 mk(
 ' Taktikkarten ',
 'https://dso-karten.com',
 'clcards',
 'promotion first',
 'Taktikkarten',
 'https://forum.thesettlersonline.pl/images/settlers/statusicon/thread_lock-16.png'
 ),
 mk(
 ' Zur Client-Seite ',
 'https://sammlerworld.de',
 'clsite',
 'promotion first',
 'Client-Seite',
 'https://forum.thesettlersonline.pl/images/settlers/statusicon/thread_lock-16.png'
 )
 );

 document.getElementById('clplay')?.addEventListener('click', e => {
 e.preventDefault();
 startClient(location.origin);
 });
 };

 init();
})();