mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-18 15:31:33 +00:00
296 lines
10 KiB
C#
296 lines
10 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Collections.Generic;
|
|
using EQExtractor2.InternalTypes;
|
|
using EQExtractor2.OpCodes;
|
|
using EQPacket;
|
|
using MyUtils;
|
|
|
|
namespace EQExtractor2.Patches
|
|
{
|
|
class PatchMay122011Decoder : PatchMarch152011Decoder
|
|
{
|
|
public PatchMay122011Decoder()
|
|
{
|
|
Version = "EQ Client Build Date May 12 2011.";
|
|
|
|
PatchConfFileName = "patch_May12-2011.conf";
|
|
|
|
ExpectedPPLength = 28536;
|
|
|
|
PPZoneIDOffset = 21204;
|
|
}
|
|
|
|
override public PositionUpdate Decode_OP_NPCMoveUpdate(byte[] UpdatePacket)
|
|
{
|
|
PositionUpdate PosUpdate = new PositionUpdate();
|
|
|
|
BitStream bs = new BitStream(UpdatePacket, (uint)UpdatePacket.Length);
|
|
|
|
PosUpdate.SpawnID = bs.readUInt(16);
|
|
|
|
UInt32 Unknown = bs.readUInt(16);
|
|
|
|
UInt32 VFlags = bs.readUInt(6);
|
|
|
|
PosUpdate.p.y = (float)bs.readInt(19) / (float)(1 << 3);
|
|
|
|
PosUpdate.p.x = (float)bs.readInt(19) / (float)(1 << 3);
|
|
|
|
PosUpdate.p.z = (float)bs.readInt(19) / (float)(1 << 3);
|
|
|
|
PosUpdate.p.heading = (float)bs.readInt(12) / (float)(1 << 3);
|
|
|
|
PosUpdate.HighRes = true;
|
|
|
|
return PosUpdate;
|
|
}
|
|
|
|
override public PositionUpdate Decode_OP_MobUpdate(byte[] MobUpdatePacket)
|
|
{
|
|
PositionUpdate PosUpdate = new PositionUpdate();
|
|
|
|
ByteStream Buffer = new ByteStream(MobUpdatePacket);
|
|
|
|
PosUpdate.SpawnID = Buffer.ReadUInt16();
|
|
|
|
Buffer.SkipBytes(2);
|
|
|
|
UInt32 Word1 = Buffer.ReadUInt32();
|
|
|
|
UInt32 Word2 = Buffer.ReadUInt32();
|
|
|
|
UInt16 Word3 = Buffer.ReadUInt16();
|
|
|
|
PosUpdate.p.y = Utils.EQ19ToFloat((Int32)(Word1 & 0x7FFFF));
|
|
|
|
// Z is in the top 13 bits of Word1 and the bottom 6 of Word2
|
|
|
|
UInt32 ZPart1 = Word1 >> 19; // ZPart1 now has low order bits of Z in bottom 13 bits
|
|
UInt32 ZPart2 = Word2 & 0x3F; // ZPart2 now has high order bits of Z in bottom 6 bits
|
|
|
|
ZPart2 = ZPart2 << 13;
|
|
|
|
PosUpdate.p.z = Utils.EQ19ToFloat((Int32)(ZPart1 | ZPart2));
|
|
|
|
PosUpdate.p.x = Utils.EQ19ToFloat((Int32)(Word2 >> 6) & 0x7FFFF);
|
|
|
|
PosUpdate.p.heading = Utils.EQ19ToFloat((Int32)(Word3 & 0xFFF));
|
|
|
|
PosUpdate.HighRes = false;
|
|
|
|
return PosUpdate;
|
|
}
|
|
|
|
override public List<ZonePoint> GetZonePointList()
|
|
{
|
|
List<ZonePoint> ZonePointList = new List<ZonePoint>();
|
|
|
|
List<byte[]> ZonePointPackets = GetPacketsOfType("OP_SendZonepoints", PacketDirection.ServerToClient);
|
|
|
|
if (ZonePointPackets.Count < 1)
|
|
{
|
|
return ZonePointList;
|
|
}
|
|
|
|
// Assume there is only 1 packet and process the first one.
|
|
|
|
ByteStream Buffer = new ByteStream(ZonePointPackets[0]);
|
|
|
|
UInt32 Entries = Buffer.ReadUInt32();
|
|
|
|
if (Entries == 0)
|
|
return ZonePointList;
|
|
|
|
float x, y, z, Heading;
|
|
|
|
UInt32 Number;
|
|
|
|
UInt16 ZoneID, Instance;
|
|
|
|
ZonePointList = new List<ZonePoint>();
|
|
|
|
for (int i = 0; i < Entries; ++i)
|
|
{
|
|
Number = Buffer.ReadUInt32();
|
|
|
|
y = Buffer.ReadSingle();
|
|
|
|
x = Buffer.ReadSingle();
|
|
|
|
z = Buffer.ReadSingle();
|
|
|
|
Heading = Buffer.ReadSingle();
|
|
|
|
if (Heading != 999)
|
|
Heading = Heading / 2;
|
|
|
|
ZoneID = Buffer.ReadUInt16();
|
|
|
|
Instance = Buffer.ReadUInt16();
|
|
|
|
Buffer.SkipBytes(8); // Skip the last UInt32
|
|
|
|
ZonePoint NewZonePoint = new ZonePoint(Number, ZoneID, Instance, x, y, z, x, y, z, Heading, ZoneID);
|
|
|
|
ZonePointList.Add(NewZonePoint);
|
|
}
|
|
|
|
return ZonePointList;
|
|
}
|
|
override public bool DumpAAs(string FileName)
|
|
{
|
|
List<byte[]> AAPackets = GetPacketsOfType("OP_SendAATable", PacketDirection.ServerToClient);
|
|
|
|
|
|
if (AAPackets.Count < 1)
|
|
return false;
|
|
|
|
StreamWriter OutputFile;
|
|
|
|
try
|
|
{
|
|
OutputFile = new StreamWriter(FileName);
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
|
|
}
|
|
|
|
OutputFile.WriteLine("-- There are " + AAPackets.Count + " OP_SendAATable packets.");
|
|
OutputFile.WriteLine("");
|
|
|
|
foreach (byte[] Packet in AAPackets)
|
|
{
|
|
UInt32 AAID = BitConverter.ToUInt32(Packet, 0);
|
|
UInt32 Unknown004 = BitConverter.ToUInt32(Packet, 4);
|
|
UInt32 HotKeySID = BitConverter.ToUInt32(Packet, 5);
|
|
UInt32 HotKeySID2 = BitConverter.ToUInt32(Packet, 9);
|
|
UInt32 TitleSID = BitConverter.ToUInt32(Packet, 13);
|
|
UInt32 DescSID = BitConverter.ToUInt32(Packet, 17);
|
|
UInt32 ClassType = BitConverter.ToUInt32(Packet, 21);
|
|
UInt32 Cost = BitConverter.ToUInt32(Packet, 25);
|
|
UInt32 Seq = BitConverter.ToUInt32(Packet, 29);
|
|
UInt32 CurrentLevel = BitConverter.ToUInt32(Packet, 33);
|
|
UInt32 Unknown037 = BitConverter.ToUInt32(Packet, 37);
|
|
UInt32 PrereqSkill = BitConverter.ToUInt32(Packet, 41);
|
|
UInt32 PrereqMinpoints = BitConverter.ToUInt32(Packet, 45);
|
|
UInt32 Type = BitConverter.ToUInt32(Packet, 49);
|
|
UInt32 SpellID = BitConverter.ToUInt32(Packet, 53);
|
|
UInt32 Unknown057 = BitConverter.ToUInt32(Packet, 57);
|
|
UInt32 SpellType = BitConverter.ToUInt32(Packet, 61);
|
|
UInt32 SpellRefresh = BitConverter.ToUInt32(Packet, 65);
|
|
UInt16 Classes = BitConverter.ToUInt16(Packet, 69);
|
|
UInt16 Berserker = BitConverter.ToUInt16(Packet, 71);
|
|
UInt32 MaxLevel = BitConverter.ToUInt32(Packet, 73);
|
|
UInt32 LastID = BitConverter.ToUInt32(Packet, 77);
|
|
UInt32 NextID = BitConverter.ToUInt32(Packet, 81);
|
|
UInt32 Cost2 = BitConverter.ToUInt32(Packet, 85);
|
|
UInt32 AAExpansion = BitConverter.ToUInt32(Packet, 96);
|
|
UInt32 SpecialCategory = BitConverter.ToUInt32(Packet, 100);
|
|
UInt32 TotalAbilities = BitConverter.ToUInt32(Packet, 108);
|
|
|
|
OutputFile.WriteLine(String.Format("AAID: {0}", AAID));
|
|
OutputFile.WriteLine(" Unknown004:\t" + Unknown004);
|
|
OutputFile.WriteLine(" HotkeySID:\t" + HotKeySID);
|
|
OutputFile.WriteLine(" HotkeySID2:\t" + HotKeySID2);
|
|
OutputFile.WriteLine(" TitleSID:\t" + TitleSID);
|
|
OutputFile.WriteLine(" DescSID:\t" + DescSID);
|
|
OutputFile.WriteLine(" ClassType:\t" + ClassType);
|
|
OutputFile.WriteLine(" Cost:\t\t" + Cost);
|
|
OutputFile.WriteLine(" Seq:\t\t" + Seq);
|
|
OutputFile.WriteLine(" CurrentLevel:\t" + CurrentLevel);
|
|
OutputFile.WriteLine(" Unknown037:\t" + Unknown037);
|
|
OutputFile.WriteLine(" PrereqSkill:\t" + PrereqSkill);
|
|
OutputFile.WriteLine(" PrereqMinPt:\t" + PrereqMinpoints);
|
|
OutputFile.WriteLine(" Type:\t\t" + Type);
|
|
OutputFile.WriteLine(" SpellID:\t" + SpellID);
|
|
OutputFile.WriteLine(" Unknown057:\t" + Unknown057);
|
|
OutputFile.WriteLine(" SpellType:\t" + SpellType);
|
|
OutputFile.WriteLine(" SpellRefresh:\t" + SpellRefresh);
|
|
OutputFile.WriteLine(" Classes:\t" + Classes);
|
|
OutputFile.WriteLine(" Berserker:\t" + Berserker);
|
|
OutputFile.WriteLine(" MaxLevel:\t" + MaxLevel);
|
|
OutputFile.WriteLine(" LastID:\t" + LastID);
|
|
OutputFile.WriteLine(" NextID:\t" + NextID);
|
|
OutputFile.WriteLine(" Cost2:\t\t" + Cost2);
|
|
OutputFile.WriteLine(" AAExpansion:\t" + AAExpansion);
|
|
OutputFile.WriteLine(" SpecialCat:\t" + SpecialCategory);
|
|
OutputFile.WriteLine("");
|
|
OutputFile.WriteLine(" TotalAbilities:\t" + TotalAbilities);
|
|
OutputFile.WriteLine("");
|
|
|
|
for (int i = 0; i < TotalAbilities; ++i)
|
|
{
|
|
UInt32 Ability = BitConverter.ToUInt32(Packet, 112 + (i * 16));
|
|
Int32 Base1 = BitConverter.ToInt32(Packet, 116 + (i * 16));
|
|
Int32 Base2 = BitConverter.ToInt32(Packet, 120 + (i * 16));
|
|
UInt32 Slot = BitConverter.ToUInt32(Packet, 124 + (i * 16));
|
|
|
|
OutputFile.WriteLine(String.Format(" Ability:\t{0}\tBase1:\t{1}\tBase2:\t{2}\tSlot:\t{3}", Ability, Base1, Base2, Slot));
|
|
|
|
}
|
|
OutputFile.WriteLine("");
|
|
|
|
}
|
|
|
|
OutputFile.Close();
|
|
|
|
return true;
|
|
}
|
|
|
|
public override void RegisterExplorers()
|
|
{
|
|
//base.RegisterExplorers();
|
|
|
|
//OpManager.RegisterExplorer("OP_SpawnDoor", ExploreSpawnDoor);
|
|
|
|
}
|
|
|
|
public void ExploreSpawnDoor(StreamWriter OutputStream, ByteStream Buffer, PacketDirection Direction)
|
|
{
|
|
uint DoorCount = Buffer.Length() / 96;
|
|
|
|
OutputStream.WriteLine("Door Count: {0}", DoorCount);
|
|
|
|
for (int d = 0; d < DoorCount; ++d)
|
|
{
|
|
string DoorName = Buffer.ReadFixedLengthString(32, false);
|
|
|
|
|
|
float YPos = Buffer.ReadSingle();
|
|
|
|
float XPos = Buffer.ReadSingle();
|
|
|
|
float ZPos = Buffer.ReadSingle();
|
|
|
|
float Heading = Buffer.ReadSingle();
|
|
|
|
UInt32 Incline = Buffer.ReadUInt32();
|
|
|
|
Int32 Size = Buffer.ReadInt32();
|
|
|
|
Buffer.SkipBytes(4); // Skip Unknown
|
|
|
|
Byte DoorID = Buffer.ReadByte();
|
|
|
|
Byte OpenType = Buffer.ReadByte();
|
|
|
|
Byte StateAtSpawn = Buffer.ReadByte();
|
|
|
|
Byte InvertState = Buffer.ReadByte();
|
|
|
|
Int32 DoorParam = Buffer.ReadInt32();
|
|
|
|
OutputStream.WriteLine(" Name: {0} ID: {1} OT: {2} SAS: {3} IS: {4} DP: {5}",
|
|
DoorName, DoorID, OpenType, StateAtSpawn, InvertState, DoorParam);
|
|
|
|
// Skip past the trailing unknowns in the door struct, moving to the next door in the packet.
|
|
|
|
Buffer.SkipBytes(28);
|
|
}
|
|
|
|
}
|
|
}
|
|
} |