'Slot', '12' => 'Casino', '13' => 'Arcade', '16' => 'Fishing' ]; public $failCode = [ 'S200' => '重復請求', '150001' => '無效的簽名', '150002' => '無效的SN', '150003' => '無效的參數', '150004' => '無效的貨幣', '150005' => '玩家已存在', '150006' => '玩家不存在', '150007' => '次级代理不存在', '150008' => '執行失敗', '150009' => '無效的方法', '150010' => '無效的用戶狀態', '150011' => '玩家狀態無需更新', '150012' => '超出數據範圍', '150013' => '無匹配數據', '150014' => '登入位置被禁止', '150015' => '分數不足夠', '150016' => '不支持禮碼', '150017' => '交易流水號不得重複', '150018' => '系統繁忙', '150019' => '日期時間各式錯誤', '150020' => '超出時間限制範圍(開始時間與結束時間之間不能大於120分鐘)', ]; private $apiDomain; private $domain; private $appId; private $appSecret; private $path = [ 'createPlayer' => '/UserInfo/CreatePlayer', 'getPlayer' => '/UserInfo/GetPlayer', 'getGameList' => '/Game/GetGameList', 'getSimpleGameList' => '/Game/GetSimpleGameList', 'getLoginH5' => '/UserInfo/GetLoginH5', 'setPlayerStatus' => '/UserInfo/SetPlayerStatus', 'getBalance' => '/Account/GetBalance', 'setBalanceTransfer' => '/Account/SetBalanceTransfer', 'getGameRecordByTime' => '/Game/GetGameRecordByTime', 'getGameRecord' => '/Game/GetGameRecord', 'removeRecords' => '/Game/RemoveRecords', ]; private $lang = [ 'zh-CN' => 'zh-ch', 'en' => 'en_us', 'zh_tc' => 'zh_tc', 'en-us' => 'en-us', 'id' => 'id', 'th' => 'th', 'my' => 'my', 'vi' => 'vi', 'fi_fi' => 'fi_fi', 'kr_ko' => 'kr_ko', 'hi_hi' => 'hi_hi', 'br_po' => 'br_po', 'lo_la' => 'lo_la', 'cam_dia' => 'en_us', // 柬埔寨语 ]; /** * @param Player|null $player * @param $type * @throws Exception */ public function __construct($type, Player $player = null) { $config = config('game_platform.' . $type); $this->appId = $config['app_id']; $this->apiDomain = $config['api_domain']; $this->domain = $config['domain']; $this->appSecret = $config['app_secret']; $this->platform = GamePlatform::query()->where('name', $type)->first(); if (!empty($player)) { $this->player = $player; $this->getLoginId(); } } /** * @throws Exception */ protected function getLoginId() { /** @var PlayerGamePlatform $playerGamePlatform */ $playerGamePlatform = $this->player->playerGamePlatform->where('platform_id', $this->platform->id)->first(); if (!empty($playerGamePlatform)) { return $this->loginId = $playerGamePlatform->player_code; } return $this->createPlayer([ 'uuid' => $this->player->uuid, 'name' => $this->player->name, ]); } /** * 创建玩家 * @param array $data * @return array|mixed|Response * @throws GameException|\think\Exception */ public function createPlayer(array $data = []) { $params = [ 'ID' => createOrderNo(), 'Method' => 'CreatePlayer', 'SN' => $this->appId, 'PlayerCode' => $data['uuid'], ]; $params['Signature'] = $this->createSign($params); $params['PlayerName'] = $data['uuid']; Log::info('MonkeyKing请求参数', [$params]); $res = doCurl($this->createUrl('createPlayer'), $params); Log::info('MonkeyKing请求返回数据', [$res]); if ($res['code'] != $this->successCode) { throw new GameException($this->failCode[$res['code']], 0); } $playerGamePlatform = new PlayerGamePlatform(); $playerGamePlatform->player_id = $this->player->id; $playerGamePlatform->platform_id = $this->platform->id; $playerGamePlatform->player_name = $data['name']; $playerGamePlatform->player_code = $data['uuid']; $playerGamePlatform->save(); $this->loginId = $playerGamePlatform->player_code; return $res; } public function createSign($params): string { return md5(implode('', $params) . $this->appSecret); } /** * 生成请求url * @param $method * @return string */ public function createUrl($method): string { return $this->apiDomain . $this->path[$method]; } /** * 创建玩家 * @return array|mixed|Response * @throws GameException|\think\Exception */ public function getPlayer() { $params = [ 'ID' => createOrderNo(), 'Method' => 'GetPlayer', 'SN' => $this->appId, 'LoginId' => $this->loginId, ]; $params['Signature'] = $this->createSign($params); Log::info('MonkeyKing请求参数', [$params]); $data = doCurl($this->createUrl('getPlayer'), $params); Log::info('MonkeyKing请求返回数据', [$data]); if ($data['code'] != $this->successCode) { throw new GameException($this->failCode[$data['code']], 0); } return $data; } /** * 获取游戏摘要MD5 (id+method+sn+APlSecretKey) * @return array|mixed|Response * @throws GameException|\think\Exception */ public function getSimpleGameList() { $params = [ 'ID' => createOrderNo(), 'Method' => 'GetSimpleGameList', 'SN' => $this->appId, ]; $params['Signature'] = $this->createSign($params); Log::info('MonkeyKing请求参数', [$params]); $data = doCurl($this->createUrl('getSimpleGameList'), $params); Log::info('MonkeyKing请求返回数据', [$data]); if ($data['code'] != $this->successCode) { throw new GameException($this->failCode[$data['code']], 0); } if (!empty($data['data']['games'])) { foreach ($data['data']['games'] as $game) { Game::query()->updateOrCreate( [ 'platform_id' => $this->platform->id, 'game_code' => $game['gameCode'], 'platform_game_type' => $game['type'], ] ); } } return $data; } /** * 获取游戏摘要MD5 (id+method+sn+APlSecretKey) * @param array $data * @return string * @throws GameException|\think\Exception */ public function login(array $data = []): string { $params = [ 'ID' => createOrderNo(), 'Method' => 'GetLoginH5', 'SN' => $this->appId, 'LoginId' => $this->loginId, ]; $params['Signature'] = $this->createSign($params); Log::info('MonkeyKing请求参数', [$params]); $res = doCurl($this->createUrl('getLoginH5'), $params); Log::info('MonkeyKing请求返回数据', [$res]); if ($res['code'] != $this->successCode) { throw new GameException($this->failCode[$res['code']], 0); } $responseH5 = [ 'Language' => $this->lang[$data['lang']] ?? 'ch', "GameId" => $data['gameCode'], 'CallbackAddress' => $data['callBackUrl'] ?? '', "AppType" => $data['appType'] ?? 1, "DeviceType" => 1, ]; $jsonString = json_encode($responseH5); $parametersValue = base64_encode($jsonString); return $this->domain . '/linkgame' . ($res['data']['loginUrl'] ?? '') . '&' . $parametersValue . '&' . $data['gameCode']; } /** * 設置登入玩家狀態。當玩家處於禁用狀態,該玩家無法在平台進行任何操作,如果玩家在遊戲進行中該玩家將會自動退出遊戲。 * 簽名密鑰方式 Md5(Id+Method+SN+LoginId+APISecretKey) * @return array|mixed|Response * @throws GameException|\think\Exception */ public function setPlayerStatus($status) { $params = [ 'ID' => createOrderNo(), 'Method' => 'GetSimpleGameList', 'SN' => $this->appId, 'LoginId' => $this->loginId, ]; $params['Signature'] = $this->createSign($params); $params['Status'] = $status; Log::info('MonkeyKing请求参数', [$params]); $data = doCurl($this->createUrl('setPlayerStatus'), $params); Log::info('MonkeyKing请求返回数据', [$data]); if ($data['code'] != $this->successCode) { throw new GameException($this->failCode[$data['code']], 0); } return $data; } /** * 玩家钱包转入游戏平台 * @return array|mixed|null * @throws GameException|\think\Exception */ public function balanceTransferOut() { return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_OUT, $this->player->wallet->money); } /** * 轉帳進出額度 * 簽名密鑰方式 MD5 (Id+Method+SN+LoginId+APISecretKey) * @param $type * @param float $amount * @param float $reward * @return array|mixed|null * @throws GameException|\think\Exception */ protected function setBalanceTransfer($type, float $amount = 0, float $reward = 0) { if ($amount == 0 && $reward == 0) { throw new GameException('转出/入金额错误', 0); } $params = [ 'ID' => createOrderNo(), 'Method' => 'SetBalanceTransfer', 'SN' => $this->appId, 'LoginId' => $this->loginId, ]; $params['Signature'] = $this->createSign($params); $params['Amount'] = $amount; $params['Reward'] = $reward; Log::info('MonkeyKing请求参数', [$params]); $res = doCurl($this->createUrl('setBalanceTransfer'), $params); Log::info('MonkeyKing请求返回数据', [$res]); if ($res['code'] != $this->successCode) { Log::error($this->failCode[$res['code']], ['res' => $res]); throw new GameException($this->failCode[$res['code']], 0); } // 记录玩家钱包转出转入记录 $this->createWalletTransfer($type, $amount, $reward, $res['data']['refId'] ?? ''); return $res; } /** * 玩家钱包转入游戏平台 * @return array|mixed|null * @throws GameException|\think\Exception */ public function balanceTransferIn() { $balance = $this->getBalance(); return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_IN, !empty($balance['data']['result']) ? -$balance['data']['result'] : 0, !empty($balance['data']['reward']) ? -$balance['data']['reward'] : 0); } /** * 獲取玩家餘額信息 * 簽名密鑰方式 MD5 (Id+Method+SN+LoginId+APISecretKey) * @return array|mixed|Response * @throws GameException|\think\Exception */ public function getBalance() { $params = [ 'ID' => createOrderNo(), 'Method' => 'GetBalance', 'SN' => $this->appId, 'LoginId' => $this->loginId, ]; $params['Signature'] = $this->createSign($params); Log::info('MonkeyKing请求参数', [$params]); $data = doCurl($this->createUrl('getBalance'), $params); Log::info('MonkeyKing请求返回数据', [$data]); if ($data['code'] != $this->successCode) { throw new GameException($this->failCode[$data['code']], 0); } return $data; } /** * 依據時間獲取遊戲紀錄 * MD5 (Id+Method+SN+StartTime+EndTime+APISecretKey) * @param int $pageIndex * @param string $startTime * @param string $endTime * @return array|mixed|null * @throws GameException|\think\Exception */ public function getGameRecordByTime(int $pageIndex = 1, string $startTime = '', string $endTime = '') { $params = [ 'ID' => createOrderNo(), 'Method' => 'GetGameRecordByTime', 'SN' => $this->appId, 'StartTime' => $startTime, 'EndTime' => $endTime, ]; $pageSize = 500; $params['Signature'] = $this->createSign($params); $params['PageSize'] = $pageSize; $params['PageIndex'] = $pageIndex; Log::info('MonkeyKing请求参数', [$params]); $res = doCurl($this->createUrl('getGameRecordByTime'), $params); Log::info('MonkeyKing请求返回数据', [$res]); if ($res['code'] != $this->successCode) { throw new GameException($this->failCode[$res['code']], 0); } return $res; } /** * 獲取玩家遊戲歷史紀錄 * MD5 (Id+Method+SN+APISecretKey) * @return array|mixed|null * @throws GameException|\think\Exception */ public function getGameRecord() { $params = [ 'ID' => createOrderNo(), 'Method' => 'GetGameRecord', 'SN' => $this->appId, ]; $params['Signature'] = $this->createSign($params); Log::info('MonkeyKing请求参数', [$params]); $res = doCurl($this->createUrl('getGameRecord'), $params); Log::info('MonkeyKing请求返回数据', [$res]); if ($res['code'] != $this->successCode) { throw new GameException($this->failCode[$res['code']], 0); } return $res; } /** * 刪除遊戲紀錄 * MD5 (Id+Method+SN+IdsToBeRemoved+APISecretKey) * @return array|mixed|null * @throws GameException|\think\Exception */ public function removeRecords($idsToBeRemoved) { $params = [ 'ID' => createOrderNo(), 'Method' => 'RemoveRecords', 'SN' => $this->appId, 'IdsToBeRemoved' => implode(',', $idsToBeRemoved), ]; $params['Signature'] = $this->createSign($params); Log::info('MonkeyKing请求参数', [$params]); $res = doCurl($this->createUrl('removeRecords'), $params); Log::info('MonkeyKing请求返回数据', [$res]); if ($res['code'] != $this->successCode) { throw new GameException($this->failCode[$res['code']], 0); } return $res; } }