intif.c 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782
  1. // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
  2. // For more information, see LICENCE in the main folder
  3. #include "../common/showmsg.h"
  4. #include "../common/socket.h"
  5. #include "../common/timer.h"
  6. #include "../common/nullpo.h"
  7. #include "../common/malloc.h"
  8. #include "../common/strlib.h"
  9. #include "map.h"
  10. #include "battle.h"
  11. #include "chrif.h"
  12. #include "clif.h"
  13. #include "pc.h"
  14. #include "intif.h"
  15. #include "storage.h"
  16. #include "party.h"
  17. #include "guild.h"
  18. #include "pet.h"
  19. #include "atcommand.h"
  20. #include "mercenary.h" //albator
  21. #include "mail.h"
  22. #include <sys/types.h>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <signal.h>
  26. #include <fcntl.h>
  27. #include <string.h>
  28. static const int packet_len_table[]={
  29. -1,-1,27,-1, -1, 0,37, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3800-0x380f
  30. -1, 7, 0, 0, 0, 0, 0, 0, -1,11, 0, 0, 0, 0, 0, 0, //0x3810
  31. 39,-1,15,15, 14,19, 7,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3820
  32. 10,-1,15, 0, 79,19, 7,-1, 0,-1,-1,-1, 14,67,186,-1, //0x3830
  33. 9, 9,-1,14, 0, 0, 0, 0, -1,74,-1,11, 11,-1, 0, 0, //0x3840
  34. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  35. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  36. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  37. 11,-1, 7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3880
  38. -1,-1, 7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3890 Homunculus [albator]
  39. };
  40. extern int char_fd; // inter serverのfdはchar_fdを使う
  41. #define inter_fd char_fd // エイリアス
  42. //-----------------------------------------------------------------
  43. // inter serverへの送信
  44. int CheckForCharServer(void)
  45. {
  46. return ((char_fd <= 0) || session[char_fd] == NULL || session[char_fd]->wdata == NULL);
  47. }
  48. // pet
  49. int intif_create_pet(int account_id,int char_id,short pet_class,short pet_lv,short pet_egg_id,
  50. short pet_equip,short intimate,short hungry,char rename_flag,char incuvate,char *pet_name)
  51. {
  52. if (CheckForCharServer())
  53. return 0;
  54. WFIFOHEAD(inter_fd, 24 + NAME_LENGTH);
  55. WFIFOW(inter_fd,0) = 0x3080;
  56. WFIFOL(inter_fd,2) = account_id;
  57. WFIFOL(inter_fd,6) = char_id;
  58. WFIFOW(inter_fd,10) = pet_class;
  59. WFIFOW(inter_fd,12) = pet_lv;
  60. WFIFOW(inter_fd,14) = pet_egg_id;
  61. WFIFOW(inter_fd,16) = pet_equip;
  62. WFIFOW(inter_fd,18) = intimate;
  63. WFIFOW(inter_fd,20) = hungry;
  64. WFIFOB(inter_fd,22) = rename_flag;
  65. WFIFOB(inter_fd,23) = incuvate;
  66. memcpy(WFIFOP(inter_fd,24),pet_name,NAME_LENGTH);
  67. WFIFOSET(inter_fd,24+NAME_LENGTH);
  68. return 0;
  69. }
  70. int intif_request_petdata(int account_id,int char_id,int pet_id)
  71. {
  72. if (CheckForCharServer())
  73. return 0;
  74. WFIFOHEAD(inter_fd, 14);
  75. WFIFOW(inter_fd,0) = 0x3081;
  76. WFIFOL(inter_fd,2) = account_id;
  77. WFIFOL(inter_fd,6) = char_id;
  78. WFIFOL(inter_fd,10) = pet_id;
  79. WFIFOSET(inter_fd,14);
  80. return 0;
  81. }
  82. int intif_save_petdata(int account_id,struct s_pet *p)
  83. {
  84. if (CheckForCharServer())
  85. return 0;
  86. WFIFOHEAD(inter_fd, sizeof(struct s_pet) + 8);
  87. WFIFOW(inter_fd,0) = 0x3082;
  88. WFIFOW(inter_fd,2) = sizeof(struct s_pet) + 8;
  89. WFIFOL(inter_fd,4) = account_id;
  90. memcpy(WFIFOP(inter_fd,8),p,sizeof(struct s_pet));
  91. WFIFOSET(inter_fd,WFIFOW(inter_fd,2));
  92. return 0;
  93. }
  94. int intif_delete_petdata(int pet_id)
  95. {
  96. if (CheckForCharServer())
  97. return 0;
  98. WFIFOHEAD(inter_fd,6);
  99. WFIFOW(inter_fd,0) = 0x3083;
  100. WFIFOL(inter_fd,2) = pet_id;
  101. WFIFOSET(inter_fd,6);
  102. return 1;
  103. }
  104. int intif_rename(struct map_session_data *sd, int type, char *name)
  105. {
  106. if (CheckForCharServer())
  107. return 1;
  108. WFIFOHEAD(inter_fd,NAME_LENGTH+12);
  109. WFIFOW(inter_fd,0) = 0x3006;
  110. WFIFOL(inter_fd,2) = sd->status.account_id;
  111. WFIFOL(inter_fd,6) = sd->status.char_id;
  112. WFIFOB(inter_fd,10) = type; //Type: 0 - PC, 1 - PET, 2 - HOM
  113. memcpy(WFIFOP(inter_fd,11),name, NAME_LENGTH);
  114. WFIFOSET(inter_fd,NAME_LENGTH+12);
  115. return 0;
  116. }
  117. // GMメッセージを送信
  118. int intif_GMmessage(const char* mes,int len,int flag)
  119. {
  120. int lp = (flag&0x10) ? 8 : 4;
  121. // Send to the local players
  122. clif_GMmessage(NULL, mes, len, flag);
  123. if (CheckForCharServer())
  124. return 0;
  125. if (other_mapserver_count < 1)
  126. return 0; //No need to send.
  127. WFIFOHEAD(inter_fd,lp + len + 4);
  128. WFIFOW(inter_fd,0) = 0x3000;
  129. WFIFOW(inter_fd,2) = lp + len + 4;
  130. WFIFOL(inter_fd,4) = 0xFF000000; //"invalid" color signals standard broadcast.
  131. WFIFOL(inter_fd,8) = 0x65756c62;
  132. memcpy(WFIFOP(inter_fd,4+lp), mes, len);
  133. WFIFOSET(inter_fd, WFIFOW(inter_fd,2));
  134. return 0;
  135. }
  136. int intif_announce(const char* mes,int len, unsigned long color, int flag)
  137. {
  138. // Send to the local players
  139. if(color == 0xFE000000) // This is main chat message [LuzZza]
  140. clif_MainChatMessage(mes);
  141. else
  142. clif_announce(NULL, mes, len, color, flag);
  143. if (CheckForCharServer())
  144. return 0;
  145. if (other_mapserver_count < 1)
  146. return 0; //No need to send.
  147. WFIFOHEAD(inter_fd, 8 + len);
  148. WFIFOW(inter_fd,0) = 0x3000;
  149. WFIFOW(inter_fd,2) = 8 + len;
  150. WFIFOL(inter_fd,4) = color;
  151. memcpy(WFIFOP(inter_fd,8), mes, len);
  152. WFIFOSET(inter_fd, WFIFOW(inter_fd,2));
  153. return 0;
  154. }
  155. // The transmission of Wisp/Page to inter-server (player not found on this server)
  156. int intif_wis_message(struct map_session_data *sd, char *nick, char *mes, int mes_len)
  157. {
  158. nullpo_retr(0, sd);
  159. if (CheckForCharServer())
  160. return 0;
  161. if (other_mapserver_count < 1)
  162. { //Character not found.
  163. clif_wis_end(sd->fd, 1);
  164. return 0;
  165. }
  166. WFIFOHEAD(inter_fd,mes_len + 52);
  167. WFIFOW(inter_fd,0) = 0x3001;
  168. WFIFOW(inter_fd,2) = mes_len + 52;
  169. memcpy(WFIFOP(inter_fd,4), sd->status.name, NAME_LENGTH);
  170. memcpy(WFIFOP(inter_fd,4+NAME_LENGTH), nick, NAME_LENGTH);
  171. memcpy(WFIFOP(inter_fd,4+2*NAME_LENGTH), mes, mes_len);
  172. WFIFOSET(inter_fd, WFIFOW(inter_fd,2));
  173. if (battle_config.etc_log)
  174. ShowInfo("intif_wis_message from %s to %s (message: '%s')\n", sd->status.name, nick, mes);
  175. return 0;
  176. }
  177. // The reply of Wisp/page
  178. int intif_wis_replay(int id, int flag)
  179. {
  180. if (CheckForCharServer())
  181. return 0;
  182. WFIFOHEAD(inter_fd,7);
  183. WFIFOW(inter_fd,0) = 0x3002;
  184. WFIFOL(inter_fd,2) = id;
  185. WFIFOB(inter_fd,6) = flag; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
  186. WFIFOSET(inter_fd,7);
  187. if (battle_config.etc_log)
  188. ShowInfo("intif_wis_replay: id: %d, flag:%d\n", id, flag);
  189. return 0;
  190. }
  191. // The transmission of GM only Wisp/Page from server to inter-server
  192. int intif_wis_message_to_gm(char *Wisp_name, int min_gm_level, char *mes)
  193. {
  194. int mes_len;
  195. if (CheckForCharServer())
  196. return 0;
  197. mes_len = strlen(mes) + 1; // + null
  198. WFIFOHEAD(inter_fd, mes_len + 30);
  199. WFIFOW(inter_fd,0) = 0x3003;
  200. WFIFOW(inter_fd,2) = mes_len + 30;
  201. memcpy(WFIFOP(inter_fd,4), Wisp_name, NAME_LENGTH);
  202. WFIFOW(inter_fd,4+NAME_LENGTH) = (short)min_gm_level;
  203. memcpy(WFIFOP(inter_fd,6+NAME_LENGTH), mes, mes_len);
  204. WFIFOSET(inter_fd, WFIFOW(inter_fd,2));
  205. if (battle_config.etc_log)
  206. ShowNotice("intif_wis_message_to_gm: from: '%s', min level: %d, message: '%s'.\n", Wisp_name, min_gm_level, mes);
  207. return 0;
  208. }
  209. int intif_regtostr(char* str, struct global_reg *reg, int qty)
  210. {
  211. int len =0, i;
  212. for (i = 0; i < qty; i++) {
  213. len+= sprintf(str+len, "%s", reg[i].str)+1; //We add 1 to consider the '\0' in place.
  214. len+= sprintf(str+len, "%s", reg[i].value)+1;
  215. }
  216. return len;
  217. }
  218. //Request for saving registry values.
  219. int intif_saveregistry(struct map_session_data *sd, int type)
  220. {
  221. struct global_reg *reg;
  222. int count;
  223. int i, p;
  224. if (CheckForCharServer())
  225. return -1;
  226. switch (type) {
  227. case 3: //Character reg
  228. reg = sd->save_reg.global;
  229. count = sd->save_reg.global_num;
  230. sd->state.reg_dirty &= ~0x4;
  231. break;
  232. case 2: //Account reg
  233. reg = sd->save_reg.account;
  234. count = sd->save_reg.account_num;
  235. sd->state.reg_dirty &= ~0x2;
  236. break;
  237. case 1: //Account2 reg
  238. reg = sd->save_reg.account2;
  239. count = sd->save_reg.account2_num;
  240. sd->state.reg_dirty &= ~0x1;
  241. break;
  242. default: //Broken code?
  243. ShowError("intif_saveregistry: Invalid type %d\n", type);
  244. return -1;
  245. }
  246. WFIFOHEAD(inter_fd, 288 * MAX_REG_NUM+13);
  247. WFIFOW(inter_fd,0)=0x3004;
  248. WFIFOL(inter_fd,4)=sd->status.account_id;
  249. WFIFOL(inter_fd,8)=sd->status.char_id;
  250. WFIFOB(inter_fd,12)=type;
  251. for( p = 13, i = 0; i < count; i++ ) {
  252. if (reg[i].str[0] && reg[i].value != 0) {
  253. p+= sprintf((char*)WFIFOP(inter_fd,p), "%s", reg[i].str)+1; //We add 1 to consider the '\0' in place.
  254. p+= sprintf((char*)WFIFOP(inter_fd,p), "%s", reg[i].value)+1;
  255. }
  256. }
  257. WFIFOW(inter_fd,2)=p;
  258. WFIFOSET(inter_fd,WFIFOW(inter_fd,2));
  259. return 0;
  260. }
  261. //Request the registries for this player.
  262. int intif_request_registry(struct map_session_data *sd, int flag)
  263. {
  264. nullpo_retr(0, sd);
  265. sd->save_reg.account2_num = -1;
  266. sd->save_reg.account_num = -1;
  267. sd->save_reg.global_num = -1;
  268. if (CheckForCharServer())
  269. return 0;
  270. WFIFOHEAD(inter_fd,6);
  271. WFIFOW(inter_fd,0) = 0x3005;
  272. WFIFOL(inter_fd,2) = sd->status.account_id;
  273. WFIFOL(inter_fd,6) = sd->status.char_id;
  274. WFIFOB(inter_fd,10) = (flag&1?1:0); //Request Acc Reg 2
  275. WFIFOB(inter_fd,11) = (flag&2?1:0); //Request Acc Reg
  276. WFIFOB(inter_fd,12) = (flag&4?1:0); //Request Char Reg
  277. WFIFOSET(inter_fd,13);
  278. return 0;
  279. }
  280. // 倉庫データ要求
  281. int intif_request_storage(int account_id)
  282. {
  283. if (CheckForCharServer())
  284. return 0;
  285. WFIFOHEAD(inter_fd,6);
  286. WFIFOW(inter_fd,0) = 0x3010;
  287. WFIFOL(inter_fd,2) = account_id;
  288. WFIFOSET(inter_fd,6);
  289. return 0;
  290. }
  291. // 倉庫データ送信
  292. int intif_send_storage(struct storage *stor)
  293. {
  294. if (CheckForCharServer())
  295. return 0;
  296. nullpo_retr(0, stor);
  297. WFIFOHEAD(inter_fd,sizeof(struct storage)+8);
  298. WFIFOW(inter_fd,0) = 0x3011;
  299. WFIFOW(inter_fd,2) = sizeof(struct storage)+8;
  300. WFIFOL(inter_fd,4) = stor->account_id;
  301. memcpy( WFIFOP(inter_fd,8),stor, sizeof(struct storage) );
  302. WFIFOSET(inter_fd,WFIFOW(inter_fd,2));
  303. return 0;
  304. }
  305. int intif_request_guild_storage(int account_id,int guild_id)
  306. {
  307. if (CheckForCharServer())
  308. return 0;
  309. WFIFOHEAD(inter_fd,10);
  310. WFIFOW(inter_fd,0) = 0x3018;
  311. WFIFOL(inter_fd,2) = account_id;
  312. WFIFOL(inter_fd,6) = guild_id;
  313. WFIFOSET(inter_fd,10);
  314. return 0;
  315. }
  316. int intif_send_guild_storage(int account_id,struct guild_storage *gstor)
  317. {
  318. if (CheckForCharServer())
  319. return 0;
  320. WFIFOHEAD(inter_fd,sizeof(struct guild_storage)+12);
  321. WFIFOW(inter_fd,0) = 0x3019;
  322. WFIFOW(inter_fd,2) = (unsigned short)sizeof(struct guild_storage)+12;
  323. WFIFOL(inter_fd,4) = account_id;
  324. WFIFOL(inter_fd,8) = gstor->guild_id;
  325. memcpy( WFIFOP(inter_fd,12),gstor, sizeof(struct guild_storage) );
  326. WFIFOSET(inter_fd,WFIFOW(inter_fd,2));
  327. return 0;
  328. }
  329. // パーティ作成要求
  330. int intif_create_party(struct party_member *member,char *name,int item,int item2)
  331. {
  332. if (CheckForCharServer())
  333. return 0;
  334. nullpo_retr(0, member);
  335. WFIFOHEAD(inter_fd,64);
  336. WFIFOW(inter_fd,0) = 0x3020;
  337. WFIFOW(inter_fd,2) = 30+sizeof(struct party_member);
  338. memcpy(WFIFOP(inter_fd,4),name, NAME_LENGTH);
  339. WFIFOB(inter_fd,28)= item;
  340. WFIFOB(inter_fd,29)= item2;
  341. memcpy(WFIFOP(inter_fd,30), member, sizeof(struct party_member));
  342. WFIFOSET(inter_fd,WFIFOW(inter_fd, 2));
  343. return 0;
  344. }
  345. // パーティ情報要求
  346. int intif_request_partyinfo(int party_id)
  347. {
  348. if (CheckForCharServer())
  349. return 0;
  350. WFIFOHEAD(inter_fd,6);
  351. WFIFOW(inter_fd,0) = 0x3021;
  352. WFIFOL(inter_fd,2) = party_id;
  353. WFIFOSET(inter_fd,6);
  354. // if(battle_config.etc_log)
  355. // printf("intif: request party info\n");
  356. return 0;
  357. }
  358. // パーティ追加要求
  359. int intif_party_addmember(int party_id,struct party_member *member)
  360. {
  361. if (CheckForCharServer())
  362. return 0;
  363. WFIFOHEAD(inter_fd,42);
  364. WFIFOW(inter_fd,0)=0x3022;
  365. WFIFOW(inter_fd,2)=8+sizeof(struct party_member);
  366. WFIFOL(inter_fd,4)=party_id;
  367. memcpy(WFIFOP(inter_fd,8),member,sizeof(struct party_member));
  368. WFIFOSET(inter_fd,WFIFOW(inter_fd, 2));
  369. return 1;
  370. }
  371. // パーティ設定変更
  372. int intif_party_changeoption(int party_id,int account_id,int exp,int item)
  373. {
  374. if (CheckForCharServer())
  375. return 0;
  376. WFIFOHEAD(inter_fd,14);
  377. WFIFOW(inter_fd,0)=0x3023;
  378. WFIFOL(inter_fd,2)=party_id;
  379. WFIFOL(inter_fd,6)=account_id;
  380. WFIFOW(inter_fd,10)=exp;
  381. WFIFOW(inter_fd,12)=item;
  382. WFIFOSET(inter_fd,14);
  383. return 0;
  384. }
  385. // パーティ脱退要求
  386. int intif_party_leave(int party_id,int account_id, int char_id)
  387. {
  388. if (CheckForCharServer())
  389. return 0;
  390. WFIFOHEAD(inter_fd,14);
  391. WFIFOW(inter_fd,0)=0x3024;
  392. WFIFOL(inter_fd,2)=party_id;
  393. WFIFOL(inter_fd,6)=account_id;
  394. WFIFOL(inter_fd,10)=char_id;
  395. WFIFOSET(inter_fd,14);
  396. return 0;
  397. }
  398. // パーティ移動要求
  399. int intif_party_changemap(struct map_session_data *sd,int online)
  400. {
  401. if (CheckForCharServer())
  402. return 0;
  403. if(!sd)
  404. return 0;
  405. WFIFOHEAD(inter_fd,19);
  406. WFIFOW(inter_fd,0)=0x3025;
  407. WFIFOL(inter_fd,2)=sd->status.party_id;
  408. WFIFOL(inter_fd,6)=sd->status.account_id;
  409. WFIFOL(inter_fd,10)=sd->status.char_id;
  410. WFIFOW(inter_fd,14)=sd->mapindex;
  411. WFIFOB(inter_fd,16)=online;
  412. WFIFOW(inter_fd,17)=sd->status.base_level;
  413. WFIFOSET(inter_fd,19);
  414. return 1;
  415. }
  416. // パーティー解散要求
  417. int intif_break_party(int party_id)
  418. {
  419. if (CheckForCharServer())
  420. return 0;
  421. WFIFOHEAD(inter_fd,6);
  422. WFIFOW(inter_fd,0)=0x3026;
  423. WFIFOL(inter_fd,2)=party_id;
  424. WFIFOSET(inter_fd,6);
  425. return 0;
  426. }
  427. // パーティ会話送信
  428. int intif_party_message(int party_id,int account_id,const char *mes,int len)
  429. {
  430. if (CheckForCharServer())
  431. return 0;
  432. if (other_mapserver_count < 1)
  433. return 0; //No need to send.
  434. WFIFOHEAD(inter_fd,len + 12);
  435. WFIFOW(inter_fd,0)=0x3027;
  436. WFIFOW(inter_fd,2)=len+12;
  437. WFIFOL(inter_fd,4)=party_id;
  438. WFIFOL(inter_fd,8)=account_id;
  439. memcpy(WFIFOP(inter_fd,12),mes,len);
  440. WFIFOSET(inter_fd,len+12);
  441. return 0;
  442. }
  443. // パーティ競合チェック要求
  444. int intif_party_checkconflict(int party_id,int account_id,int char_id)
  445. {
  446. if (CheckForCharServer())
  447. return 0;
  448. WFIFOHEAD(inter_fd,10 + NAME_LENGTH);
  449. WFIFOW(inter_fd,0)=0x3028;
  450. WFIFOL(inter_fd,2)=party_id;
  451. WFIFOL(inter_fd,6)=account_id;
  452. WFIFOL(inter_fd,10)=char_id;
  453. WFIFOSET(inter_fd,14);
  454. return 0;
  455. }
  456. int intif_party_leaderchange(int party_id,int account_id,int char_id)
  457. {
  458. if (CheckForCharServer())
  459. return 0;
  460. WFIFOHEAD(inter_fd,14);
  461. WFIFOW(inter_fd,0)=0x3029;
  462. WFIFOL(inter_fd,2)=party_id;
  463. WFIFOL(inter_fd,6)=account_id;
  464. WFIFOL(inter_fd,10)=char_id;
  465. WFIFOSET(inter_fd,14);
  466. return 0;
  467. }
  468. // ギルド作成要求
  469. int intif_guild_create(const char *name,const struct guild_member *master)
  470. {
  471. if (CheckForCharServer())
  472. return 0;
  473. nullpo_retr(0, master);
  474. WFIFOHEAD(inter_fd,sizeof(struct guild_member)+(8+NAME_LENGTH));
  475. WFIFOW(inter_fd,0)=0x3030;
  476. WFIFOW(inter_fd,2)=sizeof(struct guild_member)+(8+NAME_LENGTH);
  477. WFIFOL(inter_fd,4)=master->account_id;
  478. memcpy(WFIFOP(inter_fd,8),name,NAME_LENGTH);
  479. memcpy(WFIFOP(inter_fd,8+NAME_LENGTH),master,sizeof(struct guild_member));
  480. WFIFOSET(inter_fd,WFIFOW(inter_fd,2));
  481. return 0;
  482. }
  483. // ギルド情報要求
  484. int intif_guild_request_info(int guild_id)
  485. {
  486. if (CheckForCharServer())
  487. return 0;
  488. WFIFOHEAD(inter_fd,6);
  489. WFIFOW(inter_fd,0) = 0x3031;
  490. WFIFOL(inter_fd,2) = guild_id;
  491. WFIFOSET(inter_fd,6);
  492. return 0;
  493. }
  494. // ギルドメンバ追加要求
  495. int intif_guild_addmember(int guild_id,struct guild_member *m)
  496. {
  497. if (CheckForCharServer())
  498. return 0;
  499. WFIFOHEAD(inter_fd,sizeof(struct guild_member)+8);
  500. WFIFOW(inter_fd,0) = 0x3032;
  501. WFIFOW(inter_fd,2) = sizeof(struct guild_member)+8;
  502. WFIFOL(inter_fd,4) = guild_id;
  503. memcpy(WFIFOP(inter_fd,8),m,sizeof(struct guild_member));
  504. WFIFOSET(inter_fd,WFIFOW(inter_fd,2));
  505. return 0;
  506. }
  507. int intif_guild_change_gm(int guild_id, const char* name, int len)
  508. {
  509. if (CheckForCharServer())
  510. return 0;
  511. WFIFOHEAD(inter_fd, len + 8);
  512. WFIFOW(inter_fd, 0)=0x3033;
  513. WFIFOW(inter_fd, 2)=len+8;
  514. WFIFOL(inter_fd, 4)=guild_id;
  515. memcpy(WFIFOP(inter_fd,8),name,len);
  516. WFIFOSET(inter_fd,len+8);
  517. return 0;
  518. }
  519. // ギルドメンバ脱退/追放要求
  520. int intif_guild_leave(int guild_id,int account_id,int char_id,int flag,const char *mes)
  521. {
  522. if (CheckForCharServer())
  523. return 0;
  524. WFIFOHEAD(inter_fd, 55);
  525. WFIFOW(inter_fd, 0) = 0x3034;
  526. WFIFOL(inter_fd, 2) = guild_id;
  527. WFIFOL(inter_fd, 6) = account_id;
  528. WFIFOL(inter_fd,10) = char_id;
  529. WFIFOB(inter_fd,14) = flag;
  530. memcpy(WFIFOP(inter_fd,15),mes,40);
  531. WFIFOSET(inter_fd,55);
  532. return 0;
  533. }
  534. // ギルドメンバのオンライン状況/Lv更新要求
  535. int intif_guild_memberinfoshort(int guild_id,
  536. int account_id,int char_id,int online,int lv,int class_)
  537. {
  538. if (CheckForCharServer())
  539. return 0;
  540. WFIFOHEAD(inter_fd, 19);
  541. WFIFOW(inter_fd, 0) = 0x3035;
  542. WFIFOL(inter_fd, 2) = guild_id;
  543. WFIFOL(inter_fd, 6) = account_id;
  544. WFIFOL(inter_fd,10) = char_id;
  545. WFIFOB(inter_fd,14) = online;
  546. WFIFOW(inter_fd,15) = lv;
  547. WFIFOW(inter_fd,17) = class_;
  548. WFIFOSET(inter_fd,19);
  549. return 0;
  550. }
  551. // ギルド解散通知
  552. int intif_guild_break(int guild_id)
  553. {
  554. if (CheckForCharServer())
  555. return 0;
  556. WFIFOHEAD(inter_fd, 6);
  557. WFIFOW(inter_fd, 0) = 0x3036;
  558. WFIFOL(inter_fd, 2) = guild_id;
  559. WFIFOSET(inter_fd,6);
  560. return 0;
  561. }
  562. // ギルド会話送信
  563. int intif_guild_message(int guild_id,int account_id,const char *mes,int len)
  564. {
  565. if (CheckForCharServer())
  566. return 0;
  567. if (other_mapserver_count < 1)
  568. return 0; //No need to send.
  569. WFIFOHEAD(inter_fd, len + 12);
  570. WFIFOW(inter_fd,0)=0x3037;
  571. WFIFOW(inter_fd,2)=len+12;
  572. WFIFOL(inter_fd,4)=guild_id;
  573. WFIFOL(inter_fd,8)=account_id;
  574. memcpy(WFIFOP(inter_fd,12),mes,len);
  575. WFIFOSET(inter_fd,len+12);
  576. return 0;
  577. }
  578. // ギルド基本情報変更要求
  579. int intif_guild_change_basicinfo(int guild_id,int type,const void *data,int len)
  580. {
  581. if (CheckForCharServer())
  582. return 0;
  583. WFIFOHEAD(inter_fd, len + 10);
  584. WFIFOW(inter_fd,0)=0x3039;
  585. WFIFOW(inter_fd,2)=len+10;
  586. WFIFOL(inter_fd,4)=guild_id;
  587. WFIFOW(inter_fd,8)=type;
  588. memcpy(WFIFOP(inter_fd,10),data,len);
  589. WFIFOSET(inter_fd,len+10);
  590. return 0;
  591. }
  592. // ギルドメンバ情報変更要求
  593. int intif_guild_change_memberinfo(int guild_id,int account_id,int char_id,
  594. int type,const void *data,int len)
  595. {
  596. if (CheckForCharServer())
  597. return 0;
  598. WFIFOHEAD(inter_fd, len + 18);
  599. WFIFOW(inter_fd, 0)=0x303a;
  600. WFIFOW(inter_fd, 2)=len+18;
  601. WFIFOL(inter_fd, 4)=guild_id;
  602. WFIFOL(inter_fd, 8)=account_id;
  603. WFIFOL(inter_fd,12)=char_id;
  604. WFIFOW(inter_fd,16)=type;
  605. memcpy(WFIFOP(inter_fd,18),data,len);
  606. WFIFOSET(inter_fd,len+18);
  607. return 0;
  608. }
  609. // ギルド役職変更要求
  610. int intif_guild_position(int guild_id,int idx,struct guild_position *p)
  611. {
  612. if (CheckForCharServer())
  613. return 0;
  614. WFIFOHEAD(inter_fd, sizeof(struct guild_position)+12);
  615. WFIFOW(inter_fd,0)=0x303b;
  616. WFIFOW(inter_fd,2)=sizeof(struct guild_position)+12;
  617. WFIFOL(inter_fd,4)=guild_id;
  618. WFIFOL(inter_fd,8)=idx;
  619. memcpy(WFIFOP(inter_fd,12),p,sizeof(struct guild_position));
  620. WFIFOSET(inter_fd,WFIFOW(inter_fd,2));
  621. return 0;
  622. }
  623. // ギルドスキルアップ要求
  624. int intif_guild_skillup(int guild_id, int skill_num, int account_id)
  625. {
  626. if( CheckForCharServer() )
  627. return 0;
  628. WFIFOHEAD(inter_fd, 14);
  629. WFIFOW(inter_fd, 0) = 0x303c;
  630. WFIFOL(inter_fd, 2) = guild_id;
  631. WFIFOL(inter_fd, 6) = skill_num;
  632. WFIFOL(inter_fd, 10) = account_id;
  633. WFIFOSET(inter_fd, 14);
  634. return 0;
  635. }
  636. // ギルド同盟/敵対要求
  637. int intif_guild_alliance(int guild_id1,int guild_id2,int account_id1,int account_id2,int flag)
  638. {
  639. if (CheckForCharServer())
  640. return 0;
  641. WFIFOHEAD(inter_fd,19);
  642. WFIFOW(inter_fd, 0)=0x303d;
  643. WFIFOL(inter_fd, 2)=guild_id1;
  644. WFIFOL(inter_fd, 6)=guild_id2;
  645. WFIFOL(inter_fd,10)=account_id1;
  646. WFIFOL(inter_fd,14)=account_id2;
  647. WFIFOB(inter_fd,18)=flag;
  648. WFIFOSET(inter_fd,19);
  649. return 0;
  650. }
  651. // ギルド告知変更要求
  652. int intif_guild_notice(int guild_id,const char *mes1,const char *mes2)
  653. {
  654. if (CheckForCharServer())
  655. return 0;
  656. WFIFOHEAD(inter_fd,186);
  657. WFIFOW(inter_fd,0)=0x303e;
  658. WFIFOL(inter_fd,2)=guild_id;
  659. memcpy(WFIFOP(inter_fd,6),mes1,60);
  660. memcpy(WFIFOP(inter_fd,66),mes2,120);
  661. WFIFOSET(inter_fd,186);
  662. return 0;
  663. }
  664. // ギルドエンブレム変更要求
  665. int intif_guild_emblem(int guild_id,int len,const char *data)
  666. {
  667. if (CheckForCharServer())
  668. return 0;
  669. if(guild_id<=0 || len<0 || len>2000)
  670. return 0;
  671. WFIFOHEAD(inter_fd,len + 12);
  672. WFIFOW(inter_fd,0)=0x303f;
  673. WFIFOW(inter_fd,2)=len+12;
  674. WFIFOL(inter_fd,4)=guild_id;
  675. WFIFOL(inter_fd,8)=0;
  676. memcpy(WFIFOP(inter_fd,12),data,len);
  677. WFIFOSET(inter_fd,len+12);
  678. return 0;
  679. }
  680. //現在のギルド城占領ギルドを調べる
  681. int intif_guild_castle_dataload(int castle_id,int index)
  682. {
  683. if (CheckForCharServer())
  684. return 0;
  685. WFIFOHEAD(inter_fd,5);
  686. WFIFOW(inter_fd,0)=0x3040;
  687. WFIFOW(inter_fd,2)=castle_id;
  688. WFIFOB(inter_fd,4)=index;
  689. WFIFOSET(inter_fd,5);
  690. return 0;
  691. }
  692. //ギルド城占領ギルド変更要求
  693. int intif_guild_castle_datasave(int castle_id,int index, int value)
  694. {
  695. if (CheckForCharServer())
  696. return 0;
  697. WFIFOHEAD(inter_fd,9);
  698. WFIFOW(inter_fd,0)=0x3041;
  699. WFIFOW(inter_fd,2)=castle_id;
  700. WFIFOB(inter_fd,4)=index;
  701. WFIFOL(inter_fd,5)=value;
  702. WFIFOSET(inter_fd,9);
  703. return 0;
  704. }
  705. //-----------------------------------------------------------------
  706. // Homunculus Packets send to Inter server [albator]
  707. //-----------------------------------------------------------------
  708. int intif_homunculus_create(int account_id, struct s_homunculus *sh)
  709. {
  710. if (CheckForCharServer())
  711. return 0;
  712. WFIFOHEAD(inter_fd, sizeof(struct s_homunculus)+8);
  713. WFIFOW(inter_fd,0) = 0x3090;
  714. WFIFOW(inter_fd,2) = sizeof(struct s_homunculus)+8;
  715. WFIFOL(inter_fd,4) = account_id;
  716. memcpy(WFIFOP(inter_fd,8),sh,sizeof(struct s_homunculus));
  717. WFIFOSET(inter_fd, WFIFOW(inter_fd,2));
  718. return 0;
  719. }
  720. int intif_homunculus_requestload(int account_id, int homun_id)
  721. {
  722. if (CheckForCharServer())
  723. return 0;
  724. WFIFOHEAD(inter_fd, 10);
  725. WFIFOW(inter_fd,0) = 0x3091;
  726. WFIFOL(inter_fd,2) = account_id;
  727. WFIFOL(inter_fd,6) = homun_id;
  728. WFIFOSET(inter_fd, 10);
  729. return 1;
  730. }
  731. int intif_homunculus_requestsave(int account_id, struct s_homunculus* sh)
  732. {
  733. if (CheckForCharServer())
  734. return 0;
  735. WFIFOHEAD(inter_fd, sizeof(struct s_homunculus)+8);
  736. WFIFOW(inter_fd,0) = 0x3092;
  737. WFIFOW(inter_fd,2) = sizeof(struct s_homunculus)+8;
  738. WFIFOL(inter_fd,4) = account_id;
  739. memcpy(WFIFOP(inter_fd,8),sh,sizeof(struct s_homunculus));
  740. WFIFOSET(inter_fd, WFIFOW(inter_fd,2));
  741. return 0;
  742. }
  743. int intif_homunculus_requestdelete(int homun_id)
  744. {
  745. if (CheckForCharServer())
  746. return 0;
  747. WFIFOHEAD(inter_fd, 6);
  748. WFIFOW(inter_fd, 0) = 0x3093;
  749. WFIFOL(inter_fd,2) = homun_id;
  750. WFIFOSET(inter_fd,6);
  751. return 0;
  752. }
  753. //-----------------------------------------------------------------
  754. // Packets receive from inter server
  755. // Wisp/Page reception // rewritten by [Yor]
  756. int intif_parse_WisMessage(int fd)
  757. {
  758. struct map_session_data* sd;
  759. char *wisp_source;
  760. char name[NAME_LENGTH];
  761. int id, i;
  762. id=RFIFOL(fd,4);
  763. safestrncpy(name, (char*)RFIFOP(fd,32), NAME_LENGTH);
  764. sd = map_nick2sd(name);
  765. if(sd == NULL || strcmp(sd->status.name, name) != 0)
  766. { //Not found
  767. intif_wis_replay(id,1);
  768. return 0;
  769. }
  770. if(sd->state.ignoreAll) {
  771. intif_wis_replay(id, 2);
  772. return 0;
  773. }
  774. wisp_source = (char *) RFIFOP(fd,8); // speed up [Yor]
  775. for(i=0; i < MAX_IGNORE_LIST &&
  776. sd->ignore[i].name[0] != '\0' &&
  777. strcmp(sd->ignore[i].name, wisp_source) != 0
  778. ; i++);
  779. if (i < MAX_IGNORE_LIST && sd->ignore[i].name[0] != '\0')
  780. { //Ignored
  781. intif_wis_replay(id, 2);
  782. return 0;
  783. }
  784. //Success to send whisper.
  785. clif_wis_message(sd->fd, wisp_source, (char*)RFIFOP(fd,56),RFIFOW(fd,2)-56);
  786. intif_wis_replay(id,0); // 送信成功
  787. return 0;
  788. }
  789. // Wisp/page transmission result reception
  790. int intif_parse_WisEnd(int fd)
  791. {
  792. struct map_session_data* sd;
  793. if (battle_config.etc_log)
  794. ShowInfo("intif_parse_wisend: player: %s, flag: %d\n", RFIFOP(fd,2), RFIFOB(fd,26)); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
  795. sd = (struct map_session_data *)map_nick2sd((char *) RFIFOP(fd,2));
  796. if (sd != NULL)
  797. clif_wis_end(sd->fd, RFIFOB(fd,26));
  798. return 0;
  799. }
  800. static int mapif_parse_WisToGM_sub(struct map_session_data* sd,va_list va)
  801. {
  802. int min_gm_level = va_arg(va, int);
  803. char *wisp_name;
  804. char *message;
  805. int len;
  806. if (pc_isGM(sd) < min_gm_level) return 0;
  807. wisp_name = va_arg(va, char*);
  808. message = va_arg(va, char*);
  809. len = va_arg(va, int);
  810. clif_wis_message(sd->fd, wisp_name, message, len);
  811. return 1;
  812. }
  813. // Received wisp message from map-server via char-server for ALL gm
  814. // 0x3003/0x3803 <packet_len>.w <wispname>.24B <min_gm_level>.w <message>.?B
  815. int mapif_parse_WisToGM(int fd)
  816. {
  817. int min_gm_level, mes_len;
  818. char Wisp_name[NAME_LENGTH];
  819. char mbuf[255];
  820. char *message;
  821. mes_len = RFIFOW(fd,2) - 30;
  822. message = (char *) (mes_len >= 255 ? (char *) aMallocA(mes_len) : mbuf);
  823. min_gm_level = (int)RFIFOW(fd,28);
  824. safestrncpy(Wisp_name, (char*)RFIFOP(fd,4), NAME_LENGTH);
  825. safestrncpy(message, (char*)RFIFOP(fd,30), mes_len);
  826. // information is sended to all online GM
  827. clif_foreachclient(mapif_parse_WisToGM_sub, min_gm_level, Wisp_name, message, mes_len);
  828. if (message != mbuf)
  829. aFree(message);
  830. return 0;
  831. }
  832. // アカウント変数通知
  833. int intif_parse_Registers(int fd)
  834. {
  835. int j,p,len,max, flag;
  836. struct map_session_data *sd;
  837. struct global_reg *reg;
  838. int *qty;
  839. if( (sd=map_id2sd(RFIFOL(fd,4)))==NULL)
  840. return 1;
  841. if (RFIFOB(fd,12) == 3 && sd->status.char_id != RFIFOL(fd,8))
  842. return 1; //Character registry from another character.
  843. flag = (sd->save_reg.global_num == -1 || sd->save_reg.account_num == -1 || sd->save_reg.account2_num == -1);
  844. switch (RFIFOB(fd,12)) {
  845. case 3: //Character Registry
  846. reg = sd->save_reg.global;
  847. qty = &sd->save_reg.global_num;
  848. max = GLOBAL_REG_NUM;
  849. break;
  850. case 2: //Account Registry
  851. reg = sd->save_reg.account;
  852. qty = &sd->save_reg.account_num;
  853. max = ACCOUNT_REG_NUM;
  854. break;
  855. case 1: //Account2 Registry
  856. reg = sd->save_reg.account2;
  857. qty = &sd->save_reg.account2_num;
  858. max = ACCOUNT_REG2_NUM;
  859. break;
  860. default:
  861. ShowError("intif_parse_Registers: Unrecognized type %d\n",RFIFOB(fd,12));
  862. return 0;
  863. }
  864. for(j=0,p=13;j<max && p<RFIFOW(fd,2);j++){
  865. sscanf((char*)RFIFOP(fd,p), "%31c%n", reg[j].str,&len);
  866. reg[j].str[len]='\0';
  867. p += len+1; //+1 to skip the '\0' between strings.
  868. sscanf((char*)RFIFOP(fd,p), "%255c%n", reg[j].value,&len);
  869. reg[j].value[len]='\0';
  870. p += len+1;
  871. }
  872. *qty = j;
  873. if (flag && sd->save_reg.global_num > -1 && sd->save_reg.account_num > -1 && sd->save_reg.account2_num > -1)
  874. pc_reg_received(sd); //Received all registry values, execute init scripts and what-not. [Skotlex]
  875. return 1;
  876. }
  877. // 倉庫データ受信
  878. int intif_parse_LoadStorage(int fd)
  879. {
  880. struct storage *stor;
  881. struct map_session_data *sd;
  882. sd=map_id2sd( RFIFOL(fd,4) );
  883. if(sd==NULL){
  884. ShowError("intif_parse_LoadStorage: user not found %d\n",RFIFOL(fd,4));
  885. return 1;
  886. }
  887. if (sd->state.finalsave)
  888. return 1; //Player is already scheduled to leave the server.
  889. stor = account2storage( RFIFOL(fd,4));
  890. if (stor->storage_status == 1) { // Already open.. lets ignore this update
  891. ShowWarning("intif_parse_LoadStorage: storage received for a client already open (User %d:%d)\n", sd->status.account_id, sd->status.char_id);
  892. return 1;
  893. }
  894. if (stor->dirty) { // Already have storage, and it has been modified and not saved yet! Exploit! [Skotlex]
  895. ShowWarning("intif_parse_LoadStorage: received storage for an already modified non-saved storage! (User %d:%d)\n", sd->status.account_id, sd->status.char_id);
  896. return 1;
  897. }
  898. if (RFIFOW(fd,2)-8 != sizeof(struct storage)) {
  899. ShowError("intif_parse_LoadStorage: data size error %d %d\n", RFIFOW(fd,2)-8, sizeof(struct storage));
  900. return 1;
  901. }
  902. if(battle_config.save_log)
  903. ShowInfo("intif_openstorage: %d\n",RFIFOL(fd,4) );
  904. memcpy(stor,RFIFOP(fd,8),sizeof(struct storage));
  905. stor->dirty=0;
  906. stor->storage_status=1;
  907. sd->state.storage_flag = 1;
  908. clif_storagelist(sd,stor);
  909. clif_updatestorageamount(sd,stor);
  910. return 0;
  911. }
  912. // 倉庫データ送信成功
  913. int intif_parse_SaveStorage(int fd)
  914. {
  915. if(battle_config.save_log)
  916. ShowInfo("intif_savestorage: done %d %d\n",RFIFOL(fd,2),RFIFOB(fd,6) );
  917. storage_storage_saved(RFIFOL(fd,2));
  918. return 0;
  919. }
  920. int intif_parse_LoadGuildStorage(int fd)
  921. {
  922. struct guild_storage *gstor;
  923. struct map_session_data *sd;
  924. int guild_id;
  925. guild_id = RFIFOL(fd,8);
  926. if(guild_id <= 0)
  927. return 1;
  928. sd=map_id2sd( RFIFOL(fd,4) );
  929. if(sd==NULL){
  930. ShowError("intif_parse_LoadGuildStorage: user not found %d\n",RFIFOL(fd,4));
  931. return 1;
  932. }
  933. gstor=guild2storage(guild_id);
  934. if(!gstor) {
  935. ShowWarning("intif_parse_LoadGuildStorage: error guild_id %d not exist\n",guild_id);
  936. }
  937. if (gstor->storage_status == 1) { // Already open.. lets ignore this update
  938. ShowWarning("intif_parse_LoadGuildStorage: storage received for a client already open (User %d:%d)\n", sd->status.account_id, sd->status.char_id);
  939. return 1;
  940. }
  941. if (gstor->dirty) { // Already have storage, and it has been modified and not saved yet! Exploit! [Skotlex]
  942. ShowWarning("intif_parse_LoadGuildStorage: received storage for an already modified non-saved storage! (User %d:%d)\n", sd->status.account_id, sd->status.char_id);
  943. return 1;
  944. }
  945. if( RFIFOW(fd,2)-12 != sizeof(struct guild_storage) ){
  946. ShowError("intif_parse_LoadGuildStorage: data size error %d %d\n",RFIFOW(fd,2)-12 , sizeof(struct guild_storage));
  947. gstor->storage_status = 0;
  948. return 1;
  949. }
  950. if(battle_config.save_log)
  951. ShowInfo("intif_open_guild_storage: %d\n",RFIFOL(fd,4) );
  952. memcpy(gstor,RFIFOP(fd,12),sizeof(struct guild_storage));
  953. gstor->storage_status = 1;
  954. sd->state.storage_flag = 2;
  955. clif_guildstoragelist(sd,gstor);
  956. clif_updateguildstorageamount(sd,gstor);
  957. return 0;
  958. }
  959. int intif_parse_SaveGuildStorage(int fd)
  960. {
  961. if(battle_config.save_log) {
  962. ShowInfo("intif_save_guild_storage: done %d %d %d\n",RFIFOL(fd,2),RFIFOL(fd,6),RFIFOB(fd,10) );
  963. }
  964. storage_guild_storagesaved(/*RFIFOL(fd,2), */RFIFOL(fd,6));
  965. return 0;
  966. }
  967. // パーティ作成可否
  968. int intif_parse_PartyCreated(int fd)
  969. {
  970. if(battle_config.etc_log)
  971. ShowInfo("intif: party created by account %d\n\n", RFIFOL(fd,2));
  972. party_created(RFIFOL(fd,2), RFIFOL(fd,6),RFIFOB(fd,10),RFIFOL(fd,11), (char *)RFIFOP(fd,15));
  973. return 0;
  974. }
  975. // パーティ情報
  976. int intif_parse_PartyInfo(int fd)
  977. {
  978. if( RFIFOW(fd,2)==8){
  979. ShowWarning("intif: party noinfo %d\n",RFIFOL(fd,4));
  980. party_recv_noinfo(RFIFOL(fd,4));
  981. return 0;
  982. }
  983. // printf("intif: party info %d\n",RFIFOL(fd,4));
  984. if( RFIFOW(fd,2)!=sizeof(struct party)+4 )
  985. ShowError("intif: party info : data size error %d %d %d\n",RFIFOL(fd,4),RFIFOW(fd,2),sizeof(struct party)+4);
  986. party_recv_info((struct party *)RFIFOP(fd,4));
  987. return 0;
  988. }
  989. // パーティ追加通知
  990. int intif_parse_PartyMemberAdded(int fd)
  991. {
  992. if(battle_config.etc_log)
  993. ShowInfo("intif: party member added Party (%d), Account(%d), Char(%d)\n",RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10));
  994. party_member_added(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10), RFIFOB(fd, 14));
  995. return 0;
  996. }
  997. // パーティ設定変更通知
  998. int intif_parse_PartyOptionChanged(int fd)
  999. {
  1000. party_optionchanged(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOW(fd,10),RFIFOW(fd,12),RFIFOB(fd,14));
  1001. return 0;
  1002. }
  1003. // パーティ脱退通知
  1004. int intif_parse_PartyMemberLeaved(int fd)
  1005. {
  1006. if(battle_config.etc_log)
  1007. ShowInfo("intif: party member leaved: Party(%d), Account(%d), Char(%d)\n",RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10));
  1008. party_member_leaved(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10));
  1009. return 0;
  1010. }
  1011. // パーティ解散通知
  1012. int intif_parse_PartyBroken(int fd)
  1013. {
  1014. party_broken(RFIFOL(fd,2));
  1015. return 0;
  1016. }
  1017. // パーティ移動通知
  1018. int intif_parse_PartyMove(int fd)
  1019. {
  1020. party_recv_movemap(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOW(fd,14),RFIFOB(fd,16),RFIFOW(fd,17));
  1021. return 0;
  1022. }
  1023. // パーティメッセージ
  1024. int intif_parse_PartyMessage(int fd)
  1025. {
  1026. party_recv_message(RFIFOL(fd,4),RFIFOL(fd,8),(char *) RFIFOP(fd,12),RFIFOW(fd,2)-12);
  1027. return 0;
  1028. }
  1029. // ギルド作成可否
  1030. int intif_parse_GuildCreated(int fd)
  1031. {
  1032. guild_created(RFIFOL(fd,2),RFIFOL(fd,6));
  1033. return 0;
  1034. }
  1035. // ギルド情報
  1036. int intif_parse_GuildInfo(int fd)
  1037. {
  1038. if(RFIFOW(fd,2) == 8) {
  1039. ShowWarning("intif: guild noinfo %d\n",RFIFOL(fd,4));
  1040. guild_recv_noinfo(RFIFOL(fd,4));
  1041. return 0;
  1042. }
  1043. if( RFIFOW(fd,2)!=sizeof(struct guild)+4 )
  1044. ShowError("intif: guild info : data size error Gid: %d recv size: %d Expected size: %d\n",RFIFOL(fd,4),RFIFOW(fd,2),sizeof(struct guild)+4);
  1045. guild_recv_info((struct guild *)RFIFOP(fd,4));
  1046. return 0;
  1047. }
  1048. // ギルドメンバ追加通知
  1049. int intif_parse_GuildMemberAdded(int fd)
  1050. {
  1051. if(battle_config.etc_log)
  1052. ShowInfo("intif: guild member added %d %d %d %d\n",RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOB(fd,14));
  1053. guild_member_added(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOB(fd,14));
  1054. return 0;
  1055. }
  1056. // ギルドメンバ脱退/追放通知
  1057. int intif_parse_GuildMemberLeaved(int fd)
  1058. {
  1059. guild_member_leaved(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOB(fd,14),(char *)RFIFOP(fd,55),(char *)RFIFOP(fd,15));
  1060. return 0;
  1061. }
  1062. // ギルドメンバオンライン状態/Lv変更通知
  1063. int intif_parse_GuildMemberInfoShort(int fd)
  1064. {
  1065. guild_recv_memberinfoshort(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOB(fd,14),RFIFOW(fd,15),RFIFOW(fd,17));
  1066. return 0;
  1067. }
  1068. // ギルド解散通知
  1069. int intif_parse_GuildBroken(int fd)
  1070. {
  1071. guild_broken(RFIFOL(fd,2),RFIFOB(fd,6));
  1072. return 0;
  1073. }
  1074. // basic guild info change notice
  1075. // 0x3839 <packet len>.w <guild id>.l <type>.w <data>.?b
  1076. int intif_parse_GuildBasicInfoChanged(int fd)
  1077. {
  1078. //int len = RFIFOW(fd,2) - 10;
  1079. int guild_id = RFIFOL(fd,4);
  1080. int type = RFIFOW(fd,8);
  1081. //void* data = RFIFOP(fd,10);
  1082. struct guild* g = guild_search(guild_id);
  1083. if( g == NULL )
  1084. return 0;
  1085. switch(type) {
  1086. case GBI_EXP: g->exp = RFIFOL(fd,10); break;
  1087. case GBI_GUILDLV: g->guild_lv = RFIFOW(fd,10); break;
  1088. case GBI_SKILLPOINT: g->skill_point = RFIFOL(fd,10); break;
  1089. }
  1090. return 0;
  1091. }
  1092. // guild member info change notice
  1093. // 0x383a <packet len>.w <guild id>.l <account id>.l <char id>.l <type>.w <data>.?b
  1094. int intif_parse_GuildMemberInfoChanged(int fd)
  1095. {
  1096. //int len = RFIFOW(fd,2) - 18;
  1097. int guild_id = RFIFOL(fd,4);
  1098. int account_id = RFIFOL(fd,8);
  1099. int char_id = RFIFOL(fd,12);
  1100. int type = RFIFOW(fd,16);
  1101. void* data = RFIFOP(fd,18);
  1102. int dd = *((int *)data);
  1103. struct guild* g;
  1104. int idx;
  1105. g = guild_search(guild_id);
  1106. if( g == NULL )
  1107. return 0;
  1108. idx = guild_getindex(g,account_id,char_id);
  1109. if( idx == -1 )
  1110. return 0;
  1111. switch( type ) {
  1112. case GMI_POSITION: g->member[idx].position = dd; guild_memberposition_changed(g,idx,dd); break;
  1113. case GMI_EXP: g->member[idx].exp = dd; break;
  1114. case GMI_HAIR: g->member[idx].hair = dd; break;
  1115. case GMI_HAIR_COLOR: g->member[idx].hair_color = dd; break;
  1116. case GMI_GENDER: g->member[idx].gender = dd; break;
  1117. case GMI_CLASS: g->member[idx].class_ = dd; break;
  1118. case GMI_LEVEL: g->member[idx].lv = dd; break;
  1119. }
  1120. return 0;
  1121. }
  1122. // ギルド役職変更通知
  1123. int intif_parse_GuildPosition(int fd)
  1124. {
  1125. if( RFIFOW(fd,2)!=sizeof(struct guild_position)+12 )
  1126. ShowError("intif: guild info : data size error\n %d %d %d",RFIFOL(fd,4),RFIFOW(fd,2),sizeof(struct guild_position)+12);
  1127. guild_position_changed(RFIFOL(fd,4),RFIFOL(fd,8),(struct guild_position *)RFIFOP(fd,12));
  1128. return 0;
  1129. }
  1130. // ギルドスキル割り振り通知
  1131. int intif_parse_GuildSkillUp(int fd)
  1132. {
  1133. guild_skillupack(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10));
  1134. return 0;
  1135. }
  1136. // ギルド同盟/敵対通知
  1137. int intif_parse_GuildAlliance(int fd)
  1138. {
  1139. guild_allianceack(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOL(fd,14),RFIFOB(fd,18),(char *) RFIFOP(fd,19),(char *) RFIFOP(fd,43));
  1140. return 0;
  1141. }
  1142. // ギルド告知変更通知
  1143. int intif_parse_GuildNotice(int fd)
  1144. {
  1145. guild_notice_changed(RFIFOL(fd,2),(char *) RFIFOP(fd,6),(char *) RFIFOP(fd,66));
  1146. return 0;
  1147. }
  1148. // ギルドエンブレム変更通知
  1149. int intif_parse_GuildEmblem(int fd)
  1150. {
  1151. guild_emblem_changed(RFIFOW(fd,2)-12,RFIFOL(fd,4),RFIFOL(fd,8), (char *)RFIFOP(fd,12));
  1152. return 0;
  1153. }
  1154. // ギルド会話受信
  1155. int intif_parse_GuildMessage(int fd)
  1156. {
  1157. guild_recv_message(RFIFOL(fd,4),RFIFOL(fd,8),(char *) RFIFOP(fd,12),RFIFOW(fd,2)-12);
  1158. return 0;
  1159. }
  1160. // ギルド城データ要求返信
  1161. int intif_parse_GuildCastleDataLoad(int fd)
  1162. {
  1163. return guild_castledataloadack(RFIFOW(fd,2),RFIFOB(fd,4),RFIFOL(fd,5));
  1164. }
  1165. // ギルド城データ変更通知
  1166. int intif_parse_GuildCastleDataSave(int fd)
  1167. {
  1168. return guild_castledatasaveack(RFIFOW(fd,2),RFIFOB(fd,4),RFIFOL(fd,5));
  1169. }
  1170. // ギルド城データ一括受信(初期化時)
  1171. int intif_parse_GuildCastleAllDataLoad(int fd)
  1172. {
  1173. return guild_castlealldataload(RFIFOW(fd,2),(struct guild_castle *)RFIFOP(fd,4));
  1174. }
  1175. int intif_parse_GuildMasterChanged(int fd)
  1176. {
  1177. return guild_gm_changed(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10));
  1178. }
  1179. // pet
  1180. int intif_parse_CreatePet(int fd)
  1181. {
  1182. pet_get_egg(RFIFOL(fd,2),RFIFOL(fd,7),RFIFOB(fd,6));
  1183. return 0;
  1184. }
  1185. int intif_parse_RecvPetData(int fd)
  1186. {
  1187. struct s_pet p;
  1188. int len;
  1189. len=RFIFOW(fd,2);
  1190. if(sizeof(struct s_pet)!=len-9) {
  1191. if(battle_config.etc_log)
  1192. ShowError("intif: pet data: data size error %d %d\n",sizeof(struct s_pet),len-9);
  1193. }
  1194. else{
  1195. memcpy(&p,RFIFOP(fd,9),sizeof(struct s_pet));
  1196. pet_recv_petdata(RFIFOL(fd,4),&p,RFIFOB(fd,8));
  1197. }
  1198. return 0;
  1199. }
  1200. int intif_parse_SavePetOk(int fd)
  1201. {
  1202. if(RFIFOB(fd,6) == 1)
  1203. ShowError("pet data save failure\n");
  1204. return 0;
  1205. }
  1206. int intif_parse_DeletePetOk(int fd)
  1207. {
  1208. if(RFIFOB(fd,2) == 1)
  1209. ShowError("pet data delete failure\n");
  1210. return 0;
  1211. }
  1212. int intif_parse_ChangeNameOk(int fd)
  1213. {
  1214. struct map_session_data *sd = NULL;
  1215. if((sd=map_id2sd(RFIFOL(fd,2)))==NULL ||
  1216. sd->status.char_id != RFIFOL(fd,6))
  1217. return 0;
  1218. switch (RFIFOB(fd,10)) {
  1219. case 0: //Players [NOT SUPPORTED YET]
  1220. break;
  1221. case 1: //Pets
  1222. pet_change_name_ack(sd, (char*)RFIFOP(fd,12), RFIFOB(fd,11));
  1223. break;
  1224. case 2: //Hom
  1225. merc_hom_change_name_ack(sd, (char*)RFIFOP(fd,12), RFIFOB(fd,11));
  1226. break;
  1227. }
  1228. return 0;
  1229. }
  1230. //----------------------------------------------------------------
  1231. // Homunculus recv packets [albator]
  1232. int intif_parse_CreateHomunculus(int fd)
  1233. {
  1234. int len;
  1235. len=RFIFOW(fd,2)-9;
  1236. if(sizeof(struct s_homunculus)!=len) {
  1237. if(battle_config.etc_log)
  1238. ShowError("intif: create homun data: data size error %d != %d\n",sizeof(struct s_homunculus),len);
  1239. return 0;
  1240. }
  1241. merc_hom_recv_data(RFIFOL(fd,4), (struct s_homunculus*)RFIFOP(fd,9), RFIFOB(fd,8)) ;
  1242. return 0;
  1243. }
  1244. int intif_parse_RecvHomunculusData(int fd)
  1245. {
  1246. int len;
  1247. len=RFIFOW(fd,2)-9;
  1248. if(sizeof(struct s_homunculus)!=len) {
  1249. if(battle_config.etc_log)
  1250. ShowError("intif: homun data: data size error %d %d\n",sizeof(struct s_homunculus),len);
  1251. return 0;
  1252. }
  1253. merc_hom_recv_data(RFIFOL(fd,4), (struct s_homunculus*)RFIFOP(fd,9), RFIFOB(fd,8));
  1254. return 0;
  1255. }
  1256. int intif_parse_SaveHomunculusOk(int fd)
  1257. {
  1258. if(RFIFOB(fd,6) != 1)
  1259. ShowError("homunculus data save failure for account %d\n", RFIFOL(fd,2));
  1260. return 0;
  1261. }
  1262. int intif_parse_DeleteHomunculusOk(int fd)
  1263. {
  1264. if(RFIFOB(fd,2) != 1)
  1265. ShowError("Homunculus data delete failure\n");
  1266. return 0;
  1267. }
  1268. #ifndef TXT_ONLY
  1269. /*==========================================
  1270. * MAIL SYSTEM
  1271. * By Zephyrus
  1272. *==========================================*/
  1273. /*------------------------------------------
  1274. * Inbox Request
  1275. * flag: 0 Update Inbox | 1 OpenMail
  1276. *------------------------------------------*/
  1277. int intif_Mail_requestinbox(int char_id, unsigned char flag)
  1278. {
  1279. if (CheckForCharServer())
  1280. return 0;
  1281. WFIFOHEAD(inter_fd,7);
  1282. WFIFOW(inter_fd,0) = 0x3048;
  1283. WFIFOL(inter_fd,2) = char_id;
  1284. WFIFOB(inter_fd,6) = flag;
  1285. WFIFOSET(inter_fd,7);
  1286. return 0;
  1287. }
  1288. int intif_parse_Mail_inboxreceived(int fd)
  1289. {
  1290. struct map_session_data *sd;
  1291. unsigned char flag = RFIFOB(fd,8);
  1292. sd = map_charid2sd(RFIFOL(fd,4));
  1293. if (sd == NULL)
  1294. {
  1295. ShowError("intif_parse_Mail_inboxreceived: char not found %d\n",RFIFOL(fd,4));
  1296. return 1;
  1297. }
  1298. if (sd->state.finalsave)
  1299. return 1;
  1300. if (RFIFOW(fd,2) - 9 != sizeof(struct mail_data))
  1301. {
  1302. ShowError("intif_parse_Mail_inboxreceived: data size error %d %d\n", RFIFOW(fd,2) - 9, sizeof(struct mail_data));
  1303. return 1;
  1304. }
  1305. //FIXME: this operation is not safe [ultramage]
  1306. memcpy(&sd->mail.inbox, RFIFOP(fd,9), sizeof(struct mail_data));
  1307. if (flag)
  1308. clif_Mail_refreshinbox(sd);
  1309. else
  1310. {
  1311. char output[128];
  1312. sprintf(output, "You have %d new emails (%d unread)", sd->mail.inbox.unchecked, sd->mail.inbox.unread + sd->mail.inbox.unchecked);
  1313. clif_disp_onlyself(sd, output, strlen(output));
  1314. }
  1315. return 0;
  1316. }
  1317. /*------------------------------------------
  1318. * Mail Readed
  1319. *------------------------------------------*/
  1320. int intif_Mail_read(int mail_id)
  1321. {
  1322. if (CheckForCharServer())
  1323. return 0;
  1324. WFIFOHEAD(inter_fd,6);
  1325. WFIFOW(inter_fd,0) = 0x3049;
  1326. WFIFOL(inter_fd,2) = mail_id;
  1327. WFIFOSET(inter_fd,6);
  1328. return 0;
  1329. }
  1330. /*------------------------------------------
  1331. * Get Attachment
  1332. *------------------------------------------*/
  1333. int intif_Mail_getattach(int char_id, int mail_id)
  1334. {
  1335. if (CheckForCharServer())
  1336. return 0;
  1337. WFIFOHEAD(inter_fd,10);
  1338. WFIFOW(inter_fd,0) = 0x304a;
  1339. WFIFOL(inter_fd,2) = char_id;
  1340. WFIFOL(inter_fd,6) = mail_id;
  1341. WFIFOSET(inter_fd, 10);
  1342. return 0;
  1343. }
  1344. int intif_parse_Mail_getattach(int fd)
  1345. {
  1346. struct map_session_data *sd;
  1347. struct item item;
  1348. int zeny = RFIFOL(fd,8);
  1349. sd = map_charid2sd( RFIFOL(fd,4) );
  1350. if (sd == NULL)
  1351. {
  1352. ShowError("intif_parse_Mail_getattach: char not found %d\n",RFIFOL(fd,4));
  1353. return 1;
  1354. }
  1355. if (sd->state.finalsave)
  1356. return 1;
  1357. if (RFIFOW(fd,2) - 12 != sizeof(struct item))
  1358. {
  1359. ShowError("intif_parse_Mail_getattach: data size error %d %d\n", RFIFOW(fd,2) - 16, sizeof(struct item));
  1360. return 1;
  1361. }
  1362. memcpy(&item, RFIFOP(fd,12), sizeof(struct item));
  1363. mail_getattachment(sd, zeny, &item);
  1364. return 0;
  1365. }
  1366. /*------------------------------------------
  1367. * Delete Message
  1368. *------------------------------------------*/
  1369. int intif_Mail_delete(int char_id, int mail_id)
  1370. {
  1371. if (CheckForCharServer())
  1372. return 0;
  1373. WFIFOHEAD(inter_fd,10);
  1374. WFIFOW(inter_fd,0) = 0x304b;
  1375. WFIFOL(inter_fd,2) = char_id;
  1376. WFIFOL(inter_fd,6) = mail_id;
  1377. WFIFOSET(inter_fd,10);
  1378. return 0;
  1379. }
  1380. int intif_parse_Mail_delete(int fd)
  1381. {
  1382. int char_id = RFIFOL(fd,2);
  1383. int mail_id = RFIFOL(fd,6);
  1384. bool failed = RFIFOB(fd,10);
  1385. struct map_session_data *sd = map_charid2sd(char_id);
  1386. if (sd == NULL)
  1387. {
  1388. ShowError("intif_parse_Mail_delete: char not found %d\n", char_id);
  1389. return 1;
  1390. }
  1391. if (sd->state.finalsave)
  1392. return 1;
  1393. if (!failed)
  1394. {
  1395. int i;
  1396. ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id);
  1397. if( i < MAIL_MAX_INBOX )
  1398. {
  1399. memset(&sd->mail.inbox.msg[i], 0, sizeof(struct mail_message));
  1400. sd->mail.inbox.amount--;
  1401. }
  1402. if( sd->mail.inbox.full )
  1403. intif_Mail_requestinbox(sd->status.char_id, 1); // Free space is available for new mails
  1404. }
  1405. clif_Mail_delete(sd->fd, mail_id, failed);
  1406. return 0;
  1407. }
  1408. /*------------------------------------------
  1409. * Return Message
  1410. *------------------------------------------*/
  1411. int intif_Mail_return(int char_id, int mail_id)
  1412. {
  1413. if (CheckForCharServer())
  1414. return 0;
  1415. WFIFOHEAD(inter_fd,10);
  1416. WFIFOW(inter_fd,0) = 0x304c;
  1417. WFIFOL(inter_fd,2) = char_id;
  1418. WFIFOL(inter_fd,6) = mail_id;
  1419. WFIFOSET(inter_fd,10);
  1420. return 0;
  1421. }
  1422. int intif_parse_Mail_return(int fd)
  1423. {
  1424. struct map_session_data *sd = map_charid2sd(RFIFOL(fd,2));
  1425. int mail_id = RFIFOL(fd,6);
  1426. short fail = RFIFOB(fd,10);
  1427. if( sd == NULL )
  1428. {
  1429. ShowError("intif_parse_Mail_return: char not found %d\n",RFIFOL(fd,2));
  1430. return 1;
  1431. }
  1432. if( sd->state.finalsave )
  1433. return 1;
  1434. if( !fail )
  1435. {
  1436. int i;
  1437. ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id);
  1438. if (i < MAIL_MAX_INBOX)
  1439. {
  1440. memset(&sd->mail.inbox.msg[i], 0, sizeof(struct mail_message));
  1441. sd->mail.inbox.amount--;
  1442. }
  1443. }
  1444. clif_Mail_return(sd->fd, mail_id, fail);
  1445. return 0;
  1446. }
  1447. /*------------------------------------------
  1448. * Send Mail
  1449. *------------------------------------------*/
  1450. int intif_Mail_send(int account_id, struct mail_message *msg)
  1451. {
  1452. int len = sizeof(struct mail_message) + 8;
  1453. if (CheckForCharServer())
  1454. return 0;
  1455. WFIFOHEAD(inter_fd,len);
  1456. WFIFOW(inter_fd,0) = 0x304d;
  1457. WFIFOW(inter_fd,2) = len;
  1458. WFIFOL(inter_fd,4) = account_id;
  1459. memcpy(WFIFOP(inter_fd,8), msg, sizeof(struct mail_message));
  1460. WFIFOSET(inter_fd,len);
  1461. return 1;
  1462. }
  1463. static void intif_parse_Mail_send(int fd)
  1464. {
  1465. struct mail_message msg;
  1466. struct map_session_data *sd;
  1467. bool fail;
  1468. if( RFIFOW(fd,2) - 4 != sizeof(struct mail_message) )
  1469. {
  1470. ShowError("intif_parse_Mail_send: data size error %d %d\n", RFIFOW(fd,2) - 4, sizeof(struct mail_message));
  1471. return;
  1472. }
  1473. memcpy(&msg, RFIFOP(fd,4), sizeof(struct mail_message));
  1474. fail = (msg.id == 0);
  1475. if( (sd = map_charid2sd(msg.send_id)) )
  1476. {
  1477. if( fail )
  1478. mail_deliveryfail(sd, &msg);
  1479. else
  1480. clif_Mail_send(sd->fd, false);
  1481. }
  1482. if( fail )
  1483. return;
  1484. if( (sd = map_charid2sd(msg.dest_id)) )
  1485. {
  1486. sd->mail.inbox.changed = true;
  1487. clif_Mail_new(sd->fd, msg.id, msg.send_name, msg.title);
  1488. }
  1489. }
  1490. static void intif_parse_Mail_new(int fd)
  1491. {
  1492. struct map_session_data *sd = map_charid2sd(RFIFOL(fd,2));
  1493. int mail_id = RFIFOL(fd,6);
  1494. const char* sender_name = (char*)RFIFOP(fd,10);
  1495. const char* title = (char*)RFIFOP(fd,34);
  1496. if( sd == NULL )
  1497. return;
  1498. sd->mail.inbox.changed = true;
  1499. clif_Mail_new(sd->fd, mail_id, sender_name, title);
  1500. }
  1501. #endif
  1502. //-----------------------------------------------------------------
  1503. // inter serverからの通信
  1504. // エラーがあれば0(false)を返すこと
  1505. // パケットが処理できれば1,パケット長が足りなければ2を返すこと
  1506. int intif_parse(int fd)
  1507. {
  1508. int packet_len, cmd;
  1509. cmd = RFIFOW(fd,0);
  1510. // パケットのID確認
  1511. if(cmd<0x3800 || cmd>=0x3800+(sizeof(packet_len_table)/sizeof(packet_len_table[0])) ||
  1512. packet_len_table[cmd-0x3800]==0){
  1513. return 0;
  1514. }
  1515. // パケットの長さ確認
  1516. packet_len = packet_len_table[cmd-0x3800];
  1517. if(packet_len==-1){
  1518. if(RFIFOREST(fd)<4)
  1519. return 2;
  1520. packet_len = RFIFOW(fd,2);
  1521. }
  1522. // if(battle_config.etc_log)
  1523. // printf("intif_parse %d %x %d %d\n",fd,cmd,packet_len,RFIFOREST(fd));
  1524. if((int)RFIFOREST(fd)<packet_len){
  1525. return 2;
  1526. }
  1527. // 処理分岐
  1528. switch(cmd){
  1529. case 0x3800:
  1530. if (RFIFOL(fd,4) == 0xFF000000) //Normal announce.
  1531. clif_GMmessage(NULL,(char *) RFIFOP(fd,8),packet_len-8,0);
  1532. else if (RFIFOL(fd,4) == 0xFE000000) //Main chat message [LuzZza]
  1533. clif_MainChatMessage((char *)RFIFOP(fd,8));
  1534. else //Color announce.
  1535. clif_announce(NULL,(char *) RFIFOP(fd,8),packet_len-8,RFIFOL(fd,4),0);
  1536. break;
  1537. case 0x3801: intif_parse_WisMessage(fd); break;
  1538. case 0x3802: intif_parse_WisEnd(fd); break;
  1539. case 0x3803: mapif_parse_WisToGM(fd); break;
  1540. case 0x3804: intif_parse_Registers(fd); break;
  1541. case 0x3806: intif_parse_ChangeNameOk(fd); break;
  1542. case 0x3810: intif_parse_LoadStorage(fd); break;
  1543. case 0x3811: intif_parse_SaveStorage(fd); break;
  1544. case 0x3818: intif_parse_LoadGuildStorage(fd); break;
  1545. case 0x3819: intif_parse_SaveGuildStorage(fd); break;
  1546. case 0x3820: intif_parse_PartyCreated(fd); break;
  1547. case 0x3821: intif_parse_PartyInfo(fd); break;
  1548. case 0x3822: intif_parse_PartyMemberAdded(fd); break;
  1549. case 0x3823: intif_parse_PartyOptionChanged(fd); break;
  1550. case 0x3824: intif_parse_PartyMemberLeaved(fd); break;
  1551. case 0x3825: intif_parse_PartyMove(fd); break;
  1552. case 0x3826: intif_parse_PartyBroken(fd); break;
  1553. case 0x3827: intif_parse_PartyMessage(fd); break;
  1554. case 0x3830: intif_parse_GuildCreated(fd); break;
  1555. case 0x3831: intif_parse_GuildInfo(fd); break;
  1556. case 0x3832: intif_parse_GuildMemberAdded(fd); break;
  1557. case 0x3834: intif_parse_GuildMemberLeaved(fd); break;
  1558. case 0x3835: intif_parse_GuildMemberInfoShort(fd); break;
  1559. case 0x3836: intif_parse_GuildBroken(fd); break;
  1560. case 0x3837: intif_parse_GuildMessage(fd); break;
  1561. case 0x3839: intif_parse_GuildBasicInfoChanged(fd); break;
  1562. case 0x383a: intif_parse_GuildMemberInfoChanged(fd); break;
  1563. case 0x383b: intif_parse_GuildPosition(fd); break;
  1564. case 0x383c: intif_parse_GuildSkillUp(fd); break;
  1565. case 0x383d: intif_parse_GuildAlliance(fd); break;
  1566. case 0x383e: intif_parse_GuildNotice(fd); break;
  1567. case 0x383f: intif_parse_GuildEmblem(fd); break;
  1568. case 0x3840: intif_parse_GuildCastleDataLoad(fd); break;
  1569. case 0x3841: intif_parse_GuildCastleDataSave(fd); break;
  1570. case 0x3842: intif_parse_GuildCastleAllDataLoad(fd); break;
  1571. case 0x3843: intif_parse_GuildMasterChanged(fd); break;
  1572. // Mail System
  1573. #ifndef TXT_ONLY
  1574. case 0x3848: intif_parse_Mail_inboxreceived(fd); break;
  1575. case 0x3849: intif_parse_Mail_new(fd); break;
  1576. case 0x384a: intif_parse_Mail_getattach(fd); break;
  1577. case 0x384b: intif_parse_Mail_delete(fd); break;
  1578. case 0x384c: intif_parse_Mail_return(fd); break;
  1579. case 0x384d: intif_parse_Mail_send(fd); break;
  1580. #endif
  1581. // End of Mail System
  1582. case 0x3880: intif_parse_CreatePet(fd); break;
  1583. case 0x3881: intif_parse_RecvPetData(fd); break;
  1584. case 0x3882: intif_parse_SavePetOk(fd); break;
  1585. case 0x3883: intif_parse_DeletePetOk(fd); break;
  1586. case 0x3890: intif_parse_CreateHomunculus(fd); break;
  1587. case 0x3891: intif_parse_RecvHomunculusData(fd); break;
  1588. case 0x3892: intif_parse_SaveHomunculusOk(fd); break;
  1589. case 0x3893: intif_parse_DeleteHomunculusOk(fd); break;
  1590. default:
  1591. ShowError("intif_parse : unknown packet %d %x\n",fd,RFIFOW(fd,0));
  1592. return 0;
  1593. }
  1594. // パケット読み飛ばし
  1595. RFIFOSKIP(fd,packet_len);
  1596. return 1;
  1597. }