mirror of
https://github.com/PluralKit/PluralKit.git
synced 2026-02-04 13:06:50 +00:00
60 lines
No EOL
2.3 KiB
C#
60 lines
No EOL
2.3 KiB
C#
using System.Text.RegularExpressions;
|
|
|
|
namespace PluralKit.Core;
|
|
|
|
public static class MiscUtils
|
|
{
|
|
|
|
// discord mediaproxy URLs used to be stored directly in the database, so now we cleanup image urls before using them outside of proxying
|
|
private static readonly Regex MediaProxyUrl =
|
|
new(
|
|
@"^https?://media.discordapp.net/attachments/(\d{17,19})/(\d{17,19})/([^/\\&\?]+)\.(png|jpg|jpeg|webp)(\?.*)?$");
|
|
|
|
private static readonly string DiscordCdnReplacement = "https://cdn.discordapp.com/attachments/$1/$2/$3.$4";
|
|
|
|
// Rewrite time "cachebuster" parameters for randomly generated/chosen avatars with custom URLs.
|
|
private static readonly Regex TimePlaceholder = new(@"\{(time(?:stamp|_(?:1m|5m|30m|1h|6h|1d)))\}");
|
|
private const Int64 TimeAccuracy = 60;
|
|
|
|
public static bool TryMatchUri(string input, out Uri uri)
|
|
{
|
|
if (input.StartsWith('<') && input.EndsWith('>'))
|
|
input = input[1..^1];
|
|
|
|
try
|
|
{
|
|
uri = new Uri(input);
|
|
if (!uri.IsAbsoluteUri || uri.Scheme != "https")
|
|
return false;
|
|
}
|
|
catch (UriFormatException)
|
|
{
|
|
uri = null;
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public static string? TryGetCleanCdnUrl(this string? url) =>
|
|
url == null ? null : TimePlaceholder.Replace(MediaProxyUrl.Replace(url, DiscordCdnReplacement), ProcessTimePlaceholder);
|
|
|
|
private static string? ProcessTimePlaceholder(Match m) {
|
|
// Limit maximum accuracy to avoid too much cache thrashing, multiply for standard-ish Unix time
|
|
// AND with the maximum positive value so it's always positive (as if this code will exist long enough for the 64-bit signed unix time to go negative...)
|
|
var time = ((DateTimeOffset.UtcNow.ToUnixTimeSeconds()/TimeAccuracy)*TimeAccuracy)&Int64.MaxValue;
|
|
|
|
switch (m.Groups[1].Value) {
|
|
case "timestamp": break;
|
|
case "time_1m": time /= 60; break;
|
|
case "time_5m": time /= 60*5; break;
|
|
case "time_30m": time /= 60*30; break;
|
|
case "time_1h": time /= 60*60; break;
|
|
case "time_6h": time /= 6*60*60; break;
|
|
case "time_1d": time /= 24*60*60; break;
|
|
}
|
|
|
|
return time.ToString();
|
|
}
|
|
|
|
} |