Beispiel #1
0
        public Task <bool> Start(ILua lua, GetILuaFromLuaStatePointer lua_extructor, ModuleAssemblyLoadContext _)
        {
            TaskCompletionSource <bool> taskCompletion = new TaskCompletionSource <bool>();

            try
            {
                Random rand = new Random();

                int random_number = rand.Next(1, 500);

                lua.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB);
                lua.GetField(-1, "tonumber");
                lua.PushString(random_number.ToString());
                try
                {
                    lua.MCall(1, 1);
                }
                catch (GmodLuaException)
                {
                    throw new MCallTestException("Exception was thrown by MCall, but it is not expected.");
                }
                int received_number = (int)lua.GetNumber(-1);
                if (received_number != random_number)
                {
                    throw new MCallTestException("Numbers mismatch.");
                }
                lua.Pop(2);

                string random_error_message = Guid.NewGuid().ToString();

                lua.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB);
                lua.GetField(-1, "assert");
                lua.PushBool(false);
                lua.PushString(random_error_message);
                try
                {
                    lua.MCall(2, 0);
                }
                catch (GmodLuaException e)
                {
                    if (e.Message != random_error_message)
                    {
                        throw new MCallTestException("Error message is invalid");
                    }

                    taskCompletion.TrySetResult(true);
                }
                catch (Exception)
                {
                    throw new MCallTestException("Wrong exception type was thrown");
                }
            }
            catch (Exception e)
            {
                taskCompletion.TrySetException(new Exception[] { e });
            }

            return(taskCompletion.Task);
        }
        int SpawnFunc(ILua lua)
        {
            try
            {
                lua.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB);
                lua.GetField(-1, "ents");
                lua.GetField(-1, "Create");
                lua.PushString("prop_physics");
                lua.MCall(1, 1);

                if (lua.GetType(-1) != (int)TYPES.ENTITY)
                {
                    throw new SpawnEntityException("ents.Create returned a value which type is not Entity");
                }

                lua.GetField(-1, "SetModel");
                lua.Push(-2);
                lua.PushString("models/props_c17/oildrum001.mdl");
                lua.MCall(2, 0);

                lua.GetField(-1, "SetPos");
                lua.Push(-2);
                lua.PushVector(new System.Numerics.Vector3(0));
                lua.MCall(2, 0);

                lua.GetField(-1, "Spawn");
                lua.Push(-2);
                lua.MCall(1, 0);

                lua.GetField(-1, "IsValid");
                lua.Push(-2);
                lua.MCall(1, 1);
                if (!lua.GetBool(-1))
                {
                    throw new SpawnEntityException("Entity is not valid");
                }

                lua.Pop(lua.Top());

                taskCompletion.TrySetResult(true);
            }
            catch (Exception e)
            {
                taskCompletion.TrySetException(new Exception[] { e });
            }

            return(0);
        }
        public Task <bool> Start(ILua lua, GetILuaFromLuaStatePointer lua_extructor, ModuleAssemblyLoadContext assembly_context)
        {
            TaskCompletionSource <bool> taskCompletion = new TaskCompletionSource <bool>();

            try
            {
                lua.PushManagedClosure(lua =>
                {
                    throw new Exception(error_message);
                }, 0);

                lua.MCall(0, 0);

                throw new Exception("MCall hasn't caught an exception");
            }
            catch (Exception e)
            {
                if (e is GmodLuaException && e.ToString().Contains(error_message))
                {
                    taskCompletion.TrySetResult(true);
                }
                else
                {
                    taskCompletion.TrySetException(new Exception[] { e });
                }
            }

            return(taskCompletion.Task);
        }
