using System.IO.Compression; using System.IO; using System; using System.Threading.Tasks; using System.Linq; using System.Collections.Generic; using System.Security.Cryptography; using Discord.WebSocket; using PluginManager.Items; using System.Threading; using System.Text.Json; using System.Text; namespace PluginManager.Others { /// /// A special class with functions /// public static class Functions { /// /// The location for the Resources folder /// public static readonly string dataFolder = @"./Data/Resources/"; /// /// The location for all logs /// public static readonly string logFolder = @"./Output/Logs/"; /// /// The location for all errors /// public static readonly string errFolder = @"./Output/Errors/"; /// /// Archives folder /// public static readonly string pakFolder = @"./Data/Resources/PAK/"; /// /// Read data from a file that is inside an archive (ZIP format) /// /// The file name that is inside the archive or its full path /// The archive location from the PAKs folder /// A string that represents the content of the file or null if the file does not exists or it has no content public static async Task ReadFromPakAsync(string FileName, string archFile) { archFile = pakFolder + archFile; Directory.CreateDirectory(pakFolder); if (!File.Exists(archFile)) throw new FileNotFoundException("Failed to load file !"); Stream? textValue = null; var fs = new FileStream(archFile, FileMode.Open); var zip = new ZipArchive(fs, ZipArchiveMode.Read); foreach (var entry in zip.Entries) { if (entry.Name == FileName || entry.FullName == FileName) { Stream s = entry.Open(); StreamReader reader = new StreamReader(s); textValue = reader.BaseStream; textValue.Position = 0; reader.Close(); s.Close(); fs.Close(); break; } } return textValue; } /// /// Write logs to file /// /// The message to be wrote public static void WriteLogFile(string LogMessage) { string logsPath = logFolder + $"{DateTime.Today.ToShortDateString().Replace("/", "-").Replace("\\", "-")} Log.txt"; if (!Directory.Exists(logFolder)) Directory.CreateDirectory(logFolder); File.AppendAllText(logsPath, LogMessage + " \n"); } /// /// Write error to file /// /// The message to be wrote public static void WriteErrFile(string ErrMessage) { string errPath = errFolder + $"{DateTime.Today.ToShortDateString().Replace("/", "-").Replace("\\", "-")} Error.txt"; if (!Directory.Exists(errFolder)) Directory.CreateDirectory(errFolder); File.AppendAllText(errPath, ErrMessage + " \n"); } /// /// Merge one array of strings into one string /// /// The array of strings /// The index from where the merge should start (included) /// A string built based on the array public static string MergeStrings(this string[] s, int indexToStart) { string r = ""; int len = s.Length; if (len <= indexToStart) return ""; for (int i = indexToStart; i < len - 1; ++i) { r += s[i] + " "; } r += s[len - 1]; return r; } /// /// Get the Operating system you are runnin on /// /// An Operating system public static OperatingSystem GetOperatingSystem() { if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows)) return OperatingSystem.WINDOWS; if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Linux)) return OperatingSystem.LINUX; if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.OSX)) return OperatingSystem.MAC_OS; return OperatingSystem.UNKNOWN; } public static List GetArguments(SocketMessage message) { Command command = new Command(message); return command.Arguments; } /// /// Copy one Stream to another /// /// The base stream /// The destination stream /// The buffer to read /// The progress /// The cancellation token /// Triggered if any is empty /// Triggered if is less then or equal to 0 /// Triggered if is not readable /// Triggered in is not writable public static async Task CopyToOtherStreamAsync(this Stream stream, Stream destination, int bufferSize, IProgress? progress = null, CancellationToken cancellationToken = default) { if (stream == null) throw new ArgumentNullException(nameof(stream)); if (destination == null) throw new ArgumentNullException(nameof(destination)); if (bufferSize <= 0) throw new ArgumentOutOfRangeException(nameof(bufferSize)); if (!stream.CanRead) throw new InvalidOperationException("The stream is not readable."); if (!destination.CanWrite) throw new ArgumentException("Destination stream is not writable", nameof(destination)); byte[] buffer = new byte[bufferSize]; long totalBytesRead = 0; int bytesRead; while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false)) != 0) { await destination.WriteAsync(buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false); totalBytesRead += bytesRead; progress?.Report(totalBytesRead); } } /// /// Extract zip to location /// /// The zip location /// The target location /// The progress that is updated as a file is processed /// The type of progress /// public static async Task ExtractArchive(string zip, string folder, IProgress progress, UnzipProgressType type) { if (!Directory.Exists(folder)) Directory.CreateDirectory(folder); using (ZipArchive archive = ZipFile.OpenRead(zip)) { if (type == UnzipProgressType.PercentageFromNumberOfFiles) { int totalZIPFiles = archive.Entries.Count(); int currentZIPFile = 0; foreach (ZipArchiveEntry entry in archive.Entries) { if (entry.FullName.EndsWith("/")) Directory.CreateDirectory(Path.Combine(folder, entry.FullName)); else try { entry.ExtractToFile(Path.Combine(folder, entry.FullName), true); } catch (Exception ex) { Console.WriteLine($"Failed to extract {entry.Name}. Exception: {ex.Message}"); } currentZIPFile++; await Task.Delay(10); progress.Report((float)currentZIPFile / totalZIPFiles * 100); } } else if (type == UnzipProgressType.PercentageFromTotalSize) { ulong zipSize = 0; foreach (ZipArchiveEntry entry in archive.Entries) zipSize += (ulong)entry.CompressedLength; ulong currentSize = 0; foreach (ZipArchiveEntry entry in archive.Entries) { if (entry.FullName.EndsWith("/")) { Directory.CreateDirectory(Path.Combine(folder, entry.FullName)); continue; } try { entry.ExtractToFile(Path.Combine(folder, entry.FullName), true); currentSize += (ulong)entry.CompressedLength; } catch (Exception ex) { Console.WriteLine($"Failed to extract {entry.Name}. Exception: {ex.Message}"); } await Task.Delay(10); progress.Report((float)currentSize / zipSize * 100); } } } } /// /// Convert Bytes to highest measurement unit possible /// /// The amount of bytes /// public static (double, string) ConvertBytes(long bytes) { List units = new List() { "B", "KB", "MB", "GB", "TB" }; int i = 0; while (bytes >= 1024) { i++; bytes /= 1024; } return (bytes, units[i]); } /// /// Save to JSON file /// /// The class type /// The file path /// The values /// public static async Task SaveToJsonFile(string file, T Data) { var s = File.OpenWrite(file); await JsonSerializer.SerializeAsync(s, Data, typeof(T), new JsonSerializerOptions { WriteIndented = true }); s.Close(); } /// /// Convert json text or file to some kind of data /// /// The data type /// The file or json text /// public static async Task ConvertFromJson(string input) { Stream text; if (File.Exists(input)) text = File.Open(input, FileMode.OpenOrCreate); else text = new MemoryStream(Encoding.ASCII.GetBytes(input)); text.Position = 0; var obj = await JsonSerializer.DeserializeAsync(text); text.Close(); return (obj ?? default)!; } /// /// Check if all words from are in
/// This function returns true if
/// 1. The is part of
/// 2. The words (split by a space) of are located (separately) in
/// /// The following example will return
/// STRContains("Hello World !", "I type word Hello and then i typed word World !")
/// The following example will return
/// STRContains("Hello World !", "I typed Hello World !"
/// The following example will return
/// STRContains("Hello World", "I type World then Hello")
/// The following example will return
/// STRContains("Hello World !", "I typed Hello World")
///
///
/// The string you are checking /// The main string that should contain /// public static bool STRContains(this string str, string baseString) { if (baseString.Contains(str)) return true; string[] array = str.Split(' '); foreach (var s in array) if (!baseString.Contains(s)) return false; return true; } public static bool TryReadValueFromJson(string input, string codeName, out JsonElement element) { Stream text; if (File.Exists(input)) text = File.OpenRead(input); else text = new MemoryStream(Encoding.ASCII.GetBytes(input)); var jsonObject = JsonDocument.Parse(text); var data = jsonObject.RootElement.TryGetProperty(codeName, out element); return data; } public static string CreateMD5(string input) { using (MD5 md5 = MD5.Create()) { byte[] inputBytes = Encoding.ASCII.GetBytes(input); byte[] hashBytes = md5.ComputeHash(inputBytes); return Convert.ToHexString(hashBytes); } } } }