继续修正任务载入

This commit is contained in:
Sancaros 2024-12-06 03:42:25 +08:00
parent 7373d98228
commit ecc9ebe098
19 changed files with 946 additions and 493 deletions

View File

@ -6,220 +6,298 @@ namespace PSO2SERVER.Models
{
public enum QuestType : byte
{
Unk0 = 0,
Extreme = 1,
ARKS = 3,
LimitedTime = 4,
ExtremeDebug = 5,
Blank1 = 6,
NetCafe = 8,
WarmingDebug = 9,
Blank2 = 10,
Advance = 11,
Expedition = 12,
FreeDebug = 13,
ArksDebug = 14,
Challenge = 16,
Urgent = 17,
UrgentDebug = 18,
TimeAttack = 19,
TimeDebug = 20,
ArksDebug2 = 21,
ArksDebug3 = 22,
ArksDebug4 = 23,
ArksDebug5 = 24,
ArksDebug6 = 25,
ArksDebug7 = 26,
ArksDebug8 = 27,
ArksDebug9 = 28,
ArksDebug10 = 29,
Blank3 = 30,
Recommended = 32,
Ultimate = 33,
UltimateDebug = 34,
AGP = 35,
Bonus = 36,
StandardTraining = 37,
HunterTraining = 38,
RangerTraining = 39,
ForceTraining = 40,
FighterTraining = 41,
GunnerTraining = 42,
TechterTraining = 43,
BraverTraining = 44,
BouncerTraining = 45,
SummonerTraining = 46,
AutoAccept = 47,
Ridroid = 48,
CafeAGP = 49,
BattleBroken = 50,
BusterDebug = 51,
Poka12 = 52,
StoryEP1 = 55,
Buster = 56,
HeroTraining = 57,
Amplified = 58,
DarkBlastTraining = 61,
Endless = 62,
Blank4 = 64,
PhantomTraining = 65,
AISTraining = 66,
DamageCalculation = 68,
EtoileTraining = 69,
Divide = 70,
Stars1 = 71,
Stars2 = 72,
Stars3 = 73,
Stars4 = 74,
Stars5 = 75,
Stars6 = 76,
Unk0 = 0, // 0x00
Extreme = 1, // 0x01
ARKS = 3, // 0x03
LimitedTime = 4, // 0x04
ExtremeDebug = 5, // 0x05
Blank1 = 6, // 0x06
NetCafe = 8, // 0x08
WarmingDebug = 9, // 0x09
Blank2 = 10, // 0x0A
Advance = 11, // 0x0B
Expedition = 12, // 0x0C
FreeDebug = 13, // 0x0D
ArksDebug = 14, // 0x0E
Challenge = 16, // 0x10
Urgent = 17, // 0x11
UrgentDebug = 18, // 0x12
TimeAttack = 19, // 0x13
TimeDebug = 20, // 0x14
ArksDebug2 = 21, // 0x15
ArksDebug3 = 22, // 0x16
ArksDebug4 = 23, // 0x17
ArksDebug5 = 24, // 0x18
ArksDebug6 = 25, // 0x19
ArksDebug7 = 26, // 0x1A
ArksDebug8 = 27, // 0x1B
ArksDebug9 = 28, // 0x1C
ArksDebug10 = 29, // 0x1D
Blank3 = 30, // 0x1E
Recommended = 32, // 0x20
Ultimate = 33, // 0x21
UltimateDebug = 34, // 0x22
AGP = 35, // 0x23
Bonus = 36, // 0x24
StandardTraining = 37,// 0x25
HunterTraining = 38, // 0x26
RangerTraining = 39, // 0x27
ForceTraining = 40, // 0x28
FighterTraining = 41, // 0x29
GunnerTraining = 42, // 0x2A
TechterTraining = 43, // 0x2B
BraverTraining = 44, // 0x2C
BouncerTraining = 45, // 0x2D
SummonerTraining = 46,// 0x2E
AutoAccept = 47, // 0x2F
Ridroid = 48, // 0x30
CafeAGP = 49, // 0x31
BattleBroken = 50, // 0x32
BusterDebug = 51, // 0x33
Poka12 = 52, // 0x34
StoryEP1 = 55, // 0x37
Buster = 56, // 0x38
HeroTraining = 57, // 0x39
Amplified = 58, // 0x3A
DarkBlastTraining = 61,// 0x3D
Endless = 62, // 0x3E
Blank4 = 64, // 0x40
PhantomTraining = 65, // 0x41
AISTraining = 66, // 0x42
DamageCalculation = 68,// 0x44
EtoileTraining = 69, // 0x45
Divide = 70, // 0x46
Stars1 = 71, // 0x47
Stars2 = 72, // 0x48
Stars3 = 73, // 0x49
Stars4 = 74, // 0x4A
Stars5 = 75, // 0x4B
Stars6 = 76, // 0x4C
}
[Flags]
public enum QuestTypeAvailable : UInt64
public enum AvailableQuestType : ulong
{
None = 0x0000000000000000,
All = 0xFFFFFFFFFFFFFFFF,
Extreme = 0x0000000000000002,
StoryEP1 = 0x0000000000000004,
Arks = 0x0000000000000008,
Limited = 0x0000000000000010,
ExtremeDebug = 0x0000000000000020,
Blank1 = 0x0000000000000040,
StoryEP2 = 0x0000000000000080,
NetCafeLimited = 0x0000000000000100,
Debug = 0x0000000000000200,
Blank2 = 0x0000000000000400,
Advance = 0x0000000000000800,
FreeField = 0x0000000000001000,
FreeDebug = 0x0000000000002000,
ArksDebug1 = 0x0000000000004000,
StoryDebug = 0x0000000000008000,
Challange = 0x0000010000010000,
Emergency = 0x0000020000020000,
EmergencyDebug = 0x0000040000040000,
TimeAttack = 0x0000080000080000,
TimeDebug = 0x0000000000100000,
ArksDebug2 = 0x0000000000200000,
ArksDebug3 = 0x0000000000400000,
ArksDebug4 = 0x0000000000800000,
ArksDebug5 = 0x0000000001000000,
ArksDebug6 = 0x0000000002000000,
ArksDebug7 = 0x0000000004000000,
ArksDebug8 = 0x0000000008000000,
ArksDebug9 = 0x0000000010000000,
ArksDebug10 = 0x0000000020000000,
Blank3 = 0x0000000040000000,
StoryEP3 = 0x0000000080000000,
Featured = 0x0000000100000000,
Ultimate = 0x0000000200000000,
UltimateDebug = 0x0000000400000000,
NotSet = 0x0000000800000000,
EXTREME = 1UL << 1,
STORY_EP1 = 1UL << 2,
ARKS = 1UL << 3,
LIMITED_TIME = 1UL << 4,
EXTREME_DEBUG = 1UL << 5,
BLANK1 = 1UL << 6,
STORY_EP2 = 1UL << 7,
NET_CAFE = 1UL << 8,
WARMING_DEBUG = 1UL << 9,
BLANK2 = 1UL << 10,
ADVANCE = 1UL << 11,
EXPEDITION = 1UL << 12,
FREE_DEBUG = 1UL << 13,
ARKS_DEBUG = 1UL << 14,
STORY_DEBUG = 1UL << 15,
CHALLENGE = 1UL << 16,
URGENT = 1UL << 17,
URGENT_DEBUG = 1UL << 18,
TIME_ATTACK = 1UL << 19,
TIME_DEBUG = 1UL << 20,
ARKS_DEBUG2 = 1UL << 21,
ARKS_DEBUG3 = 1UL << 22,
ARKS_DEBUG4 = 1UL << 23,
ARKS_DEBUG5 = 1UL << 24,
ARKS_DEBUG6 = 1UL << 25,
ARKS_DEBUG7 = 1UL << 26,
ARKS_DEBUG8 = 1UL << 27,
ARKS_DEBUG9 = 1UL << 28,
ARKS_DEBUG10 = 1UL << 29,
BLANK3 = 1UL << 30,
STORY_EP3 = 1UL << 31,
RECOMMENDED = 1UL << 32,
ULTIMATE = 1UL << 33,
ULTIMATE_DEBUG = 1UL << 34,
AGP = 1UL << 35,
BONUS = 1UL << 36,
UNK1 = 1UL << 37,
STANDARD_TRAINING = 1UL << 38,
HUNTER_TRAINING = 1UL << 39,
RANGER_TRAINING = 1UL << 40,
FORCE_TRAINING = 1UL << 41,
FIGHTER_TRAINING = 1UL << 42,
GUNNER_TRAINING = 1UL << 43,
TECHTER_TRAINING = 1UL << 44,
BRAVER_TRAINING = 1UL << 45,
BOUNCER_TRAINING = 1UL << 46,
SUMMONER_TRAINING = 1UL << 47,
AUTO_ACCEPT = 1UL << 48,
RIDROID = 1UL << 49,
NET_CAFE_AGP = 1UL << 50,
BATTLE_BROKEN = 1UL << 51,
BUSTER_DEBUG = 1UL << 52,
POKA12 = 1UL << 53,
UNK2 = 1UL << 54,
UNK3 = 1UL << 55,
BUSTER = 1UL << 56,
HERO_TRAINING = 1UL << 57,
AMPLIFIED = 1UL << 58,
UNK4 = 1UL << 59,
UNK5 = 1UL << 60,
DARK_BLAST_TRAINING = 1UL << 61,
ENDLESS = 1UL << 62,
UNK6 = 1UL << 63,
BLANK4 = 1UL << 64,
PHANTOM_TRAINING = 1UL << 65,
AIS_TRAINING = 1UL << 66,
UNK7 = 1UL << 67,
DAMAGE_CALC = 1UL << 68,
ETOILE_TRAINING = 1UL << 69,
DIVIDE = 1UL << 70,
STARS1 = 1UL << 71,
STARS2 = 1UL << 72,
STARS3 = 1UL << 73,
STARS4 = 1UL << 74,
STARS5 = 1UL << 75,
STARS6 = 1UL << 76,
UNK8 = 1UL << 77
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public unsafe struct QuestDefiniton
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32 - 8)]
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string dateOrSomething;
public int field_18;
public int field_1C;
public int needsToBeNonzero;
public int alsoGetsSetToDword;
public UInt16 getsSetToWord;
public UInt16 moreWordSetting;
public int questNameString;
public int field_30;
public int field_34;
public int field_38;
public int field_3C;
public int field_40;
public int field_44;
public int field_48;
public int field_4C;
public int field_50;
public int field_54;
public int field_58;
public int field_5C;
public int field_60;
public int field_64;
public int field_68;
public int field_6C;
public int field_70;
public int field_74;
public int field_78;
public int field_7C;
public int field_80;
public int field_84;
public int field_88;
public int field_8C;
public int field_90;
public int field_94;
public int field_98;
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;
public int field_A0;
public int field_A4;
public int field_A8;
public int field_AC;
public int field_B0;
public int field_B4;
public int field_B8;
public int field_BC;
public int field_C0;
public int field_C4;
public int field_C8;
public int field_CC;
public int field_D0;
public int field_D4;
public int field_D8;
public int field_DC;
public int field_E0;
public int field_E4;
public int field_E8; // Maybe a flags
public int field_EC;
public UInt16 field_F0;
public UInt16 field_F2;
public UInt16 questBitfield1;
public byte playTime;
public byte partyType;
public byte difficulties;
public byte difficultiesCompleted;
//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;
public byte field_FB;
public byte requiredLevel;
public byte field_FD;
/// 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;
public byte field_FF;
/// 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 UInt16 field_106;
public int field_108;
public int field_10C;
public short field_110;
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 QuestDefThing field_114_1;
public QuestDefThing field_114_2;
public QuestDefThing field_114_3;
public QuestDefThing field_114_4;
public QuestDefThing field_114_5;
public QuestDefThing field_114_6;
public QuestDefThing field_114_7;
public QuestDefThing field_114_8;
public QuestDefThing field_114_9;
public QuestDefThing field_114_10;
public QuestDefThing field_114_11;
public QuestDefThing field_114_12;
public QuestDefThing field_114_13;
public QuestDefThing field_114_14;
public QuestDefThing field_114_15;
public QuestDefThing field_114_16;
//public QuestThing field_114_1;
//public QuestThing field_114_2;
//public QuestThing field_114_3;
//public QuestThing field_114_4;
//public QuestThing field_114_5;
//public QuestThing field_114_6;
//public QuestThing field_114_7;
//public QuestThing field_114_8;
//public QuestThing field_114_9;
//public QuestThing field_114_10;
//public QuestThing field_114_11;
//public QuestThing field_114_12;
//public QuestThing field_114_13;
//public QuestThing field_114_14;
//public QuestThing field_114_15;
//public QuestThing field_114_16;
public fixed byte field_114[0x320];
}
public enum QuestEstimatedTime : byte
{
Short = 1,
Medium,
Long
}
public class Quest
@ -235,12 +313,85 @@ namespace PSO2SERVER.Models
}
}
public struct QuestDefThing
public struct QuestThing
{
public int field_0;
public int field_4;
public uint field_0;
public uint field_4;
public byte field_8;
public byte field_9;
public UInt16 field_A;
public ushort field_A;
}
[Flags]
public enum QuestDifficultyType : byte
{
NORMAL = 1 << 0, // 1 0x01 (0000 0001)
HARD = 1 << 1, // 2 0x02 (0000 0010)
VERY_HARD = 1 << 2, // 4 0x04 (0000 0100)
SUPER_HARD = 1 << 3, // 8 0x08 (0000 1000)
EX_HARD = 1 << 4, // 16 0x10 (0001 0000)
ULTRA_HARD = 1 << 5, // 32 0x20 (0010 0000)
Dummy2 = 1 << 6, // 64 0x40 (0100 0000)
Dummy3 = 1 << 7 // 128 0x80 (1000 0000)
}
public enum QuestPartyType : byte
{
SoloQuest,
/// Only one party can join (up to 4 players).
SinglePartyQuest,
/// Multiple parties can join (up to 12 players).
MultiPartyQuest,
}
[Flags]
public enum QuestBitfield1 : ushort
{
MatterObjectiveQuest = 0x0001,
ClientOrderOnQuest = 0x0008,
NewQuest = 0x0100,
ClientOrder = 0x0800,
UnknownLevel = 0x1000
}
//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;
}
}

