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]
91 lines
2.0 KiB
C#
91 lines
2.0 KiB
C#
|
|
|
|
using Mono.Cecil;
|
|
using System;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Sandbox.Internal;
|
|
|
|
//
|
|
// Not currently used anywhere right now, but we may need it in the future.
|
|
//
|
|
public class AssemblyModifier
|
|
{
|
|
public string Rename { get; set; }
|
|
public Dictionary<string, string> ChangeReference { get; set; } = new();
|
|
|
|
|
|
CustomResolver resolver = new CustomResolver();
|
|
|
|
public void AddResolvable( byte[] assembly )
|
|
{
|
|
//AssemblyDefinition.ReadAssembly( assembly );
|
|
}
|
|
|
|
public byte[] Modify( byte[] dllBytes )
|
|
{
|
|
using var stream = new MemoryStream( dllBytes );
|
|
|
|
AssemblyDefinition ad = AssemblyDefinition.ReadAssembly( stream, new ReaderParameters { AssemblyResolver = resolver, InMemory = true, ReadingMode = ReadingMode.Immediate } );
|
|
|
|
if ( Rename != null )
|
|
{
|
|
ad.Name = new AssemblyNameDefinition( Rename, ad.Name.Version );
|
|
}
|
|
|
|
foreach ( var cr in ChangeReference )
|
|
{
|
|
var found = ad.MainModule.AssemblyReferences.FirstOrDefault( x => x.Name == cr.Key );
|
|
if ( found == null ) continue;
|
|
|
|
found.Name = cr.Value;
|
|
}
|
|
|
|
using var outStream = new MemoryStream();
|
|
ad.Write( outStream, new WriterParameters { } );
|
|
|
|
return outStream.ToArray();
|
|
}
|
|
|
|
|
|
class CustomResolver : DefaultAssemblyResolver
|
|
{
|
|
readonly Dictionary<string, AssemblyDefinition> cache = new();
|
|
|
|
public void Cache( AssemblyDefinition assembly )
|
|
{
|
|
cache[assembly.FullName] = assembly;
|
|
}
|
|
|
|
public override AssemblyDefinition Resolve( AssemblyNameReference name )
|
|
{
|
|
if ( cache.TryGetValue( name.FullName, out var cached ) )
|
|
return cached;
|
|
|
|
AssemblyDefinition assembly;
|
|
|
|
try
|
|
{
|
|
//
|
|
// Only resolve shit that we already have loaded
|
|
//
|
|
var loaded = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault( x => x.GetName().Name == name.Name && !string.IsNullOrEmpty( x.Location ) );
|
|
if ( loaded != null )
|
|
{
|
|
assembly = AssemblyDefinition.ReadAssembly( loaded.Location );
|
|
if ( assembly != null )
|
|
{
|
|
Cache( assembly );
|
|
return assembly;
|
|
}
|
|
}
|
|
}
|
|
catch ( AssemblyResolutionException )
|
|
{
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
}
|