* Rework some party code.

- add leader argument to party_fill_member
- add party_getmemberid
- add requester char_id to packets 0x3021 and 0x3821 (party info)
- diff members when replacing party info
- remove fixup all-player-iteration when receiving a party for the first time
- send 'party info' before 'party created'
- send 'party info' before 'party member added'
- update empty party_id when checking the player of a party

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@14968 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
flaviojs 2011-10-09 13:19:06 +00:00
parent dd51e5d71a
commit 7b1ca6d8b3
9 changed files with 185 additions and 144 deletions

View File

@ -1,5 +1,15 @@
Date Added Date Added
2011/10/09
* Rework some party code. [FlavioJS]
- add leader argument to party_fill_member
- add party_getmemberid
- add requester char_id to packets 0x3021 and 0x3821 (party info)
- diff members when replacing party info
- remove fixup all-player-iteration when receiving a party for the first time
- send 'party info' before 'party created'
- send 'party info' before 'party member added'
- update empty party_id when checking the player of a party
2011/10/07 2011/10/07
* Remove fds from the shortlist before processing. [FlavioJS] * Remove fds from the shortlist before processing. [FlavioJS]
2011/09/18 2011/09/18

View File

@ -309,29 +309,29 @@ int mapif_party_created(int fd,int account_id, int char_id, struct party *p)
} }
// パ?ティ情報見つからず // パ?ティ情報見つからず
int mapif_party_noinfo(int fd, int party_id) { static void mapif_party_noinfo(int fd, int party_id, int char_id)
WFIFOHEAD(fd, 8); {
WFIFOHEAD(fd, 12);
WFIFOW(fd,0) = 0x3821; WFIFOW(fd,0) = 0x3821;
WFIFOW(fd,2) = 8; WFIFOW(fd,2) = 12;
WFIFOL(fd,4) = party_id; WFIFOL(fd,4) = char_id;
WFIFOSET(fd,8); WFIFOL(fd,8) = party_id;
ShowWarning("int_party: info not found %d\n", party_id); WFIFOSET(fd,12);
ShowWarning("int_party: info not found (party_id=%d char_id=%d)\n", party_id, char_id);
return 0;
} }
// パ?ティ情報まとめ送り // パ?ティ情報まとめ送り
int mapif_party_info(int fd, struct party *p) { static void mapif_party_info(int fd, struct party* p, int char_id)
unsigned char buf[2048]; {
unsigned char buf[8 + sizeof(struct party)];
WBUFW(buf,0) = 0x3821; WBUFW(buf,0) = 0x3821;
memcpy(buf + 4, p, sizeof(struct party)); WBUFW(buf,2) = 8 + sizeof(struct party);
WBUFW(buf,2) = 4 + sizeof(struct party); WBUFL(buf,4) = char_id;
memcpy(WBUFP(buf,8), p, sizeof(struct party));
if (fd < 0) if (fd < 0)
mapif_sendall(buf, WBUFW(buf,2)); mapif_sendall(buf, WBUFW(buf,2));
else else
mapif_send(fd, buf, WBUFW(buf,2)); mapif_send(fd, buf, WBUFW(buf,2));
return 0;
} }
// パ?ティメンバ追加可否 // パ?ティメンバ追加可否
@ -472,25 +472,23 @@ int mapif_parse_CreateParty(int fd, char *name, int item, int item2, struct part
int_party_calc_state(p); int_party_calc_state(p);
idb_put(party_db, p->party.party_id, p); idb_put(party_db, p->party.party_id, p);
mapif_party_info(fd, &p->party, 0);
mapif_party_created(fd, leader->account_id, leader->char_id, &p->party); mapif_party_created(fd, leader->account_id, leader->char_id, &p->party);
mapif_party_info(fd, &p->party);
return 0; return 0;
} }
// パ?ティ情報要求 // パ?ティ情報要求
int mapif_parse_PartyInfo(int fd, int party_id) static void mapif_parse_PartyInfo(int fd, int party_id, int char_id)
{ {
struct party_data *p; struct party_data *p;
p = (struct party_data*)idb_get(party_db, party_id); p = (struct party_data*)idb_get(party_db, party_id);
if (p != NULL) if (p != NULL)
mapif_party_info(fd, &p->party); mapif_party_info(fd, &p->party, char_id);
else { else {
mapif_party_noinfo(fd, party_id); mapif_party_noinfo(fd, party_id, char_id);
} }
return 0;
} }
// パーティ追加要求 // パーティ追加要求
@ -524,8 +522,8 @@ int mapif_parse_PartyAddMember(int fd, int party_id, struct party_member *member
int_party_check_lv(p); int_party_check_lv(p);
} }
mapif_party_info(-1, &p->party, 0);
mapif_party_memberadded(fd, party_id, member->account_id, member->char_id, 0); mapif_party_memberadded(fd, party_id, member->account_id, member->char_id, 0);
mapif_party_info(-1, &p->party);
return 0; return 0;
} }
@ -574,7 +572,7 @@ int mapif_parse_PartyLeave(int fd, int party_id, int account_id, int char_id)
int_party_check_lv(p); int_party_check_lv(p);
} }
if (party_check_empty(&p->party) == 0) if (party_check_empty(&p->party) == 0)
mapif_party_info(-1, &p->party); mapif_party_info(-1, &p->party, 0);
return 0; return 0;
} }
} }
@ -679,7 +677,7 @@ int inter_party_parse_frommap(int fd) {
RFIFOHEAD(fd); RFIFOHEAD(fd);
switch(RFIFOW(fd,0)) { switch(RFIFOW(fd,0)) {
case 0x3020: mapif_parse_CreateParty(fd, (char*)RFIFOP(fd,4), RFIFOB(fd,28), RFIFOB(fd,29), (struct party_member*)RFIFOP(fd,30)); break; case 0x3020: mapif_parse_CreateParty(fd, (char*)RFIFOP(fd,4), RFIFOB(fd,28), RFIFOB(fd,29), (struct party_member*)RFIFOP(fd,30)); break;
case 0x3021: mapif_parse_PartyInfo(fd, RFIFOL(fd,2)); break; case 0x3021: mapif_parse_PartyInfo(fd, RFIFOL(fd,2), RFIFOL(fd,6)); break;
case 0x3022: mapif_parse_PartyAddMember(fd, RFIFOL(fd,4), (struct party_member*)RFIFOP(fd,8)); break; case 0x3022: mapif_parse_PartyAddMember(fd, RFIFOL(fd,4), (struct party_member*)RFIFOP(fd,8)); break;
case 0x3023: mapif_parse_PartyChangeOption(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOW(fd,10), RFIFOW(fd,12)); break; case 0x3023: mapif_parse_PartyChangeOption(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOW(fd,10), RFIFOW(fd,12)); break;
case 0x3024: mapif_parse_PartyLeave(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10)); break; case 0x3024: mapif_parse_PartyLeave(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10)); break;

View File

@ -52,7 +52,7 @@ int inter_send_packet_length[]={
int inter_recv_packet_length[]={ int inter_recv_packet_length[]={
-1,-1, 7,-1, -1,13,36, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3000-0x300f -1,-1, 7,-1, -1,13,36, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3000-0x300f
6,-1, 0, 0, 0, 0, 0, 0, 10,-1, 0, 0, 0, 0, 0, 0, //0x3010-0x301f 6,-1, 0, 0, 0, 0, 0, 0, 10,-1, 0, 0, 0, 0, 0, 0, //0x3010-0x301f
-1, 6,-1,14, 14,19, 6,-1, 14,14, 0, 0, 0, 0, 0, 0, //0x3020-0x302f -1,10,-1,14, 14,19, 6,-1, 14,14, 0, 0, 0, 0, 0, 0, //0x3020-0x302f Party
-1, 6,-1,-1, 55,19, 6,-1, 14,-1,-1,-1, 18,19,186,-1, //0x3030-0x303f -1, 6,-1,-1, 55,19, 6,-1, 14,-1,-1,-1, 18,19,186,-1, //0x3030-0x303f
5, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3040-0x304f 5, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3040-0x304f
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3050-0x305f 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3050-0x305f

View File

@ -357,29 +357,29 @@ int mapif_party_created(int fd,int account_id,int char_id,struct party *p)
} }
// パーティ情報見つからず // パーティ情報見つからず
int mapif_party_noinfo(int fd,int party_id) static void mapif_party_noinfo(int fd, int party_id, int char_id)
{ {
WFIFOHEAD(fd,8); WFIFOHEAD(fd, 12);
WFIFOW(fd,0)=0x3821; WFIFOW(fd,0) = 0x3821;
WFIFOW(fd,2)=8; WFIFOW(fd,2) = 12;
WFIFOL(fd,4)=party_id; WFIFOL(fd,4) = char_id;
WFIFOSET(fd,8); WFIFOL(fd,8) = party_id;
ShowWarning("int_party: info not found %d\n",party_id); WFIFOSET(fd,12);
return 0; ShowWarning("int_party: info not found (party_id=%d char_id=%d)\n", party_id, char_id);
} }
// パーティ情報まとめ送り // パーティ情報まとめ送り
int mapif_party_info(int fd,struct party *p) static void mapif_party_info(int fd, struct party* p, int char_id)
{ {
unsigned char buf[5+sizeof(struct party)]; unsigned char buf[8 + sizeof(struct party)];
WBUFW(buf,0)=0x3821; WBUFW(buf,0) = 0x3821;
WBUFW(buf,2)=4+sizeof(struct party); WBUFW(buf,2) = 8 + sizeof(struct party);
memcpy(buf+4,p,sizeof(struct party)); WBUFL(buf,4) = char_id;
memcpy(WBUFP(buf,8), p, sizeof(struct party));
if(fd<0) if(fd<0)
mapif_sendall(buf,WBUFW(buf,2)); mapif_sendall(buf,WBUFW(buf,2));
else else
mapif_send(fd,buf,WBUFW(buf,2)); mapif_send(fd,buf,WBUFW(buf,2));
return 0;
} }
// パーティメンバ追加可否 // パーティメンバ追加可否
int mapif_party_memberadded(int fd, int party_id, int account_id, int char_id, int flag) { int mapif_party_memberadded(int fd, int party_id, int account_id, int char_id, int flag) {
@ -506,8 +506,8 @@ int mapif_parse_CreateParty(int fd, char *name, int item, int item2, struct part
//Add party to db //Add party to db
int_party_calc_state(p); int_party_calc_state(p);
idb_put(party_db_, p->party.party_id, p); idb_put(party_db_, p->party.party_id, p);
mapif_party_info(fd, &p->party, 0);
mapif_party_created(fd,leader->account_id,leader->char_id,&p->party); mapif_party_created(fd,leader->account_id,leader->char_id,&p->party);
mapif_party_info(fd,&p->party);
} else { //Failed to create party. } else { //Failed to create party.
aFree(p); aFree(p);
mapif_party_created(fd,leader->account_id,leader->char_id,NULL); mapif_party_created(fd,leader->account_id,leader->char_id,NULL);
@ -516,16 +516,15 @@ int mapif_parse_CreateParty(int fd, char *name, int item, int item2, struct part
return 0; return 0;
} }
// パーティ情報要求 // パーティ情報要求
int mapif_parse_PartyInfo(int fd,int party_id) static void mapif_parse_PartyInfo(int fd, int party_id, int char_id)
{ {
struct party_data *p; struct party_data *p;
p = inter_party_fromsql(party_id); p = inter_party_fromsql(party_id);
if (p) if (p)
mapif_party_info(fd,&p->party); mapif_party_info(fd, &p->party, char_id);
else else
mapif_party_noinfo(fd,party_id); mapif_party_noinfo(fd, party_id, char_id);
return 0;
} }
// パーティ追加要求 // パーティ追加要求
int mapif_parse_PartyAddMember(int fd, int party_id, struct party_member *member) int mapif_parse_PartyAddMember(int fd, int party_id, struct party_member *member)
@ -558,8 +557,8 @@ int mapif_parse_PartyAddMember(int fd, int party_id, struct party_member *member
int_party_check_lv(p); int_party_check_lv(p);
} }
mapif_party_info(-1, &p->party, 0);
mapif_party_memberadded(fd, party_id, member->account_id, member->char_id, 0); mapif_party_memberadded(fd, party_id, member->account_id, member->char_id, 0);
mapif_party_info(-1, &p->party);
inter_party_tosql(&p->party, PS_ADDMEMBER, i); inter_party_tosql(&p->party, PS_ADDMEMBER, i);
return 0; return 0;
@ -633,7 +632,7 @@ int mapif_parse_PartyLeave(int fd, int party_id, int account_id, int char_id)
} }
if (party_check_empty(p) == 0) if (party_check_empty(p) == 0)
mapif_party_info(-1,&p->party); mapif_party_info(-1, &p->party, 0);
return 0; return 0;
} }
// When member goes to other map or levels up. // When member goes to other map or levels up.
@ -746,7 +745,7 @@ int inter_party_parse_frommap(int fd)
RFIFOHEAD(fd); RFIFOHEAD(fd);
switch(RFIFOW(fd,0)) { switch(RFIFOW(fd,0)) {
case 0x3020: mapif_parse_CreateParty(fd, (char*)RFIFOP(fd,4), RFIFOB(fd,28), RFIFOB(fd,29), (struct party_member*)RFIFOP(fd,30)); break; case 0x3020: mapif_parse_CreateParty(fd, (char*)RFIFOP(fd,4), RFIFOB(fd,28), RFIFOB(fd,29), (struct party_member*)RFIFOP(fd,30)); break;
case 0x3021: mapif_parse_PartyInfo(fd, RFIFOL(fd,2)); break; case 0x3021: mapif_parse_PartyInfo(fd, RFIFOL(fd,2), RFIFOL(fd,6)); break;
case 0x3022: mapif_parse_PartyAddMember(fd, RFIFOL(fd,4), (struct party_member*)RFIFOP(fd,8)); break; case 0x3022: mapif_parse_PartyAddMember(fd, RFIFOL(fd,4), (struct party_member*)RFIFOP(fd,8)); break;
case 0x3023: mapif_parse_PartyChangeOption(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOW(fd,10), RFIFOW(fd,12)); break; case 0x3023: mapif_parse_PartyChangeOption(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOW(fd,10), RFIFOW(fd,12)); break;
case 0x3024: mapif_parse_PartyLeave(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10)); break; case 0x3024: mapif_parse_PartyLeave(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10)); break;

