Added Patch class

- added `Patch.getPatchInfo()` method to try to get info about specified
  patch version and source
- added `Patch.latest` field to get latest available patch info
This commit is contained in:
Observer KRypt0n_ 2021-12-22 17:17:54 +02:00
parent c25b367227
commit 601b7e0a23
No known key found for this signature in database
GPG key ID: DC5D4EC1303465DA
4 changed files with 127 additions and 14 deletions

View file

@ -18,6 +18,8 @@ const app = Vue.createApp({
mounted: () => {
Window.current.show();
Patch.latest.then(console.log);
/*fetch('https://sdk-os-static.mihoyo.com/hk4e_global/mdk/launcher/api/resource?key=gcStgarh&launcher_id=10', 1000)
.then((response) => {
console.log(response);

View file

@ -75,7 +75,8 @@ export default class Game
}
/**
* Get game versions list
* Get some latest game versions list in descending order
* e.g. ["2.3.0", "2.2.0", "2.1.0"]
*
* @returns rejects Error object if company's servers are unreachable or they responded with an error
*/

View file

@ -6,24 +6,139 @@ import type {
import md5 from 'js-md5';
import constants from './Constants';
import Game from './Game';
import fetch from './core/Fetch';
declare const Neutralino;
export default class Patch
{
/*public static get latest(): Promise<PatchInfo>
public static fetchTimeout: number = 3000;
/**
* Get information about latest available patch
*
* @returns rejects Error object if the patch's repositories are unreachable or they responded with an error
*/
public static get latest(): Promise<PatchInfo>
{
return new Promise((resolve) => {
return new Promise(async (resolve, reject) => {
const getLatestPatchInfo = (versions: string[], source: 'origin' | 'additional'): Promise<PatchInfo> => {
return new Promise(async (resolve) => {
const version = versions[0];
this.getPatchInfo(version, source)
.then(async (patchInfo) => {
// Patch with version e.g. [2.4.0] doesn't exist
// so we're looking for [2.3.0] instead
if (patchInfo === null)
resolve(await getLatestPatchInfo(versions.slice(1), 'origin'));
// Otherwise - return found info
else resolve(patchInfo);
})
.catch(async (error) => {
// If we couldn't connect to the origin repo
// then we can try to connect to the additional one
if (source === 'origin')
resolve(await getLatestPatchInfo(versions, 'additional'));
// Otherwise both of origin and additional repos
// are unreachable and we should notice about that
else reject(error);
});
});
};
resolve(await getLatestPatchInfo(await Game.versions, 'origin'));
});
}
/**
* Get information about the patch with specified version
*
* Be aware that `applied = true` field may mean that the game version
* is more modern that the one that this patch was made for because
* this field actually compares some files hashes
*
* @returns null if patch with given version doesn't exist in given source
* @returns rejects Error object if the source is unreachable or it responded with an error
*/
public static getPatchInfo(version: string, source: 'origin' | 'additional' = 'origin'): Promise<PatchInfo|null>
{
return new Promise(async (resolve) => {
return new Promise(async (resolve, reject) => {
const patchUri = constants.uri.patch[source];
const patchSh = await fetch(`${patchUri}/raw/master/${version.replaceAll('.', '')}/patch.sh`);
// @ts-expect-error
fetch(`${patchUri}/raw/master/${version.replaceAll('.', '')}/patch.sh`, this.fetchTimeout)
.then((patcherResponse) => {
// Return an error if patch's server is unavailable
if (patcherResponse.status === null)
reject(new Error(`${source} patch repository is unreachable`));
// If [version]/patch.sh file doesn't exist - it means
// that patch repo has no [version]
else if (patcherResponse.status === 404)
resolve(null);
// Otherwise it should be [preparation], [testing] or [stable]
else
{
// @ts-expect-error
fetch(`${patchUri}/raw/master/${version.replaceAll('.', '')}/patch_files/unityplayer_patch.vcdiff`, this.fetchTimeout)
.then((response) => {
// Return an error if patch's server is unavailable
if (response.status === null)
reject(new Error(`${source} patch repository is unreachable`));
// If [version]/patch_files/unityplayer_patch.vcdiff file doesn't exist
// then it's [preparation] state and Krock just moved patch.sh file to the [version] folder
else if (response.status === 404)
{
resolve({
version: version,
state: 'preparation',
applied: false
});
}
// Otherwise it's [testing] or [stable]
else
{
patcherResponse.body(this.fetchTimeout)
.then((response) => {
// Return an error if patch's server is unavailable
if (response === '')
reject(new Error(`${source} patch repository is unreachable`));
// Otherwise - let's prepare [testing] or [stable] output
else
{
// If this line is commented - then it's [stable] version
// Otherwise it's [testing]
const stableMark = '#echo "If you would like to test this patch, modify this script and remove the line below this one."';
let patchInfo: PatchInfo = {
version: version,
state: response.includes(stableMark) ? 'stable' : 'testing',
applied: false
};
const originalPlayer = /if \[ "\${sum}" != "([a-z0-9]{32})" \]; then/mg.exec(response);
// If we could get original UnityPlayer.dll hash - then we can
// compare it with actual UnityPlayer.dll hash and say whether the patch
// was applied or not
if (originalPlayer !== null)
patchInfo.applied = md5(`${constants.paths.gameDir}/UnityPlayer.dll`) != originalPlayer[1];
resolve(patchInfo);
}
});
}
});
}
});
});
}*/
}
}

View file

@ -11,14 +11,9 @@ type PatchInfo = {
state: PatchState;
/**
* If the main UnityPlayer patch applied
* If the patch was applied
*/
player: boolean;
/**
* If the anti-login crash patch applied
*/
xlua: boolean;
applied: boolean;
};
export type {