Added some terminal interrupt systems. Later it will kill active commands.
This commit is contained in:
parent
51f58e6e82
commit
5412b023a0
@ -3,6 +3,7 @@ global using SharpCompress.Archives.Rar;
|
|||||||
global using SharpCompress.Archives.SevenZip;
|
global using SharpCompress.Archives.SevenZip;
|
||||||
global using SharpCompress.Readers;
|
global using SharpCompress.Readers;
|
||||||
global using SrcMod.Shell;
|
global using SrcMod.Shell;
|
||||||
|
global using SrcMod.Shell.Interop;
|
||||||
global using SrcMod.Shell.Modules.ObjectModels;
|
global using SrcMod.Shell.Modules.ObjectModels;
|
||||||
global using System;
|
global using System;
|
||||||
global using System.Collections.Generic;
|
global using System.Collections.Generic;
|
||||||
|
|||||||
25
SrcMod/Shell/Interop/Winmm.cs
Normal file
25
SrcMod/Shell/Interop/Winmm.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
namespace SrcMod.Shell.Interop;
|
||||||
|
|
||||||
|
internal static partial class Winmm
|
||||||
|
{
|
||||||
|
[LibraryImport("winmm.dll")]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
public static partial bool PlaySound([MarshalAs(UnmanagedType.LPStr)] string pszSound, nint hMod, uint fdwSound);
|
||||||
|
|
||||||
|
public enum PlaySoundFlags : uint
|
||||||
|
{
|
||||||
|
SND_SYNC = 0x00000000,
|
||||||
|
SND_ASYNC = 0x00000001,
|
||||||
|
SND_NODEFAULT = 0x00000002,
|
||||||
|
SND_MEMORY = 0x00000004,
|
||||||
|
SND_LOOP = 0x00000008,
|
||||||
|
SND_NOSTOP = 0x00000010,
|
||||||
|
SND_PURGE = 0x00000040,
|
||||||
|
SND_APPLICATION = 0x00000080,
|
||||||
|
SND_NOWAIT = 0x00002000,
|
||||||
|
SND_ALIAS = 0x00010000,
|
||||||
|
SND_FILENAME = 0x00020000,
|
||||||
|
SND_RESOURCE = 0x00040000,
|
||||||
|
SND_ALIAS_ID = 0x00100000,
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,4 @@
|
|||||||
using SrcMod.Shell.Interop;
|
namespace SrcMod.Shell.Modules;
|
||||||
|
|
||||||
namespace SrcMod.Shell.Modules;
|
|
||||||
|
|
||||||
[Module("clipboard")]
|
[Module("clipboard")]
|
||||||
public static class ClipboardModule
|
public static class ClipboardModule
|
||||||
|
|||||||
@ -16,6 +16,9 @@ public class Shell
|
|||||||
public List<HistoryItem> History;
|
public List<HistoryItem> History;
|
||||||
public string WorkingDirectory;
|
public string WorkingDirectory;
|
||||||
|
|
||||||
|
private bool lastCancel;
|
||||||
|
private bool printedCancel;
|
||||||
|
|
||||||
public Shell()
|
public Shell()
|
||||||
{
|
{
|
||||||
Console.CursorVisible = false;
|
Console.CursorVisible = false;
|
||||||
@ -79,6 +82,9 @@ public class Shell
|
|||||||
Write(" by ", ConsoleColor.White, false);
|
Write(" by ", ConsoleColor.White, false);
|
||||||
Write($"{Author}", ConsoleColor.DarkYellow);
|
Write($"{Author}", ConsoleColor.DarkYellow);
|
||||||
|
|
||||||
|
lastCancel = false;
|
||||||
|
Console.CancelKeyPress += HandleCancel;
|
||||||
|
|
||||||
ActiveGame = null;
|
ActiveGame = null;
|
||||||
|
|
||||||
ReloadDirectoryInfo();
|
ReloadDirectoryInfo();
|
||||||
@ -106,8 +112,6 @@ public class Shell
|
|||||||
|
|
||||||
public string ReadLine()
|
public string ReadLine()
|
||||||
{
|
{
|
||||||
Console.CursorVisible = true;
|
|
||||||
|
|
||||||
Write($"\n{WorkingDirectory}", ConsoleColor.DarkGreen, false);
|
Write($"\n{WorkingDirectory}", ConsoleColor.DarkGreen, false);
|
||||||
if (ActiveGame is not null) Write($" {ActiveGame}", ConsoleColor.DarkYellow, false);
|
if (ActiveGame is not null) Write($" {ActiveGame}", ConsoleColor.DarkYellow, false);
|
||||||
if (ActiveMod is not null) Write($" {ActiveMod}", ConsoleColor.Magenta, false);
|
if (ActiveMod is not null) Write($" {ActiveMod}", ConsoleColor.Magenta, false);
|
||||||
@ -116,17 +120,55 @@ public class Shell
|
|||||||
Write($" {Name}", ConsoleColor.DarkCyan, false);
|
Write($" {Name}", ConsoleColor.DarkCyan, false);
|
||||||
Write(" > ", ConsoleColor.White, false);
|
Write(" > ", ConsoleColor.White, false);
|
||||||
|
|
||||||
|
bool printed = false;
|
||||||
|
|
||||||
|
if (lastCancel && !printedCancel)
|
||||||
|
{
|
||||||
|
// Print the warning. A little bit of mess because execution must
|
||||||
|
// continue without funny printing errors but it's alright I guess.
|
||||||
|
|
||||||
|
int originalLeft = Console.CursorLeft;
|
||||||
|
|
||||||
|
Console.CursorTop -= 3;
|
||||||
|
Write("Press ^C again to exit the shell.", ConsoleColor.Red);
|
||||||
|
// Send a warning sound.
|
||||||
|
|
||||||
|
Winmm.PlaySound("SystemAsterisk", nint.Zero,
|
||||||
|
(uint)(Winmm.PlaySoundFlags.SND_ALIAS | Winmm.PlaySoundFlags.SND_ASYNC));
|
||||||
|
|
||||||
|
printedCancel = true;
|
||||||
|
Console.CursorTop += 2;
|
||||||
|
|
||||||
|
Console.CursorLeft = originalLeft;
|
||||||
|
printed = true;
|
||||||
|
}
|
||||||
|
|
||||||
Console.ForegroundColor = ConsoleColor.White;
|
Console.ForegroundColor = ConsoleColor.White;
|
||||||
|
Console.CursorVisible = true;
|
||||||
string message = Console.ReadLine()!;
|
string message = Console.ReadLine()!;
|
||||||
|
Console.CursorVisible = false;
|
||||||
Console.ResetColor();
|
Console.ResetColor();
|
||||||
|
|
||||||
Console.CursorVisible = false;
|
if (!printed)
|
||||||
|
{
|
||||||
|
lastCancel = false;
|
||||||
|
printedCancel = false;
|
||||||
|
}
|
||||||
|
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InvokeCommand(string cmd)
|
public void InvokeCommand(string cmd)
|
||||||
{
|
{
|
||||||
|
if (cmd is null)
|
||||||
|
{
|
||||||
|
// This usually won't happen, but might if for example
|
||||||
|
// the shell cancel interrupt is called. This probably
|
||||||
|
// happens for other shell interrupts are called.
|
||||||
|
Write(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
List<string> parts = new();
|
List<string> parts = new();
|
||||||
string active = string.Empty;
|
string active = string.Empty;
|
||||||
|
|
||||||
@ -205,4 +247,22 @@ public class Shell
|
|||||||
if (ActiveMod is not null) title += $" - {ActiveMod.Name}";
|
if (ActiveMod is not null) title += $" - {ActiveMod.Name}";
|
||||||
Console.Title = title;
|
Console.Title = title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void HandleCancel(object? sender, ConsoleCancelEventArgs args)
|
||||||
|
{
|
||||||
|
// Due to some funny multithreading issues, we want to make the warning label
|
||||||
|
// single-threaded on the shell.
|
||||||
|
if (!lastCancel)
|
||||||
|
{
|
||||||
|
// Enable the warning. The "ReadLine" method will do the rest.
|
||||||
|
lastCancel = true;
|
||||||
|
args.Cancel = true; // "Cancel" referring to the cancellation of the cancel operation.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actually kill the shell. We do still have to worry about some multithreaded
|
||||||
|
// nonsense, but a bearable amount of it.
|
||||||
|
Console.ResetColor();
|
||||||
|
Environment.Exit(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user