View File

@ -47,7 +47,7 @@ char main_chat_nick[16] = "Main";
int inter_recv_packet_length[] = { int inter_recv_packet_length[] = {
-1,-1, 7,-1, -1,13,36, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3000- -1,-1, 7,-1, -1,13,36, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3000-
6,-1, 0, 0, 0, 0, 0, 0, 10,-1, 0, 0, 0, 0, 0, 0, // 3010- 6,-1, 0, 0, 0, 0, 0, 0, 10,-1, 0, 0, 0, 0, 0, 0, // 3010-
-1, 6,-1,14, 14,19, 6,-1, 14,14, 0, 0, 0, 0, 0, 0, // 3020- -1,10,-1,14, 14,19, 6,-1, 14,14, 0, 0, 0, 0, 0, 0, // 3020- Party
-1, 6,-1,-1, 55,19, 6,-1, 14,-1,-1,-1, 18,19,186,-1, // 3030- -1, 6,-1,-1, 55,19, 6,-1, 14,-1,-1,-1, 18,19,186,-1, // 3030-
5, 9, 0, 0, 0, 0, 0, 0, 7, 6,10,10, 10,-1, 0, 0, // 3040- 5, 9, 0, 0, 0, 0, 0, 0, 7, 6,10,10, 10,-1, 0, 0, // 3040-
-1,-1,10,10, 0,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3050- Auction System [Zephyrus] -1,-1,10,10, 0,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3050- Auction System [Zephyrus]

View File

@ -381,14 +381,15 @@ int intif_create_party(struct party_member *member,char *name,int item,int item2
return 0; return 0;
} }
// パーティ情報要求 // パーティ情報要求
int intif_request_partyinfo(int party_id) int intif_request_partyinfo(int party_id, int char_id)
{ {
if (CheckForCharServer()) if (CheckForCharServer())
return 0; return 0;
WFIFOHEAD(inter_fd,6); WFIFOHEAD(inter_fd,10);
WFIFOW(inter_fd,0) = 0x3021; WFIFOW(inter_fd,0) = 0x3021;
WFIFOL(inter_fd,2) = party_id; WFIFOL(inter_fd,2) = party_id;
WFIFOSET(inter_fd,6); WFIFOL(inter_fd,6) = char_id;
WFIFOSET(inter_fd,10);
return 0; return 0;
} }
// パーティ追加要求 // パーティ追加要求
@ -1007,15 +1008,15 @@ int intif_parse_PartyCreated(int fd)
// パーティ情報 // パーティ情報
int intif_parse_PartyInfo(int fd) int intif_parse_PartyInfo(int fd)
{ {
if( RFIFOW(fd,2)==8){ if( RFIFOW(fd,2) == 12 ){
ShowWarning("intif: party noinfo %d\n",RFIFOL(fd,4)); ShowWarning("intif: party noinfo (char_id=%d party_id=%d)\n", RFIFOL(fd,4), RFIFOL(fd,8));
party_recv_noinfo(RFIFOL(fd,4)); party_recv_noinfo(RFIFOL(fd,8), RFIFOL(fd,4));
return 0; return 0;
} }
if( RFIFOW(fd,2)!=sizeof(struct party)+4 ) if( RFIFOW(fd,2) != 8+sizeof(struct party) )
ShowError("intif: party info : data size error %d %d %d\n",RFIFOL(fd,4),RFIFOW(fd,2),sizeof(struct party)+4); ShowError("intif: party info : data size error (char_id=%d party_id=%d packet_len=%d expected_len=%d)\n", RFIFOL(fd,4), RFIFOL(fd,8), RFIFOW(fd,2), 8+sizeof(struct party));
party_recv_info((struct party *)RFIFOP(fd,4)); party_recv_info((struct party *)RFIFOP(fd,8), RFIFOL(fd,4));
return 0; return 0;
} }
// パーティ追加通知 // パーティ追加通知

View File

@ -30,7 +30,7 @@ int intif_send_guild_storage(int account_id, struct guild_storage *gstor);
int intif_create_party(struct party_member *member,char *name,int item,int item2); int intif_create_party(struct party_member *member,char *name,int item,int item2);
int intif_request_partyinfo(int party_id); int intif_request_partyinfo(int party_id, int char_id);
int intif_party_addmember(int party_id,struct party_member *member); int intif_party_addmember(int party_id,struct party_member *member);
int intif_party_changeoption(int party_id, int account_id, int exp, int item); int intif_party_changeoption(int party_id, int account_id, int exp, int item);

View File

@ -28,8 +28,8 @@
#include <string.h> #include <string.h>
static DBMap* party_db; // int party_id -> struct party_data* static DBMap* party_db; // int party_id -> struct party_data* (releases data)
static DBMap* party_booking_db; // Party Booking [Spiria] static DBMap* party_booking_db; // int char_id -> struct party_booking_ad_info* (releases data) // Party Booking [Spiria]
static unsigned long party_booking_nextid = 1; static unsigned long party_booking_nextid = 1;
int party_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data); int party_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data);
@ -38,18 +38,36 @@ int party_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data);
* Fills the given party_member structure according to the sd provided. * Fills the given party_member structure according to the sd provided.
* Used when creating/adding people to a party. [Skotlex] * Used when creating/adding people to a party. [Skotlex]
*------------------------------------------*/ *------------------------------------------*/
static void party_fill_member(struct party_member *member, struct map_session_data *sd) static void party_fill_member(struct party_member* member, struct map_session_data* sd, unsigned int leader)
{ {
member->account_id = sd->status.account_id; member->account_id = sd->status.account_id;
member->char_id = sd->status.char_id; member->char_id = sd->status.char_id;
memcpy(member->name, sd->status.name, NAME_LENGTH); safestrncpy(member->name, sd->status.name, NAME_LENGTH);
member->class_ = sd->status.class_; member->class_ = sd->status.class_;
member->map = sd->mapindex; member->map = sd->mapindex;
member->lv = sd->status.base_level; member->lv = sd->status.base_level;
member->online = 1; member->online = 1;
member->leader = 0; member->leader = leader;
} }
/// Get the member_id of a party member.
/// Return -1 if not in party.
int party_getmemberid(struct party_data* p, struct map_session_data* sd)
{
int member_id;
nullpo_retr(-1, p);
if( sd == NULL )
return -1;// no player
ARR_FIND(0, MAX_PARTY, member_id,
p->party.member[member_id].account_id == sd->status.account_id &&
p->party.member[member_id].char_id == sd->status.char_id);
if( member_id == MAX_PARTY )
return -1;// not found
return member_id;
}
/*========================================== /*==========================================
* Request an available sd of this party * Request an available sd of this party
*------------------------------------------*/ *------------------------------------------*/
@ -72,6 +90,8 @@ static TBL_PC* party_sd_check(int party_id, int account_id, int char_id)
if (!(sd && sd->status.char_id == char_id)) if (!(sd && sd->status.char_id == char_id))
return NULL; return NULL;
if( sd->status.party_id == 0 )
sd->status.party_id = party_id;// auto-join if not in a party
if (sd->status.party_id != party_id) if (sd->status.party_id != party_id)
{ //If player belongs to a different party, kick him out. { //If player belongs to a different party, kick him out.
intif_party_leave(party_id,account_id,char_id); intif_party_leave(party_id,account_id,char_id);
@ -143,8 +163,7 @@ int party_create(struct map_session_data *sd,char *name,int item,int item2)
sd->party_creating = true; sd->party_creating = true;
party_fill_member(&leader, sd); party_fill_member(&leader, sd, 1);
leader.leader = 1;
intif_create_party(&leader,name,item,item2); intif_create_party(&leader,name,item,item2);
return 0; return 0;
@ -175,63 +194,26 @@ void party_created(int account_id,int char_id,int fail,int party_id,char *name)
} }
int party_request_info(int party_id) int party_request_info(int party_id, int char_id)
{ {
return intif_request_partyinfo(party_id); return intif_request_partyinfo(party_id, char_id);
} }
/// Checks if each char having a party actually belongs to that party. /// Invoked (from char-server) when the party info is not found.
/// If check fails, the char gets marked as 'not in a party'. int party_recv_noinfo(int party_id, int char_id)
int party_check_member(struct party *p)
{ {
int i; struct map_session_data* sd;
struct map_session_data *sd;
struct s_mapiterator* iter;
nullpo_ret(p); party_broken(party_id);
if( char_id != 0 )// requester
iter = mapit_getallusers();
for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
{ {
if( sd->status.party_id != p->party_id ) sd = map_charid2sd(char_id);
continue; if( sd && sd->status.party_id == party_id )
ARR_FIND( 0, MAX_PARTY, i, p->member[i].account_id == sd->status.account_id && p->member[i].char_id == sd->status.char_id );
if( i == MAX_PARTY )
{
ShowWarning("party_check_member: '%s' (acc:%d) is not member of party '%s' (id:%d)\n",sd->status.name,sd->status.account_id,p->name,p->party_id);
sd->status.party_id = 0; sd->status.party_id = 0;
}
} }
mapit_free(iter);
return 0; return 0;
} }
/// Marks all chars belonging to this party as 'not in a party'.
int party_recv_noinfo(int party_id)
{
struct map_session_data *sd;
struct s_mapiterator* iter;
iter = mapit_getallusers();
for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
{
if( sd->status.party_id == party_id )
sd->status.party_id = 0; // erase party
}
mapit_free(iter);
return 0;
}
static void* create_party(DBKey key, va_list args)
{
struct party_data *p;
p=(struct party_data *)aCalloc(1,sizeof(struct party_data));
return p;
}
static void party_check_state(struct party_data *p) static void party_check_state(struct party_data *p)
{ {
int i; int i;
@ -259,42 +241,92 @@ static void party_check_state(struct party_data *p)
} }
} }
int party_recv_info(struct party *sp) int party_recv_info(struct party* sp, int char_id)
{ {
struct party_data *p; struct party_data* p;
struct party_member* member;
struct map_session_data* sd;
int removed[MAX_PARTY];// member_id in old data
int removed_count = 0;
int added[MAX_PARTY];// member_id in new data
int added_count = 0;
int i; int i;
bool party_new = false; int member_id;
nullpo_ret(sp); nullpo_ret(sp);
p = (struct party_data*)idb_ensure(party_db, sp->party_id, create_party); p = (struct party_data*)idb_get(party_db, sp->party_id);
if (!p->party.party_id) //party just received. if( p != NULL )// diff members
{ {
party_new = true; for( member_id = 0; member_id < MAX_PARTY; ++member_id )
party_check_member(sp); {
} member = &p->party.member[member_id];
memcpy(&p->party,sp,sizeof(struct party)); if( member->char_id == 0 )
memset(&p->state, 0, sizeof(p->state)); continue;// empty
memset(&p->data, 0, sizeof(p->data)); ARR_FIND(0, MAX_PARTY, i,
for(i=0;i<MAX_PARTY;i++){ sp->member[i].account_id == member->account_id &&
if (!p->party.member[i].account_id) sp->member[i].char_id == member->char_id);
continue; if( i == MAX_PARTY )
p->data[i].sd = party_sd_check(p->party.party_id, p->party.member[i].account_id, p->party.member[i].char_id); removed[removed_count++] = member_id;
} }
party_check_state(p); for( member_id = 0; member_id < MAX_PARTY; ++member_id )
if (party_new) { {
//Send party data to all players. member = &sp->member[member_id];
struct map_session_data *sd; if( member->char_id == 0 )
for(i=0;i<MAX_PARTY;i++){ continue;// empty
sd = p->data[i].sd; ARR_FIND(0, MAX_PARTY, i,
if(!sd) continue; p->party.member[i].account_id == member->account_id &&
clif_charnameupdate(sd); //Update other people's display. [Skotlex] p->party.member[i].char_id == member->char_id);
clif_party_member_info(p,sd); if( i == MAX_PARTY )
clif_party_option(p,sd,0x100); added[added_count++] = member_id;
clif_party_info(p,NULL);
} }
} }
else
{
for( member_id = 0; member_id < MAX_PARTY; ++member_id )
if( sp->member[member_id].char_id != 0 )
added[added_count++] = member_id;
CREATE(p, struct party_data, 1);
idb_put(party_db, sp->party_id, p);
}
while( removed_count > 0 )// no longer in party
{
member_id = removed[--removed_count];
sd = p->data[member_id].sd;
if( sd == NULL )
continue;// not online
party_member_withdraw(sp->party_id, sd->status.account_id, sd->status.char_id);
}
memcpy(&p->party, sp, sizeof(struct party));
memset(&p->state, 0, sizeof(p->state));
memset(&p->data, 0, sizeof(p->data));
for( member_id = 0; member_id < MAX_PARTY; member_id++ )
{
member = &p->party.member[member_id];
if ( member->char_id == 0 )
continue;// empty
p->data[member_id].sd = party_sd_check(sp->party_id, member->account_id, member->char_id);
}
party_check_state(p);
while( added_count > 0 )// new in party
{
member_id = added[--added_count];
sd = p->data[member_id].sd;
if( sd == NULL )
continue;// not online
clif_charnameupdate(sd); //Update other people's display. [Skotlex]
clif_party_member_info(p,sd);
clif_party_option(p,sd,0x100);
clif_party_info(p,NULL);
if( p->instance_id != 0 )
clif_instance_join(sd->fd, p->instance_id);
}
if( char_id != 0 )// requester
{
sd = map_charid2sd(char_id);
if( sd && sd->status.party_id == sp->party_id && party_getmemberid(p,sd) == -1 )
sd->status.party_id = 0;// was not in the party
}
return 0; return 0;
} }
@ -385,7 +417,7 @@ void party_reply_invite(struct map_session_data *sd,int party_id,int flag)
if( flag == 1 && !sd->party_creating && !sd->party_joining ) if( flag == 1 && !sd->party_creating && !sd->party_joining )
{// accepted and allowed {// accepted and allowed
sd->party_joining = true; sd->party_joining = true;
party_fill_member(&member, sd); party_fill_member(&member, sd, 0);
intif_party_addmember(sd->party_invite, &member); intif_party_addmember(sd->party_invite, &member);
} }
else else
@ -407,7 +439,7 @@ void party_member_joined(struct map_session_data *sd)
int i; int i;
if (!p) if (!p)
{ {
party_request_info(sd->status.party_id); party_request_info(sd->status.party_id, sd->status.char_id);
return; return;
} }
ARR_FIND( 0, MAX_PARTY, i, p->party.member[i].account_id == sd->status.account_id && p->party.member[i].char_id == sd->status.char_id ); ARR_FIND( 0, MAX_PARTY, i, p->party.member[i].account_id == sd->status.account_id && p->party.member[i].char_id == sd->status.char_id );
@ -460,7 +492,7 @@ int party_member_added(int party_id,int account_id,int char_id, int flag)
if (i < MAX_PARTY) { if (i < MAX_PARTY) {
//TODO: This is a hack to allow the following clif calls to send the data to the new player. //TODO: This is a hack to allow the following clif calls to send the data to the new player.
//The correct player data is set when party_recv_info arrives soon afterwards. //The correct player data is set when party_recv_info arrives soon afterwards.
party_fill_member(&p->party.member[i], sd); party_fill_member(&p->party.member[i], sd, 0);
p->data[i].sd = sd; p->data[i].sd = sd;
} }

View File

@ -51,11 +51,12 @@ void do_init_party(void);
void do_final_party(void); void do_final_party(void);
struct party_data* party_search(int party_id); struct party_data* party_search(int party_id);
struct party_data* party_searchname(const char* str); struct party_data* party_searchname(const char* str);
int party_getmemberid(struct party_data* p, struct map_session_data* sd);
struct map_session_data* party_getavailablesd(struct party_data *p); struct map_session_data* party_getavailablesd(struct party_data *p);
int party_create(struct map_session_data *sd,char *name, int item, int item2); int party_create(struct map_session_data *sd,char *name, int item, int item2);
void party_created(int account_id,int char_id,int fail,int party_id,char *name); void party_created(int account_id,int char_id,int fail,int party_id,char *name);
int party_request_info(int party_id); int party_request_info(int party_id, int char_id);
int party_invite(struct map_session_data *sd,struct map_session_data *tsd); int party_invite(struct map_session_data *sd,struct map_session_data *tsd);
void party_member_joined(struct map_session_data *sd); void party_member_joined(struct map_session_data *sd);
int party_member_added(int party_id,int account_id,int char_id,int flag); int party_member_added(int party_id,int account_id,int char_id,int flag);
@ -63,8 +64,8 @@ int party_leave(struct map_session_data *sd);
int party_removemember(struct map_session_data *sd,int account_id,char *name); int party_removemember(struct map_session_data *sd,int account_id,char *name);
int party_member_withdraw(int party_id,int account_id,int char_id); int party_member_withdraw(int party_id,int account_id,int char_id);
void party_reply_invite(struct map_session_data *sd,int party_id,int flag); void party_reply_invite(struct map_session_data *sd,int party_id,int flag);
int party_recv_noinfo(int party_id); int party_recv_noinfo(int party_id, int char_id);
int party_recv_info(struct party *sp); int party_recv_info(struct party* sp, int char_id);
int party_recv_movemap(int party_id,int account_id,int char_id, unsigned short map,int online,int lv); int party_recv_movemap(int party_id,int account_id,int char_id, unsigned short map,int online,int lv);
int party_broken(int party_id); int party_broken(int party_id);
int party_optionchanged(int party_id,int account_id,int exp,int item,int flag); int party_optionchanged(int party_id,int account_id,int exp,int item,int flag);