login.c 57 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847
  1. // $Id: login.c,v 1.6 2004/09/19 21:12:07 Valaris Exp $
  2. // original : login2.c 2003/01/28 02:29:17 Rev.1.1.1.1
  3. // txt version 1.100
  4. #include <sys/types.h>
  5. #ifdef LCCWIN32
  6. #include <winsock.h>
  7. #pragma lib <libmysql.lib>
  8. #else
  9. #ifdef WIN32
  10. #define WIN32_LEAN_AND_MEAN
  11. #include <windows.h>
  12. #include <winsock2.h>
  13. #include <time.h>
  14. void Gettimeofday(struct timeval *timenow)
  15. {
  16. time_t t;
  17. t = clock();
  18. timenow->tv_usec = t;
  19. timenow->tv_sec = t / CLK_TCK;
  20. return;
  21. }
  22. #define gettimeofday(timenow, dummy) Gettimeofday(timenow)
  23. #pragma comment(lib,"libmysql.lib")
  24. #else
  25. #include <sys/socket.h>
  26. #include <netinet/in.h>
  27. #include <sys/time.h>
  28. #include <sys/ioctl.h>
  29. #include <arpa/inet.h>
  30. #include <unistd.h>
  31. #endif
  32. #endif
  33. #include <stdio.h>
  34. #include <stdlib.h>
  35. #include <time.h>
  36. #include <sys/stat.h> // for stat/lstat/fstat
  37. #include <signal.h>
  38. #include <fcntl.h>
  39. #include <string.h>
  40. //add include for DBMS(mysql)
  41. #include <mysql.h>
  42. #include "strlib.h"
  43. #include "timer.h"
  44. /*
  45. #include "timer.h"
  46. #include "core.h"
  47. #include "socket.h"
  48. #include "login.h"
  49. #include "mmo.h"
  50. #include "version.h"
  51. #include "db.h"
  52. */
  53. #include "../common/core.h"
  54. #include "../common/socket.h"
  55. #include "login.h"
  56. #include "../common/mmo.h"
  57. #include "../common/version.h"
  58. #include "../common/db.h"
  59. #include "../common/timer.h"
  60. #ifdef PASSWORDENC
  61. #include "md5calc.h"
  62. #endif
  63. #ifdef MEMWATCH
  64. #include "memwatch.h"
  65. #endif
  66. #define J_MAX_MALLOC_SIZE 65535
  67. //-----------------------------------------------------
  68. // global variable
  69. //-----------------------------------------------------
  70. int account_id_count = START_ACCOUNT_NUM;
  71. int server_num;
  72. int new_account_flag = 0;
  73. int login_port = 6900;
  74. char lan_char_ip[128]; // Lan char ip added by kashy
  75. int subnetmaski[4]; // Subnetmask added by kashy
  76. struct mmo_char_server server[MAX_SERVERS];
  77. int server_fd[MAX_SERVERS];
  78. int server_freezeflag[MAX_SERVERS]; // Char-server anti-freeze system. Counter. 5 ok, 4...0 freezed
  79. int anti_freeze_enable = 0;
  80. int ANTI_FREEZE_INTERVAL = 15;
  81. int login_fd;
  82. //Added for Mugendai's I'm Alive mod
  83. int imalive_on=0;
  84. int imalive_time=60;
  85. //Added by Mugendai for GUI
  86. int flush_on=1;
  87. int flush_time=100;
  88. char date_format[32] = "%Y-%m-%d %H:%M:%S";
  89. int auth_num = 0, auth_max = 0;
  90. int min_level_to_connect = 0; // minimum level of player/GM (0: player, 1-99: gm) to connect on the server
  91. int check_ip_flag = 1; // It's to check IP of a player between login-server and char-server (part of anti-hacking system)
  92. MYSQL mysql_handle;
  93. int ipban = 1;
  94. int dynamic_account_ban = 1;
  95. int dynamic_account_ban_class = 0;
  96. int dynamic_pass_failure_ban = 1;
  97. int dynamic_pass_failure_ban_time = 5;
  98. int dynamic_pass_failure_ban_how_many = 3;
  99. int dynamic_pass_failure_ban_how_long = 60;
  100. int login_server_port = 3306;
  101. char login_server_ip[32] = "127.0.0.1";
  102. char login_server_id[32] = "ragnarok";
  103. char login_server_pw[32] = "ragnarok";
  104. char login_server_db[32] = "ragnarok";
  105. int use_md5_passwds = 0;
  106. char login_db[256] = "login";
  107. char loginlog_db[256] = "loginlog";
  108. // added to help out custom login tables, without having to recompile
  109. // source so options are kept in the login_athena.conf or the inter_athena.conf
  110. char login_db_account_id[256] = "account_id";
  111. char login_db_userid[256] = "userid";
  112. char login_db_user_pass[256] = "user_pass";
  113. char login_db_level[256] = "level";
  114. char tmpsql[65535], tmp_sql[65535];
  115. int console = 0;
  116. int case_sensitive = 1;
  117. //-----------------------------------------------------
  118. #define AUTH_FIFO_SIZE 256
  119. struct {
  120. int account_id,login_id1,login_id2;
  121. int ip,sex,delflag;
  122. } auth_fifo[AUTH_FIFO_SIZE];
  123. int auth_fifo_pos = 0;
  124. //-----------------------------------------------------
  125. static char md5key[20], md5keylen = 16;
  126. struct dbt *online_db;
  127. //-----------------------------------------------------
  128. // Online User Database [Wizputer]
  129. //-----------------------------------------------------
  130. void add_online_user(int account_id) {
  131. int *p;
  132. p = malloc(sizeof(int));
  133. if (p == NULL) {
  134. printf("add_online_user: memory allocation failure (malloc)!\n");
  135. exit(0);
  136. }
  137. *p = account_id;
  138. numdb_insert(online_db, account_id, p);
  139. }
  140. int is_user_online(int account_id) {
  141. int *p;
  142. p = numdb_search(online_db, account_id);
  143. if (p == NULL)
  144. return 0;
  145. printf("Acccount %d\n",*p);
  146. return 1;
  147. }
  148. void remove_online_user(int account_id) {
  149. int *p;
  150. p = numdb_erase(online_db,account_id);
  151. free(p);
  152. }
  153. //-----------------------------------------------------
  154. // check user level
  155. //-----------------------------------------------------
  156. int isGM(int account_id) {
  157. int level;
  158. MYSQL_RES* sql_res;
  159. MYSQL_ROW sql_row;
  160. level = 0;
  161. sprintf(tmpsql,"SELECT `%s` FROM `%s` WHERE `%s`='%d'", login_db_level, login_db, login_db_account_id, account_id);
  162. if (mysql_query(&mysql_handle, tmpsql)) {
  163. printf("DB server Error (select GM Level to Memory)- %s\n", mysql_error(&mysql_handle));
  164. }
  165. sql_res = mysql_store_result(&mysql_handle);
  166. if (sql_res) {
  167. sql_row = mysql_fetch_row(sql_res);
  168. level = atoi(sql_row[0]);
  169. if (level > 99)
  170. level = 99;
  171. }
  172. if (level == 0) {
  173. return 0;
  174. //not GM
  175. }
  176. mysql_free_result(sql_res);
  177. return level;
  178. }
  179. //-----------------------------------------------------
  180. // Function to suppress control characters in a string.
  181. //-----------------------------------------------------
  182. int remove_control_chars(unsigned char *str) {
  183. int i;
  184. int change = 0;
  185. for(i = 0; str[i]; i++) {
  186. if (str[i] < 32) {
  187. str[i] = '_';
  188. change = 1;
  189. }
  190. }
  191. return change;
  192. }
  193. //---------------------------------------------------
  194. // E-mail check: return 0 (not correct) or 1 (valid).
  195. //---------------------------------------------------
  196. int e_mail_check(unsigned char *email) {
  197. char ch;
  198. unsigned char* last_arobas;
  199. // athena limits
  200. if (strlen(email) < 3 || strlen(email) > 39)
  201. return 0;
  202. // part of RFC limits (official reference of e-mail description)
  203. if (strchr(email, '@') == NULL || email[strlen(email)-1] == '@')
  204. return 0;
  205. if (email[strlen(email)-1] == '.')
  206. return 0;
  207. last_arobas = strrchr(email, '@');
  208. if (strstr(last_arobas, "@.") != NULL ||
  209. strstr(last_arobas, "..") != NULL)
  210. return 0;
  211. for(ch = 1; ch < 32; ch++) {
  212. if (strchr(last_arobas, ch) != NULL) {
  213. return 0;
  214. break;
  215. }
  216. }
  217. if (strchr(last_arobas, ' ') != NULL ||
  218. strchr(last_arobas, ';') != NULL)
  219. return 0;
  220. // all correct
  221. return 1;
  222. }
  223. //-----------------------------------------------------
  224. // Read Account database - mysql db
  225. //-----------------------------------------------------
  226. int mmo_auth_sqldb_init(void) {
  227. printf("Login server init....\n");
  228. // memory initialize
  229. printf("memory initialize....\n");
  230. mysql_init(&mysql_handle);
  231. // DB connection start
  232. printf("Connect Login Database Server....\n");
  233. if (!mysql_real_connect(&mysql_handle, login_server_ip, login_server_id, login_server_pw,
  234. login_server_db, login_server_port, (char *)NULL, 0)) {
  235. // pointer check
  236. printf("%s\n", mysql_error(&mysql_handle));
  237. exit(1);
  238. } else {
  239. printf("connect success!\n");
  240. }
  241. sprintf(tmpsql, "INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '', 'lserver', '100','login server started')", loginlog_db);
  242. //query
  243. if (mysql_query(&mysql_handle, tmpsql)) {
  244. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  245. }
  246. return 0;
  247. }
  248. //-----------------------------------------------------
  249. // DB server connect check
  250. //-----------------------------------------------------
  251. void mmo_auth_sqldb_sync(void) {
  252. // db connect check? or close?
  253. // ping pong DB server -if losted? then connect try. else crash.
  254. }
  255. //-----------------------------------------------------
  256. // close DB
  257. //-----------------------------------------------------
  258. void mmo_db_close(void) {
  259. int i, fd;
  260. //set log.
  261. sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '', 'lserver','100', 'login server shutdown')", loginlog_db);
  262. //query
  263. if (mysql_query(&mysql_handle, tmpsql)) {
  264. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  265. }
  266. //delete all server status
  267. sprintf(tmpsql,"DELETE FROM `sstatus`");
  268. //query
  269. if (mysql_query(&mysql_handle, tmpsql)) {
  270. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  271. }
  272. mysql_close(&mysql_handle);
  273. printf("close DB connect....\n");
  274. for (i = 0; i < MAX_SERVERS; i++) {
  275. if ((fd = server_fd[i]) >= 0)
  276. delete_session(fd);
  277. }
  278. delete_session(login_fd);
  279. }
  280. //-----------------------------------------------------
  281. // Make new account
  282. //-----------------------------------------------------
  283. int mmo_auth_sqldb_new(struct mmo_account* account,const char *tmpstr, char sex) {
  284. //no need on DB version
  285. printf("Request new account.... - not support on this version\n");
  286. return 0;
  287. }
  288. //-----------------------------------------------------
  289. // Make new account
  290. //-----------------------------------------------------
  291. int mmo_auth_new(struct mmo_account* account, const char *tmpstr, char sex) {
  292. return 0;
  293. }
  294. #ifdef LCCWIN32
  295. extern void gettimeofday(struct timeval *t, struct timezone *dummy);
  296. #endif
  297. //-----------------------------------------------------
  298. // Auth
  299. //-----------------------------------------------------
  300. int mmo_auth( struct mmo_account* account , int fd){
  301. struct timeval tv;
  302. time_t ban_until_time;
  303. char tmpstr[256];
  304. char t_uid[256], t_pass[256];
  305. char user_password[256];
  306. MYSQL_RES* sql_res ;
  307. MYSQL_ROW sql_row ;
  308. //int sql_fields, sql_cnt;
  309. char md5str[64], md5bin[32];
  310. char ip[16];
  311. unsigned char *sin_addr = (unsigned char *)&session[fd]->client_addr.sin_addr;
  312. printf ("auth start...\n");
  313. sprintf(ip, "%d.%d.%d.%d", sin_addr[0], sin_addr[1], sin_addr[2], sin_addr[3]);
  314. // auth start : time seed
  315. gettimeofday(&tv, NULL);
  316. strftime(tmpstr, 24, "%Y-%m-%d %H:%M:%S",localtime(&(tv.tv_sec)));
  317. sprintf(tmpstr+19, ".%03d", (int)tv.tv_usec/1000);
  318. jstrescapecpy(t_uid,account->userid);
  319. jstrescapecpy(t_pass, account->passwd);
  320. // make query
  321. sprintf(tmpsql, "SELECT `%s`,`%s`,`%s`,`lastlogin`,`logincount`,`sex`,`connect_until`,`last_ip`,`ban_until`,`state`,`%s`"
  322. " FROM `%s` WHERE %s `%s`='%s'", login_db_account_id, login_db_userid, login_db_user_pass, login_db_level, login_db, case_sensitive ? "BINARY" : "", login_db_userid, t_uid);
  323. //login {0-account_id/1-userid/2-user_pass/3-lastlogin/4-logincount/5-sex/6-connect_untl/7-last_ip/8-ban_until/9-state}
  324. // query
  325. if (mysql_query(&mysql_handle, tmpsql)) {
  326. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  327. }
  328. sql_res = mysql_store_result(&mysql_handle) ;
  329. if (sql_res) {
  330. sql_row = mysql_fetch_row(sql_res); //row fetching
  331. if (!sql_row) {
  332. //there's no id.
  333. printf ("auth failed no account %s %s %s\n", tmpstr, account->userid, account->passwd);
  334. mysql_free_result(sql_res);
  335. return 0;
  336. }
  337. } else {
  338. printf("mmo_auth DB result error ! \n");
  339. return 0;
  340. }
  341. // Documented by CLOWNISIUS || LLRO || Gunstar lead this one with me
  342. // IF changed to diferent returns~ you get diferent responses from your msgstringtable.txt
  343. //Ireturn 2 == line 9
  344. //Ireturn 5 == line 311
  345. //Ireturn 6 == line 450
  346. //Ireturn 7 == line 440
  347. //Ireturn 8 == line 682
  348. //Ireturn 9 == line 704
  349. //Ireturn 10 == line 705
  350. //Ireturn 11 == line 706
  351. //Ireturn 12 == line 707
  352. //Ireturn 13 == line 708
  353. //Ireturn 14 == line 709
  354. //Ireturn 15 == line 710
  355. //Ireturn -1 == line 010
  356. // Check status
  357. {
  358. int encpasswdok = 0;
  359. if (atoi(sql_row[9]) == -3) {
  360. //id is banned
  361. mysql_free_result(sql_res);
  362. return -3;
  363. } else if (atoi(sql_row[9]) == -2) { //dynamic ban
  364. //id is banned
  365. mysql_free_result(sql_res);
  366. //add IP list.
  367. return -2;
  368. }
  369. if (use_md5_passwds) {
  370. MD5_String(account->passwd,user_password);
  371. } else {
  372. jstrescapecpy(user_password, account->passwd);
  373. }
  374. printf("account id ok encval:%d\n",account->passwdenc);
  375. #ifdef PASSWORDENC
  376. if (account->passwdenc > 0) {
  377. int j = account->passwdenc;
  378. printf ("start md5calc..\n");
  379. if (j > 2)
  380. j = 1;
  381. do {
  382. if (j == 1) {
  383. sprintf(md5str, "%s%s", md5key,sql_row[2]);
  384. } else if (j == 2) {
  385. sprintf(md5str, "%s%s", sql_row[2], md5key);
  386. } else
  387. md5str[0] = 0;
  388. printf("j:%d mdstr:%s\n", j, md5str);
  389. MD5_String2binary(md5str, md5bin);
  390. encpasswdok = (memcmp(user_password, md5bin, 16) == 0);
  391. } while (j < 2 && !encpasswdok && (j++) != account->passwdenc);
  392. //printf("key[%s] md5 [%s] ", md5key, md5);
  393. printf("client [%s] accountpass [%s]\n", user_password, sql_row[2]);
  394. printf ("end md5calc..\n");
  395. }
  396. #endif
  397. if ((strcmp(user_password, sql_row[2]) && !encpasswdok)) {
  398. if (account->passwdenc == 0) {
  399. printf ("auth failed pass error %s %s %s" RETCODE, tmpstr, account->userid, user_password);
  400. #ifdef PASSWORDENC
  401. } else {
  402. char logbuf[1024], *p = logbuf;
  403. int j;
  404. p += sprintf(p, "auth failed pass error %s %s recv-md5[", tmpstr, account->userid);
  405. for(j = 0; j < 16; j++)
  406. p += sprintf(p, "%02x", ((unsigned char *)user_password)[j]);
  407. p += sprintf(p, "] calc-md5[");
  408. for(j = 0; j < 16; j++)
  409. p += sprintf(p, "%02x", ((unsigned char *)md5bin)[j]);
  410. p += sprintf(p, "] md5key[");
  411. for(j = 0; j < md5keylen; j++)
  412. p += sprintf(p, "%02x", ((unsigned char *)md5key)[j]);
  413. p += sprintf(p, "]" RETCODE);
  414. printf("%s\n", p);
  415. #endif
  416. }
  417. return 1;
  418. }
  419. printf("auth ok %s %s" RETCODE, tmpstr, account->userid);
  420. }
  421. if (atoi(sql_row[9])) {
  422. switch(atoi(sql_row[9])) { // packet 0x006a value + 1
  423. case 1: // 0 = Unregistered ID
  424. case 2: // 1 = Incorrect Password
  425. case 3: // 2 = This ID is expired
  426. case 4: // 3 = Rejected from Server
  427. case 5: // 4 = You have been blocked by the GM Team
  428. case 6: // 5 = Your Game's EXE file is not the latest version
  429. case 7: // 6 = Your are Prohibited to log in until %s
  430. case 8: // 7 = Server is jammed due to over populated
  431. case 9: // 8 = No MSG (actually, all states after 9 except 99 are No MSG, use only this)
  432. case 100: // 99 = This ID has been totally erased
  433. printf("Auth Error #%d\n", atoi(sql_row[9]));
  434. return atoi(sql_row[9]) - 1;
  435. break;
  436. default:
  437. return 99; // 99 = ID has been totally erased
  438. break;
  439. }
  440. }
  441. /*
  442. // do not remove this section. this is meant for future, and current forums usage
  443. // as a login manager and CP for login server. [CLOWNISIUS]
  444. if (atoi(sql_row[10]) == 1) {
  445. return 4;
  446. }
  447. if (atoi(sql_row[10]) >= 5) {
  448. switch(atoi(sql_row[10])) {
  449. case 5:
  450. return 5;
  451. break;
  452. case 6:
  453. return 7;
  454. break;
  455. case 7:
  456. return 9;
  457. break;
  458. case 8:
  459. return 10;
  460. break;
  461. case 9:
  462. return 11;
  463. break;
  464. default:
  465. return 10;
  466. break;
  467. }
  468. }
  469. */
  470. ban_until_time = atol(sql_row[8]);
  471. //login {0-account_id/1-userid/2-user_pass/3-lastlogin/4-logincount/5-sex/6-connect_untl/7-last_ip/8-ban_until/9-state}
  472. if (ban_until_time != 0) { // if account is banned
  473. strftime(tmpstr, 20, date_format, localtime(&ban_until_time));
  474. tmpstr[19] = '\0';
  475. if (ban_until_time > time(NULL)) { // always banned
  476. return 6; // 6 = Your are Prohibited to log in until %s
  477. } else { // ban is finished
  478. // reset the ban time
  479. sprintf(tmpsql, "UPDATE `%s` SET `ban_until`='0' WHERE %s `%s`='%s'", login_db, case_sensitive ? "BINARY" : "", login_db_userid, t_uid);
  480. if (mysql_query(&mysql_handle, tmpsql)) {
  481. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  482. }
  483. }
  484. }
  485. if (atol(sql_row[6]) != 0 && atol(sql_row[6]) < time(NULL)) {
  486. return 2; // 2 = This ID is expired
  487. }
  488. if ( is_user_online(atol(sql_row[0])) ) {
  489. printf("User [%s] is already online - Rejected.\n",sql_row[1]);
  490. #ifndef TWILIGHT
  491. return 3; // Rejected
  492. #endif
  493. }
  494. account->account_id = atoi(sql_row[0]);
  495. account->login_id1 = rand();
  496. account->login_id2 = rand();
  497. memcpy(tmpstr, sql_row[3], 19);
  498. memcpy(account->lastlogin, tmpstr, 24);
  499. account->sex = sql_row[5][0] == 'S' ? 2 : sql_row[5][0]=='M';
  500. sprintf(tmpsql, "UPDATE `%s` SET `lastlogin` = NOW(), `logincount`=`logincount` +1, `last_ip`='%s' WHERE %s `%s` = '%s'",
  501. login_db, ip, case_sensitive ? "BINARY" : "", login_db_userid, sql_row[1]);
  502. mysql_free_result(sql_res) ; //resource free
  503. if (mysql_query(&mysql_handle, tmpsql)) {
  504. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  505. }
  506. return -1;
  507. }
  508. // Send to char
  509. int charif_sendallwos(int sfd, unsigned char *buf, unsigned int len) {
  510. int i, c;
  511. int fd;
  512. c = 0;
  513. for(i = 0; i < MAX_SERVERS; i++) {
  514. if ((fd = server_fd[i]) > 0 && fd != sfd) {
  515. memcpy(WFIFOP(fd,0), buf, len);
  516. WFIFOSET(fd,len);
  517. c++;
  518. }
  519. }
  520. return c;
  521. }
  522. //--------------------------------
  523. // Char-server anti-freeze system
  524. //--------------------------------
  525. int char_anti_freeze_system(int tid, unsigned int tick, int id, int data) {
  526. int i;
  527. for(i = 0; i < MAX_SERVERS; i++) {
  528. if (server_fd[i] >= 0) {// if char-server is online
  529. // printf("char_anti_freeze_system: server #%d '%s', flag: %d.\n", i, server[i].name, server_freezeflag[i]);
  530. if (server_freezeflag[i]-- < 1) {// Char-server anti-freeze system. Counter. 5 ok, 4...0 freezed
  531. session[server_fd[i]]->eof = 1;
  532. }
  533. }
  534. }
  535. return 0;
  536. }
  537. //-----------------------------------------------------
  538. // char-server packet parse
  539. //-----------------------------------------------------
  540. int parse_fromchar(int fd){
  541. int i, id;
  542. MYSQL_RES* sql_res;
  543. MYSQL_ROW sql_row = NULL;
  544. unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr;
  545. char ip[16];
  546. sprintf(ip, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
  547. for(id = 0; id < MAX_SERVERS; id++)
  548. if (server_fd[id] == fd)
  549. break;
  550. if (id == MAX_SERVERS)
  551. session[fd]->eof = 1;
  552. if(session[fd]->eof) {
  553. if (id < MAX_SERVERS) {
  554. printf("Char-server '%s' has disconnected.\n", server[id].name);
  555. server_fd[id] = -1;
  556. memset(&server[id], 0, sizeof(struct mmo_char_server));
  557. // server delete
  558. sprintf(tmpsql, "DELETE FROM `sstatus` WHERE `index`='%d'", id);
  559. // query
  560. if (mysql_query(&mysql_handle, tmpsql)) {
  561. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  562. }
  563. }
  564. close(fd);
  565. delete_session(fd);
  566. return 0;
  567. }
  568. while(RFIFOREST(fd) >= 2) {
  569. // printf("char_parse: %d %d packet case=%x\n", fd, RFIFOREST(fd), RFIFOW(fd, 0));
  570. switch (RFIFOW(fd,0)) {
  571. case 0x2712:
  572. if (RFIFOREST(fd) < 19)
  573. return 0;
  574. {
  575. int account_id;
  576. account_id = RFIFOL(fd,2); // speed up
  577. for(i=0;i<AUTH_FIFO_SIZE;i++){
  578. if (auth_fifo[i].account_id == account_id &&
  579. auth_fifo[i].login_id1 == RFIFOL(fd,6) &&
  580. #if CMP_AUTHFIFO_LOGIN2 != 0
  581. auth_fifo[i].login_id2 == RFIFOL(fd,10) && // relate to the versions higher than 18
  582. #endif
  583. auth_fifo[i].sex == RFIFOB(fd,14) &&
  584. #if CMP_AUTHFIFO_IP != 0
  585. auth_fifo[i].ip == RFIFOL(fd,15) &&
  586. #endif
  587. !auth_fifo[i].delflag) {
  588. auth_fifo[i].delflag = 1;
  589. printf("auth -> %d\n", i);
  590. break;
  591. }
  592. }
  593. if (i != AUTH_FIFO_SIZE) { // send account_reg
  594. int p;
  595. time_t connect_until_time = 0;
  596. char email[40] = "";
  597. account_id=RFIFOL(fd,2);
  598. sprintf(tmpsql, "SELECT `email`,`connect_until` FROM `%s` WHERE `%s`='%d'", login_db, login_db_account_id, account_id);
  599. if (mysql_query(&mysql_handle, tmpsql)) {
  600. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  601. }
  602. sql_res = mysql_store_result(&mysql_handle) ;
  603. if (sql_res) {
  604. sql_row = mysql_fetch_row(sql_res);
  605. connect_until_time = atol(sql_row[1]);
  606. strcpy(email, sql_row[0]);
  607. }
  608. mysql_free_result(sql_res);
  609. if (account_id > 0) {
  610. sprintf(tmpsql, "SELECT `str`,`value` FROM `global_reg_value` WHERE `type`='1' AND `account_id`='%d'",account_id);
  611. if (mysql_query(&mysql_handle, tmpsql)) {
  612. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  613. }
  614. sql_res = mysql_store_result(&mysql_handle) ;
  615. if (sql_res) {
  616. WFIFOW(fd,0) = 0x2729;
  617. WFIFOL(fd,4) = account_id;
  618. for(p = 8; (sql_row = mysql_fetch_row(sql_res));p+=36){
  619. memcpy(WFIFOP(fd,p), sql_row[0], 32);
  620. WFIFOL(fd,p+32) = atoi(sql_row[1]);
  621. }
  622. WFIFOW(fd,2) = p;
  623. WFIFOSET(fd,p);
  624. //printf("account_reg2 send : login->char (auth fifo)\n");
  625. WFIFOW(fd,0) = 0x2713;
  626. WFIFOL(fd,2) = account_id;
  627. WFIFOB(fd,6) = 0;
  628. memcpy(WFIFOP(fd, 7), email, 40);
  629. WFIFOL(fd,47) = (unsigned long) connect_until_time;
  630. WFIFOSET(fd,51);
  631. }
  632. mysql_free_result(sql_res);
  633. }
  634. } else {
  635. WFIFOW(fd,0) = 0x2713;
  636. WFIFOL(fd,2) = account_id;
  637. WFIFOB(fd,6) = 1;
  638. WFIFOSET(fd,51);
  639. }
  640. }
  641. RFIFOSKIP(fd,19);
  642. break;
  643. case 0x2714:
  644. if (RFIFOREST(fd) < 6)
  645. return 0;
  646. // how many users on world? (update)
  647. if (server[id].users != RFIFOL(fd,2))
  648. printf("set users %s : %d\n", server[id].name, RFIFOL(fd,2));
  649. server[id].users = RFIFOL(fd,2);
  650. if(anti_freeze_enable)
  651. server_freezeflag[id] = 5; // Char anti-freeze system. Counter. 5 ok, 4...0 freezed
  652. sprintf(tmpsql,"UPDATE `sstatus` SET `user` = '%d' WHERE `index` = '%d'", server[id].users, id);
  653. // query
  654. if (mysql_query(&mysql_handle, tmpsql)) {
  655. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  656. }
  657. RFIFOSKIP(fd,6);
  658. break;
  659. // We receive an e-mail/limited time request, because a player comes back from a map-server to the char-server
  660. case 0x2716:
  661. if (RFIFOREST(fd) < 6)
  662. return 0;
  663. {
  664. int account_id;
  665. time_t connect_until_time = 0;
  666. char email[40] = "";
  667. account_id=RFIFOL(fd,2);
  668. sprintf(tmpsql,"SELECT `email`,`connect_until` FROM `%s` WHERE `%s`='%d'",login_db, login_db_account_id, account_id);
  669. if(mysql_query(&mysql_handle, tmpsql)) {
  670. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  671. }
  672. sql_res = mysql_store_result(&mysql_handle) ;
  673. if (sql_res) {
  674. sql_row = mysql_fetch_row(sql_res);
  675. connect_until_time = atol(sql_row[1]);
  676. strcpy(email, sql_row[0]);
  677. }
  678. mysql_free_result(sql_res);
  679. //printf("parse_fromchar: E-mail/limited time request from '%s' server (concerned account: %d)\n", server[id].name, RFIFOL(fd,2));
  680. WFIFOW(fd,0) = 0x2717;
  681. WFIFOL(fd,2) = RFIFOL(fd,2);
  682. memcpy(WFIFOP(fd, 6), email, 40);
  683. WFIFOL(fd,46) = (unsigned long) connect_until_time;
  684. WFIFOSET(fd,50);
  685. }
  686. RFIFOSKIP(fd,6);
  687. break;
  688. case 0x2720: // GM
  689. if (RFIFOREST(fd) < 4)
  690. return 0;
  691. if (RFIFOREST(fd) < RFIFOW(fd,2))
  692. return 0;
  693. //oldacc = RFIFOL(fd,4);
  694. printf("change GM isn't support in this login server version.\n");
  695. printf("change GM error 0 %s\n", RFIFOP(fd, 8));
  696. RFIFOSKIP(fd, RFIFOW(fd, 2));
  697. WFIFOW(fd, 0) = 0x2721;
  698. WFIFOL(fd, 2) = RFIFOL(fd,4); // oldacc;
  699. WFIFOL(fd, 6) = 0; // newacc;
  700. WFIFOSET(fd, 10);
  701. return 0;
  702. // Map server send information to change an email of an account via char-server
  703. case 0x2722: // 0x2722 <account_id>.L <actual_e-mail>.40B <new_e-mail>.40B
  704. if (RFIFOREST(fd) < 86)
  705. return 0;
  706. {
  707. int acc;
  708. char actual_email[40], new_email[40];
  709. acc = RFIFOL(fd,2);
  710. memcpy(actual_email, RFIFOP(fd,6), 40);
  711. memcpy(new_email, RFIFOP(fd,46), 40);
  712. if (e_mail_check(actual_email) == 0)
  713. printf("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual email is invalid (account: %d, ip: %s)" RETCODE,
  714. server[id].name, acc, ip);
  715. else if (e_mail_check(new_email) == 0)
  716. printf("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a invalid new e-mail (account: %d, ip: %s)" RETCODE,
  717. server[id].name, acc, ip);
  718. else if (strcmpi(new_email, "a@a.com") == 0)
  719. printf("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a default e-mail (account: %d, ip: %s)" RETCODE,
  720. server[id].name, acc, ip);
  721. else {
  722. sprintf(tmpsql, "SELECT `%s`,`email` FROM `%s` WHERE `%s` = '%d'", login_db_userid, login_db, login_db_account_id, acc);
  723. if (mysql_query(&mysql_handle, tmpsql))
  724. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  725. sql_res = mysql_store_result(&mysql_handle);
  726. if (sql_res) {
  727. sql_row = mysql_fetch_row(sql_res); //row fetching
  728. if (strcmpi(sql_row[1], actual_email) == 0) {
  729. sprintf(tmpsql, "UPDATE `%s` SET `email` = '%s' WHERE `%s` = '%d'", login_db, new_email, login_db_account_id, acc);
  730. // query
  731. if (mysql_query(&mysql_handle, tmpsql)) {
  732. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  733. }
  734. printf("Char-server '%s': Modify an e-mail on an account (@email GM command) (account: %d (%s), new e-mail: %s, ip: %s)." RETCODE,
  735. server[id].name, acc, sql_row[0], actual_email, ip);
  736. }
  737. }
  738. }
  739. }
  740. RFIFOSKIP(fd, 86);
  741. break;
  742. case 0x2724: // Receiving of map-server via char-server a status change resquest (by Yor)
  743. if (RFIFOREST(fd) < 10)
  744. return 0;
  745. {
  746. int acc, statut;
  747. acc = RFIFOL(fd,2);
  748. statut = RFIFOL(fd,6);
  749. sprintf(tmpsql, "SELECT `state` FROM `%s` WHERE `%s` = '%d'", login_db, login_db_account_id, acc);
  750. if (mysql_query(&mysql_handle, tmpsql)) {
  751. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  752. }
  753. sql_res = mysql_store_result(&mysql_handle);
  754. if (sql_res) {
  755. sql_row = mysql_fetch_row(sql_res); // row fetching
  756. }
  757. if (atoi(sql_row[0]) != statut && statut != 0) {
  758. unsigned char buf[16];
  759. WBUFW(buf,0) = 0x2731;
  760. WBUFL(buf,2) = acc;
  761. WBUFB(buf,6) = 0; // 0: change of statut, 1: ban
  762. WBUFL(buf,7) = statut; // status or final date of a banishment
  763. charif_sendallwos(-1, buf, 11);
  764. }
  765. sprintf(tmpsql,"UPDATE `%s` SET `state` = '%d' WHERE `%s` = '%d'", login_db, statut,login_db_account_id,acc);
  766. //query
  767. if(mysql_query(&mysql_handle, tmpsql)) {
  768. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  769. }
  770. RFIFOSKIP(fd,10);
  771. }
  772. return 0;
  773. case 0x2725: // Receiving of map-server via char-server a ban resquest (by Yor)
  774. if (RFIFOREST(fd) < 18)
  775. return 0;
  776. {
  777. int acc;
  778. struct tm *tmtime;
  779. time_t timestamp, tmptime;
  780. acc = RFIFOL(fd,2);
  781. sprintf(tmpsql, "SELECT `ban_until` FROM `%s` WHERE `%s` = '%d'",login_db,login_db_account_id,acc);
  782. if (mysql_query(&mysql_handle, tmpsql)) {
  783. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  784. }
  785. sql_res = mysql_store_result(&mysql_handle);
  786. if (sql_res) {
  787. sql_row = mysql_fetch_row(sql_res); // row fetching
  788. }
  789. tmptime = atol(sql_row[0]);
  790. if (tmptime == 0 || tmptime < time(NULL))
  791. timestamp = time(NULL);
  792. else
  793. timestamp = tmptime;
  794. tmtime = localtime(&timestamp);
  795. tmtime->tm_year = tmtime->tm_year + (short)RFIFOW(fd,6);
  796. tmtime->tm_mon = tmtime->tm_mon + (short)RFIFOW(fd,8);
  797. tmtime->tm_mday = tmtime->tm_mday + (short)RFIFOW(fd,10);
  798. tmtime->tm_hour = tmtime->tm_hour + (short)RFIFOW(fd,12);
  799. tmtime->tm_min = tmtime->tm_min + (short)RFIFOW(fd,14);
  800. tmtime->tm_sec = tmtime->tm_sec + (short)RFIFOW(fd,16);
  801. timestamp = mktime(tmtime);
  802. if (timestamp != -1) {
  803. if (timestamp <= time(NULL))
  804. timestamp = 0;
  805. if (tmptime != timestamp) {
  806. if (timestamp != 0) {
  807. unsigned char buf[16];
  808. WBUFW(buf,0) = 0x2731;
  809. WBUFL(buf,2) = acc;
  810. WBUFB(buf,6) = 1; // 0: change of statut, 1: ban
  811. WBUFL(buf,7) = timestamp; // status or final date of a banishment
  812. charif_sendallwos(-1, buf, 11);
  813. }
  814. printf("Account: %d Banned until: %ld\n", acc, timestamp);
  815. sprintf(tmpsql, "UPDATE `%s` SET `ban_until` = '%ld', `state`='7' WHERE `%s` = '%d'", login_db, timestamp, login_db_account_id, acc);
  816. // query
  817. if (mysql_query(&mysql_handle, tmpsql)) {
  818. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  819. }
  820. }
  821. }
  822. RFIFOSKIP(fd,18);
  823. break;
  824. }
  825. return 0;
  826. case 0x2727:
  827. if (RFIFOREST(fd) < 6)
  828. return 0;
  829. {
  830. int acc,sex;
  831. unsigned char buf[16];
  832. acc=RFIFOL(fd,4);
  833. sprintf(tmpsql,"SELECT `sex` FROM `%s` WHERE `%s` = '%d'",login_db,login_db_account_id,acc);
  834. if(mysql_query(&mysql_handle, tmpsql)) {
  835. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  836. return 0;
  837. }
  838. sql_res = mysql_store_result(&mysql_handle) ;
  839. if (sql_res) {
  840. if (mysql_num_rows(sql_res) == 0) {
  841. mysql_free_result(sql_res);
  842. return 0;
  843. }
  844. sql_row = mysql_fetch_row(sql_res); //row fetching
  845. }
  846. if (strcmpi(sql_row[0], "M") == 0)
  847. sex = 1;
  848. else
  849. sex = 0;
  850. sprintf(tmpsql,"UPDATE `%s` SET `sex` = '%c' WHERE `%s` = '%d'", login_db, (sex==0?'M':'F'), login_db_account_id, acc);
  851. //query
  852. if(mysql_query(&mysql_handle, tmpsql)) {
  853. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  854. }
  855. WBUFW(buf,0) = 0x2723;
  856. WBUFL(buf,2) = acc;
  857. WBUFB(buf,6) = sex;
  858. charif_sendallwos(-1, buf, 7);
  859. RFIFOSKIP(fd,6);
  860. }
  861. return 0;
  862. case 0x2728: // save account_reg
  863. if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
  864. return 0;
  865. {
  866. int acc,p,j;
  867. char str[32];
  868. char temp_str[32];
  869. int value;
  870. acc=RFIFOL(fd,4);
  871. if (acc>0){
  872. unsigned char buf[RFIFOW(fd,2)+1];
  873. for(p=8,j=0;p<RFIFOW(fd,2) && j<ACCOUNT_REG2_NUM;p+=36,j++){
  874. memcpy(str,RFIFOP(fd,p),32);
  875. value=RFIFOL(fd,p+32);
  876. sprintf(tmpsql,"DELETE FROM `global_reg_value` WHERE `type`='1' AND `account_id`='%d' AND `str`='%s';",acc,jstrescapecpy(temp_str,str));
  877. if(mysql_query(&mysql_handle, tmpsql)) {
  878. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  879. }
  880. sprintf(tmpsql,"INSERT INTO `global_reg_value` (`type`, `account_id`, `str`, `value`) VALUES ( 1 , '%d' , '%s' , '%d');", acc, jstrescapecpy(temp_str,str), value);
  881. if(mysql_query(&mysql_handle, tmpsql)) {
  882. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  883. }
  884. }
  885. // Send to char
  886. memcpy(WBUFP(buf,0),RFIFOP(fd,0),RFIFOW(fd,2));
  887. WBUFW(buf,0)=0x2729;
  888. charif_sendallwos(fd,buf,WBUFW(buf,2));
  889. }
  890. }
  891. RFIFOSKIP(fd,RFIFOW(fd,2));
  892. //printf("login: save account_reg (from char)\n");
  893. break;
  894. case 0x272a: // Receiving of map-server via char-server a unban resquest (by Yor)
  895. if (RFIFOREST(fd) < 6)
  896. return 0;
  897. {
  898. int acc;
  899. acc = RFIFOL(fd,2);
  900. sprintf(tmpsql,"SELECT `ban_until` FROM `%s` WHERE `%s` = '%d'",login_db,login_db_account_id,acc);
  901. if(mysql_query(&mysql_handle, tmpsql)) {
  902. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  903. }
  904. sql_res = mysql_store_result(&mysql_handle) ;
  905. if (sql_res) {
  906. sql_row = mysql_fetch_row(sql_res); //row fetching
  907. }
  908. if (atol(sql_row[0]) != 0) {
  909. sprintf(tmpsql,"UPDATE `%s` SET `ban_until` = '0', `state`='0' WHERE `%s` = '%d'", login_db,login_db_account_id,acc);
  910. //query
  911. if(mysql_query(&mysql_handle, tmpsql)) {
  912. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  913. }
  914. break;
  915. }
  916. RFIFOSKIP(fd,6);
  917. }
  918. return 0;
  919. case 0x272b: // Set account_id to online [Wizputer]
  920. if (RFIFOREST(fd) < 6)
  921. return 0;
  922. add_online_user(RFIFOL(fd,2));
  923. RFIFOSKIP(fd,6);
  924. break;
  925. case 0x272c: // Set account_id to offline [Wizputer]
  926. if (RFIFOREST(fd) < 6)
  927. return 0;
  928. remove_online_user(RFIFOL(fd,2));
  929. RFIFOSKIP(fd,6);
  930. break;
  931. default:
  932. printf("login: unknown packet %x! (from char).\n", RFIFOW(fd,0));
  933. session[fd]->eof = 1;
  934. return 0;
  935. }
  936. }
  937. return 0;
  938. }
  939. //Lan ip check added by Kashy
  940. int lan_ip_check(unsigned char *p) {
  941. int y;
  942. int lancheck = 1;
  943. int lancharip[4];
  944. unsigned int k0, k1, k2, k3;
  945. sscanf(lan_char_ip, "%d.%d.%d.%d", &k0, &k1, &k2, &k3);
  946. lancharip[0] = k0; lancharip[1] = k1; lancharip[2] = k2; lancharip[3] = k3;
  947. for(y = 0; y < 4; y++) {
  948. if ((lancharip[y] & subnetmaski[y])!= (p[y]))
  949. lancheck = 0;
  950. break; }
  951. printf("LAN check: %s.\n", (lancheck) ? "\033[1;32mLAN\033[0m" : "\033[1;31mWAN\033[0m");
  952. return lancheck;
  953. }
  954. //----------------------------------------------------------------------------------------
  955. // Default packet parsing (normal players or administation/char-server connection requests)
  956. //----------------------------------------------------------------------------------------
  957. int parse_login(int fd) {
  958. //int len;
  959. MYSQL_RES* sql_res ;
  960. MYSQL_ROW sql_row = NULL;
  961. char t_uid[100];
  962. //int sql_fields, sql_cnt;
  963. struct mmo_account account;
  964. int result, i;
  965. unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr;
  966. char ip[16];
  967. sprintf(ip, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
  968. if (ipban > 0) {
  969. //ip ban
  970. //p[0], p[1], p[2], p[3]
  971. //request DB connection
  972. //check
  973. sprintf(tmpsql, "SELECT count(*) FROM `ipbanlist` WHERE `list` = '%d.*.*.*' OR `list` = '%d.%d.*.*' OR `list` = '%d.%d.%d.*' OR `list` = '%d.%d.%d.%d'",
  974. p[0], p[0], p[1], p[0], p[1], p[2], p[0], p[1], p[2], p[3]);
  975. if (mysql_query(&mysql_handle, tmpsql)) {
  976. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  977. }
  978. sql_res = mysql_store_result(&mysql_handle) ;
  979. sql_row = mysql_fetch_row(sql_res); //row fetching
  980. if (atoi(sql_row[0]) >0) {
  981. // ip ban ok.
  982. printf ("packet from banned ip : %d.%d.%d.%d" RETCODE, p[0], p[1], p[2], p[3]);
  983. sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%d.%d.%d.%d', 'unknown','-3', 'ip banned')", loginlog_db, p[0], p[1], p[2], p[3]);
  984. // query
  985. if(mysql_query(&mysql_handle, tmpsql)) {
  986. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  987. }
  988. printf ("close session connection...\n");
  989. // close connection
  990. session[fd]->eof = 1;
  991. } else {
  992. printf ("packet from ip (ban check ok) : %d.%d.%d.%d" RETCODE, p[0], p[1], p[2], p[3]);
  993. }
  994. mysql_free_result(sql_res);
  995. }
  996. if (session[fd]->eof) {
  997. for(i = 0; i < MAX_SERVERS; i++)
  998. if (server_fd[i] == fd)
  999. server_fd[i] = -1;
  1000. close(fd);
  1001. delete_session(fd);
  1002. return 0;
  1003. }
  1004. while(RFIFOREST(fd)>=2){
  1005. printf("parse_login : %d %d packet case=%x\n", fd, RFIFOREST(fd), RFIFOW(fd,0));
  1006. switch(RFIFOW(fd,0)){
  1007. case 0x200: // New alive packet: structure: 0x200 <account.userid>.24B. used to verify if client is always alive.
  1008. if (RFIFOREST(fd) < 26)
  1009. return 0;
  1010. RFIFOSKIP(fd,26);
  1011. break;
  1012. case 0x204: // New alive packet: structure: 0x204 <encrypted.account.userid>.16B. (new ragexe from 22 june 2004)
  1013. if (RFIFOREST(fd) < 18)
  1014. return 0;
  1015. RFIFOSKIP(fd,18);
  1016. break;
  1017. case 0x64: // request client login
  1018. case 0x01dd: // request client login with encrypt
  1019. if(RFIFOREST(fd)< ((RFIFOW(fd, 0) ==0x64)?55:47))
  1020. return 0;
  1021. printf("client connection request %s from %d.%d.%d.%d\n", RFIFOP(fd, 6), p[0], p[1], p[2], p[3]);
  1022. account.userid = RFIFOP(fd, 6);
  1023. account.passwd = RFIFOP(fd, 30);
  1024. #ifdef PASSWORDENC
  1025. account.passwdenc= (RFIFOW(fd,0)==0x64)?0:PASSWORDENC;
  1026. #else
  1027. account.passwdenc=0;
  1028. #endif
  1029. result=mmo_auth(&account, fd);
  1030. jstrescapecpy(t_uid,RFIFOP(fd, 6));
  1031. if(result==-1){
  1032. int gm_level = isGM(account.account_id);
  1033. if (min_level_to_connect > gm_level) {
  1034. WFIFOW(fd,0) = 0x81;
  1035. WFIFOL(fd,2) = 1; // 01 = Server closed
  1036. WFIFOSET(fd,3);
  1037. } else {
  1038. if (p[0] != 127) {
  1039. sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%d.%d.%d.%d', '%s','100', 'login ok')", loginlog_db, p[0], p[1], p[2], p[3], t_uid);
  1040. //query
  1041. if(mysql_query(&mysql_handle, tmpsql)) {
  1042. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  1043. }
  1044. }
  1045. if (gm_level)
  1046. printf("Connection of the GM (level:%d) account '%s' accepted.\n", gm_level, account.userid);
  1047. else
  1048. printf("Connection of the account '%s' accepted.\n", account.userid);
  1049. server_num=0;
  1050. for(i = 0; i < MAX_SERVERS; i++) {
  1051. if (server_fd[i] >= 0) {
  1052. //Lan check added by Kashy
  1053. if (lan_ip_check(p))
  1054. WFIFOL(fd,47+server_num*32) = inet_addr(lan_char_ip);
  1055. else
  1056. WFIFOL(fd,47+server_num*32) = server[i].ip;
  1057. WFIFOW(fd,47+server_num*32+4) = server[i].port;
  1058. memcpy(WFIFOP(fd,47+server_num*32+6), server[i].name, 20);
  1059. WFIFOW(fd,47+server_num*32+26) = server[i].users;
  1060. WFIFOW(fd,47+server_num*32+28) = server[i].maintenance;
  1061. WFIFOW(fd,47+server_num*32+30) = server[i].new;
  1062. server_num++;
  1063. }
  1064. }
  1065. // if at least 1 char-server
  1066. if (server_num > 0) {
  1067. WFIFOW(fd,0)=0x69;
  1068. WFIFOW(fd,2)=47+32*server_num;
  1069. WFIFOL(fd,4)=account.login_id1;
  1070. WFIFOL(fd,8)=account.account_id;
  1071. WFIFOL(fd,12)=account.login_id2;
  1072. WFIFOL(fd,16)=0;
  1073. memcpy(WFIFOP(fd,20),account.lastlogin,24);
  1074. WFIFOB(fd,46)=account.sex;
  1075. WFIFOSET(fd,47+32*server_num);
  1076. if(auth_fifo_pos>=AUTH_FIFO_SIZE)
  1077. auth_fifo_pos=0;
  1078. auth_fifo[auth_fifo_pos].account_id=account.account_id;
  1079. auth_fifo[auth_fifo_pos].login_id1=account.login_id1;
  1080. auth_fifo[auth_fifo_pos].login_id2=account.login_id2;
  1081. auth_fifo[auth_fifo_pos].sex=account.sex;
  1082. auth_fifo[auth_fifo_pos].delflag=0;
  1083. auth_fifo[auth_fifo_pos].ip = session[fd]->client_addr.sin_addr.s_addr;
  1084. auth_fifo_pos++;
  1085. } else {
  1086. WFIFOW(fd,0) = 0x81;
  1087. WFIFOL(fd,2) = 1; // 01 = Server closed
  1088. WFIFOSET(fd,3);
  1089. }
  1090. }
  1091. } else {
  1092. char tmp_sql[512];
  1093. char error[64];
  1094. sprintf(tmp_sql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%d.%d.%d.%d', '%s', '%d','login failed : %%s')", loginlog_db, p[0], p[1], p[2], p[3], t_uid, result);
  1095. switch((result + 1)) {
  1096. case -2: //-3 = Account Banned
  1097. sprintf(tmpsql,tmp_sql,"Account banned.");
  1098. sprintf(error,"Account banned.");
  1099. break;
  1100. case -1: //-2 = Dynamic Ban
  1101. sprintf(tmpsql,tmp_sql,"dynamic ban (ip and account).");
  1102. sprintf(error,"dynamic ban (ip and account).");
  1103. break;
  1104. case 1: // 0 = Unregistered ID
  1105. sprintf(tmpsql,tmp_sql,"Unregisterd ID.");
  1106. sprintf(error,"Unregisterd ID.");
  1107. break;
  1108. case 2: // 1 = Incorrect Password
  1109. sprintf(tmpsql,tmp_sql,"Incorrect Password.");
  1110. sprintf(error,"Incorrect Password.");
  1111. break;
  1112. case 3: // 2 = This ID is expired
  1113. sprintf(tmpsql,tmp_sql,"Account Expired.");
  1114. sprintf(error,"Account Expired.");
  1115. break;
  1116. case 4: // 3 = Rejected from Server
  1117. sprintf(tmpsql,tmp_sql,"Rejected from server.");
  1118. sprintf(error,"Rejected from server.");
  1119. break;
  1120. case 5: // 4 = You have been blocked by the GM Team
  1121. sprintf(tmpsql,tmp_sql,"Blocked by GM.");
  1122. sprintf(error,"Blocked by GM.");
  1123. break;
  1124. case 6: // 5 = Your Game's EXE file is not the latest version
  1125. sprintf(tmpsql,tmp_sql,"Not latest game EXE.");
  1126. sprintf(error,"Not latest game EXE.");
  1127. break;
  1128. case 7: // 6 = Your are Prohibited to log in until %s
  1129. sprintf(tmpsql,tmp_sql,"Banned.");
  1130. sprintf(error,"Banned.");
  1131. break;
  1132. case 8: // 7 = Server is jammed due to over populated
  1133. sprintf(tmpsql,tmp_sql,"Server Over-population.");
  1134. sprintf(error,"Server Over-population.");
  1135. break;
  1136. case 9: // 8 = No MSG (actually, all states after 9 except 99 are No MSG, use only this)
  1137. sprintf(tmpsql,tmp_sql," ");
  1138. sprintf(error," ");
  1139. break;
  1140. case 100: // 99 = This ID has been totally erased
  1141. sprintf(tmpsql,tmp_sql,"Account gone.");
  1142. sprintf(error,"Account gone.");
  1143. break;
  1144. default:
  1145. sprintf(tmpsql,tmp_sql,"Uknown Error.");
  1146. sprintf(error,"Uknown Error.");
  1147. break;
  1148. }
  1149. //query
  1150. if(mysql_query(&mysql_handle, tmpsql)) {
  1151. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  1152. }
  1153. if ((result == 1) && (dynamic_pass_failure_ban != 0)){ // failed password
  1154. sprintf(tmpsql,"SELECT count(*) FROM `%s` WHERE `ip` = '%d.%d.%d.%d' AND `rcode` = '1' AND `time` > NOW() - INTERVAL %d MINUTE",
  1155. loginlog_db, p[0], p[1], p[2], p[3], dynamic_pass_failure_ban_time); //how many times filed account? in one ip.
  1156. if(mysql_query(&mysql_handle, tmpsql)) {
  1157. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  1158. }
  1159. //check query result
  1160. sql_res = mysql_store_result(&mysql_handle) ;
  1161. sql_row = mysql_fetch_row(sql_res); //row fetching
  1162. if (atoi(sql_row[0]) >= dynamic_pass_failure_ban_how_many ) {
  1163. sprintf(tmpsql,"INSERT INTO `ipbanlist`(`list`,`btime`,`rtime`,`reason`) VALUES ('%d.%d.%d.*', NOW() , NOW() + INTERVAL %d MINUTE ,'Password error ban: %s')", p[0], p[1], p[2], dynamic_pass_failure_ban_how_long, t_uid);
  1164. if(mysql_query(&mysql_handle, tmpsql)) {
  1165. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  1166. }
  1167. }
  1168. mysql_free_result(sql_res);
  1169. }
  1170. else if (result == -2){ //dynamic banned - add ip to ban list.
  1171. sprintf(tmpsql,"INSERT INTO `ipbanlist`(`list`,`btime`,`rtime`,`reason`) VALUES ('%d.%d.%d.*', NOW() , NOW() + INTERVAL 1 MONTH ,'Dynamic banned user id : %s')", p[0], p[1], p[2], t_uid);
  1172. if(mysql_query(&mysql_handle, tmpsql)) {
  1173. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  1174. }
  1175. result = -3;
  1176. }
  1177. sprintf(tmpsql,"SELECT `ban_until` FROM `%s` WHERE %s `%s` = '%s'",login_db, case_sensitive ? "BINARY" : "",login_db_userid, t_uid);
  1178. if(mysql_query(&mysql_handle, tmpsql)) {
  1179. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  1180. }
  1181. sql_res = mysql_store_result(&mysql_handle) ;
  1182. if (sql_res) {
  1183. sql_row = mysql_fetch_row(sql_res); //row fetching
  1184. }
  1185. //cannot connect login failed
  1186. memset(WFIFOP(fd,0),'\0',23);
  1187. WFIFOW(fd,0)=0x6a;
  1188. WFIFOB(fd,2)=result;
  1189. if (result == 6) { // 6 = Your are Prohibited to log in until %s
  1190. if (atol(sql_row[0]) != 0) { // if account is banned, we send ban timestamp
  1191. char tmpstr[256];
  1192. time_t ban_until_time;
  1193. ban_until_time = atol(sql_row[0]);
  1194. strftime(tmpstr, 20, date_format, localtime(&ban_until_time));
  1195. tmpstr[19] = '\0';
  1196. memcpy(WFIFOP(fd,3), tmpstr, 20);
  1197. } else { // we send error message
  1198. memcpy(WFIFOP(fd,3), error, 20);
  1199. }
  1200. }
  1201. WFIFOSET(fd,23);
  1202. }
  1203. RFIFOSKIP(fd,(RFIFOW(fd,0)==0x64)?55:47);
  1204. break;
  1205. case 0x01db: // request password key
  1206. if (session[fd]->session_data) {
  1207. printf("login: abnormal request of MD5 key (already opened session).\n");
  1208. session[fd]->eof = 1;
  1209. return 0;
  1210. }
  1211. printf("Request Password key -%s\n",md5key);
  1212. RFIFOSKIP(fd,2);
  1213. WFIFOW(fd,0)=0x01dc;
  1214. WFIFOW(fd,2)=4+md5keylen;
  1215. memcpy(WFIFOP(fd,4),md5key,md5keylen);
  1216. WFIFOSET(fd,WFIFOW(fd,2));
  1217. break;
  1218. case 0x2710: // request Char-server connection
  1219. if(RFIFOREST(fd)<86)
  1220. return 0;
  1221. {
  1222. unsigned char* server_name;
  1223. sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%d.%d.%d.%d', '%s@%s','100', 'charserver - %s@%d.%d.%d.%d:%d')", loginlog_db, p[0], p[1], p[2], p[3], RFIFOP(fd, 2),RFIFOP(fd, 60),RFIFOP(fd, 60), RFIFOB(fd, 54), RFIFOB(fd, 55), RFIFOB(fd, 56), RFIFOB(fd, 57), RFIFOW(fd, 58));
  1224. //query
  1225. if(mysql_query(&mysql_handle, tmpsql)) {
  1226. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  1227. }
  1228. printf("server connection request %s @ %d.%d.%d.%d:%d (%d.%d.%d.%d)\n",
  1229. RFIFOP(fd, 60), RFIFOB(fd, 54), RFIFOB(fd, 55), RFIFOB(fd, 56), RFIFOB(fd, 57), RFIFOW(fd, 58),
  1230. p[0], p[1], p[2], p[3]);
  1231. account.userid = RFIFOP(fd, 2);
  1232. account.passwd = RFIFOP(fd, 26);
  1233. account.passwdenc = 0;
  1234. server_name = RFIFOP(fd,60);
  1235. result = mmo_auth(&account, fd);
  1236. //printf("Result: %d - Sex: %d - Account ID: %d\n",result,account.sex,(int) account.account_id);
  1237. if(result == -1 && account.sex==2 && account.account_id<MAX_SERVERS && server_fd[account.account_id]==-1){
  1238. printf("Connection of the char-server '%s' accepted.\n", server_name);
  1239. memset(&server[account.account_id], 0, sizeof(struct mmo_char_server));
  1240. server[account.account_id].ip=RFIFOL(fd,54);
  1241. server[account.account_id].port=RFIFOW(fd,58);
  1242. memcpy(server[account.account_id].name,RFIFOP(fd,60),20);
  1243. server[account.account_id].users=0;
  1244. server[account.account_id].maintenance=RFIFOW(fd,82);
  1245. server[account.account_id].new=RFIFOW(fd,84);
  1246. server_fd[account.account_id]=fd;
  1247. if(anti_freeze_enable)
  1248. server_freezeflag[account.account_id] = 5; // Char-server anti-freeze system. Counter. 5 ok, 4...0 freezed
  1249. sprintf(tmpsql,"DELETE FROM `sstatus` WHERE `index`='%ld'", account.account_id);
  1250. //query
  1251. if(mysql_query(&mysql_handle, tmpsql)) {
  1252. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  1253. }
  1254. jstrescapecpy(t_uid,server[account.account_id].name);
  1255. sprintf(tmpsql,"INSERT INTO `sstatus`(`index`,`name`,`user`) VALUES ( '%ld', '%s', '%d')",
  1256. account.account_id, server[account.account_id].name,0);
  1257. //query
  1258. if(mysql_query(&mysql_handle, tmpsql)) {
  1259. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  1260. }
  1261. WFIFOW(fd,0)=0x2711;
  1262. WFIFOB(fd,2)=0;
  1263. WFIFOSET(fd,3);
  1264. session[fd]->func_parse=parse_fromchar;
  1265. realloc_fifo(fd,FIFOSIZE_SERVERLINK,FIFOSIZE_SERVERLINK);
  1266. } else {
  1267. WFIFOW(fd, 0) =0x2711;
  1268. WFIFOB(fd, 2)=3;
  1269. WFIFOSET(fd, 3);
  1270. }
  1271. }
  1272. RFIFOSKIP(fd, 86);
  1273. return 0;
  1274. case 0x7530: // request Athena information
  1275. WFIFOW(fd,0)=0x7531;
  1276. WFIFOB(fd,2)=ATHENA_MAJOR_VERSION;
  1277. WFIFOB(fd,3)=ATHENA_MINOR_VERSION;
  1278. WFIFOB(fd,4)=ATHENA_REVISION;
  1279. WFIFOB(fd,5)=ATHENA_RELEASE_FLAG;
  1280. WFIFOB(fd,6)=ATHENA_OFFICIAL_FLAG;
  1281. WFIFOB(fd,7)=ATHENA_SERVER_LOGIN;
  1282. WFIFOW(fd,8)=ATHENA_MOD_VERSION;
  1283. WFIFOSET(fd,10);
  1284. RFIFOSKIP(fd,2);
  1285. printf ("Athena version check...\n");
  1286. break;
  1287. case 0x7532:
  1288. default:
  1289. printf ("End of connection (ip: %s)" RETCODE, ip);
  1290. session[fd]->eof = 1;
  1291. return 0;
  1292. }
  1293. }
  1294. return 0;
  1295. }
  1296. // Console Command Parser [Wizputer]
  1297. int parse_console(char *buf) {
  1298. char *type,*command;
  1299. type = (char *)malloc(64);
  1300. command = (char *)malloc(64);
  1301. memset(type,0,64);
  1302. memset(command,0,64);
  1303. printf("Console: %s\n",buf);
  1304. if ( sscanf(buf, "%[^:]:%[^\n]", type , command ) < 2 )
  1305. sscanf(buf,"%[^\n]",type);
  1306. printf("Type of command: %s || Command: %s \n",type,command);
  1307. if(buf) free(buf);
  1308. if(type) free(type);
  1309. if(command) free(command);
  1310. return 0;
  1311. }
  1312. //-------------------------------------------------
  1313. // Return numerical value of a switch configuration
  1314. // on/off, english, français, deutsch, español
  1315. //-------------------------------------------------
  1316. int config_switch(const char *str) {
  1317. if (strcmpi(str, "on") == 0 || strcmpi(str, "yes") == 0 || strcmpi(str, "oui") == 0 || strcmpi(str, "ja") == 0 || strcmpi(str, "si") == 0)
  1318. return 1;
  1319. if (strcmpi(str, "off") == 0 || strcmpi(str, "no") == 0 || strcmpi(str, "non") == 0 || strcmpi(str, "nein") == 0)
  1320. return 0;
  1321. return atoi(str);
  1322. }
  1323. //Lan Support conf reading added by Kashy
  1324. int login_lan_config_read(const char *lancfgName){
  1325. int i;
  1326. char subnetmask[128];
  1327. char line[1024], w1[1024], w2[1024];
  1328. FILE *fp;
  1329. fp=fopen(lancfgName, "r");
  1330. if (fp == NULL) {
  1331. printf("file not found: %s\n", lancfgName);
  1332. return 1;
  1333. }
  1334. printf("Start reading of Lan Support configuration file\n");
  1335. while(fgets(line, sizeof(line)-1, fp)){
  1336. if (line[0] == '/' && line[1] == '/')
  1337. continue;
  1338. i = sscanf(line,"%[^:]: %[^\r\n]",w1,w2);
  1339. if(i!=2)
  1340. continue;
  1341. else if(strcmpi(w1,"lan_char_ip")==0){
  1342. strcpy(lan_char_ip, w2);
  1343. printf ("set Lan_Char_IP : %s\n",w2);
  1344. }
  1345. else if(strcmpi(w1,"subnetmask")==0){
  1346. unsigned int k0, k1, k2, k3;
  1347. strcpy(subnetmask, w2);
  1348. sscanf(subnetmask, "%d.%d.%d.%d", &k0, &k1, &k2, &k3);
  1349. subnetmaski[0] = k0; subnetmaski[1] = k1; subnetmaski[2] = k2; subnetmaski[3] = k3;
  1350. printf ("set subnetmask : %s\n",w2);
  1351. }
  1352. }
  1353. fclose(fp);
  1354. {
  1355. unsigned int a0, a1, a2, a3;
  1356. unsigned char p[4];
  1357. sscanf(lan_char_ip, "%d.%d.%d.%d", &a0, &a1, &a2, &a3);
  1358. p[0] = a0; p[1] = a1; p[2] = a2; p[3] = a3;
  1359. printf("LAN test of LAN IP of the char-server: ");
  1360. if (lan_ip_check(p) == 0) {
  1361. printf("\033[1;31m***ERROR: LAN IP of the char-server doesn't belong to the specified Sub-network\033[0m\n");
  1362. }
  1363. }
  1364. printf("End reading of Lan Support configuration file\n");
  1365. return 0;
  1366. }
  1367. //-----------------------------------------------------
  1368. //BANNED IP CHECK.
  1369. //-----------------------------------------------------
  1370. int ip_ban_check(int tid, unsigned int tick, int id, int data){
  1371. //query
  1372. if(mysql_query(&mysql_handle, "DELETE FROM `ipbanlist` WHERE `rtime` <= NOW()")) {
  1373. printf("DB server Error - %s\n", mysql_error(&mysql_handle));
  1374. }
  1375. return 0;
  1376. }
  1377. //-----------------------------------------------------
  1378. // reading configuration
  1379. //-----------------------------------------------------
  1380. int login_config_read(const char *cfgName){
  1381. int i;
  1382. char line[1024], w1[1024], w2[1024];
  1383. FILE *fp;
  1384. fp=fopen(cfgName,"r");
  1385. if(fp==NULL){
  1386. printf("Configuration file (%s) not found.\n", cfgName);
  1387. return 1;
  1388. }
  1389. printf ("start reading configuration...\n");
  1390. while(fgets(line, sizeof(line)-1, fp)){
  1391. if(line[0] == '/' && line[1] == '/')
  1392. continue;
  1393. i=sscanf(line,"%[^:]: %[^\r\n]",w1,w2);
  1394. if(i!=2)
  1395. continue;
  1396. else if(strcmpi(w1,"login_port")==0){
  1397. login_port=atoi(w2);
  1398. printf ("set login_port : %s\n",w2);
  1399. }
  1400. else if(strcmpi(w1,"ipban")==0){
  1401. ipban=atoi(w2);
  1402. printf ("set ipban : %d\n",ipban);
  1403. }
  1404. //account ban -> ip ban
  1405. else if(strcmpi(w1,"dynamic_account_ban")==0){
  1406. dynamic_account_ban=atoi(w2);
  1407. printf ("set dynamic_account_ban : %d\n",dynamic_account_ban);
  1408. }
  1409. else if(strcmpi(w1,"dynamic_account_ban_class")==0){
  1410. dynamic_account_ban_class=atoi(w2);
  1411. printf ("set dynamic_account_ban_class : %d\n",dynamic_account_ban_class);
  1412. }
  1413. //dynamic password error ban
  1414. else if(strcmpi(w1,"dynamic_pass_failure_ban")==0){
  1415. dynamic_pass_failure_ban=atoi(w2);
  1416. printf ("set dynamic_pass_failure_ban : %d\n",dynamic_pass_failure_ban);
  1417. }
  1418. else if(strcmpi(w1,"dynamic_pass_failure_ban_time")==0){
  1419. dynamic_pass_failure_ban_time=atoi(w2);
  1420. printf ("set dynamic_pass_failure_ban_time : %d\n",dynamic_pass_failure_ban_time);
  1421. }
  1422. else if(strcmpi(w1,"dynamic_pass_failure_ban_how_many")==0){
  1423. dynamic_pass_failure_ban_how_many=atoi(w2);
  1424. printf ("set dynamic_pass_failure_ban_how_many : %d\n",dynamic_pass_failure_ban_how_many);
  1425. }
  1426. else if(strcmpi(w1,"dynamic_pass_failure_ban_how_long")==0){
  1427. dynamic_pass_failure_ban_how_long=atoi(w2);
  1428. printf ("set dynamic_pass_failure_ban_how_long : %d\n",dynamic_pass_failure_ban_how_long);
  1429. }
  1430. else if(strcmpi(w1,"anti_freeze_enable")==0){
  1431. anti_freeze_enable = config_switch(w2);
  1432. }
  1433. else if (strcmpi(w1, "anti_freeze_interval") == 0) {
  1434. ANTI_FREEZE_INTERVAL = atoi(w2);
  1435. if (ANTI_FREEZE_INTERVAL < 5)
  1436. ANTI_FREEZE_INTERVAL = 5; // minimum 5 seconds
  1437. }
  1438. else if (strcmpi(w1, "import") == 0) {
  1439. login_config_read(w2);
  1440. } else if(strcmpi(w1,"imalive_on")==0) { //Added by Mugendai for I'm Alive mod
  1441. imalive_on = atoi(w2); //Added by Mugendai for I'm Alive mod
  1442. } else if(strcmpi(w1,"imalive_time")==0) { //Added by Mugendai for I'm Alive mod
  1443. imalive_time = atoi(w2); //Added by Mugendai for I'm Alive mod
  1444. } else if(strcmpi(w1,"flush_on")==0) { //Added by Mugendai for GUI
  1445. flush_on = atoi(w2); //Added by Mugendai for GUI
  1446. } else if(strcmpi(w1,"flush_time")==0) { //Added by Mugendai for GUI
  1447. flush_time = atoi(w2); //Added by Mugendai for GUI
  1448. }
  1449. else if(strcmpi(w1,"use_MD5_passwords")==0){
  1450. if (!strcmpi(w2,"yes")) {
  1451. use_md5_passwds=1;
  1452. } else if (!strcmpi(w2,"no")){
  1453. use_md5_passwds=0;
  1454. }
  1455. printf ("Using MD5 Passwords: %s \n",w2);
  1456. }
  1457. else if (strcmpi(w1, "date_format") == 0) { // note: never have more than 19 char for the date!
  1458. switch (atoi(w2)) {
  1459. case 0:
  1460. strcpy(date_format, "%d-%m-%Y %H:%M:%S"); // 31-12-2004 23:59:59
  1461. break;
  1462. case 1:
  1463. strcpy(date_format, "%m-%d-%Y %H:%M:%S"); // 12-31-2004 23:59:59
  1464. break;
  1465. case 2:
  1466. strcpy(date_format, "%Y-%d-%m %H:%M:%S"); // 2004-31-12 23:59:59
  1467. break;
  1468. case 3:
  1469. strcpy(date_format, "%Y-%m-%d %H:%M:%S"); // 2004-12-31 23:59:59
  1470. break;
  1471. }
  1472. }
  1473. else if (strcmpi(w1, "min_level_to_connect") == 0) {
  1474. min_level_to_connect = atoi(w2);
  1475. }
  1476. else if (strcmpi(w1, "check_ip_flag") == 0) {
  1477. check_ip_flag = config_switch(w2);
  1478. }
  1479. else if (strcmpi(w1, "console") == 0) {
  1480. if(strcmpi(w2,"on") == 0 || strcmpi(w2,"yes") == 0 )
  1481. console = 1;
  1482. }
  1483. else if (strcmpi(w1, "case_sensitive") == 0) {
  1484. if(strcmpi(w2,"on") == 0 || strcmpi(w2,"yes") == 0 )
  1485. case_sensitive = 1;
  1486. if(strcmpi(w2,"off") == 0 || strcmpi(w2,"no") == 0 )
  1487. case_sensitive = 0;
  1488. }
  1489. }
  1490. fclose(fp);
  1491. printf ("End reading configuration...\n");
  1492. return 0;
  1493. }
  1494. void sql_config_read(const char *cfgName){ /* Kalaspuff, to get login_db */
  1495. int i;
  1496. char line[1024], w1[1024], w2[1024];
  1497. FILE *fp=fopen(cfgName,"r");
  1498. if(fp==NULL){
  1499. printf("file not found: %s\n",cfgName);
  1500. exit(1);
  1501. }
  1502. printf("reading configure: %s\n", cfgName);
  1503. while(fgets(line, sizeof(line)-1, fp)){
  1504. if(line[0] == '/' && line[1] == '/')
  1505. continue;
  1506. i=sscanf(line,"%[^:]: %[^\r\n]",w1,w2);
  1507. if(i!=2)
  1508. continue;
  1509. if (strcmpi(w1, "login_db") == 0) {
  1510. strcpy(login_db, w2);
  1511. }
  1512. //add for DB connection
  1513. else if(strcmpi(w1,"login_server_ip")==0){
  1514. strcpy(login_server_ip, w2);
  1515. printf ("set login_server_ip : %s\n",w2);
  1516. }
  1517. else if(strcmpi(w1,"login_server_port")==0){
  1518. login_server_port=atoi(w2);
  1519. printf ("set login_server_port : %s\n",w2);
  1520. }
  1521. else if(strcmpi(w1,"login_server_id")==0){
  1522. strcpy(login_server_id, w2);
  1523. printf ("set login_server_id : %s\n",w2);
  1524. }
  1525. else if(strcmpi(w1,"login_server_pw")==0){
  1526. strcpy(login_server_pw, w2);
  1527. printf ("set login_server_pw : %s\n",w2);
  1528. }
  1529. else if(strcmpi(w1,"login_server_db")==0){
  1530. strcpy(login_server_db, w2);
  1531. printf ("set login_server_db : %s\n",w2);
  1532. }
  1533. //added for custom column names for custom login table
  1534. else if(strcmpi(w1,"login_db_account_id")==0){
  1535. strcpy(login_db_account_id, w2);
  1536. }
  1537. else if(strcmpi(w1,"login_db_userid")==0){
  1538. strcpy(login_db_userid, w2);
  1539. }
  1540. else if(strcmpi(w1,"login_db_user_pass")==0){
  1541. strcpy(login_db_user_pass, w2);
  1542. }
  1543. else if(strcmpi(w1,"login_db_level")==0){
  1544. strcpy(login_db_level, w2);
  1545. }
  1546. //end of custom table config
  1547. else if (strcmpi(w1, "loginlog_db") == 0) {
  1548. strcpy(loginlog_db, w2);
  1549. }
  1550. //support the import command, just like any other config
  1551. else if(strcmpi(w1,"import")==0){
  1552. sql_config_read(w2);
  1553. }
  1554. }
  1555. fclose(fp);
  1556. printf("reading configure done.....\n");
  1557. }
  1558. //-----------------------------------------------------
  1559. //I'm Alive Alert
  1560. //Used to output 'I'm Alive' every few seconds
  1561. //Intended to let frontends know if the app froze
  1562. //-----------------------------------------------------
  1563. int imalive_timer(int tid, unsigned int tick, int id, int data){
  1564. printf("I'm Alive\n");
  1565. return 0;
  1566. }
  1567. //-----------------------------------------------------
  1568. //Flush stdout
  1569. //stdout buffer needs flushed to be seen in GUI
  1570. //-----------------------------------------------------
  1571. int flush_timer(int tid, unsigned int tick, int id, int data){
  1572. fflush(stdout);
  1573. return 0;
  1574. }
  1575. int do_init(int argc,char **argv){
  1576. //initialize login server
  1577. int i;
  1578. //read login configue
  1579. login_config_read( (argc>1)?argv[1]:LOGIN_CONF_NAME );
  1580. sql_config_read(SQL_CONF_NAME);
  1581. login_lan_config_read((argc > 1) ? argv[1] : LAN_CONF_NAME);
  1582. //Generate Passworded Key.
  1583. printf ("memset md5key \n");
  1584. memset(md5key, 0, sizeof(md5key));
  1585. printf ("memset md5key complete\n");
  1586. printf ("memset keyleng\n");
  1587. md5keylen=rand()%4+12;
  1588. for(i=0;i<md5keylen;i++)
  1589. md5key[i]=rand()%255+1;
  1590. printf ("memset keyleng complete\n");
  1591. printf ("set FIFO Size\n");
  1592. for(i=0;i<AUTH_FIFO_SIZE;i++)
  1593. auth_fifo[i].delflag=1;
  1594. printf ("set FIFO Size complete\n");
  1595. printf ("set max servers\n");
  1596. for(i=0;i<MAX_SERVERS;i++)
  1597. server_fd[i]=-1;
  1598. printf ("set max servers complete\n");
  1599. //server port open & binding
  1600. login_fd=make_listen_port(login_port);
  1601. //Auth start
  1602. printf ("Running mmo_auth_sqldb_init()\n");
  1603. mmo_auth_sqldb_init();
  1604. printf ("finished mmo_auth_sqldb_init()\n");
  1605. //sync account when terminating.
  1606. //but no need when you using DBMS (mysql)
  1607. set_termfunc(mmo_db_close);
  1608. //set default parser as parse_login function
  1609. set_defaultparse(parse_login);
  1610. //Added for Mugendais I'm Alive mod
  1611. if(imalive_on)
  1612. add_timer_interval(gettick()+10, imalive_timer,0,0,imalive_time*1000);
  1613. //Added by Mugendai for GUI support
  1614. if(flush_on)
  1615. add_timer_interval(gettick()+10, flush_timer,0,0,flush_time);
  1616. if(anti_freeze_enable > 0) {
  1617. add_timer_func_list(char_anti_freeze_system, "char_anti_freeze_system");
  1618. i = add_timer_interval(gettick()+1000, char_anti_freeze_system, 0, 0, ANTI_FREEZE_INTERVAL * 1000);
  1619. }
  1620. // ban deleter timer - 1 minute term
  1621. printf("add interval tic (ip_ban_check)....\n");
  1622. i=add_timer_interval(gettick()+10, ip_ban_check,0,0,60*1000);
  1623. if (console) {
  1624. set_defaultconsoleparse(parse_console);
  1625. start_console();
  1626. }
  1627. // Online user database init
  1628. free(online_db);
  1629. online_db = numdb_init();
  1630. printf("The login-server is \033[1;32mready\033[0m (Server is listening on the port %d).\n\n", login_port);
  1631. return 0;
  1632. }