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();
= htmlspecialchars($languageManager->get('gallery', $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
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+
+
+
+ = htmlspecialchars($error ?: 'Bereit für den Start. Nutzen Sie die Steuerung, um die Route zu erforschen.') ?>
+
+
+
+
+
+
+
+
+ Hop = (int) $hop['hop'] ?>
+ = $hop['avgLatency'] !== null ? $hop['avgLatency'] . ' ms' : '—' ?>
+
+ = htmlspecialchars($hop['ip']) ?>
+ = htmlspecialchars($hop['raw']) ?>
+
+
+
+
+
+
+
+
+
+
Kein WebGL? Kein Problem.
+
Diese Version nutzt ein Canvas-Emulator-Setup, das auch ohne WebGL läuft. Sollte das Canvas dennoch nicht unterstützt sein, aktualisieren Sie Ihren Browser.
+
+
+
+
+
+
+