Skip to content

Instantly share code, notes, and snippets.

@salty-godzilla
Created December 25, 2023 14:08
Show Gist options
  • Save salty-godzilla/da8cc0efbe3eb0592522d3cec0c8bd15 to your computer and use it in GitHub Desktop.
Save salty-godzilla/da8cc0efbe3eb0592522d3cec0c8bd15 to your computer and use it in GitHub Desktop.
XOPS用サーバーリスト配信プログラム
[settings]
lobby_message = XOPS IS FOREVER
get_cooldown_seconds = 2
<?php
/**
* Released as public domain by jp.owo.Manda
* Tested on PHP 8.1.10
*/
declare(strict_types=1);
const settings_filepath = "settings.ini";
const server_list_filepath = "server_list.csv";
const server_expire_seconds = 60 * 5;
const server_name_max_len = 70;
// Overwrite the HTTP response code with 500 if a fatal error occurs
register_shutdown_function(function() {
$lastError = error_get_last();
if (!empty($lastError) && $lastError['type'] == E_ERROR) {
http_response_code(500);
}
});
function read_server_list_csv(string $filename): array {
$fp = fopen($filename, 'r');
$list = array();
while ($line = fgetcsv($fp)) {
$list[] = array('expire_time' => $line[0], 'address' => $line[1], 'port' => $line[2], 'name' => $line[3]);
}
return $list;
}
function write_server_list_csv(string $filename, array $list): void {
$fp = fopen($filename, 'w');
foreach ($list as $value) {
fputcsv($fp, $value);
}
}
function read_settings_ini(string $filename): array {
$array = parse_ini_file($filename);
if ($array === false) {
return array();
}
return $array;
}
if ($_SERVER['REQUEST_METHOD'] !== 'GET') {
http_response_code(400);
echo "request method not supported";
return;
}
$settings = read_settings_ini(settings_filepath);
if (empty($settings)) {
http_response_code(500);
echo "failed to load setting file";
return;
}
if (!file_exists(server_list_filepath)) {
touch(server_list_filepath);
}
$list = read_server_list_csv(server_list_filepath);
$list_updated = false;
// Remove expired servers
foreach ($list as $key => $value) {
$expire_time = strtotime($value['expire_time']);
if ($expire_time !== false && time() >= $expire_time) {
unset($list[$key]);
$list_updated = true;
}
}
$query = $_SERVER['QUERY_STRING'];
$addr = $_SERVER['REMOTE_ADDR'];
if (empty($query)) {
// Get server list
echo $settings['lobby_message'] . "\n";
echo $settings['get_cooldown_seconds'] . "\n";
foreach ($list as $value) {
echo $value['address'] . '&' . $value['port'] . '&' . $value['name'] . "\n";
}
} else if ($query === 'del') {
// Delete server from list
foreach ($list as $key => $value) {
if ($value['address'] == $addr) {
unset($list[$key]);
$list_updated = true;
break;
}
}
} else {
// Register server
$query_list = explode('&', $query);
if (count($query_list) != 2) {
http_response_code(400);
echo "invalid query";
return;
}
$name = rawurldecode($query_list[0]);
if (strlen($name) > server_name_max_len) {
http_response_code(400);
echo "server name too long";
return;
}
$name = str_replace('&', ' ', $name);
$port = trim($query_list[1]);
if (filter_var($port, FILTER_VALIDATE_INT, array('options' => array('min_range' => 1, 'max_range' => 9999))) === false) {
http_response_code(400);
echo "invalid port number";
return;
}
// Remove if already exists
foreach ($list as $key => $value) {
if ($value['address'] == $addr) {
unset($list[$key]);
$list_updated = true;
break;
}
}
$expire_time = date('Y-m-d H:i:s', time() + server_expire_seconds);
$list[] = array('expire_time' => $expire_time, 'address' => $addr, 'port' =>$port, 'name' => $name);
$list_updated = true;
}
if ($list_updated) {
write_server_list_csv(server_list_filepath, $list);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment