forked from uup-dump/api
Compare commits
1 Commits
master
...
sha256-san
Author | SHA1 | Date | |
---|---|---|---|
a2ec23d667 |
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
shared/cookie.json
|
218
fetchupd.php
218
fetchupd.php
@ -17,87 +17,8 @@ limitations under the License.
|
|||||||
|
|
||||||
require_once dirname(__FILE__).'/shared/main.php';
|
require_once dirname(__FILE__).'/shared/main.php';
|
||||||
require_once dirname(__FILE__).'/shared/requests.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';
|
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(
|
function uupFetchUpd(
|
||||||
$arch = 'amd64',
|
$arch = 'amd64',
|
||||||
$ring = 'WIF',
|
$ring = 'WIF',
|
||||||
@ -108,52 +29,35 @@ function uupFetchUpd(
|
|||||||
$type = 'Production',
|
$type = 'Production',
|
||||||
$cacheRequests = 0
|
$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();
|
uupApiPrintBrand();
|
||||||
|
|
||||||
$np = uupApiPrivateNormalizeFetchParams($params);
|
$arch = strtolower($arch);
|
||||||
|
$ring = strtoupper($ring);
|
||||||
$arch = $np['arch'];
|
$flight = ucwords(strtolower($flight));
|
||||||
$ring = $np['ring'];
|
|
||||||
$flight = 'Active';
|
$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)) {
|
$ids = uupListIds();
|
||||||
$build = uupApiPrivateGetLatestBuild();
|
if(isset($ids['error'])) {
|
||||||
|
$ids['builds'] = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$build = $ids['builds'][0]['build'];
|
||||||
|
unset($builds, $ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
$build = explode('.', $build);
|
$build = explode('.', $build);
|
||||||
if(isset($build[1])) $minor = intval($build[1]);
|
if(isset($build[1])) $minor = intval($build[1]);
|
||||||
$build = intval($build[0]);
|
$build = intval($build[0]);
|
||||||
|
$sku = intval($sku);
|
||||||
|
|
||||||
if(!($arch == 'amd64' || $arch == 'x86' || $arch == 'arm64' || $arch == 'arm' || $arch == 'all')) {
|
if(!($arch == 'amd64' || $arch == 'x86' || $arch == 'arm64' || $arch == 'arm' || $arch == 'all')) {
|
||||||
return array('error' => 'UNKNOWN_ARCH');
|
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');
|
return array('error' => 'UNKNOWN_RING');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,9 +77,6 @@ function uupFetchUpd2($params, $cacheRequests = 0) {
|
|||||||
return array('error' => 'ILLEGAL_MINOR');
|
return array('error' => 'ILLEGAL_MINOR');
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!in_array($branch, uupApiPrivateGetAcceptableBranches()))
|
|
||||||
$branch = 'auto';
|
|
||||||
|
|
||||||
if($ring == 'DEV') $ring = 'WIF';
|
if($ring == 'DEV') $ring = 'WIF';
|
||||||
if($ring == 'BETA') $ring = 'WIS';
|
if($ring == 'BETA') $ring = 'WIS';
|
||||||
if($ring == 'RELEASEPREVIEW') $ring = 'RP';
|
if($ring == 'RELEASEPREVIEW') $ring = 'RP';
|
||||||
@ -189,22 +90,45 @@ function uupFetchUpd2($params, $cacheRequests = 0) {
|
|||||||
$type = 'Production';
|
$type = 'Production';
|
||||||
}
|
}
|
||||||
|
|
||||||
$res = "api-fetch-$arch-$ring-$flight-$branch-$build-$flagsStr-$minor-$sku-$type";
|
$cacheHash = hash('sha256', strtolower("api-fetch-$arch-$ring-$flight-$build-$minor-$sku-$type"));
|
||||||
$cache = new UupDumpCache($res);
|
$cached = 0;
|
||||||
$fromCache = $cache->get();
|
|
||||||
if($fromCache !== false) return $fromCache;
|
|
||||||
|
|
||||||
consoleLogger('Fetching information from the server...');
|
if(file_exists('cache/'.$cacheHash.'.json.gz') && $cacheRequests == 1) {
|
||||||
$composerArgs = [$arch, $flight, $ring, $build, $sku, $type, $flags, $branch];
|
$cache = @gzdecode(@file_get_contents('cache/'.$cacheHash.'.json.gz'));
|
||||||
$out = sendWuPostRequestHelper('client', 'composeFetchUpdRequest', $composerArgs);
|
$cache = json_decode($cache, 1);
|
||||||
if($out === false || $out['error'] != 200) {
|
|
||||||
consoleLogger('The request has failed');
|
if(!empty($cache['content']) && ($cache['expires'] > time())) {
|
||||||
return array('error' => 'WU_REQUEST_FAILED');
|
consoleLogger('Using cached response...');
|
||||||
|
$out = $cache['content'];
|
||||||
|
$cached = 1;
|
||||||
|
} else {
|
||||||
|
$cached = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
$out = html_entity_decode($out['out']);
|
unset($cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
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.');
|
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);
|
preg_match_all('/<UpdateInfo>.*?<\/UpdateInfo>/', $out, $updateInfos);
|
||||||
$updateInfo = preg_grep('/<IsLeaf>true<\/IsLeaf>/', $updateInfos[0]);
|
$updateInfo = preg_grep('/<IsLeaf>true<\/IsLeaf>/', $updateInfos[0]);
|
||||||
sort($updateInfo);
|
sort($updateInfo);
|
||||||
@ -223,7 +147,7 @@ function uupFetchUpd2($params, $cacheRequests = 0) {
|
|||||||
$num++;
|
$num++;
|
||||||
consoleLogger("Checking build information for update {$num} of {$updatesNum}...");
|
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'])) {
|
if(isset($info['error'])) {
|
||||||
$errorCount++;
|
$errorCount++;
|
||||||
continue;
|
continue;
|
||||||
@ -236,7 +160,7 @@ function uupFetchUpd2($params, $cacheRequests = 0) {
|
|||||||
return array('error' => 'EMPTY_FILELIST');
|
return array('error' => 'EMPTY_FILELIST');
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = [
|
return array(
|
||||||
'apiVersion' => uupApiVersion(),
|
'apiVersion' => uupApiVersion(),
|
||||||
'updateId' => $updateArray[0]['updateId'],
|
'updateId' => $updateArray[0]['updateId'],
|
||||||
'updateTitle' => $updateArray[0]['updateTitle'],
|
'updateTitle' => $updateArray[0]['updateTitle'],
|
||||||
@ -244,16 +168,10 @@ function uupFetchUpd2($params, $cacheRequests = 0) {
|
|||||||
'arch' => $updateArray[0]['arch'],
|
'arch' => $updateArray[0]['arch'],
|
||||||
'fileWrite' => $updateArray[0]['fileWrite'],
|
'fileWrite' => $updateArray[0]['fileWrite'],
|
||||||
'updateArray' => $updateArray,
|
'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);
|
$updateNumId = preg_replace('/<UpdateInfo><ID>|<\/ID>.*/i', '', $updateInfo);
|
||||||
|
|
||||||
$updates = preg_replace('/<Update>/', "\n<Update>", $out);
|
$updates = preg_replace('/<Update>/', "\n<Update>", $out);
|
||||||
@ -295,15 +213,6 @@ function parseFetchUpdate($updateInfo, $out, $arch, $ring, $flight, $build, $sku
|
|||||||
$foundBuild = @$info[3];
|
$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);
|
$updateTitle = preg_grep('/<Title>.*<\/Title>/', $updateMeta);
|
||||||
sort($updateTitle);
|
sort($updateTitle);
|
||||||
|
|
||||||
@ -323,19 +232,13 @@ function parseFetchUpdate($updateInfo, $out, $arch, $ring, $flight, $build, $sku
|
|||||||
$isCumulativeUpdate = 0;
|
$isCumulativeUpdate = 0;
|
||||||
if(preg_match('/\d{4}-\d{2}.+Update|Cumulative Update|Microsoft Edge|Windows Feature Experience Pack|Cumulative security Hotpatch/i', $updateTitle)) {
|
if(preg_match('/\d{4}-\d{2}.+Update|Cumulative Update|Microsoft Edge|Windows Feature Experience Pack|Cumulative security Hotpatch/i', $updateTitle)) {
|
||||||
$isCumulativeUpdate = 1;
|
$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);
|
$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 10', 'Windows Server', $updateTitle);
|
||||||
$updateTitle = str_replace('Windows 11', 'Windows Server', $updateTitle);
|
|
||||||
}
|
|
||||||
|
|
||||||
if($sku == 406)
|
if($sku == 406)
|
||||||
$updateTitle = str_replace('Microsoft server operating system', 'Azure Stack HCI', $updateTitle);
|
$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');
|
return array('error' => 'BROKEN_UPDATE');
|
||||||
}
|
}
|
||||||
|
|
||||||
$isCorpnet = preg_match('/Corpnet Required/i', $updateTitle);
|
if(preg_match('/Corpnet Required/i', $updateTitle)) {
|
||||||
if($isCorpnet && !uupApiConfigIsTrue('allow_corpnet')) {
|
|
||||||
consoleLogger('Skipping corpnet only update...');
|
consoleLogger('Skipping corpnet only update...');
|
||||||
return array('error' => 'CORPNET_ONLY_UPDATE');
|
return array('error' => 'CORPNET_ONLY_UPDATE');
|
||||||
}
|
}
|
||||||
|
|
||||||
$fileWrite = 'NO_SAVE';
|
$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('WARNING: This build is NOT in the database. It will be saved now.');
|
||||||
consoleLogger('Parsing information to write...');
|
consoleLogger('Parsing information to write...');
|
||||||
|
if(!file_exists('fileinfo')) mkdir('fileinfo');
|
||||||
|
|
||||||
$fileList = preg_replace('/<Files>|<\/Files>/', '', $fileList[0]);
|
$fileList = preg_replace('/<Files>|<\/Files>/', '', $fileList[0]);
|
||||||
preg_match_all('/<File.*?<\/File>/', $fileList, $fileList);
|
preg_match_all('/<File.*?<\/File>/', $fileList, $fileList);
|
||||||
@ -444,9 +347,7 @@ function parseFetchUpdate($updateInfo, $out, $arch, $ring, $flight, $build, $sku
|
|||||||
$temp['title'] = $updateTitle;
|
$temp['title'] = $updateTitle;
|
||||||
$temp['ring'] = $ring;
|
$temp['ring'] = $ring;
|
||||||
$temp['flight'] = $flight;
|
$temp['flight'] = $flight;
|
||||||
$temp['branch'] = $branch;
|
|
||||||
$temp['arch'] = $foundArch;
|
$temp['arch'] = $foundArch;
|
||||||
$temp['fetchArch'] = $arch == 'all' ? 'amd64' : $arch;
|
|
||||||
$temp['build'] = $foundBuild;
|
$temp['build'] = $foundBuild;
|
||||||
$temp['checkBuild'] = $build;
|
$temp['checkBuild'] = $build;
|
||||||
$temp['sku'] = $sku;
|
$temp['sku'] = $sku;
|
||||||
@ -459,10 +360,6 @@ function parseFetchUpdate($updateInfo, $out, $arch, $ring, $flight, $build, $sku
|
|||||||
$temp['releasetype'] = $type;
|
$temp['releasetype'] = $type;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!empty($flags)) {
|
|
||||||
$temp['flags'] = $flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
$temp['created'] = time();
|
$temp['created'] = time();
|
||||||
$temp['sha256ready'] = true;
|
$temp['sha256ready'] = true;
|
||||||
$temp['files'] = $shaArray;
|
$temp['files'] = $shaArray;
|
||||||
@ -470,11 +367,10 @@ function parseFetchUpdate($updateInfo, $out, $arch, $ring, $flight, $build, $sku
|
|||||||
consoleLogger('Successfully parsed the information.');
|
consoleLogger('Successfully parsed the information.');
|
||||||
consoleLogger('Writing new build information to the disk...');
|
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) {
|
if($success) {
|
||||||
consoleLogger('Successfully written build information to the disk.');
|
consoleLogger('Successfully written build information to the disk.');
|
||||||
$fileWrite = 'INFO_WRITTEN';
|
$fileWrite = 'INFO_WRITTEN';
|
||||||
uupApiPrivateInvalidateFileinfoCache();
|
|
||||||
} else {
|
} else {
|
||||||
consoleLogger('An error has occured while writing the information to the disk.');
|
consoleLogger('An error has occured while writing the information to the disk.');
|
||||||
}
|
}
|
||||||
|
184
get.php
184
get.php
@ -18,8 +18,6 @@ limitations under the License.
|
|||||||
require_once dirname(__FILE__).'/shared/main.php';
|
require_once dirname(__FILE__).'/shared/main.php';
|
||||||
require_once dirname(__FILE__).'/shared/requests.php';
|
require_once dirname(__FILE__).'/shared/requests.php';
|
||||||
require_once dirname(__FILE__).'/shared/packs.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
|
$updateId = Update Identifier
|
||||||
@ -47,13 +45,7 @@ function uupGetFiles(
|
|||||||
return array('error' => 'INCORRECT_ID');
|
return array('error' => 'INCORRECT_ID');
|
||||||
}
|
}
|
||||||
|
|
||||||
$edition = is_array($desiredEdition) ? implode('_', $desiredEdition) : $desiredEdition;
|
$info = @file_get_contents('fileinfo/'.$updateId.'.json');
|
||||||
$res = "api-get-{$updateId}_{$usePack}_{$edition}_{$requestType}";
|
|
||||||
$cache = new UupDumpCache($res);
|
|
||||||
$fromCache = $cache->get();
|
|
||||||
if($fromCache !== false) return $fromCache;
|
|
||||||
|
|
||||||
$info = uupApiReadFileinfo($updateId);
|
|
||||||
if(empty($info)) {
|
if(empty($info)) {
|
||||||
$info = array(
|
$info = array(
|
||||||
'ring' => 'WIF',
|
'ring' => 'WIF',
|
||||||
@ -63,6 +55,8 @@ function uupGetFiles(
|
|||||||
'sku' => '48',
|
'sku' => '48',
|
||||||
'files' => array(),
|
'files' => array(),
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
$info = json_decode($info, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($info['build'])) {
|
if(isset($info['build'])) {
|
||||||
@ -76,10 +70,8 @@ function uupGetFiles(
|
|||||||
$info['sku'] = 48;
|
$info['sku'] = 48;
|
||||||
}
|
}
|
||||||
|
|
||||||
$genPack = [];
|
|
||||||
|
|
||||||
if($usePack) {
|
if($usePack) {
|
||||||
$genPack = uupApiGetPacks($updateId);
|
$genPack = uupGetGenPacks($build, $info['arch'], $updateId);
|
||||||
if(empty($genPack)) return array('error' => 'UNSUPPORTED_COMBINATION');
|
if(empty($genPack)) return array('error' => 'UNSUPPORTED_COMBINATION');
|
||||||
|
|
||||||
if(!isset($genPack[$usePack])) {
|
if(!isset($genPack[$usePack])) {
|
||||||
@ -87,8 +79,6 @@ function uupGetFiles(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$appEdition = 0;
|
|
||||||
|
|
||||||
if(!is_array($desiredEdition)) {
|
if(!is_array($desiredEdition)) {
|
||||||
$desiredEdition = strtoupper($desiredEdition);
|
$desiredEdition = strtoupper($desiredEdition);
|
||||||
$fileListSource = $desiredEdition;
|
$fileListSource = $desiredEdition;
|
||||||
@ -114,19 +104,13 @@ function uupGetFiles(
|
|||||||
|
|
||||||
case 'UPDATEONLY': break;
|
case 'UPDATEONLY': break;
|
||||||
|
|
||||||
case 'APP': $appEdition = 1;
|
|
||||||
case 'APP_MOMENT': $appEdition = 1;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if(!isset($genPack[$usePack][$desiredEdition])) {
|
if(!isset($genPack[$usePack][$desiredEdition])) {
|
||||||
return array('error' => 'UNSUPPORTED_COMBINATION');
|
return array('error' => 'UNSUPPORTED_COMBINATION');
|
||||||
}
|
}
|
||||||
|
|
||||||
$fileListSource = 'GENERATEDPACKS';
|
|
||||||
$filesPacksList = $genPack[$usePack][$desiredEdition];
|
$filesPacksList = $genPack[$usePack][$desiredEdition];
|
||||||
if($desiredEdition == 'APP' && isset($genPack[$usePack]['APP_MOMENT'])) {
|
$fileListSource = 'GENERATEDPACKS';
|
||||||
$filesPacksList = array_merge($filesPacksList, $genPack[$usePack]['APP_MOMENT']);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -139,7 +123,6 @@ function uupGetFiles(
|
|||||||
return array('error' => 'UNSUPPORTED_COMBINATION');
|
return array('error' => 'UNSUPPORTED_COMBINATION');
|
||||||
}
|
}
|
||||||
|
|
||||||
if($edition == 'APP' || $edition == 'APP_MOMENT') $appEdition = 1;
|
|
||||||
$filesPacksList = array_merge($filesPacksList, $genPack[$usePack][$edition]);
|
$filesPacksList = array_merge($filesPacksList, $genPack[$usePack][$edition]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -155,7 +138,6 @@ function uupGetFiles(
|
|||||||
$updateBuild = (isset($info['build'])) ? $info['build'] : 'UNKNOWN';
|
$updateBuild = (isset($info['build'])) ? $info['build'] : 'UNKNOWN';
|
||||||
$updateName = (isset($info['title'])) ? $info['title'] : 'Unknown update: '.$updateId;
|
$updateName = (isset($info['title'])) ? $info['title'] : 'Unknown update: '.$updateId;
|
||||||
$sha256capable = isset($info['sha256ready']);
|
$sha256capable = isset($info['sha256ready']);
|
||||||
$hasUpdates = false;
|
|
||||||
|
|
||||||
if(isset($info['releasetype'])) {
|
if(isset($info['releasetype'])) {
|
||||||
$type = $info['releasetype'];
|
$type = $info['releasetype'];
|
||||||
@ -182,34 +164,16 @@ function uupGetFiles(
|
|||||||
if(isset($filesInfoList[$val])) unset($filesInfoList[$val]);
|
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) {
|
foreach($baseless as $val) {
|
||||||
if(isset($filesInfoList[$val])) unset($filesInfoList[$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 = array_keys($filesInfoList);
|
||||||
$psf = preg_grep('/\.psf$/i', $psf);
|
$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);
|
$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) {
|
foreach($psfk as $key => $val) {
|
||||||
if(isset($psf[$key])) unset($psf[$key]);
|
if(isset($psf[$key])) unset($psf[$key]);
|
||||||
}
|
}
|
||||||
@ -237,46 +201,24 @@ function uupGetFiles(
|
|||||||
}
|
}
|
||||||
unset($removeFiles);
|
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);
|
$filesInfoKeys = array_keys($filesInfoList);
|
||||||
$updatesRegex = '/Windows(10|11)\.0-KB|SSU-.*?\....$/i';
|
|
||||||
|
|
||||||
switch($fileListSource) {
|
switch($fileListSource) {
|
||||||
case 'UPDATEONLY':
|
case 'UPDATEONLY':
|
||||||
$skipPackBuild = 1;
|
$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) {
|
foreach($removeFiles as $val) {
|
||||||
if(isset($filesInfoList[$val])) unset($filesInfoList[$val]);
|
if(isset($filesInfoList[$val])) unset($filesInfoList[$val]);
|
||||||
}
|
}
|
||||||
unset($removeFiles);
|
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);
|
$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) {
|
if(count($filesInfoKeys) == 0) {
|
||||||
return array('error' => 'NOT_CUMULATIVE_UPDATE');
|
return array('error' => 'NOT_CUMULATIVE_UPDATE');
|
||||||
}
|
}
|
||||||
|
|
||||||
if($build > 21380) $filesInfoKeys = array_merge($filesInfoKeys, $temp);
|
|
||||||
unset($temp);
|
|
||||||
$hasUpdates = true;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'WUBFILE':
|
case 'WUBFILE':
|
||||||
@ -290,24 +232,8 @@ function uupGetFiles(
|
|||||||
if($updateSku == 135) $uupCleanFunc = 'uupCleanHolo';
|
if($updateSku == 135) $uupCleanFunc = 'uupCleanHolo';
|
||||||
|
|
||||||
if($fileListSource == 'GENERATEDPACKS') {
|
if($fileListSource == 'GENERATEDPACKS') {
|
||||||
foreach($removeMSUs as $val) {
|
$temp = preg_grep('/Windows10\.0-KB.*-EXPRESS|Windows10\.0-KB.*-baseless|SSU-\d*?\.\d*?-.{3,5}-EXPRESS/i', $filesInfoKeys, PREG_GREP_INVERT);
|
||||||
if(isset($filesInfoList[$val.'.cab']) && isset($filesInfoList[$val.'.msu'])) {
|
$temp = preg_grep('/Windows10\.0-KB|SSU-\d*?\.\d*?-.*?\.cab/i', $temp);
|
||||||
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));
|
|
||||||
$filesPacksList = array_merge($filesPacksList, $temp);
|
$filesPacksList = array_merge($filesPacksList, $temp);
|
||||||
|
|
||||||
$newFiles = array();
|
$newFiles = array();
|
||||||
@ -359,7 +285,6 @@ function uupGetFiles(
|
|||||||
$filesNew = array();
|
$filesNew = array();
|
||||||
foreach($filesInfoKeys as $val) {
|
foreach($filesInfoKeys as $val) {
|
||||||
$filesNew[$val] = $filesInfoList[$val];
|
$filesNew[$val] = $filesInfoList[$val];
|
||||||
$filesNew[$val]['url'] = uupApiFixDownloadLink($filesInfoList[$val]['url']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$files = $filesNew;
|
$files = $filesNew;
|
||||||
@ -367,54 +292,48 @@ function uupGetFiles(
|
|||||||
|
|
||||||
consoleLogger('Successfully parsed the information.');
|
consoleLogger('Successfully parsed the information.');
|
||||||
|
|
||||||
$data = [
|
return array(
|
||||||
'apiVersion' => uupApiVersion(),
|
'apiVersion' => uupApiVersion(),
|
||||||
'updateName' => $updateName,
|
'updateName' => $updateName,
|
||||||
'arch' => $updateArch,
|
'arch' => $updateArch,
|
||||||
'build' => $updateBuild,
|
'build' => $updateBuild,
|
||||||
'sku' => $updateSku,
|
'sku' => $updateSku,
|
||||||
'hasUpdates' => $hasUpdates,
|
|
||||||
'appxPresent' => uupAreAppxPresent($genPack),
|
|
||||||
'files' => $files,
|
'files' => $files,
|
||||||
];
|
);
|
||||||
|
|
||||||
if($requestType > 0) {
|
|
||||||
$cacheData = $data;
|
|
||||||
$cache->put($cacheData, 30);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function uupGetOnlineFiles($updateId, $rev, $info, $cacheRequests, $type) {
|
function uupGetOnlineFiles($updateId, $rev, $info, $cacheRequests, $type) {
|
||||||
$res = "api-get-online-{$updateId}_rev.$rev";
|
$cacheHash = hash('sha256', strtolower("api-get-${updateId}_rev.$rev"));
|
||||||
$cache = new UupDumpCache($res);
|
$cached = 0;
|
||||||
$fromCache = $cache->get();
|
|
||||||
$cached = ($fromCache !== false);
|
|
||||||
|
|
||||||
if($cached) {
|
if(file_exists('cache/'.$cacheHash.'.json.gz') && $cacheRequests == 1) {
|
||||||
$out = $fromCache['out'];
|
$cache = @gzdecode(@file_get_contents('cache/'.$cacheHash.'.json.gz'));
|
||||||
$fetchTime = $fromCache['fetchTime'];
|
$cache = json_decode($cache, 1);
|
||||||
|
|
||||||
|
if(!empty($cache['content']) && ($cache['expires'] > time())) {
|
||||||
|
consoleLogger('Using cached response...');
|
||||||
|
$out = $cache['content'];
|
||||||
|
$fetchTime = $cache['fetchTime'];
|
||||||
|
$cached = 1;
|
||||||
} else {
|
} else {
|
||||||
$fetchTime = time();
|
$cached = 0;
|
||||||
consoleLogger('Fetching information from the server...');
|
|
||||||
|
|
||||||
$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');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$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('Information has been successfully fetched.');
|
||||||
}
|
}
|
||||||
|
|
||||||
consoleLogger('Parsing information...');
|
consoleLogger('Parsing information...');
|
||||||
$xmlOut = @simplexml_load_string($out);
|
$xmlOut = @simplexml_load_string($out);
|
||||||
if($xmlOut === false) {
|
if($xmlOut === false) {
|
||||||
$cache->delete();
|
@unlink('cache/'.$cacheHash.'.json.gz');
|
||||||
return array('error' => 'XML_PARSE_ERROR');
|
return array('error' => 'XML_PARSE_ERROR');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -462,11 +381,15 @@ function uupGetOnlineFiles($updateId, $rev, $info, $cacheRequests, $type) {
|
|||||||
if($sha256capable) {
|
if($sha256capable) {
|
||||||
$tempname = uupCleanSha256($name);
|
$tempname = uupCleanSha256($name);
|
||||||
if(isset($files[$tempname])) {
|
if(isset($files[$tempname])) {
|
||||||
|
if(preg_match('/\.cab$/i', $tempname)) {
|
||||||
if($size > $files[$tempname]['size']) {
|
if($size > $files[$tempname]['size']) {
|
||||||
$smaller = uupAppendSha1($tempname, $files[$tempname]['sha1']);
|
$express = 'baseless_'.$tempname;
|
||||||
$files[$smaller] = $files[$tempname];
|
$files[$express] = $files[$tempname];
|
||||||
unset($files[$tempname]);
|
unset($files[$tempname]);
|
||||||
$newName = $tempname;
|
$newName = $tempname;
|
||||||
|
} else {
|
||||||
|
$newName = 'baseless_'.$tempname;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$newName = uupAppendSha1($tempname, $sha1);
|
$newName = uupAppendSha1($tempname, $sha1);
|
||||||
}
|
}
|
||||||
@ -510,12 +433,14 @@ function uupGetOnlineFiles($updateId, $rev, $info, $cacheRequests, $type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if($cacheRequests == 1 && $cached == 0) {
|
if($cacheRequests == 1 && $cached == 0) {
|
||||||
$cacheData = [
|
$cache = array(
|
||||||
'out' => $out,
|
'expires' => time()+90,
|
||||||
|
'content' => $out,
|
||||||
'fetchTime' => $fetchTime,
|
'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;
|
return $files;
|
||||||
@ -537,14 +462,24 @@ function uupGetOfflineFiles($info) {
|
|||||||
$sha256 = isset($val['sha256']) ? $val['sha256'] : null;
|
$sha256 = isset($val['sha256']) ? $val['sha256'] : null;
|
||||||
|
|
||||||
if($sha256capable) {
|
if($sha256capable) {
|
||||||
|
// clean file name
|
||||||
$tempname = uupCleanSha256($name);
|
$tempname = uupCleanSha256($name);
|
||||||
if(isset($files[$tempname])) {
|
if(isset($files[$tempname])) {
|
||||||
|
// check existing file with the same name
|
||||||
|
if(preg_match('/\.cab$/i', $tempname)) {
|
||||||
|
// compare cab files only
|
||||||
if($size > $files[$tempname]['size']) {
|
if($size > $files[$tempname]['size']) {
|
||||||
$smaller = uupAppendSha1($tempname, $files[$tempname]['sha1']);
|
// if the existing file is smaller, rename it
|
||||||
$files[$smaller] = $files[$tempname];
|
$express = 'baseless_'.$tempname;
|
||||||
|
$files[$express] = $files[$tempname];
|
||||||
unset($files[$tempname]);
|
unset($files[$tempname]);
|
||||||
$newName = $tempname;
|
$newName = $tempname;
|
||||||
} else {
|
} 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);
|
$newName = uupAppendSha1($tempname, $sha1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -583,7 +518,8 @@ function uupAppendSha1($name, $sha1) {
|
|||||||
|
|
||||||
function uupCleanSha256($name) {
|
function uupCleanSha256($name) {
|
||||||
$replace = array(
|
$replace = array(
|
||||||
'prss_signed_appx_' => null,
|
'MetadataESD_' => null,
|
||||||
|
'metadataesd_' => null,
|
||||||
'~31bf3856ad364e35' => null,
|
'~31bf3856ad364e35' => null,
|
||||||
'~~.' => '.',
|
'~~.' => '.',
|
||||||
'~.' => '.',
|
'~.' => '.',
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
/*
|
||||||
Copyright 2023 UUP dump API authors
|
Copyright 2019 UUP dump API authors
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with 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/main.php';
|
||||||
require_once dirname(__FILE__).'/shared/packs.php';
|
require_once dirname(__FILE__).'/shared/packs.php';
|
||||||
|
require_once dirname(__FILE__).'/updateinfo.php';
|
||||||
|
|
||||||
function uupListEditions($lang = 'en-us', $updateId = 0) {
|
function uupListEditions($lang = 'en-us', $updateId = 0) {
|
||||||
|
if($updateId) {
|
||||||
|
$info = uupUpdateInfo($updateId);
|
||||||
|
}
|
||||||
|
|
||||||
if(!$lang) {
|
if(!$lang) {
|
||||||
return array('error' => 'UNSUPPORTED_LANG');
|
return array('error' => 'UNSUPPORTED_LANG');
|
||||||
}
|
}
|
||||||
|
|
||||||
$lang = strtolower($lang);
|
if(isset($info['info'])) $info = $info['info'];
|
||||||
$genPack = uupApiGetPacks($updateId);
|
|
||||||
$fancyEditionNames = uupGetInfoTexts()['fancyEditionNames'];
|
|
||||||
|
|
||||||
|
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();
|
||||||
|
$fancyEditionNames = $fancyTexts['fancyEditionNames'];
|
||||||
|
|
||||||
|
if($lang) {
|
||||||
|
$lang = strtolower($lang);
|
||||||
if(!isset($genPack[$lang])) {
|
if(!isset($genPack[$lang])) {
|
||||||
return array('error' => 'UNSUPPORTED_LANG');
|
return array('error' => 'UNSUPPORTED_LANG');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$editionList = [];
|
$editionList = array();
|
||||||
$editionListFancy = [];
|
$editionListFancy = array();
|
||||||
|
|
||||||
foreach(array_keys($genPack[$lang]) as $edition) {
|
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;
|
$editionList[] = $edition;
|
||||||
$editionListFancy[$edition] = $fancyName;
|
$editionListFancy[$edition] = $fancyName;
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return array(
|
||||||
'apiVersion' => uupApiVersion(),
|
'apiVersion' => uupApiVersion(),
|
||||||
'editionList' => $editionList,
|
'editionList' => $editionList,
|
||||||
'editionFancyNames' => $editionListFancy,
|
'editionFancyNames' => $editionListFancy,
|
||||||
];
|
);
|
||||||
}
|
}
|
||||||
|
59
listid.php
59
listid.php
@ -16,31 +16,22 @@ limitations under the License.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
require_once dirname(__FILE__).'/shared/main.php';
|
require_once dirname(__FILE__).'/shared/main.php';
|
||||||
require_once dirname(__FILE__).'/shared/cache.php';
|
|
||||||
require_once dirname(__FILE__).'/shared/fileinfo.php';
|
|
||||||
|
|
||||||
function uupApiPrivateInvalidateFileinfoCache() {
|
function uupListIds($search = null, $sortByDate = 0) {
|
||||||
$cache1 = new UupDumpCache('listid-0', false);
|
uupApiPrintBrand();
|
||||||
$cache2 = new UupDumpCache('listid-1', false);
|
|
||||||
|
|
||||||
$cache1->delete();
|
if(!file_exists('fileinfo')) return array('error' => 'NO_FILEINFO_DIR');
|
||||||
$cache2->delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
function uupApiPrivateGetFromFileinfo($sortByDate = 0) {
|
$files = scandir('fileinfo');
|
||||||
$dirs = uupApiGetFileinfoDirs();
|
|
||||||
$fileinfo = $dirs['fileinfoData'];
|
|
||||||
$fileinfoRoot = $dirs['fileinfo'];
|
|
||||||
|
|
||||||
$files = scandir($fileinfo);
|
|
||||||
$files = preg_grep('/\.json$/', $files);
|
$files = preg_grep('/\.json$/', $files);
|
||||||
|
|
||||||
consoleLogger('Parsing database info...');
|
consoleLogger('Parsing database info...');
|
||||||
|
|
||||||
$cacheFile = $fileinfoRoot.'/cache.json';
|
$cacheFile = 'cache/fileinfo_v2.json';
|
||||||
$cacheV2Version = 1;
|
$cacheV2Version = 1;
|
||||||
|
|
||||||
$database = uupApiReadJson($cacheFile);
|
$database = @file_get_contents($cacheFile);
|
||||||
|
$database = json_decode($database, true);
|
||||||
|
|
||||||
if(isset($database['version'])) {
|
if(isset($database['version'])) {
|
||||||
$version = $database['version'];
|
$version = $database['version'];
|
||||||
@ -59,13 +50,12 @@ function uupApiPrivateGetFromFileinfo($sortByDate = 0) {
|
|||||||
$newDb = array();
|
$newDb = array();
|
||||||
$builds = array();
|
$builds = array();
|
||||||
foreach($files as $file) {
|
foreach($files as $file) {
|
||||||
if($file == '.' || $file == '..')
|
if($file == '.' || $file == '..') continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
$uuid = preg_replace('/\.json$/', '', $file);
|
$uuid = preg_replace('/\.json$/', '', $file);
|
||||||
|
|
||||||
if(!isset($database[$uuid])) {
|
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';
|
$title = isset($info['title']) ? $info['title'] : 'UNKNOWN';
|
||||||
$build = isset($info['build']) ? $info['build'] : 'UNKNOWN';
|
$build = isset($info['build']) ? $info['build'] : 'UNKNOWN';
|
||||||
@ -115,7 +105,12 @@ function uupApiPrivateGetFromFileinfo($sortByDate = 0) {
|
|||||||
$builds[$tmp.$arch.$title.$uuid] = $temp;
|
$builds[$tmp.$arch.$title.$uuid] = $temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(empty($buildAssoc)) return [];
|
if(empty($buildAssoc)) {
|
||||||
|
return array(
|
||||||
|
'apiVersion' => uupApiVersion(),
|
||||||
|
'builds' => array(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
krsort($buildAssoc);
|
krsort($buildAssoc);
|
||||||
$buildsNew = array();
|
$buildsNew = array();
|
||||||
@ -146,27 +141,7 @@ function uupApiPrivateGetFromFileinfo($sortByDate = 0) {
|
|||||||
if(!$success) consoleLogger('Failed to update database cache.');
|
if(!$success) consoleLogger('Failed to update database cache.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $builds;
|
if($search) {
|
||||||
}
|
|
||||||
|
|
||||||
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(!preg_match('/^regex:/', $search)) {
|
if(!preg_match('/^regex:/', $search)) {
|
||||||
$searchSafe = preg_quote($search, '/');
|
$searchSafe = preg_quote($search, '/');
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
/*
|
||||||
Copyright 2023 UUP dump API authors
|
Copyright 2019 UUP dump API authors
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with 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__).'/shared/packs.php';
|
||||||
require_once dirname(__FILE__).'/updateinfo.php';
|
require_once dirname(__FILE__).'/updateinfo.php';
|
||||||
|
|
||||||
function uupListLangsInternal($updateId) {
|
function uupListLangs($updateId = 0) {
|
||||||
$genPack = uupApiGetPacks($updateId);
|
if($updateId) {
|
||||||
$fancyLangNames = uupGetInfoTexts()['fancyLangNames'];
|
$info = uupUpdateInfo($updateId);
|
||||||
|
}
|
||||||
|
|
||||||
$langList = [];
|
if(isset($info['info'])) {
|
||||||
$langListFancy = [];
|
$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) {
|
foreach($genPack as $key => $val) {
|
||||||
if(!count(array_diff(array_keys($val), ['LXP', 'FOD']))) {
|
if(!count(array_diff(array_keys($val), array('LXP')))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$fancyName = isset($fancyLangNames[$key]) ? $fancyLangNames[$key] : $key;
|
if(isset($fancyLangNames[$key])) {
|
||||||
|
$fancyName = $fancyLangNames[$key];
|
||||||
|
} else {
|
||||||
|
$fancyName = $key;
|
||||||
|
}
|
||||||
|
|
||||||
$langList[] = $key;
|
$langList[] = $key;
|
||||||
$langListFancy[$key] = $fancyName;
|
$langListFancy[$key] = $fancyName;
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
if(isset($info)) {
|
||||||
|
return array(
|
||||||
|
'apiVersion' => uupApiVersion(),
|
||||||
'langList' => $langList,
|
'langList' => $langList,
|
||||||
'langFancyNames' => $langListFancy,
|
'langFancyNames' => $langListFancy,
|
||||||
'appxPresent' => uupAreAppxPresent($genPack),
|
'updateInfo' => $info
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
function uupListLangs($updateId = 0, $returnInfo = true) {
|
|
||||||
if($returnInfo) {
|
|
||||||
$info = uupUpdateInfo($updateId, ignoreFiles: true);
|
|
||||||
$info = isset($info['info']) ? $info['info'] : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$langList = uupListLangsInternal($updateId);
|
|
||||||
|
|
||||||
$response = array_merge(
|
|
||||||
['apiVersion' => uupApiVersion()],
|
|
||||||
$langList
|
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
if($returnInfo) $response['updateInfo'] = $info;
|
return array(
|
||||||
|
'apiVersion' => uupApiVersion(),
|
||||||
return $response;
|
'langList' => $langList,
|
||||||
|
'langFancyNames' => $langListFancy
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
38
readme.md
38
readme.md
@ -10,7 +10,7 @@ Parameters:
|
|||||||
- **Supported values:** `amd64`, `x86`, `arm64`, `all`
|
- **Supported values:** `amd64`, `x86`, `arm64`, `all`
|
||||||
|
|
||||||
- `ring` - Channel to use when fetching information (Previously called Ring)
|
- `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`
|
- **Supported Ring values :** `WIF`, `WIS`, `RP`
|
||||||
|
|
||||||
- `flight` - Content type to use when fetching information (Previously called Flight)
|
- `flight` - Content type to use when fetching information (Previously called Flight)
|
||||||
@ -18,10 +18,10 @@ Parameters:
|
|||||||
- **Supported Flight values:** `Active`, `Skip`, `Current`
|
- **Supported Flight values:** `Active`, `Skip`, `Current`
|
||||||
- **NOTE:** `Skip` is for `WIF` ring only. `Current` is for `RP` ring only.
|
- **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.
|
- `build` - Build number to use when fetching information
|
||||||
- **Supported values:** Any correctly formatted build (`major` or `major.minor`) from range of 9841 and `PHP_INT_MAX-1`.
|
- **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
|
- **Supported values:** >= 0 and <= PHP_INT_MAX-1
|
||||||
|
|
||||||
- `sku` - SKU number to use when fetching information
|
- `sku` - SKU number to use when fetching information
|
||||||
@ -80,11 +80,9 @@ Outputs list of languages supported for specified Update ID.
|
|||||||
Parameters:
|
Parameters:
|
||||||
- `updateId` - Update identifier (optional)
|
- `updateId` - Update identifier (optional)
|
||||||
- **Supported values:** any update UUID
|
- **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`.
|
Outputs specified information of specified `updateId`.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
@ -94,36 +92,12 @@ Parameters:
|
|||||||
- `onlyInfo` - Key to output
|
- `onlyInfo` - Key to output
|
||||||
- **Supported values:** any string
|
- **Supported values:** any string
|
||||||
|
|
||||||
- `ignoreFiles` - Skips the `files` key in the output
|
|
||||||
- **Supported values:** `true` or `false`
|
|
||||||
|
|
||||||
#### shared/main.php: `uupApiVersion();`
|
#### shared/main.php: `uupApiVersion();`
|
||||||
Returns version of the API.
|
Returns version of the API.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
- None
|
- 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
|
### Error codes thrown by API
|
||||||
**fetchupd.php**
|
**fetchupd.php**
|
||||||
- UNKNOWN_ARCH
|
- UNKNOWN_ARCH
|
||||||
@ -134,7 +108,6 @@ Parameters:
|
|||||||
- ILLEGAL_MINOR
|
- ILLEGAL_MINOR
|
||||||
- NO_UPDATE_FOUND
|
- NO_UPDATE_FOUND
|
||||||
- EMPTY_FILELIST
|
- EMPTY_FILELIST
|
||||||
- WU_REQUEST_FAILED
|
|
||||||
|
|
||||||
**get.php**
|
**get.php**
|
||||||
- UNSUPPORTED_LANG
|
- UNSUPPORTED_LANG
|
||||||
@ -145,7 +118,6 @@ Parameters:
|
|||||||
- MISSING_FILES
|
- MISSING_FILES
|
||||||
- NO_FILES
|
- NO_FILES
|
||||||
- XML_PARSE_ERROR
|
- XML_PARSE_ERROR
|
||||||
- WU_REQUEST_FAILED
|
|
||||||
|
|
||||||
**listeditions.php**
|
**listeditions.php**
|
||||||
- UNSUPPORTED_LANG
|
- UNSUPPORTED_LANG
|
||||||
|
@ -25,46 +25,19 @@ function uupDevice() {
|
|||||||
return base64_encode(chunk_split($data, 1, "\0"));
|
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() {
|
function uupEncryptedData() {
|
||||||
$cookieStorage = new UupDumpCache('WuRequestCookie', false);
|
$cookieInfo = @file_get_contents(dirname(__FILE__).'/cookie.json');
|
||||||
$cookieInfo = $cookieStorage->get();
|
$cookieInfo = json_decode($cookieInfo, 1);
|
||||||
|
|
||||||
if(empty($cookieInfo)) {
|
if(empty($cookieInfo)) {
|
||||||
$data = sendWuPostRequestHelper('client', 'composeGetCookieRequest', [], false);
|
$postData = composeGetCookieRequest(uupDevice());
|
||||||
if($data === false || $data['error'] != 200)
|
sendWuPostRequest('https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx', $postData);
|
||||||
return false;
|
|
||||||
|
|
||||||
$cookieInfo = uupSaveCookieFromResponse($data['out']);
|
$encData = uupEncryptedData();
|
||||||
|
} else {
|
||||||
|
$encData = $cookieInfo['encryptedData'];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $cookieInfo['encryptedData'];
|
return $encData;
|
||||||
}
|
}
|
||||||
|
?>
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
function uupApiVersion() {
|
function uupApiVersion() {
|
||||||
return '1.47.4';
|
return '1.32.0';
|
||||||
}
|
}
|
||||||
|
|
||||||
require_once dirname(__FILE__).'/auths.php';
|
require_once dirname(__FILE__).'/auths.php';
|
||||||
|
168
shared/packs.php
168
shared/packs.php
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
/*
|
||||||
Copyright 2022 UUP dump API authors
|
Copyright 2021 UUP dump API authors
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with 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() {
|
function uupGetInfoTexts() {
|
||||||
$fancyLangNames = array(
|
$fancyLangNames = array(
|
||||||
'neutral' => 'Any Language',
|
|
||||||
'ar-sa' => 'Arabic (Saudi Arabia)',
|
'ar-sa' => 'Arabic (Saudi Arabia)',
|
||||||
'bg-bg' => 'Bulgarian',
|
'bg-bg' => 'Bulgarian',
|
||||||
'cs-cz' => 'Czech',
|
'cs-cz' => 'Czech',
|
||||||
@ -62,9 +61,6 @@ function uupGetInfoTexts() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
$fancyEditionNames = array(
|
$fancyEditionNames = array(
|
||||||
'APP' => 'Microsoft Store Inbox Apps',
|
|
||||||
'APP_MOMENT' => 'Microsoft Store Moment Apps',
|
|
||||||
'FOD' => 'Features on Demand (Capabilities)',
|
|
||||||
'CLOUD' => 'Windows S',
|
'CLOUD' => 'Windows S',
|
||||||
'CLOUDN' => 'Windows S N',
|
'CLOUDN' => 'Windows S N',
|
||||||
'CLOUDE' => 'Windows Lean',
|
'CLOUDE' => 'Windows Lean',
|
||||||
@ -83,7 +79,6 @@ function uupGetInfoTexts() {
|
|||||||
'PPIPRO' => 'Windows Team',
|
'PPIPRO' => 'Windows Team',
|
||||||
'PROFESSIONAL' => 'Windows Pro',
|
'PROFESSIONAL' => 'Windows Pro',
|
||||||
'PROFESSIONALN' => 'Windows Pro N',
|
'PROFESSIONALN' => 'Windows Pro N',
|
||||||
'PROFESSIONALCOUNTRYSPECIFIC' => 'Windows Pro China Only',
|
|
||||||
'SERVERSTANDARD' => 'Windows Server Standard',
|
'SERVERSTANDARD' => 'Windows Server Standard',
|
||||||
'SERVERSTANDARDCORE' => 'Windows Server Standard, Core',
|
'SERVERSTANDARDCORE' => 'Windows Server Standard, Core',
|
||||||
'SERVERDATACENTER' => 'Windows Server Datacenter',
|
'SERVERDATACENTER' => 'Windows Server Datacenter',
|
||||||
@ -203,17 +198,166 @@ function uupGetInfoTexts() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function uupApiGetPacks($updateId) {
|
function uupGetGenPacks($build = 15063, $arch = null, $updateId = null) {
|
||||||
if(empty($updateId)) return [];
|
$internalPacks = dirname(__FILE__).'/packs';
|
||||||
if(!file_exists('packs/'.$updateId.'.json.gz')) 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'));
|
$genPack = @gzdecode(@file_get_contents('packs/'.$updateId.'.json.gz'));
|
||||||
if(empty($genPack)) return [];
|
if(empty($genPack)) return array();
|
||||||
|
|
||||||
$genPack = json_decode($genPack, 1);
|
$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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $genPack;
|
return $genPack;
|
||||||
}
|
}
|
||||||
|
|
||||||
function uupGetGenPacks($build = 15063, $arch = null, $updateId = null) {
|
//Function to regenerate internal packs. Should not be used when not needed.
|
||||||
return uupApiGetPacks($updateId);
|
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;
|
||||||
}
|
}
|
||||||
|
BIN
shared/packs/01aa5ff6134e1c0227296a4930e4e6a5ffefcf79.json.gz
Normal file
BIN
shared/packs/01aa5ff6134e1c0227296a4930e4e6a5ffefcf79.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/01f6f08c13b51ce653628c50ca1be0dd34b2c763.json.gz
Normal file
BIN
shared/packs/01f6f08c13b51ce653628c50ca1be0dd34b2c763.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/0208081a42780c39f08f2601b3353920cbf30dc5.json.gz
Normal file
BIN
shared/packs/0208081a42780c39f08f2601b3353920cbf30dc5.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/0377581574aec8b9130b053cfd8dfdbfa997dd19.json.gz
Normal file
BIN
shared/packs/0377581574aec8b9130b053cfd8dfdbfa997dd19.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/038c28be7ad321b41623761c6bd695ed955667d2.json.gz
Normal file
BIN
shared/packs/038c28be7ad321b41623761c6bd695ed955667d2.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/03fa71d55c5e176eebef164c5e586ff5d355ec08.json.gz
Normal file
BIN
shared/packs/03fa71d55c5e176eebef164c5e586ff5d355ec08.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/045feaa1029a2e8f8cb26307bd1ae6937427b410.json.gz
Normal file
BIN
shared/packs/045feaa1029a2e8f8cb26307bd1ae6937427b410.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/0493cccaf960aed7043c158d407842d2f470195a.json.gz
Normal file
BIN
shared/packs/0493cccaf960aed7043c158d407842d2f470195a.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/059be6b8f19bccd352781c7f6ae4c8955337753b.json.gz
Normal file
BIN
shared/packs/059be6b8f19bccd352781c7f6ae4c8955337753b.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/06d08afbbaaa9f7c6615b75021a07e02fd5fa471.json.gz
Normal file
BIN
shared/packs/06d08afbbaaa9f7c6615b75021a07e02fd5fa471.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/0778039009ea692daaf8055696c77ac782cb6473.json.gz
Normal file
BIN
shared/packs/0778039009ea692daaf8055696c77ac782cb6473.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/07d1224076d0664a17c82c0c58cf510cb01766b5.json.gz
Normal file
BIN
shared/packs/07d1224076d0664a17c82c0c58cf510cb01766b5.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/07e64b8c2d61b0009882e8c7c1cb207fa583102c.json.gz
Normal file
BIN
shared/packs/07e64b8c2d61b0009882e8c7c1cb207fa583102c.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/07ea73a8992609a1fb06f541ae628ff296a73c82.json.gz
Normal file
BIN
shared/packs/07ea73a8992609a1fb06f541ae628ff296a73c82.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/085e122884a89daf3ae6e68860ca9ed02eb81acb.json.gz
Normal file
BIN
shared/packs/085e122884a89daf3ae6e68860ca9ed02eb81acb.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/08c1bdf1f74e89645235e2175dec2fa34c74379b.json.gz
Normal file
BIN
shared/packs/08c1bdf1f74e89645235e2175dec2fa34c74379b.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/0a4729feab2b0d449ecdc1eddfd10b85f4b4b4e4.json.gz
Normal file
BIN
shared/packs/0a4729feab2b0d449ecdc1eddfd10b85f4b4b4e4.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/0a6de460717d8ad9560defaa0f7755856fdb0380.json.gz
Normal file
BIN
shared/packs/0a6de460717d8ad9560defaa0f7755856fdb0380.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/0a9ee16fe5c26d7c4f6946305b284c780864a9fd.json.gz
Normal file
BIN
shared/packs/0a9ee16fe5c26d7c4f6946305b284c780864a9fd.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/0b13c3cb2d6d33e427af3e23cf0a950f0b54182c.json.gz
Normal file
BIN
shared/packs/0b13c3cb2d6d33e427af3e23cf0a950f0b54182c.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/0be28e7f73786ceefe01edeea555fb6b613c2133.json.gz
Normal file
BIN
shared/packs/0be28e7f73786ceefe01edeea555fb6b613c2133.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/0cb25a1edf29b6898b8ba214bc3090990b4e0f7f.json.gz
Normal file
BIN
shared/packs/0cb25a1edf29b6898b8ba214bc3090990b4e0f7f.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/0d00590097570276e3dd9755db1e3d9a80e7f49b.json.gz
Normal file
BIN
shared/packs/0d00590097570276e3dd9755db1e3d9a80e7f49b.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/0da899e3b907a7cc1c6d8a50aa526262fbbc4fb0.json.gz
Normal file
BIN
shared/packs/0da899e3b907a7cc1c6d8a50aa526262fbbc4fb0.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/0f46071c133d66face6c06ce5e833533566c3436.json.gz
Normal file
BIN
shared/packs/0f46071c133d66face6c06ce5e833533566c3436.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/0fdb20000af32d84a1f7b12fe056c54f0b8c6c77.json.gz
Normal file
BIN
shared/packs/0fdb20000af32d84a1f7b12fe056c54f0b8c6c77.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/1004746e37fcfd8fcc91b5d5f3e489e29af382e4.json.gz
Normal file
BIN
shared/packs/1004746e37fcfd8fcc91b5d5f3e489e29af382e4.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/110c98dda044f3b69ad0a30df1b5a1bede94901d.json.gz
Normal file
BIN
shared/packs/110c98dda044f3b69ad0a30df1b5a1bede94901d.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/115da76cb9527e16fb30152c349f3fb2652dae1e.json.gz
Normal file
BIN
shared/packs/115da76cb9527e16fb30152c349f3fb2652dae1e.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/1163d6ee8220e8b58d4dc30b5744ebace707a0dd.json.gz
Normal file
BIN
shared/packs/1163d6ee8220e8b58d4dc30b5744ebace707a0dd.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/130a78345067dc58156ffddc0616a3b6b934d139.json.gz
Normal file
BIN
shared/packs/130a78345067dc58156ffddc0616a3b6b934d139.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/13e602e31dc0f54c33410ca827510e4c04b173ce.json.gz
Normal file
BIN
shared/packs/13e602e31dc0f54c33410ca827510e4c04b173ce.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/14339b9651dc5bf690a3d713e33729f89ea117c9.json.gz
Normal file
BIN
shared/packs/14339b9651dc5bf690a3d713e33729f89ea117c9.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/1436f40615c1779758385f34f5d58615001b74f4.json.gz
Normal file
BIN
shared/packs/1436f40615c1779758385f34f5d58615001b74f4.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/1504efbff5b65730ed0b0ca91bfa431b314adbd1.json.gz
Normal file
BIN
shared/packs/1504efbff5b65730ed0b0ca91bfa431b314adbd1.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/160fff573d9d789983796b7695d2fa4c42c1f912.json.gz
Normal file
BIN
shared/packs/160fff573d9d789983796b7695d2fa4c42c1f912.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/163f57f1e53c33d0660b37348de67d6e35347567.json.gz
Normal file
BIN
shared/packs/163f57f1e53c33d0660b37348de67d6e35347567.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/169bcfee3dacfd77ee445172155d8ea9b04fdffd.json.gz
Normal file
BIN
shared/packs/169bcfee3dacfd77ee445172155d8ea9b04fdffd.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/16b7aca08fb425083620fc5247500371be064b87.json.gz
Normal file
BIN
shared/packs/16b7aca08fb425083620fc5247500371be064b87.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/16d6fe416895982d453c6aa0dbcf4029536a4189.json.gz
Normal file
BIN
shared/packs/16d6fe416895982d453c6aa0dbcf4029536a4189.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/188a5f8cd14909f8a9d5efef6af61564087b6932.json.gz
Normal file
BIN
shared/packs/188a5f8cd14909f8a9d5efef6af61564087b6932.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/1894fbf96c63b2d1bcc5a5509d0090fd943a8259.json.gz
Normal file
BIN
shared/packs/1894fbf96c63b2d1bcc5a5509d0090fd943a8259.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/18c294d075c67272097d4b9f6d7646b38c828a39.json.gz
Normal file
BIN
shared/packs/18c294d075c67272097d4b9f6d7646b38c828a39.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/1a52d5dd30a90208c10f13b646bfad88b2c4c87f.json.gz
Normal file
BIN
shared/packs/1a52d5dd30a90208c10f13b646bfad88b2c4c87f.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/1ab121756291435c1240ff73026ca09cb01d8fee.json.gz
Normal file
BIN
shared/packs/1ab121756291435c1240ff73026ca09cb01d8fee.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/1af61b62116fcba3309251501b56857a7f6e90ba.json.gz
Normal file
BIN
shared/packs/1af61b62116fcba3309251501b56857a7f6e90ba.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/1b78d65d213bc926c0dd0925b6c9d1ade6dc11ff.json.gz
Normal file
BIN
shared/packs/1b78d65d213bc926c0dd0925b6c9d1ade6dc11ff.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/1be1f76a28002e22c593a6632065da60ad0ff9be.json.gz
Normal file
BIN
shared/packs/1be1f76a28002e22c593a6632065da60ad0ff9be.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/1bf3fe050212893942dff7726962173da41d75dc.json.gz
Normal file
BIN
shared/packs/1bf3fe050212893942dff7726962173da41d75dc.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/1c0da2879bbc83b6701e069c66f0a745fb7c2870.json.gz
Normal file
BIN
shared/packs/1c0da2879bbc83b6701e069c66f0a745fb7c2870.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/1c5d4a56716eee39c652445f6d6a92995cea8031.json.gz
Normal file
BIN
shared/packs/1c5d4a56716eee39c652445f6d6a92995cea8031.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/1c8cfc71d7554c6743c38440ad3e5867e862f92d.json.gz
Normal file
BIN
shared/packs/1c8cfc71d7554c6743c38440ad3e5867e862f92d.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/1ceaa725fad2d752bc6c6bb26423a29c97eaf0b4.json.gz
Normal file
BIN
shared/packs/1ceaa725fad2d752bc6c6bb26423a29c97eaf0b4.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/1e777b7b7b5eed3f3facbee1ad592e269dcbeb0f.json.gz
Normal file
BIN
shared/packs/1e777b7b7b5eed3f3facbee1ad592e269dcbeb0f.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/1e8bc5333c92aa95421036b17b198679d2c88cf8.json.gz
Normal file
BIN
shared/packs/1e8bc5333c92aa95421036b17b198679d2c88cf8.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/1e9cbc2bc1b80304838def973aa8246013bad742.json.gz
Normal file
BIN
shared/packs/1e9cbc2bc1b80304838def973aa8246013bad742.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/1f3d6eb702c2bda91f7e8e5247ffcce6c8bdee17.json.gz
Normal file
BIN
shared/packs/1f3d6eb702c2bda91f7e8e5247ffcce6c8bdee17.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/20636b9f7802215ae681e3f37d8f9b2a557012ca.json.gz
Normal file
BIN
shared/packs/20636b9f7802215ae681e3f37d8f9b2a557012ca.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/21063b327036c66da110c3dd05eb39dfd0139d6f.json.gz
Normal file
BIN
shared/packs/21063b327036c66da110c3dd05eb39dfd0139d6f.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/21354f2d52ef04754785ebbc2f58734928d39355.json.gz
Normal file
BIN
shared/packs/21354f2d52ef04754785ebbc2f58734928d39355.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/219373bbdd267c636bc09ae8661b04c3683b31c2.json.gz
Normal file
BIN
shared/packs/219373bbdd267c636bc09ae8661b04c3683b31c2.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/21f71d842489390c56547c3ba0bf282ec285b392.json.gz
Normal file
BIN
shared/packs/21f71d842489390c56547c3ba0bf282ec285b392.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/22c7a1aca5e636221131e8ffbd95539d1be9076c.json.gz
Normal file
BIN
shared/packs/22c7a1aca5e636221131e8ffbd95539d1be9076c.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/22e6e86b3602f06c20cd21256406eadcd8a8824a.json.gz
Normal file
BIN
shared/packs/22e6e86b3602f06c20cd21256406eadcd8a8824a.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/23fb6d223a9d0712b19d80f5f814587863fdc9ca.json.gz
Normal file
BIN
shared/packs/23fb6d223a9d0712b19d80f5f814587863fdc9ca.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/24a4b24b02314197a651d7e0b6522a0bb7245b41.json.gz
Normal file
BIN
shared/packs/24a4b24b02314197a651d7e0b6522a0bb7245b41.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/24df4f734aa360eceab6ecb725b00a6a76abc8d6.json.gz
Normal file
BIN
shared/packs/24df4f734aa360eceab6ecb725b00a6a76abc8d6.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/25404f74e050aacf3b69116abe4590535e179eb9.json.gz
Normal file
BIN
shared/packs/25404f74e050aacf3b69116abe4590535e179eb9.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/255c210f4e5eb09ab8e92a634ebdbb3a8037e4f6.json.gz
Normal file
BIN
shared/packs/255c210f4e5eb09ab8e92a634ebdbb3a8037e4f6.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/2606035ed49bb6958a64b0c2f126cc5c2bd2f419.json.gz
Normal file
BIN
shared/packs/2606035ed49bb6958a64b0c2f126cc5c2bd2f419.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/27438affdb50231e6e0927c867cc018e5480dc9d.json.gz
Normal file
BIN
shared/packs/27438affdb50231e6e0927c867cc018e5480dc9d.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/274ffe8379f7682b3146428a12e7981c296b2b26.json.gz
Normal file
BIN
shared/packs/274ffe8379f7682b3146428a12e7981c296b2b26.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/281b00c4172534b9ce227206cdbfb582e91de781.json.gz
Normal file
BIN
shared/packs/281b00c4172534b9ce227206cdbfb582e91de781.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/2861eb9f3c650b613c63d3adb8716377cc67bd01.json.gz
Normal file
BIN
shared/packs/2861eb9f3c650b613c63d3adb8716377cc67bd01.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/28f5a319bd46f4e3d8c6b7a17249b71314124f8c.json.gz
Normal file
BIN
shared/packs/28f5a319bd46f4e3d8c6b7a17249b71314124f8c.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/298c448a2317673636162e124e7ff509756491f3.json.gz
Normal file
BIN
shared/packs/298c448a2317673636162e124e7ff509756491f3.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/299e358dbe33f3b9bb584c5876513dfdbe7b196e.json.gz
Normal file
BIN
shared/packs/299e358dbe33f3b9bb584c5876513dfdbe7b196e.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/2b128cbc6728738c1eb0f9a205a0a70badeabf07.json.gz
Normal file
BIN
shared/packs/2b128cbc6728738c1eb0f9a205a0a70badeabf07.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/2b5e0d2c0369da9d749023ee264383737fd8a9b7.json.gz
Normal file
BIN
shared/packs/2b5e0d2c0369da9d749023ee264383737fd8a9b7.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/2c7da70eb338967cec932a604ea01cde6ce715ad.json.gz
Normal file
BIN
shared/packs/2c7da70eb338967cec932a604ea01cde6ce715ad.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/2dd0a3673dda8695f351f82446aa9899a2e6ab8e.json.gz
Normal file
BIN
shared/packs/2dd0a3673dda8695f351f82446aa9899a2e6ab8e.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/2e26ad5e1af137e7e220e405856b3c87a3b1da7b.json.gz
Normal file
BIN
shared/packs/2e26ad5e1af137e7e220e405856b3c87a3b1da7b.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/2e3a9f9b68725db19eea00d2c2359158f00faa7d.json.gz
Normal file
BIN
shared/packs/2e3a9f9b68725db19eea00d2c2359158f00faa7d.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/2f430bb88ceef3f116fc25dd0100a1942318b16c.json.gz
Normal file
BIN
shared/packs/2f430bb88ceef3f116fc25dd0100a1942318b16c.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/3013879423c0d29a3eb7382fec86a4799fd80089.json.gz
Normal file
BIN
shared/packs/3013879423c0d29a3eb7382fec86a4799fd80089.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/32040bfb2773874a2712ed9b6e6006b8f486cf6d.json.gz
Normal file
BIN
shared/packs/32040bfb2773874a2712ed9b6e6006b8f486cf6d.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/3375f301dca9f3ad6be43e5096e6ecbd84104fef.json.gz
Normal file
BIN
shared/packs/3375f301dca9f3ad6be43e5096e6ecbd84104fef.json.gz
Normal file
Binary file not shown.
BIN
shared/packs/35097891a957dd54d308dd0abfea9acb8eef99f7.json.gz
Normal file
BIN
shared/packs/35097891a957dd54d308dd0abfea9acb8eef99f7.json.gz
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user