got it working on docker
fixed log closing exception
This commit is contained in:
17
Dockerfile
Normal file
17
Dockerfile
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
FROM mcr.microsoft.com/windows/servercore:ltsc2022
|
||||||
|
|
||||||
|
USER ContainerAdministrator
|
||||||
|
ADD https://aka.ms/highdpimfc2013x64enu vc_redist2013.exe
|
||||||
|
ADD https://aka.ms/vs/16/release/vc_redist.x64.exe vc_redist.exe
|
||||||
|
|
||||||
|
RUN vc_redist2013.exe /passive /norestart
|
||||||
|
RUN vc_redist.exe /passive /norestart
|
||||||
|
RUN del vc_redist2013.exe && del vc_redist.exe
|
||||||
|
|
||||||
|
USER ContainerUser
|
||||||
|
COPY . .
|
||||||
|
ENV TORCH_GAME_PATH="c:\dedi"
|
||||||
|
ENV TORCH_INSTANCE="c:\instance"
|
||||||
|
ENV TORCH_SERVICE="true"
|
||||||
|
ENTRYPOINT ["Torch.Server.exe"]
|
||||||
|
CMD ["-noupdate"]
|
@@ -1,22 +0,0 @@
|
|||||||
pushd
|
|
||||||
|
|
||||||
$steamData = "C:/Steam/Data/"
|
|
||||||
$steamCMDPath = "C:/Steam/steamcmd/"
|
|
||||||
$steamCMDZip = "C:/Steam/steamcmd.zip"
|
|
||||||
|
|
||||||
Add-Type -AssemblyName System.IO.Compression.FileSystem
|
|
||||||
|
|
||||||
if (!(Test-Path $steamData)) {
|
|
||||||
mkdir "$steamData"
|
|
||||||
}
|
|
||||||
if (!(Test-Path $steamCMDPath)) {
|
|
||||||
if (!(Test-Path $steamCMDZip)) {
|
|
||||||
(New-Object System.Net.WebClient).DownloadFile("https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip", "$steamCMDZip");
|
|
||||||
}
|
|
||||||
[System.IO.Compression.ZipFile]::ExtractToDirectory($steamCMDZip, $steamCMDPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
cd "$steamData"
|
|
||||||
& "$steamCMDPath/steamcmd.exe" "+login anonymous" "+force_install_dir $steamData" "+app_update 298740 validate" "+quit"
|
|
||||||
|
|
||||||
popd
|
|
@@ -1,52 +0,0 @@
|
|||||||
param([string] $ApiBase, [string]$tagName, [string]$authinfo, [string[]] $assetPaths)
|
|
||||||
Add-Type -AssemblyName "System.Web"
|
|
||||||
|
|
||||||
$headers = @{
|
|
||||||
Authorization = "Basic " + [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($authinfo))
|
|
||||||
Accept = "application/vnd.github.v3+json"
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Write-Output("Checking if release with tag " + $tagName + " already exists...")
|
|
||||||
$release = Invoke-RestMethod -Uri ($ApiBase+"releases/tags/$tagName") -Method "GET" -Headers $headers
|
|
||||||
Write-Output(" Using existing release " + $release.id + " at " + $release.html_url)
|
|
||||||
} catch {
|
|
||||||
Write-Output(" Doesn't exist")
|
|
||||||
$rel_arg = @{
|
|
||||||
tag_name=$tagName
|
|
||||||
name="Generated $tagName"
|
|
||||||
body=""
|
|
||||||
draft=$TRUE
|
|
||||||
prerelease=$tagName.Contains("alpha") -or $tagName.Contains("beta")
|
|
||||||
}
|
|
||||||
Write-Output("Creating new release " + $tagName + "...")
|
|
||||||
$release = Invoke-RestMethod -Uri ($ApiBase+"releases") -Method "POST" -Headers $headers -Body (ConvertTo-Json($rel_arg))
|
|
||||||
Write-Output(" Created new release " + $tagName + " at " + $release.html_url)
|
|
||||||
}
|
|
||||||
|
|
||||||
$assetsApiBase = $release.assets_url
|
|
||||||
Write-Output("Checking for existing assets...")
|
|
||||||
$existingAssets = Invoke-RestMethod -Uri ($assetsApiBase) -Method "GET" -Headers $headers
|
|
||||||
$assetLabels = ($assetPaths | ForEach-Object {[System.IO.Path]::GetFileName($_)})
|
|
||||||
foreach ($asset in $existingAssets) {
|
|
||||||
if ($assetLabels -contains $asset.name) {
|
|
||||||
$uri = $asset.url
|
|
||||||
Write-Output(" Deleting old asset " + $asset.name + " (id " + $asset.id + "); URI=" + $uri)
|
|
||||||
$result = Invoke-RestMethod -Uri $uri -Method "DELETE" -Headers $headers
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Write-Output("Uploading assets...")
|
|
||||||
$uploadUrl = $release.upload_url.Substring(0, $release.upload_url.LastIndexOf('{'))
|
|
||||||
foreach ($asset in $assetPaths) {
|
|
||||||
$assetName = [System.IO.Path]::GetFileName($asset)
|
|
||||||
$assetType = [System.Web.MimeMapping]::GetMimeMapping($asset)
|
|
||||||
$assetData = [System.IO.File]::ReadAllBytes($asset)
|
|
||||||
$headerExtra = $headers + @{
|
|
||||||
"Content-Type" = $assetType
|
|
||||||
Name = $assetName
|
|
||||||
}
|
|
||||||
$uri = $uploadUrl + "?name=" + $assetName
|
|
||||||
Write-Output(" Uploading " + $asset + " as " + $assetType + "; URI=" + $uri)
|
|
||||||
$result = Invoke-RestMethod -Uri $uri -Method "POST" -Headers $headerExtra -Body $assetData
|
|
||||||
Write-Output(" ID=" + $result.id + ", found at=" + $result.browser_download_url)
|
|
||||||
}
|
|
77
Jenkinsfile
vendored
77
Jenkinsfile
vendored
@@ -1,77 +0,0 @@
|
|||||||
def packageAndArchive(buildMode, packageName) {
|
|
||||||
zipFile = "bin\\${packageName}.zip"
|
|
||||||
packageDir = "bin\\${packageName}\\"
|
|
||||||
|
|
||||||
bat "IF EXIST ${zipFile} DEL ${zipFile}"
|
|
||||||
bat "IF EXIST ${packageDir} RMDIR /S /Q ${packageDir}"
|
|
||||||
|
|
||||||
bat "xcopy bin\\x64\\${buildMode} ${packageDir}"
|
|
||||||
|
|
||||||
bat "del ${packageDir}VRage.*"
|
|
||||||
bat "del ${packageDir}Sandbox.*"
|
|
||||||
bat "del ${packageDir}SpaceEngineers.*"
|
|
||||||
|
|
||||||
powershell "Add-Type -Assembly System.IO.Compression.FileSystem; [System.IO.Compression.ZipFile]::CreateFromDirectory(\"\$PWD\\${packageDir}\", \"\$PWD\\${zipFile}\")"
|
|
||||||
archiveArtifacts artifacts: zipFile, caseSensitive: false, onlyIfSuccessful: true
|
|
||||||
}
|
|
||||||
|
|
||||||
node('windows') {
|
|
||||||
stage('Checkout') {
|
|
||||||
checkout scm
|
|
||||||
bat 'git pull https://github.com/TorchAPI/Torch/ master --tags'
|
|
||||||
}
|
|
||||||
|
|
||||||
stage('Acquire SE') {
|
|
||||||
bat 'powershell -File Jenkins/jenkins-grab-se.ps1'
|
|
||||||
bat 'IF EXIST GameBinaries RMDIR GameBinaries'
|
|
||||||
bat 'mklink /J GameBinaries "C:/Steam/Data/DedicatedServer64/"'
|
|
||||||
bat 'dir GameBinaries'
|
|
||||||
}
|
|
||||||
|
|
||||||
stage('Acquire NuGet Packages') {
|
|
||||||
bat 'cd C:\\Program Files\\Jenkins'
|
|
||||||
bat '"C:\\Program Files\\Jenkins\\nuget.exe" restore Torch.sln'
|
|
||||||
}
|
|
||||||
|
|
||||||
stage('Build') {
|
|
||||||
currentBuild.description = bat(returnStdout: true, script: '@powershell -File Versioning/version.ps1').trim()
|
|
||||||
if (env.BRANCH_NAME == "master" || env.BRANCH_NAME == "Patron" || env.BRANCH_NAME == "publictest") {
|
|
||||||
buildMode = "Release"
|
|
||||||
} else {
|
|
||||||
buildMode = "Release"
|
|
||||||
}
|
|
||||||
bat "IF EXIST \"bin\" rmdir /Q /S \"bin\""
|
|
||||||
bat "IF EXIST \"bin-test\" rmdir /Q /S \"bin-test\""
|
|
||||||
bat "\"${tool 'MSBuild'}msbuild\" Torch.sln /p:Configuration=${buildMode} /p:Platform=x64 /t:Clean"
|
|
||||||
bat "\"${tool 'MSBuild'}msbuild\" Torch.sln /p:Configuration=${buildMode} /p:Platform=x64"
|
|
||||||
}
|
|
||||||
|
|
||||||
stage('Archive') {
|
|
||||||
archiveArtifacts artifacts: "bin/x64/${buildMode}/Torch*", caseSensitive: false, fingerprint: true, onlyIfSuccessful: true
|
|
||||||
|
|
||||||
packageAndArchive(buildMode, "torch-server")
|
|
||||||
|
|
||||||
/*packageAndArchive(buildMode, "torch-client", "Torch.Server*")*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disabled because they fail builds more often than they detect actual problems
|
|
||||||
stage('Test') {
|
|
||||||
bat 'IF NOT EXIST reports MKDIR reports'
|
|
||||||
bat "\"packages/xunit.runner.console.2.2.0/tools/xunit.console.exe\" \"bin-test/x64/${buildMode}/Torch.Tests.dll\" \"bin-test/x64/${buildMode}/Torch.Server.Tests.dll\" \"bin-test/x64/${buildMode}/Torch.Client.Tests.dll\" -parallel none -xml \"reports/Torch.Tests.xml\""
|
|
||||||
|
|
||||||
step([
|
|
||||||
$class: 'XUnitBuilder',
|
|
||||||
thresholdMode: 1,
|
|
||||||
thresholds: [[$class: 'FailedThreshold', failureThreshold: '1']],
|
|
||||||
tools: [[
|
|
||||||
$class: 'XUnitDotNetTestType',
|
|
||||||
deleteOutputFiles: true,
|
|
||||||
failIfNotNew: true,
|
|
||||||
pattern: 'reports/*.xml',
|
|
||||||
skipNoTestFiles: false,
|
|
||||||
stopProcessingIfError: true
|
|
||||||
]]
|
|
||||||
])
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
@@ -151,6 +151,11 @@ namespace Torch.API
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
string InstancePath { get; }
|
string InstancePath { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Name of the dedicated instance.
|
||||||
|
/// </summary>
|
||||||
|
string InstanceName { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Raised when the server's Init() method has completed.
|
/// Raised when the server's Init() method has completed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@@ -10,7 +10,9 @@ namespace Torch
|
|||||||
bool ForceUpdate { get; set; }
|
bool ForceUpdate { get; set; }
|
||||||
bool GetPluginUpdates { get; set; }
|
bool GetPluginUpdates { get; set; }
|
||||||
bool GetTorchUpdates { get; set; }
|
bool GetTorchUpdates { get; set; }
|
||||||
|
[Obsolete("Use Torch.InstanceName instead")]
|
||||||
string InstanceName { get; set; }
|
string InstanceName { get; set; }
|
||||||
|
[Obsolete("Use Torch.InstancePath instead")]
|
||||||
string InstancePath { get; set; }
|
string InstancePath { get; set; }
|
||||||
bool NoGui { get; set; }
|
bool NoGui { get; set; }
|
||||||
bool NoUpdate { get; set; }
|
bool NoUpdate { get; set; }
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
<Product>Torch</Product>
|
<Product>Torch</Product>
|
||||||
<Copyright>Copyright © Torch API 2017</Copyright>
|
<Copyright>Copyright © Torch API 2017</Copyright>
|
||||||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
|
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
|
||||||
<OutputPath>$(SolutionDir)\bin\$(Platform)\$(Configuration)\</OutputPath>
|
<OutputPath>..\bin\$(Platform)\$(Configuration)\</OutputPath>
|
||||||
<UseWpf>True</UseWpf>
|
<UseWpf>True</UseWpf>
|
||||||
<GenerateAssemblyInfo>False</GenerateAssemblyInfo>
|
<GenerateAssemblyInfo>False</GenerateAssemblyInfo>
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
@@ -22,40 +22,35 @@ namespace Torch.Server
|
|||||||
{
|
{
|
||||||
public class Initializer
|
public class Initializer
|
||||||
{
|
{
|
||||||
[Obsolete("It's hack. Do not use it!")]
|
|
||||||
internal static Initializer Instance { get; private set; }
|
internal static Initializer Instance { get; private set; }
|
||||||
|
|
||||||
private static readonly Logger Log = LogManager.GetLogger(nameof(Initializer));
|
private static readonly Logger Log = LogManager.GetLogger(nameof(Initializer));
|
||||||
private bool _init;
|
private bool _init;
|
||||||
private const string STEAMCMD_DIR = "steamcmd";
|
private const string STEAMCMD_DIR = "steamcmd";
|
||||||
private const string STEAMCMD_ZIP = "temp.zip";
|
private const string STEAMCMD_ZIP = "temp.zip";
|
||||||
private static readonly string STEAMCMD_PATH = $"{STEAMCMD_DIR}\\steamcmd.exe";
|
private static readonly string STEAMCMD_EXE = "steamcmd.exe";
|
||||||
private static readonly string RUNSCRIPT_PATH = $"{STEAMCMD_DIR}\\runscript.txt";
|
private static readonly string RUNSCRIPT_FILE = "runscript.txt";
|
||||||
|
|
||||||
private const string RUNSCRIPT = @"force_install_dir ../
|
private const string RUNSCRIPT = @"force_install_dir ../
|
||||||
login anonymous
|
login anonymous
|
||||||
app_update 298740
|
app_update 298740
|
||||||
quit";
|
quit";
|
||||||
private TorchServer _server;
|
private TorchServer _server;
|
||||||
private string _basePath;
|
|
||||||
|
|
||||||
internal Persistent<TorchConfig> ConfigPersistent { get; private set; }
|
internal Persistent<TorchConfig> ConfigPersistent { get; }
|
||||||
public TorchConfig Config => ConfigPersistent?.Data;
|
public TorchConfig Config => ConfigPersistent?.Data;
|
||||||
public TorchServer Server => _server;
|
public TorchServer Server => _server;
|
||||||
|
|
||||||
public Initializer(string basePath)
|
public Initializer(string basePath, Persistent<TorchConfig> torchConfig)
|
||||||
{
|
{
|
||||||
_basePath = basePath;
|
|
||||||
Instance = this;
|
Instance = this;
|
||||||
|
ConfigPersistent = torchConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Initialize(string[] args)
|
public bool Initialize(string[] args)
|
||||||
{
|
{
|
||||||
if (_init)
|
if (_init)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
AppDomain.CurrentDomain.UnhandledException += HandleException;
|
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
//enables logging debug messages when built in debug mode. Amazing.
|
//enables logging debug messages when built in debug mode. Amazing.
|
||||||
LogManager.Configuration.AddRule(LogLevel.Debug, LogLevel.Debug, "main");
|
LogManager.Configuration.AddRule(LogLevel.Debug, LogLevel.Debug, "main");
|
||||||
@@ -69,37 +64,6 @@ quit";
|
|||||||
if (!Enumerable.Contains(args, "-noupdate"))
|
if (!Enumerable.Contains(args, "-noupdate"))
|
||||||
RunSteamCmd();
|
RunSteamCmd();
|
||||||
|
|
||||||
var basePath = new FileInfo(typeof(Program).Assembly.Location).Directory.ToString();
|
|
||||||
var apiSource = Path.Combine(basePath, "DedicatedServer64", "steam_api64.dll");
|
|
||||||
var apiTarget = Path.Combine(basePath, "steam_api64.dll");
|
|
||||||
|
|
||||||
if (!File.Exists(apiTarget))
|
|
||||||
{
|
|
||||||
File.Copy(apiSource, apiTarget);
|
|
||||||
}
|
|
||||||
else if (File.GetLastWriteTime(apiTarget) < File.GetLastWriteTime(apiSource))
|
|
||||||
{
|
|
||||||
File.Delete(apiTarget);
|
|
||||||
File.Copy(apiSource, apiTarget);
|
|
||||||
}
|
|
||||||
|
|
||||||
var havokSource = Path.Combine(basePath, "DedicatedServer64", "Havok.dll");
|
|
||||||
var havokTarget = Path.Combine(basePath, "Havok.dll");
|
|
||||||
|
|
||||||
if (!File.Exists(havokTarget))
|
|
||||||
{
|
|
||||||
File.Copy(havokSource, havokTarget);
|
|
||||||
}
|
|
||||||
else if (File.GetLastWriteTime(havokTarget) < File.GetLastWriteTime(havokSource))
|
|
||||||
{
|
|
||||||
File.Delete(havokTarget);
|
|
||||||
File.Copy(havokSource, havokTarget);
|
|
||||||
}
|
|
||||||
|
|
||||||
InitConfig();
|
|
||||||
if (!Config.Parse(args))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(Config.WaitForPID))
|
if (!string.IsNullOrEmpty(Config.WaitForPID))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -114,9 +78,9 @@ quit";
|
|||||||
Thread.Sleep(1000);
|
Thread.Sleep(1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
// ignored
|
Log.Warn(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,11 +88,11 @@ quit";
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Run()
|
public void Run(bool isService, string instanceName, string instancePath)
|
||||||
{
|
{
|
||||||
_server = new TorchServer(Config);
|
_server = new TorchServer(Config, instancePath, instanceName);
|
||||||
|
|
||||||
if (Config.NoGui)
|
if (isService || Config.NoGui)
|
||||||
{
|
{
|
||||||
_server.Init();
|
_server.Init();
|
||||||
_server.Start();
|
_server.Start();
|
||||||
@@ -165,34 +129,23 @@ quit";
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitConfig()
|
|
||||||
{
|
|
||||||
var configName = "Torch.cfg";
|
|
||||||
var configPath = Path.Combine(Directory.GetCurrentDirectory(), configName);
|
|
||||||
if (File.Exists(configName))
|
|
||||||
{
|
|
||||||
Log.Info($"Loading config {configName}");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Log.Info($"Generating default config at {configPath}");
|
|
||||||
}
|
|
||||||
ConfigPersistent = Persistent<TorchConfig>.Load(configPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void RunSteamCmd()
|
public static void RunSteamCmd()
|
||||||
{
|
{
|
||||||
var log = LogManager.GetLogger("SteamCMD");
|
var log = LogManager.GetLogger("SteamCMD");
|
||||||
|
|
||||||
if (!Directory.Exists(STEAMCMD_DIR))
|
var path = Environment.GetEnvironmentVariable("TORCH_STEAMCMD") ?? Path.GetFullPath(STEAMCMD_DIR);
|
||||||
|
|
||||||
|
if (!Directory.Exists(path))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(STEAMCMD_DIR);
|
Directory.CreateDirectory(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!File.Exists(RUNSCRIPT_PATH))
|
var runScriptPath = Path.Combine(path, RUNSCRIPT_FILE);
|
||||||
File.WriteAllText(RUNSCRIPT_PATH, RUNSCRIPT);
|
if (!File.Exists(runScriptPath))
|
||||||
|
File.WriteAllText(runScriptPath, RUNSCRIPT);
|
||||||
|
|
||||||
if (!File.Exists(STEAMCMD_PATH))
|
var steamCmdExePath = Path.Combine(path, STEAMCMD_EXE);
|
||||||
|
if (!File.Exists(steamCmdExePath))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -201,22 +154,21 @@ quit";
|
|||||||
using (var file = File.Create(STEAMCMD_ZIP))
|
using (var file = File.Create(STEAMCMD_ZIP))
|
||||||
client.GetStreamAsync("https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip").Result.CopyTo(file);
|
client.GetStreamAsync("https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip").Result.CopyTo(file);
|
||||||
|
|
||||||
ZipFile.ExtractToDirectory(STEAMCMD_ZIP, STEAMCMD_DIR);
|
ZipFile.ExtractToDirectory(STEAMCMD_ZIP, path);
|
||||||
File.Delete(STEAMCMD_ZIP);
|
File.Delete(STEAMCMD_ZIP);
|
||||||
log.Info("SteamCMD downloaded successfully!");
|
log.Info("SteamCMD downloaded successfully!");
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
log.Error("Failed to download SteamCMD, unable to update the DS.");
|
log.Error(e, "Failed to download SteamCMD, unable to update the DS.");
|
||||||
log.Error(e);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("Checking for DS updates.");
|
log.Info("Checking for DS updates.");
|
||||||
var steamCmdProc = new ProcessStartInfo(STEAMCMD_PATH, "+runscript runscript.txt")
|
var steamCmdProc = new ProcessStartInfo(steamCmdExePath, "+runscript runscript.txt")
|
||||||
{
|
{
|
||||||
WorkingDirectory = Path.Combine(Directory.GetCurrentDirectory(), STEAMCMD_DIR),
|
WorkingDirectory = path,
|
||||||
UseShellExecute = false,
|
UseShellExecute = false,
|
||||||
RedirectStandardOutput = true,
|
RedirectStandardOutput = true,
|
||||||
StandardOutputEncoding = Encoding.ASCII
|
StandardOutputEncoding = Encoding.ASCII
|
||||||
@@ -230,29 +182,5 @@ quit";
|
|||||||
Thread.Sleep(100);
|
Thread.Sleep(100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleException(object sender, UnhandledExceptionEventArgs e)
|
|
||||||
{
|
|
||||||
_server.FatalException = true;
|
|
||||||
if (Debugger.IsAttached)
|
|
||||||
return;
|
|
||||||
var ex = (Exception)e.ExceptionObject;
|
|
||||||
Log.Fatal(ex.ToStringDemystified());
|
|
||||||
LogManager.Flush();
|
|
||||||
if (Config.RestartOnCrash)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Restarting in 5 seconds.");
|
|
||||||
Thread.Sleep(5000);
|
|
||||||
var exe = typeof(Program).Assembly.Location;
|
|
||||||
Config.WaitForPID = Environment.ProcessId.ToString();
|
|
||||||
Process.Start(exe, Config.ToString());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MessageBox.Show("Torch encountered a fatal error and needs to close. Please check the logs for details.");
|
|
||||||
}
|
|
||||||
|
|
||||||
Environment.Exit(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -41,9 +41,11 @@ namespace Torch.Server.Managers
|
|||||||
[Dependency]
|
[Dependency]
|
||||||
private FilesystemManager _filesystemManager;
|
private FilesystemManager _filesystemManager;
|
||||||
|
|
||||||
public InstanceManager(ITorchBase torchInstance) : base(torchInstance)
|
private new ITorchServer Torch { get; }
|
||||||
{
|
|
||||||
|
|
||||||
|
public InstanceManager(ITorchServer torchInstance) : base(torchInstance)
|
||||||
|
{
|
||||||
|
Torch = torchInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IWorld SelectedWorld => DedicatedConfig.SelectedWorld;
|
public IWorld SelectedWorld => DedicatedConfig.SelectedWorld;
|
||||||
@@ -74,7 +76,7 @@ namespace Torch.Server.Managers
|
|||||||
|
|
||||||
DedicatedConfig = new ConfigDedicatedViewModel((MyConfigDedicated<MyObjectBuilder_SessionSettings>) MySandboxGame.ConfigDedicated);
|
DedicatedConfig = new ConfigDedicatedViewModel((MyConfigDedicated<MyObjectBuilder_SessionSettings>) MySandboxGame.ConfigDedicated);
|
||||||
|
|
||||||
var worldFolders = Directory.EnumerateDirectories(Path.Combine(Torch.Config.InstancePath, "Saves"));
|
var worldFolders = Directory.EnumerateDirectories(Path.Combine(Torch.InstancePath, "Saves"));
|
||||||
|
|
||||||
foreach (var f in worldFolders)
|
foreach (var f in worldFolders)
|
||||||
{
|
{
|
||||||
@@ -226,7 +228,7 @@ namespace Torch.Server.Managers
|
|||||||
{
|
{
|
||||||
if (!((TorchServer)Torch).HasRun)
|
if (!((TorchServer)Torch).HasRun)
|
||||||
{
|
{
|
||||||
DedicatedConfig.Save(Path.Combine(Torch.Config.InstancePath, CONFIG_NAME));
|
DedicatedConfig.Save(Path.Combine(Torch.InstancePath, CONFIG_NAME));
|
||||||
Log.Info("Saved dedicated config.");
|
Log.Info("Saved dedicated config.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,17 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.IO.Compression;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net;
|
|
||||||
using System.ServiceProcess;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
|
||||||
#if TORCH_SERVICE
|
|
||||||
using Microsoft.VisualBasic.Devices;
|
|
||||||
#endif
|
|
||||||
using NLog;
|
|
||||||
using NLog.Fluent;
|
|
||||||
using NLog.Targets;
|
using NLog.Targets;
|
||||||
using Torch.Utils;
|
using Torch.Utils;
|
||||||
|
|
||||||
@@ -19,19 +7,17 @@ namespace Torch.Server
|
|||||||
{
|
{
|
||||||
internal static class Program
|
internal static class Program
|
||||||
{
|
{
|
||||||
/// <remarks>
|
|
||||||
/// This method must *NOT* load any types/assemblies from the vanilla game, otherwise automatic updates will fail.
|
|
||||||
/// </remarks>
|
|
||||||
[STAThread]
|
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
|
var isService = Environment.GetEnvironmentVariable("TORCH_SERVICE")
|
||||||
|
?.Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase) ?? false;
|
||||||
Target.Register<LogViewerTarget>(nameof(LogViewerTarget));
|
Target.Register<LogViewerTarget>(nameof(LogViewerTarget));
|
||||||
//Ensures that all the files are downloaded in the Torch directory.
|
//Ensures that all the files are downloaded in the Torch directory.
|
||||||
var workingDir = new FileInfo(typeof(Program).Assembly.Location).Directory!.FullName;
|
var workingDir = AppContext.BaseDirectory;
|
||||||
var binDir = Path.Combine(workingDir, "DedicatedServer64");
|
var binDir = Path.Combine(Environment.GetEnvironmentVariable("TORCH_GAME_PATH") ?? workingDir, "DedicatedServer64");
|
||||||
Directory.SetCurrentDirectory(workingDir);
|
Directory.SetCurrentDirectory(Environment.GetEnvironmentVariable("TORCH_GAME_PATH") ?? workingDir);
|
||||||
|
|
||||||
if (Directory.Exists(binDir))
|
if (!isService && Directory.Exists(binDir))
|
||||||
foreach (var file in Directory.GetFiles(binDir, "System.*.dll"))
|
foreach (var file in Directory.GetFiles(binDir, "System.*.dll"))
|
||||||
{
|
{
|
||||||
File.Delete(file);
|
File.Delete(file);
|
||||||
@@ -49,11 +35,71 @@ namespace Torch.Server
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
var initializer = new Initializer(workingDir);
|
var instanceName = Environment.GetEnvironmentVariable("TORCH_INSTANCE") ?? "Instance";
|
||||||
if (!initializer.Initialize(args))
|
string instancePath;
|
||||||
return;
|
|
||||||
|
|
||||||
initializer.Run();
|
if (Path.IsPathRooted(instanceName))
|
||||||
|
{
|
||||||
|
instancePath = instanceName;
|
||||||
|
instanceName = Path.GetDirectoryName(instanceName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
instancePath = Path.GetFullPath(instanceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
var oldTorchCfg = Path.Combine(workingDir, "Torch.cfg");
|
||||||
|
var torchCfg = Path.Combine(instancePath, "Torch.cfg");
|
||||||
|
|
||||||
|
if (File.Exists(oldTorchCfg))
|
||||||
|
File.Move(oldTorchCfg, torchCfg, true);
|
||||||
|
|
||||||
|
var config = Persistent<TorchConfig>.Load(torchCfg);
|
||||||
|
config.Data.InstanceName = instanceName;
|
||||||
|
config.Data.InstancePath = instancePath;
|
||||||
|
if (!config.Data.Parse(args))
|
||||||
|
{
|
||||||
|
Console.WriteLine("Invalid arguments");
|
||||||
|
Environment.Exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
var handler = new UnhandledExceptionHandler(config.Data, isService);
|
||||||
|
AppDomain.CurrentDomain.UnhandledException += handler.OnUnhandledException;
|
||||||
|
|
||||||
|
var initializer = new Initializer(workingDir, config);
|
||||||
|
if (!initializer.Initialize(args))
|
||||||
|
Environment.Exit(1);
|
||||||
|
|
||||||
|
CopyNative(binDir);
|
||||||
|
initializer.Run(isService, instanceName, instancePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CopyNative(string binPath)
|
||||||
|
{
|
||||||
|
var apiSource = Path.Combine(binPath, "steam_api64.dll");
|
||||||
|
var apiTarget = Path.Combine(AppContext.BaseDirectory, "steam_api64.dll");
|
||||||
|
if (!File.Exists(apiTarget))
|
||||||
|
{
|
||||||
|
File.Copy(apiSource, apiTarget);
|
||||||
|
}
|
||||||
|
else if (File.GetLastWriteTime(apiTarget) < File.GetLastWriteTime(binPath))
|
||||||
|
{
|
||||||
|
File.Delete(apiTarget);
|
||||||
|
File.Copy(apiSource, apiTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
var havokSource = Path.Combine(binPath, "Havok.dll");
|
||||||
|
var havokTarget = Path.Combine(AppContext.BaseDirectory, "Havok.dll");
|
||||||
|
|
||||||
|
if (!File.Exists(havokTarget))
|
||||||
|
{
|
||||||
|
File.Copy(havokSource, havokTarget);
|
||||||
|
}
|
||||||
|
else if (File.GetLastWriteTime(havokTarget) < File.GetLastWriteTime(havokSource))
|
||||||
|
{
|
||||||
|
File.Delete(havokTarget);
|
||||||
|
File.Copy(havokSource, havokTarget);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,31 +5,22 @@
|
|||||||
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||||
<PublishUrl>publish\</PublishUrl>
|
<PublishUrl>publish\</PublishUrl>
|
||||||
<Install>true</Install>
|
|
||||||
<InstallFrom>Disk</InstallFrom>
|
|
||||||
<UpdateEnabled>false</UpdateEnabled>
|
|
||||||
<UpdateMode>Foreground</UpdateMode>
|
|
||||||
<UpdateInterval>7</UpdateInterval>
|
|
||||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
|
||||||
<UpdatePeriodically>false</UpdatePeriodically>
|
|
||||||
<UpdateRequired>false</UpdateRequired>
|
|
||||||
<MapFileExtensions>true</MapFileExtensions>
|
|
||||||
<ApplicationRevision>0</ApplicationRevision>
|
<ApplicationRevision>0</ApplicationRevision>
|
||||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
|
||||||
<UseApplicationTrust>false</UseApplicationTrust>
|
<UseApplicationTrust>false</UseApplicationTrust>
|
||||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
|
||||||
<AssemblyTitle>Torch Server</AssemblyTitle>
|
<AssemblyTitle>Torch Server</AssemblyTitle>
|
||||||
<Product>Torch</Product>
|
<Product>Torch</Product>
|
||||||
<Copyright>Copyright © Torch API 2017</Copyright>
|
<Copyright>Copyright © Torch API 2017</Copyright>
|
||||||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
|
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
|
||||||
<OutputPath>$(SolutionDir)\bin\$(Platform)\$(Configuration)\</OutputPath>
|
<OutputPath>..\bin\$(Platform)\$(Configuration)\</OutputPath>
|
||||||
<UseWPF>true</UseWPF>
|
<UseWPF>true</UseWPF>
|
||||||
<GenerateAssemblyInfo>False</GenerateAssemblyInfo>
|
<GenerateAssemblyInfo>False</GenerateAssemblyInfo>
|
||||||
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
|
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
<Configurations>Debug;Release</Configurations>
|
<Configurations>Debug;Release</Configurations>
|
||||||
<Platforms>AnyCPU</Platforms>
|
<Platforms>AnyCPU</Platforms>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<NeutralLanguage>en</NeutralLanguage>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<StartupObject>Torch.Server.Program</StartupObject>
|
<StartupObject>Torch.Server.Program</StartupObject>
|
||||||
@@ -169,8 +160,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Page Remove="Views\WorldSelectControl.xaml" />
|
<Page Remove="Views\WorldSelectControl.xaml" />
|
||||||
|
<None Include="..\NLog.config" Visible="false" CopyToOutputDirectory="PreserveNewest" CopyToPublishDirectory="Always" />
|
||||||
|
<None Include="..\Dockerfile" Visible="false" CopyToPublishDirectory="Always" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Target Name="CopyLoggingConfig" AfterTargets="Build">
|
|
||||||
<Copy SourceFiles="$(SolutionDir)NLog.config" DestinationFolder="$(TargetDir)" />
|
|
||||||
</Target>
|
|
||||||
</Project>
|
</Project>
|
2
Torch.Server/Torch.Server.csproj.DotSettings
Normal file
2
Torch.Server/Torch.Server.csproj.DotSettings
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
|
<s:String x:Key="/Default/CodeEditing/Localization/Localizable/@EntryValue">No</s:String></wpf:ResourceDictionary>
|
@@ -18,8 +18,6 @@ namespace Torch.Server
|
|||||||
public bool ShouldUpdatePlugins => (GetPluginUpdates && !NoUpdate) || ForceUpdate;
|
public bool ShouldUpdatePlugins => (GetPluginUpdates && !NoUpdate) || ForceUpdate;
|
||||||
public bool ShouldUpdateTorch => (GetTorchUpdates && !NoUpdate) || ForceUpdate;
|
public bool ShouldUpdateTorch => (GetTorchUpdates && !NoUpdate) || ForceUpdate;
|
||||||
|
|
||||||
private string _instancePath = Path.GetFullPath("Instance");
|
|
||||||
private string _instanceName = "Instance";
|
|
||||||
private bool _autostart;
|
private bool _autostart;
|
||||||
private bool _restartOnCrash;
|
private bool _restartOnCrash;
|
||||||
private bool _noGui;
|
private bool _noGui;
|
||||||
@@ -40,21 +38,6 @@ namespace Torch.Server
|
|||||||
private UGCServiceType _ugcServiceType = UGCServiceType.Steam;
|
private UGCServiceType _ugcServiceType = UGCServiceType.Steam;
|
||||||
private bool _entityManagerEnabled = true;
|
private bool _entityManagerEnabled = true;
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
[Arg("instancename", "The name of the Torch instance.")]
|
|
||||||
[Display(Name = "Instance Name", Description = "The name of the Torch instance.", GroupName = "Server")]
|
|
||||||
public string InstanceName { get => _instanceName; set => Set(value, ref _instanceName); }
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
[Arg("instancepath", "Server data folder where saves and mods are stored.")]
|
|
||||||
[Display(Name = "Instance Path", Description = "Server data folder where saves and mods are stored.", GroupName = "Server")]
|
|
||||||
public string InstancePath
|
|
||||||
{
|
|
||||||
get => _instancePath;
|
|
||||||
set => Set(value, ref _instancePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[XmlIgnore, Arg("noupdate", "Disable automatically downloading game and plugin updates.")]
|
[XmlIgnore, Arg("noupdate", "Disable automatically downloading game and plugin updates.")]
|
||||||
public bool NoUpdate { get; set; }
|
public bool NoUpdate { get; set; }
|
||||||
@@ -81,6 +64,8 @@ namespace Torch.Server
|
|||||||
[Display(Name = "Restart On Crash", Description = "Automatically restart the server if it crashes.", GroupName = "Server")]
|
[Display(Name = "Restart On Crash", Description = "Automatically restart the server if it crashes.", GroupName = "Server")]
|
||||||
public bool RestartOnCrash { get => _restartOnCrash; set => Set(value, ref _restartOnCrash); }
|
public bool RestartOnCrash { get => _restartOnCrash; set => Set(value, ref _restartOnCrash); }
|
||||||
|
|
||||||
|
public string InstancePath { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[Arg("nogui", "Do not show the Torch UI.")]
|
[Arg("nogui", "Do not show the Torch UI.")]
|
||||||
[Display(Name = "No GUI", Description = "Do not show the Torch UI.", GroupName = "Window")]
|
[Display(Name = "No GUI", Description = "Do not show the Torch UI.", GroupName = "Window")]
|
||||||
@@ -94,6 +79,8 @@ namespace Torch.Server
|
|||||||
[Display(Name = "Update Torch", Description = "Check every start for new versions of torch.", GroupName = "Server")]
|
[Display(Name = "Update Torch", Description = "Check every start for new versions of torch.", GroupName = "Server")]
|
||||||
public bool GetTorchUpdates { get => _getTorchUpdates; set => Set(value, ref _getTorchUpdates); }
|
public bool GetTorchUpdates { get => _getTorchUpdates; set => Set(value, ref _getTorchUpdates); }
|
||||||
|
|
||||||
|
public string InstanceName { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[Display(Name = "Update Plugins", Description = "Check every start for new versions of plugins.", GroupName = "Server")]
|
[Display(Name = "Update Plugins", Description = "Check every start for new versions of plugins.", GroupName = "Server")]
|
||||||
public bool GetPluginUpdates { get => _getPluginUpdates; set => Set(value, ref _getPluginUpdates); }
|
public bool GetPluginUpdates { get => _getPluginUpdates; set => Set(value, ref _getPluginUpdates); }
|
||||||
|
@@ -55,8 +55,10 @@ namespace Torch.Server
|
|||||||
|
|
||||||
//Here to trigger rebuild
|
//Here to trigger rebuild
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public TorchServer(TorchConfig config) : base(config)
|
public TorchServer(ITorchConfig config, string instancePath, string instanceName) : base(config)
|
||||||
{
|
{
|
||||||
|
InstancePath = instancePath;
|
||||||
|
InstanceName = instanceName;
|
||||||
DedicatedInstance = new InstanceManager(this);
|
DedicatedInstance = new InstanceManager(this);
|
||||||
AddManager(DedicatedInstance);
|
AddManager(DedicatedInstance);
|
||||||
if (config.EntityManagerEnabled)
|
if (config.EntityManagerEnabled)
|
||||||
@@ -116,7 +118,7 @@ namespace Torch.Server
|
|||||||
public InstanceManager DedicatedInstance { get; }
|
public InstanceManager DedicatedInstance { get; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public string InstanceName => Config?.InstanceName;
|
public string InstanceName { get; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override uint SteamAppId => 244850;
|
protected override uint SteamAppId => 244850;
|
||||||
@@ -130,7 +132,7 @@ namespace Torch.Server
|
|||||||
public event Action<ITorchServer> Initialized;
|
public event Action<ITorchServer> Initialized;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public string InstancePath => Config?.InstancePath;
|
public string InstancePath { get; }
|
||||||
|
|
||||||
public int OnlinePlayers { get => _players; private set => SetValue(ref _players, value); }
|
public int OnlinePlayers { get => _players; private set => SetValue(ref _players, value); }
|
||||||
|
|
||||||
@@ -141,10 +143,10 @@ namespace Torch.Server
|
|||||||
MySandboxGame.IsDedicated = true;
|
MySandboxGame.IsDedicated = true;
|
||||||
base.Init();
|
base.Init();
|
||||||
Managers.GetManager<ITorchSessionManager>().SessionStateChanged += OnSessionStateChanged;
|
Managers.GetManager<ITorchSessionManager>().SessionStateChanged += OnSessionStateChanged;
|
||||||
GetManager<InstanceManager>().LoadInstance(Config.InstancePath);
|
GetManager<InstanceManager>().LoadInstance(InstancePath);
|
||||||
CanRun = true;
|
CanRun = true;
|
||||||
Initialized?.Invoke(this);
|
Initialized?.Invoke(this);
|
||||||
Log.Info($"Initialized server '{Config.InstanceName}' at '{Config.InstancePath}'");
|
Log.Info($"Initialized server '{InstanceName}' at '{InstancePath}'");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
49
Torch.Server/UnhandledExceptionHandler.cs
Normal file
49
Torch.Server/UnhandledExceptionHandler.cs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Threading;
|
||||||
|
using NLog;
|
||||||
|
using VRage;
|
||||||
|
|
||||||
|
namespace Torch.Server;
|
||||||
|
|
||||||
|
internal class UnhandledExceptionHandler
|
||||||
|
{
|
||||||
|
private readonly TorchConfig _config;
|
||||||
|
private readonly bool _isService;
|
||||||
|
private static readonly ILogger Log = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
public UnhandledExceptionHandler(TorchConfig config, bool isService)
|
||||||
|
{
|
||||||
|
_config = config;
|
||||||
|
_isService = isService;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||||||
|
{
|
||||||
|
if (Debugger.IsAttached)
|
||||||
|
return;
|
||||||
|
var ex = (Exception)e.ExceptionObject;
|
||||||
|
Log.Fatal(ex.ToStringDemystified());
|
||||||
|
LogManager.Flush();
|
||||||
|
|
||||||
|
if (_isService)
|
||||||
|
Environment.Exit(1);
|
||||||
|
|
||||||
|
if (_config.RestartOnCrash)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Restarting in 5 seconds.");
|
||||||
|
Thread.Sleep(5000);
|
||||||
|
var exe = typeof(Program).Assembly.Location;
|
||||||
|
_config.WaitForPID = Environment.ProcessId.ToString();
|
||||||
|
Process.Start(exe, _config.ToString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MyVRage.Platform.Windows.MessageBox(
|
||||||
|
"Torch encountered a fatal error and needs to close. Please check the logs for details.",
|
||||||
|
"Fatal exception", MessageBoxOptions.OkOnly);
|
||||||
|
}
|
||||||
|
|
||||||
|
Environment.Exit(1);
|
||||||
|
}
|
||||||
|
}
|
@@ -12,6 +12,7 @@ EndProject
|
|||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7AD02A71-1D4C-48F9-A8C1-789A5512424F}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7AD02A71-1D4C-48F9-A8C1-789A5512424F}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
NLog.config = NLog.config
|
NLog.config = NLog.config
|
||||||
|
Dockerfile = Dockerfile
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Torch.Tests", "Torch.Tests\Torch.Tests.csproj", "{C3C8B671-6AD1-44AA-A8DA-E0C0DC0FEDF5}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Torch.Tests", "Torch.Tests\Torch.Tests.csproj", "{C3C8B671-6AD1-44AA-A8DA-E0C0DC0FEDF5}"
|
||||||
|
@@ -46,6 +46,9 @@ namespace Torch.Patches
|
|||||||
|
|
||||||
[ReflectedMethodInfo(typeof(MyLog), nameof(MyLog.Init))]
|
[ReflectedMethodInfo(typeof(MyLog), nameof(MyLog.Init))]
|
||||||
private static MethodInfo _logInit;
|
private static MethodInfo _logInit;
|
||||||
|
|
||||||
|
[ReflectedMethodInfo(typeof(MyLog), nameof(MyLog.Close))]
|
||||||
|
private static MethodInfo _logClose;
|
||||||
#pragma warning restore 649
|
#pragma warning restore 649
|
||||||
|
|
||||||
|
|
||||||
@@ -64,6 +67,7 @@ namespace Torch.Patches
|
|||||||
context.GetPattern(_logWriteLineOptions).AddPrefix(nameof(PrefixWriteLineOptions));
|
context.GetPattern(_logWriteLineOptions).AddPrefix(nameof(PrefixWriteLineOptions));
|
||||||
|
|
||||||
context.GetPattern(_logInit).AddPrefix(nameof(PrefixInit));
|
context.GetPattern(_logInit).AddPrefix(nameof(PrefixInit));
|
||||||
|
context.GetPattern(_logClose).AddPrefix(nameof(PrefixClose));
|
||||||
}
|
}
|
||||||
|
|
||||||
[ReflectedMethod(Name = "GetIdentByThread")]
|
[ReflectedMethod(Name = "GetIdentByThread")]
|
||||||
@@ -81,6 +85,8 @@ namespace Torch.Patches
|
|||||||
return _getIndentByThread(MyLog.Default, Environment.CurrentManagedThreadId);
|
return _getIndentByThread(MyLog.Default, Environment.CurrentManagedThreadId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool PrefixClose() => false;
|
||||||
|
|
||||||
private static bool PrefixInit(MyLog __instance, StringBuilder appVersionString)
|
private static bool PrefixInit(MyLog __instance, StringBuilder appVersionString)
|
||||||
{
|
{
|
||||||
__instance.WriteLine("Log Started");
|
__instance.WriteLine("Log Started");
|
||||||
|
@@ -26,7 +26,7 @@ namespace Torch
|
|||||||
public T Data
|
public T Data
|
||||||
{
|
{
|
||||||
get => _data;
|
get => _data;
|
||||||
private set
|
private init
|
||||||
{
|
{
|
||||||
if (_data is INotifyPropertyChanged npc1)
|
if (_data is INotifyPropertyChanged npc1)
|
||||||
npc1.PropertyChanged -= OnPropertyChanged;
|
npc1.PropertyChanged -= OnPropertyChanged;
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
<Copyright>Copyright © Torch API 2017</Copyright>
|
<Copyright>Copyright © Torch API 2017</Copyright>
|
||||||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
|
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<OutputPath>$(SolutionDir)\bin\$(Platform)\$(Configuration)\</OutputPath>
|
<OutputPath>..\bin\$(Platform)\$(Configuration)\</OutputPath>
|
||||||
<UseWpf>True</UseWpf>
|
<UseWpf>True</UseWpf>
|
||||||
<GenerateAssemblyInfo>False</GenerateAssemblyInfo>
|
<GenerateAssemblyInfo>False</GenerateAssemblyInfo>
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
@@ -1,17 +0,0 @@
|
|||||||
$buildSalt = $Env:BUILD_NUMBER
|
|
||||||
$branchName = $Env:BRANCH_NAME
|
|
||||||
$gitSimpleVersion = git describe --tags --abbrev=0
|
|
||||||
$simpleVersionStandard = echo $gitSimpleVersion | Select-String -Pattern "([0-9]+)\.([0-9]+)\.([0-9]+)" | % {$_.Matches} | %{$_.Groups[1].Value+"."+$_.Groups[2].Value+"."+$_.Groups[3].Value}
|
|
||||||
$dotNetVersion = "$simpleVersionStandard.$buildSalt"
|
|
||||||
$infoVersion = -join(("$gitSimpleVersion" -replace "([0-9]+)\.([0-9]+)\.([0-9]+)","$dotNetVersion"), "-", "$branchName")
|
|
||||||
|
|
||||||
$fileContent = @"
|
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
[assembly: AssemblyVersion("$dotNetVersion")]
|
|
||||||
[assembly: AssemblyInformationalVersion("$infoVersion")]
|
|
||||||
"@
|
|
||||||
|
|
||||||
echo $fileContent | Set-Content "$PSScriptRoot/AssemblyVersion.cs"
|
|
||||||
|
|
||||||
echo "$infoVersion"
|
|
Reference in New Issue
Block a user