From 13421f2c77c80b9149337b608e6af14177225215 Mon Sep 17 00:00:00 2001 From: Timerix Date: Tue, 24 Aug 2021 20:35:02 +0300 Subject: [PATCH] project structure changed --- ConsoleGUI/Container.cs | 43 +++- ConsoleGUI/Control.cs | 11 +- ConsoleGUI/IDrawable.cs | 1 + ConsoleGUI/Label.cs | 20 +- ConsoleGUI/Window.cs | 175 +------------ ConsoleGUI/WindowOld.cs | 189 ++++++++++++++ DTLib.csproj | 9 +- Dtsod.cs => Dtsod/DtsodV21.cs | 172 ++++++++----- Dtsod/DtsodV22.cs | 456 ++++++++++++++++++++++++++++++++++ Dtsod/ValueTypes.cs | 19 ++ Filesystem/Directory.cs | 23 +- Filesystem/File.cs | 8 +- Network/FSP.cs | 82 +++--- Network/OldNetwork.cs | 2 +- Network/Package.cs | 10 +- SimpleConverter.cs | 54 ++-- 16 files changed, 961 insertions(+), 313 deletions(-) create mode 100644 ConsoleGUI/WindowOld.cs rename Dtsod.cs => Dtsod/DtsodV21.cs (56%) create mode 100644 Dtsod/DtsodV22.cs create mode 100644 Dtsod/ValueTypes.cs diff --git a/ConsoleGUI/Container.cs b/ConsoleGUI/Container.cs index 5c0b51c..981eae3 100644 --- a/ConsoleGUI/Container.cs +++ b/ConsoleGUI/Container.cs @@ -1,4 +1,7 @@ -using System.Collections.Generic; +using DTLib.Dtsod; +using DTLib.Filesystem; +using System.Collections.Generic; +using static DTLib.PublicLog; namespace DTLib.ConsoleGUI { @@ -9,13 +12,35 @@ namespace DTLib.ConsoleGUI public ushort Height { get; set; } public char[] Textmap { get; private set; } public char[] Colormap { get; private set; } + public string Name { get; private set; } - public Container() { } - - public Container(ushort width, ushort height) + public Container(string name, string layout_file) { - Width = width; - Height = height; + Name = name; + ParseLayoutFile(layout_file); + } + + void ParseLayoutFile(string layout_file) + { + DtsodV22 layout = new(File.ReadAllText(layout_file)); + AnchorPoint = (layout[Name]["anchor"][0], layout[Name]["anchor"][1]); + Width = layout[Name]["width"]; + Height = layout[Name]["height"]; + foreach (string element_name in layout[Name]["children"].Keys) + { + switch (layout[Name]["children"][element_name]["type"]) + { + case "label": + this.Add(new Label(element_name, + layout[Name]["children"][element_name]["resdir"] + $"\\{element_name}.textmap", + layout[Name]["children"][element_name]["resdir"] + $"\\{element_name}.colormap") + { + AnchorPoint = (layout[Name]["children"][element_name]["anchor"][0], + layout[Name]["children"][element_name]["anchor"][1]) + }); + break; + } + } } public void GenTextmap() @@ -25,11 +50,13 @@ namespace DTLib.ConsoleGUI Textmap[i] = ' '; foreach (var element in this) { + element.GenTextmap(); + Log("m", $"Length: {element.Textmap.Length} calculated: {element.Width * element.Height}\n"); for (ushort y = 0; y < element.Height; y++) for (ushort x = 0; x < element.Width; x++) { - element.GenTextmap(); - Textmap[(element.AnchorPoint.y + y) * Width + element.AnchorPoint.x + x] = element.Textmap[y * element.Width + x]; + //Textmap[(element.AnchorPoint.y + y) * Width + element.AnchorPoint.x + x] = element.Textmap[y * element.Width + x]; + Textmap[(y) * Width + x] = element.Textmap[y * element.Width + x]; } } } diff --git a/ConsoleGUI/Control.cs b/ConsoleGUI/Control.cs index 6a65c4c..cee2ded 100644 --- a/ConsoleGUI/Control.cs +++ b/ConsoleGUI/Control.cs @@ -1,19 +1,14 @@ namespace DTLib.ConsoleGUI { - public class Control : IDrawable + public class Control : Label { - public (ushort x, ushort y) AnchorPoint { get; set; } - public ushort Width { get; } - public ushort Height { get; } - public char[] Textmap { get; private set; } - public char[] Colormap { get; private set; } - public void GenColormap() + public new void GenColormap() { } - public void GenTextmap() + public new void GenTextmap() { } diff --git a/ConsoleGUI/IDrawable.cs b/ConsoleGUI/IDrawable.cs index 123c24b..4b940c7 100644 --- a/ConsoleGUI/IDrawable.cs +++ b/ConsoleGUI/IDrawable.cs @@ -7,6 +7,7 @@ public ushort Height { get; } public char[] Textmap { get; } public char[] Colormap { get; } + public string Name { get; } public void GenTextmap(); diff --git a/ConsoleGUI/Label.cs b/ConsoleGUI/Label.cs index 587a868..ebb979c 100644 --- a/ConsoleGUI/Label.cs +++ b/ConsoleGUI/Label.cs @@ -1,32 +1,38 @@ -namespace DTLib.ConsoleGUI +using DTLib.Filesystem; + +namespace DTLib.ConsoleGUI { public class Label : IDrawable { - public (ushort x, ushort y) AnchorPoint { get; set; } - public ushort Width { get; } - public ushort Height { get; } + public (ushort x, ushort y) AnchorPoint { get; set; } = (0, 0); + public ushort Width { get; private set; } + public ushort Height { get; private set; } public char[] Textmap { get; private set; } public char[] Colormap { get; private set; } public string TextmapFile { get; set; } public string ColormapFile { get; set; } + public string Name { get; init; } public Label() { } - public Label(string textmapFile, string colormapFile) + public Label(string name, string textmapFile, string colormapFile) { TextmapFile = textmapFile; ColormapFile = colormapFile; + Name = name; } public void GenColormap() { - + Colormap = File.ReadAllText(ColormapFile).ToCharArray(); } public void GenTextmap() { - + Textmap = File.ReadAllText(TextmapFile).ToCharArray(); + Width = 12; + Height = 3; } } } diff --git a/ConsoleGUI/Window.cs b/ConsoleGUI/Window.cs index 6daecb5..27f3af8 100644 --- a/ConsoleGUI/Window.cs +++ b/ConsoleGUI/Window.cs @@ -1,6 +1,5 @@ using DTLib.Filesystem; using System; -using System.Collections.Generic; using System.Text; namespace DTLib.ConsoleGUI @@ -8,182 +7,30 @@ namespace DTLib.ConsoleGUI // // создание gui из текста в консоли // - public class Window + public class Window : Container { - public int WindowWidth { get; private set; } - public int WindowHeight { get; private set; } - public char[,] Text; - public char[,] nowText; - public char[,] TextColors; - public char[,] nowTextColors; - public Container WindowContainer; - - public Window(int windowWidth, int windowHeight) + public Window(string layout_file) : base("window", layout_file) { - WindowWidth = windowWidth; - WindowHeight = windowHeight; - Text = new char[windowWidth, windowHeight]; - TextColors = new char[windowWidth, windowHeight]; - nowText = TextColors; - nowTextColors = new char[windowWidth, windowHeight]; - Console.WindowWidth = WindowWidth + 1; - Console.WindowHeight = WindowHeight + 1; - Console.BufferWidth = WindowWidth + 1; - Console.BufferHeight = WindowHeight + 1; + Console.Clear(); + Console.SetWindowSize(Width + 1, Height + 1); + Console.SetBufferSize(Width + 1, Height + 1); Console.OutputEncoding = Encoding.Unicode; Console.InputEncoding = Encoding.Unicode; Console.CursorVisible = false; - // заполнение массивов - for (sbyte y = 0; y < WindowHeight; y++) - { - for (sbyte x = 0; x < WindowWidth; x++) - { - Text[x, y] = ' '; - TextColors[x, y] = 'w'; - } - } - nowText = TextColors; - } - - /*// считывает массив символов из файла - // ширина и высота текста должны быть как указанные при инициализации объекта этого класса - public void ReadFromFile(string path) - { - var r = new StreamReader(path, SimpleConverter.UTF8); - char[] s = new char[1]; - // считывание текста - sbyte y = 0, x = 0; - r.Read(s, 0, 1); - while (!r.EndOfStream && y < WindowHeight) - { - if (x == WindowWidth) - { - r.Read(s, 0, 1); - x = 0; - y++; - } - else - { - Text[x, y] = s[0]; - x++; - } - r.Read(s, 0, 1); - } - r.Read(s, 0, 1); - // считывание цвета - // если не находит цвет в файле, оставляет старый - if (s[0] == '\n') - { - r.Read(s, 0, 1); - y = 0; - x = 0; - while (!r.EndOfStream && y < WindowHeight) - { - if (x == WindowWidth) - { - r.Read(s, 0, 1); - x = 0; - y++; - } - else - { - TextColors[x, y] = s[0]; - x++; - } - r.Read(s, 0, 1); - } - } - r.Close(); - }*/ - - public void ResetCursor() - { - Console.SetCursorPosition(0, WindowHeight); - } - - // заменяет символ выведенный, использовать после ShowAll() - public void ChangeChar(sbyte x, sbyte y, char ch) - { - Text[x, y] = ch; - nowText[x, y] = ch; - Console.SetCursorPosition(x, y); - ColoredConsole.Write(TextColors[x, y].ToString(), ch.ToString()); - } - - public void ChangeColor(sbyte x, sbyte y, char color) - { - TextColors[x, y] = color; - nowTextColors[x, y] = color; - Console.SetCursorPosition(x, y); - ColoredConsole.Write(color.ToString(), Text[x, y].ToString()); - } - - public void ChangeCharAndColor(sbyte x, sbyte y, char color, char ch) - { - Text[x, y] = ch; - nowText[x, y] = ch; - TextColors[x, y] = color; - nowTextColors[x, y] = color; - Console.SetCursorPosition(x, y); - ColoredConsole.Write(color.ToString(), ch.ToString()); - } - - public void ChangeLine(sbyte x, sbyte y, char color, string line) - { - Console.SetCursorPosition(x, y); - for (sbyte i = 0; i < line.Length; i++) - { - Text[x + i, y] = line[i]; - nowText[x + i, y] = line[i]; - TextColors[x + i, y] = color; - nowTextColors[x + i, y] = color; - } - ColoredConsole.Write(color.ToString(), line); } // выводит все символы - public void ShowAll() - { - var l = new List(); - for (sbyte y = 0; y < WindowHeight; y++) - { - for (sbyte x = 0; x < WindowWidth; x++) - { - l.Add(TextColors[x, y].ToString()); - l.Add(Text[x, y].ToString()); - nowText[x, y] = Text[x, y]; - nowTextColors[x, y] = TextColors[x, y]; - } - l.Add("w"); - l.Add("\n"); - } - ColoredConsole.Write(l.ToArray()); - //Console.WriteLine(); - } - - public void UpdateAll() - { - for (sbyte y = 0; y < WindowHeight; y++) - { - for (sbyte x = 0; x < WindowWidth; x++) - { - Console.SetCursorPosition(x, y); - if (TextColors[x, y] != nowTextColors[x, y] || Text[x, y] != nowText[x, y]) - { - ColoredConsole.Write(TextColors[x, y].ToString(), Text[x, y].ToString()); - nowText[x, y] = Text[x, y]; - nowTextColors[x, y] = TextColors[x, y]; - } - } - Console.Write('\n'); - } - } - public void RenderFile(string file) { Console.Clear(); Console.WriteLine(File.ReadAllText(file)); } + + public void Render() + { + GenTextmap(); + Console.WriteLine(SimpleConverter.MergeToString(Textmap)); + } } } diff --git a/ConsoleGUI/WindowOld.cs b/ConsoleGUI/WindowOld.cs new file mode 100644 index 0000000..592a4ba --- /dev/null +++ b/ConsoleGUI/WindowOld.cs @@ -0,0 +1,189 @@ +using DTLib.Filesystem; +using System; +using System.Collections.Generic; +using System.Text; + +namespace DTLib.ConsoleGUI +{ + // + // создание gui из текста в консоли + // + public class WindowOld + { + public int WindowWidth { get; private set; } + public int WindowHeight { get; private set; } + public char[,] Text; + public char[,] nowText; + public char[,] TextColors; + public char[,] nowTextColors; + + public Container WindowContainer; + + public WindowOld(int windowWidth, int windowHeight) + { + WindowWidth = windowWidth; + WindowHeight = windowHeight; + Text = new char[windowWidth, windowHeight]; + TextColors = new char[windowWidth, windowHeight]; + nowText = TextColors; + nowTextColors = new char[windowWidth, windowHeight]; + Console.WindowWidth = WindowWidth + 1; + Console.WindowHeight = WindowHeight + 1; + Console.BufferWidth = WindowWidth + 1; + Console.BufferHeight = WindowHeight + 1; + Console.OutputEncoding = Encoding.Unicode; + Console.InputEncoding = Encoding.Unicode; + Console.CursorVisible = false; + // заполнение массивов + for (sbyte y = 0; y < WindowHeight; y++) + { + for (sbyte x = 0; x < WindowWidth; x++) + { + Text[x, y] = ' '; + TextColors[x, y] = 'w'; + } + } + nowText = TextColors; + } + + /*// считывает массив символов из файла + // ширина и высота текста должны быть как указанные при инициализации объекта этого класса + public void ReadFromFile(string path) + { + var r = new StreamReader(path, SimpleConverter.UTF8); + char[] s = new char[1]; + // считывание текста + sbyte y = 0, x = 0; + r.Read(s, 0, 1); + while (!r.EndOfStream && y < WindowHeight) + { + if (x == WindowWidth) + { + r.Read(s, 0, 1); + x = 0; + y++; + } + else + { + Text[x, y] = s[0]; + x++; + } + r.Read(s, 0, 1); + } + r.Read(s, 0, 1); + // считывание цвета + // если не находит цвет в файле, оставляет старый + if (s[0] == '\n') + { + r.Read(s, 0, 1); + y = 0; + x = 0; + while (!r.EndOfStream && y < WindowHeight) + { + if (x == WindowWidth) + { + r.Read(s, 0, 1); + x = 0; + y++; + } + else + { + TextColors[x, y] = s[0]; + x++; + } + r.Read(s, 0, 1); + } + } + r.Close(); + }*/ + + public void ResetCursor() + { + Console.SetCursorPosition(0, WindowHeight); + } + + // заменяет символ выведенный, использовать после ShowAll() + public void ChangeChar(sbyte x, sbyte y, char ch) + { + Text[x, y] = ch; + nowText[x, y] = ch; + Console.SetCursorPosition(x, y); + ColoredConsole.Write(TextColors[x, y].ToString(), ch.ToString()); + } + + public void ChangeColor(sbyte x, sbyte y, char color) + { + TextColors[x, y] = color; + nowTextColors[x, y] = color; + Console.SetCursorPosition(x, y); + ColoredConsole.Write(color.ToString(), Text[x, y].ToString()); + } + + public void ChangeCharAndColor(sbyte x, sbyte y, char color, char ch) + { + Text[x, y] = ch; + nowText[x, y] = ch; + TextColors[x, y] = color; + nowTextColors[x, y] = color; + Console.SetCursorPosition(x, y); + ColoredConsole.Write(color.ToString(), ch.ToString()); + } + + public void ChangeLine(sbyte x, sbyte y, char color, string line) + { + Console.SetCursorPosition(x, y); + for (sbyte i = 0; i < line.Length; i++) + { + Text[x + i, y] = line[i]; + nowText[x + i, y] = line[i]; + TextColors[x + i, y] = color; + nowTextColors[x + i, y] = color; + } + ColoredConsole.Write(color.ToString(), line); + } + + // выводит все символы + public void ShowAll() + { + var l = new List(); + for (sbyte y = 0; y < WindowHeight; y++) + { + for (sbyte x = 0; x < WindowWidth; x++) + { + l.Add(TextColors[x, y].ToString()); + l.Add(Text[x, y].ToString()); + nowText[x, y] = Text[x, y]; + nowTextColors[x, y] = TextColors[x, y]; + } + l.Add("w"); + l.Add("\n"); + } + ColoredConsole.Write(l.ToArray()); + //Console.WriteLine(); + } + + public void UpdateAll() + { + for (sbyte y = 0; y < WindowHeight; y++) + { + for (sbyte x = 0; x < WindowWidth; x++) + { + Console.SetCursorPosition(x, y); + if (TextColors[x, y] != nowTextColors[x, y] || Text[x, y] != nowText[x, y]) + { + ColoredConsole.Write(TextColors[x, y].ToString(), Text[x, y].ToString()); + nowText[x, y] = Text[x, y]; + nowTextColors[x, y] = TextColors[x, y]; + } + } + Console.Write('\n'); + } + } + + public void RenderFile(string file) + { + Console.Clear(); + Console.WriteLine(File.ReadAllText(file)); + } + } +} diff --git a/DTLib.csproj b/DTLib.csproj index b3a6782..b995282 100644 --- a/DTLib.csproj +++ b/DTLib.csproj @@ -37,16 +37,19 @@ - + + + + - + - + diff --git a/Dtsod.cs b/Dtsod/DtsodV21.cs similarity index 56% rename from Dtsod.cs rename to Dtsod/DtsodV21.cs index bcdbfdd..1b11779 100644 --- a/Dtsod.cs +++ b/Dtsod/DtsodV21.cs @@ -4,18 +4,25 @@ using System.Linq; using System.Text; using static DTLib.PublicLog; -namespace DTLib +namespace DTLib.Dtsod { // // это как json но не совсем // - public class Dtsod : Dictionary + // v2.0 + // полностью переписан парсер + // + // v2.1 + // парсер теперь не может игнорировать комменты, потом починю + // теперь числовые значения конвертируются в правильный тип, а не в int64/uint64 (новый вариант switch из c#9.0 делал какую-то херню) + // исправлены некоторые другие баги + class DtsodV21 : Dictionary { static readonly bool debug = false; + string Text; - public string Text { get; } //public Dictionary Values { get; set; } - public Dtsod(string text) + public DtsodV21(string text) { Text = text; foreach (KeyValuePair pair in Parse(text)) @@ -23,7 +30,7 @@ namespace DTLib } // выдаёт Exception - new public dynamic this[string key] + public new dynamic this[string key] { get { @@ -38,7 +45,7 @@ namespace DTLib } // не выдаёт KeyNotFoundException - new public bool TryGetValue(string key, out dynamic value) + public new bool TryGetValue(string key, out dynamic value) { try { @@ -79,7 +86,7 @@ namespace DTLib Int, Uint, Null, - Boolean,*/ + Bool,*/ Default } @@ -88,23 +95,25 @@ namespace DTLib Dictionary parsed = new(); int i = 0; for (; i < text.Length; i++) ReadName(); + if (debug) LogNoTime("g", $"Parse returns {parsed.Keys.Count} keys\n"); return parsed; + // СЛОМАНО + /*void ReadCommentLine() + { + for (; i < text.Length && text[i] != '\n'; i++) if (debug) LogNoTime("gray", text[i].ToString()); + }*/ + void ReadName() { - void ReadCommentLine() - { - for (; i < text.Length && text[i] != '\n'; i++) ; - } bool isListElem = false; dynamic value = null; StringBuilder defaultNameBuilder = new(); - if (debug) LogNoTime("m", "ReadName"); + if (debug) LogNoTime("m", "ReadName\n"); for (; i < text.Length; i++) { - if (debug) LogNoTime("w", text[i].ToString()); switch (text[i]) { case ' ': @@ -114,31 +123,32 @@ namespace DTLib break; case ':': i++; - value = ReadValue(); string name = defaultNameBuilder.ToString(); - if (debug) LogNoTime("c", $"parsed.Add({name}, {value})\n"); + value = ReadValue(); + if (debug) LogNoTime("c", $"parsed.Add({name}, {value} { value.GetType() })\n"); if (isListElem) { if (!parsed.ContainsKey(name)) parsed.Add(name, new List()); parsed[name].Add(value); } else parsed.Add(name, value); - if (debug) LogNoTime("g", "ReadName return\n"); return; // строка, начинающаяся с # будет считаться комментом case '#': - ReadCommentLine(); + //ReadCommentLine(); break; case '}': throw new Exception("Parse.ReadName() error: unexpected '}' at " + i + " char"); // если $ перед названием параметра поставить, значение value добавится в лист с названием name case '$': + if (debug) LogNoTime("w", text[i].ToString()); if (defaultNameBuilder.ToString().Length != 0) throw new Exception("Parse.ReadName() error: unexpected '$' at " + i + " char"); isListElem = true; break; case ';': throw new Exception("Parse.ReadName() error: unexpected ';' at " + i + " char"); default: + if (debug) LogNoTime("w", text[i].ToString()); defaultNameBuilder.Append(text[i]); break; } @@ -148,6 +158,7 @@ namespace DTLib dynamic ReadValue() { ValueType type = ValueType.Default; + dynamic value = null; string ReadString() { @@ -181,7 +192,8 @@ namespace DTLib case '\n': break; case ',': - output.Add(ParseValueToRightType(valueBuilder.ToString())); + ParseValueToRightType(valueBuilder.ToString()); + output.Add(value); valueBuilder.Clear(); break; default: @@ -190,7 +202,10 @@ namespace DTLib } } if (valueBuilder.Length > 0) - output.Add(ParseValueToRightType(valueBuilder.ToString())); + { + ParseValueToRightType(valueBuilder.ToString()); + output.Add(value); + } if (debug) LogNoTime("c", text[i].ToString()); type = ValueType.List; return output; @@ -198,55 +213,92 @@ namespace DTLib Dictionary ReadComplex() { - i++; StringBuilder valueBuilder = new(); - for (; text[i] != '}'; i++) + int balance = 1; + i++; + for (; balance != 0; i++) { if (debug) LogNoTime("y", text[i].ToString()); - if (text[i] == '"') + switch (text[i]) { - valueBuilder.Append(ReadString()); + case '"': + valueBuilder.Append(ReadString()); + break; + case '}': + balance--; + if (debug) LogNoTime("b", $"\nbalance -- = {balance}\n"); + if (balance != 0) valueBuilder.Append(text[i]); + break; + case '{': + balance++; + if (debug) LogNoTime("b", $"\nbalance ++ = {balance}\n"); + valueBuilder.Append(text[i]); + break; + default: + valueBuilder.Append(text[i]); + break; } - else valueBuilder.Append(text[i]); } - if (debug) LogNoTime("y", text[i].ToString()); + i--; // i++ в for выполняется даже когда balance == 0, то есть text[i] получается == ;, что ломает всё type = ValueType.Complex; - if (debug) LogNoTime("g", valueBuilder.ToString()); return Parse(valueBuilder.ToString()); } - dynamic ParseValueToRightType(string stringValue) + void ParseValueToRightType(string stringValue) { - if (debug) LogNoTime("g", $"\nParseValueToRightType({stringValue})"); - return stringValue switch + if (debug) LogNoTime("b", $"\nParseValueToRightType({stringValue})\n"); + switch (stringValue) { - _ when stringValue.Contains('"') => stringValue.Remove(stringValue.Length - 1).Remove(0, 1), + // bool - "true" or "false" => stringValue.ToBool(), + case "true": + case "false": + value = stringValue.ToBool(); + break; // null - "null" => null, - // double - _ when stringValue.Contains('.') => stringValue.ToDouble(), - // ushort, ulong, uint - _ when (stringValue.Length > 2 && stringValue[stringValue.Length - 2] == 'u') => stringValue[stringValue.Length - 1] switch - { - 's' => stringValue.Remove(stringValue.Length - 2).ToUShort(), - 'i' => stringValue.Remove(stringValue.Length - 2).ToUInt(), - 'l' => stringValue.Remove(stringValue.Length - 2).ToULong(), - _ => throw new Exception($"Dtsod.Parse.ReadValue() error: wrong type ") - }, - // short, long, int - _ => stringValue[stringValue.Length - 1] switch - { - 's' => stringValue.Remove(stringValue.Length - 1).ToShort(), - 'l' => stringValue.Remove(stringValue.Length - 1).ToLong(), - _ => stringValue.ToInt() - } + case "null": + value = null; + break; + default: + if (stringValue.Contains('"')) value = stringValue.Remove(stringValue.Length - 1).Remove(0, 1); + // double + else if (stringValue.Contains('.')) value = stringValue.ToDouble(); + // ushort; ulong; uint + else if (stringValue.Length > 2 && stringValue[stringValue.Length - 2] == 'u') + { + switch (stringValue[stringValue.Length - 1]) + { + case 's': + value = stringValue.Remove(stringValue.Length - 2).ToUShort(); + break; + case 'i': + value = stringValue.Remove(stringValue.Length - 2).ToUInt(); + break; + case 'l': + value = stringValue.Remove(stringValue.Length - 2).ToULong(); + break; + default: + throw new Exception($"Dtsod.Parse.ReadValue() error: value= wrong type "); + }; + } + // short; long; int + else switch (stringValue[stringValue.Length - 1]) + { + case 's': + value = stringValue.Remove(stringValue.Length - 1).ToShort(); + break; + case 'l': + value = stringValue.Remove(stringValue.Length - 1).ToLong(); + break; + default: + value = stringValue.ToShort(); + break; + } + break; }; } - dynamic value = null; StringBuilder defaultValueBuilder = new(); if (debug) LogNoTime("m", "\nReadValue\n"); for (; i < text.Length; i++) @@ -263,26 +315,32 @@ namespace DTLib value = ReadString(); break; case ';': - if (debug) LogNoTime("g", $"\nReadValue returns type {type} value <{value}>\n"); - return type switch + switch (type) { - ValueType.List or ValueType.Complex => value, - ValueType.String => ParseValueToRightType(value), - ValueType.Default => ParseValueToRightType(defaultValueBuilder.ToString()), - _ => throw new Exception($"Dtlib.Parse.ReadValue() error: can't convert value to type <{type}>") + case ValueType.String: + ParseValueToRightType(value); + break; + case ValueType.Default: + ParseValueToRightType(defaultValueBuilder.ToString()); + break; }; + return value; case '[': value = ReadList(); break; case '{': value = ReadComplex(); break; + // строка, начинающаяся с # будет считаться комментом + case '#': + //ReadCommentLine(); + break; default: defaultValueBuilder.Append(text[i]); break; } } - throw new Exception("Dtsod.Parse.ReadValue error: end of text"); + throw new Exception("Dtsod.Parse.ReadValue error: wtf it's the end of function"); } } } diff --git a/Dtsod/DtsodV22.cs b/Dtsod/DtsodV22.cs new file mode 100644 index 0000000..befd24e --- /dev/null +++ b/Dtsod/DtsodV22.cs @@ -0,0 +1,456 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace DTLib.Dtsod +{ + // + // это как json но не совсем + // + // v20 + // полностью переписан парсер + // + // v21 + // парсер теперь не может игнорировать комменты, потом починю + // теперь числовые значения конвертируются в правильный тип, а не в int64/uint64 (новый вариант switch из c#9.0 делал какую-то херню) + // исправлены некоторые другие баги + // + // v22 + // метод ToString() теперь действительно деконструирует объект в текст, а не возвращает параметр text из конструктора + + public class DtsodV22 : Dictionary + { + static readonly bool debug = false; + + public struct ValueStruct + { + public dynamic Value; + public ValueTypes Type; + public bool IsList; + public ValueStruct(ValueTypes type, dynamic value, bool isList) + { + Value = value; + Type = type; + IsList = isList; + } + public ValueStruct(ValueTypes type, dynamic value) + { + Value = value; + Type = type; + IsList = false; + } + } + + public DtsodV22(string text) + { + foreach (KeyValuePair pair in Parse(text)) + Add(pair.Key, pair.Value); + } + + + public DtsodV22(Dictionary dict) + { + foreach (KeyValuePair pair in dict) + Add(pair.Key, pair.Value); + } + + // выдаёт Exception + public new dynamic this[string key] + { + get + { + if (TryGetValue(key, out dynamic value)) return value; + else throw new Exception($"Dtsod[{key}] key not found"); + } + set + { + if (TrySetValue(key, value)) return; + else throw new Exception($"Dtsod[{key}] key not found"); + } + } + + // не выдаёт KeyNotFoundException + public bool TryGetValue(string key, out dynamic value) + { + try + { + value = base[key].Value; + return true; + } + catch (KeyNotFoundException) + { + value = null; + return false; + } + } + public bool TrySetValue(string key, dynamic value) + { + try + { + bool isList; + if (value is IList) isList = true; + else isList = false; + base[key] = new(base[key].Type, value, isList); + return true; + } + catch (KeyNotFoundException) + { + return false; + } + } + + DtsodV22 Parse(string text) + { + Dictionary parsed = new(); + int i = 0; + for (; i < text.Length; i++) ReadName(); + Debug("g", $"Parse returns {parsed.Keys.Count} keys\n"); + return new DtsodV22(parsed); + + // СЛОМАНО + /*void ReadCommentLine() + { + for (; i < text.Length && text[i] != '\n'; i++) Debug("gray", text[i].ToString()); + }*/ + + void ReadName() + { + + bool isListElem = false; + dynamic value = null; + StringBuilder defaultNameBuilder = new(); + + Debug("m", "ReadName\n"); + for (; i < text.Length; i++) + { + switch (text[i]) + { + case ' ': + case '\t': + case '\r': + case '\n': + break; + case ':': + i++; + string name = defaultNameBuilder.ToString(); + value = ReadValue(out var type, out var isList); + Debug("c", $"parsed.Add({name},{type} {value} )\n"); + if (isListElem) + { + if (!parsed.ContainsKey(name)) parsed.Add(name, new(type, new List(), isList)); + parsed[name].Value.Add(value); + } + else parsed.Add(name, new(type, value, isList)); + return; + // строка, начинающаяся с # будет считаться комментом + case '#': + //ReadCommentLine(); + break; + case '}': + throw new Exception("Parse.ReadName() error: unexpected '}' at " + i + " char"); + // если $ перед названием параметра поставить, значение value добавится в лист с названием name + case '$': + Debug("w", text[i].ToString()); + if (defaultNameBuilder.ToString().Length != 0) throw new Exception("Parse.ReadName() error: unexpected '$' at " + i + " char"); + isListElem = true; + break; + case ';': + throw new Exception("Parse.ReadName() error: unexpected ';' at " + i + " char"); + default: + Debug("w", text[i].ToString()); + defaultNameBuilder.Append(text[i]); + break; + } + } + } + + dynamic ReadValue(out ValueTypes outType, out bool isList) + { + ValueTypes type = ValueTypes.Unknown; + isList = false; + dynamic value = null; + + string ReadString() + { + i++; + StringBuilder valueBuilder = new(); + valueBuilder.Append('"'); + for (; text[i] != '"' || text[i - 1] == '\\'; i++) + { + Debug("gray", text[i].ToString()); + valueBuilder.Append(text[i]); + } + valueBuilder.Append('"'); + Debug("gray", text[i].ToString()); + type = ValueTypes.String; + return valueBuilder.ToString(); + } + + List ReadList() + { + i++; + List output = new(); + StringBuilder valueBuilder = new(); + for (; text[i] != ']'; i++) + { + Debug("c", text[i].ToString()); + switch (text[i]) + { + case ' ': + case '\t': + case '\r': + case '\n': + break; + case ',': + ParseValueToRightType(valueBuilder.ToString()); + output.Add(value); + valueBuilder.Clear(); + break; + default: + valueBuilder.Append(text[i]); + break; + } + } + if (valueBuilder.Length > 0) + { + ParseValueToRightType(valueBuilder.ToString()); + output.Add(value); + } + Debug("c", text[i].ToString()); + type = ValueTypes.List; + return output; + } + + Dictionary ReadComplex() + { + StringBuilder valueBuilder = new(); + int balance = 1; + i++; + for (; balance != 0; i++) + { + Debug("y", text[i].ToString()); + switch (text[i]) + { + case '"': + valueBuilder.Append(ReadString()); + break; + case '}': + balance--; + Debug("b", $"\nbalance -- = {balance}\n"); + if (balance != 0) valueBuilder.Append(text[i]); + break; + case '{': + balance++; + Debug("b", $"\nbalance ++ = {balance}\n"); + valueBuilder.Append(text[i]); + break; + default: + valueBuilder.Append(text[i]); + break; + } + } + i--; // i++ в for выполняется даже когда balance == 0, то есть text[i] получается == ;, что ломает всё + type = ValueTypes.Complex; + return Parse(valueBuilder.ToString()); + } + + void ParseValueToRightType(string stringValue) + { + Debug("b", $"\nParseValueToRightType({stringValue})\n"); + switch (stringValue) + { + + // bool + case "true": + case "false": + type = ValueTypes.Bool; + value = stringValue.ToBool(); + break; + // null + case "null": + type = ValueTypes.Null; + value = null; + break; + default: + if (stringValue.Contains('"')) + { + type = ValueTypes.String; + value = stringValue.Remove(stringValue.Length - 1).Remove(0, 1); + } + // double + else if (stringValue.Contains('.')) + { + type = ValueTypes.Double; + value = stringValue.ToDouble(); + } + // ushort; ulong; uint + else if (stringValue.Length > 2 && stringValue[stringValue.Length - 2] == 'u') + { + switch (stringValue[stringValue.Length - 1]) + { + case 's': + type = ValueTypes.UShort; + value = stringValue.Remove(stringValue.Length - 2).ToUShort(); + break; + case 'i': + type = ValueTypes.UInt; + value = stringValue.Remove(stringValue.Length - 2).ToUInt(); + break; + case 'l': + type = ValueTypes.ULong; + value = stringValue.Remove(stringValue.Length - 2).ToULong(); + break; + default: + throw new Exception($"Dtsod.Parse.ReadValue() error: value <{stringValue}> has wrong type"); + }; + } + // short; long; int + else switch (stringValue[stringValue.Length - 1]) + { + case 's': + type = ValueTypes.Short; + value = stringValue.Remove(stringValue.Length - 1).ToShort(); + break; + case 'l': + type = ValueTypes.Long; + value = stringValue.Remove(stringValue.Length - 1).ToLong(); + break; + default: + type = ValueTypes.Int; + value = stringValue.ToShort(); + break; + } + break; + }; + } + + StringBuilder defaultValueBuilder = new(); + Debug("m", "\nReadValue\n"); + for (; i < text.Length; i++) + { + Debug("b", text[i].ToString()); + switch (text[i]) + { + case ' ': + case '\t': + case '\r': + case '\n': + break; + case '"': + value = ReadString(); + break; + case '[': + value = ReadList(); + break; + case '{': + value = ReadComplex(); + break; + case ';': + switch (type) + { + case ValueTypes.String: + ParseValueToRightType(value); + break; + case ValueTypes.Unknown: + ParseValueToRightType(defaultValueBuilder.ToString()); + break; + case ValueTypes.List: + isList = true; + break; + }; + outType = type; + return value; + // строка, начинающаяся с # будет считаться комментом + case '#': + //ReadCommentLine(); + break; + default: + defaultValueBuilder.Append(text[i]); + break; + } + } + throw new Exception("Dtsod.Parse.ReadValue error: wtf it's the end of function"); + } + } + + public override string ToString() => Deconstruct(this); + + ushort tabCount = 0; + string Deconstruct(DtsodV22 dtsod) + { + StringBuilder outBuilder = new(); + foreach (var key in dtsod.Keys) + { + outBuilder.Append('\t', tabCount); + outBuilder.Append(key); + outBuilder.Append(": "); + dtsod.TryGetValue(key, out ValueStruct value); + switch (value.Type) + { + case ValueTypes.List: + outBuilder.Append("\"list deconstruction is'nt implemented yet\""); + break; + case ValueTypes.Complex: + outBuilder.Append("\n"); + outBuilder.Append('\t', tabCount); + outBuilder.Append("{\n"); + tabCount++; + outBuilder.Append(Deconstruct(value.Value)); + tabCount--; + outBuilder.Append('\t', tabCount); + outBuilder.Append("}"); + break; + case ValueTypes.String: + outBuilder.Append("\""); + outBuilder.Append(value.Value.ToString()); + outBuilder.Append("\""); + break; + case ValueTypes.Short: + outBuilder.Append(value.Value.ToString()); + outBuilder.Append("s"); + break; + case ValueTypes.Int: + outBuilder.Append(value.Value.ToString()); + break; + case ValueTypes.Long: + outBuilder.Append(value.Value.ToString()); + outBuilder.Append("l"); + break; + case ValueTypes.UShort: + outBuilder.Append(value.Value.ToString()); + outBuilder.Append("us"); + break; + case ValueTypes.UInt: + outBuilder.Append(value.Value.ToString()); + outBuilder.Append("ui"); + break; + case ValueTypes.ULong: + outBuilder.Append(value.Value.ToString()); + outBuilder.Append("uk"); + break; + case ValueTypes.Double: + outBuilder.Append(value.Value.ToString(System.Globalization.CultureInfo.InvariantCulture)); + break; + case ValueTypes.Null: + outBuilder.Append("null"); + break; + case ValueTypes.Bool: + outBuilder.Append(value.Value.ToString().ToLower()); + break; + default: + throw new Exception($"Dtsod.Deconstruct() error: unknown type: {value.Type}"); + } + + outBuilder.Append(";\n"); + } + return outBuilder.ToString(); + } + + void Debug(params string[] msg) + { + if (debug) PublicLog.LogNoTime(msg); + } + } +} diff --git a/Dtsod/ValueTypes.cs b/Dtsod/ValueTypes.cs new file mode 100644 index 0000000..a7664c1 --- /dev/null +++ b/Dtsod/ValueTypes.cs @@ -0,0 +1,19 @@ +namespace DTLib.Dtsod +{ + public enum ValueTypes + { + List, + Complex, + String, + Short, + Int, + Long, + UShort, + UInt, + ULong, + Double, + Null, + Bool, + Unknown + } +} diff --git a/Filesystem/Directory.cs b/Filesystem/Directory.cs index b4249fe..474443b 100644 --- a/Filesystem/Directory.cs +++ b/Filesystem/Directory.cs @@ -64,8 +64,12 @@ namespace DTLib.Filesystem for (int i = 0; i < files.Count; i++) File.Delete(files[i]); for (int i = subdirs.Count - 1; i >= 0; i--) - System.IO.Directory.Delete(subdirs[i]); - System.IO.Directory.Delete(dir); + { + PublicLog.Log($"deleting {subdirs[i]}\n"); + if (Directory.Exists(subdirs[i])) System.IO.Directory.Delete(subdirs[i], true); + } + PublicLog.Log($"deleting {dir}\n"); + if (Directory.Exists(dir)) System.IO.Directory.Delete(dir, true); } public static string[] GetFiles(string dir) => System.IO.Directory.GetFiles(dir); @@ -112,5 +116,20 @@ namespace DTLib.Filesystem } public static string GetCurrent() => System.IO.Directory.GetCurrentDirectory(); + + public static void GrantAccess(string fullPath) + { + System.IO.DirectoryInfo dirInfo = new System.IO.DirectoryInfo(fullPath); + System.Security.AccessControl.DirectorySecurity dirSecurity = dirInfo.GetAccessControl(); + dirSecurity.AddAccessRule(new System.Security.AccessControl.FileSystemAccessRule( + new System.Security.Principal.SecurityIdentifier( + System.Security.Principal.WellKnownSidType.WorldSid, null), + System.Security.AccessControl.FileSystemRights.FullControl, + System.Security.AccessControl.InheritanceFlags.ObjectInherit | + System.Security.AccessControl.InheritanceFlags.ContainerInherit, + System.Security.AccessControl.PropagationFlags.NoPropagateInherit, + System.Security.AccessControl.AccessControlType.Allow)); + dirInfo.SetAccessControl(dirSecurity); + } } } diff --git a/Filesystem/File.cs b/Filesystem/File.cs index 6abf5ca..15ed96f 100644 --- a/Filesystem/File.cs +++ b/Filesystem/File.cs @@ -9,8 +9,9 @@ namespace DTLib.Filesystem public static bool Exists(string file) => System.IO.File.Exists(file); // если файл не существует, создаёт файл, создаёт папки из его пути - public static void Create(string file) + public static void Create(string file, bool delete_old = false) { + if (delete_old && File.Exists(file)) File.Delete(file); if (!File.Exists(file)) { if (file.Contains("\\")) Directory.Create(file.Remove(file.LastIndexOf('\\'))); @@ -65,9 +66,8 @@ namespace DTLib.Filesystem } public static System.IO.FileStream OpenWrite(string file) { - if (Exists(file)) Delete(file); - File.Create(file); - return System.IO.File.OpenWrite(file); + File.Create(file, true); + return System.IO.File.Open(file, System.IO.FileMode.OpenOrCreate); } public static System.IO.FileStream OpenAppend(string file) { diff --git a/Network/FSP.cs b/Network/FSP.cs index 8441a4f..4001bc7 100644 --- a/Network/FSP.cs +++ b/Network/FSP.cs @@ -1,4 +1,5 @@ -using DTLib.Filesystem; +using DTLib.Dtsod; +using DTLib.Filesystem; using System; using System.Collections.Generic; using System.Net.Sockets; @@ -13,13 +14,17 @@ namespace DTLib.Network public class FSP { Socket mainSocket; - public bool debug = true; + public bool debug = false; public FSP(Socket _mainSocket) => mainSocket = _mainSocket; public uint BytesDownloaded = 0; public uint BytesUploaded = 0; public uint Filesize = 0; + /*public delegate void PackageTransferDel(uint size); + public event PackageTransferDel PackageRecieved; + public event PackageTransferDel PackageSent;*/ + // скачивает файл с помощью FSP протокола public void DownloadFile(string filePath_server, string filePath_client) { @@ -31,7 +36,7 @@ namespace DTLib.Network public void DownloadFile(string filePath_client) { - File.Create(filePath_client); + BytesDownloaded = 0; using var fileStream = File.OpenWrite(filePath_client); Filesize = mainSocket.GetPackage().ToStr().ToUInt(); var hashstr = mainSocket.GetPackage().HashToString(); @@ -40,68 +45,79 @@ namespace DTLib.Network byte[] buffer = new byte[5120]; int fullPackagesCount = SimpleConverter.Truncate(Filesize / buffer.Length); // рассчёт скорости - int seconds = 0; + /*int seconds = 0; var speedCounter = new Timer(true, 1000, () => { seconds++; - Log("c", $"speed= {packagesCount * buffer.Length / (seconds * 1000)} kb/s\n"); - }); + PackageRecieved(BytesDownloaded); + });*/ // получение файла - for (; packagesCount < fullPackagesCount; packagesCount++) + + for (byte n = 0; packagesCount < fullPackagesCount; packagesCount++) { buffer = mainSocket.GetPackage(); + BytesDownloaded += (uint)buffer.Length; fileStream.Write(buffer, 0, buffer.Length); - fileStream.Flush(); + if (n == 100) + { + fileStream.Flush(); + n = 0; + } + else n++; } - speedCounter.Stop(); // получение остатка if ((Filesize - fileStream.Position) > 0) { mainSocket.SendPackage("remain request".ToBytes()); buffer = mainSocket.GetPackage(); + BytesDownloaded += (uint)buffer.Length; fileStream.Write(buffer, 0, buffer.Length); } + //speedCounter.Stop(); fileStream.Flush(); fileStream.Close(); - if (debug) Log(new string[] { "g", $" downloaded {packagesCount * 5120 + buffer.Length} of {Filesize} bytes\n" }); + if (debug) Log(new string[] { "g", $" downloaded {BytesDownloaded} of {Filesize} bytes\n" }); } + public byte[] DownloadFileToMemory(string filePath_server) { + BytesDownloaded = 0; if (debug) Log("b", $"requesting file download: {filePath_server}\n"); mainSocket.SendPackage("requesting file download".ToBytes()); mainSocket.SendPackage(filePath_server.ToBytes()); using var fileStream = new System.IO.MemoryStream(); - var fileSize = mainSocket.GetPackage().ToStr().ToUInt(); + Filesize = mainSocket.GetPackage().ToStr().ToUInt(); var hashstr = mainSocket.GetPackage().HashToString(); mainSocket.SendPackage("ready".ToBytes()); int packagesCount = 0; byte[] buffer = new byte[5120]; - int fullPackagesCount = SimpleConverter.Truncate(fileSize / buffer.Length); + int fullPackagesCount = SimpleConverter.Truncate(Filesize / buffer.Length); // рассчёт скорости - int seconds = 0; + /*int seconds = 0; var speedCounter = new Timer(true, 1000, () => { seconds++; - Log("c", $"speed= {packagesCount * buffer.Length / (seconds * 1000)} kb/s\n"); - }); + PackageRecieved(BytesDownloaded); + });*/ // получение файла for (; packagesCount < fullPackagesCount; packagesCount++) { buffer = mainSocket.GetPackage(); + BytesDownloaded += (uint)buffer.Length; fileStream.Write(buffer, 0, buffer.Length); - fileStream.Flush(); } - speedCounter.Stop(); // получение остатка - if ((fileSize - fileStream.Position) > 0) + if ((Filesize - fileStream.Position) > 0) { mainSocket.SendPackage("remain request".ToBytes()); buffer = mainSocket.GetPackage(); + BytesDownloaded += (uint)buffer.Length; fileStream.Write(buffer, 0, buffer.Length); } + //speedCounter.Stop(); byte[] output = fileStream.GetBuffer(); fileStream.Close(); - if (debug) Log(new string[] { "g", $" downloaded {packagesCount * 5120 + buffer.Length} of {fileSize} bytes\n" }); + if (debug) Log(new string[] { "g", $" downloaded {BytesDownloaded} of {Filesize} bytes\n" }); return output; } @@ -118,32 +134,42 @@ namespace DTLib.Network byte[] buffer = new byte[5120]; var hashstr = fileHash.HashToString(); int packagesCount = 0; - // отправка файла int fullPackagesCount = SimpleConverter.Truncate(Filesize / buffer.Length); + // рассчёт скорости + /*int seconds = 0; + var speedCounter = new Timer(true, 1000, () => + { + seconds++; + PackageSent(BytesUploaded); + });*/ + // отправка файла for (; packagesCount < fullPackagesCount; packagesCount++) { fileStream.Read(buffer, 0, buffer.Length); mainSocket.SendPackage(buffer); + BytesUploaded += (uint)buffer.Length; } // досылка остатка if ((Filesize - fileStream.Position) > 0) { - if (mainSocket.GetPackage().ToStr() != "remain request") throw new Exception("FSP_Upload() error: didn't get remain request"); + mainSocket.GetAnswer("remain request"); buffer = new byte[(Filesize - fileStream.Position).ToInt()]; fileStream.Read(buffer, 0, buffer.Length); mainSocket.SendPackage(buffer); + BytesUploaded += (uint)buffer.Length; } + //speedCounter.Stop(); fileStream.Close(); - if (debug) Log(new string[] { "g", $" uploaded {packagesCount * 5120 + buffer.Length} of {Filesize} bytes\n" }); + if (debug) Log(new string[] { "g", $" uploaded {BytesUploaded} of {Filesize} bytes\n" }); } public void DownloadByManifest(string dirOnServer, string dirOnClient, bool overwrite = false, bool delete_excess = false) { if (!dirOnClient.EndsWith("\\")) dirOnClient += "\\"; if (!dirOnServer.EndsWith("\\")) dirOnServer += "\\"; - Log("b", "downloading manifest <", "c", dirOnServer + "manifest.dtsod", "b", ">\n"); - var manifest = new Dtsod(DownloadFileToMemory(dirOnServer + "manifest.dtsod").ToStr()); - Log("g", $"found {manifest.Values.Count} files in manifest\n"); + if (debug) Log("b", "downloading manifest <", "c", dirOnServer + "manifest.dtsod", "b", ">\n"); + var manifest = new DtsodV22(DownloadFileToMemory(dirOnServer + "manifest.dtsod").ToStr()); + if (debug) Log("g", $"found {manifest.Values.Count} files in manifest\n"); var hasher = new Hasher(); foreach (string fileOnServer in manifest.Keys) { @@ -174,18 +200,18 @@ namespace DTLib.Network } } // удаление пустых папок - foreach (string dir in dirs) + /*foreach (string dir in dirs) { if (Directory.Exists(dir) && Directory.GetAllFiles(dir).Count == 0) { if (debug) Log("y", $"deleting empty dir: {dir}\n"); Directory.Delete(dir); } - } + }*/ } } - static public void CreateManifest(string dir) + public static void CreateManifest(string dir) { if (!dir.EndsWith("\\")) dir += "\\"; Log($"b", $"creating manifest of {dir}\n"); diff --git a/Network/OldNetwork.cs b/Network/OldNetwork.cs index f9f21b1..977629b 100644 --- a/Network/OldNetwork.cs +++ b/Network/OldNetwork.cs @@ -11,7 +11,7 @@ namespace DTLib.Network // получает с сайта публичный ip - public static string GetPublicIP() => new WebClient().DownloadString("https://ipv4bot.whatismyipaddress.com/"); + public static string GetPublicIP() => new WebClient().DownloadString("https://ifconfig.me/ip"); // пингует айпи с помощью встроенной в винду проги, возвращает задержку public static string PingIP(string address) diff --git a/Network/Package.cs b/Network/Package.cs index 3797ee6..18ff8a8 100644 --- a/Network/Package.cs +++ b/Network/Package.cs @@ -8,7 +8,7 @@ namespace DTLib.Network // // отправка/получение пакетов // - static public class Package + public static class Package { // принимает пакет public static byte[] GetPackage(this Socket socket) @@ -22,7 +22,6 @@ namespace DTLib.Network { socket.Receive(data, data.Length, 0); packageSize = data.BytesToInt(); - } if (packageSize != 0 && socket.Available >= packageSize) { @@ -47,5 +46,12 @@ namespace DTLib.Network list.AddRange(data); socket.Send(list.ToArray()); } + + // получает пакет и выбрасывает исключение, если пакет не соответствует образцу + public static void GetAnswer(this Socket socket, string answer) + { + var rec = socket.GetPackage().ToStr(); + if (rec != answer) throw new Exception($"GetAnswer() error: invalid answer: <{rec}>"); + } } } diff --git a/SimpleConverter.cs b/SimpleConverter.cs index 22bb7a5..18f7021 100644 --- a/SimpleConverter.cs +++ b/SimpleConverter.cs @@ -51,14 +51,6 @@ namespace DTLib // из-за чего вызов метода так: Math.Truncate(10/3) выдаст ошибку "неоднозначный вызов" public static int Truncate(this T number) => Math.Truncate(number.ToDouble()).ToInt(); - // сортирует в порядке возрастания элементы если это возможно, используя стандартный метод list.Sort(); - public static T[] Sort(this T[] array) - { - var list = array.ToList(); - list.Sort(); - return list.ToArray(); - } - // массив в лист public static List ToList(this T[] input) { @@ -84,18 +76,6 @@ namespace DTLib return false; } - // конвертирует массив в строку - public static string MergeToString(this T[] array, string separator) - { - var b = new StringBuilder(); - for (int i = 0; i < array.Length; i++) - { - b.Append(array[i].ToString()); - b.Append(separator); - } - return b.ToString(); - } - // сокращение конвертации public static int ToInt(this T input) => Convert.ToInt32(input); public static uint ToUInt(this T input) => Convert.ToUInt32(input); @@ -108,14 +88,6 @@ namespace DTLib public static sbyte ToSByte(this T input) => Convert.ToSByte(input); public static bool ToBool(this T input) => Convert.ToBoolean(input); - public static string AutoBuild(params object[] parts) - { - var builder = new StringBuilder(); - for (int i = 0; i < parts.Length; i++) - builder.Append(parts[i]); - return builder.ToString(); - } - public static int BytesToInt(this byte[] bytes) { int output = 0; @@ -135,7 +107,15 @@ namespace DTLib return output.ToArray(); } - public static string ToString(this IEnumerable collection, string separator) + public static string AutoBuild(params object[] parts) + { + var builder = new StringBuilder(); + for (int i = 0; i < parts.Length; i++) + builder.Append(parts[i].ToString()); + return builder.ToString(); + } + + public static string MergeToString(this IEnumerable collection, string separator) { StringBuilder builder = new(); foreach (T elem in collection) @@ -146,6 +126,22 @@ namespace DTLib builder.Remove(builder.Length - separator.Length, separator.Length); return builder.ToString(); } + public static string MergeToString(this IEnumerable collection) + { + StringBuilder builder = new(); + foreach (T elem in collection) + { + builder.Append(elem.ToString()); + } + return builder.ToString(); + } + public static string Multiply(this string input, int howMany) + { + StringBuilder b = new(); + for (int i = 0; i < howMany; i++) + b.Append(input); + return b.ToString(); + } } } \ No newline at end of file