Exemple #1
0
        private void BroadcastReport(DisagreementCrashReport report)
        {
            if (report == null)
            {
                return;
            }

            //Abort and giveup
            //Send a API log to the error
            Server.ApiHandler.BroadcastRoute((gateway) =>
            {
                if (gateway.Authentication.AuthLevel < API.AuthLevel.Admin)
                {
                    return(null);
                }
                return(report);
            }, "OnWorldThreadException");
        }
Exemple #2
0
        public override async Task <bool> HandleMessage(Message msg)
        {
            if (msg.Level != Message.LogLevel.Error)
            {
                return(false);
            }

            //Prepare the report
            DisagreementCrashReport report = null;

            try
            {
                if (msg.Content.StartsWith(ERROR_MESSAGE))
                {
                    //Attempt to find the person
                    var coloni    = msg.Content.IndexOf(':');
                    var client    = msg.Content.Cut(ERROR_MESSAGE.Length + 1, coloni);
                    var exception = msg.Content.Substring(coloni);
                    report = new DisagreementCrashReport()
                    {
                        Content = msg.ToString(), Exception = exception.Trim()
                    };

                    //Locate the player just for the sake of reporting
                    if (int.TryParse(client, out var cid))
                    {
                        report.Player = Server.Connections.GetPlayer(cid);
                    }

                    //If we are an IO exception, throw.
                    if (report.Exception.Contains("(IOException)"))
                    {
                        throw new ServerShutdownException("World Thread Exception - IO Exception");
                    }

                    /* Don't do any of this. We want to leave the palyer as is. They can go free.
                     * //Parse the name
                     * if (int.TryParse(client, out var cid))
                     * {
                     *  //Find the player
                     *  report.Player = Server.Connections.GetPlayer(cid);
                     *  if (report.Player == null)
                     *  {
                     *      Logger.LogWarning("Could not find the person we were holding accountable! Using last person instead.");
                     *      report.Player = Server.Connections.LastestPlayer;
                     *  }
                     *
                     *  //If we have a player, we need to determine best course of action
                     *  if (report.Player != null)
                     *  {
                     *      //World thread exception caught
                     *      if (report.Exception.Contains("(MapException) Key "))
                     *      {
                     *          //Ban the player
                     *          await report.Player.Ban(BanFormat.Replace("{exception}", report.Exception), "World Thread Monitor");
                     *
                     *          //Send the report
                     *          throw new ServerShutdownException("World Thread Exception - Key Crash");
                     *      }
                     *
                     *      if (report.Exception.Contains("(IOException)"))
                     *          throw new ServerShutdownException("World Thread Exception - IO Exception");
                     *
                     *      //Regular exception caught, just kick the player and return early so we don't process the other reboot logic
                     *      await report.Player.Kick(KickFormat.Replace("{kick}", report.Exception));
                     *      return false;
                     *  }
                     * }
                     * else
                     * {
                     *  //We didn't parse anything?
                     *  Logger.LogWarning("Failed to parse the client " + client + ", giving up and just aborting.");
                     * }
                     *
                     * //We have no user crashing us, so we will throw a general exception to get the server to reboot
                     * throw new ServerShutdownException("World Thread Exception - General Error");
                     */
                }
            }
            catch (Exception e)
            {
                //Our logic threw an exception, most likely a ServerShutdownException. Lets abort and restart the server.
                Logger.LogError(e);
                Server.LastShutdownReason = $"Disagreement Shutdown ({e.GetType().Name}): {e.Message}\n" + e.StackTrace;
                return(true);
            }
            finally
            {
                //Broadcast the report if it isn't null
                if (report != null)
                {
                    BroadcastReport(report);
                }
            }

            //We don't want to restart.
            return(false);
        }