View File

@ -76,6 +76,22 @@ namespace PSO2SERVER.Party
{
return members;
}
}
[Flags]
public enum PartyFlags : byte
{
/// Is the party only for friends.
FRIENDS_ONLY = 1 << 0, // 0x01
/// Is the party only for alliance members.
ALLIANCE_ONLY = 1 << 1, // 0x02
/// Limit multiplayer requests from other parties.
LIMIT_OTHERS = 1 << 2, // 0x04
/// Is the party only for a single run.
SINGLE_RUN = 1 << 3, // 0x08
/// Is the party actively looking for members.
OPEN = 1 << 4, // 0x10
/// Is the party voice chat focused.
VC_FOCUS = 1 << 6 // 0x40
}
}

View File

@ -0,0 +1,51 @@
using PSO2SERVER.Models;
using PSO2SERVER.Protocol.Packets;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace PSO2SERVER.Protocol.Handlers
{
[PacketHandlerAttr(0x0B, 0x17)]
public class QuestCategoryRequest : PacketHandler
{
public uint unk1 { get; set; }
public QuestType category { get; set; }
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);
unk1 = reader.ReadUInt32();
category = (QuestType)reader.ReadUInt32();
Logger.Write($"unk1 = {unk1} category = {category}");
// What am I doing
QuestDefiniton[] defs = new QuestDefiniton[1];
for (int i = 0; i < defs.Length; i++)
{
defs[i].dateOrSomething = "2012/01/05";
defs[i].quest_obj = new ObjectHeader(0x20, ObjectType.Quest);
defs[i].questNameid = 30010;
defs[i].playTime = QuestEstimatedTime.Short;
defs[i].partyType = QuestPartyType.SinglePartyQuest;
defs[i].difficulties = QuestDifficultyType.NORMAL | QuestDifficultyType.HARD | QuestDifficultyType.VERY_HARD | QuestDifficultyType.SUPER_HARD;
defs[i].req_level = 1;
// Not sure why but these need to be set for the quest to be enabled
defs[i].quest_type = (QuestType)0xF1;
defs[i].field_101 = 1;
}
context.SendPacket(new QuestCategoryPacket(defs));
context.SendPacket(new QuestCategoryStopperPacket());
}
}
}

