Overwrite

Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
Unstable Kitsune
2023-11-28 23:20:26 -05:00
parent 3cd54811de
commit b918192e4e
11608 changed files with 2644205 additions and 47 deletions

View File

@@ -0,0 +1,114 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using System;
using System.Drawing;
using System.Text.RegularExpressions;
#endregion
namespace VitaNex.Text
{
public static class BBCodeUtility
{
/*
(Description) (Syntax) (Args) (Examples)
Line Break: [br] [br]
URL: [url] link [/url] [url]http://www.google.com[/url]
URL Labeled: [url=arg] text [/url] hyperlink [url=http://www.google.com]Google Search[/url]
Center Align: [center] text [/center] [center]Hello World[/center]
Left Align: [left] text [/left] [left]Hello World[/left]
Right Align: [right] text [/right] [right]Hello World[/right]
Small Font: [small] text [/small] [small]Hello World[/small]
Big Font: [big] text [/big] [big]Hello World[/big]
Bold: [b] text [/b] [b]Hello World[/b]
Italic: [i] text [/i] [i]Hello World[/i]
Underline: [u] text [/u] [u]Hello World[/u]
Strikeout: [s] text [/s] [s]Hello World[/s]
Font Size: [size=arg] text [/size] int 1 - 4 [size=4]Hello World[/color]
Font Color: [color=arg] text [/color] hex x6 [color=#FFFFFF]Hello World[/color]
**********: ************************* named color [color=white]Hello World[/color]
*/
public static RegexOptions DefaultRegexOptions = RegexOptions.IgnoreCase | RegexOptions.Singleline;
public static readonly Regex RegexLineBreak = new Regex(@"\[br\]", DefaultRegexOptions),
RegexCenterText = new Regex(@"\[center\](.+?)\[\/center\]", DefaultRegexOptions),
RegexLeftText = new Regex(@"\[left\](.+?)\[\/left\]", DefaultRegexOptions),
RegexRightText = new Regex(@"\[right\](.+?)\[\/right\]", DefaultRegexOptions),
RegexSmallText = new Regex(@"\[small\](.+?)\[\/small\]", DefaultRegexOptions),
RegexBigText = new Regex(@"\[big\](.+?)\[\/big\]", DefaultRegexOptions),
RegexBoldText = new Regex(@"\[b\](.+?)\[\/b\]", DefaultRegexOptions),
RegexItalicText = new Regex(@"\[i\](.+?)\[\/i\]", DefaultRegexOptions),
RegexUnderlineText = new Regex(@"\[u\](.+?)\[\/u\]", DefaultRegexOptions),
RegexStrikeOutText = new Regex(@"\[s\](.+?)\[\/s\]", DefaultRegexOptions),
RegexUrl = new Regex(@"\[url\](.+?)\[\/url\]", DefaultRegexOptions),
RegexUrlAnchored = new Regex(@"\[url=([^\]]+)\]([^\]]+)\[\/url\]", DefaultRegexOptions),
RegexColorAnchored = new Regex(@"\[color=([^\]]+)\]([^\]]+)\[\/color\]", DefaultRegexOptions),
RegexSizeAnchored = new Regex(@"\[size=([^\]]+)\]([^\]]+)\[\/size\]", DefaultRegexOptions),
RegexImage = new Regex(@"\[img\](.+?)\[\/img\]", DefaultRegexOptions),
RegexImageAnchored = new Regex(@"\[img=([^\]]+)\]([^\]]+)\[\/img\]", DefaultRegexOptions),
RegexStripMisc = new Regex(@"\[([^\]]+)\]([^\]]+)\[\/[^\]]+\]", DefaultRegexOptions);
public static string ParseBBCode(
this string input,
Color? defaultColor = null,
int defaultSize = 2,
bool imgAsLink = true,
bool stripMisc = false)
{
if (String.IsNullOrWhiteSpace(input))
{
return input ?? String.Empty;
}
input = RegexLineBreak.Replace(input, "<br>");
input = RegexCenterText.Replace(input, "<center>$1</center>");
input = RegexLeftText.Replace(input, "<left>$1</left>");
input = RegexRightText.Replace(input, "<right>$1</right>");
input = RegexSmallText.Replace(input, "<small>$1</small>");
input = RegexBigText.Replace(input, "<big>$1</big>");
input = RegexBoldText.Replace(input, "<b>$1</b>");
input = RegexItalicText.Replace(input, "<i>$1</i>");
input = RegexUnderlineText.Replace(input, "<u>$1</u>");
input = RegexStrikeOutText.Replace(input, "<s>$1</s>");
input = RegexUrl.Replace(input, "<a href=\"$1\">$1</a>");
input = RegexUrlAnchored.Replace(input, "<a href=\"$1\">$2</a>");
if (imgAsLink)
{
input = RegexImage.Replace(input, "<a href=\"$1\">$1</a>");
input = RegexImageAnchored.Replace(input, "<a href=\"$1\">$2</a>");
}
input = RegexSizeAnchored.Replace(input, "<basefont size=$1>$2<basefont size=" + defaultSize + ">");
if (defaultColor != null)
{
input = RegexColorAnchored.Replace(
input,
"<basefont color=$1>$2<basefont color=#" + defaultColor.Value.ToRgb().ToString("X6") + ">");
}
else
{
input = RegexColorAnchored.Replace(input, "<basefont color=$1>$2");
}
if (stripMisc)
{
input = RegexStripMisc.Replace(input, "($1) $2");
}
return input;
}
}
}

View File

