예제 #1
0
        private void CheckForBinCopyFile()
        {
            if (string.IsNullOrEmpty(CurrentConfig.Current.PathToModHost))
            {
                return;
            }

            var BinHostFilename = Path.Combine(Path.Combine(
                                                   Path.GetDirectoryName(Assembly.GetAssembly(GetType()).Location),
                                                   Path.GetDirectoryName(CurrentConfig.Current.PathToModHost)),
                                               Path.GetFileNameWithoutExtension(CurrentConfig.Current.PathToModHost) + ".bin"
                                               );

            var HostFilename = Path.Combine(
                Path.GetDirectoryName(Assembly.GetAssembly(GetType()).Location),
                CurrentConfig.Current.PathToModHost);

            if (!File.Exists(BinHostFilename))
            {
                return;
            }

            try{ File.Delete(HostFilename); }
            catch (Exception Error) { GameAPI.Console_Write($"CheckForBinCopyFile: delete {HostFilename} => {Error}"); }

            try { File.Move(BinHostFilename, HostFilename); }
            catch (Exception Error) { GameAPI.Console_Write($"CheckForBinCopyFile: move {BinHostFilename} -> {HostFilename} => {Error}"); }
        }
        private void CreateHostProcess(string HostFilename)
        {
            try
            {
                mHostProcess = new Process
                {
                    StartInfo = new ProcessStartInfo(HostFilename)
                    {
                        UseShellExecute  = CurrentConfig.Current.WithShellWindow,
                        CreateNoWindow   = true,
                        WorkingDirectory = ProgramPath,
                        Arguments        = Environment.GetCommandLineArgs().Aggregate(
                            $"-EmpyrionToModPipe {CurrentConfig.Current.EmpyrionToModPipeName} -ModToEmpyrionPipe {CurrentConfig.Current.ModToEmpyrionPipeName}",
                            (C, A) => C + " " + A),
                    }
                };

                mHostProcess.Start();
                CurrentConfig.Current.HostProcessId = mHostProcess.Id;
                GameAPI.Console_Write($"ModClientDll: host started '{HostFilename}/{mHostProcess.Id}'");
            }
            catch (Exception Error)
            {
                GameAPI.Console_Write($"ModClientDll: host start error '{HostFilename} -> {Error}'");
                mHostProcess = null;
            }
        }
예제 #3
0
    public static void Handle_chat_message(ChatInfo data)
    {
        AlertMessage($"chat message {data.type}");
        GameAPI.Console_Write($"chat message {data.type}");
        if (data.type != 3)
        {
            return;
        }
        var handled = false;


        foreach (var item in chatCommandActions)
        {
            var r     = new Regex(item.Key);
            var match = r.Match(data.msg);

            if (!match.Success)
            {
                continue;
            }

            var content = match.Groups.Count > 0 ? match.Groups[1].ToString() : "";
            item.Value.Invoke(new PString(content));
            handled = true;
        }
    }
예제 #4
0
        private void StartHostProcess()
        {
            var HostFilename = Path.Combine(Path.GetDirectoryName(Assembly.GetAssembly(GetType()).Location), CurrentConfig.Current.PathToModHost);

            GameAPI.Console_Write($"ModClientDll: start host '{HostFilename}'");
            mHostProcessAlive = null;

            if (CurrentConfig.Current.HostProcessId != 0)
            {
                try
                {
                    mHostProcess = Process.GetProcessById(CurrentConfig.Current.HostProcessId);
                    if (mHostProcess.MainWindowTitle != HostFilename)
                    {
                        mHostProcess = null;
                    }
                }
                catch (Exception)
                {
                    mHostProcess = null;
                }
            }

            if (mHostProcess == null && CurrentConfig.Current.AutostartModHost && !string.IsNullOrEmpty(CurrentConfig.Current.PathToModHost))
            {
                if (!ExistsStopFile())
                {
                    CreateHostProcess(HostFilename);
                }
            }
        }
