Exemple #1
0
        int UnloadModule(ILua lua)
        {
            try
            {
                string module_name = lua.GetString(1);

                if (String.IsNullOrEmpty(module_name))
                {
                    throw new Exception("Module name is empty or null");
                }

                if (!module_contexts.ContainsKey(module_name))
                {
                    throw new Exception($"There is no loaded module with name { module_name }");
                }

                lua.PrintToConsole($"Unloading module { module_name } ...");

                WeakReference <GmodNetModuleAssemblyLoadContext> context_weak_reference = UnloadHelper(module_name);

                for (int i = 0; context_weak_reference.TryGetTarget(out _); i++)
                {
                    lua.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB);
                    lua.GetField(-1, "collectgarbage");
                    lua.MCall(0, 0);
                    lua.Pop(1);

                    GC.Collect();
                    GC.WaitForPendingFinalizers();

                    if (i >= 300)
                    {
                        throw new Exception($"Module {module_name} can't be unloaded: there are remaining references or background threads still executing. " +
                                            $"Module resources can't be freed. Memory leak could occur. Game restart may be required.");
                    }
                }

                lua.PrintToConsole($"Module {module_name} was unloaded.");

                lua.PushBool(true);

                return(1);
            }
            catch (Exception e)
            {
                lua.PrintToConsole("Unable to unload module: exception was thrown");
                lua.PrintToConsole(e.ToString());

                lua.PushBool(false);

                return(1);
            }
        }
Exemple #2
0
        internal void OnNativeUnload(ILua lua)
        {
            try
            {
                List <string> module_names = new List <string>();

                foreach (var p in module_contexts)
                {
                    module_names.Add(p.Key);
                }

                foreach (string name in module_names)
                {
                    try
                    {
                        WeakReference <GmodNetModuleAssemblyLoadContext> weak_reference = UnloadHelper(name);

                        for (int i = 0; weak_reference.TryGetTarget(out _); i++)
                        {
                            lua.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB);
                            lua.GetField(-1, "collectgarbage");
                            lua.MCall(0, 0);
                            lua.Pop(1);

                            GC.Collect();
                            GC.WaitForPendingFinalizers();

                            if (i >= 300)
                            {
                                throw new Exception($"Module {name} can't be unloaded: there are remaining references or background threads still executing. " +
                                                    $"Module resources can't be freed. Memory leak could occur. Game restart may be required.");
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        lua.PrintToConsole($"Exception was thrown while unloading .NET module {name}");
                        lua.PrintToConsole(e.ToString());
                    }
                }
            }
            catch (Exception e)
            {
                lua.PrintToConsole("Critiacal error occured on .NET modules unload");
                lua.PrintToConsole(e.ToString());
            }
        }
Exemple #3
0
        int LoadModule(ILua lua)
        {
            try
            {
                string module_name = lua.GetString(1);

                lua.Pop(lua.Top());

                if (String.IsNullOrEmpty(module_name))
                {
                    throw new Exception("Module name is null or empty");
                }

                if (module_contexts.ContainsKey(module_name))
                {
                    throw new Exception($"Module with name {module_name} is already loaded");
                }

                GmodNetModuleAssemblyLoadContext module_context = new GmodNetModuleAssemblyLoadContext(module_name);

                Assembly module_assembly = module_context.LoadFromAssemblyPath(Path.GetFullPath("garrysmod/lua/bin/Modules/" + module_name + "/" + module_name + ".dll"));

                Type[] module_types = module_assembly.GetTypes().Where(t => typeof(IModule).IsAssignableFrom(t)).ToArray();

                List <IModule> modules = new List <IModule>();

                List <GCHandle> gc_handles = new List <GCHandle>();

                foreach (Type t in module_types)
                {
                    IModule current_module = (IModule)Activator.CreateInstance(t);
                    modules.Add(current_module);
                    gc_handles.Add(GCHandle.Alloc(current_module));
                }

                if (modules.Count == 0)
                {
                    throw new Exception($"Module {module_name} does not contain any implementations of the IModule interface.");
                }

                lua.PrintToConsole("Loading modules from " + module_name + ".");
                lua.PrintToConsole("Number of the IModule interface implementations: " + modules.Count);

                foreach (IModule m in modules)
                {
                    lua.PrintToConsole("Loading class-module " + m.ModuleName + " version " + m.ModuleVersion + "...");
                    m.Load(lua, isServerSide, module_context);
                    lua.PrintToConsole("Class-module " + m.ModuleName + " was loaded.");
                }

                module_contexts.Add(module_name, Tuple.Create(module_context, gc_handles));

                lua.PushBool(true);

                return(1);
            }
            catch (Exception e)
            {
                lua.PrintToConsole("Unable to load module: exception was thrown");
                lua.PrintToConsole(e.ToString());

                lua.PushBool(false);

                return(1);
            }
        }