@@ -0,0 +1,52 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using System.Text;
#endregion
namespace VitaNex.Text
{
public enum EncodingType
{
Default,
ASCII,
Unicode,
BigEndianUnicode,
UTF7,
UTF8,
UTF32
}
public static class EncodingUtility
{
public static Encoding GetEncoding(this EncodingType e)
{
switch (e)
{
case EncodingType.ASCII:
return Encoding.ASCII;
case EncodingType.Unicode:
return Encoding.Unicode;
case EncodingType.BigEndianUnicode:
return Encoding.BigEndianUnicode;
case EncodingType.UTF7:
return Encoding.UTF7;
case EncodingType.UTF8:
return Encoding.UTF8;
case EncodingType.UTF32:
return Encoding.UTF32;
default:
return Encoding.Default;
}
}
}
}

View File

@@ -0,0 +1,762 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
#endregion
namespace VitaNex.Text
{
public static class Json
{
public static Encoding DefaultEncoding = Encoding.UTF8;
/// <summary>
/// Input: IDictionary (Object), IEnumerable (Array), Simple Types
/// </summary>
public static string Encode(object value)
{
return Encode(value, out JsonException _);
}
/// <summary>
/// Input: IDictionary (Object), IEnumerable (Array), Simple Types
/// </summary>
public static string Encode(object value, out JsonException e)
{
if (Encode(value, out var json, out e))
{
return json;
}
return null;
}
/// <summary>
/// Input: IDictionary (Object), IEnumerable (Array), Simple Types
/// </summary>
public static bool Encode(object value, out string json)
{
return Encode(value, out json, out _);
}
/// <summary>
/// Input: IDictionary (Object), IEnumerable (Array), Simple Types
/// </summary>
public static bool Encode(object value, out string json, out JsonException e)
{
json = null;
e = null;
try
{
var sb = new StringBuilder(0x800);
if (SerializeValue(0, value, sb))
{
json = sb.ToString();
return true;
}
int line;
int col;
var sub = sb.ToString();
var idx = Math.Max(sub.LastIndexOf('\r'), sub.LastIndexOf('\n'));
if (idx > -1)
{
line = 1 + sub.Count(c => c == '\r' || c == '\n');
col = sub.Length - idx;
}
else
{
line = 1;
col = sub.Length;
}
sub = sub.Substring(Math.Max(0, sub.Length - 16));
e = new JsonException(String.Format("Encoding failed at line {0} col {1} near {2}", line, col, sub));
}
catch (Exception x)
{
if (x is JsonException)
{
e = (JsonException)x;
}
else
{
e = new JsonException("Encoding failed", x);
}
}
return false;
}
/// <summary>
/// Output: Dictionary[string, object] (Object), IEnumerable[object] (Array), Simple Types
/// </summary>
public static object Decode(string json)
{
return Decode(json, out JsonException _);
}
/// <summary>
/// Output: Dictionary[string, object] (Object), IEnumerable[object] (Array), Simple Types
/// </summary>
public static object Decode(string json, out JsonException e)
{
if (Decode(json, out var value, out e))
{
return value;
}
return null;
}
/// <summary>
/// Output: Dictionary[string, object] (Object), IEnumerable[object] (Array), Simple Types
/// </summary>
public static bool Decode(string json, out object value)
{
return Decode(json, out value, out _);
}
/// <summary>
/// Output: Dictionary[string, object] (Object), IEnumerable[object] (Array), Simple Types
/// </summary>
public static bool Decode(string json, out object value, out JsonException e)
{
value = null;
e = null;
try
{
var index = 0;
if (DeserializeValue(json, ref index, out value))
{
return true;
}
int line;
int col;
var sub = json.Substring(0, index);
var idx = Math.Max(sub.LastIndexOf('\r'), sub.LastIndexOf('\n'));
if (idx > -1)
{
line = 1 + sub.Count(c => c == '\r' || c == '\n');
col = index - idx;
}
else
{
line = 1;
col = index;
}
sub = json.Substring(index, Math.Min(16, json.Length - index));
e = new JsonException(String.Format("Decoding failed at line {0} col {1} near {2}", line, col, sub));
}
catch (Exception x)
{
if (x is JsonException)
{
e = (JsonException)x;
}
else
{
e = new JsonException("Decoding failed", x);
}
}
return false;
}
private static bool SerializeValue(int depth, object val, StringBuilder json)
{
if (val is string)
{
return SerializeString((string)val, json);
}
if (val is IDictionary)
{
return SerializeObject(depth, (IDictionary)val, json);
}
if (val is IEnumerable)
{
return SerializeArray(depth, (IEnumerable)val, json);
}
if (val is bool && (bool)val)
{
json.Append("true");
return true;
}
if (val is bool && !(bool)val)
{
json.Append("false");
return true;
}
if (val is char)
{
return SerializeString(val.ToString(), json);
}
if (val is ValueType)
{
if (!(val is IConvertible))
{
return SerializeString(val.ToString(), json);
}
return SerializeNumber(Convert.ToDouble(val), json);
}
if (val == null)
{
json.Append("null");
return true;
}
return SerializeString(val.ToString(), json);
}
private static bool DeserializeValue(string json, ref int index, out object value)
{
value = null;
switch (PeekToken(json, index))
{
case JsonToken.Number:
return DeserializeNumber(json, ref index, out value);
case JsonToken.String:
return DeserializeString(json, ref index, out value);
case JsonToken.ArrayOpen:
return DeserializeArray(json, ref index, out value);
case JsonToken.ObjectOpen:
return DeserializeObject(json, ref index, out value);
case JsonToken.True:
{
PeekToken(json, ref index);
value = true;
}
return true;
case JsonToken.False:
{
PeekToken(json, ref index);
value = false;
}
return true;
case JsonToken.Null:
PeekToken(json, ref index);
return true;
case JsonToken.None:
break;
}
return false;
}
private static bool SerializeNumber(double num, StringBuilder json)
{
json.Append(Convert.ToString(num, CultureInfo.InvariantCulture));
return true;
}
private static bool DeserializeNumber(string json, ref int index, out object value)
{
value = null;
index = SkipWhiteSpace(json, index);
index = PeekNumber(json, index, out var len);
var val = json.Substring(index, len);
if (Double.TryParse(val, NumberStyles.Any, CultureInfo.InvariantCulture, out var num))
{
index += len;
value = num;
return true;
}
return false;
}
private static bool SerializeString(string str, StringBuilder json)
{
json.Append('"');
foreach (var c in str)
{
switch (c)
{
case '"':
json.Append("\\\"");
break;
case '\\':
json.Append("\\\\");
break;
case '\b':
json.Append("\\b");
break;
case '\f':
json.Append("\\f");
break;
case '\n':
json.Append("\\n");
break;
case '\r':
json.Append("\\r");
break;
case '\t':
json.Append("\\t");
break;
default:
{
var sur = Convert.ToInt32(c);
if (sur >= 32 && sur <= 126)
{
json.Append(c);
}
else
{
json.Append("\\u" + Convert.ToString(sur, 16).PadLeft(4, '0'));
}
}
break;
}
}
json.Append('"');
return true;
}
private static bool DeserializeString(string json, ref int index, out object value)
{
value = null;
PeekToken(json, ref index); // " or '
var o = json[index - 1];
var str = new StringBuilder(0x20);
char c;
while (index < json.Length)
{
c = json[index++];
if (c == o)
{
value = str.ToString();
return true;
}
if (c == '\\')
{
if (index == json.Length)
{
break;
}
c = json[index++];
var found = true;
switch (c)
{
case '"':
str.Append('"');
break;
case '\\':
str.Append('\\');
break;
case '/':
str.Append('/');
break;
case 'b':
str.Append('\b');
break;
case 'f':
str.Append('\f');
break;
case 'n':
str.Append('\n');
break;
case 'r':
str.Append('\r');
break;
case 't':
str.Append('\t');
break;
default:
found = false;
break;
}
if (!found && c == 'u')
{
var length = json.Length - index;
if (length < 4)
{
break;
}
var sub = json.Substring(index, 4);
if (!UInt32.TryParse(sub, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var sur))
{
return false;
}
str.Append(Char.ConvertFromUtf32((int)sur));
index += 4;
}
}
else
{
str.Append(c);
}
}
return false;
}
private static bool SerializeArray(int depth, IEnumerable arr, StringBuilder json)
{
var tabs = new string('\t', depth++);
var line = "\r\n" + tabs;
var success = true;
json.Append((depth > 1 ? line : String.Empty) + '[');
var first = true;
foreach (var value in arr)
{
if (!first)
{
json.Append(", ");
}
json.Append(line + '\t');
if (!SerializeValue(depth, value, json))
{
success = false;
break;
}
first = false;
}
if (success)
{
json.Append(line + ']');
}
return success;
}
private static bool DeserializeArray(string json, ref int index, out object value)
{
value = null;
PeekToken(json, ref index); // [
var arr = new List<object>();
while (index < json.Length)
{
switch (PeekToken(json, index))
{
case JsonToken.None:
return false;
case JsonToken.Comma:
PeekToken(json, ref index); // ,
break;
case JsonToken.ArrayClose:
{
PeekToken(json, ref index); // ]
value = arr;
}
return true;
default:
{
if (!DeserializeValue(json, ref index, out var val))
{
return false;
}
arr.Add(val);
}
break;
}
}
return false;
}
private static bool SerializeObject(int depth, IDictionary obj, StringBuilder json)
{
var tabs = new string('\t', depth++);
var line = "\r\n" + tabs;
var success = true;
json.Append((depth > 1 ? line : String.Empty) + '{');
var first = true;
var e = obj.GetEnumerator();
while (e.MoveNext())
{
var key = e.Key?.ToString() ?? String.Empty;
var value = e.Value;
if (!first)
{
json.Append(", ");
}
json.Append(line + '\t');
if (!SerializeString(key, json))
{
success = false;
break;
}
json.Append(": ");
if (!SerializeValue(depth, value, json))
{
success = false;
break;
}
first = false;
}
if (success)
{
json.Append(line + '}');
}
return success;
}
private static bool DeserializeObject(string json, ref int index, out object value)
{
value = null;
PeekToken(json, ref index); // {
var obj = new Dictionary<string, object>();
while (index < json.Length)
{
switch (PeekToken(json, index))
{
case JsonToken.None:
return false;
case JsonToken.Comma:
PeekToken(json, ref index); // ,
break;
case JsonToken.ObjectClose:
{
PeekToken(json, ref index); // }
value = obj;
}
return true;
default:
{
if (!DeserializeString(json, ref index, out var name))
{
return false;
}
if (PeekToken(json, ref index) != JsonToken.Colon) // :
{
return false;
}
if (!DeserializeValue(json, ref index, out var val))
{
return false;
}
obj[(string)name] = val;
}
break;
}
}
return false;
}
private static int SkipWhiteSpace(string json, int index)
{
while (index < json.Length)
{
if (Char.IsWhiteSpace(json[index]) || json[index] == '\r' || json[index] == '\n')
{
++index;
}
else
{
break;
}
}
return index;
}
private static int PeekNumber(string json, int index, out int length)
{
length = 0;
while (index < json.Length)
{
var c = json[index];
if (c == '-' && length > 0)
{
break;
}
if (!Char.IsDigit(c) && c != '-')
{
if ((c == 'e' || c == 'E') && index + 1 < json.Length && json[index + 1] == '+')
{
length += 2;
index += 2;
continue;
}
if (c == '.' && index + 1 < json.Length && Char.IsDigit(json[index + 1]))
{
length += 2;
index += 2;
continue;
}
break;
}
++length;
++index;
}
return index - length;
}
private static JsonToken PeekToken(string json, int index)
{
return PeekToken(json, ref index);
}
private static JsonToken PeekToken(string json, ref int index)
{
index = SkipWhiteSpace(json, index);
if (index >= json.Length)
{
return JsonToken.None;
}
var c = json[index++];
switch (c)
{
case '{':
return JsonToken.ObjectOpen;
case '}':
return JsonToken.ObjectClose;
case '[':
return JsonToken.ArrayOpen;
case ']':
return JsonToken.ArrayClose;
case ',':
return JsonToken.Comma;
case '"':
case '\'':
return JsonToken.String;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '-':
return JsonToken.Number;
case ':':
return JsonToken.Colon;
}
--index;
var length = json.Length - index;
// false
if (length >= 5 && json.IndexOf("false", index, StringComparison.OrdinalIgnoreCase) == index)
{
index += 5;
return JsonToken.False;
}
// true
if (length >= 4 && json.IndexOf("true", index, StringComparison.OrdinalIgnoreCase) == index)
{
index += 4;
return JsonToken.True;
}
// null
if (length >= 4 && json.IndexOf("null", index, StringComparison.OrdinalIgnoreCase) == index)
{
index += 4;
return JsonToken.Null;
}
return JsonToken.None;
}
}
}

