using Cryville.Common.Network; using System; using System.Collections.Generic; using System.Threading; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; using Logger = Cryville.Common.Logger; namespace Cryville.Crtr { public class Console : MonoBehaviour { public Text Logs; public InputField InputBox; CommandWorker worker; readonly Queue _fallbackQueue = new Queue(); ~Console() { worker.Deactivate(); } void Start() { Game.Init(); InputBox.Select(); worker = new CommandWorker(MainThreadFallback); worker.Activate(); } void OnApplicationQuit() { Game.Shutdown(); } public void Submit() { worker.Issue(InputBox.text); } void Update() { if ( Input.GetKeyDown(KeyCode.Return) || Input.GetKeyDown(KeyCode.KeypadEnter) ) { Submit(); InputBox.text = ""; InputBox.Select(); InputBox.ActivateInputField(); } if (_fallbackQueue.Count > 0) { switch (_fallbackQueue.Dequeue()) { case "play": SceneManager.LoadScene("Play"); break; case "quit": Application.Quit(); break; default: Logger.Log("main", 4, "Console", "Unknown command. Type \"help\" for help"); break; } } string _logs = Logs.text; Game.MainLogger.Enumerate((level, module, msg) => { string color; switch (level) { case 0: color = "#888888"; break; case 1: color = "#bbbbbb"; break; case 2: color = "#0088ff"; break; case 3: color = "#ffff00"; break; case 4: color = "#ff0000"; break; case 5: color = "#bb0000"; break; default: color = "#ff00ff"; break; } _logs += string.Format( "\r\n\x02[{0}] <{2}> {3}", DateTime.UtcNow.ToString("s"), color, module, msg ); }); Logs.text = _logs.Substring(Mathf.Max(0, _logs.IndexOf('\x02', Mathf.Max(0, _logs.Length - 8192)))); } void MainThreadFallback(string cmd) { _fallbackQueue.Enqueue(cmd); } class CommandWorker { readonly Action _fallback; Thread _thread; readonly Queue _queue = new Queue(); public CommandWorker(Action fallback) { _fallback = fallback; } public void Activate() { _thread = new Thread(ThreadLoop); _thread.Start(); } public void Deactivate() { _thread.Abort(); } public void Issue(string cmd) { lock (_queue) { _queue.Enqueue(cmd); } } void ThreadLoop() { while (true) { string cmd = null; lock (_queue) { if (_queue.Count > 0) cmd = _queue.Dequeue(); } if (cmd != null) ProcessCommand(cmd); else Thread.Sleep(20); } } void ProcessCommand(string cmd) { Logger.Log("main", 2, "Console", "Command processing: {0}", cmd); var p = cmd.Split(' '); try { switch (p[0]) { case "!http": var httpcl = new HttpClient(new Uri(p[1])); httpcl.Connect(); httpcl.Request("GET", new Uri(p[1])).MessageBody.ReadToEnd(); httpcl.Close(); break; case "!https": var httpscl = new HttpsClient(new Uri(p[1])); httpscl.Connect(); httpscl.Request("GET", new Uri(p[1])).MessageBody.ReadToEnd(); httpscl.Close(); break; /*case "!lua": Logger.Log("main", 1, "Console", "{0}", Script.RunString(p[1])); break;*/ /*case "!tls": var tlscl = new TlsTcpClient(p[1]); tlscl.Close(); break;*/ case "connect": Game.ConnectDatabase(p[1]); break; case "help": case "?": Logger.Log( "main", 1, "Console", "\n\tconnect name" + "\n\thelp" + "\n\tlist" + "\n\tplay" + "\n\tquit" ); break; case "list": Logger.Log("main", 1, "Console", "Database list:"); foreach (var i in Game.GetDatabaseList()) { Logger.Log("main", 1, "Console", "{0}", i.Name); } break; default: _fallback.Invoke(cmd); break; } } catch (Exception ex) { Logger.Log("main", 4, "Console", "{0}", ex); } Logger.Log("main", 2, "Console", "Command done: {0}", cmd); } } } }