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;
}
}