View File

@@ -0,0 +1,36 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using System;
using System.Runtime.Serialization;
#endregion
namespace VitaNex.Text
{
public class JsonException : Exception
{
public JsonException()
{ }
public JsonException(string message)
: base(message)
{ }
public JsonException(string message, Exception innerException)
: base(message, innerException)
{ }
protected JsonException(SerializationInfo info, StreamingContext context)
: base(info, context)
{ }
}
}

View File

@@ -0,0 +1,29 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
namespace VitaNex.Text
{
public enum JsonToken
{
None = 0,
ObjectOpen,
ObjectClose,
ArrayOpen,
ArrayClose,
Colon,
Comma,
String,
Number,
True,
False,
Null
}
}

View File

@@ -0,0 +1,165 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using System;
using System.Collections.Generic;
#endregion
namespace VitaNex.Text
{
public class IndependentLanguagePack
{
private readonly Dictionary<int, string> _Definitions = new Dictionary<int, string>();
/// <summary>
/// Gets the string at the given index, or String.Empty if undefined
/// </summary>
public virtual string this[int index]
{
get => _Definitions.ContainsKey(index) ? _Definitions[index] ?? String.Empty : String.Empty;
set
{
if (_Definitions.ContainsKey(index))
{
_Definitions[index] = value;
}
else
{
_Definitions.Add(index, value);
}
}
}
/// <summary>
/// Checks if the given index has a defined entry.
/// </summary>
public bool IsDefined(int index)
{
return !String.IsNullOrEmpty(this[index]);
}
/// <summary>
/// Sets the value of the given index
/// </summary>
public void Define(int index, string value)
{
this[index] = value;
}
/// <summary>
/// Sets the value of the given index
/// </summary>
public string ToString(int index)
{
return this[index];
}
/// <summary>
/// Gets a formatted message string at the given index using the specified optional parameters to be included during
/// formatting
/// </summary>
public string Format(int index, params object[] args)
{
return String.Format(this[index], args);
}
}
public class LanguagePack
{
/// <summary>
/// A table used for overriding cliloc text for each language
/// </summary>
private readonly Dictionary<ClilocLNG, Dictionary<int, string>> _TableMutations =
new Dictionary<ClilocLNG, Dictionary<int, string>>
{
{ClilocLNG.ENU, new Dictionary<int, string>()},
{ClilocLNG.DEU, new Dictionary<int, string>()},
{ClilocLNG.ESP, new Dictionary<int, string>()},
{ClilocLNG.FRA, new Dictionary<int, string>()},
{ClilocLNG.JPN, new Dictionary<int, string>()},
{ClilocLNG.KOR, new Dictionary<int, string>()},
{ClilocLNG.CHT, new Dictionary<int, string>()}
};
/// <summary>
/// Default constructor
/// </summary>
public LanguagePack(ClilocLNG lng = ClilocLNG.ENU)
{
Language = lng;
}
/// <summary>
/// Current language used by this instance
/// </summary>
public virtual ClilocLNG Language { get; protected set; }
/// <summary>
/// Gets a cliloc table using this instance' selected language
/// </summary>
protected virtual ClilocTable Table => Clilocs.Tables[Language];
/// <summary>
/// Gets the string at the given index, or String.Empty if undefined
/// </summary>
public virtual string this[int index]
{
get => !Table.IsNullOrWhiteSpace(index)
? (_TableMutations[Language].ContainsKey(index) ? _TableMutations[Language][index] : Table[index].Text)
: (_TableMutations[Language].ContainsKey(index) ? _TableMutations[Language][index] : String.Empty);
set
{
if (_TableMutations[Language].ContainsKey(index))
{
_TableMutations[Language][index] = value;
}
else
{
_TableMutations[Language].Add(index, value);
}
}
}
/// <summary>
/// Checks if the given index has a defined entry.
/// </summary>
public bool IsDefined(int index)
{
return !String.IsNullOrEmpty(this[index]);
}
/// <summary>
/// Sets the value of the given index
/// </summary>
public void Define(int index, string value)
{
this[index] = value;
}
/// <summary>
/// Sets the value of the given index
/// </summary>
public string ToString(int index)
{
return this[index];
}
/// <summary>
/// Gets a formatted message string at the given index using the specified optional parameters to be included during
/// formatting
/// </summary>
public string Format(int index, params object[] args)
{
return String.Format(this[index], args);
}
}
}

