Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -94,15 +94,18 @@ jobs:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha || github.sha }}

- name: Check docs metadata sync
shell: pwsh
run: ./tools/sync-doc-metadata.ps1 -Mode check

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}

- name: Restore dependencies
run: dotnet restore ${{ env.PROJECT_PATH }}

- name: Check docs metadata sync
shell: pwsh
run: ./tools/sync-doc-metadata.ps1 -Mode check

- name: Install GitVersion
uses: gittools/actions/gitversion/[email protected]
with:
Expand All @@ -126,9 +129,6 @@ jobs:
echo "Patch: ${{ steps.gitversion.outputs.patch }}"
echo "InformationalVersion: ${{ steps.gitversion.outputs.informationalVersion }}"

- name: Restore dependencies
run: dotnet restore ${{ env.PROJECT_PATH }}

- name: Build Publisher
run: dotnet build --no-restore ${{ env.PUBLISHER_PATH }} -c Release

Expand Down
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# UnifierTSL
# UnifierTSL

> Languages: [English](./README.md) | [简体中文](./docs/README.zh-cn.md)

Expand Down Expand Up @@ -84,13 +84,13 @@ Some heavier implementations may stay outside launcher core, but you can expect
## 📊 Version Matrix

<!-- BEGIN:version-matrix -->
The baseline values below come straight from project files and runtime version helpers in this repository:
The baseline values below come straight from project files and restored package assets used by this repository:

| Component | Version | Source |
|:--|:--|:--|
| Target framework | `.NET 9.0` | `src/UnifierTSL/*.csproj` |
| Terraria | `1.4.5.5` | `src/UnifierTSL/VersionHelper.cs` (assembly file version from OTAPI/Terraria runtime) |
| OTAPI USP | `1.1.0-pre-release-upstream.29` | `src/UnifierTSL/UnifierTSL.csproj` |
| Terraria | `1.4.5.6` | restored `OTAPI.dll` resolved via `src/UnifierTSL/obj/project.assets.json` (assembly file version) |
| OTAPI USP | `1.1.0-pre-release-upstream.30` | `src/UnifierTSL/UnifierTSL.csproj` |

<details>
<summary><strong>TShock and dependency details</strong></summary>
Expand Down Expand Up @@ -543,3 +543,5 @@ This table reflects the currently maintained/documented packaging targets, not e
<sub>Made with ❤️ by the UnifierTSL contributors · Licensed under GPL-3.0</sub>
</p>



