Custom Command Syntax

This commit is contained in:
pfg 2017-03-12 09:29:17 -07:00
parent b20d77edd1
commit 6460ccee37
8 changed files with 634 additions and 519 deletions

View file

@ -61,8 +61,9 @@ namespace ShiftOS.WinForms.Applications
this.btnAddColor = new System.Windows.Forms.Button();
this.richTextBox1 = new System.Windows.Forms.RichTextBox();
this.btnTest = new System.Windows.Forms.Button();
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.btnSave = new System.Windows.Forms.Button();
this.btnLoad = new System.Windows.Forms.Button();
this.btnApply = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// panelEditor
@ -109,9 +110,9 @@ namespace ShiftOS.WinForms.Applications
//
this.btnAddCommand.Location = new System.Drawing.Point(4, 85);
this.btnAddCommand.Name = "btnAddCommand";
this.btnAddCommand.Size = new System.Drawing.Size(75, 23);
this.btnAddCommand.Size = new System.Drawing.Size(85, 23);
this.btnAddCommand.TabIndex = 5;
this.btnAddCommand.Text = "+ Command";
this.btnAddCommand.Text = "+ Namespace";
this.btnAddCommand.UseVisualStyleBackColor = true;
this.btnAddCommand.Click += new System.EventHandler(this.btnAddCommand_Click);
//
@ -154,30 +155,43 @@ namespace ShiftOS.WinForms.Applications
this.btnTest.UseVisualStyleBackColor = true;
this.btnTest.Click += new System.EventHandler(this.btnTest_Click);
//
// button1
// btnSave
//
this.button1.Location = new System.Drawing.Point(7, 161);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(47, 23);
this.button1.TabIndex = 12;
this.button1.Text = "Apply";
this.button1.UseVisualStyleBackColor = true;
this.btnSave.Location = new System.Drawing.Point(7, 161);
this.btnSave.Name = "btnSave";
this.btnSave.Size = new System.Drawing.Size(47, 23);
this.btnSave.TabIndex = 13;
this.btnSave.Text = "Save";
this.btnSave.UseVisualStyleBackColor = true;
this.btnSave.Click += new System.EventHandler(this.btnSave_Click);
//
// button2
// btnLoad
//
this.button2.Location = new System.Drawing.Point(60, 161);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(47, 23);
this.button2.TabIndex = 13;
this.button2.Text = "Save";
this.button2.UseVisualStyleBackColor = true;
this.btnLoad.Location = new System.Drawing.Point(60, 161);
this.btnLoad.Name = "btnLoad";
this.btnLoad.Size = new System.Drawing.Size(47, 23);
this.btnLoad.TabIndex = 14;
this.btnLoad.Text = "Load";
this.btnLoad.UseVisualStyleBackColor = true;
this.btnLoad.Click += new System.EventHandler(this.btnLoad_Click);
//
// btnApply
//
this.btnApply.Location = new System.Drawing.Point(113, 161);
this.btnApply.Name = "btnApply";
this.btnApply.Size = new System.Drawing.Size(47, 23);
this.btnApply.TabIndex = 15;
this.btnApply.Text = "Apply";
this.btnApply.UseVisualStyleBackColor = true;
this.btnApply.Click += new System.EventHandler(this.btnApply_Click);
//
// FormatEditor
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Controls.Add(this.btnApply);
this.Controls.Add(this.btnLoad);
this.Controls.Add(this.btnSave);
this.Controls.Add(this.btnTest);
this.Controls.Add(this.richTextBox1);
this.Controls.Add(this.btnAddColor);
@ -204,7 +218,8 @@ namespace ShiftOS.WinForms.Applications
private System.Windows.Forms.Button btnAddColor;
private System.Windows.Forms.RichTextBox richTextBox1;
private System.Windows.Forms.Button btnTest;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.Button btnSave;
private System.Windows.Forms.Button btnLoad;
private System.Windows.Forms.Button btnApply;
}
}

View file

