Oskar1121

Untitled

Sep 13th, 2018
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 23.20 KB | None | 0 0
  1. #include "otpch.h"
  2.  
  3. #include "market.h"
  4. #include "configmanager.h"
  5.  
  6. #include "database.h"
  7. #include "game.h"
  8. #include "iologindata.h"
  9.  
  10. extern ConfigManager g_config;
  11. extern Game g_game;
  12.  
  13. void Market::startup()
  14. {
  15. Database* db = Database::getInstance();
  16. if(!db)
  17. return;
  18.  
  19. DBQuery query;
  20. query << "SELECT `id`, `owner`, `buyer`, `itemid`, `time`, `count`, `price`, `premium_price`, `description`, `name`, `sold`, `attributes` FROM `game_market`";
  21.  
  22. if(DBResult* result = db->storeQuery(query.str()))
  23. {
  24. do
  25. {
  26. uint16_t id = result->getDataInt("id");
  27. std::string owner = result->getDataString("owner"), buyer = result->getDataString("buyer");
  28. uint16_t itemid = result->getDataInt("itemid");
  29. uint64_t time = result->getDataInt("time");
  30. uint16_t count = result->getDataInt("count");
  31. uint64_t price = result->getDataInt("price");
  32. uint64_t premiumPrice = result->getDataInt("premium_price");
  33. std::string description = result->getDataString("description"), name = result->getDataString("name");
  34. bool sold = result->getDataInt("sold") == 1;
  35.  
  36. const ItemType& it = Item::items.getItemIdByClientId(itemid);
  37. if(it.id == 0)
  38. {
  39. std::cout << "> ERROR: Item id == 0." << std::endl;
  40. continue;
  41. }
  42.  
  43. uint64_t attrSize = 0;
  44. const char* attr = result->getDataStream("attributes", attrSize);
  45.  
  46. PropStream propStream;
  47. propStream.init(attr, attrSize);
  48.  
  49. if(!sold)
  50. {
  51. Item* item = Item::CreateItem(it.id, count);
  52. if(item && !item->unserializeAttr(propStream))
  53. std::cout << "[Warning - Market::startup()] Unserialize error for item with id " << item->getID() << std::endl;
  54.  
  55. addItem(item, price, premiumPrice, owner, buyer, time, description, id, false);
  56. }
  57. else
  58. addSoldItem(itemid, price, count, owner, buyer, time, name, id);
  59. }
  60. while(result->next());
  61.  
  62. result->free();
  63. }
  64.  
  65. query.str("");
  66. query << "SELECT `player_id`, `offer_id`, `for_count`, `itemtype`, `count`, `attributes` FROM `game_market_offer`";
  67. if(DBResult* result = db->storeQuery(query.str()))
  68. {
  69. do
  70. {
  71. uint32_t player_id = result->getDataInt("player_id");
  72. uint16_t offer_id = result->getDataInt("offer_id");
  73. uint16_t for_count = result->getDataInt("for_count");
  74. uint16_t itemtype = result->getDataInt("itemtype");
  75. int32_t count = result->getDataInt("count");
  76.  
  77. uint64_t attrSize = 0;
  78. const char* attr = result->getDataStream("attributes", attrSize);
  79.  
  80. Offer* offer = getOfferById(offer_id);
  81. if(!offer)
  82. continue;
  83.  
  84. PropStream propStream;
  85. propStream.init(attr, attrSize);
  86.  
  87. Item* item = Item::CreateItem(itemtype, count);
  88. if(item && !item->unserializeAttr(propStream))
  89. std::cout << "[Warning - Market::startup()] Unserialize error for item with id " << item->getID() << std::endl;
  90.  
  91. offer->addSubOfferItem(player_id, item);
  92. offer->setReofferCount(for_count);
  93. }
  94. while(result->next());
  95.  
  96. result->free();
  97. }
  98.  
  99. if(m_updateEvent != 0)
  100. {
  101. Scheduler::getInstance().stopEvent(m_updateEvent);
  102. m_updateEvent = 0;
  103. }
  104. m_updateEvent = Scheduler::getInstance().addEvent(createSchedulerTask(UPDATE_MARKET_INTERVAL,
  105. boost::bind(&Market::updateMarket, this)));
  106. }
  107.  
  108. void Market::shutdown()
  109. {
  110. Database* db = Database::getInstance();
  111. if(!db)
  112. return;
  113.  
  114. DBQuery query;
  115. DBInsert query_insert(db);
  116.  
  117. query << "DELETE FROM `game_market`";
  118. if(!db->executeQuery(query.str()))
  119. return;
  120.  
  121. query.str("");
  122. query_insert.setQuery("INSERT INTO `game_market` (`id`, `owner`, `buyer`, `itemid`, `time`, `count`, `price`, `premium_price`, `description`, `name`, `sold`, `attributes`) VALUES ");
  123. for(OfferVector::iterator it = m_offerVector.begin(); it != m_offerVector.end(); ++it)
  124. {
  125. Item* item = NULL;
  126. (*it)->getItem(item);
  127. if(!item)
  128. continue;
  129.  
  130. PropWriteStream propWriteStream;
  131. item->serializeAttr(propWriteStream);
  132.  
  133. uint32_t attributesSize = 0;
  134. const char* attributes = propWriteStream.getStream(attributesSize);
  135.  
  136. query << (*it)->getId() << "," << db->escapeString((*it)->getOwner()).c_str() << "," << db->escapeString((*it)->getBuyer()).c_str() << ","
  137. << (*it)->getItemId() << "," << (*it)->getTime() << "," << (*it)->getCount() << "," << (*it)->getPrice() << "," << (*it)->getPremiumPrice() << ","
  138. << db->escapeString((*it)->getDescription()).c_str() << "," << db->escapeString((*it)->getName()).c_str() << ",0,"
  139. << db->escapeBlob(attributes, attributesSize);
  140.  
  141. if(!query_insert.addRow(query))
  142. {
  143. std::cout << "> ERROR: Cannot add item to database." << std::endl;
  144. return;
  145. }
  146. }
  147.  
  148. for(OfferVector::iterator it = m_soldVector.begin(); it != m_soldVector.end(); ++it)
  149. {
  150. query << (*it)->getId() << "," << db->escapeString((*it)->getOwner()).c_str() << "," << db->escapeString((*it)->getBuyer()).c_str() << ","
  151. << (*it)->getItemId() << "," << (*it)->getTime() << "," << (*it)->getCount() << "," << (*it)->getPrice() << "," << (*it)->getPremiumPrice() << ","
  152. << db->escapeString((*it)->getDescription()).c_str() << "," << db->escapeString((*it)->getName()).c_str() << ",1,''";
  153.  
  154. if(!query_insert.addRow(query))
  155. {
  156. std::cout << "> ERROR: Cannot add item to database." << std::endl;
  157. return;
  158. }
  159. }
  160.  
  161. if(!query_insert.execute())
  162. std::cout << "> ERROR: Cannot update database." << std::endl;
  163.  
  164. query << "DELETE FROM `game_market_offer`";
  165. if(!db->executeQuery(query.str()))
  166. return;
  167.  
  168. query.str("");
  169. query_insert.setQuery("INSERT INTO `game_market_offer` (`player_id`, `offer_id`, `for_count`, `itemtype`, `count`, `attributes`) VALUES ");
  170. for(OfferVector::reverse_iterator it = m_offerVector.rbegin(); it != m_offerVector.rend(); ++it)
  171. {
  172. SubOfferVector offerVector = (*it)->getOfferItems();
  173. for(SubOfferVector::reverse_iterator uit = offerVector.rbegin(); uit != offerVector.rend(); ++uit)
  174. {
  175. for(ReofferList::reverse_iterator iit = uit->second.rbegin(); iit != uit->second.rend(); ++iit)
  176. {
  177. Item* item = *iit;
  178. if(!item)
  179. continue;
  180.  
  181. PropWriteStream propWriteStream;
  182. item->serializeAttr(propWriteStream);
  183.  
  184. uint32_t attributesSize = 0;
  185. const char* attributes = propWriteStream.getStream(attributesSize);
  186.  
  187. query << uit->first << "," << (*it)->getId() << "," << (*it)->getReofferCount() << "," << item->getID() << "," << (int32_t)item->getSubType() << "," << db->escapeBlob(attributes, attributesSize);
  188.  
  189. if(!query_insert.addRow(query))
  190. {
  191. std::cout << "> ERROR: 'game_market_offer' Cannot add item to database." << std::endl;
  192. return;
  193. }
  194. }
  195. }
  196. }
  197.  
  198. if(!query_insert.execute())
  199. std::cout << "> ERROR: Cannot update database." << std::endl;
  200. }
  201.  
  202. void Market::getReofferList(uint32_t playerId, uint16_t id, ReofferList& reofferList)
  203. {
  204. if(m_offerVector.empty())
  205. return;
  206.  
  207. for(OfferVector::iterator it = m_offerVector.begin(); it != m_offerVector.end(); ++it)
  208. {
  209. if((*it)->getId() != id)
  210. continue;
  211.  
  212. SubOfferVector offerVector = (*it)->getOfferItems();
  213. if(offerVector.empty())
  214. continue;
  215.  
  216. SubOfferVector::iterator _it = offerVector.find(playerId);
  217. if(_it == offerVector.end())
  218. continue;
  219.  
  220. reofferList = _it->second;
  221. break;
  222. }
  223. }
  224.  
  225. void Market::addSoldItem(uint16_t itemId, uint64_t price, uint16_t count, std::string ownerId, std::string buyerId, uint64_t time, std::string name, uint16_t id)
  226. {
  227. if((uint64_t)OTSYS_TIME() / 1000 >= time + (uint64_t)g_config.getNumber(ConfigManager::HISTORY_MARKET_TIME))
  228. return;
  229.  
  230. Offer* offer = new Offer();
  231. if(!offer)
  232. {
  233. delete offer;
  234. return;
  235. }
  236.  
  237. offer->setCount(count);
  238. offer->setOwner(ownerId);
  239. offer->setBuyer(buyerId);
  240. offer->setTime(time);
  241. offer->setName(name);
  242. offer->setItemId(itemId);
  243. offer->setPrice(price);
  244.  
  245. if(id > m_lastId)
  246. m_lastId = id;
  247. else
  248. ++m_lastId;
  249.  
  250. if(id != 0)
  251. offer->setId(id);
  252. else
  253. offer->setId(m_lastId);
  254.  
  255. m_soldVector.push_back(offer);
  256. }
  257.  
  258. Offer* Market::addItem(Item* item, uint64_t price, uint64_t premiumPrice, std::string ownerId, std::string buyerId, uint64_t time, std::string description,
  259. uint16_t id/* = 0*/, bool addToDatabase/* = true*/)
  260. {
  261. Offer* offer = new Offer();
  262. if(!offer)
  263. {
  264. delete offer;
  265. return NULL;
  266. }
  267.  
  268. offer->setItemId(item->getClientID());
  269. offer->setCount(item->getItemCount());
  270. offer->setPrice(price);
  271. offer->setPremiumPrice(premiumPrice);
  272. offer->setOwner(ownerId);
  273. offer->setTime(time);
  274. offer->setDescription(description);
  275. offer->setName(item->getName());
  276. offer->setItem(item);
  277.  
  278. if(id > m_lastId)
  279. m_lastId = id;
  280. else
  281. ++m_lastId;
  282.  
  283. if(id != 0)
  284. offer->setId(id);
  285. else
  286. offer->setId(m_lastId);
  287.  
  288. m_offerVector.push_back(offer);
  289. return offer;
  290. }
  291.  
  292. Offer* Market::getOfferById(uint16_t id)
  293. {
  294. for(OfferVector::iterator it = m_offerVector.begin(); it != m_offerVector.end(); ++it)
  295. {
  296. if((*it)->getId() == id)
  297. return *it;
  298. }
  299.  
  300. return NULL;
  301. }
  302.  
  303. bool Market::getOfferById(uint16_t id, OfferVector::iterator& it)
  304. {
  305. for(it = m_offerVector.begin(); it != m_offerVector.end(); ++it)
  306. {
  307. if((*it)->getId() == id)
  308. return true;
  309. }
  310.  
  311. return false;
  312. }
  313.  
  314. void Market::onRemoveOffer(Player* player, uint16_t id)
  315. {
  316. if(!player)
  317. return;
  318.  
  319. OfferVector::iterator offerIt;
  320. if(!getOfferById(id, offerIt))
  321. {
  322. std::cout << "> ERROR: Can't find offer with id = " << id << "." << std::endl;
  323. return;
  324. }
  325.  
  326. Offer* offer = *offerIt;
  327. if(!offer)
  328. {
  329. std::cout << "> ERROR: Can't find offer with id = " << id << "." << std::endl;
  330. return;
  331. }
  332.  
  333. if(offer->getOwner() != player->getName())
  334. {
  335. std::cout << "> ERROR: Corruption player try remove offer from market." << std::endl;
  336. return;
  337. }
  338.  
  339. const ItemType& it = Item::items.getItemIdByClientId(offer->getItemId());
  340. if(it.id == 0)
  341. {
  342. std::cout << "> ERROR: Item id == 0." << std::endl;
  343. return;
  344. }
  345.  
  346. player->sendRemoveOffer(id);
  347.  
  348. Item* item = offer->getItem();
  349. if(item)
  350. sendOfferToPlayer(player, item);
  351.  
  352. removeReofferList(offer);
  353. delete offer;
  354. m_offerVector.erase(offerIt);
  355. }
  356.  
  357. void Market::onBuyOffer(Player* player, uint16_t id, uint16_t count, bool checkMoney)
  358. {
  359. if(!player)
  360. return;
  361.  
  362. OfferVector::iterator offerIt;
  363. if(!getOfferById(id, offerIt))
  364. {
  365. std::cout << "> ERROR: Can't find offer with id = " << id << "." << std::endl;
  366. return;
  367. }
  368.  
  369. Offer* offer = *offerIt;
  370. if(!offer)
  371. {
  372. std::cout << "> ERROR: Can't find offer with id = " << id << "." << std::endl;
  373. return;
  374. }
  375.  
  376. const ItemType& it = Item::items.getItemIdByClientId(offer->getItemId());
  377. if(it.id == 0)
  378. {
  379. std::cout << "> ERROR: Item id == 0." << std::endl;
  380. return;
  381. }
  382.  
  383. Player* owner = g_game.getPlayerByNameEx(offer->getOwner());
  384. if(!owner)
  385. {
  386. std::cout << "> ERROR: Offer hasn't an owner." << std::endl;
  387. return;
  388. }
  389.  
  390. count = std::min(count, offer->getCount());
  391.  
  392. if(checkMoney)
  393. {
  394. uint64_t price = offer->getPrice() * static_cast<uint64_t>(count);
  395. if(price == 0)
  396. return;
  397.  
  398. if(player->getBalance() < price)
  399. {
  400. player->sendMarketStatus(UPDATE_NOT_ENOUGH_MONEY);
  401. return;
  402. }
  403.  
  404. uint64_t premiumPrice = offer->getPremiumPrice() * static_cast<uint64_t>(count);
  405. if(premiumPrice > 0 && player->getPremiumBalance() < premiumPrice)
  406. {
  407. player->sendMarketStatus(UPDATE_NOT_ENOUGH_MONEY);
  408. return;
  409. }
  410. else
  411. {
  412. owner->updatePremiumPoints(premiumPrice, false);
  413. player->updatePremiumPoints(premiumPrice, true);
  414. }
  415.  
  416. owner->doDepositMoney(price);
  417. player->doWithdrawMoney(price);
  418.  
  419. Item* item = offer->getItem();
  420. if(item)
  421. item->setItemCount(count);
  422.  
  423. sendOfferToPlayer(player, item);
  424. }
  425.  
  426. if(count >= offer->getCount())
  427. {
  428. offer->setBuyer(player->getName());
  429. offer->setTime(OTSYS_TIME() / 1000);
  430.  
  431. m_soldVector.push_back(offer);
  432. m_offerVector.erase(offerIt);
  433.  
  434. player->sendRemoveOffer(id);
  435. if(!owner->isVirtual())
  436. owner->sendRemoveOffer(id);
  437.  
  438. removeReofferList(offer);
  439. }
  440. else
  441. {
  442. ++m_lastId;
  443.  
  444. Offer* soldOffer = offer->clone();
  445. if(soldOffer)
  446. {
  447. soldOffer->setId(m_lastId);
  448. soldOffer->setCount(count);
  449. soldOffer->setBuyer(player->getName());
  450. soldOffer->setTime(OTSYS_TIME() / 1000);
  451. }
  452. else
  453. delete soldOffer;
  454.  
  455. count = offer->getCount() - count;
  456. offer->setCount(count);
  457.  
  458. m_soldVector.push_back(soldOffer);
  459.  
  460. player->sendUpdateOffer(id, count);
  461. if(!owner->isVirtual())
  462. owner->sendUpdateOffer(id, count);
  463. }
  464.  
  465. if(owner->isVirtual())
  466. {
  467. IOLoginData::getInstance()->savePlayer(owner);
  468. delete owner;
  469. }
  470. else if(checkMoney)
  471. owner->sendMarketStatus(UPDATE_BALANCE);
  472.  
  473. if(checkMoney)
  474. player->sendMarketStatus(UPDATE_BALANCE);
  475. }
  476.  
  477. void Market::updateOffer(Player* player, uint16_t id, uint16_t count, MarketAction_t type)
  478. {
  479. switch(type)
  480. {
  481. case MARKET_REMOVE:
  482. onRemoveOffer(player, id);
  483. break;
  484. case MARKET_BUY:
  485. onBuyOffer(player, id, count);
  486. break;
  487.  
  488. default:
  489. break;
  490. }
  491. }
  492.  
  493. void Market::updateMarket(Player* player, UpdateType_t type, uint16_t page, uint16_t category, CategorySort_t sort, const std::string& search)
  494. {
  495. switch(type)
  496. {
  497. case UPDATE_TRADE:
  498. updateTrade(player, page, (CategoryItem_t)category, sort);
  499. break;
  500. case UPDATE_OFFER:
  501. updateOffer(player);
  502. break;
  503. case UPDATE_SEARCH:
  504. updateSearch(player, page, (CategoryItem_t)category, sort, search);
  505. break;
  506. case UPDATE_HISTORY:
  507. updateHistory(player);
  508. break;
  509. case UPDATE_REOFFER:
  510. updateReofferWindow(player, page, category);
  511. break;
  512. case UPDATE_REOFFERS:
  513. updateReoffersWindow(player, page, category);
  514. break;
  515. case UPDATE_REJECT_REOFFER:
  516. updateRejectReoffer(player, page);
  517. break;
  518. case UPDATE_ACCEPT_REOFFER:
  519. updateAcceptReoffer(player, page);
  520. break;
  521.  
  522. default:
  523. break;
  524. }
  525. }
  526.  
  527. void Market::updateRejectReoffer(Player* player, uint16_t id)
  528. {
  529. if(!player)
  530. return;
  531.  
  532. Offer* offer = getOfferById(id);
  533. if(!offer)
  534. return;
  535.  
  536. SubOfferVector offerVector = offer->getOfferItems();
  537. if(offerVector.empty())
  538. return;
  539.  
  540. uint16_t i = 0, reofferId = player->getReofferPage();
  541. for(SubOfferVector::iterator it = offerVector.begin(); it != offerVector.end(); ++it)
  542. {
  543. ++i;
  544. if(i != reofferId)
  545. continue;
  546.  
  547. Player* _player = g_game.getPlayerByGuidEx(it->first);
  548. if(!_player)
  549. break;
  550.  
  551. for(ReofferList::reverse_iterator uit = it->second.rbegin(); uit != it->second.rend(); ++uit)
  552. {
  553. Item* item = *uit;
  554. if(!item)
  555. continue;
  556.  
  557. sendOfferToPlayer(_player, item);
  558. }
  559.  
  560. offer->clearReoffer(_player->getGUID());
  561. if(_player->isVirtual())
  562. {
  563. IOLoginData::getInstance()->savePlayer(_player);
  564. delete _player;
  565. }
  566.  
  567. break;
  568. }
  569.  
  570. updateReoffersWindow(player, id, 0);
  571. }
  572.  
  573. void Market::updateAcceptReoffer(Player* player, uint16_t id)
  574. {
  575. if(!player)
  576. return;
  577.  
  578. Offer* offer = getOfferById(id);
  579. if(!offer)
  580. return;
  581.  
  582. SubOfferVector offerVector = offer->getOfferItems();
  583. if(offerVector.empty())
  584. return;
  585.  
  586. Item* item = offer->getItem();
  587. uint16_t i = 0, reofferId = player->getReofferPage(), reofferCount = offer->getReofferCount();
  588. for(SubOfferVector::iterator it = offerVector.begin(); it != offerVector.end(); ++it)
  589. {
  590. Player* owner = g_game.getPlayerByGuidEx(it->first);
  591. if(!owner)
  592. break;
  593.  
  594. ++i;
  595. for(ReofferList::reverse_iterator uit = it->second.rbegin(); uit != it->second.rend(); ++uit)
  596. {
  597. Item* _item = *uit;
  598. if(!_item)
  599. continue;
  600.  
  601. if(i == reofferId)
  602. sendOfferToPlayer(player, _item);
  603. else
  604. sendOfferToPlayer(owner, _item);
  605. }
  606.  
  607. if(i == reofferId)
  608. sendOfferToPlayer(owner, item);
  609.  
  610. offer->clearReoffer(owner->getGUID());
  611. if(owner->isVirtual())
  612. {
  613. IOLoginData::getInstance()->savePlayer(owner);
  614. delete owner;
  615. }
  616. }
  617.  
  618. onBuyOffer(player, id, reofferCount, false);
  619. }
  620.  
  621. void Market::clearReofferListById(uint32_t playerId, uint16_t id)
  622. {
  623. Offer* offer = getOfferById(id);
  624. if(offer)
  625. offer->clearReoffer(playerId);
  626. }
  627.  
  628. void Market::updateReofferWindow(Player* player, uint16_t id, uint16_t count)
  629. {
  630. if(!player)
  631. return;
  632.  
  633. Offer* offer = getOfferById(id);
  634. if(!offer)
  635. return;
  636.  
  637. ReofferList list;
  638. player->getReofferList(list);
  639.  
  640. uint32_t playerId = player->getGUID();
  641. offer->clearReoffer(playerId);
  642. if(!list.empty())
  643. {
  644. for(ReofferList::iterator it = list.begin(); it != list.end(); ++it)
  645. {
  646. offer->addSubOfferItem(playerId, (*it)/*->clone()*/);
  647. //g_game.internalRemoveItem(NULL, *it);
  648. }
  649.  
  650. offer->setReofferCount(count);
  651. }
  652.  
  653. player->closeReofferWindow(false, id);
  654. }
  655.  
  656. void Market::updateReoffersWindow(Player* player, uint16_t id, uint16_t page)
  657. {
  658. if(!player)
  659. return;
  660.  
  661. Offer* offer = getOfferById(id);
  662. if(!offer)
  663. return;
  664.  
  665. SubOfferVector offerVector = offer->getOfferItems();
  666. if(offerVector.empty())
  667. {
  668. player->closeReofferWindow(false, 0);
  669. return;
  670. }
  671.  
  672. player->closeReofferWindow(false, 0);
  673.  
  674. uint16_t _page = player->getReofferPage();
  675. if(page == 1)
  676. _page = _page - 1;
  677. else if(page == 2)
  678. _page = _page + 1;
  679.  
  680. _page = std::max<uint16_t>(1, std::min<uint16_t>(offerVector.size(), _page));
  681. player->setReofferPage(_page);
  682.  
  683. uint16_t i = 0;
  684. for(SubOfferVector::iterator it = offerVector.begin(); it != offerVector.end(); ++it)
  685. {
  686. ++i;
  687. if(i != _page)
  688. continue;
  689.  
  690. g_game.openReofferWindow(player->getID(), false, id, it->second, true);
  691. break;
  692. }
  693. }
  694.  
  695. void Market::updateHistory(Player* player)
  696. {
  697. if(!player)
  698. return;
  699.  
  700. const std::string name = player->getName();
  701.  
  702. OfferVector itemList;
  703. for(OfferVector::iterator it = m_soldVector.begin(); it != m_soldVector.end(); ++it)
  704. {
  705. if((*it)->getOwner() == name || (*it)->getBuyer() == name)
  706. itemList.push_back(*it);
  707. }
  708.  
  709. player->sendMarketOffer(itemList, UPDATE_HISTORY, 0);
  710. }
  711.  
  712. void Market::updateSearch(Player* player, uint16_t page, CategoryItem_t category, CategorySort_t sort, const std::string& search)
  713. {
  714. if(!player)
  715. return;
  716.  
  717. if(search.empty())
  718. {
  719. updateTrade(player, page, category, sort);
  720. return;
  721. }
  722.  
  723. OfferVector offerList(m_offerVector);
  724. std::sort(offerList.begin(), offerList.end(), MarketSort(player, sort));
  725.  
  726. uint16_t maxOffer = g_config.getNumber(ConfigManager::MARKET_OFFER_PER_PAGE);
  727. uint16_t fromOffer = maxOffer * (page - 1);
  728. double i = 0;
  729.  
  730. const std::string name = player->getName();
  731.  
  732. OfferVector itemList;
  733. for(OfferVector::iterator it = offerList.begin(); it != offerList.end(); ++it)
  734. {
  735. if((*it)->getOwner() == name)
  736. continue;
  737.  
  738. Item* item = NULL;
  739. (*it)->getItem(item);
  740. if(!item)
  741. continue;
  742.  
  743. std::string name = item->getName();
  744. if(asLowerCaseString(name).find(asLowerCaseString(search)) != std::string::npos && isAllow(*it, category))
  745. {
  746. ++i;
  747. if(i > fromOffer && itemList.size() < maxOffer)
  748. itemList.push_back(*it);
  749. }
  750. }
  751.  
  752. if(itemList.empty())
  753. return;
  754.  
  755. player->sendMarketOffer(itemList, UPDATE_TRADE, i);
  756. }
  757.  
  758. void Market::updateTrade(Player* player, uint16_t page, CategoryItem_t category, CategorySort_t sort)
  759. {
  760. if(!player)
  761. return;
  762.  
  763. uint16_t maxOffer = g_config.getNumber(ConfigManager::MARKET_OFFER_PER_PAGE);
  764. uint16_t fromOffer = maxOffer * (page - 1);
  765.  
  766. OfferVector offerList(m_offerVector);
  767. std::sort(offerList.begin(), offerList.end(), MarketSort(player, sort));
  768.  
  769. OfferVector itemList;
  770. double i = 0;
  771. const std::string name = player->getName();
  772. for(OfferVector::iterator it = offerList.begin(); it != offerList.end(); ++it)
  773. {
  774. if((*it)->getOwner() == name || !isAllow(*it, category))
  775. continue;
  776.  
  777. ++i;
  778. if(i > fromOffer && itemList.size() < maxOffer)
  779. itemList.push_back(*it);
  780. }
  781.  
  782. if(itemList.empty())
  783. return;
  784.  
  785. player->sendMarketOffer(itemList, UPDATE_TRADE, i);
  786. }
  787.  
  788. void Market::updateOffer(Player* player)
  789. {
  790. if(!player)
  791. return;
  792.  
  793. OfferVector itemList;
  794. for(OfferVector::iterator it = m_offerVector.begin(); it != m_offerVector.end(); ++it)
  795. {
  796. if((*it)->getOwner() != player->getName())
  797. continue;
  798.  
  799. itemList.push_back(*it);
  800. }
  801.  
  802. if(itemList.empty())
  803. return;
  804.  
  805. player->sendMarketOffer(itemList, UPDATE_OFFER, 0);
  806. }
  807.  
  808. bool Market::canAdd(Player* player)
  809. {
  810. if(!player)
  811. return false;
  812.  
  813. Tile* tile = player->getTile();
  814. if(!tile || !tile->hasFlag(TILESTATE_PROTECTIONZONE))
  815. return false;
  816.  
  817. uint16_t offerCount = 0;
  818. for(OfferVector::iterator it = m_offerVector.begin(); it != m_offerVector.end(); ++it)
  819. {
  820. if((*it)->getOwner() != player->getName())
  821. continue;
  822.  
  823. ++offerCount;
  824. }
  825.  
  826. return offerCount < g_config.getNumber(ConfigManager::MARKET_OFFER_LIMIT);
  827. }
  828.  
  829. void Market::sendOfferToPlayer(Player* player, Item* item, uint16_t count)
  830. {
  831. if(!item || !player)
  832. return;
  833.  
  834. Depot* depot = player->getDepot(player->getTown(), true);
  835. if(!depot)
  836. return;
  837.  
  838. Container* container = depot->getContainer();
  839. if(!container)
  840. return;
  841.  
  842. for(uint32_t i = 0; i < container->size(); i++)
  843. {
  844. Item* _item = container->getItem(i);
  845. if(!_item || _item->getID() != ITEM_MARKET || !_item->getContainer())
  846. continue;
  847.  
  848. Item* __item = item->clone();
  849. if(!__item)
  850. {
  851. delete __item;
  852. continue;
  853. }
  854.  
  855. if(count > 1 && item->isStackable() && item->getItemCount() > count)
  856. {
  857. __item->setItemCount(count);
  858. item->setItemCount(item->getItemCount() - count);
  859. g_game.internalAddItem(NULL, _item->getContainer(), __item);
  860. }
  861. else
  862. {
  863. g_game.internalRemoveItem(NULL, item);
  864. g_game.internalAddItem(NULL, _item->getContainer(), __item);
  865. }
  866.  
  867. break;
  868. }
  869. }
  870.  
  871. void Market::removeReofferList(Offer* offer)
  872. {
  873. if(!offer)
  874. return;
  875.  
  876. SubOfferVector offerVector = offer->getOfferItems();
  877. if(!offerVector.empty())
  878. {
  879. for(SubOfferVector::iterator it = offerVector.begin(); it != offerVector.end(); ++it)
  880. {
  881. Player* player = g_game.getPlayerByGuidEx(it->first);
  882. if(!player)
  883. continue;
  884.  
  885. for(ReofferList::reverse_iterator uit = it->second.rbegin(); uit != it->second.rend(); ++uit)
  886. {
  887. Item* item = *uit;
  888. if(!item)
  889. continue;
  890.  
  891. sendOfferToPlayer(player, item);
  892. }
  893.  
  894. if(player->isVirtual())
  895. {
  896. IOLoginData::getInstance()->savePlayer(player);
  897. delete player;
  898. }
  899. }
  900. }
  901. }
  902.  
  903. void Market::updateMarket()
  904. {
  905. for(OfferVector::reverse_iterator it = m_offerVector.rbegin(); it != m_offerVector.rend(); ++it)
  906. {
  907. if(uint64_t(OTSYS_TIME() / 1000) >= (*it)->getTime())
  908. {
  909. const ItemType& mit = Item::items.getItemIdByClientId((*it)->getItemId());
  910. if(mit.id == 0)
  911. {
  912. std::cout << "> ERROR: Item id == 0." << std::endl;
  913. continue;
  914. }
  915.  
  916. removeReofferList(*it);
  917. Player* player = g_game.getPlayerByNameEx((*it)->getOwner());
  918. if(player)
  919. {
  920. Item* item = (*it)->getItem();
  921. sendOfferToPlayer(player, item);
  922. if(player->isVirtual())
  923. {
  924. IOLoginData::getInstance()->savePlayer(player);
  925. delete player;
  926. }
  927. }
  928.  
  929. delete *it;
  930. m_offerVector.erase(--it.base());
  931. }
  932. }
  933.  
  934. if(m_updateEvent != 0)
  935. {
  936. Scheduler::getInstance().stopEvent(m_updateEvent);
  937. m_updateEvent = 0;
  938. }
  939. m_updateEvent = Scheduler::getInstance().addEvent(createSchedulerTask(UPDATE_MARKET_INTERVAL,
  940. boost::bind(&Market::updateMarket, this)));
  941. }
  942.  
  943. bool Market::isAllow(Offer* offer, CategoryItem_t category)
  944. {
  945. if(!offer)
  946. return false;
  947.  
  948. const ItemType& it = Item::items.getItemIdByClientId(offer->getItemId());
  949. if(it.id == 0)
  950. {
  951. std::cout << "> ERROR[Market::isAllow]: Item id == 0." << std::endl;
  952. return false;
  953. }
  954.  
  955. switch(category)
  956. {
  957. case CATEGORY_HELMET:
  958. return it.wieldPosition == SLOT_HEAD;
  959. case CATEGORY_ARMOR:
  960. return it.wieldPosition == SLOT_ARMOR;
  961. case CATEGORY_LEGS:
  962. return it.wieldPosition == SLOT_LEGS;
  963. case CATEGORY_BOOTS:
  964. return it.wieldPosition == SLOT_FEET;
  965. case CATEGORY_SHIELD:
  966. return it.weaponType == WEAPON_SHIELD;
  967. case CATEGORY_WEAPON:
  968. return it.weaponType == WEAPON_SWORD || it.weaponType == WEAPON_AXE || it.weaponType == WEAPON_CLUB;
  969. case CATEGORY_AMMO:
  970. return it.weaponType == WEAPON_AMMO;
  971. case CATEGORY_WAND:
  972. return it.weaponType == WEAPON_WAND;
  973.  
  974. default:
  975. break;
  976. }
  977.  
  978. return true;
  979. }
  980.  
  981. Item* Market::getPlayerLookItem(uint16_t id)
  982. {
  983. Offer* offer = getOfferById(id);
  984. if(!offer)
  985. return NULL;
  986.  
  987. return offer->getItem();
  988. }
Advertisement
Add Comment
Please, Sign In to add comment