using System; using System.Diagnostics.Eventing.Reader; using System.Runtime.InteropServices; using Newtonsoft.Json; using PSO2SERVER.Json; using PSO2SERVER.Protocol; using PSO2SERVER.Protocol.Handlers; using PSO2SERVER.Protocol.Packets; namespace PSO2SERVER.Models { public class QuestDef { /// /// 任务日期 /// [JsonProperty("date")] [JsonConverter(typeof(AsciiStringConverter))] public string Date { get; set; } = new string(' ', 32); // 0x20 length string /// /// 任务对象 /// [JsonProperty("quest_obj")] public ObjectHeader QuestObj; /// /// 任务名称的ID /// [JsonProperty("name_id")] public uint NameId; /// /// 未知字段3(数组大小为27) /// [JsonProperty("unk3")] public uint[] Unk3 = new uint[27]; /// /// 未知字段4 /// [JsonProperty("unk4")] public ushort Unk4; /// /// 未知字段5 /// [JsonProperty("unk5")] public byte Unk5; /// /// 未知字段6 /// [JsonProperty("unk6")] public byte Unk6; /// /// 未知字段7(数组大小为20) /// [JsonProperty("unk7")] public uint[] Unk7 = new uint[20]; /// /// 未知字段8(数组大小为3) /// [JsonProperty("unk8")] public ushort[] Unk8 = new ushort[3]; /// /// 任务时长 /// [JsonProperty("length")] public byte Length; /// /// 任务的队伍类型 /// [JsonProperty("party_type")] [JsonConverter(typeof(QuestPartyTypeConverter))] public QuestPartyType PartyType; /// /// 可用的难度 /// [JsonProperty("difficulties")] public QuestDifficultyType Difficulties; /// /// 已完成的难度 /// [JsonProperty("difficulties_completed")] public QuestDifficultyType DifficultiesCompleted; /// /// 未知字段9 /// [JsonProperty("unk9")] public byte Unk9; /// /// 所需等级 /// [JsonProperty("req_level")] public byte ReqLevel; /// /// 所需副职业等级 /// [JsonProperty("sub_class_req_level")] public byte SubClassReqLevel; /// /// 敌人等级 /// [JsonProperty("enemy_level")] public byte EnemyLevel; /// /// 未知字段10 /// [JsonProperty("unk10")] public byte Unk10; /// /// 任务类型 /// [JsonProperty("quest_type")] public QuestType QuestType; /// /// 未知字段11(数组大小为6) /// [JsonProperty("unk11")] public byte[] Unk11 = new byte[6]; /// /// 未知字段12 /// [JsonProperty("unk12")] public ushort Unk12; /// /// 未知字段13(数组大小为2) /// [JsonProperty("unk13")] public uint[] Unk13 = new uint[2]; /// /// 未知字段14 /// [JsonProperty("unk14")] public ushort Unk14; /// /// 未知字段15(数组大小为2) /// [JsonProperty("unk15")] public byte[] Unk15 = new byte[2]; // 任务相关的其他字段 // public QuestThing[] Unk15 = new QuestThing[16]; /// /// 未知字段16(大小为0x320字节) /// [JsonProperty("unk16")] public byte[] Unk16 = new byte[0x320]; // 从数据流中读取数据并填充到当前结构体 public void ReadFromStream(PacketReader reader) { //TODO } // 将当前结构体的数据写入到数据流 public void WriteToStream(PacketWriter pkt) { pkt.WriteFixedLengthASCII(Date, 0x20); pkt.WriteObjectHeader(QuestObj); pkt.Write(NameId); pkt.WriteIntArray(Unk3); pkt.Write(Unk4); pkt.Write(Unk5); pkt.Write(Unk6); pkt.WriteIntArray(Unk7); pkt.WriteShortArray(Unk8); pkt.Write(Length); pkt.Write((byte)PartyType); pkt.Write((byte)Difficulties); pkt.Write((byte)DifficultiesCompleted); pkt.Write(Unk9); pkt.Write(ReqLevel); pkt.Write(SubClassReqLevel); pkt.Write(EnemyLevel); pkt.Write(Unk10); pkt.Write((byte)QuestType); pkt.Write(Unk11); pkt.Write(Unk12); pkt.WriteIntArray(Unk13); pkt.Write(Unk14); pkt.Write(Unk15); pkt.Write(Unk16); } } public class QuestDiff { /// /// PartyQuest date. /// [JsonProperty("date")] [JsonConverter(typeof(AsciiStringConverter))] public string Date { get; set; } = new string(' ', 32); // 0x20 length string /// /// PartyQuest object. /// [JsonProperty("quest_obj")] public ObjectHeader QuestObj { get; set; } /// /// ID of the quest name. /// [JsonProperty("name_id")] public uint NameId { get; set; } /// /// Planet ID. /// [JsonProperty("planet")] public byte Planet { get; set; } /// /// Area ID. /// [JsonProperty("area")] public byte Area { get; set; } /// /// Unknown field. /// [JsonProperty("unk1")] public byte Unk1 { get; set; } /// /// Unknown field. /// [JsonProperty("unk2")] public byte Unk2 { get; set; } /// /// Difficulty list. /// [JsonProperty("diffs")] public QuestDifficultyEntry[] Diffs { get; set; } = new QuestDifficultyEntry[8]; // 从数据流中读取数据并填充到当前结构体 public void ReadFromStream(PacketReader reader) { //TODO } // 将当前结构体的数据写入到数据流 public void WriteToStream(PacketWriter pkt) { pkt.WriteFixedLengthASCII(Date, 0x20); pkt.WriteObjectHeader(QuestObj); pkt.Write(NameId); pkt.Write(Planet); pkt.Write(Area); pkt.Write(Unk1); pkt.Write(Unk2); pkt.WriteStructArray(Diffs); } } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public unsafe struct QuestDefiniton { [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string dateOrSomething; public ObjectHeader quest_obj; public uint questNameid; //27个uint public uint field_30; public uint field_34; public uint field_38; public uint field_3C; public uint field_40; public uint field_44; public uint field_48; public uint field_4C; public uint field_50; public uint field_54; public uint field_58; public uint field_5C; public uint field_60; public uint field_64; public uint field_68; public uint field_6C; public uint field_70; public uint field_74; public uint field_78; public uint field_7C; public uint field_80; public uint field_84; public uint field_88; public uint field_8C; public uint field_90; public uint field_94; public uint field_98; public UInt16 field_9C; public byte field_9E; public byte field_9F; //20个uint public uint field_A0; public uint field_A4; public uint field_A8; public uint field_AC; public uint field_B0; public uint field_B4; public uint field_B8; public uint field_BC; public uint field_C0; public uint field_C4; public uint field_C8; public uint field_CC; public uint field_D0; public uint field_D4; public uint field_D8; public uint field_DC; public uint field_E0; public uint field_E4; public uint field_E8; // Maybe a flags public uint field_EC; public ushort field_F0; public ushort field_F2; public QuestBitfield1 questBitfield1; /// Length of the quest. public QuestEstimatedTime playTime; /// Party type of the quest. public QuestPartyType partyType; /// Available difficulties. public QuestDifficultyType difficulties; /// Completed difficulties. public QuestDifficultyType difficultiesCompleted; public byte field_FA; /// Required level. public byte req_level; /// Required sub level. public byte sub_class_req_level; /// Enemy level. public byte enemy_level; public byte field_FE; /// Type of the quest. public QuestType quest_type; public byte field_100; public byte field_101; public byte field_102; public byte field_103; public byte field_104; public byte field_105; public ushort field_106; public uint field_108; public uint field_10C; public ushort field_110; public byte field_112; public byte field_113; public fixed byte field_114[0x320]; } public class PartyQuest { public int seed { get; set; } public string name { get; set; } public QuestDefiniton questDef { get; set; } public QuestData Quest { get; set; } public ushort Diff { get; set; } = 0; public PartyQuest() { } public PartyQuest(string name) { this.name = name; } public PartyQuest(string name, QuestData quest) { this.name = name; Quest = quest; } } public struct QuestThing { public uint field_0; public uint field_4; public byte field_8; public byte field_9; public ushort field_A; } //Size: 308 bytes, confirmed in unpacker [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public unsafe struct QuestDifficulty { [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 24)] public string dateOrSomething; public ObjectHeader quest_obj; public uint name_id; public byte area; public byte planet; public byte unk1; public byte unk2; public QuestDifficultyEntry difficulty1; public QuestDifficultyEntry difficulty2; public QuestDifficultyEntry difficulty3; public QuestDifficultyEntry difficulty4; public QuestDifficultyEntry difficulty5; public QuestDifficultyEntry difficulty6; public QuestDifficultyEntry difficulty7; public QuestDifficultyEntry difficulty8; } //Size: 32, confirmed in ctor TODO public struct QuestDifficultyEntry { public byte ReqLevel; public byte SubClassReqLevel; public byte MonsterLevel; public byte Unk1; public uint AbilityAdj; public uint DmgLimit; public uint TimeLimit; public uint TimeLimit2; public uint SuppTarget; public uint Unk2; public uint Enemy1; public uint Unk3; public uint Enemy2; public uint Unk4; } }