svrjs-statistics-server-php/src/collect.php
2024-12-18 18:02:43 +01:00

172 lines
4.6 KiB
PHP

<?php
include "./config.php";
$mysqlDriver = new mysqli_driver();
$mysqlDriver->report_mode = MYSQLI_REPORT_OFF;
header("Content-Type: application/json");
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (
isset($_SERVER["CONTENT_TYPE"]) &&
!preg_match('/^application\/json(?:$|;)/', $_SERVER["CONTENT_TYPE"])
) {
header("Accept: application/json", true, 415);
echo json_encode([
"status" => 415,
"message" => "Only JSON is supported.",
]);
exit();
}
$jsonData = file_get_contents("php://input");
$parsedJsonData = json_decode($jsonData, true);
if (json_last_error() !== JSON_ERROR_NONE) {
http_response_code(400);
echo json_encode([
"status" => 400,
"message" => "JSON parse error.",
]);
exit();
}
$isValid = true;
if (
!isset($parsedJsonData["version"]) ||
!isset($parsedJsonData["runtime"]) ||
!isset($parsedJsonData["runtimeVersion"]) ||
!isset($parsedJsonData["mods"]) ||
!is_string($parsedJsonData["version"]) ||
!is_string($parsedJsonData["runtime"]) ||
!is_string($parsedJsonData["runtimeVersion"]) ||
!is_array($parsedJsonData["mods"])
) {
$isValid = false;
} elseif (!in_array($parsedJsonData["runtime"], ["Node.js", "Bun", "Deno"])) {
$isValid = false;
} else {
foreach ($parsedJsonData["mods"] as $mod) {
if (
!isset($mod["version"]) ||
!is_string($mod["name"]) ||
!is_string($mod["version"])
) {
$isValid = false;
break;
}
}
}
if (!$isValid) {
http_response_code(400);
echo json_encode([
"status" => 400,
"message" => "Invalid data.",
]);
exit();
}
$requestIP = $_SERVER["REMOTE_ADDR"];
$dnsRecords = dns_get_record(DOMAIN, DNS_A + DNS_AAAA);
if ($dnsRecords) {
$ipAddresses = array_map(
function ($record) {
return isset($record["ip"]) ? $record["ip"] : $record["ipv6"];
},
array_filter($dnsRecords, function ($record) {
return isset($record["ip"]) || isset($record["ipv6"]);
})
);
if (in_array($requestIP, $ipAddresses)) {
http_response_code(200);
echo json_encode([
"status" => 200,
"message" => "The statistics are added successfully.",
]);
exit();
}
}
$connection = new mysqli(
MYSQL_HOST,
MYSQL_USERNAME,
MYSQL_PASSWORD,
MYSQL_DATABASE,
MYSQL_PORT
);
if ($connection->connect_error) {
error_log("There was an error while processing the request!");
error_log("Error: " . $connection->connect_error);
http_response_code(500);
echo json_encode([
"status" => 500,
"message" => "An unexpected error occurred.",
]);
exit();
}
$escapedRequestIP = $connection->real_escape_string($requestIP);
$version = $connection->real_escape_string($parsedJsonData["version"]);
$runtime = $connection->real_escape_string($parsedJsonData["runtime"]);
$runtimeVersion = $connection->real_escape_string(
$parsedJsonData["runtimeVersion"]
);
$query = "INSERT INTO entries (ip, time, version, runtime, runtime_version) VALUES ('$escapedRequestIP', NOW(), '$version', '$runtime', '$runtimeVersion')";
if (!$connection->query($query)) {
error_log("There was an error while processing the request!");
error_log("Error: " . $connection->error);
http_response_code(500);
echo json_encode([
"status" => 500,
"message" => "An unexpected error occurred.",
]);
$connection->close();
exit();
}
$entryId = intval($connection->insert_id);
$entriesToInsert = [];
foreach ($parsedJsonData["mods"] as $mod) {
$name = $connection->real_escape_string($mod["name"]);
$modVersion = $connection->real_escape_string($mod["version"]);
$entriesToInsert[] = "($entryId, '$name', '$modVersion')";
}
if (!empty($entriesToInsert)) {
$query =
"INSERT INTO entries_mods (entry_id, name, version) VALUES " .
implode(", ", $entriesToInsert);
if (!$connection->query($query)) {
error_log("There was an error while processing the request!");
error_log("Error: " . $connection->error);
http_response_code(500);
echo json_encode([
"status" => 500,
"message" => "An unexpected error occurred.",
]);
$connection->close();
exit();
}
}
http_response_code(200);
echo json_encode([
"status" => 200,
"message" => "The statistics are added successfully.",
]);
$connection->close();
} else {
header("Allow: POST", true, 405);
echo json_encode([
"status" => 405,
"message" => "Invalid HTTP method.",
]);
}
?>