Structure because structure

This commit is contained in:
Mira 2023-06-16 14:20:32 +02:00
parent 01d1ea3573
commit 2b2a53466f
Signed by untrusted user who does not match committer: Xorog
GPG key ID: 983798ED9C3E7C36
17 changed files with 693 additions and 674 deletions

38
Tools/ColorTools.cs Normal file
View file

@ -0,0 +1,38 @@
namespace Xorog.UniversalExtensions;
public static class ColorTools
{
/// <summary>
/// Get closest Color to given Color
/// </summary>
/// <param name="colorArray"></param>
/// <param name="baseColor"></param>
/// <returns></returns>
public static Color GetClosestColor(List<Color> colorArray, Color baseColor)
{
var colors = colorArray.Select(x => new { Value = x, Diff = Internal.GetDiff(x, baseColor) }).ToList();
var min = colors.Min(x => x.Diff);
return colors.Find(x => x.Diff == min).Value;
}
/// <summary>
/// Convert Hex to Color
/// </summary>
/// <returns>The converted color</returns>
public static Color ToColor(this string str)
{
return ColorTranslator.FromHtml(str);
}
/// <summary>
/// Convert RGB Value to Hex
/// </summary>
/// <param name="R">Red</param>
/// <param name="G">Green</param>
/// <param name="B">Blue</param>
/// <returns>A string that represents the color in hex (e.g. 255, 0, 0 -> #FF0000)</returns>
public static string ToHex(int R, int G, int B)
{
return "#" + R.ToString("X2") + G.ToString("X2") + B.ToString("X2");
}
}

20
Tools/MathTools.cs Normal file
View file

@ -0,0 +1,20 @@
namespace Xorog.UniversalExtensions;
public static class MathTools
{
/// <summary>
/// Calculates the percentage of the given 2 values.
/// </summary>
/// <param name="current">The current value.</param>
/// <param name="max">The maximum value.</param>
/// <returns>The percentage.</returns>
/// <exception cref="ArgumentException"></exception>
public static int CalculatePercentage(double current, double max)
{
if (max == 0)
throw new ArgumentException("Max cannot be zero.");
double percentage = (current / max) * 100;
return Convert.ToInt32(percentage);
}
}

34
Tools/StringTools.cs Normal file
View file

@ -0,0 +1,34 @@
namespace Xorog.UniversalExtensions;
public static class StringTools
{
/// <summary>
/// Generate an ASCII Progressbar
/// </summary>
/// <param name="current">The current progress</param>
/// <param name="max">The maximum progress</param>
/// <param name="charlength">How long the ASCII Progressbar should be (default: <code>44</code>)</param>
/// <param name="fill">What character the filled part should be (default: <code>█</code>)</param>
/// <param name="empty">What character the not-filled part should be (default: <code>∙</code>)</param>
/// <param name="start">What character the start-part should be (default: <code>[</code>)</param>
/// <param name="end">What character the end-part part should be (default: <code>]</code>)</param>
/// <returns>A progressbar</returns>
public static string GenerateASCIIProgressbar(double current, double max, int charlength = 44, char fill = '█', char empty = '∙', char start = '[', char end = ']')
{
long first = (long)Math.Round((current / max) * charlength, 0);
long second = charlength - first;
string mediadisplay = start.ToString();
for (long i = 0; i < first; i++)
mediadisplay += fill;
for (long i = 0; i < second; i++)
mediadisplay += empty;
mediadisplay += end;
return mediadisplay;
}
}

78
Tools/WebTools.cs Normal file
View file