Beispiel #4
0
        public Task <bool> Start(ILua lua, GetILuaFromLuaStatePointer lua_extructor, ModuleAssemblyLoadContext assembly_context)
        {
            TaskCompletionSource <bool> taskCompletion = new TaskCompletionSource <bool>();

            try
            {
                lua.PushManagedFunction((lua) =>
                {
                    throw new Exception(random_string);
                });
                lua.MCall(0, 0);

                throw new Exception("The managed exception was not caught by MCall.");
            }
            catch (Exception e)
            {
                if (e is GmodLuaException && e.Message.Contains(random_string))
                {
                    taskCompletion.TrySetResult(true);
                }
                else
                {
                    taskCompletion.TrySetException(new Exception[] { e });
                }
            }

            return(taskCompletion.Task);
        }
        public Task <bool> Start(ILua lua, GetILuaFromLuaStatePointer lua_extructor, ModuleAssemblyLoadContext assembly_context)
        {
            TaskCompletionSource <bool> taskCompletion = new TaskCompletionSource <bool>();

            try
            {
                lua.PushManagedClosure(l =>
                {
                    if (l.Top() != 0)
                    {
                        throw new Exception("Closure execution stack is non-empty.");
                    }
                    l.PushString(random);
                    return(1);
                }, 0);
                lua.MCall(0, 1);
                string ret_string = lua.GetString(-1);
                lua.Pop(1);

                if (ret_string != random)
                {
                    throw new Exception("Return string is incorrect.");
                }

                taskCompletion.TrySetResult(true);
            }
            catch (Exception e)
            {
                taskCompletion.TrySetException(new Exception[] { e });
            }

            return(taskCompletion.Task);
        }
        public Task <bool> Start(ILua lua, GetILuaFromLuaStatePointer lua_extructor, ModuleAssemblyLoadContext _)
        {
            this.lua_extructor = lua_extructor;

            try
            {
                lua.CreateTable();
                lua.CreateTable();
                lua.PushManagedFunction(MetaToStringDelegate);
                lua.SetField(-2, "__tostring");
                lua.SetMetaTable(-2);

                lua.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB);
                lua.GetField(-1, "tostring");
                lua.Push(-3);
                lua.MCall(1, 1);

                string get_val = lua.GetString(-1);

                lua.Pop(2);

                if (get_val != to_str_msg)
                {
                    throw new CreateMetaTableException("Recieved string is incorrect");
                }

                taskCompletion.TrySetResult(true);
            }
            catch (Exception e)
            {
                taskCompletion.TrySetException(new Exception[] { e });
            }

            return(taskCompletion.Task);
        }
        public Task <bool> Start(ILua lua, GetILuaFromLuaStatePointer lua_extructor, ModuleAssemblyLoadContext _)
        {
            TaskCompletionSource <bool> taskCompletion = new TaskCompletionSource <bool>();

            try
            {
                lua.PushAngle(new System.Numerics.Vector3(0));
                if (!lua.GetMetaTable(-1))
                {
                    throw new GetMetaTableTestException("GetMetaTable returned false");
                }
                lua.GetField(-1, "IsZero");
                lua.Push(-3);
                lua.MCall(1, 1);
                bool received_bool = lua.GetBool(-1);
                lua.Pop(3);
                if (!received_bool)
                {
                    throw new GetMetaTableTestException("Meta function returned False but must return True");
                }

                taskCompletion.TrySetResult(true);
            }
            catch (Exception e)
            {
                taskCompletion.TrySetException(new Exception[] { e });
            }

            return(taskCompletion.Task);
        }
Beispiel #8
0
        public Task <bool> Start(ILua lua, GetILuaFromLuaStatePointer lua_extructor, ModuleAssemblyLoadContext assembly_context)
        {
            TaskCompletionSource <bool> taskCompletion = new TaskCompletionSource <bool>();

            try
            {
                IntPtr func_int_ptr;

                unsafe
                {
                    func_int_ptr = (IntPtr)(delegate * unmanaged[Cdecl] < IntPtr, int >) & TestFunc;
                }

                lua.PushCFunction(func_int_ptr);

                lua.MCall(0, 1);

                string ret_string = lua.GetString(-1);

                lua.Pop(1);

                if (ret_string != random)
                {
                    throw new Exception("Return string is incorrect");
                }

                taskCompletion.TrySetResult(true);
            }
            catch (Exception e)
            {
                taskCompletion.TrySetException(new Exception[] { e });
            }

            return(taskCompletion.Task);
        }
Beispiel #9
0
        public Task <bool> Start(ILua lua, GetILuaFromLuaStatePointer lua_extructor, ModuleAssemblyLoadContext assembly_context)
        {
            TaskCompletionSource <bool> taskCompletion = new TaskCompletionSource <bool>();

            try
            {
                lua.PushManagedFunction((lua) =>
                {
                    lua.PushString(random_string);
                    return(1);
                });
                lua.MCall(0, 1);
                string ret_string = lua.GetString(-1);
                lua.Pop(1);

                if (ret_string != random_string)
                {
                    throw new Exception("Return string is invalid");
                }

                taskCompletion.TrySetResult(true);
            }
            catch (Exception e)
            {
                taskCompletion.TrySetException(new Exception[] { e });
            }

            return(taskCompletion.Task);
        }
Beispiel #10
0
        public Task <bool> Start(ILua lua, GetILuaFromLuaStatePointer lua_extructor, ModuleAssemblyLoadContext assembly_context)
        {
            TaskCompletionSource <bool> taskCompletion = new TaskCompletionSource <bool>();

            try
            {
                lua.PushManagedClosure(lua =>
                {
                    if (lua.Top() != 3)
                    {
                        throw new Exception("Closure execution stack has incorect number of items.");
                    }

                    string one   = lua.GetString(1);
                    string two   = lua.GetString(2);
                    double three = lua.GetNumber(3);

                    lua.Pop(3);

                    lua.PushString(one + three);
                    lua.PushString(three + two);

                    if (lua.Top() != 2)
                    {
                        throw new Exception("Closure execution stack has incorrect number of items after executtion.");
                    }

                    return(2);
                }, 0);

                lua.PushString(random1);
                lua.PushString(random2);
                lua.PushNumber(random3);

                lua.MCall(3, 2);

                string ret_1 = lua.GetString(-2);
                string ret_2 = lua.GetString(-1);

                lua.Pop(2);

                if (ret_1 != random1 + random3)
                {
                    throw new Exception("First return string is incorrect.");
                }

                if (ret_2 != random3 + random2)
                {
                    throw new Exception("Second return string is incorrect.");
                }

                taskCompletion.TrySetResult(true);
            }
            catch (Exception e)
            {
                taskCompletion.TrySetException(new Exception[] { e });
            }

            return(taskCompletion.Task);
        }
        public Task <bool> Start(ILua lua, GetILuaFromLuaStatePointer lua_extructor, ModuleAssemblyLoadContext _)
        {
            this.lua_extructor = lua_extructor;

            TaskCompletionSource <bool> taskCompletion = new TaskCompletionSource <bool>();

            try
            {
                string closure_upvalue = Guid.NewGuid().ToString();

                lua.PushString(closure_upvalue);

                lua.PushCClosure(closure_ptr, 1);

                lua.MCall(0, 1);

                string received_string = lua.GetString(-1);

                lua.Pop(1);

                if (received_string != (closure_upvalue + string_to_add))
                {
                    throw new PushCClosureTestException("Received string is invalid");
                }

                taskCompletion.TrySetResult(true);
            }
            catch (Exception e)
            {
                taskCompletion.TrySetException(new Exception[] { e });
            }

            return(taskCompletion.Task);
        }
Beispiel #12
0
 internal static void PrintToConsole(this ILua lua, string message)
 {
     lua.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB);
     lua.GetField(-1, "print");
     lua.PushString(message);
     lua.MCall(1, 0);
     lua.Pop(1);
 }
 public void Unload(ILua lua)
 {
     lua.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB);
     lua.GetField(-1, "print");
     lua.PushString("Goodbye World!");
     lua.MCall(1, 0);
     lua.Pop();
 }
 public void Load(ILua lua, bool is_serverside, ModuleAssemblyLoadContext assembly_context)
 {
     lua.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB);
     lua.GetField(-1, "print");
     lua.PushString("Hello World!");
     lua.MCall(1, 0);
     lua.Pop();
 }
        public Task <bool> Start(ILua lua, GetILuaFromLuaStatePointer lua_extructor, ModuleAssemblyLoadContext assembly_context)
        {
            TaskCompletionSource <bool> taskCompletion = new TaskCompletionSource <bool>();

            try
            {
                lua.PushManagedFunction((lua) =>
                {
                    int stack_items = lua.Top();
                    if (stack_items != 3)
                    {
                        throw new Exception("The number of items on the execution stack is incorrect");
                    }

                    string first  = lua.GetString(1);
                    string second = lua.GetString(2);
                    double third  = lua.GetNumber(3);

                    lua.Pop(3);

                    lua.PushString(first + third);
                    lua.PushString(third + second);

                    return(2);
                });

                lua.PushString(random_string_1);
                lua.PushString(random_string_2);
                lua.PushNumber(random_number);

                lua.MCall(3, 2);

                string ret_1 = lua.GetString(-2);
                string ret_2 = lua.GetString(-1);

                lua.Pop(2);

                if (ret_1 != random_string_1 + random_number)
                {
                    throw new Exception("First return string is incorrect");
                }

                if (ret_2 != random_number + random_string_2)
                {
                    throw new Exception("Second return string is incorrect");
                }

                taskCompletion.TrySetResult(true);
            }
            catch (Exception e)
            {
                taskCompletion.TrySetException(new Exception[] { e });
            }

            return(taskCompletion.Task);
        }
Beispiel #16
0
        void SetPlayerList(ILua lua)
        {
            if (!getPlayersTasks.IsEmpty)
            {
                List <string> players            = new List <string>();
                Exception     executionException = null;

                try
                {
                    lua.PushGlobalTable();
                    lua.GetField(-1, "player");
                    lua.GetField(-1, "GetAll");
                    lua.MCall(0, 1);
                    lua.PushNil();
                    while (lua.Next(-2) != 0)
                    {
                        lua.GetField(-1, "Nick");
                        lua.Push(-2);
                        lua.MCall(1, 1);
                        players.Add(lua.GetString(-1));
                        lua.Pop(2);
                    }
                    lua.Pop(lua.Top());
                }
                catch (Exception e)
                {
                    executionException = e;
                }

                TaskCompletionSource <List <string> > task;
                while (getPlayersTasks.TryDequeue(out task))
                {
                    if (executionException == null)
                    {
                        task.SetResult(players);
                    }
                    else
                    {
                        task.SetException(executionException);
                    }
                }
            }
        }
Beispiel #17
0
 public void Unload(ILua lua)
 {
     lua.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB);
     lua.GetField(-1, "hook");
     lua.GetField(-1, "Remove");
     lua.PushString("Tick");
     lua.PushString(this.OnTickIdentifier);
     lua.MCall(2, 0);
     lua.Pop(2);
 }
Beispiel #18
0
        public Task <bool> Start(ILua lua, GetILuaFromLuaStatePointer lua_extructor, ModuleAssemblyLoadContext assembly_context)
        {
            TaskCompletionSource <bool> taskCompletion = new TaskCompletionSource <bool>();

            try
            {
                int stack_state = lua.Top();

                lua.PushString(random1);
                lua.PushString(random2);
                lua.PushManagedClosure(lua =>
                {
                    if (lua.Top() != 1)
                    {
                        throw new Exception("Managed closure execution stack has incorrect number of items");
                    }

                    double num = lua.GetNumber(1);

                    lua.Pop(1);

                    string first  = lua.GetString(GmodInterop.GetUpvalueIndex(1));
                    string second = lua.GetString(GmodInterop.GetUpvalueIndex(2));

                    lua.PushString(first + num + second);

                    return(1);
                }, 2);

                if (lua.Top() != stack_state + 1)
                {
                    throw new Exception("Wrong number of items left on the stack");
                }

                lua.PushNumber(random3);

                lua.MCall(1, 1);

                string ret = lua.GetString(-1);
                lua.Pop(1);

                if (ret != random1 + random3 + random2)
                {
                    throw new Exception("Return string is incorrect");
                }

                taskCompletion.TrySetResult(true);
            }
            catch (Exception e)
            {
                taskCompletion.TrySetException(new Exception[] { e });
            }

            return(taskCompletion.Task);
        }
Beispiel #19
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);
            }
        }
Beispiel #20
0
        public void Load(ILua lua, bool is_serverside, ModuleAssemblyLoadContext assembly_context)
        {
            this.lua                  = lua;
            this.isServerSide         = is_serverside;
            this.current_load_context = assembly_context;
            this.OnTickDelegate       = this.OnTick;
            this.OnTickIdentifier     = Guid.NewGuid().ToString();
            current_test              = null;

            if (isServerSide)
            {
                try
                {
                    lua.Log("Loading test runner");

                    //Register OnTick with Garry's Mod
                    lua.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB);
                    lua.GetField(-1, "hook");
                    lua.GetField(-1, "Add");
                    lua.PushString("Tick");
                    lua.PushString(this.OnTickIdentifier);
                    lua.PushManagedFunction(this.OnTickDelegate);
                    lua.MCall(3, 0);
                    lua.Pop(2);

                    //Get the list of tests
                    ListOfTests = new List <ITest>();
                    if (typeof(Tests).Assembly.GetTypes().Any(type => typeof(ITest).IsAssignableFrom(type) && type != typeof(ITest)))
                    {
                        foreach (Type t in typeof(Tests).Assembly.GetTypes().Where(type => type != typeof(ITest) && typeof(ITest).IsAssignableFrom(type)))
                        {
                            ListOfTests.Add((ITest)Activator.CreateInstance(t));
                        }
                    }

                    lua.Log("There are " + ListOfTests.Count + " tests to run:");
                    foreach (ITest test in ListOfTests)
                    {
                        lua.Log(test.GetType().ToString());
                    }

                    IsEverythingSuccessful = true;
                    tests_start_time       = DateTime.Now;
                    lua.Log("Test runner was loaded!");
                }
                catch (Exception e)
                {
                    lua.Log("Test runner FAILED to start: " + e.GetType().ToString() + ". Exception message: " + e.Message);
                }
            }
        }
