From 6eefee6543f0a3ba5c7a70b41830b750ecc7b129 Mon Sep 17 00:00:00 2001 From: daydreamer-json Date: Wed, 28 Jan 2026 12:56:25 +0900 Subject: [PATCH] Add epic game package archive --- README.md | 8 +- config/config.yaml | 4 + output/akEndfield/launcher/game/6/list.md | 2 +- .../akEndfield/launcher/game/6/list_patch.md | 2 +- output/akEndfield/launcher/game/801/all.json | 212 ++++++++ .../launcher/game/801/all_patch.json | 1 + .../akEndfield/launcher/game/801/latest.json | 209 ++++++++ output/akEndfield/launcher/game/801/list.md | 49 ++ .../launcher/game/801/list_patch.md | 1 + .../akEndfield/launcher/game/801/v1.0.14.json | 209 ++++++++ src/cmds/test.ts | 456 +++++++++-------- src/utils/api.ts | 464 +----------------- src/utils/api/accountService.ts | 67 +++ src/utils/api/binding.ts | 34 ++ src/utils/api/defaultSettings.ts | 27 + src/utils/api/launcher.ts | 79 +++ src/utils/api/launcherWeb.ts | 152 ++++++ src/utils/api/u8.ts | 82 ++++ src/utils/api/webview.ts | 40 ++ src/utils/config.ts | 6 +- 20 files changed, 1442 insertions(+), 662 deletions(-) create mode 100644 output/akEndfield/launcher/game/801/all.json create mode 100644 output/akEndfield/launcher/game/801/all_patch.json create mode 100644 output/akEndfield/launcher/game/801/latest.json create mode 100644 output/akEndfield/launcher/game/801/list.md create mode 100644 output/akEndfield/launcher/game/801/list_patch.md create mode 100644 output/akEndfield/launcher/game/801/v1.0.14.json create mode 100644 src/utils/api/accountService.ts create mode 100644 src/utils/api/binding.ts create mode 100644 src/utils/api/defaultSettings.ts create mode 100644 src/utils/api/launcher.ts create mode 100644 src/utils/api/launcherWeb.ts create mode 100644 src/utils/api/u8.ts create mode 100644 src/utils/api/webview.ts diff --git a/README.md b/README.md index bf91430..bfd3d88 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,12 @@ The APIs currently being monitored are as follows: To easily view information about past versions of game packages and other items, please refer to the following page. -- [**Game packages**](/output/akEndfield/launcher/game/6/list.md) (Windows) -- [**Game patch packages**](/output/akEndfield/launcher/game/6/list_patch.md) (Windows) +- **Game packages** + - [Windows Official](/output/akEndfield/launcher/game/6/list.md) + - [Windows Epic](/output/akEndfield/launcher/game/801/list.md) +- **Game patch packages** + - [Windows Official](/output/akEndfield/launcher/game/6/list_patch.md) + - [Windows Epic](/output/akEndfield/launcher/game/801/list_patch.md.md) - [**Game resources**](/output/akEndfield/launcher/game_resources/6/list.md) (Windows, Android, iOS, PlayStation) ## Contributing diff --git a/config/config.yaml b/config/config.yaml index f16ba87..f9a2ae4 100644 --- a/config/config.yaml +++ b/config/config.yaml @@ -6,6 +6,7 @@ network: osWinRel: YDUTE5gscDZ229CW launcher: osWinRel: TiaytKBUIEdoEwRT + osWinRelEpic: BBWoqCzuZ2bZ1Dro accountService: osWinRel: d9f6dbb6bbd6bb33 skport: 6eb76d4e13aa36e6 @@ -15,6 +16,9 @@ network: osWinRel: YDUTE5gscDZ229CW channel: osWinRel: 6 + subChannel: + osWinRel: 6 + osWinRelEpic: 801 base: accountService: YXMuZ3J5cGhsaW5lLmNvbQ== launcher: bGF1bmNoZXIuZ3J5cGhsaW5lLmNvbS9hcGk= diff --git a/output/akEndfield/launcher/game/6/list.md b/output/akEndfield/launcher/game/6/list.md index 7b3dfd6..20be9c1 100644 --- a/output/akEndfield/launcher/game/6/list.md +++ b/output/akEndfield/launcher/game/6/list.md @@ -1,4 +1,4 @@ -# Game Packages +# Game Packages (Official) - [1.0.13 (2026/01/22 16:31:25)](#ver-1.0.13-1769070686) - [1.0.14 (2026/01/25 18:30:20)](#ver-1.0.14-1769337021) diff --git a/output/akEndfield/launcher/game/6/list_patch.md b/output/akEndfield/launcher/game/6/list_patch.md index 7eb7138..fb9d18c 100644 --- a/output/akEndfield/launcher/game/6/list_patch.md +++ b/output/akEndfield/launcher/game/6/list_patch.md @@ -1,4 +1,4 @@ -# Game Patch Packages +# Game Patch Packages (Official) - [1.0.13 → 1.0.14 (2026/01/26 01:33:36)](#ver-1.0.13-1.0.14-1769362417) diff --git a/output/akEndfield/launcher/game/801/all.json b/output/akEndfield/launcher/game/801/all.json new file mode 100644 index 0000000..5bbe631 --- /dev/null +++ b/output/akEndfield/launcher/game/801/all.json @@ -0,0 +1,212 @@ +[ + { + "updatedAt": "2026-01-28T12:50:37.254+09:00", + "req": { + "appCode": "YDUTE5gscDZ229CW", + "launcherAppCode": "BBWoqCzuZ2bZ1Dro", + "channel": 6, + "subChannel": 801, + "launcherSubChannel": 801 + }, + "rsp": { + "action": 1, + "version": "1.0.14", + "request_version": "", + "pkg": { + "packs": [ + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.001", + "md5": "6f24f6b31eec12cfb6ce243d2bd8d743", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.002", + "md5": "8ceee32676963a697f0e8daa6acc2f6e", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.003", + "md5": "17d0f31bdf6a1be25e30da9995176877", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.004", + "md5": "fc6fb86ccab29f745c0aec22c611d751", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.005", + "md5": "abf77711160c031c74c9728dc0386338", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.006", + "md5": "075b3e86c03965aab435b7c72bb58511", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.007", + "md5": "a6b90ccd5eb148b07ffd608494182da9", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.008", + "md5": "5cd8023b0e4cb18b7aa35d10c65dc202", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.009", + "md5": "b11d86cfdb5dc9015a4b532b2ebf5d22", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.010", + "md5": "687e457fd9636feb9ea08f5e7c7a3283", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.011", + "md5": "a6889c0be1318ade55404bcdb213b33c", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.012", + "md5": "568e1fa0bdde5d3f3b6430df7322d546", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.013", + "md5": "a81ca3c9d29a56ad9456e1ec4abe1c5f", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.014", + "md5": "ac7b33dfb9d0de719d179d394e2bee35", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.015", + "md5": "3bb928beea143f3907c8f7ce73e52826", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.016", + "md5": "49e0c09001b1fb49ae63a9b44d372925", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.017", + "md5": "65bfc97ceaa9b6d080f968042a905ec6", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.018", + "md5": "974d7944f0e2ef76ce8f9ca7fbcb28e7", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.019", + "md5": "2c156a6a8336276ed8b5b02a6dbb5959", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.020", + "md5": "69fe77f015206da76ba38aa7abdbb28c", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.021", + "md5": "20d5dd8dbae5d51e773ed69ee045c92a", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.022", + "md5": "58ca42ab9632728a8461e0ecdb4b8165", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.023", + "md5": "2c8291bd497fe908f5b8aa5549bf4304", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.024", + "md5": "6f9cbf57b8f8a2dc7637f1872b87416a", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.025", + "md5": "2f5cb6fd50a2716a05099961f52a48e5", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.026", + "md5": "f29cd5eca40e386b1cd3a085543ff1e7", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.027", + "md5": "fdb52f1ae980c590e7166338767f8dec", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.028", + "md5": "6df9b808c3730f33a9a51bcdec2d8649", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.029", + "md5": "4828a3bf5b39df973fcca0f0bb75f66b", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.030", + "md5": "df44af4813e0e9ed782431978a6d380f", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.031", + "md5": "6ec0bed387f20fdd8dce7973e97ef539", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.032", + "md5": "a74e239dbd4d3ebfcc0cf11cf6c64a6e", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.033", + "md5": "07efc779c9eee6ed3178089237be45d3", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.034", + "md5": "0f1074ef1be0f9fa4197c96a3e126827", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.035", + "md5": "28feac64d9b4341dd01e82a10ef8fb1b", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.036", + "md5": "f231f823973d7bcf3f3bd34dcca742f9", + "package_size": "507588945" + } + ], + "total_size": "83960339238", + "file_path": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/files", + "url": "", + "md5": "", + "package_size": "0", + "file_id": "0", + "sub_channel": "801", + "game_files_md5": "9ad92d0a57c7c34ee3f0fe7eeebe514d" + }, + "patch": null, + "state": 0, + "launcher_action": 0 + } + } +] diff --git a/output/akEndfield/launcher/game/801/all_patch.json b/output/akEndfield/launcher/game/801/all_patch.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/output/akEndfield/launcher/game/801/all_patch.json @@ -0,0 +1 @@ +[] diff --git a/output/akEndfield/launcher/game/801/latest.json b/output/akEndfield/launcher/game/801/latest.json new file mode 100644 index 0000000..e14fc89 --- /dev/null +++ b/output/akEndfield/launcher/game/801/latest.json @@ -0,0 +1,209 @@ +{ + "req": { + "appCode": "YDUTE5gscDZ229CW", + "launcherAppCode": "BBWoqCzuZ2bZ1Dro", + "channel": 6, + "subChannel": 801, + "launcherSubChannel": 801 + }, + "rsp": { + "action": 1, + "version": "1.0.14", + "request_version": "", + "pkg": { + "packs": [ + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.001", + "md5": "6f24f6b31eec12cfb6ce243d2bd8d743", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.002", + "md5": "8ceee32676963a697f0e8daa6acc2f6e", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.003", + "md5": "17d0f31bdf6a1be25e30da9995176877", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.004", + "md5": "fc6fb86ccab29f745c0aec22c611d751", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.005", + "md5": "abf77711160c031c74c9728dc0386338", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.006", + "md5": "075b3e86c03965aab435b7c72bb58511", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.007", + "md5": "a6b90ccd5eb148b07ffd608494182da9", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.008", + "md5": "5cd8023b0e4cb18b7aa35d10c65dc202", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.009", + "md5": "b11d86cfdb5dc9015a4b532b2ebf5d22", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.010", + "md5": "687e457fd9636feb9ea08f5e7c7a3283", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.011", + "md5": "a6889c0be1318ade55404bcdb213b33c", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.012", + "md5": "568e1fa0bdde5d3f3b6430df7322d546", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.013", + "md5": "a81ca3c9d29a56ad9456e1ec4abe1c5f", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.014", + "md5": "ac7b33dfb9d0de719d179d394e2bee35", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.015", + "md5": "3bb928beea143f3907c8f7ce73e52826", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.016", + "md5": "49e0c09001b1fb49ae63a9b44d372925", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.017", + "md5": "65bfc97ceaa9b6d080f968042a905ec6", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.018", + "md5": "974d7944f0e2ef76ce8f9ca7fbcb28e7", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.019", + "md5": "2c156a6a8336276ed8b5b02a6dbb5959", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.020", + "md5": "69fe77f015206da76ba38aa7abdbb28c", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.021", + "md5": "20d5dd8dbae5d51e773ed69ee045c92a", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.022", + "md5": "58ca42ab9632728a8461e0ecdb4b8165", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.023", + "md5": "2c8291bd497fe908f5b8aa5549bf4304", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.024", + "md5": "6f9cbf57b8f8a2dc7637f1872b87416a", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.025", + "md5": "2f5cb6fd50a2716a05099961f52a48e5", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.026", + "md5": "f29cd5eca40e386b1cd3a085543ff1e7", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.027", + "md5": "fdb52f1ae980c590e7166338767f8dec", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.028", + "md5": "6df9b808c3730f33a9a51bcdec2d8649", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.029", + "md5": "4828a3bf5b39df973fcca0f0bb75f66b", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.030", + "md5": "df44af4813e0e9ed782431978a6d380f", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.031", + "md5": "6ec0bed387f20fdd8dce7973e97ef539", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.032", + "md5": "a74e239dbd4d3ebfcc0cf11cf6c64a6e", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.033", + "md5": "07efc779c9eee6ed3178089237be45d3", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.034", + "md5": "0f1074ef1be0f9fa4197c96a3e126827", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.035", + "md5": "28feac64d9b4341dd01e82a10ef8fb1b", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.036", + "md5": "f231f823973d7bcf3f3bd34dcca742f9", + "package_size": "507588945" + } + ], + "total_size": "83960339238", + "file_path": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/files", + "url": "", + "md5": "", + "package_size": "0", + "file_id": "0", + "sub_channel": "801", + "game_files_md5": "9ad92d0a57c7c34ee3f0fe7eeebe514d" + }, + "patch": null, + "state": 0, + "launcher_action": 0 + } +} diff --git a/output/akEndfield/launcher/game/801/list.md b/output/akEndfield/launcher/game/801/list.md new file mode 100644 index 0000000..a13c3c2 --- /dev/null +++ b/output/akEndfield/launcher/game/801/list.md @@ -0,0 +1,49 @@ +# Game Packages (Epic) + +- [1.0.14 (2026/01/28 11:50:37)](#ver-1.0.14-1769572238) + +

