Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
181
Scripts/SubSystem/VitaNex/Core/Network/Decompression.cs
Normal file
181
Scripts/SubSystem/VitaNex/Core/Network/Decompression.cs
Normal file
@@ -0,0 +1,181 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Network
|
||||
{
|
||||
public static class Decompressor
|
||||
{
|
||||
#region Decompression Tree
|
||||
private static readonly int[,] _HuffmanTree =
|
||||
{
|
||||
/*node*/ /*leaf0 leaf1*/
|
||||
/* 0*/ {2, 1}, /* 1*/ {4, 3}, /* 2*/ {0, 5}, /* 3*/ {7, 6}, /* 4*/ {9, 8}, /* 5*/ {11, 10}, /* 6*/ {13, 12}, /* 7*/
|
||||
{14, -256}, /* 8*/ {16, 15}, /* 9*/ {18, 17}, /* 10*/ {20, 19}, /* 11*/ {22, 21}, /* 12*/ {23, -1}, /* 13*/
|
||||
{25, 24}, /* 14*/ {27, 26}, /* 15*/ {29, 28}, /* 16*/ {31, 30}, /* 17*/ {33, 32}, /* 18*/ {35, 34}, /* 19*/
|
||||
{37, 36}, /* 20*/ {39, 38}, /* 21*/ {-64, 40}, /* 22*/ {42, 41}, /* 23*/ {44, 43}, /* 24*/ {45, -6}, /* 25*/
|
||||
{47, 46}, /* 26*/ {49, 48}, /* 27*/ {51, 50}, /* 28*/ {52, -119}, /* 29*/ {53, -32}, /* 30*/ {-14, 54}, /* 31*/
|
||||
{-5, 55}, /* 32*/ {57, 56}, /* 33*/ {59, 58}, /* 34*/ {-2, 60}, /* 35*/ {62, 61}, /* 36*/ {64, 63}, /* 37*/
|
||||
{66, 65}, /* 38*/ {68, 67}, /* 39*/ {70, 69}, /* 40*/ {72, 71}, /* 41*/ {73, -51}, /* 42*/ {75, 74}, /* 43*/
|
||||
{77, 76}, /* 44*/ {-111, -101}, /* 45*/ {-97, -4}, /* 46*/ {79, 78}, /* 47*/ {80, -110}, /* 48*/ {-116, 81}, /* 49*/
|
||||
{83, 82}, /* 50*/ {-255, 84}, /* 51*/ {86, 85}, /* 52*/ {88, 87}, /* 53*/ {90, 89}, /* 54*/ {-10, -15}, /* 55*/
|
||||
{92, 91}, /* 56*/ {93, -21}, /* 57*/ {94, -117}, /* 58*/ {96, 95}, /* 59*/ {98, 97}, /* 60*/ {100, 99}, /* 61*/
|
||||
{101, -114}, /* 62*/ {102, -105}, /* 63*/ {103, -26}, /* 64*/ {105, 104}, /* 65*/ {107, 106}, /* 66*/ {109, 108},
|
||||
/* 67*/ {111, 110}, /* 68*/ {-3, 112}, /* 69*/ {-7, 113}, /* 70*/ {-131, 114}, /* 71*/ {-144, 115}, /* 72*/
|
||||
{117, 116}, /* 73*/ {118, -20}, /* 74*/ {120, 119}, /* 75*/ {122, 121}, /* 76*/ {124, 123}, /* 77*/
|
||||
{126, 125}, /* 78*/ {128, 127}, /* 79*/ {-100, 129}, /* 80*/ {-8, 130},
|
||||
/* 81*/ {132, 131}, /* 82*/ {134, 133}, /* 83*/ {135, -120}, /* 84*/ {-31, 136}, /* 85*/ {138, 137}, /* 86*/
|
||||
{-234, -109}, /* 87*/ {140, 139}, /* 88*/ {142, 141}, /* 89*/ {144, 143},
|
||||
/* 90*/ {145, -112}, /* 91*/ {146, -19}, /* 92*/ {148, 147}, /* 93*/ {-66, 149}, /* 94*/ {-145, 150}, /* 95*/
|
||||
{-65, -13}, /* 96*/ {152, 151}, /* 97*/ {154, 153}, /* 98*/ {155, -30},
|
||||
/* 99*/ {157, 156}, /* 100*/ {158, -99}, /* 101*/ {160, 159}, /* 102*/ {162, 161}, /* 103*/ {163, -23}, /* 104*/
|
||||
{164, -29}, /* 105*/ {165, -11}, /* 106*/ {-115, 166}, /* 107*/ {168, 167},
|
||||
/* 108*/ {170, 169}, /* 109*/ {171, -16}, /* 110*/ {172, -34}, /* 111*/ {-132, 173}, /* 112*/ {-108, 174}, /* 113*/
|
||||
{-22, 175}, /* 114*/ {-9, 176}, /* 115*/ {-84, 177}, /* 116*/ {-37, -17},
|
||||
/* 117*/ {178, -28}, /* 118*/ {180, 179}, /* 119*/ {182, 181}, /* 120*/ {184, 183}, /* 121*/ {186, 185}, /* 122*/
|
||||
{-104, 187}, /* 123*/ {-78, 188}, /* 124*/ {-61, 189}, /* 125*/ {-178, -79},
|
||||
/* 126*/ {-134, -59}, /* 127*/ {-25, 190}, /* 128*/ {-18, -83}, /* 129*/ {-57, 191}, /* 130*/ {192, -67}, /* 131*/
|
||||
{193, -98}, /* 132*/ {-68, -12}, /* 133*/ {195, 194}, /* 134*/ {-128, -55},
|
||||
/* 135*/ {-50, -24}, /* 136*/ {196, -70}, /* 137*/ {-33, -94}, /* 138*/ {-129, 197}, /* 139*/ {198, -74}, /* 140*/
|
||||
{199, -82}, /* 141*/ {-87, -56}, /* 142*/ {200, -44}, /* 143*/ {201, -248},
|
||||
/* 144*/ {-81, -163}, /* 145*/ {-123, -52}, /* 146*/ {-113, 202}, /* 147*/ {-41, -48}, /* 148*/ {-40, -122}, /* 149*/
|
||||
{-90, 203}, /* 150*/ {204, -54}, /* 151*/ {-192, -86}, /* 152*/ {206, 205},
|
||||
/* 153*/ {-130, 207}, /* 154*/ {208, -53}, /* 155*/ {-45, -133}, /* 156*/ {210, 209}, /* 157*/ {-91, 211}, /* 158*/
|
||||
{213, 212}, /* 159*/ {-88, -106}, /* 160*/ {215, 214}, /* 161*/ {217, 216},
|
||||
/* 162*/ {-49, 218}, /* 163*/ {220, 219}, /* 164*/ {222, 221}, /* 165*/ {224, 223}, /* 166*/ {226, 225}, /* 167*/
|
||||
{-102, 227}, /* 168*/ {228, -160}, /* 169*/ {229, -46}, /* 170*/ {230, -127}, /* 171*/ {231, -103}, /* 172*/
|
||||
{233, 232}, /* 173*/ {234, -60}, /* 174*/ {-76, 235}, /* 175*/ {-121, 236}, /* 176*/ {-73, 237}, /* 177*/
|
||||
{238, -149}, /* 178*/ {-107, 239}, /* 179*/ {240, -35}, /* 180*/ {-27, -71}, /* 181*/ {241, -69}, /* 182*/
|
||||
{-77, -89}, /* 183*/ {-118, -62}, /* 184*/ {-85, -75}, /* 185*/ {-58, -72}, /* 186*/ {-80, -63}, /* 187*/
|
||||
{-42, 242}, /* 188*/ {-157, -150}, /* 189*/ {-236, -139}, /* 190*/ {-243, -126}, /* 191*/ {-214, -142}, /* 192*/
|
||||
{-206, -138}, /* 193*/ {-146, -240}, /* 194*/ {-147, -204}, /* 195*/ {-201, -152}, /* 196*/ {-207, -227}, /* 197*/
|
||||
{-209, -154}, /* 198*/ {-254, -153}, /* 199*/ {-156, -176}, /* 200*/ {-210, -165}, /* 201*/ {-185, -172}, /* 202*/
|
||||
{-170, -195}, /* 203*/ {-211, -232}, /* 204*/ {-239, -219}, /* 205*/ {-177, -200}, /* 206*/ {-212, -175}, /* 207*/
|
||||
{-143, -244}, /* 208*/ {-171, -246}, /* 209*/ {-221, -203}, /* 210*/ {-181, -202}, /* 211*/ {-250, -173}, /* 212*/
|
||||
{-164, -184}, /* 213*/ {-218, -193}, /* 214*/ {-220, -199}, /* 215*/ {-249, -190}, /* 216*/ {-217, -230}, /* 217*/
|
||||
{-216, -169}, /* 218*/ {-197, -191}, /* 219*/ {243, -47}, /* 220*/ {245, 244}, /* 221*/ {247, 246}, /* 222*/
|
||||
{-159, -148}, /* 223*/ {249, 248}, /* 224*/ {-93, -92}, /* 225*/ {-225, -96}, /* 226*/ {-95, -151}, /* 227*/
|
||||
{251, 250}, /* 228*/ {252, -241}, /* 229*/ {-36, -161}, /* 230*/ {254, 253}, /* 231*/ {-39, -135}, /* 232*/
|
||||
{-124, -187}, /* 233*/ {-251, 255}, /* 234*/ {-238, -162}, /* 235*/ {-38, -242}, /* 236*/ {-125, -43}, /* 237*/
|
||||
{-253, -215}, /* 238*/ {-208, -140}, /* 239*/ {-235, -137}, /* 240*/ {-237, -158}, /* 241*/ {-205, -136}, /* 242*/
|
||||
{-141, -155}, /* 243*/ {-229, -228}, /* 244*/ {-168, -213}, /* 245*/ {-194, -224}, /* 246*/ {-226, -196}, /* 247*/
|
||||
{-233, -183}, /* 248*/ {-167, -231}, /* 249*/ {-189, -174}, /* 250*/ {-166, -252}, /* 251*/ {-222, -198}, /* 252*/
|
||||
{-179, -188}, /* 253*/ {-182, -223}, /* 254*/ {-186, -180}, /* 255*/ {-247, -245}
|
||||
};
|
||||
#endregion
|
||||
|
||||
private static int GetBit(int buf, int bit)
|
||||
{
|
||||
return (buf >> (bit - 1)) & 1;
|
||||
}
|
||||
|
||||
private static int PutBit(ref byte b, int bit)
|
||||
{
|
||||
var bitNum = 1 << (bit - 1);
|
||||
b |= (byte)bitNum;
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static int RemoveBit(ref byte b, int bit)
|
||||
{
|
||||
int bitNum;
|
||||
|
||||
if (GetBit(b, bit) != -1)
|
||||
{
|
||||
bitNum = 1 << (bit - 1);
|
||||
b ^= (byte)bitNum;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
public static void DecompressAll(byte[] src, int srcSize, byte[] dest, out int destSize)
|
||||
{
|
||||
int node = 0, leaf, leafValue, destPos = 0, bitNum = 8, srcPos = 0;
|
||||
|
||||
while (srcPos < srcSize)
|
||||
{
|
||||
leaf = GetBit(src[srcPos], bitNum);
|
||||
leafValue = _HuffmanTree[node, leaf];
|
||||
|
||||
if (leafValue == -256)
|
||||
{
|
||||
bitNum = 8;
|
||||
node = 0;
|
||||
srcPos++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (leafValue < 1)
|
||||
{
|
||||
dest[destPos] = (byte)-leafValue;
|
||||
leafValue = 0;
|
||||
destPos++;
|
||||
}
|
||||
|
||||
bitNum--;
|
||||
node = leafValue;
|
||||
|
||||
if (bitNum >= 1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bitNum = 8;
|
||||
srcPos++;
|
||||
}
|
||||
|
||||
destSize = destPos;
|
||||
}
|
||||
|
||||
public static byte? DecompressFirstByte(byte[] src, int srcLength)
|
||||
{
|
||||
int node = 0, leaf, leafValue, bitNum = 8, srcPos = 0;
|
||||
|
||||
while (srcPos < srcLength)
|
||||
{
|
||||
leaf = GetBit(src[srcPos], bitNum);
|
||||
leafValue = _HuffmanTree[node, leaf];
|
||||
|
||||
if (leafValue == -256)
|
||||
{
|
||||
bitNum = 8;
|
||||
node = 0;
|
||||
srcPos++;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (leafValue < 1)
|
||||
{
|
||||
return (byte)-leafValue;
|
||||
}
|
||||
|
||||
bitNum--;
|
||||
node = leafValue;
|
||||
|
||||
if (bitNum >= 1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bitNum = 8;
|
||||
srcPos++;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static bool IsCompressed(byte[] buffer)
|
||||
{
|
||||
return DecompressFirstByte(buffer, buffer.Length) != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
162
Scripts/SubSystem/VitaNex/Core/Network/EmailOptions.cs
Normal file
162
Scripts/SubSystem/VitaNex/Core/Network/EmailOptions.cs
Normal file
@@ -0,0 +1,162 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Mail;
|
||||
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Network
|
||||
{
|
||||
public class EmailOptions : PropertyObject
|
||||
{
|
||||
[CommandProperty(AccessLevel.Administrator)]
|
||||
public bool Auth { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.Administrator)]
|
||||
public string From { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.Administrator)]
|
||||
public string To { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.Administrator)]
|
||||
public string Host { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.Administrator)]
|
||||
public int Port { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.Administrator)]
|
||||
public string User { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.Administrator)]
|
||||
public string Pass { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.Administrator)]
|
||||
public bool Valid => Port > 0 && !String.IsNullOrWhiteSpace(Host) && !String.IsNullOrWhiteSpace(From) && !String.IsNullOrWhiteSpace(To);
|
||||
|
||||
public EmailOptions()
|
||||
{
|
||||
Auth = false;
|
||||
From = String.Empty;
|
||||
To = String.Empty;
|
||||
Host = String.Empty;
|
||||
Port = 25;
|
||||
User = String.Empty;
|
||||
Pass = String.Empty;
|
||||
}
|
||||
|
||||
public EmailOptions(GenericReader reader)
|
||||
: base(reader)
|
||||
{ }
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
Auth = false;
|
||||
From = String.Empty;
|
||||
To = String.Empty;
|
||||
Host = String.Empty;
|
||||
Port = 0;
|
||||
User = String.Empty;
|
||||
Pass = String.Empty;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
Auth = false;
|
||||
From = String.Empty;
|
||||
To = String.Empty;
|
||||
Host = String.Empty;
|
||||
Port = 25;
|
||||
User = String.Empty;
|
||||
Pass = String.Empty;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "Email Options";
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
writer.Write(Auth);
|
||||
writer.Write(From);
|
||||
writer.Write(To);
|
||||
writer.Write(Host);
|
||||
writer.Write(Port);
|
||||
writer.Write(User);
|
||||
writer.Write(Pass);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
Auth = reader.ReadBool();
|
||||
From = reader.ReadString();
|
||||
To = reader.ReadString();
|
||||
Host = reader.ReadString();
|
||||
Port = reader.ReadInt();
|
||||
User = reader.ReadString();
|
||||
Pass = reader.ReadString();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public MailMessage CreateMessage()
|
||||
{
|
||||
return new MailMessage(From ?? String.Empty, To ?? String.Empty);
|
||||
}
|
||||
|
||||
public SmtpClient CreateClient()
|
||||
{
|
||||
var c = new SmtpClient(Host ?? String.Empty, Port > 0 ? Port : 0);
|
||||
|
||||
if (Auth)
|
||||
{
|
||||
c.Credentials = new NetworkCredential(User ?? String.Empty, Pass ?? String.Empty);
|
||||
c.UseDefaultCredentials = false;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
public static implicit operator MailMessage(EmailOptions o)
|
||||
{
|
||||
return o != null ? o.CreateMessage() : new MailMessage();
|
||||
}
|
||||
|
||||
public static implicit operator SmtpClient(EmailOptions o)
|
||||
{
|
||||
return o != null ? o.CreateClient() : new SmtpClient();
|
||||
}
|
||||
}
|
||||
}
|
||||
955
Scripts/SubSystem/VitaNex/Core/Network/ExtendedOPL.cs
Normal file
955
Scripts/SubSystem/VitaNex/Core/Network/ExtendedOPL.cs
Normal file
@@ -0,0 +1,955 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#if ServUO58
|
||||
#define ServUOX
|
||||
#endif
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Server;
|
||||
using Server.Network;
|
||||
|
||||
using VitaNex.Collections;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Network
|
||||
{
|
||||
public delegate void OPLQueryValidator(Mobile viewer, IEntity target, ref bool allow);
|
||||
|
||||
/// <summary>
|
||||
/// Provides methods for extending Item and Mobile ObjectPropertyLists by invoking event subscriptions - No more
|
||||
/// GetProperties overrides!
|
||||
/// </summary>
|
||||
public sealed class ExtendedOPL : IList<string>, IDisposable
|
||||
{
|
||||
private static readonly object _OPLLock = new object();
|
||||
|
||||
private static readonly string[] _EmptyBuffer = new string[0];
|
||||
|
||||
/// <summary>
|
||||
/// Breaks EmptyClilocs every Nth entry. EG: When 5 entries have been added, use the next clilocID
|
||||
/// </summary>
|
||||
public static int ClilocBreak = 5;
|
||||
|
||||
/// <summary>
|
||||
/// Breaks EmptyClilocs when the current string value length exceeds this threshold, regardless of the current
|
||||
/// ClilocBreak.
|
||||
/// </summary>
|
||||
public static int ClilocThreshold = 160;
|
||||
|
||||
/// <summary>
|
||||
/// Empty clilocID list extended with ~1_VAL~ *support should be the same as ~1_NOTHING~
|
||||
/// The default settings for an ExtendedOPL instance allows for up to 65 custom cliloc entries.
|
||||
/// Capacity is equal to the number of available empty clilocs multiplied by the cliloc break value.
|
||||
/// Default: 65 == 13 * 5
|
||||
/// Clilocs with multiple argument support will be parsed accordingly.
|
||||
/// It is recommended to use clilocs that contain no characters other than the argument placeholders and whitespace.
|
||||
/// </summary>
|
||||
public static int[] EmptyClilocs =
|
||||
{
|
||||
//1042971, 1070722, // ~1_NOTHING~ (Reserved by ObjectPropertyList)
|
||||
1114057, 1114778, 1114779, // ~1_val~
|
||||
1150541, // ~1_TOKEN~
|
||||
1153153, // ~1_year~
|
||||
|
||||
1041522, // ~1~~2~~3~
|
||||
1060847, // ~1_val~ ~2_val~
|
||||
1116560, // ~1_val~ ~2_val~
|
||||
1116690, // ~1_val~ ~2_val~ ~3_val~
|
||||
1116691, // ~1_val~ ~2_val~ ~3_val~
|
||||
1116692, // ~1_val~ ~2_val~ ~3_val~
|
||||
1116693, // ~1_val~ ~2_val~ ~3_val~
|
||||
1116694 // ~1_val~ ~2_val~ ~3_val~
|
||||
};
|
||||
|
||||
public static bool Initialized { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value representing the parent OPL PacketHandler that was overridden, if any
|
||||
/// </summary>
|
||||
public static PacketHandler ReqOplParent { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value representing the parent BatchOPL PacketHandler that was overridden, if any
|
||||
/// </summary>
|
||||
public static PacketHandler ReqBatchOplParent { get; private set; }
|
||||
|
||||
#if !ServUOX
|
||||
/// <summary>
|
||||
/// Gets a value representing the parent BatchOPL PacketHandler that was overridden, if any
|
||||
/// </summary>
|
||||
public static PacketHandler ReqBatchOplParent6017 { get; private set; }
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value represting the handler to use when decoding OPL packet 0xD6
|
||||
/// </summary>
|
||||
public static OutgoingPacketOverrideHandler OutParent0xD6 { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Event called when an Item based OPL is requested
|
||||
/// </summary>
|
||||
public static event Action<Item, Mobile, ExtendedOPL> OnItemOPLRequest;
|
||||
|
||||
/// <summary>
|
||||
/// Event called when a Mobile based OPL is requested
|
||||
/// </summary>
|
||||
public static event Action<Mobile, Mobile, ExtendedOPL> OnMobileOPLRequest;
|
||||
|
||||
/// <summary>
|
||||
/// Event called when an IEntity based OPL is requested that doesn't match an Item or Mobile
|
||||
/// </summary>
|
||||
public static event Action<IEntity, Mobile, ExtendedOPL> OnEntityOPLRequest;
|
||||
|
||||
/// <summary>
|
||||
/// Event called when an IEntity based OPL is requested
|
||||
/// </summary>
|
||||
public static event OPLQueryValidator OnValidateQuery;
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
if (Initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
OutParent0xD6 = OutgoingPacketOverrides.GetHandler(0xD6);
|
||||
OutgoingPacketOverrides.Register(0xD6, OnEncode0xD6);
|
||||
|
||||
ReqOplParent = PacketHandlers.GetExtendedHandler(0x10);
|
||||
PacketHandlers.RegisterExtended(ReqOplParent.PacketID, ReqOplParent.Ingame, OnQueryProperties);
|
||||
|
||||
ReqBatchOplParent = PacketHandlers.GetHandler(0xD6);
|
||||
PacketHandlers.Register(ReqBatchOplParent.PacketID, ReqBatchOplParent.Length, ReqBatchOplParent.Ingame, OnBatchQueryProperties);
|
||||
|
||||
#if !ServUOX
|
||||
ReqBatchOplParent6017 = PacketHandlers.Get6017Handler(0xD6);
|
||||
PacketHandlers.Register6017(ReqBatchOplParent6017.PacketID, ReqBatchOplParent6017.Length, ReqBatchOplParent6017.Ingame, OnBatchQueryProperties);
|
||||
#endif
|
||||
|
||||
Initialized = true;
|
||||
}
|
||||
|
||||
public static ObjectPropertyList ResolveOPL(IEntity e)
|
||||
{
|
||||
return ResolveOPL(e, false);
|
||||
}
|
||||
|
||||
public static ObjectPropertyList ResolveOPL(IEntity e, Mobile v)
|
||||
{
|
||||
return ResolveOPL(e, v, false);
|
||||
}
|
||||
|
||||
public static ObjectPropertyList ResolveOPL(IEntity e, bool headerOnly)
|
||||
{
|
||||
return ResolveOPL(e, null, headerOnly);
|
||||
}
|
||||
|
||||
public static ObjectPropertyList ResolveOPL(IEntity e, Mobile v, bool headerOnly)
|
||||
{
|
||||
if (e?.Deleted != false)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
ObjectPropertyList opl = null;
|
||||
|
||||
if (e is Item item)
|
||||
{
|
||||
if (item.BeginAction(_OPLLock))
|
||||
{
|
||||
opl = new ObjectPropertyList(item);
|
||||
|
||||
if (headerOnly)
|
||||
{
|
||||
item.AddNameProperty(opl);
|
||||
}
|
||||
else
|
||||
{
|
||||
item.GetProperties(opl);
|
||||
item.AppendChildProperties(opl);
|
||||
}
|
||||
|
||||
item.EndAction(_OPLLock);
|
||||
}
|
||||
}
|
||||
else if (e is Mobile mob)
|
||||
{
|
||||
if (mob.BeginAction(_OPLLock))
|
||||
{
|
||||
opl = new ObjectPropertyList(mob);
|
||||
|
||||
if (headerOnly)
|
||||
{
|
||||
mob.AddNameProperties(opl);
|
||||
}
|
||||
else
|
||||
{
|
||||
mob.GetProperties(opl);
|
||||
}
|
||||
|
||||
mob.EndAction(_OPLLock);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
opl = new ObjectPropertyList(e);
|
||||
|
||||
var result = e.InvokeMethod("AddNameProperty", opl);
|
||||
|
||||
if (result == null || result is Exception)
|
||||
{
|
||||
result = e.InvokeMethod("AddNameProperties", opl);
|
||||
}
|
||||
|
||||
if (result == null || result is Exception)
|
||||
{
|
||||
opl.Add(e.Name ?? string.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
if (opl != null)
|
||||
{
|
||||
if (!headerOnly)
|
||||
{
|
||||
using (var eopl = new ExtendedOPL(opl))
|
||||
{
|
||||
InvokeOPLRequest(e, v, eopl);
|
||||
}
|
||||
}
|
||||
|
||||
opl.Terminate();
|
||||
opl.SetStatic();
|
||||
}
|
||||
|
||||
return opl;
|
||||
}
|
||||
|
||||
private static void OnEncode0xD6(NetState state, PacketReader reader, ref byte[] buffer, ref int length)
|
||||
{
|
||||
if (state?.Mobile?.Deleted != false || reader == null || buffer == null || length < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var pos = reader.Seek(0, SeekOrigin.Current);
|
||||
|
||||
reader.Seek(5, SeekOrigin.Begin);
|
||||
|
||||
#if ServUOX
|
||||
var serial = reader.ReadSerial();
|
||||
#else
|
||||
var serial = reader.ReadInt32();
|
||||
#endif
|
||||
|
||||
reader.Seek(pos, SeekOrigin.Begin);
|
||||
|
||||
var ent = World.FindEntity(serial);
|
||||
|
||||
if (ent == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ObjectPropertyList opl = null;
|
||||
|
||||
try
|
||||
{
|
||||
opl = ent.GetOPL(state.Mobile);
|
||||
|
||||
if (opl != null)
|
||||
{
|
||||
buffer = opl.Compile(state.CompressionEnabled, out length);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (opl != null)
|
||||
{
|
||||
opl.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnBatchQueryProperties(NetState state, PacketReader pvSrc)
|
||||
{
|
||||
if (state?.Mobile?.Deleted != false || pvSrc == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var length = pvSrc.Size - 3;
|
||||
|
||||
if (length < 0 || length % 4 != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var count = length / 4;
|
||||
|
||||
Serial s;
|
||||
|
||||
for (var i = 0; i < count; ++i)
|
||||
{
|
||||
#if ServUOX
|
||||
s = pvSrc.ReadSerial();
|
||||
#else
|
||||
s = pvSrc.ReadInt32();
|
||||
#endif
|
||||
|
||||
if (s.IsValid)
|
||||
{
|
||||
HandleQueryProperties(state.Mobile, World.FindEntity(s));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnQueryProperties(NetState state, PacketReader pvSrc)
|
||||
{
|
||||
if (state?.Mobile?.Deleted != false || pvSrc == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if ServUOX
|
||||
var serial = pvSrc.ReadSerial();
|
||||
#else
|
||||
var serial = (Serial)pvSrc.ReadInt32();
|
||||
#endif
|
||||
|
||||
if (serial.IsValid)
|
||||
{
|
||||
HandleQueryProperties(state.Mobile, World.FindEntity(serial));
|
||||
}
|
||||
}
|
||||
|
||||
private static void HandleQueryProperties(Mobile viewer, IEntity e)
|
||||
{
|
||||
if (viewer?.Deleted != false || e?.Deleted != false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!viewer.CanSee(e))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (OnValidateQuery != null)
|
||||
{
|
||||
var allow = true;
|
||||
|
||||
OnValidateQuery(viewer, e, ref allow);
|
||||
|
||||
if (!allow)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#if ServUOX
|
||||
if (viewer.InUpdateRange(e))
|
||||
{
|
||||
SendPropertiesTo(viewer, e);
|
||||
}
|
||||
#else
|
||||
if (e is Mobile m)
|
||||
{
|
||||
if (Utility.InUpdateRange(viewer, m))
|
||||
{
|
||||
SendPropertiesTo(viewer, m);
|
||||
}
|
||||
}
|
||||
else if (e is Item item)
|
||||
{
|
||||
if (Utility.InUpdateRange(viewer, item.GetWorldLocation()))
|
||||
{
|
||||
SendPropertiesTo(viewer, item);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Forces the compilation of a new Mobile or Item based ObjectPropertyList and sends it to the specified Mobile
|
||||
/// </summary>
|
||||
/// <param name="to">Mobile viewer, the Mobile viewing the OPL</param>
|
||||
/// <param name="e">Entity owner, the Entity which owns the OPL</param>
|
||||
public static void SendPropertiesTo(Mobile to, IEntity e)
|
||||
{
|
||||
if (e is Mobile m)
|
||||
{
|
||||
SendPropertiesTo(to, m);
|
||||
}
|
||||
else if (e is Item item)
|
||||
{
|
||||
SendPropertiesTo(to, item);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Forces the compilation of a new Mobile based ObjectPropertyList and sends it to the specified Mobile
|
||||
/// </summary>
|
||||
/// <param name="to">Mobile viewer, the Mobile viewing the OPL</param>
|
||||
/// <param name="m">Mobile owner, the Mobile which owns the OPL</param>
|
||||
public static void SendPropertiesTo(Mobile to, Mobile m)
|
||||
{
|
||||
if (to == null || m == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ObjectPropertyList opl = null;
|
||||
|
||||
try
|
||||
{
|
||||
opl = m.GetOPL(to);
|
||||
|
||||
if (opl != null)
|
||||
{
|
||||
to.Send(opl);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
opl?.Release();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Forces the compilation of a new Item based ObjectPropertyList and sends it to the specified Mobile
|
||||
/// </summary>
|
||||
/// <param name="to">Mobile viewer, the Mobile viewing the OPL</param>
|
||||
/// <param name="item"></param>
|
||||
public static void SendPropertiesTo(Mobile to, Item item)
|
||||
{
|
||||
if (to == null || item == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ObjectPropertyList opl = null;
|
||||
|
||||
try
|
||||
{
|
||||
opl = item.GetOPL(to);
|
||||
|
||||
if (opl != null)
|
||||
{
|
||||
to.Send(opl);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (opl != null)
|
||||
{
|
||||
opl.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void InvokeOPLRequest(IEntity entity, Mobile viewer, ExtendedOPL eopl)
|
||||
{
|
||||
if (entity?.Deleted != false || eopl?.IsDisposed != false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (entity is Mobile mob)
|
||||
{
|
||||
OnMobileOPLRequest?.Invoke(mob, viewer, eopl);
|
||||
}
|
||||
else if (entity is Item item)
|
||||
{
|
||||
OnItemOPLRequest?.Invoke(item, viewer, eopl);
|
||||
}
|
||||
|
||||
OnEntityOPLRequest?.Invoke(entity, viewer, eopl);
|
||||
}
|
||||
|
||||
public static void AddTo(ObjectPropertyList opl, params object[] args)
|
||||
{
|
||||
if (opl?.Entity?.Deleted != false || args.IsNullOrEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using (var o = new ExtendedOPL(opl))
|
||||
{
|
||||
foreach (var a in args)
|
||||
{
|
||||
if (a is IEntity e)
|
||||
{
|
||||
o.Add(e);
|
||||
}
|
||||
else if (a != null)
|
||||
{
|
||||
o.Add(a.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
o.Add(String.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddTo(ObjectPropertyList opl, IEnumerable<object> args)
|
||||
{
|
||||
if (opl?.Entity?.Deleted != false || args == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using (var o = new ExtendedOPL(opl))
|
||||
{
|
||||
foreach (var a in args)
|
||||
{
|
||||
if (a is IEntity e)
|
||||
{
|
||||
o.Add(e);
|
||||
}
|
||||
else if (a != null)
|
||||
{
|
||||
o.Add(a.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
o.Add(String.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddTo(ObjectPropertyList opl, string line, params object[] args)
|
||||
{
|
||||
if (opl?.Entity?.Deleted != false || line == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using (var o = new ExtendedOPL(opl))
|
||||
{
|
||||
if (!args.IsNullOrEmpty())
|
||||
{
|
||||
o.Add(line, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
o.Add(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddTo(ObjectPropertyList opl, string[] lines)
|
||||
{
|
||||
if (opl?.Entity?.Deleted != false || lines.IsNullOrEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using (var o = new ExtendedOPL(opl))
|
||||
{
|
||||
o.AddRange(lines.Where(s => s != null));
|
||||
}
|
||||
}
|
||||
|
||||
private List<string> _Buffer = ListPool<string>.AcquireObject();
|
||||
|
||||
bool ICollection<string>.IsReadOnly => _Buffer == null;
|
||||
|
||||
public int Count => _Buffer?.Count ?? 0;
|
||||
|
||||
public string this[int index]
|
||||
{
|
||||
get => _Buffer?[index];
|
||||
set
|
||||
{
|
||||
if (_Buffer != null)
|
||||
{
|
||||
_Buffer[index] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the underlying ObjectPropertyList
|
||||
/// </summary>
|
||||
public ObjectPropertyList Opl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the number of lines each cliloc can hold
|
||||
/// </summary>
|
||||
public int LineBreak { get; set; } = ClilocBreak;
|
||||
|
||||
public bool IsDisposed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Create with pre-defined OPL
|
||||
/// </summary>
|
||||
/// <param name="opl">ObjectPropertyList object to wrap and extend</param>
|
||||
public ExtendedOPL(ObjectPropertyList opl)
|
||||
{
|
||||
Opl = opl;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create with pre-defined OPL
|
||||
/// </summary>
|
||||
/// <param name="opl">ObjectPropertyList object to wrap and extend</param>
|
||||
/// <param name="capacity">Capacity of the extension</param>
|
||||
public ExtendedOPL(ObjectPropertyList opl, int capacity)
|
||||
: this(opl)
|
||||
{
|
||||
_Buffer.Capacity = capacity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create with pre-defined OPL
|
||||
/// </summary>
|
||||
/// <param name="opl">ObjectPropertyList object to wrap and extend</param>
|
||||
/// <param name="list">Pre-defined list to append to the specified OPL</param>
|
||||
public ExtendedOPL(ObjectPropertyList opl, IEnumerable<string> list)
|
||||
: this(opl)
|
||||
{
|
||||
AddRange(list);
|
||||
}
|
||||
|
||||
~ExtendedOPL()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
private void Dispose(bool gc)
|
||||
{
|
||||
if (IsDisposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (!gc)
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
|
||||
try
|
||||
{
|
||||
if (Opl != null)
|
||||
{
|
||||
Flush();
|
||||
|
||||
Opl = null;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
|
||||
ObjectPool.Free(ref _Buffer);
|
||||
|
||||
IsDisposed = true;
|
||||
}
|
||||
|
||||
public bool NextEmpty(out ClilocInfo info)
|
||||
{
|
||||
info = null;
|
||||
|
||||
if (IsDisposed || Opl == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0, index; i < EmptyClilocs.Length; i++)
|
||||
{
|
||||
index = EmptyClilocs[i];
|
||||
|
||||
if (!Opl.Contains(index))
|
||||
{
|
||||
info = ClilocLNG.NULL.Lookup(index);
|
||||
|
||||
if (info != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Flush()
|
||||
{
|
||||
if (IsDisposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Apply();
|
||||
|
||||
_Buffer?.Free(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies all changes to the underlying ObjectPropertyList
|
||||
/// </summary>
|
||||
public void Apply()
|
||||
{
|
||||
if (IsDisposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_Buffer.IsNullOrEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var opl = Opl;
|
||||
|
||||
if (opl?.Entity?.Deleted != false)
|
||||
{
|
||||
Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
ObjectPool.Acquire(out StringBuilder final);
|
||||
|
||||
int take, limit = LineBreak, threshold = ClilocThreshold;
|
||||
|
||||
while (_Buffer.Count > 0)
|
||||
{
|
||||
if (!NextEmpty(out var info))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (!info.HasArgs || opl.Contains(info.Index))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
take = 0;
|
||||
|
||||
while (take < _Buffer.Count)
|
||||
{
|
||||
if (take > 0)
|
||||
{
|
||||
final.Append('\n');
|
||||
}
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(_Buffer[take]))
|
||||
{
|
||||
final.Append(_Buffer[take]);
|
||||
}
|
||||
else
|
||||
{
|
||||
final.Append(' ');
|
||||
}
|
||||
|
||||
if (++take >= limit || final.Length >= threshold)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (take == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
_Buffer.RemoveRange(0, take);
|
||||
|
||||
if (final.Length > 0)
|
||||
{
|
||||
opl.Add(info.Index, info.ToString(final));
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
final.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
ObjectPool.Free(ref final);
|
||||
|
||||
Clear();
|
||||
}
|
||||
|
||||
public void Add(string format, params object[] args)
|
||||
{
|
||||
if (_Buffer != null)
|
||||
{
|
||||
_Buffer.Add(String.Format(format ?? String.Empty, args));
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(int number, params object[] args)
|
||||
{
|
||||
if (_Buffer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var info = ClilocLNG.NULL.Lookup(number);
|
||||
|
||||
if (info != null)
|
||||
{
|
||||
_Buffer.Add(info.ToString(args));
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(IEntity o)
|
||||
{
|
||||
if (o != null && Opl != null && o != Opl.Entity)
|
||||
{
|
||||
AddRange(o.GetOPLStrings());
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(IEntity o, Mobile viewer)
|
||||
{
|
||||
if (o != null && Opl != null && o != Opl.Entity)
|
||||
{
|
||||
AddRange(o.GetOPLStrings(viewer));
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(IEntity o, ClilocLNG lng)
|
||||
{
|
||||
if (o != null && Opl != null && o != Opl.Entity)
|
||||
{
|
||||
AddRange(o.GetOPLStrings(lng));
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(ObjectPropertyList opl)
|
||||
{
|
||||
if (opl != null && opl != Opl && opl.Entity != Opl.Entity)
|
||||
{
|
||||
AddRange(opl.DecodePropertyList());
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(ObjectPropertyList opl, Mobile viewer)
|
||||
{
|
||||
if (opl != null && opl != Opl && opl.Entity != Opl.Entity)
|
||||
{
|
||||
AddRange(opl.DecodePropertyList(viewer));
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(ObjectPropertyList opl, ClilocLNG lng)
|
||||
{
|
||||
if (opl != null && opl != Opl && opl.Entity != Opl.Entity)
|
||||
{
|
||||
AddRange(opl.DecodePropertyList(lng));
|
||||
}
|
||||
}
|
||||
|
||||
public void AddRange(IEnumerable<string> lines)
|
||||
{
|
||||
_Buffer?.AddRange(lines.Select(line => line ?? String.Empty));
|
||||
}
|
||||
|
||||
public void Add(string line)
|
||||
{
|
||||
_Buffer?.Add(line ?? String.Empty);
|
||||
}
|
||||
|
||||
public bool Remove(string line)
|
||||
{
|
||||
return _Buffer?.Remove(line ?? String.Empty) == true;
|
||||
}
|
||||
|
||||
public int RemoveAll(Predicate<string> match)
|
||||
{
|
||||
return _Buffer?.RemoveAll(match) ?? 0;
|
||||
}
|
||||
|
||||
public void RemoveRange(int index, int count)
|
||||
{
|
||||
_Buffer?.RemoveRange(index, count);
|
||||
}
|
||||
|
||||
public void RemoveAt(int index)
|
||||
{
|
||||
_Buffer?.RemoveAt(index);
|
||||
}
|
||||
|
||||
public void Insert(int index, string line)
|
||||
{
|
||||
_Buffer?.Insert(index, line ?? String.Empty);
|
||||
}
|
||||
|
||||
public void Insert(int index, string format, params object[] args)
|
||||
{
|
||||
_Buffer?.Insert(index, String.Format(format ?? String.Empty, args));
|
||||
}
|
||||
|
||||
public void Insert(int index, int number, params object[] args)
|
||||
{
|
||||
_Buffer?.Insert(index, Clilocs.GetString(ClilocLNG.NULL, number, args));
|
||||
}
|
||||
|
||||
public int IndexOf(string line)
|
||||
{
|
||||
return _Buffer?.IndexOf(line ?? String.Empty) ?? -1;
|
||||
}
|
||||
|
||||
public bool Contains(string line)
|
||||
{
|
||||
return _Buffer?.Contains(line ?? String.Empty) == true;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_Buffer?.Clear();
|
||||
}
|
||||
|
||||
public void CopyTo(string[] array, int arrayIndex)
|
||||
{
|
||||
_Buffer?.CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
public IEnumerator<string> GetEnumerator()
|
||||
{
|
||||
if (_Buffer != null)
|
||||
{
|
||||
return _Buffer.GetEnumerator();
|
||||
}
|
||||
|
||||
return _EmptyBuffer.GetEnumerator<string>();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
||||
65
Scripts/SubSystem/VitaNex/Core/Network/NetworkBuffers.cs
Normal file
65
Scripts/SubSystem/VitaNex/Core/Network/NetworkBuffers.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
#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.Reflection;
|
||||
|
||||
using Server;
|
||||
using Server.Network;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Network
|
||||
{
|
||||
public static class NetworkBuffers
|
||||
{
|
||||
private static void Resize(Type owner, string field, int resize)
|
||||
{
|
||||
var f = owner.GetField(field, BindingFlags.Static | BindingFlags.NonPublic);
|
||||
|
||||
if (f != null)
|
||||
{
|
||||
var b = f.GetValue(null) as BufferPool;
|
||||
|
||||
if (b != null)
|
||||
{
|
||||
b.GetInfo(out var name, out var freeCount, out var initialCapacity, out var currentCapacity, out var bufferSize, out var misses);
|
||||
|
||||
if (bufferSize < resize && b.SetFieldValue("m_BufferSize", resize))
|
||||
{
|
||||
if (b.GetFieldValue("m_FreeBuffers", out Queue<byte[]> buffers))
|
||||
{
|
||||
buffers.Clear();
|
||||
|
||||
for (var i = 0; i < initialCapacity; i++)
|
||||
{
|
||||
buffers.Enqueue(new byte[resize]);
|
||||
}
|
||||
}
|
||||
|
||||
VitaNexCore.ToConsole(owner.Name + "." + field + " Buffers: {0:#,0} -> {1:#,0}", bufferSize, resize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[CallPriority(Int32.MaxValue)]
|
||||
public static void Configure()
|
||||
{
|
||||
VitaNexCore.OnInitialized += () =>
|
||||
{
|
||||
Resize(typeof(Packet), "m_CompressorBuffers", 0x100000);
|
||||
Resize(typeof(DisplayGumpPacked), "m_PackBuffers", 0x100000);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
#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 Server;
|
||||
using Server.Network;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Network
|
||||
{
|
||||
public delegate void OutgoingPacketOverrideHandler(
|
||||
NetState to,
|
||||
PacketReader reader,
|
||||
ref byte[] packetBuffer,
|
||||
ref int packetLength);
|
||||
|
||||
public static class OutgoingPacketOverrides
|
||||
{
|
||||
private static readonly OutgoingPacketOverrideHandler[] _Handlers;
|
||||
private static readonly OutgoingPacketOverrideHandler[] _ExtendedHandlersLow;
|
||||
private static readonly Dictionary<int, OutgoingPacketOverrideHandler> _ExtendedHandlersHigh;
|
||||
|
||||
public static bool Initialized { get; private set; }
|
||||
|
||||
static OutgoingPacketOverrides()
|
||||
{
|
||||
_Handlers = new OutgoingPacketOverrideHandler[0x100];
|
||||
_ExtendedHandlersLow = new OutgoingPacketOverrideHandler[0x100];
|
||||
_ExtendedHandlersHigh = new Dictionary<int, OutgoingPacketOverrideHandler>();
|
||||
}
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
if (Initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NetState.CreatedCallback += OnNetStateCreated;
|
||||
|
||||
Initialized = true;
|
||||
}
|
||||
|
||||
private static void OnNetStateCreated(NetState n)
|
||||
{
|
||||
n.PacketEncoder = new PacketOverrideRegistryEncoder(n.PacketEncoder);
|
||||
}
|
||||
|
||||
public static void Register(int packetID, OutgoingPacketOverrideHandler handler)
|
||||
{
|
||||
_Handlers[packetID] = handler;
|
||||
}
|
||||
|
||||
public static OutgoingPacketOverrideHandler GetHandler(int packetID)
|
||||
{
|
||||
return _Handlers[packetID];
|
||||
}
|
||||
|
||||
public static void RegisterExtended(int packetID, OutgoingPacketOverrideHandler handler)
|
||||
{
|
||||
if (packetID >= 0 && packetID < 0x100)
|
||||
{
|
||||
_ExtendedHandlersLow[packetID] = handler;
|
||||
}
|
||||
else
|
||||
{
|
||||
_ExtendedHandlersHigh[packetID] = handler;
|
||||
}
|
||||
}
|
||||
|
||||
public static OutgoingPacketOverrideHandler GetExtendedHandler(int packetID)
|
||||
{
|
||||
if (packetID >= 0 && packetID < 0x100)
|
||||
{
|
||||
return _ExtendedHandlersLow[packetID];
|
||||
}
|
||||
|
||||
_ExtendedHandlersHigh.TryGetValue(packetID, out var handler);
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
||||
private class PacketOverrideRegistryEncoder : IPacketEncoder
|
||||
{
|
||||
private static readonly byte[] _UnpackBuffer = new byte[0x10000];
|
||||
private readonly IPacketEncoder _Successor;
|
||||
|
||||
public PacketOverrideRegistryEncoder(IPacketEncoder successor)
|
||||
{
|
||||
_Successor = successor;
|
||||
}
|
||||
|
||||
public void EncodeOutgoingPacket(NetState to, ref byte[] packetBuffer, ref int packetLength)
|
||||
{
|
||||
byte[] buffer;
|
||||
byte packetId;
|
||||
|
||||
if (to.CompressionEnabled)
|
||||
{
|
||||
var firstByte = Decompressor.DecompressFirstByte(packetBuffer, packetLength);
|
||||
|
||||
if (!firstByte.HasValue)
|
||||
{
|
||||
Utility.PushColor(ConsoleColor.Yellow);
|
||||
Console.WriteLine("Outgoing Packet Override: Unable to decompress packet!");
|
||||
Utility.PopColor();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
packetId = firstByte.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
packetId = packetBuffer[0];
|
||||
}
|
||||
|
||||
var oHandler = GetHandler(packetId) ?? GetExtendedHandler(packetId);
|
||||
|
||||
if (oHandler != null)
|
||||
{
|
||||
if (to.CompressionEnabled)
|
||||
{
|
||||
Decompressor.DecompressAll(packetBuffer, packetLength, _UnpackBuffer, out var bufferLength);
|
||||
|
||||
buffer = new byte[bufferLength];
|
||||
Buffer.BlockCopy(_UnpackBuffer, 0, buffer, 0, bufferLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer = packetBuffer;
|
||||
}
|
||||
|
||||
var reader = new PacketReader(buffer, packetLength, false);
|
||||
reader.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
oHandler(to, reader, ref packetBuffer, ref packetLength);
|
||||
}
|
||||
|
||||
if (_Successor != null)
|
||||
{
|
||||
_Successor.EncodeOutgoingPacket(to, ref packetBuffer, ref packetLength);
|
||||
}
|
||||
}
|
||||
|
||||
public void DecodeIncomingPacket(NetState from, ref byte[] buffer, ref int length)
|
||||
{
|
||||
if (_Successor != null)
|
||||
{
|
||||
_Successor.DecodeIncomingPacket(from, ref buffer, ref length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Network
|
||||
{
|
||||
public enum EffectRender
|
||||
{
|
||||
Normal = 0x00,
|
||||
Multiply = 0x01,
|
||||
Lighten = 0x02,
|
||||
LightenMore = 0x03,
|
||||
Darken = 0x04,
|
||||
SemiTransparent = 0x05,
|
||||
ShadowOutline = 0x06,
|
||||
Transparent = 0x07
|
||||
}
|
||||
}
|
||||
114
Scripts/SubSystem/VitaNex/Core/Network/Packets/ScreenEffect.cs
Normal file
114
Scripts/SubSystem/VitaNex/Core/Network/Packets/ScreenEffect.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
using Server.Network;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Network
|
||||
{
|
||||
public enum ScreenFX
|
||||
{
|
||||
FadeOut = 0x00,
|
||||
FadeIn = 0x01,
|
||||
LightFlash = 0x02,
|
||||
FadeInOut = 0x03,
|
||||
DarkFlash = 0x04
|
||||
}
|
||||
|
||||
public static class ScreenEffects
|
||||
{
|
||||
public static void Send(this ScreenFX effect, Mobile to)
|
||||
{
|
||||
if (to == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (effect)
|
||||
{
|
||||
case ScreenFX.FadeOut:
|
||||
to.Send(VNScreenFadeOut.Instance);
|
||||
break;
|
||||
case ScreenFX.FadeIn:
|
||||
to.Send(VNScreenFadeIn.Instance);
|
||||
break;
|
||||
case ScreenFX.LightFlash:
|
||||
to.Send(VNScreenLightFlash.Instance);
|
||||
break;
|
||||
case ScreenFX.FadeInOut:
|
||||
to.Send(VNScreenFadeInOut.Instance);
|
||||
break;
|
||||
case ScreenFX.DarkFlash:
|
||||
to.Send(VNScreenDarkFlash.Instance);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class VNScreenEffect : Packet
|
||||
{
|
||||
public VNScreenEffect(ScreenEffectType type)
|
||||
: base(0x70, 28)
|
||||
{
|
||||
m_Stream.Write((byte)0x04);
|
||||
m_Stream.Fill(8);
|
||||
m_Stream.Write((short)type);
|
||||
m_Stream.Fill(16);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class VNScreenFadeOut : VNScreenEffect
|
||||
{
|
||||
public static readonly Packet Instance = SetStatic(new VNScreenFadeOut());
|
||||
|
||||
public VNScreenFadeOut()
|
||||
: base(ScreenEffectType.FadeOut)
|
||||
{ }
|
||||
}
|
||||
|
||||
public sealed class VNScreenFadeIn : VNScreenEffect
|
||||
{
|
||||
public static readonly Packet Instance = SetStatic(new VNScreenFadeIn());
|
||||
|
||||
public VNScreenFadeIn()
|
||||
: base(ScreenEffectType.FadeIn)
|
||||
{ }
|
||||
}
|
||||
|
||||
public sealed class VNScreenFadeInOut : VNScreenEffect
|
||||
{
|
||||
public static readonly Packet Instance = SetStatic(new VNScreenFadeInOut());
|
||||
|
||||
public VNScreenFadeInOut()
|
||||
: base(ScreenEffectType.FadeInOut)
|
||||
{ }
|
||||
}
|
||||
|
||||
public sealed class VNScreenLightFlash : VNScreenEffect
|
||||
{
|
||||
public static readonly Packet Instance = SetStatic(new VNScreenLightFlash());
|
||||
|
||||
public VNScreenLightFlash()
|
||||
: base(ScreenEffectType.LightFlash)
|
||||
{ }
|
||||
}
|
||||
|
||||
public sealed class VNScreenDarkFlash : VNScreenEffect
|
||||
{
|
||||
public static readonly Packet Instance = SetStatic(new VNScreenDarkFlash());
|
||||
|
||||
public VNScreenDarkFlash()
|
||||
: base(ScreenEffectType.DarkFlash)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
59
Scripts/SubSystem/VitaNex/Core/Network/Packets/SeasonEnum.cs
Normal file
59
Scripts/SubSystem/VitaNex/Core/Network/Packets/SeasonEnum.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Network
|
||||
{
|
||||
public enum Season
|
||||
{
|
||||
/// <summary>
|
||||
/// Spring: 0
|
||||
/// </summary>
|
||||
Spring = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Summer: 1
|
||||
/// </summary>
|
||||
Summer = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Autumn: 2
|
||||
/// </summary>
|
||||
Autumn = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Winter: 3
|
||||
/// </summary>
|
||||
Winter = 3,
|
||||
|
||||
/// <summary>
|
||||
/// Desolation: 4
|
||||
/// </summary>
|
||||
Desolation = 4,
|
||||
|
||||
/// <summary>
|
||||
/// Fall: 2
|
||||
/// </summary>
|
||||
Fall = Autumn
|
||||
}
|
||||
|
||||
public static class SeasonEnumExt
|
||||
{
|
||||
public static int GetID(this Season season)
|
||||
{
|
||||
return (int)season;
|
||||
}
|
||||
|
||||
public static string GetName(this Season season)
|
||||
{
|
||||
return season.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user