示例#1
0
        private void Initialize()
        {
            BootstrapLog.Info("Initializing.");
            _bootstrapMonoCecil.Initialize();
            _bootstrapInterface.WrapReflection();

            try
            {
                var resolutionHandler = Delegate.CreateDelegate(typeof(Func <AssemblyLoadContext, AssemblyName, Assembly>), this, "ResolveBootstrappedAssembly");
                _bootstrapInterface.BindGameAssemblyManager_LoadContext_Resolving(resolutionHandler);
            }
            catch (Exception e)
            {
                Log.Error(e, e.Message + "\n" + e.StackTrace);
            }
        }
示例#2
0
        private Assembly ResolveBootstrappedAssembly(AssemblyLoadContext loadContext, AssemblyName name)
        {
            BootstrapLog.Info($"Attempting to resolve assembly '{name.FullName}'");

            foreach (var assembly in _bootstrapInterface.GetSandboxAssemblies())
            {
                if (name.Name == assembly.GetName().Name)
                {
                    BootstrapLog.Info($"Resolved with '{assembly.FullName}'");
                    return(assembly);
                }
            }

            BootstrapLog.Error($"Could not resolve assembly '{name.FullName}'.");
            return(null);
        }
        internal bool Initialize()
        {
            BootstrapLog.Info("Initializing Sandbox.Bootstrap.MonoCecil.dll");

            AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
            {
                if (_sandboxMonoCecilAssembly == null)
                {
                    return(null);
                }

                if (args.RequestingAssembly !.FullName == _sandboxMonoCecilAssembly.FullName)
                {
                    var dnlib = FileSystem.Mounted.ReadAllBytes("bootstrap_monocecil/dnlib.dll");
                    return(Assembly.Load(dnlib.ToArray()));
                }

                return(null);
            };

            try
            {
                var bootstrap = FileSystem.Mounted.ReadAllBytes("bootstrap_monocecil/Sandbox.Bootstrap.MonoCecil.dll");
                _sandboxMonoCecilAssembly = Assembly.Load(bootstrap.ToArray());

                _monocecil_ModifyAssemblyReference = _sandboxMonoCecilAssembly.GetType("Sandbox.Bootstrap.MonoCecil.AssemblyReferenceEditor")
                                                     ?.GetMethod("ModifyAssemblyReference", BindingFlags.Public | BindingFlags.Static)
                                                     ?.CreateDelegate <Func <Stream, string[], AssemblyName[], Stream> >(null);

                if (_sandboxMonoCecilAssembly == null || _monocecil_ModifyAssemblyReference == null)
                {
                    BootstrapLog.Error("Failed to bind to Sandbox.Bootstrap.MonoCecil.AssemblyReferenceEditor. Make sure your Sandbox.Bootstrap install is correct.");
                    return(false);
                }

                BootstrapLog.Info("Succesfully loaded, ready to modify assembly references.");
                return(true);
            }
            catch (Exception ex)
            {
                BootstrapLog.Error(ex, "An exception has occured while trying to bind to Sandbox.Bootstrap.MonoCecil.AssemblyReferenceEditor. Make sure your Sandbox.Bootstrap install is correct.");
                return(false);
            }
        }
示例#4
0
        public Assembly Boot(BootstrappedAddonBuilder bootstrapBuilder)
        {
            if (bootstrapBuilder == null)
            {
                throw new ArgumentNullException(nameof(bootstrapBuilder));
            }

            BootstrapLog.Info($"Loading assembly at '{bootstrapBuilder.AssemblyName}'");

            bootstrapBuilder.AssertValid();

            // Get the name of the assembly we're trying to load.
            var relativePath = $"bootstrapped/{bootstrapBuilder.AssemblyName}/{bootstrapBuilder.AssemblyName}.dll";
            var absolutePath = FileSystem.Mounted.GetFullPath(relativePath);

            if (absolutePath == null)
            {
                BootstrapLog.Error($"Could not find assembly '{relativePath}'");
                return(null);
            }

            AssemblyName name;

            try
            {
                name = AssemblyName.GetAssemblyName(absolutePath);
                BootstrapLog.Info($"Found assembly '{name.FullName}' at '{relativePath}', attempting to load.");
            }
            catch (Exception e)
            {
                BootstrapLog.Error(e, $"Failed to load assembly '{bootstrapBuilder.AssemblyName}'.");
                return(null);
            }

            BootstrapLog.Info($"Valid filesystem: {FileSystem.Mounted.IsValid}");
            Assembly asm;

            // Now we load the assembly.
            try
            {
                using var dllFile = FileSystem.Mounted.OpenRead(relativePath);

                // Before loading, grab all of the dynamic addons currently loaded, and ask Sandbox.Bootstrap.MonoCecil to modify them.
                BootstrapLog.Info("[Sandbox.Bootstrap.MonoCecil] Attempting to override references.");
                var oldReferences = new List <string>();
                var newReferences = new List <AssemblyName>();

                foreach (var sboxAssembly in _bootstrapInterface.GetSandboxAssemblies())
                {
                    if (sboxAssembly != null)
                    {
                        var asmName = sboxAssembly.GetName();
                        var split   = asmName.Name !.Split('.');
                        if (split.Length > 1 && split[0] == "Dynamic")
                        {
                            oldReferences.Add(split[1]);
                            newReferences.Add(asmName);
                        }
                    }
                }

                var output = _bootstrapMonoCecil.ModifyAssemblyReference(dllFile, oldReferences.ToArray(), newReferences.ToArray());
                asm = _bootstrapInterface.GameAssemblyManager_LoadContext_LoadFromStream(output);
            }
            catch (Exception e)
            {
                BootstrapLog.Error(e, $"Failed to load assembly '{name.FullName}' at '{bootstrapBuilder.AssemblyName}'");
                return(null);
            }

            // Woohoo we did it.
            BootstrapLog.Info($"Successfully loaded assembly '{asm.FullName}'.");
            bootstrapBuilder.OnAssemblyLoaded?.Invoke(asm);
            return(asm);
        }
