diff --git a/index3.php b/index3.php index 88fe8c7..f3f1c13 100644 --- a/index3.php +++ b/index3.php @@ -95,9 +95,6 @@ class LanguageManager 'share' => 'Teilen', 'pip' => 'Bild-in-Bild', 'stats' => 'Stream-Status', - 'starlink' => 'Starlink-Verbindung', - 'starlink_caption' => 'Scanne den QR-Code für das Starlink Satelliteninternet.', - 'starlink_alt' => 'Starlink QR-Code', ], 'en' => [ 'title' => 'Aurora Weather Livecam', @@ -127,9 +124,6 @@ class LanguageManager 'share' => 'Share', 'pip' => 'Picture-in-Picture', 'stats' => 'Stream status', - 'starlink' => 'Starlink Connection', - 'starlink_caption' => 'Scan the QR code to reach Starlink satellite internet.', - 'starlink_alt' => 'Starlink QR code', ], 'fr' => [ 'title' => 'Aurora Weather Livecam', @@ -159,9 +153,6 @@ class LanguageManager 'share' => 'Partager', 'pip' => 'Picture-in-Picture', 'stats' => 'Statut du flux', - 'starlink' => 'Connexion Starlink', - 'starlink_caption' => 'Scannez le QR code pour accéder à l’internet satellite Starlink.', - 'starlink_alt' => 'QR code Starlink', ], 'it' => [ 'title' => 'Aurora Weather Livecam', @@ -191,41 +182,6 @@ class LanguageManager 'share' => 'Condividi', 'pip' => 'Picture-in-Picture', 'stats' => 'Stato del flusso', - 'starlink' => 'Connessione Starlink', - 'starlink_caption' => 'Scansiona il QR code per accedere a Starlink Internet satellitare.', - 'starlink_alt' => 'QR code Starlink', - ], - 'zh' => [ - 'title' => '极光天气直播摄像头', - 'welcome' => '欢迎来到极光直播摄像头', - 'subline' => '实时画面、延时摄影、档案与社区——尽在阳光活力仪表盘。', - 'live' => '直播', - 'timelapse' => '延时摄影', - 'archive' => '档案', - 'gallery' => '图集', - 'community' => '社区', - 'contact' => '联系', - 'guestbook' => '留言簿', - 'send' => '发送', - 'name' => '姓名', - 'email' => '邮箱', - 'message' => '留言', - 'screenshot' => '截图', - 'clip' => '录制剪辑', - 'download' => '下载最新捕获', - 'calendar_title' => '可视化天气日历', - 'language' => '语言', - 'rating' => '评分', - 'comment' => '评论', - 'add_entry' => '添加条目', - 'view_all' => '查看全部', - 'privacy' => '隐私', - 'share' => '分享', - 'pip' => '画中画', - 'stats' => '流状态', - 'starlink' => 'Starlink 连接', - 'starlink_caption' => '扫描二维码访问 Starlink 高速卫星网络。', - 'starlink_alt' => 'Starlink 二维码', ], ]; @@ -266,9 +222,9 @@ class WebcamManager public function getImageFiles(): array { - $files = glob(IMAGE_DIR . '/screenshot_*.jpg') ?: []; - usort($files, static fn(string $a, string $b) => filemtime($b) <=> filemtime($a)); - return array_slice($files, 0, 10); + $files = glob(IMAGE_DIR . '/screenshot_*.jpg'); + rsort($files); + return $files; } public function getLatestVideo(): ?string @@ -328,38 +284,32 @@ class WebcamManager public function getGallery(): array { $images = []; - foreach (glob(GALLERY_DIR . '/*.{jpg,jpeg,png,gif}', GLOB_BRACE) ?: [] as $file) { - $timestamp = filemtime($file) ?: 0; + foreach (glob(GALLERY_DIR . '/*.{jpg,jpeg,png,gif}', GLOB_BRACE) as $file) { $images[] = [ 'src' => str_replace(__DIR__ . '/', '', $file), - 'date' => date('Y-m-d H:i', $timestamp), - 'timestamp' => $timestamp, + 'date' => date('Y-m-d H:i', filemtime($file)) ]; } - usort($images, static fn(array $a, array $b) => $b['timestamp'] <=> $a['timestamp']); - $images = array_slice($images, 0, 10); - return array_map(static fn(array $image) => [ - 'src' => $image['src'], - 'date' => $image['date'], - ], $images); + usort($images, static fn(array $a, array $b) => strcmp($b['date'], $a['date'])); + return array_slice($images, 0, 20); } } class VisualCalendarManager { private array $monthNames = [ - 1 => ['de' => 'Januar', 'en' => 'January', 'it' => 'Gennaio', 'fr' => 'Janvier', 'zh' => '一月'], - 2 => ['de' => 'Februar', 'en' => 'February', 'it' => 'Febbraio', 'fr' => 'Février', 'zh' => '二月'], - 3 => ['de' => 'März', 'en' => 'March', 'it' => 'Marzo', 'fr' => 'Mars', 'zh' => '三月'], - 4 => ['de' => 'April', 'en' => 'April', 'it' => 'Aprile', 'fr' => 'Avril', 'zh' => '四月'], - 5 => ['de' => 'Mai', 'en' => 'May', 'it' => 'Maggio', 'fr' => 'Mai', 'zh' => '五月'], - 6 => ['de' => 'Juni', 'en' => 'June', 'it' => 'Giugno', 'fr' => 'Juin', 'zh' => '六月'], - 7 => ['de' => 'Juli', 'en' => 'July', 'it' => 'Luglio', 'fr' => 'Juillet', 'zh' => '七月'], - 8 => ['de' => 'August', 'en' => 'August', 'it' => 'Agosto', 'fr' => 'Août', 'zh' => '八月'], - 9 => ['de' => 'September', 'en' => 'September', 'it' => 'Settembre', 'fr' => 'Septembre', 'zh' => '九月'], - 10 => ['de' => 'Oktober', 'en' => 'October', 'it' => 'Ottobre', 'fr' => 'Octobre', 'zh' => '十月'], - 11 => ['de' => 'November', 'en' => 'November', 'it' => 'Novembre', 'fr' => 'Novembre', 'zh' => '十一月'], - 12 => ['de' => 'Dezember', 'en' => 'December', 'it' => 'Dicembre', 'fr' => 'Décembre', 'zh' => '十二月'], + 1 => ['de' => 'Januar', 'en' => 'January', 'it' => 'Gennaio', 'fr' => 'Janvier'], + 2 => ['de' => 'Februar', 'en' => 'February', 'it' => 'Febbraio', 'fr' => 'Février'], + 3 => ['de' => 'März', 'en' => 'March', 'it' => 'Marzo', 'fr' => 'Mars'], + 4 => ['de' => 'April', 'en' => 'April', 'it' => 'Aprile', 'fr' => 'Avril'], + 5 => ['de' => 'Mai', 'en' => 'May', 'it' => 'Maggio', 'fr' => 'Mai'], + 6 => ['de' => 'Juni', 'en' => 'June', 'it' => 'Giugno', 'fr' => 'Juin'], + 7 => ['de' => 'Juli', 'en' => 'July', 'it' => 'Luglio', 'fr' => 'Juillet'], + 8 => ['de' => 'August', 'en' => 'August', 'it' => 'Agosto', 'fr' => 'Août'], + 9 => ['de' => 'September', 'en' => 'September', 'it' => 'Settembre', 'fr' => 'Septembre'], + 10 => ['de' => 'Oktober', 'en' => 'October', 'it' => 'Ottobre', 'fr' => 'Octobre'], + 11 => ['de' => 'November', 'en' => 'November', 'it' => 'Novembre', 'fr' => 'Novembre'], + 12 => ['de' => 'Dezember', 'en' => 'December', 'it' => 'Dicembre', 'fr' => 'Décembre'], ]; public function getMonthData(int $year, int $month): array @@ -743,27 +693,6 @@ $translations = $languageManager->getAllTranslations(); justify-content: space-between; } - .qr-wrapper { - display: flex; - flex-direction: column; - align-items: center; - gap: 10px; - } - - .qr-wrapper img { - width: 160px; - height: 160px; - border-radius: 12px; - box-shadow: 0 12px 24px rgba(0,0,0,0.12); - background: white; - padding: 6px; - } - - .qr-wrapper small { - text-align: center; - color: rgba(0,0,0,0.6); - } - .badge { display: inline-flex; align-items: center; @@ -939,15 +868,6 @@ $translations = $languageManager->getAllTranslations();

get('gallery', $locale)) ?>

