新增和修正部分数据包

This commit is contained in:
Longfeng Qin 2024-12-11 03:39:12 +08:00
parent 37106641a7
commit d2ac82b478
16 changed files with 309 additions and 136 deletions

View File

@ -12,8 +12,13 @@ namespace PSO2SERVER.Models
}
public class Mission
public struct Mission
{
/*5 - main
1 - daily
2 - weekly
7 - tier */
/// Mission type.
public uint MissionType; // Mission type.
public uint StartDate; // Mission start timestamp.
public uint EndDate; // Mission end timestamp.

View File

@ -38,10 +38,10 @@ namespace PSO2SERVER.Models
public PSO2ItemCamo Camo;
[FieldOffset(0)]
public PSO2ItemUnit Unit;
[FieldOffset(0)]
public byte[] Unknown;
[FieldOffset(0)]
public PSO2ItemNone None;
//[FieldOffset(0)]
//public byte[] Unknown;
//[FieldOffset(0)]
//public PSO2ItemNone None;
}
[StructLayout(LayoutKind.Sequential)]

View File

@ -29,64 +29,36 @@ namespace PSO2SERVER.Models
}
// 对象头部结构体
public class ObjectHeader
public struct ObjectHeader
{
/// 对象的ID。
[JsonProperty("id")]
public uint ID { get; set; } = 0;
public uint ID { get; set; }
[JsonProperty("unk")]
public uint Padding { get; set; } = 0;
public uint Padding { get; set; }
/// 对象的类型。
[JsonProperty("entity_type")]
[JsonConverter(typeof(ObjectTypeConverter))]
/// 对象的类型。
public ObjectType ObjectType { get; set; } = ObjectType.Unknown;
public ObjectType ObjectType { get; set; }
/// 对象所在的区域ID。玩家对象没有设置这个字段。
[JsonProperty("map_id")]
public ushort MapID { get; set; } = 0;
//初始化结构体
public ObjectHeader()
{;
}
public struct ObjHeaderStruct
{
public uint ID { get; set; }
public uint Padding { get; set; }
public ObjectType ObjectType { get; set; }
public ushort MapID { get; set; }
// 结构体构造函数
public ObjHeaderStruct(uint id, uint padding, ObjectType objectType, ushort mapID)
{
ID = id;
Padding = padding;
ObjectType = objectType;
MapID = mapID;
}
// 结构体构造函数
public ObjHeaderStruct(uint id, ObjectType objectType)
{
ID = id;
Padding = 0;
ObjectType = objectType;
MapID = 0;
}
}
public ushort MapID { get; set; }
// 只包含ID和类型的构造函数
public ObjectHeader(uint id, ObjectType type)
public ObjectHeader(uint id, ObjectType objectType)
{
ID = id;
ObjectType = type;
Padding = 0;
ObjectType = objectType;
MapID = 0;
}
// 包含ID、类型和区域ID的构造函数
public ObjectHeader(uint id, ObjectType type, ushort mapid)
public ObjectHeader(uint id, ObjectType objectType, ushort mapid)
{
ID = id;
ObjectType = type;
Padding = 0;
ObjectType = objectType;
MapID = mapid;
}
@ -108,18 +80,6 @@ namespace PSO2SERVER.Models
writer.Write(MapID); // 写入区域ID
}
// 获取ObjHeaderStruct结构体
public ObjHeaderStruct ToObjHeaderStruct()
{
return new ObjHeaderStruct(ID, Padding, ObjectType, MapID);
}
// 从ObjHeaderStruct结构体构造ObjectHeader
public static ObjectHeader FromObjHeaderStruct(ObjHeaderStruct objHeaderStruct)
{
return new ObjectHeader(objHeaderStruct.ID, objHeaderStruct.ObjectType, objHeaderStruct.MapID);
}
// ToString 方法,用来返回 ObjectHeader 的字符串表示
public override string ToString()
{

View File

@ -15,7 +15,7 @@ namespace PSO2SERVER.Protocol.Handlers
public unsafe struct MapLoadedPacket
{
/// Loaded zone object.
public ObjectHeader.ObjHeaderStruct MapObject;
public ObjectHeader MapObject;
/// Unknown data, 32 bytes.
public fixed byte Unk[0x20];
}

View File

@ -0,0 +1,37 @@
using System;
using PSO2SERVER.Models;
using PSO2SERVER.Protocol.Packets;
namespace PSO2SERVER.Protocol.Handlers
{
[PacketHandlerAttr(0x0F, 0x01)]
public class ItemPickupRequest : PacketHandler
{
public struct ItemPickupRequestPacket
{
/// Item drop ID.
public uint DropId { get; set; }
/// Unknown field.
public uint Unk { get; set; }
// Constructor for convenience
public ItemPickupRequestPacket(uint dropId, uint unk)
{
DropId = dropId;
Unk = unk;
}
}
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
{
var info = string.Format("[<--] 接收到的数据 (hex): {0} 字节", data.Length);
Logger.WriteHex(info, data);
var reader = new PacketReader(data, position, size);
var pkt = reader.ReadStruct<ItemPickupRequestPacket>();
context.SendPacket(new ItemPickupResponsePacket(context._account.AccountId, pkt.DropId, 1, pkt.Unk));
}
}
}

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using PSO2SERVER.Models;
using PSO2SERVER.Protocol.Packets;
@ -12,12 +13,34 @@ namespace PSO2SERVER.Protocol.Handlers
if(context.Character == null)
return;
//var info = string.Format("[<--] 接收到的数据 (hex): {0} 字节", data.Length);
//Logger.WriteHex(info, data);
var info = string.Format("[<--] 接收到的数据 (hex): {0} 字节", data.Length);
Logger.WriteHex(info, data);
//Mission mission = new Mission();
var mission = new Mission
{
MissionType = 5,
StartDate = 0,
EndDate = 0,
Id = 6040309,
Unk5 = 0,
CompletionDate = 1615045153,
Unk7 = 0,
Unk8 = 0,
Unk9 = 0,
Unk10 = 1,
Unk11 = 1023,
Unk12 = 0,
Unk13 = 0,
Unk14 = 1,
Unk15 = 0,
};
//context.SendPacket(new ARKSMissionListPacket(mission));
List<Mission> Missions = new List<Mission>
{
mission
};
context.SendPacket(new ARKSMissionListPacket(Missions));
}
}
}

