summaryrefslogtreecommitdiff
path: root/pages
diff options
context:
space:
mode:
Diffstat (limited to 'pages')
-rw-r--r--pages/account.inc4
-rw-r--r--pages/api/disconnect.php12
-rw-r--r--pages/api/pluralkit-integration.php10
-rw-r--r--pages/api/save-private.php35
-rw-r--r--pages/api/save.php37
-rw-r--r--pages/api/timeline.php2
-rw-r--r--pages/byfront.inc62
-rw-r--r--pages/computers.inc1050
-rw-r--r--pages/contacts.inc273
-rw-r--r--pages/edit-private.inc40
-rw-r--r--pages/edit.inc44
-rw-r--r--pages/home.inc37
-rw-r--r--pages/metadata.inc6
-rw-r--r--pages/page.inc17
-rw-r--r--pages/pleasure.inc8
-rw-r--r--pages/schedules.inc60
-rw-r--r--pages/sessions.inc4
-rw-r--r--pages/stats.inc504
-rw-r--r--pages/terminology.inc15
19 files changed, 92 insertions, 2128 deletions
diff --git a/pages/account.inc b/pages/account.inc
index 4107f8f..b8fc9f5 100644
--- a/pages/account.inc
+++ b/pages/account.inc
@@ -22,6 +22,10 @@ require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/components/header.inc'; ?>
<img src="<?= icon('logout', null, true) ?>" style="margin-right: 5px; height: 24px; width: 24px;"><div style="display: flex; align-items: center; color: var(--bs-body-color);">Logout</div>
</a>
</div>
+
+ <hr>
+ <?php $version = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/version.json"), true); ?>
+ <p>Cold Haze System Software, build <?= $version["build"] ?>.<?= $version["revision"] ?> · © 2022-<?= date('Y') ?> <a href="https://equestria.dev" target="_blank">Equestria.dev Developers</a></p>
</div>
</div>
diff --git a/pages/api/disconnect.php b/pages/api/disconnect.php
index c4cf0bd..ffd3f40 100644
--- a/pages/api/disconnect.php
+++ b/pages/api/disconnect.php
@@ -13,13 +13,21 @@ $list = array_filter([...scandir($_SERVER['DOCUMENT_ROOT'] . "/includes/tokens")
$session = file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/tokens/" . $token) ? json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/tokens/" . $token), true) : json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/lowertokens/" . $token), true);
- return isset($session["last"]) && isset($session["profile"]) && ($session["profile"]["id"] ?? "") === ($_PROFILE["id"] ?? "");
+ return isset($session["id"]) && $session["id"] === ($_PROFILE["id"] ?? "");
});
+var_dump($list);
+
foreach ($list as $token) {
$session = file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/tokens/" . $token) ? json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/tokens/" . $token), true) : json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/lowertokens/" . $token), true);
- if (isset($_GET["id"]) && sha1($token) . md5($token) === $_GET["id"]) {
+ var_dump(bin2hex(substr($token, 0, 50)), trim($_GET["id"]));
+
+ if (bin2hex(substr($token, 0, 50)) === trim($_GET["id"])) {
+ if (file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/sessions/" . $token)) {
+ unlink($_SERVER['DOCUMENT_ROOT'] . "/includes/sessions/" . $token);
+ }
+
if (file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/tokens/" . $token)) {
unlink($_SERVER['DOCUMENT_ROOT'] . "/includes/tokens/" . $token);
} else {
diff --git a/pages/api/pluralkit-integration.php b/pages/api/pluralkit-integration.php
index 69d99b1..7d7c641 100644
--- a/pages/api/pluralkit-integration.php
+++ b/pages/api/pluralkit-integration.php
@@ -8,12 +8,6 @@ $inputJSON = file_get_contents('php://input');
$input = json_decode($inputJSON, true);
$data = $GLOBALS["ColdHazeApp"]["webhook"];
-if (isset($GLOBALS["ColdHazeApp"]["ponytown"][$user])) {
- $ponytown = $GLOBALS["ColdHazeApp"]["ponytown"][$user];
-} else {
- header("HTTP/1.1 404 Not Found") and die();
-}
-
if ($user === null) {
header("HTTP/1.1 500 Internal Server Error") and die();
}
@@ -32,6 +26,9 @@ if ($input['system_id'] === "7d9f543e-f742-40f6-9d07-86c3f2983124") {
} elseif ($input['system_id'] === "ade46823-206b-4b0c-ad3c-caae934a5f3b") {
$system = "ynmuc";
$name = "Cloudburst System";
+} elseif ($input['system_id'] === "d1cd97eb-9c92-4e42-94cd-4397a5074ff9") {
+ $system = "hrbom";
+ $name = "Moonglow";
} elseif (isset($app["other"]) && $input["system_id"] === $app["other"]["uuid"]) {
$system = $app["other"]["id"];
$name = $app["other"]["name"];
@@ -48,7 +45,6 @@ if ($input["type"] === "CREATE_MEMBER" || $input["type"] === "UPDATE_MEMBER" ||
createJob("UpdateAssets", [
"type" => "members"
]);
- createJob("UpdateLogo", []);
}
if ($input["type"] === "UPDATE_SYSTEM") {
diff --git a/pages/api/save-private.php b/pages/api/save-private.php
deleted file mode 100644
index 6843e2a..0000000
--- a/pages/api/save-private.php
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-
-require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/util/session.inc"; global $isLoggedIn;
-if (!$isLoggedIn) header("Location: /-/login") and die();
-
-$request_raw = file_get_contents('php://input');
-$json_object = json_decode($request_raw, true);
-
-$system = $_GET['system'] ?? null;
-$member = $_GET['member'] ?? null;
-$content = $json_object['content'] ?? null;
-
-if (!isset($system) || trim($system) === "" || strlen($system) !== 5 || !preg_match("/[a-z]/i", $system))
- peh_error("System not found", 404);
-
-if (!isset($member) || trim($member) === "" || strlen($member) !== 5 || !preg_match("/[a-z]/i", $member))
- if ($member !== null && $member !== "null") peh_error("System member not found", 404);
-
-if (!isset($content))
- peh_error("No content", 400);
-
-if ($member !== null && $member !== "null") {
- $file = $_SERVER['DOCUMENT_ROOT'] . "/includes/data/content/" . $member . "-private.html";
-} else {
- $file = $_SERVER['DOCUMENT_ROOT'] . "/includes/data/content/" . $system . ".html";
-}
-
-if (trim($content) === "") {
- if (file_exists($file)) {
- unlink($file);
- }
- die();
-}
-
-file_put_contents($file, $content); \ No newline at end of file
diff --git a/pages/api/save.php b/pages/api/save.php
deleted file mode 100644
index abb477d..0000000
--- a/pages/api/save.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/util/session.inc"; global $isLoggedIn; global $isLowerLoggedIn; global $app;
-if (!$isLoggedIn && !$isLowerLoggedIn) header("Location: /-/login") and die();
-
-$request_raw = file_get_contents('php://input');
-$json_object = json_decode($request_raw, true);
-
-$system = $_GET['system'] ?? null;
-$member = $_GET['member'] ?? null;
-$content = $json_object['content'] ?? null;
-
-if (!isset($system) || trim($system) === "" || strlen($system) !== 5 || !preg_match("/[a-z]/i", $system))
- peh_error("System not found", 404);
-
-if (!isset($member) || trim($member) === "" || strlen($member) !== 5 || !preg_match("/[a-z]/i", $member))
- if ($member !== null && $member !== "null") peh_error("System member not found", 404);
-
-if ($isLowerLoggedIn && $system !== $app["other"]["id"]) die();
-
-if (!isset($content))
- peh_error("No content", 400);
-
-if ($member !== null && $member !== "null") {
- $file = $_SERVER['DOCUMENT_ROOT'] . "/includes/data/content/" . $member . ".html";
-} else {
- $file = $_SERVER['DOCUMENT_ROOT'] . "/includes/data/" . $system . "/content.html";
-}
-
-if (trim($content) === "") {
- if (file_exists($file)) {
- unlink($file);
- }
- die();
-}
-
-file_put_contents($file, $content); \ No newline at end of file
diff --git a/pages/api/timeline.php b/pages/api/timeline.php
index 392d5de..ccd19f9 100644
--- a/pages/api/timeline.php
+++ b/pages/api/timeline.php
@@ -5,7 +5,7 @@ require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/util/session.inc"; global $i
$systems = array_filter(array_keys($_GET), function ($i) {
global $isLowerLoggedIn; global $isLoggedIn; global $app;
- return $i === "gdapd" || $i === "ynmuc" || (($isLowerLoggedIn || $isLoggedIn) && $i === $app["other"]["id"]);
+ return $i === "gdapd" || $i === "ynmuc" || $i === "hrbom" || (($isLowerLoggedIn || $isLoggedIn) && $i === $app["other"]["id"]);
});
require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/components/timeline.inc";
diff --git a/pages/byfront.inc b/pages/byfront.inc
index a8ff483..d3b8bf0 100644
--- a/pages/byfront.inc
+++ b/pages/byfront.inc
@@ -90,50 +90,12 @@ $travelling = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includ
})))
]; uasort($members, function ($a, $b) {
return $b["_lastFronted"] - $a["_lastFronted"];
- }); $members = array_reverse($members); foreach ($members as $member): if ($member["_lastFronted"] !== -1 && $member["_lastFronted"] !== time()):
+ }); $members = array_reverse($members); foreach ($members as $member): if ($member["_lastFronted"] <= time() - 86400 * 21):
- $metadata = $member["_metadata"];
-
- if (!isset($metadata["birth"]["year"]) || $metadata["birth"]["age"] > 0) {
- if ($metadata["birth"]["age"] === -1) {
- $age = abs(log(0));
- } elseif ($metadata["birth"]["age"] <= 0) {
- $age = null;
- } else {
- $age = $metadata["birth"]["age"];
- }
- } else {
- if ($metadata["birth"]["year"] <= 1900) {
- $age = null;
- } else {
- $age = (int)date('Y') - $metadata["birth"]["year"] + (strtotime(date('Y') . "-" . $metadata["birth"]["date"]) <= time() ? 0 : -1);
- }
- }
-
- if ((isset($age) && $age > 0 && time() > 1677628800) || time() <= 1677628800): ?>
- <div class="relation" style="margin-bottom:10px;padding:10px;border-radius:10px;display:grid;grid-template-columns: 1fr 2fr max-content;<?php if ($travelling[$member['id']]["travelling"] || ($member["_metadata"]["punished"] ?? false)): ?>opacity: 0.75;<?php endif; ?>">
+ $metadata = $member["_metadata"];?>
+ <div class="relation" style="margin-bottom:10px;padding:10px;border-radius:10px;display:grid;grid-template-columns: 1fr 2fr max-content;">
<a class="relation-intro" style="background-color:rgba(255, 255, 255, .05);border-right:1px solid rgba(255, 255, 255, .1);margin:-10px;padding:10px;border-top-left-radius:10px;border-bottom-left-radius:10px;color: white;display:flex;align-items:center;text-decoration: none;" href="/<?= $member["name"] ?>">
<img src="<?= getAsset($member['system'], $member["id"], "heads") ?>" style="width:24px;">&nbsp;<?= $member["display_name"] ?? $member["name"] ?>
- <span style="display: inline-block;margin-left: auto;">
- <?php if ($member["_metadata"]["not_fronting"]): ?>
- <span class="badge <?= isset($use2023UI) && $use2023UI ? "bg-success" : "bg-info text-black" ?> rounded-pill">Not fronting</span>
- <?php endif; ?>
- <?php if ($member["_metadata"]["less_frequent"] && !(isset($member["_metadata"]["not_fronting"]) && $member["_metadata"]["not_fronting"])): ?>
- <span class="badge bg-success rounded-pill">Less</span>
- <?php endif; ?>
- <?php if ($member["_metadata"]["persecutor"]): ?>
- <span class="badge <?= isset($use2023UI) && $use2023UI ? "bg-success" : "bg-light text-black" ?> rounded-pill">Persecutor</span>
- <?php endif; ?>
- <?php if (isset($member["_metadata"]["punished"]) && $member["_metadata"]["punished"]): ?>
- <span class="badge <?= isset($use2023UI) && $use2023UI ? "bg-success" : "bg-light text-black" ?> rounded-pill">Punished</span>
- <?php endif; ?>
- <?php if ($member["_metadata"]["shared_memory"] !== 2): ?>
- <span class="badge <?= isset($use2023UI) && $use2023UI ? "bg-success" : "text-black bg-warning" ?> rounded-pill">Memory</span>
- <?php endif; ?>
- <?php if ($travelling[$member['id']]["travelling"]): ?>
- <span class="badge <?= isset($use2023UI) && $use2023UI ? "bg-success" : "text-white bg-secondary" ?> rounded-pill">Travelling</span>
- <?php endif; ?>
- </span>
</a>
<div class="relation-item" style="display:flex;align-items:center;margin-left:10px;padding:0 20px;">
@@ -144,7 +106,23 @@ $travelling = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includ
<?php endif; ?>
</div>
</div>
- <?php endif; endif; endforeach; ?>
+ <?php endif; endforeach; ?><hr><?php foreach ($members as $member): if ($member["_lastFronted"] > time() - 86400 * 21):
+
+ $metadata = $member["_metadata"];?>
+ <div class="relation" style="margin-bottom:10px;padding:10px;border-radius:10px;display:grid;grid-template-columns: 1fr 2fr max-content;">
+ <a class="relation-intro" style="background-color:rgba(255, 255, 255, .05);border-right:1px solid rgba(255, 255, 255, .1);margin:-10px;padding:10px;border-top-left-radius:10px;border-bottom-left-radius:10px;color: white;display:flex;align-items:center;text-decoration: none;" href="/<?= $member["name"] ?>">
+ <img src="<?= getAsset($member['system'], $member["id"], "heads") ?>" style="width:24px;">&nbsp;<?= $member["display_name"] ?? $member["name"] ?>
+ </a>
+
+ <div class="relation-item" style="display:flex;align-items:center;margin-left:10px;padding:0 20px;">
+ <?php if ($member["_lastFronted"] === -1): ?>
+ Never fronted
+ <?php else: ?>
+ Last fronted <?= timeAgo($member["_lastFronted"]) ?><?php if ($member["_lastFronted"] !== time()): ?> (<?= date('l j F Y', $member["_lastFronted"]) ?>)<?php endif; ?>
+ <?php endif; ?>
+ </div>
+ </div>
+ <?php endif; endforeach; ?>
<style>
@media (max-width: 991px) {
diff --git a/pages/computers.inc b/pages/computers.inc
deleted file mode 100644
index 55d8ec5..0000000
--- a/pages/computers.inc
+++ /dev/null
@@ -1,1050 +0,0 @@
-<?php
-
-if (time() >= 1688169600) {
- peh_error("Page not found: computers", 404);
-}
-
-require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/init.inc"; global $title; global $isLoggedIn; global $lang; global $pages; global $pagename; global $_USER; global $_PROFILE;
-$computer = [];
-$parts = explode("/", $pagename);
-
-$names = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/computers/names.json"), true);
-
-if (isset($parts[1])) {
- if (file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/computers/metadata/" . $parts[1] . ".json")) {
- $computer = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/computers/metadata/" . $parts[1] . ".json"), true);
- $id = $parts[1];
- $owner = explode("-", $id)[0];
-
- if (count($parts) > 2) {
- $title = "Remote control · " . ($names[$id] ?? $computer["host"]) . " · " . $title;
- } else {
- $title = ($names[$id] ?? $computer["host"]) . " · " . $title;
- }
- } else {
- header("Location: /-/computers");
- die();
- }
-}
-
-if (isset($parts[2]) && $parts[2] !== "control") {
- header("Location: /-/computers/" . $parts[1]);
- die();
-}
-
-$parts = array_values(array_filter($parts, function ($i) {
- return $i !== "-";
-}));
-
-if (count($parts) === 2 || count($parts) === 3) {
- array_unshift($parts, null);
-}
-
-if (isset($computer["os"]) && str_ends_with($computer["os"], "unknown")) {
- $computer["os"] = trim(substr($computer["os"], 0, -7));
-}
-
-if (isset($computer["os"]) && str_ends_with($computer["os"], "rolling")) {
- $computer["os"] = trim(substr($computer["os"], 0, -7));
-}
-
-require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/components/header.inc';
-
-?>
-
-<script>
- window.userName = "<?php
-
- $fronters = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/" . ($_PROFILE["login"] === "raindrops" ? "gdapd" : "ynmuc") . "/fronters.json"), true);
- $name = $_PROFILE["login"] === "raindrops" ? "Raindrops System" : "Cloudburst Sys";
-
- if (count($fronters["members"]) > 0) {
- $name = $fronters["members"][0]["display_name"] ?? $fronters["members"][0]["name"];
- }
-
- echo($name);
-
- ?>";
-</script>
-
-<br>
-<div class="container">
- <?php if (isset($parts[2]) && !isset($parts[3])): $id = $parts[2]; ?>
- <div>
- <h2>
- <script>
- async function updateComputerName() {
- let name = document.getElementById("computer_name").innerText.trim();
-
- if (name === "") {
- name = "<?= $computer["host"] ?>";
- document.getElementById("computer_name").innerText = name;
- } else {
- await fetch("/api/computername?id=<?= $id ?>&name=" + encodeURIComponent(name));
- }
- }
- </script>
- <span id="computer_name" style="vertical-align: middle;" contenteditable="true" onkeyup="updateComputerName();"><?= $names[$id] ?? $computer["host"] ?></span>
- <a href="/-/computers" class="small btn btn-outline-light" style="float:right;margin-top:5px;vertical-align:middle;opacity:1 !important; color:white;">Back</a>
- </h2>
-
- <?php if ($computer["luna_version"] === "1.0.0"): ?>
- <div class="alert alert-danger">
- <p><b>We are unable to give you access to this device.</b></p>
- <p>This computer is running Luna version 1.0.0. This version of Luna is considered malware because of inconspicuous behavior and is therefore not usable anymore and has been disabled. This means you cannot access this computer at the moment.</p>
- Update this device to run Luna 1.1.0 or newer and try again.
- </div>
- <?php else: ?>
- <h4 style="margin-top: 20px;margin-bottom: 10px;">Overview</h4>
- <style>
- @media (max-width: 700px) {
- #g-0 {
- grid-template-columns: 1fr !important;
- }
-
- #g-0 img, #g-0 table {
- display: inline-block;
- margin-left: auto;
- margin-right: auto;
- }
-
- #g-0 table {
- margin-top: 20px;
- }
- }
- </style>
- <div style="display: grid; grid-template-columns: 256px 1fr; grid-column-gap: 30px;" id="g-0">
- <div style="display: flex; align-items: center;">
- <img style="width: 256px;" src="<?php
-
- if (isset($computer["dsb"])) {
- switch ($computer["dsb"]["platform"]) {
- case "chrome":
- echo("https://upload.wikimedia.org/wikipedia/en/3/3e/ChromeOS_screenshot.png");
- break;
-
- default:
- echo("https://ponies.equestria.horse/api/data?f=computers/screens/" . $id . "-" . $computer["screens"][0]["id"] . ".jpg");
- break;
- }
- } else {
- echo("https://ponies.equestria.horse/api/data?f=computers/screens/" . $id . "-" . $computer["screens"][0]["id"] . ".jpg");
- }
-
- ?>">
- </div>
- <div style="display: flex; align-items: center;">
- <table>
- <tbody>
- <tr>
- <td style="padding-right: 10px; text-align: right;"><b>Owner:</b></td>
- <td><?= $owner === "raindrops" ? "Raindrops System" : "Cloudburst System" ?></td>
- </tr>
- <tr>
- <td style="padding-right: 10px; text-align: right;"><b>Luna version:</b></td>
- <td><?= $computer["luna_version"] ?><?php if (isset($computer["dsb"])): ?> (<?php switch ($computer["dsb"]["platform"]) {
- case "chrome":
- echo("Chrome ");
- break;
-
- case "desktop":
- echo("Desktop ");
- break;
-
- case "android":
- echo("Android ");
- break;
-
- case "wear":
- echo("Wear OS ");
- break;
-
- case "server":
- echo("Server ");
- break;
-
- default:
- break;
- } ?> DSB <?= $computer["dsb"]["version"] ?? 0 ?>)<?php else: ?> (legacy)<?php endif; ?></td>
- </tr>
- <tr>
- <td style="padding-right: 10px; text-align: right;"><b>System:</b></td>
- <td><?= $computer["os"] ?></td>
- </tr>
- <tr>
- <td style="padding-right: 10px; text-align: right;"><b>OS kernel:</b></td>
- <td><?= $computer["kernel"] ?></td>
- </tr>
- <tr>
- <td style="padding-right: 10px; text-align: right;"><b>Serial:</b></td>
- <?php if (trim($computer["serial"]) !== ""): ?><td><?= $computer["serial"] ?> (<?= $computer["serial_source"] === "hardware" ? "logic board" : "OS" ?>)</td><?php else: ?><td>-</td><?php endif; ?>
- </tr>
- <tr>
- <td style="padding-right: 10px; text-align: right;"><b>Status:</b></td>
- <?php if (timeAgo($computer["date"]) === "now" || str_contains(timeAgo($computer["date"]), " sec ")): ?>
- <td>Online</td>
- <?php else: ?>
- <td>Last seen <?= timeAgo($computer["date"]) ?>: <?= date('j M, g:ia (T)', strtotime($computer["date"])) ?></td>
- <?php endif; ?>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
-
- <table><tbody>
- <tr>
- <td colspan="2"><h4 style="margin-top: 20px;margin-bottom: 10px;">Processors and graphics</h4></td>
- </tr>
- <tr>
- <td style="padding-right: 10px; text-align: right;"><b>Main processor:</b></td>
- <td><?= trim(($computer["cpu"]["manufacturer"] ?? "") . " " . ($computer["cpu"]["brand"] ?? "") . " " . ($computer["cpu"]["model"] ?? "")) ?> (<?= $computer["cpu"]["speed"] ?? "" ?> GHz)</td>
- </tr>
- <tr>
- <td style="padding-right: 10px; text-align: right;"><b>Processor threading:</b></td>
- <td>
- <?php if ($computer["cpu"]["processors"] > 1): ?><?= $computer["cpu"]["processors"] ?> processor<?= $computer["cpu"]["processors"] > 1 ? "s" : "" ?>,
- <?php endif; ?><?= $computer["cpu"]["physicalCores"] ?> core<?= $computer["cpu"]["physicalCores"] > 1 ? "s" : "" ?><?= isset($computer["cpu"]["efficiencyCores"]) && isset($computer["cpu"]["performanceCores"]) && $computer["cpu"]["efficiencyCores"] !== 0 && $computer["cpu"]["performanceCores"] !== 0 ? " (" . $computer["cpu"]["efficiencyCores"] . " efficiency, " . $computer["cpu"]["performanceCores"] . " performance)" : "" ?><?php if ($computer["cpu"]["cores"] !== $computer["cpu"]["physicalCores"]): ?>,
- <?= $computer["cpu"]["cores"] ?> thread<?= $computer["cpu"]["cores"] > 1 ? "s" : "" ?><?php endif; ?></td>
- </tr>
- <tr>
- <td style="padding-right: 10px; text-align: right;"><b>Hardware virtualization:</b></td>
- <td><?= isset($computer["cpu"]["virtualization"]) ? ($computer["cpu"]["virtualization"] ? "Capable" : "Disabled") : "Unknown" ?></td>
- </tr>
- <?php if (isset($computer["cpu"]["cache"])): ?>
- <tr>
- <td style="padding-right: 10px; text-align: right;"><b>Level 1 cache:</b></td>
- <td><?= round($computer["cpu"]["cache"]["l1i"] / 1024, 2) ?> KiB (instruction), <?= round($computer["cpu"]["cache"]["l1d"] / 1024, 2) ?> KiB (data)</td>
- </tr>
- <tr>
- <td style="padding-right: 10px; text-align: right;"><b>Level 2 cache:</b></td>
- <td><?= isset($computer["cpu"]["cache"]["l2"]) && is_numeric($computer["cpu"]["cache"]["l2"]) ? round($computer["cpu"]["cache"]["l2"] / 1024**2, 2) . " MiB" : "Not supported" ?></td>
- </tr>
- <tr>
- <td style="padding-right: 10px; text-align: right;"><b>Level 3 cache:</b></td>
- <td><?= isset($computer["cpu"]["cache"]["l3"]) && is_numeric($computer["cpu"]["cache"]["l3"]) ? round($computer["cpu"]["cache"]["l3"] / 1024**2, 2) . " MiB" : "Not supported" ?></td>
- </tr>
- <?php endif; ?>
- <?php if (isset($computer["gpu"])): ?>
- <?php if (isset($computer["gpu"]["controllers"]) && isset($computer["gpu"]["controllers"][0])): ?><tr>
- <td style="padding-right: 10px; text-align: right;"><b>Graphics processor<?= count($computer["gpu"]["controllers"]) > 1 ? "s" : "" ?>:</b></td>
- <td>
- <?php $index = 0; foreach ($computer["gpu"]["controllers"] as $controller): ?>
- <?= $controller["bus"] ?> <?= $controller["model"] ?> (<?php if (isset($controller["cores"])): ?><?= $controller["cores"] ?> cores, <?php endif; ?><?= $controller["vramDynamic"] ? "dynamic graphics memory" : $controller["vram"] . " MiB" ?>)
- <?= $index < count($computer["gpu"]["controllers"]) - 1 ? "<br>" : "" ?>
- <?php $index++; endforeach; ?>
- </td>
- </tr><?php endif; ?>
- <tr>
- <td style="padding-right: 10px; text-align: right;"><b>Display<?= count($computer["gpu"]["displays"]) > 1 ? "s" : "" ?>:</b></td>
- <td>
- <?php $index = 0; foreach ($computer["gpu"]["displays"] as $display): ?>
- <?= $display["connection"] ?> <?= $display["vendor"] ?> <?= $display["model"] ?> (<?= $display["currentResX"] ?>x<?= $display["currentResY"] ?><?= $display["currentResX"] !== $display["resolutionX"] ? ", native " . $display["resolutionX"] . "x" . $display["resolutionY"] : "" ?>, <?= $display["currentRefreshRate"] ?> Hz)
- <?= $index < count($computer["gpu"]["displays"]) - 1 ? "<br>" : "" ?>
- <?php $index++; endforeach; ?>
- </td>
- </tr>
- <?php endif; ?>
-
- <tr>
- <td colspan="2"><h4 style="margin-top: 20px;margin-bottom: 10px;">System memory</h4></td>
- </tr>
- <tr>
- <td style="padding-right: 10px; text-align: right;"><b>Physical memory:</b></td>
- <td><?= round($computer["ram"]["total"] / 1024**3, 2) ?> GiB (<?= round($computer["ram"]["used"] / 1024**2, 2) ?> MiB used, <?= round($computer["ram"]["free"] / 1024**2, 2) ?> MiB free)</td>
- </tr>
- <?php if (isset($computer["ram"]["active"]) && isset($computer["ram"]["available"]) && isset($computer["ram"]["buffcache"])): ?><tr>
- <td style="padding-right: 10px; text-align: right;"><b>Memory usage:</b></td>
- <td><?= round($computer["ram"]["active"] / 1024**2, 2) ?> MiB active, <?= round($computer["ram"]["available"] / 1024**2, 2) ?> MiB available, <?= round($computer["ram"]["buffcache"] / 1024**2, 2) ?> MiB cache</td>
- </tr><?php endif; ?>
- <?php if (isset($computer["ram"]["swaptotal"]) && isset($computer["ram"]["swapused"])): ?><tr>
- <td style="padding-right: 10px; text-align: right;"><b>Swap memory:</b></td>
- <td><?= round($computer["ram"]["swaptotal"] / 1024**3, 2) ?> GiB (<?= round($computer["ram"]["swapused"] / 1024**2, 2) ?> MiB used, <?= round($computer["ram"]["swapfree"] / 1024**2, 2) ?> MiB free)</td>
- </tr><?php endif; ?>
- <?php if (isset($computer["ram_chips"])): ?><tr>
- <td style="padding-right: 10px; text-align: right;"><b>RAM chips:</b></td>
- <td>
- <?php $index = 0; foreach ($computer["ram_chips"] as $chip): ?>
- <?php if (isset($chip["manufacturer"])): ?><?= $chip["manufacturer"] ?> <?php endif; ?><?= round($chip["size"] / 1024**2, 2) ?> MiB <?= $chip["type"] ?>
- <?= $index < count($computer["ram_chips"]) - 1 ? "<br>" : "" ?>
- <?php $index++; endforeach; ?>
- </td>
- </tr><?php endif; ?>
-
- <tr>
- <td colspan="2"><h4 style="margin-top: 20px;margin-bottom: 10px;">Battery</h4></td>
- </tr>
- <?php if (isset($computer["battery"])): ?>
- <?php if ($computer["battery"]["hasBattery"]): ?>
- <tr>
- <td style="padding-right: 10px; text-align: right;"><b>Battery model:</b></td>
- <td><?= preg_replace("/ +/", " ", trim($computer["battery"]["manufacturer"] . " " . $computer["battery"]["type"] . " " . $computer["battery"]["model"])) ?></td>
- </tr>
- <tr>
- <td style="padding-right: 10px; text-align: right;"><b>Charge level:</b></td>
- <td><?= $computer["battery"]["percent"] ?>%<?= $computer["battery"]["acConnected"] ? ", plugged in" : "" ?> (<?= round($computer["battery"]["voltage"], 2) ?> V)</td>
- </tr>
- <?php if (isset($computer["battery"]["cycleCount"] ) && $computer["battery"]["cycleCount"] > 0): ?>
- <tr>
- <td style="padding-right: 10px; text-align: right;"><b>Cycles:</b></td>
- <td><?= $computer["battery"]["cycleCount"] ?></td>
- </tr>
- <?php endif; ?>
- <tr>
- <td style="padding-right: 10px; text-align: right;"><b>Remaining capacity:</b></td>
- <td><?= round($computer["battery"]["currentCapacity"], 2) ?>/<?= round($computer["battery"]["maxCapacity"], 2) ?> <?= $computer["battery"]["capacityUnit"] ?><?php if (isset($computer["battery"]["designedCapacity"]) && $computer["battery"]["designedCapacity"] > 0): ?> (designed for <?= $computer["battery"]["designedCapacity"] ?> <?= $computer["battery"]["capacityUnit"] ?><?php if ($computer["battery"]["designedCapacity"] > 0): ?>, <?= round(($computer["battery"]["maxCapacity"] / $computer["battery"]["designedCapacity"]) * 100, 2) ?>% left<?php endif; ?>)<?php endif; ?></td>
- </tr>
- <?php else: ?><tr><td colspan="2">This device does not contain a battery.</td></tr><?php endif; ?><?php else: ?><tr><td colspan="2">This operating system does not support reporting battery info.</td></tr><?php endif; ?>
-
- <tr>
- <td colspan="2"><h4 style="margin-top: 20px;margin-bottom: 10px;">Operating system</h4></td>
- </tr>
- <tr>
- <td style="padding-right: 10px; text-align: right;"><b>System:</b></td>
- <td><?= $computer["os_info"]["distro"] ?> <?= $computer["os_info"]["release"] === "unknown" || $computer["os_info"]["release"] === "rolling" ? "" : $computer["os_info"]["release"] ?></td>
- </tr>
- <tr>
- <td style="padding-right: 10px; text-align: right;"><b>CPU architecture:</b></td>
- <td><?= $computer["os_info"]["arch"] ?></td>
- </tr>
- <tr>
- <td style="padding-right: 10px; text-align: right;"><b>Kernel version:</b></td>
- <td><?= $computer["os_info"]["kernel"] ?></td>
- </tr>
- <?php if (isset($computer["os_info"]["codepage"])): ?>
- <tr>
- <td style="padding-right: 10px; text-align: right;"><b>Code page:</b></td>
- <td><?= $computer["os_info"]["codepage"] ?></td>
- </tr>
- <?php endif; ?>
- <tr>
- <td style="padding-right: 10px; text-align: right;"><b>Build number:</b></td>
- <td><?= $computer["os_info"]["build"] === "rolling" ? "Rolling release" : $computer["os_info"]["build"] ?></td>
- </tr>
- <tr>
- <td style="padding-right: 10px; text-align: right;"><b>Serial number:</b></td>
- <td><?= $computer["os_info"]["serial"] ?></td>
- </tr>
- <?php if (isset($computer["os_info"]["uefi"])): ?>
- <tr>
- <td style="padding-right: 10px; text-align: right;"><b>Startup interface:</b></td>
- <td><?= $computer["os_info"]["uefi"] ? "UEFI" : "BIOS (legacy)" ?></td>
- </tr>
- <?php endif; ?>
-
- <?php if (count(array_filter($computer["versions"], function ($version, $software) {
- return trim($version) !== "" && $software !== "systemOpensslLib" && $software !== "openssl" && $software !== "node" && $software !== "v8";
- }, ARRAY_FILTER_USE_BOTH)) > 0): ?>
- <tr>
- <td colspan="2"><h4 style="margin-top: 20px;margin-bottom: 10px;">Software versions</h4></td>
- </tr>
- <?php foreach ($computer["versions"] as $software => $version): if (trim($version) !== "" && $software !== "systemOpensslLib" && $software !== "openssl" && $software !== "node" && $software !== "v8"): ?>
- <tr>
- <td style="padding-right: 10px; text-align: right;"><b><?=
- match ($software) {
- "kernel" => "OS kernel",
- "systemOpenssl" => $computer["versions"]["systemOpensslLib"],
- "npm" => "NPM",
- "yarn" => "Yarn",
- "gulp" => "Gulp",
- "grunt" => "Grunt",
- "git" => "Git",
- "tsc" => "TypeScript",
- "mysql" => "MySQL",
- "redis" => "Redis",
- "mongodb" => "MongoDB",
- "apache" => "Apache HTTPD",
- "php" => "PHP",
- "docker" => "Docker",
- "postfix" => "Postfix SMTP Server",
- "postgresql" => "PostgreSQL",
- "perl" => "Perl",
- "python" => "Python (legacy)",
- "python3" => "Python",
- "pip" => "PIP (legacy)",
- "pip3" => "PIP",
- "java" => "Java",
- "gcc" => "C compiler",
- "virtualbox" => "VirtualBox",
- "bash" => "Bash",
- "zsh" => "zsh",
- "fish" => "Fish",
- "powershell" => "PowerShell",
- "dotnet" => ".NET",
- default => $software,
- }
- ?>:</b></td>
- <td><?= $version ?></td>
- </tr>
- <?php endif; endforeach; endif; ?>
- </tbody>
- </table>
-
- <?php if (!isset($computer["remote_control"]) || $computer["remote_control"] === true): ?>
- <h4 style="margin-top: 20px;margin-bottom: 10px;" id="screens">Remote control</h4>
- <p id="page-content">
- You can remotely control this device. <a href="./<?= $id ?>/control">Open remote device.</a><br>
- <small class="text-muted">Note: The user of this device will need to approve your connection request before you can see and control their screen.</small>
- </p>
- <?php endif; ?>
-
- <?php if (count($computer["users"]) > 0): ?>
- <h4 style="margin-top: 20px;margin-bottom: 10px;">Sessions</h4>
- <table class="table">
- <thead>
- <tr>
- <th scope="col">TTY</th>
- <th scope="col">Command</th>
- <th scope="col">User</th>
- <th scope="col">Open</th>
- <th scope="col">Type</th>
- </tr>
- </thead>
- <tbody>
- <?php foreach ($computer["users"] as $user): ?>
- <tr>
- <th scope="row"><?= $user["tty"] ?></th>
- <td><?= str_replace("�", "", $user["command"]) ?></td>
- <td><?= $user["user"] ?></td>
- <td><?= $user["date"] . " " . $user["time"] ?></td>
- <td><?= trim($user["ip"]) === "" || trim($user["ip"]) === ":1" || trim($user["ip"]) === "::1" ? "Local" : "Remote (" . $user["ip"] . ")" ?></td>
- </tr>
- <?php endforeach; ?>
- </tbody>
- </table>
- <?php endif; ?>
-
- <?php if (count($computer["filesystems"]) > 0): ?>
- <h4 style="margin-top: 20px;margin-bottom: 10px;">Filesystems</h4>
- <table class="table">
- <thead>
- <tr>
- <th scope="col">Device</th>
- <th scope="col">Mount point</th>
- <th scope="col">Type</th>
- <th scope="col">Used</th>
- <th scope="col">Free</th>
- <th scope="col">Total</th>
- </tr>
- </thead>
- <tbody>
- <?php
-
- uasort($computer["filesystems"], function ($a, $b) {
- return $b["use"] - $a["use"];
- });
-
- foreach ($computer["filesystems"] as $fs): ?>
- <tr>
- <th scope="row"><?= $fs["fs"] ?></th>
- <td><?= $fs["mount"] ?></td>
- <td><?= $fs["type"] ?></td>
- <td><?= prettySize($fs["used"]) ?> (<?= $fs["use"] ?>%)</td>
- <td><?= prettySize($fs["available"]) ?></td>
- <td><?= prettySize($fs["size"]) ?></td>
- </tr>
- <?php endforeach; ?>
- </tbody>
- </table>
- <?php endif; ?>
-
- <?php if (isset($computer["audio"])): ?>
- <h4 style="margin-top: 20px;margin-bottom: 10px;">Audio devices</h4>
- <table class="table">
- <thead>
- <tr>
- <th scope="col">Type</th>
- <th scope="col">Manufacturer</th>
- <th scope="col">Name</th>
- <th scope="col">Default</th>
- <th scope="col">Connection</th>
- </tr>
- </thead>
- <tbody>
- <?php foreach ($computer["audio"] as $device): ?>
- <tr>
- <th scope="row"><?= trim($device["type"]) === "" ? "Device" : $device["type"] ?></th>
- <td><?= $device["manufacturer"] ?></td>
- <td><?= $device["name"] ?></td>
- <td><?= $device["default"] ? "Yes" : "" ?></td>
- <td><?= trim($device["channel"]) === "" ? "Virtual" : $device["channel"] ?></td>
- </tr>
- <?php endforeach; ?>
- </tbody>
- </table>
- <?php endif; ?>
-
- <?php if (isset($computer["network"])): ?>
- <h4 style="margin-top: 20px;margin-bottom: 10px;">Network cards</h4>
- <table class="table">
- <thead>
- <tr>
- <th scope="col">Interface</th>
- <th scope="col">State</th>
- <th scope="col">IP addresses</th>
- <th scope="col">MAC address</th>
- <th scope="col">Type</th>
- <th scope="col">Internal</th>
- <th scope="col">Virtual</th>
- <th scope="col">DHCP</th>
- </tr>
- </thead>
- <tbody>
- <?php
-
- uasort($computer["network"], function ($a, $b) {
- $statA = match ($a["operstate"]) {
- "up" => 300,
- "down" => 200,
- default => 100
- };
- $statB = match ($b["operstate"]) {
- "up" => 300,
- "down" => 200,
- default => 100
- };
-
- return $statB - $statA;
- });
-
- foreach ($computer["network"] as $iface): ?>
- <tr <?= $iface["operstate"] !== "up" ? 'style="opacity:.5;"' : "" ?>>
- <th scope="row"><?= $iface["ifaceName"] ?></th>
- <td><?= $iface["operstate"] === "up" ? "Active" : ($iface["operstate"] === "down" ? "Inactive" : "") ?></td>
- <td><?= trim($iface["ip4"] !== "") ? $iface["ip4"] : "" ?><?= trim($iface["ip6"] !== "") ? (trim($iface["ip4"] !== "") ? ", " : "") . $iface["ip6"] : "" ?></td>
- <td><?= trim($iface["mac"] !== "") ? $iface["mac"] : "" ?></td>
- <td><?= $iface["type"] === "wireless" ? "Wireless" : "Wired" ?></td>
- <td><?= isset($iface["internal"]) && $iface["internal"] ? "Yes" : "" ?></td>
- <td><?= $iface["virtual"] ? "Yes" : "" ?></td>
- <td><?= $iface["dhcp"] ? "Yes" : "" ?></td>
- </tr>
- <?php endforeach; ?>
- </tbody>
- </table>
- <?php endif; ?>
-
- <?php if (isset($computer["connections"])): ?>
- <h4 style="margin-top: 20px;margin-bottom: 10px;">Network connections</h4>
- <table class="table">
- <thead>
- <tr>
- <th scope="col">State</th>
- <th scope="col">Protocol</th>
- <th scope="col">Source</th>
- <th scope="col">Destination</th>
- <th scope="col">Process</th>
- </tr>
- </thead>
- <tbody>
- <?php foreach ($computer["connections"] as $connection): ?>
- <tr>
- <th scope="row"><?= match ($connection["state"]) {
- "ESTABLISHED" => "Connected",
- "LISTEN" => "Listening",
- "CLOSING" => "Terminating",
- "UNKNOWN" => "?",
- "LAST_ACK", "FIN_WAIT2", "TIME_WAIT" => "Waiting",
- "FIN_WAIT1", "CLOSE_WAIT" => "Closing",
- "SYN_RECV" => "Received",
- "SYN_SENT" => "Attempting",
- default => $connection["state"],
- } ?></th>
- <td><?= match ($connection["protocol"]) {
- "tcp4" => "TCP over IPv4",
- "tcp6" => "TCP over IPv6",
- "tcp46" => "TCP over IPv4 and IPv6",
- "udp4" => "UDP over IPv4",
- "udp6" => "UDP over IPv6",
- "udp46" => "UDP over IPv4 and IPv6",
- default => $connection["protocol"],
- } ?></td>
- <td><?= $connection["localAddress"] === "*" ? "&lt;all&gt;" : match ($connection["localAddress"]) {
- "127.0.0.1" => "&lt;local IPv4&gt;",
- "::1" => "&lt;local IPv6&gt;",
- default => $connection["localAddress"],
- } ?> (port <?= $connection["localPort"] ?>)</td>
- <td><?php if ($connection["state"] !== "LISTEN"): ?><?= $connection["peerAddress"] === "*" ? "&lt;all&gt;" : match ($connection["peerAddress"]) {
- "127.0.0.1" => "&lt;local IPv4&gt;",
- "::1" => "&lt;local IPv6&gt;",
- default => $connection["localAddress"],
- } ?> (<?= $connection["peerPort"] ?>)<?php endif; ?></td>
- <td><?php
-
- $f = array_values(array_filter($computer["processes"], function ($i) use ($connection) {
- return $i["pid"] === $connection["pid"];
- }));
-
- if (count($f) > 0) {
- echo($f[0]["name"] . " [" . $connection["pid"] . "]");
- } else {
- echo($connection["pid"]);
- }
-
- ?></td>
- </tr>
- <?php endforeach; ?>
- </tbody>
- </table>
- <?php endif; ?>
-
- <?php if (isset($computer["processes"]) && count($computer["processes"]) > 0): ?>
- <h4 style="margin-top: 20px;margin-bottom: 10px;">Processes</h4>
- <table class="table">
- <thead>
- <tr>
- <th scope="col">PID</th>
- <th scope="col">Name</th>
- <th scope="col">CPU</th>
- <th scope="col">RAM</th>
- <th scope="col">User</th>
- <th scope="col">Started</th>
- </tr>
- </thead>
- <tbody>
- <?php foreach ($computer["processes"] as $process): ?>
- <tr>
- <th scope="row"><?= $process["pid"] ?></th>
- <td><?= $process["name"] ?></td>
- <td><?= round($process["cpu"] ?? 0, 2) ?>%</td>
- <td><?= round($process["ram"], 2) ?>%</td>
- <td><?= $process["user"] ?></td>
- <td><?= isset($process["date"]) ? timeAgo($process["date"]) : "" ?></td>
- </tr>
- <?php endforeach; ?>
- </tbody>
- </table>
- <?php endif; ?>
- <?php endif; ?>
- </div>
- <?php elseif (isset($parts[3]) && $parts[3] === "control"): $id = $parts[2]; ?>
- <?php if ($computer["luna_version"] !== "1.0.0"): ?>
- <div>
- <h2>
- <span style="vertical-align: middle;">Remote controlling <?= $computer["host"] ?></span>
- <a href="/-/computers/<?= $id ?>" class="small btn btn-outline-light" style="float:right;margin-top:5px;vertical-align:middle;opacity:1 !important; color:white;">Back</a>
- </h2>
-
- <div id="remote-control-load">
- <img src="/assets/editor/load.svg" style="width: 36px; vertical-align: middle;" id="rc-loader-img" alt=""><span style="vertical-align: middle;" id="remote-control-load-msg">Initialising connection...</span></div>
- </div>
-
- <div class="alert alert-danger" id="remote-control-error" style="display:none;">
- <b>Unable to connect:</b> <span id="remote-control-error-message">Error</span>
- </div>
-
- <div id="remote-control-app" style="display: none;">
- <div style="display: flex; align-items: center;">
- <img id="display" style="max-width: 100%; max-height: 100%; height: 100%; width: 100%; opacity: .5" src="https://ponies.equestria.horse/api/data?f=computers/screens/<?= $id . "-" . $computer["screens"][0]["id"] ?>.jpg">
- </div>
-
- <div id="commands" style="background: #151515; border: 1px solid #333; margin-top: 10px; border-radius: 10px; font-family: 'JetBrains Mono', monospace; font-size: 14px;">
- <div id="output" style="height: 200px; padding: 10px 20px; overflow: auto;">
- <pre id="output-text"></pre>
- <div id="loader" style="display: none;">
- <img src="/assets/editor/load.svg" style="width: 36px; vertical-align: middle; margin-left: -8px; margin-top: -8px;" id="loader-img" alt="">
- <span id="loader-time" style="vertical-align: middle; opacity: .5; display: inline-block; margin-top: -8px; margin-left: -8px;">
- <span id="loader-time-inner"></span>
- <span id="loader-time-stopper">
- | <a id="loader-time-stopper-link" style="cursor: pointer; text-decoration: underline;" onclick="stopCommand();">Stop</a>
- </span>
- </span>
- </div>
- </div>
- <div id="entry" style="border-top: 1px solid #333;">
- <input type="text" id="command-entry" placeholder="Enter a command" style="width: 100%; color: white; background: transparent; border: none; padding: 10px 20px; outline: none;">
- </div>
- </div>
- </div>
-
- <script>
- function setLoadMessage(msg) {
- document.getElementById("remote-control-load-msg").innerText = msg;
- }
-
- function stopCommand() {
- ws.send(JSON.stringify({
- type: "halt"
- }));
- }
-
- let rejected = false;
-
- function scrollToBottom() {
- document.getElementById("output").scrollTop = document.getElementById("output").scrollHeight;
- }
-
- window.addEventListener("load", () => {
- document.getElementById("command-entry").value = "";
- });
-
- document.getElementById("command-entry").onkeydown = (event) => {
- if (event.key === "Enter") {
- event.preventDefault();
- let command = document.getElementById("command-entry").value;
- document.getElementById("command-entry").value = "";
- document.getElementById("command-entry").disabled = true;
- document.getElementById("loader-time").style.display = "none";
- document.getElementById("loader").style.display = "";
- document.getElementById("output-text").innerHTML += "\n$ " + command.replaceAll(">", "&gt;").replaceAll("<", "&lt;") + "\n";
- scrollToBottom();
- ws.send(JSON.stringify({
- type: "command",
- value: btoa(command)
- }));
- }
- }
-
- window.controlling = false;
- window.commandRunInterval = null;
-
- function connect() {
- setLoadMessage("Connecting to server...");
- window.ws = new WebSocket("wss://ponies.equestria.horse/_Computers-RemoteControl-EntryPoint/socket");
- window.baseLatency = null;
-
- ws.addEventListener('open', (data) => {
- setLoadMessage("Authenticating...");
- console.log(data);
-
- ws.send(JSON.stringify({
- type: "client",
- id: "<?= $id ?>",
- name: window.userName,
- token: "<?= $_COOKIE['PEH2_SESSION_TOKEN'] ?>"
- }));
-
- setLoadMessage("Waiting for the user to accept...");
- });
-
- ws.addEventListener('message', async (_data) => {
- setLoadMessage("Loading...");
- let data = JSON.parse(await (_data.data.text()));
-
- if (data.rejected) {
- document.getElementById("remote-control-load").style.display = "none";
- document.getElementById("remote-control-error").style.display = "";
- document.getElementById("remote-control-error-message").innerText = "The user has rejected the connection request.";
- rejected = true;
- }
-
- if (data.type === "image") {
- setLoadMessage("Loading initial image...");
-
- document.getElementById("display").style.opacity = "1";
- document.getElementById("display").src = data.url;
-
- if (baseLatency) {
- ws.send(JSON.stringify({
- type: "set_latency",
- value: Math.abs((new Date().getTime() - data.time) - baseLatency)
- }));
-
- if (Math.abs((new Date().getTime() - data.time) - baseLatency) > 200) {
- ws.send(JSON.stringify({
- type: "reduce_quality"
- }));
- } else if (Math.abs((new Date().getTime() - data.time) - baseLatency) < 150) {
- ws.send(JSON.stringify({
- type: "increase_quality"
- }));
- }
- } else {
- window.baseLatency = Math.abs(new Date().getTime() - data.time);
- }
-
- document.getElementById("remote-control-load").style.display = "none";
- document.getElementById("remote-control-app").style.display = "";
- } else if (data.type === "command_stop") {
- if (data.code !== 0) {
- if (data.signal) {
- if (data.code) {
- document.getElementById("output-text").innerHTML += "<span style='color: #ff8c8c;'>Command exited with code " + data.code.toString().replaceAll(">", "&gt;").replaceAll("<", "&lt;") + " (caused by " + data.signal.toString().replaceAll(">", "&gt;").replaceAll("<", "&lt;") + ")</span>";
- } else {
- document.getElementById("output-text").innerHTML += "<span style='color: #ff8c8c;'>Command exited with signal " + data.signal.toString().replaceAll(">", "&gt;").replaceAll("<", "&lt;");
- }
- } else {
- document.getElementById("output-text").innerHTML += "<span style='color: #ff8c8c;'>Command exited with code " + data.code.toString().replaceAll(">", "&gt;").replaceAll("<", "&lt;") + "</span>";
- }
- }
-
- clearInterval(window.commandRunInterval);
- document.getElementById("command-entry").disabled = false;
- document.getElementById("loader").style.display = "none";
- scrollToBottom();
- document.getElementById("command-entry").focus();
- } else if (data.type === "command_start") {
- document.getElementById("loader-time").style.display = "inline-block";
- document.getElementById("loader-time-inner").innerText = "";
- window.commandStartTime = new Date().getTime();
- window.commandRunInterval = setInterval(() => {
- document.getElementById("loader-time-inner").innerText = ((new Date().getTime() - window.commandStartTime) / 1000).toFixed(2) + "s";
- }, 10);
- scrollToBottom();
- } else if (data.type === "command_stdout" || data.type === "command_stderr") {
- if (data.type === "command_stderr") {
- document.getElementById("output-text").innerHTML += "<span style='color: #ffec8c;'>" + atob(data.value).replaceAll(">", "&gt;").replaceAll("<", "&lt;") + "</span>";
- } else {
- document.getElementById("output-text").innerHTML += atob(data.value).replaceAll(">", "&gt;").replaceAll("<", "&lt;");
- }
-
- scrollToBottom();
- } else {
- console.log(data);
- }
- });
-
- ws.addEventListener('close', (data) => {
- document.getElementById("display").style.opacity = "0.5";
- console.log(data);
-
- if (!rejected) {
- setLoadMessage("Connection error, retrying in 1 second.");
-
- setTimeout(() => {
- setLoadMessage("Retrying connection...");
- connect();
- }, 1000);
- }
- });
- }
-
- connect();
-
- document.getElementById("display").addEventListener("mousemove", (event) => {
- event.preventDefault();
-
- if (window.controlling) ws.send(JSON.stringify({
- type: "move_cursor",
- x: event.offsetX / document.getElementById("display").width,
- y: event.offsetY / document.getElementById("display").height
- }));
- });
-
- document.getElementById("display").addEventListener("click", (event) => {
- event.preventDefault();
-
- if (window.controlling) ws.send(JSON.stringify({
- type: "click",
- button: 0
- }));
- });
-
- document.getElementById("display").addEventListener("contextmenu", (event) => {
- event.preventDefault();
-
- if (window.controlling) ws.send(JSON.stringify({
- type: "click",
- button: 1
- }));
- });
-
- document.getElementById("display").addEventListener("auxclick", (event) => {
- event.preventDefault();
-
- if (window.controlling) ws.send(JSON.stringify({
- type: "click",
- button: 2
- }));
- });
-
- document.body.onkeydown = document.getElementById("display").onkeydown = (event) => {
- if (window.controlling) event.preventDefault();
-
- if (window.controlling) ws.send(JSON.stringify({
- type: "keyboard",
- shift: event.shiftKey,
- ctrl: event.ctrlKey,
- meta: event.metaKey,
- alt: event.altKey,
- key: event.key
- }));
- }
-
- document.getElementById("display").ondragstart = (event) => {
- event.preventDefault();
-
- if (window.controlling) ws.send(JSON.stringify({
- type: "move_cursor",
- x: event.offsetX / document.getElementById("display").width,
- y: event.offsetY / document.getElementById("display").height
- }));
- if (window.controlling) ws.send(JSON.stringify({
- type: "start_drag"
- }));
- }
-
- document.getElementById("display").ondragend = (event) => {
- event.preventDefault();
-
- if (window.controlling) ws.send(JSON.stringify({
- type: "move_cursor",
- x: event.offsetX / document.getElementById("display").width,
- y: event.offsetY / document.getElementById("display").height
- }));
- if (window.controlling) ws.send(JSON.stringify({
- type: "stop_drag"
- }));
- }
-
- function enableControl() {
- window.controlling = true;
- }
-
- function disableControl() {
- window.controlling = false;
- }
- </script>
- <?php endif; ?>
- <?php else: ?>
- <div>
- <h2>Devices</h2>
- <p>Click on a device to view information about it</p>
-
- <div class="alert alert-warning">
- <b>Luna and the Cold Haze Devices software are deprecated.</b> These applications are now deprecated and monitoring devices through Luna is not supported anymore. Basic support and servers will be shut down on July 1<sup>st</sup>.
- </div>
-
- <ul class="list-group">
- <?php
-
- $list = array_filter(scandir($_SERVER['DOCUMENT_ROOT'] . "/includes/data/computers/metadata"), function ($i) {
- return !str_starts_with($i, ".");
- });
- uasort($list, function ($a, $b) {
- $ca = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/computers/metadata/" . $a), true);
- $cb = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/computers/metadata/" . $b), true);
- return strtotime($cb["date"]) - strtotime($ca["date"]);
- });
-
- foreach ($list as $file): $computer = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/computers/metadata/" . $file), true); $id = substr($file, 0, -5); $owner = explode("-", $id)[0];
-
- if (str_ends_with($computer["os"], "unknown")) {
- $computer["os"] = trim(substr($computer["os"], 0, -7));
- }
-
- ?>
- <a href="/-/computers/<?= $id ?>" class="list-group-item list-group-item-action" style="display: grid; grid-template-columns: 100px 1fr; grid-column-gap: 10px; <?php if (timeAgo($computer["date"]) !== "now" && !str_contains(timeAgo($computer["date"]), " sec ")): ?>opacity: .5;<?php endif; ?>">
- <div style="display: flex; align-items: center;">
- <div style="aspect-ratio: 16/10; width: 100px; background-image: url('<?php
-
- if (isset($computer["dsb"])) {
- switch ($computer["dsb"]["platform"]) {
- case "chrome":
- echo("https://upload.wikimedia.org/wikipedia/en/3/3e/ChromeOS_screenshot.png");
- break;
-
- default:
- echo("https://ponies.equestria.horse/api/data?f=computers/screens/" . $id . "-" . $computer["screens"][0]["id"] . ".jpg");
- break;
- }
- } else {
- echo("https://ponies.equestria.horse/api/data?f=computers/screens/" . $id . "-" . $computer["screens"][0]["id"] . ".jpg");
- }
-
- ?>'); background-size: cover; background-position: center;"></div>
- </div>
- <div style="display: flex; align-items: center;">
- <div>
- <b><?= $names[$id] ?? $computer["host"] ?></b><br>
- <?php
-
- if (str_starts_with($computer["os"], "Google ")) {
- echo(substr($computer["os"], 7));
- } else if (str_starts_with($computer["os"], "Microsoft ")) {
- echo(substr($computer["os"], 10));
- } else {
- echo($computer["os"]);
- }
-
- ?><br>
- <?php
-
- if (isset($computer["dsb"]) && isset($computer["dsb"]["platform"])) {
- switch ($computer["dsb"]["platform"]) {
- case "desktop":
- case "chrome":
- echo("Computer");
- break;
-
- case "android":
- echo("Phone");
- break;
-
- case "wear":
- echo("Watch");
- break;
-
- case "server":
- echo("Server");
- break;
-
- default:
- echo("Device");
- break;
- }
- } else {
- echo("Legacy device");
- }
-
- ?> · Owned by <?= $owner === "raindrops" ? "Raindrops" : "Cloudburst"; ?><br>
- <?php if (timeAgo($computer["date"]) === "now" || str_contains(timeAgo($computer["date"]), " sec ")): ?>Online<?php else: ?>Last seen <?= timeAgo($computer["date"]) ?><?php endif; ?>
- </div>
- </div>
- </a>
- <?php endforeach; ?>
- </ul>
- </div>
- <?php endif; ?>
-</div>
-
-<style>
- .list-group-item {
- color: #fff;
- background-color: #222;
- border: 1px solid rgba(255, 255, 255, .125);
- }
-
- .list-group-item.disabled {
- color: #fff;
- background-color: #222;
- border-color: rgba(255, 255, 255, .125);
- opacity: .75;
- }
-
- .list-group-item:hover {
- background-color: #252525;
- color: #ddd;
- }
-
- .list-group-item:active, .list-group-item:focus {
- background-color: #272727;
- color: #bbb;
- }
-
- .modal-header {
- border-bottom: 1px solid #353738;
- }
-
- .modal-content {
- border: 1px solid rgba(255, 255, 255, .2);
- background-color: #111;
- }
-
- .btn-close {
- filter: invert(1);
- }
-
- .btn-outline-light:hover {
- color: black !important;
- }
-
- table {
- color: white !important;
- }
-
- table * {
- border-color: rgba(255, 255, 255, .25) !important;
- }
-</style>
-
-<?php require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/components/footer.inc'; ?>
diff --git a/pages/contacts.inc b/pages/contacts.inc
deleted file mode 100644
index b93460a..0000000
--- a/pages/contacts.inc
+++ /dev/null
@@ -1,273 +0,0 @@
-<?php
-
-require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/init.inc"; global $title; global $isLoggedIn; global $lang; global $pages;
-require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/util/timezones.inc'; global $timezones;
-require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/util/random.inc';
-require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/util/functions.inc';
-
-$methods = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/contactmethods.json"), true);
-$contacts = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/addressbook/contacts.json"), true);
-
-if (isset($_POST["edit"])) {
- header("Content-Type: text/plain");
- $id = $_POST["edit"];
- unset($_POST["edit"]);
-
- if (trim($id) === "" || !isset($contacts[$id])) $id = random();
-
- foreach ($_POST as $key => $value) {
- if (trim($value) === "") $_POST[$key] = null;
- if (isset($_POST[$key])) $_POST[$key] = str_replace(">", "&gt;", str_replace("<", "&lt;", str_replace("&", "&amp;", substr($_POST[$key], 0, $key === "description" ? 400 : 100))));
- }
-
- foreach ($methods as $name => $method) {
- if (isset($_POST[$name]) && isset($method["adapter"])) {
- $_POST[$name] = exec("cd \"$_SERVER[DOCUMENT_ROOT]/includes/external/addressbook\" && node \"$_SERVER[DOCUMENT_ROOT]/includes/external/addressbook/$method[adapter]\" \"$_POST[$name]\"");
- }
- }
-
- $contacts[$id] = $_POST;
- file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/addressbook/contacts.json", json_encode($contacts));
- createJob("UpdateContactMethods", [
- "contact" => $id
- ]);
-
- header("Location: /-/contacts");
- die();
-} else if (isset($_GET["delete"])) {
- if (isset($contacts[$_GET["delete"]])) {
- unset($contacts[$_GET["delete"]]);
- }
-
- file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/addressbook/contacts.json", json_encode($contacts));
-
- header("Location: /-/contacts");
- die();
-}
-
-require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/components/header.inc'; global $Parsedown;
-
-$cache = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/addressbook/saved.json"), true);
-
-uasort($contacts, function ($a, $b) {
- return strnatcasecmp($a["nick"], $b["nick"]);
-});
-
-?>
-
-<script>
- window.contacts = JSON.parse(atob(`<?= base64_encode(json_encode($contacts)) ?>`));
-</script>
-
-<br>
-<div class="container">
- <div id="page-content">
- <h2>
- <span style="vertical-align: middle;"><?= $pages["contacts"]["name"][$lang["_name"]] ?></span>
- <a onclick="createNew();" class="small btn btn-outline-light" style="float:right;margin-top:5px;vertical-align:middle;opacity:1 !important; color:white;">Create</a>
- </h2>
-
- <?php foreach ($contacts as $id => $contact): ?>
- <div class="contact-item" style="display: grid; grid-template-columns: 1.5fr 1fr;">
- <div>
- <div class="contact-item-main" style="display: grid; grid-template-columns: 1.25fr 1.25fr 0.75fr 0.75fr;">
- <span><?= $contact["nick"] ?? "" ?></span>
- <span><?= $contact["name"] ?? "" ?></span>
- <span><?= isset($contact["birthday"]) ? date('F jS', strtotime($contact["birthday"])) : "" ?></span>
- <span>
- <?php if (isset($contact["timezone"])): ?>
- <span id="timezone-<?= $id ?>">-</span>
- <script>
- setTimeout(() => {
- setInterval(() => {
- document.getElementById("timezone-<?= $id ?>").innerText = (new Intl.DateTimeFormat('en-US', {
- timeZone: '<?= $contact["timezone"] ?>',
- hour: '2-digit',
- minute: '2-digit',
- second: '2-digit',
- hour12: false
- })).format(new Date());
- }, 1000)
- }, <?= rand(0, 600) ?>);
- </script>
- <?php endif; ?>
- </span>
- </div>
- <div class="text-muted" style="margin-top: 10px;"><?= $Parsedown->text($contact["description"] ?? "") ?></div>
- </div>
- <div style="display: grid; grid-template-columns: 3fr max-content;">
- <span>
- <?php foreach ($methods as $name => $method): if (isset($contact[$name]) && isset($cache[$name][$contact[$name]])): $data = $cache[$name][$contact[$name]]["data"]; ?>
- <div class="contact-method" style="display: grid; grid-template-columns: 32px 1fr; grid-gap: 10px; width: max-content;">
- <div style="display: flex; align-items: center; justify-content: center;">
- <?php if (isset($data["link"])): ?><a style="color: inherit; text-decoration: none;" href="<?= $data["link"] ?>" target="_blank"><?php endif; ?><img alt="<?= $name ?>" style="width: 32px;" src="<?= $data["avatar"] ?>"><?php if (isset($data["link"])): ?></a><?php endif; ?>
- </div>
- <div style="display: grid; grid-template-columns: 1fr max-content; grid-gap: 10px;">
- <div>
- <div class="<?= isset($data["error"]) ? "text-danger" : "" ?>"><?php if (isset($data["link"])): ?><a style="color: inherit; text-decoration: none;" href="<?= $data["link"] ?>" target="_blank"><?php endif; ?><b><?= $data["name"] ?></b><?php if (isset($data["link"])): ?></a><?php endif; ?></div>
- <div class="text-muted"><?php if (isset($data["link"])): ?><a style="color: inherit; text-decoration: none;" href="<?= $data["link"] ?>" target="_blank"><?php endif; ?><?= $data["description"] ?><?php if (isset($data["link"])): ?></a><?php endif; ?></div>
- </div>
- <div style="display: flex; align-items: end;">
- <div class="dropdown">
- <a data-bs-toggle="dropdown" style="text-decoration: underline; cursor: pointer;">...</a>
- <ul class="dropdown-menu">
- <?php foreach ($data["copy"] as $action): ?>
- <li><a style="cursor: pointer;" class="dropdown-item" onclick="copyToClipboard('<?= base64_encode($action["text"] ?? "") ?>');"><?= $action["title"] ?></a></li>
- <?php endforeach; ?>
- </ul>
- </div>
- </div>
- </div>
- </div>
- <?php endif; endforeach; ?>
- </span>
- <span>
- <a onclick="editContact('<?= $id ?>')" style="text-decoration: underline; cursor: pointer;">E</a>, <a onclick="deleteContact('<?= $id ?>')" style="text-decoration: underline; cursor: pointer;">D</a>
- </span>
- </div>
- </div>
- <?php endforeach; ?>
- </div>
-</div>
-
-<div class="modal fade" id="create-edit">
- <div class="modal-dialog">
- <div class="modal-content">
- <div class="modal-header">
- <h4 class="modal-title" id="create-edit-title">Creating a new contact</h4>
- <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
- </div>
-
- <div class="modal-body">
- <form id="create-edit-form" method="post">
- <input type="hidden" id="create-edit-id" name="edit" value="">
- <input type="text" placeholder="Nickname" name="nick" class="form-control" style="margin-bottom:15px;color:white;background:#111;border-color:#222;" required>
- <input type="text" placeholder="Real name" name="name" class="form-control" style="margin-bottom:15px;color:white;background:#111;border-color:#222;">
- <input type="date" placeholder="Birthday" name="birthday" class="form-control" style="margin-bottom:15px;color:white;background:#111;border-color:#222;">
- <textarea name="description" rows="3" placeholder="Description" class="form-control" style="resize: none;color:white;background:#111;border-color:#222;margin-bottom:10px;"></textarea>
- <select name="timezone" class="form-select" style='display:inline-block;filter:invert(1) hue-rotate(180deg);background-image:url("data:image/svg+xml,%3csvg xmlns=&apos;http://www.w3.org/2000/svg&apos; viewBox=&apos;0 0 16 16&apos;%3e%3cpath fill=&apos;none&apos; stroke=&apos;%23000000&apos; stroke-linecap=&apos;round&apos; stroke-linejoin=&apos;round&apos; stroke-width=&apos;2&apos; d=&apos;M2 5l6 6 6-6&apos;/%3e%3c/svg%3e");'>
- <option value="">Timezone</option>
- <option disabled>———————————————</option>
- <?php foreach ($timezones as $timezone => $tz): ?>
- <option value="<?= $tz ?>"><?= $timezone ?></option>
- <?php endforeach; ?>
- </select>
-
- <hr>
-
- <div style="display: grid; grid-template-columns: max-content 1fr; grid-gap: 10px;">
- <?php foreach ($methods as $name => $method): ?>
- <div style="justify-content: right; display: flex; align-items: center;"><?= $method["name"] ?>:</div>
- <div>
- <input type="text" placeholder="<?= $method["name"] ?>" name="<?= $name ?>" class="form-control" style="color:white;background:#111;border-color:#222;">
- </div>
- <?php endforeach; ?>
- </div>
-
- <hr>
-
- <button class="btn btn-primary" id="create-edit-submit" type="submit">Create</button>
- <button id="create-edit-reset" style="display: none;" type="reset"></button>
- </form>
- </div>
- </div>
- </div>
-</div>
-
-<div class="modal fade" id="delete">
- <div class="modal-dialog">
- <div class="modal-content">
- <div class="modal-header">
- <h4 class="modal-title" id="delete-title">Delete "<span id="delete-title-name">X</span>"?</h4>
- <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
- </div>
-
- <div class="modal-body">
- <p>Are you really sure you want to delete "<span id="delete-description-name">X</span>"? This cannot be undone and will delete all data associated with this contact.</p>
- <a href="" id="delete-link" class="btn btn-primary">Delete</a>
- <a data-bs-dismiss="modal" class="btn btn-secondary">Cancel</a>
- </div>
- </div>
- </div>
-</div>
-
-<style>
- .modal-header {
- border-bottom: 1px solid #353738;
- }
-
- .modal-content {
- border: 1px solid rgba(255, 255, 255, .2);
- background-color: #111;
- }
-
- .btn-close {
- filter: invert(1);
- }
-
- .contact-item > * {
- padding: 5px 10px;
- }
-
- .contact-item {
- background-color: #111;
- border-radius: 5px;
- margin: 10px 0;
- padding: 5px;
- }
-
- .contact-method {
- background-color: #222;
- border-radius: 5px;
- padding: 5px;
- margin: 5px 0;
- }
-
- @media (max-width: 991px) {
- .contact-item, .contact-item-main {
- grid-template-columns: 1fr !important;
- }
-
- .contact-item > * {
- padding-top: 0 !important;
- padding-bottom: 0 !important;
- }
- }
-</style>
-
-<script>
- function createNew() {
- document.getElementById("create-edit-title").innerText = "Create a new contact";
- document.getElementById("create-edit-submit").innerText = "Create";
- document.getElementById("create-edit-id").value = "";
- document.getElementById("create-edit-reset").click();
-
- new bootstrap.Modal(document.getElementById("create-edit")).show();
- }
-
- function editContact(id) {
- document.getElementById("create-edit-title").innerText = "Edit an existing contact";
- document.getElementById("create-edit-submit").innerText = "Save";
- document.getElementById("create-edit-id").value = id;
- document.getElementById("create-edit-reset").click();
-
- for (let key of Object.keys(window.contacts[id])) {
- document.getElementsByName(key)[0].value = window.contacts[id][key] ?? "";
- }
-
- new bootstrap.Modal(document.getElementById("create-edit")).show();
- }
-
- function deleteContact(id) {
- document.getElementById("delete-title-name").innerText = document.getElementById("delete-description-name").innerText = window.contacts[id]["nick"];
- document.getElementById("delete-link").href = "/-/contacts/?delete=" + id;
-
- new bootstrap.Modal(document.getElementById("delete")).show();
- }
-
- function copyToClipboard(b64) {
- navigator.clipboard.writeText(atob(b64));
- }
-</script>
-
-<?php require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/components/footer.inc'; ?>
diff --git a/pages/edit-private.inc b/pages/edit-private.inc
deleted file mode 100644
index f26c8c6..0000000
--- a/pages/edit-private.inc
+++ /dev/null
@@ -1,40 +0,0 @@
-<?php
-
-require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/init.inc"; global $title; global $isLoggedIn; global $lang; global $pages;
-
-if (!isset($_GET['_']) || trim($_GET['_']) === "") peh_error("Invalid request", 400);
-
-$parts = explode("/", $_GET['_']);
-array_shift($parts);
-array_shift($parts);
-$system = $parts[0];
-$member = ($parts[1] ?? null) === "" ? null : $parts[1];
-
-if ($system !== "cloudburst" && $system !== "raindrops") peh_error("Invalid system name: " . $system, 400);
-$systemCommonName = $system === "cloudburst" ? "Cloudburst System" : "Raindrops System";
-$systemID = $system === "cloudburst" ? "ynmuc" : "gdapd";
-
-if ($member === null) {
- peh_error("Unsupported target: system", 500);
-} else {
- $members = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/" . $systemID . "/members.json"), true);
- $memberData = null;
- $memberCommonName = null;
- $memberID = null;
-
- foreach ($members as $m) {
- if ($m['name'] === $member) {
- $memberData = $m;
- $memberCommonName = $m['display_name'] ?? $m['name'];
- $memberID = $m['id'];
- }
- }
-
- if ($memberData === null) {
- peh_error("System member not found", 404);
- }
-
- require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/fragments/edit-private.inc';
-}
-
-exit; \ No newline at end of file
diff --git a/pages/edit.inc b/pages/edit.inc
deleted file mode 100644
index 28b8d88..0000000
--- a/pages/edit.inc
+++ /dev/null
@@ -1,44 +0,0 @@
-<?php
-
-require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/init.inc"; global $isLowerLoggedIn; global $title; global $isLoggedIn; global $lang; global $pages; global $app;
-
-if (!isset($_GET['_']) || trim($_GET['_']) === "") peh_error("Invalid request", 400);
-
-$parts = explode("/", $_GET['_']);
-array_shift($parts);
-array_shift($parts);
-$system = $parts[0];
-$member = !isset($parts[1]) || $parts[1] === "" ? null : $parts[1];
-
-if ($system !== "cloudburst" && $system !== "raindrops" && $system !== $app["other"]["slug"]) peh_error("Invalid system name: " . $system, 400);
-$systemCommonName = $system === "cloudburst" ? "Cloudburst System" : ($system === "raindrops" ? "Raindrops System" : $app["other"]["name"]);
-$systemID = $system === "cloudburst" ? "ynmuc" : ($system === "raindrops" ? "gdapd" : $app["other"]["id"]);
-
-if ($isLowerLoggedIn && $systemID !== $app["other"]["id"]) {
- header("Location: /") and die();
-}
-
-if ($member === null) {
- require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/fragments/sysedit.inc';
-} else {
- $members = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/" . $systemID . "/members.json"), true);
- $memberData = null;
- $memberCommonName = null;
- $memberID = null;
-
- foreach ($members as $m) {
- if ($m['name'] === $member) {
- $memberData = $m;
- $memberCommonName = $m['display_name'] ?? $m['name'];
- $memberID = $m['id'];
- }
- }
-
- if ($memberData === null) {
- peh_error("System member not found", 404);
- }
-
- require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/fragments/edit.inc';
-}
-
-exit; \ No newline at end of file
diff --git a/pages/home.inc b/pages/home.inc
index fcd04ab..11a01de 100644
--- a/pages/home.inc
+++ b/pages/home.inc
@@ -23,9 +23,9 @@ function banner() { global $isLoggedIn; global $isLowerLoggedIn; $byColor = getM
<div id="banner-lower" style="padding:5px 10px;background:#3332328a;position:relative;z-index: 999;backdrop-filter: blur(30px);">
<h2 style="margin-top: 20px;">Cold Haze</h2>
<?php if ($isLoggedIn || $isLowerLoggedIn): ?>
- <p><?= count($byColor) ?> ponies in 3 plural systems</p>
+ <p><?= count($byColor) ?> ponies in 4 plural systems</p>
<?php else: ?>
- <p><?= count($byColor) ?> <?= $lang["home"]["intro"] ?></p>
+ <p><?= count($byColor) ?> ponies in 3 plural systems</p>
<?php endif; ?>
</div>
</div>
@@ -34,35 +34,14 @@ function banner() { global $isLoggedIn; global $isLowerLoggedIn; $byColor = getM
function members() { global $isLoggedIn; global $isLowerLoggedIn; global $app; ?>
<div id="new-homepage" style="margin-top:20px;">
- <div id="new-homepage-systems" <?php if ($isLoggedIn || $isLowerLoggedIn): ?>style="grid-template-columns: repeat(3, 1fr);"<?php endif; ?>>
+ <div id="new-homepage-systems" <?php if ($isLoggedIn || $isLowerLoggedIn): ?>style="grid-template-columns: repeat(4, 1fr);"<?php endif; ?>>
<?php newHomepage("ynmuc", "cloudburst", true); ?>
<?php newHomepage("gdapd", "raindrops", true); ?>
<?php if ($isLoggedIn || $isLowerLoggedIn) newHomepage($app["other"]["id"], $app["other"]["slug"], true); ?>
+ <?php newHomepage("hrbom", "moonglow", true); ?>
</div>
</div>
-
- <div id="hpd-legacy" style="margin-top: 20px; background:rgba(255, 255, 255, .1);border-radius:10px;padding:10px 10px 10px 20px;display:grid;grid-template-columns: 128px 1fr;margin-bottom:10px;">
- <a style="display:flex;margin: -10px -20px;align-items:center;justify-content:center;text-align:center;padding: 10px 20px;border-radius: 10px;background: #77777755;width: 148px;text-decoration:none;color:white;filter:none !important;" class="hpd-system home-legacy">
- <div style="text-align:center;"><img class="home-legacy-icon" src="/assets/icons/legacy.svg" style="width:64px;"><br>Pony Legacy</div>
- </a>
-
- <div style="display:grid;grid-template-columns:repeat(6, 1fr);padding-left:10px;grid-gap:10px;">
- <?php foreach (array_filter(scandir($_SERVER['DOCUMENT_ROOT'] . "/includes/data/legacy"), function ($i) {
- return !str_starts_with($i, ".");
- }) as $id):
- $id = substr($id, 0, -5);
- $member = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/legacy/" . $id . ".json"), true);
-
- echo('<a class="member-card-container" style="text-decoration:none !important;filter:none !important;"><div class="hpd-item-card" style="background-color:rgba(255, 255, 255, .1);border:1px solid ' . (isset($member['color']) ? "#" . $member['color'] . "55" : "transparent") . ';outline-color:' . (isset($member['color']) ? "#" . $member['color'] . "55" : "transparent") . ';border-radius:10px;text-align:center;display:flex;align-items:center;justify-content:center;padding:5px;opacity:5;"><div>
-<img alt="" src="' . $member["avatar"] . '" style="border-radius:999px;background-color:rgba(0, 0, 0, .25);height:48px;display:block;margin-left:auto;margin-right:auto;">
-<div class="member-card-name" style="text-decoration:none;color:white;margin-top:5px;">' . ($member['name'] ?? $id) . '</div>
-<div class="member-card-prefix" style="text-decoration:none !important;color:white;">' . (isset($member['prefix']) ? "<code style='color:white;'>" . $member['prefix'] . "</code> · " : "") . date('j M Y', strtotime($member["date"])) . '</div>
-</div></div></a>');
-
- endforeach; ?>
- </div>
- </div>
<?php } ?>
<br>
@@ -164,7 +143,7 @@ function members() { global $isLoggedIn; global $isLowerLoggedIn; global $app; ?
<div id="timeline"></div>
<script>
async function refreshTimeline() {
- document.getElementById("timeline").innerHTML = await (await fetch("/api/timeline?gdapd&ynmuc<?= ($isLowerLoggedIn || $isLoggedIn) ? "&" . $app["other"]["id"] : "" ?>")).text();
+ document.getElementById("timeline").innerHTML = await (await fetch("/api/timeline?gdapd&ynmuc<?= ($isLowerLoggedIn || $isLoggedIn) ? "&" . $app["other"]["id"] : "" ?>&hrbom")).text();
Array.from(document.getElementsByClassName("dynamic-time")).forEach((el) => {
let time = el.getAttribute("data-time");
@@ -182,6 +161,12 @@ function members() { global $isLoggedIn; global $isLowerLoggedIn; global $app; ?
</script>
</div>
+ <?php if ($isLoggedIn || $isLowerLoggedIn): ?>
+ <div class="alert alert-warning" style="margin-top: 20px;">
+ <b>Cold Haze Documents is now deprecated.</b> Cold Haze's Documents feature is now deprecated in favor of Google Docs and will be removed in the future. Please migrate your documents to Google Drive as soon as possible.
+ </div>
+ <?php endif; ?>
+
<!--<div class="alert alert-warning" style="margin-top:20px;">
<b>Notice:</b> The administrators are currently trying a new optimisation technique based on a virtual file system (chvfs). Data loss, corruption or inconsistency may happen and should be reported on <a href="https://bugs.equestria.dev/issues/CH" target="_blank">bugs.equestria.dev</a>.
</div>-->
diff --git a/pages/metadata.inc b/pages/metadata.inc
index 2a67e9f..aea128b 100644
--- a/pages/metadata.inc
+++ b/pages/metadata.inc
@@ -12,9 +12,9 @@ array_shift($parts);
$system = $parts[0];
$member = !isset($parts[1]) || $parts[1] === "" ? null : $parts[1];
-if ($system !== "cloudburst" && $system !== "raindrops" && $system !== $app["other"]["slug"]) peh_error("Invalid system name: " . $system, 400);
-$systemCommonName = $system === "cloudburst" ? "Cloudburst System" : ($system === $app["other"]["slug"] ? $app["other"]["name"] : "Raindrops System");
-$systemID = $system === "cloudburst" ? "ynmuc" : ($system === $app["other"]["slug"] ? $app["other"]["id"] : "gdapd");
+if ($system !== "cloudburst" && $system !== "raindrops" && $system !== "moonglow" && $system !== $app["other"]["slug"]) peh_error("Invalid system name: " . $system, 400);
+$systemCommonName = $system === "cloudburst" ? "Cloudburst System" : ($system === $app["other"]["slug"] && ($isLoggedIn || $isLowerLoggedIn) ? $app["other"]["name"] : ($system === "moonglow" ? "Moonglow" : "Raindrops System"));
+$systemID = $system === "cloudburst" ? "ynmuc" : ($system === $app["other"]["slug"] && ($isLoggedIn || $isLowerLoggedIn) ? $app["other"]["id"] : ($system === "moonglow" ? "hrbom" : "gdapd"));
if ($isLowerLoggedIn && $systemID !== $app["other"]["id"]) {
header("Location: /");
diff --git a/pages/page.inc b/pages/page.inc
index 931e6e5..fb63383 100644
--- a/pages/page.inc
+++ b/pages/page.inc
@@ -9,13 +9,18 @@ if (!isset($_GET['_']) || trim($_GET['_']) === "") peh_error("Invalid request",
$parts = explode("/", $_GET['_']);
-if (($parts[0] !== "cloudburst" && $parts[0] !== "raindrops" && $parts[0] !== $app["other"]["slug"]) && (!(count($parts) > 2) || $parts[1] === "-")) {
+if (($parts[0] !== "cloudburst" && $parts[0] !== "raindrops" && $parts[0] !== "moonglow" && $parts[0] !== $app["other"]["slug"]) && (!(count($parts) > 2) || $parts[1] === "-")) {
$namesCloudburst = [...array_map(function ($i) {
return $i['name'];
}, json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/ynmuc/members.json"), true)), "unknown-cb"];
$namesRaindrops = [...array_map(function ($i) {
return $i['name'];
}, json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gdapd/members.json"), true)), "unknown-rd"];
+ $namesMoonglow = array_map(function ($i) {
+ return $i['name'];
+ }, array_filter(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/hrbom/members.json"), true), function ($i) {
+ return file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/metadata/" . $i["id"] . ".json");
+ }));
$namesOther = [];
if ($isLoggedIn || $isLowerLoggedIn) {
@@ -32,6 +37,8 @@ if (($parts[0] !== "cloudburst" && $parts[0] !== "raindrops" && $parts[0] !== $a
$parts[0] = "cloudburst";
} else if (in_array($parts[1], $namesRaindrops)) {
$parts[0] = "raindrops";
+ } else if (in_array($parts[1], $namesMoonglow)) {
+ $parts[0] = "moonglow";
} else if (in_array($parts[1], $namesOther) && ($isLoggedIn || $isLowerLoggedIn)) {
$parts[0] = $app["other"]["slug"];
}
@@ -40,11 +47,11 @@ if (($parts[0] !== "cloudburst" && $parts[0] !== "raindrops" && $parts[0] !== $a
}
$system = $parts[0];
-$member = (isset($parts[1]) ? $parts[1] : null) === "" ? null : (isset($parts[1]) ? $parts[1] : null);
+$member = ($parts[1] ?? null) === "" ? null : ($parts[1] ?? null);
-if ($system !== "cloudburst" && $system !== "raindrops" && ($system !== $app["other"]["slug"] && !$isLowerLoggedIn && !$isLoggedIn)) peh_error("System not found", 404);
-$systemCommonName = $system === "cloudburst" ? "Cloudburst System" : ($system === $app["other"]["slug"] && ($isLoggedIn || $isLowerLoggedIn) ? $app["other"]["name"] : "Raindrops System");
-$systemID = $system === "cloudburst" ? "ynmuc" : ($system === $app["other"]["slug"] && ($isLoggedIn || $isLowerLoggedIn) ? $app["other"]["id"] : "gdapd");
+if ($system !== "cloudburst" && $system !== "raindrops" && $system !== "moonglow" && ($system !== $app["other"]["slug"] && !$isLowerLoggedIn && !$isLoggedIn)) peh_error("System not found", 404);
+$systemCommonName = $system === "cloudburst" ? "Cloudburst System" : ($system === $app["other"]["slug"] && ($isLoggedIn || $isLowerLoggedIn) ? $app["other"]["name"] : ($system === "moonglow" ? "Moonglow" : "Raindrops System"));
+$systemID = $system === "cloudburst" ? "ynmuc" : ($system === $app["other"]["slug"] && ($isLoggedIn || $isLowerLoggedIn) ? $app["other"]["id"] : ($system === "moonglow" ? "hrbom" : "gdapd"));
if ($member === null) {
global $_SystemName;
diff --git a/pages/pleasure.inc b/pages/pleasure.inc
index ec468d5..883af9a 100644
--- a/pages/pleasure.inc
+++ b/pages/pleasure.inc
@@ -1,6 +1,12 @@
<?php
-require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/init.inc"; global $title; global $isLoggedIn; global $lang; global $pages;
+require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/init.inc"; global $title; global $isLoggedIn; global $lang; global $_PROFILE; global $pages;
+
+if ($_PROFILE["id"] !== "0f3661dd-ff60-4cde-bf13-1b0a59e78f11" && $_PROFILE["id"] !== "ce1606a9-344f-4547-bffe-bc2ab0eebfa8") {
+ header("Location: /");
+ die();
+}
+
$emergencyHeader = true; require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/components/header.inc';
?>
diff --git a/pages/schedules.inc b/pages/schedules.inc
index 03277cc..dde2981 100644
--- a/pages/schedules.inc
+++ b/pages/schedules.inc
@@ -33,19 +33,8 @@ global $use2023UI;
<div class="container">
<h2>Schedules</h2>
- <h4>World clock</h4>
-
<div id="schedules" style="margin-top: 20px; display: grid; grid-template-columns: repeat(4, 1fr); grid-gap: 20px;">
<div>
- <div id="live-time-other2-outer" class="day-gradient" style="text-align: center; background-color: rgba(255, 255, 255, .1); padding: 20px 0; border-radius: 10px; margin-bottom: 20px;">
- <b>Meadowsys</b><br>
- <h3 id="live-time-other2">--:--</h3>
- </div>
-
- <hr style="display: none;" class="schedules-separator">
- </div>
-
- <div>
<div id="live-time-other-outer" class="day-gradient" style="text-align: center; background-color: rgba(255, 255, 255, .1); padding: 20px 0; border-radius: 10px; margin-bottom: 20px;">
<b><?= $app["other"]["name"] ?></b><br>
<h3 id="live-time-other">--:--</h3>
@@ -69,6 +58,13 @@ global $use2023UI;
<h3 id="live-time-raindrops">--:--</h3>
</div>
</div>
+
+ <div>
+ <div id="live-time-moonwind-outer" class="day-gradient" style="text-align: center; background-color: rgba(255, 255, 255, .1); padding: 20px 0; border-radius: 10px; margin-bottom: 20px;">
+ <b>Moonwind System</b><br>
+ <h3 id="live-time-moonwind">--:--</h3>
+ </div>
+ </div>
</div>
</div>
@@ -87,31 +83,31 @@ global $use2023UI;
}
function updateTime() {
- let time0 = (new Intl.DateTimeFormat('en-US', {
- timeZone: 'America/Los_Angeles',
+ let time1 = (new Intl.DateTimeFormat('en-US', {
+ timeZone: 'Europe/Paris',
hour: 'numeric',
minute: '2-digit',
- hour12: true
+ hour12: false
})).format(new Date());
- document.getElementById("live-time-other2").innerText = time0;
- document.getElementById("live-time-other2-outer").style.backgroundPositionY = getDayPercentage(time0) + "%";
+ document.getElementById("live-time-raindrops").innerText = time1;
+ document.getElementById("live-time-raindrops-outer").style.backgroundPositionY = getDayPercentage(time1) + "%";
- let time1 = (new Intl.DateTimeFormat('en-US', {
- timeZone: 'Europe/Paris',
+ let time4 = (new Intl.DateTimeFormat('en-US', {
+ timeZone: 'Europe/Kyiv',
hour: 'numeric',
minute: '2-digit',
- hour12: true
+ hour12: false
})).format(new Date());
- document.getElementById("live-time-raindrops").innerText = time1;
- document.getElementById("live-time-raindrops-outer").style.backgroundPositionY = getDayPercentage(time1) + "%";
+ document.getElementById("live-time-moonwind").innerText = time4;
+ document.getElementById("live-time-moonwind-outer").style.backgroundPositionY = getDayPercentage(time4) + "%";
let time2 = (new Intl.DateTimeFormat('en-US', {
timeZone: 'Europe/London',
hour: 'numeric',
minute: '2-digit',
- hour12: true
+ hour12: false
})).format(new Date());
document.getElementById("live-time-cloudburst").innerText = time2;
@@ -121,24 +117,11 @@ global $use2023UI;
timeZone: 'America/Chicago',
hour: 'numeric',
minute: '2-digit',
- hour12: true
+ hour12: false
})).format(new Date());
document.getElementById("live-time-other").innerText = time3;
document.getElementById("live-time-other-outer").style.backgroundPositionY = getDayPercentage(time3) + "%";
-
- document.getElementById("live-time-other1").innerText = (new Intl.DateTimeFormat('en-US', {
- timeZone: 'America/Anchorage',
- hour: 'numeric',
- minute: '2-digit',
- hour12: true
- })).format(new Date());
- document.getElementById("live-time-other2").innerText = (new Intl.DateTimeFormat('en-US', {
- timeZone: 'America/Vancouver',
- hour: 'numeric',
- minute: '2-digit',
- hour12: true
- })).format(new Date());
}
updateTime();
@@ -148,9 +131,4 @@ global $use2023UI;
}, 10000);
</script>
-<?php if ($use2023UI) {
- echo "<div class='container'><hr></div>";
- require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/fragments/evening.inc";
-} ?>
-
<?php require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/components/footer.inc'; ?>
diff --git a/pages/sessions.inc b/pages/sessions.inc
index 0e4e779..fc861bf 100644
--- a/pages/sessions.inc
+++ b/pages/sessions.inc
@@ -57,8 +57,8 @@ $verifiedNames = [
foreach ($list as $token): $session = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/sessions/" . $token), true); if (isset($session["profile"]) && isset($session["name"]) && ($session["profile"]["id"] ?? "") === ($_PROFILE["id"] ?? "")): uasort($session["addresses"], function ($a, $b) {
return $b - $a;
}); ?>
- <a class="list-group-item list-group-item-action" onclick="logOut(&quot;<?= sha1($token) . md5($token) ?>&quot;);">
- <b><?= $session["name"] ?></b><?php if ($token === $_COOKIE["PEH2_SESSION_TOKEN"]): ?><span style="margin-left: 10px;" class="badge bg-primary">This device</span><?php endif; ?><script>window.devices["<?= sha1($token) . md5($token) ?>"]=JSON.parse(`<?= json_encode([
+ <a class="list-group-item list-group-item-action" onclick="logOut(&quot;<?= bin2hex(substr($token, 0, 50)) ?>&quot;);">
+ <b><?= $session["name"] ?></b><?php if ($token === $_COOKIE["PEH2_SESSION_TOKEN"]): ?><span style="margin-left: 10px;" class="badge bg-primary">This device</span><?php endif; ?><script>window.devices["<?= bin2hex(substr($token, 0, 50)) ?>"]=JSON.parse(`<?= json_encode([
"name" => trim($session["name"]),
"lastIP" => array_keys($session["addresses"])[count(array_keys($session["addresses"])) > 0 ? count(array_keys($session["addresses"])) - 1 : 0] ?? "-",
"lastSeen" => timeAgo($session["last"]),
diff --git a/pages/stats.inc b/pages/stats.inc
deleted file mode 100644
index 742fb87..0000000
--- a/pages/stats.inc
+++ /dev/null
@@ -1,504 +0,0 @@
-<?php
-
-require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/init.inc"; global $title; global $isLoggedIn; global $lang; global $pages;
-require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/components/header.inc';
-
-if (!file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/cache/stats.json")) file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/cache/stats.json", "{}");
-
-$cache = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/cache/stats.json"), true);
-
-?>
-
-<script src="/assets/editor/chart.js"></script>
-
-<br>
-<div class="container">
- <div id="page-content">
- <h2>Statistics</h2>
- <?php
-
- if (!isset($cache["content"]) || date('Y-m-d') !== $cache["day"]): ob_start();
-
- $switchesRaindrops = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gdapd/switches.json"), true);
- $switchesCloudburst = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/ynmuc/switches.json"), true);
-
- $weeks = [];
- $weeksRectified = [];
-
- $lastWeek = 0;
- foreach ($switchesRaindrops as $switch) {
- $week = date('YW', strtotime($switch["timestamp"]));
- if ($lastWeek === 0) $lastWeek = $week;
-
- if (!isset($weeks[$week])) $weeks[$week] = [
- "cloudburst" => 0,
- "raindrops" => 0,
- "total" => 0,
- "end" => strtotime($switch["timestamp"]),
- "start" => null
- ];
-
- if ($week !== $lastWeek) {
- if (isset($weeks[$lastWeek])) {
- $weeks[$lastWeek]["start"] = strtotime($switch["timestamp"]);
- $lastWeek = $week;
- }
- }
-
- $weeks[$week]["raindrops"]++;
- $weeks[$week]["total"]++;
- }
-
- $lastWeek = 0;
- foreach ($switchesCloudburst as $switch) {
- $week = date('YW', strtotime($switch["timestamp"]));
- if ($lastWeek === 0) $lastWeek = $week;
-
- if (!isset($weeks[$week])) $weeks[$week] = [
- "cloudburst" => 0,
- "raindrops" => 0,
- "total" => 0,
- "end" => strtotime($switch["timestamp"]),
- "start" => null
- ];
-
- if ($week !== $lastWeek) {
- if (isset($weeks[$lastWeek])) {
- $weeks[$lastWeek]["start"] = strtotime($switch["timestamp"]);
- $lastWeek = $week;
- }
- }
-
- $weeks[$week]["cloudburst"]++;
- $weeks[$week]["total"]++;
- }
-
- $index = 0;
- foreach ($weeks as $id => $week) {
- if ($index >= 20) continue;
- $weeksRectified[$id] = $week;
- $index++;
- }
-
- $weeksRectified = array_filter(array_reverse($weeksRectified), function ($i) {
- return $i["start"] > 1651363200;
- });
-
- $members = [];
- $frontersMonth = [];
-
- $fronts = [];
- $lastFrontIDs = [];
-
- foreach (array_reverse($switchesRaindrops) as $switch) {
- foreach ($lastFrontIDs as $frontID) {
- $fronts[$frontID]["end"] = strtotime($switch["timestamp"]);
- }
- $lastFrontIDs = [];
-
- $index = 0; foreach ($switch["members"] as $member) {
- if (strtotime($switch["timestamp"]) - (time() - 86400*30) < 0) continue;
- $fronts[$switch["id"] . ":" . $index] = [
- "member" => $member,
- "start" => strtotime($switch["timestamp"]),
- "end" => strtotime(date('c')),
- "duration" => null
- ];
- $lastFrontIDs[] = $switch["id"] . ":" . $index;
- } $index++;
- }
-
- foreach ($fronts as $id => $front) {
- $fronts[$id]["duration"] = $front["end"] - $front["start"];
-
- if (!($front["start"] - (time() - 86400*30) < 0)) {
- if (!isset($members[$front["member"]])) $members[$front["member"]] = [
- "time" => 0,
- "name" => getMemberWithoutSystem($front["member"])["display_name"],
- "color" => getMemberWithoutSystem($front["member"])["color"],
- ];
- $members[$front["member"]]["time"] += $fronts[$id]["duration"];
- }
- }
-
- foreach ($fronts as $front) {
- if (!isset($frontersMonth[date('Y-m', $front["start"])])) $frontersMonth[date('Y-m', $front["start"])] = [];
- if (!isset($frontersMonth[date('Y-m', $front["start"])][$front["member"]])) $frontersMonth[date('Y-m', $front["start"])][$front["member"]] = 0;
- $frontersMonth[date('Y-m', $front["start"])][$front["member"]] += $front["duration"];
- }
-
- $fronts = [];
- $lastFrontIDs = [];
-
- foreach (array_reverse($switchesCloudburst) as $switch) {
- foreach ($lastFrontIDs as $frontID) {
- $fronts[$frontID]["end"] = strtotime($switch["timestamp"]);
- }
- $lastFrontIDs = [];
-
- $index = 0; foreach ($switch["members"] as $member) {
- $fronts[$switch["id"] . ":" . $index] = [
- "member" => $member,
- "start" => strtotime($switch["timestamp"]),
- "end" => strtotime(date('c')),
- "duration" => null
- ];
- $lastFrontIDs[] = $switch["id"] . ":" . $index;
- } $index++;
- }
-
- foreach ($fronts as $id => $front) {
- $fronts[$id]["duration"] = $front["end"] - $front["start"];
-
- if (!($front["start"] - (time() - 86400*30) < 0)) {
- if (!isset($members[$front["member"]])) $members[$front["member"]] = [
- "time" => 0,
- "name" => getMemberWithoutSystem($front["member"])["display_name"],
- "color" => getMemberWithoutSystem($front["member"])["color"],
- ];
- $members[$front["member"]]["time"] += $fronts[$id]["duration"];
- }
- }
-
- foreach ($fronts as $front) {
- if (!isset($frontersMonth[date('Y-m', $front["start"])])) $frontersMonth[date('Y-m', $front["start"])] = [];
- if (!isset($frontersMonth[date('Y-m', $front["start"])][$front["member"]])) $frontersMonth[date('Y-m', $front["start"])][$front["member"]] = 0;
- $frontersMonth[date('Y-m', $front["start"])][$front["member"]] += $front["duration"];
- }
-
- $fronts = array_reverse($fronts);
- uasort($members, function ($a, $b) {
- return $b["time"] - $a["time"];
- });
-
- $frontersMonthRectified = [];
- foreach ($frontersMonth as $monthID => $month) {
- $thisMonth = [];
-
- foreach ($month as $id => $time) {
- $thisMonth[$id] = [
- "duration" => $time,
- "name" => getMemberWithoutSystem($id)["display_name"],
- "color" => getMemberWithoutSystem($id)["color"]
- ];
- }
-
- $frontersMonthRectified[$monthID] = $thisMonth;
- }
-
- uasort($frontersMonthRectified, function ($a, $b) use ($frontersMonthRectified) {
- return strtotime(array_search($a, $frontersMonthRectified) . "-01") - strtotime(array_search($b, $frontersMonthRectified) . "-01");
- });
-
- $frontersMonthMembers = [];
- foreach ($frontersMonthRectified as $month => $fronters) {
- foreach ($fronters as $fronter => $data) {
- foreach (scoreOrderGlobal() as $member) {
- if (!isset($frontersMonthMembers[$member["id"]])) $frontersMonthMembers[$member["id"]] = [];
- }
- }
-
- foreach ($frontersMonthMembers as $key => $member) {
- $frontersMonthMembers[$key][$month] = $frontersMonthRectified[$month][$key] ?? [
- "duration" => 0
- ];
- }
- }
-
- ?>
-
- <h3>Switches per week</h3>
- <canvas id="graph-00" style="width: 100%; height: 300px; max-height: 100%;"></canvas>
- <script>
- const ctx0 = document.getElementById('graph-00').getContext('2d');
- window.chart00 = [
- {
- label: "Raindrops System",
- data: JSON.parse(`<?= json_encode(array_map(function ($i) {
- return $i["raindrops"];
- }, array_values($weeksRectified))) ?>`),
- borderColor: "#e598ff"
- },
- {
- label: "Cloudburst System",
- data: JSON.parse(`<?= json_encode(array_map(function ($i) {
- return $i["cloudburst"];
- }, array_values($weeksRectified))) ?>`),
- borderColor: "#98e0ff"
- },
- {
- label: "All systems",
- data: JSON.parse(`<?= json_encode(array_map(function ($i) {
- return $i["total"];
- }, array_values($weeksRectified))) ?>`),
- borderColor: "rgba(160,255,153,0.5)",
- borderDash: [5]
- }
- ];
- const graph0 = new Chart(ctx0, {
- type: 'line',
- data: {
- labels: JSON.parse(`<?= json_encode(array_map(function ($i) {
- return date("M d", $i["start"]) . " to " . date("M d", $i["end"]);
- }, array_values($weeksRectified))) ?>`),
- datasets: window.chart00
- },
- options: {
- animation: {
- duration: 0
- },
- scales: {
- y: {
- beginAtZero: true,
- grid: {
- color: "rgba(255,255,255,0.25)"
- }
- }
- },
- plugins: {
- legend: {
- display: false
- },
- tooltip: {
- intersect: false
- }
- }
- }
- });
- </script>
-
- <h3 style="margin-top: 15px;">Average switches per day of the week</h3>
- <canvas id="graph-01" style="width: 100%; height: 300px; max-height: 100%;"></canvas>
- <?php
-
- $switchesDaysRaindrops = [0, 0, 0, 0, 0, 0, 0];
- $amountDaysRaindrops = [0, 0, 0, 0, 0, 0, 0];
- $switchDoWRaindrops = [0, 0, 0, 0, 0, 0, 0];
- $daysRaindrops = [];
-
- $switchesDaysCloudburst = [0, 0, 0, 0, 0, 0, 0];
- $amountDaysCloudburst = [0, 0, 0, 0, 0, 0, 0];
- $switchDoWCloudburst = [0, 0, 0, 0, 0, 0, 0];
- $daysCloudburst = [];
-
- foreach ($switchesCloudburst as $switch) {
- if (!in_array(date("Y-m-d", strtotime($switch["timestamp"])), $daysCloudburst)) {
- $daysCloudburst[] = date("Y-m-d", strtotime($switch["timestamp"]));
- $amountDaysCloudburst[(int)date('N', strtotime($switch["timestamp"])) - 1]++;
- }
-
- $switchesDaysCloudburst[(int)date('N', strtotime($switch["timestamp"])) - 1]++;
- }
-
- $switchDoWCloudburst = [
- $switchesDaysCloudburst[0] / $amountDaysCloudburst[0],
- $switchesDaysCloudburst[1] / $amountDaysCloudburst[1],
- $switchesDaysCloudburst[2] / $amountDaysCloudburst[2],
- $switchesDaysCloudburst[3] / $amountDaysCloudburst[3],
- $switchesDaysCloudburst[4] / $amountDaysCloudburst[4],
- $switchesDaysCloudburst[5] / $amountDaysCloudburst[5],
- $switchesDaysCloudburst[6] / $amountDaysCloudburst[6]
- ];
-
- foreach ($switchesRaindrops as $switch) {
- if (!in_array(date("Y-m-d", strtotime($switch["timestamp"])), $daysRaindrops)) {
- $daysRaindrops[] = date("Y-m-d", strtotime($switch["timestamp"]));
- $amountDaysRaindrops[(int)date('N', strtotime($switch["timestamp"])) - 1]++;
- }
-
- $switchesDaysRaindrops[(int)date('N', strtotime($switch["timestamp"])) - 1]++;
- }
-
- $switchDoWRaindrops = [
- $switchesDaysRaindrops[0] / $amountDaysRaindrops[0],
- $switchesDaysRaindrops[1] / $amountDaysRaindrops[1],
- $switchesDaysRaindrops[2] / $amountDaysRaindrops[2],
- $switchesDaysRaindrops[3] / $amountDaysRaindrops[3],
- $switchesDaysRaindrops[4] / $amountDaysRaindrops[4],
- $switchesDaysRaindrops[5] / $amountDaysRaindrops[5],
- $switchesDaysRaindrops[6] / $amountDaysRaindrops[6]
- ];
-
- $switchDoW = [
- $switchDoWCloudburst[0] + $switchDoWRaindrops[0],
- $switchDoWCloudburst[1] + $switchDoWRaindrops[1],
- $switchDoWCloudburst[2] + $switchDoWRaindrops[2],
- $switchDoWCloudburst[3] + $switchDoWRaindrops[3],
- $switchDoWCloudburst[4] + $switchDoWRaindrops[4],
- $switchDoWCloudburst[5] + $switchDoWRaindrops[5],
- $switchDoWCloudburst[6] + $switchDoWRaindrops[6]
- ];
-
- ?>
- <script>
- const ctx1 = document.getElementById('graph-01').getContext('2d');
- window.chart01 = [
- {
- label: "Switches per week",
- data: JSON.parse(`<?= json_encode($switchDoW) ?>`),
- backgroundColor: [
- 'rgba(255, 99, 132, 0.2)',
- 'rgba(255, 159, 64, 0.2)',
- 'rgba(255, 205, 86, 0.2)',
- 'rgba(75, 192, 192, 0.2)',
- 'rgba(54, 162, 235, 0.2)',
- 'rgba(153, 102, 255, 0.2)',
- 'rgba(201, 203, 207, 0.2)'
- ],
- borderColor: [
- 'rgb(255, 99, 132)',
- 'rgb(255, 159, 64)',
- 'rgb(255, 205, 86)',
- 'rgb(75, 192, 192)',
- 'rgb(54, 162, 235)',
- 'rgb(153, 102, 255)',
- 'rgb(201, 203, 207)'
- ],
- borderWidth: 1
- }
- ];
- const graph1 = new Chart(ctx1, {
- type: 'bar',
- data: {
- labels: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
- datasets: window.chart01
- },
- options: {
- animation: {
- duration: 0
- },
- scales: {
- y: {
- grid: {
- color: "rgba(255,255,255,0.25)"
- }
- }
- },
- plugins: {
- legend: {
- display: false
- },
- tooltip: {
- intersect: false
- }
- }
- }
- });
- </script>
-
- <h3 style="margin-top: 15px;">Switches per hour of the day</h3>
- <canvas id="graph-02" style="width: 100%; height: 300px; max-height: 100%;"></canvas>
- <?php
-
- $switchHoursRaindrops = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
- $switchHoursCloudburst = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
-
- foreach ($switchesCloudburst as $switch) {
- $switchHoursCloudburst[(int)date('G', strtotime($switch["timestamp"]))]++;
- }
-
- foreach ($switchesRaindrops as $switch) {
- $switchHoursRaindrops[(int)date('G', strtotime($switch["timestamp"]))]++;
- }
-
- $switchHours = [
- $switchHoursRaindrops[0] + $switchHoursCloudburst[0],
- $switchHoursRaindrops[1] + $switchHoursCloudburst[1],
- $switchHoursRaindrops[2] + $switchHoursCloudburst[2],
- $switchHoursRaindrops[3] + $switchHoursCloudburst[3],
- $switchHoursRaindrops[4] + $switchHoursCloudburst[4],
- $switchHoursRaindrops[5] + $switchHoursCloudburst[5],
- $switchHoursRaindrops[6] + $switchHoursCloudburst[6],
- $switchHoursRaindrops[7] + $switchHoursCloudburst[7],
- $switchHoursRaindrops[8] + $switchHoursCloudburst[8],
- $switchHoursRaindrops[9] + $switchHoursCloudburst[9],
- $switchHoursRaindrops[10] + $switchHoursCloudburst[10],
- $switchHoursRaindrops[11] + $switchHoursCloudburst[11],
- $switchHoursRaindrops[12] + $switchHoursCloudburst[12],
- $switchHoursRaindrops[13] + $switchHoursCloudburst[13],
- $switchHoursRaindrops[14] + $switchHoursCloudburst[14],
- $switchHoursRaindrops[15] + $switchHoursCloudburst[15],
- $switchHoursRaindrops[16] + $switchHoursCloudburst[16],
- $switchHoursRaindrops[17] + $switchHoursCloudburst[17],
- $switchHoursRaindrops[18] + $switchHoursCloudburst[18],
- $switchHoursRaindrops[19] + $switchHoursCloudburst[19],
- $switchHoursRaindrops[20] + $switchHoursCloudburst[20],
- $switchHoursRaindrops[21] + $switchHoursCloudburst[21],
- $switchHoursRaindrops[22] + $switchHoursCloudburst[22],
- $switchHoursRaindrops[23] + $switchHoursCloudburst[23],
- ];
-
- ?>
- <script>
- const ctx2 = document.getElementById('graph-02').getContext('2d');
- window.chart02 = [
- {
- label: "Switches per hour of day",
- data: JSON.parse(`<?= json_encode($switchHours) ?>`),
- borderColor: "rgb(160,255,153)"
- }
- ];
- const graph2 = new Chart(ctx2, {
- type: 'line',
- data: {
- labels: [
- "12am",
- "1am",
- "2am",
- "3am",
- "4am",
- "5am",
- "6am",
- "7am",
- "8am",
- "9am",
- "10am",
- "11am",
- "12pm",
- "1pm",
- "2pm",
- "3pm",
- "4pm",
- "5pm",
- "6pm",
- "7pm",
- "8pm",
- "9pm",
- "10pm",
- "11pm"
- ],
- datasets: window.chart02
- },
- options: {
- animation: {
- duration: 0
- },
- scales: {
- y: {
- beginAtZero: true,
- grid: {
- color: "rgba(255,255,255,0.25)"
- }
- }
- },
- plugins: {
- legend: {
- display: false
- },
- tooltip: {
- intersect: false
- }
- }
- }
- });
- </script>
- <?php $cache["content"] = ob_get_contents(); $cache["day"] = date('Y-m-d'); ob_end_clean(); endif;
-
- echo($cache["content"]);
- file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/cache/stats.json", json_encode($cache));
-
- ?>
- </div>
-</div>
-
-<?php require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/components/footer.inc'; ?>
diff --git a/pages/terminology.inc b/pages/terminology.inc
deleted file mode 100644
index 77a19de..0000000
--- a/pages/terminology.inc
+++ /dev/null
@@ -1,15 +0,0 @@
-<?php
-
-require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/init.inc"; global $title; global $isLoggedIn; global $lang; global $pages;
-require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/components/header.inc';
-
-?>
-
-<br>
-<div class="container">
- <div id="page-content">
- <?= file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/terminology.html") ?>
- </div>
-</div>
-
-<?php require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/components/footer.inc'; ?> \ No newline at end of file