'Slot', '12' => 'Casino', '13' => 'Arcade', '16' => 'Fishing' ]; public $failCode = [ '0000' => '成功', '9999' => '失敗', '9001' => '未授權訪問', '9002' => '域名為空或域名長度小於 2', '9003' => '域名驗證失敗。', '9004' => '加密數據為空或加密數據的長度等於 0。', '9005' => '斷言(SAML)未通過時間戳驗證。', '9006' => '從加密數據中提取 SAML 參數失敗。', '9007' => '未知操作。', '9008' => '與之前的值相同。', '9009' => '超時。', '9010' => '讀取超時。', '9011' => '重複交易。', '9012' => '請稍後再試。', '9013' => '系統正在維護。', '9014' => '檢測到多帳戶登錄。', '9015' => '數據不存在。', '9016' => '無效令牌。', '9019' => '請求速率限制超過。', '9020' => '每次登錄只能獲得一次遊戲票。', '9021' => '違反一次性會話策略。', '9022' => '遊戲正在維護。', '9023' => '不支持的貨幣。', '9024' => '贏取倍數必須大於或等於 10 倍。', '9025' => '不支持重放遊戲。', '9026' => '获胜金额应大于0。', '9027' => '不支持演示。', '8000' => '輸入參數錯誤,請檢查您的參數是否正確。', '8001' => '參數不能為空。', '8002' => '參數必須是正整數。', '8003' => '參數不能為負數。', '8005' => '日期秒格式錯誤', '8006' => '時間不符合。', '8007' => '參數只能使用數字。', '8008' => '找不到參數。', '8009' => '時間間隔超過允許範圍。', '8010' => '參數長度太長。', '8013' => '日期分鐘格式參數錯誤。', '8014' => '參數不得超過指定的小數位。', '7001' => '找不到指定的父 ID。', '7002' => '父級已暫停。', '7003' => '父級已鎖定。', '7004' => '父級已關閉。', '7405' => '您已登出!', '7501' => '找不到用戶 ID。', '7502' => '用戶已暫停。', '7503' => '用戶已鎖定。', '7504' => '用戶已關閉。', '7505' => '用戶未在玩遊戲。', '7506' => '演示帳戶已滿。', '7601' => '無效的用戶 ID。請僅使用 a-z、0-9 之間的字符。', '7602' => '帳戶已存在。請選擇其他用戶 ID。', '7603' => '無效的用戶名。', '7604' => '密碼必須至少 6 個字符,包含 1 個字母和 1 個數字。', '7605' => '無效的操作代碼。請僅使用數字 2、3、4、5。', '6001' => '您的現金餘額不足以取款。', '6002' => '用戶餘額為零。', '6003' => '取款金額為負。', '6004' => '重複轉帳。', '6005' => '重複的序列號。', '6009' => '存款金額超過上限。', '6010' => '餘額超過上限。', '6011' => '分配的信用額超過上限。', '6012' => '序列號正在進行中。', '6901' => '用戶正在玩遊戲,不允許轉移餘額。' ]; private $apiDomain; private $domain; private $iv; private $key; private $dc; private $parent; private $lang = [ 'zh-CN' => 'cn', 'zh-TW' => 'cn', 'jp' => 'jpn', 'en' => 'en', 'th' => 'th', 'vi' => 'vi', 'kr_ko' => 'ko', 'id' => 'id', ]; public $localGameType = [ '0' => '1',//斯洛 '32' => '1',//斯洛 '50' => '1',//斯洛 '55' => '1',//斯洛 '57' => '1',//斯洛 '58' => '1',//斯洛 '66' => '1',//斯洛 '80' => '1',//斯洛 '90' => '1',//斯洛 '130' => '1',//斯洛 '7' => '4',//捕鱼 '31' => '4',//捕鱼 '70' => '4',//捕鱼 '59' => '4',//捕鱼 '67' => '4',//捕鱼 '91' => '4',//捕鱼 '8' => '8',//宾果 '12' => '8',//宾果 '60' => '8',//宾果 '9' => '8',//宾果 '22' => '8',//宾果 '30' => '8',//宾果 '56' => '8',//宾果 '75' => '8',//宾果 '81' => '8',//宾果 '92' => '8',//宾果 '131' => '8',//宾果 '120' => '8',//宾果 '18' => '2',//赌场 '93' => '2',//赌场 '132' => '2',//赌场 '41' => '5',//真人视讯 '101' => '5',//真人视讯 ]; /** * @param Player|null $player * @param $type * @throws Exception */ public function __construct($type, Player $player = null) { $config = config('game_platform.' . $type); $this->iv = $config['iv']; $this->apiDomain = $config['api_domain'].'/apiRequest.do'; $this->domain = $config['domain']; $this->key = $config['key']; $this->dc = $config['dc']; $this->parent = $config['admin_user']; $this->platform = GamePlatform::query()->where('name', $type)->first(); if (!empty($player)) { $this->player = $player; $this->getLoginId(); } } /** * 生成请求数据 * @param $source * @return string */ public function padString($source): string { $paddingChar = ' '; $size = 16; $x = strlen($source) % $size; $padLength = $size - $x; $source .= str_repeat($paddingChar, $padLength); return $source; } /** * 生成请求数据 * @param $params * @return array */ public function buildParams($params): array { $data = $this->padString(json_encode($params)); $encryptData = openssl_encrypt($data, 'AES-128-CBC', $this->key, OPENSSL_NO_PADDING, $this->iv); $reqBase64 = base64_encode($encryptData); return [ 'dc' => $this->dc, 'x' => str_replace(array('+','/','=') , array('-','_','') , $reqBase64) ]; } /** * @throws Exception */ protected function getLoginId() { /** @var PlayerGamePlatform $playerGamePlatform */ $playerGamePlatform = PlayerGamePlatform::query() ->where('platform_id', $this->platform->id) ->where('player_id',$this->player->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 = [ 'action' => 12, 'ts' => round(microtime(true) * 1000), 'lang' => 'cn', 'parent' => $this->parent, 'uid' => $this->player->uuid, 'name' => $this->player->name ?: $this->player->uuid ]; $request = $this->buildParams($params); $res = doFormCurl($this->apiDomain, $request); if ($res['status'] != $this->successCode) { throw new GameException($this->failCode[$res['status']], 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 getPlayer() { // TODO: Implement getPlayer() method. } /** * 获取游戏摘要MD5 (id+method+sn+APlSecretKey) * @return array|mixed|Response * @throws GameException|\think\Exception */ public function getSimpleGameList() { $params = [ 'action' => 49, 'ts' => round(microtime(true) * 1000), 'parent' => $this->parent, 'lang' => 'en', ]; $request = $this->buildParams($params); $res = doFormCurl($this->apiDomain, $request); if ($res['status'] != $this->successCode) { throw new GameException($this->failCode[$res['status']], 0); } $insertData = []; if (!empty($res['data'])) { foreach ($res['data'] as $data) { foreach($data['list'] as $item){ $insertData[] = [ 'platform_id' => $this->platform->id, 'game_code' => $item['mType'], 'platform_game_type' => $data['gType'], 'game_type' => $this->localGameType[$data['gType']], 'name' => $item['name'], 'game_image' => $item['image'], ]; } } } if (!empty($insertData)) { Game::query()->upsert($insertData, ['platform_id', 'game_code']); } return $insertData; } /** * 获取游戏摘要MD5 (id+method+sn+APlSecretKey) * @param array $data * @return string * @throws GameException|\think\Exception */ public function login(array $data = []): string { $params = [ 'action' => 11, 'ts' => round(microtime(true) * 1000), 'lang' => $this->lang[$data['lang']] ?? 'en', 'uid' => $this->loginId, 'gType' => $data['platformGameType'], 'mType' => $data['gameCode'], 'windowMode' => 2, 'isAPP' => true, ]; // if($data['platformGameType'] || $data['gameCode']){ // $params['gType'] = $data['platformGameType']; // $params['mType'] = $data['gameCode']; // $params['windowMode'] = 2; // $params['isAPP'] = true; // } $request = $this->buildParams($params); $res = doFormCurl($this->apiDomain, $request); if ($res['status'] != $this->successCode) { throw new GameException($this->failCode[$res['status']], 0); } return $res['path'] ?? ''; } /** * 玩家钱包转入游戏平台 * @return array|mixed|null * @throws GameException|\think\Exception */ public function balanceTransferOut() { return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_OUT, $this->player->wallet->money); } /** * 转入游戏平台玩家钱包 * @return array|mixed|null * @throws GameException|\think\Exception */ public function balanceTransferIn() { //提现之前把用户踢下线 if($this->checkPlay()){ $this->userLogout(); sleep(1); } $balance = $this->getBalance(); if($balance == 0){ // 记录玩家钱包转出转入记录 $this->createWalletTransfer(PlayerWalletTransfer::TYPE_IN, 0, 0); return true; } return $this->setBalanceTransfer(PlayerWalletTransfer::TYPE_IN, $balance ? -$balance : 0); } /** * 轉帳進出額度 * @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) { $params = [ 'action' => 19, 'ts' => round(microtime(true) * 1000), 'parent' => $this->parent, 'uid' => $this->loginId, 'serialNo' => createOrderNo(), 'amount' => $amount ?? 0, ]; $request = $this->buildParams($params); $res = doFormCurl($this->apiDomain, $request); if ($res['status'] != $this->successCode) { throw new GameException($this->failCode[$res['status']], 0); } // 记录玩家钱包转出转入记录 $this->createWalletTransfer($type, $amount, $reward); return $res; } /** * 獲取玩家餘額信息 * @return array|mixed|Response * @throws GameException|\think\Exception */ public function getBalance() { $params = [ 'action' => 15, 'ts' => round(microtime(true) * 1000), 'parent' => $this->parent, 'uid' => $this->loginId, ]; $request = $this->buildParams($params); $res = doFormCurl($this->apiDomain, $request); if ($res['status'] != $this->successCode) { throw new GameException('JDB System Error,Please contact the administrator', 0); } return $res['data'][0]['balance'] ?? 0; } /** * 查询玩家状态 * @throws GameException|\think\Exception */ public function checkPlay(): bool { $params = [ 'action' => 52, 'ts' => round(microtime(true) * 1000), 'parent' => $this->parent, 'uid' => $this->loginId, ]; $request = $this->buildParams($params); $res = doFormCurl($this->apiDomain, $request); //游戏中 if($res['status'] == $this->successCode){ return true; } //不在游戏中 if($res['status'] == 7505){ return false; } throw new GameException($this->failCode[$res['status']], 0); } /** * 玩家踢下线 * @throws GameException|\think\Exception */ public function userLogout(): bool { $params = [ 'action' => 17, 'ts' => round(microtime(true) * 1000), 'parent' => $this->parent, 'uid' => $this->loginId, ]; $request = $this->buildParams($params); $res = doFormCurl($this->apiDomain, $request); if ($res['status'] != $this->successCode) { throw new GameException($this->failCode[$res['status']], 0); } return true; } /** * 取得區間內遊戲紀錄 * @return array * @throws Exception */ public function handleOrderHistories(): array { $list = []; try { $data = $this->getGameHistories(); if (!empty($data)) { foreach ($data as $item) { if ($item['gType'] == 9 && !empty($item['hasGamble'])) { $item['bet'] = $item['gambleBet']; } $list[] = [ 'uuid' => $item['playerId'], 'platform_id' => $this->platform->id, 'game_code' => $item['mtype'], 'bet' => abs($item['bet']), 'win' => max($item['win'], 0), 'order_no' => $item['historyId'], 'game_type' => $item['gType'], 'original_data' => json_encode($item,JSON_UNESCAPED_UNICODE), 'platform_action_at' => date('Y-m-d H:i:s', strtotime($item['lastModifyTime'])), 'created_at' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s'), ]; } } } catch (Exception $e) { return []; } return $list; } /** * 取得區間內遊戲紀錄 * @return array * @throws GameException|\think\Exception */ public function getGameHistories(): array { $params = [ 'action' => 29, 'ts' => round(microtime(true) * 1000), 'parent' => $this->parent, 'starttime' => date('d-m-Y H:i:00', strtotime('-5 minutes')), 'endtime' => date('d-m-Y H:i:00', strtotime('-4 minutes')), ]; $request = $this->buildParams($params); $res = doFormCurl($this->apiDomain, $request); if ($res['status'] != $this->successCode) { throw new GameException($this->failCode[$res['status']], 0); } return $res['data'] ?? []; } }