2020-04-28 01:50:50 +01:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Handles parsing and execution of console commands, as well as collecting log output.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
|
using System.Runtime.CompilerServices;
|
|
|
|
|
|
using System.Text;
|
2020-04-28 04:21:04 +01:00
|
|
|
|
using System.Text.RegularExpressions;
|
2020-04-28 01:50:50 +01:00
|
|
|
|
using UnityEngine.SceneManagement;
|
|
|
|
|
|
using Object = UnityEngine.Object;
|
|
|
|
|
|
|
|
|
|
|
|
public class ConsoleController
|
|
|
|
|
|
{
|
2020-05-07 03:53:54 +01:00
|
|
|
|
public static Component MessageReceiver;
|
2020-04-28 01:50:50 +01:00
|
|
|
|
private static ConsoleController instance;
|
2020-04-28 04:21:04 +01:00
|
|
|
|
private static Regex permittedCharacters = new Regex("[^a-zA-Z0-9 -]");
|
2020-04-28 01:50:50 +01:00
|
|
|
|
|
|
|
|
|
|
private ConsoleController()
|
|
|
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static ConsoleController Instance
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
if (instance == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
instance = new ConsoleController();
|
|
|
|
|
|
}
|
|
|
|
|
|
return instance;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#region Event declarations
|
|
|
|
|
|
// Used to communicate with ConsoleView
|
|
|
|
|
|
public delegate void LogChangedHandler(string[] log);
|
|
|
|
|
|
public event LogChangedHandler LogChanged;
|
|
|
|
|
|
|
|
|
|
|
|
public delegate void VisibilityChangedHandler(bool visible);
|
|
|
|
|
|
public event VisibilityChangedHandler VisibilityChanged;
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// How many log lines should be retained?
|
|
|
|
|
|
/// Note that strings submitted to appendLogLine with embedded newlines will be counted as a single line.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
const int ScrollbackSize = 100;
|
|
|
|
|
|
|
|
|
|
|
|
Queue<string> _scrollback = new Queue<string>(ScrollbackSize);
|
|
|
|
|
|
List<string> _commandHistory = new List<string>();
|
|
|
|
|
|
|
|
|
|
|
|
public string[] Log { get; private set; } //Copy of scrollback as an array for easier use by ConsoleView
|
|
|
|
|
|
|
|
|
|
|
|
public void AppendLogLine(string line) {
|
|
|
|
|
|
//Debug.Log(line);
|
|
|
|
|
|
|
|
|
|
|
|
if (_scrollback.Count >= ConsoleController.ScrollbackSize) {
|
|
|
|
|
|
_scrollback.Dequeue();
|
|
|
|
|
|
}
|
|
|
|
|
|
_scrollback.Enqueue(line);
|
|
|
|
|
|
|
|
|
|
|
|
Log = _scrollback.ToArray();
|
|
|
|
|
|
if (LogChanged != null) {
|
|
|
|
|
|
LogChanged(Log);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void RunCommandString(string commandString) {
|
|
|
|
|
|
AppendLogLine("$ " + commandString);
|
|
|
|
|
|
|
|
|
|
|
|
string[] commandSplit = ParseArguments(commandString);
|
|
|
|
|
|
string[] args = {"",""};
|
|
|
|
|
|
if (commandSplit.Length < 1) {
|
|
|
|
|
|
AppendLogLine(string.Format("Unable to process command '{0}'", commandString));
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
if (commandSplit.Length >= 2) {
|
|
|
|
|
|
int numArgs = commandSplit.Length - 1;
|
|
|
|
|
|
args = new string[numArgs];
|
|
|
|
|
|
Array.Copy(commandSplit, 1, args, 0, numArgs);
|
|
|
|
|
|
}
|
2020-05-07 03:53:54 +01:00
|
|
|
|
MessageReceiver.SendMessage(commandSplit[0].ToLower(), args, SendMessageOptions.DontRequireReceiver);
|
2020-04-28 01:50:50 +01:00
|
|
|
|
_commandHistory.Add(commandString);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static string[] ParseArguments(string commandString)
|
|
|
|
|
|
{
|
|
|
|
|
|
LinkedList<char> parmChars = new LinkedList<char>(commandString.ToCharArray());
|
|
|
|
|
|
bool inQuote = false;
|
|
|
|
|
|
var node = parmChars.First;
|
|
|
|
|
|
while (node != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var next = node.Next;
|
|
|
|
|
|
if (node.Value == '"') {
|
|
|
|
|
|
inQuote = !inQuote;
|
|
|
|
|
|
parmChars.Remove(node);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!inQuote && node.Value == ' ') {
|
|
|
|
|
|
node.Value = '\n';
|
|
|
|
|
|
}
|
|
|
|
|
|
node = next;
|
|
|
|
|
|
}
|
|
|
|
|
|
char[] parmCharsArr = new char[parmChars.Count];
|
|
|
|
|
|
parmChars.CopyTo(parmCharsArr, 0);
|
2020-04-28 04:21:04 +01:00
|
|
|
|
var args = new string(parmCharsArr).Split(new[] {'\n'}, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
|
|
for (var i = 0; i < args.Length; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
args[i] = permittedCharacters.Replace(args[i], "");
|
|
|
|
|
|
}
|
|
|
|
|
|
return args;
|
2020-04-28 01:50:50 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|