View File

@@ -0,0 +1,66 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using System;
using Server;
#endregion
namespace VitaNex.Text
{
[Flags]
public enum StringSearchFlags
{
None = 0x0,
Equals = 0x1,
Contains = 0x2,
StartsWith = 0x4,
EndsWith = 0x8
}
public static class StringSearch
{
public static bool Execute(this StringSearchFlags flags, string haystack, string needle, bool ignoreCase)
{
if (flags == StringSearchFlags.None || haystack == null || needle == null)
{
return false;
}
if (flags.HasFlag(StringSearchFlags.Equals) &&
(ignoreCase ? Insensitive.Equals(haystack, needle) : haystack.Equals(needle)))
{
return true;
}
if (flags.HasFlag(StringSearchFlags.Contains) &&
(ignoreCase ? Insensitive.Contains(haystack, needle) : haystack.Contains(needle)))
{
return true;
}
if (flags.HasFlag(StringSearchFlags.StartsWith) &&
(ignoreCase ? Insensitive.StartsWith(haystack, needle) : haystack.StartsWith(needle)))
{
return true;
}
if (flags.HasFlag(StringSearchFlags.EndsWith) &&
(ignoreCase ? Insensitive.EndsWith(haystack, needle) : haystack.EndsWith(needle)))
{
return true;
}
return false;
}
}
}

