New shell release with some config files and commands. #57
@ -1,12 +1,14 @@
|
|||||||
global using Nerd_STF.Mathematics;
|
global using Nerd_STF.Mathematics;
|
||||||
|
global using Newtonsoft.Json;
|
||||||
global using SharpCompress.Archives.Rar;
|
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.Interop;
|
global using SrcMod.Shell.Interop;
|
||||||
global using SrcMod.Shell.Modules.ObjectModels;
|
global using SrcMod.Shell.Modules.ObjectModels;
|
||||||
|
global using SrcMod.Shell.ObjectModels;
|
||||||
global using System;
|
global using System;
|
||||||
global using System.Collections.Generic;
|
global using System.Collections.Generic;
|
||||||
|
global using System.ComponentModel;
|
||||||
global using System.Diagnostics;
|
global using System.Diagnostics;
|
||||||
global using System.Formats.Tar;
|
global using System.Formats.Tar;
|
||||||
global using System.IO;
|
global using System.IO;
|
||||||
|
|||||||
79
SrcMod/Shell/LoadingBar.cs
Normal file
79
SrcMod/Shell/LoadingBar.cs
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
namespace SrcMod.Shell;
|
||||||
|
|
||||||
|
internal static class LoadingBar
|
||||||
|
{
|
||||||
|
public static int position = -1;
|
||||||
|
public static int bufferSize = 0;
|
||||||
|
public static int lastValue = -1;
|
||||||
|
public static float value = 0;
|
||||||
|
public static ConsoleColor color = Console.ForegroundColor;
|
||||||
|
|
||||||
|
public static bool Enabled { get; private set; }
|
||||||
|
|
||||||
|
public static void End(bool clear = true)
|
||||||
|
{
|
||||||
|
if (position == -1) throw new("No loading bar is active.");
|
||||||
|
|
||||||
|
if (clear)
|
||||||
|
{
|
||||||
|
Int2 oldPos = (Console.CursorLeft, Console.CursorTop);
|
||||||
|
|
||||||
|
Console.CursorLeft = 0;
|
||||||
|
Console.CursorTop = position;
|
||||||
|
Console.Write(new string(' ', Console.BufferWidth));
|
||||||
|
Console.CursorLeft = 0;
|
||||||
|
|
||||||
|
Console.SetCursorPosition(oldPos.x, oldPos.y);
|
||||||
|
}
|
||||||
|
position = -1;
|
||||||
|
Enabled = false;
|
||||||
|
}
|
||||||
|
public static void Set(float value, ConsoleColor? color = null)
|
||||||
|
{
|
||||||
|
const string left = " --- [",
|
||||||
|
right = "] --- ";
|
||||||
|
int barSize = Console.BufferWidth - left.Length - right.Length,
|
||||||
|
filled = (int)(barSize * value);
|
||||||
|
|
||||||
|
if (filled == lastValue) return;
|
||||||
|
lastValue = filled;
|
||||||
|
|
||||||
|
Int2 oldPos = (Console.CursorLeft, Console.CursorTop);
|
||||||
|
|
||||||
|
LoadingBar.value = value;
|
||||||
|
LoadingBar.color = color ?? Console.ForegroundColor;
|
||||||
|
|
||||||
|
// Erase last bar.
|
||||||
|
Console.SetCursorPosition(0, position);
|
||||||
|
Console.Write(new string(' ', bufferSize));
|
||||||
|
Console.CursorLeft = 0;
|
||||||
|
|
||||||
|
// Add new bar.
|
||||||
|
bufferSize = Console.BufferWidth;
|
||||||
|
|
||||||
|
Write(left, newLine: false);
|
||||||
|
ConsoleColor oldFore = Console.ForegroundColor;
|
||||||
|
|
||||||
|
if (color is not null) Console.ForegroundColor = color.Value;
|
||||||
|
Write(new string('=', filled), newLine: false);
|
||||||
|
if (color is not null) Console.ForegroundColor = oldFore;
|
||||||
|
Write(new string(' ', barSize - filled), newLine: false);
|
||||||
|
Write(right, newLine: false);
|
||||||
|
|
||||||
|
if (oldPos.y == Console.CursorTop) oldPos.y++;
|
||||||
|
while (oldPos.y >= Console.BufferHeight)
|
||||||
|
{
|
||||||
|
Console.WriteLine();
|
||||||
|
oldPos.y--;
|
||||||
|
position--;
|
||||||
|
}
|
||||||
|
Console.SetCursorPosition(oldPos.x, oldPos.y);
|
||||||
|
}
|
||||||
|
public static void Start(float value = 0, int? position = null, ConsoleColor? color = null)
|
||||||
|
{
|
||||||
|
if (LoadingBar.position != -1) throw new("The loading bar has already been enabled.");
|
||||||
|
LoadingBar.position = position ?? Console.CursorTop;
|
||||||
|
Enabled = true;
|
||||||
|
Set(value, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -45,7 +45,7 @@ public static class BaseModule
|
|||||||
|
|
||||||
Write($"Copying directory \"{source}\" to \"{destination}\"...");
|
Write($"Copying directory \"{source}\" to \"{destination}\"...");
|
||||||
|
|
||||||
LoadingBarStart();
|
LoadingBar.Start();
|
||||||
for (int i = 0; i < files.Length; i++)
|
for (int i = 0; i < files.Length; i++)
|
||||||
{
|
{
|
||||||
string file = files[i],
|
string file = files[i],
|
||||||
@ -53,7 +53,7 @@ public static class BaseModule
|
|||||||
destFile = Path.Combine(destination, file);
|
destFile = Path.Combine(destination, file);
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(destFile)!);
|
Directory.CreateDirectory(Path.GetDirectoryName(destFile)!);
|
||||||
File.Copy(sourceFile, destFile);
|
File.Copy(sourceFile, destFile);
|
||||||
LoadingBarSet((i + 1) / (float)files.Length, ConsoleColor.DarkGreen);
|
LoadingBar.Set((i + 1) / (float)files.Length, ConsoleColor.DarkGreen);
|
||||||
Console.CursorLeft = 0;
|
Console.CursorLeft = 0;
|
||||||
string message = $"{sourceFile}";
|
string message = $"{sourceFile}";
|
||||||
int remainder = Console.BufferWidth - message.Length;
|
int remainder = Console.BufferWidth - message.Length;
|
||||||
@ -63,7 +63,7 @@ public static class BaseModule
|
|||||||
Write(message, newLine: false);
|
Write(message, newLine: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadingBarEnd();
|
LoadingBar.End();
|
||||||
|
|
||||||
Console.CursorLeft = 0;
|
Console.CursorLeft = 0;
|
||||||
Write(new string(' ', Console.BufferWidth), newLine: false);
|
Write(new string(' ', Console.BufferWidth), newLine: false);
|
||||||
@ -361,13 +361,13 @@ public static class BaseModule
|
|||||||
|
|
||||||
Thread.Sleep(rand.Next(500, 1000));
|
Thread.Sleep(rand.Next(500, 1000));
|
||||||
|
|
||||||
LoadingBarStart();
|
LoadingBar.Start();
|
||||||
|
|
||||||
for (int i = 0; i < files.Length; i++)
|
for (int i = 0; i < files.Length; i++)
|
||||||
{
|
{
|
||||||
FileInfo file = new(files[i]);
|
FileInfo file = new(files[i]);
|
||||||
Thread.Sleep((int)(rand.Next(50, 100) * (file.Length >> 20)));
|
Thread.Sleep((int)(rand.Next(50, 100) * (file.Length >> 20)));
|
||||||
LoadingBarSet((i + 1) / (float)files.Length, ConsoleColor.Red);
|
LoadingBar.Set((i + 1) / (float)files.Length, ConsoleColor.Red);
|
||||||
Console.CursorLeft = 0;
|
Console.CursorLeft = 0;
|
||||||
string message = $"{files[i]}";
|
string message = $"{files[i]}";
|
||||||
int remainder = Console.BufferWidth - message.Length;
|
int remainder = Console.BufferWidth - message.Length;
|
||||||
@ -377,7 +377,7 @@ public static class BaseModule
|
|||||||
Write(message, newLine: false);
|
Write(message, newLine: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadingBarEnd();
|
LoadingBar.End();
|
||||||
|
|
||||||
Console.CursorLeft = 0;
|
Console.CursorLeft = 0;
|
||||||
Write(new string(' ', Console.BufferWidth), newLine: false);
|
Write(new string(' ', Console.BufferWidth), newLine: false);
|
||||||
|
|||||||
@ -168,7 +168,7 @@ public static class CompressionModule
|
|||||||
|
|
||||||
int failed = 0;
|
int failed = 0;
|
||||||
|
|
||||||
LoadingBarStart();
|
LoadingBar.Start();
|
||||||
for (int i = 0; i < files.Count; i++)
|
for (int i = 0; i < files.Count; i++)
|
||||||
{
|
{
|
||||||
bool failedThisTime = false;
|
bool failedThisTime = false;
|
||||||
@ -181,7 +181,7 @@ public static class CompressionModule
|
|||||||
failedThisTime = true;
|
failedThisTime = true;
|
||||||
failed++;
|
failed++;
|
||||||
}
|
}
|
||||||
LoadingBarSet((i + 1) / (float)files.Count, failedThisTime ? ConsoleColor.Red : ConsoleColor.DarkGreen); ;
|
LoadingBar.Set((i + 1) / (float)files.Count, failedThisTime ? ConsoleColor.Red : ConsoleColor.DarkGreen); ;
|
||||||
Console.CursorLeft = 0;
|
Console.CursorLeft = 0;
|
||||||
string message = $"{relative[i]}";
|
string message = $"{relative[i]}";
|
||||||
int remainder = Console.BufferWidth - message.Length;
|
int remainder = Console.BufferWidth - message.Length;
|
||||||
@ -194,7 +194,7 @@ public static class CompressionModule
|
|||||||
archive.Dispose();
|
archive.Dispose();
|
||||||
writer.Dispose();
|
writer.Dispose();
|
||||||
|
|
||||||
LoadingBarEnd();
|
LoadingBar.End();
|
||||||
|
|
||||||
Console.CursorLeft = 0;
|
Console.CursorLeft = 0;
|
||||||
Write(new string(' ', Console.BufferWidth), newLine: false);
|
Write(new string(' ', Console.BufferWidth), newLine: false);
|
||||||
|
|||||||
194
SrcMod/Shell/Modules/ConfigModule.cs
Normal file
194
SrcMod/Shell/Modules/ConfigModule.cs
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
namespace SrcMod.Shell.Modules;
|
||||||
|
|
||||||
|
[Module("config")]
|
||||||
|
public static class ConfigModule
|
||||||
|
{
|
||||||
|
[Command("display")]
|
||||||
|
[Command("list")]
|
||||||
|
public static void DisplayConfig(ConfigDisplayMode mode = ConfigDisplayMode.All)
|
||||||
|
{
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case ConfigDisplayMode.Raw:
|
||||||
|
DisplayConfigRaw();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ConfigDisplayMode.All:
|
||||||
|
DisplayConfigAll();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ConfigDisplayMode.GameDirectories:
|
||||||
|
DisplayConfigGameDirectories();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ConfigDisplayMode.RunUnsafeCommands:
|
||||||
|
DisplayConfigUnsafeCommands();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command("add")]
|
||||||
|
[Command("append")]
|
||||||
|
public static void AppendConfigVariable(string name, string value)
|
||||||
|
{
|
||||||
|
Config config = Config.LoadedConfig;
|
||||||
|
|
||||||
|
switch (name.Trim().ToLower())
|
||||||
|
{
|
||||||
|
case "gamedirectories":
|
||||||
|
config.GameDirectories = config.GameDirectories.Append(value).ToArray();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "rununsafecommands":
|
||||||
|
throw new($"The config variable \"{name}\" is a single variable and cannot be appended to.");
|
||||||
|
|
||||||
|
default: throw new($"Unknown config variable \"{name}\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
Config.LoadedConfig = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command("delete")]
|
||||||
|
[Command("remove")]
|
||||||
|
public static void RemoveConfigVariable(string name, string value)
|
||||||
|
{
|
||||||
|
Config config = Config.LoadedConfig;
|
||||||
|
|
||||||
|
switch (name.Trim().ToLower())
|
||||||
|
{
|
||||||
|
case "gamedirectories":
|
||||||
|
config.GameDirectories = config.GameDirectories
|
||||||
|
.Where(x => x.Trim().ToLower() != value.Trim().ToLower())
|
||||||
|
.ToArray();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "rununsafecommands":
|
||||||
|
throw new($"The config variable \"{name}\" is a single variable and cannot be appended to.");
|
||||||
|
|
||||||
|
default: throw new($"Unknown config variable \"{name}\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
Config.LoadedConfig = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command("reset")]
|
||||||
|
public static void ResetConfig(string name = "all")
|
||||||
|
{
|
||||||
|
Config config = Config.LoadedConfig;
|
||||||
|
|
||||||
|
switch (name.Trim().ToLower())
|
||||||
|
{
|
||||||
|
case "gamedirectories":
|
||||||
|
config.GameDirectories = Config.Defaults.GameDirectories;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "rununsafecommands":
|
||||||
|
config.RunUnsafeCommands = Config.Defaults.RunUnsafeCommands;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "all":
|
||||||
|
config = Config.Defaults;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: throw new($"Unknown config variable \"{name}\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
Config.LoadedConfig = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command("set")]
|
||||||
|
public static void SetConfigVariable(string name, string value)
|
||||||
|
{
|
||||||
|
Config config = Config.LoadedConfig;
|
||||||
|
|
||||||
|
switch (name.Trim().ToLower())
|
||||||
|
{
|
||||||
|
case "gamedirectories":
|
||||||
|
throw new($"The config variable \"{name}\" is a list and must be added or removed to.");
|
||||||
|
|
||||||
|
case "rununsafecommands":
|
||||||
|
if (int.TryParse(value, out int intRes))
|
||||||
|
{
|
||||||
|
AskMode mode = (AskMode)intRes;
|
||||||
|
if (!Enum.IsDefined(mode)) throw new($"(AskMode){value} is not a valid AskMode.");
|
||||||
|
config.RunUnsafeCommands = mode;
|
||||||
|
}
|
||||||
|
else if (Enum.TryParse(value, true, out AskMode modeRes))
|
||||||
|
{
|
||||||
|
if (!Enum.IsDefined(modeRes)) throw new($"\"{value}\" is not a valid AskMode.");
|
||||||
|
config.RunUnsafeCommands = modeRes;
|
||||||
|
}
|
||||||
|
else throw new($"\"{value}\" is not a valid AskMode.");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: throw new($"Unknown config variable \"{name}\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
Config.LoadedConfig = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DisplayConfigAll()
|
||||||
|
{
|
||||||
|
DisplayConfigGameDirectories();
|
||||||
|
DisplayConfigUnsafeCommands();
|
||||||
|
}
|
||||||
|
private static void DisplayConfigRaw()
|
||||||
|
{
|
||||||
|
// This is definitely a bit inefficient, but shouldn't be too much of an issue.
|
||||||
|
|
||||||
|
MemoryStream ms = new();
|
||||||
|
StreamWriter writer = new(ms, leaveOpen: true);
|
||||||
|
JsonTextWriter jsonWriter = new(writer);
|
||||||
|
|
||||||
|
Serializer.Serialize(jsonWriter, Config.LoadedConfig);
|
||||||
|
|
||||||
|
jsonWriter.Close();
|
||||||
|
writer.Close();
|
||||||
|
ms.Position = 0;
|
||||||
|
|
||||||
|
StreamReader reader = new(ms);
|
||||||
|
string msg = reader.ReadToEnd();
|
||||||
|
|
||||||
|
Write(msg);
|
||||||
|
|
||||||
|
reader.Close();
|
||||||
|
ms.Close();
|
||||||
|
}
|
||||||
|
private static void DisplayConfigGameDirectories()
|
||||||
|
{
|
||||||
|
Write("Steam Game Directories: ", null, false);
|
||||||
|
if (Config.LoadedConfig.GameDirectories is null || Config.LoadedConfig.GameDirectories.Length <= 0)
|
||||||
|
Write("None", ConsoleColor.DarkGray);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Write("[", ConsoleColor.DarkGray);
|
||||||
|
for (int i = 0; i < Config.LoadedConfig.GameDirectories.Length; i++)
|
||||||
|
{
|
||||||
|
Write(" \"", ConsoleColor.DarkGray, false);
|
||||||
|
Write(Config.LoadedConfig.GameDirectories[i], ConsoleColor.White, false);
|
||||||
|
if (i < Config.LoadedConfig.GameDirectories.Length - 1) Write("\",", ConsoleColor.DarkGray);
|
||||||
|
else Write("\"", ConsoleColor.DarkGray);
|
||||||
|
}
|
||||||
|
Write("]", ConsoleColor.DarkGray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static void DisplayConfigUnsafeCommands()
|
||||||
|
{
|
||||||
|
Write("Run Unsafe Commands: ", null, false);
|
||||||
|
ConsoleColor color = Config.LoadedConfig.RunUnsafeCommands switch
|
||||||
|
{
|
||||||
|
AskMode.Never => ConsoleColor.Red,
|
||||||
|
AskMode.Always => ConsoleColor.Green,
|
||||||
|
AskMode.Ask or _ => ConsoleColor.DarkGray
|
||||||
|
};
|
||||||
|
Write(Config.LoadedConfig.RunUnsafeCommands, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ConfigDisplayMode
|
||||||
|
{
|
||||||
|
Raw,
|
||||||
|
All,
|
||||||
|
GameDirectories,
|
||||||
|
RunUnsafeCommands
|
||||||
|
}
|
||||||
|
}
|
||||||
8
SrcMod/Shell/ObjectModels/AskMode.cs
Normal file
8
SrcMod/Shell/ObjectModels/AskMode.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace SrcMod.Shell.ObjectModels;
|
||||||
|
|
||||||
|
public enum AskMode : sbyte
|
||||||
|
{
|
||||||
|
Never = -1,
|
||||||
|
Ask = 0,
|
||||||
|
Always = 1
|
||||||
|
}
|
||||||
86
SrcMod/Shell/ObjectModels/Config.cs
Normal file
86
SrcMod/Shell/ObjectModels/Config.cs
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
namespace SrcMod.Shell.ObjectModels;
|
||||||
|
|
||||||
|
public struct Config
|
||||||
|
{
|
||||||
|
public const string FilePath = "config.json";
|
||||||
|
|
||||||
|
public static readonly Config Defaults;
|
||||||
|
|
||||||
|
public static Config LoadedConfig
|
||||||
|
{
|
||||||
|
get => p_applied;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
p_applied = value;
|
||||||
|
p_changes = p_applied.GetChanges(Defaults);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Config p_applied;
|
||||||
|
private static ConfigChanges? p_changes;
|
||||||
|
|
||||||
|
static Config()
|
||||||
|
{
|
||||||
|
Defaults = new()
|
||||||
|
{
|
||||||
|
GameDirectories = Array.Empty<string>(),
|
||||||
|
RunUnsafeCommands = AskMode.Ask
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public string[] GameDirectories;
|
||||||
|
public AskMode RunUnsafeCommands;
|
||||||
|
|
||||||
|
public Config ApplyChanges(ConfigChanges changes) => this with
|
||||||
|
{
|
||||||
|
GameDirectories = GameDirectories.Union(changes.GameDirectories ?? Array.Empty<string>()).ToArray(),
|
||||||
|
RunUnsafeCommands = changes.RunUnsafeCommands ?? RunUnsafeCommands
|
||||||
|
};
|
||||||
|
public ConfigChanges GetChanges(Config? baseConfig = null)
|
||||||
|
{
|
||||||
|
Config reference = baseConfig ?? Defaults;
|
||||||
|
ConfigChanges changes = new()
|
||||||
|
{
|
||||||
|
GameDirectories = reference.GameDirectories == GameDirectories ? null :
|
||||||
|
GameDirectories.Where(x => !reference.GameDirectories.Contains(x)).ToArray(),
|
||||||
|
RunUnsafeCommands = reference.RunUnsafeCommands == RunUnsafeCommands ? null : RunUnsafeCommands
|
||||||
|
};
|
||||||
|
|
||||||
|
return changes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void LoadConfig(string basePath)
|
||||||
|
{
|
||||||
|
string fullPath = Path.Combine(basePath, FilePath);
|
||||||
|
|
||||||
|
if (!File.Exists(fullPath))
|
||||||
|
{
|
||||||
|
p_applied = Defaults;
|
||||||
|
p_changes = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
StreamReader reader = new(fullPath);
|
||||||
|
JsonTextReader jsonReader = new(reader);
|
||||||
|
p_changes = Serializer.Deserialize<ConfigChanges?>(jsonReader);
|
||||||
|
jsonReader.Close();
|
||||||
|
reader.Close();
|
||||||
|
|
||||||
|
p_applied = p_changes is null ? Defaults : Defaults.ApplyChanges(p_changes.Value);
|
||||||
|
}
|
||||||
|
public static void SaveConfig(string basePath)
|
||||||
|
{
|
||||||
|
string fullPath = Path.Combine(basePath, FilePath);
|
||||||
|
|
||||||
|
if (p_changes is null || !p_changes.Value.HasChange)
|
||||||
|
{
|
||||||
|
if (File.Exists(fullPath)) File.Delete(fullPath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
StreamWriter writer = new(fullPath);
|
||||||
|
JsonTextWriter jsonWriter = new(writer);
|
||||||
|
Serializer.Serialize(jsonWriter, p_changes);
|
||||||
|
jsonWriter.Close();
|
||||||
|
writer.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
10
SrcMod/Shell/ObjectModels/ConfigChanges.cs
Normal file
10
SrcMod/Shell/ObjectModels/ConfigChanges.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
namespace SrcMod.Shell.ObjectModels;
|
||||||
|
|
||||||
|
public record struct ConfigChanges
|
||||||
|
{
|
||||||
|
[JsonIgnore]
|
||||||
|
public bool HasChange => GameDirectories is not null || RunUnsafeCommands is not null;
|
||||||
|
|
||||||
|
public string[]? GameDirectories;
|
||||||
|
public AskMode? RunUnsafeCommands;
|
||||||
|
}
|
||||||
@ -1,12 +1,10 @@
|
|||||||
using System.ComponentModel;
|
namespace SrcMod.Shell;
|
||||||
|
|
||||||
namespace SrcMod.Shell;
|
|
||||||
|
|
||||||
public class Shell
|
public class Shell
|
||||||
{
|
{
|
||||||
public const string Author = "That_One_Nerd";
|
public const string Author = "That_One_Nerd";
|
||||||
public const string Name = "SrcMod";
|
public const string Name = "SrcMod";
|
||||||
public const string Version = "Alpha 0.3.2";
|
public const string Version = "Alpha 0.3.3";
|
||||||
|
|
||||||
public readonly string? ShellDirectory;
|
public readonly string? ShellDirectory;
|
||||||
|
|
||||||
@ -50,6 +48,10 @@ public class Shell
|
|||||||
|
|
||||||
WorkingDirectory = Directory.GetCurrentDirectory();
|
WorkingDirectory = Directory.GetCurrentDirectory();
|
||||||
|
|
||||||
|
// Load config.
|
||||||
|
if (ShellDirectory is null) Write("[WARNING] Could not load config from shell location. Defaults will be used.");
|
||||||
|
else Config.LoadConfig(ShellDirectory);
|
||||||
|
|
||||||
// Load modules and commands.
|
// Load modules and commands.
|
||||||
List<Assembly?> possibleAsms = new()
|
List<Assembly?> possibleAsms = new()
|
||||||
{
|
{
|
||||||
@ -95,6 +97,26 @@ public class Shell
|
|||||||
ReloadDirectoryInfo();
|
ReloadDirectoryInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool LoadModule(Type moduleType)
|
||||||
|
{
|
||||||
|
if (LoadedModules.Any(x => x.Type.FullName == moduleType.FullName)) return false;
|
||||||
|
|
||||||
|
ModuleInfo? module = ModuleInfo.FromType(moduleType);
|
||||||
|
if (module is null) return false;
|
||||||
|
|
||||||
|
LoadedModules.Add(module);
|
||||||
|
LoadedCommands.AddRange(module.Commands);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public bool LoadModule<T>() => LoadModule(typeof(T));
|
||||||
|
public int LoadModules(Assembly moduleAssembly)
|
||||||
|
{
|
||||||
|
int loaded = 0;
|
||||||
|
foreach (Type moduleType in moduleAssembly.GetTypes()) if (LoadModule(moduleType)) loaded++;
|
||||||
|
return loaded;
|
||||||
|
}
|
||||||
|
|
||||||
public void AddHistory(HistoryItem item) => History.Add(item);
|
public void AddHistory(HistoryItem item) => History.Add(item);
|
||||||
public void UndoItem()
|
public void UndoItem()
|
||||||
{
|
{
|
||||||
@ -227,12 +249,12 @@ public class Shell
|
|||||||
catch (TargetInvocationException ex)
|
catch (TargetInvocationException ex)
|
||||||
{
|
{
|
||||||
Write($"[ERROR] {ex.InnerException!.Message}", ConsoleColor.Red);
|
Write($"[ERROR] {ex.InnerException!.Message}", ConsoleColor.Red);
|
||||||
if (LoadingBarEnabled) LoadingBarEnd();
|
if (LoadingBar.Enabled) LoadingBar.End();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Write($"[ERROR] {ex.Message}", ConsoleColor.Red);
|
Write($"[ERROR] {ex.Message}", ConsoleColor.Red);
|
||||||
if (LoadingBarEnabled) LoadingBarEnd();
|
if (LoadingBar.Enabled) LoadingBar.End();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -250,6 +272,11 @@ public class Shell
|
|||||||
activeCommand.Dispose();
|
activeCommand.Dispose();
|
||||||
activeCommand = null;
|
activeCommand = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ShellDirectory is null) Write("[WARNING] Could not save config to shell location. Any changes will be ignored.");
|
||||||
|
else Config.SaveConfig(ShellDirectory);
|
||||||
|
|
||||||
|
ReloadDirectoryInfo();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||||
<ApplicationIcon>Logo.ico</ApplicationIcon>
|
<ApplicationIcon>Logo.ico</ApplicationIcon>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
<NoWin32Manifest>true</NoWin32Manifest>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
@ -31,6 +32,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Nerd_STF" Version="2.3.2" />
|
<PackageReference Include="Nerd_STF" Version="2.3.2" />
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.33.0" />
|
<PackageReference Include="SharpCompress" Version="0.33.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
@ -1,16 +1,17 @@
|
|||||||
using System.Text;
|
namespace SrcMod.Shell;
|
||||||
|
|
||||||
namespace SrcMod.Shell;
|
internal static class Tools
|
||||||
|
|
||||||
public static class Tools
|
|
||||||
{
|
{
|
||||||
private static int loadingPosition = -1;
|
public static JsonSerializer Serializer { get; private set; }
|
||||||
private static int lastLoadingBufferSize = 0;
|
|
||||||
private static int lastLoadingValue = -1;
|
|
||||||
private static float loadingBarValue = 0;
|
|
||||||
private static ConsoleColor loadingBarColor = Console.ForegroundColor;
|
|
||||||
|
|
||||||
public static bool LoadingBarEnabled { get; private set; }
|
static Tools()
|
||||||
|
{
|
||||||
|
Serializer = JsonSerializer.Create(new()
|
||||||
|
{
|
||||||
|
Formatting = Formatting.Indented,
|
||||||
|
NullValueHandling = NullValueHandling.Ignore
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public static void DisplayWithPages(IEnumerable<string> lines, ConsoleColor? color = null)
|
public static void DisplayWithPages(IEnumerable<string> lines, ConsoleColor? color = null)
|
||||||
{
|
{
|
||||||
@ -73,73 +74,6 @@ public static class Tools
|
|||||||
return allFiles;
|
return allFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void LoadingBarEnd(bool clear = true)
|
|
||||||
{
|
|
||||||
if (loadingPosition == -1) throw new("No loading bar is active.");
|
|
||||||
|
|
||||||
if (clear)
|
|
||||||
{
|
|
||||||
Int2 oldPos = (Console.CursorLeft, Console.CursorTop);
|
|
||||||
|
|
||||||
Console.CursorLeft = 0;
|
|
||||||
Console.CursorTop = loadingPosition;
|
|
||||||
Console.Write(new string(' ', Console.BufferWidth));
|
|
||||||
Console.CursorLeft = 0;
|
|
||||||
|
|
||||||
Console.SetCursorPosition(oldPos.x, oldPos.y);
|
|
||||||
}
|
|
||||||
loadingPosition = -1;
|
|
||||||
LoadingBarEnabled = false;
|
|
||||||
}
|
|
||||||
public static void LoadingBarSet(float value, ConsoleColor? color = null)
|
|
||||||
{
|
|
||||||
const string left = " --- [",
|
|
||||||
right = "] --- ";
|
|
||||||
int barSize = Console.BufferWidth - left.Length - right.Length,
|
|
||||||
filled = (int)(barSize * value);
|
|
||||||
|
|
||||||
if (filled == lastLoadingValue) return;
|
|
||||||
lastLoadingValue = filled;
|
|
||||||
|
|
||||||
Int2 oldPos = (Console.CursorLeft, Console.CursorTop);
|
|
||||||
|
|
||||||
loadingBarValue = value;
|
|
||||||
loadingBarColor = color ?? Console.ForegroundColor;
|
|
||||||
|
|
||||||
// Erase last bar.
|
|
||||||
Console.SetCursorPosition(0, loadingPosition);
|
|
||||||
Console.Write(new string(' ', lastLoadingBufferSize));
|
|
||||||
Console.CursorLeft = 0;
|
|
||||||
|
|
||||||
// Add new bar.
|
|
||||||
lastLoadingBufferSize = Console.BufferWidth;
|
|
||||||
|
|
||||||
Write(left, newLine: false);
|
|
||||||
ConsoleColor oldFore = Console.ForegroundColor;
|
|
||||||
|
|
||||||
if (color is not null) Console.ForegroundColor = color.Value;
|
|
||||||
Write(new string('=', filled), newLine: false);
|
|
||||||
if (color is not null) Console.ForegroundColor = oldFore;
|
|
||||||
Write(new string(' ', barSize - filled), newLine: false);
|
|
||||||
Write(right, newLine: false);
|
|
||||||
|
|
||||||
if (oldPos.y == Console.CursorTop) oldPos.y++;
|
|
||||||
while (oldPos.y >= Console.BufferHeight)
|
|
||||||
{
|
|
||||||
Console.WriteLine();
|
|
||||||
oldPos.y--;
|
|
||||||
loadingPosition--;
|
|
||||||
}
|
|
||||||
Console.SetCursorPosition(oldPos.x, oldPos.y);
|
|
||||||
}
|
|
||||||
public static void LoadingBarStart(float value = 0, int? position = null, ConsoleColor? color = null)
|
|
||||||
{
|
|
||||||
if (loadingPosition != -1) throw new("The loading bar has already been enabled.");
|
|
||||||
loadingPosition = position ?? Console.CursorTop;
|
|
||||||
LoadingBarEnabled = true;
|
|
||||||
LoadingBarSet(value, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Write(object? message, ConsoleColor? col = null, bool newLine = true)
|
public static void Write(object? message, ConsoleColor? col = null, bool newLine = true)
|
||||||
{
|
{
|
||||||
ConsoleColor prevCol = Console.ForegroundColor;
|
ConsoleColor prevCol = Console.ForegroundColor;
|
||||||
@ -150,24 +84,45 @@ public static class Tools
|
|||||||
|
|
||||||
Console.ForegroundColor = prevCol;
|
Console.ForegroundColor = prevCol;
|
||||||
|
|
||||||
if (newLine && LoadingBarEnabled && Console.CursorTop >= Console.BufferHeight - 1)
|
if (newLine && LoadingBar.Enabled && Console.CursorTop >= Console.BufferHeight - 1)
|
||||||
{
|
{
|
||||||
loadingPosition--;
|
LoadingBar.position--;
|
||||||
LoadingBarSet(loadingBarValue, loadingBarColor);
|
LoadingBar.Set(LoadingBar.value, LoadingBar.color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool ValidateUnsafe()
|
public static bool ValidateUnsafe()
|
||||||
{
|
{
|
||||||
Write("You are about to execute an unsafe command.\nProceed? > ", ConsoleColor.DarkYellow, false);
|
switch (Config.LoadedConfig.RunUnsafeCommands)
|
||||||
|
{
|
||||||
|
case AskMode.Always:
|
||||||
|
Write("[INFO] The shell has been configured to always run unsafe commands. " +
|
||||||
|
"This can be changed in the config.", ConsoleColor.DarkGray);
|
||||||
|
return true;
|
||||||
|
|
||||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
case AskMode.Never:
|
||||||
Console.CursorVisible = true;
|
Write("[ERROR] The shell has been configured to never run unsafe commands. " +
|
||||||
string result = Console.ReadLine()!.Trim().ToLower();
|
"This can be changed in the config.", ConsoleColor.Red);
|
||||||
Console.CursorVisible = false;
|
return false;
|
||||||
Console.ResetColor();
|
|
||||||
|
|
||||||
return result == "y" || result == "yes" || result == "t" ||
|
case AskMode.Ask or _:
|
||||||
result == "true" || result == "p" || result == "proceed";
|
Write("You are about to execute an unsafe command.\nProceed? > ", ConsoleColor.DarkYellow, false);
|
||||||
|
Int2 start = (Console.CursorLeft, Console.CursorTop);
|
||||||
|
Write("\nTip: You can disable this dialog in the config.", ConsoleColor.DarkGray);
|
||||||
|
int finish = Console.CursorTop;
|
||||||
|
|
||||||
|
Console.SetCursorPosition(start.x, start.y);
|
||||||
|
|
||||||
|
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||||
|
Console.CursorVisible = true;
|
||||||
|
string result = Console.ReadLine()!.Trim().ToLower();
|
||||||
|
Console.CursorVisible = false;
|
||||||
|
Console.ResetColor();
|
||||||
|
|
||||||
|
Console.SetCursorPosition(0, finish);
|
||||||
|
|
||||||
|
return result == "y" || result == "yes" || result == "t" ||
|
||||||
|
result == "true" || result == "p" || result == "proceed";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user