@echo off setlocal DisableDelayedExpansion set "ROOT=%~dp0" set "DLL=%ROOT%bin\TerraSharp.Vanilla.dll" set "HOOK=%ROOT%bin\TerraSharp.tModLoader.dll" set "TERRASHARP_AUTOLOAD_SCRIPT=%~f0" if not "%~1"=="" goto launcher 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 echo TerraSharp auto-load echo Terraria folder: "%TerrariaDir%" echo tModLoader folder: "%TModLoaderDir%" echo. echo 1. Install echo 2. Uninstall echo 3. Exit echo. choice /c 123 /n /m "Choose [1-3]: " if errorlevel 3 exit /b 0 if errorlevel 2 goto uninstall :install echo. if not exist "%TerrariaDir%\Terraria.exe" goto tmodloader if not exist "%DLL%" (echo "%DLL%" not found, run build.bat first & goto fail) echo Terraria: call :configure Install 1 if errorlevel 1 goto fail copy /y "%DLL%" "%TerrariaDir%\TerraSharp.Vanilla.dll" >nul || (echo copy failed, close Terraria first & goto fail) call :configure Install if errorlevel 1 goto fail echo installed. Start Terraria normally; run autoload.bat again to remove. :tmodloader if not exist "%TModLoaderDir%\tModLoader.dll" goto done echo. echo tModLoader: add this to its Steam launch options (Properties ^> General ^> Launch Options): echo. powershell -NoProfile -NonInteractive -Command "[Console]::WriteLine(' cmd /d /s /c ' + [char]34 + [char]34 + $env:ROOT + 'autoload.bat' + [char]34 + ' %%command%%' + [char]34)" echo. if not exist "%HOOK%" echo (build the tModLoader DLL first: build.bat) goto done :uninstall echo. if not defined TerrariaDir goto removeHook call :configure Uninstall if errorlevel 1 goto fail del /q "%TerrariaDir%\TerraSharp.Vanilla.dll" 2>nul if exist "%TerrariaDir%\TerraSharp.Vanilla.dll" (echo Terraria: TerraSharp.Vanilla.dll in use, close Terraria first & goto fail) echo Terraria auto-load removed. :removeHook if defined TModLoaderDir echo tModLoader: remove the TerraSharp launcher from its Steam launch options. goto done :fail pause exit /b 1 :done pause exit /b 0 :configure set "TERRASHARP_CONFIG_MODE=%~1" set "TERRASHARP_CONFIG_PATH=%TerrariaDir%\Terraria.exe.config" set "TERRASHARP_CONFIG_VALIDATE=%~2" powershell -NoProfile -NonInteractive -Command "$source = [IO.File]::ReadAllText($env:TERRASHARP_AUTOLOAD_SCRIPT); & ([scriptblock]::Create($source.Substring($source.LastIndexOf('# PowerShell')))) -Mode $env:TERRASHARP_CONFIG_MODE -ConfigPath $env:TERRASHARP_CONFIG_PATH -ValidateOnly:($env:TERRASHARP_CONFIG_VALIDATE -eq '1')" exit /b %errorlevel% :launcher if not exist "%HOOK%" (echo TerraSharp: "%HOOK%" not found, run build.bat first & exit /b 1) if not defined DOTNET_STARTUP_HOOKS ( set "DOTNET_STARTUP_HOOKS=%HOOK%" goto launch ) for %%h in ("%DOTNET_STARTUP_HOOKS:;=" "%") do if /i "%%~h"=="%HOOK%" goto launch set "DOTNET_STARTUP_HOOKS=%DOTNET_STARTUP_HOOKS%;%HOOK%" :launch %* exit /b %errorlevel% # PowerShell param( [Parameter(Mandatory = $true)] [ValidateSet('Install', 'Uninstall')] [string]$Mode, [Parameter(Mandatory = $true)] [string]$ConfigPath, [switch]$ValidateOnly ) $ErrorActionPreference = 'Stop' $managerType = 'TerraSharp.LoaderDomainManager' $assemblyName = 'TerraSharp.Vanilla' $assemblyIdentity = 'TerraSharp.Vanilla, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' $ConfigPath = [IO.Path]::GetFullPath($ConfigPath) $document = New-Object Xml.XmlDocument $document.PreserveWhitespace = $true $document.XmlResolver = $null try { if ([IO.File]::Exists($ConfigPath)) { $readerSettings = New-Object Xml.XmlReaderSettings $readerSettings.DtdProcessing = [Xml.DtdProcessing]::Prohibit $reader = [Xml.XmlReader]::Create($ConfigPath, $readerSettings) try { $document.Load($reader) } finally { $reader.Dispose() } } elseif ($Mode -eq 'Uninstall') { exit 0 } else { $document.LoadXml('' + "`r`n`r`n") } if ($document.DocumentElement.Name -ne 'configuration' -or $document.DocumentElement.NamespaceURI) { throw 'Expected a configuration root element.' } $runtimeNodes = $document.SelectNodes('/configuration/runtime') if ($runtimeNodes.Count -gt 1) { throw 'The configuration contains multiple runtime sections.' } $runtime = $document.SelectSingleNode('/configuration/runtime') $typeNodes = @($document.SelectNodes('/configuration/runtime/appDomainManagerType')) $assemblyNodes = @($document.SelectNodes('/configuration/runtime/appDomainManagerAssembly')) if ($Mode -eq 'Install') { foreach ($typeNode in $typeNodes) { if ($typeNode.GetAttribute('value') -cne $managerType) { throw 'Another AppDomainManager is configured; its entries were left unchanged.' } } foreach ($assemblyNode in $assemblyNodes) { if ($assemblyNode.GetAttribute('value').Split(',')[0].Trim() -ine $assemblyName) { throw 'Another AppDomainManager assembly is configured; its entries were left unchanged.' } } if ($typeNodes.Count -gt 1 -or $assemblyNodes.Count -gt 1) { throw 'The configuration contains duplicate AppDomainManager entries.' } if ($ValidateOnly) { exit 0 } $changed = $false if ($null -eq $runtime) { $runtime = $document.CreateElement('runtime') [void]$document.DocumentElement.AppendChild($runtime) $changed = $true } foreach ($entry in @(@('appDomainManagerType', $managerType), @('appDomainManagerAssembly', $assemblyIdentity))) { $element = $runtime.SelectSingleNode($entry[0]) if ($null -eq $element) { $element = $document.CreateElement($entry[0]) [void]$runtime.AppendChild($element) } if ($element.GetAttribute('value') -cne $entry[1]) { $element.SetAttribute('value', $entry[1]) $changed = $true } } } else { $changed = $false foreach ($typeNode in $typeNodes) { if ($typeNode.GetAttribute('value') -ceq $managerType) { [void]$runtime.RemoveChild($typeNode) $changed = $true } } foreach ($assemblyNode in $assemblyNodes) { if ($assemblyNode.GetAttribute('value').Split(',')[0].Trim() -ieq $assemblyName) { [void]$runtime.RemoveChild($assemblyNode) $changed = $true } } } if (-not $changed) { exit 0 } $temporaryPath = Join-Path ([IO.Path]::GetDirectoryName($ConfigPath)) ([Guid]::NewGuid().ToString('N') + '.tmp') try { $document.Save($temporaryPath) if ([IO.File]::Exists($ConfigPath)) { [IO.File]::Replace($temporaryPath, $ConfigPath, [NullString]::Value) } else { [IO.File]::Move($temporaryPath, $ConfigPath) } } finally { if ([IO.File]::Exists($temporaryPath)) { [IO.File]::Delete($temporaryPath) } } } catch { [Console]::Error.WriteLine('TerraSharp configuration: ' + $_.Exception.Message) exit 1 }