1.0.14 (2026/01/28 11:50:37)

+ + + + +
Unpacked Size42.72 GiB
Packed Size35.47 GiB
+ +| File | MD5 Checksum | Size | +| :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------- | ---------: | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.001](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.001) | `6f24f6b31eec12cfb6ce243d2bd8d743` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.002](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.002) | `8ceee32676963a697f0e8daa6acc2f6e` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.003](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.003) | `17d0f31bdf6a1be25e30da9995176877` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.004](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.004) | `fc6fb86ccab29f745c0aec22c611d751` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.005](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.005) | `abf77711160c031c74c9728dc0386338` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.006](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.006) | `075b3e86c03965aab435b7c72bb58511` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.007](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.007) | `a6b90ccd5eb148b07ffd608494182da9` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.008](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.008) | `5cd8023b0e4cb18b7aa35d10c65dc202` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.009](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.009) | `b11d86cfdb5dc9015a4b532b2ebf5d22` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.010](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.010) | `687e457fd9636feb9ea08f5e7c7a3283` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.011](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.011) | `a6889c0be1318ade55404bcdb213b33c` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.012](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.012) | `568e1fa0bdde5d3f3b6430df7322d546` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.013](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.013) | `a81ca3c9d29a56ad9456e1ec4abe1c5f` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.014](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.014) | `ac7b33dfb9d0de719d179d394e2bee35` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.015](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.015) | `3bb928beea143f3907c8f7ce73e52826` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.016](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.016) | `49e0c09001b1fb49ae63a9b44d372925` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.017](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.017) | `65bfc97ceaa9b6d080f968042a905ec6` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.018](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.018) | `974d7944f0e2ef76ce8f9ca7fbcb28e7` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.019](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.019) | `2c156a6a8336276ed8b5b02a6dbb5959` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.020](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.020) | `69fe77f015206da76ba38aa7abdbb28c` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.021](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.021) | `20d5dd8dbae5d51e773ed69ee045c92a` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.022](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.022) | `58ca42ab9632728a8461e0ecdb4b8165` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.023](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.023) | `2c8291bd497fe908f5b8aa5549bf4304` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.024](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.024) | `6f9cbf57b8f8a2dc7637f1872b87416a` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.025](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.025) | `2f5cb6fd50a2716a05099961f52a48e5` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.026](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.026) | `f29cd5eca40e386b1cd3a085543ff1e7` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.027](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.027) | `fdb52f1ae980c590e7166338767f8dec` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.028](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.028) | `6df9b808c3730f33a9a51bcdec2d8649` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.029](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.029) | `4828a3bf5b39df973fcca0f0bb75f66b` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.030](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.030) | `df44af4813e0e9ed782431978a6d380f` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.031](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.031) | `6ec0bed387f20fdd8dce7973e97ef539` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.032](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.032) | `a74e239dbd4d3ebfcc0cf11cf6c64a6e` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.033](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.033) | `07efc779c9eee6ed3178089237be45d3` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.034](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.034) | `0f1074ef1be0f9fa4197c96a3e126827` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.035](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.035) | `28feac64d9b4341dd01e82a10ef8fb1b` | 1.00 GiB | +| [Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.036](https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.036) | `f231f823973d7bcf3f3bd34dcca742f9` | 484.07 MiB | diff --git a/output/akEndfield/launcher/game/801/list_patch.md b/output/akEndfield/launcher/game/801/list_patch.md new file mode 100644 index 0000000..718f597 --- /dev/null +++ b/output/akEndfield/launcher/game/801/list_patch.md @@ -0,0 +1 @@ +# Game Patch Packages (Epic) diff --git a/output/akEndfield/launcher/game/801/v1.0.14.json b/output/akEndfield/launcher/game/801/v1.0.14.json new file mode 100644 index 0000000..e14fc89 --- /dev/null +++ b/output/akEndfield/launcher/game/801/v1.0.14.json @@ -0,0 +1,209 @@ +{ + "req": { + "appCode": "YDUTE5gscDZ229CW", + "launcherAppCode": "BBWoqCzuZ2bZ1Dro", + "channel": 6, + "subChannel": 801, + "launcherSubChannel": 801 + }, + "rsp": { + "action": 1, + "version": "1.0.14", + "request_version": "", + "pkg": { + "packs": [ + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.001", + "md5": "6f24f6b31eec12cfb6ce243d2bd8d743", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.002", + "md5": "8ceee32676963a697f0e8daa6acc2f6e", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.003", + "md5": "17d0f31bdf6a1be25e30da9995176877", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.004", + "md5": "fc6fb86ccab29f745c0aec22c611d751", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.005", + "md5": "abf77711160c031c74c9728dc0386338", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.006", + "md5": "075b3e86c03965aab435b7c72bb58511", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.007", + "md5": "a6b90ccd5eb148b07ffd608494182da9", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.008", + "md5": "5cd8023b0e4cb18b7aa35d10c65dc202", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.009", + "md5": "b11d86cfdb5dc9015a4b532b2ebf5d22", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.010", + "md5": "687e457fd9636feb9ea08f5e7c7a3283", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.011", + "md5": "a6889c0be1318ade55404bcdb213b33c", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.012", + "md5": "568e1fa0bdde5d3f3b6430df7322d546", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.013", + "md5": "a81ca3c9d29a56ad9456e1ec4abe1c5f", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.014", + "md5": "ac7b33dfb9d0de719d179d394e2bee35", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.015", + "md5": "3bb928beea143f3907c8f7ce73e52826", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.016", + "md5": "49e0c09001b1fb49ae63a9b44d372925", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.017", + "md5": "65bfc97ceaa9b6d080f968042a905ec6", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.018", + "md5": "974d7944f0e2ef76ce8f9ca7fbcb28e7", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.019", + "md5": "2c156a6a8336276ed8b5b02a6dbb5959", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.020", + "md5": "69fe77f015206da76ba38aa7abdbb28c", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.021", + "md5": "20d5dd8dbae5d51e773ed69ee045c92a", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.022", + "md5": "58ca42ab9632728a8461e0ecdb4b8165", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.023", + "md5": "2c8291bd497fe908f5b8aa5549bf4304", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.024", + "md5": "6f9cbf57b8f8a2dc7637f1872b87416a", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.025", + "md5": "2f5cb6fd50a2716a05099961f52a48e5", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.026", + "md5": "f29cd5eca40e386b1cd3a085543ff1e7", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.027", + "md5": "fdb52f1ae980c590e7166338767f8dec", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.028", + "md5": "6df9b808c3730f33a9a51bcdec2d8649", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.029", + "md5": "4828a3bf5b39df973fcca0f0bb75f66b", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.030", + "md5": "df44af4813e0e9ed782431978a6d380f", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.031", + "md5": "6ec0bed387f20fdd8dce7973e97ef539", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.032", + "md5": "a74e239dbd4d3ebfcc0cf11cf6c64a6e", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.033", + "md5": "07efc779c9eee6ed3178089237be45d3", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.034", + "md5": "0f1074ef1be0f9fa4197c96a3e126827", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.035", + "md5": "28feac64d9b4341dd01e82a10ef8fb1b", + "package_size": "1073741824" + }, + { + "url": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/packs/Beyond_Release_v1d0-Rel-os-5157154-11_prod_obt_epic.zip.036", + "md5": "f231f823973d7bcf3f3bd34dcca742f9", + "package_size": "507588945" + } + ], + "total_size": "83960339238", + "file_path": "https://beyond.hg-cdn.com/YDUTE5gscDZ229CW/1.0/update/6/801/Windows/1.0.14_Qk2mXHuAH1JWKF37/files", + "url": "", + "md5": "", + "package_size": "0", + "file_id": "0", + "sub_channel": "801", + "game_files_md5": "9ad92d0a57c7c34ee3f0fe7eeebe514d" + }, + "patch": null, + "state": 0, + "launcher_action": 0 + } +} diff --git a/src/cmds/test.ts b/src/cmds/test.ts index 97ef20c..1c5e7d9 100644 --- a/src/cmds/test.ts +++ b/src/cmds/test.ts @@ -79,112 +79,149 @@ async function mainCmdHandler() { const cfg = appConfig.network.api.akEndfield; const channelStr = String(cfg.channel.osWinRel); - await (async () => { - logger.debug('Fetching latestGame ...'); - const rsp = await apiUtils.apiAkEndfield.launcher.latestGame( - cfg.appCode.game.osWinRel, - cfg.appCode.launcher.osWinRel, - cfg.channel.osWinRel, - cfg.channel.osWinRel, - cfg.channel.osWinRel, - null, - ); - logger.info( - `Fetched latestGame: v${rsp.version}, ${mathUtils.formatFileSize( - parseInt(rsp.pkg.total_size) - mathUtils.arrayTotal(rsp.pkg.packs.map((e) => parseInt(e.package_size))), - { - decimals: 2, - decimalPadding: true, - useBinaryUnit: true, - useBitUnit: false, - unitVisible: true, - unit: null, - }, - )}`, - ); - const prettyRsp = { - req: { - appCode: cfg.appCode.game.osWinRel, - launcherAppCode: cfg.appCode.launcher.osWinRel, - channel: cfg.channel.osWinRel, - subChannel: cfg.channel.osWinRel, - launcherSubChannel: cfg.channel.osWinRel, - }, - rsp, - }; + const gameTargets = [ + { + name: 'Official', + launcherAppCode: cfg.appCode.launcher.osWinRel, + subChannel: cfg.channel.osWinRel, + launcherSubChannel: cfg.channel.osWinRel, + dirName: String(cfg.channel.osWinRel), + }, + { + name: 'Epic', + launcherAppCode: cfg.appCode.launcher.osWinRelEpic, + subChannel: cfg.subChannel.osWinRelEpic, + launcherSubChannel: cfg.subChannel.osWinRelEpic, + dirName: String(cfg.subChannel.osWinRelEpic), + }, + ]; - await saveResult(['akEndfield', 'launcher', 'game', channelStr], rsp.version, prettyRsp); - })(); - - await (async () => { - logger.debug('Fetching latestGame (patch) ...'); - const gameAllJson = await Bun.file( - path.join(argvUtils.getArgv()['outputDir'], 'akEndfield', 'launcher', 'game', channelStr, 'all.json'), - ).json(); - const patchAllJson = await Bun.file( - path.join(argvUtils.getArgv()['outputDir'], 'akEndfield', 'launcher', 'game', channelStr, 'all_patch.json'), - ).json(); - const versionList = ([...new Set(gameAllJson.map((e: any) => e.rsp.version))] as string[]) - .sort((a, b) => semver.compare(b, a)) - .slice(1); - let needWrite: boolean = false; - const queue = new PQueue({ concurrency: appConfig.threadCount.network }); - for (const ver of versionList) { - queue.add(async () => { - const rsp = await apiUtils.apiAkEndfield.launcher.latestGame( - cfg.appCode.game.osWinRel, - cfg.appCode.launcher.osWinRel, - cfg.channel.osWinRel, - cfg.channel.osWinRel, - cfg.channel.osWinRel, - ver, - ); - const prettyRsp = { - req: { - appCode: cfg.appCode.game.osWinRel, - launcherAppCode: cfg.appCode.launcher.osWinRel, - channel: cfg.channel.osWinRel, - subChannel: cfg.channel.osWinRel, - launcherSubChannel: cfg.channel.osWinRel, - version: ver, - }, - rsp, - }; - if (rsp.patch === null) return; - if ( - patchAllJson - .map((e: any) => JSON.stringify({ req: e.req, rsp: e.rsp })) - .includes(JSON.stringify(prettyRsp)) === false - ) { - logger.debug( - `Fetched latestGame (patch): v${rsp.request_version} -> v${rsp.version}, ${mathUtils.formatFileSize( - parseInt(rsp.patch.total_size) - parseInt(rsp.patch.package_size), - { - decimals: 2, - decimalPadding: true, - unitVisible: true, - useBinaryUnit: true, - useBitUnit: false, - unit: null, - }, - )}`, - ); - patchAllJson.push({ - updatedAt: DateTime.now().toISO(), - ...prettyRsp, - }); - needWrite = true; - } - }); - } - await queue.onIdle(); - if (needWrite) { - await Bun.write( - path.join(argvUtils.getArgv()['outputDir'], 'akEndfield', 'launcher', 'game', channelStr, 'all_patch.json'), - JSON.stringify(patchAllJson, null, 2), + for (const target of gameTargets) { + await (async () => { + logger.debug(`Fetching latestGame (${target.name}) ...`); + const rsp = await apiUtils.apiAkEndfield.launcher.latestGame( + cfg.appCode.game.osWinRel, + target.launcherAppCode, + cfg.channel.osWinRel, + target.subChannel, + target.launcherSubChannel, + null, ); - } - })(); + logger.info( + `Fetched latestGame (${target.name}): v${rsp.version}, ${mathUtils.formatFileSize( + parseInt(rsp.pkg.total_size) - mathUtils.arrayTotal(rsp.pkg.packs.map((e) => parseInt(e.package_size))), + { + decimals: 2, + decimalPadding: true, + useBinaryUnit: true, + useBitUnit: false, + unitVisible: true, + unit: null, + }, + )}`, + ); + const prettyRsp = { + req: { + appCode: cfg.appCode.game.osWinRel, + launcherAppCode: target.launcherAppCode, + channel: cfg.channel.osWinRel, + subChannel: target.subChannel, + launcherSubChannel: target.launcherSubChannel, + }, + rsp, + }; + + await saveResult(['akEndfield', 'launcher', 'game', target.dirName], rsp.version, prettyRsp); + })(); + } + + for (const target of gameTargets) { + await (async () => { + logger.debug(`Fetching latestGame (patch) (${target.name}) ...`); + const gameAllJsonPath = path.join( + argvUtils.getArgv()['outputDir'], + 'akEndfield', + 'launcher', + 'game', + target.dirName, + 'all.json', + ); + const patchAllJsonPath = path.join( + argvUtils.getArgv()['outputDir'], + 'akEndfield', + 'launcher', + 'game', + target.dirName, + 'all_patch.json', + ); + + if (!(await Bun.file(gameAllJsonPath).exists())) return; + + const gameAllJson = await Bun.file(gameAllJsonPath).json(); + let patchAllJson: any[] = []; + if (await Bun.file(patchAllJsonPath).exists()) { + patchAllJson = await Bun.file(patchAllJsonPath).json(); + } + + const versionList = ([...new Set(gameAllJson.map((e: any) => e.rsp.version))] as string[]) + .sort((a, b) => semver.compare(b, a)) + .slice(1); + let needWrite: boolean = false; + const queue = new PQueue({ concurrency: appConfig.threadCount.network }); + for (const ver of versionList) { + queue.add(async () => { + const rsp = await apiUtils.apiAkEndfield.launcher.latestGame( + cfg.appCode.game.osWinRel, + target.launcherAppCode, + cfg.channel.osWinRel, + target.subChannel, + target.launcherSubChannel, + ver, + ); + const prettyRsp = { + req: { + appCode: cfg.appCode.game.osWinRel, + launcherAppCode: target.launcherAppCode, + channel: cfg.channel.osWinRel, + subChannel: target.subChannel, + launcherSubChannel: target.launcherSubChannel, + version: ver, + }, + rsp, + }; + if (rsp.patch === null) return; + if ( + patchAllJson + .map((e: any) => JSON.stringify({ req: e.req, rsp: e.rsp })) + .includes(JSON.stringify(prettyRsp)) === false + ) { + logger.debug( + `Fetched latestGame (patch) (${target.name}): v${rsp.request_version} -> v${rsp.version}, ${mathUtils.formatFileSize( + parseInt(rsp.patch.total_size) - parseInt(rsp.patch.package_size), + { + decimals: 2, + decimalPadding: true, + unitVisible: true, + useBinaryUnit: true, + useBitUnit: false, + unit: null, + }, + )}`, + ); + patchAllJson.push({ + updatedAt: DateTime.now().toISO(), + ...prettyRsp, + }); + needWrite = true; + } + }); + } + await queue.onIdle(); + if (needWrite) { + await Bun.write(patchAllJsonPath, JSON.stringify(patchAllJson, null, 2)); + } + })(); + } await (async () => { logger.debug('Fetching latestGameRes ...'); @@ -283,103 +320,126 @@ async function mainCmdHandler() { await (async () => { //* Markdown generate - await (async () => { - const gameAllJson = await Bun.file( - path.join(argvUtils.getArgv()['outputDir'], 'akEndfield', 'launcher', 'game', channelStr, 'all.json'), - ).json(); - const mdTexts: string[] = []; - mdTexts.push( - ...[ - '# Game Packages\n', - ...gameAllJson.map( - (e: any) => - `- [${e.rsp.version} (${DateTime.fromISO(e.updatedAt, { setZone: true }).setZone('UTC+8').toFormat('yyyy/MM/dd HH:mm:ss')})](#ver-${e.rsp.version}-${Math.ceil(DateTime.fromISO(e.updatedAt).toSeconds())})`, - ), - '', - ], - ...gameAllJson.map((e: any) => - [ - `

