Advertisement
Guest User

Untitled

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