mirror of
https://github.com/ACEmulator/ACE
synced 2026-08-17 12:26:06 -04:00
* .net10 build * update appveyor version * update appveyor vs version * Update appveyor.yml * Update ACE.Server.csproj * Update PacketHeaderOptional.cs * Update .vsconfig * Update ACE.Adapter.csproj * Update ACE.Common.csproj * Update ACE.Database.Tests.csproj * Update ACE.Database.csproj * Update ACE.DatLoader.Tests.csproj * Update ACE.DatLoader.csproj * Update ACE.Entity.csproj * Update ACE.Server.Tests.csproj * Update ACE.Server.csproj * Update ACE.Database.csproj * Update Dockerfile * Update ACE.Common.csproj * Update ACE.Database.Tests.csproj * Update ACE.Database.csproj * Update ACE.DatLoader.Tests.csproj * Update ACE.DatLoader.csproj * Update ACE.Server.Tests.csproj * Update SphereTests.cs * Update AppVeyor config Suppress NETSDK1233 warnings for now * Update AppVeyorBuild.bat * Update ACE.sln * Update appveyor.yml * Update appveyor.yml * Update appveyor.yml * Update README.md --------- Co-authored-by: Ty Conner <tyconner@itcproductions.com>
159 lines
6.2 KiB
C#
159 lines
6.2 KiB
C#
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
|
|
using ACE.Common.Cryptography;
|
|
|
|
namespace ACE.Server.Network
|
|
{
|
|
public class PacketHeaderOptional
|
|
{
|
|
public uint Size { get; private set; }
|
|
|
|
public uint AckSequence { get; private set; }
|
|
public double TimeSynch { get; private set; }
|
|
public float EchoRequestClientTime { get; private set; }
|
|
public List<uint> RetransmitData { get; private set; }
|
|
public bool IsValid { get; private set; } = true;
|
|
public uint FlowBytes { get; private set; }
|
|
public ushort FlowInterval { get; private set; }
|
|
|
|
private PacketHeader Header { get; set; }
|
|
private MemoryStream headerBytes = new MemoryStream();
|
|
|
|
public void Unpack(BinaryReader reader, PacketHeader header)
|
|
{
|
|
Header = header;
|
|
Size = (uint)reader.BaseStream.Position;
|
|
BinaryWriter writer = new BinaryWriter(headerBytes);
|
|
|
|
if (header.HasFlag(PacketHeaderFlags.ServerSwitch)) // 0x100
|
|
{
|
|
writer.Write(reader.ReadBytes(8));
|
|
}
|
|
|
|
if (header.HasFlag(PacketHeaderFlags.RequestRetransmit)) // 0x1000
|
|
{
|
|
if (reader.BaseStream.Length < reader.BaseStream.Position + 4) { IsValid = false; return; }
|
|
uint retransmitCount = reader.ReadUInt32();
|
|
writer.Write(retransmitCount);
|
|
RetransmitData = new List<uint>();
|
|
for (uint i = 0u; i < retransmitCount; i++)
|
|
{
|
|
if (reader.BaseStream.Length < reader.BaseStream.Position + 4) { IsValid = false; return; }
|
|
uint sequence = reader.ReadUInt32();
|
|
writer.Write(sequence);
|
|
RetransmitData.Add(sequence);
|
|
}
|
|
}
|
|
|
|
if (header.HasFlag(PacketHeaderFlags.RejectRetransmit)) // 0x2000
|
|
{
|
|
if (reader.BaseStream.Length < reader.BaseStream.Position + 4) { IsValid = false; return; }
|
|
uint count = reader.ReadUInt32();
|
|
writer.Write(count);
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
if (reader.BaseStream.Length < reader.BaseStream.Position + 4) { IsValid = false; return; }
|
|
writer.Write(reader.ReadBytes(4));
|
|
}
|
|
}
|
|
|
|
if (header.HasFlag(PacketHeaderFlags.AckSequence)) // 0x4000
|
|
{
|
|
if (reader.BaseStream.Length < reader.BaseStream.Position + 4) { IsValid = false; return; }
|
|
AckSequence = reader.ReadUInt32();
|
|
writer.Write(AckSequence);
|
|
}
|
|
|
|
if (header.HasFlag(PacketHeaderFlags.LoginRequest)) // 0x10000
|
|
{
|
|
long position = reader.BaseStream.Position;
|
|
long length = reader.BaseStream.Length - position;
|
|
if (length < 1) { IsValid = false; return; }
|
|
byte[] loginBytes = new byte[length];
|
|
var i = reader.BaseStream.Read(loginBytes, (int)position, (int)length);
|
|
if (i != length) { IsValid = false; return; }
|
|
writer.Write(loginBytes);
|
|
reader.BaseStream.Position = position;
|
|
}
|
|
|
|
if (header.HasFlag(PacketHeaderFlags.WorldLoginRequest)) // 0x20000
|
|
{
|
|
if (reader.BaseStream.Length < reader.BaseStream.Position + 8) { IsValid = false; return; }
|
|
long position = reader.BaseStream.Position;
|
|
writer.Write(reader.ReadBytes(8));
|
|
reader.BaseStream.Position = position;
|
|
}
|
|
|
|
if (header.HasFlag(PacketHeaderFlags.ConnectResponse)) // 0x80000
|
|
{
|
|
long position = reader.BaseStream.Position;
|
|
if (reader.BaseStream.Length < reader.BaseStream.Position + 8) { IsValid = false; return; }
|
|
writer.Write(reader.ReadBytes(8));
|
|
reader.BaseStream.Position = position;
|
|
}
|
|
|
|
if (header.HasFlag(PacketHeaderFlags.CICMDCommand)) // 0x400000
|
|
{
|
|
if (reader.BaseStream.Length < reader.BaseStream.Position + 8) { IsValid = false; return; }
|
|
writer.Write(reader.ReadBytes(8));
|
|
}
|
|
|
|
if (header.HasFlag(PacketHeaderFlags.TimeSync)) // 0x1000000
|
|
{
|
|
if (reader.BaseStream.Length < reader.BaseStream.Position + 8) { IsValid = false; return; }
|
|
TimeSynch = reader.ReadDouble();
|
|
writer.Write(TimeSynch);
|
|
}
|
|
|
|
if (header.HasFlag(PacketHeaderFlags.EchoRequest)) // 0x2000000
|
|
{
|
|
if (reader.BaseStream.Length < reader.BaseStream.Position + 4) { IsValid = false; return; }
|
|
EchoRequestClientTime = reader.ReadSingle();
|
|
writer.Write(EchoRequestClientTime);
|
|
}
|
|
|
|
if (header.HasFlag(PacketHeaderFlags.Flow)) // 0x8000000
|
|
{
|
|
if (reader.BaseStream.Length < reader.BaseStream.Position + 6) { IsValid = false; return; }
|
|
FlowBytes = reader.ReadUInt32();
|
|
FlowInterval = reader.ReadUInt16();
|
|
writer.Write(FlowBytes);
|
|
writer.Write(FlowInterval);
|
|
}
|
|
|
|
Size = (uint)reader.BaseStream.Position - Size;
|
|
}
|
|
|
|
public uint CalculateHash32()
|
|
{
|
|
var bytes = headerBytes.GetBuffer();
|
|
|
|
return Hash32.Calculate(bytes, (int)headerBytes.Length);
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
if (Size == 0 || !IsValid)
|
|
{
|
|
return string.Empty;
|
|
}
|
|
|
|
string nice = "";
|
|
if (Header.HasFlag(PacketHeaderFlags.Flow))
|
|
{
|
|
nice = $" {FlowBytes} Interval: {FlowInterval}";
|
|
}
|
|
if (RetransmitData != null)
|
|
{
|
|
nice += $" requesting {RetransmitData.DefaultIfEmpty().Select(t => t.ToString()).Aggregate((a, b) => a + "," + b)}";
|
|
}
|
|
if (Header.HasFlag(PacketHeaderFlags.AckSequence))
|
|
{
|
|
nice += $" AckSeq: {AckSequence}";
|
|
}
|
|
return nice.Trim();
|
|
}
|
|
}
|
|
}
|