Intercept console interrupt and handle nicely

Long ago in the early days of TShock someone asked why CTRL + C wasn't
handled and there was an explanation given along the lines of "something
something not supported on mono something something" or similar.
Attempts were made to try to handle console interrupts unsuccessfully
and the code was ripped out.

However, it's 2021, and we can now handle this signal and do the right
thing (which, ostensibly, is to save the world and shut down). Many
people like me reflexively hit CTRL + C because they want to shut down
the process. It's very infuriating that the current behavior results in
the server just dying and nothing being cleaned up properly.

Therefore, this commit changes the behavior to handle the interrupt,
save the world, and shut down nicely.

(If you still want to shutdown without saving the world, use off-nosave,
or idk, send SIGKILL).
This commit is contained in:
Lucas Nicodemus 2021-06-12 12:18:55 -07:00
parent 933c5f9e49
commit 34da464bab
2 changed files with 17 additions and 0 deletions

View file

@ -214,6 +214,8 @@ namespace TShockAPI
TerrariaApi.Reporting.CrashReporter.HeapshotRequesting += CrashReporter_HeapshotRequesting;
Console.CancelKeyPress += new ConsoleCancelEventHandler(ConsoleCancelHandler);
try
{
CliParser.Reset();
@ -638,6 +640,20 @@ namespace TShockAPI
}
}
/// <summary> ConsoleCancelHandler - Handles when Ctrl + C is sent to the server for a safe shutdown. </summary>
/// <param name="sender">The sender</param>
/// <param name="args">The ConsoleCancelEventArgs associated with the event.</param>
private void ConsoleCancelHandler(object sender, ConsoleCancelEventArgs args)
{
// Cancel the default behavior
args.Cancel = true;
Log.ConsoleInfo("Interrupt received. Saving the world and shutting down.");
// Perform a safe shutdown
TShock.Utils.StopServer(true, "Server console interrupted!");
}
/// <summary>HandleCommandLine - Handles the command line parameters passed to the server.</summary>
/// <param name="parms">parms - The array of arguments passed in through the command line.</param>
private void HandleCommandLine(string[] parms)