Advertisement
Guest User

Untitled

a guest
Feb 10th, 2016
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 30.29 KB | None | 0 0
  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.  
  26. BYTE    g_bChannel = 0;
  27. WORD    mother_port = 50080;
  28. int     passes_per_sec = 25;
  29. WORD    db_port = 0;
  30. WORD    p2p_port = 50900;
  31. char    db_addr[ADDRESS_MAX_LEN + 1];
  32. int     save_event_second_cycle = passes_per_sec * 120; // 3şĐ
  33. int     ping_event_second_cycle = passes_per_sec * 60;
  34. bool    g_bNoMoreClient = false;
  35. bool    g_bNoRegen = false;
  36. bool    g_bNoPasspod = false;
  37.  
  38. // TRAFFIC_PROFILER
  39. bool        g_bTrafficProfileOn = false;
  40. DWORD       g_dwTrafficProfileFlushCycle = 3600;
  41. // END_OF_TRAFFIC_PROFILER
  42.  
  43. int         test_server = 0;
  44. int         speed_server = 0;
  45. #ifdef __AUCTION__
  46. int         auction_server = 0;
  47. #endif
  48. bool        distribution_test_server = false;
  49. bool        china_event_server = false;
  50. bool        guild_mark_server = true;
  51. BYTE        guild_mark_min_level = 3;
  52. bool        no_wander = false;
  53. int     g_iUserLimit = 32768;
  54.  
  55. char        g_szPublicIP[16] = "0";
  56. char        g_szInternalIP[16] = "0";
  57. bool        g_bSkillDisable = false;
  58. int         g_iFullUserCount = 1200;
  59. int         g_iBusyUserCount = 650;
  60. //Canada
  61. //int           g_iFullUserCount = 600;
  62. //int           g_iBusyUserCount = 350;
  63. //Brazil
  64. //int           g_iFullUserCount = 650;
  65. //int           g_iBusyUserCount = 450;
  66. bool        g_bEmpireWhisper = true;
  67. BYTE        g_bAuthServer = false;
  68.  
  69. bool        g_bCheckClientVersion = true;
  70. string  g_stClientVersion = "1215955205";
  71. long long   g_llMaxGold = 2140000000;
  72.  
  73. BYTE        g_bBilling = false;
  74.  
  75. string  g_stAuthMasterIP;
  76. WORD        g_wAuthMasterPort = 0;
  77.  
  78. static std::set<DWORD> s_set_dwFileCRC;
  79. static std::set<DWORD> s_set_dwProcessCRC;
  80.  
  81. string g_stHostname = "";
  82. string g_table_postfix = "";
  83.  
  84. string g_stQuestDir = "./quest";
  85. //string g_stQuestObjectDir = "./quest/object";
  86. string g_stDefaultQuestObjectDir = "./quest/object";
  87. std::set<string> g_setQuestObjectDir;
  88.  
  89. std::vector<std::string>    g_stAdminPageIP;
  90. std::string g_stAdminPagePassword = "SHOWMETHEMONEY";
  91.  
  92. string g_stBlockDate = "30000705";
  93.  
  94. extern string g_stLocale;
  95.  
  96. char    teen_addr[ADDRESS_MAX_LEN + 1] = {0};
  97. WORD    teen_port   = 0;
  98.  
  99. int SPEEDHACK_LIMIT_COUNT   = 50;
  100. int SPEEDHACK_LIMIT_BONUS   = 80;
  101. int g_iSyncHackLimitCount = 10;
  102.  
  103. //˝Ăľß = VIEW_RANGE + VIEW_BONUS_RANGE
  104. //VIEW_BONUSE_RANGE : Ŭ¶óŔĚľđĆ®żÍ ˝Ăľß Ăł¸®żˇĽ­łĘą« µü ¶łľîÁú°ćżě ą®Á¦°ˇ ąß»ýÇŇĽöŔÖľî 500CMŔÇ ż©şĐŔ» Ç×»óÁŘ´Ů.
  105. int VIEW_RANGE = 5000;
  106. int VIEW_BONUS_RANGE = 500;
  107.  
  108. int g_server_id = 0;
  109. string g_strWebMallURL = "www.metin2.de";
  110.  
  111. unsigned int g_uiSpamBlockDuration = 60 * 15; // ±âş» 15şĐ
  112. unsigned int g_uiSpamBlockScore = 100; // ±âş» 100Áˇ
  113. unsigned int g_uiSpamReloadCycle = 60 * 10; // ±âş» 10şĐ
  114.  
  115. bool        g_bCheckMultiHack = true;
  116.  
  117. int         g_iSpamBlockMaxLevel = 10;
  118.  
  119. void        LoadStateUserCount();
  120. void        LoadValidCRCList();
  121. bool        LoadClientVersion();
  122. bool            g_protectNormalPlayer   = false;        // ąüąýŔÚ°ˇ "ĆňČ­¸đµĺ" ŔÎ ŔĎąÝŔŻŔú¸¦ °ř°ÝÇĎÁö ¸řÇÔ
  123. bool            g_noticeBattleZone      = false;        // Á߸łÁö´ëżˇ ŔÔŔĺÇĎ¸é ľČł»¸ŢĽĽÁö¸¦ ľË·ÁÁÜ
  124.  
  125. bool        isHackShieldEnable = false;
  126. int         HackShield_FirstCheckWaitTime = passes_per_sec * 30;
  127. int         HackShield_CheckCycleTime = passes_per_sec * 180;
  128.  
  129. bool        bXTrapEnabled = false;
  130.  
  131. int gPlayerMaxLevel = 99;
  132.  
  133. int stone_chance = 30;
  134.  
  135. bool g_BlockCharCreation = false;
  136.  
  137.  
  138. //OPENID
  139. int     openid_server = 0;
  140. char    openid_host[256];
  141. char    openid_uri[256];
  142.  
  143. bool is_string_true(const char * string)
  144. {
  145.     bool    result = 0;
  146.     if (isnhdigit(*string))
  147.     {
  148.         str_to_number(result, string);
  149.         return result > 0 ? true : false;
  150.     }
  151.     else if (LOWER(*string) == 't')
  152.         return true;
  153.     else
  154.         return false;
  155. }
  156.  
  157. static std::set<int> s_set_map_allows;
  158.  
  159. bool map_allow_find(int index)
  160. {
  161.     if (g_bAuthServer)
  162.         return false;
  163.  
  164.     if (s_set_map_allows.find(index) == s_set_map_allows.end())
  165.         return false;
  166.  
  167.     return true;
  168. }
  169.  
  170. void map_allow_log()
  171. {
  172.     std::set<int>::iterator i;
  173.  
  174.     for (i = s_set_map_allows.begin(); i != s_set_map_allows.end(); ++i)
  175.         sys_log(0, "MAP_ALLOW: %d", *i);
  176. }
  177.  
  178. void map_allow_add(int index)
  179. {
  180.     if (map_allow_find(index) == true)
  181.     {
  182.         fprintf(stdout, "!!! FATAL ERROR !!! multiple MAP_ALLOW setting!!\n");
  183.         exit(1);
  184.     }
  185.  
  186.     fprintf(stdout, "MAP ALLOW %d\n", index);
  187.     s_set_map_allows.insert(index);
  188. }
  189.  
  190. void map_allow_copy(long * pl, int size)
  191. {
  192.     int iCount = 0;
  193.     std::set<int>::iterator it = s_set_map_allows.begin();
  194.  
  195.     while (it != s_set_map_allows.end())
  196.     {
  197.         int i = *(it++);
  198.         *(pl++) = i;
  199.  
  200.         if (++iCount > size)
  201.             break;
  202.     }
  203. }
  204.  
  205. static void FN_add_adminpageIP(char *line)
  206. {
  207.     char    *last;
  208.     const char *delim = " \t\r\n";
  209.     char *v = strtok_r(line, delim, &last);
  210.  
  211.     while (v)
  212.     {
  213.         g_stAdminPageIP.push_back(v);
  214.         v = strtok_r(NULL, delim, &last);
  215.     }
  216. }
  217.  
  218. static void FN_log_adminpage()
  219. {
  220.     itertype(g_stAdminPageIP) iter = g_stAdminPageIP.begin();
  221.  
  222.     while (iter != g_stAdminPageIP.end())
  223.     {
  224.         dev_log(LOG_DEB0, "ADMIN_PAGE_IP = %s", (*iter).c_str());
  225.         ++iter;
  226.     }
  227.  
  228.     dev_log(LOG_DEB0, "ADMIN_PAGE_PASSWORD = %s", g_stAdminPagePassword.c_str());
  229. }
  230.  
  231.  
  232. bool GetIPInfo()
  233. {
  234. #ifndef __WIN32__
  235.     struct ifaddrs* ifaddrp = NULL;
  236.  
  237.     if (0 != getifaddrs(&ifaddrp))
  238.         return false;
  239.  
  240.     for( struct ifaddrs* ifap=ifaddrp ; NULL != ifap ; ifap = ifap->ifa_next )
  241.     {
  242.         struct sockaddr_in * sai = (struct sockaddr_in *) ifap->ifa_addr;
  243.  
  244.         if (!ifap->ifa_netmask ||  // ignore if no netmask
  245.                 sai->sin_addr.s_addr == 0 || // ignore if address is 0.0.0.0
  246.                 sai->sin_addr.s_addr == 16777343) // ignore if address is 127.0.0.1
  247.             continue;
  248. #else
  249.     WSADATA wsa_data;
  250.     char host_name[100];
  251.     HOSTENT* host_ent;
  252.     int n = 0;
  253.  
  254.     if (WSAStartup(0x0101, &wsa_data)) {
  255.         return false;
  256.     }
  257.  
  258.     gethostname(host_name, sizeof(host_name));
  259.     host_ent = gethostbyname(host_name);
  260.     if (host_ent == NULL) {
  261.         return false;
  262.     }
  263.     for ( ; host_ent->h_addr_list[n] != NULL; ++n) {
  264.         struct sockaddr_in addr;
  265.         struct sockaddr_in* sai = &addr;
  266.         memcpy(&sai->sin_addr.s_addr, host_ent->h_addr_list[n], host_ent->h_length);
  267. #endif
  268.  
  269.         char * netip = inet_ntoa(sai->sin_addr);
  270.  
  271.         if (!strncmp(netip, "000.000", 7)) // ignore if address is starting with 192
  272.         {
  273.             strlcpy(g_szInternalIP, netip, sizeof(g_szInternalIP));
  274. #ifndef __WIN32__
  275.             fprintf(stderr, "INTERNAL_IP: %s interface %s\n", netip, ifap->ifa_name);
  276. #else
  277.             fprintf(stderr, "INTERNAL_IP: %s\n", netip);
  278. #endif
  279.         }
  280.         else if (!strncmp(netip, "10.", 3))
  281.         {
  282.             strlcpy(g_szInternalIP, netip, sizeof(g_szInternalIP));
  283. #ifndef __WIN32__
  284.             fprintf(stderr, "INTERNAL_IP: %s interface %s\n", netip, ifap->ifa_name);
  285. #else
  286.             fprintf(stderr, "INTERNAL_IP: %s\n", netip);
  287. #endif
  288.         }
  289.         else if (g_szPublicIP[0] == '0')
  290.         {
  291.             strlcpy(g_szPublicIP, netip, sizeof(g_szPublicIP));
  292. #ifndef __WIN32__
  293.             fprintf(stderr, "PUBLIC_IP: %s interface %s\n", netip, ifap->ifa_name);
  294. #else
  295.             fprintf(stderr, "PUBLIC_IP: %s\n", netip);
  296. #endif
  297.         }
  298.     }
  299.  
  300. #ifndef __WIN32__
  301.     freeifaddrs( ifaddrp );
  302. #else
  303.     WSACleanup();
  304. #endif
  305.  
  306.     if (g_szPublicIP[0] != '0')
  307.         return true;
  308.     else
  309.         return false;
  310. }
  311.  
  312. void config_init(const string& st_localeServiceName)
  313. {
  314.     FILE    *fp;
  315.  
  316.     char    buf[256];
  317.     char    token_string[256];
  318.     char    value_string[256];
  319.  
  320.     // LOCALE_SERVICE
  321.     string  st_configFileName;
  322.  
  323.     st_configFileName.reserve(32);
  324.     st_configFileName = "CONFIG";
  325.  
  326.     if (!st_localeServiceName.empty())
  327.     {
  328.         st_configFileName += ".";
  329.         st_configFileName += st_localeServiceName;
  330.     }
  331.     // END_OF_LOCALE_SERVICE
  332.  
  333.     if (!(fp = fopen(st_configFileName.c_str(), "r")))
  334.     {
  335.         fprintf(stderr, "Can not open [%s]\n", st_configFileName.c_str());
  336.         exit(1);
  337.     }
  338.  
  339.     if (!GetIPInfo())
  340.     {
  341.         fprintf(stderr, "Can not get public ip address\n");
  342.         exit(1);
  343.     }
  344.  
  345.     char db_host[2][64], db_user[2][64], db_pwd[2][64], db_db[2][64];
  346.     // ... ľĆ... db_port´Â ŔĚąĚ ŔִµĄ... ł×ŔĚąÖ ľîÂîÇŘľßÇÔ...
  347.     int mysql_db_port[2];
  348.  
  349.     for (int n = 0; n < 2; ++n)
  350.     {
  351.         *db_host[n] = '\0';
  352.         *db_user[n] = '\0';
  353.         *db_pwd[n]= '\0';
  354.         *db_db[n]= '\0';
  355.         mysql_db_port[n] = 0;
  356.     }
  357.  
  358.     char log_host[64], log_user[64], log_pwd[64], log_db[64];
  359.     int log_port = 0;
  360.  
  361.     *log_host = '\0';
  362.     *log_user = '\0';
  363.     *log_pwd = '\0';
  364.     *log_db = '\0';
  365.  
  366.  
  367.     // DBżˇĽ­ ·ÎÄÉŔĎÁ¤ş¸¸¦ ĽĽĆĂÇϱâŔ§ÇŘĽ­´Â ´Ů¸Ą ĽĽĆĂ°Şş¸´Ů Ľ±ÇŕµÇľîĽ­
  368.     // DBÁ¤ş¸¸¸ ŔĐľîżÍ ·ÎÄÉŔĎ ĽĽĆĂŔ» ÇŃČÄ ´Ů¸Ą ĽĽĆĂŔ» Ŕűżë˝ĂÄŃľßÇŃ´Ů.
  369.     // ŔĚŔŻ´Â ·ÎÄÉŔĎ°ü·ĂµČ ĂʱâČ­ ·çĆľŔĚ °÷°÷żˇ Á¸ŔçÇϱ⠶§ą®.
  370.  
  371.     bool isCommonSQL = false;  
  372.     bool isPlayerSQL = false;
  373.  
  374.     FILE* fpOnlyForDB;
  375.  
  376.     if (!(fpOnlyForDB = fopen(st_configFileName.c_str(), "r")))
  377.     {
  378.         fprintf(stderr, "Can not open [%s]\n", st_configFileName.c_str());
  379.         exit(1);
  380.     }
  381.  
  382.     while (fgets(buf, 256, fpOnlyForDB))
  383.     {
  384.         parse_token(buf, token_string, value_string);
  385.  
  386.         TOKEN("BLOCK_LOGIN")
  387.         {
  388.             g_stBlockDate = value_string;
  389.         }
  390.  
  391.         TOKEN("adminpage_ip")
  392.         {
  393.             FN_add_adminpageIP(value_string);
  394.             //g_stAdminPageIP[0] = value_string;
  395.         }
  396.  
  397.         TOKEN("adminpage_ip1")
  398.         {
  399.             FN_add_adminpageIP(value_string);
  400.             //g_stAdminPageIP[0] = value_string;
  401.         }
  402.  
  403.         TOKEN("adminpage_ip2")
  404.         {
  405.             FN_add_adminpageIP(value_string);
  406.             //g_stAdminPageIP[1] = value_string;
  407.         }
  408.  
  409.         TOKEN("adminpage_ip3")
  410.         {
  411.             FN_add_adminpageIP(value_string);
  412.             //g_stAdminPageIP[2] = value_string;
  413.         }
  414.  
  415.         TOKEN("adminpage_password")
  416.         {
  417.             g_stAdminPagePassword = value_string;
  418.         }
  419.  
  420.         TOKEN("hostname")
  421.         {
  422.             g_stHostname = value_string;
  423.             fprintf(stdout, "HOSTNAME: %s\n", g_stHostname.c_str());
  424.             continue;
  425.         }
  426.  
  427.         TOKEN("channel")
  428.         {
  429.             str_to_number(g_bChannel, value_string);
  430.             continue;
  431.         }
  432.  
  433.         TOKEN("player_sql")
  434.         {
  435.             const char * line = two_arguments(value_string, db_host[0], sizeof(db_host[0]), db_user[0], sizeof(db_user[0]));
  436.             line = two_arguments(line, db_pwd[0], sizeof(db_pwd[0]), db_db[0], sizeof(db_db[0]));
  437.  
  438.             if (NULL != line[0])
  439.             {
  440.                 char buf[256];
  441.                 one_argument(line, buf, sizeof(buf));
  442.                 str_to_number(mysql_db_port[0], buf);
  443.             }
  444.  
  445.             if (!*db_host[0] || !*db_user[0] || !*db_pwd[0] || !*db_db[0])
  446.             {
  447.                 fprintf(stderr, "PLAYER_SQL syntax: logsql <host user password db>\n");
  448.                 exit(1);
  449.             }
  450.  
  451.             char buf[1024];
  452.             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]);
  453.             isPlayerSQL = true;
  454.             continue;
  455.         }
  456.  
  457.         TOKEN("common_sql")
  458.         {
  459.             const char * line = two_arguments(value_string, db_host[1], sizeof(db_host[1]), db_user[1], sizeof(db_user[1]));
  460.             line = two_arguments(line, db_pwd[1], sizeof(db_pwd[1]), db_db[1], sizeof(db_db[1]));
  461.  
  462.             if (NULL != line[0])
  463.             {
  464.                 char buf[256];
  465.                 one_argument(line, buf, sizeof(buf));
  466.                 str_to_number(mysql_db_port[1], buf);
  467.             }
  468.  
  469.             if (!*db_host[1] || !*db_user[1] || !*db_pwd[1] || !*db_db[1])
  470.             {
  471.                 fprintf(stderr, "COMMON_SQL syntax: logsql <host user password db>\n");
  472.                 exit(1);
  473.             }
  474.  
  475.             char buf[1024];
  476.             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]);
  477.             isCommonSQL = true;
  478.             continue;
  479.         }
  480.  
  481.         TOKEN("log_sql")
  482.         {
  483.             const char * line = two_arguments(value_string, log_host, sizeof(log_host), log_user, sizeof(log_user));
  484.             line = two_arguments(line, log_pwd, sizeof(log_pwd), log_db, sizeof(log_db));
  485.  
  486.             if (NULL != line[0])
  487.             {
  488.                 char buf[256];
  489.                 one_argument(line, buf, sizeof(buf));
  490.                 str_to_number(log_port, buf);
  491.             }
  492.  
  493.             if (!*log_host || !*log_user || !*log_pwd || !*log_db)
  494.             {
  495.                 fprintf(stderr, "LOG_SQL syntax: logsql <host user password db>\n");
  496.                 exit(1);
  497.             }
  498.  
  499.             char buf[1024];
  500.             snprintf(buf, sizeof(buf), "LOG_SQL: %s %s %s %s %d", log_host, log_user, log_pwd, log_db, log_port);
  501.             continue;
  502.         }
  503.  
  504.        
  505.         //OPENID       
  506.         TOKEN("WEB_AUTH")
  507.         {
  508.             const char * line = two_arguments(value_string, openid_host, sizeof(openid_host), openid_uri, sizeof(openid_uri));
  509.  
  510.             if (!*openid_host || !*openid_uri)
  511.             {
  512.                 fprintf(stderr, "WEB_AUTH syntax error (ex: WEB_AUTH <host(metin2.co.kr) uri(/kyw/gameauth.php)>\n");
  513.                 exit(1);
  514.             }
  515.  
  516.             char buf[1024];
  517.             openid_server = 1;
  518.             snprintf(buf, sizeof(buf), "WEB_AUTH: %s %s", openid_host, openid_uri);
  519.             continue;
  520.         }
  521.     }
  522.  
  523.     //Ăł¸®°ˇ łˇłµŔ¸´Ď ĆÄŔĎŔ» ´ÝŔÚ.
  524.     fclose(fpOnlyForDB);
  525.  
  526.     // CONFIG_SQL_INFO_ERROR
  527.     if (!isCommonSQL)
  528.     {
  529.         puts("LOAD_COMMON_SQL_INFO_FAILURE:");
  530.         puts("");
  531.         puts("CONFIG:");
  532.         puts("------------------------------------------------");
  533.         puts("COMMON_SQL: HOST USER PASSWORD DATABASE");
  534.         puts("");
  535.         exit(1);
  536.     }
  537.  
  538.     if (!isPlayerSQL)
  539.     {
  540.         puts("LOAD_PLAYER_SQL_INFO_FAILURE:");
  541.         puts("");
  542.         puts("CONFIG:");
  543.         puts("------------------------------------------------");
  544.         puts("PLAYER_SQL: HOST USER PASSWORD DATABASE");
  545.         puts("");
  546.         exit(1);
  547.     }
  548.  
  549.     // Common DB °ˇ Locale Á¤ş¸¸¦ °ˇÁö°í Ŕֱ⠶§ą®żˇ °ˇŔĺ ¸ŐŔú Á˘ĽÓÇŘľß ÇŃ´Ů.
  550.     AccountDB::instance().Connect(db_host[1], mysql_db_port[1], db_user[1], db_pwd[1], db_db[1]);
  551.  
  552.     if (false == AccountDB::instance().IsConnected())
  553.     {
  554.         fprintf(stderr, "cannot start server while no common sql connected\n");
  555.         exit(1);
  556.     }
  557.  
  558.     fprintf(stdout, "CommonSQL connected\n");
  559.  
  560.     // ·ÎÄÉŔĎ Á¤ş¸¸¦ °ˇÁ®żŔŔÚ
  561.     // <°ć°í> Äő¸®ą®żˇ Ŕý´ë Á¶°Çą®(WHERE) ´ŢÁö ¸¶ĽĽżä. (´Ů¸Ą ÁöżŞżˇĽ­ ą®Á¦°ˇ »ý±ćĽö ŔÖ˝Ŕ´Ď´Ů)
  562.     {
  563.         char szQuery[512];
  564.         snprintf(szQuery, sizeof(szQuery), "SELECT mKey, mValue FROM locale");
  565.  
  566.         std::auto_ptr<SQLMsg> pMsg(AccountDB::instance().DirectQuery(szQuery));
  567.  
  568.         if (pMsg->Get()->uiNumRows == 0)
  569.         {
  570.             fprintf(stderr, "COMMON_SQL: DirectQuery failed : %s\n", szQuery);
  571.             exit(1);
  572.         }
  573.  
  574.         MYSQL_ROW row;
  575.  
  576.         while (NULL != (row = mysql_fetch_row(pMsg->Get()->pSQLResult)))
  577.         {
  578.             // ·ÎÄÉŔĎ ĽĽĆĂ
  579.             if (strcasecmp(row[0], "LOCALE") == 0)
  580.             {
  581.                 if (LocaleService_Init(row[1]) == false)
  582.                 {
  583.                     fprintf(stderr, "COMMON_SQL: invalid locale key %s\n", row[1]);
  584.                     exit(1);
  585.                 }
  586.             }
  587.         }
  588.     }
  589.  
  590.     // ·ÎÄÉŔĎ Á¤ş¸¸¦ COMMON SQLżˇ ĽĽĆĂÇŘÁŘ´Ů.
  591.     // Âü°í·Î g_stLocale Á¤ş¸´Â LocaleService_Init() ł»şÎżˇĽ­ ĽĽĆõȴŮ.
  592.     fprintf(stdout, "Setting DB to locale %s\n", g_stLocale.c_str());
  593.  
  594.     AccountDB::instance().SetLocale(g_stLocale);
  595.  
  596.     AccountDB::instance().ConnectAsync(db_host[1], mysql_db_port[1], db_user[1], db_pwd[1], db_db[1], g_stLocale.c_str());
  597.  
  598.     // Player DB Á˘ĽÓ
  599.     DBManager::instance().Connect(db_host[0], mysql_db_port[0], db_user[0], db_pwd[0], db_db[0]);
  600.  
  601.     if (!DBManager::instance().IsConnected())
  602.     {
  603.         fprintf(stderr, "PlayerSQL.ConnectError\n");
  604.         exit(1);
  605.     }
  606.  
  607.     fprintf(stdout, "PlayerSQL connected\n");
  608.  
  609.     if (false == g_bAuthServer) // ŔÎÁő Ľ­ąö°ˇ ľĆ´Ň °ćżě
  610.     {
  611.         // Log DB Á˘ĽÓ
  612.         LogManager::instance().Connect(log_host, log_port, log_user, log_pwd, log_db);
  613.  
  614.         if (!LogManager::instance().IsConnected())
  615.         {
  616.             fprintf(stderr, "LogSQL.ConnectError\n");
  617.             exit(1);
  618.         }
  619.  
  620.         fprintf(stdout, "LogSQL connected\n");
  621.  
  622.         LogManager::instance().BootLog(g_stHostname.c_str(), g_bChannel);
  623.     }
  624.  
  625.     // SKILL_POWER_BY_LEVEL
  626.     // ˝şĆ®¸µ şń±łŔÇ ą®Á¦·Î ŔÎÇŘĽ­ AccountDB::instance().SetLocale(g_stLocale) ČÄşÎĹÍ ÇŃ´Ů.
  627.     // ą°·Đ ±ął»´Â ş°·Î ą®Á¦°ˇ ľČµČ´Ů(Çؿܰˇ ą®Á¦)
  628.     {
  629.         char szQuery[256];
  630.         snprintf(szQuery, sizeof(szQuery), "SELECT mValue FROM locale WHERE mKey='SKILL_POWER_BY_LEVEL'");
  631.         std::auto_ptr<SQLMsg> pMsg(AccountDB::instance().DirectQuery(szQuery));
  632.  
  633.         if (pMsg->Get()->uiNumRows == 0)
  634.         {
  635.             fprintf(stderr, "[SKILL_PERCENT] Query failed: %s", szQuery);
  636.             exit(1);
  637.         }
  638.  
  639.         MYSQL_ROW row;
  640.  
  641.         row = mysql_fetch_row(pMsg->Get()->pSQLResult);
  642.  
  643.         const char * p = row[0];
  644.         int cnt = 0;
  645.         char num[128];
  646.         int aiBaseSkillPowerByLevelTable[SKILL_MAX_LEVEL+1];
  647.  
  648.         fprintf(stdout, "SKILL_POWER_BY_LEVEL %s\n", p);
  649.         while (*p != '\0' && cnt < (SKILL_MAX_LEVEL + 1))
  650.         {
  651.             p = one_argument(p, num, sizeof(num));
  652.             aiBaseSkillPowerByLevelTable[cnt++] = atoi(num);
  653.  
  654.             //fprintf(stdout, "%d %d\n", cnt - 1, aiBaseSkillPowerByLevelTable[cnt - 1]);
  655.             if (*p == '\0')
  656.             {
  657.                 if (cnt != (SKILL_MAX_LEVEL + 1))
  658.                 {
  659.                     fprintf(stderr, "[SKILL_PERCENT] locale table has not enough skill information! (count: %d query: %s)", cnt, szQuery);
  660.                     exit(1);
  661.                 }
  662.  
  663.                 fprintf(stdout, "SKILL_POWER_BY_LEVEL: Done! (count %d)\n", cnt);
  664.                 break;
  665.             }
  666.         }
  667.  
  668.         // ÁľÁ·ş° ˝şĹł ĽĽĆĂ
  669.         for (int job = 0; job < JOB_MAX_NUM * 2; ++job)
  670.         {
  671.             snprintf(szQuery, sizeof(szQuery), "SELECT mValue from locale where mKey='SKILL_POWER_BY_LEVEL_TYPE%d' ORDER BY CAST(mValue AS unsigned)", job);
  672.             std::auto_ptr<SQLMsg> pMsg(AccountDB::instance().DirectQuery(szQuery));
  673.  
  674.             // ĽĽĆĂŔĚ ľČµÇľîŔÖŔ¸¸é ±âş»Ĺ×ŔĚşíŔ» »çżëÇŃ´Ů.
  675.             if (pMsg->Get()->uiNumRows == 0)
  676.             {
  677.                 CTableBySkill::instance().SetSkillPowerByLevelFromType(job, aiBaseSkillPowerByLevelTable);
  678.                 continue;
  679.             }
  680.  
  681.             row = mysql_fetch_row(pMsg->Get()->pSQLResult);
  682.             cnt = 0;
  683.             p = row[0];
  684.             int aiSkillTable[SKILL_MAX_LEVEL + 1];
  685.  
  686.             fprintf(stdout, "SKILL_POWER_BY_JOB %d %s\n", job, p);
  687.             while (*p != '\0' && cnt < (SKILL_MAX_LEVEL + 1))
  688.             {          
  689.                 p = one_argument(p, num, sizeof(num));
  690.                 aiSkillTable[cnt++] = atoi(num);
  691.  
  692.                 //fprintf(stdout, "%d %d\n", cnt - 1, aiBaseSkillPowerByLevelTable[cnt - 1]);
  693.                 if (*p == '\0')
  694.                 {
  695.                     if (cnt != (SKILL_MAX_LEVEL + 1))
  696.                     {
  697.                         fprintf(stderr, "[SKILL_PERCENT] locale table has not enough skill information! (count: %d query: %s)", cnt, szQuery);
  698.                         exit(1);
  699.                     }
  700.  
  701.                     fprintf(stdout, "SKILL_POWER_BY_JOB: Done! (job: %d count: %d)\n", job, cnt);
  702.                     break;
  703.                 }
  704.             }
  705.  
  706.             CTableBySkill::instance().SetSkillPowerByLevelFromType(job, aiSkillTable);
  707.         }      
  708.     }
  709.     // END_SKILL_POWER_BY_LEVEL
  710.  
  711.     // LOG_KEEP_DAYS_EXTEND
  712.     log_set_expiration_days(2);
  713.     // END_OF_LOG_KEEP_DAYS_EXTEND
  714.     }
  715.  
  716.     while (fgets(buf, 256, fp))
  717.     {
  718.         parse_token(buf, token_string, value_string);
  719.  
  720.        
  721.  
  722.         TOKEN("empire_whisper")
  723.         {
  724.             bool b_value = 0;
  725.             str_to_number(b_value, value_string);
  726.             g_bEmpireWhisper = !!b_value;
  727.             continue;
  728.         }
  729.  
  730.         TOKEN("mark_server")
  731.         {
  732.             guild_mark_server = is_string_true(value_string);
  733.             continue;
  734.         }
  735.  
  736.         TOKEN("mark_min_level")
  737.         {
  738.             str_to_number(guild_mark_min_level, value_string);
  739.             guild_mark_min_level = MINMAX(0, guild_mark_min_level, GUILD_MAX_LEVEL);
  740.             continue;
  741.         }
  742.  
  743.         TOKEN("port")
  744.         {
  745.             str_to_number(mother_port, value_string);
  746.             continue;
  747.         }
  748.  
  749.         TOKEN("log_keep_days")
  750.         {
  751.             int i = 0;
  752.             str_to_number(i, value_string);
  753.             log_set_expiration_days(MINMAX(1, i, 90));
  754.             continue;
  755.         }
  756.  
  757.         TOKEN("passes_per_sec")
  758.         {
  759.             str_to_number(passes_per_sec, value_string);
  760.             continue;
  761.         }
  762.  
  763.         TOKEN("p2p_port")
  764.         {
  765.             str_to_number(p2p_port, value_string);
  766.             continue;
  767.         }
  768.  
  769.         TOKEN("db_port")
  770.         {
  771.             str_to_number(db_port, value_string);
  772.             continue;
  773.         }
  774.  
  775.         TOKEN("db_addr")
  776.         {
  777.             strlcpy(db_addr, value_string, sizeof(db_addr));
  778.  
  779.             for (int n =0; n < ADDRESS_MAX_LEN; ++n)
  780.             {
  781.                 if (db_addr[n] == ' ')
  782.                     db_addr[n] = '\0';
  783.             }
  784.  
  785.             continue;
  786.         }
  787.  
  788.         TOKEN("save_event_second_cycle")
  789.         {
  790.             int cycle = 0;
  791.             str_to_number(cycle, value_string);
  792.             save_event_second_cycle = cycle * passes_per_sec;
  793.             continue;
  794.         }
  795.  
  796.         TOKEN("ping_event_second_cycle")
  797.         {
  798.             int cycle = 0;
  799.             str_to_number(cycle, value_string);
  800.             ping_event_second_cycle = cycle * passes_per_sec;
  801.             continue;
  802.         }
  803.  
  804.         TOKEN("table_postfix")
  805.         {
  806.             g_table_postfix = value_string;
  807.             continue;
  808.         }
  809.  
  810.         TOKEN("test_server")
  811.         {
  812.             printf("-----------------------------------------------\n");
  813.             printf("TEST_SERVER\n");
  814.             printf("-----------------------------------------------\n");
  815.             str_to_number(test_server, value_string);
  816.             continue;
  817.         }
  818.  
  819.         TOKEN("speed_server")
  820.         {
  821.             printf("-----------------------------------------------\n");
  822.             printf("SPEED_SERVER\n");
  823.             printf("-----------------------------------------------\n");
  824.             str_to_number(speed_server, value_string);
  825.             continue;
  826.         }
  827. #ifdef __AUCTION__
  828.         TOKEN("auction_server")
  829.         {
  830.             printf("-----------------------------------------------\n");
  831.             printf("AUCTION_SERVER\n");
  832.             printf("-----------------------------------------------\n");
  833.             str_to_number(auction_server, value_string);
  834.             continue;
  835.         }
  836. #endif
  837.         TOKEN("distribution_test_server")
  838.         {
  839.             str_to_number(distribution_test_server, value_string);
  840.             continue;
  841.         }
  842.  
  843.         TOKEN("china_event_server")
  844.         {
  845.             str_to_number(china_event_server, value_string);
  846.             continue;
  847.         }
  848.  
  849.         TOKEN("shutdowned")
  850.         {
  851.             g_bNoMoreClient = true;
  852.             continue;
  853.         }
  854.  
  855.         TOKEN("no_regen")
  856.         {
  857.             g_bNoRegen = true;
  858.             continue;
  859.         }
  860.  
  861.         TOKEN("traffic_profile")
  862.         {
  863.             g_bTrafficProfileOn = true;
  864.             continue;
  865.         }
  866.  
  867.  
  868.         TOKEN("map_allow")
  869.         {
  870.             char * p = value_string;
  871.             string stNum;
  872.  
  873.             for (; *p; p++)
  874.             {  
  875.                 if (isnhspace(*p))
  876.                 {
  877.                     if (stNum.length())
  878.                     {
  879.                         int index = 0;
  880.                         str_to_number(index, stNum.c_str());
  881.                         map_allow_add(index);
  882.                         stNum.clear();
  883.                     }
  884.                 }
  885.                 else
  886.                     stNum += *p;
  887.             }
  888.  
  889.             if (stNum.length())
  890.             {
  891.                 int index = 0;
  892.                 str_to_number(index, stNum.c_str());
  893.                 map_allow_add(index);
  894.             }
  895.  
  896.             continue;
  897.         }
  898.  
  899.         TOKEN("no_wander")
  900.         {
  901.             no_wander = true;
  902.             continue;
  903.         }
  904.  
  905.         TOKEN("user_limit")
  906.         {
  907.             str_to_number(g_iUserLimit, value_string);
  908.             continue;
  909.         }
  910.  
  911.         TOKEN("skill_disable")
  912.         {
  913.             str_to_number(g_bSkillDisable, value_string);
  914.             continue;
  915.         }
  916.  
  917.         TOKEN("auth_server")
  918.         {
  919.             char szIP[32];
  920.             char szPort[32];
  921.  
  922.             two_arguments(value_string, szIP, sizeof(szIP), szPort, sizeof(szPort));
  923.  
  924.             if (!*szIP || (!*szPort && strcasecmp(szIP, "master")))
  925.             {
  926.                 fprintf(stderr, "AUTH_SERVER: syntax error: <ip|master> <port>\n");
  927.                 exit(1);
  928.             }
  929.  
  930.             g_bAuthServer = true;
  931.  
  932.             LoadBanIP("BANIP");
  933.  
  934.             if (!strcasecmp(szIP, "master"))
  935.                 fprintf(stdout, "AUTH_SERVER: I am the master\n");
  936.             else
  937.             {
  938.                 g_stAuthMasterIP = szIP;
  939.                 str_to_number(g_wAuthMasterPort, szPort);
  940.  
  941.                 fprintf(stdout, "AUTH_SERVER: master %s %u\n", g_stAuthMasterIP.c_str(), g_wAuthMasterPort);
  942.             }
  943.             continue;
  944.         }
  945.  
  946.         TOKEN("billing")
  947.         {
  948.             g_bBilling = true;
  949.         }
  950.  
  951.         TOKEN("quest_dir")
  952.         {
  953.             sys_log(0, "QUEST_DIR SETTING : %s", value_string);
  954.             g_stQuestDir = value_string;
  955.         }
  956.  
  957.         TOKEN("quest_object_dir")
  958.         {
  959.             //g_stQuestObjectDir = value_string;
  960.             std::istringstream is(value_string);
  961.             sys_log(0, "QUEST_OBJECT_DIR SETTING : %s", value_string);
  962.             string dir;
  963.             while (!is.eof())
  964.             {
  965.                 is >> dir;
  966.                 if (is.fail())
  967.                     break;
  968.                 g_setQuestObjectDir.insert(dir);
  969.                 sys_log(0, "QUEST_OBJECT_DIR INSERT : %s", dir .c_str());
  970.             }
  971.         }
  972.  
  973.         TOKEN("teen_addr")
  974.         {
  975.             strlcpy(teen_addr, value_string, sizeof(teen_addr));
  976.  
  977.             for (int n =0; n < ADDRESS_MAX_LEN; ++n)
  978.             {
  979.                 if (teen_addr[n] == ' ')
  980.                     teen_addr[n] = '\0';
  981.             }
  982.  
  983.             continue;
  984.         }
  985.  
  986.         TOKEN("teen_port")
  987.         {
  988.             str_to_number(teen_port, value_string);
  989.         }
  990.  
  991.         TOKEN("synchack_limit_count")
  992.         {
  993.             str_to_number(g_iSyncHackLimitCount, value_string);
  994.         }
  995.  
  996.         TOKEN("speedhack_limit_count")
  997.         {
  998.             str_to_number(SPEEDHACK_LIMIT_COUNT, value_string);
  999.         }
  1000.  
  1001.         TOKEN("speedhack_limit_bonus")
  1002.         {
  1003.             str_to_number(SPEEDHACK_LIMIT_BONUS, value_string);
  1004.         }
  1005.  
  1006.         TOKEN("server_id")
  1007.         {
  1008.             str_to_number(g_server_id, value_string);
  1009.         }
  1010.  
  1011.         TOKEN("mall_url")
  1012.         {
  1013.             g_strWebMallURL = value_string;
  1014.         }
  1015.  
  1016.         TOKEN("bind_ip")
  1017.         {
  1018.             strlcpy(g_szPublicIP, value_string, sizeof(g_szPublicIP));
  1019.         }
  1020.  
  1021.         TOKEN("view_range")
  1022.         {
  1023.             str_to_number(VIEW_RANGE, value_string);
  1024.         }
  1025.  
  1026.         TOKEN("spam_block_duration")
  1027.         {
  1028.             str_to_number(g_uiSpamBlockDuration, value_string);
  1029.         }
  1030.  
  1031.         TOKEN("spam_block_score")
  1032.         {
  1033.             str_to_number(g_uiSpamBlockScore, value_string);
  1034.             g_uiSpamBlockScore = MAX(1, g_uiSpamBlockScore);
  1035.         }
  1036.  
  1037.         TOKEN("spam_block_reload_cycle")
  1038.         {
  1039.             str_to_number(g_uiSpamReloadCycle, value_string);
  1040.             g_uiSpamReloadCycle = MAX(60, g_uiSpamReloadCycle); // ĂÖĽŇ 1şĐ
  1041.         }
  1042.  
  1043.         TOKEN("check_multihack")
  1044.         {
  1045.             str_to_number(g_bCheckMultiHack, value_string);
  1046.         }
  1047.  
  1048.         TOKEN("spam_block_max_level")
  1049.         {
  1050.             str_to_number(g_iSpamBlockMaxLevel, value_string);
  1051.         }
  1052.         TOKEN("protect_normal_player")
  1053.         {
  1054.             str_to_number(g_protectNormalPlayer, value_string);
  1055.         }
  1056.         TOKEN("notice_battle_zone")
  1057.         {
  1058.             str_to_number(g_noticeBattleZone, value_string);
  1059.         }
  1060.  
  1061.         TOKEN("hackshield_enable")
  1062.         {
  1063.             int flag = 0;
  1064.  
  1065.             str_to_number(flag, value_string);
  1066.  
  1067.             //if (1 == flag && LC_IsEurope() )
  1068.             if (1 == flag)
  1069.             {
  1070.                 isHackShieldEnable = true;
  1071.             }
  1072.         }
  1073.  
  1074.         TOKEN("hackshield_first_check_time")
  1075.         {
  1076.             int secs = 30;
  1077.             str_to_number(secs, value_string);
  1078.  
  1079.             HackShield_FirstCheckWaitTime = passes_per_sec * secs;
  1080.         }
  1081.  
  1082.         TOKEN("hackshield_check_cycle_time")
  1083.         {
  1084.             int secs = 180;
  1085.             str_to_number(secs, value_string);
  1086.  
  1087.             HackShield_CheckCycleTime = passes_per_sec * secs;
  1088.         }
  1089.  
  1090.         TOKEN("xtrap_enable")
  1091.         {
  1092.             int flag = 0;
  1093.             str_to_number(flag, value_string);
  1094.  
  1095.             if (1 == flag )
  1096.             {
  1097.                 bXTrapEnabled = true;
  1098.             }
  1099.         }
  1100.  
  1101.         TOKEN("pk_protect_level")
  1102.         {
  1103.             str_to_number(PK_PROTECT_LEVEL, value_string);
  1104.             fprintf(stderr, "PK_PROTECT_LEVEL: %d", PK_PROTECT_LEVEL);
  1105.         }
  1106.  
  1107.         TOKEN("max_level")
  1108.         {
  1109.             str_to_number(gPlayerMaxLevel, value_string);
  1110.  
  1111.             gPlayerMaxLevel = MINMAX(1, gPlayerMaxLevel, PLAYER_MAX_LEVEL_CONST);
  1112.  
  1113.             fprintf(stderr, "PLAYER_MAX_LEVEL: %d\n", gPlayerMaxLevel);
  1114.         }
  1115.  
  1116.         TOKEN("stone_chance")
  1117.         {
  1118.             str_to_number(stone_chance, value_string);
  1119.  
  1120.             stone_chance = MINMAX(1, stone_chance, 100);
  1121.  
  1122.             fprintf(stderr, "STONE_CHANCE: %u/n", stone_chance);
  1123.         }int gPlayerMaxLevel = 99;
  1124.  
  1125.         TOKEN("block_char_creation")
  1126.         {
  1127.             int tmp = 0;
  1128.  
  1129.             str_to_number(tmp, value_string);
  1130.  
  1131.             if (0 == tmp)
  1132.                 g_BlockCharCreation = false;
  1133.             else
  1134.                 g_BlockCharCreation = true;
  1135.  
  1136.             continue;
  1137.         }
  1138.  
  1139.         TOKEN("server_key")
  1140.         {
  1141.             CheckServer::AddServerKey(value_string);
  1142.             continue;
  1143.         }
  1144.     }
  1145.  
  1146.     if (g_setQuestObjectDir.empty())
  1147.         g_setQuestObjectDir.insert(g_stDefaultQuestObjectDir);
  1148.  
  1149.     if (0 == db_port)
  1150.     {
  1151.         fprintf(stderr, "DB_PORT not configured\n");
  1152.         exit(1);
  1153.     }
  1154.  
  1155.     if (0 == g_bChannel)
  1156.     {
  1157.         fprintf(stderr, "CHANNEL not configured\n");
  1158.         exit(1);
  1159.     }
  1160.  
  1161.     if (g_stHostname.empty())
  1162.     {
  1163.         fprintf(stderr, "HOSTNAME must be configured.\n");
  1164.         exit(1);
  1165.     }
  1166.  
  1167.     // LOCALE_SERVICE
  1168.     LocaleService_LoadLocaleStringFile();
  1169.     LocaleService_TransferDefaultSetting();
  1170.     LocaleService_LoadEmpireTextConvertTables();
  1171.     // END_OF_LOCALE_SERVICE
  1172.  
  1173.     fclose(fp);
  1174.  
  1175.     if ((fp = fopen("CMD", "r")))
  1176.     {
  1177.         while (fgets(buf, 256, fp))
  1178.         {
  1179.             char cmd[32], levelname[32];
  1180.             int level;
  1181.  
  1182.             two_arguments(buf, cmd, sizeof(cmd), levelname, sizeof(levelname));
  1183.  
  1184.             if (!*cmd || !*levelname)
  1185.             {
  1186.                 fprintf(stderr, "CMD syntax error: <cmd> <DISABLE | LOW_WIZARD | WIZARD | HIGH_WIZARD | GOD>\n");
  1187.                 exit(1);
  1188.             }
  1189.  
  1190.             if (!strcasecmp(levelname, "LOW_WIZARD"))
  1191.                 level = GM_LOW_WIZARD;
  1192.             else if (!strcasecmp(levelname, "WIZARD"))
  1193.                 level = GM_WIZARD;
  1194.             else if (!strcasecmp(levelname, "HIGH_WIZARD"))
  1195.                 level = GM_HIGH_WIZARD;
  1196.             else if (!strcasecmp(levelname, "GOD"))
  1197.                 level = GM_GOD;
  1198.             else if (!strcasecmp(levelname, "IMPLEMENTOR"))
  1199.                 level = GM_IMPLEMENTOR;
  1200.             else if (!strcasecmp(levelname, "DISABLE"))
  1201.                 level = GM_IMPLEMENTOR + 1;
  1202.             else
  1203.             {
  1204.                 fprintf(stderr, "CMD syntax error: <cmd> <DISABLE | LOW_WIZARD | WIZARD | HIGH_WIZARD | GOD>\n");
  1205.                 exit(1);
  1206.             }
  1207.  
  1208.             interpreter_set_privilege(cmd, level);
  1209.         }
  1210.  
  1211.         fclose(fp);
  1212.     }
  1213.  
  1214.     LoadValidCRCList();
  1215.     LoadStateUserCount();
  1216.  
  1217.     CWarMapManager::instance().LoadWarMapInfo(NULL);
  1218.  
  1219.     FN_log_adminpage();
  1220. }
  1221.  
  1222. const char* get_table_postfix()
  1223. {
  1224.     return g_table_postfix.c_str();
  1225. }
  1226.  
  1227. void LoadValidCRCList()
  1228. {
  1229.     s_set_dwProcessCRC.clear();
  1230.     s_set_dwFileCRC.clear();
  1231.  
  1232.     FILE * fp;
  1233.     char buf[256];
  1234.  
  1235.     if ((fp = fopen("CRC", "r")))
  1236.     {
  1237.         while (fgets(buf, 256, fp))
  1238.         {
  1239.             if (!*buf)
  1240.                 continue;
  1241.  
  1242.             DWORD dwValidClientProcessCRC;
  1243.             DWORD dwValidClientFileCRC;
  1244.  
  1245.             sscanf(buf, " %u %u ", &dwValidClientProcessCRC, &dwValidClientFileCRC);
  1246.  
  1247.             s_set_dwProcessCRC.insert(dwValidClientProcessCRC);
  1248.             s_set_dwFileCRC.insert(dwValidClientFileCRC);
  1249.  
  1250.             fprintf(stderr, "CLIENT_CRC: %u %u\n", dwValidClientProcessCRC, dwValidClientFileCRC);
  1251.         }
  1252.  
  1253.         fclose(fp);
  1254.     }
  1255. }
  1256.  
  1257. bool LoadClientVersion()
  1258. {
  1259.     FILE * fp = fopen("VERSION", "r");
  1260.  
  1261.     if (!fp)
  1262.         return false;
  1263.  
  1264.     char buf[256];
  1265.     fgets(buf, 256, fp);
  1266.  
  1267.     char * p = strchr(buf, '\n');
  1268.     if (p) *p = '\0';
  1269.  
  1270.     fprintf(stderr, "VERSION: \"%s\"\n", buf);
  1271.  
  1272.     g_stClientVersion = buf;
  1273.     fclose(fp);
  1274.     return true;
  1275. }
  1276.  
  1277. void CheckClientVersion()
  1278. {
  1279.     if (LC_IsEurope())
  1280.     {
  1281.         g_bCheckClientVersion = true;
  1282.     }
  1283.     else
  1284.     {
  1285.         g_bCheckClientVersion = false;
  1286.     }
  1287.  
  1288.     const DESC_MANAGER::DESC_SET & set = DESC_MANAGER::instance().GetClientSet();
  1289.     DESC_MANAGER::DESC_SET::const_iterator it = set.begin();
  1290.  
  1291.     while (it != set.end())
  1292.     {
  1293.         LPDESC d = *(it++);
  1294.  
  1295.         if (!d->GetCharacter())
  1296.             continue;
  1297.  
  1298.  
  1299.         int version = atoi(g_stClientVersion.c_str());
  1300.         int date    = atoi(d->GetClientVersion() );
  1301.  
  1302.         //if (0 != g_stClientVersion.compare(d->GetClientVersion()) )
  1303.         if (version != date)
  1304.         {
  1305.             d->GetCharacter()->ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT("Ŭ¶óŔĚľđĆ® ąöŔüŔĚ Ć˛·Á ·Î±×ľĆżô µË´Ď´Ů. Á¤»óŔűŔ¸·Î ĆĐġ ČÄ Á˘ĽÓÇĎĽĽżä."));
  1306.             d->DelayedDisconnect(10);
  1307.         }
  1308.     }
  1309. }
  1310.  
  1311. void LoadStateUserCount()
  1312. {
  1313.     FILE * fp = fopen("state_user_count", "r");
  1314.  
  1315.     if (!fp)
  1316.         return;
  1317.  
  1318.     if (!LC_IsHongKong())
  1319.         fscanf(fp, " %d %d ", &g_iFullUserCount, &g_iBusyUserCount);
  1320.  
  1321.     fclose(fp);
  1322. }
  1323.  
  1324. bool IsValidProcessCRC(DWORD dwCRC)
  1325. {
  1326.     return s_set_dwProcessCRC.find(dwCRC) != s_set_dwProcessCRC.end();
  1327. }
  1328.  
  1329. bool IsValidFileCRC(DWORD dwCRC)
  1330. {
  1331.     return s_set_dwFileCRC.find(dwCRC) != s_set_dwFileCRC.end();
  1332. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement