2024-12-02 20:43:28 +08:00
|
|
|
|
using PSO2SERVER.Database;
|
2024-09-10 01:13:20 +08:00
|
|
|
|
using PSO2SERVER.Models;
|
2024-12-02 20:43:28 +08:00
|
|
|
|
using static PSO2SERVER.Models.CharacterStruct;
|
2024-11-25 23:33:41 +08:00
|
|
|
|
using static PSO2SERVER.Party.Party;
|
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
|
|
|
|
{
|
|
|
|
|
class PartyInitPacket : Packet
|
|
|
|
|
{
|
2024-11-25 23:33:41 +08:00
|
|
|
|
public unsafe struct PartyEntry
|
2024-09-10 00:31:40 +08:00
|
|
|
|
{
|
2024-11-25 23:33:41 +08:00
|
|
|
|
/// 玩家对象的头部信息(包含ID、类型、区域ID等)。
|
2024-12-11 03:39:12 +08:00
|
|
|
|
public ObjectHeader id;
|
2024-11-25 23:33:41 +08:00
|
|
|
|
|
|
|
|
|
/// 玩家昵称。
|
|
|
|
|
public string nickname;
|
|
|
|
|
|
|
|
|
|
/// 玩家角色名称。
|
|
|
|
|
public string char_name;
|
|
|
|
|
|
|
|
|
|
/// 主职业的等级。
|
|
|
|
|
public byte level;
|
|
|
|
|
|
|
|
|
|
/// 副职业的等级。
|
|
|
|
|
public byte sublevel;
|
|
|
|
|
|
|
|
|
|
/// 玩家主职业类型(`ClassType` 枚举类型)。
|
|
|
|
|
public ClassType mainClass;
|
|
|
|
|
|
|
|
|
|
/// 玩家副职业类型(`ClassType` 枚举类型)。
|
|
|
|
|
public ClassType subClass;
|
|
|
|
|
|
|
|
|
|
/// 玩家在队伍中的颜色标识。
|
|
|
|
|
public PartyColor color;
|
|
|
|
|
|
|
|
|
|
/// 7字节的未知数据(通常是填充或者未定义用途)。
|
|
|
|
|
public fixed byte unk1[7];
|
|
|
|
|
|
|
|
|
|
/// 一个未知的 uint 类型数据,具体用途不明。
|
|
|
|
|
public uint unk2;
|
|
|
|
|
|
|
|
|
|
/// 玩家HP(体力)的三个数值。具体原因为什么有三个值目前不明。
|
|
|
|
|
public fixed uint hp[3];
|
|
|
|
|
|
|
|
|
|
/// 玩家所在的地图ID。
|
|
|
|
|
public ushort mapid;
|
|
|
|
|
|
|
|
|
|
/// 另一个未知的 ushort 类型数据。
|
|
|
|
|
public ushort unk3;
|
|
|
|
|
|
|
|
|
|
/// 12字节的未知数据。
|
|
|
|
|
public fixed byte unk4[0x0C];
|
|
|
|
|
|
|
|
|
|
/// 3个未知的 uint 数组数据。
|
|
|
|
|
public fixed uint unk5[3];
|
|
|
|
|
|
|
|
|
|
/// 未知的字符串,可能是其他信息(如玩家状态或其他描述信息)。
|
|
|
|
|
public string unk6;
|
|
|
|
|
|
|
|
|
|
/// PSO VITA(PlayStation Vita)相关字段,已注释掉,可能与Vita版本相关。
|
|
|
|
|
/// public string unk10;
|
|
|
|
|
|
|
|
|
|
/// 玩家角色的 ASCII 字符串相关数据,已注释掉。
|
|
|
|
|
/// public AsciiString unk7; // ASCII 字符串
|
|
|
|
|
|
|
|
|
|
/// 玩家语言设置(`ShortLanguage` 枚举类型),已注释掉。
|
|
|
|
|
/// public ShortLanguage lang;
|
|
|
|
|
|
|
|
|
|
/// 3字节的未知数据,已注释掉。
|
|
|
|
|
/// public fixed byte unk9[3];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// 队伍实例.
|
|
|
|
|
private ObjectHeader party_object;
|
|
|
|
|
/// 队伍队长实例.
|
|
|
|
|
private ObjectHeader leader;
|
|
|
|
|
/// 队伍人数.
|
|
|
|
|
private uint people_amount;
|
|
|
|
|
/// 队伍成员.
|
|
|
|
|
private PartyEntry[] entries = new PartyEntry[4]; // 这个是一个包含 4 个 `PartyEntry` 结构的数组,表示队伍中的4个成员。
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 未知
|
|
|
|
|
/// </summary>
|
2024-12-08 10:56:05 +08:00
|
|
|
|
private string unk2 = "";
|
2024-11-25 23:33:41 +08:00
|
|
|
|
|
|
|
|
|
private Character[] players;
|
|
|
|
|
public PartyInitPacket(Character[] players)
|
|
|
|
|
{
|
|
|
|
|
this.players = players;
|
|
|
|
|
party_object = new ObjectHeader((uint)players[0].Account.AccountId, ObjectType.Party);
|
|
|
|
|
leader = new ObjectHeader((uint)players[0].Account.AccountId, ObjectType.Player);
|
|
|
|
|
people_amount = (uint)players.Length;
|
|
|
|
|
|
|
|
|
|
// 队伍结构数据
|
|
|
|
|
for (int i = 0; i < players.Length; i++)
|
|
|
|
|
{
|
2024-12-11 03:39:12 +08:00
|
|
|
|
entries[i].id = new ObjectHeader((uint)players[i].Account.AccountId, ObjectType.Player); // Header of player
|
2024-11-25 23:33:41 +08:00
|
|
|
|
entries[i].nickname = players[i].Account.Nickname;
|
|
|
|
|
entries[i].char_name = players[i].Name;
|
|
|
|
|
entries[i].level = (byte)players[i].Jobs.entries.hunter.level;
|
|
|
|
|
entries[i].sublevel = (byte)players[i].Jobs.entries.hunter.level2;
|
|
|
|
|
entries[i].mainClass = players[i].Jobs.mainClass;
|
|
|
|
|
entries[i].subClass = players[i].Jobs.subClass;
|
|
|
|
|
entries[i].color = (PartyColor)i;
|
|
|
|
|
entries[i].unk2 = 0;
|
|
|
|
|
entries[i].mapid = 0;
|
|
|
|
|
entries[i].unk3 = 0;
|
|
|
|
|
entries[i].unk6 = players[i].Name;
|
|
|
|
|
}
|
2024-09-10 00:31:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override byte[] Build()
|
|
|
|
|
{
|
2024-11-25 23:33:41 +08:00
|
|
|
|
if (players.Length < 1)
|
2024-09-10 00:31:40 +08:00
|
|
|
|
return new byte[0];
|
|
|
|
|
|
|
|
|
|
// xor: 0xD863, sub: 0xA9
|
2024-12-10 01:23:49 +08:00
|
|
|
|
PacketWriter pkt = new PacketWriter();
|
2024-12-11 02:24:51 +08:00
|
|
|
|
pkt.WriteObjectHeader(party_object);
|
|
|
|
|
pkt.WriteObjectHeader(leader); // Accounts receiving the thing
|
2024-12-10 01:23:49 +08:00
|
|
|
|
pkt.Write(people_amount); // Likely partymembercount
|
2024-11-25 23:33:41 +08:00
|
|
|
|
for (int i = 0; i < 4; i++)
|
2024-09-10 00:31:40 +08:00
|
|
|
|
{
|
2024-12-11 03:39:12 +08:00
|
|
|
|
pkt.WriteObjectHeader(entries[i].id);
|
2024-12-10 01:23:49 +08:00
|
|
|
|
pkt.WriteUtf16(entries[i].nickname, 0xD863, 0xA9);
|
|
|
|
|
pkt.WriteUtf16(entries[i].char_name, 0xD863, 0xA9);
|
|
|
|
|
pkt.Write(entries[i].level); // Active class level
|
|
|
|
|
pkt.Write(entries[i].sublevel); // idk
|
|
|
|
|
pkt.Write((byte)entries[i].mainClass); // idk
|
|
|
|
|
pkt.Write((byte)entries[i].subClass); // idk
|
|
|
|
|
pkt.Write((byte)entries[i].color); // idk
|
|
|
|
|
pkt.WriteBytes(0, 7);
|
|
|
|
|
pkt.Write(entries[i].unk2); // idk
|
2024-11-25 23:33:41 +08:00
|
|
|
|
///hp
|
2024-12-10 01:23:49 +08:00
|
|
|
|
pkt.Write((uint)0);
|
|
|
|
|
pkt.Write((uint)0);
|
|
|
|
|
pkt.Write((uint)0);
|
2024-11-25 23:33:41 +08:00
|
|
|
|
/// 玩家所在的地图ID。
|
2024-12-10 01:23:49 +08:00
|
|
|
|
pkt.Write(entries[i].mapid);
|
|
|
|
|
pkt.Write(entries[i].unk3);
|
|
|
|
|
pkt.WriteBytes(0, 12);
|
|
|
|
|
pkt.Write((uint)0);
|
|
|
|
|
pkt.Write((uint)0);
|
|
|
|
|
pkt.WriteUtf16(entries[i].unk6, 0xD863, 0xA9);
|
2024-09-10 00:31:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-12-10 01:23:49 +08:00
|
|
|
|
pkt.WriteAscii(unk2, 0xD863, 0xA9);
|
2024-11-25 23:33:41 +08:00
|
|
|
|
|
|
|
|
|
//// 队伍结构数据
|
|
|
|
|
//for(int i = 0; i < players.Length; i++)
|
|
|
|
|
//{
|
|
|
|
|
// PartyEntry pe = new PartyEntry();
|
2024-12-10 01:23:49 +08:00
|
|
|
|
// pkt.WriteStruct(new ObjectHeader((uint)players[i].Accounts.AccountId, ObjectType.Player)); // Header of player
|
|
|
|
|
// pkt.WriteUtf16(players[i].name, 0xD863, 0xA9);
|
|
|
|
|
// pkt.WriteUtf16(players[i].Accounts.Nickname, 0xD863, 0xA9);
|
|
|
|
|
// pkt.Write((byte)players[i].Jobs.entries.hunter.level); // Active class level
|
|
|
|
|
// pkt.Write((byte)players[i].Jobs.entries.hunter.level2); // idk
|
|
|
|
|
// pkt.Write((byte)players[i].Jobs.mainClass); // idk
|
|
|
|
|
// pkt.Write((byte)players[i].Jobs.subClass); // idk
|
|
|
|
|
// pkt.Write((byte)i); // idk
|
|
|
|
|
// pkt.WriteBytes(0, 7);
|
|
|
|
|
// pkt.Write((uint)0); // idk
|
2024-11-25 23:33:41 +08:00
|
|
|
|
// ///hp
|
2024-12-10 01:23:49 +08:00
|
|
|
|
// pkt.Write((uint)0);
|
|
|
|
|
// pkt.Write((uint)0);
|
|
|
|
|
// pkt.Write((uint)0);
|
2024-11-25 23:33:41 +08:00
|
|
|
|
// /// 玩家所在的地图ID。
|
2024-12-10 01:23:49 +08:00
|
|
|
|
// pkt.Write(pe.mapid);
|
|
|
|
|
// pkt.Write(pe.unk3);
|
|
|
|
|
// pkt.WriteBytes(0, 12);
|
|
|
|
|
// pkt.Write((uint)0);
|
|
|
|
|
// pkt.Write((uint)0);
|
|
|
|
|
// pkt.Write((uint)0);
|
2024-11-25 23:33:41 +08:00
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
//for(int i = 0; i < 4 - players.Length; i++) // Empty entries
|
|
|
|
|
//{
|
2024-12-10 01:23:49 +08:00
|
|
|
|
// pkt.WriteStruct(new ObjectHeader(0, 0)); // Header of player
|
|
|
|
|
// pkt.WriteMagic(0, 0xD863, 0xA9);
|
|
|
|
|
// pkt.WriteMagic(0, 0xD863, 0xA9);
|
|
|
|
|
// pkt.Write((byte)0); // Active class level
|
|
|
|
|
// pkt.Write((byte)0); // idk
|
|
|
|
|
// pkt.Write((byte)0); // idk
|
|
|
|
|
// pkt.Write((byte)0); // idk
|
|
|
|
|
// pkt.Write((byte)0); // idk
|
|
|
|
|
// pkt.WriteBytes(0, 7);
|
|
|
|
|
// pkt.Write((uint)0); // idk
|
2024-11-25 23:33:41 +08:00
|
|
|
|
// ///hp
|
2024-12-10 01:23:49 +08:00
|
|
|
|
// pkt.Write((uint)0);
|
|
|
|
|
// pkt.Write((uint)0);
|
|
|
|
|
// pkt.Write((uint)0);
|
2024-11-25 23:33:41 +08:00
|
|
|
|
// /// 玩家所在的地图ID。
|
2024-12-10 01:23:49 +08:00
|
|
|
|
// pkt.Write((ushort)0);
|
|
|
|
|
// pkt.Write((ushort)0);
|
|
|
|
|
// pkt.WriteBytes(0, 12);
|
|
|
|
|
// pkt.Write((uint)0);
|
|
|
|
|
// pkt.Write((uint)0);
|
|
|
|
|
// pkt.Write((uint)0);
|
2024-11-25 23:33:41 +08:00
|
|
|
|
//}
|
2024-09-10 00:31:40 +08:00
|
|
|
|
|
2024-12-10 01:23:49 +08:00
|
|
|
|
return pkt.ToArray();
|
2024-09-10 00:31:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override PacketHeader GetHeader()
|
|
|
|
|
{
|
2024-09-16 02:56:02 +08:00
|
|
|
|
return new PacketHeader(0x0E, 0x02, PacketFlags.PACKED);
|
2024-09-10 00:31:40 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|