Beispiel #1
0
 public void Dispose()
 {
     foreach (var m in _monitors)
     {
         m.Dispose();
     }
     _monitors.Clear();
     if (_starbound != null)
     {
         _starbound.Dispose();
         _starbound = null;
     }
 }
Beispiel #2
0
        public void Dispose()
        {
            //Dispose all the monitors
            foreach (var m in _monitors)
            {
                m.Dispose();
            }
            _monitors.Clear();

            //Force the server to close.
            if (_starbound != null)
            {
                _starbound.Dispose();
                _starbound = null;
            }
        }
Beispiel #3
0
        /// <summary>
        /// Runs the server, reading its input until its closed.
        /// </summary>
        /// <returns></returns>
        public async Task Run(System.Threading.CancellationToken cancellationToken)
        {
            //Make sure path exists
            string path = Path.Combine(WorkingDirectory, ExecutableName);

            if (!File.Exists(path))
            {
                Logger.LogError("Cannot start server as the executable '{0}' does not exist", path);
                return;
            }

            //Load the settings
            Logger.Log("Loading Settings...");

            //Make sure the configuration is valid
            if (!await Configurator.TryLoadAsync())
            {
                Logger.LogError("Cannot start server as the configuration is invalid, make sure you -import before use. see documentation for reference.", ConfigurationFile);
                return;
            }

            //Update the start time statistics.
            StartTime = DateTime.UtcNow;

            //Invoke the start event
            foreach (var m in _monitors)
            {
                try
                {
                    Logger.Log("OnServerPreStart :: {0}", m.Name);
                    await m.OnServerPreStart();
                }
                catch (Exception e)
                {
                    Logger.LogError(e, "OnServerStart ERR :: " + m.Name + " :: {0}");
                }
            }

            //Saving the settings
            Logger.Log("Saving Settings before launch...");
            await SaveConfigurationAsync();

            #region Process Handling

            //Destroy the rcon reference. We will replace it with a new one later.
            Rcon = null;

            if (_starbound != null)
            {
                Logger.Log("Cleaning up old process");
                await _starbound.StopAsync();

                _starbound.Dispose();
            }

            //Start the process
            _terminate         = false;
            _starbound         = new SBProcess(path, WorkingDirectory, Logger.Child("SB"));
            _starbound.Exited += async() =>
            {
                Logger.Log("SB Process has exited!");

                //Tell us to terminate
                _terminate = true;

                //Validate the shutdown message, setting default if there isnt one
                LastShutdownReason = LastShutdownReason ?? "Server closed for unkown reason";
                foreach (var m in _monitors)
                {
                    try
                    {
                        Logger.Log("OnServerExit {0}", m.Name);
                        await m.OnServerExit(LastShutdownReason);
                    }
                    catch (Exception e)
                    {
                        Logger.LogError(e, "OnServerExit ERR - " + m.Name + ": {0}");
                    }
                }
            };

            Logger.Log("Staring Starbound Process");
            LastShutdownReason = null;
            _starbound.Start();

            //Try and initialize the rcon.
            if (Configurator.RconServerPort > 0)
            {
                Rcon = new Rcon.StarboundRconClient(this);
                OnRconClientCreated?.Invoke(this, Rcon);
                Logger.Log("Created RCON Client.");
            }


            #region Invoke the start event
            foreach (var m in _monitors)
            {
                try
                {
                    Logger.Log("OnServerStart :: {0}", m.Name);
                    await m.OnServerStart();
                }
                catch (Exception e)
                {
                    Logger.LogError(e, "OnServerStart ERR :: " + m.Name + " :: {0}");
                }
            }
            #endregion

            try
            {
                //Handle the messages
                Logger.Log("Handling Messages");

                while (!_terminate && !cancellationToken.IsCancellationRequested)
                {
                    string[] logs = await _starbound.ReadStandardOutputAsync();

                    foreach (var l in logs)
                    {
                        _terminate = await ProcessLine(l);

                        if (_terminate)
                        {
                            break;
                        }
                    }

                    //wait some tiny amount of time
                    await Task.Delay(100, cancellationToken);
                }

                //We have exited the loop, probably because we have been terminated
                Logger.Log("Left the read loop");
            }
            catch (Exception e)
            {
                Logger.LogError(e, "CRITICAL ERROR IN RUNTIME: {0}");
                LastShutdownReason = "Critical Error: " + e.Message + "\n" + e.StackTrace;
            }
            #endregion

            //We have terminated, so dispose of us properly
            Logger.Log("Attempting to terminate process just in case of internal error.");
            await _starbound.StopAsync();

            Logger.Log("Terminated Succesfully, disposing");
            _starbound.Dispose();
            _starbound = null;
        }