View File

@ -1,38 +0,0 @@
using PSO2SERVER.Models;
using PSO2SERVER.Protocol.Packets;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PSO2SERVER.Protocol.Handlers
{
[PacketHandlerAttr(0xB, 0x17)]
public class QuestListRequestHandler : PacketHandler
{
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
{
// What am I doing
QuestDefiniton[] defs = new QuestDefiniton[1];
for (int i = 0; i < defs.Length; i++)
{
defs[i].dateOrSomething = "2012/01/05";
defs[i].needsToBeNonzero = 0x00000020;
defs[i].getsSetToWord = 0x0000000B;
defs[i].questNameString = 30010;
defs[i].playTime = (byte)QuestListPacket.EstimatedTime.Short;
defs[i].partyType = (byte)QuestListPacket.PartyType.SinglePartyQuest;
defs[i].difficulties = (byte)QuestListPacket.Difficulties.Normal | (byte)QuestListPacket.Difficulties.hard | (byte)QuestListPacket.Difficulties.VeryHard | (byte)QuestListPacket.Difficulties.SuperHard;
defs[i].requiredLevel = 1;
// Not sure why but these need to be set for the quest to be enabled
defs[i].field_FF = 0xF1;
defs[i].field_101 = 1;
}
context.SendPacket(new QuestListPacket(defs));
context.SendPacket(new NoPayloadPacket(0xB, 0x1B));
}
}
}

View File