${e.rsp.version} (${DateTime.fromISO(e.updatedAt, { setZone: true }).setZone('UTC+8').toFormat('yyyy/MM/dd HH:mm:ss')})

\n`, - ``, - ` `, - ` `, - `
Unpacked Size${mathUtils.formatFileSize( - e.rsp.pkg.total_size - mathUtils.arrayTotal(e.rsp.pkg.packs.map((f: any) => parseInt(f.package_size))), - { - decimals: 2, - decimalPadding: true, - unitVisible: true, - useBinaryUnit: true, - useBitUnit: false, - unit: null, - }, - )}
Packed Size${mathUtils.formatFileSize(mathUtils.arrayTotal(e.rsp.pkg.packs.map((f: any) => parseInt(f.package_size))), { decimals: 2, decimalPadding: true, unitVisible: true, useBinaryUnit: true, useBitUnit: false, unit: null })}
\n`, - `|File|MD5 Checksum|Size|`, - `|:--|:--|--:|`, - ...e.rsp.pkg.packs.map((f: any) => [ - `|[${new URL(f.url).pathname.split('/').pop() ?? ''}](${f.url})|\`${f.md5}\`|${mathUtils.formatFileSize(parseInt(f.package_size), { decimals: 2, decimalPadding: true, unitVisible: true, useBinaryUnit: true, useBitUnit: false, unit: null })}|`, - ]), + for (const target of gameTargets) { + await (async () => { + const gameAllJsonPath = path.join( + argvUtils.getArgv()['outputDir'], + 'akEndfield', + 'launcher', + 'game', + target.dirName, + 'all.json', + ); + if (!(await Bun.file(gameAllJsonPath).exists())) return; + const gameAllJson = await Bun.file(gameAllJsonPath).json(); + const mdTexts: string[] = []; + mdTexts.push( + ...[ + `# Game Packages (${target.name})\n`, + ...gameAllJson.map( + (e: any) => + `- [${e.rsp.version} (${DateTime.fromISO(e.updatedAt, { setZone: true }).setZone('UTC+8').toFormat('yyyy/MM/dd HH:mm:ss')})](#ver-${e.rsp.version}-${Math.ceil(DateTime.fromISO(e.updatedAt).toSeconds())})`, + ), '', - ].join('\n'), - ), - ); - await Bun.write( - path.join(argvUtils.getArgv()['outputDir'], 'akEndfield', 'launcher', 'game', channelStr, 'list.md'), - mdTexts.join('\n'), - ); - })(); + ], + ...gameAllJson.map((e: any) => + [ + `

${e.rsp.version} (${DateTime.fromISO(e.updatedAt, { setZone: true }).setZone('UTC+8').toFormat('yyyy/MM/dd HH:mm:ss')})

\n`, + ``, + ` `, + ` `, + `
Unpacked Size${mathUtils.formatFileSize( + e.rsp.pkg.total_size - mathUtils.arrayTotal(e.rsp.pkg.packs.map((f: any) => parseInt(f.package_size))), + { + decimals: 2, + decimalPadding: true, + unitVisible: true, + useBinaryUnit: true, + useBitUnit: false, + unit: null, + }, + )}
Packed Size${mathUtils.formatFileSize(mathUtils.arrayTotal(e.rsp.pkg.packs.map((f: any) => parseInt(f.package_size))), { decimals: 2, decimalPadding: true, unitVisible: true, useBinaryUnit: true, useBitUnit: false, unit: null })}
\n`, + `|File|MD5 Checksum|Size|`, + `|:--|:--|--:|`, + ...e.rsp.pkg.packs.map((f: any) => [ + `|[${new URL(f.url).pathname.split('/').pop() ?? ''}](${f.url})|\`${f.md5}\`|${mathUtils.formatFileSize(parseInt(f.package_size), { decimals: 2, decimalPadding: true, unitVisible: true, useBinaryUnit: true, useBitUnit: false, unit: null })}|`, + ]), + '', + ].join('\n'), + ), + ); + await Bun.write( + path.join(argvUtils.getArgv()['outputDir'], 'akEndfield', 'launcher', 'game', target.dirName, 'list.md'), + mdTexts.join('\n'), + ); + })(); - await (async () => { - const gameAllJson = await Bun.file( - path.join(argvUtils.getArgv()['outputDir'], 'akEndfield', 'launcher', 'game', channelStr, 'all_patch.json'), - ).json(); - const mdTexts: string[] = []; - mdTexts.push( - ...[ - '# Game Patch Packages\n', - ...gameAllJson.map( - (e: any) => - `- [${e.rsp.request_version} → ${e.rsp.version} (${DateTime.fromISO(e.updatedAt, { setZone: true }).setZone('UTC+8').toFormat('yyyy/MM/dd HH:mm:ss')})](#ver-${e.rsp.request_version}-${e.rsp.version}-${Math.ceil(DateTime.fromISO(e.updatedAt).toSeconds())})`, - ), - '', - ], - ...gameAllJson.map((e: any) => - [ - `

${e.rsp.request_version} → ${e.rsp.version} (${DateTime.fromISO(e.updatedAt, { setZone: true }).setZone('UTC+8').toFormat('yyyy/MM/dd HH:mm:ss')})

\n`, - ``, - ` `, - ` `, - `
Unpacked Size${mathUtils.formatFileSize( - e.rsp.patch.total_size - - mathUtils.arrayTotal(e.rsp.patch.patches.map((f: any) => parseInt(f.package_size))), - { - decimals: 2, - decimalPadding: true, - unitVisible: true, - useBinaryUnit: true, - useBitUnit: false, - unit: null, - }, - )}
Packed Size${mathUtils.formatFileSize(mathUtils.arrayTotal(e.rsp.patch.patches.map((f: any) => parseInt(f.package_size))), { decimals: 2, decimalPadding: true, unitVisible: true, useBinaryUnit: true, useBitUnit: false, unit: null })}
\n`, - `|File|MD5 Checksum|Size|`, - `|:--|:--|--:|`, - ...(e.rsp.patch.url - ? [ - `|[${new URL(e.rsp.patch.url).pathname.split('/').pop() ?? ''}](${e.rsp.patch.url})|\`${e.rsp.patch.md5}\`|${mathUtils.formatFileSize(parseInt(e.rsp.patch.package_size), { decimals: 2, decimalPadding: true, unitVisible: true, useBinaryUnit: true, useBitUnit: false, unit: null })}|`, - ] - : []), - ...e.rsp.patch.patches.map((f: any) => [ - `|[${new URL(f.url).pathname.split('/').pop() ?? ''}](${f.url})|\`${f.md5}\`|${mathUtils.formatFileSize(parseInt(f.package_size), { decimals: 2, decimalPadding: true, unitVisible: true, useBinaryUnit: true, useBitUnit: false, unit: null })}|`, - ]), + await (async () => { + const patchAllJsonPath = path.join( + argvUtils.getArgv()['outputDir'], + 'akEndfield', + 'launcher', + 'game', + target.dirName, + 'all_patch.json', + ); + if (!(await Bun.file(patchAllJsonPath).exists())) return; + const gameAllJson = await Bun.file(patchAllJsonPath).json(); + const mdTexts: string[] = []; + mdTexts.push( + ...[ + `# Game Patch Packages (${target.name})\n`, + ...gameAllJson.map( + (e: any) => + `- [${e.rsp.request_version} → ${e.rsp.version} (${DateTime.fromISO(e.updatedAt, { setZone: true }).setZone('UTC+8').toFormat('yyyy/MM/dd HH:mm:ss')})](#ver-${e.rsp.request_version}-${e.rsp.version}-${Math.ceil(DateTime.fromISO(e.updatedAt).toSeconds())})`, + ), '', - ].join('\n'), - ), - ); - await Bun.write( - path.join(argvUtils.getArgv()['outputDir'], 'akEndfield', 'launcher', 'game', channelStr, 'list_patch.md'), - mdTexts.join('\n'), - ); - })(); + ], + ...gameAllJson.map((e: any) => + [ + `

${e.rsp.request_version} → ${e.rsp.version} (${DateTime.fromISO(e.updatedAt, { setZone: true }).setZone('UTC+8').toFormat('yyyy/MM/dd HH:mm:ss')})

\n`, + ``, + ` `, + ` `, + `
Unpacked Size${mathUtils.formatFileSize( + e.rsp.patch.total_size - + mathUtils.arrayTotal(e.rsp.patch.patches.map((f: any) => parseInt(f.package_size))), + { + decimals: 2, + decimalPadding: true, + unitVisible: true, + useBinaryUnit: true, + useBitUnit: false, + unit: null, + }, + )}
Packed Size${mathUtils.formatFileSize(mathUtils.arrayTotal(e.rsp.patch.patches.map((f: any) => parseInt(f.package_size))), { decimals: 2, decimalPadding: true, unitVisible: true, useBinaryUnit: true, useBitUnit: false, unit: null })}
\n`, + `|File|MD5 Checksum|Size|`, + `|:--|:--|--:|`, + ...(e.rsp.patch.url + ? [ + `|[${new URL(e.rsp.patch.url).pathname.split('/').pop() ?? ''}](${e.rsp.patch.url})|\`${e.rsp.patch.md5}\`|${mathUtils.formatFileSize(parseInt(e.rsp.patch.package_size), { decimals: 2, decimalPadding: true, unitVisible: true, useBinaryUnit: true, useBitUnit: false, unit: null })}|`, + ] + : []), + ...e.rsp.patch.patches.map((f: any) => [ + `|[${new URL(f.url).pathname.split('/').pop() ?? ''}](${f.url})|\`${f.md5}\`|${mathUtils.formatFileSize(parseInt(f.package_size), { decimals: 2, decimalPadding: true, unitVisible: true, useBinaryUnit: true, useBitUnit: false, unit: null })}|`, + ]), + '', + ].join('\n'), + ), + ); + await Bun.write( + path.join( + argvUtils.getArgv()['outputDir'], + 'akEndfield', + 'launcher', + 'game', + target.dirName, + 'list_patch.md', + ), + mdTexts.join('\n'), + ); + })(); + } await (async () => { const mdTexts: string[] = []; diff --git a/src/utils/api.ts b/src/utils/api.ts index ed05d6b..2b6b18d 100644 --- a/src/utils/api.ts +++ b/src/utils/api.ts @@ -1,461 +1,9 @@ -import ky from 'ky'; -import semver from 'semver'; -import * as TypesApiAkEndfield from '../types/api/akEndfield/Api.js'; -import appConfig from './config.js'; - -const defaultKySettings = { - headers: { - 'User-Agent': appConfig.network.userAgent.minimum, - }, - timeout: appConfig.network.timeout, - retry: { limit: appConfig.network.retryCount }, -}; - -const launcherWebLang = [ - 'de-de', - 'en-us', - 'es-mx', - 'fr-fr', - 'id-id', - 'it-it', - 'ja-jp', - 'ko-kr', - 'pt-br', - 'ru-ru', - 'th-th', - 'vi-vn', - 'zh-cn', - 'zh-tw', -] as const; +import accountService from './api/accountService.js'; +import binding from './api/binding.js'; +import launcher from './api/launcher.js'; +import u8 from './api/u8.js'; +import webview from './api/webview.js'; export default { - defaultKySettings, - apiAkEndfield: { - launcher: { - latestGame: async ( - appCode: string, - launcherAppCode: string, - channel: number, - subChannel: number, - launcherSubChannel: number, - version: string | null, - ): Promise => { - if (version !== null && !semver.valid(version)) throw new Error(`Invalid version string (${version})`); - const rsp = await ky - .get(`https://${appConfig.network.api.akEndfield.base.launcher}/game/get_latest`, { - ...defaultKySettings, - searchParams: { - appcode: appCode, - launcher_appcode: launcherAppCode, - channel, - sub_channel: subChannel, - launcher_sub_channel: launcherSubChannel, - version: version ?? undefined, - }, - }) - .json(); - return rsp as TypesApiAkEndfield.LauncherLatestGame; - }, - latestGameResources: async ( - appCode: string, - gameVersion: string, // example: 1.0 - version: string, - randStr: string, - platform: 'Windows' | 'Android' | 'iOS' | 'PlayStation', - ): Promise => { - if (!semver.valid(version)) throw new Error(`Invalid version string (${version})`); - const rsp = await ky - .get(`https://${appConfig.network.api.akEndfield.base.launcher}/game/get_latest_resources`, { - ...defaultKySettings, - searchParams: { - appcode: appCode, - game_version: gameVersion, - version: version, - platform, - rand_str: randStr, - }, - }) - .json(); - return rsp as TypesApiAkEndfield.LauncherLatestGameResources; - }, - latestLauncher: async ( - appCode: string, - channel: number, - subChannel: number, - version: string | null, - targetApp: 'EndField' | null, - ): Promise => { - if (version !== null && !semver.valid(version)) throw new Error(`Invalid version string (${version})`); - const rsp = await ky - .get(`https://${appConfig.network.api.akEndfield.base.launcher}/launcher/get_latest`, { - ...defaultKySettings, - searchParams: { - appcode: appCode, - channel, - sub_channel: subChannel, - version: version ?? undefined, - targetApp: targetApp ?? undefined, - }, - }) - .json(); - return rsp as TypesApiAkEndfield.LauncherLatestLauncher; - }, - web: { - sidebar: async ( - appCode: string, - channel: number, - subChannel: number, - language: (typeof launcherWebLang)[number], - platform: 'Windows' = 'Windows', - ): Promise => { - const rsp = await ky - .post(`https://${appConfig.network.api.akEndfield.base.launcher}/proxy/web/batch_proxy`, { - ...defaultKySettings, - json: { - proxy_reqs: [ - { - kind: 'get_sidebar', - get_sidebar_req: { - appcode: appCode, - channel: String(channel), - sub_channel: String(subChannel), - language, - platform, - source: 'launcher', - }, - }, - ], - }, - }) - .json(); - return (rsp as any).proxy_rsps[0].get_sidebar_rsp as TypesApiAkEndfield.LauncherWebSidebar; - }, - singleEnt: async ( - appCode: string, - channel: number, - subChannel: number, - language: (typeof launcherWebLang)[number], - platform: 'Windows' = 'Windows', - ): Promise => { - const rsp = await ky - .post(`https://${appConfig.network.api.akEndfield.base.launcher}/proxy/web/batch_proxy`, { - ...defaultKySettings, - json: { - proxy_reqs: [ - { - kind: 'get_single_ent', - get_single_ent_req: { - appcode: appCode, - channel: String(channel), - sub_channel: String(subChannel), - language, - platform, - source: 'launcher', - }, - }, - ], - }, - }) - .json(); - return (rsp as any).proxy_rsps[0].get_single_ent_rsp as TypesApiAkEndfield.LauncherWebSingleEnt; - }, - mainBgImage: async ( - appCode: string, - channel: number, - subChannel: number, - language: (typeof launcherWebLang)[number], - platform: 'Windows' = 'Windows', - ): Promise => { - const rsp = await ky - .post(`https://${appConfig.network.api.akEndfield.base.launcher}/proxy/web/batch_proxy`, { - ...defaultKySettings, - json: { - proxy_reqs: [ - { - kind: 'get_main_bg_image', - get_main_bg_image_req: { - appcode: appCode, - channel: String(channel), - sub_channel: String(subChannel), - language, - platform, - source: 'launcher', - }, - }, - ], - }, - }) - .json(); - return (rsp as any).proxy_rsps[0].get_main_bg_image_rsp as TypesApiAkEndfield.LauncherWebMainBgImage; - }, - banner: async ( - appCode: string, - channel: number, - subChannel: number, - language: (typeof launcherWebLang)[number], - platform: 'Windows' = 'Windows', - ): Promise => { - const rsp = await ky - .post(`https://${appConfig.network.api.akEndfield.base.launcher}/proxy/web/batch_proxy`, { - ...defaultKySettings, - json: { - proxy_reqs: [ - { - kind: 'get_banner', - get_banner_req: { - appcode: appCode, - channel: String(channel), - sub_channel: String(subChannel), - language, - platform, - source: 'launcher', - }, - }, - ], - }, - }) - .json(); - return (rsp as any).proxy_rsps[0].get_banner_rsp as TypesApiAkEndfield.LauncherWebBanner; - }, - announcement: async ( - appCode: string, - channel: number, - subChannel: number, - language: (typeof launcherWebLang)[number], - platform: 'Windows' = 'Windows', - ): Promise => { - const rsp = await ky - .post(`https://${appConfig.network.api.akEndfield.base.launcher}/proxy/web/batch_proxy`, { - ...defaultKySettings, - json: { - proxy_reqs: [ - { - kind: 'get_announcement', - get_announcement_req: { - appcode: appCode, - channel: String(channel), - sub_channel: String(subChannel), - language, - platform, - source: 'launcher', - }, - }, - ], - }, - }) - .json(); - return (rsp as any).proxy_rsps[0].get_announcement_rsp as TypesApiAkEndfield.LauncherWebAnnouncement; - }, - }, - }, - accountService: { - user: { - auth: { - v1: { - tokenByEmailPassword: async ( - email: string, - password: string, - from: number = 0, - ): Promise => { - const rsp = await ky - .post( - `https://${appConfig.network.api.akEndfield.base.accountService}/user/auth/v1/token_by_email_password`, - { ...defaultKySettings, json: { email, from, password } }, - ) - .json(); - return rsp as TypesApiAkEndfield.AccSrvUserAuthV1TokenByEmail; - }, - }, - }, - oauth2: { - v2: { - grant: async ( - appCode: string, - token: string, - type: T = 0 as any, // 0 = return grant uid (Gxxxxxxxxx) and code, 1 = return hgId and token - ): Promise< - T extends 0 ? TypesApiAkEndfield.AccSrvUserOAuth2V2Grant : TypesApiAkEndfield.AccSrvUserOAuth2V2GrantType1 - > => { - const rsp = await ky - .post(`https://${appConfig.network.api.akEndfield.base.accountService}/user/oauth2/v2/grant`, { - ...defaultKySettings, - json: { appCode, token, type }, - }) - .json(); - return rsp as any; - }, - }, - }, - info: { - v1: { - basic: async (appCode: string, token: string): Promise => { - const rsp = await ky - .get(`https://${appConfig.network.api.akEndfield.base.accountService}/user/info/v1/basic`, { - ...defaultKySettings, - searchParams: { appCode, token }, - }) - .json(); - return rsp as TypesApiAkEndfield.AccSrvUserInfoV1Basic; - }, - thirdParty: async ( - appCode: string, - token: string, - ): Promise => { - const rsp = await ky - .get(`https://${appConfig.network.api.akEndfield.base.accountService}/user/info/v1/third_party`, { - ...defaultKySettings, - searchParams: { appCode, token }, - }) - .json(); - return rsp as TypesApiAkEndfield.AccSrvUserInfoV1ThirdParty; - }, - }, - }, - }, - }, - u8: { - user: { - auth: { - v2: { - tokenByChToken: async ( - appCode: string, - channelMasterId: number, - channelToken: string, - platform: number = 2, - type: number = 0, - ): Promise => { - const rsp = await ky - .post(`https://${appConfig.network.api.akEndfield.base.u8}/u8/user/auth/v2/token_by_channel_token`, { - ...defaultKySettings, - json: { - appCode, - channelMasterId, - channelToken: JSON.stringify({ - code: channelToken, - type: 1, - isSuc: true, - }), - type, - platform, - }, - }) - .json(); - return rsp as TypesApiAkEndfield.U8UserAuthV2ChToken; - }, - grant: async ( - token: string, - platform: number = 2, - type: number = 0, - ): Promise => { - const rsp = await ky - .post(`https://${appConfig.network.api.akEndfield.base.u8}/u8/user/auth/v2/grant`, { - ...defaultKySettings, - json: { token, type, platform }, - }) - .json(); - return rsp as TypesApiAkEndfield.U8UserAuthV2Grant; - }, - }, - }, - }, - game: { - server: { - v1: { - serverList: async (token: string): Promise => { - const rsp = await ky - .post(`https://${appConfig.network.api.akEndfield.base.u8}/game/server/v1/server_list`, { - ...defaultKySettings, - json: { token }, - }) - .json(); - return rsp as TypesApiAkEndfield.U8GameServerV1ServerList; - }, - }, - }, - role: { - v1: { - confirmServer: async ( - token: string, - serverId: number, - ): Promise => { - const rsp = await ky - .post(`https://${appConfig.network.api.akEndfield.base.u8}/game/role/v1/confirm_server`, { - ...defaultKySettings, - json: { token, serverId: String(serverId) }, - }) - .json(); - return rsp as TypesApiAkEndfield.U8GameRoleV1ConfirmServer; - }, - }, - }, - }, - }, - binding: { - account: { - binding: { - v1: { - bindingList: async ( - // appCode: 'arknights' | 'endfield', - token: string, - ): Promise => { - const rsp = await ky - .get(`https://${appConfig.network.api.akEndfield.base.binding}/account/binding/v1/binding_list`, { - ...defaultKySettings, - searchParams: { token }, - }) - .json(); - return rsp as TypesApiAkEndfield.BindApiAccBindV1BindList; - }, - u8TokenByUid: async ( - token: string, - uid: string, - ): Promise => { - const rsp = await ky - .post(`https://${appConfig.network.api.akEndfield.base.binding}/account/binding/v1/u8_token_by_uid`, { - ...defaultKySettings, - json: { token, uid }, - }) - .json(); - return rsp as TypesApiAkEndfield.BindApiAccBindV1U8TokenByUid; - }, - }, - }, - }, - }, - webview: { - record: { - char: async ( - token: string, - serverId: number, // 2 or 3 - poolType: - | 'E_CharacterGachaPoolType_Beginner' - | 'E_CharacterGachaPoolType_Standard' - | 'E_CharacterGachaPoolType_Special', - seqId: string | null, - lang: (typeof launcherWebLang)[number] = 'ja-jp', - ): Promise => { - const rsp = await ky - .get(`https://${appConfig.network.api.akEndfield.base.webview}/api/record/char`, { - ...defaultKySettings, - searchParams: { lang, seq_id: seqId ?? undefined, pool_type: poolType, token, server_id: serverId }, - }) - .json(); - return rsp as TypesApiAkEndfield.WebViewRecordChar; - }, - }, - content: async ( - serverId: number, // 2 or 3 - poolId: string, - lang: (typeof launcherWebLang)[number] = 'ja-jp', - ): Promise => { - const rsp = await ky - .get(`https://${appConfig.network.api.akEndfield.base.webview}/api/content`, { - ...defaultKySettings, - searchParams: { lang, pool_id: poolId, server_id: serverId }, - }) - .json(); - return rsp as TypesApiAkEndfield.WebViewRecordContent; - }, - }, - }, + apiAkEndfield: { launcher, accountService, u8, binding, webview }, }; diff --git a/src/utils/api/accountService.ts b/src/utils/api/accountService.ts new file mode 100644 index 0000000..5dade9a --- /dev/null +++ b/src/utils/api/accountService.ts @@ -0,0 +1,67 @@ +import ky from 'ky'; +import * as TypesApiAkEndfield from '../../types/api/akEndfield/Api.js'; +import appConfig from '../config.js'; +import defaultSettings from './defaultSettings.js'; + +export default { + user: { + auth: { + v1: { + tokenByEmailPassword: async ( + email: string, + password: string, + from: number = 0, + ): Promise => { + const rsp = await ky + .post( + `https://${appConfig.network.api.akEndfield.base.accountService}/user/auth/v1/token_by_email_password`, + { ...defaultSettings.ky, json: { email, from, password } }, + ) + .json(); + return rsp as TypesApiAkEndfield.AccSrvUserAuthV1TokenByEmail; + }, + }, + }, + oauth2: { + v2: { + grant: async ( + appCode: string, + token: string, + type: T = 0 as any, // 0 = return grant uid (Gxxxxxxxxx) and code, 1 = return hgId and token + ): Promise< + T extends 0 ? TypesApiAkEndfield.AccSrvUserOAuth2V2Grant : TypesApiAkEndfield.AccSrvUserOAuth2V2GrantType1 + > => { + const rsp = await ky + .post(`https://${appConfig.network.api.akEndfield.base.accountService}/user/oauth2/v2/grant`, { + ...defaultSettings.ky, + json: { appCode, token, type }, + }) + .json(); + return rsp as any; + }, + }, + }, + info: { + v1: { + basic: async (appCode: string, token: string): Promise => { + const rsp = await ky + .get(`https://${appConfig.network.api.akEndfield.base.accountService}/user/info/v1/basic`, { + ...defaultSettings.ky, + searchParams: { appCode, token }, + }) + .json(); + return rsp as TypesApiAkEndfield.AccSrvUserInfoV1Basic; + }, + thirdParty: async (appCode: string, token: string): Promise => { + const rsp = await ky + .get(`https://${appConfig.network.api.akEndfield.base.accountService}/user/info/v1/third_party`, { + ...defaultSettings.ky, + searchParams: { appCode, token }, + }) + .json(); + return rsp as TypesApiAkEndfield.AccSrvUserInfoV1ThirdParty; + }, + }, + }, + }, +}; diff --git a/src/utils/api/binding.ts b/src/utils/api/binding.ts new file mode 100644 index 0000000..44b7016 --- /dev/null +++ b/src/utils/api/binding.ts @@ -0,0 +1,34 @@ +import ky from 'ky'; +import * as TypesApiAkEndfield from '../../types/api/akEndfield/Api.js'; +import appConfig from '../config.js'; +import defaultSettings from './defaultSettings.js'; + +export default { + account: { + binding: { + v1: { + bindingList: async ( + // appCode: 'arknights' | 'endfield', + token: string, + ): Promise => { + const rsp = await ky + .get(`https://${appConfig.network.api.akEndfield.base.binding}/account/binding/v1/binding_list`, { + ...defaultSettings.ky, + searchParams: { token }, + }) + .json(); + return rsp as TypesApiAkEndfield.BindApiAccBindV1BindList; + }, + u8TokenByUid: async (token: string, uid: string): Promise => { + const rsp = await ky + .post(`https://${appConfig.network.api.akEndfield.base.binding}/account/binding/v1/u8_token_by_uid`, { + ...defaultSettings.ky, + json: { token, uid }, + }) + .json(); + return rsp as TypesApiAkEndfield.BindApiAccBindV1U8TokenByUid; + }, + }, + }, + }, +}; diff --git a/src/utils/api/defaultSettings.ts b/src/utils/api/defaultSettings.ts new file mode 100644 index 0000000..01aabcd --- /dev/null +++ b/src/utils/api/defaultSettings.ts @@ -0,0 +1,27 @@ +import appConfig from '../config.js'; + +export default { + ky: { + headers: { + 'User-Agent': appConfig.network.userAgent.minimum, + }, + timeout: appConfig.network.timeout, + retry: { limit: appConfig.network.retryCount }, + }, + launcherWebLang: [ + 'de-de', + 'en-us', + 'es-mx', + 'fr-fr', + 'id-id', + 'it-it', + 'ja-jp', + 'ko-kr', + 'pt-br', + 'ru-ru', + 'th-th', + 'vi-vn', + 'zh-cn', + 'zh-tw', + ] as const, +}; diff --git a/src/utils/api/launcher.ts b/src/utils/api/launcher.ts new file mode 100644 index 0000000..3574bad --- /dev/null +++ b/src/utils/api/launcher.ts @@ -0,0 +1,79 @@ +import ky from 'ky'; +import semver from 'semver'; +import * as TypesApiAkEndfield from '../../types/api/akEndfield/Api.js'; +import appConfig from '../config.js'; +import defaultSettings from './defaultSettings.js'; + +import launcherWeb from './launcherWeb.js'; + +export default { + latestGame: async ( + appCode: string, + launcherAppCode: string, + channel: number, + subChannel: number, + launcherSubChannel: number, + version: string | null, + ): Promise => { + if (version !== null && !semver.valid(version)) throw new Error(`Invalid version string (${version})`); + const rsp = await ky + .get(`https://${appConfig.network.api.akEndfield.base.launcher}/game/get_latest`, { + ...defaultSettings.ky, + searchParams: { + appcode: appCode, + launcher_appcode: launcherAppCode, + channel, + sub_channel: subChannel, + launcher_sub_channel: launcherSubChannel, + version: version ?? undefined, + }, + }) + .json(); + return rsp as TypesApiAkEndfield.LauncherLatestGame; + }, + latestGameResources: async ( + appCode: string, + gameVersion: string, // example: 1.0 + version: string, + randStr: string, + platform: 'Windows' | 'Android' | 'iOS' | 'PlayStation', + ): Promise => { + if (!semver.valid(version)) throw new Error(`Invalid version string (${version})`); + const rsp = await ky + .get(`https://${appConfig.network.api.akEndfield.base.launcher}/game/get_latest_resources`, { + ...defaultSettings.ky, + searchParams: { + appcode: appCode, + game_version: gameVersion, + version: version, + platform, + rand_str: randStr, + }, + }) + .json(); + return rsp as TypesApiAkEndfield.LauncherLatestGameResources; + }, + latestLauncher: async ( + appCode: string, + channel: number, + subChannel: number, + version: string | null, + targetApp: 'EndField' | null, + ): Promise => { + if (version !== null && !semver.valid(version)) throw new Error(`Invalid version string (${version})`); + const rsp = await ky + .get(`https://${appConfig.network.api.akEndfield.base.launcher}/launcher/get_latest`, { + ...defaultSettings.ky, + searchParams: { + appcode: appCode, + channel, + sub_channel: subChannel, + version: version ?? undefined, + targetApp: targetApp ?? undefined, + }, + }) + .json(); + return rsp as TypesApiAkEndfield.LauncherLatestLauncher; + }, + web: launcherWeb, +}; diff --git a/src/utils/api/launcherWeb.ts b/src/utils/api/launcherWeb.ts new file mode 100644 index 0000000..fbb8ca0 --- /dev/null +++ b/src/utils/api/launcherWeb.ts @@ -0,0 +1,152 @@ +import ky from 'ky'; +import * as TypesApiAkEndfield from '../../types/api/akEndfield/Api.js'; +import appConfig from '../config.js'; +import defaultSettings from './defaultSettings.js'; + +export default { + sidebar: async ( + appCode: string, + channel: number, + subChannel: number, + language: (typeof defaultSettings.launcherWebLang)[number], + platform: 'Windows' = 'Windows', + ): Promise => { + const rsp = await ky + .post(`https://${appConfig.network.api.akEndfield.base.launcher}/proxy/web/batch_proxy`, { + ...defaultSettings.ky, + json: { + proxy_reqs: [ + { + kind: 'get_sidebar', + get_sidebar_req: { + appcode: appCode, + channel: String(channel), + sub_channel: String(subChannel), + language, + platform, + source: 'launcher', + }, + }, + ], + }, + }) + .json(); + return (rsp as any).proxy_rsps[0].get_sidebar_rsp as TypesApiAkEndfield.LauncherWebSidebar; + }, + singleEnt: async ( + appCode: string, + channel: number, + subChannel: number, + language: (typeof defaultSettings.launcherWebLang)[number], + platform: 'Windows' = 'Windows', + ): Promise => { + const rsp = await ky + .post(`https://${appConfig.network.api.akEndfield.base.launcher}/proxy/web/batch_proxy`, { + ...defaultSettings.ky, + json: { + proxy_reqs: [ + { + kind: 'get_single_ent', + get_single_ent_req: { + appcode: appCode, + channel: String(channel), + sub_channel: String(subChannel), + language, + platform, + source: 'launcher', + }, + }, + ], + }, + }) + .json(); + return (rsp as any).proxy_rsps[0].get_single_ent_rsp as TypesApiAkEndfield.LauncherWebSingleEnt; + }, + mainBgImage: async ( + appCode: string, + channel: number, + subChannel: number, + language: (typeof defaultSettings.launcherWebLang)[number], + platform: 'Windows' = 'Windows', + ): Promise => { + const rsp = await ky + .post(`https://${appConfig.network.api.akEndfield.base.launcher}/proxy/web/batch_proxy`, { + ...defaultSettings.ky, + json: { + proxy_reqs: [ + { + kind: 'get_main_bg_image', + get_main_bg_image_req: { + appcode: appCode, + channel: String(channel), + sub_channel: String(subChannel), + language, + platform, + source: 'launcher', + }, + }, + ], + }, + }) + .json(); + return (rsp as any).proxy_rsps[0].get_main_bg_image_rsp as TypesApiAkEndfield.LauncherWebMainBgImage; + }, + banner: async ( + appCode: string, + channel: number, + subChannel: number, + language: (typeof defaultSettings.launcherWebLang)[number], + platform: 'Windows' = 'Windows', + ): Promise => { + const rsp = await ky + .post(`https://${appConfig.network.api.akEndfield.base.launcher}/proxy/web/batch_proxy`, { + ...defaultSettings.ky, + json: { + proxy_reqs: [ + { + kind: 'get_banner', + get_banner_req: { + appcode: appCode, + channel: String(channel), + sub_channel: String(subChannel), + language, + platform, + source: 'launcher', + }, + }, + ], + }, + }) + .json(); + return (rsp as any).proxy_rsps[0].get_banner_rsp as TypesApiAkEndfield.LauncherWebBanner; + }, + announcement: async ( + appCode: string, + channel: number, + subChannel: number, + language: (typeof defaultSettings.launcherWebLang)[number], + platform: 'Windows' = 'Windows', + ): Promise => { + const rsp = await ky + .post(`https://${appConfig.network.api.akEndfield.base.launcher}/proxy/web/batch_proxy`, { + ...defaultSettings.ky, + json: { + proxy_reqs: [ + { + kind: 'get_announcement', + get_announcement_req: { + appcode: appCode, + channel: String(channel), + sub_channel: String(subChannel), + language, + platform, + source: 'launcher', + }, + }, + ], + }, + }) + .json(); + return (rsp as any).proxy_rsps[0].get_announcement_rsp as TypesApiAkEndfield.LauncherWebAnnouncement; + }, +}; diff --git a/src/utils/api/u8.ts b/src/utils/api/u8.ts new file mode 100644 index 0000000..af54a9d --- /dev/null +++ b/src/utils/api/u8.ts @@ -0,0 +1,82 @@ +import ky from 'ky'; +import * as TypesApiAkEndfield from '../../types/api/akEndfield/Api.js'; +import appConfig from '../config.js'; +import defaultSettings from './defaultSettings.js'; + +export default { + user: { + auth: { + v2: { + tokenByChToken: async ( + appCode: string, + channelMasterId: number, + channelToken: string, + platform: number = 2, + type: number = 0, + ): Promise => { + const rsp = await ky + .post(`https://${appConfig.network.api.akEndfield.base.u8}/u8/user/auth/v2/token_by_channel_token`, { + ...defaultSettings.ky, + json: { + appCode, + channelMasterId, + channelToken: JSON.stringify({ + code: channelToken, + type: 1, + isSuc: true, + }), + type, + platform, + }, + }) + .json(); + return rsp as TypesApiAkEndfield.U8UserAuthV2ChToken; + }, + grant: async ( + token: string, + platform: number = 2, + type: number = 0, + ): Promise => { + const rsp = await ky + .post(`https://${appConfig.network.api.akEndfield.base.u8}/u8/user/auth/v2/grant`, { + ...defaultSettings.ky, + json: { token, type, platform }, + }) + .json(); + return rsp as TypesApiAkEndfield.U8UserAuthV2Grant; + }, + }, + }, + }, + game: { + server: { + v1: { + serverList: async (token: string): Promise => { + const rsp = await ky + .post(`https://${appConfig.network.api.akEndfield.base.u8}/game/server/v1/server_list`, { + ...defaultSettings.ky, + json: { token }, + }) + .json(); + return rsp as TypesApiAkEndfield.U8GameServerV1ServerList; + }, + }, + }, + role: { + v1: { + confirmServer: async ( + token: string, + serverId: number, + ): Promise => { + const rsp = await ky + .post(`https://${appConfig.network.api.akEndfield.base.u8}/game/role/v1/confirm_server`, { + ...defaultSettings.ky, + json: { token, serverId: String(serverId) }, + }) + .json(); + return rsp as TypesApiAkEndfield.U8GameRoleV1ConfirmServer; + }, + }, + }, + }, +}; diff --git a/src/utils/api/webview.ts b/src/utils/api/webview.ts new file mode 100644 index 0000000..8f5e928 --- /dev/null +++ b/src/utils/api/webview.ts @@ -0,0 +1,40 @@ +import ky from 'ky'; +import * as TypesApiAkEndfield from '../../types/api/akEndfield/Api.js'; +import appConfig from '../config.js'; +import defaultSettings from './defaultSettings.js'; + +export default { + record: { + char: async ( + token: string, + serverId: number, // 2 or 3 + poolType: + | 'E_CharacterGachaPoolType_Beginner' + | 'E_CharacterGachaPoolType_Standard' + | 'E_CharacterGachaPoolType_Special', + seqId: string | null, + lang: (typeof defaultSettings.launcherWebLang)[number] = 'ja-jp', + ): Promise => { + const rsp = await ky + .get(`https://${appConfig.network.api.akEndfield.base.webview}/api/record/char`, { + ...defaultSettings.ky, + searchParams: { lang, seq_id: seqId ?? undefined, pool_type: poolType, token, server_id: serverId }, + }) + .json(); + return rsp as TypesApiAkEndfield.WebViewRecordChar; + }, + }, + content: async ( + serverId: number, // 2 or 3 + poolId: string, + lang: (typeof defaultSettings.launcherWebLang)[number] = 'ja-jp', + ): Promise => { + const rsp = await ky + .get(`https://${appConfig.network.api.akEndfield.base.webview}/api/content`, { + ...defaultSettings.ky, + searchParams: { lang, pool_id: poolId, server_id: serverId }, + }) + .json(); + return rsp as TypesApiAkEndfield.WebViewRecordContent; + }, +}; diff --git a/src/utils/config.ts b/src/utils/config.ts index 77934fe..05aff82 100644 --- a/src/utils/config.ts +++ b/src/utils/config.ts @@ -17,11 +17,12 @@ type ConfigType = AllRequired< akEndfield: { appCode: { game: { osWinRel: string }; - launcher: { osWinRel: string }; + launcher: { osWinRel: string; osWinRelEpic: string }; accountService: { osWinRel: string; skport: string; binding: string }; u8: { osWinRel: string }; }; channel: { osWinRel: number }; + subChannel: { osWinRel: number; osWinRelEpic: number }; base: { accountService: string; launcher: string; @@ -63,11 +64,12 @@ const initialConfig: ConfigType = { akEndfield: { appCode: { game: { osWinRel: 'YDUTE5gscDZ229CW' }, - launcher: { osWinRel: 'TiaytKBUIEdoEwRT' }, + launcher: { osWinRel: 'TiaytKBUIEdoEwRT', osWinRelEpic: 'BBWoqCzuZ2bZ1Dro' }, accountService: { osWinRel: 'd9f6dbb6bbd6bb33', skport: '6eb76d4e13aa36e6', binding: '3dacefa138426cfe' }, u8: { osWinRel: '973bd727dd11cbb6ead8' }, }, channel: { osWinRel: 6 }, + subChannel: { osWinRel: 6, osWinRelEpic: 801 }, base: { accountService: 'YXMuZ3J5cGhsaW5lLmNvbQ==', launcher: 'bGF1bmNoZXIuZ3J5cGhsaW5lLmNvbS9hcGk=',