View File

@@ -0,0 +1,57 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using System.Drawing;
#endregion
namespace VitaNex.Text
{
public enum SystemFont
{
Default,
Arial,
Tahoma,
Terminal,
Verdana
}
public static class Fonts
{
public static readonly Font Default = new Font("Arial", 12);
public static readonly Font Arial = new Font("Arial", 12);
public static readonly Font Tahoma = new Font("Tahoma", 12);
public static readonly Font Terminal = new Font("Terminal", 12);
public static readonly Font Verdana = new Font("Verdana", 12);
public static Font Dupe(this Font font, float emSize = 12, FontStyle style = FontStyle.Regular)
{
return new Font(font.FontFamily.Name, emSize, style);
}
public static Font ToFont(this SystemFont font, float emSize = 12, FontStyle style = FontStyle.Regular)
{
switch (font)
{
case SystemFont.Arial:
return Dupe(Arial, emSize, style);
case SystemFont.Tahoma:
return Dupe(Tahoma, emSize, style);
case SystemFont.Terminal:
return Dupe(Terminal, emSize, style);
case SystemFont.Verdana:
return Dupe(Verdana, emSize, style);
default:
return Dupe(Default, emSize, style);
}
}
}
}

View File

@@ -0,0 +1,769 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using Server;
using PF = System.Drawing.Imaging.PixelFormat;
#endregion
namespace VitaNex.Text
{
public enum UOEncoding : byte
{
Ascii,
Unicode
}
public enum UOFontStyle
{
Big = 0,
Normal = 1,
Small = 2
}
public sealed class UOFonts
{
private static readonly UOFont[] _Ascii;
private static readonly UOFont[] _Unicode;
private static readonly UOChar[][][] _Chars;
private static readonly byte[] _EmptyBuffer = new byte[0];
static UOFonts()
{
_Ascii = new UOFont[10];
_Unicode = new UOFont[13];
_Chars = new UOChar[2][][];
}
private static string FindFontFile(string file, params object[] args)
{
if (!args.IsNullOrEmpty())
{
file = String.Format(file, args);
}
var path = Path.Combine(Core.BaseDirectory, "Data", "Fonts", file);
if (!File.Exists(path))
{
path = Core.FindDataFile(file);
}
return path;
}
private static Bitmap NewEmptyImage()
{
return new Bitmap(UOFont.DefaultCharSize.Width, UOFont.DefaultCharSize.Height, UOFont.PixelFormat);
}
private static UOChar NewEmptyChar(UOEncoding enc)
{
return new UOChar(enc, 0, 0, NewEmptyImage());
}
private static UOFont Instantiate(UOEncoding enc, byte id)
{
int charsWidth = 0, charsHeight = 0;
var list = _Chars[(byte)enc][id];
var i = list.Length;
while (--i >= 0)
{
charsWidth = Math.Max(charsWidth, list[i].XOffset + list[i].Width);
charsHeight = Math.Max(charsHeight, list[i].YOffset + list[i].Height);
}
return new UOFont(enc, id, 1, 4, (byte)charsWidth, (byte)charsHeight, list);
}
private static UOFont LoadAscii(byte id)
{
if (id >= _Ascii.Length)
{
return null;
}
const UOEncoding enc = UOEncoding.Ascii;
var idx = (byte)enc;
if (_Chars.InBounds(idx, id) && _Chars[idx][id] != null)
{
return _Ascii[id] ?? (_Ascii[id] = Instantiate(enc, id));
}
var fonts = _Chars[idx] ?? (_Chars[idx] = new UOChar[_Ascii.Length][]);
var chars = fonts[id] ?? (fonts[id] = new UOChar[256]);
var path = FindFontFile("fonts.mul");
if (path == null || !File.Exists(path))
{
chars.SetAll(NewEmptyChar(enc));
return _Ascii[id] ?? (_Ascii[id] = Instantiate(enc, id));
}
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
{
using (var bin = new BinaryReader(fs))
{
for (var i = 0; i <= id; i++)
{
bin.ReadByte(); // header
if (i == id)
{
for (var c = 0; c < 32; c++)
{
chars[c] = NewEmptyChar(enc);
}
}
for (var c = 32; c < chars.Length; c++)
{
var width = bin.ReadByte();
var height = bin.ReadByte();
bin.ReadByte(); // unk
if (i == id)
{
var buffer = _EmptyBuffer;
if (width * height > 0)
{
buffer = bin.ReadBytes((width * height) * 2);
}
chars[c] = new UOChar(enc, 0, 0, GetImage(width, height, buffer, enc));
}
else
{
bin.BaseStream.Seek((width * height) * 2, SeekOrigin.Current);
}
}
}
}
}
return _Ascii[id] ?? (_Ascii[id] = Instantiate(enc, id));
}
private static UOFont LoadUnicode(byte id)
{
if (id >= _Unicode.Length)
{
return null;
}
const UOEncoding enc = UOEncoding.Unicode;
var idx = (byte)enc;
if (_Chars.InBounds(idx, id) && _Chars[idx][id] != null)
{
return _Unicode[id] ?? (_Unicode[id] = Instantiate(enc, id));
}
var fonts = _Chars[idx] ?? (_Chars[idx] = new UOChar[_Unicode.Length][]);
var chars = fonts[id] ?? (fonts[id] = new UOChar[65536]);
var filePath = FindFontFile("unifont{0:#}.mul", id);
if (filePath == null)
{
chars.SetAll(NewEmptyChar(enc));
return _Unicode[id] ?? (_Unicode[id] = Instantiate(enc, id));
}
using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
using (var bin = new BinaryReader(fs))
{
for (int c = 0, o; c < chars.Length; c++)
{
fs.Seek(c * 4, SeekOrigin.Begin);
o = bin.ReadInt32();
if (o <= 0 || o >= fs.Length)
{
chars[c] = NewEmptyChar(enc);
continue;
}
fs.Seek(o, SeekOrigin.Begin);
var x = bin.ReadSByte(); // x-offset
var y = bin.ReadSByte(); // y-offset
var width = bin.ReadByte();
var height = bin.ReadByte();
var buffer = _EmptyBuffer;
if (width * height > 0)
{
buffer = bin.ReadBytes(height * (((width - 1) / 8) + 1));
}
chars[c] = new UOChar(enc, x, y, GetImage(width, height, buffer, enc));
}
}
}
return _Unicode[id] ?? (_Unicode[id] = Instantiate(enc, id));
}
private static unsafe Bitmap GetImage(int width, int height, byte[] buffer, UOEncoding enc)
{
if (width * height <= 0 || buffer.IsNullOrEmpty())
{
return NewEmptyImage();
}
var image = new Bitmap(width, height, UOFont.PixelFormat);
var bound = new Rectangle(0, 0, width, height);
var data = image.LockBits(bound, ImageLockMode.WriteOnly, UOFont.PixelFormat);
var index = 0;
var line = (ushort*)data.Scan0;
var delta = data.Stride >> 1;
int x, y;
ushort pixel;
for (y = 0; y < height; y++, line += delta)
{
var cur = line;
if (cur == null)
{
continue;
}
for (x = 0; x < width; x++)
{
pixel = 0;
if (enc > 0)
{
index = x / 8 + y * ((width + 7) / 8);
}
if (index < buffer.Length)
{
if (enc > 0)
{
pixel = buffer[index];
}
else
{
pixel = (ushort)(buffer[index++] | (buffer[index++] << 8));
}
}
if (enc > 0)
{
pixel &= (ushort)(1 << (7 - (x % 8)));
}
if (pixel == 0)
{
cur[x] = 0;
}
else if (enc > 0)
{
cur[x] = 0x8000;
}
else
{
cur[x] = (ushort)(pixel ^ 0x8000);
}
}
}
image.UnlockBits(data);
return image;
}
public static UOFont GetFont(UOEncoding enc, byte id)
{
switch (enc)
{
case UOEncoding.Ascii:
return LoadAscii(id);
case UOEncoding.Unicode:
return LoadUnicode(id);
}
return null;
}
public static UOFont GetAscii(byte id)
{
return GetFont(UOEncoding.Ascii, id);
}
public static UOFont GetUnicode(byte id)
{
return GetFont(UOEncoding.Unicode, id);
}
public static Bitmap GetImage(UOFont font, char c)
{
return font[c].GetImage();
}
public UOEncoding Encoding { get; private set; }
public UOFont this[int id] => GetFont(Encoding, (byte)id);
public int Count { get; private set; }
public byte DefaultID { get; private set; }
public UOFonts(UOEncoding enc)
{
Encoding = enc;
switch (Encoding)
{
case UOEncoding.Ascii:
{
Count = _Ascii.Length;
DefaultID = 3;
}
break;
case UOEncoding.Unicode:
{
Count = _Unicode.Length;
DefaultID = 1;
}
break;
}
}
public Bitmap GetImage(byte font, char c)
{
if (font >= Count)
{
font = DefaultID;
}
return GetImage(this[font], c);
}
public int GetWidth(byte font, string text)
{
if (font >= Count)
{
font = DefaultID;
}
return this[font].GetWidth(text);
}
public int GetHeight(byte font, string text)
{
if (font >= Count)
{
font = DefaultID;
}
return this[font].GetHeight(text);
}
public Size GetSize(byte font, string text)
{
if (font >= Count)
{
font = DefaultID;
}
return this[font].GetSize(text);
}
public int GetWidth(byte font, params string[] lines)
{
if (font >= Count)
{
font = DefaultID;
}
return this[font].GetWidth(lines);
}
public int GetHeight(byte font, params string[] lines)
{
if (font >= Count)
{
font = DefaultID;
}
return this[font].GetHeight(lines);
}
public Size GetSize(byte font, params string[] lines)
{
if (font >= Count)
{
font = DefaultID;
}
return this[font].GetSize(lines);
}
}
public sealed class UOFont
{
#if MONO
public const PF PixelFormat = PF.Format32bppArgb;
#else
public const PF PixelFormat = PF.Format16bppArgb1555;
#endif
public static Size DefaultCharSize = new Size(8, 10);
public static UOFonts Ascii { get; private set; }
public static UOFonts Unicode { get; private set; }
static UOFont()
{
Ascii = new UOFonts(UOEncoding.Ascii);
Unicode = new UOFonts(UOEncoding.Unicode);
for (var i = 0; i <= 1; i++)
{
VitaNexCore.ToConsole("[UOFont]: Preloaded {0}", Unicode[i]);
}
}
public static void Configure()
{ }
public static UOFont GetFont(UOEncoding enc, byte id)
{
return UOFonts.GetFont(enc, id);
}
public static UOFont GetAscii(byte id)
{
return UOFonts.GetFont(UOEncoding.Ascii, id);
}
public static UOFont GetUnicode(byte id)
{
return UOFonts.GetFont(UOEncoding.Unicode, id);
}
public static Bitmap GetImage(UOFont font, char c)
{
return UOFonts.GetImage(font, c);
}
public static Bitmap GetAsciiImage(byte font, char c)
{
return Ascii.GetImage(font, c);
}
public static Bitmap GetUnicodeImage(byte font, char c)
{
return Unicode.GetImage(font, c);
}
public static int GetAsciiWidth(byte font, string text)
{
return Ascii.GetWidth(font, text);
}
public static int GetAsciiHeight(byte font, string text)
{
return Ascii.GetHeight(font, text);
}
public static Size GetAsciiSize(byte font, string text)
{
return Ascii.GetSize(font, text);
}
public static int GetAsciiWidth(byte font, params string[] lines)
{
return Ascii.GetWidth(font, lines);
}
public static int GetAsciiHeight(byte font, params string[] lines)
{
return Ascii.GetHeight(font, lines);
}
public static Size GetAsciiSize(byte font, params string[] lines)
{
return Ascii.GetSize(font, lines);
}
public static int GetUnicodeWidth(byte font, string text)
{
return Unicode.GetWidth(font, text);
}
public static int GetUnicodeHeight(byte font, string text)
{
return Unicode.GetHeight(font, text);
}
public static Size GetUnicodeSize(byte font, string text)
{
return Unicode.GetSize(font, text);
}
public static int GetUnicodeWidth(byte font, params string[] lines)
{
return Unicode.GetWidth(font, lines);
}
public static int GetUnicodeHeight(byte font, params string[] lines)
{
return Unicode.GetHeight(font, lines);
}
public static Size GetUnicodeSize(byte font, params string[] lines)
{
return Unicode.GetSize(font, lines);
}
public UOEncoding Encoding { get; private set; }
public byte ID { get; private set; }
public byte MaxCharWidth { get; private set; }
public byte MaxCharHeight { get; private set; }
public byte CharSpacing { get; private set; }
public byte LineSpacing { get; private set; }
public byte LineHeight { get; private set; }
public UOChar[] Chars { get; private set; }
public int Length => Chars.Length;
public UOChar this[char c] => Chars[c % Length];
public UOChar this[int i] => Chars[i % Length];
public UOFont(
UOEncoding enc,
byte id,
byte charSpacing,
byte lineSpacing,
byte charsWidth,
byte charsHeight,
UOChar[] chars)
{
Encoding = enc;
ID = id;
CharSpacing = charSpacing;
LineSpacing = lineSpacing;
MaxCharWidth = charsWidth;
MaxCharHeight = charsHeight;
Chars = chars;
}
public int GetWidth(string value)
{
return GetSize(value).Width;
}
public int GetHeight(string value)
{
return GetSize(value).Height;
}
public Size GetSize(string value)
{
var lines = value.Split('\n');
if (lines.Length == 0)
{
lines = new[] { value };
}
return GetSize(lines);
}
public int GetWidth(params string[] lines)
{
return GetSize(lines).Width;
}
public int GetHeight(params string[] lines)
{
return GetSize(lines).Height;
}
public Size GetSize(params string[] lines)
{
var w = 0;
var h = 0;
var space = Chars[' '];
UOChar ci;
foreach (var line in lines.SelectMany(o => o.Contains('\n') ? o.Split('\n') : o.ToEnumerable()))
{
var lw = 0;
var lh = 0;
foreach (var c in line)
{
if (c == '\t')
{
lw += (CharSpacing + space.Width) * 4;
continue;
}
ci = this[c];
if (ci == null)
{
lw += (CharSpacing + space.Width);
continue;
}
lw += (CharSpacing + ci.XOffset + ci.Width);
lh = Math.Max(lh, ci.YOffset + ci.Height);
}
w = Math.Max(w, lw);
h += lh + LineSpacing;
}
return new Size(w, h);
}
public override string ToString()
{
return String.Format("({0}, {1}, {2})", Encoding, ID, Length);
}
}
public sealed class UOChar
{
public Bitmap Image { get; private set; }
public UOEncoding Encoding { get; private set; }
public sbyte XOffset { get; private set; }
public sbyte YOffset { get; private set; }
public byte Width { get; private set; }
public byte Height { get; private set; }
public UOChar(UOEncoding enc, sbyte ox, sbyte oy, Bitmap image)
{
Encoding = enc;
XOffset = ox;
YOffset = oy;
Image = image;
Width = (byte)Image.Width;
Height = (byte)Image.Height;
}
public Bitmap GetImage()
{
return GetImage(false);
}
public Bitmap GetImage(bool fill)
{
return GetImage(fill, Color555.White);
}
public Bitmap GetImage(bool fill, Color555 bgColor)
{
return GetImage(fill, bgColor, Color555.Black);
}
public unsafe Bitmap GetImage(bool fill, Color555 bgColor, Color555 textColor)
{
if (Width * Height <= 0)
{
return null;
}
var image = new Bitmap(Width, Height, UOFont.PixelFormat);
var bound = new Rectangle(0, 0, Width, Height);
var dataSrc = Image.LockBits(bound, ImageLockMode.ReadOnly, UOFont.PixelFormat);
var lineSrc = (ushort*)dataSrc.Scan0;
var deltaSrc = dataSrc.Stride >> 1;
var dataTrg = image.LockBits(bound, ImageLockMode.WriteOnly, UOFont.PixelFormat);
var lineTrg = (ushort*)dataTrg.Scan0;
var deltaTrg = dataTrg.Stride >> 1;
int x, y;
for (y = 0; y < Height; y++, lineSrc += deltaSrc, lineTrg += deltaTrg)
{
var source = lineSrc;
var target = lineTrg;
if (source == null || target == null)
{
continue;
}
for (x = 0; x < Width; x++)
{
if (source[x] != 0)
{
target[x] = textColor;
}
else if (fill)
{
target[x] = bgColor;
}
}
}
Image.UnlockBits(dataSrc);
image.UnlockBits(dataTrg);
return image;
}
}
}