@ -42,9 +42,10 @@ namespace ShiftOS.WinForms.Applications {
public partial class FormatEditor : UserControl, IShiftOSWindow {
IList<CommandFormat> parts = new List<CommandFormat>();
CommandParser parser = new CommandParser();
IList<Panel> editorBoxes = new List<Panel>();
string commandMode = "command";
string commandMode = "namespace";
int avcount = 0;
public FormatEditor() {
@ -66,10 +67,15 @@ namespace ShiftOS.WinForms.Applications {
}
private void addPart(CommandFormat part) {
parts.Add(part);
parser.AddPart(part);
addPart(part.Draw());
}
private void addPart(Control part) {
Panel container = new Panel();
Control drawnPart = part.Draw();
Control drawnPart = part;
container.Size = drawnPart.Size;
container.Controls.Add(drawnPart);
@ -103,6 +109,11 @@ namespace ShiftOS.WinForms.Applications {
private void btnAddCommand_Click(object sender, EventArgs e) {
switch (commandMode) {
case "namespace":
addPart(new CommandFormatNamespace());
commandMode = "command";
btnAddCommand.Text = "+ Command";
break;
case "command":
addPart(new CommandFormatCommand());
commandMode = "argument";
@ -129,215 +140,46 @@ namespace ShiftOS.WinForms.Applications {
}
private void richTextBox1_TextChanged(object sender, EventArgs e) {
string command = "";
Dictionary<string,string> arguments = new Dictionary<string, string>();
var result = parser.ParseCommand(richTextBox1.Text);
string text = richTextBox1.Text;
int position = 0;
int commandPos;
int firstValuePos = -1;
int lastValuePos = -1;
for(int ii = 0; ii < parts.Count; ii++) {
CommandFormat part = parts[ii];
if (part is CommandFormatMarker) {
if (part is CommandFormatCommand) {
commandPos = ii;
} else if (part is CommandFormatValue) {
if (firstValuePos > -1)
lastValuePos = ii;
else
firstValuePos = ii;
}
}
}
int i = 0;
string currentArgument = "";
int help = -1;
while (position < text.Length) {
if (i >= parts.Count) {
position = text.Length;
command = "+FALSE+";
i = 0;
}
CommandFormat part = parts[i];
string res = part.CheckValidity(text.Substring(position));
// ok so:
// example
// COMMAND text[ --] ARGUMENT VALUE text[ --] ARGUMENT VALUE
// COMMAND text[{] ARGUMENT text[=] VALUE text[, ] ARGUMENT text[=] VALUE text[}]
if (part is CommandFormatMarker) {
if (part is CommandFormatCommand) {
command = res;
help = -1;
} else if (part is CommandFormatArgument) {
currentArgument = res;
help = -1;
} else if (part is CommandFormatValue) {
arguments[currentArgument] = res;
if(i == firstValuePos)
help = lastValuePos;
if (i == lastValuePos)
help = firstValuePos;
}
}
if(res == "+FALSE+") {
if(help > -1) {
i = help;
if(i >= parts.Count) {
position = text.Length;
command = "+FALSE+";
}
}else {
position = text.Length;
command = "+FALSE+";
}
help = -1;
}else {
position += res.Length;
}
i++;
}
if (command == "+FALSE+") {
if (result.Equals(default(KeyValuePair<KeyValuePair<string, string>, Dictionary<string, string>>))) {
lblExampleCommand.Text = "Syntax Error";
} else {
string argvs = "{";
foreach (KeyValuePair<string, string> entry in arguments) {
argvs += entry.Key + "=" + entry.Value + ", ";
foreach (KeyValuePair<string, string> entry in result.Value) {
argvs += entry.Key + "=\"" + entry.Value + "\", ";
}
argvs += "}";
lblExampleCommand.Text = command + argvs;
lblExampleCommand.Text = result.Key + argvs;
}
}
private void btnTest_Click(object sender, EventArgs e) {
}
}
interface CommandFormat {
string CheckValidity(string check);
Control Draw();
}
class CommandFormatText : CommandFormat {
protected string str;
TextBox textBox;
private void btnSave_Click(object sender, EventArgs e) {
CurrentCommandParser.parser = parser;
public CommandFormatText() {
FileSkimmerBackend.GetFile(new string[] { ".cf" }, FileOpenerStyle.Save, new Action<string>((result) => {
Objects.ShiftFS.Utils.WriteAllText(result, parser.Save());
}));
}
public virtual string CheckValidity(string check) {
return check.StartsWith(str) ? str : "+FALSE+";
}
public Control Draw() {
textBox = new TextBox();
textBox.TextChanged += new EventHandler(TextChanged);
textBox.Location = new Point(0,0);
return textBox;
}
void TextChanged(object sender, EventArgs e) {
str = textBox.Text;
}
}
class CommandFormatOptionalText : CommandFormatText {
public override string CheckValidity(string check) {
return check.StartsWith(str) ? str : "";
}
}
class CommandFormatMarker : CommandFormat {
protected string str;
Button button;
public CommandFormatMarker() {
}
public virtual string CheckValidity(string check) {
string res = string.Empty;
string alphanumeric = "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm1234567890"; // not using regex for performance reasons
foreach (char c in check) {
if (alphanumeric.IndexOf(c) > -1) {
res += c;
} else {
break;
private void btnLoad_Click(object sender, EventArgs e) {
FileSkimmerBackend.GetFile(new string[] { ".cf" }, FileOpenerStyle.Open, new Action<string>((result) => {
parser = CommandParser.Load(Objects.ShiftFS.Utils.ReadAllText(result));
foreach(CommandFormat part in parser.parts) {
addPart(part.Draw());
}
}
return res;
}));
}
public virtual Control Draw() {
button = new Button();
button.Location = new Point(0, 0);
button.Text = "Marker";
return button;
}
}
class CommandFormatCommand : CommandFormatMarker {
public override Control Draw() {
Button draw = (Button)base.Draw();
draw.Text = "Command";
return draw;
}
}
class CommandFormatArgument : CommandFormatMarker {
public override Control Draw() {
Button draw = (Button)base.Draw();
draw.Text = "Argument";
return draw;
}
}
class CommandFormatValue : CommandFormatMarker {
public override string CheckValidity(string cd) {
string res = string.Empty;
var check = "";
if (cd.StartsWith("\""))
check = cd.Substring(1);
bool done = false;
foreach (char c in check) {
Console.WriteLine(check);
if (c != '"') {
res += c;
} else {
done = true;
res += "\"";
break;
}
}
return done ? "\""+res : "+FALSE+";
}
public override Control Draw() {
Button draw = (Button)base.Draw();
draw.Text = "\"Value\"";
return draw;
private void btnApply_Click(object sender, EventArgs e) {
CurrentCommandParser.parser = parser;
}
}
}

View file

@ -26,20 +26,13 @@ using Newtonsoft.Json;
using ShiftOS.Objects.ShiftFS;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using ShiftOS.Engine;
using ShiftOS.WinForms.Tools;
namespace ShiftOS.WinForms.Applications
{
namespace ShiftOS.WinForms.Applications {
[Launcher("Shifter", true, "al_shifter", "Customization")]
[RequiresUpgrade("shifter")]
[WinOpen("shifter")]

View file

@ -44,13 +44,11 @@ using static ShiftOS.Engine.SkinEngine;
using ShiftOS.Engine;
using ShiftOS.Objects;
namespace ShiftOS.WinForms.Applications
{
namespace ShiftOS.WinForms.Applications {
[Launcher("Terminal", false, null, "Utilities")]
[WinOpen("terminal")]
[DefaultIcon("iconTerminal")]
public partial class Terminal : UserControl, IShiftOSWindow
{
public partial class Terminal : UserControl, IShiftOSWindow {
public static Stack<string> ConsoleStack = new Stack<string>();
public static System.Windows.Forms.Timer ti = new System.Windows.Forms.Timer();
@ -62,81 +60,63 @@ namespace ShiftOS.WinForms.Applications
public static string RemoteGuid = "";
[Obsolete("This is used for compatibility with old parts of the backend. Please use TerminalBackend instead.")]
public static bool PrefixEnabled
{
get
{
public static bool PrefixEnabled {
get {
return TerminalBackend.PrefixEnabled;
}
set
{
set {
TerminalBackend.PrefixEnabled = value;
}
}
[Obsolete("This is used for compatibility with old parts of the backend. Please use TerminalBackend instead.")]
public static bool InStory
{
get
{
public static bool InStory {
get {
return TerminalBackend.InStory;
}
set
{
set {
TerminalBackend.InStory = value;
}
}
[Obsolete("This is used for compatibility with old parts of the backend. Please use TerminalBackend instead.")]
public static string LastCommand
{
get
{
public static string LastCommand {
get {
return TerminalBackend.LastCommand;
}
set
{
set {
TerminalBackend.LastCommand = value;
}
}
public int TutorialProgress
{
get
{
public int TutorialProgress {
get {
throw new NotImplementedException();
}
set
{
set {
throw new NotImplementedException();
}
}
[Obsolete("This is used for compatibility with old parts of the backend. Please use TerminalBackend instead.")]
public static void InvokeCommand(string text)
{
public static void InvokeCommand(string text) {
TerminalBackend.InvokeCommand(text);
}
public Terminal()
{
public Terminal() {
InitializeComponent();
SaveSystem.GameReady += () =>
{
try
{
this.Invoke(new Action(() =>
{
SaveSystem.GameReady += () => {
try {
this.Invoke(new Action(() => {
ResetAllKeywords();
rtbterm.Text = "";
TerminalBackend.PrefixEnabled = true;
TerminalBackend.InStory = false;
Console.Write($"{SaveSystem.CurrentSave.Username}@{SaveSystem.CurrentSave.SystemName}:~$ ");
if (Shiftorium.UpgradeInstalled("wm_free_placement"))
{
if (Shiftorium.UpgradeInstalled("wm_free_placement")) {
this.ParentForm.Width = 640;
this.ParentForm.Height = 480;
this.ParentForm.Left = (Screen.PrimaryScreen.Bounds.Width - 640) / 2;
@ -144,8 +124,7 @@ namespace ShiftOS.WinForms.Applications
}
}));
}
catch { }
} catch { }
};
@ -153,32 +132,21 @@ namespace ShiftOS.WinForms.Applications
}
public void FocusOnTerminal()
{
public void FocusOnTerminal() {
rtbterm.Focus();
}
public static string GetTime()
{
public static string GetTime() {
var time = DateTime.Now;
if (ShiftoriumFrontend.UpgradeInstalled("full_precision_time"))
{
if (ShiftoriumFrontend.UpgradeInstalled("full_precision_time")) {
return DateTime.Now.ToString("h:mm:ss tt");
}
else if (ShiftoriumFrontend.UpgradeInstalled("clock_am_and_pm"))
{
} else if (ShiftoriumFrontend.UpgradeInstalled("clock_am_and_pm")) {
return time.TimeOfDay.TotalHours > 12 ? $"{time.Hour - 12} PM" : $"{time.Hour} AM";
}
else if (ShiftoriumFrontend.UpgradeInstalled("clock_hours"))
{
} else if (ShiftoriumFrontend.UpgradeInstalled("clock_hours")) {
return ((int)time.TimeOfDay.TotalHours).ToString();
}
else if (ShiftoriumFrontend.UpgradeInstalled("clock_minutes"))
{
} else if (ShiftoriumFrontend.UpgradeInstalled("clock_minutes")) {
return ((int)time.TimeOfDay.TotalMinutes).ToString();
}
else if (ShiftoriumFrontend.UpgradeInstalled("clock"))
{
} else if (ShiftoriumFrontend.UpgradeInstalled("clock")) {
return ((int)time.TimeOfDay.TotalSeconds).ToString();
}
@ -188,8 +156,7 @@ namespace ShiftOS.WinForms.Applications
public static event TextSentEventHandler TextSent;
public void ResetAllKeywords()
{
public void ResetAllKeywords() {
string primary = SaveSystem.CurrentSave.Username + " ";
string secondary = "shiftos ";
@ -198,27 +165,18 @@ namespace ShiftOS.WinForms.Applications
var types = asm.GetTypes();
foreach (var type in types)
{
foreach (var a in type.GetCustomAttributes(false))
{
if (ShiftoriumFrontend.UpgradeAttributesUnlocked(type))
{
if (a is Namespace)
{
foreach (var type in types) {
foreach (var a in type.GetCustomAttributes(false)) {
if (ShiftoriumFrontend.UpgradeAttributesUnlocked(type)) {
if (a is Namespace) {
var ns = a as Namespace;
if (!primary.Contains(ns.name))
{
if (!primary.Contains(ns.name)) {
primary += ns.name + " ";
}
foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.Static))
{
if (ShiftoriumFrontend.UpgradeAttributesUnlocked(method))
{
foreach (var ma in method.GetCustomAttributes(false))
{
if (ma is Command)
{
foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.Static)) {
if (ShiftoriumFrontend.UpgradeAttributesUnlocked(method)) {
foreach (var ma in method.GetCustomAttributes(false)) {
if (ma is Command) {
var cmd = ma as Command;
if (!secondary.Contains(cmd.name))
secondary += cmd.name + " ";
@ -234,19 +192,14 @@ namespace ShiftOS.WinForms.Applications
}
public static void MakeWidget(Controls.TerminalBox txt)
{
public static void MakeWidget(Controls.TerminalBox txt) {
AppearanceManager.StartConsoleOut();
txt.GotFocus += (o, a) =>
{
txt.GotFocus += (o, a) => {
AppearanceManager.ConsoleOut = txt;
};
txt.KeyDown += (o, a) =>
{
if (a.KeyCode == Keys.Enter)
{
try
{
txt.KeyDown += (o, a) => {
if (a.KeyCode == Keys.Enter) {
try {
a.SuppressKeyPress = true;
Console.WriteLine("");
var text = txt.Lines.ToArray();
@ -254,60 +207,55 @@ namespace ShiftOS.WinForms.Applications
var text3 = "";
var text4 = Regex.Replace(text2, @"\t|\n|\r", "");
if (IsInRemoteSystem == true)
{
ServerManager.SendMessage("trm_invcmd", JsonConvert.SerializeObject(new
{
if (IsInRemoteSystem == true) {
ServerManager.SendMessage("trm_invcmd", JsonConvert.SerializeObject(new {
guid = RemoteGuid,
command = text4
}));
}
else
{
if (TerminalBackend.PrefixEnabled)
{
} else {
if (TerminalBackend.PrefixEnabled) {
text3 = text4.Remove(0, $"{SaveSystem.CurrentSave.Username}@{SaveSystem.CurrentSave.SystemName}:~$ ".Length);
}
TerminalBackend.LastCommand = text3;
TextSent?.Invoke(text4);
if (TerminalBackend.InStory == false)
{
TerminalBackend.InvokeCommand(text3);
if (TerminalBackend.InStory == false) {
if(text3 == "stop theme") {
CurrentCommandParser.parser = null;
}else {
if(CurrentCommandParser.parser == null) {
TerminalBackend.InvokeCommand(text3);
} else {
var result = CurrentCommandParser.parser.ParseCommand(text3);
if (result.Equals(default(KeyValuePair<KeyValuePair<string, string>, Dictionary<string, string>>))) {
Console.WriteLine("Syntax Error: Syntax Error");
} else {
TerminalBackend.InvokeCommand(result.Key.Key, result.Key.Value, result.Value);
}
}
}
}
if (TerminalBackend.PrefixEnabled)
{
if (TerminalBackend.PrefixEnabled) {
Console.Write($"{SaveSystem.CurrentSave.Username}@{SaveSystem.CurrentSave.SystemName}:~$ ");
}
}
} catch {
}
catch
{
}
}
else if (a.KeyCode == Keys.Back)
{
try
{
} else if (a.KeyCode == Keys.Back) {
try {
var tostring3 = txt.Lines[txt.Lines.Length - 1];
var tostringlen = tostring3.Length + 1;
var workaround = $"{SaveSystem.CurrentSave.Username}@{SaveSystem.CurrentSave.SystemName}:~$ ";
var derp = workaround.Length + 1;
if (tostringlen != derp)
{
if (tostringlen != derp) {
AppearanceManager.CurrentPosition--;
}
else
{
} else {
a.SuppressKeyPress = true;
}
}
catch
{
} catch {
Debug.WriteLine("Drunky alert in terminal.");
}
}
else if (a.KeyCode == Keys.Left)
{
} else if (a.KeyCode == Keys.Left) {
var getstring = txt.Lines[txt.Lines.Length - 1];
var stringlen = getstring.Length + 1;
var header = $"{SaveSystem.CurrentSave.Username}@{SaveSystem.CurrentSave.SystemName}:~$ ";
@ -316,28 +264,19 @@ namespace ShiftOS.WinForms.Applications
var remstrlen = txt.TextLength - stringlen;
var finalnum = selstart - remstrlen;
if (finalnum != headerlen)
{
if (finalnum != headerlen) {
AppearanceManager.CurrentPosition--;
}
else
{
} else {
a.SuppressKeyPress = true;
}
}
//( ͡° ͜ʖ ͡° ) You found the lennyface without looking at the commit message. Message Michael in the #shiftos channel on Discord saying "ladouceur" somewhere in your message if you see this.
else if (a.KeyCode == Keys.Up)
{
} else if (a.KeyCode == Keys.Up) {
var tostring3 = txt.Lines[txt.Lines.Length - 1];
if (tostring3 == $"{SaveSystem.CurrentSave.Username}@{SaveSystem.CurrentSave.SystemName}:~$ ")
Console.Write(TerminalBackend.LastCommand);
a.SuppressKeyPress = true;
}
else
{
if (TerminalBackend.InStory)
{
} else {
if (TerminalBackend.InStory) {
a.SuppressKeyPress = true;
}
AppearanceManager.CurrentPosition++;
@ -346,7 +285,7 @@ namespace ShiftOS.WinForms.Applications
};
AppearanceManager.ConsoleOut = txt;
txt.Focus();
txt.Font = LoadedSkin.TerminalFont;
@ -355,17 +294,12 @@ namespace ShiftOS.WinForms.Applications
}
private void Terminal_Load(object sender, EventArgs e)
{
ServerManager.MessageReceived += (msg) =>
{
if(msg.Name == "trm_handshake_guid")
{
private void Terminal_Load(object sender, EventArgs e) {
ServerManager.MessageReceived += (msg) => {
if (msg.Name == "trm_handshake_guid") {
IsInRemoteSystem = true;
RemoteGuid = msg.GUID;
}
else if(msg.Name == "trm_handshake_stop")
{
} else if (msg.Name == "trm_handshake_stop") {
IsInRemoteSystem = false;
RemoteGuid = "";
}
@ -373,21 +307,17 @@ namespace ShiftOS.WinForms.Applications
}
private void Terminal_FormClosing(object sender, FormClosingEventArgs e)
{
private void Terminal_FormClosing(object sender, FormClosingEventArgs e) {
ti.Stop();
IsInRemoteSystem = false;
RemoteGuid = "";
}
public void OnLoad()
{
public void OnLoad() {
MakeWidget(rtbterm);
if (SaveSystem.CurrentSave != null)
{
if (!ShiftoriumFrontend.UpgradeInstalled("window_manager"))
{
if (SaveSystem.CurrentSave != null) {
if (!ShiftoriumFrontend.UpgradeInstalled("window_manager")) {
rtbterm.Text = AppearanceManager.LastTerminalText;
rtbterm.Select(rtbterm.TextLength, 0);
}
@ -398,42 +328,30 @@ namespace ShiftOS.WinForms.Applications
}
public void OnSkinLoad()
{
try
{
public void OnSkinLoad() {
try {
rtbterm.Font = LoadedSkin.TerminalFont;
rtbterm.ForeColor = LoadedSkin.TerminalForeColor;
rtbterm.BackColor = LoadedSkin.TerminalBackColor;
}
catch
{
} catch {
}
}
public bool OnUnload()
{
if (SaveSystem.ShuttingDown == false)
{
if (!ShiftoriumFrontend.UpgradeInstalled("desktop"))
{
if (AppearanceManager.OpenForms.Count <= 1)
{
public bool OnUnload() {
if (SaveSystem.ShuttingDown == false) {
if (!ShiftoriumFrontend.UpgradeInstalled("desktop")) {
if (AppearanceManager.OpenForms.Count <= 1) {
Console.WriteLine("");
Console.WriteLine("{WIN_CANTCLOSETERMINAL}");
try
{
try {
Console.WriteLine("");
if (TerminalBackend.PrefixEnabled)
{
if (TerminalBackend.PrefixEnabled) {
Console.Write($"{SaveSystem.CurrentSave.Username}@shiftos:~$ ");
}
}
catch (Exception ex)
{
} catch (Exception ex) {
Console.WriteLine(ex);
}
return false;
@ -443,15 +361,13 @@ namespace ShiftOS.WinForms.Applications
return true;
}
public void OnUpgrade()
{
public void OnUpgrade() {
}
private void rtbterm_TextChanged(object sender, EventArgs e)
{
private void rtbterm_TextChanged(object sender, EventArgs e) {
}
}
}
//lol you found this comment i made so i chould push a change to make a point.

View file

@ -0,0 +1,366 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ShiftOS.Engine {
public static class CurrentCommandParser {
public static CommandParser parser;
}
public class CommandParser {
public IList<CommandFormat> parts = new List<CommandFormat>();
public void AddPart(CommandFormat part) {
parts.Add(part);
}
public void ImportPart(IList<CommandFormat> parts) {
this.parts = parts;
}
public string Save() {
JArray data = new JArray();
foreach(CommandFormat part in parts) {
CFValue val = new CFValue(part);
JObject obj = new JObject();
obj["type"] = new JValue(val.type);
obj["text"] = new JValue(val.text);
data.Add(obj);
}
return data.ToString();
}
public static CommandParser Load(string val) {
CommandParser parser = new CommandParser();
JArray data = JArray.Parse(val);
IList<CFValue> values = data.Select(obj => new CFValue (
(string)obj["type"],
(string)obj["text"]
)).ToList();
foreach(CFValue value in values) {
parser.AddPart(value.GetCommandFormat());
}
return parser;
}
public KeyValuePair<KeyValuePair<string, string>, Dictionary<string, string>> ParseCommand(string cdd) {
string command = "";
string ns = "";
Dictionary<string, string> arguments = new Dictionary<string, string>();
string text = cdd;
int position = 0;
int commandPos;
int firstValuePos = -1;
int lastValuePos = -1;
string syntaxError = "";
for (int ii = 0; ii < parts.Count; ii++) {
CommandFormat part = parts[ii];
if (part is CommandFormatMarker) {
if (part is CommandFormatCommand) {
commandPos = ii;
} else if (part is CommandFormatValue) {
if (firstValuePos > -1)
lastValuePos = ii;
else
firstValuePos = ii;
}
}
}
int i = 0;
string currentArgument = "";
int help = -1;
while (position < text.Length) {
if (i >= parts.Count) {
position = text.Length;
command = "+FALSE+";
i = 0;
}
CommandFormat part = parts[i];
string res = part.CheckValidity(text.Substring(position));
// ok so:
// example
// COMMAND text[ --] ARGUMENT VALUE text[ --] ARGUMENT VALUE
// COMMAND text[{] ARGUMENT text[=] VALUE text[, ] ARGUMENT text[=] VALUE text[}]
if (part is CommandFormatMarker) {
if (part is CommandFormatNamespace) {
ns = res;
help = -1;
}else if (part is CommandFormatCommand) {
command = res;
help = -1;
} else if (part is CommandFormatArgument) {
currentArgument = res;
help = -1;
} else if (part is CommandFormatValue) {
arguments[currentArgument] = string.Join("", res.Split('"'));
if (i == firstValuePos)
help = lastValuePos;
if (i == lastValuePos)
help = firstValuePos;
}
}
if (res == "+FALSE+") {
if (help > -1) {
i = help;
if (i >= parts.Count) {
position = text.Length;
command = "+FALSE+";
}
} else {
position = text.Length;
syntaxError = "Syntax Error";
command = "+FALSE+";
}
help = -1;
} else {
position += res.Length;
}
i++;
}
if (command == "+FALSE+") {
//lblExampleCommand.Text = "Syntax Error";
return new KeyValuePair<KeyValuePair<string, string>, Dictionary<string, string>>();
} else {
/*string argvs = "{";
foreach (KeyValuePair<string, string> entry in arguments) {
argvs += entry.Key + "=" + entry.Value + ", ";
}
argvs += "}";
lblExampleCommand.Text = command + argvs;*/
return new KeyValuePair<KeyValuePair<string, string>, Dictionary<string, string>> (new KeyValuePair<string, string>(ns, command), arguments);
}
}
}
public class CFValue {
public string type { get; set; }
public string text { get; set; }
public CFValue(string type, string text) {
this.type = type;
this.text = text;
}
public CFValue(CommandFormat format) {
type = "";
text = "";
if(format is CommandFormatText) {
text = ((CommandFormatText) format).str;
if(format is CommandFormatOptionalText) {
type = "optionalText";
}else if (format is CommandFormatRegex) {
type = "regexText";
}else {
type = "text";
}
}else if (format is CommandFormatMarker) {
if (format is CommandFormatNamespace) {
type = "namespace";
} else if (format is CommandFormatCommand) {
type = "command";
} else if (format is CommandFormatArgument) {
type = "argument";
} else if (format is CommandFormatValue) {
type = "value";
}
}
}
public CommandFormat GetCommandFormat() { // TODO update with better code
switch (type) {
case "text":
return new CommandFormatText(text);
case "optionalText":
return new CommandFormatOptionalText(text);
case "regexText":
return new CommandFormatRegex(text);
case "namespace":
return new CommandFormatNamespace();
case "command":
return new CommandFormatCommand();
case "argument":
return new CommandFormatArgument();
case "value":
return new CommandFormatValue();
case "color":
throw new NotImplementedException(); // fix this (make it not a notimplementedexception)
}
return new CommandFormatMarker();
}
}
public interface CommandFormat {
string CheckValidity(string check);
Control Draw();
}
public class CommandFormatText : CommandFormat {
public string str = "";
TextBox textBox;
public CommandFormatText() {
}
public CommandFormatText(string str) {
this.str = str;
}
public virtual string CheckValidity(string check) {
return check.StartsWith(str) ? str : "+FALSE+";
}
public Control Draw() {
textBox = new TextBox();
textBox.TextChanged += new EventHandler(TextChanged);
textBox.Location = new Point(0, 0);
textBox.Text = str;
return textBox;
}
void TextChanged(object sender, EventArgs e) {
str = textBox.Text;
}
}
public class CommandFormatOptionalText : CommandFormatText {
public CommandFormatOptionalText() : base() {
}
public CommandFormatOptionalText(string str) : base(str) {
}
public override string CheckValidity(string check) {
return check.StartsWith(str) ? str : "";
}
}
public class CommandFormatRegex : CommandFormatText {
public CommandFormatRegex() : base() {
}
public CommandFormatRegex(string str) : base(str) {
}
public override string CheckValidity(string check) {
Match match = (new Regex("^" + str)).Match(check);
return match.Success ? match.Value : "+FALSE+";
}
}
public class CommandFormatMarker : CommandFormat {
protected string str;
Button button;
public CommandFormatMarker() {
}
public virtual string CheckValidity(string check) {
string res = string.Empty;
string alphanumeric = "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm"; // not using regex for performance reasons
foreach (char c in check) {
if (alphanumeric.IndexOf(c) > -1) {
res += c;
} else {
break;
}
}
return res;
}
public virtual Control Draw() {
button = new Button();
button.Location = new Point(0, 0);
button.Text = "Marker";
return button;
}
}
public class CommandFormatCommand : CommandFormatMarker {
public override Control Draw() {
Button draw = (Button)base.Draw();
draw.Text = "Command";
return draw;
}
}
public class CommandFormatNamespace : CommandFormatMarker {
public override Control Draw() {
Button draw = (Button)base.Draw();
draw.Text = "Namespace";
return draw;
}
}
public class CommandFormatArgument : CommandFormatMarker {
public override Control Draw() {
Button draw = (Button)base.Draw();
draw.Text = "Argument";
return draw;
}
}
public class CommandFormatValue : CommandFormatMarker {
public override string CheckValidity(string cd) {
string res = string.Empty;
var check = "";
bool done = false;
if (cd.StartsWith("\"")) {
check = cd.Substring(1);
foreach (char c in check) {
if (c != '"') {
res += c;
} else {
done = true;
res = "\"" + res + "\"";
break;
}
}
} else{
res = base.CheckValidity(cd);
done = true;
}
return done ? res : "+FALSE+";
}
public override Control Draw() {
Button draw = (Button)base.Draw();
draw.Text = "\"Value\"";
return draw;
}
}
}

View file

@ -305,6 +305,7 @@ namespace ShiftOS.Engine
[RequiresArgument("type")]
public static bool MultArg(Dictionary<string, object> args)
{
Console.WriteLine("Success! "+args.ToString());
return true;
}

View file

@ -97,6 +97,7 @@
<Compile Include="AppearanceManager.cs" />
<Compile Include="AppLauncherDaemon.cs" />
<Compile Include="AudioManager.cs" />
<Compile Include="CommandParser.cs" />
<Compile Include="Commands.cs" />
<Compile Include="Command.cs" />
<Compile Include="CrashHandler.cs" />

View file

@ -32,26 +32,21 @@ using System.Threading.Tasks;
using Newtonsoft.Json;
using static ShiftOS.Engine.SaveSystem;
namespace ShiftOS.Engine
{
public static class TerminalBackend
{
namespace ShiftOS.Engine {
public static class TerminalBackend {
public static event Action<string, string> CommandProcessed;
public static bool Elevated { get; set; }
public static Dictionary<string, object> GetArgs(ref string text)
{
public static Dictionary<string, string> GetArgs(ref string text) {
bool shouldParse = false;
int argStart = 0;
if (text.Contains("{"))
{
if (text.Contains("{")) {
shouldParse = true;
argStart = text.IndexOf('{');
}
if (shouldParse == false)
{
if (shouldParse == false) {
string replacement = Regex.Replace(text, @"\t|\n|\r", "");
text = replacement + "{}";
shouldParse = true;
@ -61,15 +56,47 @@ namespace ShiftOS.Engine
string args = text.Substring(argStart, text.Length - argStart);
text = text.Remove(argStart, text.Length - argStart).Replace(" ", "");
return JsonConvert.DeserializeObject<Dictionary<string, object>>(args);
return JsonConvert.DeserializeObject<Dictionary<string, string>>(args);
}
public static string LastCommand = "";
public static void InvokeCommand(string text, bool isRemote = false)
{
try
{
public static void InvokeCommand(string ns, string command, Dictionary<string, string> arguments, bool isRemote = false) {
try {
if (string.IsNullOrWhiteSpace(ns))
return;
bool commandWasClient = RunClient(ns, command, arguments, isRemote);
if (!commandWasClient && !string.IsNullOrWhiteSpace(ns)) {
PrefixEnabled = false;
ServerManager.SendMessage("script", $@"{{
user: ""{ns}"",
script: ""{command}"",
args: ""{GetSentArgs(arguments)}""
}}");
}
CommandProcessed?.Invoke(ns + "." + command, JsonConvert.SerializeObject(arguments));
} catch (Exception ex) {
Console.WriteLine($"Command parse error: {ex.Message}"); // This shouldn't ever be called now
PrefixEnabled = true;
}
}
public static string GetSentArgs(Dictionary<string, string> argss) {
Dictionary<string, object> args = new Dictionary<string, object>();
foreach (KeyValuePair<string, string> arg in argss) {
args[arg.Key] = arg.Value;
}
return JsonConvert.SerializeObject(args);
}
public static void InvokeCommand(string text, bool isRemote = false) {
try {
if (string.IsNullOrWhiteSpace(text))
return;
@ -77,19 +104,17 @@ namespace ShiftOS.Engine
bool commandWasClient = RunClient(text, args, isRemote);
if (!commandWasClient && !string.IsNullOrWhiteSpace(text))
{
if (!commandWasClient) {
PrefixEnabled = false;
ServerManager.SendMessage("script", $@"{{
user: ""{text.Split('.')[0]}"",
script: ""{text.Split('.')[1]}"",
args: ""{JsonConvert.SerializeObject(args)}""
args: ""{GetSentArgs(args)}""
}}");
}
CommandProcessed?.Invoke(text, JsonConvert.SerializeObject(args));
}
catch (Exception ex)
{
CommandProcessed?.Invoke(text, GetSentArgs(args));
} catch (Exception ex) {
Console.WriteLine($"Command parse error: {ex.Message}");
PrefixEnabled = true;
@ -104,18 +129,15 @@ namespace ShiftOS.Engine
public static event EmptyEventHandler TerminalRequested;
internal static void OpenTerminal()
{
internal static void OpenTerminal() {
TerminalRequested?.Invoke();
}
public static bool CanRunRemotely(MethodInfo mth, bool isRemote)
{
public static bool CanRunRemotely(MethodInfo mth, bool isRemote) {
if (!isRemote)
return true;
foreach(var attr in mth.GetCustomAttributes(false))
{
foreach (var attr in mth.GetCustomAttributes(false)) {
if (attr is RemoteLockAttribute)
return false;
}
@ -123,60 +145,45 @@ namespace ShiftOS.Engine
return true;
}
public static bool RunClient(string text, Dictionary<string, object> args, bool isRemote = false)
{
public static bool RunClient(string ns, string cmd, Dictionary<string, string> args, bool isRemote = false) {
return RunClient(ns + "." + cmd, args, isRemote);
}
public static bool RunClient(string text, Dictionary<string, string> args, bool isRemote = false) {
latestCommmand = text;
foreach (var asmExec in System.IO.Directory.GetFiles(Environment.CurrentDirectory))
{
try
{
foreach (var asmExec in System.IO.Directory.GetFiles(Environment.CurrentDirectory)) {
try {
var asm = Assembly.LoadFile(asmExec);
var types = asm.GetTypes();
foreach (var type in types)
{
if (Shiftorium.UpgradeAttributesUnlocked(type))
{
if (KernelWatchdog.IsSafe(type))
{
foreach (var a in type.GetCustomAttributes(false))
{
if (a is Namespace)
{
foreach (var type in types) {
if (Shiftorium.UpgradeAttributesUnlocked(type)) {
if (KernelWatchdog.IsSafe(type)) {
foreach (var a in type.GetCustomAttributes(false)) {
if (a is Namespace) {
var ns = a as Namespace;
if (text.Split('.')[0] == ns.name)
{
foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.Static))
{
if (Shiftorium.UpgradeAttributesUnlocked(method))
{
if (KernelWatchdog.IsSafe(method))
{
if (CanRunRemotely(method, isRemote))
{
foreach (var ma in method.GetCustomAttributes(false))
{
if (ma is Command)
{
if (text.Split('.')[0] == ns.name) {
foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.Static)) {
if (Shiftorium.UpgradeAttributesUnlocked(method)) {
if (KernelWatchdog.IsSafe(method)) {
if (CanRunRemotely(method, isRemote)) {
foreach (var ma in method.GetCustomAttributes(false)) {
if (ma is Command) {
var cmd = ma as Command;
if (text.Split('.')[1] == cmd.name)
{
if (text.Split('.')[1] == cmd.name) {
var attr = method.GetCustomAttribute<CommandObsolete>();
if (attr != null)
{
if (attr != null) {
string newcommand = attr.newcommand;
if (attr.warn)
{
if (attr.warn) {
Console.WriteLine(Localization.Parse((newcommand == "" ? "{ERROR}" : "{WARN}") + attr.reason, new Dictionary<string, string>() {
{"%newcommand", newcommand}
}));
}
if (newcommand != "")
{
if (newcommand != "") {
// redo the entire process running newcommand
return RunClient(newcommand, args);
@ -188,13 +195,10 @@ namespace ShiftOS.Engine
bool error = false;
bool providedusage = false;
foreach (RequiresArgument argument in requiresArgs)
{
if (!args.ContainsKey(argument.argument))
{
foreach (RequiresArgument argument in requiresArgs) {
if (!args.ContainsKey(argument.argument)) {
if (!providedusage)
{
if (!providedusage) {
string usageparse = "{COMMAND_" + ns.name.ToUpper() + "_" + cmd.name.ToUpper() + "_USAGE}";
if (usageparse == Localization.Parse(usageparse))
usageparse = "";
@ -209,14 +213,11 @@ namespace ShiftOS.Engine
providedusage = true;
}
if (Shiftorium.UpgradeInstalled("help_usage"))
{
if (Shiftorium.UpgradeInstalled("help_usage")) {
Console.WriteLine(Localization.Parse("{ERROR_ARGUMENT_REQUIRED}", new Dictionary<string, string>() {
{"%argument", argument.argument}
}));
}
else
{
} else {
Console.WriteLine(Localization.Parse("{ERROR_ARGUMENT_REQUIRED_NO_USAGE}"));
}
@ -224,89 +225,69 @@ namespace ShiftOS.Engine
}
}
if (error)
{
if (error) {
throw new Exception("{ERROR_COMMAND_WRONG}");
}
try
{
try {
return (bool)method.Invoke(null, new[] { args });
}
catch (TargetInvocationException e)
{
} catch (TargetInvocationException e) {
Console.WriteLine(Localization.Parse("{ERROR_EXCEPTION_THROWN_IN_METHOD}"));
Console.WriteLine(e.InnerException.Message);
Console.WriteLine(e.InnerException.StackTrace);
return true;
}
catch
{
} catch {
return (bool)method.Invoke(null, new object[] { });
}
}
}
}
}
else
{
} else {
Console.WriteLine(text + " cannot be ran in a remote session");
return true;
}
}
}
}
}
}
}
}
}
}
}
catch { }
} catch { }
}
return false;
}
static TerminalBackend()
{
ServerMessageReceived onMessageReceived = (msg) =>
{
if (msg.Name == "trm_invokecommand")
{
static TerminalBackend() {
ServerMessageReceived onMessageReceived = (msg) => {
if (msg.Name == "trm_invokecommand") {
string text3 = "";
string text4 = msg.Contents;
if (TerminalBackend.PrefixEnabled)
{
if (TerminalBackend.PrefixEnabled) {
text3 = text4.Remove(0, $"{SaveSystem.CurrentSave.Username}@{SaveSystem.CurrentSave.SystemName}:~$ ".Length);
}
IsForwardingConsoleWrites = true;
if (TerminalBackend.InStory == false)
{
if (TerminalBackend.InStory == false) {
TerminalBackend.InvokeCommand(text3, true);
}
if (TerminalBackend.PrefixEnabled)
{
if (TerminalBackend.PrefixEnabled) {
Console.Write($"{SaveSystem.CurrentSave.Username}@{SaveSystem.CurrentSave.SystemName}:~$ ");
}
IsForwardingConsoleWrites = false;
}
else if (msg.Name == "pleasewrite")
{
} else if (msg.Name == "pleasewrite") {
Console.Write(msg.Contents);
}
else if(msg.Name == "handshake_from")
{
} else if (msg.Name == "handshake_from") {
var a = JsonConvert.DeserializeObject<Dictionary<string, object>>(msg.Contents);
string uName = a["username"] as string;
string pass = a["password"] as string;
string sys = a["sysname"] as string;
string guid = msg.GUID;
if(SaveSystem.CurrentSave.Username == uName && SaveSystem.CurrentSave.Password == pass && CurrentSave.SystemName == sys)
{
if (SaveSystem.CurrentSave.Username == uName && SaveSystem.CurrentSave.Password == pass && CurrentSave.SystemName == sys) {
ForwardGUID = guid;
ServerManager.SendMessage("trm_handshake_accept", $@"{{
guid: ""{ServerManager.thisGuid}"",
@ -326,6 +307,6 @@ namespace ShiftOS.Engine
public static bool IsForwardingConsoleWrites { get; internal set; }
public static string ForwardGUID { get; internal set; }
}
}