int_party.c 20 KB

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