Advertisement
Guest User

Untitled

a guest
Aug 20th, 2019
308
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 30.60 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include "../../libgame/include/grid.h"
  3. #include "constants.h"
  4. #include "utils.h"
  5. #include "config.h"
  6. #include "offline_shop.h"
  7. #include "desc.h"
  8. #include "desc_manager.h"
  9. #include "char.h"
  10. #include "char_manager.h"
  11. #include "item.h"
  12. #include "item_manager.h"
  13. #include "buffer_manager.h"
  14. #include "packet.h"
  15. #include "log.h"
  16. #include "db.h"
  17. #include "questmanager.h"
  18. #include "mob_manager.h"
  19. #include "locale_service.h"
  20. #include "desc_client.h"
  21. #include "group_text_parse_tree.h"
  22. #include <boost/algorithm/string/predicate.hpp>
  23. #include <cctype>
  24. #include "offlineshop_manager.h"
  25. #include "p2p.h"
  26. #include "entity.h"
  27. #include "sectree_manager.h"
  28. #include "offlineshop_config.h"
  29.  
  30. extern bool offlineshop_map_allow_find(int mapIndex);
  31.  
  32. COfflineShopManager::COfflineShopManager()
  33. {
  34. }
  35.  
  36.  
  37. COfflineShopManager::~COfflineShopManager()
  38. {
  39. }
  40.  
  41. struct FFindOfflineShop
  42. {
  43. const char * szName;
  44.  
  45. DWORD dwVID, dwRealOwner;
  46. FFindOfflineShop(const char * c_szName) : szName(c_szName), dwVID(0), dwRealOwner(0) {};
  47.  
  48. void operator()(LPENTITY ent)
  49. {
  50. if (!ent)
  51. return;
  52.  
  53. if (ent->IsType(ENTITY_CHARACTER))
  54. {
  55. LPCHARACTER ch = (LPCHARACTER)ent;
  56. if (ch->IsOfflineShopNPC() && !strcmp(szName, ch->GetName()))
  57. {
  58. dwVID = ch->GetVID();
  59. dwRealOwner = ch->GetOfflineShopRealOwner();
  60. M2_DESTROY_CHARACTER(ch);
  61. }
  62. }
  63. }
  64. };
  65.  
  66. bool COfflineShopManager::StartShopping(LPCHARACTER pkChr, LPCHARACTER pkChrShopKeeper)
  67. {
  68. if (pkChr->GetOfflineShopOwner() == pkChrShopKeeper)
  69. return false;
  70.  
  71. if (pkChrShopKeeper->IsPC())
  72. return false;
  73.  
  74. sys_log(0, "OFFLINE_SHOP: START: %s", pkChr->GetName());
  75. return true;
  76. }
  77.  
  78. LPOFFLINESHOP COfflineShopManager::CreateOfflineShop(LPCHARACTER npc, DWORD dwOwnerPID)
  79. {
  80. if(!npc)
  81. return NULL;
  82.  
  83. if (FindOfflineShop(npc->GetVID()))
  84. return NULL;
  85.  
  86. if(FindMyOfflineShop(dwOwnerPID))
  87. {
  88. m_Map_pkOfflineShopByNPC2.erase(dwOwnerPID);
  89. }
  90.  
  91. LPOFFLINESHOP pkOfflineShop = M2_NEW COfflineShop;
  92. pkOfflineShop->SetOfflineShopNPC(npc);
  93.  
  94. m_map_pkOfflineShopByNPC.insert(TShopMap::value_type(npc->GetVID(), pkOfflineShop));
  95. m_Map_pkOfflineShopByNPC2.insert(TOfflineShopMap::value_type(dwOwnerPID, npc->GetVID()));
  96. return pkOfflineShop;
  97. }
  98.  
  99. LPOFFLINESHOP COfflineShopManager::FindOfflineShop(DWORD dwVID)
  100. {
  101. TShopMap::iterator it = m_map_pkOfflineShopByNPC.find(dwVID);
  102.  
  103. if (it == m_map_pkOfflineShopByNPC.end())
  104. return NULL;
  105.  
  106. return it->second;
  107. }
  108.  
  109. void COfflineShopManager::DestroyOfflineShop(LPCHARACTER ch, DWORD dwVID, bool bDestroyAll)
  110. {
  111. if (ch == NULL)
  112. return;
  113.  
  114. if (g_bOfflineShopMapAllowLimit)
  115. {
  116. if (!offlineshop_map_allow_find(ch->GetMapIndex()))
  117. {
  118. ch->ChatPacket(CHAT_TYPE_INFO, "Nie mozesz zamknac sklepu offline w tej lokalizacji ! Sklep mozesz zamknac tylko w M1");
  119. return;
  120. }
  121. }
  122.  
  123. //sys_err("Inchidere shop %s VID shop %d", ch->GetName(), dwVID);
  124.  
  125. if (dwVID == 0)
  126. {
  127. std::auto_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT mapIndex FROM %soffline_shop_npc WHERE owner_id = %u", get_table_postfix(), ch->GetPlayerID()));
  128. if (pMsg->Get()->uiNumRows == 0)
  129. {
  130. ch->ChatPacket(CHAT_TYPE_INFO, "Nie masz zadnego otwartego sklepu offline!");
  131. return;
  132. }
  133.  
  134. ch->ChatPacket(CHAT_TYPE_INFO, "Nie mozesz zamknąc sklepu offline z innego kanalu.");
  135.  
  136. // MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
  137.  
  138. // long lMapIndex = 0;
  139. // str_to_number(lMapIndex, row[0]); // daca era si row[1]
  140.  
  141. // TPacketGGRemoveOfflineShop p;
  142. // p.bHeader = HEADER_GG_REMOVE_OFFLINE_SHOP;
  143. // p.lMapIndex = lMapIndex;
  144.  
  145. // // Set offline shop name
  146. // char szNpcName[CHARACTER_NAME_MAX_LEN + 1];
  147. // snprintf(szNpcName, sizeof(szNpcName), "%s", ch->GetName());
  148. // strlcpy(p.szNpcName, szNpcName, sizeof(p.szNpcName));
  149. // // End Of Set offline shop name
  150.  
  151. // P2P_MANAGER::instance().Send(&p, sizeof(TPacketGGRemoveOfflineShop));
  152. // Giveback(ch);
  153. // --g_shopCount[lMapIndex];
  154. }
  155. else
  156. {
  157. LPCHARACTER npc;
  158. if (!ch)
  159. npc = CHARACTER_MANAGER::instance().Find(dwVID);
  160. else
  161. npc = CHARACTER_MANAGER::instance().Find(FindMyOfflineShop(ch->GetPlayerID()));
  162.  
  163. if (!npc)
  164. {
  165. std::auto_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT mapIndex,channel FROM %soffline_shop_npc WHERE owner_id = %u", get_table_postfix(), ch->GetPlayerID()));
  166. if (pMsg->Get()->uiNumRows == 0)
  167. {
  168. ch->ChatPacket(CHAT_TYPE_INFO, "Nie masz zadnego otwartego sklepu offline!");
  169. return;
  170. }
  171.  
  172. MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
  173.  
  174. long lMapIndex = 0;
  175. str_to_number(lMapIndex, row[0]);
  176.  
  177. BYTE bChannel = 0;
  178. str_to_number(bChannel, row[1]);
  179.  
  180. //sys_err("!npc canal server %d , canal shop %d", g_bChannel, bChannel);
  181.  
  182. if (g_bChannel != bChannel)
  183. {
  184. ch->ChatPacket(CHAT_TYPE_INFO, "Musisz znajdowac się na %d kanale aby zamknac sklep offline. Aktualnie znajdujesz sie na %d kanale.", bChannel, g_bChannel);
  185. return;
  186. }
  187.  
  188. char szName[CHARACTER_NAME_MAX_LEN + 1];
  189. snprintf(szName, sizeof(szName), "%s", ch->GetName());
  190. LPSECTREE_MAP pMap = SECTREE_MANAGER::instance().GetMap(lMapIndex);
  191. FFindOfflineShop offlineShop(szName);
  192. pMap->for_each(offlineShop);
  193.  
  194. if (bDestroyAll)
  195. {
  196. --g_shopCount[lMapIndex];
  197. Giveback(ch);
  198. m_map_pkOfflineShopByNPC.erase(offlineShop.dwVID);
  199. m_Map_pkOfflineShopByNPC2.erase(offlineShop.dwRealOwner);
  200. DBManager::instance().DirectQuery("DELETE FROM %soffline_shop_npc WHERE owner_id = %u", get_table_postfix(), offlineShop.dwRealOwner);
  201. return;
  202. }
  203. }
  204.  
  205. LPOFFLINESHOP pkOfflineShop;
  206. if (!ch)
  207. pkOfflineShop = FindOfflineShop(dwVID);
  208. else
  209. pkOfflineShop = FindOfflineShop(FindMyOfflineShop(ch->GetPlayerID()));
  210.  
  211. if (!pkOfflineShop)
  212. return;
  213.  
  214. //sys_err("npc canal server %d , canal shop %d", g_bChannel, npc->GetOfflineShopChannel());
  215.  
  216. if (npc->GetOfflineShopChannel() != g_bChannel)
  217. {
  218. ch->ChatPacket(CHAT_TYPE_INFO, "Musisz znajdowac się na %d kanale aby zamknac sklep offline. Aktualnie znajdujesz sie na %d kanale.", npc->GetOfflineShopChannel(), g_bChannel);
  219. return;
  220. }
  221.  
  222. if (bDestroyAll)
  223. {
  224. Giveback(ch);
  225. pkOfflineShop->Destroy(npc);
  226. }
  227.  
  228. m_map_pkOfflineShopByNPC.erase(npc->GetVID());
  229. m_Map_pkOfflineShopByNPC2.erase(npc->GetOfflineShopRealOwner());
  230. M2_DELETE(pkOfflineShop);
  231.  
  232. if (npc != NULL)
  233. {
  234. --g_shopCount[npc->GetMapIndex()];
  235. }
  236. }
  237. }
  238.  
  239. void COfflineShopManager::Giveback(LPCHARACTER ch)
  240. {
  241. if (!ch)
  242. return;
  243.  
  244. char szQuery[2048];
  245. if (g_bOfflineShopSocketMax == 3)
  246. {
  247. snprintf(szQuery, sizeof(szQuery), "SELECT pos,count,vnum,"
  248. "socket0,socket1,socket2, attrtype0, attrvalue0, attrtype1, attrvalue1, attrtype2, attrvalue2, attrtype3, attrvalue3, attrtype4, attrvalue4, attrtype5, attrvalue5, attrtype6, attrvalue6 FROM %soffline_shop_item WHERE owner_id = %u", get_table_postfix(), ch->GetPlayerID());
  249. }
  250. else if(g_bOfflineShopSocketMax == 3)
  251. {
  252. snprintf(szQuery, sizeof(szQuery), "SELECT pos,count,vnum,"
  253. "socket0,socket1,socket2, attrtype0, attrvalue0, attrtype1, attrvalue1, attrtype2, attrvalue2, attrtype3, attrvalue3, attrtype4, attrvalue4, attrtype5, attrvalue5, attrtype6, attrvalue6 FROM %soffline_shop_item WHERE owner_id = %u", get_table_postfix(), ch->GetPlayerID());
  254. }
  255. else if(g_bOfflineShopSocketMax == 3)
  256. {
  257. snprintf(szQuery, sizeof(szQuery), "SELECT pos,count,vnum,"
  258. "socket0,socket1,socket2, attrtype0, attrvalue0, attrtype1, attrvalue1, attrtype2, attrvalue2, attrtype3, attrvalue3, attrtype4, attrvalue4, attrtype5, attrvalue5, attrtype6, attrvalue6 FROM %soffline_shop_item WHERE owner_id = %u", get_table_postfix(), ch->GetPlayerID());
  259. }
  260. else if(g_bOfflineShopSocketMax == 3)
  261. {
  262. snprintf(szQuery, sizeof(szQuery), "SELECT pos,count,vnum,"
  263. "socket0,socket1,socket2, attrtype0, attrvalue0, attrtype1, attrvalue1, attrtype2, attrvalue2, attrtype3, attrvalue3, attrtype4, attrvalue4, attrtype5, attrvalue5, attrtype6, attrvalue6 FROM %soffline_shop_item WHERE owner_id = %u", get_table_postfix(), ch->GetPlayerID());
  264. }
  265.  
  266. std::auto_ptr<SQLMsg> pMsg(DBManager::Instance().DirectQuery(szQuery));
  267. if (pMsg->Get()->uiNumRows == 0)
  268. {
  269. sys_err("COfflineShopManager::GiveBack - There is nothing for this player [%s]", ch->GetName());
  270. return;
  271. }
  272.  
  273. MYSQL_ROW row;
  274. while (NULL != (row = mysql_fetch_row(pMsg->Get()->pSQLResult)))
  275. {
  276. int cur = 0;
  277.  
  278. TPlayerItem item;
  279. str_to_number(item.pos, row[cur++]);
  280. str_to_number(item.count, row[cur++]);
  281. str_to_number(item.vnum, row[cur++]);
  282.  
  283. // Set Sockets
  284. for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i)
  285. str_to_number(item.alSockets[i], row[cur++]);
  286. // End Of Set Sockets
  287.  
  288. // Set Attributes
  289. for (int i = 0; i < ITEM_ATTRIBUTE_MAX_NUM; ++i)
  290. {
  291. str_to_number(item.aAttr[i].bType, row[cur++]);
  292. str_to_number(item.aAttr[i].sValue, row[cur++]);
  293. }
  294. // End Of Set Attributes
  295.  
  296. LPITEM pItem = ITEM_MANAGER::instance().CreateItem(item.vnum, item.count);
  297. if (pItem)
  298. {
  299. int iEmptyPos = 0;
  300.  
  301. if (pItem->IsDragonSoul())
  302. iEmptyPos = ch->GetEmptyDragonSoulInventory(pItem);
  303. else
  304. iEmptyPos = ch->GetEmptyInventory(pItem->GetSize());
  305.  
  306. if (iEmptyPos < 0)
  307. {
  308. ch->ChatPacket(CHAT_TYPE_INFO, "Nie masz wolnych miejsc w sklepie !");
  309. return;
  310. }
  311.  
  312. pItem->SetSockets(item.alSockets);
  313. pItem->SetAttributes(item.aAttr);
  314.  
  315. if (pItem->IsDragonSoul())
  316. pItem->AddToCharacter(ch, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyPos));
  317. else
  318. pItem->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos));
  319.  
  320. ch->ChatPacket(CHAT_TYPE_INFO, "Otrzymales %s yang ze sklepu offline.", pItem->GetName());
  321. DBManager::instance().DirectQuery("DELETE FROM %soffline_shop_item WHERE owner_id = %u and pos = %d", get_table_postfix(), ch->GetPlayerID(), item.pos);
  322. }
  323. }
  324. }
  325.  
  326. void COfflineShopManager::Giveback2(LPCHARACTER ch)
  327. {
  328. if (!ch)
  329. return;
  330.  
  331. char szQuery[2048];
  332.  
  333. snprintf(szQuery, sizeof(szQuery), "SELECT pos,count,vnum,"
  334. "socket0,socket1,socket2, attrtype0, attrvalue0, attrtype1, attrvalue1, attrtype2, attrvalue2, attrtype3, attrvalue3, attrtype4, attrvalue4, attrtype5, attrvalue5, attrtype6, attrvalue6 FROM %soffline_shop_item WHERE owner_id = %u", get_table_postfix(), ch->GetPlayerID());
  335.  
  336. std::auto_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery(szQuery));
  337.  
  338. if (pMsg->Get()->uiNumRows == 0)
  339. return;
  340.  
  341. MYSQL_ROW row;
  342. while (NULL != (row = mysql_fetch_row(pMsg->Get()->pSQLResult)))
  343. {
  344. int cur = 0;
  345.  
  346. TPlayerItem item;
  347. str_to_number(item.pos, row[cur++]);
  348. str_to_number(item.count, row[cur++]);
  349. str_to_number(item.vnum, row[cur++]);
  350.  
  351. // Set Sockets
  352. for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i)
  353. str_to_number(item.alSockets[i], row[cur++]);
  354. // End Of Set Sockets
  355.  
  356. // Set Attributes
  357. for (int i = 0; i < ITEM_ATTRIBUTE_MAX_NUM; ++i)
  358. {
  359. str_to_number(item.aAttr[i].bType, row[cur++]);
  360. str_to_number(item.aAttr[i].sValue, row[cur++]);
  361. }
  362. // End Of Set Attributes
  363.  
  364. LPITEM pItem = ITEM_MANAGER::instance().CreateItem(item.vnum, item.count);
  365. if (pItem)
  366. {
  367. int iEmptyPos = 0;
  368.  
  369. if (pItem->IsDragonSoul())
  370. iEmptyPos = ch->GetEmptyDragonSoulInventory(pItem);
  371. else
  372. iEmptyPos = ch->GetEmptyInventory(pItem->GetSize());
  373.  
  374. if (iEmptyPos < 0)
  375. {
  376. ch->ChatPacket(CHAT_TYPE_INFO, "Nie masz wolnych miejsc w sklepie!");
  377. return;
  378. }
  379.  
  380. pItem->SetSockets(item.alSockets);
  381. pItem->SetAttributes(item.aAttr);
  382. if (pItem->IsDragonSoul())
  383. pItem->AddToCharacter(ch, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyPos));
  384. else
  385. pItem->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos));
  386.  
  387. ch->ChatPacket(CHAT_TYPE_INFO, "Otrzymales %s ze swojego sklepu offline.", pItem->GetName());
  388. DBManager::instance().DirectQuery("DELETE FROM %soffline_shop_item WHERE owner_id = %u and pos = %d", get_table_postfix(), ch->GetPlayerID(), item.pos);
  389. }
  390. }
  391. }
  392.  
  393. void COfflineShopManager::AddItem(LPCHARACTER ch, BYTE bDisplayPos, TItemPos itemPos, long long iPrice)
  394. {
  395. if (!ch)
  396. return;
  397.  
  398. if (quest::CQuestManager::instance().GetEventFlag("block_offline_shop_add_item"))
  399. {
  400. ch->ChatPacket(CHAT_TYPE_INFO, "Dodanie przedmiotu do sklepu offline jest tymczasowo niedostepne.");
  401. return;
  402. }
  403.  
  404. if (g_bOfflineShopMapAllowLimit)
  405. {
  406. if (!offlineshop_map_allow_find(ch->GetMapIndex()))
  407. {
  408. ch->ChatPacket(CHAT_TYPE_INFO, "Nie mozesz dodawac przedmiotow w sklepie offline w tej lokalizacji!");
  409. return;
  410. }
  411. }
  412.  
  413. // Fixed bug 6.21.2015
  414. if (bDisplayPos >= OFFLINE_SHOP_HOST_ITEM_MAX_NUM)
  415. {
  416. sys_err("Overflow offline shop slot count [%s]", ch->GetName());
  417. return;
  418. }
  419. // End Of fixed bug 6.21.2015
  420.  
  421. // Check player has offline shop or not
  422. std::auto_ptr<SQLMsg> pmsg(DBManager::instance().DirectQuery("SELECT COUNT(*) FROM player.offline_shop_npc WHERE owner_id = %u", ch->GetPlayerID()));
  423. MYSQL_ROW row = mysql_fetch_row(pmsg->Get()->pSQLResult);
  424.  
  425. BYTE bResult = 0;
  426. str_to_number(bResult, row[0]);
  427.  
  428. if (!bResult)
  429. {
  430. ch->ChatPacket(CHAT_TYPE_INFO, "You don't have any opened offline shop!");
  431. return;
  432. }
  433. // End Of Check player has offline shop or not
  434.  
  435. if (!itemPos.IsValidItemPosition())
  436. {
  437. ch->ChatPacket(CHAT_TYPE_INFO, "Item position unavailable! Please try again!");
  438. return;
  439. }
  440.  
  441. LPITEM pkItem = ch->GetItem(itemPos);
  442.  
  443. if (!pkItem)
  444. return;
  445.  
  446. // Check
  447. const TItemTable * itemTable = pkItem->GetProto();
  448. if (itemTable && (IS_SET(itemTable->dwAntiFlags, ITEM_ANTIFLAG_GIVE | ITEM_ANTIFLAG_MYSHOP)))
  449. {
  450. ch->ChatPacket(CHAT_TYPE_INFO, "This item can not be sold!");
  451. return;
  452. }
  453.  
  454. if (pkItem->isLocked())
  455. return;
  456.  
  457. if (pkItem->IsEquipped())
  458. {
  459. ch->ChatPacket(CHAT_TYPE_INFO, "Nie możesz sprzedawać wyposażonych przedmiotów!");
  460. return;
  461. }
  462.  
  463. if (iPrice < 0)
  464. {
  465. ch->ChatPacket(CHAT_TYPE_INFO, "The price of a item can not be negative.");
  466. return;
  467. }
  468.  
  469. char szColumns[QUERY_MAX_LEN], szValues[QUERY_MAX_LEN];
  470.  
  471. int iLen = snprintf(szColumns, sizeof(szColumns), "id,owner_id,pos,count,price,vnum"
  472. );
  473.  
  474. int iUpdateLen = snprintf(szValues, sizeof(szValues),
  475. "%u,"
  476. "%u,"
  477. "%d,"
  478. "%u,"
  479. "%lld, "
  480. "%u"
  481. ,
  482. pkItem->GetID(), ch->GetPlayerID(), bDisplayPos, pkItem->GetCount(), iPrice, pkItem->GetVnum()
  483. );
  484.  
  485. if (g_bOfflineShopSocketMax == 3)
  486. {
  487. iLen += snprintf(szColumns + iLen, sizeof(szColumns) - iLen, ",socket0,socket1,socket2");
  488. iUpdateLen += snprintf(szValues + iUpdateLen, sizeof(szValues) - iUpdateLen, ",%ld,%ld,%ld", pkItem->GetSocket(0), pkItem->GetSocket(1), pkItem->GetSocket(2));
  489. }
  490. else if(g_bOfflineShopSocketMax == 3)
  491. {
  492. iLen += snprintf(szColumns + iLen, sizeof(szColumns) - iLen, ",socket0,socket1,socket2");
  493. iUpdateLen += snprintf(szValues + iUpdateLen, sizeof(szValues) - iUpdateLen, ",%ld,%ld,%ld,%ld", pkItem->GetSocket(0), pkItem->GetSocket(1), pkItem->GetSocket(2));
  494. }
  495. else if(g_bOfflineShopSocketMax == 3)
  496. {
  497. iLen += snprintf(szColumns + iLen, sizeof(szColumns) - iLen, ",socket0,socket1,socket2");
  498. iUpdateLen += snprintf(szValues + iUpdateLen, sizeof(szValues) - iUpdateLen, ",%ld,%ld,%ld,%ld,%ld", pkItem->GetSocket(0), pkItem->GetSocket(1), pkItem->GetSocket(2));
  499. }
  500. else if(g_bOfflineShopSocketMax == 3)
  501. {
  502. iLen += snprintf(szColumns + iLen, sizeof(szColumns) - iLen, ",socket0,socket1,socket2");
  503. iUpdateLen += snprintf(szValues + iUpdateLen, sizeof(szValues) - iUpdateLen, ",%ld,%ld,%ld,%ld,%ld,%ld", pkItem->GetSocket(0), pkItem->GetSocket(1), pkItem->GetSocket(2));
  504. }
  505.  
  506. iLen += snprintf(szColumns + iLen, sizeof(szColumns) - iLen, " ,attrtype0, attrvalue0, attrtype1, attrvalue1, attrtype2, attrvalue2, attrtype3, attrvalue3, attrtype4, attrvalue4, attrtype5, attrvalue5, attrtype6, attrvalue6");
  507. iUpdateLen += snprintf(szValues + iUpdateLen, sizeof(szValues) - iUpdateLen, ", %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
  508. pkItem->GetAttributeType(0), pkItem->GetAttributeValue(0),
  509. pkItem->GetAttributeType(1), pkItem->GetAttributeValue(1),
  510. pkItem->GetAttributeType(2), pkItem->GetAttributeValue(2),
  511. pkItem->GetAttributeType(3), pkItem->GetAttributeValue(3),
  512. pkItem->GetAttributeType(4), pkItem->GetAttributeValue(4),
  513. pkItem->GetAttributeType(5), pkItem->GetAttributeValue(5),
  514. pkItem->GetAttributeType(6), pkItem->GetAttributeValue(6)
  515. );
  516.  
  517. LPCHARACTER npc = CHARACTER_MANAGER::instance().Find(FindMyOfflineShop(ch->GetPlayerID()));
  518.  
  519. if (npc)
  520. {
  521. LPOFFLINESHOP pkOfflineShop = npc->GetOfflineShop();
  522.  
  523. if (!pkOfflineShop)
  524. return;
  525.  
  526. char szInsertQuery[QUERY_MAX_LEN];
  527. snprintf(szInsertQuery, sizeof(szInsertQuery), "INSERT INTO %soffline_shop_item (%s) VALUES (%s)", get_table_postfix(), szColumns, szValues);
  528. std::auto_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery(szInsertQuery));
  529. ITEM_MANAGER::instance().RemoveItem(pkItem);
  530.  
  531. pkOfflineShop->BroadcastUpdateItem(bDisplayPos, ch->GetPlayerID());
  532.  
  533. DWORD dwPulse = get_global_time() + 10;
  534. pkOfflineShop->SetActionPulse(dwPulse);
  535.  
  536. LogManager::instance().ItemLog(ch, pkItem, "ADD ITEM OFFLINE SHOP", "");
  537. }
  538. else
  539. ch->ChatPacket(CHAT_TYPE_INFO, "To add an item you need to be on the same channel with your offline shop.Pentru a adauga un item trebuie sa fii pe canalul cu magazinul tau offline.");
  540. }
  541.  
  542. void COfflineShopManager::RemoveItem(LPCHARACTER ch, BYTE bPos)
  543. {
  544. if (!ch)
  545. return;
  546.  
  547. if (quest::CQuestManager::instance().GetEventFlag("block_offline_shop_remove_item"))
  548. {
  549. ch->ChatPacket(CHAT_TYPE_INFO, "Produkty wycofane z sklepu offline są chwilowo niedostepne.");
  550. return;
  551. }
  552.  
  553. if (g_bOfflineShopMapAllowLimit)
  554. {
  555. if (!offlineshop_map_allow_find(ch->GetMapIndex()))
  556. {
  557. ch->ChatPacket(CHAT_TYPE_INFO, "Wyjmowac itemy mozesz tylko w miejscu gdzie znajduje sie twoj shop offline.");
  558. return;
  559. }
  560. }
  561.  
  562. if (bPos >= OFFLINE_SHOP_HOST_ITEM_MAX_NUM)
  563. {
  564. sys_log(0, "OfflineShopManager::RemoveItem - Overflow slot! [%s]", ch->GetName());
  565. return;
  566. }
  567.  
  568. // Check player has offline shop or not
  569. std::auto_ptr<SQLMsg> pMsgSelect(DBManager::instance().DirectQuery("SELECT COUNT(*) FROM player.offline_shop_npc WHERE owner_id = %u", ch->GetPlayerID()));
  570. MYSQL_ROW rowSelect = mysql_fetch_row(pMsgSelect->Get()->pSQLResult);
  571.  
  572. BYTE bResult = 0;
  573. str_to_number(bResult, rowSelect[0]);
  574.  
  575. if (!bResult)
  576. {
  577. std::auto_ptr<SQLMsg> pMsgNoShop(DBManager::instance().DirectQuery("SELECT pos,count,vnum,"
  578. "socket0,socket1,socket2, "
  579. "attrtype0, attrvalue0, attrtype1, attrvalue1, attrtype2, attrvalue2, "
  580. "attrtype3, attrvalue3, attrtype4, attrvalue4, attrtype5, attrvalue5, "
  581. "attrtype6, attrvalue6 FROM %soffline_shop_item WHERE owner_id = %u and pos = %d",
  582. get_table_postfix(), ch->GetPlayerID(), bPos));
  583.  
  584. if (pMsgNoShop->Get()->uiNumRows == 0)
  585. {
  586. sys_log(0, "OfflineShopManager::RemoveItem - This slot is empty! [%s]", ch->GetName());
  587. return;
  588. }
  589.  
  590. TPlayerItem item;
  591. int rowsNoShop;
  592. if (!(rowsNoShop = mysql_num_rows(pMsgNoShop->Get()->pSQLResult)))
  593. return;
  594.  
  595. for (int i = 0; i < rowsNoShop; ++i)
  596. {
  597. MYSQL_ROW row = mysql_fetch_row(pMsgNoShop->Get()->pSQLResult);
  598. int cur = 0;
  599.  
  600. str_to_number(item.pos, row[cur++]);
  601. str_to_number(item.count, row[cur++]);
  602. str_to_number(item.vnum, row[cur++]);
  603. str_to_number(item.alSockets[0], row[cur++]);
  604. str_to_number(item.alSockets[1], row[cur++]);
  605. str_to_number(item.alSockets[2], row[cur++]);
  606. for (int j = 0; j < ITEM_ATTRIBUTE_MAX_NUM; j++)
  607. {
  608. str_to_number(item.aAttr[j].bType, row[cur++]);
  609. str_to_number(item.aAttr[j].sValue, row[cur++]);
  610. }
  611. }
  612.  
  613. LPITEM pItem = ITEM_MANAGER::instance().CreateItem(item.vnum, item.count);
  614. if (!pItem)
  615. {
  616. ch->ChatPacket(CHAT_TYPE_INFO, "Please try again!");
  617. return;
  618. }
  619.  
  620. pItem->SetAttributes(item.aAttr);
  621. pItem->SetSockets(item.alSockets);
  622.  
  623. int iEmptyPos;
  624. if (pItem->IsDragonSoul())
  625. iEmptyPos = ch->GetEmptyDragonSoulInventory(pItem);
  626. else
  627. iEmptyPos = ch->GetEmptyInventory(pItem->GetSize());
  628.  
  629. if (iEmptyPos < 0)
  630. {
  631. ch->ChatPacket(CHAT_TYPE_INFO, "You don't have any free slots in the inventory!");
  632. return;
  633. }
  634.  
  635. if (pItem->IsDragonSoul())
  636. {
  637. pItem->AddToCharacter(ch, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyPos));
  638. }
  639. else
  640. {
  641. pItem->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos));
  642. }
  643.  
  644. DBManager::instance().DirectQuery("DELETE FROM %soffline_shop_item WHERE owner_id = %u and pos = %d", get_table_postfix(), ch->GetPlayerID(), bPos);
  645.  
  646. return;
  647. }
  648. // End Of Check player has offline shop or not
  649.  
  650. DWORD dwShopVid = FindMyOfflineShop(ch->GetPlayerID());
  651. //ch->ChatPacket(CHAT_TYPE_INFO, "[DEBUG] Find My Offline shop: Player Id #%d - Shop Vid %d", ch->GetPlayerID(), dwShopVid);
  652.  
  653. LPCHARACTER npc = CHARACTER_MANAGER::instance().Find(dwShopVid);
  654.  
  655. if (npc)
  656. {
  657. LPOFFLINESHOP pkOfflineShop = npc->GetOfflineShop();
  658.  
  659. // Check pkOfflineShop
  660. if (!pkOfflineShop)
  661. return;
  662.  
  663. std::auto_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT pos,count,vnum,"
  664. "socket0,socket1,socket2, attrtype0, attrvalue0, attrtype1, attrvalue1, attrtype2, attrvalue2, attrtype3, attrvalue3, attrtype4, attrvalue4, attrtype5, attrvalue5, attrtype6, attrvalue6 FROM %soffline_shop_item WHERE owner_id = %u and pos = %d", get_table_postfix(), ch->GetPlayerID(), bPos));
  665.  
  666. if (pMsg->Get()->uiNumRows == 0)
  667. {
  668. sys_log(0, "OfflineShopManager::RemoveItem - This slot is empty! [%s]", ch->GetName());
  669. return;
  670. }
  671.  
  672. TPlayerItem item;
  673. int rows;
  674. if (!(rows = mysql_num_rows(pMsg->Get()->pSQLResult)))
  675. return;
  676.  
  677. for (int i = 0; i < rows; ++i)
  678. {
  679. MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
  680. int cur = 0;
  681.  
  682. str_to_number(item.pos, row[cur++]);
  683. str_to_number(item.count, row[cur++]);
  684. str_to_number(item.vnum, row[cur++]);
  685. str_to_number(item.alSockets[0], row[cur++]);
  686. str_to_number(item.alSockets[1], row[cur++]);
  687. str_to_number(item.alSockets[2], row[cur++]);
  688. for (int j = 0; j < ITEM_ATTRIBUTE_MAX_NUM; j++)
  689. {
  690. str_to_number(item.aAttr[j].bType, row[cur++]);
  691. str_to_number(item.aAttr[j].sValue, row[cur++]);
  692. }
  693. }
  694.  
  695. LPITEM pItem = ITEM_MANAGER::instance().CreateItem(item.vnum, item.count);
  696. if (!pItem)
  697. {
  698. ch->ChatPacket(CHAT_TYPE_INFO, "Please try again!");
  699. return;
  700. }
  701.  
  702. pItem->SetAttributes(item.aAttr);
  703. pItem->SetSockets(item.alSockets);
  704.  
  705. int iEmptyPos;
  706. if (pItem->IsDragonSoul())
  707. iEmptyPos = ch->GetEmptyDragonSoulInventory(pItem);
  708. else
  709. iEmptyPos = ch->GetEmptyInventory(pItem->GetSize());
  710.  
  711. if (iEmptyPos < 0)
  712. {
  713. ch->ChatPacket(CHAT_TYPE_INFO, "You don't have any free slots in the shop!");
  714. return;
  715. }
  716.  
  717. if (pItem->IsDragonSoul())
  718. pItem->AddToCharacter(ch, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyPos));
  719. else
  720. pItem->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos));
  721.  
  722. DBManager::instance().DirectQuery("DELETE FROM %soffline_shop_item WHERE owner_id = %u and pos = %d", get_table_postfix(), ch->GetPlayerID(), bPos);
  723. pkOfflineShop->BroadcastUpdateItem(bPos, ch->GetPlayerID(), true);
  724.  
  725. DWORD dwPulse = get_global_time() + 10;
  726. pkOfflineShop->SetActionPulse(dwPulse);
  727.  
  728. if (LeftItemCount(ch) == 0)
  729. pkOfflineShop->Destroy(npc);
  730.  
  731. LogManager::instance().ItemLog(ch, pItem, "DELETE OFFLINE SHOP ITEM", "");
  732. }
  733. else
  734. ch->ChatPacket(CHAT_TYPE_INFO, "Nie mozesz usunac przedmiotu z innego kanalu!");
  735. }
  736.  
  737. void COfflineShopManager::Refresh(LPCHARACTER ch)
  738. {
  739. if (!ch)
  740. return;
  741.  
  742. LPCHARACTER npc = CHARACTER_MANAGER::instance().Find(FindMyOfflineShop(ch->GetPlayerID()));
  743. if (!npc)
  744. {
  745. TPacketGCShop pack;
  746. pack.header = HEADER_GC_OFFLINE_SHOP;
  747. pack.subheader = SHOP_SUBHEADER_GC_UPDATE_ITEM2;
  748.  
  749. TPacketGCOfflineShopStart pack2;
  750. memset(&pack2, 0, sizeof(pack2));
  751. pack2.owner_vid = 0;
  752. std::auto_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT pos,count,vnum,"
  753. "price,socket0,socket1,socket2, attrtype0, attrvalue0, attrtype1, attrvalue1, attrtype2, attrvalue2, attrtype3, attrvalue3, attrtype4, attrvalue4, attrtype5, attrvalue5, attrtype6, attrvalue6 FROM %soffline_shop_item WHERE owner_id = %u", get_table_postfix(), ch->GetPlayerID()));
  754. MYSQL_ROW row;
  755. while (NULL != (row = mysql_fetch_row(pMsg->Get()->pSQLResult)))
  756. {
  757. int cur = 0;
  758. BYTE bPos = 0;
  759.  
  760. str_to_number(bPos, row[cur++]);
  761. str_to_number(pack2.items[bPos].count, row[cur++]);
  762. str_to_number(pack2.items[bPos].vnum, row[cur++]);
  763. str_to_number(pack2.items[bPos].price, row[cur++]);
  764.  
  765. DWORD alSockets[ITEM_SOCKET_MAX_NUM];
  766. for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i)
  767. str_to_number(alSockets[i], row[cur++]);
  768.  
  769. TPlayerItemAttribute aAttr[ITEM_ATTRIBUTE_MAX_NUM];
  770. for (int i = 0; i < ITEM_ATTRIBUTE_MAX_NUM; ++i)
  771. {
  772. str_to_number(aAttr[i].bType, row[cur++]);
  773. str_to_number(aAttr[i].sValue, row[cur++]);
  774. }
  775.  
  776. thecore_memcpy(pack2.items[bPos].alSockets, alSockets, sizeof(pack2.items[bPos].alSockets));
  777. thecore_memcpy(pack2.items[bPos].aAttr, aAttr, sizeof(pack2.items[bPos].aAttr));
  778. }
  779.  
  780. pack.size = sizeof(pack) + sizeof(pack2);
  781. ch->GetDesc()->BufferedPacket(&pack, sizeof(TPacketGCShop));
  782. ch->GetDesc()->Packet(&pack2, sizeof(TPacketGCOfflineShopStart));
  783. }
  784. else
  785. {
  786. LPOFFLINESHOP pkOfflineShop = npc->GetOfflineShop();
  787. if (!pkOfflineShop)
  788. return;
  789.  
  790. pkOfflineShop->Refresh(ch);
  791. }
  792. }
  793.  
  794. void COfflineShopManager::RefreshMoney(LPCHARACTER ch)
  795. {
  796. if (!ch)
  797. return;
  798.  
  799. std::auto_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT money2 FROM player.player WHERE id = %u", ch->GetPlayerID()));
  800.  
  801. TPacketGCShop p;
  802. TPacketGCOfflineShopMoney p2;
  803.  
  804. p.header = HEADER_GC_OFFLINE_SHOP;
  805. p.subheader = SHOP_SUBHEADER_GC_REFRESH_MONEY;
  806.  
  807. if (pMsg->Get()->uiNumRows == 0)
  808. {
  809. p2.dwMoney = 0;
  810. p.size = sizeof(p) + sizeof(p2);
  811. ch->GetDesc()->BufferedPacket(&p, sizeof(TPacketGCShop));
  812. ch->GetDesc()->Packet(&p2, sizeof(TPacketGCOfflineShopMoney));
  813. }
  814. else
  815. {
  816. MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
  817. str_to_number(p2.dwMoney, row[0]);
  818. p.size = sizeof(p) + sizeof(p2);
  819. ch->GetDesc()->BufferedPacket(&p, sizeof(TPacketGCShop));
  820. ch->GetDesc()->Packet(&p2, sizeof(TPacketGCOfflineShopMoney));
  821. }
  822. }
  823.  
  824. DWORD COfflineShopManager::FindMyOfflineShop(DWORD dwPID)
  825. {
  826. TOfflineShopMap::iterator it = m_Map_pkOfflineShopByNPC2.find(dwPID);
  827. if (m_Map_pkOfflineShopByNPC2.end() == it)
  828. return 0;
  829.  
  830. return it->second;
  831. }
  832.  
  833. DWORD COfflineShopManager::GetPidByVid(DWORD dwVID)
  834. {
  835. for (TOfflineShopMap::iterator it = m_Map_pkOfflineShopByNPC2.begin(); it != m_Map_pkOfflineShopByNPC2.end(); it++)
  836. {
  837. if(it->second != dwVID)
  838. continue;
  839.  
  840. return it->first;
  841. }
  842.  
  843. return 0;
  844. }
  845.  
  846. void COfflineShopManager::StopShopping(LPCHARACTER ch)
  847. {
  848. LPOFFLINESHOP pkOfflineShop;
  849.  
  850. if (!(pkOfflineShop = ch->GetOfflineShop()))
  851. return;
  852.  
  853. pkOfflineShop->RemoveGuest(ch);
  854. sys_log(0, "OFFLINE_SHOP: END: %s", ch->GetName());
  855. }
  856.  
  857. void COfflineShopManager::Buy(LPCHARACTER ch, BYTE pos)
  858. {
  859. if (!ch->GetOfflineShop())
  860. return;
  861.  
  862. if (!ch->GetOfflineShopOwner())
  863. return;
  864.  
  865. if (quest::CQuestManager::instance().GetEventFlag("block_offline_shop_buy_item"))
  866. {
  867. ch->ChatPacket(CHAT_TYPE_INFO, "Zakup przedmiotow ze sklepu offline jest chwilowo niedostepny.");
  868. return;
  869. }
  870.  
  871. if (DISTANCE_APPROX(ch->GetX() - ch->GetOfflineShopOwner()->GetX(), ch->GetY() - ch->GetOfflineShopOwner()->GetY()) > 1500)
  872. {
  873. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Shop znajduje sie za daleko"));
  874. return;
  875. }
  876.  
  877. LPOFFLINESHOP pkOfflineShop = ch->GetOfflineShop();
  878.  
  879. if (!pkOfflineShop)
  880. return;
  881.  
  882. if (get_global_time() < pkOfflineShop->GetActionPulse())
  883. {
  884. ch->ChatPacket(CHAT_TYPE_INFO, "Zaczekaj 10 sekund, zanim bedziesz mogl ponownie kupic w tym sklepie!");
  885. return;
  886. }
  887.  
  888. int ret = pkOfflineShop->Buy(ch, pos);
  889.  
  890. // The result is not equal to SHOP_SUBHEADER_GC_OK, send the error to the character.
  891. if (SHOP_SUBHEADER_GC_OK != ret)
  892. {
  893. TPacketGCShop pack;
  894. pack.header = HEADER_GC_OFFLINE_SHOP;
  895. pack.subheader = ret;
  896. pack.size = sizeof(TPacketGCShop);
  897.  
  898. if (ch->GetDesc())
  899. ch->GetDesc()->Packet(&pack, sizeof(pack));
  900. }
  901. }
  902.  
  903. void COfflineShopManager::WithdrawMoney(LPCHARACTER ch, long long dwRequiredMoney)
  904. {
  905. if (g_bOfflineShopMapAllowLimit)
  906. {
  907. if (!offlineshop_map_allow_find(ch->GetMapIndex()))
  908. {
  909. ch->ChatPacket(CHAT_TYPE_INFO, "Nie mozesz wyplacic yang ze sklepu w tej lokalizacji. Mozesz wycofac tylko w M1 !");
  910. return;
  911. }
  912. }
  913.  
  914. if (!ch)
  915. return;
  916.  
  917. if (dwRequiredMoney < 0)
  918. return;
  919.  
  920. if (ch->IsObserverMode() || ch->GetExchange() || ch->GetMyShop() || ch->GetShopOwner() || ch->IsOpenSafebox() || ch->IsCubeOpen() || ch->GetOfflineShopOwner())
  921. {
  922. ch->ChatPacket(CHAT_TYPE_INFO, "Nie mozesz wyplacic yang ze sklepu offline podczas handlu!");
  923. return;
  924. }
  925.  
  926. std::auto_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT money2 FROM player.player WHERE id = %u", ch->GetPlayerID()));
  927. if (pMsg->Get()->uiNumRows == 0)
  928. return;
  929.  
  930. long long dwCurrentMoney = 0;
  931. MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
  932. str_to_number(dwCurrentMoney, row[0]);
  933.  
  934. if (dwRequiredMoney >= dwCurrentMoney)
  935. {
  936. if (test_server)
  937. ch->ChatPacket(CHAT_TYPE_INFO, "dwCurrentMoney(%lu) - dwRequiredMoney(%lu)", dwCurrentMoney, dwRequiredMoney);
  938.  
  939. dwRequiredMoney = dwCurrentMoney;
  940. }
  941.  
  942. bool isOverFlow = ch->GetGold() + dwRequiredMoney > GOLD_MAX - 1 ? true : false;
  943. if (isOverFlow)
  944. {
  945. ch->ChatPacket(CHAT_TYPE_INFO,("W tej chwili nie mozesz wyplacic pieniedzy!"));
  946. return;
  947. }
  948.  
  949. if (dwRequiredMoney == 1)
  950. dwRequiredMoney = dwCurrentMoney;
  951.  
  952. ch->PointChange(POINT_GOLD, dwRequiredMoney, false);
  953.  
  954. DBManager::instance().DirectQuery("UPDATE player.player SET money2 = money2 - "
  955. " %lld "
  956. " WHERE id = %u", dwRequiredMoney, ch->GetPlayerID());
  957. LogManager::instance().CharLog(ch, 0, "OFFLINE SHOP", "WITHDRAW MONEY");
  958. DBManager::instance().DirectQuery("INSERT INTO log.bankoffline_log (pid,name,a_retras,time) VALUES (%d, '%s', %lld, NOW())", ch->GetPlayerID(), ch->GetName(), dwRequiredMoney);
  959. }
  960.  
  961. BYTE COfflineShopManager::LeftItemCount(LPCHARACTER ch)
  962. {
  963. if (!ch)
  964. return -1;
  965.  
  966. std::auto_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT COUNT(*) FROM %soffline_shop_item WHERE owner_id = %u", get_table_postfix(), ch->GetPlayerID()));
  967. if (pMsg->Get()->uiNumRows == 0)
  968. return 0;
  969.  
  970. MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
  971. BYTE bCount = 0;
  972. str_to_number(bCount, row[0]);
  973. return bCount;
  974. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement