From 166f873669f2cb70750860121736c18b72b81bf4 Mon Sep 17 00:00:00 2001 From: MrMaho Date: Fri, 2 Oct 2026 23:51:08 +0200 Subject: [PATCH] release.ps1: build the multipart upload by hand Windows PowerShell (.NET Framework) writes form-data names without quotes and a quoted boundary, which the keymaster's parser rejected ("Send multipart/form-data"). Saved with BOM so PowerShell 5.1 reads the umlauts correctly. Co-Authored-By: Claude Opus 5.5 --- release.ps1 | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/release.ps1 b/release.ps1 index 7eb0530..2c9b53f 100644 --- a/release.ps1 +++ b/release.ps1 @@ -1,4 +1,4 @@ -# Neue Version automatisch auf den Keymaster hochladen (msco.mbm.wtf -> /download, Launcher-Updates). +# Neue Version automatisch auf den Keymaster hochladen (msco.mbm.wtf -> /download, Launcher-Updates). # Läuft nach dem Release-Build von selbst (MSCO.csproj bzw. MSCO.Launcher.csproj) - oder von Hand: # powershell -ExecutionPolicy Bypass -File release.ps1 -Product mod -File bin\Release\MSCO.dll # @@ -57,12 +57,21 @@ Add-Type -AssemblyName System.Net.Http $client = New-Object System.Net.Http.HttpClient $client.Timeout = [TimeSpan]::FromMinutes(10) $client.DefaultRequestHeaders.Authorization = New-Object System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", $token) -$form = New-Object System.Net.Http.MultipartFormDataContent -$form.Add((New-Object System.Net.Http.StringContent($Product)), "product") -$form.Add((New-Object System.Net.Http.StringContent($Version)), "version") -$form.Add((New-Object System.Net.Http.StringContent($Changelog)), "changelog") +# Multipart von Hand: Windows PowerShell (.NET Framework) schreibt name=... ohne Anführungszeichen und die Boundary in +# Anführungszeichen - das lehnt der Parser des Keymasters (Node/undici) ab. +$boundary = "----MSCO" + [Guid]::NewGuid().ToString("N") +$utf8 = New-Object System.Text.UTF8Encoding($false) +$body = New-Object System.IO.MemoryStream +function Write-Text([string]$text) { $b = $utf8.GetBytes($text); $body.Write($b, 0, $b.Length) } +foreach ($field in @(@("product", $Product), @("version", $Version), @("changelog", $Changelog))) { + Write-Text "--$boundary`r`nContent-Disposition: form-data; name=`"$($field[0])`"`r`nContent-Type: text/plain; charset=utf-8`r`n`r`n$($field[1])`r`n" +} $bytes = [System.IO.File]::ReadAllBytes((Resolve-Path $File)) -$form.Add((New-Object System.Net.Http.ByteArrayContent(,$bytes)), "file", [System.IO.Path]::GetFileName($File)) +Write-Text "--$boundary`r`nContent-Disposition: form-data; name=`"file`"; filename=`"$([System.IO.Path]::GetFileName($File))`"`r`nContent-Type: application/octet-stream`r`n`r`n" +$body.Write($bytes, 0, $bytes.Length) +Write-Text "`r`n--$boundary--`r`n" +$form = New-Object System.Net.Http.ByteArrayContent(,$body.ToArray()) +$form.Headers.TryAddWithoutValidation("Content-Type", "multipart/form-data; boundary=$boundary") | Out-Null try { $res = $client.PostAsync("$keymaster/api/releases/upload", $form).GetAwaiter().GetResult()