EvEmu  0.8.4
11 September 2021
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
MarketMgr Class Reference

#include "MarketMgr.h"

Inheritance diagram for MarketMgr:
Collaboration diagram for MarketMgr:

Public Member Functions

bool NeedsUpdate ()
 
PyRepGetMarketGroups ()
 
- Public Member Functions inherited from Singleton< MarketMgr >
 Singleton ()
 Primary constructor. More...
 

Private Attributes

MarketDB m_db
 
PyServiceMgrm_manager
 
PyRepm_marketGroups
 
int64 m_timeStamp
 

MarketMgr.cpp

singleton object for storing, manipulating and managing in-game market data this mgr keeps track of market data without abusing the db on every call. (vs old system) this mgr will also track mineral pricing, taking monthly averages, then updating base prices accordingly

: Allan

Date
: 19Dec17
 MarketMgr ()
 
 ~MarketMgr ()
 
int Initialize (PyServiceMgr *pManager)
 
void Close ()
 
void GetInfo ()
 
void Process ()
 
void SystemStartup (SystemData &data)
 
void SystemShutdown (SystemData &data)
 
void UpdatePriceHistory ()
 
bool ExecuteBuyOrder (Client *seller, uint32 orderID, InventoryItemRef iRef, Call_PlaceCharOrder &args, uint16 accountKey=Account::KeyType::Cash)
 
void ExecuteSellOrder (Client *buyer, uint32 orderID, Call_PlaceCharOrder &args)
 
void SendOnOwnOrderChanged (Client *pClient, uint32 orderID, uint8 action, bool isCorp=false, PyRep *order=nullptr)
 
void InvalidateOrdersCache (uint32 regionID, uint32 typeID)
 
PyRepGetNewPriceHistory (uint32 regionID, uint32 typeID)
 
PyRepGetOldPriceHistory (uint32 regionID, uint32 typeID)
 
void SetBasePrice ()
 
void UpdateMineralPrice ()
 
void GetCruPrices ()
 
void Populate ()
 

Additional Inherited Members

- Static Public Member Functions inherited from Singleton< MarketMgr >
static MarketMgrget ()
 
- Static Protected Attributes inherited from Singleton< MarketMgr >
static std::shared_ptr< MarketMgrmInstance
 

Detailed Description

Definition at line 23 of file MarketMgr.h.

Constructor & Destructor Documentation

MarketMgr::MarketMgr ( )

Definition at line 34 of file MarketMgr.cpp.

References m_timeStamp.

35 : m_marketGroups(nullptr),
36 m_manager(nullptr)
37 {
38  m_timeStamp = 0;
39 }
PyRep * m_marketGroups
Definition: MarketMgr.h:73
int64 m_timeStamp
Definition: MarketMgr.h:75
PyServiceMgr * m_manager
Definition: MarketMgr.h:71
MarketMgr::~MarketMgr ( )

Definition at line 41 of file MarketMgr.cpp.

42 {
43  //PyDecRef(m_marketGroups);
44 }

Member Function Documentation

void MarketMgr::Close ( )
Todo:
put a save method here which will save anything changed before shutdown

Definition at line 46 of file MarketMgr.cpp.

References m_marketGroups, PyDecRef, and sLog.

47 {
50  sLog.Warning(" MarketMgr", "Market Manager has been closed." );
51 }
PyRep * m_marketGroups
Definition: MarketMgr.h:73
#define sLog
Evaluates to a NewLog instance.
Definition: LogNew.h:250
#define PyDecRef(op)
Definition: PyRep.h:57
bool MarketMgr::ExecuteBuyOrder ( Client seller,
uint32  orderID,
InventoryItemRef  iRef,
Call_PlaceCharOrder &  args,
uint16  accountKey = Account::KeyType::Cash 
)
Todo:
take off market overhead fees

Definition at line 303 of file MarketMgr.cpp.

References _log, Corp::Role::AccountCanTake1, Corp::Role::AccountCanTake2, Corp::Role::AccountCanTake3, Corp::Role::AccountCanTake4, Corp::Role::AccountCanTake5, Corp::Role::AccountCanTake6, Corp::Role::AccountCanTake7, EvESkill::Accounting, Market::TxData::accountKey, UserError::AddFormatValue(), MarketDB::AlterOrderQuantity(), InventoryItem::AlterQuantity(), Market::Type::Buy, Account::KeyType::Cash, Market::TxData::clientID, Market::QtyStatus::Complete, corpSCC, InventoryItem::Delete(), MarketDB::DeleteOrder(), InventoryItem::Donate(), Account::KeyType::Escrow, Market::Action::Expiry, flagCorpMarket, flagHangar, RefPtr< X >::get(), Client::GetChar(), Client::GetCharacterID(), Client::GetCorporationID(), Client::GetCorpRole(), MarketDB::GetOrderInfo(), MarketDB::GetOrderRow(), Character::GetSkillLevel(), Market::QtyStatus::Invalid, InvalidateOrdersCache(), Market::TxData::isBuy, IsCharacterID, Market::TxData::isCorp, Stat::iskMarket, IsPlayerCorp, IsTraderJoe, InventoryItem::itemID(), m_db, Journal::EntryType::MarketTransaction, Market::TxData::memberID, Market::OrderInfo::memberID, Market::Action::Modify, InventoryItem::name(), Market::QtyStatus::Over, Market::OrderInfo::ownerID, Market::TxData::price, Market::TxData::quantity, InventoryItem::quantity(), Market::OrderInfo::quantity, MarketDB::RecordTransaction(), Market::TxData::regionID, Market::OrderInfo::regionID, EvEMath::Market::SalesTax(), sConfig, sDataMgr, Market::Type::Sell, Client::SendNotifyMsg(), SendOnOwnOrderChanged(), InventoryItem::Split(), sStatMgr, Market::TxData::stationID, stDataMgr, Journal::EntryType::TransactionTax, AccountService::TranserFunds(), Market::TxData::typeID, and Market::QtyStatus::Under.

303  {
304 
306  if (!m_db.GetOrderInfo(orderID, oInfo)) {
307  _log(MARKET__ERROR, "ExecuteBuyOrder - Failed to get order info for #%u.", orderID);
308  return true;
309  }
310 
311  /* will this method also be used to buy/sell using aurm?
312  * unknown yet
313  */
314 
315  // get buyer id and determine if buyer is player or corp (or bot for later)
316  bool isPlayer(false), isCorp(false), isTrader(false);
317  if (IsPlayerCorp(oInfo.ownerID)) {
318  // buyer is player corp
319  isCorp = true;
320  } else if (oInfo.ownerID == 1) {
321  oInfo.ownerID = stDataMgr.GetOwnerID(args.stationID);
322  } else if (IsCharacterID(oInfo.ownerID)) {
323  isPlayer = true;
324  } else if (IsTraderJoe(oInfo.ownerID)) {
325  isTrader = true;
326  } else {
327  // none of above conditionals hit....
328  _log(MARKET__WARNING, "ExecuteBuyOrder - ownerID %u not corp, not char, not system, not joe.", oInfo.ownerID);
329  // send the player some kind of notification about the market order, some standard market error should suffice
330  seller->SendNotifyMsg ("Your order cannot be processed at this time, please try again later.");
331  return false;
332  }
333 
334  // quantity status of seller's item vs buyer's order
336  if (iRef->quantity() == args.quantity) {
337  qtyStatus = Market::QtyStatus::Complete;
338  //use the owner change packet to alert the buyer of the new item
339  if (isPlayer) {
340  iRef->Donate(oInfo.ownerID, args.stationID, flagHangar, true);
341  } else if (isCorp) {
342  iRef->Donate(oInfo.ownerID, args.stationID, flagCorpMarket, true);
343  } else if (isTrader) {
344  // trader joe is a placeholder ID to trash every item sold to him
345  iRef->Delete ();
346  }
347  } else if (iRef->quantity() > args.quantity) {
348  // qty for sale > buy order amt
349  qtyStatus = Market::QtyStatus::Over;
350  //need to split item up...
351  if (isTrader) {
352  // trader joe is a blackhole, just subtract the amount of items we're selling to him and call it a day
353  iRef->AlterQuantity(-args.quantity, true);
354  } else {
355  InventoryItemRef siRef = iRef->Split(args.quantity);
356  if (siRef.get() == nullptr) {
357  _log(MARKET__ERROR, "ExecuteBuyOrder - Failed to split %u %s.", siRef->itemID(), siRef->name());
358  return true;
359  }
360  //use the owner change packet to alert the buyer of the new item
361  if (isPlayer) {
362  siRef->Donate(oInfo.ownerID, args.stationID, flagHangar, true);
363  } else if (isCorp) {
364  siRef->Donate(oInfo.ownerID, args.stationID, flagCorpMarket, true);
365  }
366  }
367  } else {
368  // qty for sale < buy order amt
369  qtyStatus = Market::QtyStatus::Under;
370  //use the owner change packet to alert the buyer of the new item
371  if (isPlayer) {
372  iRef->Donate(oInfo.ownerID, args.stationID, flagHangar, true);
373  } else if (isCorp) {
374  iRef->Donate(oInfo.ownerID, args.stationID, flagCorpMarket, true);
375  } else if (isTrader) {
376  iRef->Delete ();
377  }
378  }
379 
380  uint32 qtySold(args.quantity);
381  switch (qtyStatus) {
383  // this should never hit. make error here.
384  } break;
385  case Market::QtyStatus::Under: // order requires more items than seller is offering. delete args.quantity and update order
386  case Market::QtyStatus::Complete: { // order qty matches item qty. delete args.quantity and delete order
387  args.quantity = 0;
388  } break;
390  // more for sale than order requires. update args.quantity and delete order
391  args.quantity -= qtySold;
392  } break;
393  }
394 
395  float money = args.price * qtySold;
396  std::string reason = "DESC: Buying items in ";
397  reason += stDataMgr.GetStationName(args.stationID).c_str();
398  uint32 sellerWalletOwnerID = 0;
399  uint8 level = seller->GetChar ()->GetSkillLevel (EvESkill::Accounting);
400  float tax = EvEMath::Market::SalesTax (sConfig.market.salesTax, level) * money;
401 
402  if (args.useCorp) {
403  // make sure the user has permissions to take money from the corporation account
404  if (
405  (accountKey == 1000 && (seller->GetCorpRole () & Corp::Role::AccountCanTake1) == 0) ||
406  (accountKey == 1001 && (seller->GetCorpRole () & Corp::Role::AccountCanTake2) == 0) ||
407  (accountKey == 1002 && (seller->GetCorpRole () & Corp::Role::AccountCanTake3) == 0) ||
408  (accountKey == 1003 && (seller->GetCorpRole () & Corp::Role::AccountCanTake4) == 0) ||
409  (accountKey == 1004 && (seller->GetCorpRole () & Corp::Role::AccountCanTake5) == 0) ||
410  (accountKey == 1005 && (seller->GetCorpRole () & Corp::Role::AccountCanTake6) == 0) ||
411  (accountKey == 1006 && (seller->GetCorpRole () & Corp::Role::AccountCanTake7) == 0)
412  )
413  throw UserError("CrpAccessDenied").AddFormatValue ("reason", new PyString ("You do not have access to that wallet"));
414 
415  sellerWalletOwnerID = seller->GetCorporationID ();
416  _log(MARKET__DEBUG, "ExecuteBuyOrder - Seller is Corp: Price: %.2f, Tax: %.2f", money, tax);
417  } else {
418  sellerWalletOwnerID = seller->GetCharacterID ();
419  _log(MARKET__DEBUG, "ExecuteBuyOrder - Seller is Player: Price: %.2f, Tax: %.2f", money, tax);
420  }
421 
422  AccountService::TranserFunds (sellerWalletOwnerID, corpSCC, tax, reason.c_str (),
423  Journal::EntryType::TransactionTax, orderID, accountKey);
424 
425  // send wallet blink event and record the transaction in their journal.
426  reason.clear();
427  reason += "DESC: Selling items in ";
428  reason += stDataMgr.GetStationName(args.stationID).c_str();
429  // this is fulfilling a buy order. seller will receive isk from escrow if buyer is player or corp
430  if (isPlayer or isCorp) {
431  //give the money to the seller from the escrow acct at station
432  AccountService::TranserFunds(stDataMgr.GetOwnerID(args.stationID), seller->GetCharacterID(), \
433  money, reason.c_str(), Journal::EntryType::MarketTransaction, orderID, \
434  Account::KeyType::Escrow, accountKey);
435  } else {
436  // npc buyer. direct xfer to seller
437  AccountService::TranserFunds(oInfo.ownerID, seller->GetCharacterID(), money, reason.c_str(), \
439  }
440 
441  // add data to StatisticMgr
442  sStatMgr.Add(Stat::iskMarket, money);
443 
444  //record this sell transaction in market_transactions
446  data.accountKey = accountKey;
447  data.isBuy = Market::Type::Sell;
448  data.isCorp = args.useCorp;
449  data.memberID = args.useCorp?seller->GetCharacterID():0;
450  data.clientID = args.useCorp?seller->GetCorporationID():seller->GetCharacterID();
451  data.price = args.price;
452  data.quantity = args.quantity;
453  data.stationID = args.stationID;
454  data.regionID = sDataMgr.GetStationRegion(args.stationID);
455  data.typeID = args.typeID;
456 
457  if (!m_db.RecordTransaction(data)) {
458  _log(MARKET__ERROR, "ExecuteBuyOrder - Failed to record sale side of transaction.");
459  }
460 
461  if (isPlayer or isCorp) {
462  // update data for other side if player or player corp
463  data.isBuy = Market::Type::Buy;
464  data.clientID = oInfo.ownerID;
465  data.memberID = isCorp?oInfo.memberID:0;
466  if (!m_db.RecordTransaction(data)) {
467  _log(MARKET__ERROR, "ExecuteBuyOrder - Failed to record buy side of transaction.");
468  }
469  }
470 
471  if (qtyStatus == Market::QtyStatus::Under) {
472  uint32 newQty(oInfo.quantity - args.quantity);
473  _log(MARKET__TRACE, "ExecuteBuyOrder - Partially satisfied order #%u, altering quantity to %u.", orderID, newQty);
474  if (!m_db.AlterOrderQuantity(orderID, newQty)) {
475  _log(MARKET__ERROR, "ExecuteBuyOrder - Failed to alter quantity of order #%u.", orderID);
476  return true;
477  }
478  InvalidateOrdersCache(oInfo.regionID, args.typeID);
479  if (isPlayer or isCorp)
480  SendOnOwnOrderChanged(seller, orderID, Market::Action::Modify, args.useCorp);
481 
482  return false;
483  }
484 
485  _log(MARKET__TRACE, "ExecuteBuyOrder - Satisfied order #%u, deleting.", orderID);
486  PyRep* order = m_db.GetOrderRow(orderID);
487  if (!m_db.DeleteOrder(orderID)) {
488  _log(MARKET__ERROR, "ExecuteBuyOrder - Failed to delete order #%u.", orderID);
489  return true;
490  }
491  InvalidateOrdersCache(oInfo.regionID, args.typeID);
492  if (isPlayer or isCorp)
493  SendOnOwnOrderChanged(seller, orderID, Market::Action::Expiry, args.useCorp, order);
494  return true;
495 }
#define IsTraderJoe(itemID)
Definition: EVE_Defines.h:395
Base Python wire object.
Definition: PyRep.h:66
#define sConfig
A macro for easier access to the singleton.
uint32 regionID
Definition: EVE_Market.h:80
unsigned __int8 uint8
Definition: eve-compat.h:46
virtual InventoryItemRef Split(int32 qty=0, bool notify=true, bool silent=false)
void Donate(uint32 new_owner=ownerSystem, uint32 new_location=locTemp, EVEItemFlags new_flag=flagNone, bool notify=true)
#define sStatMgr
Definition: StatisticMgr.h:68
bool GetOrderInfo(uint32 orderID, Market::OrderInfo &oInfo)
Definition: MarketDB.cpp:253
#define _log(type, fmt,...)
Definition: logsys.h:124
#define stDataMgr
Python string.
Definition: PyRep.h:430
uint32 stationID
Definition: EVE_Market.h:79
uint32 quantity
Definition: EVE_Market.h:81
int64 GetCorpRole() const
Definition: Client.h:129
int32 GetCharacterID() const
Definition: Client.h:113
int32 GetCorporationID() const
Definition: Client.h:123
UserError & AddFormatValue(const char *name, PyRep *value)
Fluent version of the protected AddKeyword, allows for adding a keyword to the exception.
const char * name()
void SendNotifyMsg(const char *fmt,...)
Definition: Client.cpp:2776
CharacterRef GetChar() const
Definition: Client.h:164
void InvalidateOrdersCache(uint32 regionID, uint32 typeID)
Definition: MarketMgr.cpp:264
* args
void SendOnOwnOrderChanged(Client *pClient, uint32 orderID, uint8 action, bool isCorp=false, PyRep *order=nullptr)
Definition: MarketMgr.cpp:231
MarketDB m_db
Definition: MarketMgr.h:70
PyRep * GetOrderRow(uint32 orderID)
Definition: MarketDB.cpp:172
uint16 typeID
Definition: EVE_Market.h:77
static void TranserFunds(uint32 fromID, uint32 toID, double amount, std::string reason="", uint8 entryTypeID=Journal::EntryType::Undefined, uint32 referenceID=0, uint16 fromKey=Account::KeyType::Cash, uint16 toKey=Account::KeyType::Cash, Client *pClient=nullptr)
bool AlterQuantity(int32 qty, bool notify=false)
uint32 accountKey
Definition: EVE_Market.h:82
X * get() const
Definition: RefPtr.h:213
#define IsPlayerCorp(itemID)
Definition: EVE_Defines.h:241
bool RecordTransaction(Market::TxData &data)
Definition: MarketDB.cpp:380
uint32 memberID
Definition: EVE_Market.h:83
#define IsCharacterID(itemID)
Definition: EVE_Defines.h:206
Python object "ccp_exceptions.UserError".
Definition: PyExceptions.h:121
unsigned __int32 uint32
Definition: eve-compat.h:50
uint32 clientID
Definition: EVE_Market.h:78
float SalesTax(float baseSalesTax, uint8 accountingLvl=0, uint8 taxEvasionLvl=0)
Definition: EvEMath.cpp:215
int8 GetSkillLevel(uint16 skillTypeID, bool zeroForNotInjected=true) const
Definition: Character.cpp:575
bool AlterOrderQuantity(uint32 orderID, uint32 new_qty)
Definition: MarketDB.cpp:298
virtual void Delete()
bool DeleteOrder(uint32 orderID)
Definition: MarketDB.cpp:316
uint32 itemID() const
Definition: InventoryItem.h:98
int32 quantity() const
Definition: InventoryItem.h:97
#define sDataMgr

Here is the call graph for this function:

void MarketMgr::ExecuteSellOrder ( Client buyer,
uint32  orderID,
Call_PlaceCharOrder &  args 
)
Todo:
get/implement accountKey here....
Todo:
for corp shit, implement accountKey

Definition at line 497 of file MarketMgr.cpp.

References _log, EvESkill::Accounting, Market::TxData::accountKey, Market::OrderInfo::accountKey, MarketDB::AlterOrderQuantity(), Market::Type::Buy, Account::KeyType::Cash, Market::TxData::clientID, corpSCC, MarketDB::DeleteOrder(), InventoryItem::Donate(), Market::Action::Expiry, flagHangar, flagNone, RefPtr< X >::get(), Client::GetChar(), Client::GetCharacterID(), Client::GetCorporationID(), MarketDB::GetOrderInfo(), MarketDB::GetOrderRow(), CharacterDB::GetSkillLevel(), Character::GetSkillLevel(), InvalidateOrdersCache(), Market::TxData::isBuy, IsCharacterID, Market::TxData::isCorp, Market::OrderInfo::isCorp, Stat::iskMarket, locTemp, m_db, Journal::EntryType::MarketTransaction, Market::TxData::memberID, Market::OrderInfo::memberID, Market::Action::Modify, Market::OrderInfo::ownerID, ownerStation, Market::TxData::price, Market::TxData::quantity, Market::OrderInfo::quantity, MarketDB::RecordTransaction(), Market::TxData::regionID, Market::OrderInfo::regionID, EvEMath::Market::SalesTax(), sConfig, sDataMgr, Market::Type::Sell, SendOnOwnOrderChanged(), sEntityList, sItemFactory, sStatMgr, Market::TxData::stationID, stDataMgr, EvESkill::TaxEvasion, Journal::EntryType::TransactionTax, AccountService::TranserFunds(), and Market::TxData::typeID.

497  {
499  if (!m_db.GetOrderInfo(orderID, oInfo)) {
500  _log(MARKET__ERROR, "ExecuteSellOrder - Failed to get info about sell order %u.", orderID);
501  return;
502  }
503 
504  bool orderConsumed(false);
505  if (args.quantity > oInfo.quantity)
506  args.quantity = oInfo.quantity;
507  if (args.quantity == oInfo.quantity)
508  orderConsumed = true;
509 
510  if (sDataMgr.IsStation(oInfo.ownerID))
511  oInfo.ownerID = stDataMgr.GetOwnerID(oInfo.ownerID);
512 
514  float money = args.price * args.quantity;
515  // send wallet blink event and record the transaction in their journal.
516  std::string reason = "DESC: Buying market items in ";
517  reason += stDataMgr.GetStationName(args.stationID).c_str();
518  // this will throw if funds not available.
519  AccountService::TranserFunds(buyer->GetCharacterID(), oInfo.ownerID, money, reason.c_str(), \
521 
522  uint32 sellerCharacterID = 0;
523 
524  if (oInfo.isCorp) {
525  sellerCharacterID = oInfo.memberID;
526  } else {
527  sellerCharacterID = oInfo.ownerID;
528  }
529 
530  uint8 accountingLevel(0);
531  uint8 taxEvasionLevel(0);
532  Client* pSeller = sEntityList.FindClientByCharID (sellerCharacterID);
533 
534  if (pSeller == nullptr) {
535  accountingLevel = CharacterDB::GetSkillLevel (sellerCharacterID, EvESkill::Accounting);
536  taxEvasionLevel = CharacterDB::GetSkillLevel (sellerCharacterID, EvESkill::TaxEvasion);
537  } else {
538  accountingLevel = pSeller->GetChar ()->GetSkillLevel (EvESkill::Accounting);
539  taxEvasionLevel = pSeller->GetChar ()->GetSkillLevel (EvESkill::TaxEvasion);
540  }
541 
542  float tax = EvEMath::Market::SalesTax (sConfig.market.salesTax, accountingLevel, taxEvasionLevel) * money;
543  AccountService::TranserFunds (oInfo.ownerID, corpSCC, tax, reason.c_str (),
545  // after money is xferd, create and add item.
546  ItemData idata(args.typeID, ownerStation, locTemp, flagNone, args.quantity);
547  InventoryItemRef iRef = sItemFactory.SpawnItem(idata);
548  if (iRef.get() == nullptr)
549  return;
550 
551  //use the owner change packet to alert the buyer of the new item
552  iRef->Donate(buyer->GetCharacterID(), args.stationID, flagHangar, true);
553 
554  // add data to StatisticMgr
555  sStatMgr.Add(Stat::iskMarket, money);
556 
557  Client* seller(nullptr);
558  if (IsCharacterID(oInfo.ownerID))
559  seller = sEntityList.FindClientByCharID(oInfo.ownerID);
560 
561  if (orderConsumed) {
562  _log(MARKET__TRACE, "ExecuteSellOrder - satisfied order #%u, deleting.", orderID);
563  PyRep* order = m_db.GetOrderRow(orderID);
564  if (!m_db.DeleteOrder(orderID)) {
565  _log(MARKET__ERROR, "ExecuteSellOrder - Failed to delete order #%u.", orderID);
566  return;
567  }
568  InvalidateOrdersCache(oInfo.regionID, args.typeID);
569  SendOnOwnOrderChanged(seller, orderID, Market::Action::Expiry, args.useCorp, order);
570  } else {
571  uint32 newQty(oInfo.quantity - args.quantity);
572  _log(MARKET__TRACE, "ExecuteSellOrder - Partially satisfied order #%u, altering quantity to %u.", orderID, newQty);
573  if (!m_db.AlterOrderQuantity(orderID, newQty)) {
574  _log(MARKET__ERROR, "ExecuteSellOrder - Failed to alter quantity of order #%u.", orderID);
575  return;
576  }
577  InvalidateOrdersCache(oInfo.regionID, args.typeID);
578  SendOnOwnOrderChanged(seller, orderID, Market::Action::Modify, args.useCorp);
579  }
580 
581  //record this transaction in market_transactions
584  data.accountKey = Account::KeyType::Cash; // args.useCorp?accountKey: Account::KeyType::Cash;
585  data.isBuy = Market::Type::Buy;
586  data.isCorp = args.useCorp;
587  data.memberID = args.useCorp?buyer->GetCharacterID():0;
588  data.clientID = args.useCorp?buyer->GetCorporationID():buyer->GetCharacterID();
589  data.price = args.price;
590  data.quantity = args.quantity;
591  data.stationID = args.stationID;
592  data.regionID = sDataMgr.GetStationRegion(args.stationID);
593  data.typeID = args.typeID;
594 
595  if (!m_db.RecordTransaction(data)) {
596  _log(MARKET__ERROR, "ExecuteSellOrder - Failed to record buy side of transaction.");
597  }
598 
599  // update data for other side
600  data.accountKey = Account::KeyType::Cash; // args.useCorp?accountKey: Account::KeyType::Cash;
601  data.isBuy = Market::Type::Sell;
602  data.clientID = oInfo.ownerID;
603  if (!m_db.RecordTransaction(data)) {
604  _log(MARKET__ERROR, "ExecuteSellOrder - Failed to record sell side of transaction.");
605  }
606 }
Base Python wire object.
Definition: PyRep.h:66
#define sConfig
A macro for easier access to the singleton.
uint32 regionID
Definition: EVE_Market.h:80
unsigned __int8 uint8
Definition: eve-compat.h:46
void Donate(uint32 new_owner=ownerSystem, uint32 new_location=locTemp, EVEItemFlags new_flag=flagNone, bool notify=true)
#define sStatMgr
Definition: StatisticMgr.h:68
bool GetOrderInfo(uint32 orderID, Market::OrderInfo &oInfo)
Definition: MarketDB.cpp:253
#define _log(type, fmt,...)
Definition: logsys.h:124
#define stDataMgr
uint32 stationID
Definition: EVE_Market.h:79
uint32 quantity
Definition: EVE_Market.h:81
int32 GetCharacterID() const
Definition: Client.h:113
int32 GetCorporationID() const
Definition: Client.h:123
#define sEntityList
Definition: EntityList.h:208
CharacterRef GetChar() const
Definition: Client.h:164
void InvalidateOrdersCache(uint32 regionID, uint32 typeID)
Definition: MarketMgr.cpp:264
* args
void SendOnOwnOrderChanged(Client *pClient, uint32 orderID, uint8 action, bool isCorp=false, PyRep *order=nullptr)
Definition: MarketMgr.cpp:231
MarketDB m_db
Definition: MarketMgr.h:70
PyRep * GetOrderRow(uint32 orderID)
Definition: MarketDB.cpp:172
uint16 typeID
Definition: EVE_Market.h:77
static uint8 GetSkillLevel(uint32 charID, uint16 skillTypeID)
static void TranserFunds(uint32 fromID, uint32 toID, double amount, std::string reason="", uint8 entryTypeID=Journal::EntryType::Undefined, uint32 referenceID=0, uint16 fromKey=Account::KeyType::Cash, uint16 toKey=Account::KeyType::Cash, Client *pClient=nullptr)
uint32 accountKey
Definition: EVE_Market.h:82
X * get() const
Definition: RefPtr.h:213
bool RecordTransaction(Market::TxData &data)
Definition: MarketDB.cpp:380
uint32 memberID
Definition: EVE_Market.h:83
#define IsCharacterID(itemID)
Definition: EVE_Defines.h:206
Definition: Client.h:66
unsigned __int32 uint32
Definition: eve-compat.h:50
uint32 clientID
Definition: EVE_Market.h:78
float SalesTax(float baseSalesTax, uint8 accountingLvl=0, uint8 taxEvasionLvl=0)
Definition: EvEMath.cpp:215
int8 GetSkillLevel(uint16 skillTypeID, bool zeroForNotInjected=true) const
Definition: Character.cpp:575
bool AlterOrderQuantity(uint32 orderID, uint32 new_qty)
Definition: MarketDB.cpp:298
#define sItemFactory
Definition: ItemFactory.h:165
bool DeleteOrder(uint32 orderID)
Definition: MarketDB.cpp:316
#define sDataMgr

Here is the call graph for this function:

void MarketMgr::GetCruPrices ( )

Definition at line 916 of file MarketMgr.cpp.

References MarketDB::GetCruPriceAvg(), sDataMgr, sLog, and MarketDB::UpdateInvPrice().

917 {
918  /*
919  std::map<uint16, Market::matlData> materialMap;
920  materialMap.clear();
921  // dont update minerals...they are set.
922  //sDataMgr.GetMineralData(materialMap); // 8
923  sDataMgr.GetSalvageData(materialMap); // 53
924  sDataMgr.GetCompoundData(materialMap); // 7
925  sDataMgr.GetComponentData(materialMap); // 114
926  sDataMgr.GetPIResourceData(materialMap); // 15
927  sDataMgr.GetPICommodityData(materialMap); // 66
928 
929  MarketDB::GetCruPriceAvg(materialMap);
930 
931  MarketDB::UpdateMktPrice(materialMap);
932  */
933 
934  sLog.Warning(" SetBasePrice", "Getting types.");
935  std::map<uint16, Inv::TypeData> types;
936  sDataMgr.GetTypes(types); //19669 unique items in type data
937  sLog.Green(" SetBasePrice", "GetTypes returned %u items. Getting price avg.", types.size());
938  // delete the typeID '0'
939  types.erase(0);
940 
941  MarketDB::GetCruPriceAvg(types); //7723 unique items in price data
942  sLog.Green(" SetBasePrice", "Got Avg prices. updating items.");
943  MarketDB::UpdateInvPrice(types); //7712 non-zero prices
944  sLog.Cyan(" SetBasePrice", "Completed.");
945 }
static void UpdateInvPrice(std::map< uint16, Inv::TypeData > &data)
Definition: MarketDB.cpp:570
#define sLog
Evaluates to a NewLog instance.
Definition: LogNew.h:250
static void GetCruPriceAvg(std::map< uint16, Inv::TypeData > &data)
Definition: MarketDB.cpp:590
#define sDataMgr

Here is the call graph for this function:

void MarketMgr::GetInfo ( )

Definition at line 78 of file MarketMgr.cpp.

79 {
80  /* get info in current market data? */
81 }
PyRep* MarketMgr::GetMarketGroups ( )
inline

Definition at line 53 of file MarketMgr.h.

References m_marketGroups, and PyIncRef.

PyRep * m_marketGroups
Definition: MarketMgr.h:73
#define PyIncRef(op)
Definition: PyRep.h:56
PyRep * MarketMgr::GetNewPriceHistory ( uint32  regionID,
uint32  typeID 
)
Todo:
this doesnt belong here...

Definition at line 148 of file MarketMgr.cpp.

References _log, DBerror::c_str(), PyServiceMgr::cache_service, EvE::Time::Day, DBResultToCRowset(), PyRep::Dump(), DBQueryResult::error, DBQueryResult::GetRowCount(), ObjCacheService::GiveCache(), is_log_enabled, ObjCacheService::IsCacheLoaded(), m_manager, m_timeStamp, ObjCacheService::MakeObjectCachedMethodCallResult(), PyStatic, sConfig, and sDatabase.

148  {
149  PyRep* result(nullptr);
150  std::string method_name ("GetNewHistory_");
151  method_name += std::to_string(regionID);
152  method_name += "_";
153  method_name += std::to_string(typeID);
154  ObjectCachedMethodID method_id("marketProxy", method_name.c_str());
155  //check to see if this method is in the cache already.
156  if (!m_manager->cache_service->IsCacheLoaded(method_id)) {
157  //this method is not in cache yet, load up the contents and cache it
158  DBQueryResult res;
159 
161  if(!sDatabase.RunQuery(res,
162  "SELECT historyDate, lowPrice, highPrice, avgPrice, volume, orders"
163  " FROM mktHistory "
164  " WHERE regionID=%u AND typeID=%u"
165  " AND historyDate > %li LIMIT %u",
166  regionID, typeID, (m_timeStamp - EvE::Time::Day), sConfig.market.NewPriceLimit))
167  {
168  _log(DATABASE__ERROR, "Error in query: %s", res.error.c_str());
169  return nullptr;
170  }
171  _log(MARKET__DB_TRACE, "MarketMgr::GetNewPriceHistory() - Fetched %u buy orders for type %u in region %u from mktTransactions", res.GetRowCount(), typeID, regionID);
172 
173  result = DBResultToCRowset(res);
174  if (result == nullptr) {
175  _log(MARKET__DB_ERROR, "Failed to load cache, generating empty contents.");
176  result = PyStatic.NewNone();
177  }
178  m_manager->cache_service->GiveCache(method_id, &result);
179  }
180 
181  //now we know its in the cache one way or the other, so build a
182  //cached object cached method call result.
184 
185  if (is_log_enabled(MARKET__DB_TRACE))
186  result->Dump(MARKET__DB_TRACE, " ");
187  return result;
188 }
Base Python wire object.
Definition: PyRep.h:66
#define sConfig
A macro for easier access to the singleton.
#define sDatabase
Definition: dbcore.h:199
#define _log(type, fmt,...)
Definition: logsys.h:124
PyObjectEx * DBResultToCRowset(DBQueryResult &result)
Definition: EVEDBUtils.cpp:402
void Dump(FILE *into, const char *pfx) const
Dumps object to file.
Definition: PyRep.cpp:84
#define is_log_enabled(type)
Definition: logsys.h:78
const char * c_str() const
Definition: dbcore.h:48
#define PyStatic
Definition: PyRep.h:1209
void GiveCache(const PyRep *objectID, PyRep **contents)
DBerror error
Definition: dbcore.h:69
ObjCacheService * cache_service
Definition: PyServiceMgr.h:78
size_t GetRowCount()
Definition: dbcore.h:72
int64 m_timeStamp
Definition: MarketMgr.h:75
PyObject * MakeObjectCachedMethodCallResult(const PyRep *objectID, const char *versionCheck="run")
bool IsCacheLoaded(const PyRep *objectID) const
PyServiceMgr * m_manager
Definition: MarketMgr.h:71

Here is the call graph for this function:

PyRep * MarketMgr::GetOldPriceHistory ( uint32  regionID,
uint32  typeID 
)
Todo:
this doesnt belong here...

Definition at line 190 of file MarketMgr.cpp.

References _log, DBerror::c_str(), PyServiceMgr::cache_service, EvE::Time::Day, DBResultToCRowset(), PyRep::Dump(), DBQueryResult::error, DBQueryResult::GetRowCount(), ObjCacheService::GiveCache(), is_log_enabled, ObjCacheService::IsCacheLoaded(), m_manager, m_timeStamp, ObjCacheService::MakeObjectCachedMethodCallResult(), PyStatic, sConfig, and sDatabase.

190  {
191  PyRep* result(nullptr);
192  std::string method_name ("GetOldHistory_");
193  method_name += std::to_string(regionID);
194  method_name += "_";
195  method_name += std::to_string(typeID);
196  ObjectCachedMethodID method_id("marketProxy", method_name.c_str());
197  //check to see if this method is in the cache already.
198  if (!m_manager->cache_service->IsCacheLoaded(method_id)) {
199  //this method is not in cache yet, load up the contents and cache it
200  DBQueryResult res;
201 
203  if(!sDatabase.RunQuery(res,
204  "SELECT historyDate, lowPrice, highPrice, avgPrice, volume, orders"
205  " FROM mktHistory WHERE regionID=%u AND typeID=%u"
206  " AND historyDate > %li AND historyDate < %li LIMIT %u",
207  regionID, typeID, (m_timeStamp - (EvE::Time::Day *3)), (m_timeStamp - EvE::Time::Day), sConfig.market.OldPriceLimit))
208  {
209  _log(DATABASE__ERROR, "Error in query: %s", res.error.c_str());
210  return nullptr;
211  }
212  _log(MARKET__DB_TRACE, "MarketMgr::GetOldPriceHistory() - Fetched %u orders for type %u in region %u from mktHistory", res.GetRowCount(), typeID, regionID);
213 
214  result = DBResultToCRowset(res);
215  if (result == nullptr) {
216  _log(MARKET__DB_ERROR, "Failed to load cache, generating empty contents.");
217  result = PyStatic.NewNone();
218  }
219  m_manager->cache_service->GiveCache(method_id, &result);
220  }
221 
222  //now we know its in the cache one way or the other, so build a
223  //cached object cached method call result.
225 
226  if (is_log_enabled(MARKET__DB_TRACE))
227  result->Dump(MARKET__DB_TRACE, " ");
228  return result;
229 }
Base Python wire object.
Definition: PyRep.h:66
#define sConfig
A macro for easier access to the singleton.
#define sDatabase
Definition: dbcore.h:199
#define _log(type, fmt,...)
Definition: logsys.h:124
PyObjectEx * DBResultToCRowset(DBQueryResult &result)
Definition: EVEDBUtils.cpp:402
void Dump(FILE *into, const char *pfx) const
Dumps object to file.
Definition: PyRep.cpp:84
#define is_log_enabled(type)
Definition: logsys.h:78
const char * c_str() const
Definition: dbcore.h:48
#define PyStatic
Definition: PyRep.h:1209
void GiveCache(const PyRep *objectID, PyRep **contents)
DBerror error
Definition: dbcore.h:69
ObjCacheService * cache_service
Definition: PyServiceMgr.h:78
size_t GetRowCount()
Definition: dbcore.h:72
int64 m_timeStamp
Definition: MarketMgr.h:75
PyObject * MakeObjectCachedMethodCallResult(const PyRep *objectID, const char *versionCheck="run")
bool IsCacheLoaded(const PyRep *objectID) const
PyServiceMgr * m_manager
Definition: MarketMgr.h:71

Here is the call graph for this function:

int MarketMgr::Initialize ( PyServiceMgr pManager)

Definition at line 53 of file MarketMgr.cpp.

References MarketDB::GetUpdateTime(), m_manager, m_timeStamp, Populate(), and sLog.

54 {
55  m_manager = pManager;
56 
58 
59  Populate();
60  sLog.Blue(" MarketMgr", "Market Manager Initialized.");
61  return 1;
62 }
#define sLog
Evaluates to a NewLog instance.
Definition: LogNew.h:250
void Populate()
Definition: MarketMgr.cpp:64
int64 m_timeStamp
Definition: MarketMgr.h:75
PyServiceMgr * m_manager
Definition: MarketMgr.h:71
static int64 GetUpdateTime()
Definition: MarketDB.cpp:456

Here is the call graph for this function:

void MarketMgr::InvalidateOrdersCache ( uint32  regionID,
uint32  typeID 
)

Definition at line 264 of file MarketMgr.cpp.

References PyServiceMgr::cache_service, ObjCacheService::InvalidateCache(), and m_manager.

Referenced by ExecuteBuyOrder(), and ExecuteSellOrder().

265 {
266  std::string method_name ("GetOrders_");
267  method_name += std::to_string(regionID);
268  method_name += "_";
269  method_name += std::to_string(typeID);
270  ObjectCachedMethodID method_id("marketProxy", method_name.c_str());
271  m_manager->cache_service->InvalidateCache( method_id );
272 }
void InvalidateCache(const PyRep *objectID)
ObjCacheService * cache_service
Definition: PyServiceMgr.h:78
PyServiceMgr * m_manager
Definition: MarketMgr.h:71

Here is the call graph for this function:

Here is the caller graph for this function:

bool MarketMgr::NeedsUpdate ( )
inline

Definition at line 51 of file MarketMgr.h.

References GetFileTimeNow(), and m_timeStamp.

51 { return m_timeStamp > GetFileTimeNow()?false:true; }
double GetFileTimeNow()
Definition: utils_time.cpp:84
int64 m_timeStamp
Definition: MarketMgr.h:75

Here is the call graph for this function:

void MarketMgr::Populate ( )
protected

Definition at line 64 of file MarketMgr.cpp.

References MarketDB::GetMarketGroups(), GetTimeMSeconds(), m_db, m_marketGroups, Process(), sConfig, and sLog.

Referenced by Initialize().

65 {
66  double start = GetTimeMSeconds();
68 
69  Process();
70 
71  // market orders stored as {regionID/typeID} --do we want to store orders in memory for loaded region??
72  // m_db.GetOrders(call.client->GetRegionID(), args.arg);
73 
74  sLog.Blue(" MarketMgr", "Market Manager loaded in %.3fms.", (GetTimeMSeconds() - start));
75  sLog.Cyan(" MarketMgr", "Market Manager Updates Price History every %u hours.", sConfig.market.HistoryUpdateTime);
76 }
#define sConfig
A macro for easier access to the singleton.
PyRep * m_marketGroups
Definition: MarketMgr.h:73
PyRep * GetMarketGroups()
Definition: MarketDB.cpp:401
#define sLog
Evaluates to a NewLog instance.
Definition: LogNew.h:250
MarketDB m_db
Definition: MarketMgr.h:70
double GetTimeMSeconds()
Definition: utils_time.cpp:104
void Process()
Definition: MarketMgr.cpp:83

Here is the call graph for this function:

Here is the caller graph for this function:

void MarketMgr::Process ( )

Definition at line 83 of file MarketMgr.cpp.

Referenced by Populate().

84 {
85  // make cache timer of xx(time) then invalidate the price history cache
86 
87  //if (m_timeStamp > GetFileTimeNow())
88  // UpdatePriceHistory();
89 }

Here is the caller graph for this function:

void MarketMgr::SendOnOwnOrderChanged ( Client pClient,
uint32  orderID,
uint8  action,
bool  isCorp = false,
PyRep order = nullptr 
)

Definition at line 231 of file MarketMgr.cpp.

References Market::Action::Add, Market::Action::Expiry, Client::GetCorporationID(), MarketDB::GetOrderRow(), m_db, Market::Action::Modify, Client::SendNotification(), and sEntityList.

Referenced by ExecuteBuyOrder(), and ExecuteSellOrder().

231  {
232  if (pClient == nullptr)
233  return;
234  Notify_OnOwnOrderChanged ooc;
235  if (order != nullptr) {
236  ooc.order = order;
237  } else {
238  ooc.order = m_db.GetOrderRow(orderID);
239  }
240 
241  switch (action) {
242  case Market::Action::Add:
243  ooc.reason = "Add";
244  break;
246  ooc.reason = "Modify";
247  break;
249  ooc.reason = "Expiry";
250  break;
251  }
252 
253  ooc.isCorp = isCorp;
254  PyTuple* tmp = ooc.Encode();
255  // send journal blink and call 'self.RefreshOrders()' in client
256  if (isCorp) {
257  sEntityList.CorpNotify(pClient->GetCorporationID(), 125 /*MarketOrder*/, "OnOwnOrderChanged", "*corpid&corprole", tmp);
258  } else {
259  pClient->SendNotification("OnOwnOrderChanged", "clientID", &tmp);
260  }
261 }
void SendNotification(const PyAddress &dest, EVENotificationStream &noti, bool seq=true)
Definition: Client.cpp:2245
int32 GetCorporationID() const
Definition: Client.h:123
#define sEntityList
Definition: EntityList.h:208
Python tuple.
Definition: PyRep.h:567
MarketDB m_db
Definition: MarketMgr.h:70
PyRep * GetOrderRow(uint32 orderID)
Definition: MarketDB.cpp:172

Here is the call graph for this function:

Here is the caller graph for this function:

void MarketMgr::SetBasePrice ( )

Definition at line 610 of file MarketMgr.cpp.

References EVEDB::invGroups::AssaultShip, EVEDB::invCategories::Asteroid, EVEDB::invGroups::Battlecruiser, EVEDB::invGroups::Battleship, EVEDB::invGroups::BlackOps, EVEDB::invGroups::CapitalIndustrialShip, EVEDB::invGroups::Capsule, EVEDB::invGroups::Carrier, Inv::GrpData::catID, EVEDB::invCategories::Celestial, EVEDB::invCategories::Charge, EVEDB::invGroups::CombatRecon, EVEDB::invGroups::CommandShip, EVEDB::invCategories::Commodity, EVEDB::invGroups::CovertOps, EVEDB::invGroups::Cruiser, EVEDB::invGroups::Destroyer, EVEDB::invGroups::Dreadnought, EVEDB::invCategories::Drone, EVEDB::invGroups::ElecAttackShip, EVEDB::invGroups::EliteBattleship, EVEDB::invCategories::Entity, EVEDB::invGroups::Exhumer, EVEDB::invGroups::Freighter, EVEDB::invGroups::Frigate, MarketDB::GetCruPriceAvg(), MarketDB::GetManufacturedItems(), MarketDB::GetMaterialPrices(), MarketDB::GetMineralPrices(), EVEDB::invGroups::HeavyAssaultShip, EVEDB::invGroups::HeavyInterdictors, Inv::GrpData::id, EVEDB::invGroups::Industrial, EVEDB::invGroups::IndustrialCommandShip, EVEDB::invGroups::Interceptor, EVEDB::invGroups::Interdictor, EVEDB::invGroups::JumpFreighter, EVEDB::invGroups::Logistics, EVEDB::invGroups::Marauder, EVEDB::invCategories::Material, EVEDB::invGroups::MiningBarge, EVEDB::invCategories::Module, Market::matlData::name, EvERam::bpTypeData::productionTime, EVEDB::invGroups::Prototype_Exploration_Ship, EVEDB::invGroups::Rig_Armor, EVEDB::invGroups::Rig_Astronautic, EVEDB::invGroups::Rig_Drones, EVEDB::invGroups::Rig_Electronics, EVEDB::invGroups::Rig_Electronics_Superiority, EVEDB::invGroups::Rig_Energy_Grid, EVEDB::invGroups::Rig_Energy_Weapon, EVEDB::invGroups::Rig_Hybrid_Weapon, EVEDB::invGroups::Rig_Launcher, EVEDB::invGroups::Rig_Mining, EVEDB::invGroups::Rig_Projectile_Weapon, EVEDB::invGroups::Rig_Security_Transponder, EVEDB::invGroups::Rig_Shield, EVEDB::invGroups::Rookieship, sDataMgr, EVEDB::invCategories::Ship, EVEDB::invGroups::Shuttle, sLog, EVEDB::invCategories::Station, EVEDB::invGroups::StealthBomber, EVEDB::invGroups::StrategicCruiser, EVEDB::invGroups::Supercarrier, EVEDB::invGroups::Titan, EVEDB::invGroups::TransportShip, Market::matlData::typeID, and MarketDB::UpdateInvPrice().

611 {
612  /* method to estimate item base price, based on materials to manufacture that item
613  *
614  * mineral prices are queried from db with a +10% markup
615  *
616  * ships and modules are loaded and queried from static data for manufacturing materials
617  * those materials are queried (as required) for minerals needed
618  * once a total mineral value has been calculated, calculate estimated cost based on
619  * current mineral values
620  *
621  * final prices will have markup based on item type
622  *
623  *
624  * NOTES FOR IMPLEMETING THIS SHIT
625  *
626  * //SELECT typeID, materialTypeID, quantity FROM invTypeMaterials
627  * EvERam::RamMaterials ramMatls = EvERam::RamMaterials();
628  * ramMatls.quantity = row.GetInt(2);
629  * ramMatls.materialTypeID = row.GetInt(1);
630  *
631  * eventually, this will query all items that can be manufactured from BP or refined into minerals
632  *
633  */
634 
635  // get mineral prices and put into data map
636  // typeID/data{typeID, price, name}
637  std::map<uint16, Market::matlData> mineralMap;
638  mineralMap.clear();
639  sDataMgr.GetMineralData(mineralMap); // 8
640 
641  // this will have to use db to get current data.
642  // mineral prices are (will be) updated via a 'price average' method yet to be written
643  MarketDB::GetMineralPrices(mineralMap);
644 
645 
646  // get 'building blocks' used for cap ships and put into data map
647  //block typeID/vector<data{materialTypeID, qty}>
648  std::map<uint16, Market::matlData> materialMap;
649  materialMap.clear();
650  sDataMgr.GetComponentData(materialMap); // 125
651 
652  // get compounds from ice and put into data map
653  sDataMgr.GetCompoundData(materialMap); // 7
654 
655  // get misc commodities and put into data map
656  sDataMgr.GetMiscCommodityData(materialMap); // 456
657 
658  // get salvage items for rigs and other items made from them
659  sDataMgr.GetSalvageData(materialMap); // 53
660 
661  // get PI resources
662  sDataMgr.GetPIResourceData(materialMap); // 15
663 
664  // get PI commodities
665  sDataMgr.GetPICommodityData(materialMap); // 66
666 
667  // hack to add this item to materialMap, instead of getting entire group
668  // 22175 is Codebreaker I, which is a reproc item from Purloined Sansha Codebreaker.
670  data.typeID = 22175;
671  data.name = "Codebreaker I";
672  materialMap[22175] = data;
673 
674  // this will have to use db to get current data.
675  // mineral prices are (will be) updated via a 'price average' method yet to be written
676  MarketDB::GetMaterialPrices(materialMap);
677 
678  // add minerals to material maps
679  materialMap.insert(mineralMap.begin(), mineralMap.end());
680  //sDataMgr.GetMineralData(materialMap); // 8
681 
682 
683  // item typeID/data{inventory data}
684  std::map<uint16, Inv::TypeData> itemMap;
685  itemMap.clear();
686  // this gets only ships
687  //MarketDB::GetShipIDs(itemMap);
688  // this gets all items made from minerals either directly or indirectly
690 
691  //item typeID/vector<data{materialTypeID, qty}>
692  std::map<uint16, std::vector<EvERam::RamMaterials>> itemMatMap;
693  itemMatMap.clear();
694  std::map<uint16, Inv::TypeData>::iterator itemItr = itemMap.begin();
695  for (; itemItr != itemMap.end(); ++itemItr) {
696  // pull data for this item -need r/w iterator to work
697  sDataMgr.GetType(itemItr->first, itemItr->second);
698 
699  // get materials required for this item
700  std::vector<EvERam::RamMaterials> matVec;
701  matVec.clear();
702  sDataMgr.GetRamMaterials(itemItr->first, matVec);
703  itemMatMap[itemItr->first] = matVec;
704  }
705 
706 
707  // estimate price of item based on mineral requirements
708  bool found(true);
709  uint8 mLevel(0);
710  double current(0);
711  Inv::GrpData gData = Inv::GrpData();
713  // item typeID/data{inventory data}
714  std::map<uint16, Inv::TypeData> missingItemMap;
715  missingItemMap.clear();
716  std::map<uint16, Market::matlData>::iterator materialItr = materialMap.begin();
717  std::map<uint16, std::vector<EvERam::RamMaterials>>::iterator itemMatItr = itemMatMap.end();
718  for (itemItr = itemMap.begin(); itemItr != itemMap.end(); ++itemItr) {
719  itemMatItr = itemMatMap.find(itemItr->first);
720  if (itemMatItr == itemMatMap.end())
721  continue;
722 
723  found = true;
724  current = itemItr->second.basePrice;
725  // reset basePrice
726  itemItr->second.basePrice = 0.0;
727  // sum mineral counts with current prices for this ship
728  for (auto cur2 : itemMatItr->second) {
729  materialItr = materialMap.find(cur2.materialTypeID);
730  if (materialItr == materialMap.end()) {
731  sLog.Error(" SetBasePrice", "resource %u for %s(%u) not found in materialMap", \
732  cur2.materialTypeID, itemItr->second.name.c_str(), itemItr->first);
733  missingItemMap[itemItr->first] = Inv::TypeData();
734  found = false;
735  continue;
736  }
737  itemItr->second.basePrice += (materialItr->second.price * cur2.quantity);
738  }
739  if (!found)
740  continue;
741 
742  // add manuf costs to base price
743  // currently uses production time to add cost at line rental default of 1k install and 2500/hr
744  if (sDataMgr.GetBpDataForItem(itemItr->first, bpData)) {
745  itemItr->second.basePrice += 1000 + (2500 * (bpData.productionTime / 3600)); // time is in seconds
746  }
747 
748  mLevel = itemItr->second.metaLvl;
749  gData = Inv::GrpData();
750  sDataMgr.GetGroup(itemItr->second.groupID, gData);
751 
752  // apply modifier to base price according to item category (complexity, rarity, demand)
753  // these should also be adjusted for portion size
754  switch (gData.catID) {
756  itemItr->second.basePrice /= itemItr->second.portionSize;
757  // modify price based on meta
758  switch (mLevel) {
759  case 0: { //basic
760  itemItr->second.basePrice *= 2;
761  } break;
762  case 1: { //t1
763  itemItr->second.basePrice *= 2.5;
764  } break;
765  case 2: { //t2
766  itemItr->second.basePrice *= 3.5;
767  } break;
768  }
769  } break;
775  if (mLevel)
776  itemItr->second.basePrice *= mLevel;
777  itemItr->second.basePrice /= itemItr->second.portionSize;
778  } break;
780  if (mLevel)
781  itemItr->second.basePrice *= mLevel;
782  // asteroids cannot be 'created' per se, but the mined ore can be sold.
783  // this cat covers mined ore, so use same pricing method as charges
784  if (itemItr->first < 28000)
785  itemItr->second.basePrice /= itemItr->second.portionSize;
786  } break;
788  itemItr->second.basePrice *= 2;
789  // multiply price by metaLvl
790  if (mLevel) {
791  switch (gData.id) {
805  itemItr->second.basePrice *= (mLevel + 1);
806  } break;
807  default: {
808  itemItr->second.basePrice *= (mLevel + 10);
809  } break;
810  }
811  }
812  } break;
814  // multiply price by metaLvl
815  if (mLevel)
816  itemItr->second.basePrice *= mLevel;
817  // modify price based on class
818  switch (gData.id) {
823  itemItr->second.basePrice *= 2.1; // +80%
824  } break;
826  itemItr->second.basePrice *= 1.2; // +20%
827  } break;
840  itemItr->second.basePrice *= 1.1; // +10%
841  } break;
842  // these are good...
847  itemItr->second.basePrice *= 1.5; // +50%
848  } break;
857  // these can only be crated in pos.
861  itemItr->second.basePrice *= 0.6; // -40% these are all outrageous at calculated prices
862  } break;
864  itemItr->second.basePrice *= 0.35; // this one is weird...
865  } break;
867  itemItr->second.basePrice *= 3; // x3 for shuttles
868  } break;
871  itemItr->second.basePrice *= 1000; // x1000
872  } break;
873  }
874  } break;
876  // for some reason, station pricing is way off....
877  itemItr->second.basePrice *= 100;
878  } break;
879  }
880 
881  if (itemItr->second.basePrice < 0.01) {
882  sLog.Error(" SetBasePrice", "Calculated price for %s(%u) is 0", \
883  itemItr->second.name.c_str(), itemItr->first);
884  } /*else {
885  sLog.Blue(" SetBasePrice", "Calculated price for %u %s(cat:%u - %s - meta %u) from %.2f to %.2f", \
886  itemItr->first, itemItr->second.name.c_str(), gData.catID, gData.name.c_str(), \
887  itemItr->second.metaLvl, current, itemItr->second.basePrice);
888  }*/
889  }
890 
891  // check for missing items and get average price using crucible mkt data table
892  if (missingItemMap.empty()) {
893  // update db for 'new' base price
894  MarketDB::UpdateInvPrice(itemMap);
895  } else {
896  MarketDB::GetCruPriceAvg(missingItemMap);
897  MarketDB::UpdateInvPrice(missingItemMap);
898  sLog.Error(" SetBasePrice", "Missing material. run again.");
899  }
900 }
unsigned __int8 uint8
Definition: eve-compat.h:46
static void GetMineralPrices(std::map< uint16, Market::matlData > &data)
Definition: MarketDB.cpp:543
static void UpdateInvPrice(std::map< uint16, Inv::TypeData > &data)
Definition: MarketDB.cpp:570
std::string name
Definition: EVE_Market.h:138
#define sLog
Evaluates to a NewLog instance.
Definition: LogNew.h:250
uint32 productionTime
Definition: EVE_RAM.h:120
static void GetCruPriceAvg(std::map< uint16, Inv::TypeData > &data)
Definition: MarketDB.cpp:590
static void GetMaterialPrices(std::map< uint16, Market::matlData > &data)
Definition: MarketDB.cpp:531
static void GetManufacturedItems(std::map< uint16, Inv::TypeData > &data)
Definition: MarketDB.cpp:519
#define sDataMgr

Here is the call graph for this function:

void MarketMgr::SystemShutdown ( SystemData data)

Definition at line 96 of file MarketMgr.cpp.

97 {
98 
99 }
void MarketMgr::SystemStartup ( SystemData data)

Definition at line 91 of file MarketMgr.cpp.

92 {
93 
94 }
void MarketMgr::UpdateMineralPrice ( )

Definition at line 903 of file MarketMgr.cpp.

References sDataMgr, and MarketDB::UpdateMktPrice().

904 {
905  // get mineral prices and put into data map
906  // typeID/data{typeID, price, name}
907  std::map<uint16, Market::matlData> mineralMap;
908  mineralMap.clear();
909  sDataMgr.GetMineralData(mineralMap); // 8
910 
911  // update mineral price
912  MarketDB::UpdateMktPrice(mineralMap);
913 
914 }
static void UpdateMktPrice(std::map< uint16, Market::matlData > &data)
Definition: MarketDB.cpp:583
#define sDataMgr

Here is the call graph for this function:

void MarketMgr::UpdatePriceHistory ( )
Todo:
this doesnt belong here...
Todo:
this doesnt belong here...

Definition at line 101 of file MarketMgr.cpp.

References EvE::Time::Day, GetFileTimeNow(), EvE::Time::Hour, m_timeStamp, sConfig, sDatabase, Market::Type::Sell, MarketDB::SetUpdateTime(), and EvE::Time::Year.

