Fixes publishing
This commit is contained in:
parent
6119774dc9
commit
58be0d416c
53 changed files with 981 additions and 1225 deletions
9
.gitignore
vendored
9
.gitignore
vendored
|
|
@ -6,13 +6,14 @@
|
|||
/Distribution/Saves
|
||||
/Distribution/System.IO.Pipelines.dll
|
||||
/Distribution/rdrand.so
|
||||
/Distribution/rdrand32.dll
|
||||
/Distribution/rdrand64.dll
|
||||
/Distribution/zlib32.dll
|
||||
/Distribution/zlib64.dll
|
||||
/Distribution/rdrand.dll
|
||||
/Distribution/zlib.dll
|
||||
/Projects/Scripts/obj
|
||||
/Projects/Scripts/bin
|
||||
/Projects/Server/obj
|
||||
/Projects/Server/bin
|
||||
|
||||
*.log
|
||||
*.user
|
||||
/.idea
|
||||
/.vs
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ namespace Server.Commands
|
|||
break;
|
||||
}
|
||||
|
||||
Type type = ScriptCompiler.FindTypeByName(name);
|
||||
Type type = AssemblyHandler.FindTypeByName(name);
|
||||
|
||||
if (!IsEntity(type))
|
||||
{
|
||||
|
|
@ -241,7 +241,7 @@ namespace Server.Commands
|
|||
try
|
||||
{
|
||||
if (IsEnum(type)) return Enum.Parse(type, value, true);
|
||||
if (IsType(type)) return ScriptCompiler.FindTypeByName(value);
|
||||
if (IsType(type)) return AssemblyHandler.FindTypeByName(value);
|
||||
if (IsParsable(type)) return ParseParsable(type, value);
|
||||
object obj = value;
|
||||
|
||||
|
|
|
|||
|
|
@ -1016,7 +1016,7 @@ namespace Server.Commands
|
|||
|
||||
int indexOf = line.IndexOf(' ');
|
||||
|
||||
list.m_Type = ScriptCompiler.FindTypeByName(line.Substring(0, indexOf++), true);
|
||||
list.m_Type = AssemblyHandler.FindTypeByName(line.Substring(0, indexOf++), true);
|
||||
|
||||
if (list.m_Type == null)
|
||||
throw new ArgumentException($"Type not found for header: '{line}'");
|
||||
|
|
|
|||
|
|
@ -1014,7 +1014,7 @@ namespace Server.Commands
|
|||
|
||||
int indexOf = line.IndexOf(' ');
|
||||
|
||||
list.m_Type = ScriptCompiler.FindTypeByName(line.Substring(0, indexOf++), true);
|
||||
list.m_Type = AssemblyHandler.FindTypeByName(line.Substring(0, indexOf++), true);
|
||||
|
||||
if (list.m_Type == null)
|
||||
throw new ArgumentException($"Type not found for header: '{line}'");
|
||||
|
|
|
|||
|
|
@ -667,7 +667,7 @@ namespace Server.Commands
|
|||
List<Assembly> assemblies = new List<Assembly> { Core.Assembly };
|
||||
|
||||
|
||||
foreach (Assembly asm in ScriptCompiler.Assemblies)
|
||||
foreach (Assembly asm in AssemblyHandler.Assemblies)
|
||||
assemblies.Add(asm);
|
||||
|
||||
Assembly[] asms = assemblies.ToArray();
|
||||
|
|
|
|||
|
|
@ -144,8 +144,8 @@ namespace Server.Commands
|
|||
|
||||
AddTypes(Core.Assembly, types);
|
||||
|
||||
for (int i = 0; i < ScriptCompiler.Assemblies.Length; ++i)
|
||||
AddTypes(ScriptCompiler.Assemblies[i], types);
|
||||
for (int i = 0; i < AssemblyHandler.Assemblies.Length; ++i)
|
||||
AddTypes(AssemblyHandler.Assemblies[i], types);
|
||||
|
||||
m_RootItems = Load(types, "Data/items.cfg");
|
||||
m_RootMobiles = Load(types, "Data/mobiles.cfg");
|
||||
|
|
@ -315,7 +315,7 @@ namespace Server.Commands
|
|||
|
||||
for (int i = 0; i < split.Length; ++i)
|
||||
{
|
||||
Type type = ScriptCompiler.FindTypeByName(split[i].Trim());
|
||||
Type type = AssemblyHandler.FindTypeByName(split[i].Trim());
|
||||
|
||||
if (type == null)
|
||||
Console.WriteLine("Match type not found ('{0}')", split[i].Trim());
|
||||
|
|
|
|||
|
|
@ -444,7 +444,7 @@ namespace Server.Commands.Generic
|
|||
{
|
||||
if (e.Length >= 1)
|
||||
{
|
||||
Type t = ScriptCompiler.FindTypeByName(e.GetString(0));
|
||||
Type t = AssemblyHandler.FindTypeByName(e.GetString(0));
|
||||
|
||||
if (t == null)
|
||||
{
|
||||
|
|
@ -1108,4 +1108,4 @@ namespace Server.Commands.Generic
|
|||
LogFailure("No house was found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ namespace Server.Commands.Generic
|
|||
|
||||
int index = 0;
|
||||
|
||||
Type objectType = ScriptCompiler.FindTypeByName(args[offset + index], true);
|
||||
Type objectType = AssemblyHandler.FindTypeByName(args[offset + index], true);
|
||||
|
||||
if (objectType == null)
|
||||
throw new Exception($"No type with that name ({args[offset + index]}) was found.");
|
||||
|
|
|
|||
|
|
@ -290,7 +290,7 @@ namespace Server.Commands
|
|||
int count = bin.ReadInt32();
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
types.Add(ScriptCompiler.FindTypeByFullName(bin.ReadString()));
|
||||
types.Add(AssemblyHandler.FindTypeByFullName(bin.ReadString()));
|
||||
}
|
||||
|
||||
long total = 0;
|
||||
|
|
|
|||
|
|
@ -418,7 +418,7 @@ namespace Server.Commands
|
|||
else if (IsType(type))
|
||||
try
|
||||
{
|
||||
toSet = ScriptCompiler.FindTypeByName(value);
|
||||
toSet = AssemblyHandler.FindTypeByName(value);
|
||||
|
||||
if (toSet == null)
|
||||
return "No type with that name was found.";
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ namespace Server.Engines.BulkOrders
|
|||
string type = reader.ReadString();
|
||||
|
||||
if (type != null)
|
||||
ItemType = ScriptCompiler.FindTypeByFullName(type);
|
||||
ItemType = AssemblyHandler.FindTypeByFullName(type);
|
||||
|
||||
AmountCur = reader.ReadEncodedInt();
|
||||
Number = reader.ReadEncodedInt();
|
||||
|
|
@ -53,4 +53,4 @@ namespace Server.Engines.BulkOrders
|
|||
writer.WriteEncodedInt(Graphic);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ namespace Server.Engines.BulkOrders
|
|||
string type = reader.ReadString();
|
||||
|
||||
if (type != null)
|
||||
ItemType = ScriptCompiler.FindTypeByFullName(type);
|
||||
ItemType = AssemblyHandler.FindTypeByFullName(type);
|
||||
|
||||
RequireExceptional = reader.ReadBool();
|
||||
|
||||
|
|
@ -97,4 +97,4 @@ namespace Server.Engines.BulkOrders
|
|||
writer.WriteEncodedInt(Price);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ namespace Server.Engines.BulkOrders
|
|||
string type = reader.ReadString();
|
||||
|
||||
if ( type != null )
|
||||
realType = ScriptCompiler.FindTypeByFullName( type );
|
||||
realType = AssemblyHandler.FindTypeByFullName( type );
|
||||
|
||||
Details = new SmallBulkEntry( realType, reader.ReadInt(), reader.ReadInt() );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ namespace Server.Engines.BulkOrders
|
|||
string type = reader.ReadString();
|
||||
|
||||
if (type != null)
|
||||
Type = ScriptCompiler.FindTypeByFullName(type);
|
||||
Type = AssemblyHandler.FindTypeByFullName(type);
|
||||
|
||||
m_Number = reader.ReadInt();
|
||||
Graphic = reader.ReadInt();
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ namespace Server.Engines.BulkOrders
|
|||
|
||||
if ( split.Length >= 2 )
|
||||
{
|
||||
Type type = ScriptCompiler.FindTypeByName( split[0] );
|
||||
Type type = AssemblyHandler.FindTypeByName( split[0] );
|
||||
int graphic = Utility.ToInt32( split[split.Length - 1] );
|
||||
|
||||
if ( type != null && graphic > 0 )
|
||||
|
|
|
|||
|
|
@ -299,7 +299,7 @@ namespace Server.Engines.Doom
|
|||
if (TypeName == null)
|
||||
return;
|
||||
|
||||
Type type = ScriptCompiler.FindTypeByName(TypeName, true);
|
||||
Type type = AssemblyHandler.FindTypeByName(TypeName, true);
|
||||
|
||||
if (type == null)
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -49,12 +49,12 @@ namespace Server.Factions
|
|||
m_Factions = new List<Faction>();
|
||||
m_Towns = new List<Town>();
|
||||
|
||||
Assembly[] asms = ScriptCompiler.Assemblies;
|
||||
Assembly[] asms = AssemblyHandler.Assemblies;
|
||||
|
||||
for (int i = 0; i < asms.Length; ++i)
|
||||
{
|
||||
Assembly asm = asms[i];
|
||||
TypeCache tc = ScriptCompiler.GetTypeCache(asm);
|
||||
TypeCache tc = AssemblyHandler.GetTypeCache(asm);
|
||||
Type[] types = tc.Types;
|
||||
|
||||
for (int j = 0; j < types.Length; ++j)
|
||||
|
|
@ -75,4 +75,4 @@ namespace Server.Factions
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ namespace Server.Engines.MLQuests.Items
|
|||
string typeName = reader.ReadString();
|
||||
|
||||
if (typeName != null)
|
||||
m_QuestType = ScriptCompiler.FindTypeByFullName(typeName, false);
|
||||
m_QuestType = AssemblyHandler.FindTypeByFullName(typeName, false);
|
||||
|
||||
Message = TextDefinition.Deserialize(reader);
|
||||
}
|
||||
|
|
@ -186,7 +186,7 @@ namespace Server.Engines.MLQuests.Items
|
|||
string typeName = reader.ReadString();
|
||||
|
||||
if (typeName != null)
|
||||
m_TicketType = ScriptCompiler.FindTypeByFullName(typeName, false);
|
||||
m_TicketType = AssemblyHandler.FindTypeByFullName(typeName, false);
|
||||
|
||||
Message = TextDefinition.Deserialize(reader);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ namespace Server.Engines.MLQuests
|
|||
|
||||
string[] split = line.Split('\t');
|
||||
|
||||
Type type = ScriptCompiler.FindTypeByName(split[0]);
|
||||
Type type = AssemblyHandler.FindTypeByName(split[0]);
|
||||
|
||||
if (type == null || !baseQuestType.IsAssignableFrom(type))
|
||||
{
|
||||
|
|
@ -76,7 +76,7 @@ namespace Server.Engines.MLQuests
|
|||
|
||||
for (int i = 1; i < split.Length; ++i)
|
||||
{
|
||||
Type questerType = ScriptCompiler.FindTypeByName(split[i]);
|
||||
Type questerType = AssemblyHandler.FindTypeByName(split[i]);
|
||||
|
||||
if (questerType == null || !baseQuesterType.IsAssignableFrom(questerType))
|
||||
{
|
||||
|
|
@ -157,7 +157,7 @@ namespace Server.Engines.MLQuests
|
|||
return;
|
||||
}
|
||||
|
||||
Type index = ScriptCompiler.FindTypeByName(e.GetString(0));
|
||||
Type index = AssemblyHandler.FindTypeByName(e.GetString(0));
|
||||
|
||||
if (index == null || !Quests.TryGetValue(index, out MLQuest quest))
|
||||
{
|
||||
|
|
@ -183,7 +183,7 @@ namespace Server.Engines.MLQuests
|
|||
return;
|
||||
}
|
||||
|
||||
Type index = ScriptCompiler.FindTypeByName(e.GetString(0));
|
||||
Type index = AssemblyHandler.FindTypeByName(e.GetString(0));
|
||||
|
||||
if (index == null || !Quests.TryGetValue(index, out MLQuest quest))
|
||||
{
|
||||
|
|
@ -638,7 +638,7 @@ namespace Server.Engines.MLQuests
|
|||
if (typeName == null)
|
||||
return null; // not serialized
|
||||
|
||||
Type questType = ScriptCompiler.FindTypeByFullName(typeName);
|
||||
Type questType = AssemblyHandler.FindTypeByFullName(typeName);
|
||||
|
||||
if (questType == null)
|
||||
return null; // no longer a type
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ namespace Server.Engines.Quests
|
|||
if (fullName == null)
|
||||
return null;
|
||||
|
||||
return ScriptCompiler.FindTypeByFullName(fullName, false);
|
||||
return AssemblyHandler.FindTypeByFullName(fullName, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -185,4 +185,4 @@ namespace Server.Engines.Quests
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ namespace Server.Mobiles
|
|||
{
|
||||
public static Type GetType(string name)
|
||||
{
|
||||
return ScriptCompiler.FindTypeByName(name);
|
||||
return AssemblyHandler.FindTypeByName(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,15 +133,15 @@ namespace Server.Gumps
|
|||
List<Type> results = new List<Type>();
|
||||
Type[] types;
|
||||
|
||||
Assembly[] asms = ScriptCompiler.Assemblies;
|
||||
Assembly[] asms = AssemblyHandler.Assemblies;
|
||||
|
||||
for (int i = 0; i < asms.Length; ++i)
|
||||
{
|
||||
types = ScriptCompiler.GetTypeCache(asms[i]).Types;
|
||||
types = AssemblyHandler.GetTypeCache(asms[i]).Types;
|
||||
Match(match, types, results);
|
||||
}
|
||||
|
||||
types = ScriptCompiler.GetTypeCache(Core.Assembly).Types;
|
||||
types = AssemblyHandler.GetTypeCache(Core.Assembly).Types;
|
||||
Match(match, types, results);
|
||||
|
||||
results.Sort(new TypeNameComparer());
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ namespace Server.Gumps
|
|||
Parent = parent;
|
||||
|
||||
if (xml.MoveToAttribute("type"))
|
||||
Type = ScriptCompiler.FindTypeByFullName(xml.Value, false);
|
||||
Type = AssemblyHandler.FindTypeByFullName(xml.Value, false);
|
||||
|
||||
if (xml.MoveToAttribute("gfx"))
|
||||
ItemID = XmlConvert.ToInt32(xml.Value);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ namespace Server.Items
|
|||
SaveFlag flags = (SaveFlag)reader.ReadEncodedInt();
|
||||
|
||||
if (GetSaveFlag(flags, SaveFlag.Type))
|
||||
Type = ScriptCompiler.FindTypeByFullName(reader.ReadString(), false);
|
||||
Type = AssemblyHandler.FindTypeByFullName(reader.ReadString(), false);
|
||||
|
||||
if (GetSaveFlag(flags, SaveFlag.Name))
|
||||
Name = TextDefinition.Deserialize(reader);
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Any CPU</Platform>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<PublishDir>../Assemblies</PublishDir>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Any CPU</Platform>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<PublishDir>../Assemblies</PublishDir>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
@ -3,16 +3,11 @@
|
|||
<PropertyGroup>
|
||||
<RootNamespace>Server</RootNamespace>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.0'">
|
||||
<DefineConstants>NETCORE;NETSTANDARD</DefineConstants>
|
||||
<AssemblyName>Scripts.CS</AssemblyName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\..\Distribution\Assemblies\</OutputPath>
|
||||
<OutDir>..\..\Distribution\Assemblies</OutDir>
|
||||
<WarningsAsErrors />
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
|
|
@ -22,8 +17,7 @@
|
|||
<DefineConstants>TRACE;DEBUG</DefineConstants>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\..\Distribution\Assemblies\</OutputPath>
|
||||
<OutDir>..\..\Distribution\Assemblies</OutDir>
|
||||
<PublishDir>..\..\Distribution\Assemblies</PublishDir>
|
||||
<WarningsAsErrors />
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
|
|
@ -32,8 +26,7 @@
|
|||
<Content Include="SpecialSystems\README.TXT" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Server\Server.csproj">
|
||||
<Private>false</Private>
|
||||
<ProjectReference Include="..\Server\Server.csproj" Private="false" PrivateAssets="All" IncludeAssets="None">
|
||||
<IncludeInPackage>false</IncludeInPackage>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ namespace Server.Spells
|
|||
{
|
||||
for (int i = 0; i < m_CircleNames.Length; ++i)
|
||||
{
|
||||
Type t = ScriptCompiler.FindTypeByFullName($"Server.Spells.{m_CircleNames[i]}.{name}");
|
||||
Type t = AssemblyHandler.FindTypeByFullName($"Server.Spells.{m_CircleNames[i]}.{name}");
|
||||
|
||||
if (t?.IsSubclassOf(typeof(SpecialMove)) == false)
|
||||
{
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,6 +1,6 @@
|
|||
/***************************************************************************
|
||||
* ScriptCompiler.cs
|
||||
* -------------------
|
||||
* AssemblyHandler.cs
|
||||
* --------------------
|
||||
* begin : May 1, 2002
|
||||
* copyright : (C) The RunUO Software Team
|
||||
* email : info@runuo.com
|
||||
|
|
@ -21,63 +21,31 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
#if NETCORE
|
||||
using System.Reflection;
|
||||
using System.Runtime.Loader;
|
||||
#endif
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public static class ScriptCompiler
|
||||
public static class AssemblyHandler
|
||||
{
|
||||
private static Dictionary<Assembly, TypeCache> m_TypeCaches = new Dictionary<Assembly, TypeCache>();
|
||||
private static TypeCache m_NullCache;
|
||||
public static Assembly[] Assemblies { get; set; }
|
||||
|
||||
public static string ScriptsPath = EnsureDirectory("Assemblies");
|
||||
public static string AssembliesPath = EnsureDirectory("Assemblies");
|
||||
|
||||
public static bool LoadScripts(string path = null)
|
||||
{
|
||||
string[] files = Directory.GetFiles(path ?? ScriptsPath, "*.dll");
|
||||
|
||||
List<Assembly> assemblies = new List<Assembly>();
|
||||
|
||||
AssemblyName[] names = Assembly.GetExecutingAssembly().GetReferencedAssemblies();
|
||||
|
||||
int loaded = 0;
|
||||
|
||||
for (int i = 0; i < files.Length; i++)
|
||||
{
|
||||
#if NETCORE
|
||||
assemblies.Add(AssemblyLoadContext.Default.LoadFromAssemblyPath(files[i]));
|
||||
loaded++;
|
||||
#else
|
||||
Assemblies[i] = Assembly.LoadFrom(files[i]);
|
||||
#endif
|
||||
}
|
||||
|
||||
Assemblies = assemblies.ToArray();
|
||||
|
||||
return loaded > 0;
|
||||
}
|
||||
public static void LoadScripts(string path = null) =>
|
||||
Assemblies = Directory.GetFiles(path ?? AssembliesPath, "*.dll")
|
||||
.Select(t => AssemblyLoadContext.Default.LoadFromAssemblyPath(t)).ToArray();
|
||||
|
||||
public static void Invoke(string method)
|
||||
{
|
||||
List<MethodInfo> invoke = new List<MethodInfo>();
|
||||
|
||||
for (int a = 0; a < Assemblies.Length; ++a)
|
||||
{
|
||||
Type[] types = Assemblies[a].GetTypes();
|
||||
|
||||
for (int i = 0; i < types.Length; ++i)
|
||||
{
|
||||
MethodInfo m = types[i].GetMethod(method, BindingFlags.Static | BindingFlags.Public);
|
||||
|
||||
if (m != null)
|
||||
invoke.Add(m);
|
||||
}
|
||||
}
|
||||
invoke.AddRange(Assemblies[a].GetTypes()
|
||||
.Select(t => t.GetMethod(method, BindingFlags.Static | BindingFlags.Public)).Where(m => m != null));
|
||||
|
||||
invoke.Sort(new CallPriorityComparer());
|
||||
|
||||
|
|
@ -87,20 +55,15 @@ namespace Server
|
|||
|
||||
public static TypeCache GetTypeCache(Assembly asm)
|
||||
{
|
||||
if (asm == null)
|
||||
{
|
||||
return m_NullCache ?? (m_NullCache = new TypeCache(null));
|
||||
}
|
||||
if (!m_TypeCaches.TryGetValue(asm, out TypeCache c))
|
||||
m_TypeCaches[asm] = c = new TypeCache(asm);
|
||||
if (asm == null) return m_NullCache ??= new TypeCache(null);
|
||||
|
||||
return c;
|
||||
if (m_TypeCaches.TryGetValue(asm, out TypeCache c))
|
||||
return c;
|
||||
|
||||
return m_TypeCaches[asm] = new TypeCache(asm);
|
||||
}
|
||||
|
||||
public static Type FindTypeByFullName(string fullName)
|
||||
{
|
||||
return FindTypeByFullName(fullName, true);
|
||||
}
|
||||
public static Type FindTypeByFullName(string fullName) => FindTypeByFullName(fullName, true);
|
||||
|
||||
public static Type FindTypeByFullName(string fullName, bool ignoreCase)
|
||||
{
|
||||
|
|
@ -112,10 +75,7 @@ namespace Server
|
|||
return type ?? GetTypeCache(Core.Assembly).GetTypeByFullName(fullName, ignoreCase);
|
||||
}
|
||||
|
||||
public static Type FindTypeByName(string name)
|
||||
{
|
||||
return FindTypeByName(name, true);
|
||||
}
|
||||
public static Type FindTypeByName(string name) => FindTypeByName(name, true);
|
||||
|
||||
public static Type FindTypeByName(string name, bool ignoreCase)
|
||||
{
|
||||
|
|
@ -142,7 +102,7 @@ namespace Server
|
|||
{
|
||||
public TypeCache(Assembly asm)
|
||||
{
|
||||
Types = asm == null ? Type.EmptyTypes : asm.GetTypes();
|
||||
Types = asm?.GetTypes() ?? Type.EmptyTypes;
|
||||
|
||||
Names = new TypeTable(Types.Length);
|
||||
FullNames = new TypeTable(Types.Length);
|
||||
|
|
@ -173,15 +133,9 @@ namespace Server
|
|||
|
||||
public TypeTable FullNames{ get; }
|
||||
|
||||
public Type GetTypeByName(string name, bool ignoreCase)
|
||||
{
|
||||
return Names.Get(name, ignoreCase);
|
||||
}
|
||||
public Type GetTypeByName(string name, bool ignoreCase) => Names.Get(name, ignoreCase);
|
||||
|
||||
public Type GetTypeByFullName(string fullName, bool ignoreCase)
|
||||
{
|
||||
return FullNames.Get(fullName, ignoreCase);
|
||||
}
|
||||
public Type GetTypeByFullName(string fullName, bool ignoreCase) => FullNames.Get(fullName, ignoreCase);
|
||||
}
|
||||
|
||||
public class TypeTable
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Mobiles
|
||||
namespace Server
|
||||
{
|
||||
public class BuyItemStateComparer : IComparer<BuyItemState>
|
||||
{
|
||||
|
|
@ -103,4 +103,4 @@ namespace Server.Mobiles
|
|||
|
||||
public string Description{ get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
298
Projects/Server/Buffers/SpanWriter.cs
Normal file
298
Projects/Server/Buffers/SpanWriter.cs
Normal file
|
|
@ -0,0 +1,298 @@
|
|||
/***************************************************************************
|
||||
* SpanWriter.cs
|
||||
* -------------------
|
||||
* begin : August 5, 2019
|
||||
* copyright : (C) The ModernUO Team
|
||||
* email : hi@modernuo.com
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace Server.Buffers
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides functionality for writing primitive binary data.
|
||||
/// </summary>
|
||||
public ref struct SpanWriter
|
||||
{
|
||||
private int m_Position;
|
||||
|
||||
/// <summary>
|
||||
/// Underlying Span.
|
||||
/// </summary>
|
||||
public Span<byte> RawSpan { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Underlying Span up to the bytes written.
|
||||
/// </summary>
|
||||
public Span<byte> Span => RawSpan.Slice(0, WrittenCount);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the total length of the span.
|
||||
/// </summary>
|
||||
public int Length => RawSpan.Length;
|
||||
|
||||
/// <summary>
|
||||
/// Total bytes written to the span.
|
||||
/// </summary>
|
||||
public int WrittenCount { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Current position in the the span.
|
||||
/// </summary>
|
||||
public int Position
|
||||
{
|
||||
get => m_Position;
|
||||
set
|
||||
{
|
||||
m_Position = value;
|
||||
|
||||
if (value > WrittenCount)
|
||||
WrittenCount = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Instantiates a new SpanWriter instance.
|
||||
/// </summary>
|
||||
public SpanWriter(Span<byte> span)
|
||||
{
|
||||
RawSpan = span;
|
||||
m_Position = 0;
|
||||
WrittenCount = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a 1-byte boolean value to the span.
|
||||
/// </summary>
|
||||
public unsafe void Write(bool value)
|
||||
{
|
||||
RawSpan[Position++] = *(byte*)&value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a 1-byte unsigned integer value to the span.
|
||||
/// </summary>
|
||||
public void Write(byte value)
|
||||
{
|
||||
RawSpan[Position++] = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a 1-byte signed integer value to the span.
|
||||
/// </summary>
|
||||
public void Write(sbyte value)
|
||||
{
|
||||
RawSpan[Position++] = (byte)value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a 2-byte signed integer value to the span.
|
||||
/// </summary>
|
||||
public void Write(short value)
|
||||
{
|
||||
Write((byte)(value >> 8));
|
||||
Write((byte)value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a 2-byte unsigned integer value to the span.
|
||||
/// </summary>
|
||||
public void Write(ushort value)
|
||||
{
|
||||
Write((byte)(value >> 8));
|
||||
Write((byte)value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a 4-byte signed integer value to the span.
|
||||
/// </summary>
|
||||
public void Write(int value)
|
||||
{
|
||||
Write((byte)(value >> 24));
|
||||
Write((byte)(value >> 16));
|
||||
Write((byte)(value >> 8));
|
||||
Write((byte)value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a 4-byte unsigned integer value to the span.
|
||||
/// </summary>
|
||||
public void Write(uint value)
|
||||
{
|
||||
Write((byte)(value >> 24));
|
||||
Write((byte)(value >> 16));
|
||||
Write((byte)(value >> 8));
|
||||
Write((byte)value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an 8-byte signed integer value to the span.
|
||||
/// </summary>
|
||||
public void Write(long value)
|
||||
{
|
||||
Write((byte)(value >> 56));
|
||||
Write((byte)(value >> 48));
|
||||
Write((byte)(value >> 40));
|
||||
Write((byte)(value >> 32));
|
||||
|
||||
Write((byte)(value >> 24));
|
||||
Write((byte)(value >> 16));
|
||||
Write((byte)(value >> 8));
|
||||
Write((byte)value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an 8-byte unsigned integer value to the span.
|
||||
/// </summary>
|
||||
public void Write(ulong value)
|
||||
{
|
||||
Write((byte)(value >> 56));
|
||||
Write((byte)(value >> 48));
|
||||
Write((byte)(value >> 40));
|
||||
Write((byte)(value >> 32));
|
||||
|
||||
Write((byte)(value >> 24));
|
||||
Write((byte)(value >> 16));
|
||||
Write((byte)(value >> 8));
|
||||
Write((byte)value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a sequence of bytes to the span.
|
||||
/// </summary>
|
||||
public void Write(ReadOnlySpan<byte> input)
|
||||
{
|
||||
int size = Math.Min(input.Length, Length - Position);
|
||||
|
||||
input.Slice(0, size).CopyTo(RawSpan.Slice(Position));
|
||||
Position += size;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an ASCII-encoded string value to the span.
|
||||
/// </summary>
|
||||
public void WriteAscii(string value)
|
||||
{
|
||||
Position += Encoding.ASCII.GetBytes(value ?? "", RawSpan.Slice(Position));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a fixed-length ASCII-encoded string value to the span.
|
||||
/// </summary>
|
||||
public void WriteAsciiFixed(string value, int size, bool zero = false)
|
||||
{
|
||||
value ??= "";
|
||||
|
||||
int length = Math.Min(size, value.Length);
|
||||
|
||||
Encoding.ASCII.GetBytes(value.AsSpan(0, length), RawSpan.Slice(Position));
|
||||
|
||||
if (zero)
|
||||
{
|
||||
Position += length;
|
||||
Fill(size - length);
|
||||
}
|
||||
else
|
||||
Position += size;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a dynamic-length ASCII-encoded string value to the span, followed by a 1-byte null character.
|
||||
/// </summary>
|
||||
public void WriteAsciiNull(string value)
|
||||
{
|
||||
Position += Encoding.ASCII.GetBytes(value ?? "", RawSpan.Slice(Position));
|
||||
Write((byte)0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a dynamic-length ASCII-encoded string value to the span, followed by a 1-byte null character.
|
||||
/// </summary>
|
||||
public void WriteAsciiNull(string value, int size)
|
||||
{
|
||||
value ??= "";
|
||||
|
||||
size = Math.Min(size, value.Length);
|
||||
Position += Encoding.ASCII.GetBytes(value.AsSpan(0, size), RawSpan.Slice(Position));
|
||||
Write((byte)0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a dynamic-length little-endian unicode string value to the span.
|
||||
/// </summary>
|
||||
public void WriteLittleUni(string value)
|
||||
{
|
||||
Position += Encoding.Unicode.GetBytes(value ?? "", RawSpan.Slice(Position));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a dynamic-length little-endian unicode string value to the span, followed by a 2-byte null character.
|
||||
/// </summary>
|
||||
public void WriteLittleUniNull(string value)
|
||||
{
|
||||
WriteLittleUni(value);
|
||||
Write((ushort)0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a dynamic-length big-endian unicode string value to the span.
|
||||
/// </summary>
|
||||
public void WriteBigUni(string value)
|
||||
{
|
||||
Position += Encoding.BigEndianUnicode.GetBytes(value ?? "", RawSpan.Slice(Position));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a dynamic-length big-endian unicode string value to the span, followed by a 2-byte null character.
|
||||
/// </summary>
|
||||
public void WriteBigUniNull(string value, bool zero = false)
|
||||
{
|
||||
WriteBigUni(value);
|
||||
|
||||
if (zero)
|
||||
Fill(2);
|
||||
else
|
||||
Position += 2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a dynamic-length utf-8 string value, followed by a 1-byte null character.
|
||||
/// </summary>
|
||||
public void WriteUTF8Null(string value)
|
||||
{
|
||||
Position += Encoding.UTF8.GetBytes(value ?? "", RawSpan.Slice(Position)) + 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies the span to the destination.
|
||||
/// </summary>
|
||||
public void CopyTo(Span<byte> destination)
|
||||
{
|
||||
RawSpan.CopyTo(destination);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fills the buffer with zeroes up to count
|
||||
/// </summary>
|
||||
public void Fill(int count)
|
||||
{
|
||||
count = Math.Min(count, RawSpan.Length - Position);
|
||||
RawSpan.Slice(Position, count).Clear();
|
||||
Position += count;
|
||||
}
|
||||
}
|
||||
}
|
||||
61
Projects/Server/CityInfo.cs
Normal file
61
Projects/Server/CityInfo.cs
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
namespace Server
|
||||
{
|
||||
public sealed class CityInfo
|
||||
{
|
||||
private Point3D m_Location;
|
||||
|
||||
public CityInfo(string city, string building, int description, int x, int y, int z, Map m)
|
||||
{
|
||||
City = city;
|
||||
Building = building;
|
||||
Description = description;
|
||||
Location = new Point3D(x, y, z);
|
||||
Map = m;
|
||||
}
|
||||
|
||||
public CityInfo(string city, string building, int x, int y, int z, Map m) : this(city, building, 0, x, y, z, m)
|
||||
{
|
||||
}
|
||||
|
||||
public CityInfo(string city, string building, int description, int x, int y, int z) : this(city, building,
|
||||
description, x, y, z, Map.Trammel)
|
||||
{
|
||||
}
|
||||
|
||||
public CityInfo(string city, string building, int x, int y, int z) : this(city, building, 0, x, y, z, Map.Trammel)
|
||||
{
|
||||
}
|
||||
|
||||
public string City { get; set; }
|
||||
|
||||
public string Building { get; set; }
|
||||
|
||||
public int Description { get; set; }
|
||||
|
||||
public int X
|
||||
{
|
||||
get => m_Location.X;
|
||||
set => m_Location.X = value;
|
||||
}
|
||||
|
||||
public int Y
|
||||
{
|
||||
get => m_Location.Y;
|
||||
set => m_Location.Y = value;
|
||||
}
|
||||
|
||||
public int Z
|
||||
{
|
||||
get => m_Location.Z;
|
||||
set => m_Location.Z = value;
|
||||
}
|
||||
|
||||
public Point3D Location
|
||||
{
|
||||
get => m_Location;
|
||||
set => m_Location = value;
|
||||
}
|
||||
|
||||
public Map Map { get; set; }
|
||||
}
|
||||
}
|
||||
51
Projects/Server/Collections/ArraySet.cs
Normal file
51
Projects/Server/Collections/ArraySet.cs
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Collections
|
||||
{
|
||||
public class ArraySet<T> : IList<T>
|
||||
{
|
||||
private readonly List<T> m_List = new List<T>();
|
||||
|
||||
public T this[int index] { get => m_List[index]; set => m_List[index] = value; }
|
||||
|
||||
public int Count => m_List.Count;
|
||||
|
||||
public bool IsReadOnly => false;
|
||||
|
||||
public int Add(T item)
|
||||
{
|
||||
int indexOf = m_List.IndexOf(item);
|
||||
|
||||
if (indexOf >= 0) return indexOf;
|
||||
|
||||
m_List.Add(item);
|
||||
return m_List.Count - 1;
|
||||
}
|
||||
|
||||
public void Clear() => m_List.Clear();
|
||||
|
||||
public bool Contains(T item) => m_List.Contains(item);
|
||||
|
||||
public void CopyTo(T[] array) => m_List.CopyTo(array);
|
||||
|
||||
public void CopyTo(T[] array, int arrayIndex) => m_List.CopyTo(array, arrayIndex);
|
||||
|
||||
public void CopyTo(int index, T[] array, int arrayIndex, int count) => m_List.CopyTo(index, array, arrayIndex, count);
|
||||
|
||||
public IEnumerator<T> GetEnumerator() => m_List.GetEnumerator();
|
||||
|
||||
public int IndexOf(T item) => m_List.IndexOf(item);
|
||||
|
||||
public void Insert(int index, T item) => throw new NotImplementedException();
|
||||
|
||||
public bool Remove(T item) => throw new NotImplementedException();
|
||||
|
||||
public void RemoveAt(int index) => throw new NotImplementedException();
|
||||
|
||||
void ICollection<T>.Add(T item) => m_List.Add(item);
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => m_List.GetEnumerator();
|
||||
}
|
||||
}
|
||||
|
|
@ -22,7 +22,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Commands
|
||||
namespace Server
|
||||
{
|
||||
public delegate void CommandEventHandler(CommandEventArgs e);
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ namespace Server
|
|||
|
||||
public static Configuration Instance => m_Configuration ??= ReadConfiguration();
|
||||
|
||||
public List<string> DataDirectories { get; } = new List<string>();
|
||||
public List<string> DataDirectories { get; set; } = new List<string>();
|
||||
|
||||
private static string FilePath => Path.Join(Core.BaseDirectory, "modernuo.json");
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ using System.Collections.Generic;
|
|||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using Server.Accounting;
|
||||
using Server.Commands;
|
||||
using Server.Guilds;
|
||||
using Server.Network;
|
||||
|
||||
|
|
|
|||
|
|
@ -442,19 +442,19 @@ namespace Server
|
|||
RandomImpl.IsHardwareRNG ? "Hardware" : "Software");
|
||||
|
||||
// Load Assembly Scripts.CS.dll
|
||||
ScriptCompiler.LoadScripts();
|
||||
AssemblyHandler.LoadScripts();
|
||||
|
||||
ScriptCompiler.Invoke("Configure");
|
||||
AssemblyHandler.Invoke("Configure");
|
||||
|
||||
Region.Load();
|
||||
World.Load();
|
||||
|
||||
ScriptCompiler.Invoke("Initialize");
|
||||
AssemblyHandler.Invoke("Initialize");
|
||||
|
||||
// Start accepting new connections
|
||||
MessagePump = new MessagePump();
|
||||
|
||||
ScriptCompiler.Invoke("RegisterListeners");
|
||||
AssemblyHandler.Invoke("RegisterListeners");
|
||||
|
||||
timerThread.Start();
|
||||
|
||||
|
|
@ -513,7 +513,7 @@ namespace Server
|
|||
|
||||
VerifySerialization(ca);
|
||||
|
||||
foreach (Assembly a in ScriptCompiler.Assemblies.Where(a => a != ca)) VerifySerialization(a);
|
||||
foreach (Assembly a in AssemblyHandler.Assemblies.Where(a => a != ca)) VerifySerialization(a);
|
||||
}
|
||||
|
||||
private static void VerifyType(Type t)
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ using System.IO;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Server.Accounting;
|
||||
using Server.Commands;
|
||||
using Server.ContextMenus;
|
||||
using Server.Guilds;
|
||||
using Server.Gumps;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
***************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Server.Network
|
||||
|
|
@ -47,7 +48,7 @@ namespace Server.Network
|
|||
// If our input exceeds this length, we may potentially overflow the buffer
|
||||
private const int PossibleOverflow = (BufferSize * 8 - TerminalCodeLength) / MaximalCodeLength;
|
||||
|
||||
private static int[] _huffmanTable = {
|
||||
private static readonly int[] _huffmanTable = {
|
||||
0x2, 0x000, 0x5, 0x01F, 0x6, 0x022, 0x7, 0x034, 0x7, 0x075, 0x6, 0x028, 0x6, 0x03B, 0x7, 0x032,
|
||||
0x8, 0x0E0, 0x8, 0x062, 0x7, 0x056, 0x8, 0x079, 0x9, 0x19D, 0x8, 0x097, 0x6, 0x02A, 0x7, 0x057,
|
||||
0x8, 0x071, 0x8, 0x05B, 0x9, 0x1CC, 0x8, 0x0A7, 0x7, 0x025, 0x7, 0x04F, 0x8, 0x066, 0x8, 0x07D,
|
||||
|
|
@ -88,23 +89,12 @@ namespace Server.Network
|
|||
static Compression()
|
||||
{
|
||||
if (Core.Unix)
|
||||
{
|
||||
if (Core.Is64Bit)
|
||||
Compressor = new CompressorUnix64();
|
||||
Compressor = new UnixCompressor();
|
||||
else
|
||||
Compressor = new CompressorUnix32();
|
||||
Compressor = new Compressor();
|
||||
}
|
||||
else if (Core.Is64Bit)
|
||||
{
|
||||
Compressor = new Compressor64();
|
||||
}
|
||||
else
|
||||
{
|
||||
Compressor = new Compressor32();
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void Compress(byte[] input, int offset, int count, byte[] output, ref int length)
|
||||
public static unsafe void Compress(ReadOnlySpan<byte> input, int offset, int count, Span<byte> output, out int length)
|
||||
{
|
||||
if (input == null) throw new ArgumentNullException(nameof(input));
|
||||
|
||||
|
|
@ -121,8 +111,6 @@ namespace Server.Network
|
|||
|
||||
fixed (int* pTable = _huffmanTable)
|
||||
{
|
||||
int* pEntry;
|
||||
|
||||
fixed (byte* pInputBuffer = input)
|
||||
{
|
||||
byte* pInput = pInputBuffer + offset, pInputEnd = pInput + count;
|
||||
|
|
@ -131,6 +119,7 @@ namespace Server.Network
|
|||
{
|
||||
byte* pOutput = pOutputBuffer, pOutputEnd = pOutput + BufferSize;
|
||||
|
||||
int* pEntry;
|
||||
while (pInput < pInputEnd)
|
||||
{
|
||||
pEntry = &pTable[*pInput++ << 1];
|
||||
|
|
@ -192,183 +181,150 @@ namespace Server.Network
|
|||
}
|
||||
}
|
||||
|
||||
public static ZLibError Pack(byte[] dest, ref int destLength, byte[] source, int sourceLength)
|
||||
public static int MaxPackSize(int sourceLength) => (int)Compressor.CompressBound((ulong)sourceLength);
|
||||
|
||||
public static unsafe ZLibError Pack(Span<byte> dest, ref int destLength, ReadOnlySpan<byte> source, int sourceLength)
|
||||
{
|
||||
return Compressor.Compress(dest, ref destLength, source, sourceLength);
|
||||
ulong destLengthLong = (ulong)destLength;
|
||||
fixed (byte* dPtr = &MemoryMarshal.GetReference(dest), sPtr = &MemoryMarshal.GetReference(source))
|
||||
{
|
||||
ZLibError e = Compressor.Compress(Unsafe.AsRef<int>(dPtr), ref destLengthLong, Unsafe.AsRef<int>(sPtr), (ulong)sourceLength);
|
||||
destLength = (int)destLengthLong;
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe ZLibError Pack(Span<byte> dest, ref int destLength, ReadOnlySpan<byte> source, ZLibQuality quality)
|
||||
{
|
||||
ulong destLengthLong = (ulong)destLength;
|
||||
fixed (byte* dPtr = &MemoryMarshal.GetReference(dest), sPtr = &MemoryMarshal.GetReference(source))
|
||||
{
|
||||
ZLibError e = Compressor.Compress(Unsafe.AsRef<int>(dPtr), ref destLengthLong, Unsafe.AsRef<int>(sPtr), (ulong)source.Length, quality);
|
||||
destLength = (int)destLengthLong;
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe ZLibError Pack(Span<byte> dest, ref int destLength, ReadOnlySpan<byte> source, int sourceLength, ZLibQuality quality)
|
||||
{
|
||||
ulong destLengthLong = (ulong)destLength;
|
||||
fixed (byte* dPtr = &MemoryMarshal.GetReference(dest), sPtr = &MemoryMarshal.GetReference(source))
|
||||
{
|
||||
ZLibError e = Compressor.Compress(Unsafe.AsRef<int>(dPtr), ref destLengthLong, Unsafe.AsRef<int>(sPtr), (ulong)sourceLength, quality);
|
||||
destLength = (int)destLengthLong;
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
public static ZLibError Pack(byte[] dest, ref int destLength, byte[] source, int sourceLength, ZLibQuality quality)
|
||||
public static unsafe ZLibError Unpack(Span<byte> dest, ref int destLength, ReadOnlySpan<byte> source, int sourceLength)
|
||||
{
|
||||
return Compressor.Compress(dest, ref destLength, source, sourceLength, quality);
|
||||
ulong destLengthLong = (ulong)destLength;
|
||||
fixed (byte* dPtr = &MemoryMarshal.GetReference(dest), sPtr = &MemoryMarshal.GetReference(source))
|
||||
{
|
||||
ZLibError e = Compressor.Decompress(Unsafe.AsRef<int>(dPtr), ref destLengthLong, Unsafe.AsRef<int>(sPtr), (ulong)sourceLength);
|
||||
destLength = (int)destLengthLong;
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
public static ulong MaxPackSize(ulong sourceLength) => Compressor.CompressBound(sourceLength);
|
||||
|
||||
public static unsafe ZLibError Pack(Span<byte> dest, ref ulong destLength, ReadOnlySpan<byte> source, ulong sourceLength)
|
||||
{
|
||||
fixed(byte* dPtr = &MemoryMarshal.GetReference(dest), sPtr = &MemoryMarshal.GetReference(source))
|
||||
return Compressor.Compress(Unsafe.AsRef<int>(dPtr), ref destLength, Unsafe.AsRef<int>(sPtr), sourceLength);
|
||||
}
|
||||
|
||||
public static ZLibError Unpack(byte[] dest, ref int destLength, byte[] source, int sourceLength)
|
||||
public static unsafe ZLibError Pack(Span<byte> dest, ref ulong destLength, ReadOnlySpan<byte> source, ZLibQuality quality)
|
||||
{
|
||||
return Compressor.Decompress(dest, ref destLength, source, sourceLength);
|
||||
fixed(byte* dPtr = &MemoryMarshal.GetReference(dest), sPtr = &MemoryMarshal.GetReference(source))
|
||||
return Compressor.Compress(Unsafe.AsRef<int>(dPtr), ref destLength, Unsafe.AsRef<int>(sPtr), (ulong)source.Length, quality);
|
||||
}
|
||||
|
||||
public static unsafe ZLibError Pack(Span<byte> dest, ref ulong destLength, ReadOnlySpan<byte> source, ulong sourceLength, ZLibQuality quality)
|
||||
{
|
||||
fixed(byte* dPtr = &MemoryMarshal.GetReference(dest), sPtr = &MemoryMarshal.GetReference(source))
|
||||
return Compressor.Compress(Unsafe.AsRef<int>(dPtr), ref destLength, Unsafe.AsRef<int>(sPtr), sourceLength, quality);
|
||||
}
|
||||
|
||||
public static unsafe ZLibError Unpack(Span<byte> dest, ref ulong destLength, ReadOnlySpan<byte> source, ulong sourceLength)
|
||||
{
|
||||
fixed(byte* dPtr = &MemoryMarshal.GetReference(dest), sPtr = &MemoryMarshal.GetReference(source))
|
||||
return Compressor.Decompress(Unsafe.AsRef<int>(dPtr), ref destLength, Unsafe.AsRef<int>(sPtr), sourceLength);
|
||||
}
|
||||
}
|
||||
|
||||
public interface ICompressor
|
||||
{
|
||||
string Version{ get; }
|
||||
|
||||
ZLibError Compress(byte[] dest, ref int destLength, byte[] source, int sourceLength);
|
||||
ZLibError Compress(byte[] dest, ref int destLength, byte[] source, int sourceLength, ZLibQuality quality);
|
||||
|
||||
ZLibError Decompress(byte[] dest, ref int destLength, byte[] source, int sourceLength);
|
||||
string Version { get; }
|
||||
ZLibError Compress(in int dest, ref ulong destLength, in int source, ulong sourceLength);
|
||||
ZLibError Compress(in int dest, ref ulong destLength, in int source, ulong sourceLength, ZLibQuality quality);
|
||||
ZLibError Decompress(in int dest, ref ulong destLength, in int source, ulong sourceLength);
|
||||
ulong CompressBound(ulong sourceLength);
|
||||
}
|
||||
|
||||
public sealed class Compressor32 : ICompressor
|
||||
{
|
||||
public string Version => SafeNativeMethods.zlibVersion();
|
||||
|
||||
public ZLibError Compress(byte[] dest, ref int destLength, byte[] source, int sourceLength)
|
||||
public class Compressor : ICompressor
|
||||
{
|
||||
return SafeNativeMethods.compress(dest, ref destLength, source, sourceLength);
|
||||
}
|
||||
public string Version => zlibVersion();
|
||||
|
||||
public ZLibError Compress(byte[] dest, ref int destLength, byte[] source, int sourceLength, ZLibQuality quality)
|
||||
{
|
||||
return SafeNativeMethods.compress2(dest, ref destLength, source, sourceLength, quality);
|
||||
}
|
||||
public ZLibError Compress(in int dest, ref ulong destLength, in int source, ulong sourceLength) =>
|
||||
compress(dest, ref destLength, source, sourceLength);
|
||||
|
||||
public ZLibError Decompress(byte[] dest, ref int destLength, byte[] source, int sourceLength)
|
||||
{
|
||||
return SafeNativeMethods.uncompress(dest, ref destLength, source, sourceLength);
|
||||
}
|
||||
public ZLibError Compress(in int dest, ref ulong destLength, in int source, ulong sourceLength,
|
||||
ZLibQuality quality) => compress2(dest, ref destLength, source, sourceLength, quality);
|
||||
|
||||
internal class SafeNativeMethods
|
||||
{
|
||||
[DllImport("zlib32")]
|
||||
internal static extern string zlibVersion();
|
||||
public ZLibError Decompress(in int dest, ref ulong destLength, in int source, ulong sourceLength) =>
|
||||
uncompress(dest, ref destLength, source, sourceLength);
|
||||
|
||||
[DllImport("zlib32")]
|
||||
internal static extern ZLibError compress(byte[] dest, ref int destLength, byte[] source, int sourceLength);
|
||||
public ulong CompressBound(ulong sourceLength) => compressBound(sourceLength);
|
||||
|
||||
[DllImport("zlib32")]
|
||||
internal static extern ZLibError compress2(byte[] dest, ref int destLength, byte[] source, int sourceLength,
|
||||
[DllImport("zlib")]
|
||||
private static extern string zlibVersion();
|
||||
|
||||
[DllImport("zlib")]
|
||||
private static extern ZLibError compress(in int dest, ref ulong destLength, in int source, ulong sourceLength);
|
||||
|
||||
[DllImport("zlib")]
|
||||
private static extern ZLibError compress2(in int dest, ref ulong destLength, in int source, ulong sourceLength,
|
||||
ZLibQuality quality);
|
||||
|
||||
[DllImport("zlib32")]
|
||||
internal static extern ZLibError uncompress(byte[] dest, ref int destLen, byte[] source, int sourceLen);
|
||||
}
|
||||
[DllImport("zlib")]
|
||||
private static extern ZLibError uncompress(in int dest, ref ulong destLength, in int source, ulong sourceLength);
|
||||
|
||||
[DllImport("zlib")]
|
||||
private static extern ulong compressBound(ulong sourceLen);
|
||||
}
|
||||
|
||||
public sealed class Compressor64 : ICompressor
|
||||
public class UnixCompressor : ICompressor
|
||||
{
|
||||
public string Version => SafeNativeMethods.zlibVersion();
|
||||
public string Version => zlibVersion();
|
||||
|
||||
public ZLibError Compress(byte[] dest, ref int destLength, byte[] source, int sourceLength)
|
||||
{
|
||||
return SafeNativeMethods.compress(dest, ref destLength, source, sourceLength);
|
||||
}
|
||||
public ZLibError Compress(in int dest, ref ulong destLength, in int source, ulong sourceLength) =>
|
||||
compress(dest, ref destLength, source, sourceLength);
|
||||
|
||||
public ZLibError Compress(byte[] dest, ref int destLength, byte[] source, int sourceLength, ZLibQuality quality)
|
||||
{
|
||||
return SafeNativeMethods.compress2(dest, ref destLength, source, sourceLength, quality);
|
||||
}
|
||||
public ZLibError Compress(in int dest, ref ulong destLength, in int source, ulong sourceLength,
|
||||
ZLibQuality quality) => compress2(dest, ref destLength, source, sourceLength, quality);
|
||||
|
||||
public ZLibError Decompress(byte[] dest, ref int destLength, byte[] source, int sourceLength)
|
||||
{
|
||||
return SafeNativeMethods.uncompress(dest, ref destLength, source, sourceLength);
|
||||
}
|
||||
public ZLibError Decompress(in int dest, ref ulong destLength, in int source, ulong sourceLength) =>
|
||||
uncompress(dest, ref destLength, source, sourceLength);
|
||||
|
||||
internal class SafeNativeMethods
|
||||
{
|
||||
[DllImport("zlib64")]
|
||||
internal static extern string zlibVersion();
|
||||
public ulong CompressBound(ulong sourceLength) => compressBound(sourceLength);
|
||||
|
||||
[DllImport("zlib64")]
|
||||
internal static extern ZLibError compress(byte[] dest, ref int destLength, byte[] source, int sourceLength);
|
||||
[DllImport("libz")]
|
||||
private static extern string zlibVersion();
|
||||
|
||||
[DllImport("zlib64")]
|
||||
internal static extern ZLibError compress2(byte[] dest, ref int destLength, byte[] source, int sourceLength,
|
||||
[DllImport("libz")]
|
||||
private static extern ZLibError compress(in int dest, ref ulong destLength, in int source, ulong sourceLength);
|
||||
|
||||
[DllImport("libz")]
|
||||
private static extern ZLibError compress2(in int dest, ref ulong destLength, in int source, ulong sourceLength,
|
||||
ZLibQuality quality);
|
||||
|
||||
[DllImport("zlib64")]
|
||||
internal static extern ZLibError uncompress(byte[] dest, ref int destLen, byte[] source, int sourceLen);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class CompressorUnix32 : ICompressor
|
||||
{
|
||||
public string Version => SafeNativeMethods.zlibVersion();
|
||||
|
||||
public ZLibError Compress(byte[] dest, ref int destLength, byte[] source, int sourceLength)
|
||||
{
|
||||
return SafeNativeMethods.compress(dest, ref destLength, source, sourceLength);
|
||||
}
|
||||
|
||||
public ZLibError Compress(byte[] dest, ref int destLength, byte[] source, int sourceLength, ZLibQuality quality)
|
||||
{
|
||||
return SafeNativeMethods.compress2(dest, ref destLength, source, sourceLength, quality);
|
||||
}
|
||||
|
||||
public ZLibError Decompress(byte[] dest, ref int destLength, byte[] source, int sourceLength)
|
||||
{
|
||||
return SafeNativeMethods.uncompress(dest, ref destLength, source, sourceLength);
|
||||
}
|
||||
|
||||
internal class SafeNativeMethods
|
||||
{
|
||||
[DllImport("libz")]
|
||||
internal static extern string zlibVersion();
|
||||
[DllImport("libz")]
|
||||
private static extern ZLibError uncompress(in int dest, ref ulong destLength, in int source, ulong sourceLength);
|
||||
|
||||
[DllImport("libz")]
|
||||
internal static extern ZLibError compress(byte[] dest, ref int destLength, byte[] source, int sourceLength);
|
||||
|
||||
[DllImport("libz")]
|
||||
internal static extern ZLibError compress2(byte[] dest, ref int destLength, byte[] source, int sourceLength,
|
||||
ZLibQuality quality);
|
||||
|
||||
[DllImport("libz")]
|
||||
internal static extern ZLibError uncompress(byte[] dest, ref int destLen, byte[] source, int sourceLen);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class CompressorUnix64 : ICompressor
|
||||
{
|
||||
public string Version => SafeNativeMethods.zlibVersion();
|
||||
|
||||
public ZLibError Compress(byte[] dest, ref int destLength, byte[] source, int sourceLength)
|
||||
{
|
||||
ulong destLengthLong = (ulong)destLength;
|
||||
ZLibError z = SafeNativeMethods.compress(dest, ref destLengthLong, source, sourceLength);
|
||||
destLength = (int)destLengthLong;
|
||||
return z;
|
||||
}
|
||||
|
||||
public ZLibError Compress(byte[] dest, ref int destLength, byte[] source, int sourceLength, ZLibQuality quality)
|
||||
{
|
||||
ulong destLengthLong = (ulong)destLength;
|
||||
ZLibError z = SafeNativeMethods.compress2(dest, ref destLengthLong, source, sourceLength, quality);
|
||||
destLength = (int)destLengthLong;
|
||||
return z;
|
||||
}
|
||||
|
||||
public ZLibError Decompress(byte[] dest, ref int destLength, byte[] source, int sourceLength)
|
||||
{
|
||||
ulong destLengthLong = (ulong)destLength;
|
||||
ZLibError z = SafeNativeMethods.uncompress(dest, ref destLengthLong, source, sourceLength);
|
||||
destLength = (int)destLengthLong;
|
||||
return z;
|
||||
}
|
||||
|
||||
internal class SafeNativeMethods
|
||||
{
|
||||
[DllImport("libz")]
|
||||
internal static extern string zlibVersion();
|
||||
|
||||
[DllImport("libz")]
|
||||
internal static extern ZLibError compress(byte[] dest, ref ulong destLength, byte[] source, int sourceLength);
|
||||
|
||||
[DllImport("libz")]
|
||||
internal static extern ZLibError compress2(byte[] dest, ref ulong destLength, byte[] source, int sourceLength,
|
||||
ZLibQuality quality);
|
||||
|
||||
[DllImport("libz")]
|
||||
internal static extern ZLibError uncompress(byte[] dest, ref ulong destLen, byte[] source, int sourceLen);
|
||||
}
|
||||
private static extern ulong compressBound(ulong sourceLen);
|
||||
}
|
||||
|
||||
public enum ZLibError
|
||||
|
|
@ -379,9 +335,7 @@ namespace Server.Network
|
|||
DataError = -3,
|
||||
StreamError = -2,
|
||||
FileError = -1,
|
||||
|
||||
Okay = 0,
|
||||
|
||||
StreamEnd = 1,
|
||||
NeedDictionary = 2
|
||||
}
|
||||
|
|
@ -389,10 +343,8 @@ namespace Server.Network
|
|||
public enum ZLibQuality
|
||||
{
|
||||
Default = -1,
|
||||
|
||||
None = 0,
|
||||
|
||||
Speed = 1,
|
||||
Size = 9
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,273 +1,273 @@
|
|||
/***************************************************************************
|
||||
* Packet.cs
|
||||
* -------------------
|
||||
* begin : August 2, 2019
|
||||
* copyright : (C) The RunUO Software Team
|
||||
* email : info@runuo.com
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
using Server.Diagnostics;
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Server.Network
|
||||
{
|
||||
public abstract class Packet
|
||||
{
|
||||
private const int CompressorBufferSize = 0x10000;
|
||||
|
||||
private const int BufferSize = 4096;
|
||||
|
||||
private byte[] m_CompiledBuffer;
|
||||
private int m_CompiledLength;
|
||||
private int m_Length;
|
||||
private State m_State;
|
||||
|
||||
protected PacketWriter m_Stream;
|
||||
|
||||
protected Packet(int packetID)
|
||||
{
|
||||
PacketID = packetID;
|
||||
|
||||
if (Core.Profiling)
|
||||
{
|
||||
PacketSendProfile prof = PacketSendProfile.Acquire(GetType());
|
||||
prof.Increment();
|
||||
}
|
||||
}
|
||||
|
||||
protected Packet(int packetID, int length)
|
||||
{
|
||||
PacketID = packetID;
|
||||
m_Length = length;
|
||||
|
||||
m_Stream = PacketWriter.CreateInstance(length); // new PacketWriter( length );
|
||||
m_Stream.Write((byte)packetID);
|
||||
|
||||
if (Core.Profiling)
|
||||
{
|
||||
PacketSendProfile prof = PacketSendProfile.Acquire(GetType());
|
||||
prof.Increment();
|
||||
}
|
||||
}
|
||||
|
||||
public int PacketID { get; }
|
||||
|
||||
public PacketWriter UnderlyingStream => m_Stream;
|
||||
|
||||
public void EnsureCapacity(int length)
|
||||
{
|
||||
m_Stream = PacketWriter.CreateInstance(length); // new PacketWriter( length );
|
||||
m_Stream.Write((byte)PacketID);
|
||||
m_Stream.Write((short)0);
|
||||
}
|
||||
|
||||
public static Packet SetStatic(Packet p)
|
||||
{
|
||||
p.SetStatic();
|
||||
return p;
|
||||
}
|
||||
|
||||
public static Packet Acquire(Packet p)
|
||||
{
|
||||
p.Acquire();
|
||||
return p;
|
||||
}
|
||||
|
||||
public static void Release(ref Packet p)
|
||||
{
|
||||
p?.Release();
|
||||
p = null;
|
||||
}
|
||||
|
||||
public static void Release(Packet p)
|
||||
{
|
||||
p?.Release();
|
||||
}
|
||||
|
||||
public void SetStatic()
|
||||
{
|
||||
m_State |= State.Static | State.Acquired;
|
||||
}
|
||||
|
||||
public void Acquire()
|
||||
{
|
||||
m_State |= State.Acquired;
|
||||
}
|
||||
|
||||
public void OnSend()
|
||||
{
|
||||
Core.Set(); // Is this still needed if this is done async?
|
||||
|
||||
if ((m_State & (State.Acquired | State.Static)) == 0)
|
||||
Free();
|
||||
}
|
||||
|
||||
private void Free()
|
||||
{
|
||||
if (m_CompiledBuffer == null)
|
||||
return;
|
||||
|
||||
if ((m_State & State.Buffered) != 0)
|
||||
ArrayPool<byte>.Shared.Return(m_CompiledBuffer);
|
||||
|
||||
m_State &= ~(State.Static | State.Acquired | State.Buffered);
|
||||
|
||||
m_CompiledBuffer = null;
|
||||
}
|
||||
|
||||
public void Release()
|
||||
{
|
||||
if ((m_State & State.Acquired) != 0)
|
||||
Free();
|
||||
}
|
||||
|
||||
public byte[] Compile(bool compress, out int length)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (m_CompiledBuffer == null)
|
||||
{
|
||||
if ((m_State & State.Accessed) == 0)
|
||||
{
|
||||
m_State |= State.Accessed;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((m_State & State.Warned) == 0)
|
||||
{
|
||||
m_State |= State.Warned;
|
||||
|
||||
try
|
||||
{
|
||||
using (StreamWriter op = new StreamWriter("net_opt.log", true))
|
||||
{
|
||||
op.WriteLine("Redundant compile for packet {0}, use Acquire() and Release()", GetType());
|
||||
op.WriteLine(new StackTrace());
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
m_CompiledBuffer = new byte[0];
|
||||
m_CompiledLength = 0;
|
||||
|
||||
length = m_CompiledLength;
|
||||
return m_CompiledBuffer;
|
||||
}
|
||||
|
||||
InternalCompile(compress);
|
||||
}
|
||||
|
||||
length = m_CompiledLength;
|
||||
return m_CompiledBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
private void InternalCompile(bool compress)
|
||||
{
|
||||
if (m_Length == 0)
|
||||
{
|
||||
long streamLen = m_Stream.Length;
|
||||
|
||||
m_Stream.Seek(1, SeekOrigin.Begin);
|
||||
m_Stream.Write((ushort)streamLen);
|
||||
}
|
||||
else if (m_Stream.Length != m_Length)
|
||||
{
|
||||
int diff = (int)m_Stream.Length - m_Length;
|
||||
|
||||
Console.WriteLine("Packet: 0x{0:X2}: Bad packet length! ({1}{2} bytes)", PacketID, diff >= 0 ? "+" : "",
|
||||
diff);
|
||||
}
|
||||
|
||||
MemoryStream ms = m_Stream.UnderlyingStream;
|
||||
|
||||
m_CompiledBuffer = ms.GetBuffer();
|
||||
int length = (int)ms.Length;
|
||||
|
||||
if (compress)
|
||||
{
|
||||
byte[] buffer = ArrayPool<byte>.Shared.Rent(CompressorBufferSize);
|
||||
|
||||
Compression.Compress(m_CompiledBuffer, 0, length, buffer, ref length);
|
||||
|
||||
if (length <= 0)
|
||||
{
|
||||
Console.WriteLine("Warning: Compression buffer overflowed on packet 0x{0:X2} ('{1}') (length={2})",
|
||||
PacketID, GetType().Name, length);
|
||||
using (StreamWriter op = new StreamWriter("compression_overflow.log", true))
|
||||
{
|
||||
op.WriteLine("{0} Warning: Compression buffer overflowed on packet 0x{1:X2} ('{2}') (length={3})",
|
||||
DateTime.UtcNow, PacketID, GetType().Name, length);
|
||||
op.WriteLine(new StackTrace());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CompiledLength = length;
|
||||
|
||||
if ((m_State & State.Static) != 0)
|
||||
{
|
||||
m_CompiledBuffer = new byte[length];
|
||||
Buffer.BlockCopy(buffer, 0, m_CompiledBuffer, 0, length);
|
||||
ArrayPool<byte>.Shared.Return(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CompiledBuffer = buffer;
|
||||
m_State |= State.Buffered;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (length > 0)
|
||||
{
|
||||
byte[] old = m_CompiledBuffer;
|
||||
m_CompiledLength = length;
|
||||
|
||||
if ((m_State & State.Static) != 0)
|
||||
m_CompiledBuffer = new byte[length];
|
||||
else
|
||||
{
|
||||
m_CompiledBuffer = ArrayPool<byte>.Shared.Rent(length);
|
||||
m_State |= State.Buffered;
|
||||
}
|
||||
|
||||
Buffer.BlockCopy(old, 0, m_CompiledBuffer, 0, length);
|
||||
}
|
||||
|
||||
PacketWriter.ReleaseInstance(m_Stream);
|
||||
m_Stream = null;
|
||||
}
|
||||
|
||||
[Flags]
|
||||
private enum State
|
||||
{
|
||||
Inactive = 0x00,
|
||||
Static = 0x01,
|
||||
Acquired = 0x02,
|
||||
Accessed = 0x04,
|
||||
Buffered = 0x08,
|
||||
Warned = 0x10
|
||||
}
|
||||
}
|
||||
}
|
||||
/***************************************************************************
|
||||
* Packet.cs
|
||||
* -------------------
|
||||
* begin : August 2, 2019
|
||||
* copyright : (C) The RunUO Software Team
|
||||
* email : info@runuo.com
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
using Server.Diagnostics;
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Server.Network
|
||||
{
|
||||
public abstract class Packet
|
||||
{
|
||||
private const int CompressorBufferSize = 0x10000;
|
||||
|
||||
private const int BufferSize = 4096;
|
||||
|
||||
private byte[] m_CompiledBuffer;
|
||||
private int m_CompiledLength;
|
||||
private int m_Length;
|
||||
private State m_State;
|
||||
|
||||
protected PacketWriter m_Stream;
|
||||
|
||||
protected Packet(int packetID)
|
||||
{
|
||||
PacketID = packetID;
|
||||
|
||||
if (Core.Profiling)
|
||||
{
|
||||
PacketSendProfile prof = PacketSendProfile.Acquire(GetType());
|
||||
prof.Increment();
|
||||
}
|
||||
}
|
||||
|
||||
protected Packet(int packetID, int length)
|
||||
{
|
||||
PacketID = packetID;
|
||||
m_Length = length;
|
||||
|
||||
m_Stream = PacketWriter.CreateInstance(length); // new PacketWriter( length );
|
||||
m_Stream.Write((byte)packetID);
|
||||
|
||||
if (Core.Profiling)
|
||||
{
|
||||
PacketSendProfile prof = PacketSendProfile.Acquire(GetType());
|
||||
prof.Increment();
|
||||
}
|
||||
}
|
||||
|
||||
public int PacketID { get; }
|
||||
|
||||
public PacketWriter UnderlyingStream => m_Stream;
|
||||
|
||||
public void EnsureCapacity(int length)
|
||||
{
|
||||
m_Stream = PacketWriter.CreateInstance(length); // new PacketWriter( length );
|
||||
m_Stream.Write((byte)PacketID);
|
||||
m_Stream.Write((short)0);
|
||||
}
|
||||
|
||||
public static Packet SetStatic(Packet p)
|
||||
{
|
||||
p.SetStatic();
|
||||
return p;
|
||||
}
|
||||
|
||||
public static Packet Acquire(Packet p)
|
||||
{
|
||||
p.Acquire();
|
||||
return p;
|
||||
}
|
||||
|
||||
public static void Release(ref Packet p)
|
||||
{
|
||||
p?.Release();
|
||||
p = null;
|
||||
}
|
||||
|
||||
public static void Release(Packet p)
|
||||
{
|
||||
p?.Release();
|
||||
}
|
||||
|
||||
public void SetStatic()
|
||||
{
|
||||
m_State |= State.Static | State.Acquired;
|
||||
}
|
||||
|
||||
public void Acquire()
|
||||
{
|
||||
m_State |= State.Acquired;
|
||||
}
|
||||
|
||||
public void OnSend()
|
||||
{
|
||||
Core.Set(); // Is this still needed if this is done async?
|
||||
|
||||
if ((m_State & (State.Acquired | State.Static)) == 0)
|
||||
Free();
|
||||
}
|
||||
|
||||
private void Free()
|
||||
{
|
||||
if (m_CompiledBuffer == null)
|
||||
return;
|
||||
|
||||
if ((m_State & State.Buffered) != 0)
|
||||
ArrayPool<byte>.Shared.Return(m_CompiledBuffer);
|
||||
|
||||
m_State &= ~(State.Static | State.Acquired | State.Buffered);
|
||||
|
||||
m_CompiledBuffer = null;
|
||||
}
|
||||
|
||||
public void Release()
|
||||
{
|
||||
if ((m_State & State.Acquired) != 0)
|
||||
Free();
|
||||
}
|
||||
|
||||
public byte[] Compile(bool compress, out int length)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (m_CompiledBuffer == null)
|
||||
{
|
||||
if ((m_State & State.Accessed) == 0)
|
||||
{
|
||||
m_State |= State.Accessed;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((m_State & State.Warned) == 0)
|
||||
{
|
||||
m_State |= State.Warned;
|
||||
|
||||
try
|
||||
{
|
||||
using (StreamWriter op = new StreamWriter("net_opt.log", true))
|
||||
{
|
||||
op.WriteLine("Redundant compile for packet {0}, use Acquire() and Release()", GetType());
|
||||
op.WriteLine(new StackTrace());
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
m_CompiledBuffer = new byte[0];
|
||||
m_CompiledLength = 0;
|
||||
|
||||
length = m_CompiledLength;
|
||||
return m_CompiledBuffer;
|
||||
}
|
||||
|
||||
InternalCompile(compress);
|
||||
}
|
||||
|
||||
length = m_CompiledLength;
|
||||
return m_CompiledBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
private void InternalCompile(bool compress)
|
||||
{
|
||||
if (m_Length == 0)
|
||||
{
|
||||
long streamLen = m_Stream.Length;
|
||||
|
||||
m_Stream.Seek(1, SeekOrigin.Begin);
|
||||
m_Stream.Write((ushort)streamLen);
|
||||
}
|
||||
else if (m_Stream.Length != m_Length)
|
||||
{
|
||||
int diff = (int)m_Stream.Length - m_Length;
|
||||
|
||||
Console.WriteLine("Packet: 0x{0:X2}: Bad packet length! ({1}{2} bytes)", PacketID, diff >= 0 ? "+" : "",
|
||||
diff);
|
||||
}
|
||||
|
||||
MemoryStream ms = m_Stream.UnderlyingStream;
|
||||
|
||||
m_CompiledBuffer = ms.GetBuffer();
|
||||
int length = (int)ms.Length;
|
||||
|
||||
if (compress)
|
||||
{
|
||||
byte[] buffer = ArrayPool<byte>.Shared.Rent(CompressorBufferSize);
|
||||
|
||||
Compression.Compress(m_CompiledBuffer, 0, length, buffer, out length);
|
||||
|
||||
if (length <= 0)
|
||||
{
|
||||
Console.WriteLine("Warning: Compression buffer overflowed on packet 0x{0:X2} ('{1}') (length={2})",
|
||||
PacketID, GetType().Name, length);
|
||||
using (StreamWriter op = new StreamWriter("compression_overflow.log", true))
|
||||
{
|
||||
op.WriteLine("{0} Warning: Compression buffer overflowed on packet 0x{1:X2} ('{2}') (length={3})",
|
||||
DateTime.UtcNow, PacketID, GetType().Name, length);
|
||||
op.WriteLine(new StackTrace());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CompiledLength = length;
|
||||
|
||||
if ((m_State & State.Static) != 0)
|
||||
{
|
||||
m_CompiledBuffer = new byte[length];
|
||||
Buffer.BlockCopy(buffer, 0, m_CompiledBuffer, 0, length);
|
||||
ArrayPool<byte>.Shared.Return(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CompiledBuffer = buffer;
|
||||
m_State |= State.Buffered;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (length > 0)
|
||||
{
|
||||
byte[] old = m_CompiledBuffer;
|
||||
m_CompiledLength = length;
|
||||
|
||||
if ((m_State & State.Static) != 0)
|
||||
m_CompiledBuffer = new byte[length];
|
||||
else
|
||||
{
|
||||
m_CompiledBuffer = ArrayPool<byte>.Shared.Rent(length);
|
||||
m_State |= State.Buffered;
|
||||
}
|
||||
|
||||
Buffer.BlockCopy(old, 0, m_CompiledBuffer, 0, length);
|
||||
}
|
||||
|
||||
PacketWriter.ReleaseInstance(m_Stream);
|
||||
m_Stream = null;
|
||||
}
|
||||
|
||||
[Flags]
|
||||
private enum State
|
||||
{
|
||||
Inactive = 0x00,
|
||||
Static = 0x01,
|
||||
Acquired = 0x02,
|
||||
Accessed = 0x04,
|
||||
Buffered = 0x08,
|
||||
Warned = 0x10
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3781,65 +3781,6 @@ namespace Server.Network
|
|||
}
|
||||
}
|
||||
|
||||
public sealed class CityInfo
|
||||
{
|
||||
private Point3D m_Location;
|
||||
|
||||
public CityInfo(string city, string building, int description, int x, int y, int z, Map m)
|
||||
{
|
||||
City = city;
|
||||
Building = building;
|
||||
Description = description;
|
||||
m_Location = new Point3D(x, y, z);
|
||||
Map = m;
|
||||
}
|
||||
|
||||
public CityInfo(string city, string building, int x, int y, int z, Map m) : this(city, building, 0, x, y, z, m)
|
||||
{
|
||||
}
|
||||
|
||||
public CityInfo(string city, string building, int description, int x, int y, int z) : this(city, building,
|
||||
description, x, y, z, Map.Trammel)
|
||||
{
|
||||
}
|
||||
|
||||
public CityInfo(string city, string building, int x, int y, int z) : this(city, building, 0, x, y, z, Map.Trammel)
|
||||
{
|
||||
}
|
||||
|
||||
public string City{ get; set; }
|
||||
|
||||
public string Building{ get; set; }
|
||||
|
||||
public int Description{ get; set; }
|
||||
|
||||
public int X
|
||||
{
|
||||
get => m_Location.X;
|
||||
set => m_Location.X = value;
|
||||
}
|
||||
|
||||
public int Y
|
||||
{
|
||||
get => m_Location.Y;
|
||||
set => m_Location.Y = value;
|
||||
}
|
||||
|
||||
public int Z
|
||||
{
|
||||
get => m_Location.Z;
|
||||
set => m_Location.Z = value;
|
||||
}
|
||||
|
||||
public Point3D Location
|
||||
{
|
||||
get => m_Location;
|
||||
set => m_Location = value;
|
||||
}
|
||||
|
||||
public Map Map{ get; set; }
|
||||
}
|
||||
|
||||
public sealed class CharacterListUpdate : Packet
|
||||
{
|
||||
public CharacterListUpdate(IAccount a) : base(0x86)
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ using System.IO;
|
|||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
|
|
@ -26,46 +27,31 @@ namespace Server
|
|||
{
|
||||
if (Core.Unix && File.Exists("rdrand.so"))
|
||||
_Random = new RDRandUnix();
|
||||
else if (Core.Is64Bit && File.Exists("rdrand64.dll"))
|
||||
_Random = new RDRand64();
|
||||
else if (File.Exists("rdrand.dll"))
|
||||
_Random = new RDRand32();
|
||||
else
|
||||
_Random = new CSPRandom();
|
||||
_Random = new RDRand64();
|
||||
|
||||
if (_Random is IHardwareRNG rng && !rng.IsSupported()) _Random = new CSPRandom();
|
||||
if (_Random == null || _Random is IHardwareRNG rng && !rng.IsSupported())
|
||||
_Random = new CSPRandom();
|
||||
}
|
||||
|
||||
public static bool IsHardwareRNG => _Random is IHardwareRNG;
|
||||
|
||||
public static Type Type => _Random.GetType();
|
||||
|
||||
public static int Next(int c)
|
||||
{
|
||||
return _Random.Next(c);
|
||||
}
|
||||
public static int Next(int c) => _Random.Next(c);
|
||||
|
||||
public static bool NextBool()
|
||||
{
|
||||
return _Random.NextBool();
|
||||
}
|
||||
public static bool NextBool() => _Random.NextBool();
|
||||
|
||||
public static void NextBytes(byte[] b)
|
||||
{
|
||||
_Random.NextBytes(b);
|
||||
}
|
||||
public static void NextBytes(Span<byte> b) => _Random.NextBytes(b);
|
||||
|
||||
public static double NextDouble()
|
||||
{
|
||||
return _Random.NextDouble();
|
||||
}
|
||||
public static double NextDouble() => _Random.NextDouble();
|
||||
}
|
||||
|
||||
public interface IRandomImpl
|
||||
{
|
||||
int Next(int c);
|
||||
bool NextBool();
|
||||
void NextBytes(byte[] b);
|
||||
void NextBytes(Span<byte> b);
|
||||
double NextDouble();
|
||||
}
|
||||
|
||||
|
|
@ -74,48 +60,54 @@ namespace Server
|
|||
bool IsSupported();
|
||||
}
|
||||
|
||||
public sealed class SimpleRandom : IRandomImpl
|
||||
public abstract class BaseRandom : IRandomImpl
|
||||
{
|
||||
private Random m_Random = new Random();
|
||||
internal abstract void GetBytes(Span<byte> b);
|
||||
internal abstract void GetBytes(byte[] b, int offset, int count);
|
||||
|
||||
public int Next(int c)
|
||||
public virtual void NextBytes(Span<byte> b) => GetBytes(b);
|
||||
public virtual int Next(int c) => (int)(c * NextDouble());
|
||||
public virtual bool NextBool() => (NextByte() & 1) == 1;
|
||||
|
||||
public virtual byte NextByte()
|
||||
{
|
||||
int r;
|
||||
lock (m_Random)
|
||||
byte[] b = new byte[1];
|
||||
GetBytes(b, 0, 1);
|
||||
return b[0];
|
||||
}
|
||||
|
||||
public virtual unsafe double NextDouble()
|
||||
{
|
||||
byte[] b = new byte[8];
|
||||
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
r = m_Random.Next(c);
|
||||
b[7] = 0;
|
||||
GetBytes(b, 0, 7);
|
||||
}
|
||||
else
|
||||
{
|
||||
b[0] = 0;
|
||||
GetBytes(b, 1, 7);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
public bool NextBool()
|
||||
{
|
||||
return NextDouble() >= .5;
|
||||
}
|
||||
|
||||
public void NextBytes(byte[] b)
|
||||
{
|
||||
lock (m_Random)
|
||||
ulong r;
|
||||
fixed (byte* buf = b)
|
||||
{
|
||||
m_Random.NextBytes(b);
|
||||
}
|
||||
}
|
||||
|
||||
public double NextDouble()
|
||||
{
|
||||
double r;
|
||||
lock (m_Random)
|
||||
{
|
||||
r = m_Random.NextDouble();
|
||||
r = *(ulong*)&buf[0] >> 3;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
||||
/* double: 53 bits of significand precision
|
||||
* ulong.MaxValue >> 11 = 9007199254740991
|
||||
* 2^53 = 9007199254740992
|
||||
*/
|
||||
|
||||
public sealed class CSPRandom : IRandomImpl
|
||||
{
|
||||
return (double)r / 9007199254740992;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class CSPRandom : BaseRandom
|
||||
{
|
||||
private static int BUFFER_SIZE = 0x4000;
|
||||
private static int LARGE_REQUEST = 0x40;
|
||||
private byte[] _Buffer = new byte[BUFFER_SIZE];
|
||||
|
|
@ -132,63 +124,24 @@ namespace Server
|
|||
public CSPRandom()
|
||||
{
|
||||
_CSP.GetBytes(_Working);
|
||||
ThreadPool.QueueUserWorkItem(Fill);
|
||||
Task.Run(Fill);
|
||||
}
|
||||
|
||||
public int Next(int c)
|
||||
{
|
||||
return (int)(c * NextDouble());
|
||||
}
|
||||
|
||||
public bool NextBool()
|
||||
{
|
||||
return (NextByte() & 1) == 1;
|
||||
}
|
||||
|
||||
public void NextBytes(byte[] b)
|
||||
public override void NextBytes(Span<byte> b)
|
||||
{
|
||||
int c = b.Length;
|
||||
|
||||
if (c >= LARGE_REQUEST)
|
||||
{
|
||||
lock (_CSP)
|
||||
{
|
||||
lock (_sync)
|
||||
{
|
||||
_CSP.GetBytes(b);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
_GetBytes(b);
|
||||
}
|
||||
|
||||
public unsafe double NextDouble()
|
||||
{
|
||||
byte[] b = new byte[8];
|
||||
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
b[7] = 0;
|
||||
_GetBytes(b, 0, 7);
|
||||
}
|
||||
else
|
||||
{
|
||||
b[0] = 0;
|
||||
_GetBytes(b, 1, 7);
|
||||
}
|
||||
|
||||
ulong r = 0;
|
||||
fixed (byte* buf = b)
|
||||
{
|
||||
r = *(ulong*)&buf[0] >> 3;
|
||||
}
|
||||
|
||||
/* double: 53 bits of significand precision
|
||||
* ulong.MaxValue >> 11 = 9007199254740991
|
||||
* 2^53 = 9007199254740992
|
||||
*/
|
||||
|
||||
return (double)r / 9007199254740992;
|
||||
GetBytes(b);
|
||||
}
|
||||
|
||||
private void CheckSwap(int c)
|
||||
|
|
@ -205,474 +158,91 @@ namespace Server
|
|||
|
||||
_filled.Reset();
|
||||
|
||||
ThreadPool.QueueUserWorkItem(Fill);
|
||||
Task.Run(Fill);
|
||||
}
|
||||
|
||||
private void Fill(object o)
|
||||
private void Fill()
|
||||
{
|
||||
lock (_CSP)
|
||||
{
|
||||
_CSP.GetBytes(_Buffer);
|
||||
}
|
||||
|
||||
_CSP.GetBytes(_Buffer);
|
||||
_filled.Set();
|
||||
}
|
||||
|
||||
private void _GetBytes(byte[] b)
|
||||
internal override void GetBytes(Span<byte> b)
|
||||
{
|
||||
int c = b.Length;
|
||||
|
||||
lock (_sync)
|
||||
{
|
||||
CheckSwap(c);
|
||||
Buffer.BlockCopy(_Working, _Index, b, 0, c);
|
||||
_Working.CopyTo(b);
|
||||
_Index += c;
|
||||
}
|
||||
}
|
||||
|
||||
private void _GetBytes(byte[] b, int offset, int count)
|
||||
internal override void GetBytes(byte[] b, int offset, int count)
|
||||
{
|
||||
lock (_sync)
|
||||
{
|
||||
CheckSwap(count);
|
||||
Buffer.BlockCopy(_Working, _Index, b, offset, count);
|
||||
_Index += count;
|
||||
}
|
||||
GetBytes(b.AsSpan(offset, count));
|
||||
}
|
||||
|
||||
private byte NextByte()
|
||||
public override byte NextByte()
|
||||
{
|
||||
lock (_sync)
|
||||
{
|
||||
CheckSwap(1);
|
||||
return _Working[_Index++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class RDRandUnix : IRandomImpl, IHardwareRNG
|
||||
{
|
||||
private static int BUFFER_SIZE = 0x10000;
|
||||
private static int LARGE_REQUEST = 0x40;
|
||||
private byte[] _Buffer = new byte[BUFFER_SIZE];
|
||||
|
||||
private ManualResetEvent _filled = new ManualResetEvent(false);
|
||||
|
||||
private int _Index;
|
||||
|
||||
private object _sync = new object();
|
||||
|
||||
private byte[] _Working = new byte[BUFFER_SIZE];
|
||||
|
||||
public RDRandUnix()
|
||||
{
|
||||
SafeNativeMethods.rdrand_get_bytes(BUFFER_SIZE, _Working);
|
||||
ThreadPool.QueueUserWorkItem(Fill);
|
||||
}
|
||||
|
||||
public bool IsSupported()
|
||||
{
|
||||
uint r = 0;
|
||||
return SafeNativeMethods.rdrand_32(ref r, true) == RDRandError.Success;
|
||||
}
|
||||
|
||||
public int Next(int c)
|
||||
{
|
||||
return (int)(c * NextDouble());
|
||||
}
|
||||
|
||||
public bool NextBool()
|
||||
{
|
||||
return (NextByte() & 1) == 1;
|
||||
}
|
||||
|
||||
public void NextBytes(byte[] b)
|
||||
{
|
||||
int c = b.Length;
|
||||
|
||||
if (c >= LARGE_REQUEST)
|
||||
{
|
||||
SafeNativeMethods.rdrand_get_bytes(c, b);
|
||||
return;
|
||||
}
|
||||
|
||||
_GetBytes(b);
|
||||
}
|
||||
|
||||
public unsafe double NextDouble()
|
||||
{
|
||||
byte[] b = new byte[8];
|
||||
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
b[7] = 0;
|
||||
_GetBytes(b, 0, 7);
|
||||
}
|
||||
else
|
||||
{
|
||||
b[0] = 0;
|
||||
_GetBytes(b, 1, 7);
|
||||
}
|
||||
|
||||
ulong r = 0;
|
||||
fixed (byte* buf = b)
|
||||
{
|
||||
r = *(ulong*)&buf[0] >> 3;
|
||||
}
|
||||
|
||||
/* double: 53 bits of significand precision
|
||||
* ulong.MaxValue >> 11 = 9007199254740991
|
||||
* 2^53 = 9007199254740992
|
||||
*/
|
||||
|
||||
return (double)r / 9007199254740992;
|
||||
}
|
||||
|
||||
private void CheckSwap(int c)
|
||||
{
|
||||
if (_Index + c < BUFFER_SIZE)
|
||||
return;
|
||||
|
||||
_filled.WaitOne();
|
||||
|
||||
byte[] b = _Working;
|
||||
_Working = _Buffer;
|
||||
_Buffer = b;
|
||||
_Index = 0;
|
||||
|
||||
_filled.Reset();
|
||||
|
||||
ThreadPool.QueueUserWorkItem(Fill);
|
||||
}
|
||||
|
||||
private void Fill(object o)
|
||||
{
|
||||
SafeNativeMethods.rdrand_get_bytes(BUFFER_SIZE, _Buffer);
|
||||
_filled.Set();
|
||||
}
|
||||
|
||||
private void _GetBytes(byte[] b)
|
||||
{
|
||||
int c = b.Length;
|
||||
|
||||
lock (_sync)
|
||||
{
|
||||
CheckSwap(c);
|
||||
Buffer.BlockCopy(_Working, _Index, b, 0, c);
|
||||
_Index += c;
|
||||
}
|
||||
}
|
||||
|
||||
private void _GetBytes(byte[] b, int offset, int count)
|
||||
{
|
||||
lock (_sync)
|
||||
{
|
||||
CheckSwap(count);
|
||||
Buffer.BlockCopy(_Working, _Index, b, offset, count);
|
||||
_Index += count;
|
||||
}
|
||||
}
|
||||
|
||||
private byte NextByte()
|
||||
{
|
||||
lock (_sync)
|
||||
{
|
||||
CheckSwap(1);
|
||||
return _Working[_Index++];
|
||||
}
|
||||
}
|
||||
|
||||
internal class SafeNativeMethods
|
||||
public sealed class RDRandUnix : BaseRandom, IHardwareRNG
|
||||
{
|
||||
[DllImport("rdrand.so")]
|
||||
internal static extern RDRandError rdrand_32(ref uint rand, bool retry);
|
||||
|
||||
[DllImport("rdrand.so")]
|
||||
internal static extern RDRandError rdrand_get_bytes(int n, byte[] buffer);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class RDRand32 : IRandomImpl, IHardwareRNG
|
||||
{
|
||||
private static int BUFFER_SIZE = 0x10000;
|
||||
private static int LARGE_REQUEST = 0x40;
|
||||
private byte[] _Buffer = new byte[BUFFER_SIZE];
|
||||
|
||||
private ManualResetEvent _filled = new ManualResetEvent(false);
|
||||
|
||||
private int _Index;
|
||||
|
||||
private object _sync = new object();
|
||||
|
||||
private byte[] _Working = new byte[BUFFER_SIZE];
|
||||
|
||||
public RDRand32()
|
||||
{
|
||||
SafeNativeMethods.rdrand_get_bytes(BUFFER_SIZE, _Working);
|
||||
ThreadPool.QueueUserWorkItem(Fill);
|
||||
}
|
||||
internal static extern unsafe RDRandError rdrand_get_bytes(int n, byte* buffer);
|
||||
|
||||
public bool IsSupported()
|
||||
{
|
||||
uint r = 0;
|
||||
return SafeNativeMethods.rdrand_32(ref r, true) == RDRandError.Success;
|
||||
return rdrand_32(ref r, true) == RDRandError.Success;
|
||||
}
|
||||
|
||||
public int Next(int c)
|
||||
internal override unsafe void GetBytes(Span<byte> b)
|
||||
{
|
||||
return (int)(c * NextDouble());
|
||||
fixed(byte* ptr = b)
|
||||
rdrand_get_bytes(b.Length, ptr);
|
||||
}
|
||||
|
||||
public bool NextBool()
|
||||
internal override void GetBytes(byte[] b, int offset, int count)
|
||||
{
|
||||
return (NextByte() & 1) == 1;
|
||||
}
|
||||
|
||||
public void NextBytes(byte[] b)
|
||||
{
|
||||
int c = b.Length;
|
||||
|
||||
if (c >= LARGE_REQUEST)
|
||||
{
|
||||
SafeNativeMethods.rdrand_get_bytes(c, b);
|
||||
return;
|
||||
}
|
||||
|
||||
_GetBytes(b);
|
||||
}
|
||||
|
||||
public unsafe double NextDouble()
|
||||
{
|
||||
byte[] b = new byte[8];
|
||||
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
b[7] = 0;
|
||||
_GetBytes(b, 0, 7);
|
||||
}
|
||||
else
|
||||
{
|
||||
b[0] = 0;
|
||||
_GetBytes(b, 1, 7);
|
||||
}
|
||||
|
||||
ulong r = 0;
|
||||
fixed (byte* buf = b)
|
||||
{
|
||||
r = *(ulong*)&buf[0] >> 3;
|
||||
}
|
||||
|
||||
/* double: 53 bits of significand precision
|
||||
* ulong.MaxValue >> 11 = 9007199254740991
|
||||
* 2^53 = 9007199254740992
|
||||
*/
|
||||
|
||||
return (double)r / 9007199254740992;
|
||||
}
|
||||
|
||||
private void CheckSwap(int c)
|
||||
{
|
||||
if (_Index + c < BUFFER_SIZE)
|
||||
return;
|
||||
|
||||
_filled.WaitOne();
|
||||
|
||||
byte[] b = _Working;
|
||||
_Working = _Buffer;
|
||||
_Buffer = b;
|
||||
_Index = 0;
|
||||
|
||||
_filled.Reset();
|
||||
|
||||
ThreadPool.QueueUserWorkItem(Fill);
|
||||
}
|
||||
|
||||
private void Fill(object o)
|
||||
{
|
||||
SafeNativeMethods.rdrand_get_bytes(BUFFER_SIZE, _Buffer);
|
||||
_filled.Set();
|
||||
}
|
||||
|
||||
private void _GetBytes(byte[] b)
|
||||
{
|
||||
int c = b.Length;
|
||||
|
||||
lock (_sync)
|
||||
{
|
||||
CheckSwap(c);
|
||||
Buffer.BlockCopy(_Working, _Index, b, 0, c);
|
||||
_Index += c;
|
||||
GetBytes(b.AsSpan().Slice(offset, count));
|
||||
}
|
||||
}
|
||||
|
||||
private void _GetBytes(byte[] b, int offset, int count)
|
||||
public sealed class RDRand64 : BaseRandom, IHardwareRNG
|
||||
{
|
||||
lock (_sync)
|
||||
{
|
||||
CheckSwap(count);
|
||||
Buffer.BlockCopy(_Working, _Index, b, offset, count);
|
||||
_Index += count;
|
||||
}
|
||||
}
|
||||
[DllImport("rdrand")]
|
||||
internal static extern RDRandError rdrand_64(ref ulong rand, bool retry);
|
||||
|
||||
private byte NextByte()
|
||||
{
|
||||
lock (_sync)
|
||||
{
|
||||
CheckSwap(1);
|
||||
return _Working[_Index++];
|
||||
}
|
||||
}
|
||||
|
||||
internal class SafeNativeMethods
|
||||
{
|
||||
[DllImport("rdrand32")]
|
||||
internal static extern RDRandError rdrand_32(ref uint rand, bool retry);
|
||||
|
||||
[DllImport("rdrand32")]
|
||||
internal static extern RDRandError rdrand_get_bytes(int n, byte[] buffer);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class RDRand64 : IRandomImpl, IHardwareRNG
|
||||
{
|
||||
private static int BUFFER_SIZE = 0x10000;
|
||||
private static int LARGE_REQUEST = 0x40;
|
||||
private byte[] _Buffer = new byte[BUFFER_SIZE];
|
||||
|
||||
private ManualResetEvent _filled = new ManualResetEvent(false);
|
||||
|
||||
private int _Index;
|
||||
|
||||
private object _sync = new object();
|
||||
|
||||
private byte[] _Working = new byte[BUFFER_SIZE];
|
||||
|
||||
public RDRand64()
|
||||
{
|
||||
SafeNativeMethods.rdrand_get_bytes(BUFFER_SIZE, _Working);
|
||||
ThreadPool.QueueUserWorkItem(Fill);
|
||||
}
|
||||
[DllImport("rdrand")]
|
||||
internal static extern unsafe RDRandError rdrand_get_bytes(int n, byte* buffer);
|
||||
|
||||
public bool IsSupported()
|
||||
{
|
||||
ulong r = 0;
|
||||
return SafeNativeMethods.rdrand_64(ref r, true) == RDRandError.Success;
|
||||
return rdrand_64(ref r, true) == RDRandError.Success;
|
||||
}
|
||||
|
||||
public int Next(int c)
|
||||
internal override unsafe void GetBytes(Span<byte> b)
|
||||
{
|
||||
return (int)(c * NextDouble());
|
||||
fixed (byte* ptr = b)
|
||||
rdrand_get_bytes(b.Length, ptr);
|
||||
}
|
||||
|
||||
public bool NextBool()
|
||||
internal override void GetBytes(byte[] b, int offset, int count)
|
||||
{
|
||||
return (NextByte() & 1) == 1;
|
||||
}
|
||||
|
||||
public void NextBytes(byte[] b)
|
||||
{
|
||||
int c = b.Length;
|
||||
|
||||
if (c >= LARGE_REQUEST)
|
||||
{
|
||||
SafeNativeMethods.rdrand_get_bytes(c, b);
|
||||
return;
|
||||
}
|
||||
|
||||
_GetBytes(b);
|
||||
}
|
||||
|
||||
public unsafe double NextDouble()
|
||||
{
|
||||
byte[] b = new byte[8];
|
||||
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
b[7] = 0;
|
||||
_GetBytes(b, 0, 7);
|
||||
}
|
||||
else
|
||||
{
|
||||
b[0] = 0;
|
||||
_GetBytes(b, 1, 7);
|
||||
}
|
||||
|
||||
ulong r = 0;
|
||||
fixed (byte* buf = b)
|
||||
{
|
||||
r = *(ulong*)&buf[0] >> 3;
|
||||
}
|
||||
|
||||
/* double: 53 bits of significand precision
|
||||
* ulong.MaxValue >> 11 = 9007199254740991
|
||||
* 2^53 = 9007199254740992
|
||||
*/
|
||||
|
||||
return (double)r / 9007199254740992;
|
||||
}
|
||||
|
||||
private void CheckSwap(int c)
|
||||
{
|
||||
if (_Index + c < BUFFER_SIZE)
|
||||
return;
|
||||
|
||||
_filled.WaitOne();
|
||||
|
||||
byte[] b = _Working;
|
||||
_Working = _Buffer;
|
||||
_Buffer = b;
|
||||
_Index = 0;
|
||||
|
||||
_filled.Reset();
|
||||
|
||||
ThreadPool.QueueUserWorkItem(Fill);
|
||||
}
|
||||
|
||||
private void Fill(object o)
|
||||
{
|
||||
SafeNativeMethods.rdrand_get_bytes(BUFFER_SIZE, _Buffer);
|
||||
_filled.Set();
|
||||
}
|
||||
|
||||
private void _GetBytes(byte[] b)
|
||||
{
|
||||
int c = b.Length;
|
||||
|
||||
lock (_sync)
|
||||
{
|
||||
CheckSwap(c);
|
||||
Buffer.BlockCopy(_Working, _Index, b, 0, c);
|
||||
_Index += c;
|
||||
}
|
||||
}
|
||||
|
||||
private void _GetBytes(byte[] b, int offset, int count)
|
||||
{
|
||||
lock (_sync)
|
||||
{
|
||||
CheckSwap(count);
|
||||
Buffer.BlockCopy(_Working, _Index, b, offset, count);
|
||||
_Index += count;
|
||||
}
|
||||
}
|
||||
|
||||
private byte NextByte()
|
||||
{
|
||||
lock (_sync)
|
||||
{
|
||||
CheckSwap(1);
|
||||
return _Working[_Index++];
|
||||
}
|
||||
}
|
||||
|
||||
internal class SafeNativeMethods
|
||||
{
|
||||
[DllImport("rdrand64")]
|
||||
internal static extern RDRandError rdrand_64(ref ulong rand, bool retry);
|
||||
|
||||
[DllImport("rdrand64")]
|
||||
internal static extern RDRandError rdrand_get_bytes(int n, byte[] buffer);
|
||||
GetBytes(b.AsSpan(offset, count));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -687,4 +257,4 @@ namespace Server
|
|||
|
||||
Success = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1072,7 +1072,7 @@ namespace Server
|
|||
Type type;
|
||||
try
|
||||
{
|
||||
type = ScriptCompiler.FindTypeByName(s, false);
|
||||
type = AssemblyHandler.FindTypeByName(s, false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="Current">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
</StartupObject>
|
||||
<AssemblyName>ModernUO</AssemblyName>
|
||||
<Win32Resource />
|
||||
<Version>3.0.0</Version>
|
||||
<Version>0.0.1</Version>
|
||||
<Authors>Kamron Batman</Authors>
|
||||
<Company>ModernUO</Company>
|
||||
<Product>ModernUO</Product>
|
||||
|
|
@ -15,54 +15,43 @@
|
|||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.0'">
|
||||
<DefineConstants>NETCORE;NETSTANDARD</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DefineConstants>TRACE;DEBUG</DefineConstants>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\..\Distribution\</OutputPath>
|
||||
<OutDir>..\..\Distribution</OutDir>
|
||||
<WarningsAsErrors />
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<PublishDir>..\..\Distribution</PublishDir>
|
||||
<OutDir>..\..\Distribution</OutDir>
|
||||
<OutputPath>..\..\Distribution</OutputPath>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<OutputPath>..\..\Distribution\</OutputPath>
|
||||
<OutDir>..\..\Distribution</OutDir>
|
||||
<WarningsAsErrors />
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<PublishDir>..\..\Distribution</PublishDir>
|
||||
<OutDir>..\..\Distribution</OutDir>
|
||||
<OutputPath>..\..\Distribution</OutputPath>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Assemblies\rdrand.so">
|
||||
<Content Include="Assemblies\zlib.dll" Condition="'$(RuntimeIdentifier)'=='win-x64'">
|
||||
<Link>zlib.dll</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Assemblies\rdrand.dll" Condition="'$(RuntimeIdentifier)'=='win-x64'">
|
||||
<Link>rdrand.dll</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Assemblies\rdrand.so" Condition="'$(RuntimeIdentifier)'=='osx-x64' OR '$(RuntimeIdentifier)'=='linux-x64'">
|
||||
<Link>rdrand.so</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Assemblies\rdrand32.dll">
|
||||
<Link>rdrand32.dll</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Assemblies\rdrand64.dll">
|
||||
<Link>rdrand64.dll</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Assemblies\zlib32.dll">
|
||||
<Link>zlib32.dll</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Assemblies\zlib64.dll">
|
||||
<Link>zlib64.dll</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System.IO.Pipelines">
|
||||
<HintPath>Assemblies\System.IO.Pipelines.dll</HintPath>
|
||||
<IncludeInPackage>false</IncludeInPackage>
|
||||
</Reference>
|
||||
<PackageReference Include="System.IO.Pipelines" Version="4.6.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -422,7 +422,7 @@ namespace Server
|
|||
|
||||
public void Force()
|
||||
{
|
||||
if (ScriptCompiler.Assemblies == null || ScriptCompiler.Assemblies.Length == 0)
|
||||
if ((AssemblyHandler.Assemblies?.Length ?? 0) == 0)
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ namespace Server
|
|||
{
|
||||
string typeName = tdbReader.ReadString();
|
||||
|
||||
Type t = ScriptCompiler.FindTypeByFullName(typeName);
|
||||
Type t = AssemblyHandler.FindTypeByFullName(typeName);
|
||||
|
||||
if (t == null)
|
||||
{
|
||||
|
|
@ -703,7 +703,7 @@ namespace Server
|
|||
}
|
||||
else
|
||||
{
|
||||
Mobiles[m.Serial] = m;
|
||||
Mobiles.Add(m.Serial, m);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -723,7 +723,7 @@ namespace Server
|
|||
}
|
||||
else
|
||||
{
|
||||
Items[item.Serial] = item;
|
||||
Items.Add(item.Serial, item);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,24 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7"/>
|
||||
</startup>
|
||||
<runtime>
|
||||
<gcServer enabled="true"/>
|
||||
</runtime>
|
||||
<!--Linux users will need to uncomment and modify the following line:-->
|
||||
<!--<dllmap dll="libz" target="/lib/x86_64-linux-gnu/libz.so.1" />-->
|
||||
<appSettings>
|
||||
<add key="aspnet:RoslynCompilerLocation" value="roslyn"/>
|
||||
</appSettings>
|
||||
<system.codedom>
|
||||
<compilers>
|
||||
<compiler language="c#;cs;csharp" extension=".cs"
|
||||
type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
|
||||
warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701"/>
|
||||
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb"
|
||||
type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
|
||||
warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\"Web\" /optionInfer+"/>
|
||||
</compilers>
|
||||
</system.codedom>
|
||||
</configuration>
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages />
|
||||
Loading…
Add table
Add a link
Reference in a new issue