@ -1,15 +1,7 @@
using Org.BouncyCastle.Bcpg;
using Org.BouncyCastle.Utilities.Encoders;
using PSO2SERVER.Models;
using PSO2SERVER.Protocol.Packets;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using static PSO2SERVER.Protocol.Handlers.CharacterSelected;
using static PSO2SERVER.Protocol.Packets.QuestDifficultyPacket;
namespace PSO2SERVER.Protocol.Handlers
{
@ -26,43 +18,50 @@ namespace PSO2SERVER.Protocol.Handlers
var reader = new PacketReader(data, position, size);
Quests = reader.ReadList<ObjectHeader>();
// 现在可以对任务列表Quests进行处理
// 例如,可以记录任务的信息或进行其他处理
foreach (var quest in Quests)
var questCount = reader.ReadMagic(0xA36E, 0x10);
for (uint i = 0; i < questCount; i++)
{
if(quest.ObjectType == ObjectType.Quest)
{
QuestDifficulty[] diffs = new QuestDifficulty[1];
for (int i = 0; i < diffs.Length; i++)
{
diffs[i].dateOrSomething = "2017/2/20";
diffs[i].quest_obj.ID = quest.ID;
diffs[i].quest_obj.padding = 0;
diffs[i].quest_obj.ObjectType = ObjectType.Quest;
diffs[i].name_id = 30010;
diffs[i].area = 0x01;
diffs[i].planet = 0x03;
diffs[i].unk1 = 0x03;
diffs[i].unk2 = 0x00;
diffs[i].difficulty1 = new QuestDifficultyEntry();
diffs[i].difficulty2 = new QuestDifficultyEntry();
diffs[i].difficulty3 = new QuestDifficultyEntry();
diffs[i].difficulty4 = new QuestDifficultyEntry();
diffs[i].difficulty5 = new QuestDifficultyEntry();
diffs[i].difficulty6 = new QuestDifficultyEntry();
diffs[i].difficulty7 = new QuestDifficultyEntry();
diffs[i].difficulty8 = new QuestDifficultyEntry();
}
// 打印每个任务的 ID 和类型,方便调试
Logger.Write($"任务 ID: {quest.ID}, 任务类型: {quest.ObjectType}");
context.SendPacket(new QuestDifficultyPacket(diffs));
}
var qobj = new ObjectHeader();
qobj.ReadFromStream(reader);
Quests.Add(qobj);
// 打印每个任务的 ID 和类型,方便调试
Logger.Write($"任务 ID: {qobj.ID}, 任务类型: {qobj.ObjectType}");
}
QuestDifficulty[] diffs = new QuestDifficulty[1];
for (int i = 0; i < diffs.Length; i++)
{
diffs[i].dateOrSomething = "2012/01/05";
diffs[i].quest_obj = new ObjectHeader(0x20, ObjectType.Quest);
diffs[i].name_id = 30010;
diffs[i].area = 0x01;
diffs[i].planet = 0x03;
diffs[i].unk1 = 0x03;
diffs[i].unk2 = 0x00;
diffs[i].difficulty1 = new QuestDifficultyEntry();
diffs[i].difficulty2 = new QuestDifficultyEntry();
diffs[i].difficulty3 = new QuestDifficultyEntry();
diffs[i].difficulty4 = new QuestDifficultyEntry();
diffs[i].difficulty5 = new QuestDifficultyEntry();
diffs[i].difficulty6 = new QuestDifficultyEntry();
diffs[i].difficulty7 = new QuestDifficultyEntry();
diffs[i].difficulty8 = new QuestDifficultyEntry();
}
context.SendPacket(new QuestDifficultyPacket(diffs));
// [K873] I believe this is the correct packet, but it causes an infinite send/recieve loop, we're probably just missing something else
context.SendPacket(new QuestDifficultySendFinishedPacket());
//// 现在可以对任务列表Quests进行处理
//// 例如,可以记录任务的信息或进行其他处理
//foreach (var quest in Quests)
//{
// if(quest.ObjectType == ObjectType.Quest)
// {
// }
//}
}
}

View File

@ -12,7 +12,7 @@ namespace PSO2SERVER.Protocol.Handlers
{
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
{
// Not sure what this does yet
//Not sure what this does yet
context.SendPacket(new Unk4901Packet());
context.SendPacket(new Unk0E65Packet());
context.SendPacket(new Unk0B22Packet());

View File

@ -1,54 +1,83 @@
using System;
using PSO2SERVER.Models;
using PSO2SERVER.Protocol.Packets;
using PSO2SERVER.Party;
namespace PSO2SERVER.Protocol.Handlers
{
[PacketHandlerAttr(0x0E, 0x0C)]
public class QuestDifficultyStartHandler : PacketHandler
{
public string name { get; set; }
public string password { get; set; }
public string comments { get; set; }
public string questname { get; set; }
public byte min_level { get; set; }
public byte max_level { get; set; }
public byte playstyle { get; set; }
public PartyFlags partyFlags { get; set; }
public ulong unk { get; set; }
// Go go maximum code duplication (for now)
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
{
var reader = new PacketReader(data, position, size);
var info = string.Format("[<--] 接收到的数据 (hex): {0}字节", data.Length);
Logger.WriteHex(info, data);
//QuestDefiniton def = new QuestDefiniton
//{
// dateOrSomething = "2024/09/21",
// needsToBeNonzero = 0x00000020,
// getsSetToWord = 0x0000000B,
// questNameString = 30010,
// playTime = (byte)QuestListPacket.EstimatedTime.Short,
// partyType = (byte)QuestListPacket.PartyType.SinglePartyQuest,
// difficulties = (byte)QuestListPacket.Difficulties.Normal | (byte)QuestListPacket.Difficulties.hard | (byte)QuestListPacket.Difficulties.VeryHard | (byte)QuestListPacket.Difficulties.SuperHard,
// requiredLevel = 1,
// // Not sure why but these need to be set for the quest to be enabled
// field_FF = 0xF1,
// field_101 = 1
//};
var reader = new PacketReader(data, position, size);
name = reader.ReadUtf16(0x11CB, 0x98);
password = reader.ReadUtf16(0x11CB, 0x98);
comments = reader.ReadUtf16(0x11CB, 0x98);
questname = reader.ReadUtf16(0x11CB, 0x98);
min_level = reader.ReadByte();
max_level = reader.ReadByte();
playstyle = reader.ReadByte();
partyFlags = (PartyFlags)reader.ReadByte();
unk = reader.ReadUInt64();
// 打印输出
Logger.Write($"Name: {name}");
Logger.Write($"Password: {password}");
Logger.Write($"Comments: {comments}");
Logger.Write($"Quest Name: {questname}");
Logger.Write($"Min Level: {min_level}");
Logger.Write($"Max Level: {max_level}");
Logger.Write($"Playstyle: {playstyle}");
Logger.Write($"Party Flags: {partyFlags}"); // 如果 PartyFlags 是枚举类型
Logger.Write($"Unknown Value: {unk}");
//QuestDifficultyPacket.QuestDifficulty diff = new QuestDifficultyPacket.QuestDifficulty
//{
// dateOrSomething = "2024/09/21",
// something = 0x20,
// something2 = 0x0B,
// questNameString = 30010,
QuestDefiniton def = new QuestDefiniton
{
dateOrSomething = "2012/01/05",
quest_obj = new ObjectHeader(0x20, ObjectType.Quest),
questNameid = 30010,
playTime = QuestEstimatedTime.Short,
partyType = QuestPartyType.SinglePartyQuest,
difficulties = QuestDifficultyType.NORMAL | QuestDifficultyType.HARD | QuestDifficultyType.VERY_HARD | QuestDifficultyType.SUPER_HARD,
sub_class_req_level = 1,
// Not sure why but these need to be set for the quest to be enabled
quest_type = (QuestType)0xF1,
field_101 = 1
};
// // These are likely bitfields
// something3 = 0x00030301
//};
QuestDifficulty diff = new QuestDifficulty
{
dateOrSomething = "2012/01/05",
quest_obj = new ObjectHeader(0x20, ObjectType.Quest),
name_id = 30010,
// These are likely bitfields
area = 0x01,
planet = 0x03,
unk1 = 0x03,
unk2 = 0x00
};
var quest = new Quest("arks_010120")
{
questDef = def
};
context.currentParty.currentQuest = quest;
context.SendPacket(new SetQuestInfoPacket(def, context._account.AccountId));
context.SendPacket(new PartySetQuestPacket(0x753A, 0, def, diff, new ObjectHeader((uint)context._account.AccountId, ObjectType.Player)));
//var quest = new Quest("arks_010120")
//{
// questDef = def
//};
//context.currentParty.currentQuest = quest;
//context.SendPacket(new SetQuestInfoPacket(def, context._account.AccountId));
//context.SendPacket(new QuestStartPacket(def, diff));
}
}
}

View File

@ -81,17 +81,6 @@ namespace PSO2SERVER.Protocol
}
}
internal void WritePosition(PSOLocation location)
{
Write(Helper.FloatToHalfPrecision(location.RotX));
Write(Helper.FloatToHalfPrecision(location.RotY));
Write(Helper.FloatToHalfPrecision(location.RotZ));
Write(Helper.FloatToHalfPrecision(location.RotW));
Write(Helper.FloatToHalfPrecision(location.PosX));
Write(Helper.FloatToHalfPrecision(location.PosY));
Write(Helper.FloatToHalfPrecision(location.PosZ));
}
public void WriteUtf16(string str, uint xor, uint sub)
{
if ((str == null) || (str == "") || (str.Length == 0))
@ -151,6 +140,17 @@ namespace PSO2SERVER.Protocol
}
}
internal void WritePosition(PSOLocation location)
{
Write(Helper.FloatToHalfPrecision(location.RotX));
Write(Helper.FloatToHalfPrecision(location.RotY));
Write(Helper.FloatToHalfPrecision(location.RotZ));
Write(Helper.FloatToHalfPrecision(location.RotW));
Write(Helper.FloatToHalfPrecision(location.PosX));
Write(Helper.FloatToHalfPrecision(location.PosY));
Write(Helper.FloatToHalfPrecision(location.PosZ));
}
public void WriteAccountHeader(uint AccountId)
{
Write(AccountId);
@ -180,12 +180,111 @@ namespace PSO2SERVER.Protocol
return ms.ToArray();
}
internal void WriteBytes(byte b, uint count)
public void WriteBytes(byte b, uint count)
{
for(int i = 0; i < count; i++)
{
Write(b);
}
}
public void WriteByteArray(byte[] b)
{
Write(b);
}
public void WriteUintArray(uint[] array)
{
foreach (var item in array)
{
Write(item);
}
}
public void WriteIntArray(int[] array)
{
foreach (var item in array)
{
Write(item);
}
}
public void WriteFloatArray(float[] array)
{
foreach (var item in array)
{
Write(item);
}
}
public void WriteObjectHeader(ObjectHeader obj)
{
Write(obj.ID);
Write(obj.padding);
Write((ushort)obj.ObjectType);
Write(obj.MapID);
}
public void WriteObjectHeaderArray(ObjectHeader[] objlist)
{
foreach (var obj in objlist)
{
WriteObjectHeader(obj);
}
}
public void WriteObjectHeaderList(List<ObjectHeader> objlist)
{
foreach (var obj in objlist)
{
WriteObjectHeader(obj); // 直接写入每个 ObjectHeader 对象
}
}
// 支持 Guid 类型
public void WriteGuid(Guid guid)
{
Write(guid.ToByteArray());
}
// 支持 DateTime 类型
public void WriteDateTime(DateTime dateTime)
{
var timestamp = new DateTimeOffset(dateTime).ToUnixTimeSeconds();
Write(timestamp);
}
// 支持 List<T>
public void WriteList<T>(List<T> list) where T : struct
{
foreach (var item in list)
{
WriteStruct(item);
}
}
// 支持 2D 数组
public void Write2DIntArray(int[,] array)
{
for (int i = 0; i < array.GetLength(0); i++)
{
for (int j = 0; j < array.GetLength(1); j++)
{
Write(array[i, j]);
}
}
}
// 支持 2D 数组
public void Write2DUIntArray(uint[,] array)
{
for (int i = 0; i < array.GetLength(0); i++)
{
for (int j = 0; j < array.GetLength(1); j++)
{
Write(array[i, j]);
}
}
}
}
}

View File

@ -39,17 +39,17 @@ namespace PSO2SERVER.Protocol.Packets
public override byte[] Build()
{
PacketWriter output = new PacketWriter();
output.WriteStruct(new ObjectHeader((uint)_user_playerid, ObjectType.Player));
output.WriteStruct(_preformer);
output.Write(_preData);
output.WriteAscii(_command, 0x4315, 0x7A);
output.Write(_rest);
output.WriteMagic(_thingCount, 0x4315, 0x7A);
output.Write(_things);
output.Write(_final);
PacketWriter pkt = new PacketWriter();
pkt.WriteStruct(new ObjectHeader((uint)_user_playerid, ObjectType.Player));
pkt.WriteStruct(_preformer);
pkt.Write(_preData);
pkt.WriteAscii(_command, 0x4315, 0x7A);
pkt.Write(_rest);
pkt.WriteMagic(_thingCount, 0x4315, 0x7A);
pkt.Write(_things);
pkt.Write(_final);
return output.ToArray();
return pkt.ToArray();
}
public override PacketHeader GetHeader()

View File

