project structure changed
This commit is contained in:
parent
092a6ad347
commit
60e3bc6251
42
ConsoleGUI/Container.cs
Normal file
42
ConsoleGUI/Container.cs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace DTLib.ConsoleGUI
|
||||||
|
{
|
||||||
|
public class Container : List<IDrawable>, 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()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
21
ConsoleGUI/Control.cs
Normal file
21
ConsoleGUI/Control.cs
Normal file
@ -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()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
16
ConsoleGUI/IDrawable.cs
Normal file
16
ConsoleGUI/IDrawable.cs
Normal file
@ -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();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
32
ConsoleGUI/Label.cs
Normal file
32
ConsoleGUI/Label.cs
Normal file
@ -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()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
189
ConsoleGUI/Window.cs
Normal file
189
ConsoleGUI/Window.cs
Normal file
@ -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<string>();
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
DTLib.csproj
14
DTLib.csproj
@ -31,14 +31,22 @@
|
|||||||
<Reference Include="System.Data" />
|
<Reference Include="System.Data" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Color.cs" />
|
|
||||||
<Compile Include="CompressedArray.cs" />
|
<Compile Include="CompressedArray.cs" />
|
||||||
|
<Compile Include="ConsoleGUI\Container.cs" />
|
||||||
|
<Compile Include="ConsoleGUI\Control.cs" />
|
||||||
|
<Compile Include="ConsoleGUI\IDrawable.cs" />
|
||||||
|
<Compile Include="ConsoleGUI\Label.cs" />
|
||||||
|
<Compile Include="ConsoleGUI\Window.cs" />
|
||||||
<Compile Include="Dtsod.cs" />
|
<Compile Include="Dtsod.cs" />
|
||||||
<Compile Include="cs9somefix.cs" />
|
<Compile Include="cs9somefix.cs" />
|
||||||
<Compile Include="Filework.cs" />
|
<Compile Include="Filesystem\Directory.cs" />
|
||||||
|
<Compile Include="Filesystem\File.cs" />
|
||||||
<Compile Include="ColoredConsole.cs" />
|
<Compile Include="ColoredConsole.cs" />
|
||||||
|
<Compile Include="Filesystem\OldFilework.cs" />
|
||||||
|
<Compile Include="Network\FSP.cs" />
|
||||||
|
<Compile Include="Network\OldNetwork.cs" />
|
||||||
|
<Compile Include="Network\Package.cs" />
|
||||||
<Compile Include="PublicLog.cs" />
|
<Compile Include="PublicLog.cs" />
|
||||||
<Compile Include="Network.cs" />
|
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Hasher.cs" />
|
<Compile Include="Hasher.cs" />
|
||||||
<Compile Include="SecureRandom.cs" />
|
<Compile Include="SecureRandom.cs" />
|
||||||
|
|||||||
116
Filesystem/Directory.cs
Normal file
116
Filesystem/Directory.cs
Normal file
@ -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<string> subdirs = new List<string>();
|
||||||
|
List<string> 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<string> conflicts, bool owerwrite = false)
|
||||||
|
{
|
||||||
|
conflicts = new List<string>();
|
||||||
|
var subdirs = new List<string>();
|
||||||
|
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<string>();
|
||||||
|
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<string> GetAllFiles(string dir)
|
||||||
|
{
|
||||||
|
List<string> all_files = new List<string>();
|
||||||
|
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<string> GetAllFiles(string dir, ref List<string> all_subdirs)
|
||||||
|
{
|
||||||
|
List<string> all_files = new List<string>();
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
78
Filesystem/File.cs
Normal file
78
Filesystem/File.cs
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
69
Filesystem/OldFilework.cs
Normal file
69
Filesystem/OldFilework.cs
Normal file
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
253
Filework.cs
253
Filework.cs
@ -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<string> subdirs = new List<string>();
|
|
||||||
List<string> 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<string> conflicts, bool owerwrite = false)
|
|
||||||
{
|
|
||||||
conflicts = new List<string>();
|
|
||||||
var subdirs = new List<string>();
|
|
||||||
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<string>();
|
|
||||||
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<string> GetAllFiles(string dir)
|
|
||||||
{
|
|
||||||
List<string> all_files = new List<string>();
|
|
||||||
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<string> GetAllFiles(string dir, ref List<string> all_subdirs)
|
|
||||||
{
|
|
||||||
List<string> all_files = new List<string>();
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using DTLib.Filesystem;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using static DTLib.Filework;
|
|
||||||
|
|
||||||
namespace DTLib
|
namespace DTLib
|
||||||
{
|
{
|
||||||
|
|||||||
273
Network.cs
273
Network.cs
@ -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>();
|
|
||||||
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<string> 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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
208
Network/FSP.cs
Normal file
208
Network/FSP.cs
Normal file
@ -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<string> 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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
33
Network/OldNetwork.cs
Normal file
33
Network/OldNetwork.cs
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
51
Network/Package.cs
Normal file
51
Network/Package.cs
Normal file
@ -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>();
|
||||||
|
byte[] packageSize = data.Length.IntToBytes();
|
||||||
|
if (packageSize.Length == 1) list.Add(0);
|
||||||
|
list.AddRange(packageSize);
|
||||||
|
list.AddRange(data);
|
||||||
|
socket.Send(list.ToArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user