Last active
May 15, 2024 17:27
-
-
Save LiuQixuan/19791ac41f976dfce3b662f8f383a862 to your computer and use it in GitHub Desktop.
从官网下载不同服版本的差异文件并打包
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#先读我 | |
#脚本需要PowerShell 7.0+环境 在终端中执行命令: `winget install Microsoft.PowerShell` 自动安装PowerShell 7.0+ | |
#configPath为配置文件,配置文件获取地址: https://gist.github.com/LiuQixuan/205c6f4cc38b3a45ccd8d2592155e026 | |
$configPath = "G:\Setup\GenshinImpact\creatDiffPackage\backup_config.json" | |
$startPageData = [PSCustomObject]@{ | |
title = "差异化文件创建脚本" | |
description = "欢迎使用差异化文件创建脚本,请按照提示一步一步操作" | |
gameversion = "检测到当前安装了{0},版本号为{1},路径为{2}" | |
selection = "数字键键入您的需求:" | |
activity = @("替换资源下载进度", "子项目进度") | |
status = @("下载总进度:", "{0}版本下载进度:") | |
currentOperation = "正在下载{0}版本的{1}文件..." | |
optgroups = @( | |
@{ | |
text = "下载" | |
opts = [ordered]@{ | |
'1' = '下载国际服差异文件' | |
'2' = '下载国服差异文件' | |
'3' = '下载双服差异文件' | |
} | |
alert = "按enter键开始下载,esc返回开始页面,ctrl+C放弃操作退出脚本" | |
after = "按enter键开始打包差异文件,esc返回开始页面,ctrl+C放弃操作退出脚本" | |
rank = 1 | |
} | |
@{ | |
text = "后续操作" | |
opts = [ordered]@{ | |
c = '清理缓存' | |
x = '清理所有已下载的文件' | |
} | |
alert = "即将清理文件夹按任意键确认清理,ctrl+C放弃操作,ctrl+C放弃操作退出脚本" | |
after = "清理完成,按任意键返回开始页面" | |
rank = 2 | |
} | |
) | |
configPath = $configPath | |
} | |
function Get-GameVersion([string]$path) { | |
(Select-String -Path (Join-Path -path $path -ChildPath 'config.ini') -Pattern 'game_version=(?<version>[\d|\.]+)').Matches[0].Groups['version'].Value | |
} | |
function Get-GameServeVersion() { | |
$regItem = Get-Item -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FeatureUsage\AppSwitched" | |
$pathlist = $regItem.GetValueNames() | Where-Object { $_ -Match '(genshin)|(yuanshen)' } | |
$result = @{OSREL = $null; CNREL = $null } | |
$pathlist.ForEach({ | |
if ((Split-Path $_ -Leaf) -eq "genshinImpact.exe") { | |
$result.OSREL = @{path = $null; version = $null } | |
$result.OSREL.path = Split-Path $_ | |
} | |
elseif ((Split-Path $_ -Leaf) -eq "yuanshen.exe") { | |
$result.CNREL = @{path = $null; version = $null } | |
$result.CNREL.path = Split-Path $_ | |
} | |
elseif (((Split-Path $_ -Leaf) -eq "launcher.exe") -or ((Split-Path $_ | Split-Path -Leaf) -eq "Genshin Impact")) { | |
if ((Get-ChildItem -Path (Join-Path -Path (Split-Path $_) -ChildPath "Genshin Impact game") -Directory | Join-String -Property Name -Separator '') -match "genshin") { | |
$result.OSREL = @{path = $null; version = $null } | |
$result.OSREL.path = (Join-Path -Path (Split-Path $_) -ChildPath "Genshin Impact game") | |
} | |
else { | |
$result.CNREL = @{path = $null; version = $null } | |
$result.CNREL.path = (Join-Path -Path (Split-Path $_) -ChildPath "Genshin Impact game") | |
} | |
} | |
}) | |
$result.keys | ForEach-Object { if ($null -ne $result[$_]) { $result[$_]['version'] = Get-GameVersion -Path $result[$_].path } } | |
return $result | |
} | |
class TaskManager { | |
$config = @{} | |
download([string]$url, [string]$path) { | |
try { | |
Invoke-WebRequest -Uri $url -OutFile $path | |
} | |
catch { | |
Write-Error ("<{0}> download fail." -f $url) | |
("<{0}> download fail." -f $url)>>(Join-Path -Path $PSScriptRoot -ChildPath ("./debug.creatDiffPackage_{0}.log" -f (Get-Date -Format 'yyyy-MM-dd-HH-mm-ss'))) | |
} | |
} | |
[PSCustomObject]getScatteredURL([string]$vkey) { | |
$urls = "https://sdk-os-static.mihoyo.com/hk4e_global/mdk/launcher/api/resource?launcher_id=10&key=gcStgarh", "https://sdk-static.mihoyo.com/hk4e_cn/mdk/launcher/api/resource?launcher_id=18&key=eYd89JmJ" | |
$url = $null | |
$scatteredURL = $null | |
switch ($vkey) { | |
'OSREL' { | |
$url = $urls[0] | |
break | |
} | |
'CNREL' { | |
$url = $urls[1] | |
break | |
} | |
Default { | |
Write-Error "Error,vKey." | |
} | |
} | |
if ($null -ne $url) { | |
$respose = Invoke-WebRequest -Uri $url -Method Get -ContentType 'text/plain' | |
$json = ConvertFrom-Json -InputObject $respose.Content | |
if ($json.retcode -eq 0) { | |
$this.config['resVersion'] = $json.data.game.latest.version | |
$scatteredURL = $json.data.game.latest.decompressed_path | |
#Write-Host $name,$json.data.game.latest.entry | |
#Out-File -FilePath (Join-Path -Path $PSScriptRoot -ChildPath ("./{0}_v{1}-{2}.json" -f $name, $version, (Get-Date -UFormat "%Y_%m_%d_%H_%M"))) -Encoding utf8 -InputObject $respose.Content | |
} | |
else { | |
Write-Host "bad request." | |
} | |
} | |
return $scatteredURL | |
} | |
TaskManager($data) { | |
#todo | |
$this.config.data = $data | |
$this.initianlizing() | |
} | |
[void]run() { | |
$this.prompting() | |
# $this.configuring() | |
# $this.writing() | |
# $this.conflicts() | |
# $this.install() | |
# $this.end() | |
} | |
initianlizing() { | |
#todo | |
$global:host.ui.RawUI.WindowTitle = $this.config.data.title | |
Write-Host "initianlizing!" | |
if (Test-Path -Path ( Join-Path -Path $PSScriptRoot -ChildPath 'release')) { | |
$this.config['historyVersion'] = Get-ChildItem -Path (Join-Path $PSScriptRoot -ChildPath 'release') | ForEach-Object { $_.Name } | |
# Write-Host $this.config.historyVersion | |
} | |
$this.config['currentVersion'] = Get-GameServeVersion | |
$this.config['versionTag'] = @{OSREL = "GenshinImpact"; CNREL = "YuanShen" } | |
$this.run() | |
} | |
printTitle($data) { | |
Write-Host ($data.description) -ForegroundColor red -BackgroundColor White | |
} | |
printProgress($ddata) { | |
Write-Progress -Id 0 -Activity $this.config.data.activity[0] -Status $this.config.data.status[0] -PercentComplete ([Math]::Round($ddata.i / $ddata.total * 100)) -Completed | |
Write-Progress -Id 1 -ParentId 0 -Activity $this.config.data.activity[1] -Status ($this.config.data.status[1] -f $ddata.vKey) -PercentComplete ([Math]::Round($ddata.i / $ddata.all * 100)) -CurrentOperation ($this.config.data.currentOperation -f $ddata.vKey, $ddata.name) -Completed | |
} | |
printStartPage($data) { | |
$this.printTitle($data) | |
foreach ($_ in $this.config.currentVersion.keys) { | |
if ($null -ne $this.config.currentVersion[$_]) { | |
$tmp = $this.config.currentVersion[$_].Values.ForEach({ $_ }) | |
Write-Host ($this.config.data.gameversion -f @($_, $tmp[1], $tmp[0])) | |
} | |
} | |
Write-Host $data.selection | |
$opt = $data.optgroups[0] | |
Write-Host $opt.text | |
$opt.opts.keys.foreach({Write-Host ("`t[{0}]`t{1}" -f $_,$opt.opts[$_])}) | |
} | |
[PSCustomObject]getFileList() { | |
$coreFileList = @() | |
$otherFileList = @{'OSREL'=@();'CNREL'=@()} | |
$coreJson = Get-Content -Path $this.config.data.configPath -Raw | ConvertFrom-Json | |
$this.config['configVersion'] = $coreJson.gameVersion | |
$coreJson.copyTasks.foreach({ | |
$dir = $_.dir | |
$_.items.foreach({ | |
if ('String' -ne $_.getType()) { | |
#$_.foreach({ Write-Host "-ne>>>>>"$_ ; $coreFileList+=($_.filename.replace('LANGUAGE', $lang)) }) | |
} | |
else { | |
$coreFileList += (('' -ne $dir)?(Join-Path $dir -ChildPath $_):$_) | |
} | |
}) | |
}) | |
#$coreJson.includeItems.foreach({ if($_.language.contains($lang)){$_.list.foreach({$coreFileList+=( $_.replace('Data',"{0}_Data" -f $gameName))})} }) | |
$coreJson.includeItems.foreach({ $list = $_.list; $_.version.foreach({ $i = $_; $list.foreach({ $otherFileList[$i] += $this.config.versionTag[$i]+$_ }) }) }) | |
# $coreJson.includeItems.foreach({ $_.list.foreach({ $otherFileList[$_.version] += $gameName }) }) | |
return @($coreFileList, $otherFileList) | |
} | |
[PSCustomObject]getDownloadList([array]$vKeys) { | |
$result = @{'OSREL' = @(); 'CNREL' = @() } | |
$FileLists = $this.getFileList() | |
write-host ">>>"$FileLists[1]['OSREL'] $FileLists[1]['CNREL'] | |
$vKeys.foreach({ | |
$lang = $null | |
$gameName = $null | |
$vkey = $_ | |
switch ($vkey) { | |
'OSREL' { | |
$lang = 'English' | |
$gameName = 'GenshinImpact' | |
break | |
} | |
'CNREL' { | |
$lang = 'Chinese' | |
$gameName = 'YuanShen' | |
break | |
} | |
Default { | |
Write-Error "Error,vKey." | |
} | |
} | |
$scatteredURL = $this.getScatteredURL($_) | |
# Write-Debug $scatteredURL | |
$FileLists[0].foreach({ | |
$result[$vkey] += ('{0}/{1}' -f $scatteredURL, ($_.StartsWith('Data')? ("{0}_{1}" -f $gameName, $_):($_.StartsWith('Audio')?$_.replace('LANGUAGE', $lang):$_))) | |
}) | |
$FileLists[1][$vkey].foreach({ | |
$result[$vkey] += ('{0}/{1}' -f $scatteredURL, ($_.StartsWith('Data')? ("{0}_{1}" -f $gameName, $_):("{0}{1}" -f $gameName, $_) )) | |
}) | |
}) | |
return $result | |
} | |
printDownloadPage($vKeys) { | |
$scatteredURLs = $this.getDownloadList($vKeys ) | |
# Write-Host ">>>>>>"$scatteredURLs['CNREL'] | |
$total = 0 | |
$vKeys.foreach({ | |
# Write-Host ">>>>>"$_, $scatteredURLs[$_].count | |
$total += $scatteredURLs[$_].count | |
}) | |
$vKeys.foreach({ | |
$vKey = $_ | |
$dpath = Join-Path -Path $PSScriptRoot -ChildPath ('./release/{0}/{1}' -f $this.config.resVersion, $_) | |
New-Item -ItemType Directory -Path $dpath -Force | |
for ($i = 0; $i -lt $scatteredURLs[$_].Length; ++$i) { | |
$filePath = Join-Path -Path $dpath -ChildPath $scatteredURLs[$_][$i].split('ScatteredFiles/')[1] | |
if(-not (Test-Path -Path (Split-Path -path $filePath))){ | |
New-Item -ItemType Directory -Path (Split-Path -Path $filePath) | |
} | |
$this.download($scatteredURLs[$_][$i],$filePath) | |
# Start-Sleep -Milliseconds 250 | |
$ddata = @{vKey = $vKey; name = $scatteredURLs[$_][$i].split('ScatteredFiles/')[1]; total = $total; all = $scatteredURLs[$_].Length; i = $i } | |
# $this.printProgress($ddata) | |
Write-Progress -Id 0 -Activity $this.config.data.activity[0] -Status $this.config.data.status[0] -PercentComplete ([Math]::Round($ddata.i / $ddata.total * 100)) | |
Write-Progress -Id 1 -ParentId 0 -Activity $this.config.data.activity[1] -Status ($this.config.data.status[1] -f $ddata.vKey) -PercentComplete ([Math]::Round($ddata.i / $ddata.all * 100)) -CurrentOperation ($this.config.data.currentOperation -f $ddata.vKey, $ddata.name) | |
} | |
}) | |
Clear-History | |
} | |
printClearPage() { | |
} | |
compressZip(){ | |
$releasePath = Join-Path -Path $PSScriptRoot -ChildPath ('./release/{0}' -f $this.config.resVersion) | |
Compress-Archive -Path $releasePath -CompressionLevel Optimal -DestinationPath (Join-Path -Path $PSScriptRoot -ChildPath ('./release/release_v{0}.zip' -f $this.config.resVersion)) | |
} | |
clearTmp(){ | |
Get-ChildItem -Path (Join-Path -Path $PSScriptRoot -ChildPath 'release') | Where-Object -Property 'Attributes' -EQ 'Directory'|Remove-Item -Force -Recurse | |
} | |
prompting() { | |
#todo | |
$vKey = @('CNREL', 'OSREL') | |
$this.printStartPage($this.config.data) | |
$userInput = Read-Host $this.config.data.optgroups[0].alert | |
switch ($userInput) { | |
"1" { | |
$vKey = @('OSREL') | |
break | |
} | |
"2" { | |
$vKey = @('CNREL') | |
break | |
} | |
"3" { | |
# $vKey = @('CNREL', 'OSREL') | |
break | |
} | |
Default { | |
Write-Error "[ERROR]:input Error key." | |
Write-Error "Script will download all server version files." | |
} | |
} | |
$this.printDownloadPage($vKey) | |
Read-Host $this.config.data.optgroups[0].after | |
$this.compressZip() | |
Read-Host $this.config.data.optgroups[1].alert | |
$this.clearTmp() | |
Read-Host $this.config.data.optgroups[1].after | |
Clear-Host | |
$this.printStartPage($this.config.data) | |
} | |
configuring() { | |
#todo | |
} | |
writing() { | |
#todo | |
} | |
conflicts() { | |
#todo | |
} | |
install() { | |
#todo | |
} | |
end(){ | |
#todo | |
Read-Host "按任意键退出" | |
} | |
} | |
$taskManager = [TaskManager]::new($startPageData) | |
$taskManager.end() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment