[1130] Database Query Audit is now at 90 percent with this commit.
[mangos-git.git] / src / game / Mail.cpp
blobeebe1e62521bb1a40f02670ed6cc44412db89c91
1 /*
2 * Copyright (C) 2005,2006 MaNGOS <http://www.mangosproject.org/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program 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.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "WorldPacket.h"
20 #include "WorldSession.h"
21 #include "Opcodes.h"
22 #include "Log.h"
23 #include "Chat.h"
24 #include "World.h"
25 #include "ObjectMgr.h"
26 #include "Player.h"
27 #include "UpdateMask.h"
28 #include "Unit.h"
30 void WorldSession::HandleSendMail(WorldPacket & recv_data )
32 time_t base = time(NULL);
33 time_t etime = base + (30 * 3600);
34 WorldPacket data;
35 uint64 sender,item;
36 std::string receiver,subject,body;
37 uint32 unk1,unk2,money,COD,mID;
38 recv_data >> sender;
39 recv_data >> receiver >> subject >> body;
40 recv_data >> unk1 >> unk2;
41 recv_data >> item;
42 recv_data >> money >> COD;
44 sLog.outString("Player %u is sending mail to %s with subject %s and body %s includes item %u and %u copper and %u COD copper",GUID_LOPART(sender),receiver.c_str(),subject.c_str(),body.c_str(),GUID_LOPART(item),money,COD);
45 mID = objmgr.GenerateMailID();
47 Player* pl = GetPlayer();
49 WorldPacket tmpData;
50 uint32 tmpMoney = pl->GetUInt32Value(PLAYER_FIELD_COINAGE);
52 if (tmpMoney - money < 30)
54 tmpData.Initialize(SMSG_SEND_MAIL_RESULT);
55 tmpData << uint32(0);
56 tmpData << uint32(0);
57 tmpData << uint32(3);
58 SendPacket(&tmpData);
60 else
63 QueryResult *result = sDatabase.PQuery("SELECT `guid` FROM `character` WHERE `name` = '%s';", receiver.c_str());
65 Player *receive = objmgr.GetPlayer(receiver.c_str());
66 uint64 rc = objmgr.GetPlayerGUIDByName(receiver.c_str());
67 if (result)
69 delete result;
70 data.Initialize(SMSG_SEND_MAIL_RESULT);
71 data << uint32(0);
72 data << uint32(0);
73 data << uint32(0);
74 SendPacket(&data);
76 if (item != 0)
78 //uint32 slot = pl->GetSlotByItemGUID(item);
79 uint8 bag,slot;
80 pl->GetSlotByItemGUID(item,bag,slot);
81 //Item *it = pl->GetItemBySlot((uint8)slot);
82 Item *it = pl->GetItemBySlot(bag,(uint8)slot);
84 objmgr.AddMItem(it);
86 std::stringstream ss;
87 ss << "INSERT INTO `mail_item` (`guid`,`data`) VALUES ("
88 << it->GetGUIDLow() << ", '";
89 for(uint16 i = 0; i < it->GetValuesCount(); i++ )
91 ss << it->GetUInt32Value(i) << " ";
93 ss << "' )";
94 sDatabase.Execute( ss.str().c_str() );
96 //pl->RemoveItemFromSlot((uint8)slot);
97 pl->RemoveItemFromSlot(bag,(uint8)slot);
99 uint32 playerGold = pl->GetUInt32Value(PLAYER_FIELD_COINAGE);
100 pl->SetUInt32Value( PLAYER_FIELD_COINAGE, playerGold - 30 - money );
102 if (receive)
104 Mail* m = new Mail;
105 m->messageID = mID;
106 m->sender = pl->GetGUIDLow();
107 m->receiver = GUID_LOPART(rc);
108 m->subject = subject;
109 m->body = body;
110 m->item = GUID_LOPART(item);
111 m->money = money;
112 m->time = etime;
113 m->COD = 0;
114 m->checked = 0;
115 receive->AddMail(m);
117 data.Initialize(SMSG_RECEIVED_MAIL);
118 data << uint32(0);
119 SendPacket(&data);
120 receive->GetSession()->SendPacket(&data);
123 sDatabase.PExecute("DELETE FROM `mail` WHERE `id` = '%u'",mID);
124 sDatabase.PExecute("INSERT INTO `mail` (`id`,`sender`,`receiver`,`subject`,`body`,`item`,`time`,`money`,`cod`,`checked`) VALUES ('%u', '%u', '%u', '%s', '%s', '%u', '%u', '%u', '%u', '%u');", mID, pl->GetGUIDLow(), GUID_LOPART(rc), subject.c_str(), body.c_str(), GUID_LOPART(item), (long)etime, money, 0, 0);
127 else
129 data.Initialize(SMSG_SEND_MAIL_RESULT);
130 data << uint32(0);
131 data << uint32(0);
132 data << uint32(4);
133 SendPacket(&data);
138 void WorldSession::HandleMarkAsRead(WorldPacket & recv_data )
140 uint64 mailbox;
141 uint32 message;
142 recv_data >> mailbox;
143 recv_data >> message;
144 Player *pl = GetPlayer();
145 Mail *m = pl->GetMail(message);
146 m->checked = 1;
147 m->time = time(NULL) + (3 * 3600);
148 pl->AddMail(m);
151 void WorldSession::HandleMailDelete(WorldPacket & recv_data )
153 uint64 mailbox;
154 uint32 message;
155 WorldPacket data;
156 recv_data >> mailbox;
157 recv_data >> message;
158 Player *pl = GetPlayer();
159 Mail *m = pl->GetMail(message);
160 if (m->item != 0)
162 objmgr.RemoveMItem(m->item);
164 pl->RemoveMail(message);
166 data.Initialize(SMSG_SEND_MAIL_RESULT);
167 data << uint32(message);
168 data << uint32(4);
169 data << uint32(0);
170 SendPacket(&data);
174 void WorldSession::HandleReturnToSender(WorldPacket & recv_data )
176 uint64 mailbox;
177 uint32 message;
178 WorldPacket data;
179 recv_data >> mailbox;
180 recv_data >> message;
181 Player *pl = GetPlayer();
182 Mail *m = pl->GetMail(message);
183 m->receiver = m->sender;
184 m->sender = pl->GetGUIDLow();
185 m->time = sWorld.GetGameTime() + (30 * 3600);
186 m->checked = 0;
187 pl->RemoveMail(message);
189 data.Initialize(SMSG_SEND_MAIL_RESULT);
190 data << uint32(message);
191 data << uint32(3);
192 data << uint32(0);
193 SendPacket(&data);
195 uint64 rc = m->receiver;
196 std::string name;
197 objmgr.GetPlayerNameByGUID(rc,name);
198 Player *receive = objmgr.GetPlayer(name.c_str());
199 if (receive)
201 receive->AddMail(m);
204 sDatabase.PExecute("DELETE FROM `mail` WHERE `id` = '%u'",m->messageID);
205 sDatabase.PExecute("INSERT INTO `mail` (`id`,`sender`,`receiver`,`subject`,`body`,`item`,`time`,`money`,`cod`,`checked`) VALUES ('%u', '%u','%u', '%s', '%s', '%u','%u','%u','%u','%u');", m->messageID, pl->GetGUIDLow(), m->receiver, m->subject.c_str(), m->body.c_str(), m->item, (long)m->time, m->money, 0, m->checked);
209 void WorldSession::HandleTakeItem(WorldPacket & recv_data )
211 uint64 mailbox;
212 uint32 message;
213 WorldPacket data;
214 recv_data >> mailbox;
215 recv_data >> message;
216 Player* pl = GetPlayer();
217 Mail* m = pl->GetMail(message);
218 Item *it = objmgr.GetMItem(m->item);
220 GetPlayer()->AddNewItem(0,NULL_SLOT,it->GetEntry(),it->GetCount(), false, false);
221 /* still needs some condition so that if item can not be received, both mail and
222 mailed_items to stay till delete or return, otherwise it's dumped, also a client message */
224 m->item = 0;
225 pl->AddMail(m);
228 m->item = 0;
229 pl->AddMail(m);
230 for(i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++)
232 if (GetPlayer()->GetItemBySlot(i) == NULL)
234 slot = i;
235 break;
238 it->SetUInt64Value(ITEM_FIELD_CONTAINED,pl->GetGUID());
239 it->SetUInt64Value(ITEM_FIELD_OWNER,pl->GetGUID());
240 GetPlayer()->AddItemToSlot(slot, it);
242 objmgr.RemoveMItem(it->GetGUIDLow());
243 data.Initialize(SMSG_SEND_MAIL_RESULT);
244 data << uint32(message);
245 data << uint32(2);
246 data << uint32(0);
247 SendPacket(&data);
250 void WorldSession::HandleTakeMoney(WorldPacket & recv_data )
252 WorldPacket data;
253 uint64 mailbox;
254 uint32 id;
255 recv_data >> mailbox;
256 recv_data >> id;
257 Player *pl = GetPlayer();
258 Mail* m = pl->GetMail(id);
259 uint32 money = pl->GetUInt32Value(PLAYER_FIELD_COINAGE);
261 data.Initialize(SMSG_SEND_MAIL_RESULT);
262 data << uint32(id);
263 data << uint32(1);
264 data << uint32(0);
265 SendPacket(&data);
267 pl->SetUInt32Value(PLAYER_FIELD_COINAGE,money + m->money);
268 m->money = 0;
269 pl->AddMail(m);
273 void WorldSession::HandleGetMail(WorldPacket & recv_data )
275 uint32 info;
276 recv_data >> info;
277 WorldPacket data;
278 Player* pl = GetPlayer();
279 data.Initialize(SMSG_MAIL_LIST_RESULT);
280 data << uint8(pl->GetMailSize());
281 std::list<Mail*>::iterator itr;
282 for (itr = pl->GetmailBegin(); itr != pl->GetmailEnd();itr++)
284 data << uint32((*itr)->messageID);
285 data << uint8(0);
286 data << uint32((*itr)->sender);
287 data << uint32(0);
289 data << (*itr)->subject.c_str();
290 if((*itr)->body.c_str()!=NULL)
291 data << uint32((*itr)->messageID);
292 else
293 data << uint32(0);
294 data << uint32(0);
295 data << uint32(41);
296 if ((*itr)->item != 0)
298 Item* i = objmgr.GetMItem((*itr)->item);
299 data << uint32(i->GetUInt32Value(OBJECT_FIELD_ENTRY));
301 else
303 data << uint32(0);
305 data << uint32(0);
306 data << uint32(0);
307 data << uint32(0);
308 data << uint8(1);
309 data << uint32(0xFFFFFFFF);
310 data << uint32(0);
311 data << uint32(0);
312 data << uint32((*itr)->money);
313 data << uint32((*itr)->COD);
314 data << uint32((*itr)->checked);
316 data << float(((*itr)->time - time(NULL)) / 3600);
318 SendPacket(&data);
321 extern char *fmtstring( char *format, ... );
323 uint32 GetItemGuidFromDisplayID ( uint32 displayID, Player* pl )
326 uint8 i = 0;
327 Item * srcitem;
329 for (i = EQUIPMENT_SLOT_START; i < BANK_SLOT_BAG_END; i++)
331 srcitem = pl->GetItemBySlot(i);
333 if (srcitem)
335 if (srcitem->GetProto()->DisplayInfoID == displayID)
337 break;
342 if( i >= BANK_SLOT_BAG_END )
344 QueryResult *result = sDatabase.PQuery( "SELECT `entry` FROM `item_template` WHERE `displayid`='%u'", displayID );
346 if( !result )
348 return (uint8)-1;
351 uint32 id = (*result)[0].GetUInt32();
352 return id;
353 delete result;
356 return srcitem->GetProto()->ItemId;
359 extern char *GetInventoryImageFilefromObjectClass(uint32 classNum, uint32 subclassNum, uint32 type, uint32 DisplayID);
361 bool WorldSession::SendItemInfo( uint32 itemid, WorldPacket data )
363 // int i;
364 Player* pl = GetPlayer();
365 uint32 realID = GetItemGuidFromDisplayID(itemid, pl);
366 char const *itemInfo;
367 bool resist_added = false;
368 bool names_added = false;
370 if (realID < 0)
372 sLog.outError( "WORLD: Unknown item id 0x%.8X", realID );
373 return false;
376 ItemPrototype *itemProto = objmgr.GetItemPrototype(realID);
378 if(!itemProto)
380 sLog.outError( "WORLD: Unknown item id 0x%.8X", realID );
381 return false;
384 sLog.outDebug( "WORLD: Real item id is %u. Name %s.", realID, itemProto->Name1 );
386 data.Initialize(SMSG_ITEM_TEXT_QUERY_RESPONSE);
387 data << itemid;
389 itemInfo = fmtstring("<HTML>\n<BODY>\n");
391 itemInfo = fmtstring("%s</P></BODY>\n</HTML>\n", itemInfo);
393 data << itemInfo;
394 data << uint32(0);
395 SendPacket(&data);
397 return true;
400 void WorldSession::HandleItemTextQuery(WorldPacket & recv_data )
402 WorldPacket data;
403 uint32 mailguid;
404 uint64 unk1;
406 recv_data >> mailguid >> unk1;
408 Player* pl = GetPlayer();
410 Mail *itr;
412 itr = pl->GetMail(mailguid);
413 if(itr)
415 sLog.outDebug("We got mailguid: %d with unk: %d", mailguid, unk1);
417 data.Initialize(SMSG_ITEM_TEXT_QUERY_RESPONSE);
418 data << mailguid;
419 data << itr->body.c_str();
420 data << uint32(0);
421 SendPacket(&data);
424 else
426 QueryResult *result = sDatabase.PQuery( "SELECT * FROM `item_page` WHERE `id` = '%u'", mailguid );
428 if( result )
430 data.Initialize(SMSG_ITEM_TEXT_QUERY_RESPONSE);
431 data << mailguid;
433 uint32 nextpage = mailguid;
435 while (nextpage)
437 data << (*result)[1].GetString();
438 nextpage = (*result)[2].GetUInt32();
439 data << nextpage;
442 data << uint32(0);
443 SendPacket(&data);
444 delete result;
445 return;
448 if (!SendItemInfo( mailguid, data ))
450 data.Initialize(SMSG_ITEM_TEXT_QUERY_RESPONSE);
451 data << mailguid;
453 data << "There is no info for this item.";
455 data << uint32(0);
456 SendPacket(&data);
461 void WorldSession::HandleMailCreateTextItem(WorldPacket & recv_data )
463 uint32 unk1,unk2,mailid;
465 recv_data >> unk1 >> unk2 >> mailid;
467 sLog.outString("HandleMailCreateTextItem unk1=%d,unk2=%d,mailid=%d",unk1,unk2,mailid);
469 uint32 sbit2=5;
470 bool slotfree=false;
471 WorldPacket Data;
473 Item *item = new Item();
475 item->Create(objmgr.GenerateLowGuid(HIGHGUID_ITEM), 889, GetPlayer());
476 item->SetUInt32Value( ITEM_FIELD_ITEM_TEXT_ID , mailid );
478 Player* pl = GetPlayer();
479 GetPlayer()->AddItemToInventory(0, NULL_SLOT,item,false,false,false);
482 for(i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++)
484 if (GetPlayer()->GetItemBySlot(i) == NULL)
486 slot = i;
487 slotfree=true;
488 break;
491 if (slotfree)
493 Item *item = new Item();
495 item->Create(objmgr.GenerateLowGuid(HIGHGUID_ITEM), 889, GetPlayer(), 1);
496 item->SetUInt32Value( ITEM_FIELD_ITEM_TEXT_ID , mailid );
498 GetPlayer()->AddItemToSlot( slot, item );
500 Data.Initialize(SMSG_SEND_MAIL_RESULT);
501 Data << uint32(mailid);
502 Data << uint32(sbit2);
503 Data << uint32(0);
504 SendPacket(&Data);
506 else
508 Data.Initialize(SMSG_SEND_MAIL_RESULT);
509 Data << uint32(mailid);
510 Data << uint32(0);
511 Data << uint32(1);
512 SendPacket(&Data);
518 void WorldSession::HandleMsgQueryNextMailtime(WorldPacket & recv_data )
521 WorldPacket Data;
522 bool checkmail=false;
523 Player *pl=GetPlayer();
525 std::list<Mail*>::iterator itr;
526 for (itr = pl->GetmailBegin(); itr != pl->GetmailEnd();itr++)
528 if(!(*itr)->checked)
530 checkmail = true;
531 break;
535 if ( checkmail )
537 Data.Initialize(MSG_QUERY_NEXT_MAIL_TIME);
538 Data << uint32(0);
539 SendPacket(&Data);
541 else
543 Data.Initialize(MSG_QUERY_NEXT_MAIL_TIME);
544 Data << uint8(0x00);
545 Data << uint8(0xC0);
546 Data << uint8(0xA8);
547 Data << uint8(0xC7);
548 SendPacket(&Data);