Compare commits

..

1 Commits

Author SHA1 Message Date
a2ec23d667
sha256 sanity
Shorten files names
Exclude express and differential files
Only append hash suffix for duplicate files names (e.g. 22458 LPs for some langs)
2021-10-16 15:28:11 +03:00
479 changed files with 482 additions and 871 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
shared/cookie.json

View File

@ -17,87 +17,8 @@ limitations under the License.
require_once dirname(__FILE__).'/shared/main.php';
require_once dirname(__FILE__).'/shared/requests.php';
require_once dirname(__FILE__).'/shared/cache.php';
require_once dirname(__FILE__).'/shared/fileinfo.php';
require_once dirname(__FILE__).'/listid.php';
function uupApiPrivateParseFlags($str) {
$split = explode('+', $str);
$flagsSafe = [];
if(isset($split[1])) {
$flags = array_unique(explode(',', strtolower($split[1])));
$flagsSafe = array_intersect(getAllowedFlags(), $flags);
}
return [$split[0], $flagsSafe];
}
function uupApiPrivateGetLatestBuild() {
$builds = array('22000.1');
$ids = uupListIds();
if(isset($ids['error'])) {
$ids['builds'] = array();
}
if(empty($ids['builds'])) {
$build = $builds[0];
} else {
$build = $ids['builds'][0]['build'];
}
return $build;
}
function uupApiPrivateGetAcceptableBranches() {
return [
'auto',
'rs2_release',
'rs3_release',
'rs4_release',
'rs5_release',
'rs5_release_svc_hci',
'19h1_release',
'vb_release',
'fe_release_10x',
'fe_release',
'co_release',
'ni_release',
'zn_release',
'ge_release',
'rs_prerelease',
];
}
function uupApiPrivateNormalizeFetchParams($params) {
$np = array_replace([
'arch' => 'amd64',
'ring' => 'WIF',
'flight' => 'Active',
'branch' => 'ge_release',
'build' => 'latest',
'minor' => 0,
'sku' => 48,
'type' => 'Production',
'flags' => [],
], $params);
if(!is_array($np['flags'])) $np['flags'] = [];
$np['arch'] = strtolower($np['arch']);
$np['ring'] = strtoupper($np['ring']);
$np['flight'] = ucwords(strtolower($np['flight']));
$np['branch'] = strtolower($np['branch']);
$np['build'] = strtolower($np['build']);
$np['minor'] = intval($np['minor']);
$np['sku'] = intval($np['sku']);
$np['type'] = ucwords(strtolower($np['type']));
$np['flags'] = array_map('strtolower', $np['flags']);
return $np;
}
function uupFetchUpd(
$arch = 'amd64',
$ring = 'WIF',
@ -108,52 +29,35 @@ function uupFetchUpd(
$type = 'Production',
$cacheRequests = 0
) {
[$build, $flags] = uupApiPrivateParseFlags($build);
$params = [
'arch' => $arch,
'ring' => $ring,
'flight' => $flight,
'build' => $build,
'minor' => $minor,
'sku' => $sku,
'type' => $type,
'flags' => $flags,
];
return uupFetchUpd2($params, $cacheRequests);
}
function uupFetchUpd2($params, $cacheRequests = 0) {
uupApiPrintBrand();
$np = uupApiPrivateNormalizeFetchParams($params);
$arch = $np['arch'];
$ring = $np['ring'];
$arch = strtolower($arch);
$ring = strtoupper($ring);
$flight = ucwords(strtolower($flight));
$flight = 'Active';
$branch = $np['branch'];
$build = $np['build'];
$minor = $np['minor'];
$sku = $np['sku'];
$type = $np['type'];
$flags = $np['flags'];
$flagsStr = implode(',', $flags);
if($build == 'latest' || (!$build)) {
$builds = array('17134.1');
if(strtolower($build) == 'latest' || (!$build)) {
$build = uupApiPrivateGetLatestBuild();
$ids = uupListIds();
if(isset($ids['error'])) {
$ids['builds'] = array();
}
$build = $ids['builds'][0]['build'];
unset($builds, $ids);
}
$build = explode('.', $build);
if(isset($build[1])) $minor = intval($build[1]);
$build = intval($build[0]);
$sku = intval($sku);
if(!($arch == 'amd64' || $arch == 'x86' || $arch == 'arm64' || $arch == 'arm' || $arch == 'all')) {
return array('error' => 'UNKNOWN_ARCH');
}
if(!($ring == 'CANARY' || $ring == 'DEV' || $ring == 'BETA' || $ring == 'RELEASEPREVIEW' || $ring == 'WIF' || $ring == 'WIS' || $ring == 'RP' || $ring == 'RETAIL' || $ring == 'MSIT')) {
if(!($ring == 'DEV' || $ring == 'BETA' || $ring == 'RELEASEPREVIEW' || $ring == 'WIF' || $ring == 'WIS' || $ring == 'RP' || $ring == 'RETAIL' || $ring == 'MSIT')) {
return array('error' => 'UNKNOWN_RING');
}
@ -173,9 +77,6 @@ function uupFetchUpd2($params, $cacheRequests = 0) {
return array('error' => 'ILLEGAL_MINOR');
}
if(!in_array($branch, uupApiPrivateGetAcceptableBranches()))
$branch = 'auto';
if($ring == 'DEV') $ring = 'WIF';
if($ring == 'BETA') $ring = 'WIS';
if($ring == 'RELEASEPREVIEW') $ring = 'RP';
@ -189,21 +90,44 @@ function uupFetchUpd2($params, $cacheRequests = 0) {
$type = 'Production';
}
$res = "api-fetch-$arch-$ring-$flight-$branch-$build-$flagsStr-$minor-$sku-$type";
$cache = new UupDumpCache($res);
$fromCache = $cache->get();
if($fromCache !== false) return $fromCache;
$cacheHash = hash('sha256', strtolower("api-fetch-$arch-$ring-$flight-$build-$minor-$sku-$type"));
$cached = 0;
consoleLogger('Fetching information from the server...');
$composerArgs = [$arch, $flight, $ring, $build, $sku, $type, $flags, $branch];
$out = sendWuPostRequestHelper('client', 'composeFetchUpdRequest', $composerArgs);
if($out === false || $out['error'] != 200) {
consoleLogger('The request has failed');
return array('error' => 'WU_REQUEST_FAILED');
if(file_exists('cache/'.$cacheHash.'.json.gz') && $cacheRequests == 1) {
$cache = @gzdecode(@file_get_contents('cache/'.$cacheHash.'.json.gz'));
$cache = json_decode($cache, 1);
if(!empty($cache['content']) && ($cache['expires'] > time())) {
consoleLogger('Using cached response...');
$out = $cache['content'];
$cached = 1;
} else {
$cached = 0;
}
unset($cache);
}
$out = html_entity_decode($out['out']);
consoleLogger('Information has been successfully fetched.');
if(!$cached) {
consoleLogger('Fetching information from the server...');
$postData = composeFetchUpdRequest(uupDevice(), uupEncryptedData(), $arch, $flight, $ring, $build, $sku, $type);
$out = sendWuPostRequest('https://fe3cr.delivery.mp.microsoft.com/ClientWebService/client.asmx', $postData);
$out = html_entity_decode($out);
consoleLogger('Information has been successfully fetched.');
if($cacheRequests == 1) {
$cache = array(
'expires' => time()+120,
'content' => $out,
);
if(!file_exists('cache')) mkdir('cache');
@file_put_contents('cache/'.$cacheHash.'.json.gz', gzencode(json_encode($cache)."\n"));
unset($cache);
}
}
preg_match_all('/<UpdateInfo>.*?<\/UpdateInfo>/', $out, $updateInfos);
$updateInfo = preg_grep('/<IsLeaf>true<\/IsLeaf>/', $updateInfos[0]);
@ -223,7 +147,7 @@ function uupFetchUpd2($params, $cacheRequests = 0) {
$num++;
consoleLogger("Checking build information for update {$num} of {$updatesNum}...");
$info = parseFetchUpdate($val, $out, $arch, $ring, $flight, $build, $sku, $type, $flags, $branch);
$info = parseFetchUpdate($val, $out, $arch, $ring, $flight, $build, $sku, $type);
if(isset($info['error'])) {
$errorCount++;
continue;
@ -236,7 +160,7 @@ function uupFetchUpd2($params, $cacheRequests = 0) {
return array('error' => 'EMPTY_FILELIST');
}
$data = [
return array(
'apiVersion' => uupApiVersion(),
'updateId' => $updateArray[0]['updateId'],
'updateTitle' => $updateArray[0]['updateTitle'],
@ -244,16 +168,10 @@ function uupFetchUpd2($params, $cacheRequests = 0) {
'arch' => $updateArray[0]['arch'],
'fileWrite' => $updateArray[0]['fileWrite'],
'updateArray' => $updateArray,
];
if($cacheRequests == 1) {
$cache->put($data, 120);
}
return $data;
);
}
function parseFetchUpdate($updateInfo, $out, $arch, $ring, $flight, $build, $sku, $type, $flags, $branch) {
function parseFetchUpdate($updateInfo, $out, $arch, $ring, $flight, $build, $sku, $type) {
$updateNumId = preg_replace('/<UpdateInfo><ID>|<\/ID>.*/i', '', $updateInfo);
$updates = preg_replace('/<Update>/', "\n<Update>", $out);
@ -295,15 +213,6 @@ function parseFetchUpdate($updateInfo, $out, $arch, $ring, $flight, $build, $sku
$foundBuild = @$info[3];
}
$isNet = 0;
if(strpos($foundArch, 'netfx') !== false) {
$isNet = 1;
preg_match('/ProductReleaseInstalled Name\=".*\.(.*?)\.(.*?)" Version\=".*\.\d{5}\.(.*?)"/', $updateInfo, $info);
$foundType = @strtolower($info[1]);
$foundArch = @strtolower($info[2]);
$foundBuild = @$info[3];
}
$updateTitle = preg_grep('/<Title>.*<\/Title>/', $updateMeta);
sort($updateTitle);
@ -323,19 +232,13 @@ function parseFetchUpdate($updateInfo, $out, $arch, $ring, $flight, $build, $sku
$isCumulativeUpdate = 0;
if(preg_match('/\d{4}-\d{2}.+Update|Cumulative Update|Microsoft Edge|Windows Feature Experience Pack|Cumulative security Hotpatch/i', $updateTitle)) {
$isCumulativeUpdate = 1;
if($isNet) {
$updateTitle = preg_replace("/3.5 and 4.8.1 |3.5 and 4.8 | for $foundArch| for x64| \(KB.*?\)/i", '', $updateTitle);
} else {
$updateTitle = preg_replace('/ for .{3,5}-based systems| \(KB.*?\)/i', '', $updateTitle);
}
$updateTitle = preg_replace('/ for .{3,5}-based systems| \(KB.*?\)/i', '', $updateTitle);
}
$updateTitle = preg_replace("/ ?\d{4}-\d{2}\D ?| ?$foundArch ?| ?x64 ?/i", '', $updateTitle);
if($foundType == 'server') {
if($foundType == 'server')
$updateTitle = str_replace('Windows 10', 'Windows Server', $updateTitle);
$updateTitle = str_replace('Windows 11', 'Windows Server', $updateTitle);
}
if($sku == 406)
$updateTitle = str_replace('Microsoft server operating system', 'Azure Stack HCI', $updateTitle);
@ -397,16 +300,16 @@ function parseFetchUpdate($updateInfo, $out, $arch, $ring, $flight, $build, $sku
return array('error' => 'BROKEN_UPDATE');
}
$isCorpnet = preg_match('/Corpnet Required/i', $updateTitle);
if($isCorpnet && !uupApiConfigIsTrue('allow_corpnet')) {
if(preg_match('/Corpnet Required/i', $updateTitle)) {
consoleLogger('Skipping corpnet only update...');
return array('error' => 'CORPNET_ONLY_UPDATE');
}
$fileWrite = 'NO_SAVE';
if(!uupApiFileInfoExists($updateId)) {
if(!file_exists('fileinfo/'.$updateString.'.json')) {
consoleLogger('WARNING: This build is NOT in the database. It will be saved now.');
consoleLogger('Parsing information to write...');
if(!file_exists('fileinfo')) mkdir('fileinfo');
$fileList = preg_replace('/<Files>|<\/Files>/', '', $fileList[0]);
preg_match_all('/<File.*?<\/File>/', $fileList, $fileList);
@ -444,9 +347,7 @@ function parseFetchUpdate($updateInfo, $out, $arch, $ring, $flight, $build, $sku
$temp['title'] = $updateTitle;
$temp['ring'] = $ring;
$temp['flight'] = $flight;
$temp['branch'] = $branch;
$temp['arch'] = $foundArch;
$temp['fetchArch'] = $arch == 'all' ? 'amd64' : $arch;
$temp['build'] = $foundBuild;
$temp['checkBuild'] = $build;
$temp['sku'] = $sku;
@ -459,10 +360,6 @@ function parseFetchUpdate($updateInfo, $out, $arch, $ring, $flight, $build, $sku
$temp['releasetype'] = $type;
}
if(!empty($flags)) {
$temp['flags'] = $flags;
}
$temp['created'] = time();
$temp['sha256ready'] = true;
$temp['files'] = $shaArray;
@ -470,11 +367,10 @@ function parseFetchUpdate($updateInfo, $out, $arch, $ring, $flight, $build, $sku
consoleLogger('Successfully parsed the information.');
consoleLogger('Writing new build information to the disk...');
$success = uupApiWriteFileinfo($updateString, $temp);
$success = file_put_contents('fileinfo/'.$updateString.'.json', json_encode($temp)."\n");
if($success) {
consoleLogger('Successfully written build information to the disk.');
$fileWrite = 'INFO_WRITTEN';
uupApiPrivateInvalidateFileinfoCache();
} else {
consoleLogger('An error has occured while writing the information to the disk.');
}

198
get.php
View File

@ -18,8 +18,6 @@ limitations under the License.
require_once dirname(__FILE__).'/shared/main.php';
require_once dirname(__FILE__).'/shared/requests.php';
require_once dirname(__FILE__).'/shared/packs.php';
require_once dirname(__FILE__).'/shared/cache.php';
require_once dirname(__FILE__).'/shared/fileinfo.php';
/*
$updateId = Update Identifier
@ -44,16 +42,10 @@ function uupGetFiles(
}
if(!uupApiCheckUpdateId($updateId)) {
return array('error' => 'INCORRECT_ID');
return array('error' => 'INCORRECT_ID');
}
$edition = is_array($desiredEdition) ? implode('_', $desiredEdition) : $desiredEdition;
$res = "api-get-{$updateId}_{$usePack}_{$edition}_{$requestType}";
$cache = new UupDumpCache($res);
$fromCache = $cache->get();
if($fromCache !== false) return $fromCache;
$info = uupApiReadFileinfo($updateId);
$info = @file_get_contents('fileinfo/'.$updateId.'.json');
if(empty($info)) {
$info = array(
'ring' => 'WIF',
@ -63,6 +55,8 @@ function uupGetFiles(
'sku' => '48',
'files' => array(),
);
} else {
$info = json_decode($info, true);
}
if(isset($info['build'])) {
@ -76,10 +70,8 @@ function uupGetFiles(
$info['sku'] = 48;
}
$genPack = [];
if($usePack) {
$genPack = uupApiGetPacks($updateId);
$genPack = uupGetGenPacks($build, $info['arch'], $updateId);
if(empty($genPack)) return array('error' => 'UNSUPPORTED_COMBINATION');
if(!isset($genPack[$usePack])) {
@ -87,8 +79,6 @@ function uupGetFiles(
}
}
$appEdition = 0;
if(!is_array($desiredEdition)) {
$desiredEdition = strtoupper($desiredEdition);
$fileListSource = $desiredEdition;
@ -114,19 +104,13 @@ function uupGetFiles(
case 'UPDATEONLY': break;
case 'APP': $appEdition = 1;
case 'APP_MOMENT': $appEdition = 1;
default:
if(!isset($genPack[$usePack][$desiredEdition])) {
return array('error' => 'UNSUPPORTED_COMBINATION');
}
$fileListSource = 'GENERATEDPACKS';
$filesPacksList = $genPack[$usePack][$desiredEdition];
if($desiredEdition == 'APP' && isset($genPack[$usePack]['APP_MOMENT'])) {
$filesPacksList = array_merge($filesPacksList, $genPack[$usePack]['APP_MOMENT']);
}
$fileListSource = 'GENERATEDPACKS';
break;
}
} else {
@ -139,7 +123,6 @@ function uupGetFiles(
return array('error' => 'UNSUPPORTED_COMBINATION');
}
if($edition == 'APP' || $edition == 'APP_MOMENT') $appEdition = 1;
$filesPacksList = array_merge($filesPacksList, $genPack[$usePack][$edition]);
}
}
@ -155,7 +138,6 @@ function uupGetFiles(
$updateBuild = (isset($info['build'])) ? $info['build'] : 'UNKNOWN';
$updateName = (isset($info['title'])) ? $info['title'] : 'Unknown update: '.$updateId;
$sha256capable = isset($info['sha256ready']);
$hasUpdates = false;
if(isset($info['releasetype'])) {
$type = $info['releasetype'];
@ -182,34 +164,16 @@ function uupGetFiles(
if(isset($filesInfoList[$val])) unset($filesInfoList[$val]);
}
$baseless = preg_grep('/^baseless_/i', array_keys($filesInfoList));
$baseless = preg_grep('/^baseless_|Windows10\.0-KB.*-EXPRESS|SSU-.*-EXPRESS/i', array_keys($filesInfoList));
foreach($baseless as $val) {
if(isset($filesInfoList[$val])) unset($filesInfoList[$val]);
}
$expresscab = preg_grep('/Windows(10|11)\.0-KB.*-EXPRESS|SSU-.*-EXPRESS/i', array_keys($filesInfoList));
$expresspsf = array();
foreach($expresscab as $val) {
$name = preg_replace('/-EXPRESS.cab$/i', '', $val);
$expresspsf[] = $name;
if(isset($filesInfoList[$val])) unset($filesInfoList[$val]);
}
unset($index, $name, $expresscab);
foreach($expresspsf as $val) {
if(isset($filesInfoList[$val.'.cab'])) {
if(isset($filesInfoList[$val.'.psf'])) unset($filesInfoList[$val.'.psf']);
}
}
unset($expresspsf);
$psf = array_keys($filesInfoList);
$psf = preg_grep('/\.psf$/i', $psf);
$psfk = preg_grep('/Windows(10|11)\.0-KB.*/i', $psf);
$psfk = preg_grep('/Windows10\.0-KB.*/i', $psf);
$psfk = preg_grep('/.*-EXPRESS/i', $psfk, PREG_GREP_INVERT);
if($build < 17763) $psfk = preg_grep('/Windows(10|11)\.0-KB.*_\d\.psf$/i', $psfk, PREG_GREP_INVERT);
foreach($psfk as $key => $val) {
if(isset($psf[$key])) unset($psf[$key]);
}
@ -237,46 +201,24 @@ function uupGetFiles(
}
unset($removeFiles);
$msu = array_keys($filesInfoList);
$msu = preg_grep('/\.msu$/i', $msu);
$removeMSUs = array();
foreach($msu as $val) {
$name = preg_replace('/\.msu$/i', '', $val);
$removeMSUs[] = $name;
}
unset($index, $name, $msu);
$filesInfoKeys = array_keys($filesInfoList);
$updatesRegex = '/Windows(10|11)\.0-KB|SSU-.*?\....$/i';
switch($fileListSource) {
case 'UPDATEONLY':
$skipPackBuild = 1;
$removeFiles = preg_grep('/Windows(10|11)\.0-KB.*-baseless/i', $filesInfoKeys);
$removeFiles = preg_grep('/Windows10\.0-KB.*-EXPRESS|Windows10\.0-KB.*-baseless|SSU-\d*?\.\d*?-.{3,5}-EXPRESS/i', $filesInfoKeys);
foreach($removeFiles as $val) {
if(isset($filesInfoList[$val])) unset($filesInfoList[$val]);
}
unset($removeFiles);
foreach($removeMSUs as $val) {
if(isset($filesInfoList[$val.'.cab']) && isset($filesInfoList[$val.'.msu'])) {
unset($filesInfoList[$val.'.msu']);
}
}
unset($removeMSUs);
$filesInfoKeys = array_keys($filesInfoList);
$temp = preg_grep('/.*?AggregatedMetadata.*?\.cab|.*?DesktopDeployment.*?\.cab/i', $filesInfoKeys);
$filesInfoKeys = preg_grep($updatesRegex, $filesInfoKeys);
$filesInfoKeys = preg_grep('/Windows10\.0-KB|SSU-\d*?\.\d*?-.*?\.cab/i', $filesInfoKeys);
if(count($filesInfoKeys) == 0) {
return array('error' => 'NOT_CUMULATIVE_UPDATE');
}
if($build > 21380) $filesInfoKeys = array_merge($filesInfoKeys, $temp);
unset($temp);
$hasUpdates = true;
break;
case 'WUBFILE':
@ -290,24 +232,8 @@ function uupGetFiles(
if($updateSku == 135) $uupCleanFunc = 'uupCleanHolo';
if($fileListSource == 'GENERATEDPACKS') {
foreach($removeMSUs as $val) {
if(isset($filesInfoList[$val.'.cab']) && isset($filesInfoList[$val.'.msu'])) {
unset($filesInfoList[$val.'.msu']);
}
}
unset($removeMSUs);
$filesInfoKeys = array_keys($filesInfoList);
$temp = preg_grep('/Windows(10|11)\.0-KB.*-baseless/i', $filesInfoKeys, PREG_GREP_INVERT);
if($appEdition) {
$temp = preg_grep('/.*?AggregatedMetadata.*?\.cab/i', $temp);
} else if($build > 21380) {
$temp = preg_grep('/Windows(10|11)\.0-KB|SSU-.*?\....$|.*?AggregatedMetadata.*?\.cab|.*?DesktopDeployment.*?\.cab/i', $temp);
} else {
$temp = preg_grep($updatesRegex, $temp);
}
$hasUpdates = !empty(preg_grep($updatesRegex, $temp));
$temp = preg_grep('/Windows10\.0-KB.*-EXPRESS|Windows10\.0-KB.*-baseless|SSU-\d*?\.\d*?-.{3,5}-EXPRESS/i', $filesInfoKeys, PREG_GREP_INVERT);
$temp = preg_grep('/Windows10\.0-KB|SSU-\d*?\.\d*?-.*?\.cab/i', $temp);
$filesPacksList = array_merge($filesPacksList, $temp);
$newFiles = array();
@ -359,7 +285,6 @@ function uupGetFiles(
$filesNew = array();
foreach($filesInfoKeys as $val) {
$filesNew[$val] = $filesInfoList[$val];
$filesNew[$val]['url'] = uupApiFixDownloadLink($filesInfoList[$val]['url']);
}
$files = $filesNew;
@ -367,54 +292,48 @@ function uupGetFiles(
consoleLogger('Successfully parsed the information.');
$data = [
return array(
'apiVersion' => uupApiVersion(),
'updateName' => $updateName,
'arch' => $updateArch,
'build' => $updateBuild,
'sku' => $updateSku,
'hasUpdates' => $hasUpdates,
'appxPresent' => uupAreAppxPresent($genPack),
'files' => $files,
];
if($requestType > 0) {
$cacheData = $data;
$cache->put($cacheData, 30);
}
return $data;
);
}
function uupGetOnlineFiles($updateId, $rev, $info, $cacheRequests, $type) {
$res = "api-get-online-{$updateId}_rev.$rev";
$cache = new UupDumpCache($res);
$fromCache = $cache->get();
$cached = ($fromCache !== false);
$cacheHash = hash('sha256', strtolower("api-get-${updateId}_rev.$rev"));
$cached = 0;
if($cached) {
$out = $fromCache['out'];
$fetchTime = $fromCache['fetchTime'];
} else {
$fetchTime = time();
consoleLogger('Fetching information from the server...');
if(file_exists('cache/'.$cacheHash.'.json.gz') && $cacheRequests == 1) {
$cache = @gzdecode(@file_get_contents('cache/'.$cacheHash.'.json.gz'));
$cache = json_decode($cache, 1);
$composerArgs = [$updateId, $info, $rev, $type];
$out = sendWuPostRequestHelper('clientSecured', 'composeFileGetRequest', $composerArgs);
if($out === false || $out['error'] != 200) {
consoleLogger('The request has failed');
return array('error' => 'WU_REQUEST_FAILED');
if(!empty($cache['content']) && ($cache['expires'] > time())) {
consoleLogger('Using cached response...');
$out = $cache['content'];
$fetchTime = $cache['fetchTime'];
$cached = 1;
} else {
$cached = 0;
}
$out = $out['out'];
unset($cache);
}
if(!$cached) {
$fetchTime = time();
consoleLogger('Fetching information from the server...');
$postData = composeFileGetRequest($updateId, uupDevice(), $info, $rev, $type);
$out = sendWuPostRequest('https://fe3cr.delivery.mp.microsoft.com/ClientWebService/client.asmx/secured', $postData);
consoleLogger('Information has been successfully fetched.');
}
consoleLogger('Parsing information...');
$xmlOut = @simplexml_load_string($out);
if($xmlOut === false) {
$cache->delete();
@unlink('cache/'.$cacheHash.'.json.gz');
return array('error' => 'XML_PARSE_ERROR');
}
@ -462,11 +381,15 @@ function uupGetOnlineFiles($updateId, $rev, $info, $cacheRequests, $type) {
if($sha256capable) {
$tempname = uupCleanSha256($name);
if(isset($files[$tempname])) {
if($size > $files[$tempname]['size']) {
$smaller = uupAppendSha1($tempname, $files[$tempname]['sha1']);
$files[$smaller] = $files[$tempname];
unset($files[$tempname]);
$newName = $tempname;
if(preg_match('/\.cab$/i', $tempname)) {
if($size > $files[$tempname]['size']) {
$express = 'baseless_'.$tempname;
$files[$express] = $files[$tempname];
unset($files[$tempname]);
$newName = $tempname;
} else {
$newName = 'baseless_'.$tempname;
}
} else {
$newName = uupAppendSha1($tempname, $sha1);
}
@ -510,12 +433,14 @@ function uupGetOnlineFiles($updateId, $rev, $info, $cacheRequests, $type) {
}
if($cacheRequests == 1 && $cached == 0) {
$cacheData = [
'out' => $out,
$cache = array(
'expires' => time()+90,
'content' => $out,
'fetchTime' => $fetchTime,
];
);
$cache->put($cacheData, 90);
if(!file_exists('cache')) mkdir('cache');
@file_put_contents('cache/'.$cacheHash.'.json.gz', gzencode(json_encode($cache)."\n"));
}
return $files;
@ -537,14 +462,24 @@ function uupGetOfflineFiles($info) {
$sha256 = isset($val['sha256']) ? $val['sha256'] : null;
if($sha256capable) {
// clean file name
$tempname = uupCleanSha256($name);
if(isset($files[$tempname])) {
if($size > $files[$tempname]['size']) {
$smaller = uupAppendSha1($tempname, $files[$tempname]['sha1']);
$files[$smaller] = $files[$tempname];
unset($files[$tempname]);
$newName = $tempname;
// check existing file with the same name
if(preg_match('/\.cab$/i', $tempname)) {
// compare cab files only
if($size > $files[$tempname]['size']) {
// if the existing file is smaller, rename it
$express = 'baseless_'.$tempname;
$files[$express] = $files[$tempname];
unset($files[$tempname]);
$newName = $tempname;
} else {
// if the new file is smaller, rename it
$newName = 'baseless_'.$tempname;
}
} else {
// not a cab file, append hash to differentiate
$newName = uupAppendSha1($tempname, $sha1);
}
} else {
@ -583,7 +518,8 @@ function uupAppendSha1($name, $sha1) {
function uupCleanSha256($name) {
$replace = array(
'prss_signed_appx_' => null,
'MetadataESD_' => null,
'metadataesd_' => null,
'~31bf3856ad364e35' => null,
'~~.' => '.',
'~.' => '.',

View File

@ -1,6 +1,6 @@
<?php
/*
Copyright 2023 UUP dump API authors
Copyright 2019 UUP dump API authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -17,35 +17,59 @@ limitations under the License.
require_once dirname(__FILE__).'/shared/main.php';
require_once dirname(__FILE__).'/shared/packs.php';
require_once dirname(__FILE__).'/updateinfo.php';
function uupListEditions($lang = 'en-us', $updateId = 0) {
if($updateId) {
$info = uupUpdateInfo($updateId);
}
if(!$lang) {
return array('error' => 'UNSUPPORTED_LANG');
}
$lang = strtolower($lang);
$genPack = uupApiGetPacks($updateId);
$fancyEditionNames = uupGetInfoTexts()['fancyEditionNames'];
if(isset($info['info'])) $info = $info['info'];
if(!isset($genPack[$lang])) {
return array('error' => 'UNSUPPORTED_LANG');
if(isset($info['build'])) {
$build = explode('.', $info['build']);
$build = $build[0];
} else {
$build = 15063;
}
$editionList = [];
$editionListFancy = [];
if(!isset($info['arch'])) {
$info['arch'] = null;
}
$genPack = uupGetGenPacks($build, $info['arch'], $updateId);
$fancyTexts = uupGetInfoTexts();
$fancyEditionNames = $fancyTexts['fancyEditionNames'];
if($lang) {
$lang = strtolower($lang);
if(!isset($genPack[$lang])) {
return array('error' => 'UNSUPPORTED_LANG');
}
}
$editionList = array();
$editionListFancy = array();
foreach(array_keys($genPack[$lang]) as $edition) {
if(in_array($edition, ['LXP', 'FOD'])) continue;
if($edition == 'LXP') continue;
$fancyName = isset($fancyEditionNames[$edition]) ? $fancyEditionNames[$edition] : $edition;
if(isset($fancyEditionNames[$edition])) {
$fancyName = $fancyEditionNames[$edition];
} else {
$fancyName = $edition;
}
$editionList[] = $edition;
$editionListFancy[$edition] = $fancyName;
}
return [
return array(
'apiVersion' => uupApiVersion(),
'editionList' => $editionList,
'editionFancyNames' => $editionListFancy,
];
);
}

View File

@ -16,31 +16,22 @@ limitations under the License.
*/
require_once dirname(__FILE__).'/shared/main.php';
require_once dirname(__FILE__).'/shared/cache.php';
require_once dirname(__FILE__).'/shared/fileinfo.php';
function uupApiPrivateInvalidateFileinfoCache() {
$cache1 = new UupDumpCache('listid-0', false);
$cache2 = new UupDumpCache('listid-1', false);
function uupListIds($search = null, $sortByDate = 0) {
uupApiPrintBrand();
$cache1->delete();
$cache2->delete();
}
if(!file_exists('fileinfo')) return array('error' => 'NO_FILEINFO_DIR');
function uupApiPrivateGetFromFileinfo($sortByDate = 0) {
$dirs = uupApiGetFileinfoDirs();
$fileinfo = $dirs['fileinfoData'];
$fileinfoRoot = $dirs['fileinfo'];
$files = scandir($fileinfo);
$files = scandir('fileinfo');
$files = preg_grep('/\.json$/', $files);
consoleLogger('Parsing database info...');
$cacheFile = $fileinfoRoot.'/cache.json';
$cacheFile = 'cache/fileinfo_v2.json';
$cacheV2Version = 1;
$database = uupApiReadJson($cacheFile);
$database = @file_get_contents($cacheFile);
$database = json_decode($database, true);
if(isset($database['version'])) {
$version = $database['version'];
@ -59,13 +50,12 @@ function uupApiPrivateGetFromFileinfo($sortByDate = 0) {
$newDb = array();
$builds = array();
foreach($files as $file) {
if($file == '.' || $file == '..')
continue;
if($file == '.' || $file == '..') continue;
$uuid = preg_replace('/\.json$/', '', $file);
if(!isset($database[$uuid])) {
$info = uupApiReadFileinfoMeta($uuid);
$info = @file_get_contents('fileinfo/'.$file);
$info = json_decode($info, true);
$title = isset($info['title']) ? $info['title'] : 'UNKNOWN';
$build = isset($info['build']) ? $info['build'] : 'UNKNOWN';
@ -115,7 +105,12 @@ function uupApiPrivateGetFromFileinfo($sortByDate = 0) {
$builds[$tmp.$arch.$title.$uuid] = $temp;
}
if(empty($buildAssoc)) return [];
if(empty($buildAssoc)) {
return array(
'apiVersion' => uupApiVersion(),
'builds' => array(),
);
}
krsort($buildAssoc);
$buildsNew = array();
@ -146,27 +141,7 @@ function uupApiPrivateGetFromFileinfo($sortByDate = 0) {
if(!$success) consoleLogger('Failed to update database cache.');
}
return $builds;
}
function uupListIds($search = null, $sortByDate = 0) {
uupApiPrintBrand();
$sortByDate = $sortByDate ? 1 : 0;
$res = "listid-$sortByDate";
$cache = new UupDumpCache($res, false);
$builds = $cache->get();
$cached = ($builds !== false);
if(!$cached) {
$builds = uupApiPrivateGetFromFileinfo($sortByDate);
if($builds === false) return ['error' => 'NO_FILEINFO_DIR'];
$cache->put($builds, 60);
}
if(count($builds) && $search != null) {
if($search) {
if(!preg_match('/^regex:/', $search)) {
$searchSafe = preg_quote($search, '/');

View File

@ -1,6 +1,6 @@
<?php
/*
Copyright 2023 UUP dump API authors
Copyright 2019 UUP dump API authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -19,45 +19,60 @@ require_once dirname(__FILE__).'/shared/main.php';
require_once dirname(__FILE__).'/shared/packs.php';
require_once dirname(__FILE__).'/updateinfo.php';
function uupListLangsInternal($updateId) {
$genPack = uupApiGetPacks($updateId);
$fancyLangNames = uupGetInfoTexts()['fancyLangNames'];
function uupListLangs($updateId = 0) {
if($updateId) {
$info = uupUpdateInfo($updateId);
}
$langList = [];
$langListFancy = [];
if(isset($info['info'])) {
$info = $info['info'];
unset($info['files']);
}
if(isset($info['build'])) {
$build = explode('.', $info['build']);
$build = $build[0];
} else {
$build = 15063;
}
if(!isset($info['arch'])) {
$info['arch'] = null;
}
$genPack = uupGetGenPacks($build, $info['arch'], $updateId);
$fancyTexts = uupGetInfoTexts();
$fancyLangNames = $fancyTexts['fancyLangNames'];
$langList = array();
$langListFancy = array();
foreach($genPack as $key => $val) {
if(!count(array_diff(array_keys($val), ['LXP', 'FOD']))) {
if(!count(array_diff(array_keys($val), array('LXP')))) {
continue;
}
$fancyName = isset($fancyLangNames[$key]) ? $fancyLangNames[$key] : $key;
if(isset($fancyLangNames[$key])) {
$fancyName = $fancyLangNames[$key];
} else {
$fancyName = $key;
}
$langList[] = $key;
$langListFancy[$key] = $fancyName;
}
return [
'langList' => $langList,
'langFancyNames' => $langListFancy,
'appxPresent' => uupAreAppxPresent($genPack),
];
}
function uupListLangs($updateId = 0, $returnInfo = true) {
if($returnInfo) {
$info = uupUpdateInfo($updateId, ignoreFiles: true);
$info = isset($info['info']) ? $info['info'] : false;
if(isset($info)) {
return array(
'apiVersion' => uupApiVersion(),
'langList' => $langList,
'langFancyNames' => $langListFancy,
'updateInfo' => $info
);
} else {
return array(
'apiVersion' => uupApiVersion(),
'langList' => $langList,
'langFancyNames' => $langListFancy
);
}
$langList = uupListLangsInternal($updateId);
$response = array_merge(
['apiVersion' => uupApiVersion()],
$langList
);
if($returnInfo) $response['updateInfo'] = $info;
return $response;
}

View File

@ -10,7 +10,7 @@ Parameters:
- **Supported values:** `amd64`, `x86`, `arm64`, `all`
- `ring` - Channel to use when fetching information (Previously called Ring)
- **Supported values:** `Canary`, `Dev`, `Beta`, `ReleasePreview`, `Retail`
- **Supported values:** `Dev`, `Beta`, `ReleasePreview`, `Retail`
- **Supported Ring values :** `WIF`, `WIS`, `RP`
- `flight` - Content type to use when fetching information (Previously called Flight)
@ -18,10 +18,10 @@ Parameters:
- **Supported Flight values:** `Active`, `Skip`, `Current`
- **NOTE:** `Skip` is for `WIF` ring only. `Current` is for `RP` ring only.
- `build` - Build number to use when fetching information. Can also be used to provide optional fetch flags in `major.minor+flag1,flag2` format.
- **Supported values:** Any correctly formatted build (`major` or `major.minor`) from range of 9841 and `PHP_INT_MAX-1`.
- `build` - Build number to use when fetching information
- **Supported values:** >= 9841 and <= PHP_INT_MAX-1
- `minor` - Build minor to use when fetching information. Unused when build is formatted in `major.minor` format
- `minor` - Build minor to use when fetching information
- **Supported values:** >= 0 and <= PHP_INT_MAX-1
- `sku` - SKU number to use when fetching information
@ -80,11 +80,9 @@ Outputs list of languages supported for specified Update ID.
Parameters:
- `updateId` - Update identifier (optional)
- **Supported values:** any update UUID
- `returnInfo` - Should the full update inforation be returned with a list of languages
- **Supported values:** `true` or `false`
#### updateinfo.php: `uupUpdateInfo($updateId, $onlyInfo, $ignoreFiles);`
#### updateinfo.php: `uupUpdateInfo($updateId, $onlyInfo);`
Outputs specified information of specified `updateId`.
Parameters:
@ -94,36 +92,12 @@ Parameters:
- `onlyInfo` - Key to output
- **Supported values:** any string
- `ignoreFiles` - Skips the `files` key in the output
- **Supported values:** `true` or `false`
#### shared/main.php: `uupApiVersion();`
Returns version of the API.
Parameters:
- None
#### shared/utils.php: `uupApiCheckUpdateId($updateId);`
Checks if the provided update ID is correctly formatted.
Parameters:
- `updateId` - update ID to check
- **Supported values:** Any string
#### shared/utils.php: `uupApiIsServer($skuId);`
Checks if the provided SKU ID is a Windows Sever SKU.
Parameters:
- `skuId` - SKU ID to check
- **Supported values:** Any integer
#### shared/utils.php: `uupApiBuildMajor($build);`
Returns a build major of the build number.
Parameters:
- `build` - Build number (for example 22621.1) to split
- **Supported values:** Any correctly formatted build number
### Error codes thrown by API
**fetchupd.php**
- UNKNOWN_ARCH
@ -134,7 +108,6 @@ Parameters:
- ILLEGAL_MINOR
- NO_UPDATE_FOUND
- EMPTY_FILELIST
- WU_REQUEST_FAILED
**get.php**
- UNSUPPORTED_LANG
@ -145,7 +118,6 @@ Parameters:
- MISSING_FILES
- NO_FILES
- XML_PARSE_ERROR
- WU_REQUEST_FAILED
**listeditions.php**
- UNSUPPORTED_LANG

View File

@ -25,46 +25,19 @@ function uupDevice() {
return base64_encode(chunk_split($data, 1, "\0"));
}
function uupSaveCookieFromResponse($out) {
$outDecoded = html_entity_decode($out);
preg_match('/<NewCookie>.*?<\/NewCookie>|<GetCookieResult>.*?<\/GetCookieResult>/', $outDecoded, $cookieData);
if(empty($cookieData))
return false;
preg_match('/<Expiration>.*<\/Expiration>/', $cookieData[0], $expirationDate);
preg_match('/<EncryptedData>.*<\/EncryptedData>/', $cookieData[0], $encryptedData);
$expirationDate = preg_replace('/<Expiration>|<\/Expiration>/', '', $expirationDate[0]);
$encryptedData = preg_replace('/<EncryptedData>|<\/EncryptedData>/', '', $encryptedData[0]);
$cookieData = array(
'expirationDate' => $expirationDate,
'encryptedData' => $encryptedData,
);
$cookieStorage = new UupDumpCache('WuRequestCookie', false);
$cookieStorage->put($cookieData, false);
return $cookieData;
}
function uupInvalidateCookie() {
$cookieStorage = new UupDumpCache('WuRequestCookie', false);
$cookieInfo = $cookieStorage->delete();
}
function uupEncryptedData() {
$cookieStorage = new UupDumpCache('WuRequestCookie', false);
$cookieInfo = $cookieStorage->get();
$cookieInfo = @file_get_contents(dirname(__FILE__).'/cookie.json');
$cookieInfo = json_decode($cookieInfo, 1);
if(empty($cookieInfo)) {
$data = sendWuPostRequestHelper('client', 'composeGetCookieRequest', [], false);
if($data === false || $data['error'] != 200)
return false;
$postData = composeGetCookieRequest(uupDevice());
sendWuPostRequest('https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx', $postData);
$cookieInfo = uupSaveCookieFromResponse($data['out']);
$encData = uupEncryptedData();
} else {
$encData = $cookieInfo['encryptedData'];
}
return $cookieInfo['encryptedData'];
return $encData;
}
?>

View File

@ -1,76 +0,0 @@
<?php
/*
Copyright 2022 eraseyourknees
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
class UupDumpCache {
private $cacheFile;
private $newCacheVersion = 1;
public function __construct($resource, private $isCompressed = true) {
$res = $resource."+cache_v".$this->newCacheVersion;
$cacheHash = hash('sha256', strtolower($res));
$ext = $isCompressed ? '.json.gz' : '.json';
$this->cacheFile = 'cache/'.$cacheHash.$ext;
}
public function getFileName() {
return $this->cacheFile;
}
public function delete() {
@unlink($this->cacheFile);
}
public function get() {
$cacheFile = $this->cacheFile;
if(!file_exists($cacheFile)) {
return false;
}
$cache = @file_get_contents($cacheFile);
if($this->isCompressed) $cache = @gzdecode($cache);
$cache = json_decode($cache, 1);
$expires = $cache['expires'];
$isExpired = ($expires !== false) && (time() > $expires);
if(empty($cache['content']) || $isExpired) {
$this->delete();
return false;
}
return $cache['content'];
}
public function put($content, $validity) {
$cacheFile = $this->cacheFile;
$expires = $validity ? time() + $validity : false;
$cache = array(
'expires' => $expires,
'content' => $content,
);
if(!file_exists('cache')) mkdir('cache');
$cacheContent = json_encode($cache)."\n";
if($this->isCompressed) $cacheContent = @gzencode($cacheContent);
@file_put_contents($cacheFile, $cacheContent);
}
}

View File

@ -1,94 +0,0 @@
<?php
/*
Copyright 2022 UUP dump API authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
require_once dirname(__FILE__).'/utils.php';
function uupApiGetFileinfoDirs() {
$dirs = [];
$dirs['fileinfo'] = 'fileinfo';
$dirs['fileinfoMeta'] = $dirs['fileinfo'].'/metadata';
$dirs['fileinfoData'] = $dirs['fileinfo'].'/full';
foreach($dirs as $dir) {
if(!file_exists($dir)) mkdir($dir);
}
return $dirs;
}
function uupApiGetFileinfoName($updateId, $meta = false) {
$fileName = $updateId.'.json';
$dirs = uupApiGetFileinfoDirs();
$fileinfoMeta = $dirs['fileinfoMeta'].'/'.$fileName;
$fileinfoData = $dirs['fileinfoData'].'/'.$fileName;
return $meta ? $fileinfoMeta : $fileinfoData;
}
function uupApiFileInfoExists($updateId) {
return file_exists(uupApiGetFileinfoName($updateId));
}
function uupApiWriteFileinfoMeta($updateId, $info) {
if(isset($info['files']))
unset($info['files']);
$file = uupApiGetFileinfoName($updateId, true);
return uupApiWriteJson($file, $info);
}
function uupApiWriteFileinfo($updateId, $info) {
$file = uupApiGetFileinfoName($updateId);
if(uupApiWriteJson($file, $info) === false)
return false;
return uupApiWriteFileinfoMeta($updateId, $info);
}
function uupApiReadFileinfoMeta($updateId) {
$file = uupApiGetFileinfoName($updateId, true);
if(file_exists($file))
return uupApiReadJson($file);
$info = uupApiReadFileinfo($updateId, false);
if($info === false)
return false;
if(isset($info['files']))
unset($info['files']);
if(uupApiWriteFileinfoMeta($updateId, $info) === false)
return false;
return $info;
}
function uupApiReadFileinfo($updateId, $meta = false) {
if(!uupApiFileInfoExists($updateId))
return false;
if($meta === true)
return uupApiReadFileinfoMeta($updateId);
$file = uupApiGetFileinfoName($updateId);
$info = uupApiReadJson($file);
return $info;
}

View File

@ -16,7 +16,7 @@ limitations under the License.
*/
function uupApiVersion() {
return '1.47.4';
return '1.32.0';
}
require_once dirname(__FILE__).'/auths.php';

View File

@ -1,6 +1,6 @@
<?php
/*
Copyright 2022 UUP dump API authors
Copyright 2021 UUP dump API authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -19,7 +19,6 @@ require_once dirname(__FILE__).'/../listid.php';
function uupGetInfoTexts() {
$fancyLangNames = array(
'neutral' => 'Any Language',
'ar-sa' => 'Arabic (Saudi Arabia)',
'bg-bg' => 'Bulgarian',
'cs-cz' => 'Czech',
@ -62,9 +61,6 @@ function uupGetInfoTexts() {
);
$fancyEditionNames = array(
'APP' => 'Microsoft Store Inbox Apps',
'APP_MOMENT' => 'Microsoft Store Moment Apps',
'FOD' => 'Features on Demand (Capabilities)',
'CLOUD' => 'Windows S',
'CLOUDN' => 'Windows S N',
'CLOUDE' => 'Windows Lean',
@ -83,7 +79,6 @@ function uupGetInfoTexts() {
'PPIPRO' => 'Windows Team',
'PROFESSIONAL' => 'Windows Pro',
'PROFESSIONALN' => 'Windows Pro N',
'PROFESSIONALCOUNTRYSPECIFIC' => 'Windows Pro China Only',
'SERVERSTANDARD' => 'Windows Server Standard',
'SERVERSTANDARDCORE' => 'Windows Server Standard, Core',
'SERVERDATACENTER' => 'Windows Server Datacenter',
@ -203,17 +198,166 @@ function uupGetInfoTexts() {
);
}
function uupApiGetPacks($updateId) {
if(empty($updateId)) return [];
if(!file_exists('packs/'.$updateId.'.json.gz')) return [];
function uupGetGenPacks($build = 15063, $arch = null, $updateId = null) {
$internalPacks = dirname(__FILE__).'/packs';
$genPack = @gzdecode(@file_get_contents('packs/'.$updateId.'.json.gz'));
if(empty($genPack)) return [];
if(!file_exists($internalPacks.'/metadata.json')) {
if(!uupCreateInternalPacksMetadata($internalPacks)) {
return array();
}
}
if(!empty($updateId)) {
if(file_exists('packs/'.$updateId.'.json.gz')) {
$genPack = @gzdecode(@file_get_contents('packs/'.$updateId.'.json.gz'));
if(empty($genPack)) return array();
$genPack = json_decode($genPack, 1);
return $genPack;
}
}
$metadata = @file_get_contents($internalPacks.'/metadata.json');
if(empty($metadata)) {
return array();
} else {
$metadata = json_decode($metadata, 1);
}
$hashDetermined = 0;
$useAllHashesForBuild = 0;
if($updateId) {
if(isset($metadata['knownIds'][$updateId])) {
$hash = $metadata['knownIds'][$updateId];
$hashDetermined = 1;
}
}
if(!$hashDetermined) {
foreach($metadata['knownBuilds'] as $buildNum => $val) {
if($build < $buildNum) continue;
$useBuild = $buildNum;
break;
}
if(!isset($useBuild)) {
return array();
}
if(!$arch && !isset($metadata['knownBuilds'][$useBuild][$arch])) {
$genPack = array();
foreach($metadata['knownBuilds'][$useBuild] as $hash) {
$temp = @gzdecode(@file_get_contents($internalPacks.'/'.$hash.'.json.gz'));
if(!empty($temp)) {
$temp = json_decode($temp, 1);
$genPack = array_merge_recursive($genPack, $temp);
unset($temp);
}
}
} elseif(!isset($metadata['knownBuilds'][$useBuild][$arch])) {
return array();
} else {
$hash = $metadata['knownBuilds'][$useBuild][$arch];
}
}
if(!isset($genPack)) {
$genPack = @gzdecode(@file_get_contents($internalPacks.'/'.$hash.'.json.gz'));
if(!empty($genPack)) {
$genPack = json_decode($genPack, 1);
} else {
$genPack = array();
}
}
$genPack = json_decode($genPack, 1);
return $genPack;
}
function uupGetGenPacks($build = 15063, $arch = null, $updateId = null) {
return uupApiGetPacks($updateId);
//Function to regenerate internal packs. Should not be used when not needed.
function uupCreateInternalPacksMetadata($internalPacks) {
$metadataCreationAllowed = 0;
if(!$metadataCreationAllowed) return false;
$builds = uupListIds();
if(isset($ids['error'])) {
return false;
}
$builds = $builds['builds'];
if(!file_exists('packs')) return false;
if(!file_exists($internalPacks)) {
if(!mkdir($internalPacks)) {
return false;
}
} else {
rmdir($internalPacks);
mkdir($internalPacks);
}
$files = scandir('packs');
$files = preg_grep('/\.json.gz$/', $files);
$packs = array();
foreach($builds as $build) {
$uuid = $build['uuid'];
$file = $uuid.'.json.gz';
if(!file_exists('packs/'.$file)) continue;
$genPack = @gzdecode(@file_get_contents('packs/'.$file));
$hash = hash('sha1', $genPack);
if(!file_exists($internalPacks.'/'.$hash.'.json.gz')) {
if(!copy('packs/'.$file, $internalPacks.'/'.$hash.'.json.gz')) {
return false;
}
}
$packs['knownIds'][$uuid] = $hash;
$buildNum = explode('.', $build['build']);
$buildNum = $buildNum[0];
$packs['knownBuilds'][$buildNum][$build['arch']] = $hash;
}
file_put_contents($internalPacks.'/metadata.json', json_encode($packs)."\n");
return true;
}
//Emulation of legacy packs. Do not use in new scripts due to extremely slow process.
function uupGetPacks($build = 15063) {
$returnArray = uupGetInfoTexts();
$genPack = uupGetGenPacks($build);
foreach($genPack as $lang => $editions) {
$packsForLangs[$lang] = array_keys($editions);
$packsForLangs[$lang][] = $lang;
foreach(array_keys($editions) as $edition) {
foreach($editions[$edition] as $name) {
$newName = preg_replace('/^cabs_|^metadataesd_|~31bf3856ad364e35/i', '', $name);
$newName = preg_replace('/~~\.|~\./', '.', $newName);
$newName = preg_replace('/~/', '-', $newName);
$newName = strtolower($newName);
$packs[$lang][$edition][] = $newName;
}
$editionPacks[$edition] = $edition;
$packs[$edition][$edition] = array();
$skipNeutral[$edition] = 1;
$skipLangPack[$edition] = 1;
}
}
$returnArray['packs'] = $packs;
$returnArray['packsForLangs'] = $packsForLangs;
$returnArray['editionPacks'] = $editionPacks;
$returnArray['skipNeutral'] = $skipNeutral;
$returnArray['skipLangPack'] = $skipLangPack;
return $returnArray;
}

Some files were not shown because too many files have changed in this diff Show More