PSO2SERVER/Server/Models/PartyQuest.cs
2024-12-11 20:47:36 +08:00

460 lines
12 KiB
C#
Raw Permalink 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 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
{
/// <summary>
/// 任务日期
/// </summary>
[JsonProperty("date")]
[JsonConverter(typeof(AsciiStringConverter))]
public string Date { get; set; } = new string(' ', 32); // 0x20 length string
/// <summary>
/// 任务对象
/// </summary>
[JsonProperty("quest_obj")]
public ObjectHeader QuestObj;
/// <summary>
/// 任务名称的ID
/// </summary>
[JsonProperty("name_id")]
public uint NameId;
/// <summary>
/// 未知字段3数组大小为27
/// </summary>
[JsonProperty("unk3")]
public uint[] Unk3 = new uint[27];
/// <summary>
/// 未知字段4
/// </summary>
[JsonProperty("unk4")]
public ushort Unk4;
/// <summary>
/// 未知字段5
/// </summary>
[JsonProperty("unk5")]
public byte Unk5;
/// <summary>
/// 未知字段6
/// </summary>
[JsonProperty("unk6")]
public byte Unk6;
/// <summary>
/// 未知字段7数组大小为20
/// </summary>
[JsonProperty("unk7")]
public uint[] Unk7 = new uint[20];
/// <summary>
/// 未知字段8数组大小为3
/// </summary>
[JsonProperty("unk8")]
public ushort[] Unk8 = new ushort[3];
/// <summary>
/// 任务时长
/// </summary>
[JsonProperty("length")]
public byte Length;
/// <summary>
/// 任务的队伍类型
/// </summary>
[JsonProperty("party_type")]
[JsonConverter(typeof(QuestPartyTypeConverter))]
public QuestPartyType PartyType;
/// <summary>
/// 可用的难度
/// </summary>
[JsonProperty("difficulties")]
public QuestDifficultyType Difficulties;
/// <summary>
/// 已完成的难度
/// </summary>
[JsonProperty("difficulties_completed")]
public QuestDifficultyType DifficultiesCompleted;
/// <summary>
/// 未知字段9
/// </summary>
[JsonProperty("unk9")]
public byte Unk9;
/// <summary>
/// 所需等级
/// </summary>
[JsonProperty("req_level")]
public byte ReqLevel;
/// <summary>
/// 所需副职业等级
/// </summary>
[JsonProperty("sub_class_req_level")]
public byte SubClassReqLevel;
/// <summary>
/// 敌人等级
/// </summary>
[JsonProperty("enemy_level")]
public byte EnemyLevel;
/// <summary>
/// 未知字段10
/// </summary>
[JsonProperty("unk10")]
public byte Unk10;
/// <summary>
/// 任务类型
/// </summary>
[JsonProperty("quest_type")]
public QuestType QuestType;
/// <summary>
/// 未知字段11数组大小为6
/// </summary>
[JsonProperty("unk11")]
public byte[] Unk11 = new byte[6];
/// <summary>
/// 未知字段12
/// </summary>
[JsonProperty("unk12")]
public ushort Unk12;
/// <summary>
/// 未知字段13数组大小为2
/// </summary>
[JsonProperty("unk13")]
public uint[] Unk13 = new uint[2];
/// <summary>
/// 未知字段14
/// </summary>
[JsonProperty("unk14")]
public ushort Unk14;
/// <summary>
/// 未知字段15数组大小为2
/// </summary>
[JsonProperty("unk15")]
public byte[] Unk15 = new byte[2];
// 任务相关的其他字段
// public QuestThing[] Unk15 = new QuestThing[16];
/// <summary>
/// 未知字段16大小为0x320字节
/// </summary>
[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
{
/// <summary>
/// PartyQuest date.
/// </summary>
[JsonProperty("date")]
[JsonConverter(typeof(AsciiStringConverter))]
public string Date { get; set; } = new string(' ', 32); // 0x20 length string
/// <summary>
/// PartyQuest object.
/// </summary>
[JsonProperty("quest_obj")]
public ObjectHeader QuestObj { get; set; }
/// <summary>
/// ID of the quest name.
/// </summary>
[JsonProperty("name_id")]
public uint NameId { get; set; }
/// <summary>
/// Planet ID.
/// </summary>
[JsonProperty("planet")]
public byte Planet { get; set; }
/// <summary>
/// Area ID.
/// </summary>
[JsonProperty("area")]
public byte Area { get; set; }
/// <summary>
/// Unknown field.
/// </summary>
[JsonProperty("unk1")]
public byte Unk1 { get; set; }
/// <summary>
/// Unknown field.
/// </summary>
[JsonProperty("unk2")]
public byte Unk2 { get; set; }
/// <summary>
/// Difficulty list.
/// </summary>
[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;
}
}