Beispiel #21
0
        public Task <bool> Start(ILua lua, GetILuaFromLuaStatePointer lua_extructor, ModuleAssemblyLoadContext assembly_context)
        {
            try
            {
                lua.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB);
                lua.GetField(-1, "hook");
                lua.GetField(-1, "Add");
                lua.PushString("Tick");
                lua.PushString(hook_id);
                lua.PushManagedFunction(l =>
                {
                    try
                    {
                        if (counter < 33)
                        {
                            counter++;
                        }
                        else
                        {
                            l.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB);
                            l.GetField(-1, "hook");
                            l.GetField(-1, "Remove");
                            l.PushString("Tick");
                            l.PushString(hook_id);
                            l.MCall(2, 0);
                            l.Pop(2);

                            if (counter == 33)
                            {
                                taskCompletion.TrySetResult(true);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        taskCompletion.TrySetException(new Exception[] { e });
                    }

                    return(0);
                });
                lua.MCall(3, 0);
                lua.Pop(2);
            }
            catch (Exception e)
            {
                taskCompletion.TrySetException(new Exception[] { e });
            }

            return(taskCompletion.Task);
        }
Beispiel #22
0
        public void Dispose(ILua lua)
        {
            if (!disposed)
            {
                disposed = true;

                lua.PushGlobalTable();
                lua.GetField(-1, "hook");
                lua.GetField(-1, "Remove");
                lua.PushString("Tick");
                lua.PushString(onTickCallbackId);
                lua.MCall(2, 0);
                lua.Pop(2);
            }
        }
        public Task <bool> Start(ILua lua, GetILuaFromLuaStatePointer lua_extructor, ModuleAssemblyLoadContext assembly_context)
        {
            TaskCompletionSource <bool> taskCompletion = new TaskCompletionSource <bool>();

            try
            {
                int stack_state = lua.Top();

                custom_type_id = lua.CreateMetaTable(Guid.NewGuid().ToString());
                lua.PushManagedFunction(lua =>
                {
                    long value = (long)lua.GetUserType(1, custom_type_id);
                    lua.Pop(1);
                    lua.PushString((value * 2).ToString());
                    return(1);
                });
                lua.SetField(-2, "__call");
                lua.Pop(1);

                lua.PushUserType((IntPtr)random_integer, custom_type_id);
                lua.MCall(0, 1);
                string ret_string = lua.GetString(-1);
                lua.Pop(1);

                lua.PushMetaTable(custom_type_id);
                lua.PushNil();
                lua.SetField(-2, "__call");
                lua.Pop(1);

                if ((stack_state - lua.Top()) != 0)
                {
                    throw new Exception("Lua stack has some values left");
                }

                if (ret_string != (random_integer * 2).ToString())
                {
                    throw new Exception("Return string is incorrect");
                }

                taskCompletion.TrySetResult(true);
            }
            catch (Exception e)
            {
                taskCompletion.TrySetException(new Exception[] { e });
            }

            return(taskCompletion.Task);
        }
        public Task <bool> Start(ILua lua, GetILuaFromLuaStatePointer lua_extructor, ModuleAssemblyLoadContext _)
        {
            this.lua_extructor = lua_extructor;

            try
            {
                lua.PushManagedFunction(this.spawn_func);
                lua.MCall(0, 0);
            }
            catch (Exception e)
            {
                taskCompletion.TrySetException(new Exception[] { e });
            }

            return(taskCompletion.Task);
        }
        public Task <bool> Start(ILua lua, GetILuaFromLuaStatePointer lua_extructor, ModuleAssemblyLoadContext assembly_context)
        {
            TaskCompletionSource <bool> taskCompletion = new TaskCompletionSource <bool>();

            try
            {
                int lua_state = lua.Top();

                lua.PushString(random);
                lua.PushManagedClosure(lua =>
                {
                    if (lua.Top() != 0)
                    {
                        throw new Exception("Managed closure execution stack is non-empty");
                    }

                    string upvalue = lua.GetString(GmodInterop.GetUpvalueIndex(1));

                    lua.PushString(upvalue + upvalue);

                    return(1);
                }, 1);

                if (lua.Top() != lua_state + 1)
                {
                    throw new Exception("There is incorrect number of items on the Lua stack");
                }

                lua.MCall(0, 1);

                string ret = lua.GetString(-1);
                lua.Pop(1);

                if (ret != random + random)
                {
                    throw new Exception("Return string is incorrect");
                }

                taskCompletion.TrySetResult(true);
            }
            catch (Exception e)
            {
                taskCompletion.TrySetException(new Exception[] { e });
            }

            return(taskCompletion.Task);
        }
