RecipeDB.cpp 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. /*
  2. EQ2Emulator: Everquest II Server Emulator
  3. Copyright (C) 2007 EQ2EMulator Development Team (http://www.eq2emulator.net)
  4. This file is part of EQ2Emulator.
  5. EQ2Emulator is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. EQ2Emulator is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with EQ2Emulator. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #ifdef WIN32
  17. #include <WinSock2.h>
  18. #include <windows.h>
  19. #endif
  20. #include <mysql.h>
  21. #include <assert.h>
  22. #include "../../common/Log.h"
  23. #include "../WorldDatabase.h"
  24. #include "Recipe.h"
  25. extern MasterRecipeList master_recipe_list;
  26. extern MasterRecipeBookList master_recipebook_list;
  27. void WorldDatabase::LoadRecipes() {
  28. Recipe *recipe;
  29. Query query;
  30. MYSQL_ROW row;
  31. MYSQL_RES *res;
  32. res = query.RunQuery2(Q_SELECT, "SELECT `recipe_id`,`tier`,`level`,`icon`,`skill_level`,`technique`,`knowledge`,`name`,`book`,`device`,`product_classes`,`unknown2`,`unknown3`,`unknown4`, "
  33. "`product_item_id`, `product_name`, `product_qty`, `primary_comp_title`, `build_comp_title`, `build2_comp_title`, `build3_comp_title`, `build4_comp_title`, "
  34. "`build_comp_qty`, `build2_comp_qty`, `build3_comp_qty`, `build4_comp_qty`, `fuel_comp_title`, `fuel_comp_qty`\n"
  35. "FROM `recipes`");
  36. if (res) {
  37. while ((row = mysql_fetch_row(res))) {
  38. recipe = new Recipe();
  39. recipe->SetID(atoul(row[0]));
  40. recipe->SetTier(atoi(row[1]));
  41. recipe->SetLevel(atoi(row[2]));
  42. recipe->SetIcon(atoi(row[3]));
  43. recipe->SetSkill(atoul(row[4]));
  44. recipe->SetTechnique(atoul(row[5]));
  45. recipe->SetKnowledge(atoul(row[6]));
  46. recipe->SetName(row[7]);
  47. recipe->SetBook(row[8]);
  48. recipe->SetDevice(row[9]);
  49. recipe->SetClasses(atoul(row[10]));
  50. recipe->SetUnknown2(atoul(row[11]));
  51. recipe->SetUnknown3(atoul(row[12]));
  52. recipe->SetUnknown4(atoul(row[13]));
  53. LogWrite(TRADESKILL__DEBUG, 5, "Recipes", "Loading recipe: %s (%u)", recipe->GetName(), recipe->GetID());
  54. recipe->SetProductID(atoul(row[14]));
  55. recipe->SetProductName(row[15]);
  56. recipe->SetProductQuantity(atoi(row[16]));
  57. recipe->SetPrimaryComponentTitle(row[17]);
  58. recipe->SetBuildComponentTitle(row[18]);
  59. if (row[19] != NULL)
  60. recipe->SetBuild2ComponentTitle(row[19]);
  61. if (row[20] != NULL)
  62. recipe->SetBuild3ComponentTitle(row[20]);
  63. if (row[21] != NULL)
  64. recipe->SetBuild4ComponentTitle(row[21]);
  65. recipe->SetBuild1ComponentQuantity(atoi(row[22]));
  66. if (row[23] != NULL)
  67. recipe->SetBuild2ComponentQuantity(atoi(row[23]));
  68. if (row[24] != NULL)
  69. recipe->SetBuild3ComponentQuantity(atoi(row[24]));
  70. if (row[25] != NULL)
  71. recipe->SetBuild4ComponentQuantity(atoi(row[25]));
  72. recipe->SetFuelComponentTitle(row[26]);
  73. recipe->SetFuelComponentQuantity(atoi(row[27]));
  74. LogWrite(TRADESKILL__DEBUG, 7, "Recipes", "Loading recipe: %s (%u)", recipe->GetName(), recipe->GetID());
  75. if (!master_recipe_list.AddRecipe(recipe)) {
  76. LogWrite(TRADESKILL__ERROR, 0, "Recipes", "Error adding recipe '%s' - duplicate ID: %u", recipe->GetName(), recipe->GetID());
  77. safe_delete(recipe);
  78. continue;
  79. }
  80. }
  81. }
  82. LoadRecipeComponents();
  83. LoadRecipeProducts();
  84. LogWrite(TRADESKILL__DEBUG, 0, "Recipes", "\tLoaded %u recipes", master_recipe_list.Size());
  85. }
  86. void WorldDatabase::LoadRecipeBooks(){
  87. Recipe *recipe;
  88. Query query;
  89. MYSQL_ROW row;
  90. MYSQL_RES *res;
  91. res = query.RunQuery2(Q_SELECT, "SELECT id, name FROM items WHERE item_type='Recipe'");
  92. if (res){
  93. while ((row = mysql_fetch_row(res))){
  94. recipe = new Recipe();
  95. recipe->SetBookID(atoul(row[0]));
  96. recipe->SetBookName(row[1]);
  97. LogWrite(TRADESKILL__DEBUG, 5, "Recipes", "Loading Recipe Books: %s (%u)", recipe->GetBookName(), recipe->GetBookID());
  98. if (!master_recipebook_list.AddRecipeBook(recipe)){
  99. LogWrite(TRADESKILL__ERROR, 0, "Recipes", "Error adding Recipe Book '%s' - duplicate ID: %u", recipe->GetBookName(), recipe->GetBookID());
  100. safe_delete(recipe);
  101. continue;
  102. }
  103. }
  104. }
  105. LogWrite(TRADESKILL__DEBUG, 0, "Recipes", "\tLoaded %u Recipe Books ", master_recipebook_list.Size());
  106. }
  107. void WorldDatabase::LoadPlayerRecipes(Player *player){
  108. Recipe *recipe;
  109. Query query;
  110. MYSQL_ROW row;
  111. MYSQL_RES *res;
  112. int16 total = 0;
  113. assert(player);
  114. res = query.RunQuery2(Q_SELECT, "SELECT recipe_id, highest_stage FROM character_recipes WHERE char_id = %u", player->GetCharacterID());
  115. if (res) {
  116. while ((row = mysql_fetch_row(res))){
  117. recipe = new Recipe(master_recipe_list.GetRecipe(atoul(row[0])));
  118. recipe->SetHighestStage(atoi(row[1]));
  119. LogWrite(TRADESKILL__DEBUG, 5, "Recipes", "Loading recipe: %s (%u) for player: %s (%u)", recipe->GetName(), recipe->GetID(), player->GetName(), player->GetCharacterID());
  120. if (!player->GetRecipeList()->AddRecipe(recipe)){
  121. LogWrite(TRADESKILL__ERROR, 0, "Recipes", "Error adding recipe %u to player '%s' - duplicate ID", recipe->GetID(), player->GetName());
  122. safe_delete(recipe);
  123. continue;
  124. }
  125. total++;
  126. }
  127. LogWrite(TRADESKILL__DEBUG, 0, "Recipes", "Loaded %u recipes for player: %s (%u)", total, player->GetName(), player->GetCharacterID());
  128. }
  129. }
  130. int32 WorldDatabase::LoadPlayerRecipeBooks(int32 char_id, Player *player) {
  131. assert(player);
  132. LogWrite(TRADESKILL__DEBUG, 0, "Recipes", "Loading Character Recipe Books for player '%s' ...", player->GetName());
  133. Query query;
  134. MYSQL_ROW row;
  135. MYSQL_RES *res;
  136. int32 count = 0;
  137. int32 old_id = 0;
  138. int32 new_id = 0;
  139. Recipe* recipe;
  140. res = query.RunQuery2(Q_SELECT, "SELECT recipebook_id FROM character_recipe_books WHERE char_id = %u", char_id);
  141. if (res && mysql_num_rows(res) > 0) {
  142. while (res && (row = mysql_fetch_row(res))){
  143. count++;
  144. new_id = atoul(row[0]);
  145. if(new_id == old_id)
  146. continue;
  147. Item* item = master_item_list.GetItem(new_id);
  148. if (!item)
  149. continue;
  150. recipe = new Recipe();
  151. recipe->SetBookID(new_id);
  152. recipe->SetBookName(item->name.c_str());
  153. LogWrite(TRADESKILL__DEBUG, 5, "Recipes", "Loading Recipe Books: %s (%u)", recipe->GetBookName(), recipe->GetBookID());
  154. if (!player->GetRecipeBookList()->AddRecipeBook(recipe)) {
  155. LogWrite(TRADESKILL__ERROR, 0, "Recipes", "Error adding player Recipe Book '%s' - duplicate ID: %u", recipe->GetBookName(), recipe->GetBookID());
  156. safe_delete(recipe);
  157. continue;
  158. }
  159. old_id = new_id;
  160. }
  161. }
  162. return count;
  163. }
  164. void WorldDatabase::SavePlayerRecipeBook(Player* player, int32 recipebook_id){
  165. Query query;
  166. query.RunQuery2(Q_INSERT, "INSERT INTO character_recipe_books (char_id, recipebook_id) VALUES(%u, %u)", player->GetCharacterID(), recipebook_id);
  167. if(query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF)
  168. LogWrite(TRADESKILL__ERROR, 0, "Recipes", "Error in SavePlayerRecipeBook query '%s' : %s", query.GetQuery(), query.GetError());
  169. }
  170. void WorldDatabase::SavePlayerRecipe(Player* player, int32 recipe_id) {
  171. Query query;
  172. query.RunQuery2(Q_INSERT, "INSERT INTO character_recipes (char_id, recipe_id) VALUES (%u, %u)", player->GetCharacterID(), recipe_id);
  173. if(query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF)
  174. LogWrite(TRADESKILL__ERROR, 0, "Recipes", "Error in SavePlayerRecipeBook query '%s' : %s", query.GetQuery(), query.GetError());
  175. }
  176. void WorldDatabase::LoadRecipeComponents() {
  177. Query query;
  178. MYSQL_ROW row;
  179. MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `recipe_id`, `item_id`, `slot_id` FROM `recipe_components` ORDER BY `recipe_id` asc");
  180. int32 id = 0;
  181. Recipe* recipe = 0;
  182. if (result && mysql_num_rows(result) > 0) {
  183. while (result && (row = mysql_fetch_row(result))) {
  184. if (id != strtoul(row[0], NULL, 0)) {
  185. id = strtoul(row[0], NULL, 0);
  186. recipe = master_recipe_list.GetRecipe(id);
  187. }
  188. if (recipe) {
  189. recipe->AddBuildComp(atoi(row[1]), atoi(row[2]));
  190. }
  191. else
  192. LogWrite(TRADESKILL__ERROR, 0, "Recipes", "Error loading `recipe_build_comps`, Recipe ID: %u", id);
  193. }
  194. }
  195. }
  196. void WorldDatabase::LoadRecipeProducts() {
  197. Query query;
  198. MYSQL_ROW row;
  199. MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `recipe_id`, `stage`, `product_id`, `byproduct_id`, `product_qty`, `byproduct_qty` FROM `recipe_products` ORDER BY `recipe_id` ASC");
  200. int32 id = 0;
  201. Recipe* recipe = 0;
  202. if (result && mysql_num_rows(result) > 0) {
  203. while (result && (row = mysql_fetch_row(result))) {
  204. if (id != strtoul(row[0], NULL, 0)) {
  205. id = strtoul(row[0], NULL, 0);
  206. recipe = master_recipe_list.GetRecipe(id);
  207. }
  208. if (recipe) {
  209. int8 stage = atoi(row[1]);
  210. RecipeProducts* rp = new RecipeProducts;
  211. rp->product_id = atoul(row[2]);
  212. rp->byproduct_id = atoul(row[3]);
  213. rp->product_qty = atoi(row[4]);
  214. rp->byproduct_qty = atoi(row[5]);
  215. recipe->products[stage] = rp;
  216. }
  217. else
  218. LogWrite(TRADESKILL__ERROR, 0, "Recipes", "Error loading `recipe_products`, Recipe ID: %u", id);
  219. }
  220. }
  221. }
  222. void WorldDatabase::UpdatePlayerRecipe(Player* player, int32 recipe_id, int8 highest_stage) {
  223. Query query;
  224. query.RunQuery2(Q_UPDATE, "UPDATE `character_recipes` SET `highest_stage` = %i WHERE `char_id` = %u AND `recipe_id` = %u", highest_stage, player->GetCharacterID(), recipe_id);
  225. }
  226. /*
  227. ALTER TABLE `character_recipes`
  228. ADD COLUMN `highest_stage` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0' AFTER `recipe_id`;
  229. */