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