project structure changed

This commit is contained in:
Timerix 2021-08-24 20:35:02 +03:00
parent 60e3bc6251
commit 13421f2c77
16 changed files with 961 additions and 313 deletions

View File

@ -1,4 +1,7 @@
using System.Collections.Generic; using DTLib.Dtsod;
using DTLib.Filesystem;
using System.Collections.Generic;
using static DTLib.PublicLog;
namespace DTLib.ConsoleGUI namespace DTLib.ConsoleGUI
{ {
@ -9,13 +12,35 @@ namespace DTLib.ConsoleGUI
public ushort Height { get; set; } public ushort Height { get; set; }
public char[] Textmap { get; private set; } public char[] Textmap { get; private set; }
public char[] Colormap { get; private set; } public char[] Colormap { get; private set; }
public string Name { get; private set; }
public Container() { } public Container(string name, string layout_file)
public Container(ushort width, ushort height)
{ {
Width = width; Name = name;
Height = height; ParseLayoutFile(layout_file);
}
void ParseLayoutFile(string layout_file)
{
DtsodV22 layout = new(File.ReadAllText(layout_file));
AnchorPoint = (layout[Name]["anchor"][0], layout[Name]["anchor"][1]);
Width = layout[Name]["width"];
Height = layout[Name]["height"];
foreach (string element_name in layout[Name]["children"].Keys)
{
switch (layout[Name]["children"][element_name]["type"])
{
case "label":
this.Add(new Label(element_name,
layout[Name]["children"][element_name]["resdir"] + $"\\{element_name}.textmap",
layout[Name]["children"][element_name]["resdir"] + $"\\{element_name}.colormap")
{
AnchorPoint = (layout[Name]["children"][element_name]["anchor"][0],
layout[Name]["children"][element_name]["anchor"][1])
});
break;
}
}
} }
public void GenTextmap() public void GenTextmap()
@ -25,11 +50,13 @@ namespace DTLib.ConsoleGUI
Textmap[i] = ' '; Textmap[i] = ' ';
foreach (var element in this) foreach (var element in this)
{ {
element.GenTextmap();
Log("m", $"Length: {element.Textmap.Length} calculated: {element.Width * element.Height}\n");
for (ushort y = 0; y < element.Height; y++) for (ushort y = 0; y < element.Height; y++)
for (ushort x = 0; x < element.Width; x++) for (ushort x = 0; x < element.Width; x++)
{ {
element.GenTextmap(); //Textmap[(element.AnchorPoint.y + y) * Width + element.AnchorPoint.x + x] = element.Textmap[y * element.Width + x];
Textmap[(element.AnchorPoint.y + y) * Width + element.AnchorPoint.x + x] = element.Textmap[y * element.Width + x]; Textmap[(y) * Width + x] = element.Textmap[y * element.Width + x];
} }
} }
} }

View File

