Advertisement
Guest User

Untitled

a guest
Sep 16th, 2017
150
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 24.19 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include "constants.h"
  3. #include "config.h"
  4. #include "offlineshop_config.h"
  5. #include "event.h"
  6. #include "minilzo.h"
  7. #include "packet.h"
  8. #include "desc_manager.h"
  9. #include "item_manager.h"
  10. #include "char.h"
  11. #include "char_manager.h"
  12. #include "mob_manager.h"
  13. #include "motion.h"
  14. #include "sectree_manager.h"
  15. #include "shop_manager.h"
  16. #include "regen.h"
  17. #include "text_file_loader.h"
  18. #include "skill.h"
  19. #include "pvp.h"
  20. #include "party.h"
  21. #include "questmanager.h"
  22. #include "profiler.h"
  23. #include "lzo_manager.h"
  24. #include "messenger_manager.h"
  25. #include "db.h"
  26. #include "log.h"
  27. #include "p2p.h"
  28. #include "guild_manager.h"
  29. #include "dungeon.h"
  30. #include "cmd.h"
  31. #include "refine.h"
  32. #include "banword.h"
  33. #include "priv_manager.h"
  34. #include "war_map.h"
  35. #include "building.h"
  36. #include "login_sim.h"
  37. #include "target.h"
  38. #include "marriage.h"
  39. #include "wedding.h"
  40. #include "fishing.h"
  41. #include "item_addon.h"
  42. #include "TrafficProfiler.h"
  43. #include "locale_service.h"
  44. #include "arena.h"
  45. #include "OXEvent.h"
  46. #include "monarch.h"
  47. #include "polymorph.h"
  48. #include "blend_item.h"
  49. #include "castle.h"
  50. #include "passpod.h"
  51. #include "ani.h"
  52. #include "BattleArena.h"
  53. #include "over9refine.h"
  54. #include "horsename_manager.h"
  55. #include "pcbang.h"
  56. #include "MarkManager.h"
  57. #include "spam.h"
  58. #include "panama.h"
  59. #include "threeway_war.h"
  60. #include "auth_brazil.h"
  61. #include "DragonLair.h"
  62. #include "HackShield.h"
  63. #include "skill_power.h"
  64. #include "SpeedServer.h"
  65. #include "XTrapManager.h"
  66. #include "DragonSoul.h"
  67. #include <boost/bind.hpp>
  68. #include "offlineshop_manager.h"
  69.  
  70. #ifndef __WIN32__
  71. #endif
  72.  
  73. //#define __FILEMONITOR__
  74.  
  75. #if defined (__FreeBSD__) && defined(__FILEMONITOR__)
  76. #include "FileMonitor_FreeBSD.h"
  77. #endif
  78.  
  79. #ifdef __AUCTION__
  80. #include "auction_manager.h"
  81. #endif
  82.  
  83. #ifndef __WIN32__
  84. #include <gtest/gtest.h>
  85. #endif
  86.  
  87. #ifdef USE_STACKTRACE
  88. #include <execinfo.h>
  89. #endif
  90.  
  91. // 윈도우에서 테스트할 때는 항상 서버키 체크
  92. #ifdef _WIN32
  93. //#define _USE_SERVER_KEY_
  94. #endif
  95. #include "check_server.h"
  96.  
  97. extern void WriteVersion();
  98. //extern const char * _malloc_options;
  99. #if defined(__FreeBSD__) && defined(DEBUG_ALLOC)
  100. extern void (*_malloc_message)(const char* p1, const char* p2, const char* p3, const char* p4);
  101. // FreeBSD _malloc_message replacement
  102. void WriteMallocMessage(const char* p1, const char* p2, const char* p3, const char* p4) {
  103. FILE* fp = ::fopen(DBGALLOC_LOG_FILENAME, "a");
  104. if (fp == NULL) {
  105. return;
  106. }
  107. ::fprintf(fp, "%s %s %s %s\n", p1, p2, p3, p4);
  108. ::fclose(fp);
  109. }
  110. #endif
  111.  
  112. // TRAFFIC_PROFILER
  113. static const DWORD TRAFFIC_PROFILE_FLUSH_CYCLE = 3600; ///< TrafficProfiler 의 Flush cycle. 1시간 간격
  114. // END_OF_TRAFFIC_PROFILER
  115.  
  116. // 게임과 연결되는 소켓
  117. volatile int num_events_called = 0;
  118. int max_bytes_written = 0;
  119. int current_bytes_written = 0;
  120. int total_bytes_written = 0;
  121. BYTE g_bLogLevel = 0;
  122.  
  123. socket_t tcp_socket = 0;
  124. socket_t udp_socket = 0;
  125. socket_t p2p_socket = 0;
  126.  
  127. LPFDWATCH main_fdw = NULL;
  128.  
  129. int io_loop(LPFDWATCH fdw);
  130.  
  131. int start(int argc, char **argv);
  132. int idle();
  133. void destroy();
  134.  
  135. void test();
  136.  
  137. enum EProfile
  138. {
  139. PROF_EVENT,
  140. PROF_CHR_UPDATE,
  141. PROF_IO,
  142. PROF_HEARTBEAT,
  143. PROF_MAX_NUM
  144. };
  145.  
  146. static DWORD s_dwProfiler[PROF_MAX_NUM];
  147.  
  148. int g_shutdown_disconnect_pulse;
  149. int g_shutdown_disconnect_force_pulse;
  150. int g_shutdown_core_pulse;
  151. bool g_bShutdown=false;
  152.  
  153. extern int speed_server;
  154. #ifdef __AUCTION__
  155. extern int auction_server;
  156. #endif
  157. extern void CancelReloadSpamEvent();
  158.  
  159. void ContinueOnFatalError()
  160. {
  161. #ifdef USE_STACKTRACE
  162. void* array[200];
  163. std::size_t size;
  164. char** symbols;
  165.  
  166. size = backtrace(array, 200);
  167. symbols = backtrace_symbols(array, size);
  168.  
  169. std::ostringstream oss;
  170. oss << std::endl;
  171. for (std::size_t i = 0; i < size; ++i) {
  172. oss << " Stack> " << symbols[i] << std::endl;
  173. }
  174.  
  175. free(symbols);
  176.  
  177. sys_err("FatalError on %s", oss.str().c_str());
  178. #else
  179. sys_err("FatalError");
  180. #endif
  181. }
  182.  
  183. void ShutdownOnFatalError()
  184. {
  185. if (!g_bShutdown)
  186. {
  187. sys_err("ShutdownOnFatalError!!!!!!!!!!");
  188. {
  189. char buf[256];
  190.  
  191. strlcpy(buf, LC_TEXT("서버에 치명적인 오류가 발생하여 자동으로 재부팅됩니다."), sizeof(buf));
  192. SendNotice(buf);
  193. strlcpy(buf, LC_TEXT("10초후 자동으로 접속이 종료되며,"), sizeof(buf));
  194. SendNotice(buf);
  195. strlcpy(buf, LC_TEXT("5분 후에 정상적으로 접속하실수 있습니다."), sizeof(buf));
  196. SendNotice(buf);
  197. }
  198.  
  199. g_bShutdown = true;
  200. g_bNoMoreClient = true;
  201.  
  202. g_shutdown_disconnect_pulse = thecore_pulse() + PASSES_PER_SEC(10);
  203. g_shutdown_disconnect_force_pulse = thecore_pulse() + PASSES_PER_SEC(20);
  204. g_shutdown_core_pulse = thecore_pulse() + PASSES_PER_SEC(30);
  205. }
  206. }
  207.  
  208. namespace
  209. {
  210. struct SendDisconnectFunc
  211. {
  212. void operator () (LPDESC d)
  213. {
  214. if (d->GetCharacter())
  215. {
  216. if (d->GetCharacter()->GetGMLevel() == GM_PLAYER)
  217. d->GetCharacter()->ChatPacket(CHAT_TYPE_COMMAND, "quit Shutdown(SendDisconnectFunc)");
  218. }
  219. }
  220. };
  221.  
  222. struct DisconnectFunc
  223. {
  224. void operator () (LPDESC d)
  225. {
  226. if (d->GetType() == DESC_TYPE_CONNECTOR)
  227. return;
  228.  
  229. if (d->IsPhase(PHASE_P2P))
  230. return;
  231.  
  232. d->SetPhase(PHASE_CLOSE);
  233. }
  234. };
  235. }
  236.  
  237. extern std::map<DWORD, CLoginSim *> g_sim; // first: AID
  238. extern std::map<DWORD, CLoginSim *> g_simByPID;
  239. extern std::vector<TPlayerTable> g_vec_save;
  240. unsigned int save_idx = 0;
  241.  
  242. void heartbeat(LPHEART ht, int pulse)
  243. {
  244. DWORD t;
  245.  
  246. t = get_dword_time();
  247. num_events_called += event_process(pulse);
  248. s_dwProfiler[PROF_EVENT] += (get_dword_time() - t);
  249.  
  250. t = get_dword_time();
  251.  
  252. // 1초마다
  253. if (!(pulse % ht->passes_per_sec))
  254. {
  255. #ifdef ENABLE_LIMIT_TIME
  256. if ((unsigned)get_global_time() >= GLOBAL_LIMIT_TIME)
  257. {
  258. g_bShutdown = true;
  259. }
  260. #endif
  261.  
  262. if (g_bAuthServer && LC_IsBrazil() && !test_server)
  263. auth_brazil_log();
  264.  
  265. if (!g_bAuthServer)
  266. {
  267. TPlayerCountPacket pack;
  268. pack.dwCount = DESC_MANAGER::instance().GetLocalUserCount();
  269. db_clientdesc->DBPacket(HEADER_GD_PLAYER_COUNT, 0, &pack, sizeof(TPlayerCountPacket));
  270. }
  271. else
  272. {
  273. DESC_MANAGER::instance().ProcessExpiredLoginKey();
  274. DBManager::instance().FlushBilling();
  275. /*
  276. if (!(pulse % (ht->passes_per_sec * 600)))
  277. DBManager::instance().CheckBilling();
  278. */
  279. }
  280.  
  281. {
  282. int count = 0;
  283. itertype(g_sim) it = g_sim.begin();
  284.  
  285. while (it != g_sim.end())
  286. {
  287. if (!it->second->IsCheck())
  288. {
  289. it->second->SendLogin();
  290.  
  291. if (++count > 50)
  292. {
  293. sys_log(0, "FLUSH_SENT");
  294. break;
  295. }
  296. }
  297.  
  298. it++;
  299. }
  300.  
  301. if (save_idx < g_vec_save.size())
  302. {
  303. count = MIN(100, g_vec_save.size() - save_idx);
  304.  
  305. for (int i = 0; i < count; ++i, ++save_idx)
  306. db_clientdesc->DBPacket(HEADER_GD_PLAYER_SAVE, 0, &g_vec_save[save_idx], sizeof(TPlayerTable));
  307.  
  308. sys_log(0, "SAVE_FLUSH %d", count);
  309. }
  310. }
  311. }
  312.  
  313. //
  314. // 25 PPS(Pulse per second) 라고 가정할 때
  315. //
  316.  
  317. // 약 1.16초마다
  318. if (!(pulse % (passes_per_sec + 4)))
  319. CHARACTER_MANAGER::instance().ProcessDelayedSave();
  320.  
  321. //4초 마다
  322. #if defined (__FreeBSD__) && defined(__FILEMONITOR__)
  323. if (!(pulse % (passes_per_sec * 5)))
  324. {
  325. FileMonitorFreeBSD::Instance().Update(pulse);
  326. }
  327. #endif
  328.  
  329. // 약 5.08초마다
  330. if (!(pulse % (passes_per_sec * 5 + 2)))
  331. {
  332. ITEM_MANAGER::instance().Update();
  333. DESC_MANAGER::instance().UpdateLocalUserCount();
  334. }
  335.  
  336. s_dwProfiler[PROF_HEARTBEAT] += (get_dword_time() - t);
  337.  
  338. DBManager::instance().Process();
  339. AccountDB::instance().Process();
  340. CPVPManager::instance().Process();
  341.  
  342. if (g_bShutdown)
  343. {
  344. if (thecore_pulse() > g_shutdown_disconnect_pulse)
  345. {
  346. const DESC_MANAGER::DESC_SET & c_set_desc = DESC_MANAGER::instance().GetClientSet();
  347. std::for_each(c_set_desc.begin(), c_set_desc.end(), ::SendDisconnectFunc());
  348. g_shutdown_disconnect_pulse = INT_MAX;
  349. }
  350. else if (thecore_pulse() > g_shutdown_disconnect_force_pulse)
  351. {
  352. const DESC_MANAGER::DESC_SET & c_set_desc = DESC_MANAGER::instance().GetClientSet();
  353. std::for_each(c_set_desc.begin(), c_set_desc.end(), ::DisconnectFunc());
  354. }
  355. else if (thecore_pulse() > g_shutdown_disconnect_force_pulse + PASSES_PER_SEC(5))
  356. {
  357. thecore_shutdown();
  358. }
  359. }
  360. }
  361.  
  362. static void CleanUpForEarlyExit() {
  363. CancelReloadSpamEvent();
  364. }
  365.  
  366. int main(int argc, char **argv)
  367. {
  368. #ifdef DEBUG_ALLOC
  369. DebugAllocator::StaticSetUp();
  370. #endif
  371.  
  372. #ifndef __WIN32__
  373. // <Factor> start unit tests if option is set
  374. if ( argc > 1 )
  375. {
  376. if ( strcmp( argv[1], "unittest" ) == 0 )
  377. {
  378. ::testing::InitGoogleTest(&argc, argv);
  379. return RUN_ALL_TESTS();
  380. }
  381. }
  382. #endif
  383.  
  384. ilInit(); // DevIL Initialize
  385.  
  386. WriteVersion();
  387.  
  388. SECTREE_MANAGER sectree_manager;
  389. CHARACTER_MANAGER char_manager;
  390. ITEM_MANAGER item_manager;
  391. CShopManager shop_manager;
  392. #ifdef ENABLE_OFFLINE_SHOP_SYSTEM
  393. COfflineShopManager offlineshop_manager;
  394. #endif
  395. CMobManager mob_manager;
  396. CMotionManager motion_manager;
  397. CPartyManager party_manager;
  398. CSkillManager skill_manager;
  399. CPVPManager pvp_manager;
  400. LZOManager lzo_manager;
  401. DBManager db_manager;
  402. AccountDB account_db;
  403.  
  404. LogManager log_manager;
  405. MessengerManager messenger_manager;
  406. P2P_MANAGER p2p_manager;
  407. CGuildManager guild_manager;
  408. CGuildMarkManager mark_manager;
  409. CDungeonManager dungeon_manager;
  410. CRefineManager refine_manager;
  411. CBanwordManager banword_manager;
  412. CPrivManager priv_manager;
  413. CWarMapManager war_map_manager;
  414. building::CManager building_manager;
  415. CTargetManager target_manager;
  416. marriage::CManager marriage_manager;
  417. marriage::WeddingManager wedding_manager;
  418. CItemAddonManager item_addon_manager;
  419. CArenaManager arena_manager;
  420. COXEventManager OXEvent_manager;
  421. CMonarch Monarch;
  422. CHorseNameManager horsename_manager;
  423. CPCBangManager pcbang_manager;
  424.  
  425. DESC_MANAGER desc_manager;
  426.  
  427. TrafficProfiler trafficProfiler;
  428. CTableBySkill SkillPowerByLevel;
  429. CPolymorphUtils polymorph_utils;
  430. CProfiler profiler;
  431. CPasspod passpod;
  432. CBattleArena ba;
  433. COver9RefineManager o9r;
  434. SpamManager spam_mgr;
  435. CThreeWayWar threeway_war;
  436. CDragonLairManager dl_manager;
  437.  
  438. CHackShieldManager HSManager;
  439. CXTrapManager XTManager;
  440.  
  441. CSpeedServerManager SSManager;
  442. DSManager dsManager;
  443.  
  444. #ifdef __AUCTION__
  445. AuctionManager auctionManager;
  446. #endif
  447.  
  448. if (!start(argc, argv)) {
  449. CleanUpForEarlyExit();
  450. return 0;
  451. }
  452.  
  453. quest::CQuestManager quest_manager;
  454.  
  455. if (!quest_manager.Initialize()) {
  456. CleanUpForEarlyExit();
  457. return 0;
  458. }
  459.  
  460. MessengerManager::instance().Initialize();
  461. CGuildManager::instance().Initialize();
  462. fishing::Initialize();
  463. OXEvent_manager.Initialize();
  464. if (speed_server)
  465. CSpeedServerManager::instance().Initialize();
  466.  
  467. Cube_init();
  468. Acce_init();
  469. Blend_Item_init();
  470. ani_init();
  471. PanamaLoad();
  472.  
  473. if ( g_bTrafficProfileOn )
  474. TrafficProfiler::instance().Initialize( TRAFFIC_PROFILE_FLUSH_CYCLE, "ProfileLog" );
  475.  
  476. //if game server
  477. if (!g_bAuthServer)
  478. {
  479. //hackshield
  480. if (isHackShieldEnable)
  481. {
  482. if (!HSManager.Initialize())
  483. {
  484. fprintf(stderr, "Failed To Initialize HS");
  485. CleanUpForEarlyExit();
  486. return 0;
  487. }
  488. }
  489.  
  490. //xtrap
  491. if(bXTrapEnabled)
  492. {
  493. if (!XTManager.LoadXTrapModule())
  494. {
  495. CleanUpForEarlyExit();
  496. return 0;
  497. }
  498. #if defined (__FreeBSD__) && defined(__FILEMONITOR__)
  499. //PFN_FileChangeListener pNotifyFunc = boost::bind( &CXTrapManager::NotifyMapFileChanged, CXTrapManager::instance(), _1 );
  500. PFN_FileChangeListener pNotifyFunc = &(CXTrapManager::NotifyMapFileChanged);
  501.  
  502. const std::string strMap1Name = "map1.CS3";
  503. const std::string strMap2Name = "map2.CS3";
  504.  
  505. FileMonitorFreeBSD::Instance().AddWatch( strMap1Name, pNotifyFunc );
  506. FileMonitorFreeBSD::Instance().AddWatch( strMap2Name, pNotifyFunc );
  507. #endif
  508. }
  509. }
  510.  
  511. // Client PackageCrypt
  512.  
  513. //TODO : make it config
  514. const std::string strPackageCryptInfoDir = "package/";
  515. if( !desc_manager.LoadClientPackageCryptInfo( strPackageCryptInfoDir.c_str() ) )
  516. {
  517. sys_err("Failed to Load ClientPackageCryptInfo File(%s)", strPackageCryptInfoDir.c_str());
  518. }
  519.  
  520. #if defined (__FreeBSD__) && defined(__FILEMONITOR__)
  521. PFN_FileChangeListener pPackageNotifyFunc = &(DESC_MANAGER::NotifyClientPackageFileChanged);
  522. //FileMonitorFreeBSD::Instance().AddWatch( strPackageCryptInfoName, pPackageNotifyFunc );
  523. #endif
  524.  
  525. while (idle());
  526.  
  527. sys_log(0, "<shutdown> Starting...");
  528. g_bShutdown = true;
  529. g_bNoMoreClient = true;
  530.  
  531. if (g_bAuthServer)
  532. {
  533. DBManager::instance().FlushBilling(true);
  534.  
  535. int iLimit = DBManager::instance().CountQuery() / 50;
  536. int i = 0;
  537.  
  538. do
  539. {
  540. DWORD dwCount = DBManager::instance().CountQuery();
  541. sys_log(0, "Queries %u", dwCount);
  542.  
  543. if (dwCount == 0)
  544. break;
  545.  
  546. usleep(500000);
  547.  
  548. if (++i >= iLimit)
  549. if (dwCount == DBManager::instance().CountQuery())
  550. break;
  551. } while (1);
  552. }
  553.  
  554. sys_log(0, "<shutdown> Destroying CArenaManager...");
  555. arena_manager.Destroy();
  556. sys_log(0, "<shutdown> Destroying COXEventManager...");
  557. OXEvent_manager.Destroy();
  558.  
  559. sys_log(0, "<shutdown> Disabling signal timer...");
  560. signal_timer_disable();
  561.  
  562. sys_log(0, "<shutdown> Shutting down CHARACTER_MANAGER...");
  563. char_manager.GracefulShutdown();
  564. sys_log(0, "<shutdown> Shutting down ITEM_MANAGER...");
  565. item_manager.GracefulShutdown();
  566.  
  567. sys_log(0, "<shutdown> Flushing db_clientdesc...");
  568. db_clientdesc->FlushOutput();
  569. sys_log(0, "<shutdown> Flushing p2p_manager...");
  570. p2p_manager.FlushOutput();
  571.  
  572. sys_log(0, "<shutdown> Destroying CShopManager...");
  573. shop_manager.Destroy();
  574. sys_log(0, "<shutdown> Destroying CHARACTER_MANAGER...");
  575. char_manager.Destroy();
  576. sys_log(0, "<shutdown> Destroying ITEM_MANAGER...");
  577. item_manager.Destroy();
  578. sys_log(0, "<shutdown> Destroying DESC_MANAGER...");
  579. desc_manager.Destroy();
  580. sys_log(0, "<shutdown> Destroying quest::CQuestManager...");
  581. quest_manager.Destroy();
  582. sys_log(0, "<shutdown> Destroying building::CManager...");
  583. building_manager.Destroy();
  584.  
  585. if (!g_bAuthServer)
  586. {
  587. if (isHackShieldEnable)
  588. {
  589. sys_log(0, "<shutdown> Releasing HackShield manager...");
  590. HSManager.Release();
  591. }
  592. }
  593.  
  594. sys_log(0, "<shutdown> Flushing TrafficProfiler...");
  595. trafficProfiler.Flush();
  596.  
  597. destroy();
  598.  
  599. #ifdef DEBUG_ALLOC
  600. DebugAllocator::StaticTearDown();
  601. #endif
  602.  
  603. return 1;
  604. }
  605.  
  606. void usage()
  607. {
  608. printf("Option list\n"
  609. "-p <port> : bind port number (port must be over 1024)\n"
  610. "-l <level> : sets log level\n"
  611. "-v : log to stdout\n"
  612. "-r : do not load regen tables\n"
  613. "-t : traffic proflie on\n");
  614. }
  615.  
  616. int start(int argc, char **argv)
  617. {
  618. std::string st_localeServiceName;
  619.  
  620. bool bVerbose = false;
  621. char ch;
  622.  
  623. //_malloc_options = "A";
  624. #if defined(__FreeBSD__) && defined(DEBUG_ALLOC)
  625. _malloc_message = WriteMallocMessage;
  626. #endif
  627. #ifdef ENABLE_LIMIT_TIME
  628. if ((unsigned)get_global_time() >= GLOBAL_LIMIT_TIME)
  629. {
  630. return 0;
  631. }
  632. #endif
  633.  
  634. while ((ch = getopt(argc, argv, "npverltI")) != -1)
  635. {
  636. char* ep = NULL;
  637.  
  638. switch (ch)
  639. {
  640. case 'I': // IP
  641. strlcpy(g_szPublicIP, argv[optind], sizeof(g_szPublicIP));
  642.  
  643. printf("IP %s\n", g_szPublicIP);
  644.  
  645. optind++;
  646. optreset = 1;
  647. break;
  648.  
  649. case 'p': // port
  650. mother_port = strtol(argv[optind], &ep, 10);
  651.  
  652. if (mother_port <= 1024)
  653. {
  654. usage();
  655. return 0;
  656. }
  657.  
  658. printf("port %d\n", mother_port);
  659.  
  660. optind++;
  661. optreset = 1;
  662. break;
  663.  
  664. case 'l':
  665. {
  666. long l = strtol(argv[optind], &ep, 10);
  667.  
  668. log_set_level(l);
  669.  
  670. optind++;
  671. optreset = 1;
  672. }
  673. break;
  674.  
  675. // LOCALE_SERVICE
  676. case 'n':
  677. {
  678. if (optind < argc)
  679. {
  680. st_localeServiceName = argv[optind++];
  681. optreset = 1;
  682. }
  683. }
  684. break;
  685. // END_OF_LOCALE_SERVICE
  686.  
  687. case 'v': // verbose
  688. bVerbose = true;
  689. break;
  690.  
  691. case 'r':
  692. g_bNoRegen = true;
  693. break;
  694.  
  695. // TRAFFIC_PROFILER
  696. case 't':
  697. g_bTrafficProfileOn = true;
  698. break;
  699. // END_OF_TRAFFIC_PROFILER
  700. }
  701. }
  702.  
  703. // LOCALE_SERVICE
  704. config_init(st_localeServiceName);
  705. // END_OF_LOCALE_SERVICE
  706.  
  707. #ifdef ENABLE_OFFLINE_SHOP_SYSTEM
  708. // OFFLINE_SHOP_CONFIG
  709. offlineshop_config_init();
  710. // END_OF_OFFLINE_SHOP_CONFIG
  711. #endif
  712.  
  713. #ifdef __WIN32__
  714. // In Windows dev mode, "verbose" option is [on] by default.
  715. bVerbose = true;
  716. #endif
  717. if (!bVerbose)
  718. freopen("stdout", "a", stdout);
  719.  
  720. bool is_thecore_initialized = thecore_init(25, heartbeat);
  721.  
  722. if (!is_thecore_initialized)
  723. {
  724. fprintf(stderr, "Could not initialize thecore, check owner of pid, syslog\n");
  725. exit(0);
  726. }
  727.  
  728. if (false == CThreeWayWar::instance().LoadSetting("forkedmapindex.txt"))
  729. {
  730. if (false == g_bAuthServer)
  731. {
  732. fprintf(stderr, "Could not Load ThreeWayWar Setting file");
  733. exit(0);
  734. }
  735. }
  736.  
  737. signal_timer_disable();
  738.  
  739. main_fdw = fdwatch_new(4096);
  740.  
  741. if ((tcp_socket = socket_tcp_bind(g_szPublicIP, mother_port)) == INVALID_SOCKET)
  742. {
  743. perror("socket_tcp_bind: tcp_socket");
  744. return 0;
  745. }
  746.  
  747.  
  748. #ifndef __UDP_BLOCK__
  749. if ((udp_socket = socket_udp_bind(g_szPublicIP, mother_port)) == INVALID_SOCKET)
  750. {
  751. perror("socket_udp_bind: udp_socket");
  752. return 0;
  753. }
  754. #endif
  755.  
  756. // if internal ip exists, p2p socket uses internal ip, if not use public ip
  757. //if ((p2p_socket = socket_tcp_bind(*g_szInternalIP ? g_szInternalIP : g_szPublicIP, p2p_port)) == INVALID_SOCKET)
  758. if ((p2p_socket = socket_tcp_bind(g_szPublicIP, p2p_port)) == INVALID_SOCKET)
  759. {
  760. perror("socket_tcp_bind: p2p_socket");
  761. return 0;
  762. }
  763.  
  764. fdwatch_add_fd(main_fdw, tcp_socket, NULL, FDW_READ, false);
  765. #ifndef __UDP_BLOCK__
  766. fdwatch_add_fd(main_fdw, udp_socket, NULL, FDW_READ, false);
  767. #endif
  768. fdwatch_add_fd(main_fdw, p2p_socket, NULL, FDW_READ, false);
  769.  
  770. db_clientdesc = DESC_MANAGER::instance().CreateConnectionDesc(main_fdw, db_addr, db_port, PHASE_DBCLIENT, true);
  771. if (!g_bAuthServer) {
  772. db_clientdesc->UpdateChannelStatus(0, true);
  773. }
  774.  
  775. if (g_bAuthServer)
  776. {
  777. if (g_stAuthMasterIP.length() != 0)
  778. {
  779. fprintf(stderr, "SlaveAuth");
  780. g_pkAuthMasterDesc = DESC_MANAGER::instance().CreateConnectionDesc(main_fdw, g_stAuthMasterIP.c_str(), g_wAuthMasterPort, PHASE_P2P, true);
  781. P2P_MANAGER::instance().RegisterConnector(g_pkAuthMasterDesc);
  782. g_pkAuthMasterDesc->SetP2P(g_stAuthMasterIP.c_str(), g_wAuthMasterPort, g_bChannel);
  783.  
  784. }
  785. else
  786. {
  787. fprintf(stderr, "MasterAuth %d", LC_GetLocalType());
  788. }
  789. }
  790. /* game server to teen server */
  791. else
  792. {
  793. if (teen_addr[0] && teen_port)
  794. g_TeenDesc = DESC_MANAGER::instance().CreateConnectionDesc(main_fdw, teen_addr, teen_port, PHASE_TEEN, true);
  795.  
  796. extern unsigned int g_uiSpamBlockDuration;
  797. extern unsigned int g_uiSpamBlockScore;
  798. extern unsigned int g_uiSpamReloadCycle;
  799.  
  800. sys_log(0, "SPAM_CONFIG: duration %u score %u reload cycle %u\n",
  801. g_uiSpamBlockDuration, g_uiSpamBlockScore, g_uiSpamReloadCycle);
  802.  
  803. extern void LoadSpamDB();
  804. LoadSpamDB();
  805. }
  806.  
  807. signal_timer_enable(30);
  808. return 1;
  809. }
  810.  
  811. void destroy()
  812. {
  813. sys_log(0, "<shutdown> Canceling ReloadSpamEvent...");
  814. CancelReloadSpamEvent();
  815.  
  816. sys_log(0, "<shutdown> regen_free()...");
  817. regen_free();
  818.  
  819. sys_log(0, "<shutdown> Closing sockets...");
  820. socket_close(tcp_socket);
  821. #ifndef __UDP_BLOCK__
  822. socket_close(udp_socket);
  823. #endif
  824. socket_close(p2p_socket);
  825.  
  826. sys_log(0, "<shutdown> fdwatch_delete()...");
  827. fdwatch_delete(main_fdw);
  828.  
  829. sys_log(0, "<shutdown> event_destroy()...");
  830. event_destroy();
  831.  
  832. sys_log(0, "<shutdown> CTextFileLoader::DestroySystem()...");
  833. CTextFileLoader::DestroySystem();
  834.  
  835. sys_log(0, "<shutdown> thecore_destroy()...");
  836. thecore_destroy();
  837. }
  838.  
  839. int idle()
  840. {
  841. static struct timeval pta = { 0, 0 };
  842. static int process_time_count = 0;
  843. struct timeval now;
  844.  
  845. if (pta.tv_sec == 0)
  846. gettimeofday(&pta, (struct timezone *) 0);
  847.  
  848. int passed_pulses;
  849.  
  850. if (!(passed_pulses = thecore_idle()))
  851. return 0;
  852.  
  853. assert(passed_pulses > 0);
  854.  
  855. DWORD t;
  856.  
  857. while (passed_pulses--) {
  858. heartbeat(thecore_heart, ++thecore_heart->pulse);
  859.  
  860. // To reduce the possibility of abort() in checkpointing
  861. thecore_tick();
  862. }
  863.  
  864. t = get_dword_time();
  865. CHARACTER_MANAGER::instance().Update(thecore_heart->pulse);
  866. db_clientdesc->Update(t);
  867. s_dwProfiler[PROF_CHR_UPDATE] += (get_dword_time() - t);
  868.  
  869. t = get_dword_time();
  870. if (!io_loop(main_fdw)) return 0;
  871. s_dwProfiler[PROF_IO] += (get_dword_time() - t);
  872.  
  873. log_rotate();
  874.  
  875. gettimeofday(&now, (struct timezone *) 0);
  876. ++process_time_count;
  877.  
  878. if (now.tv_sec - pta.tv_sec > 0)
  879. {
  880. /*pt_log("[%3d] event %5d/%-5d idle %-4ld event %-4ld heartbeat %-4ld I/O %-4ld chrUpate %-4ld | WRITE: %-7d | PULSE: %d",
  881. process_time_count,
  882. num_events_called,
  883. event_count(),
  884. thecore_profiler[PF_IDLE],
  885. s_dwProfiler[PROF_EVENT],
  886. s_dwProfiler[PROF_HEARTBEAT],
  887. s_dwProfiler[PROF_IO],
  888. s_dwProfiler[PROF_CHR_UPDATE],
  889. current_bytes_written,
  890. thecore_pulse());*/
  891.  
  892. num_events_called = 0;
  893. current_bytes_written = 0;
  894.  
  895. process_time_count = 0;
  896. gettimeofday(&pta, (struct timezone *) 0);
  897.  
  898. memset(&thecore_profiler[0], 0, sizeof(thecore_profiler));
  899. memset(&s_dwProfiler[0], 0, sizeof(s_dwProfiler));
  900. }
  901. #ifdef _USE_SERVER_KEY_
  902. if (Metin2Server_IsInvalid() && 0 == (thecore_random() % 7146))
  903. {
  904. return 0; // shutdown
  905. }
  906. #endif
  907.  
  908. #ifdef __WIN32__
  909. if (_kbhit()) {
  910. int c = _getch();
  911. switch (c) {
  912. case 0x1b: // Esc
  913. return 0; // shutdown
  914. break;
  915. default:
  916. break;
  917. }
  918. }
  919. #endif
  920.  
  921. return 1;
  922. }
  923.  
  924. int io_loop(LPFDWATCH fdw)
  925. {
  926. LPDESC d;
  927. int num_events, event_idx;
  928.  
  929. DESC_MANAGER::instance().DestroyClosed(); // PHASE_CLOSE인 접속들을 끊어준다.
  930. DESC_MANAGER::instance().TryConnect();
  931.  
  932. if ((num_events = fdwatch(fdw, 0)) < 0)
  933. return 0;
  934.  
  935. for (event_idx = 0; event_idx < num_events; ++event_idx)
  936. {
  937. d = (LPDESC) fdwatch_get_client_data(fdw, event_idx);
  938.  
  939. if (!d)
  940. {
  941. if (FDW_READ == fdwatch_check_event(fdw, tcp_socket, event_idx))
  942. {
  943. DESC_MANAGER::instance().AcceptDesc(fdw, tcp_socket);
  944. fdwatch_clear_event(fdw, tcp_socket, event_idx);
  945. }
  946. else if (FDW_READ == fdwatch_check_event(fdw, p2p_socket, event_idx))
  947. {
  948. DESC_MANAGER::instance().AcceptP2PDesc(fdw, p2p_socket);
  949. fdwatch_clear_event(fdw, p2p_socket, event_idx);
  950. }
  951. /*
  952. else if (FDW_READ == fdwatch_check_event(fdw, udp_socket, event_idx))
  953. {
  954. char buf[256];
  955. struct sockaddr_in cliaddr;
  956. socklen_t socklen = sizeof(cliaddr);
  957.  
  958. int iBytesRead;
  959.  
  960. if ((iBytesRead = socket_udp_read(udp_socket, buf, 256, (struct sockaddr *) &cliaddr, &socklen)) > 0)
  961. {
  962. static CInputUDP s_inputUDP;
  963.  
  964. s_inputUDP.SetSockAddr(cliaddr);
  965.  
  966. int iBytesProceed;
  967. s_inputUDP.Process(NULL, buf, iBytesRead, iBytesProceed);
  968. }
  969.  
  970. fdwatch_clear_event(fdw, udp_socket, event_idx);
  971. }
  972. */
  973. continue;
  974. }
  975.  
  976. int iRet = fdwatch_check_event(fdw, d->GetSocket(), event_idx);
  977.  
  978. switch (iRet)
  979. {
  980. case FDW_READ:
  981. if (db_clientdesc == d)
  982. {
  983. int size = d->ProcessInput();
  984.  
  985. if (size)
  986. sys_log(1, "DB_BYTES_READ: %d", size);
  987.  
  988. if (size < 0)
  989. {
  990. d->SetPhase(PHASE_CLOSE);
  991. }
  992. }
  993. else if (d->ProcessInput() < 0)
  994. {
  995. d->SetPhase(PHASE_CLOSE);
  996. }
  997. break;
  998.  
  999. case FDW_WRITE:
  1000. if (db_clientdesc == d)
  1001. {
  1002. int buf_size = buffer_size(d->GetOutputBuffer());
  1003. int sock_buf_size = fdwatch_get_buffer_size(fdw, d->GetSocket());
  1004.  
  1005. int ret = d->ProcessOutput();
  1006.  
  1007. if (ret < 0)
  1008. {
  1009. d->SetPhase(PHASE_CLOSE);
  1010. }
  1011.  
  1012. if (buf_size)
  1013. sys_log(1, "DB_BYTES_WRITE: size %d sock_buf %d ret %d", buf_size, sock_buf_size, ret);
  1014. }
  1015. else if (d->ProcessOutput() < 0)
  1016. {
  1017. d->SetPhase(PHASE_CLOSE);
  1018. }
  1019. else if (g_TeenDesc==d)
  1020. {
  1021. int buf_size = buffer_size(d->GetOutputBuffer());
  1022. int sock_buf_size = fdwatch_get_buffer_size(fdw, d->GetSocket());
  1023.  
  1024. int ret = d->ProcessOutput();
  1025.  
  1026. if (ret < 0)
  1027. {
  1028. d->SetPhase(PHASE_CLOSE);
  1029. }
  1030.  
  1031. if (buf_size)
  1032. sys_log(0, "TEEN::Send(size %d sock_buf %d ret %d)", buf_size, sock_buf_size, ret);
  1033. }
  1034. break;
  1035.  
  1036. case FDW_EOF:
  1037. {
  1038. d->SetPhase(PHASE_CLOSE);
  1039. }
  1040. break;
  1041.  
  1042. default:
  1043. sys_err("fdwatch_check_event returned unknown %d", iRet);
  1044. d->SetPhase(PHASE_CLOSE);
  1045. break;
  1046. }
  1047. }
  1048.  
  1049. return 1;
  1050. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement