Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
457
Scripts/SubSystem/VitaNex/Core/Extensions/System/ChronExt.cs
Normal file
457
Scripts/SubSystem/VitaNex/Core/Extensions/System/ChronExt.cs
Normal file
@@ -0,0 +1,457 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System.Text;
|
||||
|
||||
using VitaNex;
|
||||
using VitaNex.Collections;
|
||||
#endregion
|
||||
|
||||
namespace System
|
||||
{
|
||||
[Flags]
|
||||
public enum Months
|
||||
{
|
||||
None = 0x000,
|
||||
January = 0x001,
|
||||
Febuary = 0x002,
|
||||
March = 0x004,
|
||||
April = 0x008,
|
||||
May = 0x010,
|
||||
June = 0x020,
|
||||
July = 0x040,
|
||||
August = 0x080,
|
||||
September = 0x100,
|
||||
October = 0x200,
|
||||
November = 0x400,
|
||||
December = 0x800,
|
||||
|
||||
All = ~None
|
||||
}
|
||||
|
||||
public enum TimeUnit
|
||||
{
|
||||
Years,
|
||||
Months,
|
||||
Weeks,
|
||||
Days,
|
||||
Hours,
|
||||
Minutes,
|
||||
Seconds,
|
||||
Milliseconds
|
||||
}
|
||||
|
||||
public static class ChronExtUtility
|
||||
{
|
||||
public static bool InRange(this TimeSpan now, TimeSpan start, TimeSpan end)
|
||||
{
|
||||
if (start <= end)
|
||||
{
|
||||
return now >= start && now <= end;
|
||||
}
|
||||
|
||||
return now >= start || now <= end;
|
||||
}
|
||||
|
||||
public static bool InRange(this DateTime now, DateTime start, DateTime end)
|
||||
{
|
||||
if (now.Year < end.Year)
|
||||
{
|
||||
return now >= start;
|
||||
}
|
||||
|
||||
if (now.Year > start.Year)
|
||||
{
|
||||
return now <= end;
|
||||
}
|
||||
|
||||
return now >= start && now <= end;
|
||||
}
|
||||
|
||||
public static double GetTotal(this TimeSpan time, TimeUnit unit)
|
||||
{
|
||||
var total = (double)time.Ticks;
|
||||
|
||||
switch (unit)
|
||||
{
|
||||
case TimeUnit.Years:
|
||||
total = time.TotalDays / 365.2422;
|
||||
break;
|
||||
case TimeUnit.Months:
|
||||
total = time.TotalDays / 30.43685;
|
||||
break;
|
||||
case TimeUnit.Weeks:
|
||||
total = time.TotalDays / 7.0;
|
||||
break;
|
||||
case TimeUnit.Days:
|
||||
total = time.TotalDays;
|
||||
break;
|
||||
case TimeUnit.Hours:
|
||||
total = time.TotalHours;
|
||||
break;
|
||||
case TimeUnit.Minutes:
|
||||
total = time.TotalMinutes;
|
||||
break;
|
||||
case TimeUnit.Seconds:
|
||||
total = time.TotalSeconds;
|
||||
break;
|
||||
case TimeUnit.Milliseconds:
|
||||
total = time.TotalMilliseconds;
|
||||
break;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
public static DateTime Interpolate(this DateTime start, DateTime end, double percent)
|
||||
{
|
||||
return new DateTime((long)(start.Ticks + ((end.Ticks - start.Ticks) * percent)));
|
||||
}
|
||||
|
||||
public static TimeSpan Interpolate(this TimeSpan start, TimeSpan end, double percent)
|
||||
{
|
||||
return new TimeSpan((long)(start.Ticks + ((end.Ticks - start.Ticks) * percent)));
|
||||
}
|
||||
|
||||
public static TimeStamp Interpolate(this TimeStamp start, TimeStamp end, double percent)
|
||||
{
|
||||
return new TimeStamp((long)(start.Ticks + ((end.Ticks - start.Ticks) * percent)));
|
||||
}
|
||||
|
||||
public static TimeStamp ToTimeStamp(this DateTime date)
|
||||
{
|
||||
return new TimeStamp(date);
|
||||
}
|
||||
|
||||
public static Months GetMonth(this DateTime date)
|
||||
{
|
||||
switch (date.Month)
|
||||
{
|
||||
case 1:
|
||||
return Months.January;
|
||||
case 2:
|
||||
return Months.Febuary;
|
||||
case 3:
|
||||
return Months.March;
|
||||
case 4:
|
||||
return Months.April;
|
||||
case 5:
|
||||
return Months.May;
|
||||
case 6:
|
||||
return Months.June;
|
||||
case 7:
|
||||
return Months.July;
|
||||
case 8:
|
||||
return Months.August;
|
||||
case 9:
|
||||
return Months.September;
|
||||
case 10:
|
||||
return Months.October;
|
||||
case 11:
|
||||
return Months.November;
|
||||
case 12:
|
||||
return Months.December;
|
||||
default:
|
||||
return Months.None;
|
||||
}
|
||||
}
|
||||
|
||||
public static string ToSimpleString(this TimeZoneInfo tzo, bool dst)
|
||||
{
|
||||
var build = ObjectPool<StringBuilder>.AcquireObject();
|
||||
|
||||
if (tzo.Id == "UTC")
|
||||
{
|
||||
return tzo.Id;
|
||||
}
|
||||
|
||||
string value;
|
||||
|
||||
if (dst)
|
||||
{
|
||||
value = tzo.DaylightName.Replace("Daylight Time", String.Empty);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = tzo.StandardName.Replace("Standard Time", String.Empty);
|
||||
}
|
||||
|
||||
foreach (var c in value)
|
||||
{
|
||||
if (!Char.IsWhiteSpace(c) && Char.IsLetter(c) && Char.IsUpper(c))
|
||||
{
|
||||
build.Append(c);
|
||||
}
|
||||
}
|
||||
|
||||
build.Append(dst ? "-DT" : "-ST");
|
||||
|
||||
value = build.ToString();
|
||||
|
||||
ObjectPool.Free(ref build);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static string ToSimpleString(this DateTime date, string format = "t D d M y")
|
||||
{
|
||||
var build = ObjectPool<StringBuilder>.AcquireObject();
|
||||
|
||||
build.EnsureCapacity(format.Length * 2);
|
||||
|
||||
var noformat = false;
|
||||
|
||||
for (var i = 0; i < format.Length; i++)
|
||||
{
|
||||
if (format[i] == '#')
|
||||
{
|
||||
noformat = !noformat;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (noformat)
|
||||
{
|
||||
build.Append(format[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (format[i])
|
||||
{
|
||||
case '\\':
|
||||
build.Append((i + 1 < format.Length) ? Convert.ToString(format[++i]) : String.Empty);
|
||||
break;
|
||||
case 'x':
|
||||
case 'z':
|
||||
{
|
||||
var utc = date.Kind == DateTimeKind.Utc;
|
||||
var tzo = utc ? TimeZoneInfo.Utc : TimeZoneInfo.Local;
|
||||
|
||||
build.Append(ToSimpleString(tzo, false));
|
||||
}
|
||||
break;
|
||||
case 'X':
|
||||
case 'Z':
|
||||
{
|
||||
var utc = date.Kind == DateTimeKind.Utc;
|
||||
var tzo = utc ? TimeZoneInfo.Utc : TimeZoneInfo.Local;
|
||||
|
||||
build.Append(ToSimpleString(tzo, date.IsDaylightSavingTime()));
|
||||
}
|
||||
break;
|
||||
case 'D':
|
||||
build.Append(date.DayOfWeek);
|
||||
break;
|
||||
case 'd':
|
||||
build.Append(date.Day);
|
||||
break;
|
||||
case 'M':
|
||||
build.Append(GetMonth(date));
|
||||
break;
|
||||
case 'm':
|
||||
build.Append(date.Month);
|
||||
break;
|
||||
case 'y':
|
||||
build.Append(date.Year);
|
||||
break;
|
||||
case 't':
|
||||
{
|
||||
var tf = String.Empty;
|
||||
|
||||
if (i + 1 < format.Length)
|
||||
{
|
||||
if (format[i + 1] == '@')
|
||||
{
|
||||
++i;
|
||||
|
||||
while (++i < format.Length && format[i] != '@')
|
||||
{
|
||||
tf += format[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
build.Append(ToSimpleString(date.TimeOfDay, !String.IsNullOrWhiteSpace(tf) ? tf : "h-m-s"));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
build.Append(format[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var value = build.ToString();
|
||||
|
||||
ObjectPool.Free(ref build);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static string ToSimpleString(this TimeSpan time, string format = "h-m-s")
|
||||
{
|
||||
var build = ObjectPool<StringBuilder>.AcquireObject();
|
||||
|
||||
build.EnsureCapacity(format.Length * 2);
|
||||
|
||||
var noformat = false;
|
||||
var nopadding = false;
|
||||
var zeroValue = false;
|
||||
var zeroEmpty = 0;
|
||||
|
||||
string fFormat, dFormat;
|
||||
object append;
|
||||
|
||||
for (var i = 0; i < format.Length; i++)
|
||||
{
|
||||
if (format[i] == '#')
|
||||
{
|
||||
noformat = !noformat;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (noformat)
|
||||
{
|
||||
build.Append(format[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (format[i])
|
||||
{
|
||||
case '!':
|
||||
nopadding = !nopadding;
|
||||
continue;
|
||||
}
|
||||
|
||||
fFormat = zeroEmpty > 0 ? (nopadding ? "{0:#.#}" : "{0:#.##}") : (nopadding ? "{0:0.#}" : "{0:0.##}");
|
||||
dFormat = zeroEmpty > 0 ? (nopadding ? "{0:#}" : "{0:##}") : (nopadding ? "{0:0}" : "{0:00}");
|
||||
|
||||
append = null;
|
||||
|
||||
switch (format[i])
|
||||
{
|
||||
case '<':
|
||||
++zeroEmpty;
|
||||
break;
|
||||
case '>':
|
||||
{
|
||||
if (zeroEmpty == 0 || (zeroEmpty > 0 && --zeroEmpty == 0))
|
||||
{
|
||||
zeroValue = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '\\':
|
||||
{
|
||||
if (i + 1 < format.Length)
|
||||
{
|
||||
append = format[++i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'x':
|
||||
append = ToSimpleString(TimeZoneInfo.Utc, false);
|
||||
break;
|
||||
case 'X':
|
||||
append = ToSimpleString(TimeZoneInfo.Utc, DateTime.UtcNow.IsDaylightSavingTime());
|
||||
break;
|
||||
case 'z':
|
||||
append = ToSimpleString(TimeZoneInfo.Local, false);
|
||||
break;
|
||||
case 'Z':
|
||||
append = ToSimpleString(TimeZoneInfo.Local, DateTime.Now.IsDaylightSavingTime());
|
||||
break;
|
||||
case 'D':
|
||||
{
|
||||
append = String.Format(fFormat, time.TotalDays);
|
||||
zeroValue = String.IsNullOrWhiteSpace((string)append);
|
||||
}
|
||||
break;
|
||||
case 'H':
|
||||
{
|
||||
append = String.Format(fFormat, time.TotalHours);
|
||||
zeroValue = String.IsNullOrWhiteSpace((string)append);
|
||||
}
|
||||
break;
|
||||
case 'M':
|
||||
{
|
||||
append = String.Format(fFormat, time.TotalMinutes);
|
||||
zeroValue = String.IsNullOrWhiteSpace((string)append);
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
{
|
||||
append = String.Format(fFormat, time.TotalSeconds);
|
||||
zeroValue = String.IsNullOrWhiteSpace((string)append);
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
{
|
||||
append = String.Format(dFormat, time.Days);
|
||||
zeroValue = String.IsNullOrWhiteSpace((string)append);
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
{
|
||||
append = String.Format(dFormat, time.Hours);
|
||||
zeroValue = String.IsNullOrWhiteSpace((string)append);
|
||||
}
|
||||
break;
|
||||
case 'm':
|
||||
{
|
||||
append = String.Format(dFormat, time.Minutes);
|
||||
zeroValue = String.IsNullOrWhiteSpace((string)append);
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
{
|
||||
append = String.Format(dFormat, time.Seconds);
|
||||
zeroValue = String.IsNullOrWhiteSpace((string)append);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
append = format[i];
|
||||
break;
|
||||
}
|
||||
|
||||
if (append != null && (!zeroValue || zeroEmpty <= 0))
|
||||
{
|
||||
build.Append(append);
|
||||
}
|
||||
}
|
||||
|
||||
var value = build.ToString();
|
||||
|
||||
ObjectPool.Free(ref build);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static string ToDirectoryName(this DateTime date, string format = "D d M y")
|
||||
{
|
||||
return ToSimpleString(date, format);
|
||||
}
|
||||
|
||||
public static string ToFileName(this DateTime date, string format = "D d M y")
|
||||
{
|
||||
return ToSimpleString(date, format);
|
||||
}
|
||||
|
||||
public static string ToDirectoryName(this TimeSpan time, string format = "h-m")
|
||||
{
|
||||
return ToSimpleString(time, format);
|
||||
}
|
||||
|
||||
public static string ToFileName(this TimeSpan time, string format = "h-m")
|
||||
{
|
||||
return ToSimpleString(time, format);
|
||||
}
|
||||
}
|
||||
}
|
||||
105
Scripts/SubSystem/VitaNex/Core/Extensions/System/ColorExt.cs
Normal file
105
Scripts/SubSystem/VitaNex/Core/Extensions/System/ColorExt.cs
Normal file
@@ -0,0 +1,105 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System.Drawing;
|
||||
|
||||
using VitaNex;
|
||||
#endregion
|
||||
|
||||
namespace System
|
||||
{
|
||||
public static class ColorExtUtility
|
||||
{
|
||||
public static Color ToColor(this KnownColor color)
|
||||
{
|
||||
return Color.FromKnownColor(color);
|
||||
}
|
||||
|
||||
public static Color555 ToColor555(this Color value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public static ushort ToArgb555(this Color value)
|
||||
{
|
||||
return ToColor555(value);
|
||||
}
|
||||
|
||||
public static int ToRgb(this Color value)
|
||||
{
|
||||
return value.ToArgb() & 0x00FFFFFF;
|
||||
}
|
||||
|
||||
public static Color Interpolate(this Color source, Color target, double percent)
|
||||
{
|
||||
if (percent <= 0.0)
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
if (percent >= 1.0)
|
||||
{
|
||||
return target;
|
||||
}
|
||||
|
||||
var r = (int)(source.R + (target.R - source.R) * percent);
|
||||
var g = (int)(source.G + (target.G - source.G) * percent);
|
||||
var b = (int)(source.B + (target.B - source.B) * percent);
|
||||
|
||||
return Color.FromArgb(255, r, g, b);
|
||||
}
|
||||
|
||||
public static Color FixBlackTransparency(this Color source)
|
||||
{
|
||||
if (source.IsEmpty || source.A <= 0 || source.R >= 0x08 || source.G >= 0x08 || source.B >= 0x08)
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
var r = source.R;
|
||||
var g = source.G;
|
||||
var b = source.B;
|
||||
|
||||
if (r != g || r != b)
|
||||
{
|
||||
var rd = 0x08 - r;
|
||||
var gd = 0x08 - g;
|
||||
var bd = 0x08 - b;
|
||||
|
||||
if (rd < gd && rd < bd)
|
||||
{
|
||||
r = 0x08;
|
||||
}
|
||||
else if (gd < rd && gd < bd)
|
||||
{
|
||||
g = 0x08;
|
||||
}
|
||||
else if (bd < rd && bd < gd)
|
||||
{
|
||||
b = 0x08;
|
||||
}
|
||||
else
|
||||
{
|
||||
r = g = b = 0x08;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
r = g = b = 0x08;
|
||||
}
|
||||
|
||||
source = Color.FromArgb(source.A, r, g, b);
|
||||
|
||||
return source;
|
||||
}
|
||||
}
|
||||
}
|
||||
396
Scripts/SubSystem/VitaNex/Core/Extensions/System/EnumExt.cs
Normal file
396
Scripts/SubSystem/VitaNex/Core/Extensions/System/EnumExt.cs
Normal file
@@ -0,0 +1,396 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace System
|
||||
{
|
||||
public static class EnumExtUtility
|
||||
{
|
||||
public static string ToString(this Enum e, bool friendly)
|
||||
{
|
||||
return friendly ? GetFriendlyName(e) : GetName(e);
|
||||
}
|
||||
|
||||
public static string GetName(this Enum e)
|
||||
{
|
||||
return EnumCache.GetName(e);
|
||||
}
|
||||
|
||||
public static string GetFriendlyName(this Enum e)
|
||||
{
|
||||
return EnumCache.GetFriendlyName(e);
|
||||
}
|
||||
|
||||
public static string GetDescription(this Enum e)
|
||||
{
|
||||
return EnumCache.GetDescription(e);
|
||||
}
|
||||
|
||||
public static T GetAttribute<T>(this Enum e) where T : Attribute
|
||||
{
|
||||
return GetAttributes<T>(e).FirstOrDefault();
|
||||
}
|
||||
|
||||
public static IEnumerable<T> GetAttributes<T>(this Enum e) where T : Attribute
|
||||
{
|
||||
var type = e.GetType();
|
||||
var info = type.GetMember(e.ToString());
|
||||
|
||||
if (info.IsNullOrEmpty() || info[0] == null)
|
||||
{
|
||||
return Enumerable.Empty<T>();
|
||||
}
|
||||
|
||||
var attributes = info[0].GetCustomAttributes(typeof(T), false);
|
||||
|
||||
if (attributes.IsNullOrEmpty())
|
||||
{
|
||||
return Enumerable.Empty<T>();
|
||||
}
|
||||
|
||||
return attributes.OfType<T>();
|
||||
}
|
||||
|
||||
public static TEnum Normalize<TEnum>(this Enum e)
|
||||
#if MONO
|
||||
where TEnum : struct, IComparable, IFormattable, IConvertible
|
||||
#else
|
||||
where TEnum : struct, Enum
|
||||
#endif
|
||||
{
|
||||
var type = typeof(TEnum);
|
||||
var flag = default(TEnum);
|
||||
|
||||
if (!type.IsEnum)
|
||||
{
|
||||
return flag;
|
||||
}
|
||||
|
||||
if (!Enum.TryParse(e.ToString(), out flag) || (!type.HasCustomAttribute<FlagsAttribute>(true) && !Enum.IsDefined(type, flag)))
|
||||
{
|
||||
flag = default(TEnum);
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
public static bool IsValid(this Enum e)
|
||||
{
|
||||
return Enum.IsDefined(e.GetType(), e);
|
||||
}
|
||||
|
||||
public static TCast[] Split<TCast>(this Enum e) where TCast : IConvertible
|
||||
{
|
||||
return GetValues<TCast>(e, true);
|
||||
}
|
||||
|
||||
public static TCast[] GetValues<TCast>(this Enum e) where TCast : IConvertible
|
||||
{
|
||||
return GetValues<TCast>(e, false);
|
||||
}
|
||||
|
||||
public static TCast[] GetValues<TCast>(this Enum e, bool local) where TCast : IConvertible
|
||||
{
|
||||
return EnumerateValues<TCast>(e, local).ToArray();
|
||||
}
|
||||
|
||||
public static TCast[] GetAbsoluteValues<TCast>(this Enum e) where TCast : IConvertible
|
||||
{
|
||||
return GetAbsoluteValues<TCast>(e, false);
|
||||
}
|
||||
|
||||
public static TCast[] GetAbsoluteValues<TCast>(this Enum e, bool local) where TCast : IConvertible
|
||||
{
|
||||
return EnumerateAbsoluteValues<TCast>(e, local).ToArray();
|
||||
}
|
||||
|
||||
public static IEnumerable<TCast> EnumerateAbsoluteValues<TCast>(this Enum e) where TCast : IConvertible
|
||||
{
|
||||
return EnumerateAbsoluteValues<TCast>(e, false);
|
||||
}
|
||||
|
||||
public static IEnumerable<TCast> EnumerateAbsoluteValues<TCast>(this Enum e, bool local) where TCast : IConvertible
|
||||
{
|
||||
return EnumerateValues<TCast>(e, local).Where(o => !Equals(o, 0) && !Equals(o, String.Empty)).ToArray();
|
||||
}
|
||||
|
||||
public static IEnumerable<TCast> EnumerateValues<TCast>(this Enum e) where TCast : IConvertible
|
||||
{
|
||||
return EnumerateValues<TCast>(e, false);
|
||||
}
|
||||
|
||||
public static IEnumerable<TCast> EnumerateValues<TCast>(this Enum e, bool local) where TCast : IConvertible
|
||||
{
|
||||
var eType = e.GetType();
|
||||
var vType = typeof(TCast);
|
||||
var vals = EnumCache.EnumerateValues(eType);
|
||||
|
||||
if (local)
|
||||
{
|
||||
vals = vals.Where(e.HasFlag);
|
||||
}
|
||||
|
||||
if (vType.IsEqual(typeof(char)))
|
||||
{
|
||||
return vals.Select(Convert.ToChar).Cast<TCast>();
|
||||
}
|
||||
|
||||
if (vType.IsEqual(typeof(sbyte)))
|
||||
{
|
||||
return vals.Select(Convert.ToSByte).Cast<TCast>();
|
||||
}
|
||||
|
||||
if (vType.IsEqual(typeof(byte)))
|
||||
{
|
||||
return vals.Select(Convert.ToByte).Cast<TCast>();
|
||||
}
|
||||
|
||||
if (vType.IsEqual(typeof(short)))
|
||||
{
|
||||
return vals.Select(Convert.ToInt16).Cast<TCast>();
|
||||
}
|
||||
|
||||
if (vType.IsEqual(typeof(ushort)))
|
||||
{
|
||||
return vals.Select(Convert.ToUInt16).Cast<TCast>();
|
||||
}
|
||||
|
||||
if (vType.IsEqual(typeof(int)))
|
||||
{
|
||||
return vals.Select(Convert.ToInt32).Cast<TCast>();
|
||||
}
|
||||
|
||||
if (vType.IsEqual(typeof(uint)))
|
||||
{
|
||||
return vals.Select(Convert.ToUInt32).Cast<TCast>();
|
||||
}
|
||||
|
||||
if (vType.IsEqual(typeof(long)))
|
||||
{
|
||||
return vals.Select(Convert.ToInt64).Cast<TCast>();
|
||||
}
|
||||
|
||||
if (vType.IsEqual(typeof(ulong)))
|
||||
{
|
||||
return vals.Select(Convert.ToUInt64).Cast<TCast>();
|
||||
}
|
||||
|
||||
if (vType.IsEqual(typeof(string)))
|
||||
{
|
||||
return vals.Select(Convert.ToString).Cast<TCast>();
|
||||
}
|
||||
|
||||
return vals.Cast<TCast>();
|
||||
}
|
||||
|
||||
public static bool AnyFlags<TEnum>(this Enum e, IEnumerable<TEnum> flags)
|
||||
#if MONO
|
||||
where TEnum : struct, IComparable, IFormattable, IConvertible
|
||||
#else
|
||||
where TEnum : struct, Enum
|
||||
#endif
|
||||
{
|
||||
if (!e.GetType().HasCustomAttribute<FlagsAttribute>(true))
|
||||
{
|
||||
return flags != null && flags.Any(o => Equals(e, o));
|
||||
}
|
||||
|
||||
return flags != null && flags.Cast<Enum>().Any(e.HasFlag);
|
||||
}
|
||||
|
||||
public static bool AnyFlags<TEnum>(this Enum e, params TEnum[] flags)
|
||||
#if MONO
|
||||
where TEnum : struct, IComparable, IFormattable, IConvertible
|
||||
#else
|
||||
where TEnum : struct, Enum
|
||||
#endif
|
||||
{
|
||||
if (!e.GetType().HasCustomAttribute<FlagsAttribute>(true))
|
||||
{
|
||||
return flags != null && flags.Any(o => Equals(e, o));
|
||||
}
|
||||
|
||||
return flags != null && flags.Cast<Enum>().Any(e.HasFlag);
|
||||
}
|
||||
|
||||
public static bool AllFlags<TEnum>(this Enum e, IEnumerable<TEnum> flags)
|
||||
#if MONO
|
||||
where TEnum : struct, IComparable, IFormattable, IConvertible
|
||||
#else
|
||||
where TEnum : struct, Enum
|
||||
#endif
|
||||
{
|
||||
if (!e.GetType().HasCustomAttribute<FlagsAttribute>(true))
|
||||
{
|
||||
return flags != null && flags.All(o => Equals(e, o));
|
||||
}
|
||||
|
||||
return flags != null && flags.Cast<Enum>().All(e.HasFlag);
|
||||
}
|
||||
|
||||
public static bool AllFlags<TEnum>(this Enum e, params TEnum[] flags)
|
||||
#if MONO
|
||||
where TEnum : struct, IComparable, IFormattable, IConvertible
|
||||
#else
|
||||
where TEnum : struct, Enum
|
||||
#endif
|
||||
{
|
||||
if (!e.GetType().HasCustomAttribute<FlagsAttribute>(true))
|
||||
{
|
||||
return flags != null && flags.All(o => Equals(e, o));
|
||||
}
|
||||
|
||||
return flags != null && flags.Cast<Enum>().All(e.HasFlag);
|
||||
}
|
||||
|
||||
private static class EnumCache
|
||||
{
|
||||
public class Entry
|
||||
{
|
||||
public readonly Enum[] Values;
|
||||
public readonly string[] Names, FriendlyNames, Descriptions;
|
||||
|
||||
public Entry(Type type)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
Values = new Enum[0];
|
||||
Names = new string[0];
|
||||
FriendlyNames = new string[0];
|
||||
Descriptions = new string[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
Values = Enum.GetValues(type).CastToArray<Enum>();
|
||||
Names = Enum.GetNames(type);
|
||||
|
||||
FriendlyNames = new string[Names.Length];
|
||||
Descriptions = new string[Names.Length];
|
||||
|
||||
for (var i = 0; i < Values.Length; i++)
|
||||
{
|
||||
FriendlyNames[i] = Names[i].SpaceWords();
|
||||
Descriptions[i] = String.Join("\n", GetAttributes<DescriptionAttribute>(Values[i]).Where(o => !String.IsNullOrWhiteSpace(o.Description)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly Entry _Empty = new Entry(null);
|
||||
|
||||
private static readonly Dictionary<Type, Entry> _Cache = new Dictionary<Type, Entry>();
|
||||
|
||||
public static Entry Lookup(Type type)
|
||||
{
|
||||
if (type == null || !type.IsEnum)
|
||||
{
|
||||
return _Empty;
|
||||
}
|
||||
|
||||
if (!_Cache.TryGetValue(type, out var result))
|
||||
{
|
||||
_Cache[type] = result = new Entry(type);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static string[] GetNames(Type type)
|
||||
{
|
||||
return Lookup(type).Names;
|
||||
}
|
||||
|
||||
public static Enum[] GetValues(Type type)
|
||||
{
|
||||
return Lookup(type).Values;
|
||||
}
|
||||
|
||||
public static string[] GetDescriptions(Type type)
|
||||
{
|
||||
return Lookup(type).Descriptions;
|
||||
}
|
||||
|
||||
public static IEnumerable<string> EnumerateNames(Type type)
|
||||
{
|
||||
return GetNames(type);
|
||||
}
|
||||
|
||||
public static IEnumerable<Enum> EnumerateValues(Type type)
|
||||
{
|
||||
return GetValues(type);
|
||||
}
|
||||
|
||||
public static IEnumerable<string> EnumerateDescriptions(Type type)
|
||||
{
|
||||
return GetDescriptions(type);
|
||||
}
|
||||
|
||||
public static string GetName(Enum e)
|
||||
{
|
||||
var type = e.GetType();
|
||||
var entry = Lookup(type);
|
||||
|
||||
var index = Array.IndexOf(entry.Values, e);
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
return entry.Names[index];
|
||||
}
|
||||
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
public static string GetFriendlyName(Enum e)
|
||||
{
|
||||
var type = e.GetType();
|
||||
var entry = Lookup(type);
|
||||
|
||||
var index = Array.IndexOf(entry.Values, e);
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
return entry.FriendlyNames[index];
|
||||
}
|
||||
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
public static string GetDescription(Enum e)
|
||||
{
|
||||
var type = e.GetType();
|
||||
var entry = Lookup(type);
|
||||
|
||||
var index = Array.IndexOf(entry.Values, e);
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
return entry.Descriptions[index];
|
||||
}
|
||||
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
public static int GetIndex(Enum e)
|
||||
{
|
||||
var type = e.GetType();
|
||||
var entry = Lookup(type);
|
||||
|
||||
return Array.IndexOf(entry.Values, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2607
Scripts/SubSystem/VitaNex/Core/Extensions/System/EnumerableExt.cs
Normal file
2607
Scripts/SubSystem/VitaNex/Core/Extensions/System/EnumerableExt.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,61 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System.IO;
|
||||
|
||||
using Server;
|
||||
|
||||
using VitaNex;
|
||||
#endregion
|
||||
|
||||
namespace System
|
||||
{
|
||||
public static class ExceptionExtUtility
|
||||
{
|
||||
public static void ToConsole(this Exception e, bool simple = false, bool log = false)
|
||||
{
|
||||
if (e == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lock (VitaNexCore.ConsoleLock)
|
||||
{
|
||||
Utility.PushColor(ConsoleColor.Red);
|
||||
Console.WriteLine(simple ? e.Message : e.ToString());
|
||||
Utility.PopColor();
|
||||
}
|
||||
|
||||
if (log)
|
||||
{
|
||||
Log(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Log(this Exception e, FileInfo file = null)
|
||||
{
|
||||
if (e == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
file = file ?? VitaNexCore.LogFile;
|
||||
|
||||
var now = String.Format("***ERROR LOG [{0}]***", DateTime.Now);
|
||||
|
||||
lock (VitaNexCore.IOLock)
|
||||
{
|
||||
file.AppendText(false, String.Empty, now, e.Message, e.ToString(), e.HelpLink, String.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
508
Scripts/SubSystem/VitaNex/Core/Extensions/System/IOExt.cs
Normal file
508
Scripts/SubSystem/VitaNex/Core/Extensions/System/IOExt.cs
Normal file
@@ -0,0 +1,508 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using VitaNex;
|
||||
using VitaNex.IO;
|
||||
#endregion
|
||||
|
||||
namespace System.IO
|
||||
{
|
||||
public static class IOExtUtility
|
||||
{
|
||||
public static FileMime GetMimeType(this FileInfo file)
|
||||
{
|
||||
file.Refresh();
|
||||
|
||||
return FileMime.Lookup(file);
|
||||
}
|
||||
|
||||
public static byte[] ReadAllBytes(this FileInfo file)
|
||||
{
|
||||
file.Refresh();
|
||||
|
||||
return File.ReadAllBytes(file.FullName);
|
||||
}
|
||||
|
||||
public static string[] ReadAllLines(this FileInfo file)
|
||||
{
|
||||
file.Refresh();
|
||||
|
||||
return File.ReadAllLines(file.FullName);
|
||||
}
|
||||
|
||||
public static string ReadAllText(this FileInfo file)
|
||||
{
|
||||
file.Refresh();
|
||||
|
||||
return File.ReadAllText(file.FullName);
|
||||
}
|
||||
|
||||
public static void WriteAllBytes(this FileInfo file, byte[] bytes)
|
||||
{
|
||||
File.WriteAllBytes(file.FullName, bytes);
|
||||
|
||||
file.Refresh();
|
||||
}
|
||||
|
||||
public static void WriteAllLines(this FileInfo file, string[] contents)
|
||||
{
|
||||
File.WriteAllLines(file.FullName, contents);
|
||||
|
||||
file.Refresh();
|
||||
}
|
||||
|
||||
public static void WriteAllLines(this FileInfo file, string[] contents, Encoding encoding)
|
||||
{
|
||||
File.WriteAllLines(file.FullName, contents, encoding);
|
||||
|
||||
file.Refresh();
|
||||
}
|
||||
|
||||
public static void WriteAllLines(this FileInfo file, IEnumerable<string> contents)
|
||||
{
|
||||
File.WriteAllLines(file.FullName, contents);
|
||||
|
||||
file.Refresh();
|
||||
}
|
||||
|
||||
public static void WriteAllLines(this FileInfo file, IEnumerable<string> contents, Encoding encoding)
|
||||
{
|
||||
File.WriteAllLines(file.FullName, contents, encoding);
|
||||
|
||||
file.Refresh();
|
||||
}
|
||||
|
||||
public static void WriteAllText(this FileInfo file, string contents)
|
||||
{
|
||||
File.WriteAllText(file.FullName, contents);
|
||||
|
||||
file.Refresh();
|
||||
}
|
||||
|
||||
public static void WriteAllText(this FileInfo file, string contents, Encoding encoding)
|
||||
{
|
||||
File.WriteAllText(file.FullName, contents, encoding);
|
||||
|
||||
file.Refresh();
|
||||
}
|
||||
|
||||
public static bool GetAttribute(this FileInfo file, FileAttributes attr)
|
||||
{
|
||||
file.Refresh();
|
||||
|
||||
if (file.Exists)
|
||||
{
|
||||
return file.Attributes.HasFlag(attr);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void SetAttribute(this FileInfo file, FileAttributes attr, bool value)
|
||||
{
|
||||
file.Refresh();
|
||||
|
||||
if (!file.Exists)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (value)
|
||||
{
|
||||
file.Attributes |= attr;
|
||||
}
|
||||
else
|
||||
{
|
||||
file.Attributes &= ~attr;
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetHidden(this FileInfo file, bool value)
|
||||
{
|
||||
file.Refresh();
|
||||
|
||||
SetAttribute(file, FileAttributes.Hidden, value);
|
||||
}
|
||||
|
||||
public static FileStream OpenRead(this FileInfo file, bool create = false, bool replace = false)
|
||||
{
|
||||
file.Refresh();
|
||||
|
||||
if (file.Exists)
|
||||
{
|
||||
if (replace)
|
||||
{
|
||||
file = EnsureFile(file, true);
|
||||
}
|
||||
}
|
||||
else if (create)
|
||||
{
|
||||
file = EnsureFile(file, replace);
|
||||
}
|
||||
|
||||
return file.Open(FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
}
|
||||
|
||||
public static FileStream OpenWrite(this FileInfo file, bool create = false, bool replace = false)
|
||||
{
|
||||
file.Refresh();
|
||||
|
||||
if (file.Exists)
|
||||
{
|
||||
if (replace)
|
||||
{
|
||||
file = EnsureFile(file, true);
|
||||
}
|
||||
}
|
||||
else if (create)
|
||||
{
|
||||
file = EnsureFile(file, replace);
|
||||
}
|
||||
|
||||
return file.Open(FileMode.Open, FileAccess.Write, FileShare.Write);
|
||||
}
|
||||
|
||||
public static FileStream OpenAppend(this FileInfo file, bool create = false, bool replace = false)
|
||||
{
|
||||
file.Refresh();
|
||||
|
||||
if (file.Exists)
|
||||
{
|
||||
if (replace)
|
||||
{
|
||||
file = EnsureFile(file, true);
|
||||
}
|
||||
}
|
||||
else if (create)
|
||||
{
|
||||
file = EnsureFile(file, replace);
|
||||
}
|
||||
|
||||
return file.Open(FileMode.Append, FileAccess.Write, FileShare.Write);
|
||||
}
|
||||
|
||||
public static FileStream Open(this FileInfo file, bool create = false, bool replace = false)
|
||||
{
|
||||
file.Refresh();
|
||||
|
||||
if (file.Exists)
|
||||
{
|
||||
if (replace)
|
||||
{
|
||||
file = EnsureFile(file, true);
|
||||
}
|
||||
}
|
||||
else if (create)
|
||||
{
|
||||
file = EnsureFile(file, replace);
|
||||
}
|
||||
|
||||
return file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
|
||||
}
|
||||
|
||||
public static void AppendText(this FileInfo file, bool truncate, params string[] lines)
|
||||
{
|
||||
if (lines == null || lines.Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
file.Refresh();
|
||||
|
||||
if (!file.Exists)
|
||||
{
|
||||
file = EnsureFile(file, false);
|
||||
}
|
||||
else if (truncate)
|
||||
{
|
||||
file = EnsureFile(file, true);
|
||||
}
|
||||
|
||||
using (var fs = OpenAppend(file))
|
||||
{
|
||||
var data = String.Join(Environment.NewLine, lines) + Environment.NewLine;
|
||||
var buffer = Encoding.UTF8.GetBytes(data);
|
||||
|
||||
fs.Write(buffer, 0, buffer.Length);
|
||||
fs.Flush();
|
||||
}
|
||||
|
||||
file.Refresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures a files' existence
|
||||
/// </summary>
|
||||
/// <returns>FileInfo representing the file ensured for 'info'</returns>
|
||||
public static FileInfo EnsureFile(this FileInfo file)
|
||||
{
|
||||
return EnsureFile(file, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures a files' existence
|
||||
/// </summary>
|
||||
/// <param name="file"></param>
|
||||
/// <param name="replace">True: replace the file if it exists</param>
|
||||
/// <returns>FileInfo representing the file ensured for 'info'</returns>
|
||||
public static FileInfo EnsureFile(this FileInfo file, bool replace)
|
||||
{
|
||||
file.Refresh();
|
||||
|
||||
EnsureDirectory(file.Directory, false);
|
||||
|
||||
if (!file.Exists)
|
||||
{
|
||||
using (var fs = file.Create())
|
||||
{
|
||||
fs.Close();
|
||||
}
|
||||
}
|
||||
else if (replace)
|
||||
{
|
||||
VitaNexCore.TryCatch(file.Delete);
|
||||
|
||||
using (var fs = file.Create())
|
||||
{
|
||||
fs.Close();
|
||||
}
|
||||
}
|
||||
|
||||
file.Refresh();
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures a directories' existence
|
||||
/// </summary>
|
||||
/// <returns>DirectoryInfo representing the directory ensured for 'info'</returns>
|
||||
public static DirectoryInfo EnsureDirectory(this DirectoryInfo dir)
|
||||
{
|
||||
return EnsureDirectory(dir, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures a directories' existence
|
||||
/// </summary>
|
||||
/// <param name="dir"></param>
|
||||
/// <param name="replace">True: replace the directory if it exists</param>
|
||||
/// <returns>DirectoryInfo representing the directory ensured for 'info'</returns>
|
||||
public static DirectoryInfo EnsureDirectory(this DirectoryInfo dir, bool replace)
|
||||
{
|
||||
dir.Refresh();
|
||||
|
||||
if (!dir.Exists)
|
||||
{
|
||||
dir.Create();
|
||||
}
|
||||
else if (replace)
|
||||
{
|
||||
EmptyDirectory(dir, true);
|
||||
|
||||
VitaNexCore.TryCatch(dir.Delete, true);
|
||||
|
||||
dir.Create();
|
||||
}
|
||||
|
||||
dir.Refresh();
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Empties the contents of the specified directory with the option to include sub directories
|
||||
/// </summary>
|
||||
/// <param name="dir">Directory to empty</param>
|
||||
/// <param name="incDirs">True: includes sub directories</param>
|
||||
public static void EmptyDirectory(this DirectoryInfo dir, bool incDirs)
|
||||
{
|
||||
dir.Refresh();
|
||||
|
||||
if (!dir.Exists)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var f in dir.EnumerateFiles())
|
||||
{
|
||||
VitaNexCore.TryCatch(f.Delete);
|
||||
}
|
||||
|
||||
if (incDirs)
|
||||
{
|
||||
foreach (var d in dir.EnumerateDirectories())
|
||||
{
|
||||
VitaNexCore.TryCatch(d.Delete, true);
|
||||
}
|
||||
}
|
||||
|
||||
dir.Refresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Empties the contents of the specified directory, including all sub-directories and files that are older than the
|
||||
/// given age.
|
||||
/// </summary>
|
||||
/// <param name="dir">Directory to empty</param>
|
||||
/// <param name="age">Age at which a directory or file is considered old enough to be deleted</param>
|
||||
public static void EmptyDirectory(this DirectoryInfo dir, TimeSpan age)
|
||||
{
|
||||
EmptyDirectory(dir, age, "*", SearchOption.AllDirectories);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Empties the contents of the specified directory, only deleting files that meet the mask criteria and are older than
|
||||
/// the given age.
|
||||
/// </summary>
|
||||
/// <param name="dir">Directory to empty</param>
|
||||
/// <param name="age">Age at which a directory or file is considered old enough to be deleted</param>
|
||||
/// <param name="mask">String mask to use to filter file names</param>
|
||||
/// <param name="option">Search options</param>
|
||||
public static void EmptyDirectory(this DirectoryInfo dir, TimeSpan age, string mask, SearchOption option)
|
||||
{
|
||||
dir.Refresh();
|
||||
|
||||
if (!dir.Exists)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var expire = DateTime.UtcNow.Subtract(age);
|
||||
|
||||
foreach (var d in AllDirectories(dir, mask, option).Where(d => d.CreationTimeUtc < expire))
|
||||
{
|
||||
VitaNexCore.TryCatch(d.Delete, true);
|
||||
}
|
||||
|
||||
foreach (var f in AllFiles(dir, mask, option).Where(f => f.CreationTimeUtc < expire))
|
||||
{
|
||||
VitaNexCore.TryCatch(f.Delete);
|
||||
}
|
||||
|
||||
dir.Refresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Empties the contents of the specified directory, only deleting files that meet the mask criteria
|
||||
/// </summary>
|
||||
/// <param name="dir">Directory to empty</param>
|
||||
/// <param name="mask">String mask to use to filter file names</param>
|
||||
/// <param name="option">Search options</param>
|
||||
public static void EmptyDirectory(this DirectoryInfo dir, string mask, SearchOption option)
|
||||
{
|
||||
dir.Refresh();
|
||||
|
||||
if (!dir.Exists)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var d in AllDirectories(dir, mask, option))
|
||||
{
|
||||
VitaNexCore.TryCatch(d.Delete, true);
|
||||
}
|
||||
|
||||
foreach (var f in AllFiles(dir, mask, option))
|
||||
{
|
||||
VitaNexCore.TryCatch(f.Delete);
|
||||
}
|
||||
|
||||
dir.Refresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies the contents of the specified directory to the specified target directory, only including files that meet
|
||||
/// the mask criteria
|
||||
/// </summary>
|
||||
/// <param name="source">Directory to copy</param>
|
||||
/// <param name="dest">Directory to copy to</param>
|
||||
public static void CopyDirectory(this DirectoryInfo source, DirectoryInfo dest)
|
||||
{
|
||||
CopyDirectory(source, dest, "*", SearchOption.AllDirectories);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies the contents of the specified directory to the specified target directory, only including files that meet
|
||||
/// the mask criteria
|
||||
/// </summary>
|
||||
/// <param name="source">Directory to copy</param>
|
||||
/// <param name="dest">Directory to copy to</param>
|
||||
/// <param name="mask">String mask to use to filter file names</param>
|
||||
/// <param name="option">Search options</param>
|
||||
public static void CopyDirectory(this DirectoryInfo source, DirectoryInfo dest, string mask, SearchOption option)
|
||||
{
|
||||
source.Refresh();
|
||||
|
||||
if (!source.Exists)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EnsureDirectory(dest, false);
|
||||
|
||||
foreach (var f in AllFiles(source, mask, option))
|
||||
{
|
||||
VitaNexCore.TryCatch(
|
||||
() =>
|
||||
{
|
||||
var t = new FileInfo(f.FullName.Replace(source.FullName, dest.FullName));
|
||||
|
||||
EnsureDirectory(t.Directory);
|
||||
|
||||
f.CopyTo(t.FullName, true);
|
||||
});
|
||||
}
|
||||
|
||||
source.Refresh();
|
||||
dest.Refresh();
|
||||
}
|
||||
|
||||
public static IEnumerable<DirectoryInfo> AllDirectories(this DirectoryInfo dir, string mask, SearchOption option)
|
||||
{
|
||||
foreach (var d in dir.EnumerateDirectories(mask).Where(d => d != dir))
|
||||
{
|
||||
if (option == SearchOption.AllDirectories)
|
||||
{
|
||||
foreach (var s in AllDirectories(d, mask, SearchOption.AllDirectories).Where(s => s != d))
|
||||
{
|
||||
yield return s;
|
||||
}
|
||||
}
|
||||
|
||||
yield return d;
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<FileInfo> AllFiles(this DirectoryInfo dir, string mask, SearchOption option)
|
||||
{
|
||||
if (option == SearchOption.AllDirectories)
|
||||
{
|
||||
foreach (var f in dir.EnumerateDirectories()
|
||||
.Where(d => d != dir)
|
||||
.SelectMany(d => AllFiles(d, mask, SearchOption.AllDirectories)))
|
||||
{
|
||||
yield return f;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var f in dir.EnumerateFiles(mask))
|
||||
{
|
||||
yield return f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
115
Scripts/SubSystem/VitaNex/Core/Extensions/System/IPAddressExt.cs
Normal file
115
Scripts/SubSystem/VitaNex/Core/Extensions/System/IPAddressExt.cs
Normal file
@@ -0,0 +1,115 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace System
|
||||
{
|
||||
public static class IPAddressExtUtility
|
||||
{
|
||||
private static readonly Regex _AddressPattern = new Regex(@"([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})");
|
||||
|
||||
private static IPAddress _Public;
|
||||
|
||||
public static IPAddress FindPublic()
|
||||
{
|
||||
if (_Public != null)
|
||||
{
|
||||
return _Public;
|
||||
}
|
||||
|
||||
var data = String.Empty;
|
||||
|
||||
var request = WebRequest.Create("https://api.ipify.org");
|
||||
|
||||
using (var response = request.GetResponse())
|
||||
{
|
||||
var r = response.GetResponseStream();
|
||||
|
||||
if (r != null)
|
||||
{
|
||||
using (var stream = new StreamReader(r))
|
||||
{
|
||||
data = stream.ReadToEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var m = _AddressPattern.Match(data);
|
||||
|
||||
return (_Public = m.Success ? IPAddress.Parse(m.Value) : null);
|
||||
}
|
||||
|
||||
public static IEnumerable<IPAddress> FindInternal(this IPAddress address)
|
||||
{
|
||||
if (address.Equals(IPAddress.Any) || address.Equals(IPAddress.IPv6Any))
|
||||
{
|
||||
return NetworkInterface.GetAllNetworkInterfaces()
|
||||
.Select(a => a.GetIPProperties())
|
||||
.SelectMany(p => p.UnicastAddresses.Where(u => address.AddressFamily == u.Address.AddressFamily))
|
||||
.Select(uni => uni.Address);
|
||||
}
|
||||
|
||||
return address.ToEnumerable();
|
||||
}
|
||||
|
||||
public static bool IsPrivateNetwork(this IPAddress address)
|
||||
{
|
||||
// 10.0.0.0/8
|
||||
// 172.16.0.0/12
|
||||
// 192.168.0.0/16
|
||||
// 169.254.0.0/16
|
||||
// 100.64.0.0/10 RFC 6598
|
||||
|
||||
if (address.AddressFamily == AddressFamily.InterNetworkV6)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Utility.IPMatch("192.168.*", address))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Utility.IPMatch("10.*", address))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Utility.IPMatch("172.16-31.*", address))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Utility.IPMatch("169.254.*", address))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Utility.IPMatch("100.64-127.*", address))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
423
Scripts/SubSystem/VitaNex/Core/Extensions/System/NumericExt.cs
Normal file
423
Scripts/SubSystem/VitaNex/Core/Extensions/System/NumericExt.cs
Normal file
@@ -0,0 +1,423 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
namespace System
|
||||
{
|
||||
public static class NumericExtUtility
|
||||
{
|
||||
private static string GetOrdinalSuffix(double value)
|
||||
{
|
||||
var ones = (int)(value % 10);
|
||||
var tens = (int)Math.Floor(value / 10.0) % 10;
|
||||
|
||||
string suff;
|
||||
|
||||
if (tens == 1)
|
||||
{
|
||||
suff = "th";
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (ones)
|
||||
{
|
||||
case 1:
|
||||
suff = "st";
|
||||
break;
|
||||
case 2:
|
||||
suff = "nd";
|
||||
break;
|
||||
case 3:
|
||||
suff = "rd";
|
||||
break;
|
||||
default:
|
||||
suff = "th";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return suff;
|
||||
}
|
||||
|
||||
public static string ToOrdinalString(this decimal value, string format = "#,0")
|
||||
{
|
||||
return value.ToString(format) + GetOrdinalSuffix((double)value);
|
||||
}
|
||||
|
||||
public static string ToOrdinalString(this double value, string format = "#,0")
|
||||
{
|
||||
return value.ToString(format) + GetOrdinalSuffix(value);
|
||||
}
|
||||
|
||||
public static string ToOrdinalString(this float value, string format = "#,0")
|
||||
{
|
||||
return value.ToString(format) + GetOrdinalSuffix(value);
|
||||
}
|
||||
|
||||
public static string ToOrdinalString(this sbyte value, string format = "#,0")
|
||||
{
|
||||
return value.ToString(format) + GetOrdinalSuffix(value);
|
||||
}
|
||||
|
||||
public static string ToOrdinalString(this byte value, string format = "#,0")
|
||||
{
|
||||
return value.ToString(format) + GetOrdinalSuffix(value);
|
||||
}
|
||||
|
||||
public static string ToOrdinalString(this short value, string format = "#,0")
|
||||
{
|
||||
return value.ToString(format) + GetOrdinalSuffix(value);
|
||||
}
|
||||
|
||||
public static string ToOrdinalString(this ushort value, string format = "#,0")
|
||||
{
|
||||
return value.ToString(format) + GetOrdinalSuffix(value);
|
||||
}
|
||||
|
||||
public static string ToOrdinalString(this int value, string format = "#,0")
|
||||
{
|
||||
return value.ToString(format) + GetOrdinalSuffix(value);
|
||||
}
|
||||
|
||||
public static string ToOrdinalString(this uint value, string format = "#,0")
|
||||
{
|
||||
return value.ToString(format) + GetOrdinalSuffix(value);
|
||||
}
|
||||
|
||||
public static string ToOrdinalString(this long value, string format = "#,0")
|
||||
{
|
||||
return value.ToString(format) + GetOrdinalSuffix(value);
|
||||
}
|
||||
|
||||
public static string ToOrdinalString(this ulong value, string format = "#,0")
|
||||
{
|
||||
return value.ToString(format) + GetOrdinalSuffix(value);
|
||||
}
|
||||
|
||||
public static decimal Overflow(this decimal value, decimal min, decimal max)
|
||||
{
|
||||
if (min > max)
|
||||
{
|
||||
var swapMin = Math.Min(min, max);
|
||||
var swapMax = Math.Max(min, max);
|
||||
|
||||
min = swapMin;
|
||||
max = swapMax;
|
||||
}
|
||||
|
||||
if (value < min)
|
||||
{
|
||||
while (value < min)
|
||||
{
|
||||
value = max - (min - value);
|
||||
}
|
||||
}
|
||||
else if (value > max)
|
||||
{
|
||||
while (value > max)
|
||||
{
|
||||
value = min + (value - max);
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static double Overflow(this double value, double min, double max)
|
||||
{
|
||||
if (min > max)
|
||||
{
|
||||
var swapMin = Math.Min(min, max);
|
||||
var swapMax = Math.Max(min, max);
|
||||
|
||||
min = swapMin;
|
||||
max = swapMax;
|
||||
}
|
||||
|
||||
if (value < min)
|
||||
{
|
||||
while (value < min)
|
||||
{
|
||||
value = max - (min - value);
|
||||
}
|
||||
}
|
||||
else if (value > max)
|
||||
{
|
||||
while (value > max)
|
||||
{
|
||||
value = min + (value - max);
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static float Overflow(this float value, float min, float max)
|
||||
{
|
||||
if (min > max)
|
||||
{
|
||||
var swapMin = Math.Min(min, max);
|
||||
var swapMax = Math.Max(min, max);
|
||||
|
||||
min = swapMin;
|
||||
max = swapMax;
|
||||
}
|
||||
|
||||
if (value < min)
|
||||
{
|
||||
while (value < min)
|
||||
{
|
||||
value = max - (min - value);
|
||||
}
|
||||
}
|
||||
else if (value > max)
|
||||
{
|
||||
while (value > max)
|
||||
{
|
||||
value = min + (value - max);
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static sbyte Overflow(this sbyte value, sbyte min, sbyte max)
|
||||
{
|
||||
if (min > max)
|
||||
{
|
||||
var swapMin = Math.Min(min, max);
|
||||
var swapMax = Math.Max(min, max);
|
||||
|
||||
min = swapMin;
|
||||
max = swapMax;
|
||||
}
|
||||
|
||||
if (value < min)
|
||||
{
|
||||
while (value < min)
|
||||
{
|
||||
value = (sbyte)(max - (min - value));
|
||||
}
|
||||
}
|
||||
else if (value > max)
|
||||
{
|
||||
while (value > max)
|
||||
{
|
||||
value = (sbyte)(min + (value - max));
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static byte Overflow(this byte value, byte min, byte max)
|
||||
{
|
||||
if (min > max)
|
||||
{
|
||||
var swapMin = Math.Min(min, max);
|
||||
var swapMax = Math.Max(min, max);
|
||||
|
||||
min = swapMin;
|
||||
max = swapMax;
|
||||
}
|
||||
|
||||
if (value < min)
|
||||
{
|
||||
while (value < min)
|
||||
{
|
||||
value = (byte)(max - (min - value));
|
||||
}
|
||||
}
|
||||
else if (value > max)
|
||||
{
|
||||
while (value > max)
|
||||
{
|
||||
value = (byte)(min + (value - max));
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static short Overflow(this short value, short min, short max)
|
||||
{
|
||||
if (min > max)
|
||||
{
|
||||
var swapMin = Math.Min(min, max);
|
||||
var swapMax = Math.Max(min, max);
|
||||
|
||||
min = swapMin;
|
||||
max = swapMax;
|
||||
}
|
||||
|
||||
if (value < min)
|
||||
{
|
||||
while (value < min)
|
||||
{
|
||||
value = (short)(max - (min - value));
|
||||
}
|
||||
}
|
||||
else if (value > max)
|
||||
{
|
||||
while (value > max)
|
||||
{
|
||||
value = (short)(min + (value - max));
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static ushort Overflow(this ushort value, ushort min, ushort max)
|
||||
{
|
||||
if (min > max)
|
||||
{
|
||||
var swapMin = Math.Min(min, max);
|
||||
var swapMax = Math.Max(min, max);
|
||||
|
||||
min = swapMin;
|
||||
max = swapMax;
|
||||
}
|
||||
|
||||
if (value < min)
|
||||
{
|
||||
while (value < min)
|
||||
{
|
||||
value = (ushort)(max - (min - value));
|
||||
}
|
||||
}
|
||||
else if (value > max)
|
||||
{
|
||||
while (value > max)
|
||||
{
|
||||
value = (ushort)(min + (value - max));
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static int Overflow(this int value, int min, int max)
|
||||
{
|
||||
if (min > max)
|
||||
{
|
||||
var swapMin = Math.Min(min, max);
|
||||
var swapMax = Math.Max(min, max);
|
||||
|
||||
min = swapMin;
|
||||
max = swapMax;
|
||||
}
|
||||
|
||||
if (value < min)
|
||||
{
|
||||
while (value < min)
|
||||
{
|
||||
value = max - (min - value);
|
||||
}
|
||||
}
|
||||
else if (value > max)
|
||||
{
|
||||
while (value > max)
|
||||
{
|
||||
value = min + (value - max);
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static uint Overflow(this uint value, uint min, uint max)
|
||||
{
|
||||
if (min > max)
|
||||
{
|
||||
var swapMin = Math.Min(min, max);
|
||||
var swapMax = Math.Max(min, max);
|
||||
|
||||
min = swapMin;
|
||||
max = swapMax;
|
||||
}
|
||||
|
||||
if (value < min)
|
||||
{
|
||||
while (value < min)
|
||||
{
|
||||
value = max - (min - value);
|
||||
}
|
||||
}
|
||||
else if (value > max)
|
||||
{
|
||||
while (value > max)
|
||||
{
|
||||
value = min + (value - max);
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static long Overflow(this long value, long min, long max)
|
||||
{
|
||||
if (min > max)
|
||||
{
|
||||
var swapMin = Math.Min(min, max);
|
||||
var swapMax = Math.Max(min, max);
|
||||
|
||||
min = swapMin;
|
||||
max = swapMax;
|
||||
}
|
||||
|
||||
if (value < min)
|
||||
{
|
||||
while (value < min)
|
||||
{
|
||||
value = max - (min - value);
|
||||
}
|
||||
}
|
||||
else if (value > max)
|
||||
{
|
||||
while (value > max)
|
||||
{
|
||||
value = min + (value - max);
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static ulong Overflow(this ulong value, ulong min, ulong max)
|
||||
{
|
||||
if (min > max)
|
||||
{
|
||||
var swapMin = Math.Min(min, max);
|
||||
var swapMax = Math.Max(min, max);
|
||||
|
||||
min = swapMin;
|
||||
max = swapMax;
|
||||
}
|
||||
|
||||
if (value < min)
|
||||
{
|
||||
while (value < min)
|
||||
{
|
||||
value = max - (min - value);
|
||||
}
|
||||
}
|
||||
else if (value > max)
|
||||
{
|
||||
while (value > max)
|
||||
{
|
||||
value = min + (value - max);
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
401
Scripts/SubSystem/VitaNex/Core/Extensions/System/ObjectExt.cs
Normal file
401
Scripts/SubSystem/VitaNex/Core/Extensions/System/ObjectExt.cs
Normal file
@@ -0,0 +1,401 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
using VitaNex;
|
||||
using VitaNex.Reflection;
|
||||
#endregion
|
||||
|
||||
namespace System
|
||||
{
|
||||
public static class ObjectExtUtility
|
||||
{
|
||||
private const BindingFlags _CommonFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;
|
||||
|
||||
private static readonly Delegate[] _EmptyDelegates = new Delegate[0];
|
||||
|
||||
public static Delegate[] GetEventDelegates(this object obj, string eventName)
|
||||
{
|
||||
var t = obj as Type ?? obj.GetType();
|
||||
|
||||
var f = _CommonFlags;
|
||||
|
||||
if (t.IsSealed && t.IsAbstract)
|
||||
{
|
||||
f &= ~BindingFlags.Instance;
|
||||
}
|
||||
|
||||
var ei = t.GetEvent(eventName, f);
|
||||
|
||||
if (ei == null)
|
||||
{
|
||||
return _EmptyDelegates;
|
||||
}
|
||||
|
||||
var efi = t.GetField(ei.Name, f | BindingFlags.GetField);
|
||||
|
||||
if (efi == null)
|
||||
{
|
||||
efi = t.GetField("EVENT_" + ei.Name.ToUpper(), f | BindingFlags.GetField);
|
||||
}
|
||||
|
||||
if (efi == null)
|
||||
{
|
||||
return _EmptyDelegates;
|
||||
}
|
||||
|
||||
var efv = (Delegate)efi.GetValue(obj is Type ? null : obj);
|
||||
|
||||
return efv.GetInvocationList();
|
||||
}
|
||||
|
||||
public static MethodInfo[] GetEventMethods(this object obj, string eventName)
|
||||
{
|
||||
return GetEventDelegates(obj, eventName).Select(e => e.Method).ToArray();
|
||||
}
|
||||
|
||||
public static bool GetFieldValue(this object obj, string name, out object value)
|
||||
{
|
||||
return GetFieldValue<object>(obj, name, out value);
|
||||
}
|
||||
|
||||
public static bool GetFieldValue<T>(this object obj, string name, out T value)
|
||||
{
|
||||
value = default(T);
|
||||
|
||||
if (obj == null || String.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var t = obj as Type ?? obj.GetType();
|
||||
|
||||
var f = _CommonFlags;
|
||||
|
||||
if (t.IsSealed && t.IsAbstract)
|
||||
{
|
||||
f &= ~BindingFlags.Instance;
|
||||
}
|
||||
|
||||
var o = t.GetField(name, f);
|
||||
|
||||
try
|
||||
{
|
||||
value = (T)o.GetValue(obj is Type ? null : obj);
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool SetFieldValue(this object obj, string name, object value)
|
||||
{
|
||||
return SetFieldValue<object>(obj, name, value);
|
||||
}
|
||||
|
||||
public static bool SetFieldValue<T>(this object obj, string name, T value)
|
||||
{
|
||||
if (obj == null || String.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var t = obj as Type ?? obj.GetType();
|
||||
|
||||
var f = _CommonFlags;
|
||||
|
||||
if (t.IsSealed && t.IsAbstract)
|
||||
{
|
||||
f &= ~BindingFlags.Instance;
|
||||
}
|
||||
|
||||
var o = t.GetField(name, f);
|
||||
|
||||
try
|
||||
{
|
||||
o.SetValue(obj is Type ? null : obj, value);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool GetPropertyValue(this object obj, string name, out object value)
|
||||
{
|
||||
return GetPropertyValue<object>(obj, name, out value);
|
||||
}
|
||||
|
||||
public static bool GetPropertyValue<T>(this object obj, string name, out T value)
|
||||
{
|
||||
value = default(T);
|
||||
|
||||
if (obj == null || String.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var t = obj as Type ?? obj.GetType();
|
||||
|
||||
var f = _CommonFlags;
|
||||
|
||||
if (t.IsSealed && t.IsAbstract)
|
||||
{
|
||||
f &= ~BindingFlags.Instance;
|
||||
}
|
||||
|
||||
var o = t.GetProperty(name, f, null, typeof(T), Type.EmptyTypes, null);
|
||||
|
||||
try
|
||||
{
|
||||
value = (T)o.GetValue(obj is Type ? null : obj, null);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool SetPropertyValue(this object obj, string name, object value)
|
||||
{
|
||||
return SetPropertyValue<object>(obj, name, value);
|
||||
}
|
||||
|
||||
public static bool SetPropertyValue<T>(this object obj, string name, T value)
|
||||
{
|
||||
if (obj == null || String.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var t = obj as Type ?? obj.GetType();
|
||||
|
||||
var f = _CommonFlags;
|
||||
|
||||
if (t.IsSealed && t.IsAbstract)
|
||||
{
|
||||
f &= ~BindingFlags.Instance;
|
||||
}
|
||||
|
||||
var o = t.GetProperty(name, f, null, typeof(T), Type.EmptyTypes, null);
|
||||
|
||||
try
|
||||
{
|
||||
o.SetValue(obj is Type ? null : obj, value, null);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static object InvokeMethod(this object obj, string name, params object[] args)
|
||||
{
|
||||
if (obj == null || String.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var t = obj as Type ?? obj.GetType();
|
||||
|
||||
var f = _CommonFlags;
|
||||
|
||||
if (t.IsSealed && t.IsAbstract)
|
||||
{
|
||||
f &= ~BindingFlags.Instance;
|
||||
}
|
||||
|
||||
var a = args != null ? Type.GetTypeArray(args) : Type.EmptyTypes;
|
||||
|
||||
var o = t.GetMethod(name, f, null, a, null);
|
||||
|
||||
try
|
||||
{
|
||||
if (o.ReturnType == typeof(void))
|
||||
{
|
||||
return o.Invoke(obj is Type ? null : obj, args) ?? true;
|
||||
}
|
||||
|
||||
return o.Invoke(obj is Type ? null : obj, args);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return ex;
|
||||
}
|
||||
}
|
||||
|
||||
public static T InvokeMethod<T>(this object obj, string name, params object[] args)
|
||||
{
|
||||
if (InvokeMethod(obj, name, args) is T o)
|
||||
{
|
||||
return o;
|
||||
}
|
||||
|
||||
#if NET48_OR_GREATER
|
||||
return default;
|
||||
#else
|
||||
return default(T);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static int GetTypeHashCode(this object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
var type = obj.GetType();
|
||||
|
||||
return type.GetValueHashCode();
|
||||
}
|
||||
|
||||
public static string GetTypeName(this object obj, bool raw)
|
||||
{
|
||||
Type type;
|
||||
|
||||
if (obj is Type t)
|
||||
{
|
||||
type = t;
|
||||
}
|
||||
else if (obj is ITypeSelectProperty ts)
|
||||
{
|
||||
type = ts.ExpectedType;
|
||||
}
|
||||
else
|
||||
{
|
||||
type = obj.GetType();
|
||||
}
|
||||
|
||||
if (raw)
|
||||
{
|
||||
return type.Name;
|
||||
}
|
||||
|
||||
return type.ResolveName();
|
||||
}
|
||||
|
||||
public static bool TypeEquals<T>(this object obj)
|
||||
{
|
||||
return TypeEquals<T>(obj, true);
|
||||
}
|
||||
|
||||
public static bool TypeEquals<T>(this object obj, bool child)
|
||||
{
|
||||
return TypeEquals(obj, typeof(T), child);
|
||||
}
|
||||
|
||||
public static bool TypeEquals(this object obj, object other)
|
||||
{
|
||||
return TypeEquals(obj, other, true);
|
||||
}
|
||||
|
||||
public static bool TypeEquals(this object obj, object other, bool child)
|
||||
{
|
||||
if (obj == null || other == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(obj, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Type l, r;
|
||||
|
||||
if (obj is Type tl)
|
||||
{
|
||||
l = tl;
|
||||
}
|
||||
else if (obj is ITypeSelectProperty tsl)
|
||||
{
|
||||
l = tsl.InternalType;
|
||||
}
|
||||
else
|
||||
{
|
||||
l = obj.GetType();
|
||||
}
|
||||
|
||||
if (other is Type tr)
|
||||
{
|
||||
r = tr;
|
||||
}
|
||||
else if (other is ITypeSelectProperty tsr)
|
||||
{
|
||||
r = tsr.InternalType;
|
||||
}
|
||||
else
|
||||
{
|
||||
r = other as Type ?? other.GetType();
|
||||
}
|
||||
|
||||
if (child)
|
||||
{
|
||||
return l.IsEqualOrChildOf(r);
|
||||
}
|
||||
|
||||
return l.IsEqual(r);
|
||||
}
|
||||
|
||||
public static int CompareNull<T>(this T obj, T other)
|
||||
{
|
||||
var result = 0;
|
||||
|
||||
CompareNull(obj, other, ref result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static bool CompareNull<T>(this T obj, T other, ref int result)
|
||||
{
|
||||
if (obj == null && other == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj == null)
|
||||
{
|
||||
++result;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (other == null)
|
||||
{
|
||||
--result;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static FieldList<T> GetFields<T>(this T obj, BindingFlags flags = BindingFlags.Default, Func<FieldInfo, bool> filter = null)
|
||||
{
|
||||
return new FieldList<T>(obj, flags, filter);
|
||||
}
|
||||
|
||||
public static PropertyList<T> GetProperties<T>(this T obj, BindingFlags flags = BindingFlags.Default, Func<PropertyInfo, bool> filter = null)
|
||||
{
|
||||
return new PropertyList<T>(obj, flags, filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
1252
Scripts/SubSystem/VitaNex/Core/Extensions/System/StringExt.cs
Normal file
1252
Scripts/SubSystem/VitaNex/Core/Extensions/System/StringExt.cs
Normal file
File diff suppressed because it is too large
Load Diff
448
Scripts/SubSystem/VitaNex/Core/Extensions/System/TypeExt.cs
Normal file
448
Scripts/SubSystem/VitaNex/Core/Extensions/System/TypeExt.cs
Normal file
@@ -0,0 +1,448 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
using Server;
|
||||
|
||||
using VitaNex.Crypto;
|
||||
#endregion
|
||||
|
||||
namespace System
|
||||
{
|
||||
public static class TypeExtUtility
|
||||
{
|
||||
private static readonly Dictionary<Type, List<Type>> _ChildrenCache;
|
||||
private static readonly Dictionary<Type, List<Type>> _ConstructableChildrenCache;
|
||||
|
||||
private static readonly Dictionary<Type, int> _ValueHashCache;
|
||||
|
||||
static TypeExtUtility()
|
||||
{
|
||||
_ChildrenCache = new Dictionary<Type, List<Type>>(0x100);
|
||||
_ConstructableChildrenCache = new Dictionary<Type, List<Type>>(0x100);
|
||||
|
||||
_ValueHashCache = new Dictionary<Type, int>(0x400);
|
||||
}
|
||||
|
||||
private static string FormatName(string value)
|
||||
{
|
||||
var i = value.IndexOf('`');
|
||||
|
||||
return (i > 0 ? value.Substring(0, i) : value).SpaceWords();
|
||||
}
|
||||
|
||||
public static string ResolveName(this Type t)
|
||||
{
|
||||
return FormatName(t.Name);
|
||||
}
|
||||
|
||||
public static int GetValueHashCode(this Type t)
|
||||
{
|
||||
if (t == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!_ValueHashCache.TryGetValue(t, out var hash) || hash == 0)
|
||||
{
|
||||
using (var c = new CryptoHashCode(CryptoHashType.MD5, t.FullName))
|
||||
{
|
||||
_ValueHashCache[t] = hash = c.ValueHash;
|
||||
}
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
public static Type[] GetTypeCache(this Assembly asm)
|
||||
{
|
||||
return ScriptCompiler.GetTypeCache(asm).Types;
|
||||
}
|
||||
|
||||
public static Type[] GetHierarchy(this Type t)
|
||||
{
|
||||
return GetHierarchy(t, false);
|
||||
}
|
||||
|
||||
public static Type[] GetHierarchy(this Type t, bool self)
|
||||
{
|
||||
return EnumerateHierarchy(t, self).ToArray();
|
||||
}
|
||||
|
||||
public static IEnumerable<Type> EnumerateHierarchy(this Type t)
|
||||
{
|
||||
return EnumerateHierarchy(t, false);
|
||||
}
|
||||
|
||||
public static IEnumerable<Type> EnumerateHierarchy(this Type t, bool self)
|
||||
{
|
||||
if (t == null)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (self)
|
||||
{
|
||||
yield return t;
|
||||
}
|
||||
|
||||
while (t.BaseType != null)
|
||||
{
|
||||
yield return t = t.BaseType;
|
||||
}
|
||||
}
|
||||
|
||||
public static Type FindParent<T>(this Type type)
|
||||
{
|
||||
var ot = typeof(T);
|
||||
|
||||
return EnumerateHierarchy(type, false).FirstOrDefault(pt => pt == ot);
|
||||
}
|
||||
|
||||
public static bool TryFindParent<T>(this Type type, out Type parent)
|
||||
{
|
||||
return (parent = FindParent<T>(type)) != null;
|
||||
}
|
||||
|
||||
public static Type FindParent<T>(this Type type, Func<Type, bool> predicate)
|
||||
{
|
||||
var ot = typeof(T);
|
||||
|
||||
return EnumerateHierarchy(type, false).Where(t => t == ot).FirstOrDefault(predicate);
|
||||
}
|
||||
|
||||
public static bool TryFindParent<T>(this Type type, Func<Type, bool> predicate, out Type parent)
|
||||
{
|
||||
return (parent = FindParent<T>(type, predicate)) != null;
|
||||
}
|
||||
|
||||
public static Type FindParent(this Type type, Func<Type, bool> predicate)
|
||||
{
|
||||
return EnumerateHierarchy(type, false).FirstOrDefault(predicate);
|
||||
}
|
||||
|
||||
public static bool TryFindParent(this Type type, Func<Type, bool> predicate, out Type parent)
|
||||
{
|
||||
return (parent = FindParent(type, predicate)) != null;
|
||||
}
|
||||
|
||||
public static bool GetCustomAttributes<TAttribute>(this Type t, bool inherit, out TAttribute[] attrs)
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
attrs = GetCustomAttributes<TAttribute>(t, inherit);
|
||||
return attrs != null && attrs.Length > 0;
|
||||
}
|
||||
|
||||
public static TAttribute[] GetCustomAttributes<TAttribute>(this Type t, bool inherit)
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
return t != null
|
||||
? t.GetCustomAttributes(typeof(TAttribute), inherit).Cast<TAttribute>().ToArray()
|
||||
: new TAttribute[0];
|
||||
}
|
||||
|
||||
public static bool HasCustomAttribute<TAttribute>(this Type t, bool inherit)
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
var attrs = GetCustomAttributes<TAttribute>(t, inherit);
|
||||
|
||||
return attrs != null && attrs.Length > 0;
|
||||
}
|
||||
|
||||
public static int CompareTo(this Type t, Type other)
|
||||
{
|
||||
var result = 0;
|
||||
|
||||
if (t.CompareNull(other, ref result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
var lp = t.BaseType;
|
||||
|
||||
while (lp != null)
|
||||
{
|
||||
if (lp == other)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
lp = lp.BaseType;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
public static bool IsEqual(this Type a, string bName)
|
||||
{
|
||||
return IsEqual(a, bName, true);
|
||||
}
|
||||
|
||||
public static bool IsEqual(this Type a, string bName, bool ignoreCase)
|
||||
{
|
||||
return IsEqual(a, bName, ignoreCase, bName.ContainsAny('.', '+'));
|
||||
}
|
||||
|
||||
public static bool IsEqual(this Type a, string bName, bool ignoreCase, bool fullName)
|
||||
{
|
||||
var b = Type.GetType(bName) ??
|
||||
(fullName ? ScriptCompiler.FindTypeByFullName(bName) : ScriptCompiler.FindTypeByName(bName));
|
||||
|
||||
return IsEqual(a, b);
|
||||
}
|
||||
|
||||
public static bool IsEqual(this Type a, Type b)
|
||||
{
|
||||
return a == b;
|
||||
}
|
||||
|
||||
public static bool IsEqual<TObj>(this Type t)
|
||||
{
|
||||
return IsEqual(t, typeof(TObj));
|
||||
}
|
||||
|
||||
public static bool IsEqualOrChildOf(this Type a, string bName)
|
||||
{
|
||||
return IsEqualOrChildOf(a, bName, true);
|
||||
}
|
||||
|
||||
public static bool IsEqualOrChildOf(this Type a, string bName, bool ignoreCase)
|
||||
{
|
||||
return IsEqualOrChildOf(a, bName, ignoreCase, bName.ContainsAny('.', '+'));
|
||||
}
|
||||
|
||||
public static bool IsEqualOrChildOf(this Type a, string bName, bool ignoreCase, bool fullName)
|
||||
{
|
||||
var b = Type.GetType(bName) ??
|
||||
(fullName ? ScriptCompiler.FindTypeByFullName(bName) : ScriptCompiler.FindTypeByName(bName));
|
||||
|
||||
return IsEqualOrChildOf(a, b);
|
||||
}
|
||||
|
||||
public static bool IsEqualOrChildOf(this Type a, Type b)
|
||||
{
|
||||
return IsEqual(a, b) || IsChildOf(a, b);
|
||||
}
|
||||
|
||||
public static bool IsEqualOrChildOf<TObj>(this Type t)
|
||||
{
|
||||
return IsEqualOrChildOf(t, typeof(TObj));
|
||||
}
|
||||
|
||||
public static bool IsChildOf(this Type a, Type b)
|
||||
{
|
||||
return a != null && b != null && a != b && !a.IsInterface && !a.IsEnum &&
|
||||
(b.IsInterface ? HasInterface(a, b) : b.IsAssignableFrom(a));
|
||||
}
|
||||
|
||||
public static bool IsChildOf<TObj>(this Type t)
|
||||
{
|
||||
return IsChildOf(t, typeof(TObj));
|
||||
}
|
||||
|
||||
public static bool HasInterface(this Type t, string i)
|
||||
{
|
||||
var iType = Type.GetType(i, false) ??
|
||||
(i.IndexOf('.') < 0 ? ScriptCompiler.FindTypeByName(i) : ScriptCompiler.FindTypeByFullName(i));
|
||||
|
||||
return iType != null && iType.IsInterface && HasInterface(t, iType);
|
||||
}
|
||||
|
||||
public static bool HasInterface<TObj>(this Type t)
|
||||
{
|
||||
return HasInterface(t, typeof(TObj));
|
||||
}
|
||||
|
||||
public static bool HasInterface(this Type t, Type i)
|
||||
{
|
||||
return t != null && i != null && i.IsInterface && t.GetInterface(i.FullName) != null;
|
||||
}
|
||||
|
||||
public static bool IsConstructable(this Type a)
|
||||
{
|
||||
return IsConstructable(a, Type.EmptyTypes);
|
||||
}
|
||||
|
||||
public static bool IsConstructable(this Type a, Type[] argTypes)
|
||||
{
|
||||
if (a == null || a.IsAbstract || a.IsInterface || a.IsEnum)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return a.GetConstructor(argTypes) != null;
|
||||
}
|
||||
|
||||
public static bool IsConstructableFrom(this Type a, Type b)
|
||||
{
|
||||
if (a == null || b == null || a.IsAbstract || !IsChildOf(a, b))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return a.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).Length > 0;
|
||||
}
|
||||
|
||||
public static bool IsConstructableFrom<TObj>(this Type t)
|
||||
{
|
||||
return IsConstructableFrom(t, typeof(TObj));
|
||||
}
|
||||
|
||||
public static bool IsConstructableFrom(this Type a, Type b, Type[] argTypes)
|
||||
{
|
||||
if (a == null || b == null || a.IsAbstract || !IsChildOf(a, b))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return a.GetConstructor(argTypes) != null;
|
||||
}
|
||||
|
||||
public static bool IsConstructableFrom<TObj>(this Type t, Type[] argTypes)
|
||||
{
|
||||
return IsConstructableFrom(t, typeof(TObj), argTypes);
|
||||
}
|
||||
|
||||
public static Type[] GetChildren(this Type type, Func<Type, bool> predicate = null)
|
||||
{
|
||||
return FindChildren(type, predicate).ToArray();
|
||||
}
|
||||
|
||||
public static IEnumerable<Type> FindChildren(this Type type, Func<Type, bool> predicate = null)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
return Type.EmptyTypes;
|
||||
}
|
||||
|
||||
var types = _ChildrenCache.GetValue(type);
|
||||
|
||||
if (types == null)
|
||||
{
|
||||
var asm = ScriptCompiler.Assemblies.With(Core.Assembly, Assembly.GetCallingAssembly()).ToList();
|
||||
|
||||
asm.Prune();
|
||||
|
||||
types = asm.Select(GetTypeCache).SelectMany(o => o.Where(t => !IsEqual(t, type) && IsChildOf(t, type))).ToList();
|
||||
|
||||
asm.Free(true);
|
||||
|
||||
if (types.Count > 0 && types.Count <= 0x100)
|
||||
{
|
||||
_ChildrenCache[type] = types;
|
||||
}
|
||||
}
|
||||
|
||||
if (_ChildrenCache.Count >= 0x100)
|
||||
{
|
||||
_ChildrenCache.Pop().Value.Free(true);
|
||||
}
|
||||
|
||||
return predicate != null ? types.Where(predicate) : types.AsEnumerable();
|
||||
}
|
||||
|
||||
public static Type[] GetConstructableChildren(this Type type, Func<Type, bool> predicate = null)
|
||||
{
|
||||
return FindConstructableChildren(type, predicate).ToArray();
|
||||
}
|
||||
|
||||
public static IEnumerable<Type> FindConstructableChildren(this Type type, Func<Type, bool> predicate = null)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
return Type.EmptyTypes;
|
||||
}
|
||||
|
||||
var types = _ConstructableChildrenCache.GetValue(type);
|
||||
|
||||
if (types == null)
|
||||
{
|
||||
types = FindChildren(type).Where(t => IsConstructableFrom(t, type)).ToList();
|
||||
|
||||
if (types.Count > 0 && types.Count <= 0x100)
|
||||
{
|
||||
_ConstructableChildrenCache[type] = types;
|
||||
}
|
||||
}
|
||||
|
||||
if (_ConstructableChildrenCache.Count >= 0x100)
|
||||
{
|
||||
_ConstructableChildrenCache.Pop().Value.Free(true);
|
||||
}
|
||||
|
||||
return predicate != null ? types.Where(predicate) : types.AsEnumerable();
|
||||
}
|
||||
|
||||
public static TObj CreateInstance<TObj>(this Type t, params object[] args)
|
||||
{
|
||||
if (t == null || t.IsAbstract || t.IsInterface || t.IsEnum)
|
||||
{
|
||||
return default(TObj);
|
||||
}
|
||||
|
||||
if (args == null || args.Length == 0)
|
||||
{
|
||||
return (TObj)Activator.CreateInstance(t, true);
|
||||
}
|
||||
|
||||
return (TObj)Activator.CreateInstance(t, args);
|
||||
}
|
||||
|
||||
public static TObj CreateInstanceSafe<TObj>(this Type t, params object[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
return CreateInstance<TObj>(t, args);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e = new TypeConstructException(t, new StackTrace(1, true), e);
|
||||
|
||||
e.ToConsole(true, true);
|
||||
|
||||
return default(TObj);
|
||||
}
|
||||
}
|
||||
|
||||
public static object CreateInstanceUnsafe(this Type t, params object[] args)
|
||||
{
|
||||
return CreateInstance<object>(t, args);
|
||||
}
|
||||
|
||||
public static object CreateInstance(this Type t, params object[] args)
|
||||
{
|
||||
return CreateInstanceSafe<object>(t, args);
|
||||
}
|
||||
}
|
||||
|
||||
public class TypeConstructException : Exception
|
||||
{
|
||||
private readonly string _Trace;
|
||||
|
||||
public override string StackTrace => _Trace;
|
||||
|
||||
public TypeConstructException(Type type, StackTrace trace, Exception inner)
|
||||
: base("Type Construction Failed: " + type.FullName, inner)
|
||||
{
|
||||
_Trace = trace.ToString();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return base.ToString() + "\n\n" + _Trace;
|
||||
}
|
||||
}
|
||||
}
|
||||
32
Scripts/SubSystem/VitaNex/Core/Extensions/System/UriExt.cs
Normal file
32
Scripts/SubSystem/VitaNex/Core/Extensions/System/UriExt.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System.Collections.Generic;
|
||||
|
||||
using VitaNex.Web;
|
||||
#endregion
|
||||
|
||||
namespace System
|
||||
{
|
||||
public static class UriExtUtility
|
||||
{
|
||||
public static IEnumerable<KeyValuePair<string, string>> DecodeQueryString(this Uri uri)
|
||||
{
|
||||
return WebAPI.DecodeQuery(uri.Query);
|
||||
}
|
||||
|
||||
public static Uri EncodeQueryString(this Uri uri, IEnumerable<KeyValuePair<string, string>> queries)
|
||||
{
|
||||
return new Uri(uri.GetLeftPart(UriPartial.Path) + WebAPI.EncodeQuery(queries));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user