using System.IO.Compression; using System.IO; using System; using System.Threading.Tasks; using System.Linq; using System.Collections.Generic; using Discord.WebSocket; using PluginManager.Items; using System.Threading; 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/"; /// /// The location for all languages /// public static readonly string langFolder = @"./Data/Languages/"; /// /// Archives folder /// public static readonly string pakFolder = @"./Data/Resources/PAKS/"; /// /// The mark that the line is a comment /// private static readonly char commentMark = '#'; /// /// Read data from file /// /// File name /// Setting name /// Separator between setting key code and its value /// The value of the specified setting key code in the specified file () public static string? readCodeFromFile(string fileName, string Code, char separator) => File.ReadAllLines(fileName) .Where(p => p.StartsWith(Code) && !p.StartsWith(commentMark.ToString())) .First().Split(separator)[1] ?? null; /// /// 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 !"); string? 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 = await reader.ReadToEndAsync(); 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 + "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 + "Error.txt"; if (!Directory.Exists(errFolder)) Directory.CreateDirectory(errFolder); File.AppendAllText(errPath, ErrMessage + " \n"); } /// /// Write to settings file /// /// The settings file path /// The Key value of the setting /// The new value of the settings /// The separator between the key and the value public static void WriteToSettings(string file, string Code, string newValue, char separator) { string[] lines = File.ReadAllLines(file); File.Delete(file); bool ok = false; foreach (var line in lines) if (line.StartsWith(Code)) { File.AppendAllText(file, Code + separator + newValue + "\n"); ok = true; } else File.AppendAllText(file, line + "\n"); if (!ok) File.AppendAllText(file, Code + separator + newValue + "\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; } /// /// Write setting /// /// The full path to the setting /// The new Value public static void WriteToSettingsFast(string SettingName, string NewValue) { string path = dataFolder; // Resources/ string[] args = SettingName.Split('.'); int len = args.Length; if (len < 2) return; for (int i = 0; i < len - 2; i++) path += args[i] + "/"; path += args[len - 2] + ".txt"; WriteToSettings(path, args[len - 1].Replace('_', ' '), NewValue, '='); } /// /// 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); } } } }