You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

395 lines
14 KiB
PHTML

5 years ago
<?php
namespace Base\Service;
use Base\Model\PromoteModel;
use Base\Model\ApplyModel;
use Base\Tool\Base62;
use Base\Tool\PlistDemo;
5 years ago
class GameSourceService {
const IS_FIXED_IOS13 = true;
5 years ago
public function __construct()
{
}
/**
* 获取IPA中的.app后缀目录
*/
public function getIpaAppPath($ipaPath)
{
$appPath = '';
$zipGameSource = zip_open($ipaPath);
if ($zipGameSource) {
while ($zipEntry = zip_read($zipGameSource)) {
if (preg_match("/^Payload.*?\.app/", zip_entry_name($zipEntry), $matches)) {
$appPath = $matches[0];
break;
}
}
zip_close($zipGameSource);
}
return $appPath;
}
5 years ago
public function getChannelConfigFile($gameSource)
{
5 years ago
$configUrl = '';
if ($gameSource['sdk_version'] == 1) {
$configUrl = "META-INF/mch.properties";
} else {
$appPath = $this->getIpaAppPath($this->getGameSourceUrl($gameSource));
$configUrl = $appPath . '/_CodeSignature/TXChannel';
5 years ago
}
return $configUrl;
}
public function getChannelConfigFolder($gameSource, array $packData)
{
$gameSourceUrl = $this->getGameSourceUrl($gameSource);
$appPath = $this->getIpaAppPath($this->getGameSourceUrl($gameSource));
5 years ago
return $appPath . '/TXChannel/' . Base62::encode(json_encode($packData));
}
5 years ago
public function getGameSourceUrl($gameSource)
{
if (empty($gameSource)) {
return '';
}
5 years ago
$path = '';
5 years ago
if($gameSource['file_type'] == 1) {
5 years ago
$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'],
5 years ago
'promote_id' => $apply ? $apply['promote_id'] : '0',
'promote_account' => $apply ? $apply['promote_account'] : '自然渠道',
'source_version' => $gameSource['source_version'],
];
5 years ago
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)
5 years ago
{
$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)) {
5 years ago
$rows = explode('/' . $distFolder);
unset($rows[count($rows) -1]);
$txChannelFolder = implode('/', $rows);
$zip->deleteName($txChannelFolder);
$zip->addEmptyDir($distFolder);
$zip->close();
return true;
}
return false;
}
5 years ago
/**
* 原包打包
*/
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;
5 years ago
$relativeUrl = str_replace('Uploads/SourcePack', 'Uploads/Ios/original', $relativeUrl);
5 years ago
copy($oldLocalPath, $localPath);
}
$status = $this->packChannel($localPath, $game, $gameSource);
5 years ago
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,
5 years ago
'message' => '打包失败上传OSS失败' . $result['message'],
5 years ago
];
}
$plistUrl = '';
$orgPlistUrl = '';
if ($game['sdk_version'] == 2) {
$params = [
'packageName' => $gameSource['bao_name'],
'gameId' => $game['id'],
5 years ago
'gameName' => $game['game_name'],
5 years ago
'promoteId' => 0,
'packageUrl' => $fileUrl,
5 years ago
'gameIcon' => get_cover($game['icon'], 'path'),
5 years ago
'type' => 'pack'
];
$result = $this->createPlist($params);
if ($result['status']) {
$plistUrl = $result['data']['path'];
} else {
return [
'status' => false,
5 years ago
'message' => '打包失败生成plist文件失败' . $result['message'],
5 years ago
];
}
$params['type'] = 'org';
$result = $this->createPlist($params);
if ($result['status']) {
$orgPlistUrl = $result['data']['path'];
} else {
return [
'status' => false,
5 years ago
'message' => '打包失败生成原包plist文件失败' . $result['message'],
5 years ago
];
}
}
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) {
5 years ago
$fileName .= '.apk';
$savePath = 'Uploads/GamePack/' . $fileName;
5 years ago
} else {
5 years ago
$fileName .= '.ipa';
$savePath = 'Uploads/IosGamePack/' . $fileName;
5 years ago
}
$relativePath = './' . $savePath;
$localPath = ROOTTT . $savePath;
copy($gameSourceUrl, $localPath);
$status = $this->packChannel($localPath, $game, $gameSource, $apply);
5 years ago
if (!$status) {
return [
'status' => false,
'message' => '打包失败,加入渠道信息失败!',
];
}
5 years ago
$distFilePath = 'GamePack/' . $fileName;
$result = $this->uploadPackage($localPath, $distFilePath, false);
5 years ago
if ($result['status']) {
$packageUrl = $result['data']['url'];
$packageUrl = $packageUrl == '@' ? $relativePath : $packageUrl;
} else {
return [
'status' => false,
5 years ago
'message' => '打包失败上传OSS失败' . $result['message'],
5 years ago
];
}
$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'],
5 years ago
'gameName' => $game['game_name'],
5 years ago
'promoteId' => $apply['promote_id'],
'packageUrl' => $packageUrl,
5 years ago
'gameIcon' => get_cover($game['icon'], 'path'),
5 years ago
'type' => 'pack'
];
$result = $this->createPlist($params);
if ($result['status']) {
$plistUrl = $result['data']['path'];
} else {
return [
'status' => false,
5 years ago
'message' => '打包失败生成plist文件失败' . $result['message'],
5 years ago
];
}
}
5 years ago
$applyService = new ApplyService();
5 years ago
$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'] ?? '';
5 years ago
$gameName = $params['gameName'] ?? '';
5 years ago
$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);
5 years ago
$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 {
5 years ago
$element->nodeValue = C('DOMAIN_DOWNLOAD') . ltrim($packageUrl, '.');
5 years ago
}
break;
case 'icon':
if (preg_match("/http/", $gameIcon)) {
$element->nodeValue = $gameIcon;
} else {
5 years ago
$element->nodeValue = C('DOMAIN_OFFICIAL_PC') . ltrim($gameIcon, '.');
5 years ago
}
break;
case 'com.dell':
$element->nodeValue = $packageName;
break;
case '1.0.0':
$element->nodeValue = false;
break;
case 'mchdemo':
5 years ago
$element->nodeValue = $gameName;
5 years ago
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
]
];
}
5 years ago
}