Files
supercardinality-online/index.php
T

169 lines
4.2 KiB
PHP

<?php
function generate_uuid_v4(): string {
$bytes = openssl_random_pseudo_bytes(16);
$bytes[6] = chr(ord($bytes[6]) & 0x0f | 0x40); // set version to 0100
$bytes[8] = chr(ord($bytes[8]) & 0x3f | 0x80); // set bits 6-7 to 10
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($bytes), 4));
}
if (file_exists("config.php")) {
include "config.php";
}
if (empty($state_file)) {
$state_file = "state.json";
}
if (empty($error_reporting)) {
$error_reporting = false;
}
if (empty($lobby_timeout_seconds)) {
$lobby_timeout_seconds = 30;
}
if ($error_reporting) {
error_reporting(E_ALL);
ini_set('display_errors', 1);
}
$reachable = false;
if (isset($_GET["new"])) {
if ($check_reachability) {
require "enet_probe.php";
$host = $_SERVER['REMOTE_ADDR'];
if (!empty($_GET["host"])) {
$host = $_GET["host"];
}
$port = 50403;
if (!empty($_GET["port"]) && is_numeric($_GET["port"])) {
$port = intval($_GET["port"]);
}
$reachable = enet_probe($host, $port);
}
else {
$reachable = true;
}
}
$dirname = dirname($state_file);
if (!is_dir($dirname)) {
mkdir($dirname, 0777, true);
}
$state_fp = fopen($state_file, "c+");
flock($state_fp, LOCK_EX);
$contents = stream_get_contents($state_fp);
$state = json_decode($contents, true);
if (empty($state)) {
$state = ["lobbies" => []];
}
$cutoff_timestamp = time() - $lobby_timeout_seconds;
foreach (array_keys($state["lobbies"]) as $id) {
if ($state["lobbies"][$id]["updated_at"] < $cutoff_timestamp) {
unset($state["lobbies"][$id]);
}
}
if (isset($_GET["list"])) {
$list = [];
foreach ($state["lobbies"] as $id => $lobby) {
$list[$id] = [
"id" => $lobby["id"],
"host" => $lobby["host"],
"port" => $lobby["port"],
"name" => $lobby["name"],
"creator" => $lobby["creator"],
"version" => $lobby["version"],
"created_at" => $lobby["created_at"],
];
}
header("Content-Type: application/json");
echo json_encode(["lobbies" => $list]);
}
elseif (isset($_GET["new"])) {
header("Content-Type: application/json");
if ($reachable) {
$id = generate_uuid_v4();
$secret = generate_uuid_v4();
$version = $_GET["version"] ?? "";
$creator = $_GET["creator"] ?? "";
$name = "{$creator}'s lobby";
if (!empty($_GET["name"])) {
$name = $_GET["name"];
}
$lobby = [
"id" => $id,
"secret" => $secret,
"host" => $host,
"port" => $port,
"name" => $name,
"version" => $version,
"creator" => $creator,
"updated_at" => time(),
"created_at" => time(),
];
$state["lobbies"][$id] = $lobby;
echo json_encode($lobby);
}
else {
http_response_code(424);
echo json_encode(["error" => "NOT_REACHABLE", "host" => $host, "port" => $port]);
}
}
elseif (isset($_GET["update"])) {
$id = $_GET["id"];
$secret = $_GET["secret"];
$lobby = $state["lobbies"][$id];
header("Content-Type: application/json");
if (!in_array($id, array_keys($state["lobbies"])) || empty($lobby)) {
http_response_code(404);
echo json_encode(["error" => "NOT_FOUND", "id" => $id]);
}
elseif ($lobby["secret"] != $secret) {
http_response_code(403);
echo json_encode(["error" => "NOT_AUTHORIZED", "id" => $id]);
}
else {
$name = $_GET["name"] ?? "";
if (!empty($name)) {
$lobby["name"] = $name;
}
$lobby["updated_at"] = time();
$state["lobbies"][$id] = $lobby;
echo json_encode(["result" => "updated"]);
}
}
elseif (isset($_GET["close"])) {
$id = $_GET["id"];
$secret = $_GET["secret"];
$lobby = $state["lobbies"][$id];
header("Content-Type: application/json");
if (!in_array($id, array_keys($state["lobbies"])) || empty($lobby)) {
http_response_code(404);
echo json_encode(["error" => "NOT_FOUND", "id" => $id]);
}
elseif ($lobby["secret"] != $secret) {
http_response_code(403);
echo json_encode(["error" => "NOT_AUTHORIZED", "id" => $id]);
}
else {
unset($state["lobbies"][$id]);
echo json_encode(["result" => "closed"]);
}
}
else {
header("Content-Type: application/json");
echo json_encode(["status" => "OK"]);
}
ftruncate($state_fp, 0);
rewind($state_fp);
fwrite($state_fp, json_encode($state, JSON_PRETTY_PRINT));
fflush($state_fp);
flock($state_fp, LOCK_UN);
fclose($state_fp);