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,517 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using Server;
using Server.Commands;
using VitaNex.Collections;
using VitaNex.IO;
using VitaNex.Network;
#endregion
namespace VitaNex
{
public static partial class Clilocs
{
private static readonly Dictionary<Type, int> _TypeCache = new Dictionary<Type, int>(0x1000);
private static readonly ObjectProperty _LabelNumberProp = new ObjectProperty("LabelNumber");
private static readonly ClilocLNG[] _Languages = default(ClilocLNG).EnumerateValues<ClilocLNG>().Not(o => o == ClilocLNG.NULL).ToArray();
public static readonly Regex VarPattern = new Regex(@"~(?<index>\d+)(?<sep>_*)(?<desc>\w*)~", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled);
public static readonly Regex NumPattern = new Regex(@"#(?<index>\d+)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled);
public static ClilocLNG DefaultLanguage { get; set; } = ClilocLNG.ENU;
public static CoreServiceOptions CSOptions { get; private set; }
public static Dictionary<ClilocLNG, ClilocTable> Tables { get; private set; }
private static void ExportCommand(CommandEventArgs e)
{
if (e.Mobile?.Deleted != false)
{
return;
}
e.Mobile.SendMessage(0x55, "Export requested...");
if (e.Arguments?.Length > 0 && !String.IsNullOrWhiteSpace(e.Arguments[0]))
{
if (Enum.TryParse(e.Arguments[0], true, out ClilocLNG lng) && lng != ClilocLNG.NULL)
{
VitaNexCore.TryCatch(() =>
{
var file = Export(lng);
if (file != null && file.Exists && file.Length > 0)
{
e.Mobile.SendMessage(0x55, $"{lng} clilocs have been exported to: {file.FullName}");
}
else
{
e.Mobile.SendMessage(0x22, $"Could not export clilocs for {lng}");
}
},
ex =>
{
e.Mobile.SendMessage(0x22, "A fatal exception occurred, check the console for details.");
CSOptions.ToConsole(ex);
});
return;
}
}
e.Mobile.SendMessage($"Usage: {CommandSystem.Prefix}{e.Command} <{String.Join(" | ", _Languages)}>");
}
public static FileInfo Export(ClilocLNG lng)
{
if (lng == ClilocLNG.NULL)
{
lng = DefaultLanguage;
}
var list = new XmlDataStore<int, ClilocData>(VitaNexCore.DataDirectory + "/Exported Clilocs/", lng.ToString());
var table = Tables[lng];
list.OnSerialize = doc =>
{
XmlNode node;
XmlCDataSection cdata;
ClilocInfo info;
XmlNode root = doc.CreateElement("clilocs");
var attr = doc.CreateAttribute("len");
attr.Value = table.Count.ToString(CultureInfo.InvariantCulture);
if (root.Attributes != null)
{
root.Attributes.Append(attr);
}
attr = doc.CreateAttribute("lng");
attr.Value = table.Language.ToString();
if (root.Attributes != null)
{
root.Attributes.Append(attr);
}
foreach (var d in table)
{
if (d.Length <= 0)
{
continue;
}
info = d.Lookup(table.InputFile, true);
if (String.IsNullOrWhiteSpace(info?.Text))
{
continue;
}
node = doc.CreateElement("cliloc");
attr = doc.CreateAttribute("idx");
attr.Value = d.Index.ToString(CultureInfo.InvariantCulture);
if (node.Attributes != null)
{
node.Attributes.Append(attr);
}
attr = doc.CreateAttribute("len");
attr.Value = d.Length.ToString(CultureInfo.InvariantCulture);
if (node.Attributes != null)
{
node.Attributes.Append(attr);
}
cdata = doc.CreateCDataSection(info.Text);
node.AppendChild(cdata);
root.AppendChild(node);
}
doc.AppendChild(root);
table.Clear();
return true;
};
list.Export();
list.Clear();
return list.Document;
}
public static ClilocInfo Lookup(this ClilocLNG lng, Type type)
{
if (type == null)
{
return null;
}
if (lng == ClilocLNG.NULL)
{
lng = DefaultLanguage;
}
try
{
if (_TypeCache.TryGetValue(type, out var index))
{
if (index < 0)
{
return null;
}
return Lookup(lng, index);
}
if (!_LabelNumberProp.IsSupported(typeof(int), type))
{
return null;
}
var o = type.CreateInstanceSafe<object>();
if (o != null)
{
index = _LabelNumberProp.GetValue(o, -1); // LabelNumber_get()
o.InvokeMethod("Delete");
}
else
{
index = -1;
}
_TypeCache[type] = index;
if (index >= 0)
{
return Lookup(lng, index);
}
}
catch
{
}
return null;
}
public static ClilocInfo Lookup(this ClilocLNG lng, int index)
{
if (index < 0)
{
return null;
}
if (lng == ClilocLNG.NULL)
{
lng = DefaultLanguage;
}
if (Tables.TryGetValue(lng, out var table) && !table.IsNullOrWhiteSpace(index))
{
return table[index];
}
if (lng != ClilocLNG.ENU)
{
return Lookup(ClilocLNG.ENU, index);
}
return null;
}
public static string GetRawString(this ClilocLNG lng, int index)
{
if (index < 0)
{
return null;
}
if (lng == ClilocLNG.NULL)
{
lng = DefaultLanguage;
}
if (Tables.TryGetValue(lng, out var table) && !table.IsNullOrWhiteSpace(index))
{
return table[index]?.Text ?? String.Empty;
}
if (lng != ClilocLNG.ENU)
{
return GetRawString(ClilocLNG.ENU, index);
}
return String.Empty;
}
public static string GetString(this ClilocLNG lng, int index, StringBuilder args)
{
return Lookup(lng, index)?.ToString(args) ?? String.Empty;
}
public static string GetString(this ClilocLNG lng, int index, string args)
{
return Lookup(lng, index)?.ToString(args) ?? String.Empty;
}
public static string GetString(this ClilocLNG lng, int index, params object[] args)
{
return Lookup(lng, index)?.ToString(args) ?? String.Empty;
}
public static string GetString(this ClilocLNG lng, Type type)
{
return Lookup(lng, type)?.ToString() ?? String.Empty;
}
public static string GetString(this TextDefinition text)
{
return GetString(text, DefaultLanguage);
}
public static string GetString(this TextDefinition text, Mobile m)
{
return GetString(text, GetLanguage(m));
}
public static string GetString(this TextDefinition text, ClilocLNG lng)
{
if (ReferenceEquals(text, null))
{
return String.Empty;
}
return text.Number > 0 ? GetString(lng, text.Number) : (text.String ?? String.Empty);
}
public static bool IsNullOrEmpty(this TextDefinition text)
{
if (ReferenceEquals(text, null))
{
return true;
}
return text.Number <= 0 && String.IsNullOrEmpty(text.String) && String.IsNullOrEmpty(GetString(text));
}
public static bool IsNullOrWhiteSpace(this TextDefinition text)
{
if (ReferenceEquals(text, null))
{
return true;
}
return text.Number <= 0 && String.IsNullOrWhiteSpace(text.String) && String.IsNullOrWhiteSpace(GetString(text));
}
private static IEnumerable<T> Enumerate<T>(ObjectPropertyList list, ClilocLNG lng, bool lookup, Func<int, string, T> selector)
{
if (list?.Entity?.Deleted != false || selector == null)
{
yield break;
}
if (lng == ClilocLNG.NULL)
{
lng = DefaultLanguage;
}
ObjectPool.Acquire(out StringBuilder param);
var data = list.GetBuffer();
var index = 15;
while (index + 4 < data.Length)
{
var num = data[index++] << 24 | data[index++] << 16 | data[index++] << 8 | data[index++];
if (index + 2 > data.Length)
{
break;
}
var paramLength = data[index++] << 8 | data[index++];
if (paramLength > 0)
{
var terminate = index + paramLength;
if (terminate >= data.Length)
{
terminate = data.Length - 1;
}
while (index + 2 <= terminate + 1)
{
if ((data[index++] | data[index++] << 8) == 0)
{
break;
}
param.Append(Encoding.Unicode.GetChars(data, index - 2, 2));
}
}
yield return selector(num, lookup ? GetString(lng, num, param) : String.Empty);
param.Clear();
}
ObjectPool.Free(ref param);
}
public static IEnumerable<int> EnumerateNumbers(this ObjectPropertyList list)
{
return Enumerate(list, DefaultLanguage, false, (id, text) => id);
}
public static IEnumerable<string> EnumerateLines(this ObjectPropertyList list)
{
return EnumerateLines(list, DefaultLanguage);
}
public static IEnumerable<string> EnumerateLines(this ObjectPropertyList list, Mobile m)
{
return EnumerateLines(list, GetLanguage(m));
}
public static IEnumerable<string> EnumerateLines(this ObjectPropertyList list, ClilocLNG lng)
{
return Enumerate(list, lng, true, (id, text) => text);
}
public static IEnumerable<TextDefinition> EnumerateEntries(this ObjectPropertyList list)
{
return EnumerateEntries(list, DefaultLanguage);
}
public static IEnumerable<TextDefinition> EnumerateEntries(this ObjectPropertyList list, Mobile m)
{
return EnumerateEntries(list, GetLanguage(m));
}
public static IEnumerable<TextDefinition> EnumerateEntries(this ObjectPropertyList list, ClilocLNG lng)
{
return Enumerate(list, lng, true, (id, text) => new TextDefinition(id, text));
}
public static string[] DecodePropertyList(this ObjectPropertyList list)
{
return DecodePropertyList(list, DefaultLanguage);
}
public static string[] DecodePropertyList(this ObjectPropertyList list, Mobile m)
{
return DecodePropertyList(list, GetLanguage(m));
}
public static string[] DecodePropertyList(this ObjectPropertyList list, ClilocLNG lng)
{
return EnumerateLines(list, lng).ToArray();
}
public static string DecodePropertyListHeader(this ObjectPropertyList list)
{
return DecodePropertyListHeader(list, DefaultLanguage);
}
public static string DecodePropertyListHeader(this ObjectPropertyList list, Mobile v)
{
return DecodePropertyListHeader(list, GetLanguage(v));
}
public static string DecodePropertyListHeader(this ObjectPropertyList list, ClilocLNG lng)
{
return EnumerateLines(list, lng).FirstOrDefault() ?? String.Empty;
}
public static string[] GetAllLines(this ObjectPropertyList list)
{
return DecodePropertyList(list);
}
public static string[] GetAllLines(this ObjectPropertyList list, ClilocLNG lng)
{
return DecodePropertyList(list, lng);
}
public static string GetHeader(this ObjectPropertyList list)
{
return DecodePropertyListHeader(list);
}
public static string GetHeader(this ObjectPropertyList list, ClilocLNG lng)
{
return DecodePropertyListHeader(list, lng);
}
public static string[] GetBody(this ObjectPropertyList list)
{
return GetBody(list, DefaultLanguage);
}
public static string[] GetBody(this ObjectPropertyList list, ClilocLNG lng)
{
return EnumerateLines(list, lng).Skip(1).ToArray();
}
public static bool Contains(this ObjectPropertyList list, int num)
{
return IndexOf(list, num) != -1;
}
public static int IndexOf(this ObjectPropertyList list, int num)
{
return EnumerateNumbers(list).IndexOf(num);
}
public static ClilocLNG GetLanguage(this Mobile m)
{
if (m == null)
{
return ClilocLNG.NULL;
}
if (!Enum.TryParse(m.Language, out ClilocLNG lng))
{
lng = ClilocLNG.ENU;
}
return lng;
}
}
}

View File

@@ -0,0 +1,90 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Server;
using VitaNex.IO;
#endregion
namespace VitaNex
{
[CoreService("Clilocs", "1.0.0.0", TaskPriority.High)]
public static partial class Clilocs
{
static Clilocs()
{
CSOptions = new CoreServiceOptions(typeof(Clilocs));
Tables = new Dictionary<ClilocLNG, ClilocTable>
{
{ClilocLNG.ENU, new ClilocTable()},
{ClilocLNG.DEU, new ClilocTable()},
{ClilocLNG.ESP, new ClilocTable()},
{ClilocLNG.FRA, new ClilocTable()},
{ClilocLNG.JPN, new ClilocTable()},
{ClilocLNG.KOR, new ClilocTable()},
{ClilocLNG.CHT, new ClilocTable()}
};
}
private static void CSConfig()
{
CommandUtility.Register("ExportCliloc", AccessLevel.Administrator, ExportCommand);
var tables = new List<ClilocTable>(Tables.Values);
//bool noFind = false;
Core.DataDirectories.TakeWhile(path => !tables.TrueForAll(t => t.Loaded))
.Where(path => !String.IsNullOrWhiteSpace(path))
.ForEach(
path => Parallel.ForEach(
Tables,
kvp =>
{
if (kvp.Value.Loaded)
{
return;
}
var file = "Cliloc." + kvp.Key.ToString().ToLower();
var stub = IOUtility.GetSafeFilePath(path + "/" + file, true);
if (!File.Exists(stub))
{
//CSOptions.ToConsole("WARNING: {0} not found!", file);
//noFind = true;
return;
}
kvp.Value.Load(new FileInfo(stub));
}));
/*if (noFind)
{
CSOptions.ToConsole(
"WARNING: One or more required cliloc files could not be loaded, any features that rely on this service will not work as expected and/or may cause a fatal exception!");
}*/
tables.Free(true);
}
private static void CSInvoke()
{ }
}
}

View File

@@ -0,0 +1,68 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using System.IO;
using System.Text;
using Server;
#endregion
namespace VitaNex
{
public sealed class ClilocData
{
private ClilocInfo _Info;
public ClilocLNG Language { get; private set; }
public int Index { get; private set; }
public long Offset { get; private set; }
public long Length { get; private set; }
public ClilocData(ClilocLNG lng, int index, long offset, long length)
{
Language = lng;
Index = index;
Offset = offset;
Length = length;
}
public void Clear()
{
_Info = null;
}
public void Load(GenericReader bin)
{
bin.Seek(Offset, SeekOrigin.Begin);
var data = new byte[Length];
for (long i = 0; i < data.Length; i++)
{
data[i] = bin.ReadByte();
}
_Info = new ClilocInfo(Language, Index, Encoding.UTF8.GetString(data));
}
public ClilocInfo Lookup(FileInfo file, bool forceUpdate = false)
{
if (_Info == null || forceUpdate)
{
VitaNexCore.TryCatch(f => f.Deserialize(Load), file, Clilocs.CSOptions.ToConsole);
}
return _Info;
}
}
}

View File

@@ -0,0 +1,153 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using System;
using System.Linq;
using System.Text;
using System.Threading;
using Server;
using VitaNex.Collections;
#endregion
namespace VitaNex
{
public sealed class ClilocInfo : IDisposable
{
private volatile object[] _Buffer;
public ClilocLNG Language { get; private set; }
public int Index { get; private set; }
public int Count { get; private set; }
public string Text { get; private set; }
public string Format { get; private set; }
public bool HasArgs { get; private set; }
public ClilocInfo(ClilocLNG lng, int index, string text)
{
Language = lng;
Index = index;
Text = text ?? String.Empty;
Format = Clilocs.VarPattern.Replace(Text, e => $"{{{Count++}}}");
HasArgs = Count > 0;
}
private string Compile(object[] args)
{
if (!HasArgs)
{
return Text;
}
if (args == null)
{
args = Array.Empty<object>();
}
if (_Buffer == null)
{
_Buffer = new object[Count];
}
var sep = Count > 1 ? "\t" : null;
var max = Math.Max(args.Length, _Buffer.Length);
var lim = _Buffer.Length - 1;
for (var i = 0; i < max; i++)
{
if (i >= _Buffer.Length)
{
_Buffer[lim] = $"{_Buffer[lim]} {args[i]}";
}
else if (i < args.Length)
{
if (i < lim)
{
_Buffer[i] = $"{args[i]}{sep}";
}
else
{
_Buffer[i] = args[i];
}
}
else
{
if (i < lim)
{
_Buffer[i] = sep;
}
else
{
_Buffer[i] = null;
}
}
}
var result = String.Format(Format, _Buffer);
Array.Clear(_Buffer, 0, _Buffer.Length);
return Clilocs.NumPattern.Replace(result, match =>
{
if (Int32.TryParse(match.Groups["index"].Value, out var sid))
{
return Clilocs.GetRawString(Language, sid);
}
return match.Value;
});
}
public override string ToString()
{
return Text;
}
public string ToString(StringBuilder args)
{
return ToString(args?.ToString());
}
public string ToString(string args)
{
return ToString(args?.Split('\t'));
}
public string ToString(params object[] args)
{
return Compile(args);
}
public TextDefinition ToDefinition()
{
return new TextDefinition(Index, Text);
}
void IDisposable.Dispose()
{
GC.SuppressFinalize(this);
_Buffer = null;
Text = null;
Format = null;
}
}
}

View File

@@ -0,0 +1,56 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
namespace VitaNex
{
public enum ClilocLNG
{
NULL,
ENU,
DEU,
ESP,
FRA,
JPN,
KOR,
CHT
}
public static class ClilocLNGExt
{
public static string ToFullString(this ClilocLNG lng)
{
if (lng == ClilocLNG.NULL)
{
lng = Clilocs.DefaultLanguage;
}
switch (lng)
{
case ClilocLNG.ENU:
return "English";
case ClilocLNG.DEU:
return "German";
case ClilocLNG.ESP:
return "Spanish";
case ClilocLNG.FRA:
return "French";
case ClilocLNG.JPN:
return "Japanese";
case ClilocLNG.KOR:
return "Korean";
case ClilocLNG.CHT:
return "Chinese";
}
return lng.ToString();
}
}
}

View File

@@ -0,0 +1,189 @@
#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.IO;
using System.Threading.Tasks;
using Server;
#endregion
namespace VitaNex
{
public sealed class ClilocTable : IEnumerable<ClilocData>, IDisposable
{
private readonly Dictionary<int, ClilocData> _Table = new Dictionary<int, ClilocData>();
public int Count => _Table.Count;
public ClilocLNG Language { get; private set; }
public FileInfo InputFile { get; private set; }
public bool Loaded { get; private set; }
public ClilocInfo this[int index] => Lookup(index);
public void Dispose()
{
Unload();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _Table.Values.GetEnumerator();
}
public IEnumerator<ClilocData> GetEnumerator()
{
return _Table.Values.GetEnumerator();
}
public void Clear()
{
foreach (var d in _Table.Values)
{
d.Clear();
}
_Table.Clear();
}
public void Unload()
{
if (!Loaded)
{
return;
}
Language = ClilocLNG.NULL;
InputFile = null;
Clear();
Loaded = false;
}
public void Load(FileInfo file)
{
if (Loaded)
{
if (Insensitive.Equals(file?.FullName, InputFile?.FullName))
{
return;
}
Clear();
}
VitaNexCore.TryCatch(f =>
{
if (!Enum.TryParse(f.Extension.TrimStart('.'), true, out ClilocLNG lng))
{
throw new FileLoadException($"Could not detect language for: {f.FullName}");
}
Language = lng;
InputFile = f;
InputFile.Deserialize(reader =>
{
var size = reader.Seek(0, SeekOrigin.End);
reader.Seek(0, SeekOrigin.Begin);
reader.ReadInt();
reader.ReadShort();
while (reader.Seek(0, SeekOrigin.Current) < size)
{
var index = reader.ReadInt();
reader.ReadByte();
int length = reader.ReadShort();
var offset = reader.Seek(0, SeekOrigin.Current);
reader.Seek(length, SeekOrigin.Current);
_Table[index] = new ClilocData(Language, index, offset, length);
}
});
Loaded = true;
}, file, Clilocs.CSOptions.ToConsole);
}
public bool Contains(int index)
{
return _Table.ContainsKey(index);
}
public bool IsNullOrWhiteSpace(int index)
{
if (!_Table.TryGetValue(index, out var data) || data == null)
{
return true;
}
var info = data.Lookup(InputFile);
if (info == null || String.IsNullOrWhiteSpace(info.Text))
{
return true;
}
return false;
}
public ClilocInfo Update(int index)
{
if (!_Table.TryGetValue(index, out var data) || data == null)
{
return null;
}
return data.Lookup(InputFile, true);
}
public ClilocInfo Lookup(int index)
{
if (!_Table.TryGetValue(index, out var data) || data == null)
{
return null;
}
return data.Lookup(InputFile);
}
public void LookupAll()
{
VitaNexCore.TryCatch(() =>
{
InputFile.Deserialize(reader =>
{
foreach (var d in _Table.Values)
{
VitaNexCore.TryCatch(d.Load, reader, Clilocs.CSOptions.ToConsole);
}
});
}, Clilocs.CSOptions.ToConsole);
}
public override string ToString()
{
return Language == ClilocLNG.NULL ? "Not Loaded" : $"Cliloc.{Language}";
}
}
}