Structure because structure
This commit is contained in:
parent
01d1ea3573
commit
2b2a53466f
17 changed files with 693 additions and 674 deletions
38
Tools/ColorTools.cs
Normal file
38
Tools/ColorTools.cs
Normal 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
20
Tools/MathTools.cs
Normal 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
34
Tools/StringTools.cs
Normal 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
78
Tools/WebTools.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
33
Tools/WindowsAPI/WindowsUtils.cs
Normal file
33
Tools/WindowsAPI/WindowsUtils.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
25
Tools/WindowsAPI/kernel32.cs
Normal file
25
Tools/WindowsAPI/kernel32.cs
Normal 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
10
Tools/WindowsAPI/psapi.cs
Normal 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);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue