2024-12-02 20:43:28 +08:00
|
|
|
|
using PSO2SERVER.Database;
|
|
|
|
|
using PSO2SERVER.Models;
|
2024-12-03 18:17:43 +08:00
|
|
|
|
using PSO2SERVER.Zone;
|
2024-11-29 10:01:28 +08:00
|
|
|
|
using System.Runtime.InteropServices;
|
2024-12-02 20:43:28 +08:00
|
|
|
|
using static PSO2SERVER.Models.CharacterStruct;
|
2024-11-29 10:01:28 +08:00
|
|
|
|
using static PSO2SERVER.Protocol.Packets.CharacterSpawnPacket;
|
2024-09-10 00:31:40 +08:00
|
|
|
|
|
2024-11-27 18:05:53 +08:00
|
|
|
|
namespace PSO2SERVER.Protocol.Packets
|
2024-09-10 00:31:40 +08:00
|
|
|
|
{
|
|
|
|
|
public class CharacterSpawnPacket : Packet
|
|
|
|
|
{
|
2024-11-30 16:18:27 +08:00
|
|
|
|
public enum CharacterSpawnType : byte
|
2024-09-18 00:55:35 +08:00
|
|
|
|
{
|
|
|
|
|
/// Spawned character is not related to the receiver.
|
|
|
|
|
Other = 0x27,
|
|
|
|
|
/// Spawned character is related to the receiver.
|
|
|
|
|
Myself = 0x2F,
|
|
|
|
|
|
|
|
|
|
Undefined = 0xFF,
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-06 23:40:36 +08:00
|
|
|
|
//private readonly Character _character;
|
|
|
|
|
//public byte IsItMe = (byte)CharacterSpawnType.Myself;
|
|
|
|
|
//public uint IsGM = 0;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// CharacterSpawnPacket Struct
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// Spawned character's player object.
|
|
|
|
|
public ObjectHeader objHeader { get; set; } = new ObjectHeader();
|
|
|
|
|
public PSOLocation objPosition { get; set; } = new PSOLocation();
|
|
|
|
|
public ushort unk1 { get; set; } = 0;
|
|
|
|
|
/// Always `Character`. (?)
|
|
|
|
|
public string objName { get; set; } = "Character";//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; }
|
|
|
|
|
public CharacterSpawnType spawn_type { get; set; }
|
|
|
|
|
public byte unk9 { get; set; }
|
|
|
|
|
public ushort unk10 { get; set; }
|
|
|
|
|
public Character _character { get; set; }
|
2024-12-07 13:42:43 +08:00
|
|
|
|
public uint unk11 { get; set; }
|
2024-12-06 23:40:36 +08:00
|
|
|
|
/// Set to `1` if the player is a GM.
|
|
|
|
|
public uint gm_flag { get; set; }
|
|
|
|
|
public string nickname { get; set; }
|
|
|
|
|
//#[SeekAfter(0x60)]
|
|
|
|
|
public byte[] unk12 { get; set; } = new byte[0x40];
|
2024-09-10 00:31:40 +08:00
|
|
|
|
|
|
|
|
|
public CharacterSpawnPacket(Character character, PSOLocation locatiion)
|
|
|
|
|
{
|
2024-12-06 23:40:36 +08:00
|
|
|
|
objHeader = new ObjectHeader((uint)character.Account.AccountId, ObjectType.Player);
|
2024-09-10 00:31:40 +08:00
|
|
|
|
_character = character;
|
2024-12-06 23:40:36 +08:00
|
|
|
|
objPosition = locatiion;
|
2024-09-10 00:31:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-12-06 21:49:29 +08:00
|
|
|
|
public CharacterSpawnPacket(Character character, PSOLocation locatiion, bool isme, bool isgm)
|
2024-09-10 00:31:40 +08:00
|
|
|
|
{
|
2024-12-06 23:40:36 +08:00
|
|
|
|
objHeader = new ObjectHeader((uint)character.Account.AccountId, ObjectType.Player);
|
2024-09-10 00:31:40 +08:00
|
|
|
|
_character = character;
|
2024-12-06 23:40:36 +08:00
|
|
|
|
spawn_type = isme ? CharacterSpawnType.Myself : CharacterSpawnType.Other;
|
|
|
|
|
objPosition = locatiion;
|
|
|
|
|
gm_flag = isgm ? (uint)1 : 0;
|
2024-09-10 00:31:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region implemented abstract members of Packet
|
|
|
|
|
|
|
|
|
|
public override byte[] Build()
|
|
|
|
|
{
|
2024-12-06 23:40:36 +08:00
|
|
|
|
var pkt = new PacketWriter();
|
2024-12-03 13:10:49 +08:00
|
|
|
|
// Accounts header
|
2024-12-06 23:40:36 +08:00
|
|
|
|
pkt.WriteStruct(objHeader);
|
2024-09-10 00:31:40 +08:00
|
|
|
|
// Spawn position
|
2024-12-06 23:40:36 +08:00
|
|
|
|
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)spawn_type);
|
|
|
|
|
pkt.Write(unk9);
|
|
|
|
|
pkt.Write(unk10);
|
2024-11-30 16:18:27 +08:00
|
|
|
|
// Character data.
|
2024-12-07 01:44:49 +08:00
|
|
|
|
pkt.Write(_character.BuildCharacterByteArray());
|
2024-12-07 13:42:43 +08:00
|
|
|
|
pkt.Write(unk11);
|
2024-12-06 23:40:36 +08:00
|
|
|
|
pkt.Write(gm_flag);
|
|
|
|
|
pkt.WriteFixedLengthUtf16(_character.Account.Nickname, 0x10);
|
2024-12-07 13:42:43 +08:00
|
|
|
|
//for (var i = 0; i < 0x60; i++)
|
|
|
|
|
// pkt.Write((byte)0);
|
|
|
|
|
//pkt.Write(unk12);
|
2024-12-06 23:40:36 +08:00
|
|
|
|
|
|
|
|
|
//pkt.Write((ushort)0); // 0x46
|
|
|
|
|
//pkt.Write((uint)602); // 0x48
|
|
|
|
|
//pkt.Write((uint)1); // 0x4C
|
|
|
|
|
//pkt.Write((uint)53); // 0x50
|
|
|
|
|
//pkt.Write((uint)0); // 0x54
|
|
|
|
|
|
|
|
|
|
//// Character spawn type.
|
|
|
|
|
//pkt.Write(IsItMe); // 0x58
|
|
|
|
|
//pkt.Write((byte)0x00);
|
|
|
|
|
//pkt.Write((ushort)0x00);
|
|
|
|
|
|
|
|
|
|
//////writer.write((ushort)0x022f); // 0x5c
|
|
|
|
|
////writer.write((byte)0x2f); // 0x5c
|
|
|
|
|
////writer.write((byte)0x02);
|
|
|
|
|
//////writer.write((ushort)0x0132); // 0x5e
|
|
|
|
|
////writer.write((byte)0x32);
|
|
|
|
|
////writer.write((byte)0x01);
|
|
|
|
|
|
|
|
|
|
////JobParam jobParam = _character.Jobs;
|
|
|
|
|
////jobParam.mainClass = ClassType.Luster;
|
|
|
|
|
////jobParam.subClass = ClassType.Phantom;
|
|
|
|
|
////jobParam.entries.Luster.level = 100;
|
|
|
|
|
|
|
|
|
|
//// Character data.
|
|
|
|
|
//pkt.Write((uint)_character.AccountID);
|
|
|
|
|
//pkt.Write((uint)_character.CharacterID);
|
|
|
|
|
//pkt.Write((uint)_character.Unk1);//4
|
|
|
|
|
//pkt.Write((uint)_character.VoiceType);//4
|
|
|
|
|
//pkt.Write((ushort)_character.Unk2);//2
|
|
|
|
|
//pkt.Write(_character.VoicePitch);//2
|
|
|
|
|
//pkt.WriteFixedLengthUtf16(_character.Name, 16);
|
|
|
|
|
//pkt.Write((uint)_character.Unk3); // 0x90
|
|
|
|
|
//pkt.WriteStruct(_character.Looks);
|
|
|
|
|
//pkt.WriteStruct(_character.Jobs);
|
|
|
|
|
//pkt.WriteFixedLengthUtf16(_character.Account.Nickname, 16);
|
|
|
|
|
//pkt.WriteBytes(0, 116);
|
|
|
|
|
|
|
|
|
|
//pkt.Write((uint)0); // 0x204
|
|
|
|
|
//pkt.Write(IsGM); // gmflag?
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//for (var i = 0; i < 0x60; i++)
|
|
|
|
|
// pkt.Write((byte)0);
|
2024-09-10 00:31:40 +08:00
|
|
|
|
|
2024-12-02 20:43:28 +08:00
|
|
|
|
//for (var i = 0; i < 0x40; i++)
|
|
|
|
|
// writer.Write((byte)0);
|
|
|
|
|
|
2024-12-06 23:40:36 +08:00
|
|
|
|
return pkt.ToArray();
|
2024-09-10 00:31:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override PacketHeader GetHeader()
|
|
|
|
|
{
|
2024-09-21 12:35:09 +08:00
|
|
|
|
return new PacketHeader(0x08, 0x04, PacketFlags.None);
|
2024-09-10 00:31:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
}
|