8 changes: 5 additions & 3 deletions docs/README.zh-cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,13 @@ UnifierTSL 把 [OTAPI Unified Server Process](https://github.com/CedaryCat/OTAPI
## 📊 版本矩阵

<!-- BEGIN:version-matrix -->
下面这些基线值直接来自仓库内项目文件与运行时版本辅助逻辑
下面这些基线值直接来自仓库内项目文件与该仓库实际使用的已还原包资产

| 组件 | 版本 | 来源 |
|:--|:--|:--|
| 目标框架 | `.NET 9.0` | `src/UnifierTSL/*.csproj` |
| Terraria | `1.4.5.5` | `src/UnifierTSL/VersionHelper.cs`(从 OTAPI/Terraria 运行时程序集文件版本读取) |
| OTAPI USP | `1.1.0-pre-release-upstream.29` | `src/UnifierTSL/UnifierTSL.csproj` |
| Terraria | `1.4.5.6` | 通过 `src/UnifierTSL/obj/project.assets.json` 定位已还原的 `OTAPI.dll`(程序集文件版本) |
| OTAPI USP | `1.1.0-pre-release-upstream.30` | `src/UnifierTSL/UnifierTSL.csproj` |

<details>
<summary><strong>TShock 与依赖详情</strong></summary>
Expand Down Expand Up @@ -543,3 +543,5 @@ dotnet run --project src/UnifierTSL.Publisher/UnifierTSL.Publisher.csproj -- \
<sub>Made with ❤️ by the UnifierTSL contributors · Licensed under GPL-3.0</sub>
</p>



2 changes: 1 addition & 1 deletion src/UnifierTSL/UnifierTSL.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="OTAPI.USP" Version="1.1.0-pre-release-upstream.29" />
<PackageReference Include="OTAPI.USP" Version="1.1.0-pre-release-upstream.30" />
<PackageReference Include="ModFramework" Version="1.1.15" />
<PackageReference Include="MonoMod.RuntimeDetour" Version="25.2.3" />
<PackageReference Include="MonoMod.RuntimeDetour.HookGen" Version="22.7.31.1" />
Expand Down
156 changes: 149 additions & 7 deletions tools/sync-doc-metadata.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,147 @@ function Get-PackageVersion {
return [string]$node.Version
}

function Get-RestoreAssets {
param(
[Parameter(Mandatory = $true)]
[string]$Path,
[Parameter(Mandatory = $true)]
[string]$ProjectPath
)

if (-not (Test-Path -LiteralPath $Path)) {
throw "Could not locate restore assets '$Path'. Run: dotnet restore '$ProjectPath'"
}

return (Get-Content -Path $Path -Raw -Encoding UTF8 | ConvertFrom-Json)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): project.assets.json is deeply nested and may be truncated without an explicit ConvertFrom-Json -Depth

On Windows PowerShell, ConvertFrom-Json defaults to -Depth 2, which will silently truncate this deeply nested file and can lead to subtle runtime issues when accessing nested properties. Please specify an explicit depth (e.g. ConvertFrom-Json -Depth 100) so the assets file is fully parsed across PowerShell versions.

}

function Convert-NuGetRelativePath {
param(
[Parameter(Mandatory = $true)]
[string]$Path
)

return ($Path -replace '[\\/]', [System.IO.Path]::DirectorySeparatorChar)
}

function Get-RestoredPackageLibrary {
param(
[Parameter(Mandatory = $true)]
[psobject]$Assets,
[Parameter(Mandatory = $true)]
[string]$PackageId
)

$pattern = '^{0}/' -f [regex]::Escape($PackageId)
$library = $Assets.libraries.PSObject.Properties |
Where-Object { $_.Name -imatch $pattern } |
Select-Object -First 1

if ($null -eq $library) {
throw "Could not locate restored package '$PackageId' in project assets."
}

return $library
}

function Get-RestoredTargetPackageEntry {
param(
[Parameter(Mandatory = $true)]
[psobject]$Assets,
[Parameter(Mandatory = $true)]
[string]$TargetFramework,
[Parameter(Mandatory = $true)]
[string]$PackageLibraryName
)

$target = $Assets.targets.PSObject.Properties |
Where-Object { $_.Name -eq $TargetFramework -or $_.Name -like "$TargetFramework/*" } |
Where-Object { $_.Value.PSObject.Properties.Name -contains $PackageLibraryName } |
Select-Object -First 1

if ($null -eq $target) {
throw "Could not locate restore target entry for '$PackageLibraryName' under '$TargetFramework'."
}

return $target.Value.PSObject.Properties[$PackageLibraryName].Value
}