示例#5
0
        /// <summary>
        /// Setup all of the required Reflection to interface with Sandbox.
        /// </summary>
        /// <exception cref="InvalidOperationException"> Thrown if any of the required Reflection calls fail. If this occurs, Sandbox likely got updated. Create an issue on our github repo. </exception>
        internal void WrapReflection()
        {
            if (_wrapped)
            {
                return;
            }

            _wrapped = true;
            BootstrapLog.Info("Wrapping Sandbox internals using Reflection.");

            // Retrieve Sandbox's context interface from the Global class.
            _contextInterface = typeof(Global).GetProperty("GameInterface", BindingFlags.Static | BindingFlags.NonPublic)
                                ?.GetValue(null, null);

            if (_contextInterface == null)
            {
                BootstrapLog.Error("Bootstrapper is out of date! Could not retrieve Global.GameInterface!");
                return;
            }

            // Create a delegate for the ContextInterface.OnNewAssembly method.
            var original = Type.GetType($"Sandbox.ServerInterface, {typeof(Global).Assembly.FullName}")
                           ?.GetMethod("OnNewAssembly", BindingFlags.NonPublic | BindingFlags.Instance);

            if (original == null)
            {
                BootstrapLog.Error("Bootstrapper is out of date! Could not bind to Sandbox.ContextInterface.OnNewAssembly(Assembly, Assembly)!");
                return;
            }

            _onNewAssembly = original.CreateDelegate <Action <Assembly, Assembly> >(_contextInterface);

            // Retrieve Sandbox's AssemblyLibrary
            _assemblyLibrary_All = Type.GetType($"Sandbox.AssemblyLibrary, {typeof(Global).Assembly.FullName}")
                                   ?.GetField("All", BindingFlags.Static | BindingFlags.Public);

            if (_assemblyLibrary_All == null)
            {
                BootstrapLog.Error("Bootstrapper is out of date! Could not bind to Sandbox.AssemblyLibrary.All!");
                return;
            }

            // Retrieve Sandbox's AssemblyLibrary
            _assemblyWrapper_Assembly = Type.GetType($"Sandbox.AssemblyWrapper, {typeof(Global).Assembly.FullName}")
                                        ?.GetField("Assembly", BindingFlags.Public | BindingFlags.Instance);

            if (_assemblyWrapper_Assembly == null)
            {
                BootstrapLog.Error("Bootstrapper is out of date! Could not bind to Sandbox.AssemblyWrapper.Assembly!");
                return;
            }

            _gameAssemblyManager_OnAssembly = Type.GetType($"Sandbox.GameAssemblyManager, {typeof(Global).Assembly.FullName}")
                                              ?.GetMethod("OnAssembly", BindingFlags.NonPublic | BindingFlags.Static)
                                              ?.CreateDelegate <Action <string, Stream, Stream> >();

            if (_gameAssemblyManager_OnAssembly == null)
            {
                BootstrapLog.Error("Bootstrapper is out of date! Could not bind to Sandbox.GameAssemblyManager.OnAssembly!");
                return;
            }

            _gameAssemblyManager_LoadContext = Type.GetType($"Sandbox.GameAssemblyManager, {typeof(Global).Assembly.FullName}")
                                               ?.GetField("LoadContext", BindingFlags.NonPublic | BindingFlags.Static);

            if (_gameAssemblyManager_LoadContext == null)
            {
                BootstrapLog.Error("Bootstrapper is out of date! Could not bind to Sandbox.GameAssemblyManager.LoadContext!");
                return;
            }

            _gameAssemblyManager_LoadContext_Resolving = typeof(AssemblyLoadContext).GetEvent("Resolving", BindingFlags.Instance | BindingFlags.Public);
            if (_gameAssemblyManager_LoadContext_Resolving == null)
            {
                BootstrapLog.Error("Bootstrapper is out of date! Could not bind to Sandbox.GameAssemblyManager.LoadContext.Resolving!");
                return;
            }

            try
            {
                _gameAssemblyManager_LoadContext_LoadFromStream = typeof(AssemblyLoadContext)
                                                                  .GetMethod("LoadFromStream", new[] { typeof(Stream) })
                                                                  ?.CreateDelegate <Func <Stream, Assembly> >(_gameAssemblyManager_LoadContext?.GetValue(null));

                if (_gameAssemblyManager_LoadContext_LoadFromStream == null)
                {
                    BootstrapLog.Error("Bootstrapper is out of date! Could not bind to Sandbox.GameAssemblyManager.LoadContext.LoadFromStream!");
                    return;
                }
            }
            catch (Exception e)
            {
                Log.Info($"{e.Message}\n{e.StackTrace}");
            }
        }