@ -1,4 +1,5 @@
using PSO2SERVER.Models;
using Org.BouncyCastle.Utilities;
using PSO2SERVER.Models;
using System;
using System.Collections.Generic;
using System.Linq;
@ -8,9 +9,32 @@ namespace PSO2SERVER.Protocol.Packets
{
public class StartCutscenePacket : Packet
{
public string scene_name { get; set; }
public uint[] unk1 { get; set; } = new uint[9];
public List<ObjectHeader> unk2 { get; set; } = new List<ObjectHeader>();
public ulong unk3 { get; set; }
public uint unk4 { get; set; }
public byte unk5 { get; set; }
public byte unk6 { get; set; }
public byte unk7 { get; set; }
public string unk8 { get; set; }
public string unk9 { get; set; }
public uint unk10 { get; set; }
public ObjectHeader unk11 { get; set; }
public StartCutscenePacket()
public StartCutscenePacket(string scene_name, List<ObjectHeader> unk2, ulong unk3, uint unk4, byte unk5, byte unk6, byte unk7, string unk8, string unk9, uint unk10, ObjectHeader unk11)
{
this.scene_name = scene_name;
this.unk2 = unk2;
this.unk3 = unk3;
this.unk4 = unk4;
this.unk5 = unk5;
this.unk6 = unk6;
this.unk7 = unk7;
this.unk8 = unk8;
this.unk9 = unk9;
this.unk10 = unk10;
this.unk11 = unk11;
}
#region implemented abstract members of Packet
@ -18,6 +42,18 @@ namespace PSO2SERVER.Protocol.Packets
public override byte[] Build()
{
var pkt = new PacketWriter();
pkt.WriteAscii(scene_name, 0xB65A, 0x7D);
pkt.WriteUintArray(unk1);
pkt.WriteObjectHeaderList(unk2);
pkt.Write(unk3);
pkt.Write(unk4);
pkt.Write(unk5);
pkt.Write(unk6);
pkt.Write(unk7);
pkt.WriteAscii(unk8, 0xB65A, 0x7D);
pkt.WriteAscii(unk9, 0xB65A, 0x7D);
pkt.Write(unk10);
pkt.WriteObjectHeader(unk11);
return pkt.ToArray();
}

View File

@ -4,45 +4,220 @@ using System.Linq;
using System.Text;
using PSO2SERVER.Models;
using System.Runtime.InteropServices;
using System.IO;
namespace PSO2SERVER.Protocol.Packets
{
class QuestAvailablePacket : Packet
public class QuestAvailablePacket : Packet
{
public short[] amount = new short[Enum.GetValues(typeof(QuestType)).Length];
QuestTypeAvailable available = QuestTypeAvailable.Arks;
public ushort Unk1 { get; set; }
public ushort ExtremeCount { get; set; }
public ushort Unk2 { get; set; }
public ushort ArksCount { get; set; }
public ushort LimitedTimeCount { get; set; }
public ushort ExtremeDebugCount { get; set; }
public ushort Blank1Count { get; set; }
public ushort Unk3 { get; set; }
public ushort NetCafeCount { get; set; }
public ushort WarmingDebugCount { get; set; }
public ushort Blank2Count { get; set; }
public ushort AdvanceCount { get; set; }
public ushort ExpeditionCount { get; set; }
public ushort ExpeditionDebugCount { get; set; }
public ushort ArksDebugCount { get; set; }
public ushort Unk4Count { get; set; }
public ushort ChallengeCount { get; set; }
public ushort UrgentCount { get; set; }
public ushort UrgentDebugCount { get; set; }
public ushort TimeAttackCount { get; set; }
public ushort TimeAttackDebugCount { get; set; }
// Array of 9 ushort values (arks_debug2_count)
public ushort[] ArksDebug2Count { get; set; } = new ushort[9];
public ushort Blank3Count { get; set; }
public ushort Unk5 { get; set; }
public ushort RecommendedCount { get; set; }
public ushort Unk6 { get; set; }
public ushort UltimateDebugCount { get; set; }
public ushort AgpCount { get; set; }
public ushort BonusCount { get; set; }
public ushort Unk7 { get; set; }
// Array of 10 ushort values (training_count)
public ushort[] TrainingCount { get; set; } = new ushort[10];
public ushort TriggerCount { get; set; }
public ushort RidroidCount { get; set; }
public ushort NetCafeAgpCount { get; set; }
public ushort BattleBrokenCount { get; set; }
public ushort BusterDebugCount { get; set; }
public ushort Poka12Count { get; set; }
public ushort Unk8 { get; set; }
public ushort Unk9 { get; set; }
public ushort BusterCount { get; set; }
public ushort HeroTrainingCount { get; set; }
public ushort AmplifiedCount { get; set; }
public ushort Unk10 { get; set; }
public ushort Unk11 { get; set; }
public ushort DarkBlastTrainingCount { get; set; }
public ushort EndlessCount { get; set; }
public ushort Unk12 { get; set; }
public ushort Unk13 { get; set; }
public ushort PhantomTrainingCount { get; set; }
public ushort AisTrainingCount { get; set; }
public ushort Unk14 { get; set; }
public ushort DamageCalcCount { get; set; }
public ushort EtoileTrainingCount { get; set; }
public ushort DivideCount { get; set; }
// Unsure fields (stars1_count, stars2_count, stars3_count)
public ushort Stars1Count { get; set; }
public ushort Stars2Count { get; set; }
public ushort Stars3Count { get; set; }
// Array of 2 ushort values (unk15)
public ushort[] Unk15 { get; set; } = new ushort[2];
// NotOn attribute is specific to certain frameworks (e.g., Vita platform)
// You can use attributes like [Obsolete] in C# if needed
public ushort[] Unk16 { get; set; } = new ushort[2];
// AvailableQuestType values
public AvailableQuestType AvailableTypes { get; set; }
public AvailableQuestType Unk19 { get; set; }
// Round boost active flag
public uint RoundBoost { get; set; }
public uint Unk21 { get; set; }
// Constructor
public QuestAvailablePacket()
{
}
//public short[] amount = new short[Enum.GetValues(typeof(QuestType)).Length];
//AvailableQuestType available = AvailableQuestType.ARKS;
public override byte[] Build()
{
PacketWriter writer = new PacketWriter();
writer.Write(Unk1);
writer.Write(ExtremeCount);
writer.Write(Unk2);
writer.Write(ArksCount);
writer.Write(LimitedTimeCount);
writer.Write(ExtremeDebugCount);
writer.Write(Blank1Count);
writer.Write(Unk3);
writer.Write(NetCafeCount);
writer.Write(WarmingDebugCount);
writer.Write(Blank2Count);
writer.Write(AdvanceCount);
writer.Write(ExpeditionCount);
writer.Write(ExpeditionDebugCount);
writer.Write(ArksDebugCount);
writer.Write(Unk4Count);
writer.Write(ChallengeCount);
writer.Write(UrgentCount);
writer.Write(UrgentDebugCount);
writer.Write(TimeAttackCount);
writer.Write(TimeAttackDebugCount);
// Filler/Padding?
writer.Write((UInt16)0);
// Amounts
for (int i = 0; i < amount.Length; i++)
// 写入 ArksDebug2Count 数组
foreach (var count in ArksDebug2Count)
{
amount[i] = 1; // Just for testing
writer.Write(amount[i]);
writer.Write(count);
}
// Padding/Blank entries?
for (int i = 0; i < 2; i++)
writer.Write((int)0);
writer.Write(Blank3Count);
writer.Write(Unk5);
writer.Write(RecommendedCount);
writer.Write(Unk6);
writer.Write(UltimateDebugCount);
writer.Write(AgpCount);
writer.Write(BonusCount);
writer.Write(Unk7);
// Available Bitfield
writer.Write((UInt64)available);
// 写入 TrainingCount 数组
foreach (var count in TrainingCount)
{
writer.Write(count);
}
// Filler/Padding?
for (int i = 0; i < 2; i++)
writer.Write((int)0);
writer.Write(TriggerCount);
writer.Write(RidroidCount);
writer.Write(NetCafeAgpCount);
writer.Write(BattleBrokenCount);
writer.Write(BusterDebugCount);
writer.Write(Poka12Count);
writer.Write(Unk8);
writer.Write(Unk9);
writer.Write(BusterCount);
writer.Write(HeroTrainingCount);
writer.Write(AmplifiedCount);
writer.Write(Unk10);
writer.Write(Unk11);
writer.Write(DarkBlastTrainingCount);
writer.Write(EndlessCount);
writer.Write(Unk12);
writer.Write(Unk13);
writer.Write(PhantomTrainingCount);
writer.Write(AisTrainingCount);
writer.Write(Unk14);
writer.Write(DamageCalcCount);
writer.Write(EtoileTrainingCount);
writer.Write(DivideCount);
writer.Write(Stars1Count);
writer.Write(Stars2Count);
writer.Write(Stars3Count);
// 写入 Unk15 数组
foreach (var count in Unk15)
{
writer.Write(count);
}
// 写入 Unk16 数组
foreach (var count in Unk16)
{
writer.Write(count);
}
// 写入 AvailableTypes 和 Unk19 (作为枚举类型,转换为整数)
writer.Write((ulong)AvailableTypes);
writer.Write((ulong)Unk19);
writer.Write(RoundBoost);
writer.Write(Unk21);
//// Filler/Padding?
//writer.Write((UInt16)0);
//// Amounts
//for (int i = 0; i < amount.Length; i++)
//{
// amount[i] = 1; // Just for testing
// writer.Write(amount[i]);
//}
//// Padding/Blank entries?
//for (int i = 0; i < 2; i++)
// writer.Write((int)0);
//// Available Bitfield
//writer.Write((UInt64)available);
//// Filler/Padding?
//for (int i = 0; i < 2; i++)
// writer.Write((int)0);
return writer.ToArray();
}
public override PacketHeader GetHeader()
{
return new PacketHeader(0x0B, 0x16);
return new PacketHeader(0x0B, 0x16, PacketFlags.None);
}
}
}

View File

@ -3,11 +3,11 @@ using PSO2SERVER.Models;
namespace PSO2SERVER.Protocol.Packets
{
class QuestListPacket : Packet
public class QuestCategoryPacket : Packet
{
private QuestDefiniton[] questdefs;
public QuestListPacket(QuestDefiniton[] questdefs)
public QuestCategoryPacket(QuestDefiniton[] questdefs)
{
this.questdefs = questdefs;
}
@ -44,42 +44,5 @@ namespace PSO2SERVER.Protocol.Packets
120 -> Item Data 1?
12C -> Item Data 2?
*/
[Flags]
public enum QuestBitfield1 : ushort
{
MatterObjectiveQuest = 0x0001,
ClientOrderOnQuest = 0x0008,
NewQuest = 0x0100,
ClientOrder = 0x0800,
UnknownLevel = 0x1000
}
public enum PartyType
{
SoloQuest,
SinglePartyQuest,
MultiPartyQuest,
}
public enum EstimatedTime
{
Short = 1,
Medium,
Long
}
[Flags]
public enum Difficulties
{
Normal = 0x01,
hard = 0x02,
VeryHard = 0x04,
SuperHard = 0x08,
ExtraHard = 0x10,
Dummy1 = 0x20,
Dummy2 = 0x40,
Dummy3 = 0x80,
}
}
}

View File

@ -61,46 +61,5 @@ namespace PSO2SERVER.Protocol.Packets
{
return new PacketHeader(0x0B, 0x1A, PacketFlags.PACKED);
}
//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;
}
}
}

