summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--log/empty.txt0
-rw-r--r--save/empty.txt0
-rw-r--r--src/common/HPMDataCheck.h3
-rw-r--r--src/map/clif.c70
-rw-r--r--src/map/packets_struct.h48
-rw-r--r--src/map/quest.c8
6 files changed, 100 insertions, 29 deletions
diff --git a/log/empty.txt b/log/empty.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/log/empty.txt
diff --git a/save/empty.txt b/save/empty.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/save/empty.txt
diff --git a/src/common/HPMDataCheck.h b/src/common/HPMDataCheck.h
index 923b6ccbf..c60bec4c8 100644
--- a/src/common/HPMDataCheck.h
+++ b/src/common/HPMDataCheck.h
@@ -492,6 +492,7 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = {
{ "packet_itemlist_equip", sizeof(struct packet_itemlist_equip), SERVER_TYPE_MAP },
{ "packet_itemlist_normal", sizeof(struct packet_itemlist_normal), SERVER_TYPE_MAP },
{ "packet_maptypeproperty2", sizeof(struct packet_maptypeproperty2), SERVER_TYPE_MAP },
+ { "packet_mission_info_sub", sizeof(struct packet_mission_info_sub), SERVER_TYPE_MAP },
{ "packet_monster_hp", sizeof(struct packet_monster_hp), SERVER_TYPE_MAP },
{ "packet_notify_bounditem", sizeof(struct packet_notify_bounditem), SERVER_TYPE_MAP },
{ "packet_npc_market_open", sizeof(struct packet_npc_market_open), SERVER_TYPE_MAP },
@@ -499,6 +500,8 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = {
{ "packet_npc_market_result_ack", sizeof(struct packet_npc_market_result_ack), SERVER_TYPE_MAP },
{ "packet_package_item_announce", sizeof(struct packet_package_item_announce), SERVER_TYPE_MAP },
{ "packet_party_leader_changed", sizeof(struct packet_party_leader_changed), SERVER_TYPE_MAP },
+ { "packet_quest_list_header", sizeof(struct packet_quest_list_header), SERVER_TYPE_MAP },
+ { "packet_quest_list_info", sizeof(struct packet_quest_list_info), SERVER_TYPE_MAP },
{ "packet_roulette_close_ack", sizeof(struct packet_roulette_close_ack), SERVER_TYPE_MAP },
{ "packet_roulette_generate_ack", sizeof(struct packet_roulette_generate_ack), SERVER_TYPE_MAP },
{ "packet_roulette_info_ack", sizeof(struct packet_roulette_info_ack), SERVER_TYPE_MAP },
diff --git a/src/map/clif.c b/src/map/clif.c
index d499cf67f..95ad088e5 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -15480,41 +15480,55 @@ void clif_parse_PartyTick(int fd, struct map_session_data* sd)
/// Sends list of all quest states (ZC_ALL_QUEST_LIST).
/// 02b1 <packet len>.W <num>.L { <quest id>.L <active>.B }*num
+/// 097a <packet len>.W <num>.L { <quest id>.L <active>.B <remaining time>.L <time>.L <count>.W { <mob_id>.L <killed>.W <total>.W <mob name>.24B }*count }*num
void clif_quest_send_list(struct map_session_data *sd)
{
- int fd = sd->fd;
- int i;
-#if PACKETVER >= 20141022
- int info_len = 15;
- int len;
+ int i, len, real_len;
+ uint8 *buf = NULL;
+ struct packet_quest_list_header *packet = NULL;
nullpo_retv(sd);
- len = sd->avail_quests*info_len+8;
- WFIFOHEAD(fd,len);
- WFIFOW(fd, 0) = 0x97a;
-#else
- int info_len = 5;
- int len;
- nullpo_retv(sd);
- len = sd->avail_quests*info_len+8;
- WFIFOHEAD(fd,len);
- WFIFOW(fd, 0) = 0x2b1;
-#endif
- WFIFOW(fd, 2) = len;
- WFIFOL(fd, 4) = sd->avail_quests;
+
+ len = sizeof(struct packet_quest_list_header)
+ + sd->avail_quests * (sizeof(struct packet_quest_list_info)
+ + MAX_QUEST_OBJECTIVES * sizeof(struct packet_mission_info_sub)); // >= than the actual length
+ buf = aMalloc(len);
+ packet = (struct packet_quest_list_header *)WBUFP(buf, 0);
+ real_len = sizeof(*packet);
+
+ packet->PacketType = questListType;
+ packet->questCount = sd->avail_quests;
for (i = 0; i < sd->avail_quests; i++) {
- #if PACKETVER >= 20141022
+ struct packet_quest_list_info *info = (struct packet_quest_list_info *)(buf+real_len);
+#if PACKETVER >= 20141022
struct quest_db *qi = quest->db(sd->quest_log[i].quest_id);
- #endif
- WFIFOL(fd, i*info_len+8) = sd->quest_log[i].quest_id;
- WFIFOB(fd, i*info_len+12) = sd->quest_log[i].state;
- #if PACKETVER >= 20141022
- WFIFOL(fd, i*info_len+13) = sd->quest_log[i].time - qi->time;
- WFIFOL(fd, i*info_len+17) = sd->quest_log[i].time;
- WFIFOW(fd, i*info_len+21) = qi->objectives_count;
- #endif
+ int j;
+#endif // PACKETVER >= 20141022
+ real_len += sizeof(*info);
+
+ info->questID = sd->quest_log[i].quest_id;
+ info->active = sd->quest_log[i].state;
+#if PACKETVER >= 20141022
+ info->quest_svrTime = sd->quest_log[i].time - qi->time;
+ info->quest_endTime = sd->quest_log[i].time;
+ info->hunting_count = qi->objectives_count;
+
+ for (j = 0; j < qi->objectives_count; j++) {
+ struct mob_db *mob_data;
+ Assert_retb(j < MAX_QUEST_OBJECTIVES);
+ real_len += sizeof(info->objectives[j]);
+
+ mob_data = mob->db(qi->objectives[j].mob);
+
+ info->objectives[j].mob_id = qi->objectives[j].mob;
+ info->objectives[j].huntCount = sd->quest_log[i].count[j];
+ info->objectives[j].maxCount = qi->objectives[j].count;
+ safestrncpy(info->objectives[j].mobName, mob_data->jname, sizeof(info->objectives[j].mobName));
+ }
+#endif // PACKETVER >= 20141022
}
- WFIFOSET(fd, len);
+ packet->PacketLength = real_len;
+ clif->send(buf, real_len, &sd->bl, SELF);
}
/// Sends list of all quest missions (ZC_ALL_QUEST_MISSION).
diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h
index 8f9747747..58c17ef0a 100644
--- a/src/map/packets_struct.h
+++ b/src/map/packets_struct.h
@@ -257,6 +257,13 @@ enum packet_headers {
rouletteinfoackType = 0xa1c,
roulettgenerateackType = 0xa20,
roulettercvitemackType = 0xa22,
+#if 0 // Unknown
+ questListType = 0x9f8, ///< ZC_ALL_QUEST_LIST3
+#elif PACKETVER >= 20141022
+ questListType = 0x97a, ///< ZC_ALL_QUEST_LIST2
+#else // PACKETVER < 20141022
+ questListType = 0x2b1, ///< ZC_ALL_QUEST_LIST
+#endif // PACKETVER >= 20141022
};
#if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
@@ -1101,6 +1108,47 @@ struct packet_hotkey {
} hotkey[MAX_HOTKEYS];
} __attribute__((packed));
+/**
+ * MISSION_HUNT_INFO
+ */
+struct packet_mission_info_sub {
+ int32 mob_id;
+ int16 huntCount;
+ int16 maxCount;
+ char mobName[NAME_LENGTH];
+} __attribute__((packed));
+
+/**
+ * PACKET_ZC_ALL_QUEST_LIST2_INFO (PACKETVER >= 20141022)
+ * PACKET_ZC_ALL_QUEST_LIST3_INFO (PACKETVER Unknown) / unused
+ */
+struct packet_quest_list_info {
+ int32 questID;
+ int8 active;
+#if PACKETVER >= 20141022
+ int32 quest_svrTime;
+ int32 quest_endTime;
+ int16 hunting_count;
+ struct packet_mission_info_sub objectives[]; // Note: This will be < MAX_QUEST_OBJECTIVES
+#endif // PACKETVER >= 20141022
+} __attribute__((packed));
+
+/**
+ * Header for:
+ * PACKET_ZC_ALL_QUEST_LIST (PACKETVER < 20141022)
+ * PACKET_ZC_ALL_QUEST_LIST2 (PACKETVER >= 20141022)
+ * PACKET_ZC_ALL_QUEST_LIST3 (PACKETVER Unknown) / unused
+ *
+ * @remark
+ * Contains (is followed by) a variable-length array of packet_quest_list_info
+ */
+struct packet_quest_list_header {
+ uint16 PacketType;
+ uint16 PacketLength;
+ int32 questCount;
+ //struct packet_quest_list_info list[]; // Variable-length
+} __attribute__((packed));
+
#if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
#pragma pack(pop)
#endif // not NetBSD < 6 / Solaris
diff --git a/src/map/quest.c b/src/map/quest.c
index 790e96253..e4216b18e 100644
--- a/src/map/quest.c
+++ b/src/map/quest.c
@@ -59,18 +59,24 @@ struct quest_db *quest_db(int quest_id) {
* @param sd Player's data
* @return 0 in case of success, nonzero otherwise (i.e. the player has no quests)
*/
-int quest_pc_login(TBL_PC *sd) {
+int quest_pc_login(TBL_PC *sd)
+{
+#if PACKETVER < 20141022
int i;
+#endif
if(sd->avail_quests == 0)
return 1;
clif->quest_send_list(sd);
+
+#if PACKETVER < 20141022
clif->quest_send_mission(sd);
for( i = 0; i < sd->avail_quests; i++ ) {
// TODO[Haru]: is this necessary? Does quest_send_mission not take care of this?
clif->quest_update_objective(sd, &sd->quest_log[i]);
}
+#endif
return 0;
}