-
-

get('starlink', $locale)) ?>

-
- - <?= htmlspecialchars($languageManager->get('starlink_alt', $locale)) ?> - - get('starlink_caption', $locale)) ?> -
-
diff --git a/route2.php b/route2.php new file mode 100644 index 0000000..66a4032 --- /dev/null +++ b/route2.php @@ -0,0 +1,722 @@ +&1'; + $rawOutput = shell_exec($command); + if ($rawOutput === null) { + $error = 'Traceroute konnte nicht ausgeführt werden. Ist das Kommando verfügbar?'; + } else { + $traceData = parseTraceroute($rawOutput); + if (empty($traceData)) { + $error = 'Keine Hops gefunden. Prüfen Sie den Hostnamen oder versuchen Sie es später erneut.'; + } + } + } +} + +if (empty($traceData)) { + $traceData = getSampleTrace(); + if ($error === '') { + $error = 'Es werden Beispieldaten angezeigt. Starten Sie eine Abfrage, um echte Traceroute-Daten zu sehen.'; + } +} + +$positions = generateGalaxyLayout(count($traceData)); +$traceWithPositions = array_map(function ($hop, $index) use ($positions) { + return $hop + [ + 'position' => $positions[$index] ?? ['x' => 0, 'y' => 0, 'z' => 0], + ]; +}, $traceData, array_keys($traceData)); + +function parseTraceroute(string $raw): array +{ + $lines = preg_split('/\r?\n/', trim($raw)); + if (!$lines) { + return []; + } + + $hops = []; + foreach ($lines as $line) { + if (!preg_match('/^\s*(\d+)\s+(.+)/', $line, $parts)) { + continue; + } + + $hopNumber = (int) $parts[1]; + $rest = $parts[2]; + + preg_match('/([0-9a-fA-F:\.\-]+|\*)/', $rest, $ipMatch); + $ip = $ipMatch[1] ?? '*'; + $ip = $ip === '*' ? 'Zeitüberschreitung' : $ip; + + preg_match_all('/(\d+\.\d+)\s+ms/', $rest, $latencyMatches); + $latencies = array_map('floatval', $latencyMatches[1] ?? []); + $avgLatency = !empty($latencies) ? round(array_sum($latencies) / count($latencies), 2) : null; + + $hops[] = [ + 'hop' => $hopNumber, + 'ip' => $ip, + 'avgLatency' => $avgLatency, + 'raw' => trim($line), + ]; + } + + return $hops; +} + +function getSampleTrace(): array +{ + return [ + ['hop' => 1, 'ip' => '192.168.0.1', 'avgLatency' => 1.23, 'raw' => '1 192.168.0.1 1.12 ms 1.20 ms 1.38 ms'], + ['hop' => 2, 'ip' => '10.12.34.1', 'avgLatency' => 9.87, 'raw' => '2 10.12.34.1 9.44 ms 9.90 ms 10.29 ms'], + ['hop' => 3, 'ip' => '172.16.5.4', 'avgLatency' => 18.54, 'raw' => '3 172.16.5.4 18.12 ms 18.45 ms 18.71 ms'], + ['hop' => 4, 'ip' => '198.51.100.12', 'avgLatency' => 27.42, 'raw' => '4 198.51.100.12 27.03 ms 27.54 ms 27.68 ms'], + ['hop' => 5, 'ip' => '203.0.113.5', 'avgLatency' => 36.18, 'raw' => '5 203.0.113.5 35.82 ms 36.19 ms 36.52 ms'], + ['hop' => 6, 'ip' => '93.184.216.34', 'avgLatency' => 48.91, 'raw' => '6 93.184.216.34 48.44 ms 48.90 ms 49.39 ms'], + ]; +} + +function generateGalaxyLayout(int $count): array +{ + $positions = []; + $radiusStep = 28; + $angleOffset = pi() * (3 - sqrt(5)); // Golden angle + $heightStep = 12; + + for ($i = 0; $i < $count; $i++) { + $radius = ($i + 1) * 4 + ($i % 2 === 0 ? $radiusStep : $radiusStep * 0.6); + $angle = $i * $angleOffset; + $y = ($i - $count / 2) * $heightStep; + + $positions[] = [ + 'x' => cos($angle) * $radius, + 'y' => $y, + 'z' => sin($angle) * $radius, + ]; + } + + return $positions; +} +?> + + + + + + HyperTracer 3D + + + + + + +
+

