Advertisement
Guest User

/

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