getIpaAppPath($this->getGameSourceUrl($gameSource)); $configUrl = $appPath . '/_CodeSignature/TXChannel'; } return $configUrl; } public function getChannelConfigFolder($gameSource, array $packData) { $gameSourceUrl = $this->getGameSourceUrl($gameSource); $appPath = $this->getIpaAppPath($this->getGameSourceUrl($gameSource)); return $appPath . '/TXChannel/' . Base62::encode(json_encode($packData)); } public function getGameSourceUrl($gameSource) { if (empty($gameSource)) { return ''; } $path = ''; if($gameSource['file_type'] == 1) { $path = './Uploads/SourcePack/'; }else{ $path = './Uploads/Ios/original/'; } $fileUrl = $path . $gameSource['file_name']; return ROOTTT . ltrim($fileUrl, './'); } public function packChannel($localPath, $game, $gameSource, $apply = null) { $packData = [ 'game_id' => $game['id'], 'game_name' => $game['game_name'], 'game_appid' => $game['game_appid'], 'promote_id' => $apply ? $apply['promote_id'] : '', 'promote_account' => $apply ? $apply['promote_account'] : '自然渠道', 'source_version' => $gameSource['source_version'], ]; if (self::IS_FIXED_IOS13 && $game['sdk_version'] == 2) { $channelFolder = $this->getChannelConfigFolder($gameSource, $packData); return $this->packChannelFolder($localPath, $channelFolder); } else { $channelFile = $this->getChannelConfigFile($gameSource); return $this->packChannelFile($localPath, $channelFile, $packData); } return false; } /** * 打入渠道信息文件 * @param string $zipFile 包文件地址 * @param string $distFile 打入文件名 * @param array $packData 打入信息 * @return boolean 是否成功 */ public function packChannelFile($zipFile, $distFile, array $packData) { $zip = new \ZipArchive(); if ($zip->open($zipFile, \ZipArchive::CREATE)) { $zip->addFromString($distFile, json_encode($packData)); $zip->close(); return true; } return false; } /** * 打入渠道信息目录(用于IOS,主要为了解决IOS13问题) * @param string $zipFile 包文件地址 * @param string $distFolder 打入文件夹 * @return boolean 是否成功 */ public function packChannelFolder($zipFile, $distFolder) { $zip = new \ZipArchive(); if ($zip->open($zipFile, \ZipArchive::CREATE)) { $zip->addEmptyDir($distFolder); $zip->close(); return true; } return false; } /** * 原包打包 */ public function sourcePack($gameSource, $game) { $relativeUrl = $gameSource['file_url']; $localPath = ROOTTT . ltrim($relativeUrl, './'); $originalUrl = ''; if ($game['sdk_version'] == 2) { $oldLocalPath = $localPath; $localPath = str_replace('Uploads/SourcePack', 'Uploads/Ios/original', $oldLocalPath); $originalUrl = $relativeUrl; $relativeUrl = str_replace('Uploads/SourcePack', 'Uploads/Ios/original', $relativeUrl); copy($oldLocalPath, $localPath); } $status = $this->packChannel($localPath, $game, $gameSource); if (!$status) { return [ 'status' => false, 'message' => '打包失败,原包加入信息失败!', ]; } $distFilePath = 'SourcePack/' . $gameSource['file_name']; $result = $this->uploadPackage($localPath, $distFilePath); $fileUrl = ''; if ($result['status']) { $fileUrl = $result['data']['url']; $fileUrl = $fileUrl == '@' ? $relativeUrl : $fileUrl; } else { return [ 'status' => false, 'message' => '打包失败,上传OSS失败!' . $result['message'], ]; } $plistUrl = ''; $orgPlistUrl = ''; if ($game['sdk_version'] == 2) { $params = [ 'packageName' => $gameSource['bao_name'], 'gameId' => $game['id'], 'gameName' => $game['game_name'], 'promoteId' => 0, 'packageUrl' => $fileUrl, 'gameIcon' => get_cover($game['icon'], 'path'), 'type' => 'pack' ]; $result = $this->createPlist($params); if ($result['status']) { $plistUrl = $result['data']['path']; } else { return [ 'status' => false, 'message' => '打包失败,生成plist文件失败!' . $result['message'], ]; } $params['type'] = 'org'; $result = $this->createPlist($params); if ($result['status']) { $orgPlistUrl = $result['data']['path']; } else { return [ 'status' => false, 'message' => '打包失败,生成原包plist文件失败!' . $result['message'], ]; } } return [ 'status' => true, 'message' => '打包成功!', 'data' => [ 'plistUrl' => $plistUrl, 'orgPlistUrl' => $orgPlistUrl, 'fileUrl' => $fileUrl, 'originalUrl' => $originalUrl, ] ]; } /** * 渠道打包 */ public function channelPack($gameSource, $game, $apply, $launchCount = 0) { $gameSourceUrl = $this->getGameSourceUrl($gameSource); if ($gameSource == null || !file_exists($gameSourceUrl)) { M('apply', 'tab_')->where(['id' => $apply['id']])->setField('enable_status', -1); } /* 检测是否存在投放申请,存在则更改投放申请信息,否则进行渠道打包 */ if ($launchCount > 0) { M('apply', 'tab_')->where(['id' => $apply['id']])->setField('enable_status', 3); $launchData = ['launch_packge' => 2, 'launch_down_url'=>'' , 'launch_plist_url'=>'']; M('apply_launch', 'tab_')->where(['apply_id' => $apply['id'], 'launch_packge'=>['in', [0, 2, 3]]])->save($launchData); } $savePath = ''; $fileName = 'game_package' . $apply['game_id'] . '-' . $apply['promote_id']; if ($apply['sdk_version'] == 1) { $fileName .= '.apk'; $savePath = 'Uploads/GamePack/' . $fileName; } else { $fileName .= '.ipa'; $savePath = 'Uploads/IosGamePack/' . $fileName; } $relativePath = './' . $savePath; $localPath = ROOTTT . $savePath; copy($gameSourceUrl, $localPath); $status = $this->packChannel($localPath, $game, $gameSource, $apply); if (!$status) { return [ 'status' => false, 'message' => '打包失败,加入渠道信息失败!', ]; } $distFilePath = 'GamePack/' . $fileName; $result = $this->uploadPackage($localPath, $distFilePath, false); if ($result['status']) { $packageUrl = $result['data']['url']; $packageUrl = $packageUrl == '@' ? $relativePath : $packageUrl; } else { return [ 'status' => false, 'message' => '打包失败,上传OSS失败!' . $result['message'], ]; } $plistInfo = ['game_id' => $apply['game_id'], 'promote_id' => $apply['promote_id']]; $plistUrl = ''; if ($apply['sdk_version'] == 2) { $params = [ 'packageName' => $gameSource['bao_name'], 'gameId' => $game['id'], 'gameName' => $game['game_name'], 'promoteId' => $apply['promote_id'], 'packageUrl' => $packageUrl, 'gameIcon' => get_cover($game['icon'], 'path'), 'type' => 'pack' ]; $result = $this->createPlist($params); if ($result['status']) { $plistUrl = $result['data']['path']; } else { return [ 'status' => false, 'message' => '打包失败,生成plist文件失败!' . $result['message'], ]; } } $applyService = new ApplyService(); $applyService->updateAfterPack($apply, $packageUrl, $plistUrl); return [ 'status' => true, 'message' => '打包成功!', 'data' => [ 'plistUrl' => $plistUrl, ] ]; } public function uploadPackage($localFilePath, $distFilePath, $isDeleteLocal = false) { if (get_tool_status('oss_storage') == 1) { $ossService = new OssService(); $result = $ossService->upload($localFilePath, $distFilePath); if ($isDeleteLocal && file_exists($localFilePath)) { @unlink($localFilePath); } return $result; } else { // 不上传OSS等第三方服务器 return [ 'status' => true, 'message' => '上传成功', 'data' => [ 'url' => '@' ], ]; } } //生成游戏渠道plist文件 public function createPlist($params) { $packageName = $params['packageName'] ?? ''; $gameName = $params['gameName'] ?? ''; $gameId = $params['gameId'] ?? 0; $promoteId = $params['promoteId'] ?? 0; $packageUrl = $params['packageUrl'] ?? ''; $platformId = $params['platformId'] ?? 0; $position = $params['position'] ?? 0; $gameIcon = $params['gameIcon'] ?? ''; $type = $params['type'] ?? ''; if ($gameId == 0) { return [ 'status' => false, 'message' => '游戏ID错误', ]; } if ($type == '' || !in_array($type, ['org', 'pack'])) { return [ 'status' => false, 'message' => '类型错误', ]; } $xml = new \DOMDocument(); $xml->loadXML(PlistDemo::$content); $online = $xml->getElementsByTagName('dict'); //查找节点 $elements = $online->item(1)->getElementsByTagName('string'); //第二个节点下所有string foreach ($elements as $element) { switch ($element->textContent) { case 'ipa_url': if (preg_match("/http/", $packageUrl)) { $element->nodeValue = $packageUrl; } else { $element->nodeValue = C('DOMAIN_DOWNLOAD') . ltrim($packageUrl, '.'); } break; case 'icon': if (preg_match("/http/", $gameIcon)) { $element->nodeValue = $gameIcon; } else { $element->nodeValue = C('DOMAIN_OFFICIAL_PC') . ltrim($gameIcon, '.'); } break; case 'com.dell': $element->nodeValue = $packageName; break; case '1.0.0': $element->nodeValue = false; break; case 'mchdemo': $element->nodeValue = $gameName; break; } } $fileName = ''; if ($type == 'pack') { if ($promoteId == 0) { $fileName = 'Uploads/SourcePlist/'. $gameId . '.Plist'; } elseif ($platformId > 0) { $fileName = 'Uploads/GamePlist/'. $gameId . '-' . $promoteId . '-' . $platformId . '-' .$position . '.Plist'; } else { $fileName = 'Uploads/GamePlist/'. $gameId . '-' . $promoteId . '.Plist'; } } elseif ($type == 'org') { $fileName = 'Uploads/OrgSourcePlist/'. $gameId . '.Plist'; } $xml->save('./' . $fileName); return [ 'status' => true, 'message' => '生成成功', 'data' => [ 'path' => './' . $fileName ] ]; } }