Files
2026-07-31 03:36:58 +00:00

213 lines
7.4 KiB
PHP

<?php
declare(strict_types=1);
/**
* คัดกรองการสร้างห้องเกม — Admin proxy ไป Node + เก็บประวัติอนุมัติ/ปฏิเสธ
*/
require __DIR__ . '/_common.php';
require_login();
if (!function_exists('curl_init')) {
json_response(['ok' => false, 'error' => 'ต้องเปิด PHP extension curl'], 500);
}
function room_moderation_disk_path(): string
{
return dirname(__DIR__, 2) . '/Game/data/room-moderation.json';
}
function room_approval_history_path(): string
{
return ADMIN_PRIVATE_DIR . '/room-approval-history.json';
}
function sync_room_moderation_disk(bool $enabled): void
{
$path = room_moderation_disk_path();
$dir = dirname($path);
if (!is_dir($dir)) {
@mkdir($dir, 0755, true);
}
$json = json_encode(['enabled' => $enabled], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
if ($json !== false) {
@file_put_contents($path, $json, LOCK_EX);
}
}
function read_room_approval_history(): array
{
$path = room_approval_history_path();
if (!is_file($path)) {
return [];
}
$raw = @file_get_contents($path);
$j = json_decode($raw ?: '[]', true);
return is_array($j) ? $j : [];
}
function append_room_approval_history(array $row): void
{
$rows = read_room_approval_history();
array_unshift($rows, $row);
if (count($rows) > 500) {
$rows = array_slice($rows, 0, 500);
}
if (!is_dir(ADMIN_PRIVATE_DIR)) {
@mkdir(ADMIN_PRIVATE_DIR, 0750, true);
}
$json = json_encode($rows, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
if ($json !== false) {
@file_put_contents(room_approval_history_path(), $json, LOCK_EX);
}
}
function node_room_approvals_url(string $suffix = ''): string
{
$port = preg_replace('/[^0-9]/', '', (string)(getenv('GAME_NODE_PORT') ?: '13010')) ?: '13010';
$host = getenv('GAME_NODE_INTERNAL_HOST') ?: '127.0.0.1';
return 'http://' . $host . ':' . $port . '/Game/api/admin/room-approvals' . $suffix;
}
function proxy_node_room_approvals(string $method, ?string $body = null, string $suffix = ''): array
{
$ch = curl_init(node_room_approvals_url($suffix));
if ($ch === false) {
return ['ok' => false, 'error' => 'curl init failed', 'httpCode' => 0];
}
$headers = ['Accept: application/json'];
if ($body !== null && $method !== 'GET') {
$headers[] = 'Content-Type: application/json';
}
$opts = [
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 12,
];
if ($body !== null && $method !== 'GET') {
$opts[CURLOPT_POSTFIELDS] = $body;
}
curl_setopt_array($ch, $opts);
$out = curl_exec($ch);
$code = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
$err = curl_error($ch);
curl_close($ch);
if ($out === false || $out === '') {
return ['ok' => false, 'error' => 'ไม่ต่อถึงเซิร์ฟเวอร์เกม (Node): ' . $err, 'httpCode' => $code];
}
$j = json_decode($out, true);
if (!is_array($j)) {
return ['ok' => false, 'error' => 'ตอบกลับจาก Node ไม่ถูกต้อง', 'httpCode' => $code];
}
$j['httpCode'] = $code;
return $j;
}
$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
$admin = current_admin();
if ($method === 'GET') {
$action = isset($_GET['action']) ? (string)$_GET['action'] : 'pending';
$store = read_store();
$enabled = !empty($store['roomModeration']['enabled']);
sync_room_moderation_disk($enabled);
if ($action === 'settings') {
json_response([
'ok' => true,
'enabled' => $enabled,
]);
}
if ($action === 'history') {
json_response([
'ok' => true,
'history' => read_room_approval_history(),
'enabled' => $enabled,
]);
}
$node = proxy_node_room_approvals('GET');
if (empty($node['ok'])) {
json_response([
'ok' => true,
'enabled' => $enabled,
'pending' => [],
'nodeError' => $node['error'] ?? 'Node unavailable',
]);
}
json_response([
'ok' => true,
'enabled' => $enabled,
'nodeModerationEnabled' => !empty($node['moderationEnabled']),
'pending' => $node['pending'] ?? [],
]);
}
if ($method === 'PATCH') {
$raw = file_get_contents('php://input') ?: '{}';
$body = json_decode($raw, true);
if (!is_array($body)) {
json_response(['ok' => false, 'error' => 'ข้อมูลไม่ถูกต้อง'], 400);
}
$store = read_store();
if (!isset($store['roomModeration']) || !is_array($store['roomModeration'])) {
$store['roomModeration'] = ['enabled' => true];
}
if (array_key_exists('enabled', $body)) {
$store['roomModeration']['enabled'] = !!$body['enabled'];
}
if (!write_store($store)) {
json_response(['ok' => false, 'error' => 'บันทึกการตั้งค่าไม่สำเร็จ'], 500);
}
sync_room_moderation_disk(!empty($store['roomModeration']['enabled']));
json_response(['ok' => true, 'enabled' => !empty($store['roomModeration']['enabled'])]);
}
if ($method === 'POST') {
$raw = file_get_contents('php://input') ?: '{}';
$body = json_decode($raw, true);
if (!is_array($body)) {
json_response(['ok' => false, 'error' => 'ข้อมูลไม่ถูกต้อง'], 400);
}
$spaceId = isset($body['spaceId']) ? trim((string)$body['spaceId']) : '';
$act = isset($body['action']) ? trim((string)$body['action']) : '';
$note = isset($body['note']) ? trim((string)$body['note']) : '';
if ($spaceId === '' || !in_array($act, ['approve', 'reject', 'dismiss'], true)) {
json_response(['ok' => false, 'error' => 'ต้องระบุ spaceId และ action (reject|dismiss)'], 400);
}
$meta = isset($body['meta']) && is_array($body['meta']) ? $body['meta'] : [];
$payload = json_encode([
'spaceId' => $spaceId,
'action' => $act,
'note' => $note,
], JSON_UNESCAPED_UNICODE);
$result = proxy_node_room_approvals('POST', $payload, '');
if (empty($result['ok'])) {
json_response(['ok' => false, 'error' => $result['error'] ?? 'ดำเนินการไม่สำเร็จ'], !empty($result['httpCode']) && $result['httpCode'] >= 400 ? (int)$result['httpCode'] : 400);
}
append_room_approval_history([
'at' => gmdate('c'),
'action' => $act,
'spaceId' => $spaceId,
'spaceName' => $meta['spaceName'] ?? $spaceId,
'creatorDisplayName' => $meta['creatorDisplayName'] ?? '',
'creatorPlayerKey' => $meta['creatorPlayerKey'] ?? '',
'adminUsername' => is_array($admin) ? ($admin['username'] ?? '') : '',
'note' => $note,
'kicked' => isset($result['kicked']) ? (int)$result['kicked'] : null,
]);
json_response([
'ok' => true,
'action' => $act,
'spaceId' => $spaceId,
'kicked' => $result['kicked'] ?? null,
]);
}
json_response(['ok' => false, 'error' => 'Method not allowed'], 405);