From a8ee3c14340344c50c34514520c165aa283e91e0 Mon Sep 17 00:00:00 2001 From: flaviojs Date: Sun, 9 Oct 2011 13:19:06 +0000 Subject: * 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://rathena.svn.sourceforge.net/svnroot/rathena/trunk@14968 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/intif.c | 19 +++--- src/map/intif.h | 2 +- src/map/party.c | 192 +++++++++++++++++++++++++++++++++----------------------- src/map/party.h | 7 ++- 4 files changed, 127 insertions(+), 93 deletions(-) (limited to 'src/map') diff --git a/src/map/intif.c b/src/map/intif.c index 1b69c0837..9fea3be43 100644 --- a/src/map/intif.c +++ b/src/map/intif.c @@ -381,14 +381,15 @@ int intif_create_party(struct party_member *member,char *name,int item,int item2 return 0; } // パーティ情報要求 -int intif_request_partyinfo(int party_id) +int intif_request_partyinfo(int party_id, int char_id) { if (CheckForCharServer()) return 0; - WFIFOHEAD(inter_fd,6); + WFIFOHEAD(inter_fd,10); WFIFOW(inter_fd,0) = 0x3021; WFIFOL(inter_fd,2) = party_id; - WFIFOSET(inter_fd,6); + WFIFOL(inter_fd,6) = char_id; + WFIFOSET(inter_fd,10); return 0; } // パーティ追加要求 @@ -1007,15 +1008,15 @@ int intif_parse_PartyCreated(int fd) // パーティ情報 int intif_parse_PartyInfo(int fd) { - if( RFIFOW(fd,2)==8){ - ShowWarning("intif: party noinfo %d\n",RFIFOL(fd,4)); - party_recv_noinfo(RFIFOL(fd,4)); + if( RFIFOW(fd,2) == 12 ){ + ShowWarning("intif: party noinfo (char_id=%d party_id=%d)\n", RFIFOL(fd,4), RFIFOL(fd,8)); + party_recv_noinfo(RFIFOL(fd,8), RFIFOL(fd,4)); return 0; } - if( RFIFOW(fd,2)!=sizeof(struct party)+4 ) - ShowError("intif: party info : data size error %d %d %d\n",RFIFOL(fd,4),RFIFOW(fd,2),sizeof(struct party)+4); - party_recv_info((struct party *)RFIFOP(fd,4)); + if( RFIFOW(fd,2) != 8+sizeof(struct party) ) + 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,8), RFIFOL(fd,4)); return 0; } // パーティ追加通知 diff --git a/src/map/intif.h b/src/map/intif.h index 73dc5b863..1df990108 100644 --- a/src/map/intif.h +++ b/src/map/intif.h @@ -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_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_changeoption(int party_id, int account_id, int exp, int item); diff --git a/src/map/party.c b/src/map/party.c index 88f53bcb0..803c8d491 100644 --- a/src/map/party.c +++ b/src/map/party.c @@ -28,8 +28,8 @@ #include -static DBMap* party_db; // int party_id -> struct party_data* -static DBMap* party_booking_db; // Party Booking [Spiria] +static DBMap* party_db; // int party_id -> struct party_data* (releases data) +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; 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. * 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->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->map = sd->mapindex; member->lv = sd->status.base_level; 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 *------------------------------------------*/ @@ -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)) 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 player belongs to a different party, kick him out. 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; - party_fill_member(&leader, sd); - leader.leader = 1; + party_fill_member(&leader, sd, 1); intif_create_party(&leader,name,item,item2); 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. -/// If check fails, the char gets marked as 'not in a party'. -int party_check_member(struct party *p) +/// Invoked (from char-server) when the party info is not found. +int party_recv_noinfo(int party_id, int char_id) { - int i; - struct map_session_data *sd; - struct s_mapiterator* iter; + struct map_session_data* sd; - nullpo_ret(p); - - iter = mapit_getallusers(); - for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) ) + party_broken(party_id); + if( char_id != 0 )// requester { - if( sd->status.party_id != p->party_id ) - continue; - - 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 = map_charid2sd(char_id); + if( sd && sd->status.party_id == party_id ) sd->status.party_id = 0; - } } - mapit_free(iter); - - 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) { 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; - bool party_new = false; + int member_id; nullpo_ret(sp); - p = (struct party_data*)idb_ensure(party_db, sp->party_id, create_party); - if (!p->party.party_id) //party just received. + p = (struct party_data*)idb_get(party_db, sp->party_id); + if( p != NULL )// diff members + { + for( member_id = 0; member_id < MAX_PARTY; ++member_id ) + { + member = &p->party.member[member_id]; + if( member->char_id == 0 ) + continue;// empty + ARR_FIND(0, MAX_PARTY, i, + sp->member[i].account_id == member->account_id && + sp->member[i].char_id == member->char_id); + if( i == MAX_PARTY ) + removed[removed_count++] = member_id; + } + for( member_id = 0; member_id < MAX_PARTY; ++member_id ) + { + member = &sp->member[member_id]; + if( member->char_id == 0 ) + continue;// empty + ARR_FIND(0, MAX_PARTY, i, + p->party.member[i].account_id == member->account_id && + p->party.member[i].char_id == member->char_id); + if( i == MAX_PARTY ) + added[added_count++] = member_id; + } + } + else { - party_new = true; - party_check_member(sp); + 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); } - memcpy(&p->party,sp,sizeof(struct party)); + 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(i=0;iparty.member[i].account_id) - continue; - p->data[i].sd = party_sd_check(p->party.party_id, p->party.member[i].account_id, p->party.member[i].char_id); + 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); - if (party_new) { - //Send party data to all players. - struct map_session_data *sd; - for(i=0;idata[i].sd; - if(!sd) continue; - 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); - } + 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; } @@ -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 ) {// accepted and allowed sd->party_joining = true; - party_fill_member(&member, sd); + party_fill_member(&member, sd, 0); intif_party_addmember(sd->party_invite, &member); } else @@ -407,7 +439,7 @@ void party_member_joined(struct map_session_data *sd) int i; if (!p) { - party_request_info(sd->status.party_id); + party_request_info(sd->status.party_id, sd->status.char_id); 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 ); @@ -460,7 +492,7 @@ int party_member_added(int party_id,int account_id,int char_id, int flag) if (i < MAX_PARTY) { //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. - party_fill_member(&p->party.member[i], sd); + party_fill_member(&p->party.member[i], sd, 0); p->data[i].sd = sd; } diff --git a/src/map/party.h b/src/map/party.h index 1c59197b3..9fde5a6a4 100644 --- a/src/map/party.h +++ b/src/map/party.h @@ -51,11 +51,12 @@ void do_init_party(void); void do_final_party(void); struct party_data* party_search(int party_id); 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); 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); -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); void party_member_joined(struct map_session_data *sd); 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_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); -int party_recv_noinfo(int party_id); -int party_recv_info(struct party *sp); +int party_recv_noinfo(int party_id, int char_id); +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_broken(int party_id); int party_optionchanged(int party_id,int account_id,int exp,int item,int flag); -- cgit v1.2.3-60-g2f50