View File

@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using PSO2SERVER.Models;
using PSO2SERVER.Protocol.Packets;
namespace PSO2SERVER.Protocol.Handlers
{
[PacketHandlerAttr(0x4A, 0x0C)]
public class SetTrackedMission : PacketHandler
{
public struct SetTrackedMissionPacket
{
/// Mission ID or [`u32::MAX`] if no mission is selected.
public uint Id { get; set; }
}
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
{
if(context.Character == null)
return;
var info = string.Format("[<--] 接收到的数据 (hex): {0} 字节", data.Length);
Logger.WriteHex(info, data);
var reader = new PacketReader(data, position, size);
var pkt = reader.ReadStruct<SetTrackedMissionPacket>();
Logger.Write($"pkt.id:{pkt.Id}");
}
}
}

View File

@ -40,9 +40,9 @@ namespace PSO2SERVER.Protocol.Packets
public struct FullMovementData
{
[FieldOffset(0x0)]
public ObjectHeader.ObjHeaderStruct entity1;
public ObjectHeader entity1;
[FieldOffset(0xC)]
public ObjectHeader.ObjHeaderStruct entity2;
public ObjectHeader entity2;
[FieldOffset(0x18)]
public UInt32 timestamp;
[FieldOffset(0x1C)]

View File

@ -10,7 +10,7 @@ namespace PSO2SERVER.Protocol.Packets
public unsafe struct PartyEntry
{
/// 玩家对象的头部信息包含ID、类型、区域ID等
public ObjectHeader.ObjHeaderStruct id;
public ObjectHeader id;
/// 玩家昵称。
public string nickname;
@ -94,7 +94,7 @@ namespace PSO2SERVER.Protocol.Packets
// 队伍结构数据
for (int i = 0; i < players.Length; i++)
{
entries[i].id = new ObjectHeader.ObjHeaderStruct((uint)players[i].Account.AccountId, ObjectType.Player); // Header of player
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;
@ -121,7 +121,7 @@ namespace PSO2SERVER.Protocol.Packets
pkt.Write(people_amount); // Likely partymembercount
for (int i = 0; i < 4; i++)
{
pkt.WriteStruct(entries[i].id);
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

View File

@ -0,0 +1,31 @@
using PSO2SERVER.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PSO2SERVER.Protocol.Packets
{
public class Unk0FPacket : Packet
{
public Unk0FPacket()
{
}
#region implemented abstract members of Packet
public override byte[] Build()
{
var pkt = new PacketWriter();
return pkt.ToArray();
}
public override PacketHeader GetHeader()
{
return new PacketHeader(0x0F, 0x0, PacketFlags.None);
}
#endregion
}
}

View File

@ -0,0 +1,52 @@
using PSO2SERVER.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PSO2SERVER.Protocol.Packets
{
public class ItemAttributesPacket : Packet
{
/// Attribute ID (?) (seen only 0 or 1).
public ushort Id { get; set; }
/// Segment ID.
public ushort Segment { get; set; }
/// Total data size.
public uint TotalSize { get; set; }
/// ICE archive data segment.
public byte[] Data { get; set; }
// Constructor for convenience
public ItemAttributesPacket(ushort id, ushort segment, uint totalSize, byte[] data)
{
Id = id;
Segment = segment;
TotalSize = totalSize;
Data = data;
}
#region implemented abstract members of Packet
public override byte[] Build()
{
var pkt = new PacketWriter();
pkt.Write(Id);
pkt.Write(Segment);
pkt.Write(TotalSize);
pkt.Write(Data);
return pkt.ToArray();
}
public override PacketHeader GetHeader()
{
return new PacketHeader(0x0F, 0x00, PacketFlags.PACKED);
}
#endregion
}
}

View File

@ -0,0 +1,46 @@
using PSO2SERVER.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PSO2SERVER.Protocol.Packets
{
public class ItemPickupResponsePacket : Packet
{
/// Packet receiver object (? or player, who picked up the item, unsure)
public ObjectHeader Target { get; set; } = new ObjectHeader();
/// Item drop ID.
public uint Drop_id { get; set; } = new uint();
/// Was the item actually picked up.
public uint Was_pickedup { get; set; } = new uint();
public uint Unk { get; set; } = new uint();
public ItemPickupResponsePacket(int player_id, uint drop_id, uint was_pickedup, uint unk)
{
Target = new ObjectHeader((uint)player_id, ObjectType.Player);
Drop_id = drop_id;
Was_pickedup = was_pickedup;
Unk = unk;
}
#region implemented abstract members of Packet
public override byte[] Build()
{
var pkt = new PacketWriter();
pkt.WriteObjectHeader(Target);
pkt.Write(Drop_id);
pkt.Write(Was_pickedup);
pkt.Write(Unk);
return pkt.ToArray();
}
public override PacketHeader GetHeader()
{
return new PacketHeader(0x0F, 0x02, PacketFlags.None);
}
#endregion
}
}

View File

@ -7,6 +7,11 @@ namespace PSO2SERVER.Protocol.Packets
{
public Int64 NewAmount = 0;
public SetMesetaPacket(long newAmount)
{
NewAmount = newAmount;
}
#region implemented abstract members of Packet
public override byte[] Build()

View File

@ -8,69 +8,39 @@ namespace PSO2SERVER.Protocol.Packets
{
public class ARKSMissionListPacket : Packet
{
public struct MissionListPacket
public uint Unk1 { get; set; } = new uint();
public List<Mission> Missions { get; set; } = new List<Mission>();
public uint DailyUpdate { get; set; } = new uint();
public uint WeeklyUpdate { get; set; } = new uint();
public uint TierUpdate { get; set; } = new uint();
public ARKSMissionListPacket(List<Mission> mission)
{
public uint Unk1; // 对应 Rust 的 u32
public List<Mission> Missions; // 使用 List 替代 Vec
public uint DailyUpdate; // 对应 Rust 的 u32
public uint WeeklyUpdate; // 对应 Rust 的 u32
public uint TierUpdate; // 对应 Rust 的 u32
Unk1 = 0;
Missions = mission;
DailyUpdate = 1689272266;
WeeklyUpdate = 1689273267;
TierUpdate = 1689273267;
// 不使用构造函数,而是使用默认值
public static MissionListPacket Create()
{
return new MissionListPacket
{
Missions = new List<Mission>(),
Unk1 = 0,
DailyUpdate = 0,
WeeklyUpdate = 0,
TierUpdate = 0
};
}
}
MissionListPacket pkt { get; set; }
public ARKSMissionListPacket(Mission mission)
{
pkt = MissionListPacket.Create(); // 使用工厂方法初始化 pkt
// 初始化 pkt 或添加初始任务
pkt.Missions.Add(mission);
}
// 增加任务
public void AddMission(Mission mission)
{
pkt.Missions.Add(mission);
}
// 删除任务
public bool RemoveMission(Mission mission)
{
return pkt.Missions.Remove(mission);
}
// 更新任务
public void UpdateMission(int index, Mission mission)
{
if (index >= 0 && index < pkt.Missions.Count)
{
pkt.Missions[index] = mission;
}
}
#region implemented abstract members of Packet
public override byte[] Build()
{
var writer = new PacketWriter();
return writer.ToArray();
var pkt = new PacketWriter();
pkt.Write(Unk1);
pkt.WriteMagic(Missions.Count, 0xC691, 0x47);
foreach (var mission in Missions) {pkt.WriteStruct(mission);}
pkt.Write(DailyUpdate);
pkt.Write(WeeklyUpdate);
pkt.Write(TierUpdate);
return pkt.ToArray();
}
public override PacketHeader GetHeader()
{
return new PacketHeader(0x4A, 0x01, PacketFlags.None);
return new PacketHeader(0x4A, 0x01, PacketFlags.PACKED);
}
#endregion

View File

@ -8,35 +8,43 @@ namespace PSO2SERVER.Protocol.Packets
{
public class Unk4A03Packet : Packet
{
public struct Unk4A03Packet_t
{
public uint Unk1; // 对应 Rust 的 u32
public List<Mission> Unk2; // 使用 List 替代 Vec
public List<uint> Unk3; // 使用 List 替代 Vec
public List<Unk2Struct> Unk4; // 使用 List 替代 Vec
public uint Unk5; // 对应 Rust 的 u32
}
public uint Unk1; // 对应 Rust 的 u32
public List<Mission> Unk2; // 使用 List 替代 Vec
public List<uint> Unk3; // 使用 List 替代 Vec
public List<Unk2Struct> Unk4; // 使用 List 替代 Vec
public uint Unk5; // 对应 Rust 的 u32
Unk4A03Packet_t pkt = new Unk4A03Packet_t();
public Unk4A03Packet(Mission mission, uint unk3, Unk2Struct unk4)
public Unk4A03Packet(uint unk1, List<Mission> unk2, List<uint> unk3, List<Unk2Struct> unk4, uint unk5)
{
pkt.Unk2.Add(mission);
pkt.Unk3.Add(unk3);
pkt.Unk4.Add(unk4);
Unk1 = unk1;
Unk2 = unk2;
Unk3 = unk3;
Unk4 = unk4;
Unk5 = unk5;
}
#region implemented abstract members of Packet
public override byte[] Build()
{
var writer = new PacketWriter();
return writer.ToArray();
var pkt = new PacketWriter();
pkt.Write(Unk1);
pkt.WriteMagic(Unk2.Count, 0xD20D, 0xDD);
foreach (var mission in Unk2) {pkt.WriteStruct(mission);}
pkt.WriteMagic(Unk3.Count, 0xD20D, 0xDD);
foreach (var unk3 in Unk3) { pkt.WriteStruct(unk3); }
pkt.WriteMagic(Unk4.Count, 0xD20D, 0xDD);
foreach (var unk2 in Unk4) { pkt.WriteStruct(unk2); }
pkt.Write(Unk5);
return pkt.ToArray();
}
public override PacketHeader GetHeader()
{
return new PacketHeader(0x4A, 0x03, PacketFlags.None);
return new PacketHeader(0x4A, 0x03, PacketFlags.PACKED);
}
#endregion

View File

@ -339,6 +339,7 @@
<Compile Include="Protocol\Handlers\04-ObjectHandler\04-75-ActionEnd.cs" />
<Compile Include="Protocol\Handlers\06-PlayerStatusHandler\06-01-DealDamage.cs" />
<Compile Include="Protocol\Handlers\0B-QuestHandler\0B-20-AcceptQuest.cs" />
<Compile Include="Protocol\Handlers\0F-ItemHandler\0F-01-ItemPickupRequest.cs" />
<Compile Include="Protocol\Handlers\0F-ItemHandler\0F-E0-MoveToMatStorageRequest.cs" />
<Compile Include="Protocol\Handlers\0F-ItemHandler\0F-28-UNK.cs" />
<Compile Include="Protocol\Handlers\11-ClientHandler\11-14-BlockLogin.cs" />
@ -413,11 +414,15 @@
<Compile Include="Protocol\Handlers\34-UNK\34-72-UNK.cs" />
<Compile Include="Protocol\Handlers\48-UNK\48-16-UNK4816.cs" />
<Compile Include="Protocol\Handlers\49-UNK\49-00-UNK4900.cs" />
<Compile Include="Protocol\Handlers\4A-ARKSMisionsHandler\4A-0C-SetTrackedMission.cs" />
<Compile Include="Protocol\Handlers\4A-ARKSMisionsHandler\4A-00-MissionListRequest.cs" />
<Compile Include="Protocol\Handlers\4D-ClassicMissionPassHandler\4D-02-MissionPassRequest.cs" />
<Compile Include="Protocol\Handlers\4D-ClassicMissionPassHandler\4D-00-MissionPassInfoRequest.cs" />
<Compile Include="Protocol\Packets\04-ObjectRelatedPacket\04-75-ActionEndPacket.cs" />
<Compile Include="Protocol\Packets\0B-QuestPacket\0B-1B-QuestCategoryStopperPacket.cs" />
<Compile Include="Protocol\Packets\0F-ItemPacket\00 - 复制.cs" />
<Compile Include="Protocol\Packets\0F-ItemPacket\0F-00-ItemAttributesPacket.cs" />
<Compile Include="Protocol\Packets\0F-ItemPacket\0F-02-ItemPickupResponsePacket.cs" />
<Compile Include="Protocol\Packets\0F-ItemPacket\0F-BC-ChangeWeaponPalettePacket.cs" />
<Compile Include="Protocol\Packets\0F-ItemPacket\0F-DF-LoadMaterialStoragePacket.cs" />
<Compile Include="Protocol\Packets\0F-ItemPacket\0F-E1-MoveToMatStoragePacket.cs" />