using MySqlX.XDevAPI; using Newtonsoft.Json; using PSO2SERVER.Database; using PSO2SERVER.Models; using PSO2SERVER.Zone; using System.IO; using System.Runtime.InteropServices; using static PSO2SERVER.Models.CharacterStruct; using static PSO2SERVER.Protocol.Packets.CharacterSpawnPacket; namespace PSO2SERVER.Protocol.Packets { public class CharacterSpawnPacket : Packet { public enum CharacterSpawnType : byte { /// Spawned character is not related to the receiver. Other = 0x27, /// Spawned character is related to the receiver. Myself = 0x2F, Undefined = 0xFF, } //private readonly Character _character; //public byte IsItMe = (byte)CharacterSpawnType.Myself; //public uint IsGM = 0; /// /// CharacterSpawnPacket Struct /// /// Spawned character's player object. [JsonProperty("object")] public ObjectHeader ObjHeader { get; set; } = new ObjectHeader(); [JsonProperty("position")] public PSOLocation ObjPosition { get; set; } = new PSOLocation(); [JsonProperty("unk1")] public ushort Unk1 { get; set; } = 0; /// Enemy name. [JsonProperty("name")] public string ObjName { get; set; } = "Character";//Ascii 0x20 public ushort Unk3 { get; set; } = 1; public ushort Unk4 { get; set; } public uint Unk5 { get; set; } public uint Unk6 { get; set; } public uint Unk7 { get; set; } public uint Unk8 { get; set; } /// Character spawn type. public CharacterSpawnType SpawnType { get; set; } public byte Unk9 { get; set; } public ushort Unk10 { get; set; } /// Character data. public Character Character { get; set; } public uint Unk11 { get; set; } /// Set to `1` if the player is a GM. public uint GmFlag { get; set; } /// Player's nickname. public string Nickname { get; set; }//0x10 //#[SeekAfter(0x60)] public byte[] Unk12 { get; set; } = new byte[0x40]; public readonly Client _client; public CharacterSpawnPacket() { } public CharacterSpawnPacket(Client c, PSOLocation locatiion) { _client = c; ObjHeader = new ObjectHeader((uint)c._account.AccountId, ObjectType.Player); ObjPosition = locatiion; Character = c.Character; } public CharacterSpawnPacket(Client c, PSOLocation locatiion, bool isme, bool isgm) { _client = c; ObjHeader = new ObjectHeader((uint)c._account.AccountId, ObjectType.Player); ObjPosition = locatiion; Character = c.Character; SpawnType = isme ? CharacterSpawnType.Myself : CharacterSpawnType.Other; GmFlag = isgm ? (uint)1 : 0; } #region implemented abstract members of Packet public override byte[] Build() { var pkt = new PacketWriter(); // Accounts header pkt.WriteObjectHeader(ObjHeader); // Spawn position pkt.WritePosition(ObjPosition); pkt.Write(Unk1); pkt.WriteFixedLengthASCII(ObjName, 0x20); pkt.Write(Unk3); // 0x44 pkt.Write(Unk4); pkt.Write(Unk5); pkt.Write(Unk6); pkt.Write(Unk7); pkt.Write(Unk8); pkt.Write((byte)SpawnType); pkt.Write(Unk9); pkt.Write(Unk10); // Character data. pkt.Write(Character.BuildCharacterByteArray()); pkt.Write(Unk11); pkt.Write(GmFlag); pkt.WriteFixedLengthUtf16(_client._account.Nickname, 0x10); pkt.BaseStream.Seek(0x60 - (0x10 * 2), SeekOrigin.Current); pkt.Write(Unk12); return pkt.ToArray(); } public override PacketHeader GetHeader() { return new PacketHeader(0x08, 0x04, PacketFlags.None); } #endregion } }