120 lines
4.6 KiB
PHP
120 lines
4.6 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* ภายในเซิร์ฟเวอร์เท่านั้น — มอบเหรียญ + คะแนนสะสม (high score) ให้ผู้เล่นหลังจบมินิเกม
|
|
* เรียกจาก Game server (Node) เท่านั้น โดยตรวจ secret ร่วม (Admin/private/game-award-secret.txt)
|
|
*
|
|
* POST JSON: {
|
|
* "secret": "<shared secret>",
|
|
* "awards": [ { "playerKey": "...", "nickname": "...", "coins": 10 }, ... ]
|
|
* }
|
|
* - บวก coins (ใช้จ่ายได้) และ score (สะสมถาวร ไม่ลด) เท่ากับจำนวนเหรียญที่ได้
|
|
* - cap ต่อรายการ 0–100 กันยิงมั่ว
|
|
*/
|
|
require __DIR__ . '/_common.php';
|
|
|
|
date_default_timezone_set('Asia/Bangkok');
|
|
|
|
if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') {
|
|
json_response(['ok' => false, 'error' => 'Use POST'], 405);
|
|
}
|
|
|
|
$secretFile = ADMIN_PRIVATE_DIR . '/game-award-secret.txt';
|
|
$expected = is_file($secretFile) ? trim((string) @file_get_contents($secretFile)) : '';
|
|
|
|
$body = require_json_body();
|
|
$secret = (string) ($body['secret'] ?? '');
|
|
if ($expected === '' || strlen($secret) < 16 || !hash_equals($expected, $secret)) {
|
|
json_response(['ok' => false, 'error' => 'unauthorized'], 403);
|
|
}
|
|
|
|
$awards = (isset($body['awards']) && is_array($body['awards'])) ? $body['awards'] : [];
|
|
if (!$awards) {
|
|
json_response(['ok' => true, 'updated' => 0]);
|
|
}
|
|
|
|
$store = read_store();
|
|
if (!isset($store['accounts']) || !is_array($store['accounts'])) {
|
|
$store['accounts'] = [];
|
|
}
|
|
|
|
/* index บัญชี guest ตาม playerKey */
|
|
$byKey = [];
|
|
foreach ($store['accounts'] as $i => $a) {
|
|
if (($a['loginType'] ?? '') === 'guest') {
|
|
$byKey[(string) ($a['providerUserId'] ?? '')] = $i;
|
|
}
|
|
}
|
|
|
|
$updated = 0;
|
|
foreach ($awards as $aw) {
|
|
if (!is_array($aw)) {
|
|
continue;
|
|
}
|
|
$key = trim((string) ($aw['playerKey'] ?? ''));
|
|
if (!preg_match('/^[a-zA-Z0-9_-]{8,128}$/', $key)) {
|
|
continue;
|
|
}
|
|
$coins = (int) ($aw['coins'] ?? 0);
|
|
if ($coins < 0) $coins = 0;
|
|
if ($coins > 100) $coins = 100;
|
|
$nick = trim((string) ($aw['nickname'] ?? ''));
|
|
if (function_exists('mb_substr')) {
|
|
$nick = $nick !== '' ? mb_substr($nick, 0, 24) : '';
|
|
} else {
|
|
$nick = $nick !== '' ? substr($nick, 0, 24) : '';
|
|
}
|
|
|
|
$caseId = preg_replace('/[^0-9]/', '', (string) ($aw['caseId'] ?? ''));
|
|
$noScore = !empty($aw['noScore']); // Fund ฯลฯ: บวกแค่ coins ไม่บวก high-score
|
|
|
|
if (isset($byKey[$key])) {
|
|
$i = $byKey[$key];
|
|
if (!empty($store['accounts'][$i]['blocked'])) {
|
|
continue;
|
|
}
|
|
$store['accounts'][$i]['coins'] = max(0, (int) ($store['accounts'][$i]['coins'] ?? 0)) + $coins;
|
|
if (!$noScore) {
|
|
$store['accounts'][$i]['score'] = max(0, (int) ($store['accounts'][$i]['score'] ?? 0)) + $coins;
|
|
}
|
|
if (!$noScore && $caseId !== '') {
|
|
if (!isset($store['accounts'][$i]['scoreByCase']) || !is_array($store['accounts'][$i]['scoreByCase'])) {
|
|
$store['accounts'][$i]['scoreByCase'] = [];
|
|
}
|
|
$store['accounts'][$i]['scoreByCase'][$caseId] = max(0, (int) ($store['accounts'][$i]['scoreByCase'][$caseId] ?? 0)) + $coins;
|
|
}
|
|
if ($nick !== '') {
|
|
$store['accounts'][$i]['lbName'] = $nick;
|
|
if (($store['accounts'][$i]['displayName'] ?? '') === 'Guest' || ($store['accounts'][$i]['displayName'] ?? '') === '') {
|
|
$store['accounts'][$i]['displayName'] = $nick;
|
|
}
|
|
}
|
|
$store['accounts'][$i]['updatedAt'] = gmdate('c');
|
|
} else {
|
|
$store['accounts'][] = [
|
|
'id' => new_id(),
|
|
'email' => '',
|
|
'displayName' => ($nick !== '' ? $nick : 'Guest'),
|
|
'loginType' => 'guest',
|
|
'providerUserId' => $key,
|
|
'notes' => 'auto: game-award',
|
|
'blocked' => false,
|
|
'coins' => $coins,
|
|
'score' => ($noScore ? 0 : $coins),
|
|
'scoreByCase' => ((!$noScore && $caseId !== '') ? [$caseId => $coins] : []),
|
|
'lbName' => $nick,
|
|
'createdAt' => gmdate('c'),
|
|
'updatedAt' => gmdate('c'),
|
|
];
|
|
$byKey[$key] = count($store['accounts']) - 1;
|
|
}
|
|
$updated++;
|
|
}
|
|
|
|
if (!write_store($store)) {
|
|
json_response(['ok' => false, 'error' => 'บันทึกไม่สำเร็จ'], 500);
|
|
}
|
|
|
|
json_response(['ok' => true, 'updated' => $updated]);
|