Files
TerraSharp/autoload.bat
T

204 lines
7.6 KiB
Batchfile

@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('<?xml version="1.0" encoding="utf-8"?>' + "`r`n<configuration>`r`n</configuration>")
}
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
}