mirror of
https://github.com/Facepunch/sbox-public.git
synced 2025-12-23 22:48:07 -05:00
This commit imports the C# engine code and game files, excluding C++ source code. [Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
85 lines
2.5 KiB
C#
85 lines
2.5 KiB
C#
using Mono.Cecil;
|
|
using System;
|
|
using System.Collections.Concurrent;
|
|
|
|
namespace Sandbox;
|
|
|
|
public partial class AccessControl
|
|
{
|
|
static ConcurrentDictionary<AssemblyNameReference, AssemblyDefinition> GlobalAssemblyCache = new( AssemblyNameComparer.Instance );
|
|
|
|
public AssemblyDefinition Resolve( AssemblyNameReference name )
|
|
{
|
|
//
|
|
// Look in the dynamic assemblies first
|
|
//
|
|
if ( Assemblies != null )
|
|
{
|
|
if ( Assemblies.TryGetValue( name, out var assm ) )
|
|
return assm;
|
|
|
|
var newestNameMatch = Assemblies
|
|
.Where( x => x.Key.Name.Equals( name.Name, StringComparison.OrdinalIgnoreCase ) )
|
|
//.Where( x => x.Key.Version.CompareTo( name.Version ) >= 0 )
|
|
.OrderByDescending( x => x.Key.Version )
|
|
.FirstOrDefault();
|
|
|
|
if ( newestNameMatch.Value != null )
|
|
return newestNameMatch.Value;
|
|
}
|
|
//
|
|
// We only resolve certain named dlls from disk - and certainly not package.
|
|
//
|
|
if ( !name.Name.StartsWith( "Sandbox.", StringComparison.OrdinalIgnoreCase ) &&
|
|
!name.Name.StartsWith( "System.", StringComparison.OrdinalIgnoreCase ) &&
|
|
name.Name != "Microsoft.AspNetCore.Components" )
|
|
throw NotResolved( name );
|
|
|
|
//
|
|
// Now look at our System. and Sandbox. assemblies
|
|
//
|
|
if ( GlobalAssemblyCache.TryGetValue( name, out var systemAssembly ) )
|
|
return systemAssembly;
|
|
|
|
lock ( GlobalAssemblyCache )
|
|
{
|
|
return GlobalAssemblyCache.GetOrAdd( name, FindAssemblyOnDisk );
|
|
}
|
|
}
|
|
|
|
AssemblyDefinition FindAssemblyOnDisk( AssemblyNameReference name )
|
|
{
|
|
var dllName = $"{name.Name}.dll";
|
|
|
|
var corePath = System.IO.Path.GetDirectoryName( typeof( Object ).Assembly.Location );
|
|
var testPath = System.IO.Path.Combine( corePath, dllName );
|
|
|
|
if ( !System.IO.File.Exists( testPath ) )
|
|
{
|
|
var gamePath = System.IO.Path.GetDirectoryName( GetType().Assembly.Location );
|
|
testPath = System.IO.Path.Combine( gamePath, dllName );
|
|
}
|
|
|
|
if ( !System.IO.File.Exists( testPath ) )
|
|
throw NotResolved( name );
|
|
|
|
var fileContent = System.IO.File.ReadAllBytes( testPath );
|
|
var stream = new MemoryStream( fileContent );
|
|
|
|
var options = new ReaderParameters { ReadingMode = ReadingMode.Immediate, InMemory = true, AssemblyResolver = this };
|
|
var assm = AssemblyDefinition.ReadAssembly( stream, options );
|
|
|
|
return assm;
|
|
}
|
|
|
|
private Exception NotResolved( AssemblyNameReference name )
|
|
{
|
|
return new System.Exception( $"Couldn't resolve '{name}' [{string.Join( ";", Assemblies.Select( x => $"{x.Key}@{x.Key}" ) )}]" );
|
|
}
|
|
|
|
public AssemblyDefinition Resolve( AssemblyNameReference name, ReaderParameters parameters )
|
|
{
|
|
return Resolve( name );
|
|
}
|
|
}
|