// ==UserScript== // @name Jasbee Gebäude-Prozentanzeige // @namespace http://tampermonkey.net/ // @version 3.7 // @description Scannt alle Gebäude im Hintergrund über direkte Pfade (Unterstützt neues Layout, robuste Pfeilerkennung per URL & Namenskorrektur) // @author Daniel + Gemini // @match https://www.jasbee.de/module/* // @grant none // ==/UserScript== (function() { 'use strict'; const allowedPages = [ 'city.php', 'lager.php', 'baumarkt.php', 'sportsbar.php', 'aliengeb.php', 'sauna.php', 'haus.php', 'fussball.php', 'schwimmhalle.php', 'fabrik.php', 'fitness.php', 'bazar.php' ]; const currentPath = window.location.pathname; const currentPage = currentPath.substring(currentPath.lastIndexOf('/') + 1).toLowerCase(); if (!allowedPages.some(page => currentPage.includes(page))) { return; } const popup = document.createElement('div'); popup.id = 'gebaeude-prozent-popup'; popup.style.position = 'fixed'; popup.style.top = '10px'; popup.style.right = '10px'; popup.style.backgroundColor = 'rgba(20, 20, 20, 0.95)'; popup.style.color = '#fff'; popup.style.padding = '15px'; popup.style.borderRadius = '8px'; popup.style.boxShadow = '0 4px 15px rgba(0,0,0,0.6)'; popup.style.zIndex = '2147483647'; popup.style.fontFamily = 'Segoe UI, Arial, sans-serif'; popup.style.fontSize = '13px'; popup.style.maxHeight = '400px'; popup.style.overflowY = 'auto'; popup.style.minWidth = '290px'; popup.style.border = '1px solid #444'; popup.style.userSelect = 'none'; popup.innerHTML = ` `; document.body.appendChild(popup); const scanBtn = document.getElementById('scan-jasbee-buildings'); if (currentPage.includes('city.php')) { scanBtn.style.display = 'inline-block'; } const header = document.getElementById('popup-header'); let isDragging = false; let currentX, currentY, initialX, initialY; let xOffset = 0, yOffset = 0; const savedPos = localStorage.getItem('jasbee_popup_pos'); if (savedPos) { const pos = JSON.parse(savedPos); popup.style.transform = `translate3d(${pos.x}px, ${pos.y}px, 0)`; xOffset = pos.x; yOffset = pos.y; } header.addEventListener('mousedown', (e) => { if (e.target === header) { initialX = e.clientX - xOffset; initialY = e.clientY - yOffset; isDragging = true; } }); document.addEventListener('mousemove', (e) => { if (isDragging) { e.preventDefault(); currentX = e.clientX - initialX; currentY = e.clientY - initialY; xOffset = currentX; yOffset = currentY; popup.style.transform = `translate3d(${currentX}px, ${currentY}px, 0)`; } }); document.addEventListener('mouseup', () => { if (isDragging) { isDragging = false; localStorage.setItem('jasbee_popup_pos', JSON.stringify({x: currentX, y: currentY})); } }); document.getElementById('clear-jasbee-data').addEventListener('click', () => { if (confirm('Möchtest du alle gespeicherten Zustandswerte löschen?')) { localStorage.removeItem('jasbee_building_data'); updateBuildingStatus(); } }); scanBtn.addEventListener('click', startBackgroundScan); function getStoredData() { const data = localStorage.getItem('jasbee_building_data'); return data ? JSON.parse(data) : {}; } function saveStoredData(data) { localStorage.setItem('jasbee_building_data', JSON.stringify(data)); } function extractBuildingState(doc) { const ringElement = doc.querySelector('.city-building-dashboard__ring'); if (ringElement) { const strongEl = ringElement.querySelector('strong'); if (strongEl && strongEl.textContent.includes('%')) { return strongEl.textContent.trim(); } const textContent = ringElement.textContent.trim(); if (textContent.includes('%')) { return textContent; } } const percentElements = doc.querySelectorAll('.pie-number'); for (let el of percentElements) { const txt = el.textContent.trim(); if (txt.includes('%')) { const parentCard = el.closest('.card'); if (parentCard) { const cardHeader = parentCard.querySelector('h3'); if (cardHeader && cardHeader.textContent.trim() === 'Gebäudezustand') { return txt; } } } } return ''; } function startBackgroundScan() { const targets = allowedPages .filter(page => page !== 'city.php') .map(page => `https://www.jasbee.de/module/${page}`); scanBtn.disabled = true; scanBtn.style.background = '#555'; let index = 0; const iframe = document.createElement('iframe'); iframe.style.display = 'none'; document.body.appendChild(iframe); function loadNext() { if (index >= targets.length) { document.body.removeChild(iframe); scanBtn.disabled = false; scanBtn.style.background = '#ff9800'; scanBtn.innerText = 'Alle scannen'; updateBuildingStatus(); return; } scanBtn.innerText = `Scan ${index + 1}/${targets.length}`; iframe.src = targets[index]; index++; } iframe.addEventListener('load', () => { try { const doc = iframe.contentDocument || iframe.contentWindow.document; let buildingName = ''; if (iframe.src.includes('aliengeb.php')) { buildingName = 'Aliengebäude'; } else { const breadcrumbItems = doc.querySelectorAll('.breadcrumb li'); if (breadcrumbItems.length > 0) { buildingName = breadcrumbItems[breadcrumbItems.length - 1].textContent.trim().replace(/[\t\r\n]/g, ''); } if (!buildingName) { const currentTarget = targets[index - 1]; const pageName = currentTarget.substring(currentTarget.lastIndexOf('/') + 1).replace('.php', ''); buildingName = pageName.charAt(0).toUpperCase() + pageName.slice(1); } } const stateValue = extractBuildingState(doc); if (buildingName && stateValue) { let currentStorage = getStoredData(); currentStorage[buildingName] = { value: stateValue, url: iframe.src }; saveStoredData(currentStorage); updateBuildingStatus(); } } catch (e) { console.error("Fehler beim Auslesen des Iframes:", e); } setTimeout(loadNext, 500); }); loadNext(); } function updateBuildingStatus() { const contentDiv = document.getElementById('popup-content'); let currentStorage = getStoredData(); let hasNewData = false; let buildingName = ''; if (window.location.href.includes('aliengeb.php')) { buildingName = 'Aliengebäude'; } else { const breadcrumbItems = document.querySelectorAll('.breadcrumb li'); if (breadcrumbItems.length > 0) { buildingName = breadcrumbItems[breadcrumbItems.length - 1].textContent.trim().replace(/[\t\r\n]/g, ''); } } if (buildingName && !buildingName.toLowerCase().includes('city')) { const stateValue = extractBuildingState(document); if (stateValue) { const oldVal = (typeof currentStorage[buildingName] === 'object') ? currentStorage[buildingName].value : currentStorage[buildingName]; if (oldVal !== stateValue) { currentStorage[buildingName] = { value: stateValue, url: window.location.href }; hasNewData = true; } } } if (hasNewData) { saveStoredData(currentStorage); } let buildingList = []; for (let name in currentStorage) { const entry = currentStorage[name]; const val = (typeof entry === 'object') ? entry.value : entry; const url = (typeof entry === 'object') ? entry.url : ''; buildingList.push({ name: name, value: val, url: url, numeric: parseFloat(val) || 0 }); } if (buildingList.length === 0) { contentDiv.innerHTML = 'Noch keine Zustände erfasst. Klicke auf "Alle scannen" oder besuche deine Gebäude.'; } else { buildingList.sort((a, b) => a.numeric - b.numeric); let html = ''; buildingList.forEach(item => { let color = '#4caf50'; if (item.numeric < 50) color = '#f44336'; else if (item.numeric < 90) color = '#ffeb3b'; // Robuster Vergleich: Entweder über den Gebäudenamen ODER über den Dateinamen der URL let isCurrentBuilding = false; if (buildingName && item.name.toLowerCase() === buildingName.toLowerCase()) { isCurrentBuilding = true; } else if (item.url && window.location.href) { const currentFile = window.location.pathname.split('/').pop().toLowerCase(); const itemFile = item.url.split('/').pop().toLowerCase(); if (currentFile && itemFile && currentFile === itemFile && currentFile !== 'city.php') { isCurrentBuilding = true; } } const isCurrentStyle = isCurrentBuilding ? 'background-color: rgba(255,255,255,0.08); font-style: italic;' : ''; const prefix = isCurrentBuilding ? '➡️ ' : ''; const nameDisplay = item.url ? `${prefix}${item.name}` : `${prefix}${item.name}`; html += ``; }); html += '
${nameDisplay} ${item.value}
'; contentDiv.innerHTML = html; } } updateBuildingStatus(); })();