-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathCommandLineInterface.cs
148 lines (129 loc) · 4.68 KB
/
CommandLineInterface.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
using FEZRepacker.Interface.Actions;
namespace FEZRepacker.Interface
{
internal static class CommandLineInterface
{
public static CommandLineAction[] Commands = new CommandLineAction[]
{
new HelpAction(),
new ListPackageContentAction(),
new UnpackConvertAction(),
new UnpackRawAction(),
new UnpackDecompressedAction(),
new PackAction(),
new UnpackGameAction(),
new ConvertFromXnbAction(),
new ConvertToXnbAction()
};
public static CommandLineAction? FindCommand(string name)
{
var validCommands = Commands.Where(command => command.Name == name || command.Aliases.Contains(name));
if (validCommands.Any())
{
return validCommands.First();
}
else
{
return null;
}
}
/// <param name="args">The command to execute</param>
/// <returns>True if a command was executed, false otherwise.</returns>
public static bool ParseCommandLine(string[] args)
{
if (args.Length == 0) return false;
var command = FindCommand(args[0]);
if (command == null)
{
Console.WriteLine($"Unknown command \"{args[0]}\".");
Console.WriteLine($"Type \"FEZRepacker.exe --help\" for a list of commands.");
return false;
}
string[] cmdArgs = args.Skip(1).ToArray();
int maxArgs = command.Arguments.Length;
int minArgs = command.Arguments.Count(arg => !arg.Optional);
if (cmdArgs.Length < minArgs || cmdArgs.Length > maxArgs)
{
Console.WriteLine($"Invalid usage for command \"{args[0]}\" (incorrect number of parameters).");
Console.WriteLine($"Use \"FEZRepacker.exe --help {args[0]}\" for a usage instruction for that command.");
return false;
}
try
{
command.Execute(cmdArgs);
}
catch (Exception ex)
{
#if DEBUG
throw;
#else
Console.Error.WriteLine($"Error while executing command: {ex.Message}");
#endif
}
return true;
}
/// <summary>
/// Runs interactive mode which repeadetly requests user input and parses it as commands.
/// </summary>
public static void RunInteractiveMode()
{
Console.Write('\a'); //alert user
ShowInteractiveModeHelp();
while (true)
{
Console.WriteLine();
Console.Write("> FEZRepacker.exe ");
string? line = Console.ReadLine();
if (line == null) return; // No lines remain to read. Exit the program.
var args = ParseArguments(line);
if (ParseInteractiveModeCommands(args, out var shouldTerminate))
{
if (shouldTerminate) break;
else continue;
}
else if (ParseCommandLine(args))
{
continue;
}
else
{
ShowInteractiveModeHelp();
}
}
}
private static void ShowInteractiveModeHelp()
{
Console.WriteLine("To get usage help, use '--help'");
Console.WriteLine("To exit, use 'exit'");
}
private static bool ParseInteractiveModeCommands(string[] args, out bool terminationRequested)
{
terminationRequested = false;
if (args.Length == 0) return false;
switch (args[0].ToLower())
{
case "cls":
case "clear":
Console.Clear();
return true;
case "exit":
case "end":
case "stop":
case "terminate":
terminationRequested = true;
Console.WriteLine("Exiting...");
return true;
default:
Console.WriteLine();
return false;
}
}
private static string[] ParseArguments(string argumentsString)
{
return argumentsString.Split('"')
.SelectMany((element, index) => (index % 2 == 0) ? element.Split(' ') : new[] { element })
.Where(s => !string.IsNullOrEmpty(s))
.ToArray();
}
}
}