PSO2SERVER/Server/Protocol/Packets/0E-PartyPacket/0E-02-PartyInitPacket.cs

210 lines
8.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using PSO2SERVER.Database;
using PSO2SERVER.Models;
using static PSO2SERVER.Models.CharacterStruct;
using static PSO2SERVER.Party.Party;
namespace PSO2SERVER.Protocol.Packets
{
class PartyInitPacket : Packet
{
public unsafe struct PartyEntry
{
/// 玩家对象的头部信息包含ID、类型、区域ID等
public ObjectHeader id;
/// 玩家昵称。
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 VITAPlayStation 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>
private string unk2 = "";
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++)
{
entries[i].id = new ObjectHeader((uint)players[i].Account.AccountId, ObjectType.Player); // Header of player
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;
}
}
public override byte[] Build()
{
if (players.Length < 1)
return new byte[0];
// xor: 0xD863, sub: 0xA9
PacketWriter pkt = new PacketWriter();
pkt.WriteObjectHeader(party_object);
pkt.WriteObjectHeader(leader); // Accounts receiving the thing
pkt.Write(people_amount); // Likely partymembercount
for (int i = 0; i < 4; i++)
{
pkt.WriteObjectHeader(entries[i].id);
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
///hp
pkt.Write((uint)0);
pkt.Write((uint)0);
pkt.Write((uint)0);
/// 玩家所在的地图ID。
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);
}
pkt.WriteAscii(unk2, 0xD863, 0xA9);
//// 队伍结构数据
//for(int i = 0; i < players.Length; i++)
//{
// PartyEntry pe = new PartyEntry();
// 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
// ///hp
// pkt.Write((uint)0);
// pkt.Write((uint)0);
// pkt.Write((uint)0);
// /// 玩家所在的地图ID。
// pkt.Write(pe.mapid);
// pkt.Write(pe.unk3);
// pkt.WriteBytes(0, 12);
// pkt.Write((uint)0);
// pkt.Write((uint)0);
// pkt.Write((uint)0);
//}
//for(int i = 0; i < 4 - players.Length; i++) // Empty entries
//{
// 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
// ///hp
// pkt.Write((uint)0);
// pkt.Write((uint)0);
// pkt.Write((uint)0);
// /// 玩家所在的地图ID。
// pkt.Write((ushort)0);
// pkt.Write((ushort)0);
// pkt.WriteBytes(0, 12);
// pkt.Write((uint)0);
// pkt.Write((uint)0);
// pkt.Write((uint)0);
//}
return pkt.ToArray();
}
public override PacketHeader GetHeader()
{
return new PacketHeader(0x0E, 0x02, PacketFlags.PACKED);
}
}
}