Advertisement
Guest User

Untitled

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