@ -0,0 +1,78 @@
namespace Xorog.UniversalExtensions;
public static class WebTools
{
/// <summary>
/// Get the URL a redirect leads to (limited to StatusCodes 301, 303, 307, 308)
/// </summary>
/// <param name="url">The shortened URL</param>
/// <returns>The URL the redirect leads to</returns>
public static async Task<string> UnshortenUrl(string url, bool UseHeadMethod = true)
{
_logger?.LogDebug("Unshortening Url '{Url}', using head method: {UseHeadMethod}", url, UseHeadMethod);
HttpClient client = new(new HttpClientHandler()
{
AllowAutoRedirect = false,
AutomaticDecompression = DecompressionMethods.GZip,
});
client.Timeout = TimeSpan.FromSeconds(60);
client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36");
client.DefaultRequestHeaders.Add("upgrade-insecure-requests", "1");
client.DefaultRequestHeaders.Add("accept-encoding", "gzip, deflate, br");
client.DefaultRequestHeaders.Add("accept-language", "en-US,en;q=0.9");
client.MaxResponseContentBufferSize = 4096;
HttpRequestMessage requestMessage = new HttpRequestMessage((UseHeadMethod ? HttpMethod.Head : HttpMethod.Get), url);
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
var request_task = client.SendAsync(requestMessage, cancellationTokenSource.Token);
try
{
await request_task.WaitAsync(TimeSpan.FromSeconds(3));
}
catch (Exception)
{
if (UseHeadMethod)
return await UnshortenUrl(url, false);
throw;
}
if (!request_task.IsCompleted)
cancellationTokenSource.Cancel();
if (UseHeadMethod && request_task.IsFaulted && request_task.Exception.InnerException.GetType() == typeof(HttpRequestException))
{
_logger?.LogWarning("Unshortening Url '{Url}' failed, falling back to non-head method", url);
return await UnshortenUrl(url, false);
}
var statuscode = request_task.Result.StatusCode;
var header = request_task.Result.Headers;
if (UseHeadMethod && statuscode is HttpStatusCode.NotFound or HttpStatusCode.InternalServerError)
{
_logger?.LogWarning("Unshortening Url '{Url}' failed, falling back to non-head method", url);
return await UnshortenUrl(url, false);
}
if (statuscode is HttpStatusCode.Found
or HttpStatusCode.Redirect
or HttpStatusCode.SeeOther
or HttpStatusCode.RedirectKeepVerb
or HttpStatusCode.RedirectMethod
or HttpStatusCode.PermanentRedirect
or HttpStatusCode.TemporaryRedirect)
{
if (header is not null && header.Location is not null)
return await UnshortenUrl(header.Location.AbsoluteUri);
else
return url;
}
else
return url;
}
}

View file

@ -0,0 +1,33 @@
using System.Runtime.CompilerServices;
namespace Xorog.UniversalExtensions.WindowsAPI;
public class WindowsUtils
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static FileInfo? GetMainModuleFilepath(int pid)
{
var processHandle = kernel32.OpenProcess(0x0400 | 0x0010, false, pid);
if (processHandle == IntPtr.Zero)
return null;
const int lengthSb = 4000;
var sb = new StringBuilder(lengthSb);
string? result = null;
if (psapi.GetModuleFileNameEx(processHandle, IntPtr.Zero, sb, lengthSb) > 0)
{
result = Path.GetFullPath(sb.ToString());
}
kernel32.CloseHandle(processHandle);
if (result == null)
return null;
return new FileInfo(result);
}
}

View file

@ -0,0 +1,25 @@
using System.Runtime.InteropServices;
namespace Xorog.UniversalExtensions.WindowsAPI;
public class kernel32
{
/// <summary>
/// Opens an existing local process object.
/// </summary>
/// <param name="processAccess">The access to the process object. This access right is checked against the security descriptor for the process. This parameter can be one or more of the process access rights.</param>
/// <param name="bInheritHandle">If this value is TRUE, processes created by this process will inherit the handle. Otherwise, the processes do not inherit this handle.</param>
/// <param name="processId">The identifier of the local process to be opened.</param>
/// <returns>If the function succeeds, the return value is an open handle to the specified process. If the function fails, the return value is NULL.</returns>
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processId);
/// <summary>
/// Closes an open object handle.
/// </summary>
/// <param name="hObject">A valid handle to an open object.</param>
/// <returns>If the function succeeds, the return value is true.</returns>
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CloseHandle(IntPtr hObject);
}

10
Tools/WindowsAPI/psapi.cs Normal file
View file

@ -0,0 +1,10 @@
using System.Runtime.InteropServices;
namespace Xorog.UniversalExtensions.WindowsAPI;
#pragma warning disable CS8981 // The type name only contains lower-cased ascii characters. Such names may become reserved for the language.
public class psapi
{
[DllImport("psapi.dll")]
public static extern uint GetModuleFileNameEx(IntPtr hProcess, IntPtr hModule, [Out] StringBuilder lpBaseName, [In][MarshalAs(UnmanagedType.U4)] int nSize);
}