mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-23 13:07:07 +01:00
Fix up the dynamic loading stuff
This commit is contained in:
@@ -60,6 +60,8 @@ after_test:
|
||||
- dotnet publish src/Tgstation.Server.Host/Tgstation.Server.Host.csproj -o ../../artifacts/ServerHost -c %CONFIGURATION%
|
||||
- dotnet publish src/Tgstation.Server.Host.Console/Tgstation.Server.Host.Console.csproj -o ../../artifacts/ServerConsole -c %CONFIGURATION%
|
||||
- ps: Copy-Item -path "src/Tgstation.Server.Host.Service/bin/$env:CONFIGURATION" -destination artifacts/ServerService -recurse
|
||||
- ps: Copy-Item -path "artifacts/ServerHost" -destination artifacts/ServerService/lib/Default -recurse
|
||||
- ps: Copy-Item -path "artifacts/ServerHost" -destination artifacts/ServerConsole/lib/Default -recurse
|
||||
- ps: $env:TGSVersion = [System.Diagnostics.FileVersionInfo]::GetVersionInfo("$env:APPVEYOR_BUILD_FOLDER/artifacts/ServerHost/Tgstation.Server.Host.dll").FileVersion
|
||||
deploy:
|
||||
- provider: GitHub
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.6.0" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.6.1" />
|
||||
<PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
using System.Threading.Tasks;
|
||||
using Tgstation.Server.Host.Startup;
|
||||
|
||||
namespace Tgstation.Server.Host.Console.Debug
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
internal static IServerFactory serverFactory = new ServerFactory();
|
||||
|
||||
static async Task Main(string[] args)
|
||||
{
|
||||
using (var server = serverFactory.CreateServer(args, "Updates"))
|
||||
await server.RunAsync(default).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<LangVersion>7.1</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<LangVersion>7.1</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Tgstation.Server.Host\Tgstation.Server.Host.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -17,6 +17,10 @@
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.1.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Tgstation.Server.Host.Watchdog\Tgstation.Server.Host.Watchdog.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -17,8 +17,4 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.1.1" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
@@ -13,6 +12,10 @@ namespace Tgstation.Server.Host.Watchdog
|
||||
/// </summary>
|
||||
sealed class IsolatedServerFactory : AssemblyLoadContext, IServerFactory
|
||||
{
|
||||
const string DllExtension = "dll";
|
||||
|
||||
static readonly string assemblyFileName = String.Join(".", nameof(Tgstation), nameof(Server), nameof(Host), DllExtension);
|
||||
|
||||
/// <summary>
|
||||
/// The path of the <see cref="Assembly"/> to load
|
||||
/// </summary>
|
||||
@@ -22,7 +25,24 @@ namespace Tgstation.Server.Host.Watchdog
|
||||
/// Construct a <see cref="IsolatedServerFactory"/>
|
||||
/// </summary>
|
||||
/// <param name="assemblyPath">The value of <see cref="assemblyPath"/></param>
|
||||
public IsolatedServerFactory(string assemblyPath) => this.assemblyPath = assemblyPath ?? throw new ArgumentNullException(nameof(assemblyPath));
|
||||
public IsolatedServerFactory(string assemblyPath)
|
||||
{
|
||||
this.assemblyPath = assemblyPath ?? throw new ArgumentNullException(nameof(assemblyPath));
|
||||
|
||||
Resolving += IsolatedServerFactory_Resolving;
|
||||
}
|
||||
|
||||
//https://stackoverflow.com/a/40921746/3976486
|
||||
Assembly IsolatedServerFactory_Resolving(AssemblyLoadContext context, AssemblyName assemblyName)
|
||||
{
|
||||
if (assemblyName.Name.EndsWith("resources", StringComparison.Ordinal))
|
||||
return null;
|
||||
|
||||
var foundDll = Directory.GetFileSystemEntries(assemblyPath, String.Join(".", assemblyName.Name, DllExtension), SearchOption.AllDirectories).FirstOrDefault();
|
||||
if (foundDll != default)
|
||||
return context.LoadFromAssemblyPath(foundDll);
|
||||
return context.LoadFromAssemblyName(assemblyName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the <see cref="Assembly"/> at <see cref="assemblyPath"/> and creates an <see cref="IServer"/> from it
|
||||
@@ -32,26 +52,15 @@ namespace Tgstation.Server.Host.Watchdog
|
||||
/// <returns>A new <see cref="IServer"/></returns>
|
||||
public IServer CreateServer(string[] args, string updatePath)
|
||||
{
|
||||
//help here: https://stackoverflow.com/questions/40908568/assembly-loading-in-net-core
|
||||
var assembly = LoadFromAssemblyPath(Path.Combine(assemblyPath, assemblyFileName));
|
||||
|
||||
var oldCd = Environment.CurrentDirectory;
|
||||
Directory.SetCurrentDirectory(Path.GetDirectoryName(assemblyPath));
|
||||
try
|
||||
{
|
||||
var assembly = LoadFromAssemblyPath(assemblyPath);
|
||||
//find the IServerFactory implementation
|
||||
var serverFactoryInterfaceType = typeof(IServerFactory);
|
||||
var serverFactoryImplementationType = assembly.GetTypes().Where(x => serverFactoryInterfaceType.IsAssignableFrom(x)).First();
|
||||
|
||||
//find the IServerFactory implementation
|
||||
var serverFactoryInterfaceType = typeof(IServerFactory);
|
||||
var serverFactoryImplementationType = assembly.GetTypes().Where(x => serverFactoryInterfaceType.IsAssignableFrom(x)).First();
|
||||
var serverFactory = (IServerFactory)Activator.CreateInstance(serverFactoryImplementationType);
|
||||
|
||||
var serverFactory = (IServerFactory)Activator.CreateInstance(serverFactoryImplementationType);
|
||||
|
||||
return serverFactory.CreateServer(args, updatePath);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Directory.SetCurrentDirectory(oldCd);
|
||||
}
|
||||
return serverFactory.CreateServer(args, updatePath);
|
||||
}
|
||||
|
||||
//honestly have no idea what this is for, but the examples i see just return null and it seems to work just fine
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.6.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.1.1" />
|
||||
<PackageReference Include="System.Runtime.Loader" Version="4.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -46,7 +46,6 @@ namespace Tgstation.Server.Host.Watchdog
|
||||
const string DefaultAssemblyPath = "Default";
|
||||
|
||||
var assemblyStoragePath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "lib");
|
||||
var assemblyName = String.Join(".", nameof(Tgstation), nameof(Server), nameof(Host), "dll");
|
||||
|
||||
logger.LogInformation("Host watchdog starting...");
|
||||
|
||||
@@ -60,7 +59,7 @@ namespace Tgstation.Server.Host.Watchdog
|
||||
logger.LogTrace("Atttempting to create new server factory...");
|
||||
Guid updateGuid;
|
||||
{ //forces serverFactory out of the picture once the scope ends
|
||||
var serverFactory = isolatedAssemblyLoader.CreateIsolatedServerFactory(Path.Combine(nextAssemblyPath, assemblyName));
|
||||
var serverFactory = isolatedAssemblyLoader.CreateIsolatedServerFactory(nextAssemblyPath);
|
||||
using (var server = serverFactory.CreateServer(args, assemblyStoragePath))
|
||||
{
|
||||
logger.LogTrace("Running server...");
|
||||
|
||||
@@ -124,7 +124,7 @@ namespace Tgstation.Server.Host.Core
|
||||
builder.EnableSensitiveDataLogging();
|
||||
};
|
||||
|
||||
switch (databaseConfiguration.DatabaseType)
|
||||
switch (databaseConfiguration?.DatabaseType ?? DatabaseType.Sqlite)
|
||||
{
|
||||
case DatabaseType.MySql:
|
||||
services.AddDbContext<MySqlDatabaseContext>(ConfigureDatabase);
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<LangVersion>7.1</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
@@ -36,6 +37,7 @@
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<LangVersion>7.1</LangVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Castle.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
|
||||
|
||||
@@ -102,6 +102,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "v4", "v4", "{057FAC33-CC31-
|
||||
src\DMAPI\tgs\v4\commands.dm = src\DMAPI\tgs\v4\commands.dm
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tgstation.Server.Host.Console.Debug", "src\Tgstation.Server.Host.Console.Debug\Tgstation.Server.Host.Console.Debug.csproj", "{15BE5763-DA6F-433F-A4C2-9FCF85F5CC21}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -211,6 +213,12 @@ Global
|
||||
{AA80A190-52E2-4BE3-BFEB-1F148D9E9007}.Docker|Any CPU.Build.0 = Release|Any CPU
|
||||
{AA80A190-52E2-4BE3-BFEB-1F148D9E9007}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AA80A190-52E2-4BE3-BFEB-1F148D9E9007}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{15BE5763-DA6F-433F-A4C2-9FCF85F5CC21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{15BE5763-DA6F-433F-A4C2-9FCF85F5CC21}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{15BE5763-DA6F-433F-A4C2-9FCF85F5CC21}.Docker|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{15BE5763-DA6F-433F-A4C2-9FCF85F5CC21}.Docker|Any CPU.Build.0 = Debug|Any CPU
|
||||
{15BE5763-DA6F-433F-A4C2-9FCF85F5CC21}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{15BE5763-DA6F-433F-A4C2-9FCF85F5CC21}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
Reference in New Issue
Block a user