@ -1,19 +1,14 @@
namespace DTLib.ConsoleGUI namespace DTLib.ConsoleGUI
{ {
public class Control : IDrawable public class Control : Label
{ {
public (ushort x, ushort y) AnchorPoint { get; set; }
public ushort Width { get; }
public ushort Height { get; }
public char[] Textmap { get; private set; }
public char[] Colormap { get; private set; }
public void GenColormap() public new void GenColormap()
{ {
} }
public void GenTextmap() public new void GenTextmap()
{ {
} }

View File

@ -7,6 +7,7 @@
public ushort Height { get; } public ushort Height { get; }
public char[] Textmap { get; } public char[] Textmap { get; }
public char[] Colormap { get; } public char[] Colormap { get; }
public string Name { get; }
public void GenTextmap(); public void GenTextmap();

View File

@ -1,32 +1,38 @@
namespace DTLib.ConsoleGUI using DTLib.Filesystem;
namespace DTLib.ConsoleGUI
{ {
public class Label : IDrawable public class Label : IDrawable
{ {
public (ushort x, ushort y) AnchorPoint { get; set; } public (ushort x, ushort y) AnchorPoint { get; set; } = (0, 0);
public ushort Width { get; } public ushort Width { get; private set; }
public ushort Height { get; } public ushort Height { get; private set; }
public char[] Textmap { get; private set; } public char[] Textmap { get; private set; }
public char[] Colormap { get; private set; } public char[] Colormap { get; private set; }
public string TextmapFile { get; set; } public string TextmapFile { get; set; }
public string ColormapFile { get; set; } public string ColormapFile { get; set; }
public string Name { get; init; }
public Label() { } public Label() { }
public Label(string textmapFile, string colormapFile) public Label(string name, string textmapFile, string colormapFile)
{ {
TextmapFile = textmapFile; TextmapFile = textmapFile;
ColormapFile = colormapFile; ColormapFile = colormapFile;
Name = name;
} }
public void GenColormap() public void GenColormap()
{ {
Colormap = File.ReadAllText(ColormapFile).ToCharArray();
} }
public void GenTextmap() public void GenTextmap()
{ {
Textmap = File.ReadAllText(TextmapFile).ToCharArray();
Width = 12;
Height = 3;
} }
} }
} }

View File

@ -1,6 +1,5 @@
using DTLib.Filesystem; using DTLib.Filesystem;
using System; using System;
using System.Collections.Generic;
using System.Text; using System.Text;
namespace DTLib.ConsoleGUI namespace DTLib.ConsoleGUI
@ -8,182 +7,30 @@ namespace DTLib.ConsoleGUI
// //
// создание gui из текста в консоли // создание gui из текста в консоли
// //
public class Window public class Window : Container
{ {
public int WindowWidth { get; private set; }
public int WindowHeight { get; private set; }
public char[,] Text;
public char[,] nowText;
public char[,] TextColors;
public char[,] nowTextColors;
public Container WindowContainer; public Window(string layout_file) : base("window", layout_file)
public Window(int windowWidth, int windowHeight)
{ {
WindowWidth = windowWidth; Console.Clear();
WindowHeight = windowHeight; Console.SetWindowSize(Width + 1, Height + 1);
Text = new char[windowWidth, windowHeight]; Console.SetBufferSize(Width + 1, Height + 1);
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.OutputEncoding = Encoding.Unicode;
Console.InputEncoding = Encoding.Unicode; Console.InputEncoding = Encoding.Unicode;
Console.CursorVisible = false; 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) public void RenderFile(string file)
{ {
Console.Clear(); Console.Clear();
Console.WriteLine(File.ReadAllText(file)); Console.WriteLine(File.ReadAllText(file));
} }
public void Render()
{
GenTextmap();
Console.WriteLine(SimpleConverter.MergeToString(Textmap));
}
} }
} }

189
ConsoleGUI/WindowOld.cs Normal file
View File

@ -0,0 +1,189 @@
using DTLib.Filesystem;
using System;
using System.Collections.Generic;
using System.Text;
namespace DTLib.ConsoleGUI
{
//
// создание gui из текста в консоли
//
public class WindowOld
{
public int WindowWidth { get; private set; }
public int WindowHeight { get; private set; }
public char[,] Text;
public char[,] nowText;
public char[,] TextColors;
public char[,] nowTextColors;
public Container WindowContainer;
public WindowOld(int windowWidth, int windowHeight)
{
WindowWidth = windowWidth;
WindowHeight = windowHeight;
Text = new char[windowWidth, windowHeight];
TextColors = new char[windowWidth, windowHeight];
nowText = TextColors;
nowTextColors = new char[windowWidth, windowHeight];
Console.WindowWidth = WindowWidth + 1;
Console.WindowHeight = WindowHeight + 1;
Console.BufferWidth = WindowWidth + 1;
Console.BufferHeight = WindowHeight + 1;
Console.OutputEncoding = Encoding.Unicode;
Console.InputEncoding = Encoding.Unicode;
Console.CursorVisible = false;
// заполнение массивов
for (sbyte y = 0; y < WindowHeight; y++)
{
for (sbyte x = 0; x < WindowWidth; x++)
{
Text[x, y] = ' ';
TextColors[x, y] = 'w';
}
}
nowText = TextColors;
}
/*// считывает массив символов из файла
// ширина и высота текста должны быть как указанные при инициализации объекта этого класса
public void ReadFromFile(string path)
{
var r = new StreamReader(path, SimpleConverter.UTF8);
char[] s = new char[1];
// считывание текста
sbyte y = 0, x = 0;
r.Read(s, 0, 1);
while (!r.EndOfStream && y < WindowHeight)
{
if (x == WindowWidth)
{
r.Read(s, 0, 1);
x = 0;
y++;
}
else
{
Text[x, y] = s[0];
x++;
}
r.Read(s, 0, 1);
}
r.Read(s, 0, 1);
// считывание цвета
// если не находит цвет в файле, оставляет старый
if (s[0] == '\n')
{
r.Read(s, 0, 1);
y = 0;
x = 0;
while (!r.EndOfStream && y < WindowHeight)
{
if (x == WindowWidth)
{
r.Read(s, 0, 1);
x = 0;
y++;
}
else
{
TextColors[x, y] = s[0];
x++;
}
r.Read(s, 0, 1);
}
}
r.Close();
}*/
public void ResetCursor()
{
Console.SetCursorPosition(0, WindowHeight);
}
// заменяет символ выведенный, использовать после ShowAll()
public void ChangeChar(sbyte x, sbyte y, char ch)
{
Text[x, y] = ch;
nowText[x, y] = ch;
Console.SetCursorPosition(x, y);
ColoredConsole.Write(TextColors[x, y].ToString(), ch.ToString());
}
public void ChangeColor(sbyte x, sbyte y, char color)
{
TextColors[x, y] = color;
nowTextColors[x, y] = color;
Console.SetCursorPosition(x, y);
ColoredConsole.Write(color.ToString(), Text[x, y].ToString());
}
public void ChangeCharAndColor(sbyte x, sbyte y, char color, char ch)
{
Text[x, y] = ch;
nowText[x, y] = ch;
TextColors[x, y] = color;
nowTextColors[x, y] = color;
Console.SetCursorPosition(x, y);
ColoredConsole.Write(color.ToString(), ch.ToString());
}
public void ChangeLine(sbyte x, sbyte y, char color, string line)
{
Console.SetCursorPosition(x, y);
for (sbyte i = 0; i < line.Length; i++)
{
Text[x + i, y] = line[i];
nowText[x + i, y] = line[i];
TextColors[x + i, y] = color;
nowTextColors[x + i, y] = color;
}
ColoredConsole.Write(color.ToString(), line);
}
// выводит все символы
public void ShowAll()
{
var l = new List<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));
}
}
}

View File

@ -37,16 +37,19 @@
<Compile Include="ConsoleGUI\IDrawable.cs" /> <Compile Include="ConsoleGUI\IDrawable.cs" />
<Compile Include="ConsoleGUI\Label.cs" /> <Compile Include="ConsoleGUI\Label.cs" />
<Compile Include="ConsoleGUI\Window.cs" /> <Compile Include="ConsoleGUI\Window.cs" />
<Compile Include="Dtsod.cs" /> <Compile Include="ConsoleGUI\WindowOld.cs" />
<Compile Include="Dtsod\DtsodV22.cs" />
<Compile Include="Dtsod\DtsodV21.cs" />
<Compile Include="cs9somefix.cs" /> <Compile Include="cs9somefix.cs" />
<Compile Include="Dtsod\ValueTypes.cs" />
<Compile Include="Filesystem\Directory.cs" /> <Compile Include="Filesystem\Directory.cs" />
<Compile Include="Filesystem\File.cs" /> <Compile Include="Filesystem\File.cs" />
<Compile Include="ColoredConsole.cs" />
<Compile Include="Filesystem\OldFilework.cs" /> <Compile Include="Filesystem\OldFilework.cs" />
<Compile Include="ColoredConsole.cs" />
<Compile Include="Network\FSP.cs" /> <Compile Include="Network\FSP.cs" />
<Compile Include="Network\OldNetwork.cs" />
<Compile Include="Network\Package.cs" /> <Compile Include="Network\Package.cs" />
<Compile Include="PublicLog.cs" /> <Compile Include="PublicLog.cs" />
<Compile Include="Network\OldNetwork.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" />

View File

@ -4,18 +4,25 @@ using System.Linq;
using System.Text; using System.Text;
using static DTLib.PublicLog; using static DTLib.PublicLog;
namespace DTLib namespace DTLib.Dtsod
{ {
// //
// это как json но не совсем // это как json но не совсем
// //
public class Dtsod : Dictionary<string, dynamic> // v2.0
// полностью переписан парсер
//
// v2.1
// парсер теперь не может игнорировать комменты, потом починю
// теперь числовые значения конвертируются в правильный тип, а не в int64/uint64 (новый вариант switch из c#9.0 делал какую-то херню)
// исправлены некоторые другие баги
class DtsodV21 : Dictionary<string, dynamic>
{ {
static readonly bool debug = false; static readonly bool debug = false;
string Text;
public string Text { get; }
//public Dictionary<string, dynamic> Values { get; set; } //public Dictionary<string, dynamic> Values { get; set; }
public Dtsod(string text) public DtsodV21(string text)
{ {
Text = text; Text = text;
foreach (KeyValuePair<string, dynamic> pair in Parse(text)) foreach (KeyValuePair<string, dynamic> pair in Parse(text))
@ -23,7 +30,7 @@ namespace DTLib
} }
// выдаёт Exception // выдаёт Exception
new public dynamic this[string key] public new dynamic this[string key]
{ {
get get
{ {
@ -38,7 +45,7 @@ namespace DTLib
} }
// не выдаёт KeyNotFoundException // не выдаёт KeyNotFoundException
new public bool TryGetValue(string key, out dynamic value) public new bool TryGetValue(string key, out dynamic value)
{ {
try try
{ {
@ -79,7 +86,7 @@ namespace DTLib
Int, Int,
Uint, Uint,
Null, Null,
Boolean,*/ Bool,*/
Default Default
} }
@ -88,23 +95,25 @@ namespace DTLib
Dictionary<string, dynamic> parsed = new(); Dictionary<string, dynamic> parsed = new();
int i = 0; int i = 0;
for (; i < text.Length; i++) ReadName(); for (; i < text.Length; i++) ReadName();
if (debug) LogNoTime("g", $"Parse returns {parsed.Keys.Count} keys\n");
return parsed; return parsed;
// СЛОМАНО
/*void ReadCommentLine()
{
for (; i < text.Length && text[i] != '\n'; i++) if (debug) LogNoTime("gray", text[i].ToString());
}*/
void ReadName() void ReadName()
{ {
void ReadCommentLine()
{
for (; i < text.Length && text[i] != '\n'; i++) ;
}
bool isListElem = false; bool isListElem = false;
dynamic value = null; dynamic value = null;
StringBuilder defaultNameBuilder = new(); StringBuilder defaultNameBuilder = new();
if (debug) LogNoTime("m", "ReadName"); if (debug) LogNoTime("m", "ReadName\n");
for (; i < text.Length; i++) for (; i < text.Length; i++)
{ {
if (debug) LogNoTime("w", text[i].ToString());
switch (text[i]) switch (text[i])
{ {
case ' ': case ' ':
@ -114,31 +123,32 @@ namespace DTLib
break; break;
case ':': case ':':
i++; i++;
value = ReadValue();
string name = defaultNameBuilder.ToString(); string name = defaultNameBuilder.ToString();
if (debug) LogNoTime("c", $"parsed.Add({name}, {value})\n"); value = ReadValue();
if (debug) LogNoTime("c", $"parsed.Add({name}, {value} { value.GetType() })\n");
if (isListElem) if (isListElem)
{ {
if (!parsed.ContainsKey(name)) parsed.Add(name, new List<dynamic>()); if (!parsed.ContainsKey(name)) parsed.Add(name, new List<dynamic>());
parsed[name].Add(value); parsed[name].Add(value);
} }
else parsed.Add(name, value); else parsed.Add(name, value);
if (debug) LogNoTime("g", "ReadName return\n");
return; return;
// строка, начинающаяся с # будет считаться комментом // строка, начинающаяся с # будет считаться комментом
case '#': case '#':
ReadCommentLine(); //ReadCommentLine();
break; break;
case '}': case '}':
throw new Exception("Parse.ReadName() error: unexpected '}' at " + i + " char"); throw new Exception("Parse.ReadName() error: unexpected '}' at " + i + " char");
// если $ перед названием параметра поставить, значение value добавится в лист с названием name // если $ перед названием параметра поставить, значение value добавится в лист с названием name
case '$': case '$':
if (debug) LogNoTime("w", text[i].ToString());
if (defaultNameBuilder.ToString().Length != 0) throw new Exception("Parse.ReadName() error: unexpected '$' at " + i + " char"); if (defaultNameBuilder.ToString().Length != 0) throw new Exception("Parse.ReadName() error: unexpected '$' at " + i + " char");
isListElem = true; isListElem = true;
break; break;
case ';': case ';':
throw new Exception("Parse.ReadName() error: unexpected ';' at " + i + " char"); throw new Exception("Parse.ReadName() error: unexpected ';' at " + i + " char");
default: default:
if (debug) LogNoTime("w", text[i].ToString());
defaultNameBuilder.Append(text[i]); defaultNameBuilder.Append(text[i]);
break; break;
} }
@ -148,6 +158,7 @@ namespace DTLib
dynamic ReadValue() dynamic ReadValue()
{ {
ValueType type = ValueType.Default; ValueType type = ValueType.Default;
dynamic value = null;
string ReadString() string ReadString()
{ {
@ -181,7 +192,8 @@ namespace DTLib
case '\n': case '\n':
break; break;
case ',': case ',':
output.Add(ParseValueToRightType(valueBuilder.ToString())); ParseValueToRightType(valueBuilder.ToString());
output.Add(value);
valueBuilder.Clear(); valueBuilder.Clear();
break; break;
default: default:
@ -190,7 +202,10 @@ namespace DTLib
} }
} }
if (valueBuilder.Length > 0) if (valueBuilder.Length > 0)
output.Add(ParseValueToRightType(valueBuilder.ToString())); {
ParseValueToRightType(valueBuilder.ToString());
output.Add(value);
}
if (debug) LogNoTime("c", text[i].ToString()); if (debug) LogNoTime("c", text[i].ToString());
type = ValueType.List; type = ValueType.List;
return output; return output;
@ -198,55 +213,92 @@ namespace DTLib
Dictionary<string, dynamic> ReadComplex() Dictionary<string, dynamic> ReadComplex()
{ {
i++;
StringBuilder valueBuilder = new(); StringBuilder valueBuilder = new();
for (; text[i] != '}'; i++) int balance = 1;
i++;
for (; balance != 0; i++)
{ {
if (debug) LogNoTime("y", text[i].ToString()); if (debug) LogNoTime("y", text[i].ToString());
if (text[i] == '"') switch (text[i])
{ {
valueBuilder.Append(ReadString()); case '"':
valueBuilder.Append(ReadString());
break;
case '}':
balance--;
if (debug) LogNoTime("b", $"\nbalance -- = {balance}\n");
if (balance != 0) valueBuilder.Append(text[i]);
break;
case '{':
balance++;
if (debug) LogNoTime("b", $"\nbalance ++ = {balance}\n");
valueBuilder.Append(text[i]);
break;
default:
valueBuilder.Append(text[i]);
break;
} }
else valueBuilder.Append(text[i]);
} }
if (debug) LogNoTime("y", text[i].ToString()); i--; // i++ в for выполняется даже когда balance == 0, то есть text[i] получается == ;, что ломает всё
type = ValueType.Complex; type = ValueType.Complex;
if (debug) LogNoTime("g", valueBuilder.ToString());
return Parse(valueBuilder.ToString()); return Parse(valueBuilder.ToString());
} }
dynamic ParseValueToRightType(string stringValue) void ParseValueToRightType(string stringValue)
{ {
if (debug) LogNoTime("g", $"\nParseValueToRightType({stringValue})"); if (debug) LogNoTime("b", $"\nParseValueToRightType({stringValue})\n");
return stringValue switch switch (stringValue)
{ {
_ when stringValue.Contains('"') => stringValue.Remove(stringValue.Length - 1).Remove(0, 1),
// bool // bool
"true" or "false" => stringValue.ToBool(), case "true":
case "false":
value = stringValue.ToBool();
break;
// null // null
"null" => null, case "null":
// double value = null;
_ when stringValue.Contains('.') => stringValue.ToDouble(), break;
// ushort, ulong, uint default:
_ when (stringValue.Length > 2 && stringValue[stringValue.Length - 2] == 'u') => stringValue[stringValue.Length - 1] switch if (stringValue.Contains('"')) value = stringValue.Remove(stringValue.Length - 1).Remove(0, 1);
{ // double
's' => stringValue.Remove(stringValue.Length - 2).ToUShort(), else if (stringValue.Contains('.')) value = stringValue.ToDouble();
'i' => stringValue.Remove(stringValue.Length - 2).ToUInt(), // ushort; ulong; uint
'l' => stringValue.Remove(stringValue.Length - 2).ToULong(), else if (stringValue.Length > 2 && stringValue[stringValue.Length - 2] == 'u')
_ => throw new Exception($"Dtsod.Parse.ReadValue() error: wrong type <u{stringValue[stringValue.Length - 1]}>") {
}, switch (stringValue[stringValue.Length - 1])
// short, long, int {
_ => stringValue[stringValue.Length - 1] switch case 's':
{ value = stringValue.Remove(stringValue.Length - 2).ToUShort();
's' => stringValue.Remove(stringValue.Length - 1).ToShort(), break;
'l' => stringValue.Remove(stringValue.Length - 1).ToLong(), case 'i':
_ => stringValue.ToInt() value = stringValue.Remove(stringValue.Length - 2).ToUInt();
} break;
case 'l':
value = stringValue.Remove(stringValue.Length - 2).ToULong();
break;
default:
throw new Exception($"Dtsod.Parse.ReadValue() error: value= wrong type <u{stringValue[stringValue.Length - 1]}>");
};
}
// short; long; int
else switch (stringValue[stringValue.Length - 1])
{
case 's':
value = stringValue.Remove(stringValue.Length - 1).ToShort();
break;
case 'l':
value = stringValue.Remove(stringValue.Length - 1).ToLong();
break;
default:
value = stringValue.ToShort();
break;
}
break;
}; };
} }
dynamic value = null;
StringBuilder defaultValueBuilder = new(); StringBuilder defaultValueBuilder = new();
if (debug) LogNoTime("m", "\nReadValue\n"); if (debug) LogNoTime("m", "\nReadValue\n");
for (; i < text.Length; i++) for (; i < text.Length; i++)
@ -263,26 +315,32 @@ namespace DTLib
value = ReadString(); value = ReadString();
break; break;
case ';': case ';':
if (debug) LogNoTime("g", $"\nReadValue returns type {type} value <{value}>\n"); switch (type)
return type switch
{ {
ValueType.List or ValueType.Complex => value, case ValueType.String:
ValueType.String => ParseValueToRightType(value), ParseValueToRightType(value);
ValueType.Default => ParseValueToRightType(defaultValueBuilder.ToString()), break;
_ => throw new Exception($"Dtlib.Parse.ReadValue() error: can't convert value to type <{type}>") case ValueType.Default:
ParseValueToRightType(defaultValueBuilder.ToString());
break;
}; };
return value;
case '[': case '[':
value = ReadList(); value = ReadList();
break; break;
case '{': case '{':
value = ReadComplex(); value = ReadComplex();
break; break;
// строка, начинающаяся с # будет считаться комментом
case '#':
//ReadCommentLine();
break;
default: default:
defaultValueBuilder.Append(text[i]); defaultValueBuilder.Append(text[i]);
break; break;
} }
} }
throw new Exception("Dtsod.Parse.ReadValue error: end of text"); throw new Exception("Dtsod.Parse.ReadValue error: wtf it's the end of function");
} }
} }
} }

456
Dtsod/DtsodV22.cs Normal file
View File

@ -0,0 +1,456 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DTLib.Dtsod
{
//
// это как json но не совсем
//
// v20
// полностью переписан парсер
//
// v21
// парсер теперь не может игнорировать комменты, потом починю
// теперь числовые значения конвертируются в правильный тип, а не в int64/uint64 (новый вариант switch из c#9.0 делал какую-то херню)
// исправлены некоторые другие баги
//
// v22
// метод ToString() теперь действительно деконструирует объект в текст, а не возвращает параметр text из конструктора
public class DtsodV22 : Dictionary<string, DtsodV22.ValueStruct>
{
static readonly bool debug = false;
public struct ValueStruct
{
public dynamic Value;
public ValueTypes Type;
public bool IsList;
public ValueStruct(ValueTypes type, dynamic value, bool isList)
{
Value = value;
Type = type;
IsList = isList;
}
public ValueStruct(ValueTypes type, dynamic value)
{
Value = value;
Type = type;
IsList = false;
}
}
public DtsodV22(string text)
{
foreach (KeyValuePair<string, ValueStruct> pair in Parse(text))
Add(pair.Key, pair.Value);
}
public DtsodV22(Dictionary<string, DtsodV22.ValueStruct> dict)
{
foreach (KeyValuePair<string, ValueStruct> pair in dict)
Add(pair.Key, pair.Value);
}
// выдаёт Exception
public new dynamic this[string key]
{
get
{
if (TryGetValue(key, out dynamic value)) return value;
else throw new Exception($"Dtsod[{key}] key not found");
}
set
{
if (TrySetValue(key, value)) return;
else throw new Exception($"Dtsod[{key}] key not found");
}
}
// не выдаёт KeyNotFoundException
public bool TryGetValue(string key, out dynamic value)
{
try
{
value = base[key].Value;
return true;
}
catch (KeyNotFoundException)
{
value = null;
return false;
}
}
public bool TrySetValue(string key, dynamic value)
{
try
{
bool isList;
if (value is IList) isList = true;
else isList = false;
base[key] = new(base[key].Type, value, isList);
return true;
}
catch (KeyNotFoundException)
{
return false;
}
}
DtsodV22 Parse(string text)
{
Dictionary<string, ValueStruct> parsed = new();
int i = 0;
for (; i < text.Length; i++) ReadName();
Debug("g", $"Parse returns {parsed.Keys.Count} keys\n");
return new DtsodV22(parsed);
// СЛОМАНО
/*void ReadCommentLine()
{
for (; i < text.Length && text[i] != '\n'; i++) Debug("gray", text[i].ToString());
}*/
void ReadName()
{
bool isListElem = false;
dynamic value = null;
StringBuilder defaultNameBuilder = new();
Debug("m", "ReadName\n");
for (; i < text.Length; i++)
{
switch (text[i])
{
case ' ':
case '\t':
case '\r':
case '\n':
break;
case ':':
i++;
string name = defaultNameBuilder.ToString();
value = ReadValue(out var type, out var isList);
Debug("c", $"parsed.Add({name},{type} {value} )\n");
if (isListElem)
{
if (!parsed.ContainsKey(name)) parsed.Add(name, new(type, new List<dynamic>(), isList));
parsed[name].Value.Add(value);
}
else parsed.Add(name, new(type, value, isList));
return;
// строка, начинающаяся с # будет считаться комментом
case '#':
//ReadCommentLine();
break;
case '}':
throw new Exception("Parse.ReadName() error: unexpected '}' at " + i + " char");
// если $ перед названием параметра поставить, значение value добавится в лист с названием name
case '$':
Debug("w", text[i].ToString());
if (defaultNameBuilder.ToString().Length != 0) throw new Exception("Parse.ReadName() error: unexpected '$' at " + i + " char");
isListElem = true;
break;
case ';':
throw new Exception("Parse.ReadName() error: unexpected ';' at " + i + " char");
default:
Debug("w", text[i].ToString());
defaultNameBuilder.Append(text[i]);
break;
}
}
}
dynamic ReadValue(out ValueTypes outType, out bool isList)
{
ValueTypes type = ValueTypes.Unknown;
isList = false;
dynamic value = null;
string ReadString()
{
i++;
StringBuilder valueBuilder = new();
valueBuilder.Append('"');
for (; text[i] != '"' || text[i - 1] == '\\'; i++)
{
Debug("gray", text[i].ToString());
valueBuilder.Append(text[i]);
}
valueBuilder.Append('"');
Debug("gray", text[i].ToString());
type = ValueTypes.String;
return valueBuilder.ToString();
}
List<dynamic> ReadList()
{
i++;
List<dynamic> output = new();
StringBuilder valueBuilder = new();
for (; text[i] != ']'; i++)
{
Debug("c", text[i].ToString());
switch (text[i])
{
case ' ':
case '\t':
case '\r':
case '\n':
break;
case ',':
ParseValueToRightType(valueBuilder.ToString());
output.Add(value);
valueBuilder.Clear();
break;
default:
valueBuilder.Append(text[i]);
break;
}
}
if (valueBuilder.Length > 0)
{
ParseValueToRightType(valueBuilder.ToString());
output.Add(value);
}
Debug("c", text[i].ToString());
type = ValueTypes.List;
return output;
}
Dictionary<string, ValueStruct> ReadComplex()
{
StringBuilder valueBuilder = new();
int balance = 1;
i++;
for (; balance != 0; i++)
{
Debug("y", text[i].ToString());
switch (text[i])
{
case '"':
valueBuilder.Append(ReadString());
break;
case '}':
balance--;
Debug("b", $"\nbalance -- = {balance}\n");
if (balance != 0) valueBuilder.Append(text[i]);
break;
case '{':
balance++;
Debug("b", $"\nbalance ++ = {balance}\n");
valueBuilder.Append(text[i]);
break;
default:
valueBuilder.Append(text[i]);
break;
}
}
i--; // i++ в for выполняется даже когда balance == 0, то есть text[i] получается == ;, что ломает всё
type = ValueTypes.Complex;
return Parse(valueBuilder.ToString());
}
void ParseValueToRightType(string stringValue)
{
Debug("b", $"\nParseValueToRightType({stringValue})\n");
switch (stringValue)
{
// bool
case "true":
case "false":
type = ValueTypes.Bool;
value = stringValue.ToBool();
break;
// null
case "null":
type = ValueTypes.Null;
value = null;
break;
default:
if (stringValue.Contains('"'))
{
type = ValueTypes.String;
value = stringValue.Remove(stringValue.Length - 1).Remove(0, 1);
}
// double
else if (stringValue.Contains('.'))
{
type = ValueTypes.Double;
value = stringValue.ToDouble();
}
// ushort; ulong; uint
else if (stringValue.Length > 2 && stringValue[stringValue.Length - 2] == 'u')
{
switch (stringValue[stringValue.Length - 1])
{
case 's':
type = ValueTypes.UShort;
value = stringValue.Remove(stringValue.Length - 2).ToUShort();
break;
case 'i':
type = ValueTypes.UInt;
value = stringValue.Remove(stringValue.Length - 2).ToUInt();
break;
case 'l':
type = ValueTypes.ULong;
value = stringValue.Remove(stringValue.Length - 2).ToULong();
break;
default:
throw new Exception($"Dtsod.Parse.ReadValue() error: value <{stringValue}> has wrong type");
};
}
// short; long; int
else switch (stringValue[stringValue.Length - 1])
{
case 's':
type = ValueTypes.Short;
value = stringValue.Remove(stringValue.Length - 1).ToShort();
break;
case 'l':
type = ValueTypes.Long;
value = stringValue.Remove(stringValue.Length - 1).ToLong();
break;
default:
type = ValueTypes.Int;
value = stringValue.ToShort();
break;
}
break;
};
}
StringBuilder defaultValueBuilder = new();
Debug("m", "\nReadValue\n");
for (; i < text.Length; i++)
{
Debug("b", text[i].ToString());
switch (text[i])
{
case ' ':
case '\t':
case '\r':
case '\n':
break;
case '"':
value = ReadString();
break;
case '[':
value = ReadList();
break;
case '{':
value = ReadComplex();
break;
case ';':
switch (type)
{
case ValueTypes.String:
ParseValueToRightType(value);
break;
case ValueTypes.Unknown:
ParseValueToRightType(defaultValueBuilder.ToString());
break;
case ValueTypes.List:
isList = true;
break;
};
outType = type;
return value;
// строка, начинающаяся с # будет считаться комментом
case '#':
//ReadCommentLine();
break;
default:
defaultValueBuilder.Append(text[i]);
break;
}
}
throw new Exception("Dtsod.Parse.ReadValue error: wtf it's the end of function");
}
}
public override string ToString() => Deconstruct(this);
ushort tabCount = 0;
string Deconstruct(DtsodV22 dtsod)
{
StringBuilder outBuilder = new();
foreach (var key in dtsod.Keys)
{
outBuilder.Append('\t', tabCount);
outBuilder.Append(key);
outBuilder.Append(": ");
dtsod.TryGetValue(key, out ValueStruct value);
switch (value.Type)
{
case ValueTypes.List:
outBuilder.Append("\"list deconstruction is'nt implemented yet\"");
break;
case ValueTypes.Complex:
outBuilder.Append("\n");
outBuilder.Append('\t', tabCount);
outBuilder.Append("{\n");
tabCount++;
outBuilder.Append(Deconstruct(value.Value));
tabCount--;
outBuilder.Append('\t', tabCount);
outBuilder.Append("}");
break;
case ValueTypes.String:
outBuilder.Append("\"");
outBuilder.Append(value.Value.ToString());
outBuilder.Append("\"");
break;
case ValueTypes.Short:
outBuilder.Append(value.Value.ToString());
outBuilder.Append("s");
break;
case ValueTypes.Int:
outBuilder.Append(value.Value.ToString());
break;
case ValueTypes.Long:
outBuilder.Append(value.Value.ToString());
outBuilder.Append("l");
break;
case ValueTypes.UShort:
outBuilder.Append(value.Value.ToString());
outBuilder.Append("us");
break;
case ValueTypes.UInt:
outBuilder.Append(value.Value.ToString());
outBuilder.Append("ui");
break;
case ValueTypes.ULong:
outBuilder.Append(value.Value.ToString());
outBuilder.Append("uk");
break;
case ValueTypes.Double:
outBuilder.Append(value.Value.ToString(System.Globalization.CultureInfo.InvariantCulture));
break;
case ValueTypes.Null:
outBuilder.Append("null");
break;
case ValueTypes.Bool:
outBuilder.Append(value.Value.ToString().ToLower());
break;
default:
throw new Exception($"Dtsod.Deconstruct() error: unknown type: {value.Type}");
}
outBuilder.Append(";\n");
}
return outBuilder.ToString();
}
void Debug(params string[] msg)
{
if (debug) PublicLog.LogNoTime(msg);
}
}
}

19
Dtsod/ValueTypes.cs Normal file
View File

@ -0,0 +1,19 @@
namespace DTLib.Dtsod
{
public enum ValueTypes
{
List,
Complex,
String,
Short,
Int,
Long,
UShort,
UInt,
ULong,
Double,
Null,
Bool,
Unknown
}
}

View File

@ -64,8 +64,12 @@ namespace DTLib.Filesystem
for (int i = 0; i < files.Count; i++) for (int i = 0; i < files.Count; i++)
File.Delete(files[i]); File.Delete(files[i]);
for (int i = subdirs.Count - 1; i >= 0; i--) for (int i = subdirs.Count - 1; i >= 0; i--)
System.IO.Directory.Delete(subdirs[i]); {
System.IO.Directory.Delete(dir); PublicLog.Log($"deleting {subdirs[i]}\n");
if (Directory.Exists(subdirs[i])) System.IO.Directory.Delete(subdirs[i], true);
}
PublicLog.Log($"deleting {dir}\n");
if (Directory.Exists(dir)) System.IO.Directory.Delete(dir, true);
} }
public static string[] GetFiles(string dir) => System.IO.Directory.GetFiles(dir); public static string[] GetFiles(string dir) => System.IO.Directory.GetFiles(dir);
@ -112,5 +116,20 @@ namespace DTLib.Filesystem
} }
public static string GetCurrent() => System.IO.Directory.GetCurrentDirectory(); public static string GetCurrent() => System.IO.Directory.GetCurrentDirectory();
public static void GrantAccess(string fullPath)
{
System.IO.DirectoryInfo dirInfo = new System.IO.DirectoryInfo(fullPath);
System.Security.AccessControl.DirectorySecurity dirSecurity = dirInfo.GetAccessControl();
dirSecurity.AddAccessRule(new System.Security.AccessControl.FileSystemAccessRule(
new System.Security.Principal.SecurityIdentifier(
System.Security.Principal.WellKnownSidType.WorldSid, null),
System.Security.AccessControl.FileSystemRights.FullControl,
System.Security.AccessControl.InheritanceFlags.ObjectInherit |
System.Security.AccessControl.InheritanceFlags.ContainerInherit,
System.Security.AccessControl.PropagationFlags.NoPropagateInherit,
System.Security.AccessControl.AccessControlType.Allow));
dirInfo.SetAccessControl(dirSecurity);
}
} }
} }

