Force shutdown server if SIGINT is received twice

Previously, I updated the SIGINT handler so that it would safely shut
down. This is because I'm an idiot and like most people like me, I use
CTRL + C as my exclusive way to close all programs in the command line
environment. This poses a risk because it doesn't save the world and
shuts down improperly.

However, I forgot that Terraria has interactive menus that you can't
exit from. So, in these menus, the only way out was CTRL + C. @Onusai
reported this, so this changes the behavior a second time.

Now, when passing SIGINT, you can pass it twice. This will cause the
program to actually exit on the second time, such as when you're stuck
at a menu. Hooray.
This commit is contained in:
Lucas Nicodemus 2021-11-25 11:06:31 -08:00
parent 58bc876eab
commit 996229b9af
2 changed files with 11 additions and 2 deletions

View file

@ -13,7 +13,7 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin
* If there is no section called "Upcoming changes" below this line, please add one with `## Upcoming changes` as the first line, and then a bulleted item directly after with the first change.
## Upcoming changes
* Hopefully not another Terraria version for a few days.
* Changed the server behavior when `SIGINT` is received. When `SIGINT` is trapped, the server will attempt to shut down safely. When it is trapped a second time in a session, it will immediately exit. (`SIGINT` is typically triggered via CTRL + C.) This means that it is possible to corrupt your world if you force shutdown at the wrong time (e.g., while the world is saving), but hopefully you expect this to happen if you hit CTRL + C twice in a session and you read the warning. (@hakusaro, @Onusai)
## TShock 4.5.9
* Added the ability to change a `TSPlayer`'s PVP mode. (@AgaSpace)

View file

@ -640,15 +640,24 @@ namespace TShockAPI
}
}
private bool tryingToShutdown = false;
/// <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)
{
if (tryingToShutdown)
{
System.Environment.Exit(1);
return;
}
// Cancel the default behavior
args.Cancel = true;
Log.ConsoleInfo("Interrupt received. Saving the world and shutting down.");
tryingToShutdown = true;
Log.ConsoleInfo("Shutting down safely. To force shutdown, send SIGINT (CTRL + C) again.");
// Perform a safe shutdown
TShock.Utils.StopServer(true, "Server console interrupted!");