char_int.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #include <signal.h>
  5. #include <fcntl.h>
  6. #include <string.h>
  7. #include "login.h"
  8. //--------------------------------
  9. // Send to char
  10. //--------------------------------
  11. int charif_sendallwos(int sfd, unsigned char *buf, unsigned int len) {
  12. int i, c;
  13. int fd;
  14. c = 0;
  15. for(i = 0; i < MAX_SERVERS && i < servers_connected; i++) {
  16. if ((fd = server_fd[i]) > 0 && fd != sfd) {
  17. memcpy(WFIFOP(fd,0), buf, len);
  18. WFIFOSET(fd,len);
  19. c++;
  20. }
  21. }
  22. return c;
  23. }
  24. //--------------------------------
  25. // Char-server anti-freeze system
  26. //--------------------------------
  27. int char_anti_freeze_system(int tid, unsigned int tick, int id, int data) {
  28. int i;
  29. for(i = 0; i < MAX_SERVERS && i < servers_connected; i++) {
  30. if (server_fd[i] >= 0) {// if char-server is online
  31. // printf("char_anti_freeze_system: server #%d '%s', flag: %d.\n", i, server[i].name, server_freezeflag[i]);
  32. if (server_freezeflag[i]-- < 1) {// Char-server anti-freeze system. Counter. 5 ok, 4...0 freezed
  33. session[server_fd[i]]->eof = 1;
  34. }
  35. }
  36. }
  37. return 0;
  38. }
  39. //-------------------------------------------
  40. // Request for account reg from char-server [Edit: Wizputer]
  41. //-------------------------------------------
  42. void send_account_reg(int fd) {
  43. int account_id = RFIFOL(fd,2);
  44. int i;
  45. for(i=0;i<AUTH_FIFO_SIZE;i++){
  46. if (auth_fifo[i].account_id == account_id &&
  47. auth_fifo[i].login_id1 == RFIFOL(fd,6) &&
  48. #if CMP_AUTHFIFO_LOGIN2 != 0
  49. auth_fifo[i].login_id2 == RFIFOL(fd,10) && // relate to the versions higher than 18
  50. #endif
  51. auth_fifo[i].sex == RFIFOB(fd,14) &&
  52. #if CMP_AUTHFIFO_IP != 0
  53. auth_fifo[i].ip == RFIFOL(fd,15) &&
  54. #endif
  55. !auth_fifo[i].delflag) {
  56. auth_fifo[i].delflag = 1;
  57. #ifdef DEBUG
  58. printf("Client: [%d] Auth Number: [%d]\n",fd, i);
  59. #endif
  60. break;
  61. }
  62. }
  63. if (i != AUTH_FIFO_SIZE) { // send account_reg
  64. int p;
  65. time_t connect_until_time = 0;
  66. char email[40] = "";
  67. sprintf(tmpsql, "SELECT `email`,`connect_until` FROM `%s` WHERE `%s`='%d'", login_db, login_db_account_id, account_id);
  68. sql_query(tmpsql,"send_account_reg");
  69. if ((sql_res = mysql_store_result(&mysql_handle))) {
  70. if((sql_row = mysql_fetch_row(sql_res))) {
  71. connect_until_time = atol(sql_row[1]);
  72. strcpy(email, sql_row[0]);
  73. }
  74. }
  75. mysql_free_result(sql_res);
  76. if (account_id > 0) {
  77. sprintf(tmpsql, "SELECT `str`,`value` FROM `global_reg_value` WHERE `type`='1' AND `account_id`='%d'",account_id);
  78. sql_query(tmpsql,"send_account_reg");
  79. if ((sql_res = mysql_store_result(&mysql_handle))) {
  80. WFIFOW(fd,0) = 0x2729;
  81. WFIFOL(fd,4) = account_id;
  82. for(p = 8; (sql_row = mysql_fetch_row(sql_res));p+=36){
  83. memcpy(WFIFOP(fd,p), sql_row[0], 32);
  84. WFIFOL(fd,p+32) = atoi(sql_row[1]);
  85. }
  86. WFIFOW(fd,2) = p;
  87. WFIFOSET(fd,p);
  88. #ifdef DEBUG
  89. printf("account_reg2 send : login->char (auth fifo)\n");
  90. #endif
  91. WFIFOW(fd,0) = 0x2713;
  92. WFIFOL(fd,2) = account_id;
  93. WFIFOB(fd,6) = 0;
  94. memcpy(WFIFOP(fd, 7), email, 40);
  95. WFIFOL(fd,47) = (unsigned long) connect_until_time;
  96. WFIFOSET(fd,51);
  97. }
  98. mysql_free_result(sql_res);
  99. }
  100. } else {
  101. WFIFOW(fd,0) = 0x2713;
  102. WFIFOL(fd,2) = account_id;
  103. WFIFOB(fd,6) = 1;
  104. WFIFOSET(fd,51);
  105. }
  106. RFIFOSKIP(fd,19);
  107. }
  108. //----------------------------------------------------------
  109. // Number of users in the world (connected char-server(s)) [Edit: Wizputer]
  110. //----------------------------------------------------------
  111. void number_world_users(int fd, int id) {
  112. #ifdef DEBUG
  113. if (server[id].users != RFIFOL(fd,2))
  114. printf("set number users %s : %d\n", server[id].name, RFIFOL(fd,2));
  115. #endif
  116. server[id].users = RFIFOL(fd,2);
  117. if(anti_freeze_enable)
  118. server_freezeflag[id] = 5; // Char anti-freeze system. Counter. 5 ok, 4...0 freezed
  119. sprintf(tmpsql,"UPDATE `sstatus` SET `user` = '%d' WHERE `index` = '%d'", server[id].users, id);
  120. sql_query(tmpsql,"number_world_users");
  121. RFIFOSKIP(fd,6);
  122. }
  123. //-----------------------------------------
  124. // Email and Time request from char-server [Edit: Wizputer]
  125. //-----------------------------------------
  126. void email_time_request(int fd, int id) {
  127. int account_id=RFIFOL(fd,2);
  128. time_t connect_until_time = 0;
  129. char email[40] = "";
  130. sprintf(tmpsql,"SELECT `email`,`connect_until` FROM `%s` WHERE `%s`='%d'",login_db, login_db_account_id, account_id);
  131. sql_query(tmpsql,"email_time_request");
  132. if ((sql_res = mysql_store_result(&mysql_handle))) {
  133. if((sql_row = mysql_fetch_row(sql_res))) {
  134. connect_until_time = atol(sql_row[1]);
  135. strcpy(email, sql_row[0]);
  136. }
  137. }
  138. mysql_free_result(sql_res);
  139. #ifdef DEBUG
  140. printf("parse_fromchar: E-mail/limited time request from '%s' server (concerned account: %d)\n", server[id].name, account_id);
  141. #endif
  142. WFIFOW(fd,0) = 0x2717;
  143. WFIFOL(fd,2) = account_id;
  144. memcpy(WFIFOP(fd, 6), email, 40);
  145. WFIFOL(fd,46) = (unsigned long) connect_until_time;
  146. WFIFOSET(fd,50);
  147. RFIFOSKIP(fd,6);
  148. }
  149. //--------------------------------
  150. // Request to change email [Edit: Wizputer]
  151. //--------------------------------
  152. void change_account_email(int fd, int id, char ip[16]) {
  153. int acc = RFIFOL(fd,2);
  154. char actual_email[40], new_email[40];
  155. memcpy(actual_email, RFIFOP(fd,6), 40);
  156. memcpy(new_email, RFIFOP(fd,46), 40);
  157. if (e_mail_check(actual_email) == 0) {
  158. #ifdef DEBUG
  159. 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,
  160. server[id].name, acc, ip);
  161. #endif
  162. } else if (e_mail_check(new_email) == 0) {
  163. #ifdef DEBUG
  164. 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,
  165. server[id].name, acc, ip);
  166. #endif
  167. } else if (strcmpi(new_email, "athena@athena.com") == 0) {
  168. #ifdef DEBUG
  169. 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,
  170. server[id].name, acc, ip);
  171. #endif
  172. } else {
  173. sprintf(tmpsql, "SELECT `%s`,`email` FROM `%s` WHERE `%s` = '%d'", login_db_userid, login_db, login_db_account_id, acc);
  174. sql_query(tmpsql,"change_account_email");
  175. if ((sql_res = mysql_store_result(&mysql_handle))) {
  176. if((sql_row = mysql_fetch_row(sql_res))) { //row fetching
  177. if (strcmpi(sql_row[1], actual_email) == 0) {
  178. sprintf(tmpsql, "UPDATE `%s` SET `email` = '%s' WHERE `%s` = '%d'", login_db, new_email, login_db_account_id, acc);
  179. sql_query(tmpsql,"change_account_email");
  180. #ifdef DEBUG
  181. printf("Char-server '%s': Modify an e-mail on an account (@email GM command) (account: %d (%s), new e-mail: %s, ip: %s)." RETCODE,
  182. server[id].name, acc, sql_row[0], actual_email, ip);
  183. #endif
  184. }
  185. }
  186. }
  187. }
  188. RFIFOSKIP(fd, 86);
  189. }
  190. //-----------------------------------------------
  191. // State change request from map server (By Yor) [Edit: Wizputer]
  192. //-----------------------------------------------
  193. void status_change_request(int fd) {
  194. int acc = RFIFOL(fd,2), status = RFIFOL(fd,6);
  195. sprintf(tmpsql, "SELECT `state` FROM `%s` WHERE `%s` = '%d'", login_db, login_db_account_id, acc);
  196. sql_query(tmpsql,"status_change_request");
  197. if ((sql_res = mysql_store_result(&mysql_handle))) {
  198. if((sql_row = mysql_fetch_row(sql_res))) { // row fetching
  199. if (atoi(sql_row[0]) != status && status != 0) {
  200. unsigned char buf[16];
  201. WBUFW(buf,0) = 0x2731;
  202. WBUFL(buf,2) = acc;
  203. WBUFB(buf,6) = 0; // 0: change of statut, 1: ban
  204. WBUFL(buf,7) = status; // status or final date of a banishment
  205. charif_sendallwos(-1, buf, 11);
  206. }
  207. }
  208. sprintf(tmpsql,"UPDATE `%s` SET `state` = '%d' WHERE `%s` = '%d'", login_db, status,login_db_account_id,acc);
  209. sql_query(tmpsql,"status_change_request");
  210. }
  211. RFIFOSKIP(fd,10);
  212. }
  213. //--------------------------------------
  214. // Ban request from map-server (By Yor) [Edit: Wizputer]
  215. //--------------------------------------
  216. void ban_request(int fd) {
  217. int acc=RFIFOL(fd,2);
  218. struct tm *tmtime;
  219. time_t timestamp, tmptime;
  220. sprintf(tmpsql, "SELECT `ban_until` FROM `%s` WHERE `%s` = '%d'",login_db,login_db_account_id,acc);
  221. sql_query(tmpsql,"ban_request");
  222. if ((sql_res = mysql_store_result(&mysql_handle)) && (sql_row = mysql_fetch_row(sql_res))) {
  223. tmptime = atol(sql_row[0]);
  224. if (tmptime == 0 || tmptime < time(NULL))
  225. timestamp = time(NULL);
  226. else
  227. timestamp = tmptime;
  228. tmtime = localtime(&timestamp);
  229. tmtime->tm_year = tmtime->tm_year + (short)RFIFOW(fd,6);
  230. tmtime->tm_mon = tmtime->tm_mon + (short)RFIFOW(fd,8);
  231. tmtime->tm_mday = tmtime->tm_mday + (short)RFIFOW(fd,10);
  232. tmtime->tm_hour = tmtime->tm_hour + (short)RFIFOW(fd,12);
  233. tmtime->tm_min = tmtime->tm_min + (short)RFIFOW(fd,14);
  234. tmtime->tm_sec = tmtime->tm_sec + (short)RFIFOW(fd,16);
  235. timestamp = mktime(tmtime);
  236. if (timestamp != -1) {
  237. if (timestamp <= time(NULL))
  238. timestamp = 0;
  239. if (tmptime != timestamp) {
  240. if (timestamp != 0) {
  241. unsigned char buf[16];
  242. WBUFW(buf,0) = 0x2731;
  243. WBUFL(buf,2) = acc;
  244. WBUFB(buf,6) = 1; // 0: change of statut, 1: ban
  245. WBUFL(buf,7) = timestamp; // status or final date of a banishment
  246. charif_sendallwos(-1, buf, 11);
  247. }
  248. #ifdef DEBUG
  249. printf("Account: [%d] Banned until: [%ld]\n", acc, timestamp);
  250. #endif
  251. sprintf(tmpsql, "UPDATE `%s` SET `ban_until` = '%ld', `state`='7' WHERE `%s` = '%d'", login_db, timestamp, login_db_account_id, acc);
  252. sql_query(tmpsql,"ban_request");
  253. }
  254. }
  255. }
  256. RFIFOSKIP(fd,18);
  257. }
  258. //-----------------------------
  259. // Change sex [Edit: Wizputer]
  260. //-----------------------------
  261. void change_sex(int fd) {
  262. int sex,acc=RFIFOL(fd,4);
  263. unsigned char buf[16];
  264. sprintf(tmpsql,"SELECT `sex` FROM `%s` WHERE `%s` = '%d'",login_db,login_db_account_id,acc);
  265. sql_query(tmpsql,"change_sex");
  266. if ((sql_res = mysql_store_result(&mysql_handle)) && (sql_row = mysql_fetch_row(sql_res))) {
  267. if (strcmpi(sql_row[0], "M") == 0)
  268. sex = 1;
  269. else
  270. sex = 0;
  271. sprintf(tmpsql,"UPDATE `%s` SET `sex` = '%c' WHERE `%s` = '%d'", login_db, (sex==0?'M':'F'), login_db_account_id, acc);
  272. sql_query(tmpsql,"change_sex");
  273. WBUFW(buf,0) = 0x2723;
  274. WBUFL(buf,2) = acc;
  275. WBUFB(buf,6) = sex;
  276. charif_sendallwos(-1, buf, 7);
  277. }
  278. RFIFOSKIP(fd,6);
  279. }
  280. //-------------------------------
  281. // Save Account Reg [Edit: Wizputer]
  282. //-------------------------------
  283. void save_account_reg(int fd){
  284. int p,j,value,acc=RFIFOL(fd,4);
  285. char str[32];
  286. char temp_str[32];
  287. if (acc>0){
  288. unsigned char buf[RFIFOW(fd,2)+1];
  289. for(p=8,j=0;p<RFIFOW(fd,2) && j<ACCOUNT_REG2_NUM;p+=36,j++){
  290. memcpy(str,RFIFOP(fd,p),32);
  291. value=RFIFOL(fd,p+32);
  292. sprintf(tmpsql,"REPLACE INTO `global_reg_value` (`type`, `account_id`, `str`, `value`) VALUES ( 1 , '%d' , '%s' , '%d');", acc, jstrescapecpy(temp_str,str), value);
  293. sql_query(tmpsql,"save_account_reg");
  294. }
  295. // Send to char
  296. memcpy(WBUFP(buf,0),RFIFOP(fd,0),RFIFOW(fd,2));
  297. WBUFW(buf,0)=0x2729;
  298. charif_sendallwos(fd,buf,WBUFW(buf,2));
  299. }
  300. RFIFOSKIP(fd,RFIFOW(fd,2));
  301. #ifdef DEBUG
  302. printf("login: save account_reg (from char)\n");
  303. #endif
  304. }
  305. //------------------------------------------------
  306. // Recieve unban request from map-server (by Yor) [Edit: Wizputer]
  307. //------------------------------------------------
  308. void unban_request(int fd) {
  309. int acc = RFIFOL(fd,2);
  310. sprintf(tmpsql,"UPDATE `%s` SET `ban_until` = '0', `state`='0' WHERE `%s` = '%d' AND `state`='6'", login_db,login_db_account_id,acc);
  311. sql_query(tmpsql,"unban_request");
  312. RFIFOSKIP(fd,6);
  313. }
  314. //-----------------------------------------------------
  315. // char-server packet parse [Edit: Wizputer]
  316. //-----------------------------------------------------
  317. int parse_fromchar(int fd){
  318. int id;
  319. unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr;
  320. char ip[16];
  321. sprintf(ip, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
  322. for(id = 0; id < MAX_SERVERS && id < servers_connected; id++)
  323. if (server_fd[id] == fd)
  324. break;
  325. if (id == MAX_SERVERS)
  326. session[fd]->eof = 1;
  327. if(session[fd]->eof) {
  328. if (id < MAX_SERVERS) {
  329. printf("Char-server '%s' has disconnected.\n", server[id].name);
  330. server_fd[id] = -1;
  331. memset(&server[id], 0, sizeof(struct mmo_char_server));
  332. servers_connected--;
  333. // server delete
  334. sprintf(tmpsql, "DELETE FROM `sstatus` WHERE `index`='%d'", id);
  335. sql_query(tmpsql,"parse_fromchar");
  336. }
  337. close(fd);
  338. delete_session(fd);
  339. return 0;
  340. }
  341. while(RFIFOREST(fd) >= 2) {
  342. #ifdef DEBUG_PACKETS
  343. printf("char_parse: %d %d packet case=%x\n", fd, RFIFOREST(fd), RFIFOW(fd, 0));
  344. #endif
  345. switch (RFIFOW(fd,0)) {
  346. case 0x2712:
  347. if (RFIFOREST(fd) < 19)
  348. return 0;
  349. send_account_reg(fd);
  350. break;
  351. case 0x2714:
  352. if (RFIFOREST(fd) < 6)
  353. return 0;
  354. number_world_users(fd,id);
  355. break;
  356. case 0x2716:
  357. if (RFIFOREST(fd) < 6)
  358. return 0;
  359. email_time_request(fd, id);
  360. break;
  361. case 0x2722:
  362. if (RFIFOREST(fd) < 86)
  363. return 0;
  364. change_account_email(fd, id, ip);
  365. break;
  366. case 0x2724:
  367. if (RFIFOREST(fd) < 10)
  368. return 0;
  369. status_change_request(fd);
  370. break;
  371. case 0x2725:
  372. if (RFIFOREST(fd) < 18)
  373. return 0;
  374. ban_request(fd);
  375. break;
  376. case 0x2727:
  377. if (RFIFOREST(fd) < 6)
  378. return 0;
  379. change_sex(fd);
  380. break;
  381. case 0x2728:
  382. if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
  383. return 0;
  384. save_account_reg(fd);
  385. break;
  386. case 0x272a:
  387. if (RFIFOREST(fd) < 6)
  388. return 0;
  389. unban_request(fd);
  390. return 0;
  391. case 0x272b: // Set account_id to online [Wizputer]
  392. if (RFIFOREST(fd) < 6)
  393. return 0;
  394. add_online_user(RFIFOL(fd,2));
  395. RFIFOSKIP(fd,6);
  396. break;
  397. case 0x272c: // Set account_id to offline [Wizputer]
  398. if (RFIFOREST(fd) < 6)
  399. return 0;
  400. remove_online_user(RFIFOL(fd,2));
  401. RFIFOSKIP(fd,6);
  402. break;
  403. default:
  404. #ifdef DEBUG
  405. printf("login: unknown packet %x! (from char).\n", RFIFOW(fd,0));
  406. #endif
  407. session[fd]->eof = 1;
  408. }
  409. }
  410. return 0;
  411. }