int_quest.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
  2. // For more information, see LICENCE in the main folder
  3. #include "../common/mmo.h"
  4. #include "../common/db.h"
  5. #include "../common/malloc.h"
  6. #include "../common/showmsg.h"
  7. #include "../common/socket.h"
  8. #include "../common/strlib.h"
  9. #include "../common/sql.h"
  10. #include "../common/timer.h"
  11. #include "char.h"
  12. #include "inter.h"
  13. #include "int_quest.h"
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include <stdlib.h>
  17. //Load entire questlog for a character
  18. int mapif_quests_fromsql(int char_id, struct quest questlog[])
  19. {
  20. int i;
  21. struct quest tmp_quest;
  22. SqlStmt * stmt;
  23. stmt = SqlStmt_Malloc(sql_handle);
  24. if( stmt == NULL )
  25. {
  26. SqlStmt_ShowDebug(stmt);
  27. return 0;
  28. }
  29. memset(&tmp_quest, 0, sizeof(struct quest));
  30. if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `quest_id`, `state`, `time`, `count1`, `count2`, `count3` FROM `%s` WHERE `char_id`=? LIMIT %d", quest_db, MAX_QUEST_DB)
  31. || SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
  32. || SQL_ERROR == SqlStmt_Execute(stmt)
  33. || SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &tmp_quest.quest_id, 0, NULL, NULL)
  34. || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_INT, &tmp_quest.state, 0, NULL, NULL)
  35. || SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_UINT, &tmp_quest.time, 0, NULL, NULL)
  36. || SQL_ERROR == SqlStmt_BindColumn(stmt, 3, SQLDT_INT, &tmp_quest.count[0], 0, NULL, NULL)
  37. || SQL_ERROR == SqlStmt_BindColumn(stmt, 4, SQLDT_INT, &tmp_quest.count[1], 0, NULL, NULL)
  38. || SQL_ERROR == SqlStmt_BindColumn(stmt, 5, SQLDT_INT, &tmp_quest.count[2], 0, NULL, NULL) )
  39. SqlStmt_ShowDebug(stmt);
  40. for( i = 0; i < MAX_QUEST_DB && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i )
  41. memcpy(&questlog[i], &tmp_quest, sizeof(tmp_quest));
  42. SqlStmt_Free(stmt);
  43. return i;
  44. }
  45. //Delete a quest
  46. bool mapif_quest_delete(int char_id, int quest_id)
  47. {
  48. if ( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `quest_id` = '%d' AND `char_id` = '%d'", quest_db, quest_id, char_id) )
  49. {
  50. Sql_ShowDebug(sql_handle);
  51. return false;
  52. }
  53. return true;
  54. }
  55. //Add a quest to a questlog
  56. bool mapif_quest_add(int char_id, struct quest qd)
  57. {
  58. if ( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s`(`quest_id`, `char_id`, `state`, `time`, `count1`, `count2`, `count3`) VALUES ('%d', '%d', '%d','%d', '%d', '%d', '%d')", quest_db, qd.quest_id, char_id, qd.state, qd.time, qd.count[0], qd.count[1], qd.count[2]) )
  59. {
  60. Sql_ShowDebug(sql_handle);
  61. return false;
  62. }
  63. return true;
  64. }
  65. //Update a questlog
  66. bool mapif_quest_update(int char_id, struct quest qd)
  67. {
  68. if ( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `state`='%d', `count1`='%d', `count2`='%d', `count3`='%d' WHERE `quest_id` = '%d' AND `char_id` = '%d'", quest_db, qd.state, qd.count[0], qd.count[1], qd.count[2], qd.quest_id, char_id) )
  69. {
  70. Sql_ShowDebug(sql_handle);
  71. return false;
  72. }
  73. return true;
  74. }
  75. //Save quests
  76. int mapif_parse_quest_save(int fd)
  77. {
  78. int i, j, k, num2, num1 = (RFIFOW(fd,2)-8)/sizeof(struct quest);
  79. int char_id = RFIFOL(fd,4);
  80. struct quest qd1[MAX_QUEST_DB],qd2[MAX_QUEST_DB];
  81. bool success = true;
  82. memset(qd1, 0, sizeof(qd1));
  83. memset(qd2, 0, sizeof(qd2));
  84. if( num1 ) memcpy(&qd1, RFIFOP(fd,8), RFIFOW(fd,2)-8);
  85. num2 = mapif_quests_fromsql(char_id, qd2);
  86. for( i = 0; i < num1; i++ )
  87. {
  88. ARR_FIND( 0, num2, j, qd1[i].quest_id == qd2[j].quest_id );
  89. if( j < num2 ) // Update existed quests
  90. { // Only states and counts are changable.
  91. ARR_FIND( 0, MAX_QUEST_OBJECTIVES, k, qd1[i].count[k] != qd2[j].count[k] );
  92. if( k != MAX_QUEST_OBJECTIVES || qd1[i].state != qd2[j].state )
  93. success &= mapif_quest_update(char_id, qd1[i]);
  94. if( j < (--num2) )
  95. {
  96. memmove(&qd2[j],&qd2[j+1],sizeof(struct quest)*(num2-j));
  97. memset(&qd2[num2], 0, sizeof(struct quest));
  98. }
  99. }
  100. else // Add new quests
  101. success &= mapif_quest_add(char_id, qd1[i]);
  102. }
  103. for( i = 0; i < num2; i++ ) // Quests not in qd1 but in qd2 are to be erased.
  104. success &= mapif_quest_delete(char_id, qd2[i].quest_id);
  105. WFIFOHEAD(fd,7);
  106. WFIFOW(fd,0) = 0x3861;
  107. WFIFOL(fd,2) = char_id;
  108. WFIFOB(fd,6) = success?1:0;
  109. WFIFOSET(fd,7);
  110. return 0;
  111. }
  112. //Send questlog to map server
  113. int mapif_parse_quest_load(int fd)
  114. {
  115. int char_id = RFIFOL(fd,2);
  116. struct quest tmp_questlog[MAX_QUEST_DB];
  117. int num_quests, i, num_complete = 0;
  118. int complete[MAX_QUEST_DB];
  119. memset(tmp_questlog, 0, sizeof(tmp_questlog));
  120. memset(complete, 0, sizeof(complete));
  121. num_quests = mapif_quests_fromsql(char_id, tmp_questlog);
  122. WFIFOHEAD(fd,num_quests*sizeof(struct quest)+8);
  123. WFIFOW(fd,0) = 0x3860;
  124. WFIFOW(fd,2) = num_quests*sizeof(struct quest)+8;
  125. WFIFOL(fd,4) = char_id;
  126. //Active and inactive quests
  127. for( i = 0; i < num_quests; i++ )
  128. {
  129. if( tmp_questlog[i].state == Q_COMPLETE )
  130. {
  131. complete[num_complete++] = i;
  132. continue;
  133. }
  134. memcpy(WFIFOP(fd,(i-num_complete)*sizeof(struct quest)+8), &tmp_questlog[i], sizeof(struct quest));
  135. }
  136. // Completed quests
  137. for( i = num_quests - num_complete; i < num_quests; i++ )
  138. memcpy(WFIFOP(fd,i*sizeof(struct quest)+8), &tmp_questlog[complete[i-num_quests+num_complete]], sizeof(struct quest));
  139. WFIFOSET(fd,num_quests*sizeof(struct quest)+8);
  140. return 0;
  141. }
  142. int inter_quest_parse_frommap(int fd)
  143. {
  144. switch(RFIFOW(fd,0))
  145. {
  146. case 0x3060: mapif_parse_quest_load(fd); break;
  147. case 0x3061: mapif_parse_quest_save(fd); break;
  148. default:
  149. return 0;
  150. }
  151. return 1;
  152. }