예제 #5
0
        private void CreateHostProcess(string HostFilename)
        {
            try
            {
                mHostProcess = new Process
                {
                    StartInfo = new ProcessStartInfo(HostFilename)
                    {
                        UseShellExecute  = CurrentConfig.Current.WithShellWindow,
                        LoadUserProfile  = true,
                        CreateNoWindow   = true,
                        WindowStyle      = ProcessWindowStyle.Hidden,
                        WorkingDirectory = Path.GetDirectoryName(HostFilename),
                        Arguments        = Environment.GetCommandLineArgs().Aggregate(
                            $"-EmpyrionToModPipe {CurrentConfig.Current.EmpyrionToModPipeName} " +
                            $"-ModToEmpyrionPipe {CurrentConfig.Current.ModToEmpyrionPipeName} " +
                            $"-GameDir \"{ProgramPath}\"",
                            (C, A) => C + " " + A) +
                                           (CurrentConfig.Current.AdditionalArguments == null ? "" : " " + CurrentConfig.Current.AdditionalArguments),
                    }
                };

                mHostProcess.Start();
                CurrentConfig.Current.HostProcessId = mHostProcess.Id;
                CurrentConfig.Save();
                GameAPI.Console_Write($"ModClientDll: host started '{HostFilename}/{mHostProcess.Id}'");
            }
            catch (Exception Error)
            {
                GameAPI.Console_Write($"ModClientDll: host start error '{HostFilename} -> {Error}'");
                mHostProcess = null;
            }
        }
        public void Game_Exit()
        {
            Exit = true;
            GameAPI.Console_Write($"ModClientDll: Game_Exit {CurrentConfig.Current.ModToEmpyrionPipeName}");
            OutServer?.SendMessage(new ClientHostComData()
            {
                Command = ClientHostCommand.Game_Exit
            });

            if (!ExposeShutdownHost && CurrentConfig.Current.AutoshutdownModHost && mHostProcess != null)
            {
                try
                {
                    try { mHostProcess.CloseMainWindow(); } catch { }
                    CurrentConfig.Current.HostProcessId = 0;
                    CurrentConfig.Save();

                    Thread.Sleep(1000);
                }
                catch (Exception Error)
                {
                    GameAPI.Console_Write($"ModClientDll: Game_Exit {Error}");
                }
            }

            InServer?.Close();
            OutServer?.Close();
        }
예제 #7
0
        private void LoadAssembly(string aFileName)
        {
            try
            {
                var ModFilename = Path.Combine(Path.GetDirectoryName(Assembly.GetAssembly(GetType()).Location), aFileName);

                GameAPI.Console_Write($"ModDispatcher: load {ModFilename}");
                var Mod     = Assembly.LoadFile(ModFilename);
                var ModType = Mod.GetTypes().Where(T => T.GetInterfaces().Contains(typeof(ModInterface))).FirstOrDefault();
                if (ModType != null)
                {
                    var ModInstance = Activator.CreateInstance(ModType) as ModInterface;
                    mModInstance.Add(ModInstance);
                    GameAPI.Console_Write($"ModDispatcher: loaded {ModFilename}");
                }
                else
                {
                    GameAPI.Console_Write($"ModDispatcher: no ModInterface class found");
                }
            }
            catch (ReflectionTypeLoadException Error)
            {
                GameAPI.Console_Write($"ModDispatcher: {aFileName} -> {Error}");
                Array.ForEach(Error.LoaderExceptions, E => GameAPI.Console_Write($"ModDispatcher: {aFileName} -> LE:{E}"));
            }
            catch (Exception Error)
            {
                GameAPI.Console_Write($"ModDispatcher: {aFileName} -> {Error}");
            }
        }
예제 #8
0
        private Assembly TryLoadAssembly(string aAssembly)
        {
            try{
                var Result = Assembly.LoadFile(aAssembly);
                if (Result == null)
                {
                    return(Result);
                }
            }
            catch {}

            string CurrentDir = null;

            try
            {
                CurrentDir = Directory.GetCurrentDirectory();
                GameAPI.Console_Write($"Try load within: {CurrentDir} -> {Path.GetDirectoryName(aAssembly)}");
                Directory.SetCurrentDirectory(Path.GetDirectoryName(aAssembly));
                return(Assembly.LoadFile(aAssembly));
            }
            finally
            {
                Directory.SetCurrentDirectory(CurrentDir);
            }
        }
        private void HandleModCommunication(ModComData msg)
        {
            if (OutServer == null)
            {
                return;
            }

            try
            {
                switch (msg.Command)
                {
                case ModCommand.GetPathFor: OutServer.SendMessage(new ModComData()
                    {
                        Command = msg.Command, SequenceId = msg.SequenceId, Data = ModAPI.Application.GetPathFor((AppFolder)msg.Data)
                    }); break;

                case ModCommand.PlayfieldDataReceived:
                {
                    var data = msg.Data as PlayfieldNetworkData;
                    ModAPI.Network.SendToPlayfieldServer(data.Sender, data.PlayfieldName, data.Data);
                    break;
                }
                }
            }
            catch (System.Exception Error)
            {
                GameAPI.Console_Write($"ModClientDll: {Error.Message}");
            }
        }
