diff --git a/DTLib/FileWork.cs b/DTLib/FileWork.cs index ce5a53b..1978c9a 100644 --- a/DTLib/FileWork.cs +++ b/DTLib/FileWork.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.IO; namespace DTLib { @@ -14,12 +13,7 @@ namespace DTLib { lock (new object()) { - File.Create(logfile); - var st = File.OpenAppend(logfile); - var writer = new StreamWriter(st, SimpleConverter.UTF8); - writer.Write(msg); - writer.Close(); - st.Close(); + File.WriteAllText(logfile, msg); } } @@ -29,7 +23,7 @@ namespace DTLib lock (new object()) { key += ": "; - using var reader = new StreamReader(configfile); + using var reader = new System.IO.StreamReader(configfile); while (!reader.EndOfStream) { string st = reader.ReadLine(); @@ -66,7 +60,7 @@ namespace DTLib } } reader.Close(); - throw new System.Exception($"ReadFromConfig({configfile}, {key}) error: key not found"); + throw new Exception($"ReadFromConfig({configfile}, {key}) error: key not found"); } } @@ -137,6 +131,7 @@ namespace DTLib } public static string[] GetFiles(string dir) => System.IO.Directory.GetFiles(dir); + public static string[] GetFiles(string dir, string searchPattern) => System.IO.Directory.GetFiles(dir, searchPattern); public static string[] GetDirectories(string dir) => System.IO.Directory.GetDirectories(dir); // выдает список всех файлов @@ -208,7 +203,7 @@ namespace DTLib public static byte[] ReadAllBytes(string file) { - using FileStream stream = System.IO.File.OpenRead(file); + using var stream = File.OpenRead(file); int size = GetSize(file); byte[] output = new byte[size]; stream.Read(output, 0, size); @@ -220,8 +215,7 @@ namespace DTLib public static void WriteAllBytes(string file, byte[] content) { - File.Create(file); - using FileStream stream = System.IO.File.OpenWrite(file); + using var stream = File.OpenWrite(file); stream.Write(content, 0, content.Length); stream.Close(); } @@ -231,27 +225,27 @@ namespace DTLib public static void AppendAllBytes(string file, byte[] content) { File.Create(file); - using FileStream stream = System.IO.File.OpenWrite(file); - stream.Write(content, GetSize(file), content.Length); + using var stream = File.OpenAppend(file); + stream.Write(content, 0, content.Length); stream.Close(); } public static void AppendAllText(string file, string content) => AppendAllBytes(file, content.ToBytes()); - public static FileStream OpenRead(string file) + public static System.IO.FileStream OpenRead(string file) { if (!Exists(file)) throw new Exception($"file not found: <{file}>"); return System.IO.File.OpenRead(file); } - public static FileStream OpenWrite(string file) + public static System.IO.FileStream OpenWrite(string file) { File.Create(file); return System.IO.File.OpenWrite(file); } - public static FileStream OpenAppend(string file) + public static System.IO.FileStream OpenAppend(string file) { File.Create(file); - return System.IO.File.Open(file, FileMode.Append); + return System.IO.File.Open(file, System.IO.FileMode.Append); } } } diff --git a/DTLib/Hasher.cs b/DTLib/Hasher.cs index 05b3c87..787b9f6 100644 --- a/DTLib/Hasher.cs +++ b/DTLib/Hasher.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -using System.IO; using System.Security.Cryptography; +using static DTLib.Filework; namespace DTLib { diff --git a/DTLib/NetWork.cs b/DTLib/NetWork.cs index 20a89be..5d7e75a 100644 --- a/DTLib/NetWork.cs +++ b/DTLib/NetWork.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; -//using System.IO; using System.Net; using System.Net.Sockets; using System.Threading; @@ -141,7 +140,6 @@ namespace DTLib } fileStream.Close(); Log(new string[] { "g", $" uploaded {packagesCount * 5120 + buffer.Length} of {fileSize} bytes\n" }); - } // получает с сайта публичный ip @@ -163,33 +161,6 @@ namespace DTLib return rezult.Remove(rezult.Length - 4); } - // скачивание файла с фтп сервера - /*public static void FtpDownload(string address, string login, string password, string outfile) - { - try - { - // debug - Log(new string[] { "y", "file on server: <", "c", address, "y", ">\nfile on client: <", "c", outfile, "y", ">\n" }); - // создание запроса - // "ftp://m1net.keenetic.pro:20000/" + @infile - FtpWebRequest request = (FtpWebRequest)WebRequest.Create(address); - request.Credentials = new NetworkCredential(login, password); - request.Method = WebRequestMethods.Ftp.DownloadFile; - // получение ответа на запрос - FtpWebResponse response = (FtpWebResponse)request.GetResponse(); - Stream responseStream = response.GetResponseStream(); - FileStream fs = new FileStream(@Directory.GetCurrentDirectory() + '\\' + @outfile, FileMode.Create); - byte[] buffer = new byte[64]; - int size = 0; - - while ((size = responseStream.Read(buffer, 0, buffer.Length)) > 0) - fs.Write(buffer, 0, size); - fs.Close(); - response.Close(); - } - catch (WebException e) { throw new Exception("ftp error:\n" + ((FtpWebResponse)e.Response).StatusDescription + '\n'); } - }*/ - public class FSP { Socket mainSocket; diff --git a/dtlauncher-client-win/LauncherWindow.xaml.cs b/dtlauncher-client-win/LauncherWindow.xaml.cs index fe29a2e..8855e63 100644 --- a/dtlauncher-client-win/LauncherWindow.xaml.cs +++ b/dtlauncher-client-win/LauncherWindow.xaml.cs @@ -1,9 +1,9 @@ using DTLib; using System; -using System.IO; using System.Net.Sockets; using System.Text; using System.Windows; +using static DTLib.Filework; namespace dtlauncher_client_win { diff --git a/dtlauncher-client-win/LoginWindow.xaml.cs b/dtlauncher-client-win/LoginWindow.xaml.cs index a8f39ec..f07aae9 100644 --- a/dtlauncher-client-win/LoginWindow.xaml.cs +++ b/dtlauncher-client-win/LoginWindow.xaml.cs @@ -1,10 +1,10 @@ using DTLib; using System; -using System.IO; using System.Net; using System.Net.Sockets; using System.Text; using System.Windows; +using static DTLib.Filework; namespace dtlauncher_client_win { @@ -23,11 +23,11 @@ namespace dtlauncher_client_win { InitializeComponent(); LogBox.Text = " \n"; // костыль для работы Log() - Filework.Directory.Create("logs"); - Filework.Directory.Create("downloads"); - Filework.Directory.Create("installed"); - Filework.Directory.Create("installscripts"); - Filework.Directory.Create("launchinfo"); + Directory.Create("logs"); + Directory.Create("downloads"); + Directory.Create("installed"); + Directory.Create("installscripts"); + Directory.Create("launchinfo"); PublicLog.Log += Log; LoginButton.Click += Login; RegisterButton.Click += Register; @@ -122,7 +122,7 @@ namespace dtlauncher_client_win public void Log(string msg) { if (LogBox.Text[LogBox.Text.Length - 1] == '\n') msg = "[" + DateTime.Now.ToString() + "]: " + msg; - Filework.LogToFile(logfile, msg); + LogToFile(logfile, msg); LogBox.Text += msg; } diff --git a/dtlauncher-client-win/dtlauncher-client-win.csproj b/dtlauncher-client-win/dtlauncher-client-win.csproj index fb191dd..51d8d30 100644 --- a/dtlauncher-client-win/dtlauncher-client-win.csproj +++ b/dtlauncher-client-win/dtlauncher-client-win.csproj @@ -107,14 +107,14 @@ - - {e02ea967-fd29-47d2-b25b-ba684b784aee} - dtscript - {ce793497-2d5c-42d8-b311-e9b32af9cdfb} DTLib + + {e02ea967-fd29-47d2-b25b-ba684b784aee} + dtscript + diff --git a/dtlauncher-server-win/DtlauncherServer.cs b/dtlauncher-server-win/DtlauncherServer.cs index 4aaba08..89f0140 100644 --- a/dtlauncher-server-win/DtlauncherServer.cs +++ b/dtlauncher-server-win/DtlauncherServer.cs @@ -1,12 +1,11 @@ using DTLib; using System; using System.Collections.Generic; -using System.IO; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; -using static DTLib.Network; +using static DTLib.Filework; namespace dtlauncher_server { @@ -49,7 +48,7 @@ namespace dtlauncher_server config = config = new(File.ReadAllText("server.dtsod")); int f = (int)config["server_port"]; Log("b", "local address: <", "c", config["server_ip"], "b", - ">\npublic address: <", "c", GetPublicIP(), "b", + ">\npublic address: <", "c", Network.GetPublicIP(), "b", ">\nport: <", "c", config["server_port"].ToString(), "b", ">\n"); mainSocket.Bind(new IPEndPoint(IPAddress.Parse(config["server_ip"]), (int)config["server_port"])); mainSocket.Listen(1000); diff --git a/dtlauncher.sln b/dtlauncher.sln index 60a4795..73a3214 100644 --- a/dtlauncher.sln +++ b/dtlauncher.sln @@ -13,12 +13,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dtlauncher-server-win", "dt {CE793497-2D5C-42D8-B311-E9B32AF9CDFB} = {CE793497-2D5C-42D8-B311-E9B32AF9CDFB} EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dtscript", "..\dtscript\dtscript.csproj", "{E02EA967-FD29-47D2-B25B-BA684B784AEE}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "updater", "updater\updater.csproj", "{4784D974-A342-4202-9430-90FE5AC00FC7}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DTLib", "DTLib\DTLib.csproj", "{CE793497-2D5C-42D8-B311-E9B32AF9CDFB}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dtscript", "dtscript\dtscript.csproj", "{E02EA967-FD29-47D2-B25B-BA684B784AEE}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Build|Any CPU = Build|Any CPU @@ -28,12 +28,12 @@ Global {367793EE-4757-4ADD-BF7E-960DC9EB6DF9}.Build|Any CPU.Build.0 = Build|Any CPU {8B9889A7-93DC-4914-92D1-8209BD3BA71A}.Build|Any CPU.ActiveCfg = Build|Any CPU {8B9889A7-93DC-4914-92D1-8209BD3BA71A}.Build|Any CPU.Build.0 = Build|Any CPU - {E02EA967-FD29-47D2-B25B-BA684B784AEE}.Build|Any CPU.ActiveCfg = Build|Any CPU - {E02EA967-FD29-47D2-B25B-BA684B784AEE}.Build|Any CPU.Build.0 = Build|Any CPU {4784D974-A342-4202-9430-90FE5AC00FC7}.Build|Any CPU.ActiveCfg = Build|Any CPU {4784D974-A342-4202-9430-90FE5AC00FC7}.Build|Any CPU.Build.0 = Build|Any CPU {CE793497-2D5C-42D8-B311-E9B32AF9CDFB}.Build|Any CPU.ActiveCfg = Build|Any CPU {CE793497-2D5C-42D8-B311-E9B32AF9CDFB}.Build|Any CPU.Build.0 = Build|Any CPU + {E02EA967-FD29-47D2-B25B-BA684B784AEE}.Build|Any CPU.ActiveCfg = Build|Any CPU + {E02EA967-FD29-47D2-B25B-BA684B784AEE}.Build|Any CPU.Build.0 = Build|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/dtscript/App.config b/dtscript/App.config new file mode 100644 index 0000000..4bfa005 --- /dev/null +++ b/dtscript/App.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/dtscript/MainClass.cs b/dtscript/MainClass.cs new file mode 100644 index 0000000..19b16c1 --- /dev/null +++ b/dtscript/MainClass.cs @@ -0,0 +1,53 @@ +using DTLib; +using System; + +namespace DTScript +{ + public class MainClass + { + static void Main(string[] args) + { + try + { + Filework.Directory.Create("dtscript-logs"); + PublicLog.Log += Log; + var scripter = new ScriptRunner(); + if (args.Length == 0 || args.Length > 2) throw new Exception("enter script file path\n"); + else if (args.Length == 1) scripter.RunScriptFile(args[0]); + else if (args.Length == 2 && args[0] == "-debug") + { + scripter.debug = true; + scripter.Debug("y", "debug is enabled\n"); + scripter.RunScriptFile(args[1]); + } + else throw new Exception("unknown args\n"); + } + catch (Exception ex) + { + Log("r", $"dtscript.Main() error:\n{ex.Message}\n{ex.StackTrace}\n"); + } + Log("gray", " \n"); + } + + // вывод лога в консоль и файл + static readonly string logfile = $"dtscript-logs\\dtscript-{DateTime.Now}.log".Replace(':', '-').Replace(' ', '_'); + + static void Log(params string[] msg) + { + if (msg.Length == 1) + { + msg[0] = "[" + DateTime.Now.ToString() + "]: " + msg[0]; + Filework.LogToFile(logfile, msg[0]); + } + else if (msg.Length % 2 != 0) throw new Exception("incorrect array to log\n"); + else + { + msg[1] = "[" + DateTime.Now.ToString() + "]: " + msg[1]; + var str = new System.Text.StringBuilder(); + for (int i = 0; i < msg.Length; i++) str.Append(msg[++i]); + Filework.LogToFile(logfile, str.ToString()); + } + ColoredConsole.Write(msg); + } + } +} diff --git a/dtscript/Properties/AssemblyInfo.cs b/dtscript/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..2f86bb2 --- /dev/null +++ b/dtscript/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// Общие сведения об этой сборке предоставляются следующим набором +// набора атрибутов. Измените значения этих атрибутов для изменения сведений, +// связанные с этой сборкой. +[assembly: AssemblyTitle("dtscript")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("dtscript")] +[assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми +// для компонентов COM. Если необходимо обратиться к типу в этой сборке через +// из модели COM задайте для атрибута ComVisible этого типа значение true. +[assembly: ComVisible(false)] + +// Следующий GUID представляет идентификатор typelib, если этот проект доступен из модели COM +[assembly: Guid("e02ea967-fd29-47d2-b25b-ba684b784aee")] + +// Сведения о версии сборки состоят из указанных ниже четырех значений: +// +// Основной номер версии +// Дополнительный номер версии +// Номер сборки +// Номер редакции +// +// Можно задать все значения или принять номера сборки и редакции по умолчанию +// используя "*", как показано ниже: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/dtscript/ScriptRunner.cs b/dtscript/ScriptRunner.cs new file mode 100644 index 0000000..51a4b15 --- /dev/null +++ b/dtscript/ScriptRunner.cs @@ -0,0 +1,462 @@ +using DTLib; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Net.Sockets; +using static DTLib.Filework; + +namespace DTScript +{ + // + // основной класс скриптового интерпретатора + // + public class ScriptRunner + { + // выводит текст через DTLib если дебаг включен + public bool debug = false; + public Socket mainSocket; + internal void Debug(params string[] msg) + { + if (debug) PublicLog.Log(msg); + } + + // cчитывание текста из файла и запуск выполнения + public void RunScriptFile(string scriptfile) + { + Debug("g", @"----\ " + scriptfile + " /----\n"); + try { Execute(SplitScript(File.ReadAllText(scriptfile))); } + catch (Exception e) { PublicLog.Log("r", $"dtscript RunScriptFile() error:\n{e.Message}\n{e.StackTrace}\n", "gray", " \n"); } + } + + int globalindex = -1; + List> Storage = new(); + + object GetValue(string key) + { + Debug("m", "GetValue(", "c", "<", "b", key, "c", ">", "m", ")\n"); + for (int i = 0; i <= globalindex; i++) + if (Storage[i].ContainsKey(key)) return Storage[i][key]; + throw new Exception($"GetValue() exception: storage doesn't contain key<{key}>"); + } + + void SetValue(string key, object value) + { + Debug("m", "SetValue(", "c", "<", "b", key, "c", "> ", "c", "<", "b", value.ToString(), "c", ">", "m", ")\n"); + for (int i = 0; i <= globalindex; i++) + if (Storage[i].ContainsKey(key)) + { + Storage[i][key] = value; + Debug(Storage[i][key].ToString()); + return; + }//throw new Exception($"SetValue() exception: storage alredy contains key<{key}>"); + Storage[globalindex].Add(key, value); + } + + dynamic Execute(List script) + { + Debug("y", " executing...\n"); + // создание локального + globalindex++; + List subscript; + Storage.Add(new Dictionary()); + // запуск цикла + for (int index = 0; index < script.Count; index++) + { + if (debug) + { + PublicLog.Log(new string[] { + "y","\noperator: ", "m",script[index].Operator, "y"," options: ", "c", "<", "b", script[index].Options[0], "c", ">"}); + for (ushort n = 1; n < script[index].Options.Length; n++) + PublicLog.Log("w", ", ", "c", "<", "b", script[index].Options[n], "c", ">"); + PublicLog.Log("\n"); + } + switch (script[index].Operator) + { + case "return": + Debug("g", "script ended"); + return GetValue(script[index].Options[0]); + case "Run": + var proc = new Process(); + proc.StartInfo.FileName = script[index].Options[0].Replace("\"", ""); + proc.StartInfo.Arguments = script[index].Options[1].Replace("\"", ""); + /*if (script[index].Options.Length == 3 && script[index].Options[2] == "true") + { + proc.StartInfo.CreateNoWindow = true; + Debug("g", $"process {script[index].Operator} started in hidden mode\n"); + } + else if (script[index].Options.Length == 3 && script[index].Options[2] == "false") + { + proc.StartInfo.CreateNoWindow = false; + Debug("g", $"process {script[index].Operator} started in not hidden mode\n"); + } + else throw new Exception("invalid arguments in Run().\n it must be: Run(string exe_file, string arguments, true/false nowindow)\n"); + proc.StartInfo.UseShellExecute = false;*/ + proc.Start(); + proc.WaitForExit(); + proc.Close(); + break; + case "Log": + Debug("y", $"Log() has {script[index].Options.Length} args\n"); + PublicLog.Log(CalcString(script[index].Options.ToList())); + break; + case "ShowFiles": + Debug("y", $"Log() has {script[index].Options.Length} args\n"); + foreach (string file in Directory.GetFiles(CalcString(script[index].Options.ToList()))) + PublicLog.Log(file + '\n'); + break; + case "bool": + if (script[index].Options.Length > 2 && script[index].Options[1] == "=") + { + List expr = new(); + for (ushort n = 2; n < script[index].Options.Length; n++) + expr.Add(script[index].Options[n]); + // сравнение и добавление результата в storage[globalindex] + SetValue(script[index].Options[0], Compare(expr)); + Debug(new string[] {"y"," bool ","b", script[index].Options[0], + "w", " = ", "c", GetValue(script[index].Options[0]).ToString() + '\n'}); + } + else throw new Exception("error: incorrect bool defination\n"); + break; + case "num": + if (script[index].Options.Length > 2 && script[index].Options[1] == "=") + { + List expr = new(); + for (ushort n = 2; n < script[index].Options.Length; n++) + { + expr.Add(script[index].Options[n]); + } + SetValue(script[index].Options[0], (double)Calc(expr)); + Debug(new string[] {"y"," num ","b", script[index].Options[0], + "w", " = ", "c", GetValue(script[index].Options[0]).ToString() + '\n'}); + } + else throw new Exception("Execute() error: incorrect double defination\n"); + break; + case "string": + if (script[index].Options.Length > 2 && script[index].Options[1] == "=") + { + List expr = new(); + for (ushort n = 2; n < script[index].Options.Length; n++) + { + expr.Add(script[index].Options[n]); + } + SetValue(script[index].Options[0], CalcString(expr)); + Debug(new string[] {"y"," string ","b", script[index].Options[0], + "w", " = ", "c", GetValue(script[index].Options[0]).ToString() + '\n'}); + } + break; + case "while": + if (script[index + 1].Operator != "{") throw new Exception("Execute() error: expect { after for()"); + subscript = SplitScript(script[index + 1].Options[0]); + while (Compare(script[index].Options.ToList())) + { + Execute(subscript); + } + index++; + break; + case "if": + if (script[index + 1].Operator != "{") throw new Exception("Execute() error: expect { after for()"); + subscript = SplitScript(script[index + 1].Options[0]); + if (Compare(script[index].Options.ToList())) + { + Execute(subscript); + } + index++; + break; + case "Download": + mainSocket.FSP_Download(script[index].Options[0], script[index].Options[1]); + break; + case "DirDelete": + Filework.Directory.Delete(script[index].Options[0]); + break; + case "FileDelete": + File.Delete(script[index].Options[0]); + break; + case "FileWrite": + Filework.File.Create(script[index].Options[0]); + File.WriteAllText(script[index].Options[0], script[index].Options[1]); + break; + case "FileAppend": + Filework.File.Create(script[index].Options[0]); + File.AppendAllText(script[index].Options[0], script[index].Options[1]); + break; + default: + throw new Exception($"Execute() error: invalid construct: {script[index].Operator}\n"); + } + } + Storage.RemoveAt(globalindex); + globalindex--; + return null; + + // операции со строками + string CalcString(List expr) + { + Debug("m", "CalcString("); + foreach (string part in expr) + Debug("c", "<", "b", part, "c", ">"); + Debug("m", ")", "y", " started\n"); + // извлечение значений переменных + for (ushort n = 0; n < expr.Count; n++) + { + switch (expr[n][0]) + { + case '+': + break; + case '"': + if (!expr[n].EndsWith("\"")) throw new Exception("Calc() error: invalid value <" + expr[n] + ">\n"); + break; + default: + expr[n] = GetValue(expr[n]).ToString(); + break; + } + } + // вычисление + string rezult = ""; + for (ushort i = 0; i < expr.Count; i++) + { + + if (expr[i] == "+") + { + i++; + rezult += expr[i]; + } + else if (i == 0) rezult = expr[0]; + else throw new Exception($"error in Calc(): arg {expr[i]}\n"); + } + if (rezult.Contains("\\n")) rezult = rezult.Replace("\\n", "\n"); + if (rezult.Contains("\"")) rezult = rezult.Replace("\"", ""); + Debug("y", " returns <", "b", $"{rezult}", "y", ">\n"); + return rezult; + } + // операции с числами + double Calc(List expr) + { + Debug("m", "Calc("); + foreach (string part in expr) + Debug("c", "<", "b", part, "c", ">"); + Debug("m", ")", "y", " started\n"); + // извлечение значений переменных + for (ushort n = 0; n < expr.Count; n++) + { + switch (expr[n][0]) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '+': + case '-': + case '*': + case '/': + break; + default: + expr[n] = GetValue(expr[n]).ToString(); + break; + } + } + // вычисление + double rezult = new(); + for (ushort i = 0; i < expr.Count; i++) + switch (expr[i][0]) + { + case '+': + i++; + rezult += Convert.ToDouble(expr[i]); + break; + case '-': + i++; + rezult -= Convert.ToDouble(expr[i]); + break; + case '*': + i++; + rezult *= Convert.ToDouble(expr[i]); + break; + case '/': + i++; + rezult /= Convert.ToDouble(expr[i]); + break; + default: + if (i == 0) rezult += Convert.ToDouble(expr[i]); + else throw new Exception($"error in Calc(): arg {expr[i]}\n"); + break; + } + Debug("y", " returns <", "b", $"{rezult}", "y", ">\n"); + return rezult; + } + // сравнение + bool Compare(List expr) + { + Debug("m", "Compare("); + foreach (string part in expr) + Debug("c", "<", "b", part, "c", ">"); + Debug("m", ")", "y", " started\n"); + // вычисление значений правой и левой части неравенства + char act = '\0'; + double rezult_0 = new(), rezult_1; + List _expr = new List(); + for (ushort n = 0; n < expr.Count; n++) + { + Debug("m", $" <{expr[n]}>\n"); + switch (expr[n][0]) + { + case '<': + case '>': + act = expr[n][0]; + rezult_0 = Calc(_expr); + _expr.Clear(); + break; + case '!': + case '=': + act = expr[n][0]; + rezult_0 = Calc(_expr); + _expr.Clear(); + n++; + break; + default: + _expr.Add(expr[n]); + break; + } + } + Debug("y", " rezult_0 = <", "b", rezult_0.ToString(), "y", ">\n"); + rezult_1 = Calc(_expr); + Debug("y", " rezult_1 = <", "b", rezult_1.ToString(), "y", ">\n"); + Debug("y", " act = <", "b", act.ToString(), "y", ">\n"); + bool output = act switch + { + '<' => rezult_0 < rezult_1, + '>' => rezult_0 > rezult_1, + '!' => rezult_0 != rezult_1, + '=' => rezult_0 == rezult_1, + _ => throw new Exception($"error: incorrect comparsion symbol: <{act}>\n"), + }; + Debug("y", " return <", "c", $"{output}", "y", ">\n"); + return output; + } + } + + List SplitScript(string text) + { + // лист для хранения обработанного текста + List script = new(); + string construct = ""; + string option = ""; + List options = new(); + for (int index = 0; index < text.Length; index++) + { + switch (text[index]) + { + // конец распознания конструкта + case ';': + Debug(text[index].ToString() + '\n'); + // добавление конструкта и его параметров в лист + if (construct != "") script.Add(new Construction(construct, options)); + construct = ""; + option = ""; + options.Clear(); + break; + // распознание параметров конструкта + case '(': + Debug(text[index].ToString()); + while (text[index] != ')') + { + index++; + switch (text[index]) + { + case '"': + Debug("g", text[index].ToString()); + do + { + option += text[index]; + index++; + Debug("g", text[index].ToString()); + } while (text[index] != '"'); + option += text[index]; + break; + case ' ': + case '\t': + case '\r': + case '\n': + break; + case ')': + case ',': + Debug(text[index].ToString()); + options.Add(option); + option = ""; + break; + // математика + case '+': + case '-': + case '*': + case '/': + case '!': + case '=': + Debug(text[index].ToString()); + if (option != "") options.Add(option); + option = ""; + options.Add(text[index].ToString()); + break; + default: + option += text[index]; + Debug("c", text[index].ToString()); + break; + } + } + if (debug && text[index + 1] == ';') PublicLog.Log("y", "\n " + options.Count + " options have read\n"); + break; + // очистка конструкта от лишних символов + case ' ': + case '\t': + case '\r': + case '\n': + break; + // + case '{': + Debug("SplitScript() found <{>"); + // добавление конструкта и его параметров в лист + if (construct != "") script.Add(new Construction(construct, options)); + options.Clear(); + option = ""; + construct = ""; + index++; + short bracketBalance = 1; + while (bracketBalance != 0) + { + if (text[index] == '{') bracketBalance++; + if (text[index] == '}') bracketBalance--; + option += text[index]; + index++; + } + option.Remove(option.Length - 1); + script.Add(new Construction("{", new List { option })); + option = ""; + break; + case '}': + //throw new Exception($"SplitScript() error: unexpected '}}' on line {line}\n"); + break; + default: + construct += text[index]; + Debug("m", text[index].ToString()); + break; + } + } + // возврат листа + return script; + } + + class Construction + { + public string Operator { get; private set; } + public string[] Options { get; private set; } + public Construction(string oper, List opts) + { + Operator = oper; + Options = opts.ToArray(); + } + } + } +} \ No newline at end of file diff --git a/dtscript/dtscript.csproj b/dtscript/dtscript.csproj new file mode 100644 index 0000000..38c31ec --- /dev/null +++ b/dtscript/dtscript.csproj @@ -0,0 +1,98 @@ + + + + + Debug + AnyCPU + {E02EA967-FD29-47D2-B25B-BA684B784AEE} + Exe + dtscript + dtscript + v4.8 + 512 + true + true + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + + AnyCPU + none + true + bin\ + TRACE + prompt + 4 + true + preview + + + DTScript.MainClass + + + dtscript.ico + + + + + + + + + + + + + + + + + + + + + + False + Microsoft .NET Framework 4.7.2 %28x86 и x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + + + + + + + + {ce793497-2d5c-42d8-b311-e9b32af9cdfb} + DTLib + + + + + del /q /f dtscript.exe.config +copy dtscript.exe C:\projects\c#\dtlauncher\dtlauncher-server-win\bin\share\client\dtscript.exe + + + + + + \ No newline at end of file diff --git a/dtscript/dtscript.ico b/dtscript/dtscript.ico new file mode 100644 index 0000000..df420bb Binary files /dev/null and b/dtscript/dtscript.ico differ diff --git a/dtscript/dtscript.sln b/dtscript/dtscript.sln new file mode 100644 index 0000000..0f54d92 --- /dev/null +++ b/dtscript/dtscript.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30611.23 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dtscript", "dtscript.csproj", "{E02EA967-FD29-47D2-B25B-BA684B784AEE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DTLib", "..\DTLib\DTLib.csproj", "{CE793497-2D5C-42D8-B311-E9B32AF9CDFB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + build|Any CPU = build|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E02EA967-FD29-47D2-B25B-BA684B784AEE}.build|Any CPU.ActiveCfg = build|Any CPU + {E02EA967-FD29-47D2-B25B-BA684B784AEE}.build|Any CPU.Build.0 = build|Any CPU + {CE793497-2D5C-42D8-B311-E9B32AF9CDFB}.build|Any CPU.ActiveCfg = Build|Any CPU + {CE793497-2D5C-42D8-B311-E9B32AF9CDFB}.build|Any CPU.Build.0 = Build|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {A1D642E1-876E-4187-91D5-526827AE36A2} + EndGlobalSection +EndGlobal diff --git a/dtscript/dtscript_doc.txt b/dtscript/dtscript_doc.txt new file mode 100644 index 0000000..18d1f83 --- /dev/null +++ b/dtscript/dtscript_doc.txt @@ -0,0 +1,63 @@ +Мне было лень изучать жабаскрып, потому всего за полгода я сделал вот этот dtscript (как выразился Абикак, "питоний джабаскрып"). +Синтаксис dtscript не завист от пробелов, табов, переносов строк. Конец одной конструкции определяется по символу ';' или '}' (если перед этим был символ '{') + + +========================================[переменные]======================================== + +объявление переменной и присвоение значения синтаксически никак не отличаются: + тип(имя = значение); + +у переменных есть контекст: + bool(h=false); + if (...) + { + bool(j=true); + Log("w", h); выведет true, так как есть доступ к переменным предыдущих уровней + } + Log("w", j); выдаст ошибку "KeyNotFoundException", так как вызывается с предшествующего объявлению переменной уровня + +┌────────┬────────────────┬───────────┬───────────────────┐ +│ тип │ аналог в c# │ операции │ пример │ +├────────┼────────────────┼───────────┼───────────────────┤ +│ bool │ System.Boolean │ <,>,==,!= │ bool(a=1<3); │ +├────────┼────────────────┼───────────┼───────────────────┤ +│ num │ System.Double │ +,-,*,/ │ num(a=9.6); │ +├────────┼────────────────┼───────────┼───────────────────┤ +│ string │ System.String │ + │ string(a="text"); │ +└────────┴────────────────┴───────────┴───────────────────┘ + + +==========================================[методы]========================================== + +Oбъявлять свои методы пока что нельзя, можно только использовать встроенные: + метод; если нет параметров + Метод(параметр0, параметр1...); параметрами могут быть значения и переменные, но не выражения + +┌────────────────────────────┬─────────────────────────────────────────────────────────┬────────────────────────────────────────────────────────┐ +│ метод │ аналог в с# │ шо делает │ +├────────────────────────────┼─────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────┤ +│ pause │ System.Console.ReadKey() │ приостанавливает выполнение скрипта до нажатия клавиши │ +├────────────────────────────┼─────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────┤ +│ break │ break │ прекращает выполнение уровня скрипта │ +├────────────────────────────┼─────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────┤ +│ Log("w", "text", ...) │ DTLib.ColoredConsole.Write(params string[]) │ выводит в консоль цветной текст │ +├────────────────────────────┼─────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────┤ +│ Run("файл.ехе","аргументы")│ System.Diagnostics.Process.Start(string) │ запускает прогу │ +├────────────────────────────┼─────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────┤ +│ Download("f0", "f1") │ DTLib.NetWork.FSP_Download(this Socket, string, string) │ скачивает файл по FSP протоколу │ +└────────────────────────────┴─────────────────────────────────────────────────────────┴────────────────────────────────────────────────────────┘ + + +=========================================[операторы]======================================== + +Параметром может быть переменная, но не выражение. + +while (bool) +{ + ... +} + +if (bool) +{ + ... +} diff --git a/updater/Updater.cs b/updater/Updater.cs index c87a7a9..c79e19e 100644 --- a/updater/Updater.cs +++ b/updater/Updater.cs @@ -1,7 +1,6 @@ using DTLib; using System; using System.Diagnostics; -using System.IO; using System.Net; using System.Net.Sockets; using System.Text;