CelesteNet.Server
CelesteNetServerModuleWrapper.Core.cs
#if NETCORE
using Celeste.Mod.CelesteNet.DataTypes;
using Mono.Options;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.Loader;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Celeste.Mod.CelesteNet.Server {
public partial clast CelesteNetServerModuleWrapper {
private astemblyLoadContext? ALC;
private void Loadastembly() {
long stamp = DateTime.UtcNow.Ticks / TimeSpan.TicksPerMillisecond;
string dir = Path.Combine(Path.GetTempPath(), $"CelesteNetServerModuleCache.{Server.Timestamp}");
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
string path = Path.Combine(dir, $"{Path.GetFileNameWithoutExtension(astemblyPath)}.{stamp}.dll");
File.Copy(astemblyPath, path);
if (File.Exists(Path.ChangeExtension(astemblyPath, "pdb")))
File.Copy(Path.ChangeExtension(astemblyPath, "pdb"), Path.ChangeExtension(path, "pdb"));
ALC = new ModuleastemblyLoadContext($"ModCtx.{stamp}.{ID}");
ALC.Resolving += (ctx, name) => {
foreach (CelesteNetServerModuleWrapper wrapper in Server.ModuleWrappers)
if (wrapper.ID == name.Name)
return wrapper.astembly;
astemblyLoadContext? parent = astemblyLoadContext.GetLoadContext(typeof(CelesteNetServerModuleWrapper).astembly);
if (parent != null)
foreach (astembly asm in parent.astemblies)
if (asm.GetName().Name == name.Name)
return asm;
return null;
};
astembly = ALC.LoadFromastemblyPath(path);
}
private void Unloadastembly() {
ALC?.Unload();
ALC = null;
}
public clast ModuleastemblyLoadContext : astemblyLoadContext {
public ModuleastemblyLoadContext(string name)
: base(name, isCollectible: true) {
}
protected override astembly? Load(astemblyName name) {
return null;
}
}
}
}
#endif