- tweak: fix resolving think
This commit is contained in:
@@ -8,12 +8,10 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Utils\runtime.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Utils\runtime.json">
|
||||
<LogicalName>Utility.runtime.json</LogicalName>
|
||||
</EmbeddedResource>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.0" />
|
||||
<PackageReference Include="libsodium" Version="1.0.20" />
|
||||
<PackageReference Include="Robust.Natives" Version="0.1.1" />
|
||||
<PackageReference Include="SharpZstd.Interop" Version="1.5.6" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -7,8 +7,17 @@ public static class ServiceExt
|
||||
{
|
||||
public static void AddServices(this IServiceCollection services)
|
||||
{
|
||||
foreach (var (type, inference) in GetServicesWithHelpAttribute(Assembly.GetExecutingAssembly()))
|
||||
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
AddServices(services, assembly);
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddServices(this IServiceCollection services, Assembly assembly)
|
||||
{
|
||||
foreach (var (type, inference) in GetServicesWithHelpAttribute(assembly))
|
||||
{
|
||||
Console.WriteLine("[ServiceMng] ADD SERVICE " + type);
|
||||
if (inference is null)
|
||||
{
|
||||
services.AddSingleton(type);
|
||||
|
||||
@@ -10,20 +10,36 @@ namespace Nebula.Shared.Services;
|
||||
[ServiceRegister]
|
||||
public class AssemblyService
|
||||
{
|
||||
private readonly Dictionary<string,Assembly> _assemblies = new();
|
||||
private readonly List<Assembly> _assemblies = new();
|
||||
private readonly DebugService _debugService;
|
||||
|
||||
public AssemblyService(DebugService debugService)
|
||||
{
|
||||
_debugService = debugService;
|
||||
|
||||
SharpZstd.Interop.ZstdImportResolver.ResolveLibrary += (name, assembly1, path) =>
|
||||
{
|
||||
if (name.Equals("SharpZstd.Native"))
|
||||
{
|
||||
_debugService.Debug("RESOLVING SHARPZSTD THINK: " + name + " " + path);
|
||||
GetRuntimeInfo(out string platform, out string architecture, out string extension);
|
||||
string fileName = GetDllName(platform, architecture, extension);
|
||||
|
||||
if (NativeLibrary.TryLoad(fileName, assembly1, path, out var nativeLibrary))
|
||||
{
|
||||
return nativeLibrary;
|
||||
}
|
||||
}
|
||||
return IntPtr.Zero;
|
||||
};
|
||||
}
|
||||
|
||||
//public IReadOnlyList<Assembly> Assemblies => _assemblies;
|
||||
public IReadOnlyList<Assembly> Assemblies => _assemblies;
|
||||
|
||||
public AssemblyApi Mount(IFileApi fileApi, string apiName = "")
|
||||
public AssemblyApi Mount(IFileApi fileApi)
|
||||
{
|
||||
var asmApi = new AssemblyApi(fileApi);
|
||||
AssemblyLoadContext.Default.Resolving += (context, name) => OnAssemblyResolving(context, name, asmApi, apiName);
|
||||
AssemblyLoadContext.Default.Resolving += (context, name) => OnAssemblyResolving(context, name, asmApi);
|
||||
AssemblyLoadContext.Default.ResolvingUnmanagedDll += LoadContextOnResolvingUnmanaged;
|
||||
|
||||
return asmApi;
|
||||
@@ -53,11 +69,6 @@ public class AssemblyService
|
||||
|
||||
public bool TryOpenAssembly(string name, AssemblyApi assemblyApi, [NotNullWhen(true)] out Assembly? assembly)
|
||||
{
|
||||
if (_assemblies.TryGetValue(name, out assembly))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!TryOpenAssemblyStream(name, assemblyApi, out var asm, out var pdb))
|
||||
{
|
||||
assembly = null;
|
||||
@@ -66,8 +77,9 @@ public class AssemblyService
|
||||
|
||||
assembly = AssemblyLoadContext.Default.LoadFromStream(asm, pdb);
|
||||
_debugService.Log("LOADED ASSEMBLY " + name);
|
||||
|
||||
_assemblies.Add(name, assembly);
|
||||
|
||||
|
||||
if (!_assemblies.Contains(assembly)) _assemblies.Add(assembly);
|
||||
|
||||
asm.Dispose();
|
||||
pdb?.Dispose();
|
||||
@@ -86,13 +98,27 @@ public class AssemblyService
|
||||
assemblyApi.TryOpen($"{name}.pdb", out pdb);
|
||||
return true;
|
||||
}
|
||||
|
||||
private readonly HashSet<string> _resolvingAssemblies = new HashSet<string>();
|
||||
|
||||
private Assembly? OnAssemblyResolving(AssemblyLoadContext context, AssemblyName name, AssemblyApi assemblyApi,
|
||||
string apiName)
|
||||
private Assembly? OnAssemblyResolving(AssemblyLoadContext context, AssemblyName name, AssemblyApi assemblyApi)
|
||||
{
|
||||
|
||||
_debugService.Debug($"Resolving assembly from {apiName}: {name.Name}");
|
||||
return TryOpenAssembly(name.Name!, assemblyApi, out var assembly) ? assembly : null;
|
||||
if (_resolvingAssemblies.Contains(name.FullName))
|
||||
{
|
||||
_debugService.Debug($"Already resolving {name.Name}, skipping.");
|
||||
return null; // Prevent recursive resolution
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_resolvingAssemblies.Add(name.FullName);
|
||||
_debugService.Debug($"Resolving assembly from FileAPI: {name.Name}");
|
||||
return TryOpenAssembly(name.Name!, assemblyApi, out var assembly) ? assembly : null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_resolvingAssemblies.Remove(name.FullName);
|
||||
}
|
||||
}
|
||||
|
||||
private IntPtr LoadContextOnResolvingUnmanaged(Assembly assembly, string unmanaged)
|
||||
@@ -104,7 +130,66 @@ public class AssemblyService
|
||||
|
||||
if (NativeLibrary.TryLoad(a, out var handle))
|
||||
return handle;
|
||||
|
||||
_debugService.Error("Loading dll error! Not found");
|
||||
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
public static string GetDllName(
|
||||
string platform,
|
||||
string architecture,
|
||||
string extension)
|
||||
{
|
||||
string name = $"SharpZstd.Native.{extension}";
|
||||
return name;
|
||||
}
|
||||
|
||||
public static void GetRuntimeInfo(
|
||||
out string platform,
|
||||
out string architecture,
|
||||
out string extension)
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
platform = "win";
|
||||
extension = "dll";
|
||||
}
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
{
|
||||
platform = "linux";
|
||||
extension = "so";
|
||||
}
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
||||
{
|
||||
platform = "osx";
|
||||
extension = "dylib";
|
||||
}
|
||||
else
|
||||
{
|
||||
platform = "linux";
|
||||
extension = "so";
|
||||
}
|
||||
|
||||
if (RuntimeInformation.ProcessArchitecture == Architecture.X64)
|
||||
{
|
||||
architecture = "x64";
|
||||
}
|
||||
else if (RuntimeInformation.ProcessArchitecture == Architecture.X86)
|
||||
{
|
||||
architecture = "x86";
|
||||
}
|
||||
else if (RuntimeInformation.ProcessArchitecture == Architecture.Arm)
|
||||
{
|
||||
architecture = "arm";
|
||||
}
|
||||
else if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
|
||||
{
|
||||
architecture = "arm64";
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new PlatformNotSupportedException("Unsupported process architecture.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,6 +45,12 @@ public partial class AuthService(
|
||||
SelectedAuth = null;
|
||||
}
|
||||
|
||||
public void SetAuth(Guid guid, string token, string login, string authServer)
|
||||
{
|
||||
SelectedAuth = new CurrentAuthInfo(guid, new LoginToken(token, DateTimeOffset.Now),
|
||||
new AuthLoginPassword(login, "", authServer));
|
||||
}
|
||||
|
||||
public async Task<bool> EnsureToken()
|
||||
{
|
||||
if (SelectedAuth is null) return false;
|
||||
|
||||
@@ -81,7 +81,7 @@ public sealed class EngineService
|
||||
|
||||
try
|
||||
{
|
||||
return _assemblyService.Mount(_fileService.OpenZip(version, _fileService.EngineFileApi),$"Engine.Ensure-{version}");
|
||||
return _assemblyService.Mount(_fileService.OpenZip(version, _fileService.EngineFileApi));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -161,7 +161,7 @@ public sealed class EngineService
|
||||
|
||||
try
|
||||
{
|
||||
return _assemblyService.Mount(_fileService.OpenZip(fileName, _fileService.EngineFileApi),"Engine.EnsureModule");
|
||||
return _assemblyService.Mount(_fileService.OpenZip(fileName, _fileService.EngineFileApi));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
@@ -10,18 +10,8 @@ public sealed class RunnerService(
|
||||
ConfigurationService varService,
|
||||
FileService fileService,
|
||||
EngineService engineService,
|
||||
AssemblyService assemblyService,
|
||||
AuthService authService,
|
||||
PopupMessageService popupMessageService,
|
||||
CancellationService cancellationService)
|
||||
: IRedialApi
|
||||
AssemblyService assemblyService)
|
||||
{
|
||||
public async Task PrepareRun(RobustUrl url)
|
||||
{
|
||||
var buildInfo = await contentService.GetBuildInfo(url, cancellationService.Token);
|
||||
await PrepareRun(buildInfo, cancellationService.Token);
|
||||
}
|
||||
|
||||
public async Task PrepareRun(RobustBuildInfo buildInfo, CancellationToken cancellationToken)
|
||||
{
|
||||
debugService.Log("Prepare Content!");
|
||||
@@ -67,60 +57,4 @@ public sealed class RunnerService(
|
||||
|
||||
await Task.Run(() => loader.Main(args), cancellationToken);
|
||||
}
|
||||
|
||||
public async Task RunGame(string urlraw)
|
||||
{
|
||||
var url = new RobustUrl(urlraw);
|
||||
|
||||
using var cancelTokenSource = new CancellationTokenSource();
|
||||
var buildInfo = await contentService.GetBuildInfo(url, cancelTokenSource.Token);
|
||||
|
||||
var account = authService.SelectedAuth;
|
||||
if (account is null)
|
||||
{
|
||||
popupMessageService.Popup("Error! Auth is required!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (buildInfo.BuildInfo.Auth.Mode != "Disabled")
|
||||
{
|
||||
Environment.SetEnvironmentVariable("ROBUST_AUTH_TOKEN", account.Token.Token);
|
||||
Environment.SetEnvironmentVariable("ROBUST_AUTH_USERID", account.UserId.ToString());
|
||||
Environment.SetEnvironmentVariable("ROBUST_AUTH_PUBKEY", buildInfo.BuildInfo.Auth.PublicKey);
|
||||
Environment.SetEnvironmentVariable("ROBUST_AUTH_SERVER", account.AuthLoginPassword.AuthServer);
|
||||
}
|
||||
|
||||
var args = new List<string>
|
||||
{
|
||||
// Pass username to launched client.
|
||||
// We don't load username from client_config.toml when launched via launcher.
|
||||
"--username", account.AuthLoginPassword.Login,
|
||||
|
||||
// Tell game we are launcher
|
||||
"--cvar", "launch.launcher=true"
|
||||
};
|
||||
|
||||
var connectionString = url.ToString();
|
||||
if (!string.IsNullOrEmpty(buildInfo.BuildInfo.ConnectAddress))
|
||||
connectionString = buildInfo.BuildInfo.ConnectAddress;
|
||||
|
||||
// We are using the launcher. Don't show main menu etc..
|
||||
// Note: --launcher also implied --connect.
|
||||
// For this reason, content bundles do not set --launcher.
|
||||
args.Add("--launcher");
|
||||
|
||||
args.Add("--connect-address");
|
||||
args.Add(connectionString);
|
||||
|
||||
args.Add("--ss14-address");
|
||||
args.Add(url.ToString());
|
||||
debugService.Debug("Connect to " + url.ToString() + " " + account.AuthLoginPassword.AuthServer);
|
||||
|
||||
await Run(args.ToArray(), buildInfo, this, cancelTokenSource.Token);
|
||||
}
|
||||
|
||||
public async void Redial(Uri uri, string text = "")
|
||||
{
|
||||
//await RunGame(uri.ToString());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user