diff --git a/DTLib/DTLib.csproj b/DTLib/DTLib.csproj index 043db00..21cd6b5 100644 --- a/DTLib/DTLib.csproj +++ b/DTLib/DTLib.csproj @@ -35,10 +35,10 @@ - + - + diff --git a/DTLib/FileWork.cs b/DTLib/FileWork.cs index 65b3228..ce5a53b 100644 --- a/DTLib/FileWork.cs +++ b/DTLib/FileWork.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.IO; namespace DTLib @@ -6,15 +7,15 @@ namespace DTLib // // методы для работы с файловой системой // - public static class FileWork + public static class Filework { // записывает текст в файл и закрывает файл - public static void Log(string logfile, string msg) + public static void LogToFile(string logfile, string msg) { lock (new object()) { - FileCreate(logfile); - var st = File.Open(logfile, FileMode.Append); + File.Create(logfile); + var st = File.OpenAppend(logfile); var writer = new StreamWriter(st, SimpleConverter.UTF8); writer.Write(msg); writer.Close(); @@ -22,29 +23,6 @@ namespace DTLib } } - // создает папку если её не существует - public static void DirCreate(string dir) - { - if (!Directory.Exists(dir)) - { - // проверяет существование папки, в которой нужно создать dir - if (dir.Contains("\\") && !Directory.Exists(dir.Remove(dir.LastIndexOf('\\')))) - DirCreate(dir.Remove(dir.LastIndexOf('\\'))); - Directory.CreateDirectory(dir); - } - } - - // создаёт файл, сохдаёт папки из его пути - public static void FileCreate(string path) - { - if (!File.Exists(path)) - { - if (path.Contains("\\")) DirCreate(path.Remove(path.LastIndexOf('\\'))); - using var s = File.Create(path); - s.Close(); - } - } - // чтение параметров из конфига public static string ReadFromConfig(string configfile, string key) { @@ -92,93 +70,189 @@ namespace DTLib } } - // копирует все файли и папки - public static void DirCopy(string source_dir, string new_dir, bool Override) + + public static class Directory { - DirCreate(new_dir); - List subdirs = new List(); - List files = GetAllFiles(source_dir, ref subdirs); - for (int i = 0; i < subdirs.Count; i++) + public static bool Exists(string dir) => System.IO.Directory.Exists(dir); + + // создает папку, если её не существует + public static void Create(string dir) { - DirCreate(subdirs[i].Replace(source_dir, new_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); + } } - for (int i = 0; i < files.Count; i++) + // копирует все файлы и папки + public static void Copy(string source_dir, string new_dir, bool owerwrite = false) { - string f = files[i].Replace(source_dir, new_dir); - File.Copy(files[i], f, Override); - //PublicLog.Log(new string[] {"g", $"file <", "c", files[i], "b", "> have copied to <", "c", newfile, "b", ">\n'" }); + Create(new_dir); + List subdirs = new List(); + List files = GetAllFiles(source_dir, ref subdirs); + for (int i = 0; i < subdirs.Count; i++) + { + Create(subdirs[i].Replace(source_dir, new_dir)); + } + for (int i = 0; i < files.Count; i++) + { + string f = files[i].Replace(source_dir, new_dir); + File.Copy(files[i], f, owerwrite); + //PublicLog.Log(new string[] {"g", $"file <", "c", files[i], "b", "> have copied to <", "c", newfile, "b", ">\n'" }); + } } + + // копирует все файлы и папки и выдаёт список конфликтующих файлов + public static void Copy(string source_dir, string new_dir, out List conflicts, bool owerwrite = false) + { + conflicts = new List(); + var subdirs = new List(); + var files = GetAllFiles(source_dir, ref subdirs); + Create(new_dir); + for (int i = 0; i < subdirs.Count; i++) + { + Create(subdirs[i].Replace(source_dir, new_dir)); + } + for (int i = 0; i < files.Count; i++) + { + string newfile = files[i].Replace(source_dir, new_dir); + if (File.Exists(newfile)) conflicts.Add(newfile); + File.Copy(files[i], newfile, owerwrite); + //PublicLog.Log(new string[] {"g", $"file <", "c", files[i], "b", "> have copied to <", "c", newfile, "b", ">\n'" }); + } + } + + // удаляет папку со всеми подпапками и файлами + public static void Delete(string dir) + { + var subdirs = new List(); + var files = GetAllFiles(dir, ref subdirs); + for (int i = 0; i < files.Count; i++) + File.Delete(files[i]); + for (int i = subdirs.Count - 1; i >= 0; i--) + System.IO.Directory.Delete(subdirs[i]); + System.IO.Directory.Delete(dir); + } + + public static string[] GetFiles(string dir) => System.IO.Directory.GetFiles(dir); + public static string[] GetDirectories(string dir) => System.IO.Directory.GetDirectories(dir); + + // выдает список всех файлов + public static List GetAllFiles(string dir) + { + List all_files = new List(); + string[] cur_files = Directory.GetFiles(dir); + for (int i = 0; i < cur_files.Length; i++) + { + all_files.Add(cur_files[i]); + //PublicLog.Log(new string[] { "b", "file found: <", "c", cur_files[i], "b", ">\n" }); + } + string[] cur_subdirs = Directory.GetDirectories(dir); + for (int i = 0; i < cur_subdirs.Length; i++) + { + //PublicLog.Log(new string[] { "b", "subdir found: <", "c", cur_subdirs[i], "b", ">\n" }); + all_files.AddRange(GetAllFiles(cur_subdirs[i])); + } + return all_files; + } + + // выдает список всех файлов и подпапок в папке + public static List GetAllFiles(string dir, ref List all_subdirs) + { + List all_files = new List(); + string[] cur_files = Directory.GetFiles(dir); + for (int i = 0; i < cur_files.Length; i++) + { + all_files.Add(cur_files[i]); + //PublicLog.Log(new string[] { "b", "file found: <", "c", cur_files[i], "b", ">\n" }); + } + string[] cur_subdirs = Directory.GetDirectories(dir); + for (int i = 0; i < cur_subdirs.Length; i++) + { + all_subdirs.Add(cur_subdirs[i]); + //PublicLog.Log(new string[] { "b", "subdir found: <", "c", cur_subdirs[i], "b", ">\n" }); + all_files.AddRange(GetAllFiles(cur_subdirs[i], ref all_subdirs)); + } + return all_files; + } + } - // копирует все файли и папки и выдаёт список конфликтующих файлов - public static void DirCopy(string source_dir, string new_dir, bool owerwrite, out List conflicts) + public static class File { - conflicts = new List(); - var subdirs = new List(); - var files = GetAllFiles(source_dir, ref subdirs); - DirCreate(new_dir); - for (int i = 0; i < subdirs.Count; i++) - { - DirCreate(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 int GetSize(string file) => new System.IO.FileInfo(file).Length.ToInt(); - // выдает список всех файлов - public static List GetAllFiles(string dir) - { - List all_files = new List(); - string[] cur_files = Directory.GetFiles(dir); - for (int i = 0; i < cur_files.Length; i++) - { - all_files.Add(cur_files[i]); - //PublicLog.Log(new string[] { "b", "file found: <", "c", cur_files[i], "b", ">\n" }); - } - string[] cur_subdirs = Directory.GetDirectories(dir); - for (int i = 0; i < cur_subdirs.Length; i++) - { - //PublicLog.Log(new string[] { "b", "subdir found: <", "c", cur_subdirs[i], "b", ">\n" }); - all_files.AddRange(GetAllFiles(cur_subdirs[i])); - } - return all_files; - } + public static bool Exists(string file) => System.IO.File.Exists(file); - // выдает список всех файлов и подпапок в папке - public static List GetAllFiles(string dir, ref List all_subdirs) - { - List all_files = new List(); - string[] cur_files = Directory.GetFiles(dir); - for (int i = 0; i < cur_files.Length; i++) + // если файл не существует, создаёт файл, создаёт папки из его пути + public static void Create(string file) { - all_files.Add(cur_files[i]); - //PublicLog.Log(new string[] { "b", "file found: <", "c", cur_files[i], "b", ">\n" }); + if (!File.Exists(file)) + { + if (file.Contains("\\")) Directory.Create(file.Remove(file.LastIndexOf('\\'))); + using var stream = System.IO.File.Create(file); + stream.Close(); + } } - 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 void DirDelete(string dir) - { - var subdirs = new List(); - var files = GetAllFiles(dir, ref subdirs); - for (int i = 0; i < files.Count; i++) - File.Delete(files[i]); - for (int i = subdirs.Count - 1; i >= 0; i--) - Directory.Delete(subdirs[i]); - Directory.Delete(dir); + 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 FileStream stream = System.IO.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) + { + File.Create(file); + using FileStream stream = System.IO.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) + { + File.Create(file); + using FileStream stream = System.IO.File.OpenWrite(file); + stream.Write(content, GetSize(file), content.Length); + stream.Close(); + } + + public static void AppendAllText(string file, string content) => AppendAllBytes(file, content.ToBytes()); + + public static FileStream OpenRead(string file) + { + if (!Exists(file)) throw new Exception($"file not found: <{file}>"); + return System.IO.File.OpenRead(file); + } + public static FileStream OpenWrite(string file) + { + File.Create(file); + return System.IO.File.OpenWrite(file); + } + public static FileStream OpenAppend(string file) + { + File.Create(file); + return System.IO.File.Open(file, FileMode.Append); + } } } } diff --git a/DTLib/NetWork.cs b/DTLib/NetWork.cs index b560f96..20a89be 100644 --- a/DTLib/NetWork.cs +++ b/DTLib/NetWork.cs @@ -1,11 +1,12 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.IO; +//using System.IO; using System.Net; using System.Net.Sockets; using System.Threading; using static DTLib.PublicLog; +using static DTLib.Filework; namespace DTLib { @@ -13,138 +14,8 @@ namespace DTLib // весь униврсальный неткод тут // большинство методов предназначены для работы с TCP сокетами (Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) // - public static class NetWork + public static class Network { - // скачивание файла с фтп сервера - public static void FtpDownload(string address, string login, string password, string outfile) - { - try - { - // debug - Log(new string[] { "y", "file on server: <", "c", address, "y", ">\nfile on client: <", "c", outfile, "y", ">\n" }); - // создание запроса - // "ftp://m1net.keenetic.pro:20000/" + @infile - FtpWebRequest request = (FtpWebRequest)WebRequest.Create(address); - request.Credentials = new NetworkCredential(login, password); - request.Method = WebRequestMethods.Ftp.DownloadFile; - // получение ответа на запрос - FtpWebResponse response = (FtpWebResponse)request.GetResponse(); - Stream responseStream = response.GetResponseStream(); - FileStream fs = new FileStream(@Directory.GetCurrentDirectory() + '\\' + @outfile, FileMode.Create); - byte[] buffer = new byte[64]; - int size = 0; - - while ((size = responseStream.Read(buffer, 0, buffer.Length)) > 0) - fs.Write(buffer, 0, size); - fs.Close(); - response.Close(); - } - catch (WebException e) { throw new Exception("ftp error:\n" + ((FtpWebResponse)e.Response).StatusDescription + '\n'); } - } - - // пингует айпи с помощью встроенной в винду проги, возвращает задержку - public 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); - } - - // скачивает файл с помощью FSP протокола - public static void FSP_Download(this Socket mainSocket, string filePath_server, string filePath_client) - { - Log("g", $"requesting file download: {filePath_server}\n"); - mainSocket.SendPackage("requesting file download".ToBytes()); - mainSocket.SendPackage(filePath_server.ToBytes()); - FSP_Download(mainSocket, filePath_client); - } - - public static void FSP_Download(this Socket mainSocket, string filePath_client) - { - FileWork.FileCreate(filePath_client); - using var fileStream = File.OpenWrite(filePath_client); - var fileSize = Convert.ToUInt32(mainSocket.GetPackage().ToStr()); - 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(); - Log(new string[] { "g", $" downloaded {packagesCount * 5120 + buffer.Length} of {fileSize} bytes\n" }); - - } - - // отдаёт файл с помощью FSP протокола - public static void FSP_Upload(this Socket mainSocket, string filePath) - { - Log("b", $"uploading file {filePath}\n"); - using var fileStream = File.OpenRead(filePath); - var fileSize = new FileInfo(filePath).Length; - 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 seconds = 0; - // рассчёт скорости - var speedCounter = new Timer(true, 1000, () => - { - seconds++; - Log("c", $"speed= {packagesCount * buffer.Length / (seconds * 1000)} kb/s\n"); - }); - // отправка файла - int fullPackagesCount = SimpleConverter.Truncate(fileSize / buffer.Length); - for (; packagesCount < fullPackagesCount; packagesCount++) - { - fileStream.Read(buffer, 0, buffer.Length); - mainSocket.SendPackage(buffer); - } - speedCounter.Stop(); - // досылка остатка - 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(); - Log(new string[] { "g", $" uploaded {packagesCount * 5120 + buffer.Length} of {fileSize} bytes\n" }); - - } // ждёт пакет заданного размера с заданным началом и концом public static byte[] GetPackage(this Socket socket) @@ -184,7 +55,246 @@ namespace DTLib socket.Send(list.ToArray()); } + + // скачивает файл с помощью FSP протокола + public static void FSP_Download(this Socket mainSocket, string filePath_server, string filePath_client) + { + Log("g", $"requesting file download: {filePath_server}\n"); + mainSocket.SendPackage("requesting file download".ToBytes()); + mainSocket.SendPackage(filePath_server.ToBytes()); + FSP_Download(mainSocket, filePath_client); + } + + public static void FSP_Download(this Socket mainSocket, string filePath_client) + { + File.Create(filePath_client); + using var fileStream = File.OpenWrite(filePath_client); + 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); + } + fileStream.Flush(); + fileStream.Close(); + Log(new string[] { "g", $" downloaded {packagesCount * 5120 + buffer.Length} of {fileSize} bytes\n" }); + + } + + // отдаёт файл с помощью FSP протокола + public static void FSP_Upload(this Socket mainSocket, string filePath) + { + Log("b", $"uploading file {filePath}\n"); + using var fileStream = File.OpenRead(filePath); + var fileSize = File.GetSize(filePath); + 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 seconds = 0; + // рассчёт скорости + var speedCounter = new Timer(true, 1000, () => + { + seconds++; + Log("c", $"speed= {packagesCount * buffer.Length / (seconds * 1000)} kb/s\n"); + }); + // отправка файла + int fullPackagesCount = SimpleConverter.Truncate(fileSize / buffer.Length); + for (; packagesCount < fullPackagesCount; packagesCount++) + { + fileStream.Read(buffer, 0, buffer.Length); + mainSocket.SendPackage(buffer); + } + speedCounter.Stop(); + // досылка остатка + 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(); + Log(new string[] { "g", $" uploaded {packagesCount * 5120 + buffer.Length} of {fileSize} bytes\n" }); + + } + // получает с сайта публичный 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 static void FtpDownload(string address, string login, string password, string outfile) + { + try + { + // debug + Log(new string[] { "y", "file on server: <", "c", address, "y", ">\nfile on client: <", "c", outfile, "y", ">\n" }); + // создание запроса + // "ftp://m1net.keenetic.pro:20000/" + @infile + FtpWebRequest request = (FtpWebRequest)WebRequest.Create(address); + request.Credentials = new NetworkCredential(login, password); + request.Method = WebRequestMethods.Ftp.DownloadFile; + // получение ответа на запрос + FtpWebResponse response = (FtpWebResponse)request.GetResponse(); + Stream responseStream = response.GetResponseStream(); + FileStream fs = new FileStream(@Directory.GetCurrentDirectory() + '\\' + @outfile, FileMode.Create); + byte[] buffer = new byte[64]; + int size = 0; + + while ((size = responseStream.Read(buffer, 0, buffer.Length)) > 0) + fs.Write(buffer, 0, size); + fs.Close(); + response.Close(); + } + catch (WebException e) { throw new Exception("ftp error:\n" + ((FtpWebResponse)e.Response).StatusDescription + '\n'); } + }*/ + + public class FSP + { + Socket mainSocket; + FSP(Socket _mainSocket) => mainSocket = _mainSocket; + + //public delegate void FSP_LogDelegate(uint bytes); + public uint BytesDownloaded = 0; + public uint BytesUploaded = 0; + public uint Filesize = 0; + + // скачивает файл с помощью FSP протокола + public void DownloadFile(string filePath_server, string filePath_client) + { + Log("g", $"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); + // получение файла + for (; packagesCount < fullPackagesCount; packagesCount++) + { + buffer = mainSocket.GetPackage(); + fileStream.Write(buffer, 0, buffer.Length); + fileStream.Flush(); + } + // получение остатка + if ((Filesize - fileStream.Position) > 0) + { + mainSocket.SendPackage("remain request".ToBytes()); + buffer = mainSocket.GetPackage(); + fileStream.Write(buffer, 0, buffer.Length); + } + fileStream.Flush(); + fileStream.Close(); + Log(new string[] { "g", $" downloaded {packagesCount * 5120 + buffer.Length} of {Filesize} bytes\n" }); + } + + // отдаёт файл с помощью FSP протокола + public void UploadFile(string filePath) + { + 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(); + Log(new string[] { "g", $" uploaded {packagesCount * 5120 + buffer.Length} of {Filesize} bytes\n" }); + } + + public void DownloadByManifest(string manifestOnServer, string dirOnClient) + { + Log("b", "downloading manifest <", "c", manifestOnServer, "b", ">\n"); + DownloadFile(manifestOnServer, "TEMP\\manifestOnServer"); + var manifest = new Dtsod(File.ReadAllText("TEMP\\manifest.dtsod")); + Log("g", $"found {manifest.Values.Count} files in manifest\n"); + var hasher = new Hasher(); + foreach (string fileOnServer in manifest.Values.Keys) + { + string fileOnClient = $"{dirOnClient}\\{fileOnServer}"; + Log("b", "file <", "c", fileOnClient, "b", ">... "); + if (!File.Exists(fileOnClient)) + { + LogNoTime("y", "doesn't exist\n"); + DownloadFile(fileOnServer, fileOnClient); + } + else if (hasher.HashFile(fileOnClient).HashToString() != manifest[fileOnServer]) + { + LogNoTime("y", "outdated\n"); + DownloadFile(fileOnServer, fileOnClient); + } + else LogNoTime("g", "without changes\n"); + } + Directory.Delete("TEMP"); + } + } } } diff --git a/DTLib/PublicLog.cs b/DTLib/PublicLog.cs index 5b38768..aa08e32 100644 --- a/DTLib/PublicLog.cs +++ b/DTLib/PublicLog.cs @@ -5,12 +5,10 @@ // public static class PublicLog { - public delegate void LogDelegate(string[] msg); + public delegate void LogDelegate(params string[] msg); // вот к этому объекту подключайте методы для вывода логов - public static LogDelegate LogDel; - - // этот метод вызывается в библиотеке - public static void Log(params string[] msg) - => LogDel(msg); + public static LogDelegate Log; + public static LogDelegate LogNoTime; + public static LogDelegate FSP_DownloadSpeed; } } diff --git a/dtlauncher-client-win/LauncherWindow.xaml.cs b/dtlauncher-client-win/LauncherWindow.xaml.cs index 717c471..fe29a2e 100644 --- a/dtlauncher-client-win/LauncherWindow.xaml.cs +++ b/dtlauncher-client-win/LauncherWindow.xaml.cs @@ -29,7 +29,7 @@ namespace dtlauncher_client_win mainSocket = _socket; logfile = _logfile; LogBox.Text += _log; - PublicLog.LogDel += Log; + PublicLog.Log += Log; this.Closed += AppClose; // переключение вкладок кнопками var green = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(44, 220, 17)); @@ -86,7 +86,7 @@ namespace dtlauncher_client_win public void Log(string msg) { if (LogBox.Text[LogBox.Text.Length - 1] == '\n') msg = "[" + DateTime.Now.ToString() + "]: " + msg; - FileWork.Log(logfile, msg); + Filework.LogToFile(logfile, msg); LogBox.Text += msg; } diff --git a/dtlauncher-client-win/LoginWindow.xaml.cs b/dtlauncher-client-win/LoginWindow.xaml.cs index f2071fb..a8f39ec 100644 --- a/dtlauncher-client-win/LoginWindow.xaml.cs +++ b/dtlauncher-client-win/LoginWindow.xaml.cs @@ -23,12 +23,12 @@ namespace dtlauncher_client_win { InitializeComponent(); LogBox.Text = " \n"; // костыль для работы Log() - FileWork.DirCreate("logs"); - FileWork.DirCreate("downloads"); - FileWork.DirCreate("installed"); - FileWork.DirCreate("installscripts"); - FileWork.DirCreate("launchinfo"); - PublicLog.LogDel += Log; + Filework.Directory.Create("logs"); + Filework.Directory.Create("downloads"); + Filework.Directory.Create("installed"); + Filework.Directory.Create("installscripts"); + Filework.Directory.Create("launchinfo"); + PublicLog.Log += Log; LoginButton.Click += Login; RegisterButton.Click += Register; Log("[" + DateTime.Now.ToString() + "]: launcher is starting\n"); @@ -105,7 +105,7 @@ namespace dtlauncher_client_win if (recieved != "success") throw new Exception($"Login() error: invalid server answer <{recieved}>"); Log("succesfully connected\n"); // вызов нового окна - PublicLog.LogDel -= Log; + PublicLog.Log -= Log; var lauWin = new LauncherWindow(mainSocket, logfile, LogBox.Text); lauWin.Show(); this.Closed -= AppClose; @@ -122,7 +122,7 @@ namespace dtlauncher_client_win public void Log(string msg) { if (LogBox.Text[LogBox.Text.Length - 1] == '\n') msg = "[" + DateTime.Now.ToString() + "]: " + msg; - FileWork.Log(logfile, msg); + Filework.LogToFile(logfile, msg); LogBox.Text += msg; } diff --git a/dtlauncher-client-win/ProgramLabel.xaml.cs b/dtlauncher-client-win/ProgramLabel.xaml.cs index d5e8263..75941da 100644 --- a/dtlauncher-client-win/ProgramLabel.xaml.cs +++ b/dtlauncher-client-win/ProgramLabel.xaml.cs @@ -96,7 +96,9 @@ namespace dtlauncher_client_win switch (descriptor["id"]) { case "anarx_1.12": - + Window.Install(); + Window.Log($"launching file <{launchinfo["launchfile"]}>\n"); + Process.Start(launchinfo["launchfile"]); break; default: Window.Log($"launching file <{launchinfo["launchfile"]}>\n"); diff --git a/dtlauncher-server-win/DtlauncherServer.cs b/dtlauncher-server-win/DtlauncherServer.cs index 0b1a927..4aaba08 100644 --- a/dtlauncher-server-win/DtlauncherServer.cs +++ b/dtlauncher-server-win/DtlauncherServer.cs @@ -6,7 +6,7 @@ using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; -using static DTLib.NetWork; +using static DTLib.Network; namespace dtlauncher_server { @@ -25,7 +25,7 @@ namespace dtlauncher_server Console.Title = "dtlauncher server"; Console.InputEncoding = Encoding.Unicode; Console.OutputEncoding = Encoding.Unicode; - PublicLog.LogDel += Log; + PublicLog.Log += Log; /*var outBuilder = new StringBuilder(); string time = DateTime.Now.ToString().Replace(':', '-').Replace(' ', '_'); foreach (var _file in Directory.GetFiles(@"D:\!dtlauncher-server\share\public\Conan_Exiles")) @@ -97,9 +97,9 @@ namespace dtlauncher_server { lock (new object()) { - if (msg.Length == 1) FileWork.Log(logfile, msg[0]); + if (msg.Length == 1) Filework.LogToFile(logfile, msg[0]); else if (msg.Length % 2 != 0) throw new Exception("incorrect array to log\n"); - else FileWork.Log(logfile, SimpleConverter.AutoBuild(msg)); + else Filework.LogToFile(logfile, SimpleConverter.AutoBuild(msg)); ColoredConsole.Write(msg); } } @@ -143,7 +143,7 @@ namespace dtlauncher_server recieved = handlerSocket.GetPackage().ToStr(); filepath = $"registration_requests\\{recieved.Remove(0, recieved.IndexOf(':') + 2)}.req"; File.WriteAllText(filepath, recieved); - Log("b", $"text wrote to file <","c","registration_requests\\{filepath}","b",">\n"); + Log("b", $"text wrote to file <", "c", "registration_requests\\{filepath}", "b", ">\n"); break; default: throw new Exception("unknown request: " + request); @@ -159,7 +159,7 @@ namespace dtlauncher_server string login; lock (new object()) { - login = FileWork.ReadFromConfig("users.db", hash.HashToString()); + login = Filework.ReadFromConfig("users.db", hash.HashToString()); } handlerSocket.SendPackage("success".ToBytes()); Log("g", "user <", "c", login, "g", "> succesfully logined\n"); @@ -203,7 +203,7 @@ namespace dtlauncher_server public static void CreateManifest(string dir) { if (!dir.EndsWith("\\")) dir += "\\"; - var files = FileWork.GetAllFiles(dir); + var files = Filework.Directory.GetAllFiles(dir); if (files.Contains(dir + "manifest.dtsod")) files.Remove(dir + "manifest.dtsod"); StringBuilder manifestBuilder = new(); Hasher hasher = new(); diff --git a/dtlauncher.sln b/dtlauncher.sln index 56f8864..60a4795 100644 --- a/dtlauncher.sln +++ b/dtlauncher.sln @@ -17,11 +17,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dtscript", "..\dtscript\dts EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "updater", "updater\updater.csproj", "{4784D974-A342-4202-9430-90FE5AC00FC7}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{EBC1E4F2-AC73-4D69-A3E6-0432960EC929}" - ProjectSection(SolutionItems) = preProject - .editorconfig = .editorconfig - EndProjectSection -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DTLib", "DTLib\DTLib.csproj", "{CE793497-2D5C-42D8-B311-E9B32AF9CDFB}" EndProject Global diff --git a/updater/Updater.cs b/updater/Updater.cs index 65edffd..c87a7a9 100644 --- a/updater/Updater.cs +++ b/updater/Updater.cs @@ -22,7 +22,7 @@ namespace updater Console.Title = "dtlauncher updater"; Console.InputEncoding = Encoding.Unicode; Console.OutputEncoding = Encoding.Unicode; - PublicLog.LogDel += Log; + PublicLog.Log += Log; // подключение к центральному серверу while (true) { @@ -55,30 +55,11 @@ namespace updater } else { - Log("b", "downloading manifest\n"); - mainSocket.FSP_Download("manifest.dtsod", "TEMP\\manifest.dtsod"); - var manifest = new Dtsod(File.ReadAllText("TEMP\\manifest.dtsod")); - Log("g", $"found {manifest.Values.Count} files in manifest\n"); - var hasher = new Hasher(); - foreach (string file in manifest.Values.Keys) - { - Log("b", "file <", "c", file, "b", ">... "); - if (!File.Exists(file)) - { - LogNoTime("y", "doesn't exist\n"); - mainSocket.FSP_Download(file, file); - } - else if (hasher.HashFile(file).HashToString() != manifest[file]) - { - LogNoTime("y", "outdated\n"); - mainSocket.FSP_Download(file, file); - } - else LogNoTime("g", "without changes\n"); - } + // установка шрифтов Log("installing fonts\n"); Process.Start("fonts\\fontinst.exe"); - FileWork.DirDelete("TEMP"); + Filework.Directory.Delete("TEMP"); Log("deleted TEMP\n"); Process.Start("dtlauncher-client-win.exe", "updated"); } @@ -102,9 +83,9 @@ namespace updater { lock (new object()) { - if (msg.Length == 1) FileWork.Log(logfile, msg[0]); + if (msg.Length == 1) Filework.LogToFile(logfile, msg[0]); else if (msg.Length % 2 != 0) throw new Exception("incorrect array to log\n"); - else FileWork.Log(logfile, SimpleConverter.AutoBuild(msg)); + else Filework.LogToFile(logfile, SimpleConverter.AutoBuild(msg)); ColoredConsole.Write(msg); } }