View File

@ -9,8 +9,9 @@ namespace DTLib.Filesystem
public static bool Exists(string file) => System.IO.File.Exists(file); public static bool Exists(string file) => System.IO.File.Exists(file);
// если файл не существует, создаёт файл, создаёт папки из его пути // если файл не существует, создаёт файл, создаёт папки из его пути
public static void Create(string file) public static void Create(string file, bool delete_old = false)
{ {
if (delete_old && File.Exists(file)) File.Delete(file);
if (!File.Exists(file)) if (!File.Exists(file))
{ {
if (file.Contains("\\")) Directory.Create(file.Remove(file.LastIndexOf('\\'))); if (file.Contains("\\")) Directory.Create(file.Remove(file.LastIndexOf('\\')));
@ -65,9 +66,8 @@ namespace DTLib.Filesystem
} }
public static System.IO.FileStream OpenWrite(string file) public static System.IO.FileStream OpenWrite(string file)
{ {
if (Exists(file)) Delete(file); File.Create(file, true);
File.Create(file); return System.IO.File.Open(file, System.IO.FileMode.OpenOrCreate);
return System.IO.File.OpenWrite(file);
} }
public static System.IO.FileStream OpenAppend(string file) public static System.IO.FileStream OpenAppend(string file)
{ {

View File

@ -1,4 +1,5 @@
using DTLib.Filesystem; using DTLib.Dtsod;
using DTLib.Filesystem;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net.Sockets; using System.Net.Sockets;
@ -13,13 +14,17 @@ namespace DTLib.Network
public class FSP public class FSP
{ {
Socket mainSocket; Socket mainSocket;
public bool debug = true; public bool debug = false;
public FSP(Socket _mainSocket) => mainSocket = _mainSocket; public FSP(Socket _mainSocket) => mainSocket = _mainSocket;
public uint BytesDownloaded = 0; public uint BytesDownloaded = 0;
public uint BytesUploaded = 0; public uint BytesUploaded = 0;
public uint Filesize = 0; public uint Filesize = 0;
/*public delegate void PackageTransferDel(uint size);
public event PackageTransferDel PackageRecieved;
public event PackageTransferDel PackageSent;*/
// скачивает файл с помощью FSP протокола // скачивает файл с помощью FSP протокола
public void DownloadFile(string filePath_server, string filePath_client) public void DownloadFile(string filePath_server, string filePath_client)
{ {
@ -31,7 +36,7 @@ namespace DTLib.Network
public void DownloadFile(string filePath_client) public void DownloadFile(string filePath_client)
{ {
File.Create(filePath_client); BytesDownloaded = 0;
using var fileStream = File.OpenWrite(filePath_client); using var fileStream = File.OpenWrite(filePath_client);
Filesize = mainSocket.GetPackage().ToStr().ToUInt(); Filesize = mainSocket.GetPackage().ToStr().ToUInt();
var hashstr = mainSocket.GetPackage().HashToString(); var hashstr = mainSocket.GetPackage().HashToString();
@ -40,68 +45,79 @@ namespace DTLib.Network
byte[] buffer = new byte[5120]; byte[] buffer = new byte[5120];
int fullPackagesCount = SimpleConverter.Truncate(Filesize / buffer.Length); int fullPackagesCount = SimpleConverter.Truncate(Filesize / buffer.Length);
// рассчёт скорости // рассчёт скорости
int seconds = 0; /*int seconds = 0;
var speedCounter = new Timer(true, 1000, () => var speedCounter = new Timer(true, 1000, () =>
{ {
seconds++; seconds++;
Log("c", $"speed= {packagesCount * buffer.Length / (seconds * 1000)} kb/s\n"); PackageRecieved(BytesDownloaded);
}); });*/
// получение файла // получение файла
for (; packagesCount < fullPackagesCount; packagesCount++)
for (byte n = 0; packagesCount < fullPackagesCount; packagesCount++)
{ {
buffer = mainSocket.GetPackage(); buffer = mainSocket.GetPackage();
BytesDownloaded += (uint)buffer.Length;
fileStream.Write(buffer, 0, buffer.Length); fileStream.Write(buffer, 0, buffer.Length);
fileStream.Flush(); if (n == 100)
{
fileStream.Flush();
n = 0;
}
else n++;
} }
speedCounter.Stop();
// получение остатка // получение остатка
if ((Filesize - fileStream.Position) > 0) if ((Filesize - fileStream.Position) > 0)
{ {
mainSocket.SendPackage("remain request".ToBytes()); mainSocket.SendPackage("remain request".ToBytes());
buffer = mainSocket.GetPackage(); buffer = mainSocket.GetPackage();
BytesDownloaded += (uint)buffer.Length;
fileStream.Write(buffer, 0, buffer.Length); fileStream.Write(buffer, 0, buffer.Length);
} }
//speedCounter.Stop();
fileStream.Flush(); fileStream.Flush();
fileStream.Close(); fileStream.Close();
if (debug) Log(new string[] { "g", $" downloaded {packagesCount * 5120 + buffer.Length} of {Filesize} bytes\n" }); if (debug) Log(new string[] { "g", $" downloaded {BytesDownloaded} of {Filesize} bytes\n" });
} }
public byte[] DownloadFileToMemory(string filePath_server) public byte[] DownloadFileToMemory(string filePath_server)
{ {
BytesDownloaded = 0;
if (debug) Log("b", $"requesting file download: {filePath_server}\n"); if (debug) Log("b", $"requesting file download: {filePath_server}\n");
mainSocket.SendPackage("requesting file download".ToBytes()); mainSocket.SendPackage("requesting file download".ToBytes());
mainSocket.SendPackage(filePath_server.ToBytes()); mainSocket.SendPackage(filePath_server.ToBytes());
using var fileStream = new System.IO.MemoryStream(); using var fileStream = new System.IO.MemoryStream();
var fileSize = mainSocket.GetPackage().ToStr().ToUInt(); Filesize = mainSocket.GetPackage().ToStr().ToUInt();
var hashstr = mainSocket.GetPackage().HashToString(); var hashstr = mainSocket.GetPackage().HashToString();
mainSocket.SendPackage("ready".ToBytes()); mainSocket.SendPackage("ready".ToBytes());
int packagesCount = 0; int packagesCount = 0;
byte[] buffer = new byte[5120]; byte[] buffer = new byte[5120];
int fullPackagesCount = SimpleConverter.Truncate(fileSize / buffer.Length); int fullPackagesCount = SimpleConverter.Truncate(Filesize / buffer.Length);
// рассчёт скорости // рассчёт скорости
int seconds = 0; /*int seconds = 0;
var speedCounter = new Timer(true, 1000, () => var speedCounter = new Timer(true, 1000, () =>
{ {
seconds++; seconds++;
Log("c", $"speed= {packagesCount * buffer.Length / (seconds * 1000)} kb/s\n"); PackageRecieved(BytesDownloaded);
}); });*/
// получение файла // получение файла
for (; packagesCount < fullPackagesCount; packagesCount++) for (; packagesCount < fullPackagesCount; packagesCount++)
{ {
buffer = mainSocket.GetPackage(); buffer = mainSocket.GetPackage();
BytesDownloaded += (uint)buffer.Length;
fileStream.Write(buffer, 0, buffer.Length); fileStream.Write(buffer, 0, buffer.Length);
fileStream.Flush();
} }
speedCounter.Stop();
// получение остатка // получение остатка
if ((fileSize - fileStream.Position) > 0) if ((Filesize - fileStream.Position) > 0)
{ {
mainSocket.SendPackage("remain request".ToBytes()); mainSocket.SendPackage("remain request".ToBytes());
buffer = mainSocket.GetPackage(); buffer = mainSocket.GetPackage();
BytesDownloaded += (uint)buffer.Length;
fileStream.Write(buffer, 0, buffer.Length); fileStream.Write(buffer, 0, buffer.Length);
} }
//speedCounter.Stop();
byte[] output = fileStream.GetBuffer(); byte[] output = fileStream.GetBuffer();
fileStream.Close(); fileStream.Close();
if (debug) Log(new string[] { "g", $" downloaded {packagesCount * 5120 + buffer.Length} of {fileSize} bytes\n" }); if (debug) Log(new string[] { "g", $" downloaded {BytesDownloaded} of {Filesize} bytes\n" });
return output; return output;
} }
@ -118,32 +134,42 @@ namespace DTLib.Network
byte[] buffer = new byte[5120]; byte[] buffer = new byte[5120];
var hashstr = fileHash.HashToString(); var hashstr = fileHash.HashToString();
int packagesCount = 0; int packagesCount = 0;
// отправка файла
int fullPackagesCount = SimpleConverter.Truncate(Filesize / buffer.Length); int fullPackagesCount = SimpleConverter.Truncate(Filesize / buffer.Length);
// рассчёт скорости
/*int seconds = 0;
var speedCounter = new Timer(true, 1000, () =>
{
seconds++;
PackageSent(BytesUploaded);
});*/
// отправка файла
for (; packagesCount < fullPackagesCount; packagesCount++) for (; packagesCount < fullPackagesCount; packagesCount++)
{ {
fileStream.Read(buffer, 0, buffer.Length); fileStream.Read(buffer, 0, buffer.Length);
mainSocket.SendPackage(buffer); mainSocket.SendPackage(buffer);
BytesUploaded += (uint)buffer.Length;
} }
// досылка остатка // досылка остатка
if ((Filesize - fileStream.Position) > 0) if ((Filesize - fileStream.Position) > 0)
{ {
if (mainSocket.GetPackage().ToStr() != "remain request") throw new Exception("FSP_Upload() error: didn't get remain request"); mainSocket.GetAnswer("remain request");
buffer = new byte[(Filesize - fileStream.Position).ToInt()]; buffer = new byte[(Filesize - fileStream.Position).ToInt()];
fileStream.Read(buffer, 0, buffer.Length); fileStream.Read(buffer, 0, buffer.Length);
mainSocket.SendPackage(buffer); mainSocket.SendPackage(buffer);
BytesUploaded += (uint)buffer.Length;
} }
//speedCounter.Stop();
fileStream.Close(); fileStream.Close();
if (debug) Log(new string[] { "g", $" uploaded {packagesCount * 5120 + buffer.Length} of {Filesize} bytes\n" }); if (debug) Log(new string[] { "g", $" uploaded {BytesUploaded} of {Filesize} bytes\n" });
} }
public void DownloadByManifest(string dirOnServer, string dirOnClient, bool overwrite = false, bool delete_excess = false) public void DownloadByManifest(string dirOnServer, string dirOnClient, bool overwrite = false, bool delete_excess = false)
{ {
if (!dirOnClient.EndsWith("\\")) dirOnClient += "\\"; if (!dirOnClient.EndsWith("\\")) dirOnClient += "\\";
if (!dirOnServer.EndsWith("\\")) dirOnServer += "\\"; if (!dirOnServer.EndsWith("\\")) dirOnServer += "\\";
Log("b", "downloading manifest <", "c", dirOnServer + "manifest.dtsod", "b", ">\n"); if (debug) Log("b", "downloading manifest <", "c", dirOnServer + "manifest.dtsod", "b", ">\n");
var manifest = new Dtsod(DownloadFileToMemory(dirOnServer + "manifest.dtsod").ToStr()); var manifest = new DtsodV22(DownloadFileToMemory(dirOnServer + "manifest.dtsod").ToStr());
Log("g", $"found {manifest.Values.Count} files in manifest\n"); if (debug) Log("g", $"found {manifest.Values.Count} files in manifest\n");
var hasher = new Hasher(); var hasher = new Hasher();
foreach (string fileOnServer in manifest.Keys) foreach (string fileOnServer in manifest.Keys)
{ {
@ -174,18 +200,18 @@ namespace DTLib.Network
} }
} }
// удаление пустых папок // удаление пустых папок
foreach (string dir in dirs) /*foreach (string dir in dirs)
{ {
if (Directory.Exists(dir) && Directory.GetAllFiles(dir).Count == 0) if (Directory.Exists(dir) && Directory.GetAllFiles(dir).Count == 0)
{ {
if (debug) Log("y", $"deleting empty dir: {dir}\n"); if (debug) Log("y", $"deleting empty dir: {dir}\n");
Directory.Delete(dir); Directory.Delete(dir);
} }
} }*/
} }
} }
static public void CreateManifest(string dir) public static void CreateManifest(string dir)
{ {
if (!dir.EndsWith("\\")) dir += "\\"; if (!dir.EndsWith("\\")) dir += "\\";
Log($"b", $"creating manifest of {dir}\n"); Log($"b", $"creating manifest of {dir}\n");

View File

@ -11,7 +11,7 @@ namespace DTLib.Network
// получает с сайта публичный ip // получает с сайта публичный ip
public static string GetPublicIP() => new WebClient().DownloadString("https://ipv4bot.whatismyipaddress.com/"); public static string GetPublicIP() => new WebClient().DownloadString("https://ifconfig.me/ip");
// пингует айпи с помощью встроенной в винду проги, возвращает задержку // пингует айпи с помощью встроенной в винду проги, возвращает задержку
public static string PingIP(string address) public static string PingIP(string address)

View File

@ -8,7 +8,7 @@ namespace DTLib.Network
// //
// отправка/получение пакетов // отправка/получение пакетов
// //
static public class Package public static class Package
{ {
// принимает пакет // принимает пакет
public static byte[] GetPackage(this Socket socket) public static byte[] GetPackage(this Socket socket)
@ -22,7 +22,6 @@ namespace DTLib.Network
{ {
socket.Receive(data, data.Length, 0); socket.Receive(data, data.Length, 0);
packageSize = data.BytesToInt(); packageSize = data.BytesToInt();
} }
if (packageSize != 0 && socket.Available >= packageSize) if (packageSize != 0 && socket.Available >= packageSize)
{ {
@ -47,5 +46,12 @@ namespace DTLib.Network
list.AddRange(data); list.AddRange(data);
socket.Send(list.ToArray()); socket.Send(list.ToArray());
} }
// получает пакет и выбрасывает исключение, если пакет не соответствует образцу
public static void GetAnswer(this Socket socket, string answer)
{
var rec = socket.GetPackage().ToStr();
if (rec != answer) throw new Exception($"GetAnswer() error: invalid answer: <{rec}>");
}
} }
} }

View File

@ -51,14 +51,6 @@ namespace DTLib
// из-за чего вызов метода так: Math.Truncate(10/3) выдаст ошибку "неоднозначный вызов" // из-за чего вызов метода так: Math.Truncate(10/3) выдаст ошибку "неоднозначный вызов"
public static int Truncate<T>(this T number) => Math.Truncate(number.ToDouble()).ToInt(); public static int Truncate<T>(this T number) => Math.Truncate(number.ToDouble()).ToInt();
// сортирует в порядке возрастания элементы если это возможно, используя стандартный метод list.Sort();
public static T[] Sort<T>(this T[] array)
{
var list = array.ToList();
list.Sort();
return list.ToArray();
}
// массив в лист // массив в лист
public static List<T> ToList<T>(this T[] input) public static List<T> ToList<T>(this T[] input)
{ {
@ -84,18 +76,6 @@ namespace DTLib
return false; return false;
} }
// конвертирует массив в строку
public static string MergeToString<T>(this T[] array, string separator)
{
var b = new StringBuilder();
for (int i = 0; i < array.Length; i++)
{
b.Append(array[i].ToString());
b.Append(separator);
}
return b.ToString();
}
// сокращение конвертации // сокращение конвертации
public static int ToInt<T>(this T input) => Convert.ToInt32(input); public static int ToInt<T>(this T input) => Convert.ToInt32(input);
public static uint ToUInt<T>(this T input) => Convert.ToUInt32(input); public static uint ToUInt<T>(this T input) => Convert.ToUInt32(input);
@ -108,14 +88,6 @@ namespace DTLib
public static sbyte ToSByte<T>(this T input) => Convert.ToSByte(input); public static sbyte ToSByte<T>(this T input) => Convert.ToSByte(input);
public static bool ToBool<T>(this T input) => Convert.ToBoolean(input); public static bool ToBool<T>(this T input) => Convert.ToBoolean(input);
public static string AutoBuild(params object[] parts)
{
var builder = new StringBuilder();
for (int i = 0; i < parts.Length; i++)
builder.Append(parts[i]);
return builder.ToString();
}
public static int BytesToInt(this byte[] bytes) public static int BytesToInt(this byte[] bytes)
{ {
int output = 0; int output = 0;
@ -135,7 +107,15 @@ namespace DTLib
return output.ToArray(); return output.ToArray();
} }
public static string ToString<T>(this IEnumerable<T> collection, string separator) public static string AutoBuild(params object[] parts)
{
var builder = new StringBuilder();
for (int i = 0; i < parts.Length; i++)
builder.Append(parts[i].ToString());
return builder.ToString();
}
public static string MergeToString<T>(this IEnumerable<T> collection, string separator)
{ {
StringBuilder builder = new(); StringBuilder builder = new();
foreach (T elem in collection) foreach (T elem in collection)
@ -146,6 +126,22 @@ namespace DTLib
builder.Remove(builder.Length - separator.Length, separator.Length); builder.Remove(builder.Length - separator.Length, separator.Length);
return builder.ToString(); return builder.ToString();
} }
public static string MergeToString<T>(this IEnumerable<T> collection)
{
StringBuilder builder = new();
foreach (T elem in collection)
{
builder.Append(elem.ToString());
}
return builder.ToString();
}
public static string Multiply(this string input, int howMany)
{
StringBuilder b = new();
for (int i = 0; i < howMany; i++)
b.Append(input);
return b.ToString();
}
} }
} }