Beispiel #26
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());
            }
        }
Beispiel #27
0
        public GmodInteropService(ILua lua)
        {
            disposed         = false;
            onTickCallbackId = Guid.NewGuid().ToString();
            getPlayersTasks  = new ConcurrentQueue <TaskCompletionSource <List <string> > >();

            lua.PushGlobalTable();
            lua.GetField(-1, "hook");
            lua.GetField(-1, "Add");
            lua.PushString("Tick");
            lua.PushString(onTickCallbackId);
            lua.PushManagedFunction(lua =>
            {
                SetPlayerList(lua);
                return(0);
            });
            lua.MCall(3, 0);
            lua.Pop(2);
        }
Beispiel #28
0
        public Task <bool> Start(ILua lua, GetILuaFromLuaStatePointer lua_extructor, ModuleAssemblyLoadContext assembly_context)
        {
            TaskCompletionSource <bool> taskCompletion = new();

            try
            {
                unsafe
                {
                    lua.PushCFunction(&TestFunc);
                    lua.MCall(0, 2);

                    string ret_string = lua.GetString(-1);
                    double ret_number = lua.GetNumber(-2);

                    lua.Pop(2);

                    if (ret_string != random_string)
                    {
                        throw new Exception("Returned string is invalid");
                    }

                    if (ret_number != random_number)
                    {
                        throw new Exception("Returned number is invalid");
                    }

                    taskCompletion.TrySetResult(true);
                }
            }
            catch (Exception e)
            {
                taskCompletion.TrySetException(new Exception[] { e });
            }

            return(taskCompletion.Task);
        }
        public Task <bool> Start(ILua lua, GetILuaFromLuaStatePointer lua_extructor, ModuleAssemblyLoadContext _)
        {
            TaskCompletionSource <bool> taskCompletion = new TaskCompletionSource <bool>();

            try
            {
                this.lua_extructor = lua_extructor;

                this.NewTypeId = lua.CreateMetaTable("TestType1");

                lua.PushManagedFunction(this.ToStringImpl);

                lua.SetField(-2, "__tostring");

                lua.Pop(1);


                //Create new table to test newly created metatable

                lua.CreateTable();

                lua.PushMetaTable(this.NewTypeId);

                lua.SetMetaTable(-2);

                /*
                 * if(!lua.IsType(-1, this.NewTypeId))
                 * {
                 *  throw new Exception("Received type id is invalid");
                 * }
                 *
                 * string received_type_name = lua.GetTypeName(lua.GetType(-1));
                 *
                 * if(received_type_name != "TestType1")
                 * {
                 *  throw new Exception("Received type name is invalid");
                 * }
                 */

                lua.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB);

                lua.GetField(-1, "tostring");

                lua.Push(-3);

                lua.MCall(1, 1);

                if (lua.GetString(-1) != this.RandomString)
                {
                    throw new Exception("Metatable method __tostring returned incorrect string");
                }

                lua.Pop(3);

                lua.PushMetaTable(NewTypeId);

                lua.PushNil();

                lua.SetField(-2, "__tostring");

                lua.Pop(1);

                taskCompletion.TrySetResult(true);
            }
            catch (Exception e)
            {
                taskCompletion.TrySetException(new Exception[] { e });
            }

            return(taskCompletion.Task);
        }