HyperTracer 3D

+
+ + + +
+
+
+ +
+ +
+
Hop 1:
+
+
+ WebGL konnte nicht initialisiert werden. Bitte verwenden Sie einen modernen Browser oder aktivieren Sie WebGL. +
+
+
+ + + diff --git a/route3.php b/route3.php new file mode 100644 index 0000000..8640f33 --- /dev/null +++ b/route3.php @@ -0,0 +1,673 @@ +&1'; + $rawOutput = shell_exec($command); + if ($rawOutput === null) { + $error = 'Traceroute konnte nicht ausgeführt werden. Ist das Kommando verfügbar?'; + } else { + $traceData = parseTraceroute($rawOutput); + if (empty($traceData)) { + $error = 'Keine Hops gefunden. Prüfen Sie den Hostnamen oder versuchen Sie es später erneut.'; + } + } + } +} + +if (empty($traceData)) { + $traceData = getSampleTrace(); + if ($error === '') { + $error = 'Es werden Beispieldaten angezeigt. Starten Sie eine Abfrage, um echte Traceroute-Daten zu sehen.'; + } +} + +$positions = generateHelixLayout(count($traceData)); +$traceWithPositions = array_map(function ($hop, $index) use ($positions) { + return $hop + [ + 'position' => $positions[$index] ?? ['x' => 0, 'y' => 0, 'z' => 0], + ]; +}, $traceData, array_keys($traceData)); + +function parseTraceroute(string $raw): array +{ + $lines = preg_split('/\r?\n/', trim($raw)); + if (!$lines) { + return []; + } + + $hops = []; + foreach ($lines as $line) { + if (!preg_match('/^\s*(\d+)\s+(.+)/', $line, $parts)) { + continue; + } + + $hopNumber = (int) $parts[1]; + $rest = $parts[2]; + + preg_match('/([0-9a-fA-F:\.\-]+|\*)/', $rest, $ipMatch); + $ip = $ipMatch[1] ?? '*'; + $ip = $ip === '*' ? 'Zeitüberschreitung' : $ip; + + preg_match_all('/(\d+\.\d+)\s+ms/', $rest, $latencyMatches); + $latencies = array_map('floatval', $latencyMatches[1] ?? []); + $avgLatency = !empty($latencies) ? round(array_sum($latencies) / count($latencies), 2) : null; + + $hops[] = [ + 'hop' => $hopNumber, + 'ip' => $ip, + 'avgLatency' => $avgLatency, + 'raw' => trim($line), + ]; + } + + return $hops; +} + +function getSampleTrace(): array +{ + return [ + ['hop' => 1, 'ip' => '192.168.0.1', 'avgLatency' => 1.23, 'raw' => '1 192.168.0.1 1.12 ms 1.20 ms 1.38 ms'], + ['hop' => 2, 'ip' => '10.12.34.1', 'avgLatency' => 9.87, 'raw' => '2 10.12.34.1 9.44 ms 9.90 ms 10.29 ms'], + ['hop' => 3, 'ip' => '172.16.5.4', 'avgLatency' => 18.54, 'raw' => '3 172.16.5.4 18.12 ms 18.45 ms 18.71 ms'], + ['hop' => 4, 'ip' => '198.51.100.12', 'avgLatency' => 27.42, 'raw' => '4 198.51.100.12 27.03 ms 27.54 ms 27.68 ms'], + ['hop' => 5, 'ip' => '203.0.113.5', 'avgLatency' => 36.18, 'raw' => '5 203.0.113.5 35.82 ms 36.19 ms 36.52 ms'], + ['hop' => 6, 'ip' => '93.184.216.34', 'avgLatency' => 48.91, 'raw' => '6 93.184.216.34 48.44 ms 48.90 ms 49.39 ms'], + ]; +} + +function generateHelixLayout(int $count): array +{ + $positions = []; + $radius = 160; + $heightStep = 70; + $angleStep = pi() / 3; + + for ($i = 0; $i < $count; $i++) { + $angle = $i * $angleStep; + $y = ($i - ($count - 1) / 2) * $heightStep; + $positions[] = [ + 'x' => cos($angle) * $radius, + 'y' => $y, + 'z' => sin($angle) * $radius, + ]; + } + + return $positions; +} +?> + + + + + + HyperTracer Canvas Edition + + + + + + +
+

HyperTracer — Canvas Flight Deck

+
+ + +
+
+ + + +
+ + +
+ + + +