From 60e3bc6251b55c1d979c49bb386477fb3ed6b40f Mon Sep 17 00:00:00 2001 From: Timerix Date: Sat, 7 Aug 2021 01:08:42 +0300 Subject: [PATCH] project structure changed --- ConsoleGUI/Container.cs | 42 ++++++ ConsoleGUI/Control.cs | 21 +++ ConsoleGUI/IDrawable.cs | 16 +++ ConsoleGUI/Label.cs | 32 +++++ ConsoleGUI/Window.cs | 189 ++++++++++++++++++++++++++ DTLib.csproj | 14 +- Filesystem/Directory.cs | 116 ++++++++++++++++ Filesystem/File.cs | 78 +++++++++++ Filesystem/OldFilework.cs | 69 ++++++++++ Filework.cs | 253 ----------------------------------- Hasher.cs | 4 +- Network.cs | 273 -------------------------------------- Network/FSP.cs | 208 +++++++++++++++++++++++++++++ Network/OldNetwork.cs | 33 +++++ Network/Package.cs | 51 +++++++ 15 files changed, 868 insertions(+), 531 deletions(-) create mode 100644 ConsoleGUI/Container.cs create mode 100644 ConsoleGUI/Control.cs create mode 100644 ConsoleGUI/IDrawable.cs create mode 100644 ConsoleGUI/Label.cs create mode 100644 ConsoleGUI/Window.cs create mode 100644 Filesystem/Directory.cs create mode 100644 Filesystem/File.cs create mode 100644 Filesystem/OldFilework.cs delete mode 100644 Filework.cs delete mode 100644 Network.cs create mode 100644 Network/FSP.cs create mode 100644 Network/OldNetwork.cs create mode 100644 Network/Package.cs diff --git a/ConsoleGUI/Container.cs b/ConsoleGUI/Container.cs new file mode 100644 index 0000000..5c0b51c --- /dev/null +++ b/ConsoleGUI/Container.cs @@ -0,0 +1,42 @@ +using System.Collections.Generic; + +namespace DTLib.ConsoleGUI +{ + public class Container : List, IDrawable + { + public (ushort x, ushort y) AnchorPoint { get; set; } + public ushort Width { get; set; } + public ushort Height { get; set; } + public char[] Textmap { get; private set; } + public char[] Colormap { get; private set; } + + public Container() { } + + public Container(ushort width, ushort height) + { + Width = width; + Height = height; + } + + public void GenTextmap() + { + Textmap = new char[Width * Height]; + for (int i = 0; i < Textmap.Length; i++) + Textmap[i] = ' '; + foreach (var element in this) + { + 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]; + } + } + } + + public void GenColormap() + { + + } + } +} diff --git a/ConsoleGUI/Control.cs b/ConsoleGUI/Control.cs new file mode 100644 index 0000000..6a65c4c --- /dev/null +++ b/ConsoleGUI/Control.cs @@ -0,0 +1,21 @@ +namespace DTLib.ConsoleGUI +{ + public class Control : IDrawable + { + 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 void GenTextmap() + { + + } + } +} diff --git a/ConsoleGUI/IDrawable.cs b/ConsoleGUI/IDrawable.cs new file mode 100644 index 0000000..123c24b --- /dev/null +++ b/ConsoleGUI/IDrawable.cs @@ -0,0 +1,16 @@ +namespace DTLib.ConsoleGUI +{ + public interface IDrawable + { + public (ushort x, ushort y) AnchorPoint { get; set; } + public ushort Width { get; } + public ushort Height { get; } + public char[] Textmap { get; } + public char[] Colormap { get; } + + public void GenTextmap(); + + public void GenColormap(); + + } +} diff --git a/ConsoleGUI/Label.cs b/ConsoleGUI/Label.cs new file mode 100644 index 0000000..587a868 --- /dev/null +++ b/ConsoleGUI/Label.cs @@ -0,0 +1,32 @@ +namespace DTLib.ConsoleGUI +{ + public class Label : IDrawable + { + 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 string TextmapFile { get; set; } + public string ColormapFile { get; set; } + + public Label() { } + + public Label(string textmapFile, string colormapFile) + { + TextmapFile = textmapFile; + ColormapFile = colormapFile; + } + + public void GenColormap() + { + + } + + public void GenTextmap() + { + + } + } +} diff --git a/ConsoleGUI/Window.cs b/ConsoleGUI/Window.cs new file mode 100644 index 0000000..6daecb5 --- /dev/null +++ b/ConsoleGUI/Window.cs @@ -0,0 +1,189 @@ +using DTLib.Filesystem; +using System; +using System.Collections.Generic; +using System.Text; + +namespace DTLib.ConsoleGUI +{ + // + // создание gui из текста в консоли + // + public class Window + { + 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) + { + 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 7693215..b3a6782 100644 --- a/DTLib.csproj +++ b/DTLib.csproj @@ -31,14 +31,22 @@ - + + + + + - + + + + + + - diff --git a/Filesystem/Directory.cs b/Filesystem/Directory.cs new file mode 100644 index 0000000..b4249fe --- /dev/null +++ b/Filesystem/Directory.cs @@ -0,0 +1,116 @@ +using System.Collections.Generic; + +namespace DTLib.Filesystem +{ + + public static class Directory + { + public static bool Exists(string dir) => System.IO.Directory.Exists(dir); + + // создает папку, если её не существует + public static void Create(string dir) + { + if (!Directory.Exists(dir)) + { + // проверяет существование папки, в которой нужно создать dir + if (dir.Contains("\\") && !Directory.Exists(dir.Remove(dir.LastIndexOf('\\')))) + Create(dir.Remove(dir.LastIndexOf('\\'))); + System.IO.Directory.CreateDirectory(dir); + } + } + // копирует все файлы и папки + public static void Copy(string source_dir, string new_dir, bool owerwrite = false) + { + Create(new_dir); + List subdirs = new List(); + List files = GetAllFiles(source_dir, ref subdirs); + for (int i = 0; i < subdirs.Count; i++) + { + Create(subdirs[i].Replace(source_dir, new_dir)); + } + for (int i = 0; i < files.Count; i++) + { + string f = files[i].Replace(source_dir, new_dir); + File.Copy(files[i], f, owerwrite); + //PublicLog.Log(new string[] {"g", $"file <", "c", files[i], "b", "> have copied to <", "c", newfile, "b", ">\n'" }); + } + } + + // копирует все файлы и папки и выдаёт список конфликтующих файлов + public static void Copy(string source_dir, string new_dir, out List conflicts, bool owerwrite = false) + { + conflicts = new List(); + var subdirs = new List(); + var files = GetAllFiles(source_dir, ref subdirs); + Create(new_dir); + for (int i = 0; i < subdirs.Count; i++) + { + Create(subdirs[i].Replace(source_dir, new_dir)); + } + for (int i = 0; i < files.Count; i++) + { + string newfile = files[i].Replace(source_dir, new_dir); + if (File.Exists(newfile)) conflicts.Add(newfile); + File.Copy(files[i], newfile, owerwrite); + //PublicLog.Log(new string[] {"g", $"file <", "c", files[i], "b", "> have copied to <", "c", newfile, "b", ">\n'" }); + } + } + + // удаляет папку со всеми подпапками и файлами + public static void Delete(string dir) + { + var subdirs = new List(); + var files = GetAllFiles(dir, ref subdirs); + 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); + } + + 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); + + // выдает список всех файлов + public static List GetAllFiles(string dir) + { + List all_files = new List(); + string[] cur_files = Directory.GetFiles(dir); + for (int i = 0; i < cur_files.Length; i++) + { + all_files.Add(cur_files[i]); + //PublicLog.Log(new string[] { "b", "file found: <", "c", cur_files[i], "b", ">\n" }); + } + string[] cur_subdirs = Directory.GetDirectories(dir); + for (int i = 0; i < cur_subdirs.Length; i++) + { + //PublicLog.Log(new string[] { "b", "subdir found: <", "c", cur_subdirs[i], "b", ">\n" }); + all_files.AddRange(GetAllFiles(cur_subdirs[i])); + } + return all_files; + } + + // выдает список всех файлов и подпапок в папке + public static List GetAllFiles(string dir, ref List all_subdirs) + { + List all_files = new List(); + string[] cur_files = Directory.GetFiles(dir); + for (int i = 0; i < cur_files.Length; i++) + { + all_files.Add(cur_files[i]); + //PublicLog.Log(new string[] { "b", "file found: <", "c", cur_files[i], "b", ">\n" }); + } + string[] cur_subdirs = Directory.GetDirectories(dir); + for (int i = 0; i < cur_subdirs.Length; i++) + { + all_subdirs.Add(cur_subdirs[i]); + //PublicLog.Log(new string[] { "b", "subdir found: <", "c", cur_subdirs[i], "b", ">\n" }); + all_files.AddRange(GetAllFiles(cur_subdirs[i], ref all_subdirs)); + } + return all_files; + } + + public static string GetCurrent() => System.IO.Directory.GetCurrentDirectory(); + } +} diff --git a/Filesystem/File.cs b/Filesystem/File.cs new file mode 100644 index 0000000..6abf5ca --- /dev/null +++ b/Filesystem/File.cs @@ -0,0 +1,78 @@ +using System; + +namespace DTLib.Filesystem +{ + public static class File + { + public static int GetSize(string file) => new System.IO.FileInfo(file).Length.ToInt(); + + public static bool Exists(string file) => System.IO.File.Exists(file); + + // если файл не существует, создаёт файл, создаёт папки из его пути + public static void Create(string file) + { + if (!File.Exists(file)) + { + if (file.Contains("\\")) Directory.Create(file.Remove(file.LastIndexOf('\\'))); + using var stream = System.IO.File.Create(file); + stream.Close(); + } + } + + public static void Copy(string srcPath, string newPath, bool replace = false) + { + if (!replace && Exists(newPath)) throw new Exception($"file <{newPath}> alredy exists"); + Create(newPath); + WriteAllBytes(newPath, ReadAllBytes(srcPath)); + } + + public static void Delete(string file) => System.IO.File.Delete(file); + + public static byte[] ReadAllBytes(string file) + { + using var stream = File.OpenRead(file); + int size = GetSize(file); + byte[] output = new byte[size]; + stream.Read(output, 0, size); + stream.Close(); + return output; + } + + public static string ReadAllText(string file) => ReadAllBytes(file).ToStr(); + + public static void WriteAllBytes(string file, byte[] content) + { + using var stream = File.OpenWrite(file); + stream.Write(content, 0, content.Length); + stream.Close(); + } + + public static void WriteAllText(string file, string content) => WriteAllBytes(file, content.ToBytes()); + + public static void AppendAllBytes(string file, byte[] content) + { + 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 System.IO.FileStream OpenRead(string file) + { + if (!Exists(file)) throw new Exception($"file not found: <{file}>"); + return System.IO.File.OpenRead(file); + } + public static System.IO.FileStream OpenWrite(string file) + { + if (Exists(file)) Delete(file); + File.Create(file); + return System.IO.File.OpenWrite(file); + } + public static System.IO.FileStream OpenAppend(string file) + { + File.Create(file); + return System.IO.File.Open(file, System.IO.FileMode.Append); + } + } +} diff --git a/Filesystem/OldFilework.cs b/Filesystem/OldFilework.cs new file mode 100644 index 0000000..2012d8d --- /dev/null +++ b/Filesystem/OldFilework.cs @@ -0,0 +1,69 @@ +using System; + +namespace DTLib.Filesystem +{ + // + // некоторые старые методы, которые хорошо бы вырезать + // + public static class OldFilework + { + // записывает текст в файл и закрывает файл + public static void LogToFile(string logfile, string msg) + { + lock (new object()) + { + File.AppendAllText(logfile, msg); + } + } + + // чтение параметров из конфига + public static string ReadFromConfig(string configfile, string key) + { + lock (new object()) + { + key += ": "; + using var reader = new System.IO.StreamReader(configfile); + while (!reader.EndOfStream) + { + string st = reader.ReadLine(); + if (st.StartsWith(key)) + { + string value = ""; + for (int i = key.Length; i < st.Length; i++) + { + if (st[i] == '#') return value; + if (st[i] == '%') + { + bool stop = false; + string placeholder = ""; + i++; + while (!stop) + { + if (st[i] == '%') + { + stop = true; + value += ReadFromConfig(configfile, placeholder); + } + else + { + placeholder += st[i]; + i++; + } + } + } + else value += st[i]; + } + reader.Close(); + //if (value == "") throw new System.Exception($"ReadFromConfig({configfile}, {key}) error: key not found"); + return value; + } + } + reader.Close(); + throw new Exception($"ReadFromConfig({configfile}, {key}) error: key not found"); + } + } + + + + } +} diff --git a/Filework.cs b/Filework.cs deleted file mode 100644 index a3469b3..0000000 --- a/Filework.cs +++ /dev/null @@ -1,253 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace DTLib -{ - // - // методы для работы с файловой системой - // - public static class Filework - { - // записывает текст в файл и закрывает файл - public static void LogToFile(string logfile, string msg) - { - lock (new object()) - { - File.AppendAllText(logfile, msg); - } - } - - // чтение параметров из конфига - public static string ReadFromConfig(string configfile, string key) - { - lock (new object()) - { - key += ": "; - using var reader = new System.IO.StreamReader(configfile); - while (!reader.EndOfStream) - { - string st = reader.ReadLine(); - if (st.StartsWith(key)) - { - string value = ""; - for (int i = key.Length; i < st.Length; i++) - { - if (st[i] == '#') return value; - if (st[i] == '%') - { - bool stop = false; - string placeholder = ""; - i++; - while (!stop) - { - if (st[i] == '%') - { - stop = true; - value += ReadFromConfig(configfile, placeholder); - } - else - { - placeholder += st[i]; - i++; - } - } - } - else value += st[i]; - } - reader.Close(); - //if (value == "") throw new System.Exception($"ReadFromConfig({configfile}, {key}) error: key not found"); - return value; - } - } - reader.Close(); - throw new Exception($"ReadFromConfig({configfile}, {key}) error: key not found"); - } - } - - - public static class Directory - { - public static bool Exists(string dir) => System.IO.Directory.Exists(dir); - - // создает папку, если её не существует - public static void Create(string dir) - { - if (!Directory.Exists(dir)) - { - // проверяет существование папки, в которой нужно создать dir - if (dir.Contains("\\") && !Directory.Exists(dir.Remove(dir.LastIndexOf('\\')))) - Create(dir.Remove(dir.LastIndexOf('\\'))); - System.IO.Directory.CreateDirectory(dir); - } - } - // копирует все файлы и папки - public static void Copy(string source_dir, string new_dir, bool owerwrite = false) - { - Create(new_dir); - List subdirs = new List(); - List files = GetAllFiles(source_dir, ref subdirs); - for (int i = 0; i < subdirs.Count; i++) - { - Create(subdirs[i].Replace(source_dir, new_dir)); - } - for (int i = 0; i < files.Count; i++) - { - string f = files[i].Replace(source_dir, new_dir); - File.Copy(files[i], f, owerwrite); - //PublicLog.Log(new string[] {"g", $"file <", "c", files[i], "b", "> have copied to <", "c", newfile, "b", ">\n'" }); - } - } - - // копирует все файлы и папки и выдаёт список конфликтующих файлов - public static void Copy(string source_dir, string new_dir, out List conflicts, bool owerwrite = false) - { - conflicts = new List(); - var subdirs = new List(); - var files = GetAllFiles(source_dir, ref subdirs); - Create(new_dir); - for (int i = 0; i < subdirs.Count; i++) - { - Create(subdirs[i].Replace(source_dir, new_dir)); - } - for (int i = 0; i < files.Count; i++) - { - string newfile = files[i].Replace(source_dir, new_dir); - if (File.Exists(newfile)) conflicts.Add(newfile); - File.Copy(files[i], newfile, owerwrite); - //PublicLog.Log(new string[] {"g", $"file <", "c", files[i], "b", "> have copied to <", "c", newfile, "b", ">\n'" }); - } - } - - // удаляет папку со всеми подпапками и файлами - public static void Delete(string dir) - { - var subdirs = new List(); - var files = GetAllFiles(dir, ref subdirs); - 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); - } - - 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); - - // выдает список всех файлов - public static List GetAllFiles(string dir) - { - List all_files = new List(); - string[] cur_files = Directory.GetFiles(dir); - for (int i = 0; i < cur_files.Length; i++) - { - all_files.Add(cur_files[i]); - //PublicLog.Log(new string[] { "b", "file found: <", "c", cur_files[i], "b", ">\n" }); - } - string[] cur_subdirs = Directory.GetDirectories(dir); - for (int i = 0; i < cur_subdirs.Length; i++) - { - //PublicLog.Log(new string[] { "b", "subdir found: <", "c", cur_subdirs[i], "b", ">\n" }); - all_files.AddRange(GetAllFiles(cur_subdirs[i])); - } - return all_files; - } - - // выдает список всех файлов и подпапок в папке - public static List GetAllFiles(string dir, ref List all_subdirs) - { - List all_files = new List(); - string[] cur_files = Directory.GetFiles(dir); - for (int i = 0; i < cur_files.Length; i++) - { - all_files.Add(cur_files[i]); - //PublicLog.Log(new string[] { "b", "file found: <", "c", cur_files[i], "b", ">\n" }); - } - string[] cur_subdirs = Directory.GetDirectories(dir); - for (int i = 0; i < cur_subdirs.Length; i++) - { - all_subdirs.Add(cur_subdirs[i]); - //PublicLog.Log(new string[] { "b", "subdir found: <", "c", cur_subdirs[i], "b", ">\n" }); - all_files.AddRange(GetAllFiles(cur_subdirs[i], ref all_subdirs)); - } - return all_files; - } - - public static string GetCurrent() => System.IO.Directory.GetCurrentDirectory(); - } - - public static class File - { - public static int GetSize(string file) => new System.IO.FileInfo(file).Length.ToInt(); - - public static bool Exists(string file) => System.IO.File.Exists(file); - - // если файл не существует, создаёт файл, создаёт папки из его пути - public static void Create(string file) - { - if (!File.Exists(file)) - { - if (file.Contains("\\")) Directory.Create(file.Remove(file.LastIndexOf('\\'))); - using var stream = System.IO.File.Create(file); - stream.Close(); - } - } - - public static void Copy(string srcPath, string newPath, bool replace = false) - { - if (!replace && Exists(newPath)) throw new Exception($"file <{newPath}> alredy exists"); - Create(newPath); - WriteAllBytes(newPath, ReadAllBytes(srcPath)); - } - - public static void Delete(string file) => System.IO.File.Delete(file); - - public static byte[] ReadAllBytes(string file) - { - using var stream = File.OpenRead(file); - int size = GetSize(file); - byte[] output = new byte[size]; - stream.Read(output, 0, size); - stream.Close(); - return output; - } - - public static string ReadAllText(string file) => ReadAllBytes(file).ToStr(); - - public static void WriteAllBytes(string file, byte[] content) - { - using var stream = File.OpenWrite(file); - stream.Write(content, 0, content.Length); - stream.Close(); - } - - public static void WriteAllText(string file, string content) => WriteAllBytes(file, content.ToBytes()); - - public static void AppendAllBytes(string file, byte[] content) - { - 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 System.IO.FileStream OpenRead(string file) - { - if (!Exists(file)) throw new Exception($"file not found: <{file}>"); - return System.IO.File.OpenRead(file); - } - public static System.IO.FileStream OpenWrite(string file) - { - if (Exists(file)) Delete(file); - File.Create(file); - return System.IO.File.OpenWrite(file); - } - public static System.IO.FileStream OpenAppend(string file) - { - File.Create(file); - return System.IO.File.Open(file, System.IO.FileMode.Append); - } - } - } -} diff --git a/Hasher.cs b/Hasher.cs index bec42c0..0bd98fb 100644 --- a/Hasher.cs +++ b/Hasher.cs @@ -1,6 +1,6 @@ -using System.Collections.Generic; +using DTLib.Filesystem; +using System.Collections.Generic; using System.Security.Cryptography; -using static DTLib.Filework; namespace DTLib { diff --git a/Network.cs b/Network.cs deleted file mode 100644 index c74389a..0000000 --- a/Network.cs +++ /dev/null @@ -1,273 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Net; -using System.Net.Sockets; -using System.Text; -using System.Threading; -using static DTLib.Filework; -using static DTLib.PublicLog; - -namespace DTLib -{ - // - // весь униврсальный неткод тут - // большинство методов предназначены для работы с TCP сокетами (Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) - // - public static class Network - { - - // ждёт пакет заданного размера с заданным началом и концом - public static byte[] GetPackage(this Socket socket) - { - int packageSize = 0; - byte[] data = new byte[2]; - // цикл выполняется пока не пройдёт 2000 мс - for (ushort s = 0; s < 400; s += 1) - { - if (packageSize == 0 && socket.Available >= 2) - { - socket.Receive(data, data.Length, 0); - packageSize = data.BytesToInt(); - - } - if (packageSize != 0 && socket.Available >= packageSize) - { - data = new byte[packageSize]; - socket.Receive(data, data.Length, 0); - return data; - } - else Thread.Sleep(5); - } - throw new Exception($"GetPackage() error: timeout. socket.Available={socket.Available}\n"); - } - - // отправляет пакет заданного размера, добавля в конец нули если длина data меньше чем packageSize - public static void SendPackage(this Socket socket, byte[] data) - { - if (data.Length > 65536) throw new Exception($"SendPackage() error: package is too big ({data.Length} bytes)"); - if (data.Length == 0) throw new Exception($"SendPackage() error: package has zero size"); - var list = new List(); - byte[] packageSize = data.Length.IntToBytes(); - if (packageSize.Length == 1) list.Add(0); - list.AddRange(packageSize); - list.AddRange(data); - socket.Send(list.ToArray()); - } - - // получает с сайта публичный ip - public static string GetPublicIP() => new WebClient().DownloadString("https://ipv4bot.whatismyipaddress.com/"); - - // пингует айпи с помощью встроенной в винду проги, возвращает задержку - public static string PingIP(string address) - { - Process proc = new Process(); - proc.StartInfo.FileName = "cmd.exe"; - proc.StartInfo.Arguments = "/c @echo off & chcp 65001 >nul & ping -n 5 " + address; - proc.StartInfo.CreateNoWindow = true; - proc.StartInfo.UseShellExecute = false; - proc.StartInfo.RedirectStandardOutput = true; - proc.Start(); - var outStream = proc.StandardOutput; - var rezult = outStream.ReadToEnd(); - rezult = rezult.Remove(0, rezult.LastIndexOf('=') + 2); - return rezult.Remove(rezult.Length - 4); - } - - public class FSP - { - Socket mainSocket; - public bool debug = true; - public FSP(Socket _mainSocket) => mainSocket = _mainSocket; - - public uint BytesDownloaded = 0; - public uint BytesUploaded = 0; - public uint Filesize = 0; - - // скачивает файл с помощью FSP протокола - public void DownloadFile(string filePath_server, string filePath_client) - { - if (debug) Log("b", $"requesting file download: {filePath_server}\n"); - mainSocket.SendPackage("requesting file download".ToBytes()); - mainSocket.SendPackage(filePath_server.ToBytes()); - DownloadFile(filePath_client); - } - - public void DownloadFile(string filePath_client) - { - File.Create(filePath_client); - using var fileStream = File.OpenWrite(filePath_client); - 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 seconds = 0; - var speedCounter = new Timer(true, 1000, () => - { - seconds++; - Log("c", $"speed= {packagesCount * buffer.Length / (seconds * 1000)} kb/s\n"); - }); - // получение файла - for (; packagesCount < fullPackagesCount; packagesCount++) - { - buffer = mainSocket.GetPackage(); - fileStream.Write(buffer, 0, buffer.Length); - fileStream.Flush(); - } - speedCounter.Stop(); - // получение остатка - if ((Filesize - fileStream.Position) > 0) - { - mainSocket.SendPackage("remain request".ToBytes()); - buffer = mainSocket.GetPackage(); - fileStream.Write(buffer, 0, buffer.Length); - } - fileStream.Flush(); - fileStream.Close(); - if (debug) Log(new string[] { "g", $" downloaded {packagesCount * 5120 + buffer.Length} of {Filesize} bytes\n" }); - } - public byte[] DownloadFileToMemory(string filePath_server) - { - 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(); - 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 seconds = 0; - var speedCounter = new Timer(true, 1000, () => - { - seconds++; - Log("c", $"speed= {packagesCount * buffer.Length / (seconds * 1000)} kb/s\n"); - }); - // получение файла - for (; packagesCount < fullPackagesCount; packagesCount++) - { - buffer = mainSocket.GetPackage(); - fileStream.Write(buffer, 0, buffer.Length); - fileStream.Flush(); - } - speedCounter.Stop(); - // получение остатка - if ((fileSize - fileStream.Position) > 0) - { - mainSocket.SendPackage("remain request".ToBytes()); - buffer = mainSocket.GetPackage(); - fileStream.Write(buffer, 0, buffer.Length); - } - byte[] output = fileStream.GetBuffer(); - fileStream.Close(); - if (debug) Log(new string[] { "g", $" downloaded {packagesCount * 5120 + buffer.Length} of {fileSize} bytes\n" }); - return output; - } - - // отдаёт файл с помощью FSP протокола - public void UploadFile(string filePath) - { - if (debug) Log("b", $"uploading file {filePath}\n"); - using var fileStream = File.OpenRead(filePath); - Filesize = File.GetSize(filePath).ToUInt(); - var fileHash = new Hasher().HashFile(filePath); - mainSocket.SendPackage(Filesize.ToString().ToBytes()); - mainSocket.SendPackage(fileHash); - if (mainSocket.GetPackage().ToStr() != "ready") throw new Exception("user socket isn't ready"); - byte[] buffer = new byte[5120]; - var hashstr = fileHash.HashToString(); - int packagesCount = 0; - // отправка файла - int fullPackagesCount = SimpleConverter.Truncate(Filesize / buffer.Length); - for (; packagesCount < fullPackagesCount; packagesCount++) - { - fileStream.Read(buffer, 0, buffer.Length); - mainSocket.SendPackage(buffer); - } - // досылка остатка - if ((Filesize - fileStream.Position) > 0) - { - if (mainSocket.GetPackage().ToStr() != "remain request") throw new Exception("FSP_Upload() error: didn't get remain request"); - buffer = new byte[(Filesize - fileStream.Position).ToInt()]; - fileStream.Read(buffer, 0, buffer.Length); - mainSocket.SendPackage(buffer); - } - fileStream.Close(); - if (debug) Log(new string[] { "g", $" uploaded {packagesCount * 5120 + buffer.Length} 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"); - var hasher = new Hasher(); - foreach (string fileOnServer in manifest.Keys) - { - string fileOnClient = dirOnClient + fileOnServer; - if (debug) Log("b", "file <", "c", fileOnClient, "b", ">... "); - if (!File.Exists(fileOnClient)) - { - if (debug) LogNoTime("y", "doesn't exist\n"); - DownloadFile(dirOnServer + fileOnServer, fileOnClient); - } - else if (overwrite && hasher.HashFile(fileOnClient).HashToString() != manifest[fileOnServer]) - { - if (debug) LogNoTime("y", "outdated\n"); - DownloadFile(dirOnServer + fileOnServer, fileOnClient); - } - else if (debug) LogNoTime("g", "without changes\n"); - } - // удаление лишних файлов - if (delete_excess) - { - List dirs = new(); - foreach (string file in Directory.GetAllFiles(dirOnClient, ref dirs)) - { - if (!manifest.ContainsKey(file)) - { - Log("y", $"deleting excess file: {file}"); - File.Delete(file); - } - } - // удаление пустых папок - foreach (string dir in dirs) - { - if (Directory.GetAllFiles(dir).Count == 0) - { - Log("y", $"deleting empty dir: {dir}"); - Directory.Delete(dir); - } - } - } - } - - static public void CreateManifest(string dir) - { - if (!dir.EndsWith("\\")) dir += "\\"; - Log($"b", $"creating manifest of {dir}\n"); - StringBuilder manifestBuilder = new(); - Hasher hasher = new(); - if (Directory.GetFiles(dir).Contains(dir + "manifest.dtsod")) File.Delete(dir + "manifest.dtsod"); - foreach (string _file in Directory.GetAllFiles(dir)) - { - string file = _file.Remove(0, dir.Length); - manifestBuilder.Append(file); - manifestBuilder.Append(": \""); - byte[] hash = hasher.HashFile(dir + file); - manifestBuilder.Append(hash.HashToString()); - manifestBuilder.Append("\";\n"); - } - File.WriteAllText(dir + "manifest.dtsod", manifestBuilder.ToString()); - Log($"g", $" manifest of {dir} created\n"); - } - } - } -} diff --git a/Network/FSP.cs b/Network/FSP.cs new file mode 100644 index 0000000..8441a4f --- /dev/null +++ b/Network/FSP.cs @@ -0,0 +1,208 @@ +using DTLib.Filesystem; +using System; +using System.Collections.Generic; +using System.Net.Sockets; +using System.Text; +using static DTLib.PublicLog; + +namespace DTLib.Network +{ + // + // передача файлов по сети + // + public class FSP + { + Socket mainSocket; + public bool debug = true; + public FSP(Socket _mainSocket) => mainSocket = _mainSocket; + + public uint BytesDownloaded = 0; + public uint BytesUploaded = 0; + public uint Filesize = 0; + + // скачивает файл с помощью FSP протокола + public void DownloadFile(string filePath_server, string filePath_client) + { + if (debug) Log("b", $"requesting file download: {filePath_server}\n"); + mainSocket.SendPackage("requesting file download".ToBytes()); + mainSocket.SendPackage(filePath_server.ToBytes()); + DownloadFile(filePath_client); + } + + public void DownloadFile(string filePath_client) + { + File.Create(filePath_client); + using var fileStream = File.OpenWrite(filePath_client); + 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 seconds = 0; + var speedCounter = new Timer(true, 1000, () => + { + seconds++; + Log("c", $"speed= {packagesCount * buffer.Length / (seconds * 1000)} kb/s\n"); + }); + // получение файла + for (; packagesCount < fullPackagesCount; packagesCount++) + { + buffer = mainSocket.GetPackage(); + fileStream.Write(buffer, 0, buffer.Length); + fileStream.Flush(); + } + speedCounter.Stop(); + // получение остатка + if ((Filesize - fileStream.Position) > 0) + { + mainSocket.SendPackage("remain request".ToBytes()); + buffer = mainSocket.GetPackage(); + fileStream.Write(buffer, 0, buffer.Length); + } + fileStream.Flush(); + fileStream.Close(); + if (debug) Log(new string[] { "g", $" downloaded {packagesCount * 5120 + buffer.Length} of {Filesize} bytes\n" }); + } + public byte[] DownloadFileToMemory(string filePath_server) + { + 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(); + 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 seconds = 0; + var speedCounter = new Timer(true, 1000, () => + { + seconds++; + Log("c", $"speed= {packagesCount * buffer.Length / (seconds * 1000)} kb/s\n"); + }); + // получение файла + for (; packagesCount < fullPackagesCount; packagesCount++) + { + buffer = mainSocket.GetPackage(); + fileStream.Write(buffer, 0, buffer.Length); + fileStream.Flush(); + } + speedCounter.Stop(); + // получение остатка + if ((fileSize - fileStream.Position) > 0) + { + mainSocket.SendPackage("remain request".ToBytes()); + buffer = mainSocket.GetPackage(); + fileStream.Write(buffer, 0, buffer.Length); + } + byte[] output = fileStream.GetBuffer(); + fileStream.Close(); + if (debug) Log(new string[] { "g", $" downloaded {packagesCount * 5120 + buffer.Length} of {fileSize} bytes\n" }); + return output; + } + + // отдаёт файл с помощью FSP протокола + public void UploadFile(string filePath) + { + if (debug) Log("b", $"uploading file {filePath}\n"); + using var fileStream = File.OpenRead(filePath); + Filesize = File.GetSize(filePath).ToUInt(); + var fileHash = new Hasher().HashFile(filePath); + mainSocket.SendPackage(Filesize.ToString().ToBytes()); + mainSocket.SendPackage(fileHash); + if (mainSocket.GetPackage().ToStr() != "ready") throw new Exception("user socket isn't ready"); + byte[] buffer = new byte[5120]; + var hashstr = fileHash.HashToString(); + int packagesCount = 0; + // отправка файла + int fullPackagesCount = SimpleConverter.Truncate(Filesize / buffer.Length); + for (; packagesCount < fullPackagesCount; packagesCount++) + { + fileStream.Read(buffer, 0, buffer.Length); + mainSocket.SendPackage(buffer); + } + // досылка остатка + if ((Filesize - fileStream.Position) > 0) + { + if (mainSocket.GetPackage().ToStr() != "remain request") throw new Exception("FSP_Upload() error: didn't get remain request"); + buffer = new byte[(Filesize - fileStream.Position).ToInt()]; + fileStream.Read(buffer, 0, buffer.Length); + mainSocket.SendPackage(buffer); + } + fileStream.Close(); + if (debug) Log(new string[] { "g", $" uploaded {packagesCount * 5120 + buffer.Length} 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"); + var hasher = new Hasher(); + foreach (string fileOnServer in manifest.Keys) + { + string fileOnClient = dirOnClient + fileOnServer; + if (debug) Log("b", "file <", "c", fileOnClient, "b", ">... "); + if (!File.Exists(fileOnClient)) + { + if (debug) LogNoTime("y", "doesn't exist\n"); + DownloadFile(dirOnServer + fileOnServer, fileOnClient); + } + else if (overwrite && hasher.HashFile(fileOnClient).HashToString() != manifest[fileOnServer]) + { + if (debug) LogNoTime("y", "outdated\n"); + DownloadFile(dirOnServer + fileOnServer, fileOnClient); + } + else if (debug) LogNoTime("g", "without changes\n"); + } + // удаление лишних файлов + if (delete_excess) + { + List dirs = new(); + foreach (string file in Directory.GetAllFiles(dirOnClient, ref dirs)) + { + if (!manifest.ContainsKey(file.Remove(0, dirOnClient.Length))) + { + if (debug) Log("y", $"deleting excess file: {file}\n"); + File.Delete(file); + } + } + // удаление пустых папок + 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) + { + if (!dir.EndsWith("\\")) dir += "\\"; + Log($"b", $"creating manifest of {dir}\n"); + StringBuilder manifestBuilder = new(); + Hasher hasher = new(); + if (Directory.GetFiles(dir).Contains(dir + "manifest.dtsod")) File.Delete(dir + "manifest.dtsod"); + foreach (string _file in Directory.GetAllFiles(dir)) + { + string file = _file.Remove(0, dir.Length); + manifestBuilder.Append(file); + manifestBuilder.Append(": \""); + byte[] hash = hasher.HashFile(dir + file); + manifestBuilder.Append(hash.HashToString()); + manifestBuilder.Append("\";\n"); + } + File.WriteAllText(dir + "manifest.dtsod", manifestBuilder.ToString()); + Log($"g", $" manifest of {dir} created\n"); + } + } +} diff --git a/Network/OldNetwork.cs b/Network/OldNetwork.cs new file mode 100644 index 0000000..f9f21b1 --- /dev/null +++ b/Network/OldNetwork.cs @@ -0,0 +1,33 @@ +using System.Diagnostics; +using System.Net; + +namespace DTLib.Network +{ + // + // пара почти никогда не используемых методов + // + public static class OldNetwork + { + + + // получает с сайта публичный ip + public static string GetPublicIP() => new WebClient().DownloadString("https://ipv4bot.whatismyipaddress.com/"); + + // пингует айпи с помощью встроенной в винду проги, возвращает задержку + public static string PingIP(string address) + { + Process proc = new Process(); + proc.StartInfo.FileName = "cmd.exe"; + proc.StartInfo.Arguments = "/c @echo off & chcp 65001 >nul & ping -n 5 " + address; + proc.StartInfo.CreateNoWindow = true; + proc.StartInfo.UseShellExecute = false; + proc.StartInfo.RedirectStandardOutput = true; + proc.Start(); + var outStream = proc.StandardOutput; + var rezult = outStream.ReadToEnd(); + rezult = rezult.Remove(0, rezult.LastIndexOf('=') + 2); + return rezult.Remove(rezult.Length - 4); + } + + } +} diff --git a/Network/Package.cs b/Network/Package.cs new file mode 100644 index 0000000..3797ee6 --- /dev/null +++ b/Network/Package.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Net.Sockets; +using System.Threading; + +namespace DTLib.Network +{ + // + // отправка/получение пакетов + // + static public class Package + { + // принимает пакет + public static byte[] GetPackage(this Socket socket) + { + int packageSize = 0; + byte[] data = new byte[2]; + // цикл выполняется пока не пройдёт 2000 мс + for (ushort s = 0; s < 400; s += 1) + { + if (packageSize == 0 && socket.Available >= 2) + { + socket.Receive(data, data.Length, 0); + packageSize = data.BytesToInt(); + + } + if (packageSize != 0 && socket.Available >= packageSize) + { + data = new byte[packageSize]; + socket.Receive(data, data.Length, 0); + return data; + } + else Thread.Sleep(5); + } + throw new Exception($"GetPackage() error: timeout. socket.Available={socket.Available}\n"); + } + + // отправляет пакет + public static void SendPackage(this Socket socket, byte[] data) + { + if (data.Length > 65536) throw new Exception($"SendPackage() error: package is too big ({data.Length} bytes)"); + if (data.Length == 0) throw new Exception($"SendPackage() error: package has zero size"); + var list = new List(); + byte[] packageSize = data.Length.IntToBytes(); + if (packageSize.Length == 1) list.Add(0); + list.AddRange(packageSize); + list.AddRange(data); + socket.Send(list.ToArray()); + } + } +}