inter.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723
  1. // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
  2. // For more information, see LICENCE in the main folder
  3. #include "../common/db.h"
  4. #include "../common/mmo.h"
  5. #include "../common/socket.h"
  6. #include "../common/timer.h"
  7. #include "../common/malloc.h"
  8. #include "../common/lock.h"
  9. #include "../common/showmsg.h"
  10. #include "../common/strlib.h"
  11. #include "char.h"
  12. #include "inter.h"
  13. #include "int_party.h"
  14. #include "int_guild.h"
  15. #include "int_status.h"
  16. #include "int_storage.h"
  17. #include "int_pet.h"
  18. #include "int_homun.h"
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <stdlib.h>
  22. #define WISDATA_TTL (60*1000) // Existence time of Wisp/page data (60 seconds)
  23. // that is the waiting time of answers of all map-servers
  24. #define WISDELLIST_MAX 256 // Number of elements of Wisp/page data deletion list
  25. char accreg_txt[1024] = "save/accreg.txt";
  26. #ifndef TXT_SQL_CONVERT
  27. char inter_log_filename[1024] = "log/inter.log";
  28. char main_chat_nick[16] = "Main";
  29. static DBMap* accreg_db = NULL; // int account_id -> struct accreg*
  30. unsigned int party_share_level = 10;
  31. // sending packet list
  32. // NOTE: This variable ain't used at all! And it's confusing.. where do I add that the length of packet 0x2b07 is 10? x.x [Skotlex]
  33. int inter_send_packet_length[]={
  34. -1,-1,27,-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3000-0x300f
  35. -1, 7, 0, 0, 0, 0, 0, 0, -1,11, 0, 0, 0, 0, 0, 0,
  36. 35,-1,11,15, 34,29, 7,-1, 0, 0, 0, 0, 0, 0, 0, 0,
  37. 10,-1,15, 0, 79,19, 7,-1, 0,-1,-1,-1, 14,67,186,-1,
  38. 9, 9,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  39. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  40. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  41. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  42. 11,-1, 7, 3, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  43. };
  44. // recv. packet list
  45. int inter_recv_packet_length[]={
  46. -1,-1, 7,-1, -1,13,36, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3000-0x300f
  47. 6,-1, 0, 0, 0, 0, 0, 0, 10,-1, 0, 0, 0, 0, 0, 0, //0x3010-0x301f
  48. -1, 6,-1,14, 14,19, 6,-1, 14,14, 0, 0, 0, 0, 0, 0, //0x3020-0x302f
  49. -1, 6,-1,-1, 55,19, 6,-1, 14,-1,-1,-1, 18,19,186,-1, //0x3030-0x303f
  50. 5, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3040-0x304f
  51. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3050-0x305f
  52. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3060-0x306f
  53. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3070-0x307f
  54. 48,14,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3080-0x308f
  55. -1,10,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3090-0x309f Homunculus packets [albator]
  56. };
  57. struct WisData {
  58. int id, fd, count, len;
  59. unsigned long tick;
  60. unsigned char src[24], dst[24], msg[1024];
  61. };
  62. static DBMap* wis_db = NULL; // int wis_id -> struct WisData*
  63. static int wis_dellist[WISDELLIST_MAX], wis_delnum;
  64. //--------------------------------------------------------
  65. // アカウント変数を文字列へ変換
  66. int inter_accreg_tostr(char *str, struct accreg *reg) {
  67. int j;
  68. char *p = str;
  69. p += sprintf(p, "%d\t", reg->account_id);
  70. for(j = 0; j < reg->reg_num; j++) {
  71. p += sprintf(p,"%s,%s ", reg->reg[j].str, reg->reg[j].value);
  72. }
  73. return 0;
  74. }
  75. #endif //TXT_SQL_CONVERT
  76. // アカウント変数を文字列から変換
  77. int inter_accreg_fromstr(const char *str, struct accreg *reg) {
  78. int j, n;
  79. const char *p = str;
  80. if (sscanf(p, "%d\t%n", &reg->account_id, &n ) != 1 || reg->account_id <= 0)
  81. return 1;
  82. for(j = 0, p += n; j < ACCOUNT_REG_NUM; j++, p += n) {
  83. if (sscanf(p, "%[^,],%[^ ] %n", reg->reg[j].str, reg->reg[j].value, &n) != 2)
  84. break;
  85. }
  86. reg->reg_num = j;
  87. return 0;
  88. }
  89. #ifndef TXT_SQL_CONVERT
  90. // アカウント変数の読み込み
  91. int inter_accreg_init(void) {
  92. char line[8192];
  93. FILE *fp;
  94. int c = 0;
  95. struct accreg *reg;
  96. accreg_db = idb_alloc(DB_OPT_RELEASE_DATA);
  97. if( (fp = fopen(accreg_txt, "r")) == NULL)
  98. return 1;
  99. while(fgets(line, sizeof(line), fp))
  100. {
  101. reg = (struct accreg*)aCalloc(sizeof(struct accreg), 1);
  102. if (reg == NULL) {
  103. ShowFatalError("inter: accreg: out of memory!\n");
  104. exit(EXIT_FAILURE);
  105. }
  106. if (inter_accreg_fromstr(line, reg) == 0 && reg->account_id > 0) {
  107. idb_put(accreg_db, reg->account_id, reg);
  108. } else {
  109. ShowError("inter: accreg: broken data [%s] line %d\n", accreg_txt, c);
  110. aFree(reg);
  111. }
  112. c++;
  113. }
  114. fclose(fp);
  115. return 0;
  116. }
  117. // アカウント変数のセーブ用
  118. int inter_accreg_save_sub(DBKey key, void *data, va_list ap) {
  119. char line[8192];
  120. FILE *fp;
  121. struct accreg *reg = (struct accreg *)data;
  122. if (reg->reg_num > 0) {
  123. inter_accreg_tostr(line,reg);
  124. fp = va_arg(ap, FILE *);
  125. fprintf(fp, "%s\n", line);
  126. }
  127. return 0;
  128. }
  129. // アカウント変数のセーブ
  130. int inter_accreg_save(void) {
  131. FILE *fp;
  132. int lock;
  133. if ((fp = lock_fopen(accreg_txt,&lock)) == NULL) {
  134. ShowError("int_accreg: can't write [%s] !!! data is lost !!!\n", accreg_txt);
  135. return 1;
  136. }
  137. accreg_db->foreach(accreg_db, inter_accreg_save_sub,fp);
  138. lock_fclose(fp, accreg_txt, &lock);
  139. return 0;
  140. }
  141. //--------------------------------------------------------
  142. #endif //TXT_SQL_CONVERT
  143. /*==========================================
  144. * 設定ファイルを読み込む
  145. *------------------------------------------*/
  146. static int inter_config_read(const char *cfgName) {
  147. char line[1024], w1[1024], w2[1024];
  148. FILE *fp;
  149. fp = fopen(cfgName, "r");
  150. if (fp == NULL) {
  151. ShowError("file not found: %s\n", cfgName);
  152. return 1;
  153. }
  154. while(fgets(line, sizeof(line), fp))
  155. {
  156. if (line[0] == '/' && line[1] == '/')
  157. continue;
  158. if (sscanf(line,"%[^:]: %[^\r\n]", w1, w2) != 2)
  159. continue;
  160. if (strcmpi(w1, "storage_txt") == 0) {
  161. strncpy(storage_txt, w2, sizeof(storage_txt));
  162. } else if (strcmpi(w1, "party_txt") == 0) {
  163. strncpy(party_txt, w2, sizeof(party_txt));
  164. } else if (strcmpi(w1, "pet_txt") == 0) {
  165. strncpy(pet_txt, w2, sizeof(pet_txt));
  166. } else if (strcmpi(w1, "accreg_txt") == 0) {
  167. strncpy(accreg_txt, w2, sizeof(accreg_txt));
  168. } else if (strcmpi(w1, "guild_txt") == 0) {
  169. strncpy(guild_txt, w2, sizeof(guild_txt));
  170. } else if (strcmpi(w1, "castle_txt") == 0) {
  171. strncpy(castle_txt, w2, sizeof(castle_txt));
  172. } else if (strcmpi(w1, "guild_storage_txt") == 0) {
  173. strncpy(guild_storage_txt, w2, sizeof(guild_storage_txt));
  174. #ifndef TXT_SQL_CONVERT
  175. } else if (strcmpi(w1, "homun_txt") == 0) {
  176. strncpy(homun_txt, w2, sizeof(homun_txt));
  177. } else if (strcmpi(w1, "party_share_level") == 0) {
  178. party_share_level = (unsigned int)atof(w2);
  179. } else if (strcmpi(w1, "inter_log_filename") == 0) {
  180. strncpy(inter_log_filename, w2, sizeof(inter_log_filename));
  181. } else if(strcmpi(w1,"log_inter")==0) {
  182. log_inter = atoi(w2);
  183. } else if(strcmpi(w1, "main_chat_nick")==0){ // Main chat nick [LuzZza]
  184. strcpy(main_chat_nick, w2);
  185. #endif //TXT_SQL_CONVERT
  186. } else if (strcmpi(w1, "import") == 0) {
  187. inter_config_read(w2);
  188. }
  189. }
  190. fclose(fp);
  191. return 0;
  192. }
  193. #ifndef TXT_SQL_CONVERT
  194. // ログ書き出し
  195. int inter_log(char *fmt,...) {
  196. FILE *logfp;
  197. va_list ap;
  198. va_start(ap,fmt);
  199. logfp = fopen(inter_log_filename, "a");
  200. if (logfp) {
  201. vfprintf(logfp, fmt, ap);
  202. fclose(logfp);
  203. }
  204. va_end(ap);
  205. return 0;
  206. }
  207. // セーブ
  208. int inter_save(void) {
  209. #ifdef ENABLE_SC_SAVING
  210. inter_status_save();
  211. #endif
  212. inter_party_save();
  213. inter_guild_save();
  214. inter_storage_save();
  215. inter_guild_storage_save();
  216. inter_pet_save();
  217. inter_homun_save();
  218. inter_accreg_save();
  219. return 0;
  220. }
  221. #endif //TXT_SQL_CONVERT
  222. // 初期化
  223. int inter_init_txt(const char *file)
  224. {
  225. inter_config_read(file);
  226. #ifndef TXT_SQL_CONVERT
  227. wis_db = idb_alloc(DB_OPT_RELEASE_DATA);
  228. inter_party_init();
  229. inter_guild_init();
  230. inter_storage_init();
  231. inter_pet_init();
  232. inter_homun_init();
  233. inter_accreg_init();
  234. #endif //TXT_SQL_CONVERT
  235. return 0;
  236. }
  237. #ifndef TXT_SQL_CONVERT
  238. // finalize
  239. void inter_final(void) {
  240. accreg_db->destroy(accreg_db, NULL);
  241. wis_db->destroy(wis_db, NULL);
  242. inter_party_final();
  243. inter_guild_final();
  244. inter_storage_final();
  245. inter_pet_final();
  246. inter_homun_final();
  247. return;
  248. }
  249. // マップサーバー接続
  250. int inter_mapif_init(int fd) {
  251. inter_guild_mapif_init(fd);
  252. return 0;
  253. }
  254. //--------------------------------------------------------
  255. // sended packets to map-server
  256. // broadcast sending
  257. int mapif_broadcast(unsigned char *mes, int len, unsigned long fontColor, short fontType, short fontSize, short fontAlign, short fontY, int sfd)
  258. {
  259. unsigned char *buf = (unsigned char*)aMallocA((len)*sizeof(unsigned char));
  260. WBUFW(buf,0) = 0x3800;
  261. WBUFW(buf,2) = len;
  262. WBUFL(buf,4) = fontColor;
  263. WBUFW(buf,8) = fontType;
  264. WBUFW(buf,10) = fontSize;
  265. WBUFW(buf,12) = fontAlign;
  266. WBUFW(buf,14) = fontY;
  267. memcpy(WBUFP(buf,16), mes, len - 16);
  268. mapif_sendallwos(sfd, buf, len);
  269. if (buf)
  270. aFree(buf);
  271. return 0;
  272. }
  273. // Wisp/page transmission to one map-server
  274. int mapif_wis_message2(struct WisData *wd, int fd) {
  275. WFIFOHEAD(fd, 56+wd->len);
  276. WFIFOW(fd, 0) = 0x3801;
  277. WFIFOW(fd, 2) = 56 + wd->len;
  278. WFIFOL(fd, 4) = wd->id;
  279. memcpy(WFIFOP(fd, 8), wd->src, NAME_LENGTH);
  280. memcpy(WFIFOP(fd,32), wd->dst, NAME_LENGTH);
  281. memcpy(WFIFOP(fd,56), wd->msg, wd->len);
  282. wd->count = 1;
  283. WFIFOSET(fd,WFIFOW(fd,2));
  284. return 1;
  285. }
  286. // Wisp/page transmission to all map-server
  287. int mapif_wis_message(struct WisData *wd) {
  288. unsigned char buf[2048];
  289. if (wd->len > 2047-56) wd->len = 2047-56; //Force it to fit to avoid crashes. [Skotlex]
  290. WBUFW(buf, 0) = 0x3801;
  291. WBUFW(buf, 2) = 56 + wd->len;
  292. WBUFL(buf, 4) = wd->id;
  293. memcpy(WBUFP(buf, 8), wd->src, NAME_LENGTH);
  294. memcpy(WBUFP(buf,32), wd->dst, NAME_LENGTH);
  295. memcpy(WBUFP(buf,56), wd->msg, wd->len);
  296. wd->count = mapif_sendall(buf, WBUFW(buf,2));
  297. return 0;
  298. }
  299. int mapif_wis_fail(int fd, char *src) {
  300. unsigned char buf[27];
  301. WBUFW(buf, 0) = 0x3802;
  302. memcpy(WBUFP(buf, 2), src, NAME_LENGTH);
  303. WBUFB(buf,26) = 1; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
  304. mapif_send(fd, buf, 27);
  305. return 0;
  306. }
  307. // Wisp/page transmission result to map-server
  308. int mapif_wis_end(struct WisData *wd, int flag)
  309. {
  310. unsigned char buf[27];
  311. WBUFW(buf, 0) = 0x3802;
  312. memcpy(WBUFP(buf, 2), wd->src, 24);
  313. WBUFB(buf,26) = flag; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
  314. mapif_send(wd->fd, buf, 27);
  315. return 0;
  316. }
  317. // Account registry transfer to map-server
  318. static void mapif_account_reg(int fd, unsigned char *src)
  319. {
  320. WBUFW(src,0)=0x3804; //NOTE: writing to RFIFO
  321. mapif_sendallwos(fd, src, WBUFW(src,2));
  322. }
  323. // アカウント変数要求返信
  324. int mapif_account_reg_reply(int fd,int account_id, int char_id)
  325. {
  326. struct accreg *reg = (struct accreg*)idb_get(accreg_db,account_id);
  327. WFIFOHEAD(fd, ACCOUNT_REG_NUM * 288+ 13);
  328. WFIFOW(fd,0) = 0x3804;
  329. WFIFOL(fd,4) = account_id;
  330. WFIFOL(fd,8) = char_id;
  331. WFIFOB(fd,12) = 2; //Acc Reg
  332. if (reg == NULL) {
  333. WFIFOW(fd,2) = 13;
  334. } else {
  335. int i, p;
  336. for (p=13,i = 0; i < reg->reg_num; i++) {
  337. p+= sprintf((char*)WFIFOP(fd,p), "%s", reg->reg[i].str)+1; //We add 1 to consider the '\0' in place.
  338. p+= sprintf((char*)WFIFOP(fd,p), "%s", reg->reg[i].value)+1;
  339. }
  340. WFIFOW(fd,2)=p;
  341. }
  342. WFIFOSET(fd,WFIFOW(fd,2));
  343. return 0;
  344. }
  345. //Request to kick char from a certain map server. [Skotlex]
  346. int mapif_disconnectplayer(int fd, int account_id, int char_id, int reason)
  347. {
  348. if (fd < 0)
  349. return -1;
  350. WFIFOHEAD(fd, 7);
  351. WFIFOW(fd,0) = 0x2b1f;
  352. WFIFOL(fd,2) = account_id;
  353. WFIFOB(fd,6) = reason;
  354. WFIFOSET(fd,7);
  355. return 0;
  356. }
  357. //--------------------------------------------------------
  358. // Existence check of WISP data
  359. int check_ttl_wisdata_sub(DBKey key, void *data, va_list ap) {
  360. unsigned long tick;
  361. struct WisData *wd = (struct WisData *)data;
  362. tick = va_arg(ap, unsigned long);
  363. if (DIFF_TICK(tick, wd->tick) > WISDATA_TTL && wis_delnum < WISDELLIST_MAX)
  364. wis_dellist[wis_delnum++] = wd->id;
  365. return 0;
  366. }
  367. int check_ttl_wisdata(void) {
  368. unsigned long tick = gettick();
  369. int i;
  370. do {
  371. wis_delnum = 0;
  372. wis_db->foreach(wis_db, check_ttl_wisdata_sub, tick);
  373. for(i = 0; i < wis_delnum; i++) {
  374. struct WisData *wd = (struct WisData*)idb_get(wis_db, wis_dellist[i]);
  375. ShowWarning("inter: wis data id=%d time out : from %s to %s\n", wd->id, wd->src, wd->dst);
  376. // removed. not send information after a timeout. Just no answer for the player
  377. //mapif_wis_end(wd, 1); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
  378. idb_remove(wis_db, wd->id);
  379. }
  380. } while(wis_delnum >= WISDELLIST_MAX);
  381. return 0;
  382. }
  383. //--------------------------------------------------------
  384. // received packets from map-server
  385. // broadcast sending
  386. int mapif_parse_broadcast(int fd)
  387. {
  388. RFIFOHEAD(fd);
  389. mapif_broadcast(RFIFOP(fd,16), RFIFOW(fd,2), RFIFOL(fd,4), RFIFOW(fd,8), RFIFOW(fd,10), RFIFOW(fd,12), RFIFOW(fd,14), fd);
  390. return 0;
  391. }
  392. static struct WisData* mapif_create_whisper(int fd, char* src, char* dst, char* mes, int meslen)
  393. {
  394. static int wisid = 0;
  395. struct WisData* wd = (struct WisData *)aCalloc(sizeof(struct WisData), 1);
  396. if (wd == NULL){
  397. ShowFatalError("inter: WisRequest: out of memory !\n");
  398. return NULL;
  399. }
  400. wd->id = ++wisid;
  401. wd->fd = fd;
  402. wd->len= meslen;
  403. memcpy(wd->src, src, NAME_LENGTH);
  404. memcpy(wd->dst, dst, NAME_LENGTH);
  405. memcpy(wd->msg, mes, meslen);
  406. wd->tick = gettick();
  407. return wd;
  408. }
  409. // Wisp/page request to send
  410. int mapif_parse_WisRequest(int fd)
  411. {
  412. struct mmo_charstatus* char_status;
  413. struct WisData* wd;
  414. char name[NAME_LENGTH];
  415. int fd2;
  416. if (RFIFOW(fd,2)-52 >= sizeof(wd->msg)) {
  417. ShowWarning("inter: Wis message size too long.\n");
  418. return 0;
  419. } else if (RFIFOW(fd,2)-52 <= 0) { // normaly, impossible, but who knows...
  420. ShowError("inter: Wis message doesn't exist.\n");
  421. return 0;
  422. }
  423. safestrncpy(name, (char*)RFIFOP(fd,28), NAME_LENGTH); //Received name may be too large and not contain \0! [Skotlex]
  424. // search if character exists before to ask all map-servers
  425. char_status = search_character_byname(name);
  426. if (char_status == NULL)
  427. return mapif_wis_fail(fd, (char*)RFIFOP(fd, 4));
  428. // Character exists.
  429. // to be sure of the correct name, rewrite it
  430. memset(name, 0, NAME_LENGTH);
  431. strncpy(name, char_status->name, NAME_LENGTH);
  432. // if source is destination, don't ask other servers.
  433. if (strcmp((char*)RFIFOP(fd,4),name) == 0)
  434. return mapif_wis_fail(fd, (char*)RFIFOP(fd, 4));
  435. //Look for online character.
  436. fd2 = search_character_online(char_status->account_id, char_status->char_id);
  437. if (fd2 >= 0) { //Character online, send whisper.
  438. wd = mapif_create_whisper(fd, (char*)RFIFOP(fd, 4), (char*)RFIFOP(fd,28), (char*)RFIFOP(fd,52), RFIFOW(fd,2)-52);
  439. if (!wd) return 1;
  440. idb_put(wis_db, wd->id, wd);
  441. mapif_wis_message2(wd, fd2);
  442. return 0;
  443. }
  444. //Not found.
  445. return mapif_wis_fail(fd, (char*)RFIFOP(fd,4));
  446. }
  447. // Wisp/page transmission result
  448. int mapif_parse_WisReply(int fd) {
  449. int id, flag;
  450. struct WisData *wd;
  451. RFIFOHEAD(fd);
  452. id = RFIFOL(fd,2);
  453. flag = RFIFOB(fd,6);
  454. wd = (struct WisData*)idb_get(wis_db, id);
  455. if (wd == NULL)
  456. return 0; // This wisp was probably suppress before, because it was timeout or because of target was found on another map-server
  457. if ((--wd->count) <= 0 || flag != 1) {
  458. mapif_wis_end(wd, flag); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
  459. idb_remove(wis_db, id);
  460. }
  461. return 0;
  462. }
  463. // Received wisp message from map-server for ALL gm (just copy the message and resends it to ALL map-servers)
  464. int mapif_parse_WisToGM(int fd) {
  465. unsigned char buf[2048]; // 0x3003/0x3803 <packet_len>.w <wispname>.24B <min_gm_level>.w <message>.?B
  466. ShowDebug("Sent packet back!\n");
  467. memcpy(WBUFP(buf,0), RFIFOP(fd,0), RFIFOW(fd,2));
  468. WBUFW(buf, 0) = 0x3803;
  469. mapif_sendall(buf, RFIFOW(fd,2));
  470. return 0;
  471. }
  472. static void* create_accreg(DBKey key, va_list args) {
  473. struct accreg *reg;
  474. reg = (struct accreg*)aCalloc(sizeof(struct accreg), 1);
  475. reg->account_id = key.i;
  476. return reg;
  477. }
  478. // アカウント変数保存要求
  479. int mapif_parse_Registry(int fd) {
  480. int j, p, len;
  481. struct accreg *reg;
  482. RFIFOHEAD(fd);
  483. switch (RFIFOB(fd,12)) {
  484. case 3: //Character registry
  485. return char_parse_Registry(RFIFOL(fd,4), RFIFOL(fd,8), RFIFOP(fd,13), RFIFOW(fd,2)-13);
  486. case 2: //Acc Reg
  487. break;
  488. case 1: //Acc Reg2, forward to login
  489. return save_accreg2(RFIFOP(fd,4), RFIFOW(fd,2)-4);
  490. default: //Error?
  491. return 1;
  492. }
  493. reg = (struct accreg*)idb_ensure(accreg_db, RFIFOL(fd,4), create_accreg);
  494. for(j=0,p=13;j<ACCOUNT_REG_NUM && p<RFIFOW(fd,2);j++){
  495. sscanf((char*)RFIFOP(fd,p), "%31c%n",reg->reg[j].str,&len);
  496. reg->reg[j].str[len]='\0';
  497. p +=len+1; //+1 to skip the '\0' between strings.
  498. sscanf((char*)RFIFOP(fd,p), "%255c%n",reg->reg[j].value,&len);
  499. reg->reg[j].value[len]='\0';
  500. p +=len+1;
  501. }
  502. reg->reg_num=j;
  503. mapif_account_reg(fd, RFIFOP(fd,0)); // 他のMAPサーバーに送信
  504. return 0;
  505. }
  506. // Request the value of all registries.
  507. int mapif_parse_RegistryRequest(int fd)
  508. {
  509. RFIFOHEAD(fd);
  510. //Load Char Registry
  511. if (RFIFOB(fd,12))
  512. char_account_reg_reply(fd,RFIFOL(fd,2),RFIFOL(fd,6));
  513. //Load Account Registry
  514. if (RFIFOB(fd,11))
  515. mapif_account_reg_reply(fd,RFIFOL(fd,2),RFIFOL(fd,6));
  516. //Ask Login Server for Account2 values.
  517. if (RFIFOB(fd,10))
  518. request_accreg2(RFIFOL(fd,2),RFIFOL(fd,6));
  519. return 1;
  520. }
  521. static void mapif_namechange_ack(int fd, int account_id, int char_id, int type, int flag, char *name){
  522. WFIFOHEAD(fd, NAME_LENGTH+13);
  523. WFIFOW(fd, 0) =0x3806;
  524. WFIFOL(fd, 2) =account_id;
  525. WFIFOL(fd, 6) =char_id;
  526. WFIFOB(fd,10) =type;
  527. WFIFOB(fd,11) =flag;
  528. memcpy(WFIFOP(fd, 12), name, NAME_LENGTH);
  529. WFIFOSET(fd, NAME_LENGTH+13);
  530. }
  531. int mapif_parse_NameChangeRequest(int fd)
  532. {
  533. int account_id, char_id, type;
  534. char* name;
  535. int i;
  536. RFIFOHEAD(fd);
  537. account_id = RFIFOL(fd, 2);
  538. char_id = RFIFOL(fd, 6);
  539. type = RFIFOB(fd, 10);
  540. name = (char*)RFIFOP(fd, 11);
  541. // Check Authorised letters/symbols in the name
  542. if (char_name_option == 1) { // only letters/symbols in char_name_letters are authorised
  543. for (i = 0; i < NAME_LENGTH && name[i]; i++)
  544. if (strchr(char_name_letters, name[i]) == NULL) {
  545. mapif_namechange_ack(fd, account_id, char_id, type, 0, name);
  546. return 0;
  547. }
  548. } else if (char_name_option == 2) { // letters/symbols in char_name_letters are forbidden
  549. for (i = 0; i < NAME_LENGTH && name[i]; i++)
  550. if (strchr(char_name_letters, name[i]) != NULL) {
  551. mapif_namechange_ack(fd, account_id, char_id, type, 0, name);
  552. return 0;
  553. }
  554. }
  555. //TODO: type holds the type of object to rename.
  556. //If it were a player, it needs to have the guild information and db information
  557. //updated here, because changing it on the map won't make it be saved [Skotlex]
  558. //name allowed.
  559. mapif_namechange_ack(fd, account_id, char_id, type, 1, name);
  560. return 0;
  561. }
  562. //--------------------------------------------------------
  563. /// Returns the length of the next complete packet to process,
  564. /// or 0 if no complete packet exists in the queue.
  565. ///
  566. /// @param length The minimum allowed length, or -1 for dynamic lookup
  567. int inter_check_length(int fd, int length)
  568. {
  569. if( length == -1 )
  570. {// variable-length packet
  571. if( RFIFOREST(fd) < 4 )
  572. return 0;
  573. length = RFIFOW(fd,2);
  574. }
  575. if( (int)RFIFOREST(fd) < length )
  576. return 0;
  577. return length;
  578. }
  579. // map server からの通信(1パケットのみ解析すること)
  580. // エラーなら0(false)、処理できたなら1、
  581. // パケット長が足りなければ2をかえさなければならない
  582. int inter_parse_frommap(int fd) {
  583. int cmd, len;
  584. RFIFOHEAD(fd);
  585. cmd = RFIFOW(fd,0);
  586. len = 0;
  587. // inter鯖管轄かを調べる
  588. if (cmd < 0x3000 || cmd >= 0x3000 + ARRAYLENGTH(inter_recv_packet_length))
  589. return 0;
  590. if (inter_recv_packet_length[cmd-0x3000] == 0) //This is necessary, because otherwise we return 2 and the char server will just hang waiting for packets! [Skotlex]
  591. return 0;
  592. // パケット長を調べる
  593. if ((len = inter_check_length(fd, inter_recv_packet_length[cmd - 0x3000])) == 0)
  594. return 2;
  595. switch(cmd) {
  596. case 0x3000: mapif_parse_broadcast(fd); break;
  597. case 0x3001: mapif_parse_WisRequest(fd); break;
  598. case 0x3002: mapif_parse_WisReply(fd); break;
  599. case 0x3003: mapif_parse_WisToGM(fd); break;
  600. case 0x3004: mapif_parse_Registry(fd); break;
  601. case 0x3005: mapif_parse_RegistryRequest(fd); break;
  602. case 0x3006: mapif_parse_NameChangeRequest(fd); break;
  603. default:
  604. if (inter_party_parse_frommap(fd))
  605. break;
  606. if (inter_guild_parse_frommap(fd))
  607. break;
  608. if (inter_storage_parse_frommap(fd))
  609. break;
  610. if (inter_pet_parse_frommap(fd))
  611. break;
  612. if (inter_homun_parse_frommap(fd))
  613. break;
  614. return 0;
  615. }
  616. RFIFOSKIP(fd, len);
  617. return 1;
  618. }
  619. #endif //TXT_SQL_CONVERT