admin.c 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879
  1. #include "../common/cbasetypes.h"
  2. #include "../common/mmo.h"
  3. #include "../common/core.h"
  4. #include "../common/socket.h"
  5. #include "../common/db.h"
  6. #include "../common/timer.h"
  7. #include "../common/malloc.h"
  8. #include "../common/strlib.h"
  9. #include "../common/showmsg.h"
  10. #include "../common/version.h"
  11. #include "../common/md5calc.h"
  12. #include "../common/lock.h"
  13. #include "login.h"
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <sys/stat.h> // for stat/lstat/fstat
  18. extern struct Login_Config login_config;
  19. #define MAX_SERVERS 30
  20. extern struct mmo_char_server server[MAX_SERVERS];
  21. extern struct mmo_account* auth_dat;
  22. extern uint32 auth_num;
  23. extern int account_id_count;
  24. extern char GM_account_filename[1024];
  25. int charif_sendallwos(int sfd, unsigned char *buf, unsigned int len);
  26. int search_account_index(char* account_name);
  27. int mmo_auth_new(struct mmo_account* account);
  28. void mmo_auth_sync(void);
  29. int mmo_auth_tostr(char* str, struct mmo_account* p);
  30. int read_gm_account(void);
  31. void send_GM_accounts(int fd);
  32. int isGM(int account_id);
  33. //---------------------------------------
  34. // Packet parsing for administation login
  35. //---------------------------------------
  36. int parse_admin(int fd)
  37. {
  38. unsigned int i, j;
  39. char* account_name;
  40. uint32 ipl = session[fd]->client_addr;
  41. char ip[16];
  42. ip2str(ipl, ip);
  43. if( session[fd]->flag.eof )
  44. {
  45. do_close(fd);
  46. ShowInfo("Remote administration has disconnected (session #%d).\n", fd);
  47. return 0;
  48. }
  49. while( RFIFOREST(fd) >= 2 )
  50. {
  51. uint16 command = RFIFOW(fd,0);
  52. switch( command )
  53. {
  54. case 0x7530: // Request of the server version
  55. ShowStatus("'ladmin': Sending of the server version (ip: %s)\n", ip);
  56. WFIFOHEAD(fd,10);
  57. WFIFOW(fd,0) = 0x7531;
  58. WFIFOB(fd,2) = ATHENA_MAJOR_VERSION;
  59. WFIFOB(fd,3) = ATHENA_MINOR_VERSION;
  60. WFIFOB(fd,4) = ATHENA_REVISION;
  61. WFIFOB(fd,5) = ATHENA_RELEASE_FLAG;
  62. WFIFOB(fd,6) = ATHENA_OFFICIAL_FLAG;
  63. WFIFOB(fd,7) = ATHENA_SERVER_LOGIN;
  64. WFIFOW(fd,8) = ATHENA_MOD_VERSION;
  65. WFIFOSET(fd,10);
  66. RFIFOSKIP(fd,2);
  67. break;
  68. case 0x7920: // Request of an accounts list
  69. if (RFIFOREST(fd) < 10)
  70. return 0;
  71. {
  72. int st, ed;
  73. uint16 len;
  74. CREATE_BUFFER(id, int, auth_num);
  75. st = RFIFOL(fd,2);
  76. ed = RFIFOL(fd,6);
  77. RFIFOSKIP(fd,10);
  78. WFIFOW(fd,0) = 0x7921;
  79. if (st < 0)
  80. st = 0;
  81. if (ed > END_ACCOUNT_NUM || ed < st || ed <= 0)
  82. ed = END_ACCOUNT_NUM;
  83. ShowStatus("'ladmin': Sending an accounts list (ask: from %d to %d, ip: %s)\n", st, ed, ip);
  84. // Sort before send
  85. for(i = 0; i < auth_num; i++) {
  86. unsigned int k;
  87. id[i] = i;
  88. for(j = 0; j < i; j++) {
  89. if (auth_dat[id[i]].account_id < auth_dat[id[j]].account_id) {
  90. for(k = i; k > j; k--) {
  91. id[k] = id[k-1];
  92. }
  93. id[j] = i; // id[i]
  94. break;
  95. }
  96. }
  97. }
  98. // Sending accounts information
  99. len = 4;
  100. for(i = 0; i < auth_num && len < 30000; i++) {
  101. int account_id = auth_dat[id[i]].account_id; // use sorted index
  102. if (account_id >= st && account_id <= ed) {
  103. j = id[i];
  104. WFIFOL(fd,len) = account_id;
  105. WFIFOB(fd,len+4) = (unsigned char)isGM(account_id);
  106. memcpy(WFIFOP(fd,len+5), auth_dat[j].userid, 24);
  107. WFIFOB(fd,len+29) = auth_dat[j].sex;
  108. WFIFOL(fd,len+30) = auth_dat[j].logincount;
  109. if (auth_dat[j].state == 0 && auth_dat[j].unban_time != 0) // if no state and banished
  110. WFIFOL(fd,len+34) = 7; // 6 = Your are Prohibited to log in until %s
  111. else
  112. WFIFOL(fd,len+34) = auth_dat[j].state;
  113. len += 38;
  114. }
  115. }
  116. WFIFOW(fd,2) = len;
  117. WFIFOSET(fd,len);
  118. //if (id) free(id);
  119. DELETE_BUFFER(id);
  120. }
  121. break;
  122. case 0x7930: // Request for an account creation
  123. if (RFIFOREST(fd) < 91)
  124. return 0;
  125. {
  126. struct mmo_account ma;
  127. safestrncpy(ma.userid, (char*)RFIFOP(fd, 2), NAME_LENGTH);
  128. safestrncpy(ma.pass, (char*)RFIFOP(fd,26), NAME_LENGTH);
  129. safestrncpy(ma.email, (char*)RFIFOP(fd,51), 40);
  130. memcpy(ma.lastlogin, "-", 2);
  131. ma.sex = RFIFOB(fd,50);
  132. RFIFOSKIP(fd,91);
  133. WFIFOW(fd,0) = 0x7931;
  134. WFIFOL(fd,2) = 0xffffffff; // invalid account id
  135. safestrncpy((char*)WFIFOP(fd,6), ma.userid, 24);
  136. if (strlen(ma.userid) < 4 || strlen(ma.pass) < 4) {
  137. ShowNotice("'ladmin': Attempt to create an invalid account (account or pass is too short, ip: %s)\n", ip);
  138. } else if (ma.sex != 'F' && ma.sex != 'M') {
  139. ShowNotice("'ladmin': Attempt to create an invalid account (account: %s, received pass: %s, invalid sex, ip: %s)\n", ma.userid, ma.pass, ip);
  140. } else if (account_id_count > END_ACCOUNT_NUM) {
  141. ShowNotice("'ladmin': Attempt to create an account, but there is no more available id number (account: %s, pass: %s, sex: %c, ip: %s)\n", ma.userid, ma.pass, ma.sex, ip);
  142. } else {
  143. remove_control_chars(ma.userid);
  144. remove_control_chars(ma.pass);
  145. remove_control_chars(ma.email);
  146. ARR_FIND( 0, auth_num, i, strncmp(auth_dat[i].userid, ma.userid, 24) == 0 );
  147. if( i < auth_num )
  148. ShowNotice("'ladmin': Attempt to create an already existing account (account: %s, pass: %s, received pass: %s, ip: %s)\n", auth_dat[i].userid, auth_dat[i].pass, ma.pass, ip);
  149. else
  150. {
  151. int new_id;
  152. new_id = mmo_auth_new(&ma);
  153. ShowNotice("'ladmin': Account creation (account: %s (id: %d), pass: %s, sex: %c, email: %s, ip: %s)\n", ma.userid, new_id, ma.pass, ma.sex, auth_dat[i].email, ip);
  154. WFIFOL(fd,2) = new_id;
  155. mmo_auth_sync();
  156. }
  157. }
  158. WFIFOSET(fd,30);
  159. }
  160. break;
  161. case 0x7932: // Request for an account deletion
  162. if (RFIFOREST(fd) < 26)
  163. return 0;
  164. WFIFOW(fd,0) = 0x7933;
  165. WFIFOL(fd,2) = 0xFFFFFFFF;
  166. account_name = (char*)RFIFOP(fd,2);
  167. account_name[23] = '\0';
  168. remove_control_chars(account_name);
  169. i = search_account_index(account_name);
  170. if (i != -1) {
  171. // Char-server is notified of deletion (for characters deletion).
  172. unsigned char buf[65535];
  173. WBUFW(buf,0) = 0x2730;
  174. WBUFL(buf,2) = auth_dat[i].account_id;
  175. charif_sendallwos(-1, buf, 6);
  176. // send answer
  177. memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
  178. WFIFOL(fd,2) = auth_dat[i].account_id;
  179. // save deleted account in log file
  180. ShowNotice("'ladmin': Account deletion (account: %s, id: %d, ip: %s) - saved in next line:\n", auth_dat[i].userid, auth_dat[i].account_id, ip);
  181. mmo_auth_tostr((char*)buf, &auth_dat[i]);
  182. ShowNotice("%s\n", buf);
  183. // delete account
  184. memset(auth_dat[i].userid, '\0', sizeof(auth_dat[i].userid));
  185. auth_dat[i].account_id = -1;
  186. mmo_auth_sync();
  187. } else {
  188. memcpy(WFIFOP(fd,6), account_name, 24);
  189. ShowNotice("'ladmin': Attempt to delete an unknown account (account: %s, ip: %s)\n", account_name, ip);
  190. }
  191. WFIFOSET(fd,30);
  192. RFIFOSKIP(fd,26);
  193. break;
  194. case 0x7934: // Request to change a password
  195. if (RFIFOREST(fd) < 50)
  196. return 0;
  197. WFIFOW(fd,0) = 0x7935;
  198. WFIFOL(fd,2) = 0xFFFFFFFF; /// WTF??? an unsigned being set to a -1
  199. account_name = (char*)RFIFOP(fd,2);
  200. account_name[23] = '\0';
  201. remove_control_chars(account_name);
  202. i = search_account_index(account_name);
  203. if (i != -1) {
  204. memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
  205. memcpy(auth_dat[i].pass, RFIFOP(fd,26), 24);
  206. auth_dat[i].pass[23] = '\0';
  207. remove_control_chars(auth_dat[i].pass);
  208. WFIFOL(fd,2) = auth_dat[i].account_id;
  209. ShowNotice("'ladmin': Modification of a password (account: %s, new password: %s, ip: %s)\n", auth_dat[i].userid, auth_dat[i].pass, ip);
  210. mmo_auth_sync();
  211. } else {
  212. memcpy(WFIFOP(fd,6), account_name, 24);
  213. ShowNotice("'ladmin': Attempt to modify the password of an unknown account (account: %s, ip: %s)\n", account_name, ip);
  214. }
  215. WFIFOSET(fd,30);
  216. RFIFOSKIP(fd,50);
  217. break;
  218. case 0x7936: // Request to modify a state
  219. if (RFIFOREST(fd) < 50)
  220. return 0;
  221. {
  222. char error_message[20];
  223. uint32 statut;
  224. WFIFOW(fd,0) = 0x7937;
  225. WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
  226. account_name = (char*)RFIFOP(fd,2);
  227. account_name[23] = '\0';
  228. remove_control_chars(account_name);
  229. statut = RFIFOL(fd,26);
  230. memcpy(error_message, RFIFOP(fd,30), 20);
  231. error_message[19] = '\0';
  232. remove_control_chars(error_message);
  233. if (statut != 7 || error_message[0] == '\0') { // 7: // 6 = Your are Prohibited to log in until %s
  234. strcpy(error_message, "-");
  235. }
  236. i = search_account_index(account_name);
  237. if (i != -1) {
  238. memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
  239. WFIFOL(fd,2) = auth_dat[i].account_id;
  240. if (auth_dat[i].state == statut && strcmp(auth_dat[i].error_message, error_message) == 0)
  241. ShowNotice("'ladmin': Modification of a state, but the state of the account is already the good state (account: %s, received state: %d, ip: %s)\n", account_name, statut, ip);
  242. else {
  243. if (statut == 7)
  244. ShowNotice("'ladmin': Modification of a state (account: %s, new state: %d - prohibited to login until '%s', ip: %s)\n", auth_dat[i].userid, statut, error_message, ip);
  245. else
  246. ShowNotice("'ladmin': Modification of a state (account: %s, new state: %d, ip: %s)\n", auth_dat[i].userid, statut, ip);
  247. if (auth_dat[i].state == 0) {
  248. unsigned char buf[16];
  249. WBUFW(buf,0) = 0x2731;
  250. WBUFL(buf,2) = auth_dat[i].account_id;
  251. WBUFB(buf,6) = 0; // 0: change of statut, 1: ban
  252. WBUFL(buf,7) = statut; // status or final date of a banishment
  253. charif_sendallwos(-1, buf, 11);
  254. }
  255. auth_dat[i].state = statut;
  256. memcpy(auth_dat[i].error_message, error_message, 20);
  257. mmo_auth_sync();
  258. }
  259. } else {
  260. memcpy(WFIFOP(fd,6), account_name, 24);
  261. ShowNotice("'ladmin': Attempt to modify the state of an unknown account (account: %s, received state: %d, ip: %s)\n", account_name, statut, ip);
  262. }
  263. WFIFOL(fd,30) = statut;
  264. }
  265. WFIFOSET(fd,34);
  266. RFIFOSKIP(fd,50);
  267. break;
  268. case 0x7938: // Request for servers list and # of online players
  269. {
  270. uint8 server_num = 0;
  271. ShowStatus("'ladmin': Sending of servers list (ip: %s)\n", ip);
  272. for(i = 0; i < MAX_SERVERS; i++) {
  273. if (server[i].fd >= 0) {
  274. WFIFOL(fd,4+server_num*32) = htonl(server[i].ip);
  275. WFIFOW(fd,4+server_num*32+4) = htons(server[i].port);
  276. memcpy(WFIFOP(fd,4+server_num*32+6), server[i].name, 20);
  277. WFIFOW(fd,4+server_num*32+26) = server[i].users;
  278. WFIFOW(fd,4+server_num*32+28) = server[i].maintenance;
  279. WFIFOW(fd,4+server_num*32+30) = server[i].new_;
  280. server_num++;
  281. }
  282. }
  283. WFIFOW(fd,0) = 0x7939;
  284. WFIFOW(fd,2) = 4 + 32 * server_num;
  285. WFIFOSET(fd,4+32*server_num);
  286. RFIFOSKIP(fd,2);
  287. break;
  288. }
  289. case 0x793a: // Request to password check
  290. if (RFIFOREST(fd) < 50)
  291. return 0;
  292. WFIFOW(fd,0) = 0x793b;
  293. WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
  294. account_name = (char*)RFIFOP(fd,2);
  295. account_name[23] = '\0';
  296. remove_control_chars(account_name);
  297. i = search_account_index(account_name);
  298. if (i != -1) {
  299. char pass[25];
  300. memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
  301. memcpy(pass, RFIFOP(fd,26), 24);
  302. pass[24] = '\0';
  303. remove_control_chars(pass);
  304. if (strcmp(auth_dat[i].pass, pass) == 0) {
  305. WFIFOL(fd,2) = auth_dat[i].account_id;
  306. ShowNotice("'ladmin': Check of password OK (account: %s, password: %s, ip: %s)\n", auth_dat[i].userid, auth_dat[i].pass, ip);
  307. } else {
  308. ShowNotice("'ladmin': Failure of password check (account: %s, proposed pass: %s, ip: %s)\n", auth_dat[i].userid, pass, ip);
  309. }
  310. } else {
  311. memcpy(WFIFOP(fd,6), account_name, 24);
  312. ShowNotice("'ladmin': Attempt to check the password of an unknown account (account: %s, ip: %s)\n", account_name, ip);
  313. }
  314. WFIFOSET(fd,30);
  315. RFIFOSKIP(fd,50);
  316. break;
  317. case 0x793c: // Request to modify sex
  318. if (RFIFOREST(fd) < 27)
  319. return 0;
  320. WFIFOW(fd,0) = 0x793d;
  321. WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
  322. account_name = (char*)RFIFOP(fd,2);
  323. account_name[23] = '\0';
  324. remove_control_chars(account_name);
  325. memcpy(WFIFOP(fd,6), account_name, 24);
  326. {
  327. char sex;
  328. sex = RFIFOB(fd,26);
  329. if (sex != 'F' && sex != 'M') {
  330. if (sex > 31)
  331. ShowNotice("'ladmin': Attempt to give an invalid sex (account: %s, received sex: %c, ip: %s)\n", account_name, sex, ip);
  332. else
  333. ShowNotice("'ladmin': Attempt to give an invalid sex (account: %s, received sex: 'control char', ip: %s)\n", account_name, ip);
  334. } else {
  335. i = search_account_index(account_name);
  336. if (i != -1) {
  337. memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
  338. if (auth_dat[i].sex != ((sex == 'S' || sex == 's') ? 2 : (sex == 'M' || sex == 'm'))) {
  339. unsigned char buf[16];
  340. WFIFOL(fd,2) = auth_dat[i].account_id;
  341. auth_dat[i].sex = (sex == 'S' || sex == 's') ? 2 : (sex == 'M' || sex == 'm');
  342. ShowNotice("'ladmin': Modification of a sex (account: %s, new sex: %c, ip: %s)\n", auth_dat[i].userid, sex, ip);
  343. mmo_auth_sync();
  344. // send to all char-server the change
  345. WBUFW(buf,0) = 0x2723;
  346. WBUFL(buf,2) = auth_dat[i].account_id;
  347. WBUFB(buf,6) = auth_dat[i].sex;
  348. charif_sendallwos(-1, buf, 7);
  349. } else {
  350. ShowNotice("'ladmin': Modification of a sex, but the sex is already the good sex (account: %s, sex: %c, ip: %s)\n", auth_dat[i].userid, sex, ip);
  351. }
  352. } else {
  353. ShowNotice("'ladmin': Attempt to modify the sex of an unknown account (account: %s, received sex: %c, ip: %s)\n", account_name, sex, ip);
  354. }
  355. }
  356. }
  357. WFIFOSET(fd,30);
  358. RFIFOSKIP(fd,27);
  359. break;
  360. case 0x793e: // Request to modify GM level
  361. if (RFIFOREST(fd) < 27)
  362. return 0;
  363. WFIFOW(fd,0) = 0x793f;
  364. WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
  365. account_name = (char*)RFIFOP(fd,2);
  366. account_name[23] = '\0';
  367. remove_control_chars(account_name);
  368. memcpy(WFIFOP(fd,6), account_name, 24);
  369. {
  370. char new_gm_level;
  371. new_gm_level = RFIFOB(fd,26);
  372. if (new_gm_level < 0 || new_gm_level > 99) {
  373. ShowNotice("'ladmin': Attempt to give an invalid GM level (account: %s, received GM level: %d, ip: %s)\n", account_name, (int)new_gm_level, ip);
  374. } else {
  375. i = search_account_index(account_name);
  376. if (i != -1) {
  377. int acc = auth_dat[i].account_id;
  378. memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
  379. if (isGM(acc) != new_gm_level) {
  380. // modification of the file
  381. FILE *fp, *fp2;
  382. int lock;
  383. char line[512];
  384. int GM_account, GM_level;
  385. int modify_flag;
  386. char tmpstr[24];
  387. time_t raw_time;
  388. if ((fp2 = lock_fopen(GM_account_filename, &lock)) != NULL) {
  389. if ((fp = fopen(GM_account_filename, "r")) != NULL) {
  390. time(&raw_time);
  391. strftime(tmpstr, 23, login_config.date_format, localtime(&raw_time));
  392. modify_flag = 0;
  393. // read/write GM file
  394. while(fgets(line, sizeof(line), fp))
  395. {
  396. while(line[0] != '\0' && (line[strlen(line)-1] == '\n' || line[strlen(line)-1] == '\r'))
  397. line[strlen(line)-1] = '\0'; // TODO: remove this
  398. if ((line[0] == '/' && line[1] == '/') || line[0] == '\0')
  399. fprintf(fp2, "%s\n", line);
  400. else {
  401. if (sscanf(line, "%d %d", &GM_account, &GM_level) != 2 && sscanf(line, "%d: %d", &GM_account, &GM_level) != 2)
  402. fprintf(fp2, "%s\n", line);
  403. else if (GM_account != acc)
  404. fprintf(fp2, "%s\n", line);
  405. else if (new_gm_level < 1) {
  406. fprintf(fp2, "// %s: 'ladmin' GM level removed on account %d '%s' (previous level: %d)\n//%d %d\n", tmpstr, acc, auth_dat[i].userid, GM_level, acc, new_gm_level);
  407. modify_flag = 1;
  408. } else {
  409. fprintf(fp2, "// %s: 'ladmin' GM level on account %d '%s' (previous level: %d)\n%d %d\n", tmpstr, acc, auth_dat[i].userid, GM_level, acc, new_gm_level);
  410. modify_flag = 1;
  411. }
  412. }
  413. }
  414. if (modify_flag == 0)
  415. fprintf(fp2, "// %s: 'ladmin' GM level on account %d '%s' (previous level: 0)\n%d %d\n", tmpstr, acc, auth_dat[i].userid, acc, new_gm_level);
  416. fclose(fp);
  417. } else {
  418. ShowNotice("'ladmin': Attempt to modify of a GM level - impossible to read GM accounts file (account: %s (%d), received GM level: %d, ip: %s)\n", auth_dat[i].userid, acc, (int)new_gm_level, ip);
  419. }
  420. if (lock_fclose(fp2, GM_account_filename, &lock) == 0) {
  421. WFIFOL(fd,2) = acc;
  422. ShowNotice("'ladmin': Modification of a GM level (account: %s (%d), new GM level: %d, ip: %s)\n", auth_dat[i].userid, acc, (int)new_gm_level, ip);
  423. // read and send new GM informations
  424. read_gm_account();
  425. send_GM_accounts(-1);
  426. } else {
  427. ShowNotice("'ladmin': Attempt to modify of a GM level - impossible to write GM accounts file (account: %s (%d), received GM level: %d, ip: %s)\n", auth_dat[i].userid, acc, (int)new_gm_level, ip);
  428. }
  429. } else {
  430. ShowNotice("'ladmin': Attempt to modify of a GM level - impossible to write GM accounts file (account: %s (%d), received GM level: %d, ip: %s)\n", auth_dat[i].userid, acc, (int)new_gm_level, ip);
  431. }
  432. } else {
  433. ShowNotice("'ladmin': Attempt to modify of a GM level, but the GM level is already the good GM level (account: %s (%d), GM level: %d, ip: %s)\n", auth_dat[i].userid, acc, (int)new_gm_level, ip);
  434. }
  435. } else {
  436. ShowNotice("'ladmin': Attempt to modify the GM level of an unknown account (account: %s, received GM level: %d, ip: %s)\n", account_name, (int)new_gm_level, ip);
  437. }
  438. }
  439. }
  440. WFIFOSET(fd,30);
  441. RFIFOSKIP(fd,27);
  442. break;
  443. case 0x7940: // Request to modify e-mail
  444. if (RFIFOREST(fd) < 66)
  445. return 0;
  446. WFIFOW(fd,0) = 0x7941;
  447. WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
  448. account_name = (char*)RFIFOP(fd,2);
  449. account_name[23] = '\0';
  450. remove_control_chars(account_name);
  451. memcpy(WFIFOP(fd,6), account_name, 24);
  452. {
  453. char email[40];
  454. memcpy(email, RFIFOP(fd,26), 40);
  455. if (e_mail_check(email) == 0) {
  456. ShowNotice("'ladmin': Attempt to give an invalid e-mail (account: %s, ip: %s)\n", account_name, ip);
  457. } else {
  458. remove_control_chars(email);
  459. i = search_account_index(account_name);
  460. if (i != -1) {
  461. memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
  462. memcpy(auth_dat[i].email, email, 40);
  463. WFIFOL(fd,2) = auth_dat[i].account_id;
  464. ShowNotice("'ladmin': Modification of an email (account: %s, new e-mail: %s, ip: %s)\n", auth_dat[i].userid, email, ip);
  465. mmo_auth_sync();
  466. } else {
  467. ShowNotice("'ladmin': Attempt to modify the e-mail of an unknown account (account: %s, received e-mail: %s, ip: %s)\n", account_name, email, ip);
  468. }
  469. }
  470. }
  471. WFIFOSET(fd,30);
  472. RFIFOSKIP(fd,66);
  473. break;
  474. case 0x7942: // Request to modify memo field
  475. if ((int)RFIFOREST(fd) < 28 || (int)RFIFOREST(fd) < (28 + RFIFOW(fd,26)))
  476. return 0;
  477. WFIFOW(fd,0) = 0x7943;
  478. WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
  479. account_name = (char*)RFIFOP(fd,2);
  480. account_name[23] = '\0';
  481. remove_control_chars(account_name);
  482. i = search_account_index(account_name);
  483. if (i != -1) {
  484. int size_of_memo = sizeof(auth_dat[i].memo);
  485. memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
  486. memset(auth_dat[i].memo, '\0', size_of_memo);
  487. if (RFIFOW(fd,26) == 0) {
  488. strncpy(auth_dat[i].memo, "-", size_of_memo);
  489. } else if (RFIFOW(fd,26) > size_of_memo - 1) {
  490. memcpy(auth_dat[i].memo, RFIFOP(fd,28), size_of_memo - 1);
  491. } else {
  492. memcpy(auth_dat[i].memo, RFIFOP(fd,28), RFIFOW(fd,26));
  493. }
  494. auth_dat[i].memo[size_of_memo - 1] = '\0';
  495. remove_control_chars(auth_dat[i].memo);
  496. WFIFOL(fd,2) = auth_dat[i].account_id;
  497. ShowNotice("'ladmin': Modification of a memo field (account: %s, new memo: %s, ip: %s)\n", auth_dat[i].userid, auth_dat[i].memo, ip);
  498. mmo_auth_sync();
  499. } else {
  500. memcpy(WFIFOP(fd,6), account_name, 24);
  501. ShowNotice("'ladmin': Attempt to modify the memo field of an unknown account (account: %s, ip: %s)\n", account_name, ip);
  502. }
  503. WFIFOSET(fd,30);
  504. RFIFOSKIP(fd,28 + RFIFOW(fd,26));
  505. break;
  506. case 0x7944: // Request to found an account id
  507. if (RFIFOREST(fd) < 26)
  508. return 0;
  509. WFIFOW(fd,0) = 0x7945;
  510. WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
  511. account_name = (char*)RFIFOP(fd,2);
  512. account_name[23] = '\0';
  513. remove_control_chars(account_name);
  514. i = search_account_index(account_name);
  515. if (i != -1) {
  516. memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
  517. WFIFOL(fd,2) = auth_dat[i].account_id;
  518. ShowNotice("'ladmin': Request (by the name) of an account id (account: %s, id: %d, ip: %s)\n", auth_dat[i].userid, auth_dat[i].account_id, ip);
  519. } else {
  520. memcpy(WFIFOP(fd,6), account_name, 24);
  521. ShowNotice("'ladmin': ID request (by the name) of an unknown account (account: %s, ip: %s)\n", account_name, ip);
  522. }
  523. WFIFOSET(fd,30);
  524. RFIFOSKIP(fd,26);
  525. break;
  526. case 0x7946: // Request to found an account name
  527. if (RFIFOREST(fd) < 6)
  528. return 0;
  529. WFIFOW(fd,0) = 0x7947;
  530. WFIFOL(fd,2) = RFIFOL(fd,2);
  531. memset(WFIFOP(fd,6), '\0', 24);
  532. for(i = 0; i < auth_num; i++) {
  533. if (auth_dat[i].account_id == (int)RFIFOL(fd,2)) {
  534. strncpy((char*)WFIFOP(fd,6), auth_dat[i].userid, 24);
  535. ShowNotice("'ladmin': Request (by id) of an account name (account: %s, id: %d, ip: %s)\n", auth_dat[i].userid, RFIFOL(fd,2), ip);
  536. break;
  537. }
  538. }
  539. if (i == auth_num) {
  540. ShowNotice("'ladmin': Name request (by id) of an unknown account (id: %d, ip: %s)\n", RFIFOL(fd,2), ip);
  541. strncpy((char*)WFIFOP(fd,6), "", 24);
  542. }
  543. WFIFOSET(fd,30);
  544. RFIFOSKIP(fd,6);
  545. break;
  546. case 0x7948: // Request to change the validity limit (timestamp) (absolute value)
  547. if (RFIFOREST(fd) < 30)
  548. return 0;
  549. {
  550. time_t timestamp;
  551. char tmpstr[2048];
  552. WFIFOW(fd,0) = 0x7949;
  553. WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
  554. account_name = (char*)RFIFOP(fd,2);
  555. account_name[23] = '\0';
  556. remove_control_chars(account_name);
  557. timestamp = (time_t)RFIFOL(fd,26);
  558. strftime(tmpstr, 24, login_config.date_format, localtime(&timestamp));
  559. i = search_account_index(account_name);
  560. if (i != -1) {
  561. memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
  562. ShowNotice("'ladmin': Change of a validity limit (account: %s, new validity: %d (%s), ip: %s)\n", auth_dat[i].userid, timestamp, (timestamp == 0 ? "unlimited" : tmpstr), ip);
  563. auth_dat[i].expiration_time = timestamp;
  564. WFIFOL(fd,2) = auth_dat[i].account_id;
  565. mmo_auth_sync();
  566. } else {
  567. memcpy(WFIFOP(fd,6), account_name, 24);
  568. ShowNotice("'ladmin': Attempt to change the validity limit of an unknown account (account: %s, received validity: %d (%s), ip: %s)\n", account_name, timestamp, (timestamp == 0 ? "unlimited" : tmpstr), ip);
  569. }
  570. WFIFOL(fd,30) = (unsigned int)timestamp;
  571. }
  572. WFIFOSET(fd,34);
  573. RFIFOSKIP(fd,30);
  574. break;
  575. case 0x794a: // Request to change the final date of a banishment (timestamp) (absolute value)
  576. if (RFIFOREST(fd) < 30)
  577. return 0;
  578. {
  579. time_t timestamp;
  580. char tmpstr[2048];
  581. WFIFOW(fd,0) = 0x794b;
  582. WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
  583. account_name = (char*)RFIFOP(fd,2);
  584. account_name[23] = '\0';
  585. remove_control_chars(account_name);
  586. timestamp = (time_t)RFIFOL(fd,26);
  587. if (timestamp <= time(NULL))
  588. timestamp = 0;
  589. strftime(tmpstr, 24, login_config.date_format, localtime(&timestamp));
  590. i = search_account_index(account_name);
  591. if (i != -1) {
  592. memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
  593. WFIFOL(fd,2) = auth_dat[i].account_id;
  594. ShowNotice("'ladmin': Change of the final date of a banishment (account: %s, new final date of banishment: %d (%s), ip: %s)\n", auth_dat[i].userid, timestamp, (timestamp == 0 ? "no banishment" : tmpstr), ip);
  595. if (auth_dat[i].unban_time != timestamp) {
  596. if (timestamp != 0) {
  597. unsigned char buf[16];
  598. WBUFW(buf,0) = 0x2731;
  599. WBUFL(buf,2) = auth_dat[i].account_id;
  600. WBUFB(buf,6) = 1; // 0: change of statut, 1: ban
  601. WBUFL(buf,7) = (unsigned int)timestamp; // status or final date of a banishment
  602. charif_sendallwos(-1, buf, 11);
  603. }
  604. auth_dat[i].unban_time = timestamp;
  605. mmo_auth_sync();
  606. }
  607. } else {
  608. memcpy(WFIFOP(fd,6), account_name, 24);
  609. ShowNotice("'ladmin': Attempt to change the final date of a banishment of an unknown account (account: %s, received final date of banishment: %d (%s), ip: %s)\n", account_name, timestamp, (timestamp == 0 ? "no banishment" : tmpstr), ip);
  610. }
  611. WFIFOL(fd,30) = (unsigned int)timestamp;
  612. }
  613. WFIFOSET(fd,34);
  614. RFIFOSKIP(fd,30);
  615. break;
  616. case 0x794c: // Request to change the final date of a banishment (timestamp) (relative change)
  617. if (RFIFOREST(fd) < 38)
  618. return 0;
  619. {
  620. time_t timestamp;
  621. struct tm *tmtime;
  622. char tmpstr[2048];
  623. WFIFOW(fd,0) = 0x794d;
  624. WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
  625. account_name = (char*)RFIFOP(fd,2);
  626. account_name[23] = '\0';
  627. remove_control_chars(account_name);
  628. i = search_account_index(account_name);
  629. if (i != -1) {
  630. WFIFOL(fd,2) = auth_dat[i].account_id;
  631. memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
  632. if (auth_dat[i].unban_time == 0 || auth_dat[i].unban_time < time(NULL))
  633. timestamp = time(NULL);
  634. else
  635. timestamp = auth_dat[i].unban_time;
  636. tmtime = localtime(&timestamp);
  637. tmtime->tm_year = tmtime->tm_year + (short)RFIFOW(fd,26);
  638. tmtime->tm_mon = tmtime->tm_mon + (short)RFIFOW(fd,28);
  639. tmtime->tm_mday = tmtime->tm_mday + (short)RFIFOW(fd,30);
  640. tmtime->tm_hour = tmtime->tm_hour + (short)RFIFOW(fd,32);
  641. tmtime->tm_min = tmtime->tm_min + (short)RFIFOW(fd,34);
  642. tmtime->tm_sec = tmtime->tm_sec + (short)RFIFOW(fd,36);
  643. timestamp = mktime(tmtime);
  644. if (timestamp != -1) {
  645. if (timestamp <= time(NULL))
  646. timestamp = 0;
  647. strftime(tmpstr, 24, login_config.date_format, localtime(&timestamp));
  648. ShowNotice("'ladmin': Adjustment of a final date of a banishment (account: %s, (%+d y %+d m %+d d %+d h %+d mn %+d s) -> new validity: %d (%s), ip: %s)\n", auth_dat[i].userid, (short)RFIFOW(fd,26), (short)RFIFOW(fd,28), (short)RFIFOW(fd,30), (short)RFIFOW(fd,32), (short)RFIFOW(fd,34), (short)RFIFOW(fd,36), timestamp, (timestamp == 0 ? "no banishment" : tmpstr), ip);
  649. if (auth_dat[i].unban_time != timestamp) {
  650. if (timestamp != 0) {
  651. unsigned char buf[16];
  652. WBUFW(buf,0) = 0x2731;
  653. WBUFL(buf,2) = auth_dat[i].account_id;
  654. WBUFB(buf,6) = 1; // 0: change of statut, 1: ban
  655. WBUFL(buf,7) = (unsigned int)timestamp; // status or final date of a banishment
  656. charif_sendallwos(-1, buf, 11);
  657. }
  658. auth_dat[i].unban_time = timestamp;
  659. mmo_auth_sync();
  660. }
  661. } else {
  662. strftime(tmpstr, 24, login_config.date_format, localtime(&auth_dat[i].unban_time));
  663. ShowNotice("'ladmin': Impossible to adjust the final date of a banishment (account: %s, %d (%s) + (%+d y %+d m %+d d %+d h %+d mn %+d s) -> ???, ip: %s)\n", auth_dat[i].userid, auth_dat[i].unban_time, (auth_dat[i].unban_time == 0 ? "no banishment" : tmpstr), (short)RFIFOW(fd,26), (short)RFIFOW(fd,28), (short)RFIFOW(fd,30), (short)RFIFOW(fd,32), (short)RFIFOW(fd,34), (short)RFIFOW(fd,36), ip);
  664. }
  665. WFIFOL(fd,30) = (unsigned long)auth_dat[i].unban_time;
  666. } else {
  667. memcpy(WFIFOP(fd,6), account_name, 24);
  668. ShowNotice("'ladmin': Attempt to adjust the final date of a banishment of an unknown account (account: %s, ip: %s)\n", account_name, ip);
  669. WFIFOL(fd,30) = 0;
  670. }
  671. }
  672. WFIFOSET(fd,34);
  673. RFIFOSKIP(fd,38);
  674. break;
  675. case 0x794e: // Request to send a broadcast message
  676. if (RFIFOREST(fd) < 8 || RFIFOREST(fd) < (8 + RFIFOL(fd,4)))
  677. return 0;
  678. WFIFOW(fd,0) = 0x794f;
  679. WFIFOW(fd,2) = 0xFFFF; // WTF???
  680. if (RFIFOL(fd,4) < 1) {
  681. ShowNotice("'ladmin': Receiving a message for broadcast, but message is void (ip: %s)\n", ip);
  682. } else {
  683. // at least 1 char-server
  684. for(i = 0; i < MAX_SERVERS; i++)
  685. if (server[i].fd >= 0)
  686. break;
  687. if (i == MAX_SERVERS) {
  688. ShowNotice("'ladmin': Receiving a message for broadcast, but no char-server is online (ip: %s)\n", ip);
  689. } else {
  690. unsigned char buf[32000];
  691. char message[32000];
  692. WFIFOW(fd,2) = 0;
  693. memset(message, '\0', sizeof(message));
  694. memcpy(message, RFIFOP(fd,8), RFIFOL(fd,4));
  695. message[sizeof(message)-1] = '\0';
  696. remove_control_chars(message);
  697. if (RFIFOW(fd,2) == 0)
  698. ShowNotice("'ladmin': Receiving a message for broadcast (message (in yellow): %s, ip: %s)\n", message, ip);
  699. else
  700. ShowNotice("'ladmin': Receiving a message for broadcast (message (in blue): %s, ip: %s)\n", message, ip);
  701. // send same message to all char-servers (no answer)
  702. memcpy(WBUFP(buf,0), RFIFOP(fd,0), 8 + RFIFOL(fd,4));
  703. WBUFW(buf,0) = 0x2726;
  704. charif_sendallwos(-1, buf, 8 + RFIFOL(fd,4));
  705. }
  706. }
  707. WFIFOSET(fd,4);
  708. RFIFOSKIP(fd,8 + RFIFOL(fd,4));
  709. break;
  710. case 0x7950: // Request to change the validity limite (timestamp) (relative change)
  711. if (RFIFOREST(fd) < 38)
  712. return 0;
  713. {
  714. time_t timestamp;
  715. struct tm *tmtime;
  716. char tmpstr[2048];
  717. char tmpstr2[2048];
  718. WFIFOW(fd,0) = 0x7951;
  719. WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
  720. account_name = (char*)RFIFOP(fd,2);
  721. account_name[23] = '\0';
  722. remove_control_chars(account_name);
  723. i = search_account_index(account_name);
  724. if (i != -1) {
  725. WFIFOL(fd,2) = auth_dat[i].account_id;
  726. memcpy(WFIFOP(fd,6), auth_dat[i].userid, 24);
  727. timestamp = auth_dat[i].expiration_time;
  728. if (timestamp == 0 || timestamp < time(NULL))
  729. timestamp = time(NULL);
  730. tmtime = localtime(&timestamp);
  731. tmtime->tm_year = tmtime->tm_year + (short)RFIFOW(fd,26);
  732. tmtime->tm_mon = tmtime->tm_mon + (short)RFIFOW(fd,28);
  733. tmtime->tm_mday = tmtime->tm_mday + (short)RFIFOW(fd,30);
  734. tmtime->tm_hour = tmtime->tm_hour + (short)RFIFOW(fd,32);
  735. tmtime->tm_min = tmtime->tm_min + (short)RFIFOW(fd,34);
  736. tmtime->tm_sec = tmtime->tm_sec + (short)RFIFOW(fd,36);
  737. timestamp = mktime(tmtime);
  738. if (timestamp != -1) {
  739. strftime(tmpstr, 24, login_config.date_format, localtime(&auth_dat[i].expiration_time));
  740. strftime(tmpstr2, 24, login_config.date_format, localtime(&timestamp));
  741. ShowNotice("'ladmin': Adjustment of a validity limit (account: %s, %d (%s) + (%+d y %+d m %+d d %+d h %+d mn %+d s) -> new validity: %d (%s), ip: %s)\n", auth_dat[i].userid, auth_dat[i].expiration_time, (auth_dat[i].expiration_time == 0 ? "unlimited" : tmpstr), (short)RFIFOW(fd,26), (short)RFIFOW(fd,28), (short)RFIFOW(fd,30), (short)RFIFOW(fd,32), (short)RFIFOW(fd,34), (short)RFIFOW(fd,36), timestamp, (timestamp == 0 ? "unlimited" : tmpstr2), ip);
  742. auth_dat[i].expiration_time = timestamp;
  743. mmo_auth_sync();
  744. WFIFOL(fd,30) = (unsigned long)auth_dat[i].expiration_time;
  745. } else {
  746. strftime(tmpstr, 24, login_config.date_format, localtime(&auth_dat[i].expiration_time));
  747. ShowNotice("'ladmin': Impossible to adjust a validity limit (account: %s, %d (%s) + (%+d y %+d m %+d d %+d h %+d mn %+d s) -> ???, ip: %s)\n", auth_dat[i].userid, auth_dat[i].expiration_time, (auth_dat[i].expiration_time == 0 ? "unlimited" : tmpstr), (short)RFIFOW(fd,26), (short)RFIFOW(fd,28), (short)RFIFOW(fd,30), (short)RFIFOW(fd,32), (short)RFIFOW(fd,34), (short)RFIFOW(fd,36), ip);
  748. WFIFOL(fd,30) = 0;
  749. }
  750. } else {
  751. memcpy(WFIFOP(fd,6), account_name, 24);
  752. ShowNotice("'ladmin': Attempt to adjust the validity limit of an unknown account (account: %s, ip: %s)\n", account_name, ip);
  753. WFIFOL(fd,30) = 0;
  754. }
  755. }
  756. WFIFOSET(fd,34);
  757. RFIFOSKIP(fd,38);
  758. break;
  759. case 0x7952: // Request about informations of an account (by account name)
  760. if (RFIFOREST(fd) < 26)
  761. return 0;
  762. WFIFOW(fd,0) = 0x7953;
  763. WFIFOL(fd,2) = 0xFFFFFFFF; // WTF???
  764. account_name = (char*)RFIFOP(fd,2);
  765. account_name[23] = '\0';
  766. remove_control_chars(account_name);
  767. i = search_account_index(account_name);
  768. if (i != -1) {
  769. WFIFOL(fd,2) = auth_dat[i].account_id;
  770. WFIFOB(fd,6) = (unsigned char)isGM(auth_dat[i].account_id);
  771. memcpy(WFIFOP(fd,7), auth_dat[i].userid, 24);
  772. WFIFOB(fd,31) = auth_dat[i].sex;
  773. WFIFOL(fd,32) = auth_dat[i].logincount;
  774. WFIFOL(fd,36) = auth_dat[i].state;
  775. memcpy(WFIFOP(fd,40), auth_dat[i].error_message, 20);
  776. memcpy(WFIFOP(fd,60), auth_dat[i].lastlogin, 24);
  777. memcpy(WFIFOP(fd,84), auth_dat[i].last_ip, 16);
  778. memcpy(WFIFOP(fd,100), auth_dat[i].email, 40);
  779. WFIFOL(fd,140) = (unsigned long)auth_dat[i].expiration_time;
  780. WFIFOL(fd,144) = (unsigned long)auth_dat[i].unban_time;
  781. WFIFOW(fd,148) = (uint16)strlen(auth_dat[i].memo);
  782. if (auth_dat[i].memo[0]) {
  783. memcpy(WFIFOP(fd,150), auth_dat[i].memo, strlen(auth_dat[i].memo));
  784. }
  785. ShowNotice("'ladmin': Sending information of an account (request by the name; account: %s, id: %d, ip: %s)\n", auth_dat[i].userid, auth_dat[i].account_id, ip);
  786. WFIFOSET(fd,150+strlen(auth_dat[i].memo));
  787. } else {
  788. memcpy(WFIFOP(fd,7), account_name, 24);
  789. WFIFOW(fd,148) = 0;
  790. ShowNotice("'ladmin': Attempt to obtain information (by the name) of an unknown account (account: %s, ip: %s)\n", account_name, ip);
  791. WFIFOSET(fd,150);
  792. }
  793. RFIFOSKIP(fd,26);
  794. break;
  795. case 0x7954: // Request about information of an account (by account id)
  796. if (RFIFOREST(fd) < 6)
  797. return 0;
  798. WFIFOW(fd,0) = 0x7953;
  799. WFIFOL(fd,2) = RFIFOL(fd,2);
  800. memset(WFIFOP(fd,7), '\0', 24);
  801. for(i = 0; i < auth_num; i++) {
  802. if (auth_dat[i].account_id == (int)RFIFOL(fd,2)) {
  803. ShowNotice("'ladmin': Sending information of an account (request by the id; account: %s, id: %d, ip: %s)\n", auth_dat[i].userid, RFIFOL(fd,2), ip);
  804. WFIFOB(fd,6) = (unsigned char)isGM(auth_dat[i].account_id);
  805. memcpy(WFIFOP(fd,7), auth_dat[i].userid, 24);
  806. WFIFOB(fd,31) = auth_dat[i].sex;
  807. WFIFOL(fd,32) = auth_dat[i].logincount;
  808. WFIFOL(fd,36) = auth_dat[i].state;
  809. memcpy(WFIFOP(fd,40), auth_dat[i].error_message, 20);
  810. memcpy(WFIFOP(fd,60), auth_dat[i].lastlogin, 24);
  811. memcpy(WFIFOP(fd,84), auth_dat[i].last_ip, 16);
  812. memcpy(WFIFOP(fd,100), auth_dat[i].email, 40);
  813. WFIFOL(fd,140) = (unsigned long)auth_dat[i].expiration_time;
  814. WFIFOL(fd,144) = (unsigned long)auth_dat[i].unban_time;
  815. WFIFOW(fd,148) = (uint16)strlen(auth_dat[i].memo);
  816. if (auth_dat[i].memo[0]) {
  817. memcpy(WFIFOP(fd,150), auth_dat[i].memo, strlen(auth_dat[i].memo));
  818. }
  819. WFIFOSET(fd,150+strlen(auth_dat[i].memo));
  820. break;
  821. }
  822. }
  823. if (i == auth_num) {
  824. ShowNotice("'ladmin': Attempt to obtain information (by the id) of an unknown account (id: %d, ip: %s)\n", RFIFOL(fd,2), ip);
  825. strncpy((char*)WFIFOP(fd,7), "", 24);
  826. WFIFOW(fd,148) = 0;
  827. WFIFOSET(fd,150);
  828. }
  829. RFIFOSKIP(fd,6);
  830. break;
  831. case 0x7955: // Request to reload GM file (no answer)
  832. ShowStatus("'ladmin': Request to re-load GM configuration file (ip: %s).\n", ip);
  833. read_gm_account();
  834. // send GM accounts to all char-servers
  835. send_GM_accounts(-1);
  836. RFIFOSKIP(fd,2);
  837. break;
  838. default:
  839. ShowStatus("'ladmin': End of connection, unknown packet (ip: %s)\n", ip);
  840. set_eof(fd);
  841. return 0;
  842. }
  843. }
  844. RFIFOSKIP(fd,RFIFOREST(fd));
  845. return 0;
  846. }