summaryrefslogtreecommitdiff
path: root/pages
diff options
context:
space:
mode:
authorRaindropsSys <raindrops@equestria.dev>2023-11-17 23:25:29 +0100
committerRaindropsSys <raindrops@equestria.dev>2023-11-17 23:25:29 +0100
commit953ddd82e48dd206cef5ac94456549aed13b3ad5 (patch)
tree8f003106ee2e7f422e5a22d2ee04d0db302e66c0 /pages
parent62a9199846b0c07c03218703b33e8385764f42d9 (diff)
downloadpluralconnect-953ddd82e48dd206cef5ac94456549aed13b3ad5.tar.gz
pluralconnect-953ddd82e48dd206cef5ac94456549aed13b3ad5.tar.bz2
pluralconnect-953ddd82e48dd206cef5ac94456549aed13b3ad5.zip
Updated 30 files and deleted 2976 files (automated)
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