1. #include "stdafx.h"
  2. #include "Cache.h"
  3. #include "QID.h"
  4. #include "ClientManager.h"
  5. #ifdef __AUCTION__
  6. #include "AuctionManager.h"
  7. #endif
  8. #include "Main.h"
  9. extern CPacketInfo g_item_info;
  10. extern int g_iPlayerCacheFlushSeconds;
  11. extern int g_iItemCacheFlushSeconds;
  12. extern int g_test_server;
  13. // MYSHOP_PRICE_LIST
  14. extern int g_iItemPriceListTableCacheFlushSeconds;
  15. // END_OF_MYSHOP_PRICE_LIST
  16. //
  17. extern int g_item_count;
  18. const int auctionMinFlushSec = 1800;
  19. CItemCache::CItemCache()
  20. {
  21. m_expireTime = MIN(1800, g_iItemCacheFlushSeconds);
  22. }
  23. CItemCache::~CItemCache()
  24. {
  25. }
  26. // ÀÌ°Å ÀÌ»óÇѵ¥...
  27. // Delete¸¦ ÇßÀ¸¸é, Cacheµµ ÇØÁ¦ÇØ¾ß ÇÏ´Â°Í ¾Æ´Ñ°¡???
  28. // ±Ùµ¥ Cache¸¦ ÇØÁ¦ÇÏ´Â ºÎºĞÀÌ ¾ø¾î.
  29. // ¸ø ãÀº °Ç°¡?
  30. // ÀÌ·¸°Ô ÇسõÀ¸¸é, °è¼Ó ½Ã°£ÀÌ µÉ ¶§¸¶´Ù ¾ÆÀÌÅÛÀ» °è¼Ó Áö¿ö...
  31. // ÀÌ¹Ì »ç¶óÁø ¾ÆÀÌÅÛÀε¥... È®Àλç»ì??????
  32. // fixme
  33. // by rtsummit
  34. void CItemCache::Delete()
  35. {
  36. if (m_data.vnum == 0)
  37. return;
  38. //char szQuery[QUERY_MAX_LEN];
  39. //szQuery[QUERY_MAX_LEN] = '\0';
  40. if (g_test_server)
  41. sys_log(0, "ItemCache::Delete : DELETE %u", m_data.id);
  42. m_data.vnum = 0;
  43. m_bNeedQuery = true;
  44. m_lastUpdateTime = time(0);
  45. OnFlush();
  46. //m_bNeedQuery = false;
  47. //m_lastUpdateTime = time(0) - m_expireTime; // ¹Ù·Î ŸÀӾƿô µÇµµ·Ï ÇÏÀÚ.
  48. }
  49. void CItemCache::OnFlush()
  50. {
  51. if (m_data.vnum == 0) // vnumÀÌ 0ÀÌ¸é »èÁ¦Ç϶ó°í Ç¥½ÃµÈ °ÍÀÌ´Ù.
  52. {
  53. char szQuery[QUERY_MAX_LEN];
  54. snprintf(szQuery, sizeof(szQuery), "DELETE FROM item%s WHERE id=%u", GetTablePostfix(), m_data.id);
  55. CDBManager::instance().ReturnQuery(szQuery, QID_ITEM_DESTROY, 0, NULL);
  56. if (g_test_server)
  57. sys_log(0, "ItemCache::Flush : DELETE %u %s", m_data.id, szQuery);
  58. }
  59. else
  60. {
  61. long alSockets[ITEM_SOCKET_MAX_NUM];
  62. TPlayerItemAttribute aAttr[ITEM_ATTRIBUTE_MAX_NUM];
  63. bool isSocket = false, isAttr = false;
  64. memset(&alSockets, 0, sizeof(long) * ITEM_SOCKET_MAX_NUM);
  65. memset(&aAttr, 0, sizeof(TPlayerItemAttribute) * ITEM_ATTRIBUTE_MAX_NUM);
  66. TPlayerItem * p = &m_data;
  67. if (memcmp(alSockets, p->alSockets, sizeof(long) * ITEM_SOCKET_MAX_NUM))
  68. isSocket = true;
  69. if (memcmp(aAttr, p->aAttr, sizeof(TPlayerItemAttribute) * ITEM_ATTRIBUTE_MAX_NUM))
  70. isAttr = true;
  71. char szColumns[QUERY_MAX_LEN];
  72. char szValues[QUERY_MAX_LEN];
  73. char szUpdate[QUERY_MAX_LEN];
  74. int iLen = snprintf(szColumns, sizeof(szColumns), "id, owner_id, window, pos, count, vnum");
  75. int iValueLen = snprintf(szValues, sizeof(szValues), "%u, %u, %d, %d, %u, %u",
  76. p->id, p->owner, p->window, p->pos, p->count, p->vnum);
  77. int iUpdateLen = snprintf(szUpdate, sizeof(szUpdate), "owner_id=%u, window=%d, pos=%d, count=%u, vnum=%u",
  78. p->owner, p->window, p->pos, p->count, p->vnum);
  79. if (isSocket)
  80. {
  81. iLen += snprintf(szColumns + iLen, sizeof(szColumns) - iLen, ", socket0, socket1, socket2, socket3");
  82. iValueLen += snprintf(szValues + iValueLen, sizeof(szValues) - iValueLen,
  83. ", %lu, %lu, %lu, %lu", p->alSockets[0], p->alSockets[1], p->alSockets[2], p->alSockets[3]);
  84. iUpdateLen += snprintf(szUpdate + iUpdateLen, sizeof(szUpdate) - iUpdateLen,
  85. ", socket0=%lu, socket1=%lu, socket2=%lu, socket3=%lu", p->alSockets[0], p->alSockets[1], p->alSockets[2], p->alSockets[3]);
  86. }
  87. if (isAttr)
  88. {
  89. iLen += snprintf(szColumns + iLen, sizeof(szColumns) - iLen,
  90. ", attrtype0, attrvalue0, attrtype1, attrvalue1, attrtype2, attrvalue2, attrtype3, attrvalue3"
  91. ", attrtype4, attrvalue4, attrtype5, attrvalue5, attrtype6, attrvalue6");
  92. iValueLen += snprintf(szValues + iValueLen, sizeof(szValues) - iValueLen,
  93. ", %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
  94. p->aAttr[0].bType, p->aAttr[0].sValue,
  95. p->aAttr[1].bType, p->aAttr[1].sValue,
  96. p->aAttr[2].bType, p->aAttr[2].sValue,
  97. p->aAttr[3].bType, p->aAttr[3].sValue,
  98. p->aAttr[4].bType, p->aAttr[4].sValue,
  99. p->aAttr[5].bType, p->aAttr[5].sValue,
  100. p->aAttr[6].bType, p->aAttr[6].sValue);
  101. iUpdateLen += snprintf(szUpdate + iUpdateLen, sizeof(szUpdate) - iUpdateLen,
  102. ", attrtype0=%d, attrvalue0=%d"
  103. ", attrtype1=%d, attrvalue1=%d"
  104. ", attrtype2=%d, attrvalue2=%d"
  105. ", attrtype3=%d, attrvalue3=%d"
  106. ", attrtype4=%d, attrvalue4=%d"
  107. ", attrtype5=%d, attrvalue5=%d"
  108. ", attrtype6=%d, attrvalue6=%d",
  109. p->aAttr[0].bType, p->aAttr[0].sValue,
  110. p->aAttr[1].bType, p->aAttr[1].sValue,
  111. p->aAttr[2].bType, p->aAttr[2].sValue,
  112. p->aAttr[3].bType, p->aAttr[3].sValue,
  113. p->aAttr[4].bType, p->aAttr[4].sValue,
  114. p->aAttr[5].bType, p->aAttr[5].sValue,
  115. p->aAttr[6].bType, p->aAttr[6].sValue);
  116. }
  117. char szItemQuery[QUERY_MAX_LEN + QUERY_MAX_LEN];
  118. snprintf(szItemQuery, sizeof(szItemQuery), "REPLACE INTO item%s (%s) VALUES(%s)", GetTablePostfix(), szColumns, szValues);
  119. if (g_test_server)
  120. sys_log(0, "ItemCache::Flush :REPLACE (%s)", szItemQuery);
  121. CDBManager::instance().ReturnQuery(szItemQuery, QID_ITEM_SAVE, 0, NULL);
  122. //g_item_info.Add(p->vnum);
  123. ++g_item_count;
  124. }
  125. m_bNeedQuery = false;
  126. }
  127. //
  128. // CPlayerTableCache
  129. //
  130. CPlayerTableCache::CPlayerTableCache()
  131. {
  132. m_expireTime = MIN(1800, g_iPlayerCacheFlushSeconds);
  133. }
  134. CPlayerTableCache::~CPlayerTableCache()
  135. {
  136. }
  137. void CPlayerTableCache::OnFlush()
  138. {
  139. if (g_test_server)
  140. sys_log(0, "PlayerTableCache::Flush : %s", m_data.name);
  141. char szQuery[QUERY_MAX_LEN];
  142. CreatePlayerSaveQuery(szQuery, sizeof(szQuery), &m_data);
  143. CDBManager::instance().ReturnQuery(szQuery, QID_PLAYER_SAVE, 0, NULL);
  144. }
  145. // MYSHOP_PRICE_LIST
  146. //
  147. // CItemPriceListTableCache class implementation
  148. //
  149. const int CItemPriceListTableCache::s_nMinFlushSec = 1800;
  150. CItemPriceListTableCache::CItemPriceListTableCache()
  151. {
  152. m_expireTime = MIN(s_nMinFlushSec, g_iItemPriceListTableCacheFlushSeconds);
  153. }
  154. void CItemPriceListTableCache::UpdateList(const TItemPriceListTable* pUpdateList)
  155. {
  156. //
  157. // ÀÌ¹Ì Ä³½ÌµÈ ¾ÆÀÌÅÛ°ú Áߺ¹µÈ ¾ÆÀÌÅÛÀ» ã°í Áߺ¹µÇÁö ¾Ê´Â ÀÌÀü Á¤º¸´Â tmpvec ¿¡ ³Ö´Â´Ù.
  158. //
  159. std::vector<TItemPriceInfo> tmpvec;
  160. for (uint idx = 0; idx < m_data.byCount; ++idx)
  161. {
  162. const TItemPriceInfo* pos = pUpdateList->aPriceInfo;
  163. for (; pos != pUpdateList->aPriceInfo + pUpdateList->byCount && m_data.aPriceInfo[idx].dwVnum != pos->dwVnum; ++pos)
  164. ;
  165. if (pos == pUpdateList->aPriceInfo + pUpdateList->byCount)
  166. tmpvec.push_back(m_data.aPriceInfo[idx]);
  167. }
  168. //
  169. // pUpdateList ¸¦ m_data ¿¡ º¹»çÇÏ°í ³²Àº °ø°£À» tmpvec ÀÇ ¾Õ¿¡¼­ ºÎÅÍ ³²Àº ¸¸Å­ º¹»çÇÑ´Ù.
  170. //
  171. if (pUpdateList->byCount > SHOP_PRICELIST_MAX_NUM)
  172. {
  173. sys_err("Count overflow!");
  174. return;
  175. }
  176. m_data.byCount = pUpdateList->byCount;
  177. thecore_memcpy(m_data.aPriceInfo, pUpdateList->aPriceInfo, sizeof(TItemPriceInfo) * pUpdateList->byCount);
  178. int nDeletedNum; // »èÁ¦µÈ °¡°İÁ¤º¸ÀÇ °¹¼ö
  179. if (pUpdateList->byCount < SHOP_PRICELIST_MAX_NUM)
  180. {
  181. size_t sizeAddOldDataSize = SHOP_PRICELIST_MAX_NUM - pUpdateList->byCount;
  182. if (tmpvec.size() < sizeAddOldDataSize)
  183. sizeAddOldDataSize = tmpvec.size();
  184. thecore_memcpy(m_data.aPriceInfo + pUpdateList->byCount, &tmpvec[0], sizeof(TItemPriceInfo) * sizeAddOldDataSize);
  185. m_data.byCount += sizeAddOldDataSize;
  186. nDeletedNum = tmpvec.size() - sizeAddOldDataSize;
  187. }
  188. else
  189. nDeletedNum = tmpvec.size();
  190. m_bNeedQuery = true;
  191. sys_log(0,
  192. "ItemPriceListTableCache::UpdateList : OwnerID[%u] Update [%u] Items, Delete [%u] Items, Total [%u] Items",
  193. m_data.dwOwnerID, pUpdateList->byCount, nDeletedNum, m_data.byCount);
  194. }
  195. void CItemPriceListTableCache::OnFlush()
  196. {
  197. char szQuery[QUERY_MAX_LEN];
  198. //
  199. // ÀÌ Ä³½ÃÀÇ ¼ÒÀ¯ÀÚ¿¡ ´ëÇÑ ±âÁ¸¿¡ DB ¿¡ ÀúÀåµÈ ¾ÆÀÌÅÛ °¡°İÁ¤º¸¸¦ ¸ğµÎ »èÁ¦ÇÑ´Ù.
  200. //
  201. snprintf(szQuery, sizeof(szQuery), "DELETE FROM myshop_pricelist%s WHERE owner_id = %u", GetTablePostfix(), m_data.dwOwnerID);
  202. CDBManager::instance().ReturnQuery(szQuery, QID_ITEMPRICE_DESTROY, 0, NULL);
  203. //
  204. // ij½ÃÀÇ ³»¿ëÀ» ¸ğµÎ DB ¿¡ ¾´´Ù.
  205. //
  206. for (int idx = 0; idx < m_data.byCount; ++idx)
  207. {
  208. snprintf(szQuery, sizeof(szQuery),
  209. #ifdef ENABLE_CHEQUE_SYSTEM
  210. "INSERT INTO myshop_pricelist%s(owner_id, item_vnum, price, cheque) VALUES(%u, %u, %u, %u)",
  211. GetTablePostfix(), m_data.dwOwnerID, m_data.aPriceInfo[idx].dwVnum, m_data.aPriceInfo[idx].price.dwPrice, m_data.aPriceInfo[idx].price.byChequePrice);
  212. #else
  213. "INSERT INTO myshop_pricelist%s(owner_id, item_vnum, price) VALUES(%u, %u, %u)",
  214. GetTablePostfix(), m_data.dwOwnerID, m_data.aPriceInfo[idx].dwVnum, m_data.aPriceInfo[idx].dwPrice);
  215. #endif
  216. CDBManager::instance().ReturnQuery(szQuery, QID_ITEMPRICE_SAVE, 0, NULL);
  217. }
  218. sys_log(0, "ItemPriceListTableCache::Flush : OwnerID[%u] Update [%u]Items", m_data.dwOwnerID, m_data.byCount);
  219. m_bNeedQuery = false;
  220. }
  221. // END_OF_MYSHOP_PRICE_LIST
  222. #ifdef __AUCTION__
  223. CAuctionItemInfoCache::CAuctionItemInfoCache()
  224. {
  225. m_expireTime = MIN (auctionMinFlushSec, g_iItemCacheFlushSeconds);
  226. }
  227. CAuctionItemInfoCache::~CAuctionItemInfoCache()
  228. {
  229. }
  230. void CAuctionItemInfoCache::Delete()
  231. {
  232. if (m_data.item_num == 0)
  233. return;
  234. if (g_test_server)
  235. sys_log(0, "CAuctionItemInfoCache::Delete : DELETE %u", m_data.item_id);
  236. m_data.item_num = 0;
  237. m_bNeedQuery = true;
  238. m_lastUpdateTime = time(0);
  239. OnFlush();
  240. delete this;
  241. }
  242. void CAuctionItemInfoCache::OnFlush()
  243. {
  244. char szQuery[QUERY_MAX_LEN];
  245. if (m_data.item_num == 0)
  246. {
  247. snprintf(szQuery, sizeof(szQuery), "DELETE FROM auction where item_id = %d", m_data.item_id);
  248. CDBManager::instance().AsyncQuery(szQuery);
  249. }
  250. else
  251. {
  252. snprintf(szQuery, sizeof(szQuery), "REPLACE INTO auction VALUES (%u, %d, %d, %u, \"%s\", %u, %u, %u, %u)",
  253. m_data.item_num, m_data.offer_price, m_data.price, m_data.offer_id, m_data.shown_name, (DWORD)m_data.empire, (DWORD)m_data.expired_time,
  254. m_data.item_id, m_data.bidder_id);
  255. CDBManager::instance().AsyncQuery(szQuery);
  256. }
  257. }
  258. CSaleItemInfoCache::CSaleItemInfoCache()
  259. {
  260. m_expireTime = MIN (auctionMinFlushSec, g_iItemCacheFlushSeconds);
  261. }
  262. CSaleItemInfoCache::~CSaleItemInfoCache()
  263. {
  264. }
  265. void CSaleItemInfoCache::Delete()
  266. {
  267. }
  268. void CSaleItemInfoCache::OnFlush()
  269. {
  270. char szQuery[QUERY_MAX_LEN];
  271. snprintf(szQuery, sizeof(szQuery), "REPLACE INTO sale VALUES (%u, %d, %d, %u, \"%s\", %u, %u, %u, %u)",
  272. m_data.item_num, m_data.offer_price, m_data.price, m_data.offer_id, m_data.shown_name, (DWORD)m_data.empire, (DWORD)m_data.expired_time,
  273. m_data.item_id, m_data.wisher_id);
  274. CDBManager::instance().AsyncQuery(szQuery);
  275. }
  276. CWishItemInfoCache::CWishItemInfoCache()
  277. {
  278. m_expireTime = MIN (auctionMinFlushSec, g_iItemCacheFlushSeconds);
  279. }
  280. CWishItemInfoCache::~CWishItemInfoCache()
  281. {
  282. }
  283. void CWishItemInfoCache::Delete()
  284. {
  285. }
  286. void CWishItemInfoCache::OnFlush()
  287. {
  288. char szQuery[QUERY_MAX_LEN];
  289. snprintf(szQuery, sizeof(szQuery), "REPLACE INTO wish VALUES (%u, %d, %d, %u, \"%s\", %u, %d)",
  290. m_data.item_num, m_data.offer_price, m_data.price, m_data.offer_id, m_data.shown_name, (DWORD)m_data.empire, (DWORD)m_data.expired_time);
  291. CDBManager::instance().AsyncQuery(szQuery);
  292. }
  293. #endif