예제 #10
0
    private static void remoteExecCommand(PString pstr)
    {
        PString outCmd = new PString($"remoteex {pstr.pstr}");

        GameAPI.Game_Request(CmdId.Request_ConsoleCommand, 0, outCmd);
        GameAPI.Console_Write($"remoteex: {outCmd.ToString()}");
        GameAPI.Game_Request(CmdId.Request_ConsoleCommand, 0, new Eleon.Modding.PString("SAY 'remote exex command'"));
    }
예제 #11
0
        void CheckHostProcess()
        {
            if (Exit || WithinUpdate)
            {
                return;
            }

            if (!ExistsStartFile())
            {
                try
                {
                    if (mHostProcess != null && !mHostProcess.HasExited)
                    {
                        GameAPI.Console_Write($"ModClientDll: start.txt not found");

                        OutServer?.SendMessage(new ClientHostComData()
                        {
                            Command = ClientHostCommand.Game_Exit
                        });
                        Thread.Sleep(1000);

                        GameAPI.Console_Write($"ModClientDll: stopped");
                    }
                }
                catch { }

                return;
            }

            try{ OutServer?.SendMessage(new ClientHostComData()
                {
                    Command = ClientHostCommand.ProcessInformation
                }); } catch {}

            if (CurrentConfig.Current.AutostartModHostAfterNSeconds == 0 || !CurrentConfig.Current.AutostartModHost)
            {
                return;
            }
            try { if (mHostProcess != null && !mHostProcess.HasExited)
                  {
                      return;
                  }
            } catch { }

            if (!mHostProcessAlive.HasValue)
            {
                mHostProcessAlive = DateTime.Now;
            }
            if ((DateTime.Now - mHostProcessAlive.Value).TotalSeconds <= CurrentConfig.Current.AutostartModHostAfterNSeconds)
            {
                return;
            }

            mHostProcessAlive = null;

            CheckForBinCopyFile();
            StartHostProcess();
        }
예제 #12
0
        void CheckHostProcess()
        {
            if (Exit)
            {
                return;
            }

            if (ExistsStopFile())
            {
                try
                {
                    if (mHostProcess != null && !mHostProcess.HasExited)
                    {
                        GameAPI.Console_Write($"ModClientDll: stop.txt found");

                        OutServer?.SendMessage(new ClientHostComData()
                        {
                            Command = ClientHostCommand.Game_Exit
                        });
                        Thread.Sleep(1000);

                        InServer?.Close();
                        OutServer?.Close();

                        GameAPI.Console_Write($"ModClientDll: stopped");
                    }
                }
                catch { }

                return;
            }

            if (CurrentConfig.Current.AutostartModHostAfterNSeconds == 0 || !CurrentConfig.Current.AutostartModHost)
            {
                return;
            }
            try { if (mHostProcess != null && !mHostProcess.HasExited)
                  {
                      return;
                  }
            } catch { }

            if (!mHostProcessAlive.HasValue)
            {
                mHostProcessAlive = DateTime.Now;
            }
            if ((DateTime.Now - mHostProcessAlive.Value).TotalSeconds <= CurrentConfig.Current.AutostartModHostAfterNSeconds)
            {
                return;
            }

            mHostProcessAlive = null;

            StartModToEmpyrionPipe();
            StartHostProcess();
            StartEmpyrionToModPipe();
        }