View File

@ -0,0 +1,24 @@
using System;
using PSO2SERVER.Models;
namespace PSO2SERVER.Protocol.Packets
{
public class QuestCategoryStopperPacket : Packet
{
/// Following: [`crate::protocol::Packet::QuestCategory`]
public QuestCategoryStopperPacket()
{
}
public override byte[] Build()
{
PacketWriter writer = new PacketWriter();
return writer.ToArray();
}
public override PacketHeader GetHeader()
{
return new PacketHeader(0x0B, 0x1B, PacketFlags.None);
}
}
}

View File

@ -49,7 +49,7 @@ namespace PSO2SERVER.Protocol.Packets
public override byte[] Build()
{
PacketWriter writer = new PacketWriter();
writer.Write(questdef.questNameString);
writer.Write(questdef.questNameid);
writer.Write(Unk1);
writer.Write(Unk2);
writer.Write(Unk3);

View File

@ -0,0 +1,47 @@
using System;
using System.Runtime.InteropServices;
using PSO2SERVER.Models;
namespace PSO2SERVER.Protocol.Packets
{
class PartySetQuestPacket : Packet
{
public uint Name { get; set; }
public uint Difficulty { get; set; }
public QuestType QuestType { get; set; }
public QuestDefiniton QuestDefiniton { get; set; }
public QuestDifficulty QuestDifficulty { get; set; }
public ObjectHeader Player { get; set; }
public ushort unk1 { get; set; } = 0;
public ushort unk2 { get; set; } = 0;
public PartySetQuestPacket(uint name, uint difficulty, QuestDefiniton data, QuestDifficulty Questdifficulty, ObjectHeader player)
{
Name = name;
Difficulty = difficulty;
QuestDefiniton = data;
QuestDifficulty = Questdifficulty;
Player = player;
}
public override byte[] Build()
{
PacketWriter writer = new PacketWriter();
writer.Write(Name); // Unknown
writer.Write(Difficulty); // Unknown
writer.Write((uint)QuestType);
writer.WriteStruct<QuestDefiniton>(QuestDefiniton);
writer.WriteStruct<QuestDifficulty>(QuestDifficulty);
writer.WriteStruct<ObjectHeader>(Player);
writer.Write(unk1);
writer.Write(unk2);
return writer.ToArray();
}
public override PacketHeader GetHeader()
{
return new PacketHeader(0x0E, 0x31, PacketFlags.None);
}
}
}

View File

@ -1,36 +0,0 @@
using System;
using System.Runtime.InteropServices;
using PSO2SERVER.Models;
namespace PSO2SERVER.Protocol.Packets
{
class QuestStartPacket : Packet
{
QuestDefiniton data;
QuestDifficultyPacket.QuestDifficulty difficulty;
public QuestStartPacket(QuestDefiniton data, QuestDifficultyPacket.QuestDifficulty difficulty)
{
this.data = data;
this.difficulty = difficulty;
}
public override byte[] Build()
{
PacketWriter writer = new PacketWriter();
writer.Write(0x753A); // Unknown
writer.Write((int)0); // Unknown
writer.WriteStruct<QuestDefiniton>(data);
writer.WriteStruct<QuestDifficultyPacket.QuestDifficulty>(difficulty);
return writer.ToArray();
}
public override PacketHeader GetHeader()
{
return new PacketHeader(0x0E, 0x31);
}
}
}

View File

@ -206,7 +206,7 @@
<Compile Include="Protocol\Handlers\0B-QuestHandler\0B-CD-AcceptStoryQuestHandler.cs" />
<Compile Include="Protocol\Handlers\0B-QuestHandler\0B-09-MinimapRevealRequest.cs" />
<Compile Include="Protocol\Handlers\0B-QuestHandler\0B-15-QuestCounterAvailableHander.cs" />
<Compile Include="Protocol\Handlers\0B-QuestHandler\0B-17-QuestListRequestHandler.cs" />
<Compile Include="Protocol\Handlers\0B-QuestHandler\0B-17-QuestCategoryRequest.cs" />
<Compile Include="Protocol\Handlers\0B-QuestHandler\0B-19-QuestDifficultyRequestHandler.cs" />
<Compile Include="Protocol\Handlers\0B-QuestHandler\0B-30-QuestCounterHandler.cs" />
<Compile Include="Protocol\Handlers\--UNK.cs" />
@ -241,6 +241,7 @@
<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\0B-QuestPacket\0B-1B-QuestCategoryStopperPacket.cs" />
<Compile Include="Protocol\Packets\1E-UnkPacket\1E-0C-Unk1E0CPacket.cs" />
<Compile Include="Protocol\Packets\0B-QuestPacket\0B-1C-QuestDifficultySendFinishedPacket.cs" />
<Compile Include="Protocol\Packets\0F-ItemPacket\0F-0C-LoadEquipedPacket.cs" />
@ -369,10 +370,10 @@
<Compile Include="Protocol\Packets\21-PalettePacket\21-03-FullPaletteInfoPacket.cs" />
<Compile Include="Protocol\Packets\21-PalettePacket\21-01-LoadPalettePacket.cs" />
<Compile Include="Protocol\Packets\0E-PartyPacket\0E-02-PartyInitPacket.cs" />
<Compile Include="Protocol\Packets\0E-PartyPacket\0E-31-QuestStartPacket.cs" />
<Compile Include="Protocol\Packets\0E-PartyPacket\0E-31-PartySetQuestPacket.cs" />
<Compile Include="Protocol\Packets\0B-QuestPacket\0B-1A-QuestDifficultyPacket.cs" />
<Compile Include="Protocol\Packets\0B-QuestPacket\0B-16-QuestAvailablePacket.cs" />
<Compile Include="Protocol\Packets\0B-QuestPacket\0B-18-QuestListPacket.cs" />
<Compile Include="Protocol\Packets\0B-QuestPacket\0B-18-QuestCategoryPacket.cs" />
<Compile Include="Protocol\Packets\11-ClientPacket\11-1C-SetCurrencyPacket.cs" />
<Compile Include="Protocol\Packets\0F-ItemPacket\0F-14-SetMesetaPacket.cs" />
<Compile Include="Protocol\Packets\03-ServerPacket\03-04-LoadingScreenTransitionPacket.cs" />

View File

@ -173,25 +173,6 @@ namespace PSO2SERVER.Zone
}
else
{
//PacketWriter writer = new PacketWriter();
//writer.WriteStruct(new ObjectHeader(3, ObjectType.Map));
//writer.WriteStruct(new ObjectHeader((uint)c._account.AccountId, ObjectType.Accounts));
//writer.Write(0x1); // 8 Zeros
//writer.Write(0); // 8 Zeros
//writer.Write(~(uint)Type); // F4 FF FF FF
//writer.Write(MapID); // Map ID maybe
//writer.Write((uint)Flags);
//writer.Write(GenerationArgs.seed); // 81 8F E6 19 (Maybe seed)
//writer.Write(VariantID); // Randomgen enable / disable maybe
//writer.Write(GenerationArgs.xsize); // X Size
//writer.Write(GenerationArgs.ysize); // Y Size
//writer.Write(1);
//writer.Write(1);
//writer.Write(~0); // FF FF FF FF FF FF FF FF
//writer.Write(0x301);
//c.SendPacket(0x3, 0x0, 0x0, writer.ToArray());
var _map = new Map("", MapID, VariantID, Type, Flags);
_map.GenerationArgs.seed = GenerationArgs.seed;
_map.GenerationArgs.xsize = GenerationArgs.xsize;
@ -254,10 +235,6 @@ namespace PSO2SERVER.Zone
foreach (Client other in Clients)
{
//PacketWriter writer = new PacketWriter();
//writer.WriteStruct(new ObjectHeader((uint)other._account.AccountId, ObjectType.Accounts));
//writer.WriteStruct(new ObjectHeader((uint)c._account.AccountId, ObjectType.Accounts));
//other.SendPacket(0x4, 0x3B, 0x40, writer.ToArray());
other.SendPacket(new DespawnPlayerPacket(other._account.AccountId, c._account.AccountId));
}