205 lines
7.6 KiB
Batchfile
205 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 -AssemblyPath $env:DLL -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,
|
|
[string]$AssemblyPath,
|
|
[switch]$ValidateOnly
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
$managerType = 'TerraSharp.LoaderDomainManager'
|
|
$assemblyName = 'TerraSharp.Vanilla'
|
|
$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') {
|
|
$assemblyIdentity = [Reflection.AssemblyName]::GetAssemblyName($AssemblyPath).FullName
|
|
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
|
|
}
|