daily pastebin goal
58%
SHARE
TWEET

Untitled

a guest Oct 3rd, 2017 108 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include "stdafx.h"
  2. #include <sstream>
  3. #ifndef __WIN32__
  4. #include <ifaddrs.h>
  5. #endif
  6.  
  7. #include "constants.h"
  8. #include "utils.h"
  9. #include "log.h"
  10. #include "desc.h"
  11. #include "desc_manager.h"
  12. #include "item_manager.h"
  13. #include "p2p.h"
  14. #include "char.h"
  15. #include "ip_ban.h"
  16. #include "war_map.h"
  17. #include "locale_service.h"
  18. #include "config.h"
  19. #include "dev_log.h"
  20. #include "db.h"
  21. #include "skill_power.h"
  22. #include "check_server.h"
  23.  
  24. using std::string;
  25. #ifdef __CHANNEL_CHANGE_SYSTEM__
  26. int chChange_nYang = 0;
  27. BYTE chChange_nLevel = 1;
  28. static std::set<int> s_chChange_map_n_allows;
  29. static std::set<int> s_chChange_port_n_allows;
  30. #endif
  31. #ifdef __MOUNT_SYSTEM__
  32. static std::set<int> s_Mount_map_unallowed_find;
  33. #endif
  34. BYTE    g_bChannel = 0;
  35. WORD    mother_port = 50080;
  36. int     passes_per_sec = 25;
  37. WORD    db_port = 0;
  38. WORD    p2p_port = 50900;
  39. char    db_addr[ADDRESS_MAX_LEN + 1];
  40. int     save_event_second_cycle = passes_per_sec * 120; // 3분
  41. int     ping_event_second_cycle = passes_per_sec * 60;
  42. bool    g_bNoMoreClient = false;
  43. bool    g_bNoRegen = false;
  44. bool    g_bNoPasspod = false;
  45.  
  46.  
  47. // TRAFFIC_PROFILER
  48. bool        g_bTrafficProfileOn = false;
  49. DWORD       g_dwTrafficProfileFlushCycle = 3600;
  50. // END_OF_TRAFFIC_PROFILER
  51.  
  52. int         test_server = 0;
  53. int         speed_server = 0;
  54. #ifdef __AUCTION__
  55. int         auction_server = 0;
  56. #endif
  57. bool        distribution_test_server = false;
  58. bool        china_event_server = false;
  59. bool        guild_mark_server = true;
  60. BYTE        guild_mark_min_level = 3;
  61. bool        no_wander = false;
  62. int     g_iUserLimit = 32768;
  63.  
  64. char        g_szPublicIP[16] = "0";
  65. char        g_szInternalIP[16] = "0";
  66. bool        g_bSkillDisable = false;
  67. int         g_iFullUserCount = 1200;
  68. int         g_iBusyUserCount = 650;
  69. //Canada
  70. //int           g_iFullUserCount = 600;
  71. //int           g_iBusyUserCount = 350;
  72. //Brazil
  73. //int           g_iFullUserCount = 650;
  74. //int           g_iBusyUserCount = 450;
  75. bool        g_bEmpireWhisper = true;
  76. BYTE        g_bAuthServer = false;
  77.  
  78. bool        g_bCheckClientVersion = true;
  79. string  g_stClientVersion = "1";
  80.  
  81. BYTE        g_bBilling = false;
  82.  
  83. string  g_stAuthMasterIP;
  84. WORD        g_wAuthMasterPort = 0;
  85.  
  86. static std::set<DWORD> s_set_dwFileCRC;
  87. static std::set<DWORD> s_set_dwProcessCRC;
  88.  
  89. string g_stHostname = "";
  90. string g_table_postfix = "";
  91.  
  92. string g_stQuestDir = "./quest";
  93. //string g_stQuestObjectDir = "./quest/object";
  94. string g_stDefaultQuestObjectDir = "./quest/object";
  95. std::set<string> g_setQuestObjectDir;
  96.  
  97. std::vector<std::string>    g_stAdminPageIP;
  98. std::string g_stAdminPagePassword = "SHOWMETHEMONEY";
  99.  
  100. string g_stBlockDate = "30000705";
  101.  
  102. extern string g_stLocale;
  103.  
  104. char    teen_addr[ADDRESS_MAX_LEN + 1] = {0};
  105. WORD    teen_port   = 0;
  106.  
  107. int SPEEDHACK_LIMIT_COUNT   = 50;
  108. int SPEEDHACK_LIMIT_BONUS   = 80;
  109. int g_iSyncHackLimitCount = 10;
  110.  
  111. //시야 = VIEW_RANGE + VIEW_BONUS_RANGE
  112. //VIEW_BONUSE_RANGE : 클라이언트와 시야 처리에서너무 딱 떨어질경우 문제가 발생할수있어 500CM의 여분을 항상준다.
  113. int VIEW_RANGE = 5000;
  114. int VIEW_BONUS_RANGE = 500;
  115.  
  116. int g_server_id = 0;
  117. string g_strWebMallURL = "www.metin2.de";
  118.  
  119. unsigned int g_uiSpamBlockDuration = 60 * 15; // 기본 15분
  120. unsigned int g_uiSpamBlockScore = 100; // 기본 100점
  121. unsigned int g_uiSpamReloadCycle = 60 * 10; // 기본 10분
  122.  
  123. bool        g_bCheckMultiHack = true;
  124.  
  125. int         g_iSpamBlockMaxLevel = 10;
  126.  
  127. void        LoadStateUserCount();
  128. void        LoadValidCRCList();
  129. void        LoadClientVersion();
  130. bool        g_protectNormalPlayer   = false;        // 범법자가 "평화모드" 인 일반유저를 공격하지 못함
  131. bool            g_noticeBattleZone      = false;        // 중립지대에 입장하면 안내메세지를 알려줌
  132.  
  133. bool        isHackShieldEnable = false;
  134. int         HackShield_FirstCheckWaitTime = passes_per_sec * 30;
  135. int         HackShield_CheckCycleTime = passes_per_sec * 180;
  136.  
  137. bool        bXTrapEnabled = false;
  138.  
  139. bool        v_syslog_notice = false;
  140. bool        v_syschat_notice = false;
  141. bool        v_ban_waithack = false;
  142. int gPlayerMaxLevel = 99;
  143. int     g_iShoutLimitLevel = 15;
  144. bool    g_bGlobalShoutEnable = true;
  145. bool    g_bShoutAddonEnable = true;
  146. bool    g_bDisableEmpireLanguageCheck = true;
  147.  
  148. bool g_BlockCharCreation = false;
  149.  
  150.  
  151. //OPENID
  152. int     openid_server = 0;
  153. char    openid_host[256];
  154. char    openid_uri[256];
  155.  
  156. bool g_bEnableNewKingdomForWolfman = true; // Wolfman character is born in self kingdom if you are disable this command.
  157.  
  158. bool is_string_true(const char * string)
  159. {
  160.     bool    result = 0;
  161.     if (isnhdigit(*string))
  162.     {
  163.         str_to_number(result, string);
  164.         return result > 0 ? true : false;
  165.     }
  166.     else if (LOWER(*string) == 't')
  167.         return true;
  168.     else
  169.         return false;
  170. }
  171.  
  172. static std::set<int> s_set_map_allows;
  173.  
  174. bool map_allow_find(int index)
  175. {
  176.     if (g_bAuthServer)
  177.         return false;
  178.  
  179.     if (s_set_map_allows.find(index) == s_set_map_allows.end())
  180.         return false;
  181.  
  182.     return true;
  183. }
  184.  
  185. void map_allow_log()
  186. {
  187.     std::set<int>::iterator i;
  188.  
  189.     for (i = s_set_map_allows.begin(); i != s_set_map_allows.end(); ++i)
  190.         sys_log(0, "MAP_ALLOW: %d", *i);
  191. }
  192.  
  193. void map_allow_add(int index)
  194. {
  195.     if (map_allow_find(index) == true)
  196.     {
  197.         fprintf(stdout, "!!! FATAL ERROR !!! multiple MAP_ALLOW setting!!\n");
  198.         exit(1);
  199.     }
  200.  
  201.     fprintf(stdout, "MAP ALLOW %d\n", index);
  202.     s_set_map_allows.insert(index);
  203. }
  204.  
  205. void map_allow_copy(long * pl, int size)
  206. {
  207.     int iCount = 0;
  208.     std::set<int>::iterator it = s_set_map_allows.begin();
  209.  
  210.     while (it != s_set_map_allows.end())
  211.     {
  212.         int i = *(it++);
  213.         *(pl++) = i;
  214.  
  215.         if (++iCount > size)
  216.             break;
  217.     }
  218. }
  219. #ifdef __CHANNEL_CHANGE_SYSTEM__
  220. bool chChange_map_allow_find(int idx)
  221. {
  222.     if (g_bAuthServer)
  223.         return false;
  224.    
  225.     if (s_chChange_map_n_allows.find(idx) == s_chChange_map_n_allows.end())
  226.         return false;
  227.    
  228.     return true;
  229. }
  230.  
  231. void chChange_map_allow_add(int idx)
  232. {
  233.     if (chChange_map_allow_find(idx) == true)
  234.     {
  235.         fprintf(stdout, "<Channel Change> Error: there are multiple settings. Map index: %d\n", idx);
  236.     }
  237.     else
  238.     {
  239.         fprintf(stdout, "<Channel Change> Unallowed map index: %d\n", idx);
  240.         s_chChange_map_n_allows.insert(idx);
  241.     }
  242. }
  243.  
  244. bool chChange_port_allow_find(int idx)
  245. {
  246.     if (g_bAuthServer)
  247.         return false;
  248.    
  249.     if (s_chChange_port_n_allows.find(idx) == s_chChange_port_n_allows.end())
  250.         return false;
  251.    
  252.     return true;
  253. }
  254.  
  255. void chChange_port_allow_add(int idx)
  256. {
  257.     if (chChange_port_allow_find(idx) == true)
  258.     {
  259.         fprintf(stdout, "<Channel Change> Error: there are multiple settings. Port: %d\n", idx);
  260.     }
  261.     else
  262.     {
  263.         fprintf(stdout, "<Channel Change> Unallowed port: %d\n", idx);
  264.         s_chChange_port_n_allows.insert(idx);
  265.     }
  266. }
  267. #endif
  268. #ifdef __MOUNT_SYSTEM__
  269. bool Mount_map_unallowed_find(int idx)
  270. {
  271.     if (g_bAuthServer)
  272.         return false;
  273.    
  274.     if (s_Mount_map_unallowed_find.find(idx) == s_Mount_map_unallowed_find.end())
  275.         return false;
  276.    
  277.     return true;
  278. }
  279.  
  280. void Mount_map_unallowed_add(int idx)
  281. {
  282.     if (Mount_map_unallowed_find(idx) == true)
  283.         fprintf(stdout, "<Mount System> Error: there are multiple settings. Map index: %d\n", idx);
  284.     else
  285.     {
  286.         fprintf(stdout, "<Mount System> Unallowed map index: %d\n", idx);
  287.         s_Mount_map_unallowed_find.insert(idx);
  288.     }
  289. }
  290. #endif
  291. static void FN_add_adminpageIP(char *line)
  292. {
  293.     char    *last;
  294.     const char *delim = " \t\r\n";
  295.     char *v = strtok_r(line, delim, &last);
  296.  
  297.     while (v)
  298.     {
  299.         g_stAdminPageIP.push_back(v);
  300.         v = strtok_r(NULL, delim, &last);
  301.     }
  302. }
  303.  
  304. static void FN_log_adminpage()
  305. {
  306.     itertype(g_stAdminPageIP) iter = g_stAdminPageIP.begin();
  307.  
  308.     while (iter != g_stAdminPageIP.end())
  309.     {
  310.         dev_log(LOG_DEB0, "ADMIN_PAGE_IP = %s", (*iter).c_str());
  311.         ++iter;
  312.     }
  313.  
  314.     dev_log(LOG_DEB0, "ADMIN_PAGE_PASSWORD = %s", g_stAdminPagePassword.c_str());
  315. }
  316.  
  317. bool GetIPInfo()
  318. {
  319. #ifndef __WIN32__
  320.     struct ifaddrs* ifaddrp = NULL;
  321.  
  322.     if (0 != getifaddrs(&ifaddrp))
  323.         return false;
  324.  
  325.     for( struct ifaddrs* ifap=ifaddrp ; NULL != ifap ; ifap = ifap->ifa_next )
  326.     {
  327.         struct sockaddr_in * sai = (struct sockaddr_in *) ifap->ifa_addr;
  328.  
  329.         if (!ifap->ifa_netmask ||  // ignore if no netmask
  330.                 sai->sin_addr.s_addr == 0 || // ignore if address is 0.0.0.0
  331.                 sai->sin_addr.s_addr == 16777343) // ignore if address is 127.0.0.1
  332.             continue;
  333. #else
  334.     WSADATA wsa_data;
  335.     char host_name[100];
  336.     HOSTENT* host_ent;
  337.     int n = 0;
  338.  
  339.     if (WSAStartup(0x0101, &wsa_data)) {
  340.         return false;
  341.     }
  342.  
  343.     gethostname(host_name, sizeof(host_name));
  344.     host_ent = gethostbyname(host_name);
  345.     if (host_ent == NULL) {
  346.         return false;
  347.     }
  348.     for ( ; host_ent->h_addr_list[n] != NULL; ++n) {
  349.         struct sockaddr_in addr;
  350.         struct sockaddr_in* sai = &addr;
  351.         memcpy(&sai->sin_addr.s_addr, host_ent->h_addr_list[n], host_ent->h_length);
  352. #endif
  353.  
  354.         char * netip = inet_ntoa(sai->sin_addr);
  355.        
  356.         if (!g_szInternalIP && netip)
  357.         {
  358.             sys_err("TEST_IP");
  359.             thecore_shutdown();
  360.         }
  361.  
  362.         if (!strncmp(netip, "999.999", 7)) // ignore if address is starting with 192
  363.         {
  364.             strlcpy(g_szInternalIP, netip, sizeof(g_szInternalIP));
  365. #ifndef __WIN32__
  366.             fprintf(stderr, "INTERNAL_IP: %s interface %s\n", netip, ifap->ifa_name);
  367. #else
  368.             fprintf(stderr, "INTERNAL_IP: %s\n", netip);
  369. #endif
  370.         }
  371.         else if (!strncmp(netip, "10.", 3))
  372.         {
  373.             strlcpy(g_szInternalIP, netip, sizeof(g_szInternalIP));
  374. #ifndef __WIN32__
  375.             fprintf(stderr, "INTERNAL_IP: %s interface %s\n", netip, ifap->ifa_name);
  376. #else
  377.             fprintf(stderr, "INTERNAL_IP: %s\n", netip);
  378. #endif
  379.         }
  380.         else if (g_szPublicIP[0] == '0')
  381.         {
  382.             strlcpy(g_szPublicIP, netip, sizeof(g_szPublicIP));
  383. #ifndef __WIN32__
  384.             fprintf(stderr, "PUBLIC_IP: %s interface %s\n", netip, ifap->ifa_name);
  385. #else
  386.             fprintf(stderr, "PUBLIC_IP: %s\n", netip);
  387. #endif
  388.         }
  389.     }
  390.  
  391. #ifndef __WIN32__
  392.     freeifaddrs( ifaddrp );
  393. #else
  394.     WSACleanup();
  395. #endif
  396.  
  397.     if (g_szPublicIP[0] != '0')
  398.         return true;
  399.     else
  400.         return false;
  401. }
  402. #ifdef OFFLINE_SHOP
  403. std::map<DWORD, DWORD> g_ShopIndexCount;
  404. std::map<int, TShopCost> g_ShopCosts;
  405. #include <boost/algorithm/string.hpp>
  406. void LoadShopConfig()
  407. {
  408.     SQLMsg * pkMsg(DBManager::instance().DirectQuery("SELECT `id`,`time`,`time_type`+0,`cost` from shop_cost"));
  409.     SQLResult * pRes = pkMsg->Get();
  410.     if (pRes->uiNumRows)
  411.     {
  412.         MYSQL_ROW row;
  413.         g_ShopIndexCount.clear();
  414.         while ((row = mysql_fetch_row(pRes->pSQLResult)))
  415.         {
  416.             int id;
  417.             str_to_number(id, row[0]);
  418.             TShopCost c;
  419.             str_to_number(c.days, row[1]);
  420.             BYTE type;
  421.             str_to_number(type, row[2]);
  422.             if (type == 1)
  423.                 c.time = 86400;
  424.             else if (type == 2)
  425.                 c.time = 3600;
  426.             else
  427.                 c.time = 0;
  428.             str_to_number(c.price, row[3]);
  429.             g_ShopCosts[id] = c;
  430.         }
  431.     }
  432.     const DESC_MANAGER::DESC_SET & set = DESC_MANAGER::instance().GetClientSet();
  433.     DESC_MANAGER::DESC_SET::const_iterator it = set.begin();
  434.  
  435.     while (it != set.end())
  436.     {
  437.         LPDESC d = *(it++);
  438.  
  439.         if (!d->GetCharacter())
  440.             continue;
  441.         d->GetCharacter()->SendShopCost();
  442.     }
  443.  
  444. }
  445. void LoadIndexShopLimit()
  446. {
  447.     SQLMsg * pkMsg(DBManager::instance().DirectQuery("SELECT map_index,shop_limit from `shop_limit` where channel=%d or channel=0", g_bChannel));
  448.     SQLResult * pRes = pkMsg->Get();
  449.     if (pRes->uiNumRows)
  450.     {
  451.         MYSQL_ROW row;
  452.         g_ShopIndexCount.clear();
  453.         while ((row = mysql_fetch_row(pRes->pSQLResult)))
  454.         {
  455.  
  456.             int index, limit;
  457.             str_to_number(index, row[0]);
  458.             str_to_number(limit, row[1]);
  459.             if (!map_allow_find(index))
  460.                 continue;
  461.             g_ShopIndexCount.insert(std::make_pair(index,limit));
  462.             sys_log(0, "Shop Map %d limit %d\n", index, limit);
  463.         }
  464.     }
  465.     fprintf(stdout, "\n");
  466.  
  467.  
  468. }
  469. #endif
  470. void config_init(const string& st_localeServiceName)
  471. {
  472.     FILE    *fp;
  473.  
  474.     char    buf[256];
  475.     char    token_string[256];
  476.     char    value_string[256];
  477.  
  478.     // LOCALE_SERVICE
  479.     string  st_configFileName;
  480.  
  481.     st_configFileName.reserve(32);
  482.     st_configFileName = "CONFIG";
  483.  
  484.     if (!st_localeServiceName.empty())
  485.     {
  486.         st_configFileName += ".";
  487.         st_configFileName += st_localeServiceName;
  488.     }
  489.     // END_OF_LOCALE_SERVICE
  490.  
  491.     if (!(fp = fopen(st_configFileName.c_str(), "r")))
  492.     {
  493.         fprintf(stderr, "Can not open [%s]\n", st_configFileName.c_str());
  494.         exit(1);
  495.     }
  496.  
  497.     if (!GetIPInfo())
  498.     {
  499.         fprintf(stderr, "Can not get public ip address\n");
  500.         exit(1);
  501.     }
  502.  
  503.     char db_host[2][64], db_user[2][64], db_pwd[2][64], db_db[2][64];
  504.     // ... 아... db_port는 이미 있는데... 네이밍 어찌해야함...
  505.     int mysql_db_port[2];
  506.  
  507.     for (int n = 0; n < 2; ++n)
  508.     {
  509.         *db_host[n] = '\0';
  510.         *db_user[n] = '\0';
  511.         *db_pwd[n]= '\0';
  512.         *db_db[n]= '\0';
  513.         mysql_db_port[n] = 0;
  514.     }
  515.  
  516.     char log_host[64], log_user[64], log_pwd[64], log_db[64];
  517.     int log_port = 0;
  518.  
  519.     *log_host = '\0';
  520.     *log_user = '\0';
  521.     *log_pwd = '\0';
  522.     *log_db = '\0';
  523.  
  524.  
  525.     // DB에서 로케일정보를 세팅하기위해서는 다른 세팅값보다 선행되어서
  526.     // DB정보만 읽어와 로케일 세팅을 한후 다른 세팅을 적용시켜야한다.
  527.     // 이유는 로케일관련된 초기화 루틴이 곳곳에 존재하기 때문.
  528.  
  529.     bool isCommonSQL = false;  
  530.     bool isPlayerSQL = false;
  531.  
  532.     FILE* fpOnlyForDB;
  533.  
  534.     if (!(fpOnlyForDB = fopen(st_configFileName.c_str(), "r")))
  535.     {
  536.         fprintf(stderr, "Can not open [%s]\n", st_configFileName.c_str());
  537.         exit(1);
  538.     }
  539.  
  540.     while (fgets(buf, 256, fpOnlyForDB))
  541.     {
  542.         parse_token(buf, token_string, value_string);
  543.  
  544.         TOKEN("BLOCK_LOGIN")
  545.         {
  546.             g_stBlockDate = value_string;
  547.         }
  548.  
  549.         TOKEN("adminpage_ip")
  550.         {
  551.             FN_add_adminpageIP(value_string);
  552.             //g_stAdminPageIP[0] = value_string;
  553.         }
  554.  
  555.         TOKEN("adminpage_ip1")
  556.         {
  557.             FN_add_adminpageIP(value_string);
  558.             //g_stAdminPageIP[0] = value_string;
  559.         }
  560.  
  561.         TOKEN("adminpage_ip2")
  562.         {
  563.             FN_add_adminpageIP(value_string);
  564.             //g_stAdminPageIP[1] = value_string;
  565.         }
  566.  
  567.         TOKEN("adminpage_ip3")
  568.         {
  569.             FN_add_adminpageIP(value_string);
  570.             //g_stAdminPageIP[2] = value_string;
  571.         }
  572.  
  573.         TOKEN("adminpage_password")
  574.         {
  575.             g_stAdminPagePassword = value_string;
  576.         }
  577.  
  578.         TOKEN("hostname")
  579.         {
  580.             g_stHostname = value_string;
  581.             fprintf(stdout, "HOSTNAME: %s\n", g_stHostname.c_str());
  582.             continue;
  583.         }
  584.  
  585.         TOKEN("channel")
  586.         {
  587.             str_to_number(g_bChannel, value_string);
  588.             continue;
  589.         }
  590.  
  591.         TOKEN("player_sql")
  592.         {
  593.             const char * line = two_arguments(value_string, db_host[0], sizeof(db_host[0]), db_user[0], sizeof(db_user[0]));
  594.             line = two_arguments(line, db_pwd[0], sizeof(db_pwd[0]), db_db[0], sizeof(db_db[0]));
  595.  
  596.             if (NULL != line[0])
  597.             {
  598.                 char buf[256];
  599.                 one_argument(line, buf, sizeof(buf));
  600.                 str_to_number(mysql_db_port[0], buf);
  601.             }
  602.  
  603.             if (!*db_host[0] || !*db_user[0] || !*db_pwd[0] || !*db_db[0])
  604.             {
  605.                 fprintf(stderr, "PLAYER_SQL syntax: logsql <host user password db>\n");
  606.                 exit(1);
  607.             }
  608.  
  609.             char buf[1024];
  610.             snprintf(buf, sizeof(buf), "PLAYER_SQL: %s %s %s %s %d", db_host[0], db_user[0], db_pwd[0], db_db[0], mysql_db_port[0]);
  611.             isPlayerSQL = true;
  612.             continue;
  613.         }
  614.  
  615.         TOKEN("common_sql")
  616.         {
  617.             const char * line = two_arguments(value_string, db_host[1], sizeof(db_host[1]), db_user[1], sizeof(db_user[1]));
  618.             line = two_arguments(line, db_pwd[1], sizeof(db_pwd[1]), db_db[1], sizeof(db_db[1]));
  619.  
  620.             if (NULL != line[0])
  621.             {
  622.                 char buf[256];
  623.                 one_argument(line, buf, sizeof(buf));
  624.                 str_to_number(mysql_db_port[1], buf);
  625.             }
  626.  
  627.             if (!*db_host[1] || !*db_user[1] || !*db_pwd[1] || !*db_db[1])
  628.             {
  629.                 fprintf(stderr, "COMMON_SQL syntax: logsql <host user password db>\n");
  630.                 exit(1);
  631.             }
  632.  
  633.             char buf[1024];
  634.             snprintf(buf, sizeof(buf), "COMMON_SQL: %s %s %s %s %d", db_host[1], db_user[1], db_pwd[1], db_db[1], mysql_db_port[1]);
  635.             isCommonSQL = true;
  636.             continue;
  637.         }
  638.  
  639.         TOKEN("log_sql")
  640.         {
  641.             const char * line = two_arguments(value_string, log_host, sizeof(log_host), log_user, sizeof(log_user));
  642.             line = two_arguments(line, log_pwd, sizeof(log_pwd), log_db, sizeof(log_db));
  643.  
  644.             if (NULL != line[0])
  645.             {
  646.                 char buf[256];
  647.                 one_argument(line, buf, sizeof(buf));
  648.                 str_to_number(log_port, buf);
  649.             }
  650.  
  651.             if (!*log_host || !*log_user || !*log_pwd || !*log_db)
  652.             {
  653.                 fprintf(stderr, "LOG_SQL syntax: logsql <host user password db>\n");
  654.                 exit(1);
  655.             }
  656.  
  657.             char buf[1024];
  658.             snprintf(buf, sizeof(buf), "LOG_SQL: %s %s %s %s %d", log_host, log_user, log_pwd, log_db, log_port);
  659.             continue;
  660.         }
  661.  
  662.        
  663.         //OPENID       
  664.         TOKEN("WEB_AUTH")
  665.         {
  666.             const char * line = two_arguments(value_string, openid_host, sizeof(openid_host), openid_uri, sizeof(openid_uri));
  667.  
  668.             if (!*openid_host || !*openid_uri)
  669.             {
  670.                 fprintf(stderr, "WEB_AUTH syntax error (ex: WEB_AUTH <host(metin2.co.kr) uri(/kyw/gameauth.php)>\n");
  671.                 exit(1);
  672.             }
  673.  
  674.             char buf[1024];
  675.             openid_server = 1;
  676.             snprintf(buf, sizeof(buf), "WEB_AUTH: %s %s", openid_host, openid_uri);
  677.             continue;
  678.         }
  679.     }
  680.  
  681.     //처리가 끝났으니 파일을 닫자.
  682.     fclose(fpOnlyForDB);
  683.  
  684.     // CONFIG_SQL_INFO_ERROR
  685.     if (!isCommonSQL)
  686.     {
  687.         puts("LOAD_COMMON_SQL_INFO_FAILURE:");
  688.         puts("");
  689.         puts("CONFIG:");
  690.         puts("------------------------------------------------");
  691.         puts("COMMON_SQL: HOST USER PASSWORD DATABASE");
  692.         puts("");
  693.         exit(1);
  694.     }
  695.  
  696.     if (!isPlayerSQL)
  697.     {
  698.         puts("LOAD_PLAYER_SQL_INFO_FAILURE:");
  699.         puts("");
  700.         puts("CONFIG:");
  701.         puts("------------------------------------------------");
  702.         puts("PLAYER_SQL: HOST USER PASSWORD DATABASE");
  703.         puts("");
  704.         exit(1);
  705.     }
  706.  
  707.     // Common DB 가 Locale 정보를 가지고 있기 때문에 가장 먼저 접속해야 한다.
  708.     AccountDB::instance().Connect(db_host[1], mysql_db_port[1], db_user[1], db_pwd[1], db_db[1]);
  709.  
  710.     if (false == AccountDB::instance().IsConnected())
  711.     {
  712.         fprintf(stderr, "cannot start server while no common sql connected\n");
  713.         exit(1);
  714.     }
  715.  
  716.     fprintf(stdout, "CommonSQL connected\n");
  717.  
  718.     // 로케일 정보를 가져오자
  719.     // <경고> 쿼리문에 절대 조건문(WHERE) 달지 마세요. (다른 지역에서 문제가 생길수 있습니다)
  720.     {
  721.         char szQuery[512];
  722.         snprintf(szQuery, sizeof(szQuery), "SELECT mKey, mValue FROM locale");
  723.  
  724.         std::auto_ptr<SQLMsg> pMsg(AccountDB::instance().DirectQuery(szQuery));
  725.  
  726.         if (pMsg->Get()->uiNumRows == 0)
  727.         {
  728.             fprintf(stderr, "COMMON_SQL: DirectQuery failed : %s\n", szQuery);
  729.             exit(1);
  730.         }
  731.  
  732.         MYSQL_ROW row;
  733.  
  734.         while (NULL != (row = mysql_fetch_row(pMsg->Get()->pSQLResult)))
  735.         {
  736.             // 로케일 세팅
  737.             if (strcasecmp(row[0], "LOCALE") == 0)
  738.             {
  739.                 if (LocaleService_Init(row[1]) == false)
  740.                 {
  741.                     fprintf(stderr, "COMMON_SQL: invalid locale key %s\n", row[1]);
  742.                     exit(1);
  743.                 }
  744.             }
  745.         }
  746.     }
  747.  
  748.     // 로케일 정보를 COMMON SQL에 세팅해준다.
  749.     // 참고로 g_stLocale 정보는 LocaleService_Init() 내부에서 세팅된다.
  750.     fprintf(stdout, "Setting DB to locale %s\n", g_stLocale.c_str());
  751.  
  752.     AccountDB::instance().SetLocale(g_stLocale);
  753.  
  754.     AccountDB::instance().ConnectAsync(db_host[1], mysql_db_port[1], db_user[1], db_pwd[1], db_db[1], g_stLocale.c_str());
  755.  
  756.     // Player DB 접속
  757.     DBManager::instance().Connect(db_host[0], mysql_db_port[0], db_user[0], db_pwd[0], db_db[0]);
  758.  
  759.     if (!DBManager::instance().IsConnected())
  760.     {
  761.         fprintf(stderr, "PlayerSQL.ConnectError\n");
  762.         exit(1);
  763.     }
  764.  
  765.     fprintf(stdout, "PlayerSQL connected\n");
  766.  
  767.     if (false == g_bAuthServer) // 인증 서버가 아닐 경우
  768.     {
  769.         // Log DB 접속
  770.         LogManager::instance().Connect(log_host, log_port, log_user, log_pwd, log_db);
  771.  
  772.         if (!LogManager::instance().IsConnected())
  773.         {
  774.             fprintf(stderr, "LogSQL.ConnectError\n");
  775.             exit(1);
  776.         }
  777.  
  778.         fprintf(stdout, "LogSQL connected\n");
  779.  
  780.         LogManager::instance().BootLog(g_stHostname.c_str(), g_bChannel);
  781.     }
  782.  
  783.     // SKILL_POWER_BY_LEVEL
  784.     // 스트링 비교의 문제로 인해서 AccountDB::instance().SetLocale(g_stLocale) 후부터 한다.
  785.     // 물론 국내는 별로 문제가 안된다(해외가 문제)
  786.     {
  787.         char szQuery[256];
  788.         snprintf(szQuery, sizeof(szQuery), "SELECT mValue FROM locale WHERE mKey='SKILL_POWER_BY_LEVEL'");
  789.         std::auto_ptr<SQLMsg> pMsg(AccountDB::instance().DirectQuery(szQuery));
  790.  
  791.         if (pMsg->Get()->uiNumRows == 0)
  792.         {
  793.             fprintf(stderr, "[SKILL_PERCENT] Query failed: %s", szQuery);
  794.             exit(1);
  795.         }
  796.  
  797.         MYSQL_ROW row;
  798.  
  799.         row = mysql_fetch_row(pMsg->Get()->pSQLResult);
  800.  
  801.         const char * p = row[0];
  802.         int cnt = 0;
  803.         char num[128];
  804.         int aiBaseSkillPowerByLevelTable[SKILL_MAX_LEVEL+1];
  805.  
  806.         fprintf(stdout, "SKILL_POWER_BY_LEVEL %s\n", p);
  807.         while (*p != '\0' && cnt < (SKILL_MAX_LEVEL + 1))
  808.         {
  809.             p = one_argument(p, num, sizeof(num));
  810.             aiBaseSkillPowerByLevelTable[cnt++] = atoi(num);
  811.  
  812.             //fprintf(stdout, "%d %d\n", cnt - 1, aiBaseSkillPowerByLevelTable[cnt - 1]);
  813.             if (*p == '\0')
  814.             {
  815.                 if (cnt != (SKILL_MAX_LEVEL + 1))
  816.                 {
  817.                     fprintf(stderr, "[SKILL_PERCENT] locale table has not enough skill information! (count: %d query: %s)", cnt, szQuery);
  818.                     exit(1);
  819.                 }
  820.  
  821.                 fprintf(stdout, "SKILL_POWER_BY_LEVEL: Done! (count %d)\n", cnt);
  822.                 break;
  823.             }
  824.         }
  825.  
  826.         // 종족별 스킬 세팅
  827.         for (int job = 0; job < JOB_MAX_NUM * 2; ++job)
  828.         {
  829.             snprintf(szQuery, sizeof(szQuery), "SELECT mValue from locale where mKey='SKILL_POWER_BY_LEVEL_TYPE%d' ORDER BY CAST(mValue AS unsigned)", job);
  830.             std::auto_ptr<SQLMsg> pMsg(AccountDB::instance().DirectQuery(szQuery));
  831.  
  832.             // 세팅이 안되어있으면 기본테이블을 사용한다.
  833.             if (pMsg->Get()->uiNumRows == 0)
  834.             {
  835.                 CTableBySkill::instance().SetSkillPowerByLevelFromType(job, aiBaseSkillPowerByLevelTable);
  836.                 continue;
  837.             }
  838.  
  839.             row = mysql_fetch_row(pMsg->Get()->pSQLResult);
  840.             cnt = 0;
  841.             p = row[0];
  842.             int aiSkillTable[SKILL_MAX_LEVEL + 1];
  843.  
  844.             fprintf(stdout, "SKILL_POWER_BY_JOB %d %s\n", job, p);
  845.             while (*p != '\0' && cnt < (SKILL_MAX_LEVEL + 1))
  846.             {          
  847.                 p = one_argument(p, num, sizeof(num));
  848.                 aiSkillTable[cnt++] = atoi(num);
  849.  
  850.                 //fprintf(stdout, "%d %d\n", cnt - 1, aiBaseSkillPowerByLevelTable[cnt - 1]);
  851.                 if (*p == '\0')
  852.                 {
  853.                     if (cnt != (SKILL_MAX_LEVEL + 1))
  854.                     {
  855.                         fprintf(stderr, "[SKILL_PERCENT] locale table has not enough skill information! (count: %d query: %s)", cnt, szQuery);
  856.                         exit(1);
  857.                     }
  858.  
  859.                     fprintf(stdout, "SKILL_POWER_BY_JOB: Done! (job: %d count: %d)\n", job, cnt);
  860.                     break;
  861.                 }
  862.             }
  863.  
  864.             CTableBySkill::instance().SetSkillPowerByLevelFromType(job, aiSkillTable);
  865.         }      
  866.     }
  867.     // END_SKILL_POWER_BY_LEVEL
  868.  
  869.     // LOG_KEEP_DAYS_EXTEND
  870.     log_set_expiration_days(2);
  871.     // END_OF_LOG_KEEP_DAYS_EXTEND
  872.  
  873.     while (fgets(buf, 256, fp))
  874.     {
  875.         parse_token(buf, token_string, value_string);
  876.  
  877.         TOKEN("empire_whisper")
  878.         {
  879.             bool b_value = 0;
  880.             str_to_number(b_value, value_string);
  881.             g_bEmpireWhisper = !!b_value;
  882.             continue;
  883.         }
  884.        
  885.         TOKEN("mark_server")
  886.         {
  887.             guild_mark_server = is_string_true(value_string);
  888.             continue;
  889.         }
  890.  
  891.         TOKEN("mark_min_level")
  892.         {
  893.             str_to_number(guild_mark_min_level, value_string);
  894.             guild_mark_min_level = MINMAX(0, guild_mark_min_level, GUILD_MAX_LEVEL);
  895.             continue;
  896.         }
  897.  
  898.         TOKEN("port")
  899.         {
  900.             str_to_number(mother_port, value_string);
  901.             continue;
  902.         }
  903.  
  904.         TOKEN("log_keep_days")
  905.         {
  906.             int i = 0;
  907.             str_to_number(i, value_string);
  908.             log_set_expiration_days(MINMAX(1, i, 90));
  909.             continue;
  910.         }
  911.  
  912.         TOKEN("passes_per_sec")
  913.         {
  914.             str_to_number(passes_per_sec, value_string);
  915.             continue;
  916.         }
  917.  
  918.         TOKEN("p2p_port")
  919.         {
  920.             str_to_number(p2p_port, value_string);
  921.             continue;
  922.         }
  923.  
  924.         TOKEN("db_port")
  925.         {
  926.             str_to_number(db_port, value_string);
  927.             continue;
  928.         }
  929.  
  930.         TOKEN("db_addr")
  931.         {
  932.             strlcpy(db_addr, value_string, sizeof(db_addr));
  933.  
  934.             for (int n =0; n < ADDRESS_MAX_LEN; ++n)
  935.             {
  936.                 if (db_addr[n] == ' ')
  937.                     db_addr[n] = '\0';
  938.             }
  939.  
  940.             continue;
  941.         }
  942.  
  943.         TOKEN("save_event_second_cycle")
  944.         {
  945.             int cycle = 0;
  946.             str_to_number(cycle, value_string);
  947.             save_event_second_cycle = cycle * passes_per_sec;
  948.             continue;
  949.         }
  950.  
  951.         TOKEN("ping_event_second_cycle")
  952.         {
  953.             int cycle = 0;
  954.             str_to_number(cycle, value_string);
  955.             ping_event_second_cycle = cycle * passes_per_sec;
  956.             continue;
  957.         }
  958.  
  959.         TOKEN("table_postfix")
  960.         {
  961.             g_table_postfix = value_string;
  962.             continue;
  963.         }
  964.  
  965.         TOKEN("test_server")
  966.         {
  967.             printf("-----------------------------------------------\n");
  968.             printf("TEST_SERVER\n");
  969.             printf("-----------------------------------------------\n");
  970.             str_to_number(test_server, value_string);
  971.             continue;
  972.         }
  973.  
  974.         TOKEN("speed_server")
  975.         {
  976.             printf("-----------------------------------------------\n");
  977.             printf("SPEED_SERVER\n");
  978.             printf("-----------------------------------------------\n");
  979.             str_to_number(speed_server, value_string);
  980.             continue;
  981.         }
  982. #ifdef __AUCTION__
  983.         TOKEN("auction_server")
  984.         {
  985.             printf("-----------------------------------------------\n");
  986.             printf("AUCTION_SERVER\n");
  987.             printf("-----------------------------------------------\n");
  988.             str_to_number(auction_server, value_string);
  989.             continue;
  990.         }
  991. #endif
  992.         TOKEN("distribution_test_server")
  993.         {
  994.             str_to_number(distribution_test_server, value_string);
  995.             continue;
  996.         }
  997.  
  998.         TOKEN("china_event_server")
  999.         {
  1000.             str_to_number(china_event_server, value_string);
  1001.             continue;
  1002.         }
  1003.  
  1004.         TOKEN("shutdowned")
  1005.         {
  1006.             g_bNoMoreClient = true;
  1007.             continue;
  1008.         }
  1009. #ifdef __MOUNT_SYSTEM__
  1010.         TOKEN("MOUNT_MAP_UNALLOWED")
  1011.         {
  1012.             char * p = value_string;
  1013.             string stNum;
  1014.             for (; *p; p++)
  1015.             {
  1016.                 if (isnhspace(*p))
  1017.                 {
  1018.                     if (stNum.length())
  1019.                     {
  1020.                         int idx = 0;
  1021.                         str_to_number(idx, stNum.c_str());
  1022.                         Mount_map_unallowed_add(idx);
  1023.                         stNum.clear();
  1024.                     }
  1025.                 }
  1026.                 else
  1027.                     stNum += *p;
  1028.             }
  1029.            
  1030.             if (stNum.length())
  1031.             {
  1032.                 int idx = 0;
  1033.                 str_to_number(idx, stNum.c_str());
  1034.                 Mount_map_unallowed_add(idx);
  1035.             }
  1036.            
  1037.             continue;
  1038.         }
  1039. #endif
  1040.         TOKEN("no_regen")
  1041.         {
  1042.             g_bNoRegen = true;
  1043.             continue;
  1044.         }
  1045.  
  1046.         TOKEN("traffic_profile")
  1047.         {
  1048.             g_bTrafficProfileOn = true;
  1049.             continue;
  1050.         }
  1051.  
  1052.  
  1053.         TOKEN("map_allow")
  1054.         {
  1055.             char * p = value_string;
  1056.             string stNum;
  1057.  
  1058.             for (; *p; p++)
  1059.             {  
  1060.                 if (isnhspace(*p))
  1061.                 {
  1062.                     if (stNum.length())
  1063.                     {
  1064.                         int index = 0;
  1065.                         str_to_number(index, stNum.c_str());
  1066.                         map_allow_add(index);
  1067.                         stNum.clear();
  1068.                     }
  1069.                 }
  1070.                 else
  1071.                     stNum += *p;
  1072.             }
  1073.  
  1074.             if (stNum.length())
  1075.             {
  1076.                 int index = 0;
  1077.                 str_to_number(index, stNum.c_str());
  1078.                 map_allow_add(index);
  1079.             }
  1080.  
  1081.             continue;
  1082.         }
  1083.  
  1084.         TOKEN("no_wander")
  1085.         {
  1086.             no_wander = true;
  1087.             continue;
  1088.         }
  1089.  
  1090.         TOKEN("user_limit")
  1091.         {
  1092.             str_to_number(g_iUserLimit, value_string);
  1093.             continue;
  1094.         }
  1095.  
  1096.         TOKEN("skill_disable")
  1097.         {
  1098.             str_to_number(g_bSkillDisable, value_string);
  1099.             continue;
  1100.         }
  1101.  
  1102.         TOKEN("auth_server")
  1103.         {
  1104.             char szIP[32];
  1105.             char szPort[32];
  1106.  
  1107.             two_arguments(value_string, szIP, sizeof(szIP), szPort, sizeof(szPort));
  1108.  
  1109.             if (!*szIP || (!*szPort && strcasecmp(szIP, "master")))
  1110.             {
  1111.                 fprintf(stderr, "AUTH_SERVER: syntax error: <ip|master> <port>\n");
  1112.                 exit(1);
  1113.             }
  1114.  
  1115.             g_bAuthServer = true;
  1116.  
  1117.             LoadBanIP("BANIP");
  1118.  
  1119.             if (!strcasecmp(szIP, "master"))
  1120.                 fprintf(stdout, "AUTH_SERVER: I am the master\n");
  1121.             else
  1122.             {
  1123.                 g_stAuthMasterIP = szIP;
  1124.                 str_to_number(g_wAuthMasterPort, szPort);
  1125.  
  1126.                 fprintf(stdout, "AUTH_SERVER: master %s %u\n", g_stAuthMasterIP.c_str(), g_wAuthMasterPort);
  1127.             }
  1128.             continue;
  1129.         }
  1130.  
  1131.         TOKEN("billing")
  1132.         {
  1133.             g_bBilling = true;
  1134.         }
  1135.  
  1136.         TOKEN("quest_dir")
  1137.         {
  1138.             sys_log(0, "QUEST_DIR SETTING : %s", value_string);
  1139.             g_stQuestDir = value_string;
  1140.         }
  1141.  
  1142.         TOKEN("quest_object_dir")
  1143.         {
  1144.             //g_stQuestObjectDir = value_string;
  1145.             std::istringstream is(value_string);
  1146.             sys_log(0, "QUEST_OBJECT_DIR SETTING : %s", value_string);
  1147.             string dir;
  1148.             while (!is.eof())
  1149.             {
  1150.                 is >> dir;
  1151.                 if (is.fail())
  1152.                     break;
  1153.                 g_setQuestObjectDir.insert(dir);
  1154.                 sys_log(0, "QUEST_OBJECT_DIR INSERT : %s", dir .c_str());
  1155.             }
  1156.         }
  1157.  
  1158.         TOKEN("teen_addr")
  1159.         {
  1160.             strlcpy(teen_addr, value_string, sizeof(teen_addr));
  1161.  
  1162.             for (int n =0; n < ADDRESS_MAX_LEN; ++n)
  1163.             {
  1164.                 if (teen_addr[n] == ' ')
  1165.                     teen_addr[n] = '\0';
  1166.             }
  1167.  
  1168.             continue;
  1169.         }
  1170.  
  1171.         TOKEN("teen_port")
  1172.         {
  1173.             str_to_number(teen_port, value_string);
  1174.         }
  1175.  
  1176.         TOKEN("synchack_limit_count")
  1177.         {
  1178.             str_to_number(g_iSyncHackLimitCount, value_string);
  1179.         }
  1180.  
  1181.         TOKEN("speedhack_limit_count")
  1182.         {
  1183.             str_to_number(SPEEDHACK_LIMIT_COUNT, value_string);
  1184.         }
  1185.  
  1186.         TOKEN("speedhack_limit_bonus")
  1187.         {
  1188.             str_to_number(SPEEDHACK_LIMIT_BONUS, value_string);
  1189.         }
  1190.  
  1191.         TOKEN("server_id")
  1192.         {
  1193.             str_to_number(g_server_id, value_string);
  1194.         }
  1195.  
  1196.         TOKEN("mall_url")
  1197.         {
  1198.             g_strWebMallURL = value_string;
  1199.         }
  1200.  
  1201.  
  1202.         TOKEN("view_range")
  1203.         {
  1204.             str_to_number(VIEW_RANGE, value_string);
  1205.         }
  1206.  
  1207.         TOKEN("spam_block_duration")
  1208.         {
  1209.             str_to_number(g_uiSpamBlockDuration, value_string);
  1210.         }
  1211.  
  1212.         TOKEN("spam_block_score")
  1213.         {
  1214.             str_to_number(g_uiSpamBlockScore, value_string);
  1215.             g_uiSpamBlockScore = MAX(1, g_uiSpamBlockScore);
  1216.         }
  1217.  
  1218.         TOKEN("spam_block_reload_cycle")
  1219.         {
  1220.             str_to_number(g_uiSpamReloadCycle, value_string);
  1221.             g_uiSpamReloadCycle = MAX(60, g_uiSpamReloadCycle); // 최소 1분
  1222.         }
  1223.  
  1224.         TOKEN("check_multihack")
  1225.         {
  1226.             str_to_number(g_bCheckMultiHack, value_string);
  1227.         }
  1228.  
  1229.         TOKEN("spam_block_max_level")
  1230.         {
  1231.             str_to_number(g_iSpamBlockMaxLevel, value_string);
  1232.         }
  1233.         TOKEN("protect_normal_player")
  1234.         {
  1235.             str_to_number(g_protectNormalPlayer, value_string);
  1236.         }
  1237.         TOKEN("notice_battle_zone")
  1238.         {
  1239.             str_to_number(g_noticeBattleZone, value_string);
  1240.         }
  1241.  
  1242.         TOKEN("hackshield_enable")
  1243.         {
  1244.             int flag = 0;
  1245.  
  1246.             str_to_number(flag, value_string);
  1247.  
  1248.             //if (1 == flag && LC_IsEurope() )
  1249.             if (1 == flag)
  1250.             {
  1251.                 isHackShieldEnable = true;
  1252.             }
  1253.         }
  1254.  
  1255.         TOKEN("hackshield_first_check_time")
  1256.         {
  1257.             int secs = 30;
  1258.             str_to_number(secs, value_string);
  1259.  
  1260.             HackShield_FirstCheckWaitTime = passes_per_sec * secs;
  1261.         }
  1262.  
  1263.         TOKEN("hackshield_check_cycle_time")
  1264.         {
  1265.             int secs = 180;
  1266.             str_to_number(secs, value_string);
  1267.  
  1268.             HackShield_CheckCycleTime = passes_per_sec * secs;
  1269.         }
  1270.  
  1271.         TOKEN("xtrap_enable")
  1272.         {
  1273.             int flag = 0;
  1274.             str_to_number(flag, value_string);
  1275.  
  1276.             if (1 == flag )
  1277.             {
  1278.                 bXTrapEnabled = true;
  1279.             }
  1280.         }
  1281.  
  1282.         TOKEN("pk_protect_level")
  1283.         {
  1284.             str_to_number(PK_PROTECT_LEVEL, value_string);
  1285.             fprintf(stderr, "PK_PROTECT_LEVEL: %d", PK_PROTECT_LEVEL);
  1286.         }
  1287.  
  1288.         TOKEN("max_level")
  1289.         {
  1290.             str_to_number(gPlayerMaxLevel, value_string);
  1291.  
  1292.             gPlayerMaxLevel = MINMAX(1, gPlayerMaxLevel, PLAYER_MAX_LEVEL_CONST);
  1293.  
  1294.             fprintf(stderr, "PLAYER_MAX_LEVEL: %d\n", gPlayerMaxLevel);
  1295.         }
  1296.  
  1297.         TOKEN("enable_waithack_syslog")
  1298.         {
  1299.             str_to_number(v_syslog_notice, value_string);
  1300.             continue;
  1301.         }
  1302.  
  1303.         TOKEN("enable_waithack_syschat")
  1304.         {
  1305.             str_to_number(v_syschat_notice, value_string);
  1306.             continue;
  1307.         }
  1308.  
  1309.         TOKEN("enable_waithack_ban")
  1310.         {
  1311.             str_to_number(v_ban_waithack, value_string);
  1312.             continue;
  1313.         }
  1314.  
  1315.         TOKEN("block_char_creation")
  1316.         {
  1317.             int tmp = 0;
  1318.  
  1319.             str_to_number(tmp, value_string);
  1320.  
  1321.             if (0 == tmp)
  1322.                 g_BlockCharCreation = false;
  1323.             else
  1324.                 g_BlockCharCreation = true;
  1325.  
  1326.             continue;
  1327.         }
  1328.  
  1329.         TOKEN("server_key")
  1330.         {
  1331.             CheckServer::AddServerKey(value_string);
  1332.             continue;
  1333.         }
  1334.  
  1335.         TOKEN("ENABLE_NEW_WOLFMAN")
  1336.         {
  1337.             str_to_number(g_bEnableNewKingdomForWolfman, value_string);
  1338.             continue;
  1339.         }
  1340.     }
  1341.  
  1342.     if (g_setQuestObjectDir.empty())
  1343.         g_setQuestObjectDir.insert(g_stDefaultQuestObjectDir);
  1344.  
  1345.     if (0 == db_port)
  1346.     {
  1347.         fprintf(stderr, "DB_PORT not configured\n");
  1348.         exit(1);
  1349.     }
  1350.  
  1351.     if (0 == g_bChannel)
  1352.     {
  1353.         fprintf(stderr, "CHANNEL not configured\n");
  1354.         exit(1);
  1355.     }
  1356.  
  1357.     if (g_stHostname.empty())
  1358.     {
  1359.         fprintf(stderr, "HOSTNAME must be configured.\n");
  1360.         exit(1);
  1361.     }
  1362.  
  1363.     // LOCALE_SERVICE
  1364.     LocaleService_LoadLocaleStringFile();
  1365.     LocaleService_TransferDefaultSetting();
  1366.     LocaleService_LoadEmpireTextConvertTables();
  1367.     // END_OF_LOCALE_SERVICE
  1368.  
  1369.     fclose(fp);
  1370.  
  1371.  
  1372.     LoadValidCRCList();
  1373.     LoadStateUserCount();
  1374. #ifdef OFFLINE_SHOP
  1375. LoadShopConfig();
  1376. LoadIndexShopLimit();
  1377. #endif
  1378.     CWarMapManager::instance().LoadWarMapInfo(NULL);
  1379.  
  1380.     FN_log_adminpage();
  1381. }
  1382.  
  1383. const char* get_table_postfix()
  1384. {
  1385.     return g_table_postfix.c_str();
  1386. }
  1387.  
  1388. void LoadValidCRCList()
  1389. {
  1390.     s_set_dwProcessCRC.clear();
  1391.     s_set_dwFileCRC.clear();
  1392.  
  1393.     FILE * fp;
  1394.     char buf[256];
  1395.  
  1396.     if ((fp = fopen("CRC", "r")))
  1397.     {
  1398.         while (fgets(buf, 256, fp))
  1399.         {
  1400.             if (!*buf)
  1401.                 continue;
  1402.  
  1403.             DWORD dwValidClientProcessCRC;
  1404.             DWORD dwValidClientFileCRC;
  1405.  
  1406.             sscanf(buf, " %u %u ", &dwValidClientProcessCRC, &dwValidClientFileCRC);
  1407.  
  1408.             s_set_dwProcessCRC.insert(dwValidClientProcessCRC);
  1409.             s_set_dwFileCRC.insert(dwValidClientFileCRC);
  1410.  
  1411.             fprintf(stderr, "CLIENT_CRC: %u %u\n", dwValidClientProcessCRC, dwValidClientFileCRC);
  1412.         }
  1413.  
  1414.         fclose(fp);
  1415.     }
  1416. }
  1417.  
  1418.  
  1419.  
  1420. void CheckClientVersion()
  1421. {
  1422.     if (LC_IsEurope())
  1423.     {
  1424.         g_bCheckClientVersion = true;
  1425.     }
  1426.     else
  1427.     {
  1428.         g_bCheckClientVersion = false;
  1429.     }
  1430.  
  1431.     const DESC_MANAGER::DESC_SET & set = DESC_MANAGER::instance().GetClientSet();
  1432.     DESC_MANAGER::DESC_SET::const_iterator it = set.begin();
  1433.  
  1434.     while (it != set.end())
  1435.     {
  1436.         LPDESC d = *(it++);
  1437.  
  1438.         if (!d->GetCharacter())
  1439.             continue;
  1440.  
  1441.  
  1442.         int version = atoi(g_stClientVersion.c_str());
  1443.         int date    = atoi(d->GetClientVersion() );
  1444.  
  1445.         //if (0 != g_stClientVersion.compare(d->GetClientVersion()) )
  1446.         if (version != date)
  1447.         {
  1448.             d->GetCharacter()->ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT("클라이언트 버전이 틀려 로그아웃 됩니다. 정상적으로 패치 후 접속하세요."));
  1449.             d->DelayedDisconnect(10);
  1450.         }
  1451.     }
  1452. }
  1453.  
  1454. void LoadStateUserCount()
  1455. {
  1456.     FILE * fp = fopen("state_user_count", "r");
  1457.  
  1458.     if (!fp)
  1459.         return;
  1460.  
  1461.     if (!LC_IsHongKong())
  1462.         fscanf(fp, " %d %d ", &g_iFullUserCount, &g_iBusyUserCount);
  1463.  
  1464.     fclose(fp);
  1465. }
  1466.  
  1467. void LoadClientVersion()
  1468. {
  1469.     FILE * fp = fopen("CLIENT_VERSION", "r");
  1470.  
  1471.     if (!fp)
  1472.         return;
  1473.  
  1474.     int clientVersion = 0;
  1475.     fscanf(fp, " %d", &clientVersion);
  1476.  
  1477.     g_stClientVersion = clientVersion;
  1478.  
  1479.     fclose(fp);
  1480.     sys_log(0, "Reloaded: version %s", g_stClientVersion.c_str());
  1481. }
  1482.  
  1483. bool IsValidProcessCRC(DWORD dwCRC)
  1484. {
  1485.     return s_set_dwProcessCRC.find(dwCRC) != s_set_dwProcessCRC.end();
  1486. }
  1487.  
  1488. bool IsValidFileCRC(DWORD dwCRC)
  1489. {
  1490.     return s_set_dwFileCRC.find(dwCRC) != s_set_dwFileCRC.end();
  1491. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top