Example #1
0
        private void CompileAndCreateInstance(string program, string storage)
        {
            if (MySession.Static.EnableIngameScripts == false)
            {
                return;
            }
            m_wasTerminated = false;
            Assembly temp = null;

            MyGuiScreenEditor.CompileProgram(program, m_compilerErrors, ref temp);
            if (temp != null)
            {
                try
                {
                    m_assembly = IlInjector.InjectCodeToAssembly("IngameScript_safe", temp, typeof(IlInjector).GetMethod("CountInstructions", BindingFlags.Public | BindingFlags.Static), typeof(IlInjector).GetMethod("CountMethodCalls", BindingFlags.Public | BindingFlags.Static));

                    var type = m_assembly.GetType("Program");
                    if (type != null)
                    {
                        IlInjector.RestartCountingInstructions(MAX_NUM_EXECUTED_INSTRUCTIONS);
                        IlInjector.RestartCountingMethods(MAX_NUM_METHOD_CALLS);
                        try
                        {
                            m_instance = Activator.CreateInstance(type) as IMyGridProgram;
                            if (m_instance != null)
                            {
                                m_previousRunTimestamp = 0;
                                m_instance.Storage     = storage;
                                m_instance.Me          = this;
                                m_instance.Echo        = EchoTextToDetailInfo;
                            }
                        }
                        catch (TargetInvocationException ex)
                        {
                            if (ex.InnerException != null)
                            {
                                string response = MyTexts.GetString(MySpaceTexts.ProgrammableBlock_Exception_ExceptionCaught) + ex.InnerException.Message;
                                if (DetailedInfo.ToString() != response)
                                {
                                    SyncObject.SendProgramResponseMessage(response);
                                    WriteProgramResponse(response);
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    string response = MyTexts.GetString(MySpaceTexts.ProgrammableBlock_Exception_ExceptionCaught) + ex.Message;
                    if (DetailedInfo.ToString() != response)
                    {
                        SyncObject.SendProgramResponseMessage(response);
                        WriteProgramResponse(response);
                    }
                }
            }
        }
        private void CompileAndCreateInstance(string program, string storage)
        {
            if (MySession.Static.EnableIngameScripts == false)
            {
                return;
            }
            m_terminationReason = ScriptTerminationReason.None;
            try
            {
                Assembly temp = null;
                MyGuiScreenEditor.CompileProgram(program, m_compilerErrors, ref temp);
                if (temp != null)
                {
                    m_assembly = IlInjector.InjectCodeToAssembly("IngameScript_safe", temp, typeof(IlInjector).GetMethod("CountInstructions", BindingFlags.Public | BindingFlags.Static), typeof(IlInjector).GetMethod("CountMethodCalls", BindingFlags.Public | BindingFlags.Static));

                    var type = m_assembly.GetType("Program");
                    if (type != null)
                    {
                        m_instance = FormatterServices.GetUninitializedObject(type) as IMyGridProgram;
                        var    constructor = type.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null);
                        string response;
                        if (m_instance == null || constructor == null)
                        {
                            response = MyTexts.GetString(MySpaceTexts.ProgrammableBlock_Exception_NoValidConstructor);
                            SetDetailedInfo(response);
                            return;
                        }
                        m_runtime.Reset();
                        m_instance.Runtime = m_runtime;
                        m_instance.Storage = storage;
                        m_instance.Me      = this;
                        m_instance.Echo    = EchoTextToDetailInfo;
                        RunSandboxedProgramAction(p =>
                        {
                            constructor.Invoke(p, null);

                            if (!m_instance.HasMainMethod)
                            {
                                if (m_echoOutput.Length > 0)
                                {
                                    response = m_echoOutput.ToString();
                                }
                                response = MyTexts.GetString(MySpaceTexts.ProgrammableBlock_Exception_NoMain);
                                OnProgramTermination(ScriptTerminationReason.NoEntryPoint);
                            }
                        }, out response);
                        SetDetailedInfo(response);
                    }
                }
            }
            catch (Exception ex)
            {
                string response = MyTexts.GetString(MySpaceTexts.ProgrammableBlock_Exception_ExceptionCaught) + ex.Message;
                SetDetailedInfo(response);
            }
        }
        private void CompileAndCreateInstance(string program, string storage)
        {
            if (MySession.Static.EnableIngameScripts == false)
            {
                return;
            }
            m_terminationReason = ScriptTerminationReason.None;
            try
            {
                if (MyFakes.ENABLE_ROSLYN_SCRIPTS)
                {
#if !XB1
                    m_assembly = MyScriptCompiler.Static.Compile(
                        MyApiTarget.Ingame,
                        Path.Combine(MyFileSystem.UserDataPath, GetAssemblyName()),
                        MyScriptCompiler.Static.GetIngameScript(program, "Program", typeof(MyGridProgram).Name),
                        m_compilerMessages).Result;

                    m_compilerErrors.Clear();
                    m_compilerErrors.AddRange(m_compilerMessages.Select(m => m.Text));

                    CreateInstance(m_assembly, m_compilerErrors, storage);
#else // XB1
#if !XB1_SKIPASSERTFORNOW
                    System.Diagnostics.Debug.Assert(false, "No scripts on XB1");
#endif // !XB1_SKIPASSERTFORNOW
#endif // XB1
                }
                else
                {
                    Assembly temp = null;
                    MyGuiScreenEditor.CompileProgram(program, m_compilerErrors, ref temp);
                    if (temp != null)
                    {
#if !XB1 // XB1_NOILINJECTOR
                        m_assembly = IlInjector.InjectCodeToAssembly("IngameScript_safe", temp, typeof(IlInjector).GetMethod("CountInstructions", BindingFlags.Public | BindingFlags.Static), typeof(IlInjector).GetMethod("CountMethodCalls", BindingFlags.Public | BindingFlags.Static));
#else // XB1
                        System.Diagnostics.Debug.Assert(false, "No scripts on XB1");
                        return;
#endif // XB1

                        CreateInstance(m_assembly, m_compilerErrors, storage);
                    }
                }
            }
            catch (Exception ex)
            {
                string response = MyTexts.GetString(MySpaceTexts.ProgrammableBlock_Exception_ExceptionCaught) + ex.Message;
                SetDetailedInfo(response);
            }
        }
Example #4
0
    public override void Execute()
    {
        if (Environment.GetEnvironmentVariable("NOBSERVABLE_DEBUG_ATTACH") == "1")
        {
            LogError($"Attach debugger to {Process.GetCurrentProcess().Id}");
            while (!Debugger.IsAttached)
            {
                Thread.Sleep(1000);
            }
        }

        var context = new WeavingContext(TypeSystem, this, ModuleDefinition);

        foreach (var t in AllTypes(ModuleDefinition.Types))
        {
            var observeAll = t.CustomAttributes.Any(ca => ca.AttributeType.AreEqual(context.ObservableAttributeReference));
            foreach (var p in t.Properties)
            {
                var getter = p.GetMethod;
                var setter = p.SetMethod;
                if (getter == null || setter == null)
                {
                    continue;
                }
                if (getter.IsStatic || setter.IsStatic)
                {
                    continue;
                }
                if (observeAll ||
                    p.CustomAttributes.Any(ca => ca.AttributeType.AreEqual(context.ObservableAttributeReference)))
                {
                    IlInjector.InstrumentProperty(context, p);
                }
            }

            if (context.BlazorHelperAsm != null && IsBlazorComponent(t))
            {
                if (t.Interfaces.Any(iface => iface.InterfaceType.FullName == "NObservable.Blazor.IObserverComponent"))
                {
                    IlInjector.InstrumentBlazorComponent(context, t);
                }
            }
        }
    }
Example #5
0
    public override void Execute()
    {
        if (Environment.GetEnvironmentVariable("NOBSERVABLE_DEBUG_ATTACH") == "1")
        {
            LogError($"Attach debugger to {Process.GetCurrentProcess().Id}");
            while (!Debugger.IsAttached)
            {
                Thread.Sleep(1000);
            }
        }

        var context = new WeavingContext(TypeSystem, ModuleDefinition);

        foreach (var t in AllTypes(ModuleDefinition.Types))
        {
            var            observeAll = t.CustomAttributes.Any(ca => ca.AttributeType.AreEqual(context.ObservableAttributeReference));
            FieldReference field      = null;

            if (t.Name.StartsWith("BasicEngineTest"))
            {
                var set = t.GetMethods().First(m => m.Name == "Wtf");
                Console.WriteLine();
            }
            foreach (var p in t.Properties)
            {
                var getter = p.GetMethod;
                var setter = p.SetMethod;
                if (getter == null || setter == null)
                {
                    continue;
                }
                if (getter.IsStatic || setter.IsStatic)
                {
                    continue;
                }
                if (observeAll ||
                    p.CustomAttributes.Any(ca => ca.AttributeType.AreEqual(context.ObservableAttributeReference)))
                {
                    IlInjector.InstrumentProperty(context, p);
                }
            }
        }
    }
        private void CompileAndCreateInstance(string program, string storage)
        {
            if (MySession.Static.EnableIngameScripts == false)
            {
                return;
            }
            m_wasTerminated = false;
            m_mainMethod    = null;
            Assembly temp = null;

            MyGuiScreenEditor.CompileProgram(program, m_compilerErrors, ref temp);
            if (temp != null)
            {
                try
                {
                    m_assembly = IlInjector.InjectCodeToAssembly("IngameScript_safe", temp, typeof(IlInjector).GetMethod("CountInstructions", BindingFlags.Public | BindingFlags.Static));

                    var type = m_assembly.GetType("Program");
                    if (type != null)
                    {
                        IlInjector.RestartCountingInstructions(MAX_NUM_EXECUTED_INSTRUCTIONS);
                        try
                        {
                            m_instance         = Activator.CreateInstance(type);
                            m_programGridGroup = type.GetField("GridTerminalSystem", BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);
                            m_storageField     = type.GetField("Storage", BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);
                            m_meField          = type.GetField("Me", BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);
                            m_echoField        = type.GetField("Echo", BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);
                            m_elapsedTimeField = type.GetField("ElapsedTime", BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);
                            if (m_programGridGroup != null)
                            {
                                // First try to get the main method with a string argument. If this fails, try to get one without.
                                m_mainMethod = type.GetMethod("Main", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, new[] { typeof(string) }, null);
                                m_mainMethodSupportsArgument = m_mainMethod != null;
                                if (m_mainMethod == null)
                                {
                                    m_mainMethod = type.GetMethod("Main", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
                                }
                            }
                            if (m_storageField != null)
                            {
                                m_storageField.SetValue(m_instance, storage);
                            }
                            if (m_meField != null)
                            {
                                m_meField.SetValue(m_instance, this);
                            }
                            if (m_echoField != null)
                            {
                                m_echoField.SetValue(m_instance, new Action <string>(EchoTextToDetailInfo));
                            }
                        }
                        catch (TargetInvocationException ex)
                        {
                            if (ex.InnerException != null)
                            {
                                string response = MyTexts.GetString(MySpaceTexts.ProgrammableBlock_Exception_ExceptionCaught) + ex.InnerException.Message;
                                if (DetailedInfo.ToString() != response)
                                {
                                    SyncObject.SendProgramResponseMessage(response);
                                    WriteProgramResponse(response);
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    string response = MyTexts.GetString(MySpaceTexts.ProgrammableBlock_Exception_ExceptionCaught) + ex.Message;
                    if (DetailedInfo.ToString() != response)
                    {
                        SyncObject.SendProgramResponseMessage(response);
                        WriteProgramResponse(response);
                    }
                }
            }
        }
        public string ExecuteCode(string argument)
        {
            if (m_isRunning)
            {
                return(MyTexts.GetString(MySpaceTexts.ProgrammableBlock_Exception_AllreadyRunning));
            }
            if (m_wasTerminated == true)
            {
                return(DetailedInfo.ToString());
            }
            DetailedInfo.Clear();
            m_echoOutput.Clear();
            if (m_assembly == null)
            {
                return(MyTexts.GetString(MySpaceTexts.ProgrammableBlock_Exception_NoAssembly));
            }
            if (m_mainMethod == null)
            {
                return(MyTexts.GetString(MySpaceTexts.ProgrammableBlock_Exception_NoMain));
            }
            if (this.m_elapsedTimeField != null)
            {
                if (m_previousRunTimestamp == 0)
                {
                    m_previousRunTimestamp = Stopwatch.GetTimestamp();
                    m_elapsedTimeField.SetValue(m_instance, TimeSpan.Zero);
                }
                else
                {
                    var currentTimestamp = Stopwatch.GetTimestamp();
                    var elapsedTime      = (currentTimestamp - m_previousRunTimestamp) * Sync.RelativeSimulationRatio;
                    m_elapsedTimeField.SetValue(m_instance, TimeSpan.FromSeconds(elapsedTime * STOPWATCH_FREQUENCY));
                    m_previousRunTimestamp = currentTimestamp;
                }
            }
            if (m_programGridGroup != null)
            {
                var gridGroup      = MyCubeGridGroups.Static.Logical.GetGroup(CubeGrid);
                var terminalSystem = gridGroup.GroupData.TerminalSystem;
                terminalSystem.UpdateGridBlocksOwnership(this.OwnerId);
                m_programGridGroup.SetValue(m_instance, terminalSystem);
            }

            m_isRunning = true;
            string retVal = "";

            IlInjector.RestartCountingInstructions(MAX_NUM_EXECUTED_INSTRUCTIONS);
            try
            {
                if (m_mainMethodSupportsArgument)
                {
                    // Don't know if it's really necessary to predefine this argument array, I suspect not
                    // due to the cleverness of the compiler, but I do it this way just in case.
                    // Obviously if programmable block execution becomes asynchronous at some point this
                    // must be reworked.
                    m_argumentArray[0] = argument ?? string.Empty;
                    m_mainMethod.Invoke(m_instance, m_argumentArray);
                }
                else
                {
                    m_mainMethod.Invoke(m_instance, null);
                }
                if (m_echoOutput.Length > 0)
                {
                    retVal = m_echoOutput.ToString();
                }
            }
            catch (TargetInvocationException ex)
            {
                // Since we just had an exception I'm not fussed about using old
                // fashioned string concatenation here. We'll still want the echo
                // output, since its primary purpose is debugging.
                if (m_echoOutput.Length > 0)
                {
                    retVal = m_echoOutput.ToString();
                }
                OnProgramTermination();
                if (ex.InnerException is ScriptOutOfRangeException)
                {
                    retVal += MyTexts.GetString(MySpaceTexts.ProgrammableBlock_Exception_TooComplex);
                }
                else if (ex.InnerException != null)
                {
                    retVal += MyTexts.GetString(MySpaceTexts.ProgrammableBlock_Exception_ExceptionCaught) + ex.InnerException.Message;
                }
            }
            m_isRunning = false;
            return(retVal);
        }
        public ScriptTerminationReason ExecuteCode(string argument, out string response)
        {
            if (m_isRunning)
            {
                response = MyTexts.GetString(MySpaceTexts.ProgrammableBlock_Exception_AllreadyRunning);
                return(ScriptTerminationReason.AlreadyRunning);
            }
            if (m_terminationReason != ScriptTerminationReason.None)
            {
                response = DetailedInfo.ToString();
                return(m_terminationReason);
            }
            DetailedInfo.Clear();
            m_echoOutput.Clear();
            if (m_assembly == null)
            {
                response = MyTexts.GetString(MySpaceTexts.ProgrammableBlock_Exception_NoAssembly);
                return(ScriptTerminationReason.NoScript);
            }
            if (!m_instance.HasMainMethod)
            {
                response = MyTexts.GetString(MySpaceTexts.ProgrammableBlock_Exception_NoMain);
                return(ScriptTerminationReason.NoEntryPoint);
            }
            if (m_previousRunTimestamp == 0)
            {
                m_previousRunTimestamp = Stopwatch.GetTimestamp();
                m_instance.ElapsedTime = TimeSpan.Zero;
            }
            else
            {
                var currentTimestamp = Stopwatch.GetTimestamp();
                var elapsedTime      = (currentTimestamp - m_previousRunTimestamp) * Sync.RelativeSimulationRatio;
                m_instance.ElapsedTime = TimeSpan.FromSeconds(elapsedTime * STOPWATCH_FREQUENCY);
                m_previousRunTimestamp = currentTimestamp;
            }
            var gridGroup      = MyCubeGridGroups.Static.Logical.GetGroup(CubeGrid);
            var terminalSystem = gridGroup.GroupData.TerminalSystem;

            terminalSystem.UpdateGridBlocksOwnership(this.OwnerId);
            m_instance.GridTerminalSystem = terminalSystem;

            m_isRunning = true;
            response    = "";
            try
            {
                using (IlInjector.BeginRunBlock(MAX_NUM_EXECUTED_INSTRUCTIONS, MAX_NUM_METHOD_CALLS))
                {
                    m_instance.Main(argument);
                }
                if (m_echoOutput.Length > 0)
                {
                    response = m_echoOutput.ToString();
                }
            }
            catch (Exception ex)
            {
                // Since we just had an exception I'm not fussed about using old
                // fashioned string concatenation here. We'll still want the echo
                // output, since its primary purpose is debugging.
                if (m_echoOutput.Length > 0)
                {
                    response = m_echoOutput.ToString();
                }
                if (ex is ScriptOutOfRangeException)
                {
                    if (IlInjector.IsWithinRunBlock())
                    {
                        // If we're within a nested run, we don't reset the program, we just pass the error
                        response += MyTexts.GetString(MySpaceTexts.ProgrammableBlock_Exception_NestedTooComplex);
                        return(ScriptTerminationReason.InstructionOverflow);
                    }
                    else
                    {
                        response += MyTexts.GetString(MySpaceTexts.ProgrammableBlock_Exception_TooComplex);
                        OnProgramTermination(ScriptTerminationReason.InstructionOverflow);
                    }
                }
                else
                {
                    response += MyTexts.GetString(MySpaceTexts.ProgrammableBlock_Exception_ExceptionCaught) + ex.Message;
                    OnProgramTermination(ScriptTerminationReason.RuntimeException);
                }
            }
            finally
            {
                m_isRunning = false;
            }
            return(m_terminationReason);
        }
Example #9
0
        public string ExecuteCode(string argument)
        {
            if (m_isRunning)
            {
                return(MyTexts.GetString(MySpaceTexts.ProgrammableBlock_Exception_AllreadyRunning));
            }
            if (m_wasTerminated == true)
            {
                return(DetailedInfo.ToString());
            }
            DetailedInfo.Clear();
            m_echoOutput.Clear();
            if (m_assembly == null)
            {
                return(MyTexts.GetString(MySpaceTexts.ProgrammableBlock_Exception_NoAssembly));
            }
            if (!m_instance.HasMainMethod)
            {
                return(MyTexts.GetString(MySpaceTexts.ProgrammableBlock_Exception_NoMain));
            }
            if (m_previousRunTimestamp == 0)
            {
                m_previousRunTimestamp = Stopwatch.GetTimestamp();
                m_instance.ElapsedTime = TimeSpan.Zero;
            }
            else
            {
                var currentTimestamp = Stopwatch.GetTimestamp();
                var elapsedTime      = (currentTimestamp - m_previousRunTimestamp) * Sync.RelativeSimulationRatio;
                m_instance.ElapsedTime = TimeSpan.FromSeconds(elapsedTime * STOPWATCH_FREQUENCY);
                m_previousRunTimestamp = currentTimestamp;
            }
            var gridGroup      = MyCubeGridGroups.Static.Logical.GetGroup(CubeGrid);
            var terminalSystem = gridGroup.GroupData.TerminalSystem;

            terminalSystem.UpdateGridBlocksOwnership(this.OwnerId);
            m_instance.GridTerminalSystem = terminalSystem;

            m_isRunning = true;
            string retVal = "";

            IlInjector.RestartCountingInstructions(MAX_NUM_EXECUTED_INSTRUCTIONS);
            try
            {
                m_instance.Main(argument);
                if (m_echoOutput.Length > 0)
                {
                    retVal = m_echoOutput.ToString();
                }
            }
            catch (Exception ex)
            {
                // Since we just had an exception I'm not fussed about using old
                // fashioned string concatenation here. We'll still want the echo
                // output, since its primary purpose is debugging.
                if (m_echoOutput.Length > 0)
                {
                    retVal = m_echoOutput.ToString();
                }
                OnProgramTermination();
                if (ex is ScriptOutOfRangeException)
                {
                    retVal += MyTexts.GetString(MySpaceTexts.ProgrammableBlock_Exception_TooComplex);
                }
                else
                {
                    retVal += MyTexts.GetString(MySpaceTexts.ProgrammableBlock_Exception_ExceptionCaught) + ex.Message;
                }
            }
            m_isRunning = false;
            return(retVal);
        }
        public ScriptTerminationReason RunSandboxedProgramAction(Action <ModAPI.IMyGridProgram> action, out string response)
        {
            if (m_isRunning)
            {
                response = MyTexts.GetString(MySpaceTexts.ProgrammableBlock_Exception_AllreadyRunning);
                return(ScriptTerminationReason.AlreadyRunning);
            }
            if (m_terminationReason != ScriptTerminationReason.None)
            {
                response = DetailedInfo.ToString();
                return(m_terminationReason);
            }
            DetailedInfo.Clear();
            m_echoOutput.Clear();
            if (m_assembly == null)
            {
                response = MyTexts.GetString(MySpaceTexts.ProgrammableBlock_Exception_NoAssembly);
                return(ScriptTerminationReason.NoScript);
            }
            var gridGroup      = MyCubeGridGroups.Static.Logical.GetGroup(CubeGrid);
            var terminalSystem = gridGroup.GroupData.TerminalSystem;

            terminalSystem.UpdateGridBlocksOwnership(this.OwnerId);
            m_instance.GridTerminalSystem = terminalSystem;

            m_isRunning = true;
            response    = "";
#if !XB1 // XB1_NOILINJECTOR
            try {
                using (var handle = IlInjector.BeginRunBlock(MAX_NUM_EXECUTED_INSTRUCTIONS, MAX_NUM_METHOD_CALLS)) {
                    m_runtime.InjectorHandle = handle;
                    action(m_instance);
                }
                if (m_echoOutput.Length > 0)
                {
                    response = m_echoOutput.ToString();
                }
                return(m_terminationReason);
            } catch (Exception ex) {
                // Unwrap the exception if necessary
                if (ex is TargetInvocationException)
                {
                    ex = ex.InnerException;
                }

                // Since we just had an exception I'm not fussed about using old
                // fashioned string concatenation here. We'll still want the echo
                // output, since its primary purpose is debugging.
                if (m_echoOutput.Length > 0)
                {
                    response = m_echoOutput.ToString();
                }
                if (ex is ScriptOutOfRangeException)
                {
                    if (IlInjector.IsWithinRunBlock())
                    {
                        // If we're within a nested run, we don't reset the program, we just pass the error
                        response += MyTexts.GetString(MySpaceTexts.ProgrammableBlock_Exception_NestedTooComplex);
                        return(ScriptTerminationReason.InstructionOverflow);
                    }
                    else
                    {
                        response += MyTexts.GetString(MySpaceTexts.ProgrammableBlock_Exception_TooComplex);
                        OnProgramTermination(ScriptTerminationReason.InstructionOverflow);
                    }
                }
                else
                {
                    response += MyTexts.GetString(MySpaceTexts.ProgrammableBlock_Exception_ExceptionCaught) + ex.Message;
                    OnProgramTermination(ScriptTerminationReason.RuntimeException);
                }
                return(m_terminationReason);
            } finally {
                m_runtime.InjectorHandle = null;
                m_isRunning = false;
            }
#else // XB1
            System.Diagnostics.Debug.Assert(false, "No scripts on XB1!");
            return(m_terminationReason);
#endif // XB1
        }