function Resolve-RestoredPackageAssetPath {
param(
[Parameter(Mandatory = $true)]
[psobject]$Assets,
[Parameter(Mandatory = $true)]
[string]$TargetFramework,
[Parameter(Mandatory = $true)]
[string]$PackageId,
[Parameter(Mandatory = $true)]
[string]$AssetFileName,
[Parameter(Mandatory = $true)]
[string]$ProjectPath
)

$library = Get-RestoredPackageLibrary -Assets $Assets -PackageId $PackageId
$targetPackage = Get-RestoredTargetPackageEntry -Assets $Assets -TargetFramework $TargetFramework -PackageLibraryName $library.Name
$runtimeAssets = @($targetPackage.runtime.PSObject.Properties)
Comment on lines +130 to +132
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Handle missing runtime assets more gracefully to avoid null-reference errors

If the resolved package entry has no runtime section (or it’s empty), $targetPackage.runtime will be $null and this line will throw a generic null-reference error. Please add an explicit $null check before accessing .runtime and raise a clearer, targeted error when no runtime assets exist for the resolved package/TFM, consistent with the other guarded cases in this script.

Suggested change
$library = Get-RestoredPackageLibrary -Assets $Assets -PackageId $PackageId
$targetPackage = Get-RestoredTargetPackageEntry -Assets $Assets -TargetFramework $TargetFramework -PackageLibraryName $library.Name
$runtimeAssets = @($targetPackage.runtime.PSObject.Properties)
$library = Get-RestoredPackageLibrary -Assets $Assets -PackageId $PackageId
$targetPackage = Get-RestoredTargetPackageEntry -Assets $Assets -TargetFramework $TargetFramework -PackageLibraryName $library.Name
if (-not $targetPackage.runtime) {
throw "Restored package '$PackageId' for target framework '$TargetFramework' does not contain any runtime assets."
}
$runtimeAssets = @($targetPackage.runtime.PSObject.Properties)

$assetRelativePath = $runtimeAssets |
Where-Object { [System.IO.Path]::GetFileName([string]$_.Name) -ieq $AssetFileName } |
Select-Object -ExpandProperty Name -First 1

if ([string]::IsNullOrWhiteSpace($assetRelativePath)) {
throw "Could not locate runtime asset '$AssetFileName' for restored package '$PackageId'."
}

$packageRelativePath = Convert-NuGetRelativePath -Path ([string]$library.Value.path)
$normalizedAssetRelativePath = Convert-NuGetRelativePath -Path $assetRelativePath
$assetPath = $Assets.packageFolders.PSObject.Properties.Name |
ForEach-Object {
Join-Path (Join-Path $_ $packageRelativePath) $normalizedAssetRelativePath
} |
Where-Object { Test-Path -LiteralPath $_ } |
Select-Object -First 1

if ([string]::IsNullOrWhiteSpace($assetPath)) {
throw "Could not resolve restored asset '$AssetFileName' for package '$PackageId'. Run: dotnet restore '$ProjectPath'"
}

return $assetPath
}

function Get-AssemblyFileVersion {
param(
[Parameter(Mandatory = $true)]
[string]$Path
)

$fileVersion = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($Path).FileVersion
if ([string]::IsNullOrWhiteSpace($fileVersion)) {
throw "Could not read assembly file version from '$Path'."
}

return $fileVersion
}

function Get-TerrariaVersionFromRestoreAssets {
param(
[Parameter(Mandatory = $true)]
[psobject]$Assets,
[Parameter(Mandatory = $true)]
[string]$TargetFramework,
[Parameter(Mandatory = $true)]
[string]$ProjectPath
)

$otapiPath = Resolve-RestoredPackageAssetPath `
-Assets $Assets `
-TargetFramework $TargetFramework `
-PackageId 'OTAPI.USP' `
-AssetFileName 'OTAPI.dll' `
-ProjectPath $ProjectPath

return Get-AssemblyFileVersion -Path $otapiPath
}

function Convert-TargetFrameworkDisplay {
param(
[Parameter(Mandatory = $true)]
Expand All @@ -68,12 +209,12 @@ function Build-EnglishVersionBlock {

$lines = @(
'<!-- BEGIN:version-matrix -->',
'The baseline values below come straight from project files and runtime version helpers in this repository:',
'The baseline values below come straight from project files and restored package assets used by this repository:',
'',
'| Component | Version | Source |',
'|:--|:--|:--|',
('| Target framework | `{0}` | `src/UnifierTSL/*.csproj` |' -f $Metadata.TargetFrameworkDisplay),
'| Terraria | `1.4.5.5` | `src/UnifierTSL/VersionHelper.cs` (assembly file version from OTAPI/Terraria runtime) |',
('| Terraria | `{0}` | restored `OTAPI.dll` resolved via `src/UnifierTSL/obj/project.assets.json` (assembly file version) |' -f $Metadata.TerrariaVersion),
('| OTAPI USP | `{0}` | `src/UnifierTSL/UnifierTSL.csproj` |' -f $Metadata.OTAPIUSPVersion),
'',
'<details>',
Expand Down Expand Up @@ -111,12 +252,12 @@ function Build-ChineseVersionBlock {

$lines = @(
'<!-- BEGIN:version-matrix -->',
'下面这些基线值直接来自仓库内项目文件与运行时版本辅助逻辑:',
'下面这些基线值直接来自仓库内项目文件与该仓库实际使用的已还原包资产:',
'',
'| 组件 | 版本 | 来源 |',
'|:--|:--|:--|',
('| 目标框架 | `{0}` | `src/UnifierTSL/*.csproj` |' -f $Metadata.TargetFrameworkDisplay),
'| Terraria | `1.4.5.5` | `src/UnifierTSL/VersionHelper.cs`(从 OTAPI/Terraria 运行时程序集文件版本读取) |',
('| Terraria | `{0}` | 通过 `src/UnifierTSL/obj/project.assets.json` 定位已还原的 `OTAPI.dll`(程序集文件版本) |' -f $Metadata.TerrariaVersion),
('| OTAPI USP | `{0}` | `src/UnifierTSL/UnifierTSL.csproj` |' -f $Metadata.OTAPIUSPVersion),
'',
'<details>',
Expand Down Expand Up @@ -187,11 +328,13 @@ function Sync-MarkedBlock {
$repoRoot = (Resolve-Path (Join-Path $PSScriptRoot '..')).Path
$unifierCsproj = Join-Path $repoRoot 'src/UnifierTSL/UnifierTSL.csproj'
$tshockCsproj = Join-Path $repoRoot 'src/Plugins/TShockAPI/TShockAPI.csproj'
$restoreAssetsPath = Join-Path $repoRoot 'src/UnifierTSL/obj/project.assets.json'
$readmeEn = Join-Path $repoRoot 'README.md'
$readmeZh = Join-Path $repoRoot 'docs/README.zh-cn.md'

$unifierXml = Get-ProjectXml -Path $unifierCsproj
$tshockXml = Get-ProjectXml -Path $tshockCsproj
$restoreAssets = Get-RestoreAssets -Path $restoreAssetsPath -ProjectPath $unifierCsproj

$unifierProps = $unifierXml.Project.PropertyGroup | Select-Object -First 1
$tshockProps = $tshockXml.Project.PropertyGroup | Select-Object -First 1
Expand All @@ -203,6 +346,7 @@ if ([string]::IsNullOrWhiteSpace($targetFramework)) {

$metadata = @{
TargetFrameworkDisplay = Convert-TargetFrameworkDisplay -TargetFramework $targetFramework
TerrariaVersion = Get-TerrariaVersionFromRestoreAssets -Assets $restoreAssets -TargetFramework $targetFramework -ProjectPath $unifierCsproj
OTAPIUSPVersion = Get-PackageVersion -ProjectXml $unifierXml -PackageId 'OTAPI.USP'
ModFrameworkVersion = Get-PackageVersion -ProjectXml $unifierXml -PackageId 'ModFramework'
MonoModRuntimeDetourVersion = Get-PackageVersion -ProjectXml $unifierXml -PackageId 'MonoMod.RuntimeDetour'
Expand All @@ -228,10 +372,8 @@ $changed = (Sync-MarkedBlock -Path $readmeEn -NewBlock $englishBlock -Mode $Mode
$changed = (Sync-MarkedBlock -Path $readmeZh -NewBlock $chineseBlock -Mode $Mode) -or $changed

if ($Mode -eq 'check' -and $changed) {
throw "Documentation metadata is out of sync. Run: pwsh ./tools/sync-doc-metadata.ps1 -Mode apply"
throw "Documentation metadata is out of sync. Run the sync script in apply mode: ./tools/sync-doc-metadata.ps1 -Mode apply"
}

Write-Host "Version metadata sync check completed in '$Mode' mode."



Loading