View File

@@ -0,0 +1,107 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
namespace VitaNex.Text
{
public static class UniGlyph
{
public const char Infinity = '\u221E';
public const char Cross1 = '\u2020';
public const char Cross2 = '\u2021';
public const char WingLeft = '\u261C';
public const char WingRight = '\u261E';
public const char ChevronLeft = '\u00AB';
public const char ChevronRight = '\u00BB';
public const char ChevronLeftLarge = '\u226A';
public const char ChevronRightLarge = '\u226B';
public const char ArrowLeft = '\u2190';
public const char ArrowUp = '\u2191';
public const char ArrowRight = '\u2192';
public const char ArrowDown = '\u2193';
public const char ArrowLeftRight = '\u2194';
public const char ArrowUpDown = '\u2195';
public const char ArrowNW = '\u2196';
public const char ArrowNE = '\u2197';
public const char ArrowSE = '\u2198';
public const char ArrowSW = '\u2199';
public const char CircleX = '\u203B';
public const char CircleDot = '\u25C9';
public const char CircleFill = '\u25CF';
public const char CircleEmpty = '\u25CB';
public const char CircleLeftFill = '\u25D0';
public const char CircleRightFill = '\u25D1';
public const char TriUpEmpty = '\u25B3';
public const char TriUpFill = '\u25B2';
public const char TriRightEmpty = '\u25B7';
public const char TriRightFill = '\u25B6';
public const char TriDownEmpty = '\u25BD';
public const char TriDownFill = '\u25BC';
public const char TriLeftEmpty = '\u25C1';
public const char TriLeftFill = '\u25C0';
public const char StarFill = '\u2605';
public const char StarEmpty = '\u2606';
public const char DiamondFill = '\u25C6';
public const char DiamondEmpty = '\u25C7';
public const char SpadeFill = '\u2660';
public const char SpadeEmpty = '\u2664';
public const char HeartFill = '\u2665';
public const char HeartEmpty = '\u2661';
public const char ClubFill = '\u2663';
public const char ClubEmpty = '\u2667';
public const char NoteCrotchet = '\u2669';
public const char NoteQuaver = '\u266A';
public const char NoteQuaver2 = '\u266C';
public const char Coffee = '\u2668';
public const char HashTag = '\u266F';
public const char CurrencyCent = '\u00A2';
public const char CurrencyUSD = '\u0024';
public const char CurrencyGBP = '\u00A3';
public const char CurrencyYEN = '\u00A5';
public const char CurrencySIM = '\u00A7';
public const char CurrencyEUR = '\u0404';
public const char CircleNum1 = '\u2460';
public const char CircleNum2 = '\u2461';
public const char CircleNum3 = '\u2462';
public const char CircleNum4 = '\u2463';
public const char CircleNum5 = '\u2464';
public const char CircleNum6 = '\u2465';
public const char CircleNum7 = '\u2466';
public const char CircleNum8 = '\u2467';
public const char CircleNum9 = '\u2468';
public const char CircleNum10 = '\u2469';
public const char CircleNum11 = '\u246A';
public const char CircleNum12 = '\u246B';
public const char CircleNum13 = '\u246C';
public const char CircleNum14 = '\u246D';
public const char CircleNum15 = '\u246E';
public const char CircleNum16 = '\u246F';
public const char CircleNum17 = '\u2470';
public const char CircleNum18 = '\u2471';
public const char CircleNum19 = '\u2472';
public const char CircleNum20 = '\u2473';
}
}