64 lines
3.8 KiB
PowerShell
64 lines
3.8 KiB
PowerShell
[CmdletBinding(SupportsShouldProcess)]
|
|
param(
|
|
[Parameter(Mandatory=$true)][string]$WebglRoot,
|
|
[string]$PatchZip = ''
|
|
)
|
|
$ErrorActionPreference = 'Stop'
|
|
if (-not $PatchZip) { $PatchZip = Join-Path $PSScriptRoot 'Client-BuddyDefense-15888.zip' }
|
|
$PatchZip = (Resolve-Path -LiteralPath $PatchZip).Path
|
|
$WebglRoot = (Resolve-Path -LiteralPath $WebglRoot).Path
|
|
if (-not (Test-Path -LiteralPath $WebglRoot -PathType Container)) { throw 'WebglRoot must be an existing website directory.' }
|
|
$versionPath = Join-Path $WebglRoot 'cdn/version.json'
|
|
if (-not (Test-Path -LiteralPath $versionPath) -and
|
|
-not (Get-ChildItem -LiteralPath $WebglRoot -Filter '*.webgl.data.unityweb.bin.txt' -File | Select-Object -First 1)) {
|
|
throw 'This does not look like the existing /game/Friends/webgl website folder. Choose the website folder, not the AIServer folder.'
|
|
}
|
|
Add-Type -AssemblyName System.IO.Compression.FileSystem
|
|
$archive = [IO.Compression.ZipFile]::OpenRead($PatchZip)
|
|
try {
|
|
$contents = @{}
|
|
foreach ($entry in $archive.Entries) {
|
|
$name = $entry.FullName.Replace('\','/')
|
|
if ($name -ne 'cdn/version.json' -and $name -notmatch '^yoo/DefaultPackage/[A-Za-z0-9_.-]+$') {
|
|
throw "Unexpected patch entry: $name"
|
|
}
|
|
if ($contents.ContainsKey($name) -or $entry.Length -gt 5242880) { throw "Invalid patch entry: $name" }
|
|
$reader = $entry.Open(); $memory = New-Object IO.MemoryStream
|
|
try { $reader.CopyTo($memory); $contents[$name] = $memory.ToArray() }
|
|
finally { $reader.Dispose(); $memory.Dispose() }
|
|
}
|
|
} finally { $archive.Dispose() }
|
|
if ($contents.Count -ne 5 -or -not $contents.ContainsKey('cdn/version.json')) { throw 'Expected the five-file hot-update patch.' }
|
|
$version = [Text.Encoding]::UTF8.GetString($contents['cdn/version.json']) | ConvertFrom-Json
|
|
if ($version.packVersion -notmatch '^[a-f0-9]{32}$') { throw 'Invalid packVersion.' }
|
|
$indexName = "yoo/DefaultPackage/DefaultPackage_$($version.packVersion).bytes"
|
|
if (-not $contents.ContainsKey($indexName)) { throw 'Version refers to a missing manifest.' }
|
|
$md5 = [Security.Cryptography.MD5]::Create()
|
|
try { $indexHash = [BitConverter]::ToString($md5.ComputeHash($contents[$indexName])).Replace('-','').ToLowerInvariant() }
|
|
finally { $md5.Dispose() }
|
|
if ($indexHash -ne $version.packVersion) { throw 'Manifest MD5 does not match packVersion. Nothing published.' }
|
|
$changed = 0
|
|
if ($PSCmdlet.ShouldProcess($WebglRoot,"Publish pack $($version.packVersion); write cdn/version.json last")) {
|
|
# Content-addressed resources must exist before exposing the new global version.
|
|
$names = @($contents.Keys | Where-Object { $_ -ne 'cdn/version.json' } | Sort-Object) + @('cdn/version.json')
|
|
foreach ($name in $names) {
|
|
$target = Join-Path $WebglRoot $name
|
|
if (Test-Path -LiteralPath $target) {
|
|
$old = [IO.File]::ReadAllBytes($target)
|
|
if ([Convert]::ToBase64String($old) -eq [Convert]::ToBase64String($contents[$name])) { continue }
|
|
}
|
|
New-Item -ItemType Directory -Path (Split-Path -Parent $target) -Force | Out-Null
|
|
if ($name -eq 'cdn/version.json') {
|
|
$temporary = "$target.publish-$([Guid]::NewGuid().ToString('N')).tmp"
|
|
try {
|
|
[IO.File]::WriteAllBytes($temporary,$contents[$name])
|
|
if (Test-Path -LiteralPath $target) { [IO.File]::Replace($temporary,$target,"$target.previous") }
|
|
else { [IO.File]::Move($temporary,$target) }
|
|
} finally { if (Test-Path -LiteralPath $temporary) { Remove-Item -LiteralPath $temporary } }
|
|
} else { [IO.File]::WriteAllBytes($target,$contents[$name]) }
|
|
$changed++
|
|
Write-Output "Published $name"
|
|
}
|
|
Write-Output "Done: packVersion=$($version.packVersion); changedFiles=$changed. Check the public cdn/version.json, then restart the mini game."
|
|
}
|