예제 #13
0
        private void UpdateEWA(ProcessInformation aProcessInformation)
        {
            if (!Directory.Exists(Path.Combine(EmpyrionConfiguration.ModPath, @"EWALoader\Update\EWALoader\EWA")))
            {
                return;
            }

            try
            {
                WithinUpdate = true;
                RetrieveHostProcessInformation(aProcessInformation);

                GameAPI.Console_Write($"ModClientDll: EWA_Update");
                OutServer?.SendMessage(new ClientHostComData()
                {
                    Command = ClientHostCommand.UpdateEWA
                });

                if (mHostProcess != null)
                {
                    try
                    {
                        mHostProcessAlive = null;

                        for (int i = 0; i < 5 * 60; i++)
                        {
                            Thread.Sleep(1000);
                            if (mHostProcess.HasExited)
                            {
                                break;
                            }
                        }

                        try { mHostProcess.CloseMainWindow(); } catch { }

                        mHostProcess = null;
                        CurrentConfig.Current.HostProcessId = 0;
                        CurrentConfig.Save();
                    }
                    catch (Exception Error)
                    {
                        GameAPI.Console_Write($"UpdateEWA: Game_Exit {Error}");
                    }
                }

                UpdateEWAFiles();
            }
            catch (Exception Error)
            {
                GameAPI.Console_Write($"UpdateEWA: EWA_Update {Error}");
            }
            finally
            {
                WithinUpdate = false;
            }
        }
예제 #14
0
 private async Task SaveApiCall(Action aCall, ModInterface aMod, string aErrorInfo)
 {
     try
     {
         await Task.Run(aCall);
     }
     catch (Exception Error)
     {
         GameAPI.Console_Write($"Exception [{aMod}] {aErrorInfo} => {Error}");
     }
 }
        private void HandleClientHostCommunication(ClientHostComData aMsg)
        {
            switch (aMsg.Command)
            {
            case ClientHostCommand.RestartHost: break;

            case ClientHostCommand.ExposeShutdownHost: ExposeShutdownHost = true; break;

            case ClientHostCommand.Console_Write: GameAPI.Console_Write(aMsg.Data as string); break;
            }
        }
예제 #16
0
        private void LoadAssembly(string aFileName)
        {
            CurrentModFile = aFileName;
            AppDomain.CurrentDomain.AssemblyResolve += ModResolveEventHandler;
            string CurrentDirectory = Directory.GetCurrentDirectory();

            try
            {
                var ModFilename = Path.Combine(Path.GetDirectoryName(Assembly.GetAssembly(GetType()).Location), aFileName);

                GameAPI.Console_Write($"ModDispatcher: load {ModFilename} CurrentDir{CurrentDirectory} ProgDir:{ProgramPath}");
                Assembly Mod = TryLoadAssembly(ModFilename);

                var ModType = Mod.GetTypes().Where(T => T.GetInterfaces().Contains(typeof(ModInterface))).FirstOrDefault();
                if (ModType != null)
                {
                    Directory.SetCurrentDirectory(ProgramPath);
                    var ModInstance = Activator.CreateInstance(ModType) as ModInterface;
                    mModInstance.Add(ModInstance);
                    GameAPI.Console_Write($"ModDispatcher: loaded {ModFilename}");
                }
                else
                {
                    ModType = Mod.GetTypes().Where(T => T.GetInterfaces().Any(I => I.FullName.Contains(nameof(ModInterface)))).FirstOrDefault();
                    if (ModType != null)
                    {
                        GameAPI.Console_Write($"ModDispatcher: no class implements: {typeof(ModInterface).AssemblyQualifiedName}\n" +
                                              ModType.GetInterfaces()?.Aggregate("", (S, I) => S + I.AssemblyQualifiedName + "\n") +
                                              ModType.GetMethods()?.Aggregate("", (S, M) => S + M.Name + "\n"));
                    }
                    else
                    {
                        GameAPI.Console_Write($"ModDispatcher: no ModInterface class found: " +
                                              Mod.GetTypes().Aggregate("", (S, T) => S + T.FullName + ":" + T.GetInterfaces()?.Aggregate("", (SS, I) => SS + I.FullName) + "\n"));
                    }
                }
            }
            catch (ReflectionTypeLoadException Error)
            {
                GameAPI.Console_Write($"ModDispatcher: {aFileName} -> {Error}");
                Array.ForEach(Error.LoaderExceptions, E => GameAPI.Console_Write($"ModDispatcher: {aFileName} -> LE:{E}"));
            }
            catch (Exception Error)
            {
                GameAPI.Console_Write($"ModDispatcher: {aFileName} -> {Error}");
            }
            finally
            {
                Directory.SetCurrentDirectory(CurrentDirectory);
            }

            AppDomain.CurrentDomain.AssemblyResolve -= ModResolveEventHandler;
        }
예제 #17
0
        private void RetrieveHostProcessInformation(ProcessInformation aData)
        {
            if (aData == null)
            {
                return;
            }

            if (CurrentConfig.Current.HostProcessId != aData.Id)
            {
                GameAPI.Console_Write($"HostProcessId: " + aData.Id);
            }
            CurrentConfig.Current.HostProcessId = aData.Id;
            try{ mHostProcess = Process.GetProcessById(CurrentConfig.Current.HostProcessId); } catch (Exception) {}
        }
예제 #18
0
 private void StartEmpyrionToModPipe()
 {
     try
     {
         try { OutServer?.Close(); } catch { }
         Thread.Sleep(1000);
         OutServer = new ClientMessagePipe(CurrentConfig.Current.EmpyrionToModPipeName)
         {
             log = GameAPI.Console_Write
         };
     }
     catch (Exception Error)
     {
         GameAPI.Console_Write($"ModClientDll: ClientMessagePipe '{CurrentConfig.Current.EmpyrionToModPipeName} -> {Error}'");
     }
 }
예제 #19
0
        private void StartModToEmpyrionPipe()
        {
            GameAPI.Console_Write($"StartModToEmpyrionPipe: start {CurrentConfig.Current.ModToEmpyrionPipeName}");
            try { InServer?.Close(); } catch { }
            Thread.Sleep(1000);

            InServer = new ServerMessagePipe(CurrentConfig.Current.ModToEmpyrionPipeName)
            {
                log = GameAPI.Console_Write
            };
            InServer.Callback = Msg => {
                if (InServerMessageHandler.TryGetValue(Msg.GetType(), out Action <object> Handler))
                {
                    Handler(Msg);
                }
            };

            GameAPI.Console_Write($"StartModToEmpyrionPipe: startet {CurrentConfig.Current.ModToEmpyrionPipeName}");
        }
예제 #20
0
    private static void testBroker(PString pstr)
    {
        GameAPI.Console_Write($"**** executing broker test");
        var cmd = new APICmd(CmdId.Request_ConsoleCommand, new Eleon.Modding.PString("SAY 'broker test'"));


        broker.HandleCall <object>(cmd, (x, y) => {
            switch (x)
            {
            case CmdId.Event_Ok:
                GameAPI.Console_Write("test successful");
                break;

            case CmdId.Event_Error:
                GameAPI.Console_Write("test error");
                break;
            }
        });
    }
        public void Game_Event(CmdId eventId, ushort seqNr, object data)
        {
            if (OutServer == null)
            {
                return;
            }

            try
            {
                var msg = new EmpyrionGameEventData()
                {
                    eventId = eventId, seqNr = seqNr
                };
                msg.SetEmpyrionObject(data);
                OutServer.SendMessage(msg);
            }
            catch (System.Exception Error)
            {
                GameAPI.Console_Write($"ModClientDll: {Error.Message}");
            }
        }
예제 #22
0
        public void Game_Event(CmdId eventId, ushort seqNr, object data)
        {
            if (OutServer == null)
            {
                return;
            }

            try
            {
                //GameAPI.Console_Write($"ModClientDll: eventId:{eventId} seqNr:{seqNr} data:{data}");
                OutServer.SendMessage(new EmpyrionGameEventData()
                {
                    eventId = eventId, seqNr = seqNr, data = data
                });
                //GameAPI.Console_Write($"ModClientDll: send");
            }
            catch (System.Exception Error)
            {
                GameAPI.Console_Write($"ModClientDll: {Error.Message}");
            }
        }
