diff --git a/.gitignore b/.gitignore
index 8d76898..f8dd7fe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -252,3 +252,6 @@ ModelManifest.xml
# FAKE - F# Make
.fake/
GameBinaries
+
+# Generated Files
+**Gen.cs
diff --git a/jenkins-grab-se.ps1 b/Jenkins/jenkins-grab-se.ps1
similarity index 100%
rename from jenkins-grab-se.ps1
rename to Jenkins/jenkins-grab-se.ps1
diff --git a/Jenkins/release.ps1 b/Jenkins/release.ps1
new file mode 100644
index 0000000..81e5e63
--- /dev/null
+++ b/Jenkins/release.ps1
@@ -0,0 +1,52 @@
+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)
+}
\ No newline at end of file
diff --git a/Jenkinsfile b/Jenkinsfile
index 4f6b1e1..cec3b0b 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -1,10 +1,11 @@
node {
stage('Checkout') {
checkout scm
+ bat 'git pull --tags'
}
stage('Acquire SE') {
- bat 'powershell -File jenkins-grab-se.ps1'
+ bat 'powershell -File Jenkins/jenkins-grab-se.ps1'
bat 'IF EXIST GameBinaries RMDIR GameBinaries'
bat 'mklink /J GameBinaries "C:/Steam/Data/DedicatedServer64/"'
}
@@ -14,6 +15,7 @@ node {
}
stage('Build') {
+ currentBuild.description = bat(returnStdout: true, script: '@powershell -File Versioning/version.ps1').trim()
bat "\"${tool 'MSBuild'}msbuild\" Torch.sln /p:Configuration=Release /p:Platform=x64"
}
@@ -36,6 +38,30 @@ node {
}
stage('Archive') {
- archive 'bin/x64/Release/Torch.*'
+ bat '''IF EXIST bin\\torch-server.zip DEL bin\\torch-server.zip
+ IF EXIST bin\\package-server RMDIR /S /Q bin\\package-server
+ xcopy bin\\x64\\Release bin\\package-server\\
+ del bin\\package-server\\Torch.Client*'''
+ bat "powershell -Command \"Add-Type -Assembly System.IO.Compression.FileSystem; [System.IO.Compression.ZipFile]::CreateFromDirectory(\\\"\$PWD\\bin\\package-server\\\", \\\"\$PWD\\bin\\torch-server.zip\\\")\""
+ archiveArtifacts artifacts: 'bin/torch-server.zip', caseSensitive: false, onlyIfSuccessful: true
+
+ bat '''IF EXIST bin\\torch-client.zip DEL bin\\torch-client.zip
+ IF EXIST bin\\package-client RMDIR /S /Q bin\\package-client
+ xcopy bin\\x64\\Release bin\\package-client\\
+ del bin\\package-client\\Torch.Server*'''
+ bat "powershell -Command \"Add-Type -Assembly System.IO.Compression.FileSystem; [System.IO.Compression.ZipFile]::CreateFromDirectory(\\\"\$PWD\\bin\\package-client\\\", \\\"\$PWD\\bin\\torch-client.zip\\\")\""
+ archiveArtifacts artifacts: 'bin/torch-client.zip', caseSensitive: false, onlyIfSuccessful: true
+
+ archiveArtifacts artifacts: 'bin/x64/Release/Torch*', caseSensitive: false, fingerprint: true, onlyIfSuccessful: true
}
-}
+
+ gitVersion = bat(returnStdout: true, script: "@git describe --tags").trim()
+ gitSimpleVersion = bat(returnStdout: true, script: "@git describe --tags --abbrev=0").trim()
+ if (gitVersion == gitSimpleVersion) {
+ stage('Release') {
+ withCredentials([usernamePassword(credentialsId: 'torch-github', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
+ powershell "& ./Jenkins/release.ps1 \"https://api.github.com/repos/TorchAPI/Torch/\" \"$gitSimpleVersion\" \"$USERNAME:$PASSWORD\" @(\"bin/torch-server.zip\", \"bin/torch-client.zip\")"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Setup (run before opening solution).bat b/Setup (run before opening solution).bat
index 15d629b..38c267e 100644
--- a/Setup (run before opening solution).bat
+++ b/Setup (run before opening solution).bat
@@ -3,11 +3,11 @@
@echo off
set /p path="Please enter the folder location of your SpaceEngineersDedicated.exe: "
cd %~dp0
-mklink /D GameBinaries %path%
+mklink /J GameBinaries "%path%"
if errorlevel 1 goto Error
echo Done! You can now open the Torch solution without issue.
goto End
:Error
echo An error occured creating the symlink.
:End
-pause
\ No newline at end of file
+pause
diff --git a/Torch.API/ITorchBase.cs b/Torch.API/ITorchBase.cs
index 53a45e1..b7e15d0 100644
--- a/Torch.API/ITorchBase.cs
+++ b/Torch.API/ITorchBase.cs
@@ -4,6 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Torch.API.Managers;
+using Torch.API.Session;
using VRage.Game.ModAPI;
namespace Torch.API
@@ -33,15 +34,22 @@ namespace Torch.API
///
event Action SessionUnloaded;
+ ///
+ /// Gets the currently running session instance, or null if none exists.
+ ///
+ ITorchSession CurrentSession { get; }
+
///
/// Configuration for the current instance.
///
ITorchConfig Config { get; }
///
+ [Obsolete]
IMultiplayerManager Multiplayer { get; }
///
+ [Obsolete]
IPluginManager Plugins { get; }
///
diff --git a/Torch.API/Plugins/PluginAttribute.cs b/Torch.API/Plugins/PluginAttribute.cs
index 867555c..7b60e32 100644
--- a/Torch.API/Plugins/PluginAttribute.cs
+++ b/Torch.API/Plugins/PluginAttribute.cs
@@ -1,22 +1,55 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace Torch.API.Plugins
{
+ ///
+ /// Indicates that the given type should be loaded by the plugin manager as a plugin.
+ ///
+ [AttributeUsage(AttributeTargets.Class)]
public class PluginAttribute : Attribute
{
+ ///
+ /// The display name of the plugin
+ ///
public string Name { get; }
+ ///
+ /// The version of the plugin
+ ///
public Version Version { get; }
+ ///
+ /// The GUID of the plugin
+ ///
public Guid Guid { get; }
+ ///
+ /// Creates a new plugin attribute with the given attributes
+ ///
+ ///
+ ///
+ ///
public PluginAttribute(string name, string version, string guid)
{
Name = name;
Version = Version.Parse(version);
Guid = Guid.Parse(guid);
}
+
+ ///
+ /// Creates a new plugin attribute with the given attributes. Version is computed as the version of the assembly containing the given type.
+ ///
+ ///
+ /// Version is this type's assembly's version
+ ///
+ public PluginAttribute(string name, Type versionSupplier, string guid)
+ {
+ Name = name;
+ Version = versionSupplier.Assembly.GetName().Version;
+ Guid = Guid.Parse(guid);
+ }
}
}
diff --git a/Torch.API/Properties/AssemblyInfo.cs b/Torch.API/Properties/AssemblyInfo.cs
index 6a116b9..a2627e8 100644
--- a/Torch.API/Properties/AssemblyInfo.cs
+++ b/Torch.API/Properties/AssemblyInfo.cs
@@ -1,36 +1,17 @@
using System.Reflection;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("TorchAPI")]
+[assembly: AssemblyTitle("Torch API")]
[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("TorchAPI")]
-[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyProduct("Torch")]
+[assembly: AssemblyCopyright("Copyright © Torch API 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("fba5d932-6254-4a1e-baf4-e229fa94e3c2")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+#if DEBUG
+[assembly: AssemblyConfiguration("Debug")]
+#else
+[assembly: AssemblyConfiguration("Release")]
+#endif
\ No newline at end of file
diff --git a/Torch.API/Session/ITorchSession.cs b/Torch.API/Session/ITorchSession.cs
new file mode 100644
index 0000000..710c9dd
--- /dev/null
+++ b/Torch.API/Session/ITorchSession.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Sandbox.Game.World;
+using Torch.API.Managers;
+
+namespace Torch.API.Session
+{
+ ///
+ /// Represents the Torch code working with a single game session
+ ///
+ public interface ITorchSession
+ {
+ ///
+ /// The Torch instance this session is bound to
+ ///
+ ITorchBase Torch { get; }
+
+ ///
+ /// The Space Engineers game session this session is bound to.
+ ///
+ MySession KeenSession { get; }
+
+ ///
+ IDependencyManager Managers { get; }
+ }
+}
diff --git a/Torch.API/Session/ITorchSessionManager.cs b/Torch.API/Session/ITorchSessionManager.cs
new file mode 100644
index 0000000..08fef9e
--- /dev/null
+++ b/Torch.API/Session/ITorchSessionManager.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Torch.API.Managers;
+
+namespace Torch.API.Session
+{
+ ///
+ /// Creates a manager for the given session if applicable.
+ ///
+ ///
+ /// This is for creating managers that will live inside the session, not the manager that controls sesssions.
+ ///
+ /// The session to construct a bound manager for
+ /// The manager that will live in the session, or null if none.
+ public delegate IManager SessionManagerFactoryDel(ITorchSession session);
+
+ ///
+ /// Manages the creation and destruction of instances for each created by Space Engineers.
+ ///
+ public interface ITorchSessionManager : IManager
+ {
+ ///
+ /// The currently running session
+ ///
+ ITorchSession CurrentSession { get; }
+
+ ///
+ /// Adds the given factory as a supplier for session based managers
+ ///
+ /// Session based manager supplier
+ /// true if added, false if already present
+ /// If the factory is null
+ bool AddFactory(SessionManagerFactoryDel factory);
+
+ ///
+ /// Remove the given factory from the suppliers for session based managers
+ ///
+ /// Session based manager supplier
+ /// true if removed, false if not present
+ /// If the factory is null
+ bool RemoveFactory(SessionManagerFactoryDel factory);
+ }
+}
diff --git a/Torch.API/Torch.API.csproj b/Torch.API/Torch.API.csproj
index c8f60f1..99b4836 100644
--- a/Torch.API/Torch.API.csproj
+++ b/Torch.API/Torch.API.csproj
@@ -10,6 +10,8 @@
v4.6.1
512
+
+
true
@@ -36,8 +38,8 @@
..\GameBinaries\HavokWrapper.dll
False
-
- ..\packages\NLog.4.4.1\lib\net45\NLog.dll
+
+ ..\packages\NLog.4.4.12\lib\net45\NLog.dll
True
@@ -154,6 +156,9 @@
+
+ Properties\AssemblyVersion.cs
+
@@ -175,16 +180,15 @@
+
+
+
+
+
-
+
\ No newline at end of file
diff --git a/Torch.API/packages.config b/Torch.API/packages.config
index 1c68ff1..9d88a31 100644
--- a/Torch.API/packages.config
+++ b/Torch.API/packages.config
@@ -1,4 +1,5 @@
-
+
+
\ No newline at end of file
diff --git a/Torch.Client.Tests/Properties/AssemblyInfo.cs b/Torch.Client.Tests/Properties/AssemblyInfo.cs
index 137a83c..137a623 100644
--- a/Torch.Client.Tests/Properties/AssemblyInfo.cs
+++ b/Torch.Client.Tests/Properties/AssemblyInfo.cs
@@ -1,36 +1,17 @@
using System.Reflection;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Torch.Client.Tests")]
+[assembly: AssemblyTitle("Torch Client Tests")]
[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Torch.Client.Tests")]
-[assembly: AssemblyCopyright("Copyright © 2017")]
+[assembly: AssemblyProduct("Torch")]
+[assembly: AssemblyCopyright("Copyright © Torch API 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("632e78c0-0dac-4b71-b411-2f1b333cc310")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+#if DEBUG
+[assembly: AssemblyConfiguration("Debug")]
+#else
+[assembly: AssemblyConfiguration("Release")]
+#endif
\ No newline at end of file
diff --git a/Torch.Client.Tests/Torch.Client.Tests.csproj b/Torch.Client.Tests/Torch.Client.Tests.csproj
index a95e05b..d73b8d4 100644
--- a/Torch.Client.Tests/Torch.Client.Tests.csproj
+++ b/Torch.Client.Tests/Torch.Client.Tests.csproj
@@ -34,6 +34,10 @@
$(SolutionDir)\bin-test\x64\Release\Torch.Client.Tests.xml
+
+ ..\packages\NLog.4.4.12\lib\net45\NLog.dll
+ True
+
@@ -56,6 +60,9 @@
+
+ Properties\AssemblyVersion.cs
+
@@ -81,5 +88,9 @@
+
+
+
+
\ No newline at end of file
diff --git a/Torch.Client.Tests/packages.config b/Torch.Client.Tests/packages.config
index 1158086..30eb495 100644
--- a/Torch.Client.Tests/packages.config
+++ b/Torch.Client.Tests/packages.config
@@ -1,5 +1,7 @@
+
+
diff --git a/Torch.Client/Properties/AssemblyInfo.cs b/Torch.Client/Properties/AssemblyInfo.cs
index be8ba40..0610f70 100644
--- a/Torch.Client/Properties/AssemblyInfo.cs
+++ b/Torch.Client/Properties/AssemblyInfo.cs
@@ -1,4 +1,17 @@
using System.Reflection;
+using System.Runtime.InteropServices;
-[assembly: AssemblyVersion("1.0.229.265")]
-[assembly: AssemblyFileVersion("1.0.229.265")]
\ No newline at end of file
+[assembly: AssemblyTitle("Torch Client")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Torch")]
+[assembly: AssemblyCopyright("Copyright © Torch API 2017")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+[assembly: ComVisible(false)]
+
+#if DEBUG
+[assembly: AssemblyConfiguration("Debug")]
+#else
+[assembly: AssemblyConfiguration("Release")]
+#endif
\ No newline at end of file
diff --git a/Torch.Client/Properties/AssemblyInfo.tt b/Torch.Client/Properties/AssemblyInfo.tt
deleted file mode 100644
index 9937cb7..0000000
--- a/Torch.Client/Properties/AssemblyInfo.tt
+++ /dev/null
@@ -1,16 +0,0 @@
-<#@ template debug="false" hostspecific="false" language="C#" #>
-<#@ assembly name="System.Core" #>
-<#@ import namespace="System.Linq" #>
-<#@ import namespace="System.Text" #>
-<#@ import namespace="System.Collections.Generic" #>
-<#@ output extension=".cs" #>
-using System.Reflection;
-
-<# var dt = DateTime.Now;
- int major = 1;
- int minor = 0;
- int build = dt.DayOfYear;
- int rev = (int)dt.TimeOfDay.TotalMinutes / 2;
-#>
-[assembly: AssemblyVersion("<#= major #>.<#= minor #>.<#= build #>.<#= rev #>")]
-[assembly: AssemblyFileVersion("<#= major #>.<#= minor #>.<#= build #>.<#= rev #>")]
\ No newline at end of file
diff --git a/Torch.Client/Properties/AssemblyInfo1.cs b/Torch.Client/Properties/AssemblyInfo1.cs
deleted file mode 100644
index 013f62e..0000000
--- a/Torch.Client/Properties/AssemblyInfo1.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-[assembly: AssemblyTitle("Torch Client")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Torch")]
-[assembly: AssemblyCopyright("Copyright © Torch API 2017")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-[assembly: ComVisible(false)]
\ No newline at end of file
diff --git a/Torch.Client/Torch.Client.csproj b/Torch.Client/Torch.Client.csproj
index 77e51d5..abe6a5f 100644
--- a/Torch.Client/Torch.Client.csproj
+++ b/Torch.Client/Torch.Client.csproj
@@ -13,6 +13,8 @@
4
true
+
+
true
@@ -40,7 +42,7 @@
- ..\packages\NLog.4.4.1\lib\net45\NLog.dll
+ ..\packages\NLog.4.4.12\lib\net45\NLog.dll
True
@@ -116,12 +118,10 @@
-
- AssemblyInfo.tt
- True
- True
+
+ Properties\AssemblyVersion.cs
-
+
@@ -164,25 +164,13 @@
-
-
- TextTemplatingFileGenerator
- AssemblyInfo.cs
-
-
+
copy "$(SolutionDir)NLog.config" "$(TargetDir)"
-
\ No newline at end of file
diff --git a/Torch.Client/TorchClient.cs b/Torch.Client/TorchClient.cs
index b98883d..384ad3b 100644
--- a/Torch.Client/TorchClient.cs
+++ b/Torch.Client/TorchClient.cs
@@ -12,6 +12,7 @@ using VRage.Steam;
using Torch.API;
using VRage;
using VRage.FileSystem;
+using VRage.GameServices;
using VRageRender;
using VRageRender.ExternalApp;
@@ -53,7 +54,7 @@ namespace Torch.Client
_startup.DetectSharpDxLeaksBeforeRun();
var steamService = new SteamService(Game.IsDedicated, APP_ID);
- MyServiceManager.Instance.AddService(steamService);
+ MyServiceManager.Instance.AddService(steamService);
_renderer = null;
SpaceEngineersGame.SetupPerGameSettings();
// I'm sorry, but it's what Keen does in SpaceEngineers.MyProgram
diff --git a/Torch.Client/packages.config b/Torch.Client/packages.config
index 1c68ff1..9d88a31 100644
--- a/Torch.Client/packages.config
+++ b/Torch.Client/packages.config
@@ -1,4 +1,5 @@
-
+
+
\ No newline at end of file
diff --git a/Torch.Server.Tests/Properties/AssemblyInfo.cs b/Torch.Server.Tests/Properties/AssemblyInfo.cs
index 11ceb07..8891763 100644
--- a/Torch.Server.Tests/Properties/AssemblyInfo.cs
+++ b/Torch.Server.Tests/Properties/AssemblyInfo.cs
@@ -1,36 +1,17 @@
using System.Reflection;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Torch.Server.Tests")]
+[assembly: AssemblyTitle("Torch Server Tests")]
[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Torch.Server.Tests")]
-[assembly: AssemblyCopyright("Copyright © 2017")]
+[assembly: AssemblyProduct("Torch")]
+[assembly: AssemblyCopyright("Copyright © Torch API 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("9efd1d91-2fa2-47ed-b537-d8bc3b0e543e")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+#if DEBUG
+[assembly: AssemblyConfiguration("Debug")]
+#else
+[assembly: AssemblyConfiguration("Release")]
+#endif
\ No newline at end of file
diff --git a/Torch.Server.Tests/Torch.Server.Tests.csproj b/Torch.Server.Tests/Torch.Server.Tests.csproj
index 96dac2a..a3e28b1 100644
--- a/Torch.Server.Tests/Torch.Server.Tests.csproj
+++ b/Torch.Server.Tests/Torch.Server.Tests.csproj
@@ -34,6 +34,10 @@
$(SolutionDir)\bin-test\x64\Release\Torch.Server.Tests.xml
+
+ ..\packages\NLog.4.4.12\lib\net45\NLog.dll
+ True
+
@@ -56,6 +60,9 @@
+
+ Properties\AssemblyVersion.cs
+
@@ -82,4 +89,5 @@
+
\ No newline at end of file
diff --git a/Torch.Server.Tests/packages.config b/Torch.Server.Tests/packages.config
index 1158086..30eb495 100644
--- a/Torch.Server.Tests/packages.config
+++ b/Torch.Server.Tests/packages.config
@@ -1,5 +1,7 @@
+
+
diff --git a/Torch.Server/Initializer.cs b/Torch.Server/Initializer.cs
new file mode 100644
index 0000000..e4fe99e
--- /dev/null
+++ b/Torch.Server/Initializer.cs
@@ -0,0 +1,185 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.IO.Compression;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows.Threading;
+using NLog;
+using Torch.Utils;
+
+namespace Torch.Server
+{
+ public class Initializer
+ {
+ private static readonly Logger Log = LogManager.GetLogger(nameof(Initializer));
+ private bool _init;
+ private const string STEAMCMD_DIR = "steamcmd";
+ private const string STEAMCMD_ZIP = "temp.zip";
+ private static readonly string STEAMCMD_PATH = $"{STEAMCMD_DIR}\\steamcmd.exe";
+ private static readonly string RUNSCRIPT_PATH = $"{STEAMCMD_DIR}\\runscript.txt";
+ private const string RUNSCRIPT = @"force_install_dir ../
+login anonymous
+app_update 298740
+quit";
+
+ private TorchAssemblyResolver _resolver;
+ private TorchConfig _config;
+ private TorchServer _server;
+ private string _basePath;
+
+ public TorchConfig Config => _config;
+ public TorchServer Server => _server;
+
+ public Initializer(string basePath)
+ {
+ _basePath = basePath;
+ }
+
+ public bool Initialize(string[] args)
+ {
+ if (_init)
+ return false;
+
+ AppDomain.CurrentDomain.UnhandledException += HandleException;
+
+ if (!args.Contains("-noupdate"))
+ RunSteamCmd();
+
+ _resolver = new TorchAssemblyResolver(Path.Combine(_basePath, "DedicatedServer64"));
+ _config = InitConfig();
+ if (!_config.Parse(args))
+ return false;
+
+ if (!string.IsNullOrEmpty(_config.WaitForPID))
+ {
+ try
+ {
+ var pid = int.Parse(_config.WaitForPID);
+ var waitProc = Process.GetProcessById(pid);
+ Log.Info("Continuing in 5 seconds.");
+ Thread.Sleep(5000);
+ if (!waitProc.HasExited)
+ {
+ Log.Warn($"Killing old process {pid}.");
+ waitProc.Kill();
+ }
+
+ }
+ catch
+ {
+ // ignored
+ }
+ }
+
+ _init = true;
+ return true;
+ }
+
+ public void Run()
+ {
+ _server = new TorchServer(_config);
+ _server.Init();
+
+ if (!_config.NoGui)
+ {
+ var ui = new TorchUI(_server);
+ if (_config.Autostart)
+ new Thread(_server.Start).Start();
+ ui.ShowDialog();
+ }
+ else
+ _server.Start();
+
+ _resolver?.Dispose();
+ }
+
+ private TorchConfig InitConfig()
+ {
+ var configName = "Torch.cfg";
+ var configPath = Path.Combine(Directory.GetCurrentDirectory(), configName);
+ if (File.Exists(configName))
+ {
+ Log.Info($"Loading config {configPath}");
+ return TorchConfig.LoadFrom(configPath);
+ }
+ else
+ {
+ Log.Info($"Generating default config at {configPath}");
+ var config = new TorchConfig { InstancePath = Path.GetFullPath("Instance") };
+ config.Save(configPath);
+ return config;
+ }
+ }
+
+ private static void RunSteamCmd()
+ {
+ var log = LogManager.GetLogger("SteamCMD");
+
+ if (!Directory.Exists(STEAMCMD_DIR))
+ {
+ Directory.CreateDirectory(STEAMCMD_DIR);
+ }
+
+ if (!File.Exists(RUNSCRIPT_PATH))
+ File.WriteAllText(RUNSCRIPT_PATH, RUNSCRIPT);
+
+ if (!File.Exists(STEAMCMD_PATH))
+ {
+ try
+ {
+ log.Info("Downloading SteamCMD.");
+ using (var client = new WebClient())
+ client.DownloadFile("https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip", STEAMCMD_ZIP);
+
+ ZipFile.ExtractToDirectory(STEAMCMD_ZIP, STEAMCMD_DIR);
+ File.Delete(STEAMCMD_ZIP);
+ log.Info("SteamCMD downloaded successfully!");
+ }
+ catch
+ {
+ log.Error("Failed to download SteamCMD, unable to update the DS.");
+ return;
+ }
+ }
+
+ log.Info("Checking for DS updates.");
+ var steamCmdProc = new ProcessStartInfo(STEAMCMD_PATH, "+runscript runscript.txt")
+ {
+ WorkingDirectory = Path.Combine(Directory.GetCurrentDirectory(), STEAMCMD_DIR),
+ UseShellExecute = false,
+ RedirectStandardOutput = true,
+ StandardOutputEncoding = Encoding.ASCII
+ };
+ var cmd = Process.Start(steamCmdProc);
+
+ // ReSharper disable once PossibleNullReferenceException
+ while (!cmd.HasExited)
+ {
+ log.Info(cmd.StandardOutput.ReadLine());
+ Thread.Sleep(100);
+ }
+ }
+
+
+ private void HandleException(object sender, UnhandledExceptionEventArgs e)
+ {
+ var ex = (Exception)e.ExceptionObject;
+ Log.Fatal(ex);
+ Console.WriteLine("Exiting in 5 seconds.");
+ Thread.Sleep(5000);
+ if (_config.RestartOnCrash)
+ {
+ var exe = typeof(Program).Assembly.Location;
+ _config.WaitForPID = Process.GetCurrentProcess().Id.ToString();
+ Process.Start(exe, _config.ToString());
+ }
+ //1627 = Function failed during execution.
+ Environment.Exit(1627);
+ }
+ }
+}
diff --git a/Torch.Server/Managers/InstanceManager.cs b/Torch.Server/Managers/InstanceManager.cs
index c8d52b8..f11a446 100644
--- a/Torch.Server/Managers/InstanceManager.cs
+++ b/Torch.Server/Managers/InstanceManager.cs
@@ -131,7 +131,7 @@ namespace Torch.Server.Managers
public void SaveConfig()
{
- DedicatedConfig.Save();
+ DedicatedConfig.Save(Path.Combine(Torch.Config.InstancePath, CONFIG_NAME));
Log.Info("Saved dedicated config.");
try
diff --git a/Torch.Server/Program.cs b/Torch.Server/Program.cs
index 4a4fac9..efcc40a 100644
--- a/Torch.Server/Program.cs
+++ b/Torch.Server/Program.cs
@@ -25,6 +25,7 @@ using System.IO.Compression;
using System.Net;
using System.Security.Policy;
using Torch.Server.Managers;
+using Torch.Utils;
using VRage.FileSystem;
using VRageRender;
@@ -32,268 +33,32 @@ namespace Torch.Server
{
internal static class Program
{
- private static ITorchServer _server;
- private static Logger _log = LogManager.GetLogger("Torch");
- private static bool _restartOnCrash;
- private static TorchConfig _config;
- private static bool _steamCmdDone;
-
- ///
+ ///
/// This method must *NOT* load any types/assemblies from the vanilla game, otherwise automatic updates will fail.
- ///
+ ///
[STAThread]
public static void Main(string[] args)
{
//Ensures that all the files are downloaded in the Torch directory.
- Directory.SetCurrentDirectory(new FileInfo(typeof(Program).Assembly.Location).Directory.ToString());
-
- foreach (var file in Directory.GetFiles(Directory.GetCurrentDirectory(), "*.old"))
- File.Delete(file);
-
- AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
- AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
+ var workingDir = new FileInfo(typeof(Program).Assembly.Location).Directory.ToString();
+ var binDir = Path.Combine(workingDir, "DedicatedServer64");
+ Directory.SetCurrentDirectory(workingDir);
if (!Environment.UserInteractive)
{
using (var service = new TorchService())
+ using (new TorchAssemblyResolver(binDir))
{
ServiceBase.Run(service);
}
return;
}
- //CommandLine reflection triggers assembly loading, so DS update must be completely separated.
- if (!args.Contains("-noupdate"))
- {
- if (!Directory.Exists("DedicatedServer64"))
- {
- _log.Error("Game libraries not found. Press the Enter key to install the dedicated server.");
- Console.ReadLine();
- }
- RunSteamCmd();
- }
-
- InitConfig();
-
- if (!_config.Parse(args))
+ var initializer = new Initializer(workingDir);
+ if (!initializer.Initialize(args))
return;
- if (!string.IsNullOrEmpty(_config.WaitForPID))
- {
- try
- {
- var pid = int.Parse(_config.WaitForPID);
- var waitProc = Process.GetProcessById(pid);
- _log.Info("Continuing in 5 seconds.");
- Thread.Sleep(5000);
- if (!waitProc.HasExited)
- {
- _log.Warn($"Killing old process {pid}.");
- waitProc.Kill();
- }
-
- }
- catch
- {
- // ignored
- }
- }
-
- _restartOnCrash = _config.RestartOnCrash;
- RunServer(_config);
- }
-
- public static void InitConfig()
- {
- var configName = "Torch.cfg";
- var configPath = Path.Combine(Directory.GetCurrentDirectory(), configName);
- if (File.Exists(configName))
- {
- _log.Info($"Loading config {configPath}");
- _config = TorchConfig.LoadFrom(configPath);
- }
- else
- {
- _log.Info($"Generating default config at {configPath}");
- _config = new TorchConfig { InstancePath = Path.GetFullPath("Instance") };
- _config.Save(configPath);
- }
- }
-
- private const string STEAMCMD_DIR = "steamcmd";
- private const string STEAMCMD_ZIP = "temp.zip";
- private static readonly string STEAMCMD_PATH = $"{STEAMCMD_DIR}\\steamcmd.exe";
- private static readonly string RUNSCRIPT_PATH = $"{STEAMCMD_DIR}\\runscript.txt";
- private const string RUNSCRIPT = @"force_install_dir ../
-login anonymous
-app_update 298740
-quit";
-
- public static void RunSteamCmd()
- {
- if (_steamCmdDone)
- return;
-
- var log = LogManager.GetLogger("SteamCMD");
-
- if (!Directory.Exists(STEAMCMD_DIR))
- {
- Directory.CreateDirectory(STEAMCMD_DIR);
- }
-
- if (!File.Exists(RUNSCRIPT_PATH))
- File.WriteAllText(RUNSCRIPT_PATH, RUNSCRIPT);
-
- if (!File.Exists(STEAMCMD_PATH))
- {
- try
- {
- log.Info("Downloading SteamCMD.");
- using (var client = new WebClient())
- client.DownloadFile("https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip", STEAMCMD_ZIP);
-
- ZipFile.ExtractToDirectory(STEAMCMD_ZIP, STEAMCMD_DIR);
- File.Delete(STEAMCMD_ZIP);
- log.Info("SteamCMD downloaded successfully!");
- }
- catch
- {
- log.Error("Failed to download SteamCMD, unable to update the DS.");
- return;
- }
- }
-
- log.Info("Checking for DS updates.");
- var steamCmdProc = new ProcessStartInfo(STEAMCMD_PATH, "+runscript runscript.txt")
- {
- WorkingDirectory = Path.Combine(Directory.GetCurrentDirectory(), STEAMCMD_DIR),
- UseShellExecute = false,
- RedirectStandardOutput = true,
- StandardOutputEncoding = Encoding.ASCII
- };
- var cmd = Process.Start(steamCmdProc);
-
- // ReSharper disable once PossibleNullReferenceException
- while (!cmd.HasExited)
- {
- log.Info(cmd.StandardOutput.ReadLine());
- Thread.Sleep(100);
- }
-
- _steamCmdDone = true;
- }
-
- public static void RunServer(TorchConfig config)
- {
-
-
- /*
- if (!parser.ParseArguments(args, config))
- {
- _log.Error($"Parsing arguments failed: {string.Join(" ", args)}");
- return;
- }
-
- if (!string.IsNullOrEmpty(config.Config) && File.Exists(config.Config))
- {
- config = ServerConfig.LoadFrom(config.Config);
- parser.ParseArguments(args, config);
- }*/
-
- //RestartOnCrash autostart autosave=15
- //gamepath ="C:\Program Files\Space Engineers DS" instance="Hydro Survival" instancepath="C:\ProgramData\SpaceEngineersDedicated\Hydro Survival"
-
- /*
- if (config.InstallService)
- {
- var serviceName = $"\"Torch - {config.InstanceName}\"";
- // Working on installing the service properly instead of with sc.exe
- _log.Info($"Installing service '{serviceName}");
- var exePath = $"\"{Assembly.GetExecutingAssembly().Location}\"";
- var createInfo = new ServiceCreateInfo
- {
- Name = config.InstanceName,
- BinaryPath = exePath,
- };
- _log.Info("Service Installed");
-
- var runArgs = string.Join(" ", args.Skip(1));
- _log.Info($"Installing Torch as a service with arguments '{runArgs}'");
- var startInfo = new ProcessStartInfo
- {
- FileName = "sc.exe",
- Arguments = $"create Torch binPath=\"{Assembly.GetExecutingAssembly().Location} {runArgs}\"",
- CreateNoWindow = true,
- UseShellExecute = true,
- Verb = "runas"
- };
- Process.Start(startInfo).WaitForExit();
- _log.Info("Torch service installed");
- return;
- }
-
- if (config.UninstallService)
- {
- _log.Info("Uninstalling Torch service");
- var startInfo = new ProcessStartInfo
- {
- FileName = "sc.exe",
- Arguments = "delete Torch",
- CreateNoWindow = true,
- UseShellExecute = true,
- Verb = "runas"
- };
- Process.Start(startInfo).WaitForExit();
- _log.Info("Torch service uninstalled");
- return;
- }*/
-
- _server = new TorchServer(config);
-
- _server.Init();
- if (config.NoGui || config.Autostart)
- {
- new Thread(() => _server.Start()).Start();
- }
-
- if (!config.NoGui)
- {
- var ui = new TorchUI((TorchServer)_server);
- ui.ShowDialog();
- }
- }
-
- private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
- {
- try
- {
- var basePath = Path.Combine(Path.GetDirectoryName(typeof(Program).Assembly.Location), "DedicatedServer64");
- string asmPath = Path.Combine(basePath, new AssemblyName(args.Name).Name + ".dll");
- if (File.Exists(asmPath))
- return Assembly.LoadFrom(asmPath);
- }
- catch
- {
- // ignored
- }
-
- return null;
- }
-
- private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
- {
- var ex = (Exception)e.ExceptionObject;
- _log.Fatal(ex);
- Console.WriteLine("Exiting in 5 seconds.");
- Thread.Sleep(5000);
- if (_restartOnCrash)
- {
- var exe = typeof(Program).Assembly.Location;
- _config.WaitForPID = Process.GetCurrentProcess().Id.ToString();
- Process.Start(exe, _config.ToString());
- }
- //1627 = Function failed during execution.
- Environment.Exit(1627);
+ initializer.Run();
}
}
}
diff --git a/Torch.Server/Properties/AssemblyInfo.cs b/Torch.Server/Properties/AssemblyInfo.cs
index 34b834d..2256788 100644
--- a/Torch.Server/Properties/AssemblyInfo.cs
+++ b/Torch.Server/Properties/AssemblyInfo.cs
@@ -1,4 +1,17 @@
using System.Reflection;
+using System.Runtime.InteropServices;
-[assembly: AssemblyVersion("1.1.229.265")]
-[assembly: AssemblyFileVersion("1.1.229.265")]
\ No newline at end of file
+[assembly: AssemblyTitle("Torch Server")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Torch")]
+[assembly: AssemblyCopyright("Copyright © Torch API 2017")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+[assembly: ComVisible(false)]
+
+#if DEBUG
+[assembly: AssemblyConfiguration("Debug")]
+#else
+[assembly: AssemblyConfiguration("Release")]
+#endif
\ No newline at end of file
diff --git a/Torch.Server/Properties/AssemblyInfo.tt b/Torch.Server/Properties/AssemblyInfo.tt
deleted file mode 100644
index 890b974..0000000
--- a/Torch.Server/Properties/AssemblyInfo.tt
+++ /dev/null
@@ -1,16 +0,0 @@
-<#@ template debug="false" hostspecific="false" language="C#" #>
-<#@ assembly name="System.Core" #>
-<#@ import namespace="System.Linq" #>
-<#@ import namespace="System.Text" #>
-<#@ import namespace="System.Collections.Generic" #>
-<#@ output extension=".cs" #>
-using System.Reflection;
-
-<# var dt = DateTime.Now;
- int major = 1;
- int minor = 1;
- int build = dt.DayOfYear;
- int rev = (int)dt.TimeOfDay.TotalMinutes / 2;
-#>
-[assembly: AssemblyVersion("<#= major #>.<#= minor #>.<#= build #>.<#= rev #>")]
-[assembly: AssemblyFileVersion("<#= major #>.<#= minor #>.<#= build #>.<#= rev #>")]
\ No newline at end of file
diff --git a/Torch.Server/Properties/AssemblyInfo1.cs b/Torch.Server/Properties/AssemblyInfo1.cs
deleted file mode 100644
index c1db141..0000000
--- a/Torch.Server/Properties/AssemblyInfo1.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-[assembly: AssemblyTitle("Torch Server")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Torch")]
-[assembly: AssemblyCopyright("Copyright © Torch API 2017")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-[assembly: ComVisible(false)]
\ No newline at end of file
diff --git a/Torch.Server/Torch.Server.csproj b/Torch.Server/Torch.Server.csproj
index 4d85e77..fbfab75 100644
--- a/Torch.Server/Torch.Server.csproj
+++ b/Torch.Server/Torch.Server.csproj
@@ -13,6 +13,8 @@
4
true
+
+
true
@@ -61,7 +63,8 @@
..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll
- ..\packages\NLog.4.4.11\lib\net45\NLog.dll
+ ..\packages\NLog.4.4.12\lib\net45\NLog.dll
+ True
False
@@ -184,15 +187,14 @@
+
+ Properties\AssemblyVersion.cs
+
-
- True
- True
- AssemblyInfo.tt
-
-
+
+
@@ -357,22 +359,10 @@
-
-
- TextTemplatingFileGenerator
- AssemblyInfo.cs
-
-
+
copy "$(SolutionDir)NLog.config" "$(TargetDir)"
-
\ No newline at end of file
diff --git a/Torch.Server/TorchConfig.cs b/Torch.Server/TorchConfig.cs
index 669f145..bb1c8ad 100644
--- a/Torch.Server/TorchConfig.cs
+++ b/Torch.Server/TorchConfig.cs
@@ -8,6 +8,7 @@ using NLog;
namespace Torch.Server
{
+ // TODO: redesign this gerbage
public class TorchConfig : CommandLine, ITorchConfig
{
private static Logger _log = LogManager.GetLogger("Config");
diff --git a/Torch.Server/TorchServer.cs b/Torch.Server/TorchServer.cs
index f5a9b56..987aad9 100644
--- a/Torch.Server/TorchServer.cs
+++ b/Torch.Server/TorchServer.cs
@@ -145,9 +145,17 @@ namespace Torch.Server
VRage.Service.ExitListenerSTA.OnExit += delegate { MySandboxGame.Static?.Exit(); };
base.Start();
- //Stops RunInternal from calling MyFileSystem.InitUserSpecific(null), we call it in InstanceManager.
+ // Stops RunInternal from calling MyFileSystem.InitUserSpecific(null), we call it in InstanceManager.
MySandboxGame.IsReloading = true;
- _dsRunInternal.Invoke();
+ try
+ {
+ _dsRunInternal.Invoke();
+ }
+ catch (TargetInvocationException e)
+ {
+ // Makes log formatting a little nicer.
+ throw e.InnerException ?? e;
+ }
MySandboxGame.Log.Close();
State = ServerState.Stopped;
diff --git a/Torch.Server/TorchService.cs b/Torch.Server/TorchService.cs
index ca8edc7..e33fda3 100644
--- a/Torch.Server/TorchService.cs
+++ b/Torch.Server/TorchService.cs
@@ -14,13 +14,15 @@ namespace Torch.Server
{
public const string Name = "Torch (SEDS)";
private TorchServer _server;
- private static Logger _log = LogManager.GetLogger("Torch");
+ private Initializer _initializer;
public TorchService()
{
- ServiceName = Name;
+ var workingDir = new FileInfo(typeof(TorchService).Assembly.Location).Directory.ToString();
+ Directory.SetCurrentDirectory(workingDir);
+ _initializer = new Initializer(workingDir);
- CanHandlePowerEvent = true;
+ ServiceName = Name;
CanHandleSessionChangeEvent = false;
CanPauseAndContinue = false;
CanStop = true;
@@ -31,17 +33,8 @@ namespace Torch.Server
{
base.OnStart(args);
- string configName = args.Length > 0 ? args[0] : "Torch.cfg";
- var options = new TorchConfig("Torch");
- if (File.Exists(configName))
- options = TorchConfig.LoadFrom(configName);
- else
- options.Save(configName);
-
- _server = new TorchServer(options);
- _server.Init();
- _server.RunArgs = args;
- Task.Run(() => _server.Start());
+ _initializer.Initialize(args);
+ _initializer.Run();
}
///
@@ -50,17 +43,5 @@ namespace Torch.Server
_server.Stop();
base.OnStop();
}
-
- ///
- protected override void OnShutdown()
- {
- base.OnShutdown();
- }
-
- ///
- protected override bool OnPowerEvent(PowerBroadcastStatus powerStatus)
- {
- return base.OnPowerEvent(powerStatus);
- }
}
}
diff --git a/Torch.Server/Views/ChatControl.xaml b/Torch.Server/Views/ChatControl.xaml
index 8d3e692..3f6ea01 100644
--- a/Torch.Server/Views/ChatControl.xaml
+++ b/Torch.Server/Views/ChatControl.xaml
@@ -10,20 +10,9 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
diff --git a/Torch.Server/Views/ChatControl.xaml.cs b/Torch.Server/Views/ChatControl.xaml.cs
index 03bab57..6078aeb 100644
--- a/Torch.Server/Views/ChatControl.xaml.cs
+++ b/Torch.Server/Views/ChatControl.xaml.cs
@@ -41,23 +41,32 @@ namespace Torch.Server
{
_server = (TorchBase)server;
_multiplayer = (MultiplayerManager)server.Multiplayer;
- ChatItems.Items.Clear();
DataContext = _multiplayer;
+
+ ChatItems.Inlines.Clear();
+ _multiplayer.ChatHistory.ForEach(InsertMessage);
if (_multiplayer.ChatHistory is INotifyCollectionChanged ncc)
ncc.CollectionChanged += ChatHistory_CollectionChanged;
+ ChatScroller.ScrollToBottom();
}
private void ChatHistory_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
- ChatItems.ScrollToItem(ChatItems.Items.Count - 1);
- /*
- if (VisualTreeHelper.GetChildrenCount(ChatItems) > 0)
- {
-
- Border border = (Border)VisualTreeHelper.GetChild(ChatItems, 0);
- ScrollViewer scrollViewer = (ScrollViewer)VisualTreeHelper.GetChild(border, 0);
- scrollViewer.ScrollToBottom();
- }*/
+ foreach (IChatMessage msg in e.NewItems)
+ InsertMessage(msg);
+ }
+
+ private void InsertMessage(IChatMessage msg)
+ {
+ bool atBottom = ChatScroller.VerticalOffset + 8 > ChatScroller.ScrollableHeight;
+ var span = new Span();
+ span.Inlines.Add($"{msg.Timestamp} ");
+ span.Inlines.Add(new Run(msg.Name) { Foreground = msg.Name == "Server" ? Brushes.DarkBlue : Brushes.Blue });
+ span.Inlines.Add($": {msg.Message}");
+ span.Inlines.Add(new LineBreak());
+ ChatItems.Inlines.Add(span);
+ if (atBottom)
+ ChatScroller.ScrollToBottom();
}
private void SendButton_Click(object sender, RoutedEventArgs e)
@@ -81,7 +90,7 @@ namespace Torch.Server
var commands = _server.Commands;
if (commands.IsCommand(text))
{
- _multiplayer.ChatHistory.Add(new ChatMessage(DateTime.Now, 0, "Server", text));
+ _multiplayer.ChatHistory.Add(new ChatMessage(DateTime.Now, 0, "Server", text));
_server.Invoke(() =>
{
var response = commands.HandleCommandFromServer(text);
diff --git a/Torch.Server/packages.config b/Torch.Server/packages.config
index cd583f4..5221eb5 100644
--- a/Torch.Server/packages.config
+++ b/Torch.Server/packages.config
@@ -1,5 +1,6 @@
+
-
+
\ No newline at end of file
diff --git a/Torch.Tests/Properties/AssemblyInfo.cs b/Torch.Tests/Properties/AssemblyInfo.cs
index 089d989..1551025 100644
--- a/Torch.Tests/Properties/AssemblyInfo.cs
+++ b/Torch.Tests/Properties/AssemblyInfo.cs
@@ -1,36 +1,17 @@
using System.Reflection;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Torch.Tests")]
+[assembly: AssemblyTitle("Torch Tests")]
[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Torch.Tests")]
-[assembly: AssemblyCopyright("Copyright © 2017")]
+[assembly: AssemblyProduct("Torch")]
+[assembly: AssemblyCopyright("Copyright © Torch API 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("c3c8b671-6ad1-44aa-a8da-e0c0dc0fedf5")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+#if DEBUG
+[assembly: AssemblyConfiguration("Debug")]
+#else
+[assembly: AssemblyConfiguration("Release")]
+#endif
\ No newline at end of file
diff --git a/Torch.Tests/Torch.Tests.csproj b/Torch.Tests/Torch.Tests.csproj
index 20ab0ad..fc5f81a 100644
--- a/Torch.Tests/Torch.Tests.csproj
+++ b/Torch.Tests/Torch.Tests.csproj
@@ -34,6 +34,10 @@
$(SolutionDir)\bin-test\x64\Release\Torch.Tests.xml
+
+ ..\packages\NLog.4.4.12\lib\net45\NLog.dll
+ True
+
@@ -56,9 +60,12 @@
+
+ Properties\AssemblyVersion.cs
+
+
-
@@ -76,5 +83,9 @@
+
+
+
+
\ No newline at end of file
diff --git a/Torch.Tests/packages.config b/Torch.Tests/packages.config
index 1158086..30eb495 100644
--- a/Torch.Tests/packages.config
+++ b/Torch.Tests/packages.config
@@ -1,5 +1,7 @@
+
+
diff --git a/Torch.sln b/Torch.sln
index d99ed03..a1a48ba 100644
--- a/Torch.sln
+++ b/Torch.sln
@@ -22,6 +22,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Torch.Server.Tests", "Torch
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Torch.Client.Tests", "Torch.Client.Tests\Torch.Client.Tests.csproj", "{632E78C0-0DAC-4B71-B411-2F1B333CC310}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Versioning", "Versioning", "{762F6A0D-55EF-4173-8CDE-309D183F40C4}"
+ ProjectSection(SolutionItems) = preProject
+ Versioning\AssemblyVersion.cs = Versioning\AssemblyVersion.cs
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@@ -60,6 +65,9 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {762F6A0D-55EF-4173-8CDE-309D183F40C4} = {7AD02A71-1D4C-48F9-A8C1-789A5512424F}
+ EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BB51D91F-958D-4B63-A897-3C40642ACD3E}
EndGlobalSection
diff --git a/Torch/Commands/Command.cs b/Torch/Commands/Command.cs
index dc95c51..7aedcab 100644
--- a/Torch/Commands/Command.cs
+++ b/Torch/Commands/Command.cs
@@ -62,7 +62,7 @@ namespace Torch.Commands
_parameters = commandMethod.GetParameters();
var sb = new StringBuilder();
- sb.Append($"/{string.Join(" ", Path)} ");
+ sb.Append($"!{string.Join(" ", Path)} ");
for (var i = 0; i < _parameters.Length; i++)
{
var param = _parameters[i];
diff --git a/Torch/Managers/UpdateManager.cs b/Torch/Managers/UpdateManager.cs
index 8702299..02d0a2a 100644
--- a/Torch/Managers/UpdateManager.cs
+++ b/Torch/Managers/UpdateManager.cs
@@ -108,6 +108,9 @@ namespace Torch.Managers
private async void CheckAndUpdateTorch()
{
+ // Doesn't work properly or reliably, TODO update when Jenkins is fully configured
+ return;
+
if (!Torch.Config.GetTorchUpdates)
return;
diff --git a/Torch/Properties/AssemblyInfo.cs b/Torch/Properties/AssemblyInfo.cs
index 465d2d9..21a30ba 100644
--- a/Torch/Properties/AssemblyInfo.cs
+++ b/Torch/Properties/AssemblyInfo.cs
@@ -1,36 +1,17 @@
using System.Reflection;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Piston")]
+[assembly: AssemblyTitle("Torch")]
[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Piston")]
-[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyProduct("Torch")]
+[assembly: AssemblyCopyright("Copyright © Torch API 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("7e01635c-3b67-472e-bcd6-c5539564f214")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+#if DEBUG
+[assembly: AssemblyConfiguration("Debug")]
+#else
+[assembly: AssemblyConfiguration("Release")]
+#endif
\ No newline at end of file
diff --git a/Torch/Session/TorchSession.cs b/Torch/Session/TorchSession.cs
new file mode 100644
index 0000000..6ec4a2d
--- /dev/null
+++ b/Torch/Session/TorchSession.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using NLog;
+using Sandbox.Game.World;
+using Torch.API;
+using Torch.API.Managers;
+using Torch.API.Session;
+using Torch.Managers;
+
+namespace Torch.Session
+{
+ public class TorchSession : ITorchSession
+ {
+ private static readonly Logger _log = LogManager.GetCurrentClassLogger();
+
+ ///
+ /// The Torch instance this session is bound to
+ ///
+ public ITorchBase Torch { get; }
+
+ ///
+ /// The Space Engineers game session this session is bound to.
+ ///
+ public MySession KeenSession { get; }
+
+ ///
+ public IDependencyManager Managers { get; }
+
+ public TorchSession(ITorchBase torch, MySession keenSession)
+ {
+ Torch = torch;
+ KeenSession = keenSession;
+ Managers = new DependencyManager(torch.Managers);
+ }
+
+ internal void Attach()
+ {
+ Managers.Attach();
+ }
+
+ internal void Detach()
+ {
+ Managers.Detach();
+ }
+ }
+}
diff --git a/Torch/Session/TorchSessionManager.cs b/Torch/Session/TorchSessionManager.cs
new file mode 100644
index 0000000..3e4b1a6
--- /dev/null
+++ b/Torch/Session/TorchSessionManager.cs
@@ -0,0 +1,93 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using NLog;
+using Sandbox.Game.World;
+using Torch.API;
+using Torch.API.Managers;
+using Torch.API.Session;
+using Torch.Managers;
+using Torch.Session;
+
+namespace Torch.Session
+{
+ ///
+ /// Manages the creation and destruction of instances for each created by Space Engineers.
+ ///
+ public class TorchSessionManager : Manager, ITorchSessionManager
+ {
+ private static readonly Logger _log = LogManager.GetCurrentClassLogger();
+ private TorchSession _currentSession;
+
+ ///
+ public ITorchSession CurrentSession => _currentSession;
+
+ private readonly HashSet _factories = new HashSet();
+
+ public TorchSessionManager(ITorchBase torchInstance) : base(torchInstance)
+ {
+ }
+
+ ///
+ public bool AddFactory(SessionManagerFactoryDel factory)
+ {
+ if (factory == null)
+ throw new ArgumentNullException(nameof(factory), "Factory must be non-null");
+ return _factories.Add(factory);
+ }
+
+ ///
+ public bool RemoveFactory(SessionManagerFactoryDel factory)
+ {
+ if (factory == null)
+ throw new ArgumentNullException(nameof(factory), "Factory must be non-null");
+ return _factories.Remove(factory);
+ }
+
+ private void SessionLoaded()
+ {
+ if (_currentSession != null)
+ {
+ _log.Warn($"Override old torch session {_currentSession.KeenSession.Name}");
+ _currentSession.Detach();
+ }
+
+ _log.Info($"Starting new torch session for {MySession.Static.Name}");
+ _currentSession = new TorchSession(Torch, MySession.Static);
+ foreach (SessionManagerFactoryDel factory in _factories)
+ {
+ IManager manager = factory(CurrentSession);
+ if (manager != null)
+ CurrentSession.Managers.AddManager(manager);
+ }
+ (CurrentSession as TorchSession)?.Attach();
+ }
+
+ private void SessionUnloaded()
+ {
+ if (_currentSession == null)
+ return;
+ _log.Info($"Unloading torch session for {_currentSession.KeenSession.Name}");
+ _currentSession.Detach();
+ _currentSession = null;
+ }
+
+ ///
+ public override void Attach()
+ {
+ MySession.AfterLoading += SessionLoaded;
+ MySession.OnUnloaded += SessionUnloaded;
+ }
+
+ ///
+ public override void Detach()
+ {
+ _currentSession?.Detach();
+ _currentSession = null;
+ MySession.AfterLoading -= SessionLoaded;
+ MySession.OnUnloaded -= SessionUnloaded;
+ }
+ }
+}
diff --git a/Torch/SteamService.cs b/Torch/SteamService.cs
index a39b443..552bc4f 100644
--- a/Torch/SteamService.cs
+++ b/Torch/SteamService.cs
@@ -3,9 +3,11 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using NLog;
using SteamSDK;
using VRage.Steam;
using Sandbox;
+using Sandbox.Engine.Networking;
using Torch.Utils;
using VRage.GameServices;
@@ -19,6 +21,9 @@ namespace Torch
///
public class SteamService : MySteamService
{
+ private static readonly Logger _log = LogManager.GetCurrentClassLogger();
+
+#pragma warning disable 649
[ReflectedSetter(Name = nameof(SteamServerAPI))]
private static Action _steamServerAPISetter;
[ReflectedSetter(Name = "m_gameServer")]
@@ -45,6 +50,7 @@ namespace Torch
private static Action RegisterCallbacks;
[ReflectedSetter(Name = nameof(Peer2Peer))]
private static Action _steamPeer2PeerSetter;
+#pragma warning restore 649
public SteamService(bool isDedicated, uint appId)
: base(true, appId)
@@ -53,7 +59,7 @@ namespace Torch
_steamServerAPISetter.Invoke(this, null);
_steamGameServerSetter.Invoke(this, null);
_steamAppIdSetter.Invoke(this, appId);
-
+
if (isDedicated)
{
_steamServerAPISetter.Invoke(this, null);
@@ -63,7 +69,10 @@ namespace Torch
{
SteamAPI steamApi = SteamAPI.Instance;
_steamApiSetter.Invoke(this, steamApi);
- _steamIsActiveSetter.Invoke(this, steamApi.Init());
+ bool initResult = steamApi.Init();
+ if (!initResult)
+ _log.Warn("Failed to initialize SteamService");
+ _steamIsActiveSetter.Invoke(this, initResult);
if (IsActive)
{
@@ -76,7 +85,8 @@ namespace Torch
_steamInventoryAPISetter.Invoke(this, new MySteamInventory());
RegisterCallbacks(this);
- }
+ } else
+ _log.Warn("SteamService isn't initialized; Torch Client won't start");
}
_steamPeer2PeerSetter.Invoke(this, new MySteamPeer2Peer());
diff --git a/Torch/Torch.csproj b/Torch/Torch.csproj
index 92974e5..77002b8 100644
--- a/Torch/Torch.csproj
+++ b/Torch/Torch.csproj
@@ -10,6 +10,8 @@
v4.6.1
512
+
+
true
@@ -41,7 +43,7 @@
..\GameBinaries\Newtonsoft.Json.dll
- ..\packages\NLog.4.4.1\lib\net45\NLog.dll
+ ..\packages\NLog.4.4.12\lib\net45\NLog.dll
True
@@ -147,11 +149,14 @@
+
+ Properties\AssemblyVersion.cs
+
-
+
@@ -180,9 +185,12 @@
+
+
+
@@ -191,7 +199,6 @@
-
CollectionEditor.xaml
@@ -213,12 +220,9 @@
Designer
+
+
+
-
+
\ No newline at end of file
diff --git a/Torch/TorchBase.cs b/Torch/TorchBase.cs
index 7bdc650..3a40a23 100644
--- a/Torch/TorchBase.cs
+++ b/Torch/TorchBase.cs
@@ -19,9 +19,11 @@ using SpaceEngineers.Game;
using Torch.API;
using Torch.API.Managers;
using Torch.API.ModAPI;
+using Torch.API.Session;
using Torch.Commands;
using Torch.Managers;
using Torch.Utils;
+using Torch.Session;
using VRage.Collections;
using VRage.FileSystem;
using VRage.Game.ObjectBuilder;
@@ -51,21 +53,36 @@ namespace Torch
///
public ITorchConfig Config { get; protected set; }
///
- public Version TorchVersion { get; protected set; }
+ public Version TorchVersion { get; }
+
+ ///
+ /// The version of Torch used, with extra data.
+ ///
+ public string TorchVersionVerbose { get; }
+
///
public Version GameVersion { get; private set; }
///
public string[] RunArgs { get; set; }
///
+ [Obsolete("Use GetManager() or the [Dependency] attribute.")]
public IPluginManager Plugins { get; protected set; }
///
+ [Obsolete("Use GetManager() or the [Dependency] attribute.")]
public IMultiplayerManager Multiplayer { get; protected set; }
///
+ [Obsolete("Use GetManager() or the [Dependency] attribute.")]
public EntityManager Entities { get; protected set; }
///
+ [Obsolete("Use GetManager() or the [Dependency] attribute.")]
public INetworkManager Network { get; protected set; }
///
+ [Obsolete("Use GetManager() or the [Dependency] attribute.")]
public CommandManager Commands { get; protected set; }
+
+ ///
+ public ITorchSession CurrentSession => Managers?.GetManager()?.CurrentSession;
+
///
public event Action SessionLoading;
///
@@ -96,7 +113,8 @@ namespace Torch
Instance = this;
- TorchVersion = Assembly.GetExecutingAssembly().GetName().Version;
+ TorchVersion = Assembly.GetExecutingAssembly().GetName().Version;
+ TorchVersionVerbose = Assembly.GetEntryAssembly().GetCustomAttribute()?.InformationalVersion ?? TorchVersion.ToString();
RunArgs = new string[0];
Managers = new DependencyManager();
@@ -107,6 +125,7 @@ namespace Torch
Network = new NetworkManager(this);
Commands = new CommandManager(this);
+ Managers.AddManager(new TorchSessionManager(this));
Managers.AddManager(new FilesystemManager(this));
Managers.AddManager(new UpdateManager(this));
Managers.AddManager(Network);
@@ -116,7 +135,6 @@ namespace Torch
Managers.AddManager(Entities);
Managers.AddManager(new ChatManager(this));
-
TorchAPI.Instance = this;
}
@@ -145,7 +163,7 @@ namespace Torch
{
callback?.Invoke(SaveGameStatus.GameNotReady);
}
- else if(MyAsyncSaving.InProgress)
+ else if (MyAsyncSaving.InProgress)
{
callback?.Invoke(SaveGameStatus.SaveInProgress);
}
@@ -234,11 +252,11 @@ namespace Torch
SpaceEngineersGame.SetupBasicGameInfo();
SpaceEngineersGame.SetupPerGameSettings();
- TorchVersion = Assembly.GetEntryAssembly().GetName().Version;
+ Debug.Assert(MyPerGameSettings.BasicGameInfo.GameVersion != null, "MyPerGameSettings.BasicGameInfo.GameVersion != null");
GameVersion = new Version(new MyVersion(MyPerGameSettings.BasicGameInfo.GameVersion.Value).FormattedText.ToString().Replace("_", "."));
- var verInfo = $"{Config.InstanceName} - Torch {TorchVersion}, SE {GameVersion}";
- try { Console.Title = verInfo; }
- catch {
+ try { Console.Title = $"{Config.InstanceName} - Torch {TorchVersion}, SE {GameVersion}"; }
+ catch
+ {
///Running as service
}
@@ -247,7 +265,8 @@ namespace Torch
#else
Log.Info("RELEASE");
#endif
- Log.Info(verInfo);
+ Log.Info($"Torch Version: {TorchVersionVerbose}");
+ Log.Info($"Game Version: {GameVersion}");
Log.Info($"Executing assembly: {Assembly.GetEntryAssembly().FullName}");
Log.Info($"Executing directory: {AppDomain.CurrentDomain.BaseDirectory}");
@@ -306,19 +325,19 @@ namespace Torch
///
public virtual void Start()
{
-
+
}
///
public virtual void Stop()
{
-
+
}
///
public virtual void Restart()
{
-
+
}
///
@@ -336,7 +355,7 @@ namespace Torch
///
public virtual void Update()
{
- Plugins.UpdatePlugins();
+ GetManager().UpdatePlugins();
}
}
}
diff --git a/Torch/Utils/ReflectedManager.cs b/Torch/Utils/ReflectedManager.cs
index ce27f93..6a6f342 100644
--- a/Torch/Utils/ReflectedManager.cs
+++ b/Torch/Utils/ReflectedManager.cs
@@ -23,6 +23,15 @@ namespace Torch.Utils
/// Declaring type of the member to access. If null, inferred from the instance argument type.
///
public Type Type { get; set; } = null;
+
+ ///
+ /// Assembly qualified name of
+ ///
+ public string TypeName
+ {
+ get => Type?.AssemblyQualifiedName;
+ set => Type = value == null ? null : Type.GetType(value, true);
+ }
}
///
@@ -93,6 +102,19 @@ namespace Torch.Utils
[AttributeUsage(AttributeTargets.Field)]
public class ReflectedMethodAttribute : ReflectedMemberAttribute
{
+ ///
+ /// When set the parameters types for the method are assumed to be this.
+ ///
+ public Type[] OverrideTypes { get; set; }
+
+ ///
+ /// Assembly qualified names of
+ ///
+ public string[] OverrideTypeNames
+ {
+ get => OverrideTypes.Select(x => x.AssemblyQualifiedName).ToArray();
+ set => OverrideTypes = value?.Select(x => x == null ? null : Type.GetType(x)).ToArray();
+ }
}
///
@@ -125,7 +147,7 @@ namespace Torch.Utils
private static readonly string[] _namespaceBlacklist = new[] {
"System", "VRage", "Sandbox", "SpaceEngineers"
};
-
+
///
/// Registers the assembly load event and loads every already existing assembly.
///
@@ -232,10 +254,14 @@ namespace Torch.Utils
trueParameterTypes = parameters.Skip(1).Select(x => x.ParameterType).ToArray();
}
+ var invokeTypes = new Type[trueParameterTypes.Length];
+ for (var i = 0; i < invokeTypes.Length; i++)
+ invokeTypes[i] = attr.OverrideTypes?[i] ?? trueParameterTypes[i];
+
MethodInfo methodInstance = trueType.GetMethod(attr.Name ?? field.Name,
(attr is ReflectedStaticMethodAttribute ? BindingFlags.Static : BindingFlags.Instance) |
BindingFlags.Public |
- BindingFlags.NonPublic, null, CallingConventions.Any, trueParameterTypes, null);
+ BindingFlags.NonPublic, null, CallingConventions.Any, invokeTypes, null);
if (methodInstance == null)
{
string methodType = attr is ReflectedStaticMethodAttribute ? "static" : "instance";
@@ -245,13 +271,38 @@ namespace Torch.Utils
$"Unable to find {methodType} method {attr.Name ?? field.Name} in type {trueType.FullName} with parameters {methodParams}");
}
+
if (attr is ReflectedStaticMethodAttribute)
- field.SetValue(null, Delegate.CreateDelegate(field.FieldType, methodInstance));
+ {
+ if (attr.OverrideTypes != null)
+ {
+ ParameterExpression[] paramExp =
+ parameters.Select(x => Expression.Parameter(x.ParameterType)).ToArray();
+ var argExp = new Expression[invokeTypes.Length];
+ for (var i = 0; i < argExp.Length; i++)
+ if (invokeTypes[i] != paramExp[i].Type)
+ argExp[i] = Expression.Convert(paramExp[i], invokeTypes[i]);
+ else
+ argExp[i] = paramExp[i];
+ field.SetValue(null,
+ Expression.Lambda(Expression.Call(methodInstance, argExp), paramExp)
+ .Compile());
+ }
+ else
+ field.SetValue(null, Delegate.CreateDelegate(field.FieldType, methodInstance));
+ }
else
{
- ParameterExpression[] paramExp = parameters.Select(x => Expression.Parameter(x.ParameterType)).ToArray();
+ ParameterExpression[] paramExp =
+ parameters.Select(x => Expression.Parameter(x.ParameterType)).ToArray();
+ var argExp = new Expression[invokeTypes.Length];
+ for (var i = 0; i < argExp.Length; i++)
+ if (invokeTypes[i] != paramExp[i + 1].Type)
+ argExp[i] = Expression.Convert(paramExp[i + 1], invokeTypes[i]);
+ else
+ argExp[i] = paramExp[i + 1];
field.SetValue(null,
- Expression.Lambda(Expression.Call(paramExp[0], methodInstance, paramExp.Skip(1)), paramExp)
+ Expression.Lambda(Expression.Call(paramExp[0], methodInstance, argExp), paramExp)
.Compile());
}
}
@@ -287,7 +338,7 @@ namespace Torch.Utils
if (trueType == null && isStatic)
throw new ArgumentException("Static field setters need their type defined", nameof(field));
- if (!isStatic)
+ if (!isStatic && trueType == null)
trueType = parameters[0].ParameterType;
}
else if (attr is ReflectedGetterAttribute)
@@ -300,7 +351,7 @@ namespace Torch.Utils
if (trueType == null && isStatic)
throw new ArgumentException("Static field getters need their type defined", nameof(field));
- if (!isStatic)
+ if (!isStatic && trueType == null)
trueType = parameters[0].ParameterType;
}
else
@@ -318,10 +369,15 @@ namespace Torch.Utils
$"Unable to find field or property for {trueName} in {trueType.FullName} or its base types", nameof(field));
ParameterExpression[] paramExp = parameters.Select(x => Expression.Parameter(x.ParameterType)).ToArray();
+ Expression instanceExpr = null;
+ if (!isStatic)
+ {
+ instanceExpr = trueType == paramExp[0].Type ? (Expression) paramExp[0] : Expression.Convert(paramExp[0], trueType);
+ }
MemberExpression fieldExp = sourceField != null
- ? Expression.Field(isStatic ? null : paramExp[0], sourceField)
- : Expression.Property(isStatic ? null : paramExp[0], sourceProperty);
+ ? Expression.Field(instanceExpr, sourceField)
+ : Expression.Property(instanceExpr, sourceProperty);
Expression impl;
if (attr is ReflectedSetterAttribute)
{
diff --git a/Torch/packages.config b/Torch/packages.config
index 18ffc48..ec3af32 100644
--- a/Torch/packages.config
+++ b/Torch/packages.config
@@ -1,5 +1,6 @@
-
+
+
\ No newline at end of file
diff --git a/TransformOnBuild.targets b/TransformOnBuild.targets
new file mode 100644
index 0000000..063e4aa
--- /dev/null
+++ b/TransformOnBuild.targets
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Versioning/AssemblyVersion.cs b/Versioning/AssemblyVersion.cs
new file mode 100644
index 0000000..c663bea
--- /dev/null
+++ b/Versioning/AssemblyVersion.cs
@@ -0,0 +1,4 @@
+using System.Reflection;
+
+[assembly: AssemblyVersion("0.0.0.0")]
+[assembly: AssemblyInformationalVersion("v0.0.0-dev")]
diff --git a/Versioning/version.ps1 b/Versioning/version.ps1
new file mode 100644
index 0000000..2e624b4
--- /dev/null
+++ b/Versioning/version.ps1
@@ -0,0 +1,20 @@
+$gitVersion = git describe --tags
+$gitSimpleVersion = git describe --tags --abbrev=0
+if ($gitSimpleVersion.Equals($gitVersion)) {
+ $buildSalt = 0
+} else {
+ $gitLatestCommit = git rev-parse --short HEAD
+ $buildSalt = [System.Numerics.BigInteger]::Abs([System.Numerics.BigInteger]::Parse($gitLatestCommit, [System.Globalization.NumberStyles]::HexNumber) % 16383) + 1
+}
+$dotNetVersion = echo $gitSimpleVersion | Select-String -Pattern "([0-9]+)\.([0-9]+)\.([0-9]+)" | % {$_.Matches} | %{$_.Groups[1].Value+"."+$_.Groups[2].Value+"."+$_.Groups[3].Value+".$buildSalt"}
+
+$fileContent = @"
+using System.Reflection;
+
+[assembly: AssemblyVersion("$dotNetVersion")]
+[assembly: AssemblyInformationalVersion("$gitVersion")]
+"@
+
+echo $fileContent | Set-Content "$PSScriptRoot/AssemblyVersion.cs"
+
+echo "$gitVersion / $dotNetVersion"
\ No newline at end of file