Advertisement
Guest User

Untitled

a guest
Sep 27th, 2019
262
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 73.76 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include "constants.h"
  3. #include "config.h"
  4. #include "utils.h"
  5. #include "desc_manager.h"
  6. #include "char.h"
  7. #include "char_manager.h"
  8. #include "item.h"
  9. #include "item_manager.h"
  10. #include "packet.h"
  11. #include "protocol.h"
  12. #include "mob_manager.h"
  13. #include "shop_manager.h"
  14. #include "sectree_manager.h"
  15. #include "skill.h"
  16. #include "questmanager.h"
  17. #include "p2p.h"
  18. #include "guild.h"
  19. #include "guild_manager.h"
  20. #include "start_position.h"
  21. #include "party.h"
  22. #include "refine.h"
  23. #include "banword.h"
  24. #include "priv_manager.h"
  25. #include "db.h"
  26. #include "building.h"
  27. #include "login_sim.h"
  28. #include "wedding.h"
  29. #include "login_data.h"
  30. #include "unique_item.h"
  31.  
  32. #include "monarch.h"
  33. #include "affect.h"
  34. #include "castle.h"
  35. #include "block_country.h"
  36. #include "motion.h"
  37.  
  38. #include "dev_log.h"
  39.  
  40. #include "log.h"
  41.  
  42. #include "horsename_manager.h"
  43. #include "pcbang.h"
  44. #include "gm.h"
  45. #include "panama.h"
  46. #include "map_location.h"
  47. #include "HackShield.h"
  48. #include "XTrapManager.h"
  49.  
  50. #include "DragonSoul.h"
  51.  
  52. #ifdef __AUCTION__
  53. #include "auction_manager.h"
  54. #endif
  55. extern BYTE g_bAuthServer;
  56. #ifdef __AUCTION__
  57. extern int auction_server;
  58. #endif
  59. extern void gm_insert(const char * name, BYTE level);
  60. extern BYTE gm_get_level(const char * name, const char * host, const char* account );
  61. extern void gm_host_insert(const char * host);
  62. extern int openid_server;
  63.  
  64. #ifdef OFFLINE_SHOP
  65. static LPEVENT s_pkShopEvent = NULL;
  66. static LPEVENT s_pkFixShopEvent = NULL;
  67.  
  68. EVENTINFO(shop_event_info)
  69. {
  70. // used to send command
  71. DWORD empty;
  72. };
  73. #include "shop.h"
  74. EVENTFUNC(shop_event)
  75. {
  76. LPCHARACTER pc;
  77. CharacterVectorInteractor i;
  78.  
  79. if (CHARACTER_MANAGER::instance().GetCharactersByRaceNum(30000, i))
  80. {
  81. CharacterVectorInteractor::iterator it = i.begin();
  82.  
  83. while (it != i.end()) {
  84. LPCHARACTER pc = *it++;
  85. if (pc)
  86. {
  87. LPSHOP shop;
  88. if ((shop = pc->GetMyShop())) {
  89. if (pc->GetShopTime() < (unsigned)get_global_time() || shop->GetItemCount() <= 0)
  90. pc->DeleteMyShop();
  91. }
  92. else
  93. M2_DESTROY_CHARACTER(pc);
  94. }
  95.  
  96. }
  97. }
  98.  
  99. (void)pc;
  100. return PASSES_PER_SEC(SHOP_TIME_REFRESH);
  101. }
  102.  
  103. EVENTFUNC(fix_shop_event)
  104. {
  105. char szSockets[1024] = { '\0' };
  106. char *tempSockets = szSockets;
  107. for (int i = 0; i < ITEM_SOCKET_MAX_NUM; i++)
  108. {
  109. tempSockets += sprintf(tempSockets, "ps.socket%d", i);
  110.  
  111. if (i<ITEM_SOCKET_MAX_NUM - 1)
  112. tempSockets += sprintf(tempSockets, ",");
  113. }
  114. char szAttrs[1024] = { '\0' };
  115. char *tempAttrs = szAttrs;
  116. for (int i = 0; i < ITEM_ATTRIBUTE_MAX_NUM; i++)
  117. {
  118. if (i < 7)
  119. tempAttrs += sprintf(tempAttrs, "ps.attrtype%d,attrvalue%d", i, i);
  120. else
  121. tempAttrs += sprintf(tempAttrs, "ps.applytype%d,applyvalue%d", i - 7, i - 7);
  122. if (i<ITEM_ATTRIBUTE_MAX_NUM - 1)
  123. tempAttrs += sprintf(tempAttrs, ",");
  124. }
  125. SQLMsg * pkMsg(DBManager::instance().DirectQuery("SELECT ps.id,ps.shop_id,ps.player_id,REPLACE('%s','#PLAYER_NAME#',p.name),ps.vnum,ps.count,ps.price,%s,%s FROM `player_shop_items` ps LEFT JOIN player p ON p.id=ps.player_id where not EXISTS(select name from player_shop WHERE id=ps.shop_id) and not ISNULL(p.name)", LC_TEXT("SHOP_NAME"), szSockets, szAttrs));
  126. SQLResult * pRes = pkMsg->Get();
  127. if (pRes->uiNumRows>0)
  128. {
  129. MYSQL_ROW row;
  130. while ((row = mysql_fetch_row(pRes->pSQLResult)) != NULL)
  131. {
  132. DWORD id = 0,pid = 0,vnum = 0,count = 0,socket[6],attr[7][2];
  133. int col = 0;
  134. str_to_number(id, row[col++]);
  135. str_to_number(pid, row[col++]);
  136. col++;
  137.  
  138. str_to_number(vnum, row[col++]);
  139. str_to_number(count, row[col++]);
  140. for (int i = 0;i < ITEM_SOCKET_MAX_NUM;i++)
  141. str_to_number(socket[i], row[col++]);
  142. for (int i = 0;i < ITEM_ATTRIBUTE_MAX_NUM;i++)
  143. {
  144. str_to_number(attr[i][0], row[col++]);
  145. str_to_number(attr[i][1], row[col++]);
  146. }
  147. char query[1024];
  148. sprintf(query, "INSERT INTO player_gift SET owner_id=%d,vnum=%d,count=%d,reason='%s',`from`=replace(\"%s\",' ','_'),status='WAIT',date_add=NOW()",
  149. pid, vnum,count, LC_TEXT("Inchidere magazin"), row[3]);
  150.  
  151. for (int s = 0; s < ITEM_SOCKET_MAX_NUM; s++)
  152. {
  153. sprintf(query, "%s, socket%d='%d'", query, s, socket[s]);
  154.  
  155. }
  156. for (int ia = 0; ia < ITEM_ATTRIBUTE_MAX_NUM; ia++)
  157. {
  158. if (ia < 7)
  159. {
  160. sprintf(query, "%s, attrtype%d='%d'", query, ia, attr[ia][0]);
  161. sprintf(query, "%s, attrvalue%d='%d'", query, ia, attr[ia][1]);
  162. }
  163. else{
  164. sprintf(query, "%s, applytype%d='%d'", query, ia-7, attr[ia][0]);
  165. sprintf(query, "%s, applyvalue%d='%d'", query, ia-7, attr[ia][1]);
  166. }
  167.  
  168.  
  169. }
  170. DBManager::instance().DirectQuery(query);
  171. DBManager::instance().DirectQuery("delete from player_shop_items where id=%d",id);
  172.  
  173. }
  174. }
  175. return PASSES_PER_SEC(SHOP_TIME_REFRESH*60);
  176. }
  177. void CreateShops()
  178. {
  179. //sys_log(0,"Downloading shops list..");
  180. if (quest::CQuestManager::instance().GetEventFlag("shop_off") == 1)
  181. return;
  182. SQLMsg * pkMsg(DBManager::instance().DirectQuery("SELECT id,map_index from player_shop WHERE channel=%d and status='OK' and exists(select name from player where id=player_id)", g_bChannel));
  183. SQLResult * pRes = pkMsg->Get();
  184. if (pRes->uiNumRows>0)
  185. {
  186. MYSQL_ROW row;
  187. while ((row = mysql_fetch_row(pRes->pSQLResult)) != NULL)
  188. {
  189. long map_index;
  190. DWORD id = 0, vid;
  191. str_to_number(id, row[0]);
  192. str_to_number(map_index, row[1]);
  193. //sys_log(0,"Find shop id %d map_index %d",id,map_index);
  194. if (!CShopManager::instance().FindPCShop(id))
  195. {
  196.  
  197. //sys_log(0,"Creating offline shop id %d",id);
  198. CShopManager::instance().StartOfflineShop(id, true);
  199. }
  200. (void)vid;
  201. }
  202. }
  203. if (NULL == s_pkShopEvent)
  204. {
  205. shop_event_info* info = AllocEventInfo<shop_event_info>();
  206. s_pkShopEvent = event_create(shop_event, info,1);
  207. }
  208. if (NULL == s_pkFixShopEvent)
  209. {
  210. shop_event_info* info = AllocEventInfo<shop_event_info>();
  211. s_pkFixShopEvent = event_create(fix_shop_event, info,1);
  212. }
  213. }
  214. #endif
  215.  
  216. #ifdef OFFLINE_SHOP
  217. #include "shop_manager.h"
  218. void CInputDB::ShopClose(const char * c_pData)
  219. {
  220. TPacketShopClose * p = (TPacketShopClose *)c_pData;
  221. if (p->pid)
  222. {
  223. LPCHARACTER owner = CHARACTER_MANAGER::instance().FindByPID(p->pid);
  224. if (owner)
  225. {
  226. #ifdef GIFT_SYSTEM
  227. owner->RefreshGift();
  228. #endif
  229. owner->RemovePrivShopTable(p->shop_id);
  230. owner->SendShops();
  231. owner->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Magazinul a fost inchis, toate itemele si totii banii sunt in inventarul magazinului"));
  232. }
  233. return;
  234. }
  235.  
  236. LPCHARACTER pc;
  237. CharacterVectorInteractor i;
  238.  
  239. if (CHARACTER_MANAGER::instance().GetCharactersByRaceNum(30000, i))
  240. {
  241. CharacterVectorInteractor::iterator it = i.begin();
  242.  
  243. while (it != i.end()) {
  244. LPCHARACTER pc = *it++;
  245. if (pc)
  246. if (pc->GetPrivShop() == p->shop_id) {
  247. pc->DeleteMyShop();
  248. return;
  249. }
  250.  
  251. }
  252. }
  253. (void)pc;
  254. }
  255. void CInputDB::ShopName(const char * c_pData)
  256. {
  257. TPacketShopName * p = (TPacketShopName *)c_pData;
  258.  
  259. LPCHARACTER pc;
  260. CharacterVectorInteractor i;
  261.  
  262. if (CHARACTER_MANAGER::instance().GetCharactersByRaceNum(30000, i))
  263. {
  264. CharacterVectorInteractor::iterator it = i.begin();
  265.  
  266. while (it != i.end()) {
  267. LPCHARACTER pc = *it++;
  268. if (pc)
  269. {
  270. if (pc->GetPrivShop() == p->shop_id) {
  271. pc->SetShopSign(p->szSign);
  272. return;
  273. }
  274. }
  275. }
  276. }
  277. (void)pc;
  278. }
  279. void CInputDB::ShopUpdateItem(const char * c_pData)
  280. {
  281. TPacketShopUpdateItem * p = (TPacketShopUpdateItem *)c_pData;
  282.  
  283. LPCHARACTER pc;
  284. CharacterVectorInteractor i;
  285.  
  286. if (CHARACTER_MANAGER::instance().GetCharactersByRaceNum(30000, i))
  287. {
  288. CharacterVectorInteractor::iterator it = i.begin();
  289.  
  290. while (it != i.end()) {
  291. LPCHARACTER pc = *it++;
  292. if (pc)
  293. {
  294. if (pc->GetPrivShop() == p->shop_id) {
  295. pc->UpdateShopItems();
  296. return;
  297. }
  298. }
  299. }
  300. }
  301. (void)pc;
  302. }
  303. #endif
  304.  
  305. #define MAPNAME_DEFAULT "none"
  306.  
  307. bool GetServerLocation(TAccountTable & rTab, BYTE bEmpire)
  308. {
  309. bool bFound = false;
  310.  
  311. for (int i = 0; i < PLAYER_PER_ACCOUNT; ++i)
  312. {
  313. if (0 == rTab.players[i].dwID)
  314. continue;
  315.  
  316. bFound = true;
  317. long lIndex = 0;
  318.  
  319. if (!CMapLocation::instance().Get(rTab.players[i].x,
  320. rTab.players[i].y,
  321. lIndex,
  322. rTab.players[i].lAddr,
  323. rTab.players[i].wPort))
  324. {
  325. sys_err("location error name %s mapindex %d %d x %d empire %d",
  326. rTab.players[i].szName, lIndex, rTab.players[i].x, rTab.players[i].y, rTab.bEmpire);
  327.  
  328. rTab.players[i].x = EMPIRE_START_X(rTab.bEmpire);
  329. rTab.players[i].y = EMPIRE_START_Y(rTab.bEmpire);
  330.  
  331. lIndex = 0;
  332.  
  333. if (!CMapLocation::instance().Get(rTab.players[i].x, rTab.players[i].y, lIndex, rTab.players[i].lAddr, rTab.players[i].wPort))
  334. {
  335. sys_err("cannot find server for mapindex %d %d x %d (name %s)",
  336. lIndex,
  337. rTab.players[i].x,
  338. rTab.players[i].y,
  339. rTab.players[i].szName);
  340.  
  341. continue;
  342. }
  343. }
  344.  
  345. struct in_addr in;
  346. in.s_addr = rTab.players[i].lAddr;
  347. sys_log(0, "success to %s:%d", inet_ntoa(in), rTab.players[i].wPort);
  348. }
  349.  
  350. return bFound;
  351. }
  352.  
  353. extern std::map<DWORD, CLoginSim *> g_sim;
  354. extern std::map<DWORD, CLoginSim *> g_simByPID;
  355.  
  356. void CInputDB::LoginSuccess(DWORD dwHandle, const char *data)
  357. {
  358. sys_log(0, "LoginSuccess");
  359.  
  360. TAccountTable * pTab = (TAccountTable *) data;
  361.  
  362. itertype(g_sim) it = g_sim.find(pTab->id);
  363. if (g_sim.end() != it)
  364. {
  365. sys_log(0, "CInputDB::LoginSuccess - already exist sim [%s]", pTab->login);
  366. it->second->SendLoad();
  367. return;
  368. }
  369.  
  370. LPDESC d = DESC_MANAGER::instance().FindByHandle(dwHandle);
  371.  
  372. if (!d)
  373. {
  374. sys_log(0, "CInputDB::LoginSuccess - cannot find handle [%s]", pTab->login);
  375.  
  376. TLogoutPacket pack;
  377.  
  378. strlcpy(pack.login, pTab->login, sizeof(pack.login));
  379. db_clientdesc->DBPacket(HEADER_GD_LOGOUT, dwHandle, &pack, sizeof(pack));
  380. return;
  381. }
  382.  
  383. if (strcmp(pTab->status, "OK")) // OK가 아니면
  384. {
  385. sys_log(0, "CInputDB::LoginSuccess - status[%s] is not OK [%s]", pTab->status, pTab->login);
  386.  
  387. TLogoutPacket pack;
  388.  
  389. strlcpy(pack.login, pTab->login, sizeof(pack.login));
  390. db_clientdesc->DBPacket(HEADER_GD_LOGOUT, dwHandle, &pack, sizeof(pack));
  391.  
  392. LoginFailure(d, pTab->status);
  393. return;
  394. }
  395.  
  396. for (int i = 0; i != PLAYER_PER_ACCOUNT; ++i)
  397. {
  398. TSimplePlayer& player = pTab->players[i];
  399. sys_log(0, "\tplayer(%s).job(%d)", player.szName, player.byJob);
  400. }
  401.  
  402. bool bFound = GetServerLocation(*pTab, pTab->bEmpire);
  403.  
  404. d->BindAccountTable(pTab);
  405.  
  406. if (!bFound) // 캐릭터가 없으면 랜덤한 제국으로 보낸다.. -_-
  407. {
  408. TPacketGCEmpire pe;
  409. pe.bHeader = HEADER_GC_EMPIRE;
  410. pe.bEmpire = number(1, 3);
  411. d->Packet(&pe, sizeof(pe));
  412. }
  413. else
  414. {
  415. TPacketGCEmpire pe;
  416. pe.bHeader = HEADER_GC_EMPIRE;
  417. pe.bEmpire = d->GetEmpire();
  418. d->Packet(&pe, sizeof(pe));
  419. }
  420.  
  421. d->SetPhase(PHASE_SELECT);
  422. d->SendLoginSuccessPacket();
  423.  
  424. sys_log(0, "InputDB::login_success: %s", pTab->login);
  425. }
  426.  
  427. void CInputDB::PlayerCreateFailure(LPDESC d, BYTE bType)
  428. {
  429. if (!d)
  430. return;
  431.  
  432. TPacketGCCreateFailure pack;
  433.  
  434. pack.header = HEADER_GC_CHARACTER_CREATE_FAILURE;
  435. pack.bType = bType;
  436.  
  437. d->Packet(&pack, sizeof(pack));
  438. }
  439.  
  440. void CInputDB::PlayerCreateSuccess(LPDESC d, const char * data)
  441. {
  442. if (!d)
  443. return;
  444.  
  445. TPacketDGCreateSuccess * pPacketDB = (TPacketDGCreateSuccess *) data;
  446.  
  447. if (pPacketDB->bAccountCharacterIndex >= PLAYER_PER_ACCOUNT)
  448. {
  449. d->Packet(encode_byte(HEADER_GC_CHARACTER_CREATE_FAILURE), 1);
  450. return;
  451. }
  452.  
  453. long lIndex = 0;
  454.  
  455. if (!CMapLocation::instance().Get(pPacketDB->player.x,
  456. pPacketDB->player.y,
  457. lIndex,
  458. pPacketDB->player.lAddr,
  459. pPacketDB->player.wPort))
  460. {
  461. sys_err("InputDB::PlayerCreateSuccess: cannot find server for mapindex %d %d x %d (name %s)",
  462. lIndex,
  463. pPacketDB->player.x,
  464. pPacketDB->player.y,
  465. pPacketDB->player.szName);
  466. }
  467.  
  468. TAccountTable & r_Tab = d->GetAccountTable();
  469. r_Tab.players[pPacketDB->bAccountCharacterIndex] = pPacketDB->player;
  470.  
  471. TPacketGCPlayerCreateSuccess pack;
  472.  
  473. pack.header = HEADER_GC_CHARACTER_CREATE_SUCCESS;
  474. pack.bAccountCharacterIndex = pPacketDB->bAccountCharacterIndex;
  475. pack.player = pPacketDB->player;
  476.  
  477. d->Packet(&pack, sizeof(TPacketGCPlayerCreateSuccess));
  478.  
  479. // 기본 무기와 귀환부를 지급
  480. TPlayerItem t;
  481. memset(&t, 0, sizeof(t));
  482.  
  483. if (china_event_server)
  484. {
  485. t.window = INVENTORY;
  486. t.count = 1;
  487. t.owner = r_Tab.players[pPacketDB->bAccountCharacterIndex].dwID;
  488.  
  489. //무사: 자인갑+3,철편투구+3,금편신발+3,남만도+3,백금목걸이+3, 흑단귀걸이+3, 소산부+3, 오각패+3, 흑단팔찌+3
  490. //자객:영린+3,연환두건+3,금편신발+3,마안도+3,화안궁+3,옥목걸이+3, 옥귀걸이+3, 오각패+3, 흑단팔찌+3
  491. //수라:음양갑+3,애희투구+3,금편신발+3,남만도+3,진주목걸이+3, 백금귀걸이+3, 오각패+3, 흑단팔찌+3
  492. //무당:서천의+3,태을모+3,금편신발+3,자린선+3,매화령+3,진주목걸이+3, 백금귀걸이+3, 오각패+3, 흑단팔찌+3
  493.  
  494. struct SInitialItem
  495. {
  496. DWORD dwVnum;
  497. BYTE pos;
  498. };
  499.  
  500. const int MAX_INITIAL_ITEM = 9;
  501.  
  502. static SInitialItem initialItems[JOB_MAX_NUM][MAX_INITIAL_ITEM] =
  503. {
  504. { {11243, 2}, {12223, 3}, {15103, 4}, { 93, 1}, {16143, 8}, {17103, 9}, { 3083, 0}, {13193, 11}, {14103, 12}, },
  505. { {11443, 0}, {12363, 3}, {15103, 4}, { 1053, 2}, { 2083, 1}, {16083, 7}, {17083, 8}, {13193, 9}, {14103, 10}, },
  506. { {11643, 0}, {12503, 2}, {15103, 3}, { 93, 1}, {16123, 4}, {17143, 7}, {13193, 8}, {14103, 9}, { 0, 0}, },
  507. { {11843, 0}, {12643, 1}, {15103, 2}, { 7083, 3}, { 5053, 4}, {16123, 6}, {17143, 7}, {13193, 8}, {14103, 9}, },
  508. };
  509.  
  510. int job = pPacketDB->player.byJob;
  511. for (int i=0; i < MAX_INITIAL_ITEM; i++)
  512. {
  513. if (initialItems[job][i].dwVnum == 0)
  514. continue;
  515.  
  516. t.id = ITEM_MANAGER::instance().GetNewID();
  517. t.pos = initialItems[job][i].pos;
  518. t.vnum = initialItems[job][i].dwVnum;
  519.  
  520. db_clientdesc->DBPacketHeader(HEADER_GD_ITEM_SAVE, 0, sizeof(TPlayerItem));
  521. db_clientdesc->Packet(&t, sizeof(TPlayerItem));
  522. }
  523. }
  524.  
  525. LogManager::instance().CharLog(pack.player.dwID, 0, 0, 0, "CREATE PLAYER", "", d->GetHostName());
  526. }
  527.  
  528. void CInputDB::PlayerDeleteSuccess(LPDESC d, const char * data)
  529. {
  530. if (!d)
  531. return;
  532.  
  533. BYTE account_index;
  534. account_index = decode_byte(data);
  535. d->BufferedPacket(encode_byte(HEADER_GC_CHARACTER_DELETE_SUCCESS), 1);
  536. d->Packet(encode_byte(account_index), 1);
  537.  
  538. d->GetAccountTable().players[account_index].dwID = 0;
  539. }
  540.  
  541. void CInputDB::PlayerDeleteFail(LPDESC d)
  542. {
  543. if (!d)
  544. return;
  545.  
  546. d->Packet(encode_byte(HEADER_GC_CHARACTER_DELETE_WRONG_SOCIAL_ID), 1);
  547. //d->Packet(encode_byte(account_index), 1);
  548.  
  549. //d->GetAccountTable().players[account_index].dwID = 0;
  550. }
  551.  
  552. void CInputDB::ChangeName(LPDESC d, const char * data)
  553. {
  554. if (!d)
  555. return;
  556.  
  557. TPacketDGChangeName * p = (TPacketDGChangeName *) data;
  558.  
  559. TAccountTable & r = d->GetAccountTable();
  560.  
  561. if (!r.id)
  562. return;
  563.  
  564. for (size_t i = 0; i < PLAYER_PER_ACCOUNT; ++i)
  565. if (r.players[i].dwID == p->pid)
  566. {
  567. strlcpy(r.players[i].szName, p->name, sizeof(r.players[i].szName));
  568. r.players[i].bChangeName = 0;
  569.  
  570. TPacketGCChangeName pgc;
  571.  
  572. pgc.header = HEADER_GC_CHANGE_NAME;
  573. pgc.pid = p->pid;
  574. strlcpy(pgc.name, p->name, sizeof(pgc.name));
  575.  
  576. d->Packet(&pgc, sizeof(TPacketGCChangeName));
  577. break;
  578. }
  579. }
  580.  
  581. void CInputDB::PlayerLoad(LPDESC d, const char * data)
  582. {
  583. TPlayerTable * pTab = (TPlayerTable *) data;
  584.  
  585. if (!d)
  586. return;
  587.  
  588. long lMapIndex = pTab->lMapIndex;
  589. PIXEL_POSITION pos;
  590.  
  591. if (lMapIndex == 0)
  592. {
  593. lMapIndex = SECTREE_MANAGER::instance().GetMapIndex(pTab->x, pTab->y);
  594.  
  595. if (lMapIndex == 0) // 좌표를 찾을 수 없다.
  596. {
  597. lMapIndex = EMPIRE_START_MAP(d->GetAccountTable().bEmpire);
  598. pos.x = EMPIRE_START_X(d->GetAccountTable().bEmpire);
  599. pos.y = EMPIRE_START_Y(d->GetAccountTable().bEmpire);
  600. }
  601. else
  602. {
  603. pos.x = pTab->x;
  604. pos.y = pTab->y;
  605. }
  606. }
  607. pTab->lMapIndex = lMapIndex;
  608.  
  609. // Private 맵에 있었는데, Private 맵이 사라진 상태라면 출구로 돌아가야 한다.
  610. // ----
  611. // 근데 출구로 돌아가야 한다면서... 왜 출구가 아니라 private map 상에 대응되는 pulic map의 위치를 찾냐고...
  612. // 역사를 모르니... 또 하드코딩 한다.
  613. // 아귀동굴이면, 출구로...
  614. // by rtsummit
  615. if (!SECTREE_MANAGER::instance().GetValidLocation(pTab->lMapIndex, pTab->x, pTab->y, lMapIndex, pos, d->GetEmpire()))
  616. {
  617. sys_err("InputDB::PlayerLoad : cannot find valid location %d x %d (name: %s)", pTab->x, pTab->y, pTab->name);
  618. d->SetPhase(PHASE_CLOSE);
  619. return;
  620. }
  621.  
  622. pTab->x = pos.x;
  623. pTab->y = pos.y;
  624. pTab->lMapIndex = lMapIndex;
  625.  
  626. if (d->GetCharacter() || d->IsPhase(PHASE_GAME))
  627. {
  628. LPCHARACTER p = d->GetCharacter();
  629. sys_err("login state already has main state (character %s %p)", p->GetName(), get_pointer(p));
  630. return;
  631. }
  632.  
  633. if (NULL != CHARACTER_MANAGER::Instance().FindPC(pTab->name))
  634. {
  635. sys_err("InputDB: PlayerLoad : %s already exist in game", pTab->name);
  636. return;
  637. }
  638.  
  639. LPCHARACTER ch = CHARACTER_MANAGER::instance().CreateCharacter(pTab->name, pTab->id);
  640.  
  641. ch->BindDesc(d);
  642. ch->SetPlayerProto(pTab);
  643. ch->SetEmpire(d->GetEmpire());
  644.  
  645. d->BindCharacter(ch);
  646.  
  647. {
  648. // P2P Login
  649. TPacketGGLogin p;
  650.  
  651. p.bHeader = HEADER_GG_LOGIN;
  652. strlcpy(p.szName, ch->GetName(), sizeof(p.szName));
  653. p.dwPID = ch->GetPlayerID();
  654. p.bEmpire = ch->GetEmpire();
  655. p.lMapIndex = SECTREE_MANAGER::instance().GetMapIndex(ch->GetX(), ch->GetY());
  656. p.bChannel = g_bChannel;
  657.  
  658. P2P_MANAGER::instance().Send(&p, sizeof(TPacketGGLogin));
  659.  
  660. char buf[51];
  661. #ifdef ENABLE_REBORN_SYSTEM
  662. snprintf(buf, sizeof(buf), "%s %lld %d %ld %d %d",
  663. inet_ntoa(ch->GetDesc()->GetAddr().sin_addr), ch->GetGold(), g_bChannel, ch->GetMapIndex(), ch->GetAlignment(), ch->GetReborn());
  664. #else
  665. snprintf(buf, sizeof(buf), "%s %lld %d %ld %d",
  666. inet_ntoa(ch->GetDesc()->GetAddr().sin_addr), ch->GetGold(), g_bChannel, ch->GetMapIndex(), ch->GetAlignment());
  667. #endif
  668. LogManager::instance().CharLog(ch, 0, "LOGIN", buf);
  669.  
  670. if (LC_IsYMIR() || LC_IsKorea() || LC_IsBrazil() || LC_IsJapan())
  671. {
  672. LogManager::instance().LoginLog(true,
  673. ch->GetDesc()->GetAccountTable().id, ch->GetPlayerID(), ch->GetLevel(), ch->GetJob(), ch->GetRealPoint(POINT_PLAYTIME));
  674.  
  675. if (LC_IsBrazil() != true )
  676. {
  677. ch->SetPCBang(CPCBangManager::instance().IsPCBangIP(ch->GetDesc()->GetHostName()));
  678. }
  679. }
  680. }
  681.  
  682. d->SetPhase(PHASE_LOADING);
  683. ch->MainCharacterPacket();
  684.  
  685. long lPublicMapIndex = lMapIndex >= 10000 ? lMapIndex / 10000 : lMapIndex;
  686.  
  687. //Send Supplementary Data Block if new map requires security packages in loading this map
  688. const TMapRegion * rMapRgn = SECTREE_MANAGER::instance().GetMapRegion(lPublicMapIndex);
  689. if( rMapRgn )
  690. {
  691. DESC_MANAGER::instance().SendClientPackageSDBToLoadMap( d, rMapRgn->strMapName.c_str() );
  692. }
  693. //if (!map_allow_find(lMapIndex >= 10000 ? lMapIndex / 10000 : lMapIndex) || !CheckEmpire(ch, lMapIndex))
  694. if (!map_allow_find(lPublicMapIndex))
  695. {
  696. sys_err("InputDB::PlayerLoad : entering %d map is not allowed here (name: %s, empire %u)",
  697. lMapIndex, pTab->name, d->GetEmpire());
  698.  
  699. ch->SetWarpLocation(EMPIRE_START_MAP(d->GetEmpire()),
  700. EMPIRE_START_X(d->GetEmpire()) / 100,
  701. EMPIRE_START_Y(d->GetEmpire()) / 100);
  702.  
  703. d->SetPhase(PHASE_CLOSE);
  704. return;
  705. }
  706.  
  707. quest::CQuestManager::instance().BroadcastEventFlagOnLogin(ch);
  708.  
  709. for (int i = 0; i < QUICKSLOT_MAX_NUM; ++i)
  710. ch->SetQuickslot(i, pTab->quickslot[i]);
  711.  
  712. ch->PointsPacket();
  713. ch->SkillLevelPacket();
  714.  
  715. sys_log(0, "InputDB: player_load %s %dx%dx%d LEVEL %d MOV_SPEED %d JOB %d ATG %d DFG %d GMLv %d",
  716. pTab->name,
  717. ch->GetX(), ch->GetY(), ch->GetZ(),
  718. ch->GetLevel(),
  719. ch->GetPoint(POINT_MOV_SPEED),
  720. ch->GetJob(),
  721. ch->GetPoint(POINT_ATT_GRADE),
  722. ch->GetPoint(POINT_DEF_GRADE),
  723. ch->GetGMLevel());
  724.  
  725. ch->QuerySafeboxSize();
  726.  
  727. if (isHackShieldEnable)
  728. {
  729. if (! CHackShieldManager::instance().CreateClientHandle(ch->GetPlayerID()))
  730. {
  731. d->SetPhase(PHASE_CLOSE);
  732. }
  733. else
  734. {
  735. ch->StartHackShieldCheckCycle( HackShield_CheckCycleTime );
  736. }
  737. }
  738.  
  739. CXTrapManager::instance().CreateClientSession( ch );
  740. }
  741.  
  742. void CInputDB::Boot(const char* data)
  743. {
  744. signal_timer_disable();
  745.  
  746. // 패킷 사이즈 체크
  747. DWORD dwPacketSize = decode_4bytes(data);
  748. data += 4;
  749.  
  750. // 패킷 버전 체크
  751. BYTE bVersion = decode_byte(data);
  752. data += 1;
  753.  
  754. sys_log(0, "BOOT: PACKET: %d", dwPacketSize);
  755. sys_log(0, "BOOT: VERSION: %d", bVersion);
  756. if (bVersion != 6)
  757. {
  758. sys_err("boot version error");
  759. thecore_shutdown();
  760. }
  761.  
  762. sys_log(0, "sizeof(TMobTable) = %d", sizeof(TMobTable));
  763. sys_log(0, "sizeof(TItemTable) = %d", sizeof(TItemTable));
  764. sys_log(0, "sizeof(TShopTable) = %d", sizeof(TShopTable));
  765. sys_log(0, "sizeof(TSkillTable) = %d", sizeof(TSkillTable));
  766. sys_log(0, "sizeof(TRefineTable) = %d", sizeof(TRefineTable));
  767. sys_log(0, "sizeof(TItemAttrTable) = %d", sizeof(TItemAttrTable));
  768. sys_log(0, "sizeof(TItemRareTable) = %d", sizeof(TItemAttrTable));
  769. sys_log(0, "sizeof(TBanwordTable) = %d", sizeof(TBanwordTable));
  770. sys_log(0, "sizeof(TLand) = %d", sizeof(building::TLand));
  771. sys_log(0, "sizeof(TObjectProto) = %d", sizeof(building::TObjectProto));
  772. sys_log(0, "sizeof(TObject) = %d", sizeof(building::TObject));
  773. //ADMIN_MANAGER
  774. sys_log(0, "sizeof(TAdminManager) = %d", sizeof (TAdminInfo) );
  775. //END_ADMIN_MANAGER
  776.  
  777. WORD size;
  778.  
  779. /*
  780. * MOB
  781. */
  782.  
  783. if (decode_2bytes(data)!=sizeof(TMobTable))
  784. {
  785. sys_err("mob table size error");
  786. thecore_shutdown();
  787. return;
  788. }
  789. data += 2;
  790.  
  791. size = decode_2bytes(data);
  792. data += 2;
  793. sys_log(0, "BOOT: MOB: %d", size);
  794.  
  795. if (size)
  796. {
  797. CMobManager::instance().Initialize((TMobTable *) data, size);
  798. data += size * sizeof(TMobTable);
  799. }
  800.  
  801. /*
  802. * ITEM
  803. */
  804.  
  805. if (decode_2bytes(data) != sizeof(TItemTable))
  806. {
  807. sys_err("item table size error");
  808. thecore_shutdown();
  809. return;
  810. }
  811. data += 2;
  812.  
  813. size = decode_2bytes(data);
  814. data += 2;
  815. sys_log(0, "BOOT: ITEM: %d", size);
  816.  
  817.  
  818. if (size)
  819. {
  820. ITEM_MANAGER::instance().Initialize((TItemTable *) data, size);
  821. data += size * sizeof(TItemTable);
  822. }
  823.  
  824. /*
  825. * SHOP
  826. */
  827.  
  828. if (decode_2bytes(data) != sizeof(TShopTable))
  829. {
  830. sys_err("shop table size error");
  831. thecore_shutdown();
  832. return;
  833. }
  834. data += 2;
  835.  
  836. size = decode_2bytes(data);
  837. data += 2;
  838. sys_log(0, "BOOT: SHOP: %d", size);
  839.  
  840.  
  841. if (size)
  842. {
  843. if (!CShopManager::instance().Initialize((TShopTable *) data, size))
  844. {
  845. sys_err("shop table Initialize error");
  846. thecore_shutdown();
  847. return;
  848. }
  849. data += size * sizeof(TShopTable);
  850. }
  851.  
  852. /*
  853. * SKILL
  854. */
  855.  
  856. if (decode_2bytes(data) != sizeof(TSkillTable))
  857. {
  858. sys_err("skill table size error");
  859. thecore_shutdown();
  860. return;
  861. }
  862. data += 2;
  863.  
  864. size = decode_2bytes(data);
  865. data += 2;
  866. sys_log(0, "BOOT: SKILL: %d", size);
  867.  
  868. if (size)
  869. {
  870. if (!CSkillManager::instance().Initialize((TSkillTable *) data, size))
  871. {
  872. sys_err("cannot initialize skill table");
  873. thecore_shutdown();
  874. return;
  875. }
  876.  
  877. data += size * sizeof(TSkillTable);
  878. }
  879. /*
  880. * REFINE RECIPE
  881. */
  882. if (decode_2bytes(data) != sizeof(TRefineTable))
  883. {
  884. sys_err("refine table size error");
  885. thecore_shutdown();
  886. return;
  887. }
  888. data += 2;
  889.  
  890. size = decode_2bytes(data);
  891. data += 2;
  892. sys_log(0, "BOOT: REFINE: %d", size);
  893.  
  894. if (size)
  895. {
  896. CRefineManager::instance().Initialize((TRefineTable*) data, size);
  897. data += size * sizeof(TRefineTable);
  898. }
  899.  
  900. /*
  901. * ITEM ATTR
  902. */
  903. if (decode_2bytes(data) != sizeof(TItemAttrTable))
  904. {
  905. sys_err("item attr table size error");
  906. thecore_shutdown();
  907. return;
  908. }
  909. data += 2;
  910.  
  911. size = decode_2bytes(data);
  912. data += 2;
  913. sys_log(0, "BOOT: ITEM_ATTR: %d", size);
  914.  
  915. if (size)
  916. {
  917. TItemAttrTable * p = (TItemAttrTable *) data;
  918.  
  919. for (int i = 0; i < size; ++i, ++p)
  920. {
  921. if (p->dwApplyIndex >= MAX_APPLY_NUM)
  922. continue;
  923.  
  924. g_map_itemAttr[p->dwApplyIndex] = *p;
  925. sys_log(0, "ITEM_ATTR[%d]: %s %u", p->dwApplyIndex, p->szApply, p->dwProb);
  926. }
  927. }
  928.  
  929. data += size * sizeof(TItemAttrTable);
  930.  
  931.  
  932. /*
  933. * ITEM RARE
  934. */
  935. if (decode_2bytes(data) != sizeof(TItemAttrTable))
  936. {
  937. sys_err("item rare table size error");
  938. thecore_shutdown();
  939. return;
  940. }
  941. data += 2;
  942.  
  943. size = decode_2bytes(data);
  944. data += 2;
  945. sys_log(0, "BOOT: ITEM_RARE: %d", size);
  946.  
  947. if (size)
  948. {
  949. TItemAttrTable * p = (TItemAttrTable *) data;
  950.  
  951. for (int i = 0; i < size; ++i, ++p)
  952. {
  953. if (p->dwApplyIndex >= MAX_APPLY_NUM)
  954. continue;
  955.  
  956. g_map_itemRare[p->dwApplyIndex] = *p;
  957. sys_log(0, "ITEM_RARE[%d]: %s %u", p->dwApplyIndex, p->szApply, p->dwProb);
  958. }
  959. }
  960.  
  961. data += size * sizeof(TItemAttrTable);
  962.  
  963.  
  964. /*
  965. * BANWORDS
  966. */
  967.  
  968. if (decode_2bytes(data) != sizeof(TBanwordTable))
  969. {
  970. sys_err("ban word table size error");
  971. thecore_shutdown();
  972. return;
  973. }
  974. data += 2;
  975.  
  976. size = decode_2bytes(data);
  977. data += 2;
  978.  
  979. CBanwordManager::instance().Initialize((TBanwordTable *) data, size);
  980. data += size * sizeof(TBanwordTable);
  981.  
  982. {
  983. using namespace building;
  984.  
  985. /*
  986. * LANDS
  987. */
  988.  
  989. if (decode_2bytes(data) != sizeof(TLand))
  990. {
  991. sys_err("land table size error");
  992. thecore_shutdown();
  993. return;
  994. }
  995. data += 2;
  996.  
  997. size = decode_2bytes(data);
  998. data += 2;
  999.  
  1000. TLand * kLand = (TLand *) data;
  1001. data += size * sizeof(TLand);
  1002.  
  1003. for (WORD i = 0; i < size; ++i, ++kLand)
  1004. CManager::instance().LoadLand(kLand);
  1005.  
  1006. /*
  1007. * OBJECT PROTO
  1008. */
  1009.  
  1010. if (decode_2bytes(data) != sizeof(TObjectProto))
  1011. {
  1012. sys_err("object proto table size error");
  1013. thecore_shutdown();
  1014. return;
  1015. }
  1016. data += 2;
  1017.  
  1018. size = decode_2bytes(data);
  1019. data += 2;
  1020.  
  1021. CManager::instance().LoadObjectProto((TObjectProto *) data, size);
  1022. data += size * sizeof(TObjectProto);
  1023.  
  1024. /*
  1025. * OBJECT
  1026. */
  1027. if (decode_2bytes(data) != sizeof(TObject))
  1028. {
  1029. sys_err("object table size error");
  1030. thecore_shutdown();
  1031. return;
  1032. }
  1033. data += 2;
  1034.  
  1035. size = decode_2bytes(data);
  1036. data += 2;
  1037.  
  1038. TObject * kObj = (TObject *) data;
  1039. data += size * sizeof(TObject);
  1040.  
  1041. for (WORD i = 0; i < size; ++i, ++kObj)
  1042. CManager::instance().LoadObject(kObj, true);
  1043. }
  1044. #ifdef __AUCTION__
  1045. // Auction
  1046. AuctionManager::instance().Boot(data);
  1047. #endif
  1048. set_global_time(*(time_t *) data);
  1049. data += sizeof(time_t);
  1050.  
  1051. if (decode_2bytes(data) != sizeof(TItemIDRangeTable) )
  1052. {
  1053. sys_err("ITEM ID RANGE size error");
  1054. thecore_shutdown();
  1055. return;
  1056. }
  1057. data += 2;
  1058.  
  1059. size = decode_2bytes(data);
  1060. data += 2;
  1061.  
  1062. TItemIDRangeTable* range = (TItemIDRangeTable*) data;
  1063. data += size * sizeof(TItemIDRangeTable);
  1064.  
  1065. TItemIDRangeTable* rangespare = (TItemIDRangeTable*) data;
  1066. data += size * sizeof(TItemIDRangeTable);
  1067.  
  1068. //ADMIN_MANAGER
  1069. //관리자 등록
  1070. int ChunkSize = decode_2bytes(data );
  1071. data += 2;
  1072. int HostSize = decode_2bytes(data );
  1073. data += 2;
  1074. sys_log(0, "GM Value Count %d %d", HostSize, ChunkSize );
  1075. for (int n = 0; n < HostSize; ++n )
  1076. {
  1077. gm_new_host_inert(data );
  1078. sys_log(0, "GM HOST : IP[%s] ", data );
  1079. data += ChunkSize;
  1080. }
  1081.  
  1082.  
  1083. data += 2;
  1084. int adminsize = decode_2bytes(data );
  1085. data += 2;
  1086.  
  1087. for (int n = 0; n < adminsize; ++n )
  1088. {
  1089. tAdminInfo& rAdminInfo = *(tAdminInfo*)data;
  1090.  
  1091. gm_new_insert(rAdminInfo );
  1092.  
  1093. data += sizeof(rAdminInfo );
  1094. }
  1095.  
  1096. //END_ADMIN_MANAGER
  1097.  
  1098. //MONARCH
  1099. data += 2;
  1100. data += 2;
  1101.  
  1102. TMonarchInfo& p = *(TMonarchInfo *) data;
  1103. data += sizeof(TMonarchInfo);
  1104.  
  1105. CMonarch::instance().SetMonarchInfo(&p);
  1106.  
  1107. for (int n = 1; n < 4; ++n)
  1108. {
  1109. if (p.name[n] && *p.name[n])
  1110. sys_log(0, "[MONARCH] Empire %d Pid %d Money %d %s", n, p.pid[n], p.money[n], p.name[n]);
  1111. }
  1112.  
  1113. int CandidacySize = decode_2bytes(data);
  1114. data += 2;
  1115.  
  1116. int CandidacyCount = decode_2bytes(data);
  1117. data += 2;
  1118.  
  1119. if (test_server)
  1120. sys_log (0, "[MONARCH] Size %d Count %d", CandidacySize, CandidacyCount);
  1121.  
  1122. data += CandidacySize * CandidacyCount;
  1123.  
  1124.  
  1125. //END_MONARCH
  1126.  
  1127. WORD endCheck=decode_2bytes(data);
  1128. if (endCheck != 0xffff)
  1129. {
  1130. sys_err("boot packet end check error [%x]!=0xffff", endCheck);
  1131. thecore_shutdown();
  1132. return;
  1133. }
  1134. else
  1135. sys_log(0, "boot packet end check ok [%x]==0xffff", endCheck );
  1136. data +=2;
  1137.  
  1138. if (!ITEM_MANAGER::instance().SetMaxItemID(*range))
  1139. {
  1140. sys_err("not enough item id contact your administrator!");
  1141. thecore_shutdown();
  1142. return;
  1143. }
  1144.  
  1145. if (!ITEM_MANAGER::instance().SetMaxSpareItemID(*rangespare))
  1146. {
  1147. sys_err("not enough item id for spare contact your administrator!");
  1148. thecore_shutdown();
  1149. return;
  1150. }
  1151.  
  1152.  
  1153.  
  1154. // LOCALE_SERVICE
  1155. const int FILE_NAME_LEN = 256;
  1156. char szCommonDropItemFileName[FILE_NAME_LEN];
  1157. char szETCDropItemFileName[FILE_NAME_LEN];
  1158. char szMOBDropItemFileName[FILE_NAME_LEN];
  1159. char szDropItemGroupFileName[FILE_NAME_LEN];
  1160. char szSpecialItemGroupFileName[FILE_NAME_LEN];
  1161. char szMapIndexFileName[FILE_NAME_LEN];
  1162. char szItemVnumMaskTableFileName[FILE_NAME_LEN];
  1163. char szDragonSoulTableFileName[FILE_NAME_LEN];
  1164.  
  1165. snprintf(szCommonDropItemFileName, sizeof(szCommonDropItemFileName),
  1166. "%s/common_drop_item.txt", LocaleService_GetBasePath().c_str());
  1167. snprintf(szETCDropItemFileName, sizeof(szETCDropItemFileName),
  1168. "%s/etc_drop_item.txt", LocaleService_GetBasePath().c_str());
  1169. snprintf(szMOBDropItemFileName, sizeof(szMOBDropItemFileName),
  1170. "%s/mob_drop_item.txt", LocaleService_GetBasePath().c_str());
  1171. snprintf(szSpecialItemGroupFileName, sizeof(szSpecialItemGroupFileName),
  1172. "%s/special_item_group.txt", LocaleService_GetBasePath().c_str());
  1173. snprintf(szDropItemGroupFileName, sizeof(szDropItemGroupFileName),
  1174. "%s/drop_item_group.txt", LocaleService_GetBasePath().c_str());
  1175. snprintf(szMapIndexFileName, sizeof(szMapIndexFileName),
  1176. "%s/index", LocaleService_GetMapPath().c_str());
  1177. snprintf(szItemVnumMaskTableFileName, sizeof(szItemVnumMaskTableFileName),
  1178. "%s/ori_to_new_table.txt", LocaleService_GetBasePath().c_str());
  1179. snprintf(szDragonSoulTableFileName, sizeof(szDragonSoulTableFileName),
  1180. "%s/dragon_soul_table.txt", LocaleService_GetBasePath().c_str());
  1181.  
  1182. sys_log(0, "Initializing Informations of Cube System");
  1183. if (!Cube_InformationInitialize())
  1184. {
  1185. sys_err("cannot init cube infomation.");
  1186. thecore_shutdown();
  1187. return;
  1188. }
  1189.  
  1190. sys_log(0, "LoadLocaleFile: CommonDropItem: %s", szCommonDropItemFileName);
  1191. if (!ITEM_MANAGER::instance().ReadCommonDropItemFile(szCommonDropItemFileName))
  1192. {
  1193. sys_err("cannot load CommonDropItem: %s", szCommonDropItemFileName);
  1194. thecore_shutdown();
  1195. return;
  1196. }
  1197.  
  1198. sys_log(0, "LoadLocaleFile: ETCDropItem: %s", szETCDropItemFileName);
  1199. if (!ITEM_MANAGER::instance().ReadEtcDropItemFile(szETCDropItemFileName))
  1200. {
  1201. sys_err("cannot load ETCDropItem: %s", szETCDropItemFileName);
  1202. thecore_shutdown();
  1203. return;
  1204. }
  1205.  
  1206. sys_log(0, "LoadLocaleFile: DropItemGroup: %s", szDropItemGroupFileName);
  1207. if (!ITEM_MANAGER::instance().ReadDropItemGroup(szDropItemGroupFileName))
  1208. {
  1209. sys_err("cannot load DropItemGroup: %s", szDropItemGroupFileName);
  1210. thecore_shutdown();
  1211. return;
  1212. }
  1213.  
  1214. sys_log(0, "LoadLocaleFile: SpecialItemGroup: %s", szSpecialItemGroupFileName);
  1215. if (!ITEM_MANAGER::instance().ReadSpecialDropItemFile(szSpecialItemGroupFileName))
  1216. {
  1217. sys_err("cannot load SpecialItemGroup: %s", szSpecialItemGroupFileName);
  1218. thecore_shutdown();
  1219. return;
  1220. }
  1221.  
  1222. sys_log(0, "LoadLocaleFile: ItemVnumMaskTable : %s", szItemVnumMaskTableFileName);
  1223. if (!ITEM_MANAGER::instance().ReadItemVnumMaskTable(szItemVnumMaskTableFileName))
  1224. {
  1225. sys_log(0, "Could not open MaskItemTable");
  1226. }
  1227.  
  1228. sys_log(0, "LoadLocaleFile: MOBDropItemFile: %s", szMOBDropItemFileName);
  1229. if (!ITEM_MANAGER::instance().ReadMonsterDropItemGroup(szMOBDropItemFileName))
  1230. {
  1231. sys_err("cannot load MOBDropItemFile: %s", szMOBDropItemFileName);
  1232. thecore_shutdown();
  1233. return;
  1234. }
  1235.  
  1236. sys_log(0, "LoadLocaleFile: MapIndex: %s", szMapIndexFileName);
  1237. if (!SECTREE_MANAGER::instance().Build(szMapIndexFileName, LocaleService_GetMapPath().c_str()))
  1238. {
  1239. sys_err("cannot load MapIndex: %s", szMapIndexFileName);
  1240. thecore_shutdown();
  1241. return;
  1242. }
  1243.  
  1244. sys_log(0, "LoadLocaleFile: DragonSoulTable: %s", szDragonSoulTableFileName);
  1245. if (!DSManager::instance().ReadDragonSoulTableFile(szDragonSoulTableFileName))
  1246. {
  1247. sys_err("cannot load DragonSoulTable: %s", szDragonSoulTableFileName);
  1248. //thecore_shutdown();
  1249. //return;
  1250. }
  1251.  
  1252. // END_OF_LOCALE_SERVICE
  1253.  
  1254.  
  1255. building::CManager::instance().FinalizeBoot();
  1256.  
  1257. CMotionManager::instance().Build();
  1258.  
  1259. signal_timer_enable(30);
  1260.  
  1261. if (test_server)
  1262. {
  1263. CMobManager::instance().DumpRegenCount("mob_count");
  1264. }
  1265.  
  1266. CPCBangManager::instance().RequestUpdateIPList(0);
  1267.  
  1268. // castle_boot
  1269. castle_boot();
  1270.  
  1271. #ifdef OFFLINE_SHOP
  1272. CreateShops();
  1273. #endif
  1274.  
  1275. // request blocked_country_ip
  1276. {
  1277. db_clientdesc->DBPacket(HEADER_GD_BLOCK_COUNTRY_IP, 0, NULL, 0);
  1278. dev_log(LOG_DEB0, "<sent HEADER_GD_BLOCK_COUNTRY_IP>");
  1279. }
  1280. }
  1281.  
  1282. EVENTINFO(quest_login_event_info)
  1283. {
  1284. DWORD dwPID;
  1285.  
  1286. quest_login_event_info()
  1287. : dwPID( 0 )
  1288. {
  1289. }
  1290. };
  1291.  
  1292. EVENTFUNC(quest_login_event)
  1293. {
  1294. quest_login_event_info* info = dynamic_cast<quest_login_event_info*>( event->info );
  1295.  
  1296. if ( info == NULL )
  1297. {
  1298. sys_err( "quest_login_event> <Factor> Null pointer" );
  1299. return 0;
  1300. }
  1301.  
  1302. DWORD dwPID = info->dwPID;
  1303.  
  1304. LPCHARACTER ch = CHARACTER_MANAGER::instance().FindByPID(dwPID);
  1305.  
  1306. if (!ch)
  1307. return 0;
  1308.  
  1309. LPDESC d = ch->GetDesc();
  1310.  
  1311. if (!d)
  1312. return 0;
  1313.  
  1314. if (d->IsPhase(PHASE_HANDSHAKE) ||
  1315. d->IsPhase(PHASE_LOGIN) ||
  1316. d->IsPhase(PHASE_SELECT) ||
  1317. d->IsPhase(PHASE_DEAD) ||
  1318. d->IsPhase(PHASE_LOADING))
  1319. {
  1320. return PASSES_PER_SEC(1);
  1321. }
  1322. else if (d->IsPhase(PHASE_CLOSE))
  1323. {
  1324. return 0;
  1325. }
  1326. else if (d->IsPhase(PHASE_GAME))
  1327. {
  1328. sys_log(0, "QUEST_LOAD: Login pc %d by event", ch->GetPlayerID());
  1329. quest::CQuestManager::instance().Login(ch->GetPlayerID());
  1330. return 0;
  1331. }
  1332. else
  1333. {
  1334. sys_err(0, "input_db.cpp:quest_login_event INVALID PHASE pid %d", ch->GetPlayerID());
  1335. return 0;
  1336. }
  1337. }
  1338.  
  1339. void CInputDB::QuestLoad(LPDESC d, const char * c_pData)
  1340. {
  1341. if (NULL == d)
  1342. return;
  1343.  
  1344. LPCHARACTER ch = d->GetCharacter();
  1345.  
  1346. if (NULL == ch)
  1347. return;
  1348.  
  1349. const DWORD dwCount = decode_4bytes(c_pData);
  1350.  
  1351. const TQuestTable* pQuestTable = reinterpret_cast<const TQuestTable*>(c_pData+4);
  1352.  
  1353. if (NULL != pQuestTable)
  1354. {
  1355. if (dwCount != 0)
  1356. {
  1357. if (ch->GetPlayerID() != pQuestTable[0].dwPID)
  1358. {
  1359. sys_err("PID differs %u %u", ch->GetPlayerID(), pQuestTable[0].dwPID);
  1360. return;
  1361. }
  1362. }
  1363.  
  1364. sys_log(0, "QUEST_LOAD: count %d", dwCount);
  1365.  
  1366. quest::PC * pkPC = quest::CQuestManager::instance().GetPCForce(ch->GetPlayerID());
  1367.  
  1368. if (!pkPC)
  1369. {
  1370. sys_err("null quest::PC with id %u", pQuestTable[0].dwPID);
  1371. return;
  1372. }
  1373.  
  1374. if (pkPC->IsLoaded())
  1375. return;
  1376.  
  1377. for (unsigned int i = 0; i < dwCount; ++i)
  1378. {
  1379. std::string st(pQuestTable[i].szName);
  1380.  
  1381. st += ".";
  1382. st += pQuestTable[i].szState;
  1383.  
  1384. sys_log(0, " %s %d", st.c_str(), pQuestTable[i].lValue);
  1385. pkPC->SetFlag(st.c_str(), pQuestTable[i].lValue, false);
  1386. }
  1387.  
  1388. pkPC->SetLoaded();
  1389. pkPC->Build();
  1390.  
  1391. if (ch->GetDesc()->IsPhase(PHASE_GAME))
  1392. {
  1393. sys_log(0, "QUEST_LOAD: Login pc %d", pQuestTable[0].dwPID);
  1394. quest::CQuestManager::instance().Login(pQuestTable[0].dwPID);
  1395. }
  1396. else
  1397. {
  1398. quest_login_event_info* info = AllocEventInfo<quest_login_event_info>();
  1399. info->dwPID = ch->GetPlayerID();
  1400.  
  1401. event_create(quest_login_event, info, PASSES_PER_SEC(1));
  1402. }
  1403. }
  1404. }
  1405.  
  1406. void CInputDB::SafeboxLoad(LPDESC d, const char * c_pData)
  1407. {
  1408. if (!d)
  1409. return;
  1410.  
  1411. TSafeboxTable * p = (TSafeboxTable *) c_pData;
  1412.  
  1413. if (d->GetAccountTable().id != p->dwID)
  1414. {
  1415. sys_err("SafeboxLoad: safebox has different id %u != %u", d->GetAccountTable().id, p->dwID);
  1416. return;
  1417. }
  1418.  
  1419. if (!d->GetCharacter())
  1420. return;
  1421.  
  1422. BYTE bSize = 1;
  1423.  
  1424. LPCHARACTER ch = d->GetCharacter();
  1425.  
  1426. //PREVENT_TRADE_WINDOW
  1427. if (ch->GetShopOwner() || ch->GetExchange() || ch->GetMyShop())
  1428. {
  1429. d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("다른거래창이 열린상태에서는 창고를 열수가 없습니다." ) );
  1430. d->GetCharacter()->CancelSafeboxLoad();
  1431. return;
  1432. }
  1433. //END_PREVENT_TRADE_WINDOW
  1434.  
  1435. // ADD_PREMIUM
  1436. if (d->GetCharacter()->GetPremiumRemainSeconds(PREMIUM_SAFEBOX) > 0 ||
  1437. d->GetCharacter()->IsEquipUniqueGroup(UNIQUE_GROUP_LARGE_SAFEBOX))
  1438. bSize = 3;
  1439. // END_OF_ADD_PREMIUM
  1440.  
  1441. //if (d->GetCharacter()->IsEquipUniqueItem(UNIQUE_ITEM_SAFEBOX_EXPAND))
  1442. //bSize = 3; // 창고확장권
  1443.  
  1444. //d->GetCharacter()->LoadSafebox(p->bSize * SAFEBOX_PAGE_SIZE, p->dwGold, p->wItemCount, (TPlayerItem *) (c_pData + sizeof(TSafeboxTable)));
  1445. d->GetCharacter()->LoadSafebox(bSize * SAFEBOX_PAGE_SIZE, p->dwGold, p->wItemCount, (TPlayerItem *) (c_pData + sizeof(TSafeboxTable)));
  1446. }
  1447.  
  1448. void CInputDB::SafeboxChangeSize(LPDESC d, const char * c_pData)
  1449. {
  1450. if (!d)
  1451. return;
  1452.  
  1453. BYTE bSize = *(BYTE *) c_pData;
  1454.  
  1455. if (!d->GetCharacter())
  1456. return;
  1457.  
  1458. d->GetCharacter()->ChangeSafeboxSize(bSize);
  1459. }
  1460.  
  1461. //
  1462. // @version 05/06/20 Bang2ni - ReqSafeboxLoad 의 취소
  1463. //
  1464. void CInputDB::SafeboxWrongPassword(LPDESC d)
  1465. {
  1466. if (!d)
  1467. return;
  1468.  
  1469. if (!d->GetCharacter())
  1470. return;
  1471.  
  1472. TPacketCGSafeboxWrongPassword p;
  1473. p.bHeader = HEADER_GC_SAFEBOX_WRONG_PASSWORD;
  1474. d->Packet(&p, sizeof(p));
  1475.  
  1476. d->GetCharacter()->CancelSafeboxLoad();
  1477. }
  1478.  
  1479. void CInputDB::SafeboxChangePasswordAnswer(LPDESC d, const char* c_pData)
  1480. {
  1481. if (!d)
  1482. return;
  1483.  
  1484. if (!d->GetCharacter())
  1485. return;
  1486.  
  1487. TSafeboxChangePasswordPacketAnswer* p = (TSafeboxChangePasswordPacketAnswer*) c_pData;
  1488. if (p->flag)
  1489. {
  1490. d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<창고> 창고 비밀번호가 변경되었습니다."));
  1491. }
  1492. else
  1493. {
  1494. d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<창고> 기존 비밀번호가 틀렸습니다."));
  1495. }
  1496. }
  1497.  
  1498. void CInputDB::MallLoad(LPDESC d, const char * c_pData)
  1499. {
  1500. if (!d)
  1501. return;
  1502.  
  1503. TSafeboxTable * p = (TSafeboxTable *) c_pData;
  1504.  
  1505. if (d->GetAccountTable().id != p->dwID)
  1506. {
  1507. sys_err("safebox has different id %u != %u", d->GetAccountTable().id, p->dwID);
  1508. return;
  1509. }
  1510.  
  1511. if (!d->GetCharacter())
  1512. return;
  1513.  
  1514. d->GetCharacter()->LoadMall(p->wItemCount, (TPlayerItem *) (c_pData + sizeof(TSafeboxTable)));
  1515. }
  1516.  
  1517. void CInputDB::LoginAlready(LPDESC d, const char * c_pData)
  1518. {
  1519. if (!d)
  1520. return;
  1521.  
  1522. // INTERNATIONAL_VERSION 이미 접속중이면 접속 끊음
  1523. {
  1524. TPacketDGLoginAlready * p = (TPacketDGLoginAlready *) c_pData;
  1525.  
  1526. LPDESC d2 = DESC_MANAGER::instance().FindByLoginName(p->szLogin);
  1527.  
  1528. if (d2)
  1529. d2->DisconnectOfSameLogin();
  1530. else
  1531. {
  1532. TPacketGGDisconnect pgg;
  1533.  
  1534. pgg.bHeader = HEADER_GG_DISCONNECT;
  1535. strlcpy(pgg.szLogin, p->szLogin, sizeof(pgg.szLogin));
  1536.  
  1537. P2P_MANAGER::instance().Send(&pgg, sizeof(TPacketGGDisconnect));
  1538. }
  1539. }
  1540. // END_OF_INTERNATIONAL_VERSION
  1541.  
  1542. LoginFailure(d, "ALREADY");
  1543. }
  1544.  
  1545. void CInputDB::EmpireSelect(LPDESC d, const char * c_pData)
  1546. {
  1547. sys_log(0, "EmpireSelect %p", get_pointer(d));
  1548.  
  1549. if (!d)
  1550. return;
  1551.  
  1552. TAccountTable & rTable = d->GetAccountTable();
  1553. rTable.bEmpire = *(BYTE *) c_pData;
  1554.  
  1555. TPacketGCEmpire pe;
  1556. pe.bHeader = HEADER_GC_EMPIRE;
  1557. pe.bEmpire = rTable.bEmpire;
  1558. d->Packet(&pe, sizeof(pe));
  1559.  
  1560. for (int i = 0; i < PLAYER_PER_ACCOUNT; ++i)
  1561. if (rTable.players[i].dwID)
  1562. {
  1563. rTable.players[i].x = EMPIRE_START_X(rTable.bEmpire);
  1564. rTable.players[i].y = EMPIRE_START_Y(rTable.bEmpire);
  1565. }
  1566.  
  1567. GetServerLocation(d->GetAccountTable(), rTable.bEmpire);
  1568.  
  1569. d->SendLoginSuccessPacket();
  1570. }
  1571.  
  1572. void CInputDB::MapLocations(const char * c_pData)
  1573. {
  1574. BYTE bCount = *(BYTE *) (c_pData++);
  1575.  
  1576. sys_log(0, "InputDB::MapLocations %d", bCount);
  1577.  
  1578. TMapLocation * pLoc = (TMapLocation *) c_pData;
  1579.  
  1580. while (bCount--)
  1581. {
  1582. for (int i = 0; i < 32; ++i)
  1583. {
  1584. if (0 == pLoc->alMaps[i])
  1585. break;
  1586.  
  1587. CMapLocation::instance().Insert(pLoc->alMaps[i], pLoc->szHost, pLoc->wPort);
  1588. }
  1589.  
  1590. pLoc++;
  1591. }
  1592. }
  1593.  
  1594. void CInputDB::P2P(const char * c_pData)
  1595. {
  1596. extern LPFDWATCH main_fdw;
  1597.  
  1598. TPacketDGP2P * p = (TPacketDGP2P *) c_pData;
  1599.  
  1600. P2P_MANAGER& mgr = P2P_MANAGER::instance();
  1601.  
  1602. if (false == DESC_MANAGER::instance().IsP2PDescExist(p->szHost, p->wPort))
  1603. {
  1604. LPCLIENT_DESC pkDesc = NULL;
  1605. sys_log(0, "InputDB:P2P %s:%u", p->szHost, p->wPort);
  1606. pkDesc = DESC_MANAGER::instance().CreateConnectionDesc(main_fdw, p->szHost, p->wPort, PHASE_P2P, false);
  1607. mgr.RegisterConnector(pkDesc);
  1608. pkDesc->SetP2P(p->szHost, p->wPort, p->bChannel);
  1609. }
  1610. }
  1611.  
  1612. void CInputDB::GuildLoad(const char * c_pData)
  1613. {
  1614. CGuildManager::instance().LoadGuild(*(DWORD *) c_pData);
  1615. }
  1616.  
  1617. void CInputDB::GuildSkillUpdate(const char* c_pData)
  1618. {
  1619. TPacketGuildSkillUpdate * p = (TPacketGuildSkillUpdate *) c_pData;
  1620.  
  1621. CGuild * g = CGuildManager::instance().TouchGuild(p->guild_id);
  1622.  
  1623. if (g)
  1624. {
  1625. g->UpdateSkill(p->skill_point, p->skill_levels);
  1626. g->GuildPointChange(POINT_SP, p->amount, p->save?true:false);
  1627. }
  1628. }
  1629.  
  1630. void CInputDB::GuildWar(const char* c_pData)
  1631. {
  1632. TPacketGuildWar * p = (TPacketGuildWar*) c_pData;
  1633.  
  1634. sys_log(0, "InputDB::GuildWar %u %u state %d", p->dwGuildFrom, p->dwGuildTo, p->bWar);
  1635.  
  1636. switch (p->bWar)
  1637. {
  1638. case GUILD_WAR_SEND_DECLARE:
  1639. case GUILD_WAR_RECV_DECLARE:
  1640. CGuildManager::instance().DeclareWar(p->dwGuildFrom, p->dwGuildTo, p->bType);
  1641. break;
  1642.  
  1643. case GUILD_WAR_REFUSE:
  1644. CGuildManager::instance().RefuseWar(p->dwGuildFrom, p->dwGuildTo);
  1645. break;
  1646.  
  1647. case GUILD_WAR_WAIT_START:
  1648. CGuildManager::instance().WaitStartWar(p->dwGuildFrom, p->dwGuildTo);
  1649. break;
  1650.  
  1651. case GUILD_WAR_CANCEL:
  1652. CGuildManager::instance().CancelWar(p->dwGuildFrom, p->dwGuildTo);
  1653. break;
  1654.  
  1655. case GUILD_WAR_ON_WAR:
  1656. CGuildManager::instance().StartWar(p->dwGuildFrom, p->dwGuildTo);
  1657. break;
  1658.  
  1659. case GUILD_WAR_END:
  1660. CGuildManager::instance().EndWar(p->dwGuildFrom, p->dwGuildTo);
  1661. break;
  1662.  
  1663. case GUILD_WAR_OVER:
  1664. CGuildManager::instance().WarOver(p->dwGuildFrom, p->dwGuildTo, p->bType);
  1665. break;
  1666.  
  1667. case GUILD_WAR_RESERVE:
  1668. CGuildManager::instance().ReserveWar(p->dwGuildFrom, p->dwGuildTo, p->bType);
  1669. break;
  1670.  
  1671. default:
  1672. sys_err("Unknown guild war state");
  1673. break;
  1674. }
  1675. }
  1676.  
  1677. void CInputDB::GuildWarScore(const char* c_pData)
  1678. {
  1679. TPacketGuildWarScore* p = (TPacketGuildWarScore*) c_pData;
  1680. CGuild * g = CGuildManager::instance().TouchGuild(p->dwGuildGainPoint);
  1681. g->SetWarScoreAgainstTo(p->dwGuildOpponent, p->lScore);
  1682. }
  1683.  
  1684. void CInputDB::GuildSkillRecharge()
  1685. {
  1686. CGuildManager::instance().SkillRecharge();
  1687. }
  1688.  
  1689. void CInputDB::GuildExpUpdate(const char* c_pData)
  1690. {
  1691. TPacketGuildSkillUpdate * p = (TPacketGuildSkillUpdate *) c_pData;
  1692. sys_log(1, "GuildExpUpdate %d", p->amount);
  1693.  
  1694. CGuild * g = CGuildManager::instance().TouchGuild(p->guild_id);
  1695.  
  1696. if (g)
  1697. g->GuildPointChange(POINT_EXP, p->amount);
  1698. }
  1699.  
  1700. void CInputDB::GuildAddMember(const char* c_pData)
  1701. {
  1702. TPacketDGGuildMember * p = (TPacketDGGuildMember *) c_pData;
  1703. CGuild * g = CGuildManager::instance().TouchGuild(p->dwGuild);
  1704.  
  1705. if (g)
  1706. g->AddMember(p);
  1707. }
  1708.  
  1709. void CInputDB::GuildRemoveMember(const char* c_pData)
  1710. {
  1711. TPacketGuild* p=(TPacketGuild*)c_pData;
  1712. CGuild* g = CGuildManager::instance().TouchGuild(p->dwGuild);
  1713.  
  1714. if (g)
  1715. g->RemoveMember(p->dwInfo);
  1716. }
  1717.  
  1718. void CInputDB::GuildChangeGrade(const char* c_pData)
  1719. {
  1720. TPacketGuild* p=(TPacketGuild*)c_pData;
  1721. CGuild* g = CGuildManager::instance().TouchGuild(p->dwGuild);
  1722.  
  1723. if (g)
  1724. g->P2PChangeGrade((BYTE)p->dwInfo);
  1725. }
  1726.  
  1727. void CInputDB::GuildChangeMemberData(const char* c_pData)
  1728. {
  1729. sys_log(0, "Recv GuildChangeMemberData");
  1730. TPacketGuildChangeMemberData * p = (TPacketGuildChangeMemberData *) c_pData;
  1731. CGuild * g = CGuildManager::instance().TouchGuild(p->guild_id);
  1732.  
  1733. if (g)
  1734. g->ChangeMemberData(p->pid, p->offer, p->level, p->grade);
  1735. }
  1736.  
  1737. void CInputDB::GuildDisband(const char* c_pData)
  1738. {
  1739. TPacketGuild * p = (TPacketGuild*) c_pData;
  1740. CGuildManager::instance().DisbandGuild(p->dwGuild);
  1741. }
  1742.  
  1743. void CInputDB::GuildLadder(const char* c_pData)
  1744. {
  1745. TPacketGuildLadder* p = (TPacketGuildLadder*) c_pData;
  1746. sys_log(0, "Recv GuildLadder %u %d / w %d d %d l %d", p->dwGuild, p->lLadderPoint, p->lWin, p->lDraw, p->lLoss);
  1747. CGuild * g = CGuildManager::instance().TouchGuild(p->dwGuild);
  1748.  
  1749. g->SetLadderPoint(p->lLadderPoint);
  1750. g->SetWarData(p->lWin, p->lDraw, p->lLoss);
  1751. }
  1752.  
  1753. void CInputDB::ItemLoad(LPDESC d, const char * c_pData)
  1754. {
  1755. LPCHARACTER ch;
  1756.  
  1757. if (!d || !(ch = d->GetCharacter()))
  1758. return;
  1759.  
  1760. if (ch->IsItemLoaded())
  1761. return;
  1762.  
  1763. DWORD dwCount = decode_4bytes(c_pData);
  1764. c_pData += sizeof(DWORD);
  1765.  
  1766. sys_log(0, "ITEM_LOAD: COUNT %s %u", ch->GetName(), dwCount);
  1767.  
  1768. std::vector<LPITEM> v;
  1769.  
  1770. TPlayerItem * p = (TPlayerItem *) c_pData;
  1771.  
  1772. for (DWORD i = 0; i < dwCount; ++i, ++p)
  1773. {
  1774. LPITEM item = ITEM_MANAGER::instance().CreateItem(p->vnum, p->count, p->id);
  1775.  
  1776. if (!item)
  1777. {
  1778. sys_err("cannot create item by vnum %u (name %s id %u)", p->vnum, ch->GetName(), p->id);
  1779. continue;
  1780. }
  1781.  
  1782. item->SetSkipSave(true);
  1783. item->SetSockets(p->alSockets);
  1784. item->SetAttributes(p->aAttr);
  1785. item->SetLastOwnerPID(p->owner);
  1786.  
  1787. if ((p->window == INVENTORY && ch->GetInventoryItem(p->pos)) ||
  1788. (p->window == EQUIPMENT && ch->GetWear(p->pos)))
  1789. {
  1790. sys_log(0, "ITEM_RESTORE: %s %s", ch->GetName(), item->GetName());
  1791. v.push_back(item);
  1792. }
  1793. else
  1794. {
  1795. switch (p->window)
  1796. {
  1797. case INVENTORY:
  1798. case DRAGON_SOUL_INVENTORY:
  1799. #ifdef ENABLE_SPECIAL_STORAGE
  1800. case UPGRADE_INVENTORY:
  1801. case BOOK_INVENTORY:
  1802. case STONE_INVENTORY:
  1803. #endif
  1804. item->AddToCharacter(ch, TItemPos(p->window, p->pos));
  1805. break;
  1806.  
  1807. case EQUIPMENT:
  1808. if (item->CheckItemUseLevel(ch->GetLevel()) == true )
  1809. {
  1810. if (item->EquipTo(ch, p->pos) == false )
  1811. {
  1812. v.push_back(item);
  1813. }
  1814. }
  1815. else
  1816. {
  1817. v.push_back(item);
  1818. }
  1819. break;
  1820. }
  1821. }
  1822.  
  1823. if (false == item->OnAfterCreatedItem())
  1824. sys_err("Failed to call ITEM::OnAfterCreatedItem (vnum: %d, id: %d)", item->GetVnum(), item->GetID());
  1825.  
  1826. item->SetSkipSave(false);
  1827. }
  1828.  
  1829. itertype(v) it = v.begin();
  1830.  
  1831. while (it != v.end())
  1832. {
  1833. LPITEM item = *(it++);
  1834.  
  1835. int pos = ch->GetEmptyInventory(item->GetSize());
  1836.  
  1837. if (pos < 0)
  1838. {
  1839. PIXEL_POSITION coord;
  1840. coord.x = ch->GetX();
  1841. coord.y = ch->GetY();
  1842.  
  1843. item->AddToGround(ch->GetMapIndex(), coord);
  1844. item->SetOwnership(ch, 180);
  1845. item->StartDestroyEvent();
  1846. }
  1847. else
  1848. item->AddToCharacter(ch, TItemPos(INVENTORY, pos));
  1849. }
  1850.  
  1851. ch->CheckMaximumPoints();
  1852. ch->PointsPacket();
  1853.  
  1854. ch->SetItemLoaded();
  1855. }
  1856.  
  1857. void CInputDB::AffectLoad(LPDESC d, const char * c_pData)
  1858. {
  1859. if (!d)
  1860. return;
  1861.  
  1862. if (!d->GetCharacter())
  1863. return;
  1864.  
  1865. LPCHARACTER ch = d->GetCharacter();
  1866.  
  1867. DWORD dwPID = decode_4bytes(c_pData);
  1868. c_pData += sizeof(DWORD);
  1869.  
  1870. DWORD dwCount = decode_4bytes(c_pData);
  1871. c_pData += sizeof(DWORD);
  1872.  
  1873. if (ch->GetPlayerID() != dwPID)
  1874. return;
  1875.  
  1876. ch->LoadAffect(dwCount, (TPacketAffectElement *) c_pData);
  1877.  
  1878. }
  1879.  
  1880.  
  1881.  
  1882. void CInputDB::PartyCreate(const char* c_pData)
  1883. {
  1884. TPacketPartyCreate* p = (TPacketPartyCreate*) c_pData;
  1885. CPartyManager::instance().P2PCreateParty(p->dwLeaderPID);
  1886. }
  1887.  
  1888. void CInputDB::PartyDelete(const char* c_pData)
  1889. {
  1890. TPacketPartyDelete* p = (TPacketPartyDelete*) c_pData;
  1891. CPartyManager::instance().P2PDeleteParty(p->dwLeaderPID);
  1892. }
  1893.  
  1894. void CInputDB::PartyAdd(const char* c_pData)
  1895. {
  1896. TPacketPartyAdd* p = (TPacketPartyAdd*) c_pData;
  1897. CPartyManager::instance().P2PJoinParty(p->dwLeaderPID, p->dwPID, p->bState);
  1898. }
  1899.  
  1900. void CInputDB::PartyRemove(const char* c_pData)
  1901. {
  1902. TPacketPartyRemove* p = (TPacketPartyRemove*) c_pData;
  1903. CPartyManager::instance().P2PQuitParty(p->dwPID);
  1904. }
  1905.  
  1906. void CInputDB::PartyStateChange(const char* c_pData)
  1907. {
  1908. TPacketPartyStateChange * p = (TPacketPartyStateChange *) c_pData;
  1909. LPPARTY pParty = CPartyManager::instance().P2PCreateParty(p->dwLeaderPID);
  1910.  
  1911. if (!pParty)
  1912. return;
  1913.  
  1914. pParty->SetRole(p->dwPID, p->bRole, p->bFlag);
  1915. }
  1916.  
  1917. void CInputDB::PartySetMemberLevel(const char* c_pData)
  1918. {
  1919. TPacketPartySetMemberLevel* p = (TPacketPartySetMemberLevel*) c_pData;
  1920. LPPARTY pParty = CPartyManager::instance().P2PCreateParty(p->dwLeaderPID);
  1921.  
  1922. if (!pParty)
  1923. return;
  1924.  
  1925. pParty->P2PSetMemberLevel(p->dwPID, p->bLevel);
  1926. }
  1927.  
  1928. void CInputDB::Time(const char * c_pData)
  1929. {
  1930. set_global_time(*(time_t *) c_pData);
  1931. }
  1932.  
  1933. void CInputDB::ReloadProto(const char * c_pData)
  1934. {
  1935. WORD wSize;
  1936.  
  1937. /*
  1938. * Skill
  1939. */
  1940. wSize = decode_2bytes(c_pData);
  1941. c_pData += sizeof(WORD);
  1942. if (wSize) CSkillManager::instance().Initialize((TSkillTable *) c_pData, wSize);
  1943. c_pData += sizeof(TSkillTable) * wSize;
  1944.  
  1945. /*
  1946. * Banwords
  1947. */
  1948.  
  1949. wSize = decode_2bytes(c_pData);
  1950. c_pData += sizeof(WORD);
  1951. CBanwordManager::instance().Initialize((TBanwordTable *) c_pData, wSize);
  1952. c_pData += sizeof(TBanwordTable) * wSize;
  1953.  
  1954. /*
  1955. * ITEM
  1956. */
  1957. wSize = decode_2bytes(c_pData);
  1958. c_pData += 2;
  1959. sys_log(0, "RELOAD: ITEM: %d", wSize);
  1960.  
  1961. if (wSize)
  1962. {
  1963. ITEM_MANAGER::instance().Initialize((TItemTable *) c_pData, wSize);
  1964. c_pData += wSize * sizeof(TItemTable);
  1965. }
  1966.  
  1967. /*
  1968. * MONSTER
  1969. */
  1970. wSize = decode_2bytes(c_pData);
  1971. c_pData += 2;
  1972. sys_log(0, "RELOAD: MOB: %d", wSize);
  1973.  
  1974. if (wSize)
  1975. {
  1976. CMobManager::instance().Initialize((TMobTable *) c_pData, wSize);
  1977. c_pData += wSize * sizeof(TMobTable);
  1978. }
  1979.  
  1980. CMotionManager::instance().Build();
  1981.  
  1982. CHARACTER_MANAGER::instance().for_each_pc(std::mem_fun(&CHARACTER::ComputePoints));
  1983. }
  1984.  
  1985. void CInputDB::GuildSkillUsableChange(const char* c_pData)
  1986. {
  1987. TPacketGuildSkillUsableChange* p = (TPacketGuildSkillUsableChange*) c_pData;
  1988.  
  1989. CGuild* g = CGuildManager::instance().TouchGuild(p->dwGuild);
  1990.  
  1991. g->SkillUsableChange(p->dwSkillVnum, p->bUsable?true:false);
  1992. }
  1993.  
  1994. void CInputDB::AuthLogin(LPDESC d, const char * c_pData)
  1995. {
  1996. if (!d)
  1997. return;
  1998.  
  1999. BYTE bResult = *(BYTE *) c_pData;
  2000.  
  2001. TPacketGCAuthSuccess ptoc;
  2002.  
  2003. ptoc.bHeader = HEADER_GC_AUTH_SUCCESS;
  2004.  
  2005. if (bResult)
  2006. {
  2007. // Panama 암호화 팩에 필요한 키 보내기
  2008. SendPanamaList(d);
  2009. ptoc.dwLoginKey = d->GetLoginKey();
  2010.  
  2011. //NOTE: AuthSucess보다 먼저 보내야지 안그러면 PHASE Close가 되서 보내지지 않는다.-_-
  2012. //Send Client Package CryptKey
  2013. {
  2014. DESC_MANAGER::instance().SendClientPackageCryptKey(d);
  2015. DESC_MANAGER::instance().SendClientPackageSDBToLoadMap(d, MAPNAME_DEFAULT);
  2016. }
  2017. }
  2018. else
  2019. {
  2020. ptoc.dwLoginKey = 0;
  2021. }
  2022.  
  2023. ptoc.bResult = bResult;
  2024.  
  2025. d->Packet(&ptoc, sizeof(TPacketGCAuthSuccess));
  2026. sys_log(0, "AuthLogin result %u key %u", bResult, d->GetLoginKey());
  2027. }
  2028. void CInputDB::AuthLoginOpenID(LPDESC d, const char * c_pData)
  2029. {
  2030. if (!d)
  2031. return;
  2032.  
  2033. BYTE bResult = *(BYTE *) c_pData;
  2034.  
  2035. TPacketGCAuthSuccessOpenID ptoc;
  2036.  
  2037. ptoc.bHeader = HEADER_GC_AUTH_SUCCESS_OPENID;
  2038.  
  2039. if (bResult)
  2040. {
  2041. // Panama 암호화 팩에 필요한 키 보내기
  2042. SendPanamaList(d);
  2043. ptoc.dwLoginKey = d->GetLoginKey();
  2044.  
  2045. //NOTE: AuthSucess보다 먼저 보내야지 안그러면 PHASE Close가 되서 보내지지 않는다.-_-
  2046. //Send Client Package CryptKey
  2047. {
  2048. DESC_MANAGER::instance().SendClientPackageCryptKey(d);
  2049. DESC_MANAGER::instance().SendClientPackageSDBToLoadMap(d, MAPNAME_DEFAULT);
  2050. }
  2051. }
  2052. else
  2053. {
  2054. ptoc.dwLoginKey = 0;
  2055. }
  2056.  
  2057. strcpy(ptoc.login, d->GetLogin().c_str());
  2058.  
  2059. ptoc.bResult = bResult;
  2060.  
  2061. d->Packet(&ptoc, sizeof(TPacketGCAuthSuccessOpenID));
  2062. sys_log(0, "AuthLogin result %u key %u", bResult, d->GetLoginKey());
  2063. }
  2064.  
  2065. void CInputDB::ChangeEmpirePriv(const char* c_pData)
  2066. {
  2067. TPacketDGChangeEmpirePriv* p = (TPacketDGChangeEmpirePriv*) c_pData;
  2068.  
  2069. // ADD_EMPIRE_PRIV_TIME
  2070. CPrivManager::instance().GiveEmpirePriv(p->empire, p->type, p->value, p->bLog, p->end_time_sec);
  2071. // END_OF_ADD_EMPIRE_PRIV_TIME
  2072. }
  2073.  
  2074. /**
  2075. * @version 05/06/08 Bang2ni - 지속시간 추가
  2076. */
  2077. void CInputDB::ChangeGuildPriv(const char* c_pData)
  2078. {
  2079. TPacketDGChangeGuildPriv* p = (TPacketDGChangeGuildPriv*) c_pData;
  2080.  
  2081. // ADD_GUILD_PRIV_TIME
  2082. CPrivManager::instance().GiveGuildPriv(p->guild_id, p->type, p->value, p->bLog, p->end_time_sec);
  2083. // END_OF_ADD_GUILD_PRIV_TIME
  2084. }
  2085.  
  2086. void CInputDB::ChangeCharacterPriv(const char* c_pData)
  2087. {
  2088. TPacketDGChangeCharacterPriv* p = (TPacketDGChangeCharacterPriv*) c_pData;
  2089. CPrivManager::instance().GiveCharacterPriv(p->pid, p->type, p->value, p->bLog);
  2090. }
  2091.  
  2092. void CInputDB::MoneyLog(const char* c_pData)
  2093. {
  2094. TPacketMoneyLog * p = (TPacketMoneyLog *) c_pData;
  2095.  
  2096. if (p->type == 4) // QUEST_MONEY_LOG_SKIP
  2097. return;
  2098.  
  2099. if (g_bAuthServer ==true )
  2100. return;
  2101.  
  2102. LogManager::instance().MoneyLog(p->type, p->vnum, p->gold);
  2103. }
  2104.  
  2105. void CInputDB::GuildMoneyChange(const char* c_pData)
  2106. {
  2107. TPacketDGGuildMoneyChange* p = (TPacketDGGuildMoneyChange*) c_pData;
  2108.  
  2109. CGuild* g = CGuildManager::instance().TouchGuild(p->dwGuild);
  2110. if (g)
  2111. {
  2112. g->RecvMoneyChange(p->iTotalGold);
  2113. }
  2114. }
  2115.  
  2116. void CInputDB::GuildWithdrawMoney(const char* c_pData)
  2117. {
  2118. TPacketDGGuildMoneyWithdraw* p = (TPacketDGGuildMoneyWithdraw*) c_pData;
  2119.  
  2120. CGuild* g = CGuildManager::instance().TouchGuild(p->dwGuild);
  2121. if (g)
  2122. {
  2123. g->RecvWithdrawMoneyGive(p->iChangeGold);
  2124. }
  2125. }
  2126.  
  2127. void CInputDB::SetEventFlag(const char* c_pData)
  2128. {
  2129. TPacketSetEventFlag* p = (TPacketSetEventFlag*) c_pData;
  2130. quest::CQuestManager::instance().SetEventFlag(p->szFlagName, p->lValue);
  2131. }
  2132.  
  2133. void CInputDB::CreateObject(const char * c_pData)
  2134. {
  2135. using namespace building;
  2136. CManager::instance().LoadObject((TObject *) c_pData);
  2137. }
  2138.  
  2139. void CInputDB::DeleteObject(const char * c_pData)
  2140. {
  2141. using namespace building;
  2142. CManager::instance().DeleteObject(*(DWORD *) c_pData);
  2143. }
  2144.  
  2145. void CInputDB::UpdateLand(const char * c_pData)
  2146. {
  2147. using namespace building;
  2148. CManager::instance().UpdateLand((TLand *) c_pData);
  2149. }
  2150.  
  2151. ////////////////////////////////////////////////////////////////////
  2152. // Billing
  2153. ////////////////////////////////////////////////////////////////////
  2154. void CInputDB::BillingRepair(const char * c_pData)
  2155. {
  2156. DWORD dwCount = *(DWORD *) c_pData;
  2157. c_pData += sizeof(DWORD);
  2158.  
  2159. TPacketBillingRepair * p = (TPacketBillingRepair *) c_pData;
  2160.  
  2161. for (DWORD i = 0; i < dwCount; ++i, ++p)
  2162. {
  2163. CLoginData * pkLD = M2_NEW CLoginData;
  2164.  
  2165. pkLD->SetKey(p->dwLoginKey);
  2166. pkLD->SetLogin(p->szLogin);
  2167. pkLD->SetIP(p->szHost);
  2168.  
  2169. sys_log(0, "BILLING: REPAIR %s host %s", p->szLogin, p->szHost);
  2170. }
  2171. }
  2172.  
  2173. void CInputDB::BillingExpire(const char * c_pData)
  2174. {
  2175. TPacketBillingExpire * p = (TPacketBillingExpire *) c_pData;
  2176.  
  2177. LPDESC d = DESC_MANAGER::instance().FindByLoginName(p->szLogin);
  2178.  
  2179. if (!d)
  2180. return;
  2181.  
  2182. LPCHARACTER ch = d->GetCharacter();
  2183.  
  2184. if (p->dwRemainSeconds <= 60)
  2185. {
  2186. int i = MAX(5, p->dwRemainSeconds);
  2187. sys_log(0, "BILLING_EXPIRE: %s %u", p->szLogin, p->dwRemainSeconds);
  2188. d->DelayedDisconnect(i);
  2189. }
  2190. else
  2191. {
  2192. if ((p->dwRemainSeconds - d->GetBillingExpireSecond()) > 60)
  2193. {
  2194. d->SetBillingExpireSecond(p->dwRemainSeconds);
  2195.  
  2196. if (ch)
  2197. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("결재기간이 %d분 후 만료 됩니다."), (p->dwRemainSeconds / 60));
  2198. }
  2199. }
  2200. }
  2201.  
  2202. void CInputDB::BillingLogin(const char * c_pData)
  2203. {
  2204. if (NULL == c_pData)
  2205. return;
  2206.  
  2207. TPacketBillingLogin * p;
  2208.  
  2209. DWORD dwCount = *(DWORD *) c_pData;
  2210. c_pData += sizeof(DWORD);
  2211.  
  2212. p = (TPacketBillingLogin *) c_pData;
  2213.  
  2214. for (DWORD i = 0; i < dwCount; ++i, ++p)
  2215. {
  2216. DBManager::instance().SetBilling(p->dwLoginKey, p->bLogin);
  2217. }
  2218. }
  2219.  
  2220. void CInputDB::BillingCheck(const char * c_pData)
  2221. {
  2222. DWORD size = *(DWORD *) c_pData;
  2223. c_pData += sizeof(DWORD);
  2224.  
  2225. for (DWORD i = 0; i < size; ++i)
  2226. {
  2227. DWORD dwKey = *(DWORD *) c_pData;
  2228. c_pData += sizeof(DWORD);
  2229.  
  2230. sys_log(0, "BILLING: NOT_LOGIN %u", dwKey);
  2231. DBManager::instance().SetBilling(dwKey, 0, true);
  2232. }
  2233. }
  2234.  
  2235. void CInputDB::Notice(const char * c_pData)
  2236. {
  2237. extern void SendNotice(const char * c_pszBuf);
  2238.  
  2239. char szBuf[256+1];
  2240. strlcpy(szBuf, c_pData, sizeof(szBuf));
  2241.  
  2242. sys_log(0, "InputDB:: Notice: %s", szBuf);
  2243.  
  2244. //SendNotice(LC_TEXT(szBuf));
  2245. SendNotice(szBuf);
  2246. }
  2247.  
  2248. void CInputDB::VCard(const char * c_pData)
  2249. {
  2250. TPacketGDVCard * p = (TPacketGDVCard *) c_pData;
  2251.  
  2252. sys_log(0, "VCARD: %u %s %s %s %s", p->dwID, p->szSellCharacter, p->szSellAccount, p->szBuyCharacter, p->szBuyAccount);
  2253.  
  2254. std::auto_ptr<SQLMsg> pmsg(DBManager::instance().DirectQuery("SELECT sell_account, buy_account, time FROM vcard WHERE id=%u", p->dwID));
  2255. if (pmsg->Get()->uiNumRows != 1)
  2256. {
  2257. sys_log(0, "VCARD_FAIL: no data");
  2258. return;
  2259. }
  2260.  
  2261. MYSQL_ROW row = mysql_fetch_row(pmsg->Get()->pSQLResult);
  2262.  
  2263. if (strcmp(row[0], p->szSellAccount))
  2264. {
  2265. sys_log(0, "VCARD_FAIL: sell account differ %s", row[0]);
  2266. return;
  2267. }
  2268.  
  2269. if (!row[1] || *row[1])
  2270. {
  2271. sys_log(0, "VCARD_FAIL: buy account already exist");
  2272. return;
  2273. }
  2274.  
  2275. int time = 0;
  2276. str_to_number(time, row[2]);
  2277.  
  2278. if (!row[2] || time < 0)
  2279. {
  2280. sys_log(0, "VCARD_FAIL: time null");
  2281. return;
  2282. }
  2283.  
  2284. std::auto_ptr<SQLMsg> pmsg1(DBManager::instance().DirectQuery("UPDATE GameTime SET LimitTime=LimitTime+%d WHERE UserID='%s'", time, p->szBuyAccount));
  2285.  
  2286. if (pmsg1->Get()->uiAffectedRows == 0 || pmsg1->Get()->uiAffectedRows == (uint32_t)-1)
  2287. {
  2288. sys_log(0, "VCARD_FAIL: cannot modify GameTime table");
  2289. return;
  2290. }
  2291.  
  2292. std::auto_ptr<SQLMsg> pmsg2(DBManager::instance().DirectQuery("UPDATE vcard,GameTime SET sell_pid='%s', buy_pid='%s', buy_account='%s', sell_time=NOW(), new_time=GameTime.LimitTime WHERE vcard.id=%u AND GameTime.UserID='%s'", p->szSellCharacter, p->szBuyCharacter, p->szBuyAccount, p->dwID, p->szBuyAccount));
  2293.  
  2294. if (pmsg2->Get()->uiAffectedRows == 0 || pmsg2->Get()->uiAffectedRows == (uint32_t)-1)
  2295. {
  2296. sys_log(0, "VCARD_FAIL: cannot modify vcard table");
  2297. return;
  2298. }
  2299.  
  2300. sys_log(0, "VCARD_SUCCESS: %s %s", p->szBuyAccount, p->szBuyCharacter);
  2301. }
  2302.  
  2303. void CInputDB::GuildWarReserveAdd(TGuildWarReserve * p)
  2304. {
  2305. CGuildManager::instance().ReserveWarAdd(p);
  2306. }
  2307.  
  2308. void CInputDB::GuildWarReserveDelete(DWORD dwID)
  2309. {
  2310. CGuildManager::instance().ReserveWarDelete(dwID);
  2311. }
  2312.  
  2313. void CInputDB::GuildWarBet(TPacketGDGuildWarBet * p)
  2314. {
  2315. CGuildManager::instance().ReserveWarBet(p);
  2316. }
  2317.  
  2318. void CInputDB::MarriageAdd(TPacketMarriageAdd * p)
  2319. {
  2320. sys_log(0, "MarriageAdd %u %u %u %s %s", p->dwPID1, p->dwPID2, (DWORD)p->tMarryTime, p->szName1, p->szName2);
  2321. marriage::CManager::instance().Add(p->dwPID1, p->dwPID2, p->tMarryTime, p->szName1, p->szName2);
  2322. }
  2323.  
  2324. void CInputDB::MarriageUpdate(TPacketMarriageUpdate * p)
  2325. {
  2326. sys_log(0, "MarriageUpdate %u %u %d %d", p->dwPID1, p->dwPID2, p->iLovePoint, p->byMarried);
  2327. marriage::CManager::instance().Update(p->dwPID1, p->dwPID2, p->iLovePoint, p->byMarried);
  2328. }
  2329.  
  2330. void CInputDB::MarriageRemove(TPacketMarriageRemove * p)
  2331. {
  2332. sys_log(0, "MarriageRemove %u %u", p->dwPID1, p->dwPID2);
  2333. marriage::CManager::instance().Remove(p->dwPID1, p->dwPID2);
  2334. }
  2335.  
  2336. void CInputDB::WeddingRequest(TPacketWeddingRequest* p)
  2337. {
  2338. marriage::WeddingManager::instance().Request(p->dwPID1, p->dwPID2);
  2339. }
  2340.  
  2341. void CInputDB::WeddingReady(TPacketWeddingReady* p)
  2342. {
  2343. sys_log(0, "WeddingReady %u %u %u", p->dwPID1, p->dwPID2, p->dwMapIndex);
  2344. marriage::CManager::instance().WeddingReady(p->dwPID1, p->dwPID2, p->dwMapIndex);
  2345. }
  2346.  
  2347. void CInputDB::WeddingStart(TPacketWeddingStart* p)
  2348. {
  2349. sys_log(0, "WeddingStart %u %u", p->dwPID1, p->dwPID2);
  2350. marriage::CManager::instance().WeddingStart(p->dwPID1, p->dwPID2);
  2351. }
  2352.  
  2353. void CInputDB::WeddingEnd(TPacketWeddingEnd* p)
  2354. {
  2355. sys_log(0, "WeddingEnd %u %u", p->dwPID1, p->dwPID2);
  2356. marriage::CManager::instance().WeddingEnd(p->dwPID1, p->dwPID2);
  2357. }
  2358.  
  2359. // MYSHOP_PRICE_LIST
  2360. void CInputDB::MyshopPricelistRes(LPDESC d, const TPacketMyshopPricelistHeader* p )
  2361. {
  2362. LPCHARACTER ch;
  2363.  
  2364. if (!d || !(ch = d->GetCharacter()) )
  2365. return;
  2366.  
  2367. sys_log(0, "RecvMyshopPricelistRes name[%s]", ch->GetName());
  2368. ch->UseSilkBotaryReal(p );
  2369.  
  2370. }
  2371. // END_OF_MYSHOP_PRICE_LIST
  2372.  
  2373.  
  2374. //RELOAD_ADMIN
  2375. void CInputDB::ReloadAdmin(const char * c_pData )
  2376. {
  2377. gm_new_clear();
  2378. int ChunkSize = decode_2bytes(c_pData );
  2379. c_pData += 2;
  2380. int HostSize = decode_2bytes(c_pData );
  2381. c_pData += 2;
  2382.  
  2383. for (int n = 0; n < HostSize; ++n )
  2384. {
  2385. gm_new_host_inert(c_pData );
  2386. c_pData += ChunkSize;
  2387. }
  2388.  
  2389.  
  2390. c_pData += 2;
  2391. int size = decode_2bytes(c_pData );
  2392. c_pData += 2;
  2393.  
  2394. for (int n = 0; n < size; ++n )
  2395. {
  2396. tAdminInfo& rAdminInfo = *(tAdminInfo*)c_pData;
  2397.  
  2398. gm_new_insert(rAdminInfo );
  2399.  
  2400. c_pData += sizeof (tAdminInfo );
  2401.  
  2402. LPCHARACTER pChar = CHARACTER_MANAGER::instance().FindPC(rAdminInfo.m_szName );
  2403. if (pChar )
  2404. {
  2405. pChar->SetGMLevel();
  2406. }
  2407. }
  2408.  
  2409. }
  2410. //END_RELOAD_ADMIN
  2411.  
  2412. ////////////////////////////////////////////////////////////////////
  2413. // Analyze
  2414. // @version 05/06/10 Bang2ni - 아이템 가격정보 리스트 패킷(HEADER_DG_MYSHOP_PRICELIST_RES) 처리루틴 추가.
  2415. ////////////////////////////////////////////////////////////////////
  2416. int CInputDB::Analyze(LPDESC d, BYTE bHeader, const char * c_pData)
  2417. {
  2418. switch (bHeader)
  2419. {
  2420. case HEADER_DG_BOOT:
  2421. Boot(c_pData);
  2422. break;
  2423. #ifdef OFFLINE_SHOP
  2424. case HEADER_DG_SHOP_NAME:
  2425. ShopName(c_pData);
  2426. break;
  2427. case HEADER_DG_SHOP_CLOSE:
  2428. ShopClose(c_pData);
  2429. break;
  2430. case HEADER_DG_SHOP_UPDATE_ITEM:
  2431. ShopUpdateItem(c_pData);
  2432. break;
  2433. #endif
  2434. case HEADER_DG_LOGIN_SUCCESS:
  2435. LoginSuccess(m_dwHandle, c_pData);
  2436. break;
  2437.  
  2438. case HEADER_DG_LOGIN_NOT_EXIST:
  2439. LoginFailure(DESC_MANAGER::instance().FindByHandle(m_dwHandle), "NOID");
  2440. break;
  2441.  
  2442. case HEADER_DG_LOGIN_WRONG_PASSWD:
  2443. LoginFailure(DESC_MANAGER::instance().FindByHandle(m_dwHandle), "WRONGPWD");
  2444. break;
  2445.  
  2446. case HEADER_DG_LOGIN_ALREADY:
  2447. LoginAlready(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
  2448. break;
  2449.  
  2450. case HEADER_DG_PLAYER_LOAD_SUCCESS:
  2451. PlayerLoad(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
  2452. break;
  2453.  
  2454. case HEADER_DG_PLAYER_CREATE_SUCCESS:
  2455. PlayerCreateSuccess(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
  2456. break;
  2457.  
  2458. case HEADER_DG_PLAYER_CREATE_FAILED:
  2459. PlayerCreateFailure(DESC_MANAGER::instance().FindByHandle(m_dwHandle), 0);
  2460. break;
  2461.  
  2462. case HEADER_DG_PLAYER_CREATE_ALREADY:
  2463. PlayerCreateFailure(DESC_MANAGER::instance().FindByHandle(m_dwHandle), 1);
  2464. break;
  2465.  
  2466. case HEADER_DG_PLAYER_DELETE_SUCCESS:
  2467. PlayerDeleteSuccess(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
  2468. break;
  2469.  
  2470. case HEADER_DG_PLAYER_LOAD_FAILED:
  2471. //sys_log(0, "PLAYER_LOAD_FAILED");
  2472. break;
  2473.  
  2474. case HEADER_DG_PLAYER_DELETE_FAILED:
  2475. //sys_log(0, "PLAYER_DELETE_FAILED");
  2476. PlayerDeleteFail(DESC_MANAGER::instance().FindByHandle(m_dwHandle));
  2477. break;
  2478.  
  2479. case HEADER_DG_ITEM_LOAD:
  2480. ItemLoad(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
  2481. break;
  2482.  
  2483. case HEADER_DG_QUEST_LOAD:
  2484. QuestLoad(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
  2485. break;
  2486.  
  2487. case HEADER_DG_AFFECT_LOAD:
  2488. AffectLoad(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
  2489. break;
  2490.  
  2491. case HEADER_DG_SAFEBOX_LOAD:
  2492. SafeboxLoad(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
  2493. break;
  2494.  
  2495. case HEADER_DG_SAFEBOX_CHANGE_SIZE:
  2496. SafeboxChangeSize(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
  2497. break;
  2498.  
  2499. case HEADER_DG_SAFEBOX_WRONG_PASSWORD:
  2500. SafeboxWrongPassword(DESC_MANAGER::instance().FindByHandle(m_dwHandle));
  2501. break;
  2502.  
  2503. case HEADER_DG_SAFEBOX_CHANGE_PASSWORD_ANSWER:
  2504. SafeboxChangePasswordAnswer(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
  2505. break;
  2506.  
  2507. case HEADER_DG_MALL_LOAD:
  2508. MallLoad(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
  2509. break;
  2510.  
  2511. case HEADER_DG_EMPIRE_SELECT:
  2512. EmpireSelect(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
  2513. break;
  2514.  
  2515. case HEADER_DG_MAP_LOCATIONS:
  2516. MapLocations(c_pData);
  2517. break;
  2518.  
  2519. case HEADER_DG_P2P:
  2520. P2P(c_pData);
  2521. break;
  2522.  
  2523. case HEADER_DG_GUILD_SKILL_UPDATE:
  2524. GuildSkillUpdate(c_pData);
  2525. break;
  2526.  
  2527. case HEADER_DG_GUILD_LOAD:
  2528. GuildLoad(c_pData);
  2529. break;
  2530.  
  2531. case HEADER_DG_GUILD_SKILL_RECHARGE:
  2532. GuildSkillRecharge();
  2533. break;
  2534.  
  2535. case HEADER_DG_GUILD_EXP_UPDATE:
  2536. GuildExpUpdate(c_pData);
  2537. break;
  2538.  
  2539. case HEADER_DG_PARTY_CREATE:
  2540. PartyCreate(c_pData);
  2541. break;
  2542.  
  2543. case HEADER_DG_PARTY_DELETE:
  2544. PartyDelete(c_pData);
  2545. break;
  2546.  
  2547. case HEADER_DG_PARTY_ADD:
  2548. PartyAdd(c_pData);
  2549. break;
  2550.  
  2551. case HEADER_DG_PARTY_REMOVE:
  2552. PartyRemove(c_pData);
  2553. break;
  2554.  
  2555. case HEADER_DG_PARTY_STATE_CHANGE:
  2556. PartyStateChange(c_pData);
  2557. break;
  2558.  
  2559. case HEADER_DG_PARTY_SET_MEMBER_LEVEL:
  2560. PartySetMemberLevel(c_pData);
  2561. break;
  2562.  
  2563. case HEADER_DG_TIME:
  2564. Time(c_pData);
  2565. break;
  2566.  
  2567. case HEADER_DG_GUILD_ADD_MEMBER:
  2568. GuildAddMember(c_pData);
  2569. break;
  2570.  
  2571. case HEADER_DG_GUILD_REMOVE_MEMBER:
  2572. GuildRemoveMember(c_pData);
  2573. break;
  2574.  
  2575. case HEADER_DG_GUILD_CHANGE_GRADE:
  2576. GuildChangeGrade(c_pData);
  2577. break;
  2578.  
  2579. case HEADER_DG_GUILD_CHANGE_MEMBER_DATA:
  2580. GuildChangeMemberData(c_pData);
  2581. break;
  2582.  
  2583. case HEADER_DG_GUILD_DISBAND:
  2584. GuildDisband(c_pData);
  2585. break;
  2586.  
  2587. case HEADER_DG_RELOAD_PROTO:
  2588. ReloadProto(c_pData);
  2589. break;
  2590.  
  2591. case HEADER_DG_GUILD_WAR:
  2592. GuildWar(c_pData);
  2593. break;
  2594.  
  2595. case HEADER_DG_GUILD_WAR_SCORE:
  2596. GuildWarScore(c_pData);
  2597. break;
  2598.  
  2599. case HEADER_DG_GUILD_LADDER:
  2600. GuildLadder(c_pData);
  2601. break;
  2602.  
  2603. case HEADER_DG_GUILD_SKILL_USABLE_CHANGE:
  2604. GuildSkillUsableChange(c_pData);
  2605. break;
  2606.  
  2607. case HEADER_DG_CHANGE_NAME:
  2608. ChangeName(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
  2609. break;
  2610.  
  2611. case HEADER_DG_AUTH_LOGIN:
  2612. if (openid_server)
  2613. AuthLoginOpenID(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
  2614. else
  2615. AuthLogin(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
  2616. break;
  2617.  
  2618. case HEADER_DG_CHANGE_EMPIRE_PRIV:
  2619. ChangeEmpirePriv(c_pData);
  2620. break;
  2621.  
  2622. case HEADER_DG_CHANGE_GUILD_PRIV:
  2623. ChangeGuildPriv(c_pData);
  2624. break;
  2625.  
  2626. case HEADER_DG_CHANGE_CHARACTER_PRIV:
  2627. ChangeCharacterPriv(c_pData);
  2628. break;
  2629.  
  2630. case HEADER_DG_MONEY_LOG:
  2631. MoneyLog(c_pData);
  2632. break;
  2633.  
  2634. case HEADER_DG_GUILD_WITHDRAW_MONEY_GIVE:
  2635. GuildWithdrawMoney(c_pData);
  2636. break;
  2637.  
  2638. case HEADER_DG_GUILD_MONEY_CHANGE:
  2639. GuildMoneyChange(c_pData);
  2640. break;
  2641.  
  2642. case HEADER_DG_SET_EVENT_FLAG:
  2643. SetEventFlag(c_pData);
  2644. break;
  2645.  
  2646. case HEADER_DG_BILLING_REPAIR:
  2647. BillingRepair(c_pData);
  2648. break;
  2649.  
  2650. case HEADER_DG_BILLING_EXPIRE:
  2651. BillingExpire(c_pData);
  2652. break;
  2653.  
  2654. case HEADER_DG_BILLING_LOGIN:
  2655. BillingLogin(c_pData);
  2656. break;
  2657.  
  2658. case HEADER_DG_BILLING_CHECK:
  2659. BillingCheck(c_pData);
  2660. break;
  2661.  
  2662. case HEADER_DG_VCARD:
  2663. VCard(c_pData);
  2664. break;
  2665.  
  2666. case HEADER_DG_CREATE_OBJECT:
  2667. CreateObject(c_pData);
  2668. break;
  2669.  
  2670. case HEADER_DG_DELETE_OBJECT:
  2671. DeleteObject(c_pData);
  2672. break;
  2673.  
  2674. case HEADER_DG_UPDATE_LAND:
  2675. UpdateLand(c_pData);
  2676. break;
  2677.  
  2678. case HEADER_DG_NOTICE:
  2679. Notice(c_pData);
  2680. break;
  2681.  
  2682. case HEADER_DG_GUILD_WAR_RESERVE_ADD:
  2683. GuildWarReserveAdd((TGuildWarReserve *) c_pData);
  2684. break;
  2685.  
  2686. case HEADER_DG_GUILD_WAR_RESERVE_DEL:
  2687. GuildWarReserveDelete(*(DWORD *) c_pData);
  2688. break;
  2689.  
  2690. case HEADER_DG_GUILD_WAR_BET:
  2691. GuildWarBet((TPacketGDGuildWarBet *) c_pData);
  2692. break;
  2693.  
  2694. case HEADER_DG_MARRIAGE_ADD:
  2695. MarriageAdd((TPacketMarriageAdd*) c_pData);
  2696. break;
  2697.  
  2698. case HEADER_DG_MARRIAGE_UPDATE:
  2699. MarriageUpdate((TPacketMarriageUpdate*) c_pData);
  2700. break;
  2701.  
  2702. case HEADER_DG_MARRIAGE_REMOVE:
  2703. MarriageRemove((TPacketMarriageRemove*) c_pData);
  2704. break;
  2705.  
  2706. case HEADER_DG_WEDDING_REQUEST:
  2707. WeddingRequest((TPacketWeddingRequest*) c_pData);
  2708. break;
  2709.  
  2710. case HEADER_DG_WEDDING_READY:
  2711. WeddingReady((TPacketWeddingReady*) c_pData);
  2712. break;
  2713.  
  2714. case HEADER_DG_WEDDING_START:
  2715. WeddingStart((TPacketWeddingStart*) c_pData);
  2716. break;
  2717.  
  2718. case HEADER_DG_WEDDING_END:
  2719. WeddingEnd((TPacketWeddingEnd*) c_pData);
  2720. break;
  2721.  
  2722. // MYSHOP_PRICE_LIST
  2723. case HEADER_DG_MYSHOP_PRICELIST_RES:
  2724. MyshopPricelistRes(DESC_MANAGER::instance().FindByHandle(m_dwHandle), (TPacketMyshopPricelistHeader*) c_pData );
  2725. break;
  2726. // END_OF_MYSHOP_PRICE_LIST
  2727. //
  2728. // RELOAD_ADMIN
  2729. case HEADER_DG_RELOAD_ADMIN:
  2730. ReloadAdmin(c_pData );
  2731. break;
  2732. //END_RELOAD_ADMIN
  2733.  
  2734. case HEADER_DG_ADD_MONARCH_MONEY:
  2735. AddMonarchMoney(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData );
  2736. break;
  2737.  
  2738. case HEADER_DG_DEC_MONARCH_MONEY:
  2739. DecMonarchMoney(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData );
  2740. break;
  2741.  
  2742. case HEADER_DG_TAKE_MONARCH_MONEY:
  2743. TakeMonarchMoney(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData );
  2744. break;
  2745.  
  2746. case HEADER_DG_CHANGE_MONARCH_LORD_ACK :
  2747. ChangeMonarchLord((TPacketChangeMonarchLordACK*)c_pData);
  2748. break;
  2749.  
  2750. case HEADER_DG_UPDATE_MONARCH_INFO :
  2751. UpdateMonarchInfo((TMonarchInfo*)c_pData);
  2752. break;
  2753.  
  2754. case HEADER_DG_BLOCK_COUNTRY_IP:
  2755. this->AddBlockCountryIp((TPacketBlockCountryIp *) c_pData);
  2756. break;
  2757. case HEADER_DG_BLOCK_EXCEPTION:
  2758. this->BlockException((TPacketBlockException *) c_pData);
  2759. break;
  2760.  
  2761. case HEADER_DG_ACK_CHANGE_GUILD_MASTER :
  2762. this->GuildChangeMaster((TPacketChangeGuildMaster*) c_pData);
  2763. break;
  2764. case HEADER_DG_ACK_SPARE_ITEM_ID_RANGE :
  2765. ITEM_MANAGER::instance().SetMaxSpareItemID(*((TItemIDRangeTable*)c_pData) );
  2766. break;
  2767.  
  2768. case HEADER_DG_UPDATE_HORSE_NAME :
  2769. case HEADER_DG_ACK_HORSE_NAME :
  2770. CHorseNameManager::instance().UpdateHorseName(
  2771. ((TPacketUpdateHorseName*)c_pData)->dwPlayerID,
  2772. ((TPacketUpdateHorseName*)c_pData)->szHorseName);
  2773. break;
  2774.  
  2775. case HEADER_DG_NEED_LOGIN_LOG:
  2776. DetailLog( (TPacketNeedLoginLogInfo*) c_pData );
  2777. break;
  2778. // 독일 선물 기능 테스트
  2779. case HEADER_DG_ITEMAWARD_INFORMER:
  2780. ItemAwardInformer((TPacketItemAwardInfromer*) c_pData);
  2781. break;
  2782. case HEADER_DG_RESPOND_CHANNELSTATUS:
  2783. RespondChannelStatus(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
  2784. break;
  2785. #ifdef __AUCTION__
  2786. case HEADER_DG_AUCTION_RESULT:
  2787. if (auction_server)
  2788. AuctionManager::instance().recv_result_auction(m_dwHandle, (TPacketDGResultAuction*)c_pData);
  2789. break;
  2790. #endif
  2791. default:
  2792. return (-1);
  2793. }
  2794.  
  2795. return 0;
  2796. }
  2797.  
  2798. bool CInputDB::Process(LPDESC d, const void * orig, int bytes, int & r_iBytesProceed)
  2799. {
  2800. const char * c_pData = (const char *) orig;
  2801. BYTE bHeader, bLastHeader = 0;
  2802. int iSize;
  2803. int iLastPacketLen = 0;
  2804.  
  2805. for (m_iBufferLeft = bytes; m_iBufferLeft > 0;)
  2806. {
  2807. if (m_iBufferLeft < 9)
  2808. return true;
  2809.  
  2810. bHeader = *((BYTE *) (c_pData)); // 1
  2811. m_dwHandle = *((DWORD *) (c_pData + 1)); // 4
  2812. iSize = *((DWORD *) (c_pData + 5)); // 4
  2813.  
  2814. sys_log(1, "DBCLIENT: header %d handle %d size %d bytes %d", bHeader, m_dwHandle, iSize, bytes);
  2815.  
  2816. if (m_iBufferLeft - 9 < iSize)
  2817. return true;
  2818.  
  2819. const char * pRealData = (c_pData + 9);
  2820.  
  2821. if (Analyze(d, bHeader, pRealData) < 0)
  2822. {
  2823. sys_err("in InputDB: UNKNOWN HEADER: %d, LAST HEADER: %d(%d), REMAIN BYTES: %d, DESC: %d",
  2824. bHeader, bLastHeader, iLastPacketLen, m_iBufferLeft, d->GetSocket());
  2825.  
  2826. //printdata((BYTE*) orig, bytes);
  2827. //d->SetPhase(PHASE_CLOSE);
  2828. }
  2829.  
  2830. c_pData += 9 + iSize;
  2831. m_iBufferLeft -= 9 + iSize;
  2832. r_iBytesProceed += 9 + iSize;
  2833.  
  2834. iLastPacketLen = 9 + iSize;
  2835. bLastHeader = bHeader;
  2836. }
  2837.  
  2838. return true;
  2839. }
  2840.  
  2841. void CInputDB::AddMonarchMoney(LPDESC d, const char * data )
  2842. {
  2843. int Empire = *(int *) data;
  2844. data += sizeof(int);
  2845.  
  2846. int Money = *(int *) data;
  2847. data += sizeof(int);
  2848.  
  2849. CMonarch::instance().AddMoney(Money, Empire);
  2850.  
  2851. DWORD pid = CMonarch::instance().GetMonarchPID(Empire);
  2852.  
  2853. LPCHARACTER ch = CHARACTER_MANAGER::instance().FindByPID(pid);
  2854.  
  2855. if (ch)
  2856. {
  2857. if (number(1, 100) > 95)
  2858. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("현재 %s 국고에는 %u 의 돈이 있습니다"), EMPIRE_NAME(Empire), CMonarch::instance().GetMoney(Empire));
  2859. }
  2860. }
  2861.  
  2862. void CInputDB::DecMonarchMoney(LPDESC d, const char * data)
  2863. {
  2864. int Empire = *(int *) data;
  2865. data += sizeof(int);
  2866.  
  2867. int Money = *(int *) data;
  2868. data += sizeof(int);
  2869.  
  2870. CMonarch::instance().DecMoney(Money, Empire);
  2871.  
  2872. DWORD pid = CMonarch::instance().GetMonarchPID(Empire);
  2873.  
  2874. LPCHARACTER ch = CHARACTER_MANAGER::instance().FindByPID(pid);
  2875.  
  2876. if (ch)
  2877. {
  2878. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("현재 %s 국고에는 %d 의 돈이 있습니다"), EMPIRE_NAME(Empire), CMonarch::instance().GetMoney(Empire));
  2879. }
  2880. }
  2881.  
  2882. void CInputDB::TakeMonarchMoney(LPDESC d, const char * data)
  2883. {
  2884. int Empire = *(int *) data;
  2885. data += sizeof(int);
  2886.  
  2887. int Money = *(int *) data;
  2888. data += sizeof(int);
  2889.  
  2890. if (!CMonarch::instance().DecMoney(Money, Empire))
  2891. {
  2892. if (!d)
  2893. return;
  2894.  
  2895. if (!d->GetCharacter())
  2896. return;
  2897.  
  2898. LPCHARACTER ch = d->GetCharacter();
  2899. ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("국고에 돈이 부족하거나 돈을 가져올수 없는 상황입니다"));
  2900. }
  2901. }
  2902.  
  2903. void CInputDB::ChangeMonarchLord(TPacketChangeMonarchLordACK* info)
  2904. {
  2905. char notice[256];
  2906. snprintf(notice, sizeof(notice), LC_TEXT("%s의 군주가 %s 님으로 교체되었습니다."), EMPIRE_NAME(info->bEmpire), info->szName);
  2907. SendNotice(notice);
  2908. }
  2909.  
  2910. void CInputDB::UpdateMonarchInfo(TMonarchInfo* info)
  2911. {
  2912. CMonarch::instance().SetMonarchInfo(info);
  2913. sys_log(0, "MONARCH INFO UPDATED");
  2914. }
  2915.  
  2916. void CInputDB::AddBlockCountryIp(TPacketBlockCountryIp * data)
  2917. {
  2918. add_blocked_country_ip(data);
  2919. }
  2920.  
  2921. void CInputDB::BlockException(TPacketBlockException *data)
  2922. {
  2923. block_exception(data);
  2924. }
  2925.  
  2926. void CInputDB::GuildChangeMaster(TPacketChangeGuildMaster* p)
  2927. {
  2928. CGuildManager::instance().ChangeMaster(p->dwGuildID);
  2929. }
  2930.  
  2931. void CInputDB::DetailLog(const TPacketNeedLoginLogInfo* info)
  2932. {
  2933. if (true == LC_IsEurope() || true == LC_IsYMIR() || true == LC_IsKorea() )
  2934. {
  2935. LPCHARACTER pChar = CHARACTER_MANAGER::instance().FindByPID( info->dwPlayerID );
  2936.  
  2937. if (NULL != pChar)
  2938. {
  2939. LogManager::instance().DetailLoginLog(true, pChar);
  2940.  
  2941. if (isHackShieldEnable)
  2942. {
  2943. pChar->StartHackShieldCheckCycle( HackShield_FirstCheckWaitTime );
  2944. }
  2945. }
  2946. }
  2947. }
  2948.  
  2949. void CInputDB::ItemAwardInformer(TPacketItemAwardInfromer *data)
  2950. {
  2951. LPDESC d = DESC_MANAGER::instance().FindByLoginName(data->login); //login정보
  2952.  
  2953. if(d == NULL)
  2954. return;
  2955. else
  2956. {
  2957. if (d->GetCharacter())
  2958. {
  2959. LPCHARACTER ch = d->GetCharacter();
  2960. ch->SetItemAward_vnum(data->vnum); // ch 에 임시 저장해놨다가 QuestLoad 함수에서 처리
  2961. ch->SetItemAward_cmd(data->command);
  2962.  
  2963. if(d->IsPhase(PHASE_GAME)) //게임페이즈일때
  2964. {
  2965. quest::CQuestManager::instance().ItemInformer(ch->GetPlayerID(),ch->GetItemAward_vnum()); //questmanager 호출
  2966. }
  2967. }
  2968. }
  2969. }
  2970.  
  2971. void CInputDB::RespondChannelStatus(LPDESC desc, const char* pcData)
  2972. {
  2973. if (!desc) {
  2974. return;
  2975. }
  2976. const int nSize = decode_4bytes(pcData);
  2977. pcData += sizeof(nSize);
  2978.  
  2979. BYTE bHeader = HEADER_GC_RESPOND_CHANNELSTATUS;
  2980. desc->BufferedPacket(&bHeader, sizeof(BYTE));
  2981. desc->BufferedPacket(&nSize, sizeof(nSize));
  2982. if (0 < nSize) {
  2983. desc->BufferedPacket(pcData, sizeof(TChannelStatus)*nSize);
  2984. }
  2985. BYTE bSuccess = 1;
  2986. desc->Packet(&bSuccess, sizeof(bSuccess));
  2987. desc->SetChannelStatusRequested(false);
  2988. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement