int_party.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  1. // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
  2. // For more information, see LICENCE in the main folder
  3. #include "../common/cbasetypes.h"
  4. #include "../common/mmo.h"
  5. #include "../common/malloc.h"
  6. #include "../common/socket.h"
  7. #include "../common/db.h"
  8. #include "../common/lock.h"
  9. #include "../common/showmsg.h"
  10. #include "char.h"
  11. #include "inter.h"
  12. #include "int_party.h"
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. char party_txt[1024] = "save/party.txt";
  17. #ifndef TXT_SQL_CONVERT
  18. struct party_data {
  19. struct party party;
  20. unsigned int min_lv, max_lv;
  21. int family; //Is this party a family? if so, this holds the child id.
  22. unsigned char size; //Total size of party.
  23. };
  24. static DBMap* party_db; // int party_id -> struct party_data*
  25. static int party_newid = 100;
  26. int mapif_party_broken(int party_id, int flag);
  27. int party_check_empty(struct party *p);
  28. int mapif_parse_PartyLeave(int fd, int party_id, int account_id, int char_id);
  29. int party_check_exp_share(struct party_data *p);
  30. int mapif_party_optionchanged(int fd,struct party *p, int account_id, int flag);
  31. //Updates party's level range and unsets even share if broken.
  32. static int int_party_check_lv(struct party_data *p) {
  33. int i;
  34. unsigned int lv;
  35. p->min_lv = UINT_MAX;
  36. p->max_lv = 0;
  37. for(i=0;i<MAX_PARTY;i++){
  38. if(!p->party.member[i].online)
  39. continue;
  40. lv=p->party.member[i].lv;
  41. if (lv < p->min_lv) p->min_lv = lv;
  42. if (lv > p->max_lv) p->max_lv = lv;
  43. }
  44. if (p->party.exp && !party_check_exp_share(p)) {
  45. p->party.exp = 0;
  46. mapif_party_optionchanged(0, &p->party, 0, 0);
  47. return 0;
  48. }
  49. return 1;
  50. }
  51. //Calculates the state of a party.
  52. static void int_party_calc_state(struct party_data *p)
  53. {
  54. int i;
  55. unsigned int lv;
  56. p->min_lv = UINT_MAX;
  57. p->max_lv = 0;
  58. p->party.count =
  59. p->size =
  60. p->family = 0;
  61. //Check party size.
  62. for(i=0;i<MAX_PARTY;i++){
  63. if (!p->party.member[i].lv) continue;
  64. p->size++;
  65. if(p->party.member[i].online)
  66. p->party.count++;
  67. }
  68. if(p->size == 3) {
  69. //Check Family State.
  70. p->family = char_family(
  71. p->party.member[0].char_id,
  72. p->party.member[1].char_id,
  73. p->party.member[2].char_id
  74. );
  75. }
  76. //max/min levels.
  77. for(i=0;i<MAX_PARTY;i++){
  78. lv=p->party.member[i].lv;
  79. if (!lv) continue;
  80. if(p->party.member[i].online &&
  81. //On families, the kid is not counted towards exp share rules.
  82. p->party.member[i].char_id != p->family)
  83. {
  84. if( lv < p->min_lv ) p->min_lv=lv;
  85. if( p->max_lv < lv ) p->max_lv=lv;
  86. }
  87. }
  88. if (p->party.exp && !party_check_exp_share(p)) {
  89. p->party.exp = 0; //Set off even share.
  90. mapif_party_optionchanged(0, &p->party, 0, 0);
  91. }
  92. return;
  93. }
  94. // パ?ティデ?タの文字列への?換
  95. int inter_party_tostr(char *str, struct party *p) {
  96. int i, len;
  97. len = sprintf(str, "%d\t%s\t%d,%d\t", p->party_id, p->name, p->exp, p->item);
  98. for(i = 0; i < MAX_PARTY; i++) {
  99. struct party_member *m = &p->member[i];
  100. len += sprintf(str + len, "%d,%d,%d\t", m->account_id, m->char_id, m->leader);
  101. }
  102. return 0;
  103. }
  104. #endif //TXT_SQL_CONVERT
  105. // パ?ティデ?タの文字列からの?換
  106. int inter_party_fromstr(char *str, struct party *p) {
  107. int i, j;
  108. int tmp_int[16];
  109. char tmp_str[256];
  110. #ifndef TXT_SQL_CONVERT
  111. struct mmo_charstatus* status;
  112. #endif
  113. memset(p, 0, sizeof(struct party));
  114. if (sscanf(str, "%d\t%255[^\t]\t%d,%d\t", &tmp_int[0], tmp_str, &tmp_int[1], &tmp_int[2]) != 4)
  115. return 1;
  116. p->party_id = tmp_int[0];
  117. memcpy(p->name, tmp_str, NAME_LENGTH);
  118. p->exp = tmp_int[1]?1:0;
  119. p->item = tmp_int[2];
  120. for(j = 0; j < 3 && str != NULL; j++)
  121. str = strchr(str + 1, '\t');
  122. for(i = 0; i < MAX_PARTY; i++) {
  123. struct party_member *m = &p->member[i];
  124. if (str == NULL)
  125. return 1;
  126. if (sscanf(str + 1, "%d,%d,%d\t", &tmp_int[0], &tmp_int[1], &tmp_int[2]) != 3)
  127. return 1;
  128. m->account_id = tmp_int[0];
  129. m->char_id = tmp_int[1];
  130. m->leader = tmp_int[2]?1:0;
  131. str = strchr(str + 1, '\t');
  132. #ifndef TXT_SQL_CONVERT
  133. if (!m->account_id) continue;
  134. //Lookup player for rest of data.
  135. status = search_character(m->account_id, m->char_id);
  136. if (!status) continue;
  137. memcpy(m->name, status->name, NAME_LENGTH);
  138. m->class_ = status->class_;
  139. m->map = status->last_point.map;
  140. m->lv = status->base_level;
  141. #endif //TXT_SQL_CONVERT
  142. }
  143. return 0;
  144. }
  145. #ifndef TXT_SQL_CONVERT
  146. // パ?ティデ?タのロ?ド
  147. int inter_party_init() {
  148. char line[8192];
  149. struct party_data *p;
  150. FILE *fp;
  151. int c = 0;
  152. int i, j;
  153. party_db = idb_alloc(DB_OPT_RELEASE_DATA);
  154. if ((fp = fopen(party_txt, "r")) == NULL)
  155. return 1;
  156. while(fgets(line, sizeof(line), fp))
  157. {
  158. j = 0;
  159. if (sscanf(line, "%d\t%%newid%%\n%n", &i, &j) == 1 && j > 0 && party_newid <= i) {
  160. party_newid = i;
  161. continue;
  162. }
  163. p = (struct party_data*)aCalloc(sizeof(struct party_data), 1);
  164. if (p == NULL){
  165. ShowFatalError("int_party: out of memory!\n");
  166. exit(EXIT_FAILURE);
  167. }
  168. memset(p, 0, sizeof(struct party_data));
  169. if (inter_party_fromstr(line, &p->party) == 0 && p->party.party_id > 0) {
  170. int_party_calc_state(p);
  171. if (p->party.party_id >= party_newid)
  172. party_newid = p->party.party_id + 1;
  173. idb_put(party_db, p->party.party_id, p);
  174. party_check_empty(&p->party);
  175. } else {
  176. ShowError("int_party: broken data [%s] line %d\n", party_txt, c + 1);
  177. aFree(p);
  178. }
  179. c++;
  180. }
  181. fclose(fp);
  182. return 0;
  183. }
  184. void inter_party_final()
  185. {
  186. party_db->destroy(party_db, NULL);
  187. return;
  188. }
  189. // パ?ティ?デ?タのセ?ブ用
  190. int inter_party_save_sub(DBKey key, void *data, va_list ap) {
  191. char line[8192];
  192. FILE *fp;
  193. inter_party_tostr(line, &((struct party_data*)data)->party);
  194. fp = va_arg(ap, FILE *);
  195. fprintf(fp, "%s\n", line);
  196. return 0;
  197. }
  198. // パ?ティ?デ?タのセ?ブ
  199. int inter_party_save() {
  200. FILE *fp;
  201. int lock;
  202. if ((fp = lock_fopen(party_txt, &lock)) == NULL) {
  203. ShowError("int_party: can't write [%s] !!! data is lost !!!\n", party_txt);
  204. return 1;
  205. }
  206. party_db->foreach(party_db, inter_party_save_sub, fp);
  207. lock_fclose(fp,party_txt, &lock);
  208. return 0;
  209. }
  210. // Search for the party according to its name
  211. struct party_data* search_partyname(char *str)
  212. {
  213. struct DBIterator* iter;
  214. struct party_data* p;
  215. struct party_data* result = NULL;
  216. iter = party_db->iterator(party_db);
  217. for( p = (struct party_data*)iter->first(iter,NULL); iter->exists(iter); p = (struct party_data*)iter->next(iter,NULL) )
  218. {
  219. if( strncmpi(p->party.name, str, NAME_LENGTH) == 0 )
  220. {
  221. result = p;
  222. break;
  223. }
  224. }
  225. iter->destroy(iter);
  226. return result;
  227. }
  228. // Returns whether this party can keep having exp share or not.
  229. int party_check_exp_share(struct party_data *p) {
  230. return (p->party.count < 2|| p->max_lv - p->min_lv <= party_share_level);
  231. }
  232. // パ?ティが空かどうかチェック
  233. int party_check_empty(struct party *p) {
  234. int i;
  235. for(i = 0; i < MAX_PARTY; i++) {
  236. if (p->member[i].account_id > 0) {
  237. return 0;
  238. }
  239. }
  240. mapif_party_broken(p->party_id, 0);
  241. idb_remove(party_db, p->party_id);
  242. return 1;
  243. }
  244. //-------------------------------------------------------------------
  245. // map serverへの通信
  246. // パ?ティ作成可否
  247. int mapif_party_created(int fd,int account_id, int char_id, struct party *p)
  248. {
  249. WFIFOHEAD(fd, 39);
  250. WFIFOW(fd,0) = 0x3820;
  251. WFIFOL(fd,2) = account_id;
  252. WFIFOL(fd,6) = char_id;
  253. if (p != NULL) {
  254. WFIFOB(fd,10) = 0;
  255. WFIFOL(fd,11) = p->party_id;
  256. memcpy(WFIFOP(fd,15), p->name, NAME_LENGTH);
  257. ShowInfo("Created party (%d - %s)\n", p->party_id, p->name);
  258. } else {
  259. WFIFOB(fd,10) = 1;
  260. WFIFOL(fd,11) = 0;
  261. memset(WFIFOP(fd,15), 0, NAME_LENGTH);
  262. }
  263. WFIFOSET(fd,39);
  264. return 0;
  265. }
  266. // パ?ティ情報見つからず
  267. int mapif_party_noinfo(int fd, int party_id) {
  268. WFIFOHEAD(fd, 8);
  269. WFIFOW(fd,0) = 0x3821;
  270. WFIFOW(fd,2) = 8;
  271. WFIFOL(fd,4) = party_id;
  272. WFIFOSET(fd,8);
  273. ShowWarning("int_party: info not found %d\n", party_id);
  274. return 0;
  275. }
  276. // パ?ティ情報まとめ送り
  277. int mapif_party_info(int fd, struct party *p) {
  278. unsigned char buf[2048];
  279. WBUFW(buf,0) = 0x3821;
  280. memcpy(buf + 4, p, sizeof(struct party));
  281. WBUFW(buf,2) = 4 + sizeof(struct party);
  282. if (fd < 0)
  283. mapif_sendall(buf, WBUFW(buf,2));
  284. else
  285. mapif_send(fd, buf, WBUFW(buf,2));
  286. return 0;
  287. }
  288. // パ?ティメンバ追加可否
  289. int mapif_party_memberadded(int fd, int party_id, int account_id, int char_id, int flag) {
  290. WFIFOHEAD(fd, 15);
  291. WFIFOW(fd,0) = 0x3822;
  292. WFIFOL(fd,2) = party_id;
  293. WFIFOL(fd,6) = account_id;
  294. WFIFOL(fd,10) = char_id;
  295. WFIFOB(fd,14) = flag;
  296. WFIFOSET(fd,15);
  297. return 0;
  298. }
  299. // パ?ティ設定?更通知
  300. int mapif_party_optionchanged(int fd,struct party *p, int account_id, int flag) {
  301. unsigned char buf[15];
  302. WBUFW(buf,0) = 0x3823;
  303. WBUFL(buf,2) = p->party_id;
  304. WBUFL(buf,6) = account_id;
  305. WBUFW(buf,10) = p->exp;
  306. WBUFW(buf,12) = p->item;
  307. WBUFB(buf,14) = flag;
  308. if (flag == 0)
  309. mapif_sendall(buf, 15);
  310. else
  311. mapif_send(fd, buf, 15);
  312. return 0;
  313. }
  314. // パ?ティ?退通知
  315. int mapif_party_withdraw(int party_id,int account_id, int char_id) {
  316. unsigned char buf[16];
  317. WBUFW(buf,0) = 0x3824;
  318. WBUFL(buf,2) = party_id;
  319. WBUFL(buf,6) = account_id;
  320. WBUFL(buf,10) = char_id;
  321. mapif_sendall(buf, 14);
  322. return 0;
  323. }
  324. // パ?ティマップ更新通知
  325. int mapif_party_membermoved(struct party *p, int idx) {
  326. unsigned char buf[20];
  327. WBUFW(buf,0) = 0x3825;
  328. WBUFL(buf,2) = p->party_id;
  329. WBUFL(buf,6) = p->member[idx].account_id;
  330. WBUFL(buf,10) = p->member[idx].char_id;
  331. WBUFW(buf,14) = p->member[idx].map;
  332. WBUFB(buf,16) = p->member[idx].online;
  333. WBUFW(buf,17) = p->member[idx].lv;
  334. mapif_sendall(buf, 19);
  335. return 0;
  336. }
  337. // パ?ティ解散通知
  338. int mapif_party_broken(int party_id, int flag) {
  339. unsigned char buf[7];
  340. WBUFW(buf,0) = 0x3826;
  341. WBUFL(buf,2) = party_id;
  342. WBUFB(buf,6) = flag;
  343. mapif_sendall(buf, 7);
  344. ShowInfo("Party broken (%d)\n", party_id);
  345. return 0;
  346. }
  347. // パ?ティ??言
  348. int mapif_party_message(int party_id, int account_id, char *mes, int len, int sfd) {
  349. unsigned char buf[2048];
  350. WBUFW(buf,0) = 0x3827;
  351. WBUFW(buf,2) = len + 12;
  352. WBUFL(buf,4) = party_id;
  353. WBUFL(buf,8) = account_id;
  354. memcpy(WBUFP(buf,12), mes, len);
  355. mapif_sendallwos(sfd, buf,len + 12);
  356. return 0;
  357. }
  358. //-------------------------------------------------------------------
  359. // map serverからの通信
  360. // パ?ティ
  361. int mapif_parse_CreateParty(int fd, char *name, int item, int item2, struct party_member *leader)
  362. {
  363. struct party_data *p;
  364. int i;
  365. //FIXME: this should be removed once the savefiles can handle all symbols
  366. for(i = 0; i < NAME_LENGTH && name[i]; i++) {
  367. if (!(name[i] & 0xe0) || name[i] == 0x7f) {
  368. ShowInfo("int_party: illegal party name [%s]\n", name);
  369. mapif_party_created(fd, leader->account_id, leader->char_id, NULL);
  370. return 0;
  371. }
  372. }
  373. if ((p = search_partyname(name)) != NULL) {
  374. ShowInfo("int_party: same name party exists [%s]\n", name);
  375. mapif_party_created(fd, leader->account_id, leader->char_id, NULL);
  376. return 0;
  377. }
  378. // Check Authorised letters/symbols in the name of the character
  379. if (char_name_option == 1) { // only letters/symbols in char_name_letters are authorised
  380. for (i = 0; i < NAME_LENGTH && name[i]; i++)
  381. if (strchr(char_name_letters, name[i]) == NULL) {
  382. mapif_party_created(fd, leader->account_id, leader->char_id, NULL);
  383. return 0;
  384. }
  385. } else if (char_name_option == 2) { // letters/symbols in char_name_letters are forbidden
  386. for (i = 0; i < NAME_LENGTH && name[i]; i++)
  387. if (strchr(char_name_letters, name[i]) != NULL) {
  388. mapif_party_created(fd, leader->account_id, leader->char_id, NULL);
  389. return 0;
  390. }
  391. }
  392. p = (struct party_data *) aCalloc(sizeof(struct party_data), 1);
  393. if (p == NULL) {
  394. ShowFatalError("int_party: out of memory !\n");
  395. mapif_party_created(fd,leader->account_id,leader->char_id,NULL);
  396. return 0;
  397. }
  398. p->party.party_id = party_newid++;
  399. memcpy(p->party.name, name, NAME_LENGTH);
  400. p->party.exp = 0;
  401. p->party.item=(item?1:0)|(item2?2:0);
  402. memcpy(&p->party.member[0], leader, sizeof(struct party_member));
  403. p->party.member[0].leader = 1;
  404. int_party_calc_state(p);
  405. idb_put(party_db, p->party.party_id, p);
  406. mapif_party_created(fd, leader->account_id, leader->char_id, &p->party);
  407. mapif_party_info(fd, &p->party);
  408. return 0;
  409. }
  410. // パ?ティ情報要求
  411. int mapif_parse_PartyInfo(int fd, int party_id)
  412. {
  413. struct party_data *p;
  414. p = (struct party_data*)idb_get(party_db, party_id);
  415. if (p != NULL)
  416. mapif_party_info(fd, &p->party);
  417. else {
  418. mapif_party_noinfo(fd, party_id);
  419. char_clearparty(party_id);
  420. }
  421. return 0;
  422. }
  423. // パーティ追加要求
  424. int mapif_parse_PartyAddMember(int fd, int party_id, struct party_member *member)
  425. {
  426. struct party_data *p;
  427. int i;
  428. p = (struct party_data*)idb_get(party_db, party_id);
  429. if( p == NULL || p->size == MAX_PARTY ) {
  430. mapif_party_memberadded(fd, party_id, member->account_id, member->char_id, 1);
  431. return 0;
  432. }
  433. ARR_FIND( 0, MAX_PARTY, i, p->party.member[i].account_id == 0 );
  434. if( i == MAX_PARTY )
  435. {// Party full
  436. mapif_party_memberadded(fd, party_id, member->account_id, member->char_id, 1);
  437. return 0;
  438. }
  439. memcpy(&p->party.member[i], member, sizeof(struct party_member));
  440. p->party.member[i].leader = 0;
  441. if (p->party.member[i].online) p->party.count++;
  442. p->size++;
  443. if (p->size == 3) //Check family state.
  444. int_party_calc_state(p);
  445. else //Check even share range.
  446. if (member->lv < p->min_lv || member->lv > p->max_lv || p->family) {
  447. if (p->family) p->family = 0; //Family state broken.
  448. int_party_check_lv(p);
  449. }
  450. mapif_party_memberadded(fd, party_id, member->account_id, member->char_id, 0);
  451. mapif_party_info(-1, &p->party);
  452. return 0;
  453. }
  454. // パ?ティ?設定?更要求
  455. int mapif_parse_PartyChangeOption(int fd, int party_id, int account_id, int exp, int item)
  456. {
  457. struct party_data *p;
  458. int flag = 0;
  459. p = (struct party_data*)idb_get(party_db, party_id);
  460. if (p == NULL)
  461. return 0;
  462. p->party.exp = exp;
  463. if (exp>0 && !party_check_exp_share(p)) {
  464. flag |= 0x01;
  465. p->party.exp = 0;
  466. }
  467. p->party.item = item&0x3;
  468. mapif_party_optionchanged(fd, &p->party, account_id, flag);
  469. return 0;
  470. }
  471. // パ?ティ?退要求
  472. int mapif_parse_PartyLeave(int fd, int party_id, int account_id, int char_id)
  473. {
  474. struct party_data *p;
  475. int i,lv;
  476. p = (struct party_data*)idb_get(party_db, party_id);
  477. if (!p) return 0;
  478. for(i = 0; i < MAX_PARTY; i++) {
  479. if(p->party.member[i].account_id == account_id &&
  480. p->party.member[i].char_id == char_id)
  481. {
  482. mapif_party_withdraw(party_id, account_id, char_id);
  483. lv = p->party.member[i].lv;
  484. if(p->party.member[i].online) p->party.count--;
  485. memset(&p->party.member[i], 0, sizeof(struct party_member));
  486. p->size--;
  487. if (lv == p->min_lv || lv == p->max_lv || p->family)
  488. {
  489. if(p->family) p->family = 0; //Family state broken.
  490. int_party_check_lv(p);
  491. }
  492. if (party_check_empty(&p->party) == 0)
  493. mapif_party_info(-1, &p->party);
  494. return 0;
  495. }
  496. }
  497. return 0;
  498. }
  499. int mapif_parse_PartyChangeMap(int fd, int party_id, int account_id, int char_id, unsigned short map, int online, unsigned int lv)
  500. {
  501. struct party_data *p;
  502. int i;
  503. p = (struct party_data*)idb_get(party_db, party_id);
  504. if (p == NULL)
  505. return 0;
  506. for(i = 0; i < MAX_PARTY &&
  507. (p->party.member[i].account_id != account_id ||
  508. p->party.member[i].char_id != char_id); i++);
  509. if (i == MAX_PARTY) return 0;
  510. if (p->party.member[i].online != online)
  511. {
  512. p->party.member[i].online = online;
  513. if (online)
  514. p->party.count++;
  515. else
  516. p->party.count--;
  517. // Even share check situations: Family state (always breaks)
  518. // character logging on/off is max/min level (update level range)
  519. // or character logging on/off has a different level (update level range using new level)
  520. if (p->family ||
  521. (p->party.member[i].lv <= p->min_lv || p->party.member[i].lv >= p->max_lv) ||
  522. (p->party.member[i].lv != lv && (lv <= p->min_lv || lv >= p->max_lv))
  523. )
  524. {
  525. p->party.member[i].lv = lv;
  526. int_party_check_lv(p);
  527. }
  528. //Send online/offline update.
  529. mapif_party_membermoved(&p->party, i);
  530. }
  531. if (p->party.member[i].lv != lv) {
  532. if(p->party.member[i].lv == p->min_lv ||
  533. p->party.member[i].lv == p->max_lv)
  534. {
  535. p->party.member[i].lv = lv;
  536. int_party_check_lv(p);
  537. } else
  538. p->party.member[i].lv = lv;
  539. //There is no need to send level update to map servers
  540. //since they do nothing with it.
  541. }
  542. if (p->party.member[i].map != map) {
  543. p->party.member[i].map = map;
  544. mapif_party_membermoved(&p->party, i);
  545. }
  546. return 0;
  547. }
  548. // パ?ティ解散要求
  549. int mapif_parse_BreakParty(int fd, int party_id) {
  550. idb_remove(party_db, party_id);
  551. mapif_party_broken(fd, party_id);
  552. return 0;
  553. }
  554. // パ?ティメッセ?ジ送信
  555. int mapif_parse_PartyMessage(int fd, int party_id, int account_id, char *mes, int len)
  556. {
  557. return mapif_party_message(party_id, account_id, mes, len, fd);
  558. }
  559. int mapif_parse_PartyLeaderChange(int fd,int party_id,int account_id,int char_id)
  560. {
  561. struct party_data *p;
  562. int i;
  563. p = (struct party_data*)idb_get(party_db, party_id);
  564. if (p == NULL)
  565. return 0;
  566. for (i = 0; i < MAX_PARTY; i++)
  567. {
  568. if(p->party.member[i].leader)
  569. p->party.member[i].leader = 0;
  570. if(p->party.member[i].account_id == account_id &&
  571. p->party.member[i].char_id == char_id)
  572. p->party.member[i].leader = 1;
  573. }
  574. return 1;
  575. }
  576. // map server からの通信
  577. // ?1パケットのみ解析すること
  578. // ?パケット長デ?タはinter.cにセットしておくこと
  579. // ?パケット長チェックや、RFIFOSKIPは呼び出し元で行われるので行ってはならない
  580. // ?エラ?なら0(false)、そうでないなら1(true)をかえさなければならない
  581. int inter_party_parse_frommap(int fd) {
  582. RFIFOHEAD(fd);
  583. switch(RFIFOW(fd,0)) {
  584. case 0x3020: mapif_parse_CreateParty(fd, (char*)RFIFOP(fd,4), RFIFOB(fd,28), RFIFOB(fd,29), (struct party_member*)RFIFOP(fd,30)); break;
  585. case 0x3021: mapif_parse_PartyInfo(fd, RFIFOL(fd,2)); break;
  586. case 0x3022: mapif_parse_PartyAddMember(fd, RFIFOL(fd,4), (struct party_member*)RFIFOP(fd,8)); break;
  587. case 0x3023: mapif_parse_PartyChangeOption(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOW(fd,10), RFIFOW(fd,12)); break;
  588. case 0x3024: mapif_parse_PartyLeave(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10)); break;
  589. case 0x3025: mapif_parse_PartyChangeMap(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOW(fd,14), RFIFOB(fd,16), RFIFOW(fd,17)); break;
  590. case 0x3026: mapif_parse_BreakParty(fd, RFIFOL(fd,2)); break;
  591. case 0x3027: mapif_parse_PartyMessage(fd, RFIFOL(fd,4), RFIFOL(fd,8), (char*)RFIFOP(fd,12), RFIFOW(fd,2)-12); break;
  592. case 0x3029: mapif_parse_PartyLeaderChange(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10)); break;
  593. default:
  594. return 0;
  595. }
  596. return 1;
  597. }
  598. // サ?バ?から?退要求(キャラ削除用)
  599. int inter_party_leave(int party_id, int account_id, int char_id) {
  600. return mapif_parse_PartyLeave(-1, party_id, account_id, char_id);
  601. }
  602. #endif //TXT_SQL_CONVERT