예제 #23
0
        private void HandleClientHostCommunication(ClientHostComData aMsg)
        {
            switch (aMsg.Command)
            {
            case ClientHostCommand.RestartHost: break;

            case ClientHostCommand.ExposeShutdownHost: ExposeShutdownHost = true; break;

            case ClientHostCommand.Console_Write: GameAPI.Console_Write(aMsg.Data as string); break;

            case ClientHostCommand.ProcessInformation: if (aMsg.Data == null)
                {
                    ReturnProcessInformation();
                }
                else
                {
                    RetrieveHostProcessInformation(aMsg.Data as ProcessInformation);
                }
                break;

            case ClientHostCommand.UpdateEWA: new Thread(() => UpdateEWA(aMsg.Data as ProcessInformation)).Start(); break;
            }
        }
예제 #24
0
        private Assembly ModResolveEventHandler(object aSender, ResolveEventArgs aArgs)
        {
            var Delimitter = aArgs.Name.IndexOf(',');
            var ModPath    = Path.Combine(
                Path.GetDirectoryName(Assembly.GetAssembly(GetType()).Location),
                Path.GetDirectoryName(CurrentModFile),
                (Delimitter > 0 ? aArgs.Name.Substring(0, Delimitter) : aArgs.Name) + ".dll");

            GameAPI.Console_Write($"ModResolveEventHandler1: {ModPath}");
            if (File.Exists(ModPath))
            {
                return(Assembly.LoadFrom(ModPath));
            }

            ModPath = Path.Combine(ProgramPath, @"DedicatedServer\EmpyrionDedicated_Data\Managed", Path.GetFileName(ModPath));
            GameAPI.Console_Write($"ModResolveEventHandler2: {ModPath}");
            if (File.Exists(ModPath))
            {
                return(Assembly.LoadFrom(ModPath));
            }

            throw new FileNotFoundException("Assembly not found", ModPath);
        }
예제 #25
0
        private async Task SafeApiCall(Action aCall, ModInterface aMod, string aErrorInfo)
        {
            try
            {
                void SafeCall()
                {
                    try
                    {
                        aCall();
                    }
                    catch (Exception error)
                    {
                        GameAPI.Console_Write($"Exception [{aMod}] {aErrorInfo} => {error}");
                    }
                }

                await Task.Run(() => SafeCall());
            }
            catch (Exception Error)
            {
                GameAPI.Console_Write($"Exception [{aMod}] {aErrorInfo} => {Error}");
            }
        }
예제 #26
0
        private void UpdateEWAFiles()
        {
            try
            {
                if (Directory.Exists(Path.Combine(EmpyrionConfiguration.ModPath, @"EWALoader\EWA.bak")))
                {
                    Directory.Delete(Path.Combine(EmpyrionConfiguration.ModPath, @"EWALoader\EWA.bak"), true);
                }

                Directory.Move(
                    Path.Combine(EmpyrionConfiguration.ModPath, @"EWALoader\EWA"),
                    Path.Combine(EmpyrionConfiguration.ModPath, @"EWALoader\EWA.bak")
                    );

                Directory.Move(
                    Path.Combine(EmpyrionConfiguration.ModPath, @"EWALoader\Update\EWALoader\EWA"),
                    Path.Combine(EmpyrionConfiguration.ModPath, @"EWALoader\EWA")
                    );
            }
            catch (Exception Error)
            {
                GameAPI.Console_Write($"UpdateEWA: Update {Error}");
            }
        }
예제 #27
0
 private static void getStructures()
 {
     GameAPI.Console_Write("Structures Requested");
     GameAPI.Game_Request(CmdId.Request_GlobalStructure_List, 0, null);
 }
예제 #28
0
 private static void execConsoleCommand(PString command)
 {
     GameAPI.Game_Request(CmdId.Request_ConsoleCommand, 0, command);
     GameAPI.Console_Write($"text: {command.pstr}");
     GameAPI.Game_Request(CmdId.Request_ConsoleCommand, 0, new Eleon.Modding.PString("SAY 'remote command'"));
 }
예제 #29
0
 private static void requestPlayfieldStats(PString pstr)
 {
     GameAPI.Console_Write($"**** requesting stats for: {pstr.pstr}");
     GameAPI.Game_Request(CmdId.Request_Playfield_Stats, 0, pstr);
     GameAPI.Game_Request(CmdId.Request_ConsoleCommand, 0, new Eleon.Modding.PString("SAY 'requesting playfield stats'"));
 }