From a2decc5d8acbf0c309c1396d4023c490d6e6a038 Mon Sep 17 00:00:00 2001 From: ultramage Date: Mon, 19 Nov 2007 14:51:23 +0000 Subject: Random cleaning of party.c in attempt to make party_send_xy_timer() crashes a bit clearer... - now party_db is iterated instead of using foreach() git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@11761 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/common/mmo.h | 2 +- src/map/party.c | 279 +++++++++++++++++++++++++++---------------------------- src/map/party.h | 6 +- 3 files changed, 143 insertions(+), 144 deletions(-) diff --git a/src/common/mmo.h b/src/common/mmo.h index f679d61f5..1db623982 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -309,7 +309,7 @@ struct party_member { unsigned short map; unsigned short lv; unsigned leader : 1, - online : 1; + online : 1; }; struct party { diff --git a/src/map/party.c b/src/map/party.c index 66100784e..70fdafe97 100644 --- a/src/map/party.c +++ b/src/map/party.c @@ -56,44 +56,42 @@ void do_final_party(void) // void do_init_party(void) { - party_db=idb_alloc(DB_OPT_RELEASE_DATA); + party_db = idb_alloc(DB_OPT_RELEASE_DATA); add_timer_func_list(party_send_xy_timer, "party_send_xy_timer"); add_timer_interval(gettick()+battle_config.party_update_interval, party_send_xy_timer, 0, 0, battle_config.party_update_interval); } -// -struct party_data *party_search(int party_id) +/// Party data lookup using party id. +struct party_data* party_search(int party_id) { if(!party_id) return NULL; return idb_get(party_db,party_id); } -int party_searchname_sub(DBKey key,void *data,va_list ap) -{ - struct party_data *p=(struct party_data *)data,**dst; - char *str; - str=va_arg(ap,char *); - dst=va_arg(ap,struct party_data **); - if(strncmpi(p->party.name,str,NAME_LENGTH)==0) - *dst=p; - return 0; -} -struct party_data* party_searchname(char *str) +/// Party data lookup using party name. +struct party_data* party_searchname(const char* str) { - struct party_data *p=NULL; - party_db->foreach(party_db,party_searchname_sub,str,&p); + struct party_data* p; + + DBIterator* iter = party_db->iterator(party_db); + for( p = iter->first(iter,NULL); iter->exists(iter); p = iter->next(iter,NULL) ) + { + if( strncmpi(p->party.name,str,NAME_LENGTH) == 0 ) + break; + } + iter->destroy(iter); + return p; } int party_create(struct map_session_data *sd,char *name,int item,int item2) { struct party_member leader; - nullpo_retr(0, sd); if(sd->status.party_id) { clif_party_created(sd,2); - return 0; + return 0; // "already in a party" } party_fill_member(&leader, sd); @@ -116,7 +114,7 @@ int party_created(int account_id,int char_id,int fail,int party_id,char *name) if(fail){ clif_party_created(sd,1); - return 0; + return 0; // "party name already exists" } sd->status.party_id=party_id; if(idb_get(party_db,party_id)!=NULL){ @@ -137,6 +135,8 @@ int party_request_info(int party_id) return intif_request_partyinfo(party_id); } +/// Checks if each char having a party actually belongs to that party. +/// If check fails, the char is marked as 'not in a party'. int party_check_member(struct party *p) { int i, users; @@ -148,27 +148,23 @@ int party_check_member(struct party *p) for(i=0;istatus.party_id==p->party_id) + sd = all_sd[i]; + if( sd && sd->status.party_id == p->party_id ) { - int j,f=1; - for(j=0;jmember[j].account_id==sd->status.account_id && - p->member[j].char_id==sd->status.char_id) - { - f=0; - break; - } - } - - if(f){ - sd->status.party_id=0; - ShowWarning("party: check_member %d[%s] is not member\n",sd->status.account_id,sd->status.name); + int j; + ARR_FIND( 0, MAX_PARTY, j, p->member[j].account_id == sd->status.account_id && p->member[j].char_id == sd->status.char_id ); + if( j == MAX_PARTY ) + { + ShowWarning("party_check_member: '%s' (acc:%d) is not member of party '%s' (id:%d)\n",sd->status.char_id,sd->status.name,p->name,p->party_id); + sd->status.party_id = 0; } } } + return 0; } +/// Marks all chars belonging to this party as 'not in a party'. int party_recv_noinfo(int party_id) { int i, users; @@ -319,7 +315,6 @@ int party_reply_invite(struct map_session_data *sd,int account_id,int flag) { struct map_session_data *tsd= map_id2sd(account_id); struct party_member member; - nullpo_retr(0, sd); if(flag==1){ party_fill_member(&member, sd); @@ -334,12 +329,13 @@ int party_reply_invite(struct map_session_data *sd,int account_id,int flag) return 1; } -/// Invoked (from char-server) when a member is added to the party. +/// Invoked (from char-server) when a new member is added to the party. int party_member_added(int party_id,int account_id,int char_id, int flag) { struct map_session_data *sd = map_id2sd(account_id),*sd2; struct party_data *p = party_search(party_id); int i; + if(sd == NULL || sd->status.char_id != char_id){ if (flag == 0) { ShowError("party: member added error %d is not online\n",account_id); @@ -378,97 +374,92 @@ int party_member_added(int party_id,int account_id,int char_id, int flag) return 0; } -int party_removemember(struct map_session_data *sd,int account_id,char *name) +/// Party member 'sd' requesting kick of member with . +int party_removemember(struct map_session_data* sd, int account_id, char* name) { struct party_data *p; int i; - nullpo_retr(0, sd); - - if( (p = party_search(sd->status.party_id)) == NULL ) + p = party_search(sd->status.party_id); + if( p == NULL ) return 0; - for(i=0;iparty.member[i].account_id==sd->status.account_id && - p->party.member[i].char_id==sd->status.char_id) { - if(p->party.member[i].leader) - break; - return 0; - } - } - if (i >= MAX_PARTY) //Request from someone not in party? o.O - return 0; - - for(i=0;iparty.member[i].account_id==account_id && - strncmp(p->party.member[i].name,name,NAME_LENGTH)==0) - { - intif_party_leave(p->party.party_id,account_id,p->party.member[i].char_id); - return 1; - } - } - return 0; + // check the requesting char's party membership + 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 ); + if( i == MAX_PARTY ) + return 0; // request from someone not in party? o.O + if( !p->party.member[i].leader ) + return 0; // only party leader may remove members + + ARR_FIND( 0, MAX_PARTY, i, p->party.member[i].account_id == account_id && strncmp(p->party.member[i].name,name,NAME_LENGTH) == 0 ); + if( i == MAX_PARTY ) + return 0; // no such char in party + + intif_party_leave(p->party.party_id,account_id,p->party.member[i].char_id); + return 1; } +/// Party member 'sd' requesting exit from party. int party_leave(struct map_session_data *sd) { struct party_data *p; int i; - nullpo_retr(0, sd); - - if( (p = party_search(sd->status.party_id)) == NULL ) + p = party_search(sd->status.party_id); + if( p == NULL ) return 0; - - for(i=0;iparty.member[i].account_id==sd->status.account_id && - p->party.member[i].char_id==sd->status.char_id){ - intif_party_leave(p->party.party_id,sd->status.account_id,sd->status.char_id); - return 0; - } - } - return 0; + + 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 ); + if( i == MAX_PARTY ) + return 0; + + intif_party_leave(p->party.party_id,sd->status.account_id,sd->status.char_id); + return 1; } -int party_member_leaved(int party_id,int account_id,int char_id) +/// Invoked (from char-server) when a party member leaves the party. +int party_member_leaved(int party_id, int account_id, int char_id) { - struct map_session_data *sd=map_id2sd(account_id); - struct party_data *p=party_search(party_id); + struct map_session_data* sd = map_id2sd(account_id); + struct party_data* p = party_search(party_id); int i; - if (sd && sd->status.char_id != char_id) //Wrong target - sd = NULL; - if(p!=NULL){ - for(i=0;iparty.member[i].account_id==account_id && - p->party.member[i].char_id==char_id){ - clif_party_leaved(p,sd,account_id,p->party.member[i].name,0x00); - memset(&p->party.member[i], 0, sizeof(p->party.member[0])); - memset(&p->data[i], 0, sizeof(p->data[0])); - p->party.count--; - party_check_state(p); - break; - } + + if( p ) + { + ARR_FIND( 0, MAX_PARTY, i, p->party.member[i].account_id == account_id && p->party.member[i].char_id == char_id ); + if( i < MAX_PARTY ) + { + clif_party_leaved(p,sd,account_id,p->party.member[i].name,0x00); + memset(&p->party.member[i], 0, sizeof(p->party.member[0])); + memset(&p->data[i], 0, sizeof(p->data[0])); + p->party.count--; + party_check_state(p); + } } - if(sd!=NULL && sd->status.party_id==party_id){ - sd->status.party_id=0; - sd->state.party_sent=0; + + if( sd && sd->status.party_id==party_id && sd->status.char_id == char_id ) + { + sd->status.party_id = 0; + sd->state.party_sent = 0; clif_charnameupdate(sd); //Update name display [Skotlex] //TODO: hp bars should be cleared too } return 0; } +/// Invoked (from char-server) when a party is disbanded. int party_broken(int party_id) { - struct party_data *p; + struct party_data* p; int i; - if( (p=party_search(party_id))==NULL ) + + p = party_search(party_id); + if( p == NULL ) return 0; - + for(i=0;idata[i].sd!=NULL){ - clif_party_leaved(p,p->data[i].sd, - p->party.member[i].account_id,p->party.member[i].name,0x10); + clif_party_leaved(p,p->data[i].sd,p->party.member[i].account_id,p->party.member[i].name,0x10); p->data[i].sd->status.party_id=0; p->data[i].sd->state.party_sent=0; } @@ -507,29 +498,35 @@ int party_optionchanged(int party_id,int account_id,int exp,int item,int flag) return 0; } +/// Invoked (from char-server) when a party member +/// - changes maps +/// - logs in or out +/// - gains a level (disabled) int party_recv_movemap(int party_id,int account_id,int char_id, unsigned short map,int online,int lv) { - struct party_data *p; + struct map_session_data* sd; + struct party_member* m; + struct party_data* p; int i; - if( (p=party_search(party_id))==NULL) + + p = party_search(party_id); + if( p == NULL ) return 0; - for(i=0;iparty.member[i]; - if(m->account_id==account_id && m->char_id==char_id){ - m->map = map; - m->online=online; - m->lv=lv; - //Check if they still exist on this map server - sd = map_id2sd(m->account_id); - p->data[i].sd = (sd!=NULL && sd->status.party_id==p->party.party_id && sd->status.char_id == m->char_id && !sd->state.waitingdisconnect)?sd:NULL; - break; - } - } - if(i==MAX_PARTY){ - ShowError("party: not found member %d/%d on %d[%s]",account_id,char_id,party_id,p->party.name); + + ARR_FIND( 0, MAX_PARTY, i, p->party.member[i].account_id == account_id && p->party.member[i].char_id == char_id ); + if( i == MAX_PARTY ) + { + ShowError("party_recv_movemap: char %d/%d not found in party %s (id:%d)",account_id,char_id,p->party.name,party_id); return 0; } + + m = &p->party.member[i]; + m->map = map; + m->online = online; + m->lv = lv; + //Check if they still exist on this map server + sd = map_id2sd(m->account_id); + p->data[i].sd = (sd!=NULL && sd->status.party_id==p->party.party_id && sd->status.char_id == m->char_id && !sd->state.waitingdisconnect)?sd:NULL; clif_party_info(p,NULL); return 0; @@ -589,8 +586,8 @@ int party_send_logout(struct map_session_data *sd) p=party_search(sd->status.party_id); if(!p) return 0; - for(i=0;idata[i].sd != sd;i++); - if (i < MAX_PARTY) + ARR_FIND( 0, MAX_PARTY, i, p->data[i].sd == sd ); + if( i < MAX_PARTY ) memset(&p->data[i], 0, sizeof(p->data[0])); return 1; @@ -678,36 +675,36 @@ int party_skill_check(struct map_session_data *sd, int party_id, int skillid, in return 0; } -int party_send_xy_timer_sub(DBKey key,void *data,va_list ap) +int party_send_xy_timer(int tid,unsigned int tick,int id,int data) { - struct party_data *p=(struct party_data *)data; - struct map_session_data *sd; - int i; + struct party_data* p; - nullpo_retr(0, p); - - for(i=0;idata[i].sd) continue; - sd = p->data[i].sd; - if (p->data[i].x != sd->bl.x || p->data[i].y != sd->bl.y) - { - clif_party_xy(sd); - p->data[i].x = sd->bl.x; - p->data[i].y = sd->bl.y; - } - if (battle_config.party_hp_mode && - p->data[i].hp != sd->battle_status.hp) + DBIterator* iter = party_db->iterator(party_db); + // for each existing party, + for( p = iter->first(iter,NULL); iter->exists(iter); p = iter->next(iter,NULL) ) + { + int i; + // for each member of this party, + for( i = 0; i < MAX_PARTY; i++ ) { - clif_party_hp(sd); - p->data[i].hp = sd->battle_status.hp; + struct map_session_data* sd = p->data[i].sd; + if( !sd ) continue; + + if( p->data[i].x != sd->bl.x || p->data[i].y != sd->bl.y ) + {// perform position update + clif_party_xy(sd); + p->data[i].x = sd->bl.x; + p->data[i].y = sd->bl.y; + } + if (battle_config.party_hp_mode && p->data[i].hp != sd->battle_status.hp) + {// perform hp update + clif_party_hp(sd); + p->data[i].hp = sd->battle_status.hp; + } } } - return 0; -} + iter->destroy(iter); -int party_send_xy_timer(int tid,unsigned int tick,int id,int data) -{ - party_db->foreach(party_db,party_send_xy_timer_sub,tick); return 0; } @@ -861,6 +858,7 @@ int party_sub_count(struct block_list *bl, va_list ap) return 1; } +/// Executes 'func' for each party member on the same map and in range (0:whole map) int party_foreachsamemap(int (*func)(struct block_list*,va_list),struct map_session_data *sd,int range,...) { struct party_data *p; @@ -883,8 +881,9 @@ int party_foreachsamemap(int (*func)(struct block_list*,va_list),struct map_sess va_start(ap,range); - for(i=0;idata[i].sd; + for(i=0;idata[i].sd; if(!psd) continue; if(psd->bl.m!=sd->bl.m || !psd->bl.prev) continue; diff --git a/src/map/party.h b/src/map/party.h index c32863602..8329647b2 100644 --- a/src/map/party.h +++ b/src/map/party.h @@ -17,8 +17,8 @@ extern int party_share_level; void do_init_party(void); void do_final_party(void); -struct party_data *party_search(int party_id); -struct party_data *party_searchname(char *str); +struct party_data* party_search(int party_id); +struct party_data* party_searchname(const char* str); int party_create(struct map_session_data *sd,char *name, int item, int item2); int party_created(int account_id,int char_id,int fail,int party_id,char *name); @@ -47,6 +47,6 @@ int party_exp_share(struct party_data *p,struct block_list *src,unsigned int bas int party_share_loot(struct party_data* p, struct map_session_data* sd, struct item* item_data, int first_charid); int party_send_dot_remove(struct map_session_data *sd); int party_sub_count(struct block_list *bl, va_list ap); -int party_foreachsamemap(int (*func)(struct block_list *,va_list),struct map_session_data *sd,int type,...); +int party_foreachsamemap(int (*func)(struct block_list *,va_list),struct map_session_data *sd,int range,...); #endif /* _PARTY_H_ */ -- cgit v1.2.3-70-g09d2