PSO2SERVER/Server/Protocol/Packets/08-SpawnPacket/08-04-CharacterSpawnPacket.cs
2024-12-19 01:21:00 +08:00

124 lines
4.1 KiB
C#

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;
/// <summary>
/// CharacterSpawnPacket Struct
/// </summary>
/// 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
}
}