· 8 years ago · May 02, 2018, 08:08 AM
1#include "ScriptMgr.h"
2#include "ScriptedCreature.h"
3#include "ScriptedGossip.h"
4#include "GameEventMgr.h"
5#include "Player.h"
6#include "WorldSession.h"
7
8class NPC_Crafter : public CreatureScript
9
10{
11public:
12 NPC_Crafter() : CreatureScript("NPC_Crafter")
13 {
14
15 }
16
17 //Protection against SQL Injection
18 bool string_is_valid(const std::string &str)
19 {
20 return find_if(str.begin(), str.end(),
21 [](char c) { return !(isalnum(c) || (c == ' ')); }) == str.end();
22 }
23
24 void Zapros(Player* player, Creature* creature, const char* code) {
25
26 if (!string_is_valid(code))
27 {
28 player->PlayerTalkClass->SendCloseGossip();
29 return;
30 }
31
32
33 std::string code2 = code;
34 QueryResult result = WorldDatabase.PQuery("SELECT `name`, `item`, `count`, `r_item1`, `r_count1`, `r_item2`, `r_count2`, `r_item3`, `r_count3`, `r_item4`, `r_count4`, `r_item5`, `r_count5` FROM `craft_system` WHERE `name` = '%s'", code);
35 if (!result)
36 {
37 creature->Whisper("Recipe named '" + code2 + "' not found.", LANG_UNIVERSAL, player, false);
38 //TODO: UPDATE GOSSIP MENU INSTEAD CLOSE
39 player->PlayerTalkClass->SendCloseGossip();
40 return;
41 }
42
43 Field * fields = NULL;
44 fields = result->Fetch();
45 std::string name = fields[0].GetString();
46 uint32 item = fields[1].GetUInt32();
47 uint32 count = fields[2].GetUInt32();
48 uint32 r_item1 = fields[3].GetUInt32();
49 uint32 r_count1 = fields[4].GetUInt32();
50 uint32 r_item2 = fields[5].GetUInt32();
51 uint32 r_count2 = fields[6].GetUInt32();
52 uint32 r_item3 = fields[7].GetInt32();
53 uint32 r_count3 = fields[8].GetInt32();
54 uint32 r_item4 = fields[9].GetInt32();
55 uint32 r_count4 = fields[10].GetInt32();
56 uint32 r_item5 = fields[11].GetInt32();
57 uint32 r_count5 = fields[12].GetInt32();
58
59 if (item == 0 || count == 0 || r_item1 == 0 || r_count1 == 0) // empty row
60 {
61 creature->Whisper("Error! Row '" + name + "' incorrectly filled.", LANG_UNIVERSAL, player, false);
62 player->PlayerTalkClass->SendCloseGossip();
63 return;
64 }
65
66 ItemPosCountVec dest;
67 uint32 no_space = 0;
68 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, item, count, &no_space);
69 if (msg != EQUIP_ERR_OK)
70 {
71 creature->Whisper("Inventory is full!", LANG_UNIVERSAL, player, false);
72 player->PlayerTalkClass->SendCloseGossip();
73 return;
74 }
75 if (player->HasItemCount(r_item1, r_count1) &&
76 player->HasItemCount(r_item2, r_count2) &&
77 player->HasItemCount(r_item3, r_count3) &&
78 player->HasItemCount(r_item4, r_count4) &&
79 player->HasItemCount(r_item5, r_count5))
80 {
81 player->AddItem(item, count);
82 player->DestroyItemCount(r_item1, r_count1, true);
83 player->DestroyItemCount(r_item2, r_count2, true);
84 player->DestroyItemCount(r_item3, r_count3, true);
85 player->DestroyItemCount(r_item4, r_count4, true);
86 player->DestroyItemCount(r_item5, r_count5, true);
87 player->PlayerTalkClass->SendCloseGossip();
88 return;
89 }
90 if (player->HasItemCount(r_item1, r_count1) &&
91 player->HasItemCount(r_item2, r_count2) &&
92 player->HasItemCount(r_item3, r_count3) &&
93 player->HasItemCount(r_item4, r_count4) &&
94 r_item5 == 0)
95 {
96 player->AddItem(item, count);
97 player->DestroyItemCount(r_item1, r_count1, true);
98 player->DestroyItemCount(r_item2, r_count2, true);
99 player->DestroyItemCount(r_item3, r_count3, true);
100 player->DestroyItemCount(r_item4, r_count4, true);
101 player->PlayerTalkClass->SendCloseGossip();
102 return;
103 }
104 if (player->HasItemCount(r_item1, r_count1) &&
105 player->HasItemCount(r_item2, r_count2) &&
106 player->HasItemCount(r_item3, r_count3) &&
107 r_item4 == 0)
108 {
109 player->AddItem(item, count);
110 player->DestroyItemCount(r_item1, r_count1, true);
111 player->DestroyItemCount(r_item2, r_count2, true);
112 player->DestroyItemCount(r_item3, r_count3, true);
113 player->PlayerTalkClass->SendCloseGossip();
114 return;
115 }
116 if (player->HasItemCount(r_item1, r_count1) &&
117 player->HasItemCount(r_item2, r_count2) &&
118 r_item3 == 0)
119 {
120 player->AddItem(item, count);
121 player->DestroyItemCount(r_item1, r_count1, true);
122 player->DestroyItemCount(r_item2, r_count2, true);
123 player->PlayerTalkClass->SendCloseGossip();
124 return;
125 }
126 if (player->HasItemCount(r_item1, r_count1) &&
127 r_item2 == 0)
128 {
129 player->AddItem(item, count);
130 player->DestroyItemCount(r_item1, r_count1, true);
131 player->PlayerTalkClass->SendCloseGossip();
132 return;
133 }
134
135 else
136 {
137 std::ostringstream ss;
138 if (r_item1 != 0 && r_item2 != 0 && r_item3 != 0 && r_item4 !=0 && r_item5 !=0) //5 items
139 {
140 ss << "To create " << GetItemLink(item, player->GetSession()) << "x" << count << " (" << name << ") required:\n" <<
141 GetItemLink(r_item1, player->GetSession()) << "x" << r_count1 << "\n" <<
142 GetItemLink(r_item2, player->GetSession()) << "x" << r_count2 << "\n" <<
143 GetItemLink(r_item3, player->GetSession()) << "x" << r_count3 << "\n" <<
144 GetItemLink(r_item4, player->GetSession()) << "x" << r_count4 << "\n" <<
145 GetItemLink(r_item5, player->GetSession()) << "x" << r_count5;
146 creature->Whisper(ss.str().c_str(), LANG_UNIVERSAL, player, false);
147 player->PlayerTalkClass->SendCloseGossip();
148 return;
149 }
150 if (r_item1 != 0 && r_item2 != 0 && r_item3 != 0 && r_item4 != 0 && r_item5 == 0) //4 items
151 {
152 ss << "To create " << GetItemLink(item, player->GetSession()) << "x" << count << " (" << name << ") required:\n" <<
153 GetItemLink(r_item1, player->GetSession()) << "x" << r_count1 << "\n" <<
154 GetItemLink(r_item2, player->GetSession()) << "x" << r_count2 << "\n" <<
155 GetItemLink(r_item3, player->GetSession()) << "x" << r_count3 << "\n" <<
156 GetItemLink(r_item4, player->GetSession()) << "x" << r_count4;
157 creature->Whisper(ss.str().c_str(), LANG_UNIVERSAL, player, false);
158 player->PlayerTalkClass->SendCloseGossip();
159 return;
160 }
161 if (r_item1 != 0 && r_item2 != 0 && r_item3 != 0 && r_item4 == 0) //3 items
162 {
163 ss << "To create " << GetItemLink(item, player->GetSession()) << "x" << count << " (" << name << ") required:\n" <<
164 GetItemLink(r_item1, player->GetSession()) << "x" << r_count1 << "\n" <<
165 GetItemLink(r_item2, player->GetSession()) << "x" << r_count2 << "\n" <<
166 GetItemLink(r_item3, player->GetSession()) << "x" << r_count3;
167 creature->Whisper(ss.str().c_str(), LANG_UNIVERSAL, player, false);
168 player->PlayerTalkClass->SendCloseGossip();
169 return;
170 }
171 if (r_item1 != 0 && r_item2 != 0 && r_item3 == 0) //2 items
172 {
173 ss << "To create " << GetItemLink(item, player->GetSession()) << "x" << count << " (" << name << ") required:\n" <<
174 GetItemLink(r_item1, player->GetSession()) << "x" << r_count1 << "\n" <<
175 GetItemLink(r_item2, player->GetSession()) << "x" << r_count2;
176 creature->Whisper(ss.str().c_str(), LANG_UNIVERSAL, player, false);
177 player->PlayerTalkClass->SendCloseGossip();
178 return;
179 }
180 if (r_item1 != 0 && r_item2 == 0) //1 item
181 {
182 ss << "To create " << GetItemLink(item, player->GetSession()) << "x" << count << " (" << name << ") required:\n" <<
183 GetItemLink(r_item1, player->GetSession()) << "x" << r_count1;
184 creature->Whisper(ss.str().c_str(), LANG_UNIVERSAL, player, false);
185 player->PlayerTalkClass->SendCloseGossip();
186 return;
187 }
188 return;
189 }
190 return;
191 }
192
193 void Info(Player* player, Creature* creature, const char* code) {
194
195 if (!string_is_valid(code))
196 {
197 player->PlayerTalkClass->SendCloseGossip();
198 return;
199 }
200
201
202 std::string code2 = code;
203 QueryResult result = WorldDatabase.PQuery("SELECT `name`, `item`, `count`, `r_item1`, `r_count1`, `r_item2`, `r_count2`, `r_item3`, `r_count3`, `r_item4`, `r_count4`, `r_item5`, `r_count5` FROM `craft_system` WHERE `name` = '%s'", code);
204 if (!result)
205 {
206 creature->Whisper("Recipe named '" + code2 + "' not found.", LANG_UNIVERSAL, player, false);
207 //TODO: UPDATE GOSSIP MENU INSTEAD CLOSE
208 player->PlayerTalkClass->SendCloseGossip();
209 return;
210 }
211
212 Field * fields = NULL;
213 fields = result->Fetch();
214 std::string name = fields[0].GetString();
215 uint32 item = fields[1].GetUInt32();
216 uint32 count = fields[2].GetUInt32();
217 uint32 r_item1 = fields[3].GetUInt32();
218 uint32 r_count1 = fields[4].GetUInt32();
219 uint32 r_item2 = fields[5].GetUInt32();
220 uint32 r_count2 = fields[6].GetUInt32();
221 uint32 r_item3 = fields[7].GetInt32();
222 uint32 r_count3 = fields[8].GetInt32();
223 uint32 r_item4 = fields[9].GetInt32();
224 uint32 r_count4 = fields[10].GetInt32();
225 uint32 r_item5 = fields[11].GetInt32();
226 uint32 r_count5 = fields[12].GetInt32();
227
228 if (item == 0 || count == 0 || r_item1 == 0 || r_count1 == 0) // empty row
229 {
230 creature->Whisper("Error! Row '" + name + "' incorrectly filled.", LANG_UNIVERSAL, player, false);
231 player->PlayerTalkClass->SendCloseGossip();
232 return;
233 }
234
235 std::ostringstream ss;
236 if (r_item1 != 0 && r_item2 != 0 && r_item3 != 0 && r_item4 != 0 && r_item5 != 0) //5 items
237 {
238 ss << "To create " << GetItemLink(item, player->GetSession()) << "x" << count << " (" << name << ") required:\n" <<
239 GetItemLink(r_item1, player->GetSession()) << "x" << r_count1 << "\n" <<
240 GetItemLink(r_item2, player->GetSession()) << "x" << r_count2 << "\n" <<
241 GetItemLink(r_item3, player->GetSession()) << "x" << r_count3 << "\n" <<
242 GetItemLink(r_item4, player->GetSession()) << "x" << r_count4 << "\n" <<
243 GetItemLink(r_item5, player->GetSession()) << "x" << r_count5;
244 creature->Whisper(ss.str().c_str(), LANG_UNIVERSAL, player, false);
245 player->PlayerTalkClass->SendCloseGossip();
246 return;
247 }
248 if (r_item1 != 0 && r_item2 != 0 && r_item3 != 0 && r_item4 != 0 && r_item5 == 0) //4 items
249 {
250 ss << "To create " << GetItemLink(item, player->GetSession()) << "x" << count << " (" << name << ") required:\n" <<
251 GetItemLink(r_item1, player->GetSession()) << "x" << r_count1 << "\n" <<
252 GetItemLink(r_item2, player->GetSession()) << "x" << r_count2 << "\n" <<
253 GetItemLink(r_item3, player->GetSession()) << "x" << r_count3 << "\n" <<
254 GetItemLink(r_item4, player->GetSession()) << "x" << r_count4;
255 creature->Whisper(ss.str().c_str(), LANG_UNIVERSAL, player, false);
256 player->PlayerTalkClass->SendCloseGossip();
257 return;
258 }
259 if (r_item1 != 0 && r_item2 != 0 && r_item3 != 0 && r_item4 == 0) //3 items
260 {
261 ss << "To create " << GetItemLink(item, player->GetSession()) << "x" << count << " (" << name << ") required:\n" <<
262 GetItemLink(r_item1, player->GetSession()) << "x" << r_count1 << "\n" <<
263 GetItemLink(r_item2, player->GetSession()) << "x" << r_count2 << "\n" <<
264 GetItemLink(r_item3, player->GetSession()) << "x" << r_count3;
265 creature->Whisper(ss.str().c_str(), LANG_UNIVERSAL, player, false);
266 player->PlayerTalkClass->SendCloseGossip();
267 return;
268 }
269 if (r_item1 != 0 && r_item2 != 0 && r_item3 == 0) //2 items
270 {
271 ss << "To create " << GetItemLink(item, player->GetSession()) << "x" << count << " (" << name << ") required:\n" <<
272 GetItemLink(r_item1, player->GetSession()) << "x" << r_count1 << "\n" <<
273 GetItemLink(r_item2, player->GetSession()) << "x" << r_count2;
274 creature->Whisper(ss.str().c_str(), LANG_UNIVERSAL, player, false);
275 player->PlayerTalkClass->SendCloseGossip();
276 return;
277 }
278 if (r_item1 != 0 && r_item2 == 0) //1 item
279 {
280 ss << "To create " << GetItemLink(item, player->GetSession()) << "x" << count << " (" << name << ") required:\n" <<
281 GetItemLink(r_item1, player->GetSession()) << "x" << r_count1;
282 creature->Whisper(ss.str().c_str(), LANG_UNIVERSAL, player, false);
283 player->PlayerTalkClass->SendCloseGossip();
284 return;
285 }
286 return;
287 }
288
289
290 //TODO: Fix if item doesn't exists
291 std::string NPC_Crafter::GetItemLink(uint32 entry, WorldSession* session) const
292 {
293 const ItemTemplate* temp = sObjectMgr->GetItemTemplate(entry);
294 int loc_idx = session->GetSessionDbLocaleIndex();
295 std::string name = temp->Name1;
296 if (ItemLocale const* il = sObjectMgr->GetItemLocale(entry))
297 ObjectMgr::GetLocaleString(il->Name, loc_idx, name);
298
299 std::ostringstream oss;
300 oss << "|c" << std::hex << ItemQualityColors[temp->Quality] << std::dec <<
301 "|Hitem:" << entry << ":0:0:0:0:0:0:0:0:0|h[" << name << "]|h|r";
302
303 return oss.str();
304 }
305
306 bool OnGossipHello(Player* player, Creature* creature)
307 {
308 player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TRAINER, "Create", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1, "Input name of recipe", 0, 1);
309 player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_CHAT, "Required reagents", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2, "Input name of recipe", 0, 1);
310 //player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "TEST", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
311 player->ADD_GOSSIP_ITEM(GOSSIP_ICON_TALK, "Выйти", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
312 player->PlayerTalkClass->SendGossipMenu(1, creature->GetGUID());
313 return true;
314 }
315
316 bool OnGossipSelectCode(Player* player, Creature* creature, uint32 sender, uint32 action, const char* code)
317 {
318 player->PlayerTalkClass->ClearMenus();
319 switch (action)
320 {
321
322 case GOSSIP_ACTION_INFO_DEF + 1:
323 Zapros(player, creature, code);
324 break;
325
326 case GOSSIP_ACTION_INFO_DEF + 2:
327 Info(player, creature, code);
328 break;
329
330 }
331 return true;
332 }
333
334 bool OnGossipSelect(Player *player, Creature * creature, uint32 sender, uint32 action)
335 {
336 player->PlayerTalkClass->ClearMenus();
337 switch (action)
338 {
339
340 case GOSSIP_ACTION_INFO_DEF + 3:
341 //NEED FIX FOR THIS
342 //creature->Whisper(GetItemLink(0, player->GetSession()), LANG_UNIVERSAL, player, false);
343 break;
344
345 case GOSSIP_ACTION_INFO_DEF + 4:
346 player->PlayerTalkClass->SendCloseGossip();
347 break;
348
349 }
350 return true;
351 }
352
353};
354
355void AddSC_NPC_Crafter()
356{
357 new NPC_Crafter();
358
359}
360
361
362
363
364
365
366
367
368////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////SQL FOR
369THIS////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
370
371
372/*
373SQLyog Ultimate v10.42
374MySQL - 5.5.9-log : Database - world
375*********************************************************************
376*/
377
378
379/*!40101 SET NAMES utf8 */;
380
381/*!40101 SET SQL_MODE=''*/;
382
383/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
384/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
385/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
386/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
387CREATE DATABASE /*!32312 IF NOT EXISTS*/`world` /*!40100 DEFAULT CHARACTER SET latin1 */;
388
389USE `world`;
390
391/*Table structure for table `craft_system` */
392
393DROP TABLE IF EXISTS `craft_system`;
394
395CREATE TABLE `craft_system` (
396 `name` longtext NOT NULL COMMENT 'Craft item name',
397 `item` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Craft item entry',
398 `count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Craft count',
399 `r_item1` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Reagent 1 entry',
400 `r_count1` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Reagent 1 count',
401 `r_item2` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Reagent 2 entry',
402 `r_count2` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Reagent 2 count',
403 `r_item3` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Reagent 3 entry',
404 `r_count3` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Reagent 3 count',
405 `r_item4` int(10) unsigned NOT NULL DEFAULT '0',
406 `r_count4` int(10) unsigned NOT NULL DEFAULT '0',
407 `r_item5` int(10) unsigned NOT NULL DEFAULT '0',
408 `r_count5` int(10) unsigned NOT NULL DEFAULT '0'
409) ENGINE=InnoDB DEFAULT CHARSET=utf8;
410
411/*Data for the table `craft_system` */
412
413insert into `craft_system`(`name`,`item`,`count`,`r_item1`,`r_count1`,`r_item2`,`r_count2`,`r_item3`,`r_count3`,`r_item4`,`r_count4`,`r_item5`,`r_count5`) values ('test2',38497,1,6652,1,32595,2,0,0,0,0,0,0),('test1',40599,10,33635,1,0,0,0,0,0,0,0,0),('test3',49778,1,32595,1,0,0,0,0,0,0,0,0),('test11',53924,2,11613,3,39450,10,7101,6,50248,4,49984,7),('test4',0,0,0,0,0,0,0,0,0,0,0,0),('string1',2550,1,33635,1,0,0,0,0,0,0,0,0);
414
415/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
416/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
417/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
418/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;