102 {
103  m_timeStamp = GetFileTimeNow() + (EvE::Time::Hour * sConfig.market.HistoryUpdateTime);
105 
106  DBerror err;
107  int64 cutoff_time = m_timeStamp;
108  cutoff_time -= cutoff_time % EvE::Time::Day; //round down to an even day boundary.
109  cutoff_time -= EvE::Time::Day * 2; //the cutoff between "new" and "old" price history in days
110 
112  //build the history record from the recent market transactions.
113  sDatabase.RunQuery(err,
114  "INSERT INTO"
115  " mktHistory"
116  " (regionID, typeID, historyDate, lowPrice, highPrice, avgPrice, volume, orders)"
117  " SELECT"
118  " regionID,"
119  " typeID,"
120  " transactionDate,"
121  " MIN(price),"
122  " MAX(price),"
123  " AVG(price),"
124  " SUM(quantity),"
125  " COUNT(transactionID)"
126  " FROM mktTransactions"
127  " WHERE transactionType=%u AND transactionDate < %li",
128  //" GROUP BY regionID, typeID, transactionDate",
129  Market::Type::Sell, cutoff_time);
130 
132  // remove the transactions which have been aged out?
133  if (sConfig.market.DeleteOldTransactions)
134  sDatabase.RunQuery(err, "DELETE FROM mktTransactions WHERE transactionDate < %li", (cutoff_time - EvE::Time::Year));
135 }
#define sConfig
A macro for easier access to the singleton.
#define sDatabase
Definition: dbcore.h:199
static void SetUpdateTime(int64 setTime)
Definition: MarketDB.cpp:470
double GetFileTimeNow()
Definition: utils_time.cpp:84
signed __int64 int64
Definition: eve-compat.h:51
int64 m_timeStamp
Definition: MarketMgr.h:75
Definition: dbcore.h:39

Here is the call graph for this function:

Member Data Documentation

MarketDB MarketMgr::m_db
private

Definition at line 70 of file MarketMgr.h.

Referenced by ExecuteBuyOrder(), ExecuteSellOrder(), Populate(), and SendOnOwnOrderChanged().

PyServiceMgr* MarketMgr::m_manager
private
PyRep* MarketMgr::m_marketGroups
private

Definition at line 73 of file MarketMgr.h.

Referenced by Close(), GetMarketGroups(), and Populate().

int64 MarketMgr::m_timeStamp
private

The documentation for this class was generated from the following files: