@echo off rem Builds into run\\ under a unique assembly name and injects it into whichever of Terraria or tModLoader is running: the game locks the injected DLL and binds simple-named assemblies by name only. setlocal DisableDelayedExpansion set "ROOT=%~dp0" if /i "%~1"=="log" goto log set "STAMP=%DATE%%TIME%" for %%c in ("/" ":" "." "," "-" " ") do call set "STAMP=%%STAMP:%%~c=%%" set "OUT=%ROOT%run\%STAMP%" set "GamePathsLoaded=" for /f "usebackq tokens=1,* delims==" %%a in (`powershell -NoProfile -NonInteractive -Command "$ErrorActionPreference = 'Stop'; try { $properties = [xml](Get-Content -LiteralPath ($env:ROOT + 'Directory.Build.props') -Raw); foreach ($name in 'TerrariaDir', 'TModLoaderDir') { $value = $properties.SelectSingleNode('/Project/PropertyGroup/' + $name).InnerText; Write-Output ($name + '=' + $value) }; 'GamePathsLoaded=1' } catch { [Console]::Error.WriteLine($_.Exception.Message); exit 1 }"`) do if not defined %%a set "%%a=%%b" if not defined GamePathsLoaded exit /b 1 if not exist "%TerrariaDir%\Terraria.exe" (echo Terraria not found at the configured path, skipping its build & goto tmodloader) echo Terraria: "%TerrariaDir%" dotnet build "%ROOT%src\TerraSharp\TerraSharp.csproj" -c Release -f net48 -o "%OUT%" "-p:TerrariaDir=%TerrariaDir%" -p:AssemblyName=TerraSharp.Vanilla_%STAMP% -p:TerraSharpLogging=true || exit /b 1 :tmodloader if not exist "%TModLoaderDir%\tModLoader.dll" (echo tModLoader not found at the configured path, skipping its build & goto inject) echo tModLoader: "%TModLoaderDir%" dotnet build "%ROOT%src\TerraSharp\TerraSharp.csproj" -c Release -f net8.0 -o "%OUT%" "-p:TModLoaderDir=%TModLoaderDir%" -p:AssemblyName=TerraSharp.tModLoader_%STAMP% -p:TerraSharpLogging=true || exit /b 1 :inject if not exist "%TerrariaDir%\Terraria.exe" if not exist "%TModLoaderDir%\tModLoader.dll" (echo Set TerrariaDir or TModLoaderDir in Directory.Build.props to an installed game & exit /b 1) call "%ROOT%build.bat" injector || exit /b 1 start "TerraSharp log" "%ComSpec%" /d /c ""%~f0" log" "%ROOT%bin\TerraSharp.Injector.exe" "%OUT%" exit /b %errorlevel% :log set "TERRASHARP_LOG_SCRIPT=%~f0" powershell -NoProfile -Command "$source = Get-Content -LiteralPath $env:TERRASHARP_LOG_SCRIPT -Raw; & ([scriptblock]::Create(($source -split '(?m)^# TerraSharp log viewer\r?$', 2)[1]))" exit /b %errorlevel% # TerraSharp log viewer $ErrorActionPreference = 'Stop' $createdNew = $false $viewerMutex = [System.Threading.Mutex]::new($true, 'Local\TerraSharp.LogViewer', [ref]$createdNew) try { if (-not $createdNew) { return } $Host.UI.RawUI.WindowTitle = 'TerraSharp log' $logPath = Join-Path ([System.IO.Path]::GetTempPath()) 'terrasharp.log' Write-Host "Following $logPath (Ctrl+C to stop)" -ForegroundColor Gray while (-not (Test-Path -LiteralPath $logPath -PathType Leaf)) { Start-Sleep -Milliseconds 200 } $color = 'Gray' Get-Content -LiteralPath $logPath -Encoding UTF8 -Tail 30 -Wait | ForEach-Object { if ($_ -match '^\d{2}:\d{2}:\d{2}(?:\.\d{3})? (?:\[(DEBUG|INFO|WARNING|ERROR)\] )?') { $color = switch ($Matches[1]) { 'DEBUG' { 'DarkGray' } 'INFO' { 'Gray' } 'WARNING' { 'Yellow' } 'ERROR' { 'Red' } default { 'Gray' } } } Write-Host $_ -ForegroundColor $color } } finally { if ($createdNew) { $viewerMutex.ReleaseMutex() } $viewerMutex.Dispose() }