Beispiel #30
0
        public void Load(ILua lua, bool is_serverside, ModuleAssemblyLoadContext assembly_context)
        {
            lua.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB);
            lua.GetField(-1, "print");
            lua.PushString("Hello World RPC");
            lua.MCall(1, 0);
            lua.Pop();

            int DiscordRPC_update_callbacks(ILua lua)
            {
                lua.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB);
                lua.GetField(-1, "print");
                lua.PushString("It Works!");
                lua.MCall(1, 0);
                lua.Pop();

                lua.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB);
                lua.GetField(-1, "game");
                lua.GetField(-1, "GetMap");
                lua.MCall(0, 1);
                map = lua.GetString(-1);
                lua.Pop();

                lua.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB);
                lua.GetField(-1, "game");
                lua.GetField(-1, "SinglePlayer");
                lua.MCall(0, 1);
                bool IsSinglePlayer = lua.GetBool(-1);

                lua.Pop();

                lua.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB);
                lua.GetField(-1, "engine");
                lua.GetField(-1, "ActiveGamemode");
                lua.MCall(0, 1);
                gamemode = lua.GetString(-1);
                lua.Pop();

                if (IsSinglePlayer)
                {
                    activityDetails = "SinglePlayer";
                }
                else
                {
                    lua.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB);
                    lua.GetField(-1, "player");
                    lua.GetField(-1, "GetCount");
                    lua.MCall(0, 1);
                    int players = (int)lua.GetNumber(-1);
                    lua.Pop();

                    lua.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB);
                    lua.GetField(-1, "game");
                    lua.GetField(-1, "MaxPlayers");
                    lua.MCall(0, 1);
                    int maxPlayers = (int)lua.GetNumber(-1);
                    lua.Pop();

                    activityDetails = $"{players}/{maxPlayers}";
                }

                /*if (!is_serverside)
                 * {
                 *  lua.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB);
                 *  lua.GetField(-1, "LocalPlayer"); //team.GetScore(ply:Team())
                 *  lua.MCall(0, 1);
                 *
                 *  lua.GetField(-1, "Team");
                 *  lua.Push(-2);
                 *  lua.MCall(0, 1);
                 *  double team = lua.GetNumber(-1);
                 *  lua.Pop();
                 *
                 *  lua.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB);
                 *  lua.GetField(-1, "teams");
                 *  lua.GetField(-1, "GetScore");
                 *  lua.PushNumber(team);
                 *  lua.MCall(1, 1);
                 *  score = (int)lua.GetNumber(-1);
                 *  lua.Pop();
                 * }*/


                UpdateActivity();
                return(0);
            };

            lua.PushSpecial(SPECIAL_TABLES.SPECIAL_GLOB);
            lua.PushManagedFunction(DiscordRPC_update_callbacks);
            lua.SetField(-2, "DiscordRPC_update_activity");
            lua.Pop(1);


            discord = new Discord.Discord(client_ID, (UInt64)Discord.CreateFlags.Default);
            discord.SetLogHook(Discord.LogLevel.Debug, (level, message) =>
            {
                Console.WriteLine("Log[{0}] {1}", level, message);
            });

            var applicationManager = discord.GetApplicationManager();

            // Get the current locale. This can be used to determine what text or audio the user wants.
            Console.WriteLine("Current Locale: {0}", applicationManager.GetCurrentLocale());
            // Get the current branch. For example alpha or beta.
            Console.WriteLine("Current Branch: {0}", applicationManager.GetCurrentBranch());
            // If you want to verify information from your game's server then you can
            // grab the access token and send it to your server.
            //
            // This automatically looks for an environment variable passed by the Discord client,
            // if it does not exist the Discord client will focus itself for manual authorization.
            //
            // By-default the SDK grants the identify and rpc scopes.
            // Read more at https://discordapp.com/developers/docs/topics/oauth2
            // applicationManager.GetOAuth2Token((Discord.Result result, ref Discord.OAuth2Token oauth2Token) =>
            // {
            //     Console.WriteLine("Access Token {0}", oauth2Token.AccessToken);
            // });

            var activityManager = discord.GetActivityManager();
            var lobbyManager    = discord.GetLobbyManager();

            // Received when someone accepts a request to join or invite.
            // Use secrets to receive back the information needed to add the user to the group/party/match
            activityManager.OnActivityJoin += secret =>
            {
                Console.WriteLine("OnJoin {0}", secret);
                lobbyManager.ConnectLobbyWithActivitySecret(secret, (Discord.Result result, ref Discord.Lobby lobby) =>
                {
                    Console.WriteLine("Connected to lobby: {0}", lobby.Id);
                    lobbyManager.ConnectNetwork(lobby.Id);
                    lobbyManager.OpenNetworkChannel(lobby.Id, 0, true);
                    foreach (var user in lobbyManager.GetMemberUsers(lobby.Id))
                    {
                        lobbyManager.SendNetworkMessage(lobby.Id, user.Id, 0,
                                                        Encoding.UTF8.GetBytes(String.Format("Hello, {0}!", user.Username)));
                    }
                    UpdateActivity();
                });
            };
            // Received when someone accepts a request to spectate
            activityManager.OnActivitySpectate += secret =>
            {
                Console.WriteLine("OnSpectate {0}", secret);
            };
            // A join request has been received. Render the request on the UI.
            activityManager.OnActivityJoinRequest += (ref Discord.User user) =>
            {
                Console.WriteLine("OnJoinRequest {0} {1}", user.Id, user.Username);
            };
            // An invite has been received. Consider rendering the user / activity on the UI.
            activityManager.OnActivityInvite += (Discord.ActivityActionType Type, ref Discord.User user, ref Discord.Activity activity2) =>
            {
                Console.WriteLine("OnInvite {0} {1} {2}", Type, user.Username, activity2.Name);
                // activityManager.AcceptInvite(user.Id, result =>
                // {
                //     Console.WriteLine("AcceptInvite {0}", result);
                // });
            };
            // This is used to register the game in the registry such that Discord can find it.
            // This is only needed by games acquired from other platforms, like Steam.
            // activityManager.RegisterCommand();

            var imageManager = discord.GetImageManager();

            var userManager = discord.GetUserManager();


            lobbyManager.OnLobbyMessage += (lobbyID, userID, data) =>
            {
                Console.WriteLine("lobby message: {0} {1}", lobbyID, Encoding.UTF8.GetString(data));
            };
            lobbyManager.OnNetworkMessage += (lobbyId, userId, channelId, data) =>
            {
                Console.WriteLine("network message: {0} {1} {2} {3}", lobbyId, userId, channelId, Encoding.UTF8.GetString(data));
            };
            lobbyManager.OnSpeaking += (lobbyID, userID, speaking) =>
            {
                Console.WriteLine("lobby speaking: {0} {1} {2}", lobbyID, userID, speaking);
            };

            UpdateActivity();


            /*
             * var overlayManager = discord.GetOverlayManager();
             * overlayManager.OnOverlayLocked += locked =>
             * {
             *  Console.WriteLine("Overlay Locked: {0}", locked);
             * };
             * overlayManager.SetLocked(false);
             */

            var storageManager = discord.GetStorageManager();
            var contents       = new byte[20000];
            var random         = new Random();

            random.NextBytes(contents);
            Console.WriteLine("storage path: {0}", storageManager.GetPath());
            storageManager.WriteAsync("foo", contents, res =>
            {
                var files = storageManager.Files();
                foreach (var file in files)
                {
                    Console.WriteLine("file: {0} size: {1} last_modified: {2}", file.Filename, file.Size, file.LastModified);
                }
                storageManager.ReadAsyncPartial("foo", 400, 50, (result, data) =>
                {
                    Console.WriteLine("partial contents of foo match {0}", Enumerable.SequenceEqual(data, new ArraySegment <byte>(contents, 400, 50)));
                });
                storageManager.ReadAsync("foo", (result, data) =>
                {
                    Console.WriteLine("length of contents {0} data {1}", contents.Length, data.Length);
                    Console.WriteLine("contents of foo match {0}", Enumerable.SequenceEqual(data, contents));
                    Console.WriteLine("foo exists? {0}", storageManager.Exists("foo"));
                    storageManager.Delete("foo");
                    Console.WriteLine("post-delete foo exists? {0}", storageManager.Exists("foo"));
                });
            });

            var storeManager = discord.GetStoreManager();

            storeManager.OnEntitlementCreate += (ref Discord.Entitlement entitlement) =>
            {
                Console.WriteLine("Entitlement Create1: {0}", entitlement.Id);
            };

            // Start a purchase flow.
            // storeManager.StartPurchase(487507201519255552, result =>
            // {
            //     if (result == Discord.Result.Ok)
            //     {
            //         Console.WriteLine("Purchase Complete");
            //     }
            //     else
            //     {
            //         Console.WriteLine("Purchase Canceled");
            //     }
            // });

            // Get all entitlements.
            storeManager.FetchEntitlements(result =>
            {
                if (result == Discord.Result.Ok)
                {
                    foreach (var entitlement in storeManager.GetEntitlements())
                    {
                        Console.WriteLine("entitlement: {0} - {1} {2}", entitlement.Id, entitlement.Type, entitlement.SkuId);
                    }
                }
            });

            // Get all SKUs.
            storeManager.FetchSkus(result =>
            {
                if (result == Discord.Result.Ok)
                {
                    foreach (var sku in storeManager.GetSkus())
                    {
                        Console.WriteLine("sku: {0} - {1} {2}", sku.Name, sku.Price.Amount, sku.Price.Currency);
                    }
                }
            });
            updater = new Thread(UpdaterThread);
            updater.Start();
        }