request ? $this->request->get('record_id') : null; $recordId = is_numeric((string) $recordIdRaw) ? (int) $recordIdRaw : null; return $this->success('', GameLiveService::buildSnapshot($recordId)); } public function snapshot(WebmanRequest $request): Response { $response = $this->initializeBackend($request); if ($response !== null) { return $response; } $recordIdRaw = $request->get('record_id'); $recordId = is_numeric((string) $recordIdRaw) ? (int) $recordIdRaw : null; return $this->success('', GameLiveService::buildSnapshot($recordId)); } /** * WebSocket config for admin live page. */ public function wsConfig(WebmanRequest $request): Response { $response = $this->initializeBackend($request); if ($response !== null) { return $response; } $topics = [ 'admin.live.snapshot', 'admin.live.opened', 'admin.live.finalized', 'jackpot.hit', 'period.tick', 'period.locked', 'period.opened', 'period.payout', 'period.payout.tick', 'bet.accepted', 'bet.win', 'wallet.changed', 'auto.spin.progress', ]; return $this->success('', [ 'name' => 'ws.admin.live', 'ws_url' => WebSocketConfigHelper::wsUrl($request), 'connect_tip' => 'The admin live page auto-subscribes topics for status, draw result and payout events.', 'subscribe_topics' => $topics, 'sample_messages' => [ '{"action":"ping"}', '{"action":"subscribe","topics":["admin.live.snapshot","admin.live.opened"]}', '{"action":"subscribe","topics":["period.tick","period.opened","wallet.changed"]}', ], ]); } public function calculate(WebmanRequest $request): Response { $response = $this->initializeBackend($request); if ($response !== null) { return $response; } if ($request->method() !== 'POST') { return $this->error(__('Parameter error')); } $recordIdRaw = $request->post('record_id'); $recordId = is_numeric((string) $recordIdRaw) ? (int) $recordIdRaw : null; $manualRaw = $request->post('manual_number'); $manualNumber = is_numeric((string) $manualRaw) ? (int) $manualRaw : null; $res = GameLiveService::calculateResult($recordId, $manualNumber); if (!($res['ok'] ?? false)) { $errMsg = $res['msg'] ?? null; return $this->error(is_string($errMsg) ? $errMsg : __('Calculation failed')); } $okMsg = $res['msg'] ?? ''; return $this->success(is_string($okMsg) ? $okMsg : '', $res); } /** * Schedule draw number for current period. */ public function draw(WebmanRequest $request): Response { $response = $this->initializeBackend($request); if ($response !== null) { return $response; } if ($request->method() !== 'POST') { return $this->error(__('Parameter error')); } $recordIdRaw = $request->post('record_id'); $recordId = is_numeric((string) $recordIdRaw) ? (int) $recordIdRaw : null; $manualRaw = $request->post('manual_number'); if (!is_numeric((string) $manualRaw)) { return $this->error(__('Please enter the draw number')); } $manualNumber = (int) $manualRaw; $res = GameLiveService::scheduleDraw($recordId, $manualNumber); if (!($res['ok'] ?? false)) { $errMsg = $res['msg'] ?? null; return $this->error(is_string($errMsg) ? $errMsg : __('Schedule failed')); } $okMsg = $res['msg'] ?? ''; return $this->success(is_string($okMsg) ? $okMsg : '', $res); } /** * Runtime switch for game period generation and betting. */ public function runtime(WebmanRequest $request): Response { $response = $this->initializeBackend($request); if ($response !== null) { return $response; } if ($request->method() !== 'POST') { return $this->error(__('Parameter error')); } $raw = $request->post('enabled'); $enabled = $raw === true || $raw === '1' || $raw === 1; GameRecordService::setAutoCreateEnabled($enabled); if ($enabled) { GameRecordService::bootstrapPeriodWhenRuntimeEnabled(); } else { GameLiveService::voidOrphanActiveRoundsOnRuntimeDisabled(); } return $this->success('', GameLiveService::buildSnapshot(null)); } /** * Void current period and refund waiting orders. */ public function voidPeriod(WebmanRequest $request): Response { $response = $this->initializeBackend($request); if ($response !== null) { return $response; } if ($request->method() !== 'POST') { return $this->error(__('Parameter error')); } $recordIdRaw = $request->post('record_id'); $recordId = is_numeric((string) $recordIdRaw) ? (int) $recordIdRaw : null; $voidReason = $request->post('void_reason'); $reasonStr = is_string($voidReason) ? $voidReason : ''; $res = GameLiveService::voidCurrentPeriod($recordId, $reasonStr); if (!($res['ok'] ?? false)) { $errMsg = $res['msg'] ?? null; return $this->error(is_string($errMsg) ? $errMsg : __('Void failed')); } $okMsg = $res['msg'] ?? ''; $snapshot = GameLiveService::buildSnapshotAfterVoid(); $refund = $res['refund'] ?? null; if (is_array($refund)) { $snapshot['void_refund'] = $refund; } return $this->success(is_string($okMsg) ? $okMsg : '', $snapshot); } }