Cleanup party withdraw (#1585)

* Added enum for withdraw result in mmo.h.
* Added name of kicked player and changed `sd` init from `account_id` to `char_id`.
* Fixed party list window isn't updated when member kicked.
* Updated packet documentation.
* Thanks to @aleos89 @Lemongrass3110

Signed-off-by: Cydh Ramdh <cydh@pservero.com>
This commit is contained in:
Cydh Ramdh 2016-10-06 10:58:05 +07:00 committed by GitHub
parent 01b1052570
commit 9a52768f6f
13 changed files with 88 additions and 84 deletions

View File

@ -703,16 +703,18 @@ Currently the max packet size is 0xFFFF (see 'WFIFOSET()' in 'src/common/socket.
0x3024
Type: ZI
Structure: <cmd>.W <party_id>.L <aid>.L <cid>.L
index: 0,2,6,10
len: 14
Structure: <cmd>.W <party_id>.L <aid>.L <cid>.L <name>.24B <type>.B
index: 0,2,6,10,14,48
len: 49
parameter:
- cmd : packet identification (0x3024)
- party_id
- aid
- cid
- party_id : Party ID
- aid : Account ID
- cid : Character ID
- name : Character Name
- type : Leave (PARTY_MEMBER_WITHDRAW_LEAVE) or kick (PARTY_MEMBER_WITHDRAW_EXPEL) the player
desc:
- Request to leave party
- Request to leave party or kick party member
0x3025
Type: ZI
@ -1615,15 +1617,16 @@ Currently the max packet size is 0xFFFF (see 'WFIFOSET()' in 'src/common/socket.
0x3824
Type: IZ
Structure: <cmd>.W <party_id>.L <account_id>.L <char_id>.L <?>.?B
index: 0,2,6,10,14
len: 16?
Structure: <cmd>.W <party_id>.L <account_id>.L <char_id>.L <name>.24B <type>.B
index: 0,2,6,10,14,48
len: 49
parameter:
- cmd : packet identification (0x3824)
- party_ud
- account_id
- char_id
- ?
- party_id : Party ID
- account_id : Account ID
- char_id : Character ID
- name : Character Name
- type : Leaving reason/result
desc:
- Withdrawal notification party

View File

@ -1701,7 +1701,7 @@ int char_delete_char_sql(uint32 char_id){
//Make the character leave the party [Skotlex]
if (party_id)
inter_party_leave(party_id, account_id, char_id);
inter_party_leave(party_id, account_id, char_id, name);
/* delete char's pet */
//Delete the hatched pet if you have one...

View File

@ -28,7 +28,7 @@ static DBMap* party_db_; // int party_id -> struct party_data*
int mapif_party_broken(int party_id,int flag);
int party_check_empty(struct party_data *p);
int mapif_parse_PartyLeave(int fd, int party_id, uint32 account_id, uint32 char_id);
int mapif_parse_PartyLeave(int fd, int party_id, uint32 account_id, uint32 char_id, char *name, enum e_party_member_withdraw type);
int party_check_exp_share(struct party_data *p);
int mapif_party_optionchanged(int fd,struct party *p, uint32 account_id, int flag);
@ -404,14 +404,16 @@ int mapif_party_optionchanged(int fd,struct party *p,uint32 account_id,int flag)
}
//Withdrawal notification party
int mapif_party_withdraw(int party_id,uint32 account_id, uint32 char_id) {
unsigned char buf[16];
int mapif_party_withdraw(int party_id, uint32 account_id, uint32 char_id, char *name, enum e_party_member_withdraw type) {
unsigned char buf[15+NAME_LENGTH];
WBUFW(buf,0) = 0x3824;
WBUFL(buf,2) = party_id;
WBUFL(buf,6) = account_id;
WBUFL(buf,10) = char_id;
chmapif_sendall(buf, 14);
memcpy(WBUFP(buf,14), name, NAME_LENGTH);
WBUFB(buf,14+NAME_LENGTH) = type;
chmapif_sendall(buf,15+NAME_LENGTH);
return 0;
}
@ -586,7 +588,7 @@ int mapif_parse_PartyChangeOption(int fd,int party_id,uint32 account_id,int exp,
}
//Request leave party
int mapif_parse_PartyLeave(int fd, int party_id, uint32 account_id, uint32 char_id)
int mapif_parse_PartyLeave(int fd, int party_id, uint32 account_id, uint32 char_id, char *name, enum e_party_member_withdraw type)
{
struct party_data *p;
int i,j=-1;
@ -608,14 +610,15 @@ int mapif_parse_PartyLeave(int fd, int party_id, uint32 account_id, uint32 char_
if (i >= MAX_PARTY)
return 0; //Member not found?
mapif_party_withdraw(party_id, account_id, char_id);
mapif_party_withdraw(party_id, account_id, char_id, name, type);
if (p->party.member[i].leader){
// TODO: Official allow 'leaderless' party
p->party.member[i].account_id = 0;
for (j = 0; j < MAX_PARTY; j++) {
if (!p->party.member[j].account_id)
continue;
mapif_party_withdraw(party_id, p->party.member[j].account_id, p->party.member[j].char_id);
mapif_party_withdraw(party_id, p->party.member[j].account_id, p->party.member[j].char_id, p->party.member[j].name, type);
p->party.member[j].account_id = 0;
}
//Party gets deleted on the check_empty call below.
@ -775,7 +778,7 @@ int inter_party_parse_frommap(int fd)
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 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), (char *)RFIFOP(fd,14), (enum e_party_member_withdraw)RFIFOB(fd,14+NAME_LENGTH)); break;
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;
case 0x3026: mapif_parse_BreakParty(fd, RFIFOL(fd,2)); break;
case 0x3027: mapif_parse_PartyMessage(fd, RFIFOL(fd,4), RFIFOL(fd,8), (char*)RFIFOP(fd,12), RFIFOW(fd,2)-12); break;
@ -788,9 +791,9 @@ int inter_party_parse_frommap(int fd)
}
//Leave request from the server (for delete character)
int inter_party_leave(int party_id,uint32 account_id, uint32 char_id)
int inter_party_leave(int party_id,uint32 account_id, uint32 char_id, char *name)
{
return mapif_parse_PartyLeave(-1,party_id,account_id, char_id);
return mapif_parse_PartyLeave(-1,party_id,account_id, char_id, name, PARTY_MEMBER_WITHDRAW_EXPEL);
}
int inter_party_CharOnline(uint32 char_id, int party_id)

View File

@ -19,7 +19,7 @@ struct party;
int inter_party_parse_frommap(int fd);
int inter_party_sql_init(void);
void inter_party_sql_final(void);
int inter_party_leave(int party_id,uint32 account_id, uint32 char_id);
int inter_party_leave(int party_id,uint32 account_id, uint32 char_id, char *name);
int inter_party_CharOnline(uint32 char_id, int party_id);
int inter_party_CharOffline(uint32 char_id, int party_id);

View File

@ -46,7 +46,7 @@ unsigned int party_share_level = 10;
int inter_recv_packet_length[] = {
-1,-1, 7,-1, -1,13,36, (2+4+4+4+1+NAME_LENGTH), 0,-1, 0, 0, 0, 0, 0, 0, // 3000-
6,-1, 0, 0, 0, 0, 0, 0, 10,-1, 0, 0, 0, 0, 0, 0, // 3010-
-1,10,-1,14, 14,19, 6,-1, 14,14, 6, 0, 0, 0, 0, 0, // 3020- Party
-1,10,-1,14, 15+NAME_LENGTH,19, 6,-1, 14,14, 6, 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, 9, 0, 0, 0, 0, 0, 0, 7, 6,10,10, 10,-1, 0, 0, // 3040-
-1,-1,10,10, 0,-1,12, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3050- Auction System [Zephyrus]

View File

@ -838,6 +838,13 @@ enum e_pc_reg_loading {
PRL_ALL = 0xFF,
};
enum e_party_member_withdraw {
PARTY_MEMBER_WITHDRAW_LEAVE, ///< /leave
PARTY_MEMBER_WITHDRAW_EXPEL, ///< Kicked
PARTY_MEMBER_WITHDRAW_CANT_LEAVE, ///< TODO: Cannot /leave
PARTY_MEMBER_WITHDRAW_CANT_EXPEL, ///< TODO: Cannot be kicked
};
// Sanity checks...
#if MAX_ZENY > INT_MAX
#error MAX_ZENY is too big

View File

@ -7401,37 +7401,26 @@ void clif_party_option(struct party_data *p,struct map_session_data *sd,int flag
clif_send(buf,packet_len(cmd),&sd->bl,SELF);
}
/**
* 0105 <account id>.L <char name>.24B <result>.B (ZC_DELETE_MEMBER_FROM_GROUP).
* @param sd Send the notification for this player
* @param account_id Account ID of kicked member
* @param name Name of kicked member
* @param result Party leave result @see PARTY_MEMBER_WITHDRAW
* @param target Send target
**/
void clif_party_withdraw(struct map_session_data *sd, uint32 account_id, const char* name, enum e_party_member_withdraw result, enum send_target target) {
unsigned char buf[2+4+NAME_LENGTH+1];
/// 0105 <account id>.L <char name>.24B <result>.B (ZC_DELETE_MEMBER_FROM_GROUP).
/// result:
/// 0 = leave
/// 1 = expel
/// 2 = cannot leave party on this map
/// 3 = cannot expel from party on this map
void clif_party_withdraw(struct party_data* p, struct map_session_data* sd, uint32 account_id, const char* name, int flag)
{
unsigned char buf[64];
if (!sd)
return;
nullpo_retv(p);
WBUFW(buf,0) = 0x0105;
WBUFL(buf,2) = account_id;
memcpy(WBUFP(buf,6), name, NAME_LENGTH);
WBUFB(buf,6+NAME_LENGTH) = result;
if(!sd && (flag&0xf0)==0)
{
int i;
ARR_FIND(0,MAX_PARTY,i,p->data[i].sd);
if (i < MAX_PARTY)
sd = p->data[i].sd;
}
if(!sd) return;
WBUFW(buf,0)=0x105;
WBUFL(buf,2)=account_id;
memcpy(WBUFP(buf,6),name,NAME_LENGTH);
WBUFB(buf,30)=flag&0x0f;
if((flag&0xf0)==0)
clif_send(buf,packet_len(0x105),&sd->bl,PARTY);
else
clif_send(buf,packet_len(0x105),&sd->bl,SELF);
clif_send(buf, 2+4+NAME_LENGTH+1, &sd->bl, target);
}

View File

@ -721,7 +721,7 @@ void clif_party_info(struct party_data* p, struct map_session_data *sd);
void clif_party_invite(struct map_session_data *sd,struct map_session_data *tsd);
void clif_party_invite_reply(struct map_session_data* sd, const char* nick, enum e_party_invite_reply reply);
void clif_party_option(struct party_data *p,struct map_session_data *sd,int flag);
void clif_party_withdraw(struct party_data* p, struct map_session_data* sd, uint32 account_id, const char* name, int flag);
void clif_party_withdraw(struct map_session_data *sd, uint32 account_id, const char* name, enum e_party_member_withdraw result, enum send_target target);
void clif_party_message(struct party_data* p, uint32 account_id, const char* mes, int len);
void clif_party_xy(struct map_session_data *sd);
void clif_party_xy_single(int fd, struct map_session_data *sd);

View File

@ -27,7 +27,7 @@
static const int packet_len_table[]={
-1,-1,27,-1, -1, 0,37,-1, 10+NAME_LENGTH,-1, 0, 0, 0, 0, 0, 0, //0x3800-0x380f
0, 0, 0, 0, 0, 0, 0, 0, -1,11, 0, 0, 0, 0, 0, 0, //0x3810
39,-1,15,15, 14,19, 7,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3820
39,-1,15,15, 15+NAME_LENGTH,19, 7,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3820
10,-1,15, 0, 79,19, 7,-1, 0,-1,-1,-1, 14,67,186,-1, //0x3830
-1, 0, 0,14, 0, 0, 0, 0, -1,74,-1,11, 11,-1, 0, 0, //0x3840
-1,-1, 7, 7, 7,11, 8,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3850 Auctions [Zephyrus] itembound[Akinari]
@ -620,16 +620,18 @@ int intif_party_changeoption(int party_id,uint32 account_id,int exp,int item)
* @param char_id : cid of player to leave
* @return 0:char-serv disconected, 1=msg sent
*/
int intif_party_leave(int party_id,uint32 account_id, uint32 char_id)
int intif_party_leave(int party_id, uint32 account_id, uint32 char_id, char *name, enum e_party_member_withdraw type)
{
if (CheckForCharServer())
return 0;
WFIFOHEAD(inter_fd,14);
WFIFOW(inter_fd,0)=0x3024;
WFIFOL(inter_fd,2)=party_id;
WFIFOL(inter_fd,6)=account_id;
WFIFOL(inter_fd,10)=char_id;
WFIFOSET(inter_fd,14);
WFIFOHEAD(inter_fd,15+NAME_LENGTH);
WFIFOW(inter_fd,0) = 0x3024;
WFIFOL(inter_fd,2) = party_id;
WFIFOL(inter_fd,6) = account_id;
WFIFOL(inter_fd,10) = char_id;
memcpy((char *)WFIFOP(inter_fd,14), name, NAME_LENGTH);
WFIFOB(inter_fd,14+NAME_LENGTH) = type;
WFIFOSET(inter_fd,15+NAME_LENGTH);
return 1;
}
@ -1527,8 +1529,8 @@ int intif_parse_PartyOptionChanged(int fd)
int intif_parse_PartyMemberWithdraw(int fd)
{
if(battle_config.etc_log)
ShowInfo("intif: party member withdraw: Party(%d), Account(%d), Char(%d)\n",RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10));
party_member_withdraw(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10));
ShowInfo("intif: party member withdraw: Type(%d) Party(%d), Account(%d), Char(%d), Name(%s)\n",RFIFOB(fd,14+NAME_LENGTH),RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),(char*)RFIFOP(fd,14));
party_member_withdraw(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),(char*)RFIFOP(fd,14),(enum e_party_member_withdraw)RFIFOB(fd,14+NAME_LENGTH));
return 1;
}

View File

@ -37,7 +37,7 @@ int intif_request_partyinfo(int party_id, uint32 char_id);
int intif_party_addmember(int party_id,struct party_member *member);
int intif_party_changeoption(int party_id, uint32 account_id, int exp, int item);
int intif_party_leave(int party_id,uint32 account_id, uint32 char_id);
int intif_party_leave(int party_id, uint32 account_id, uint32 char_id, char *name, enum e_party_member_withdraw type);
int intif_party_changemap(struct map_session_data *sd, int online);
int intif_break_party(int party_id);
int intif_party_message(int party_id, uint32 account_id, const char *mes,int len);

View File

@ -87,7 +87,7 @@ static TBL_PC* party_sd_check(int party_id, uint32 account_id, uint32 char_id)
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);
intif_party_leave(party_id,account_id,char_id,sd->status.name,PARTY_MEMBER_WITHDRAW_LEAVE);
return NULL;
}
@ -165,7 +165,7 @@ void party_created(uint32 account_id,uint32 char_id,int fail,int party_id,char *
if (!sd || sd->status.char_id != char_id || !sd->party_creating ) { // Character logged off before creation ack?
if (!fail) // break up party since player could not be added to it.
intif_party_leave(party_id,account_id,char_id);
intif_party_leave(party_id,account_id,char_id,"",PARTY_MEMBER_WITHDRAW_LEAVE);
return;
}
@ -309,7 +309,7 @@ int party_recv_info(struct party* sp, uint32 char_id)
if( sd == NULL )
continue; // not online
party_member_withdraw(sp->party_id, sd->status.account_id, sd->status.char_id);
party_member_withdraw(sp->party_id, sd->status.account_id, sd->status.char_id, sd->status.name, PARTY_MEMBER_WITHDRAW_LEAVE);
}
memcpy(&p->party, sp, sizeof(struct party));
@ -488,7 +488,7 @@ int party_member_added(int party_id,uint32 account_id,uint32 char_id, int flag)
if(sd == NULL || sd->status.char_id != char_id || !sd->party_joining ) {
if (!flag) //Char logged off before being accepted into party.
intif_party_leave(party_id,account_id,char_id);
intif_party_leave(party_id,account_id,char_id,"",PARTY_MEMBER_WITHDRAW_LEAVE);
return 0;
}
@ -500,7 +500,7 @@ int party_member_added(int party_id,uint32 account_id,uint32 char_id, int flag)
if (!p) {
ShowError("party_member_added: party %d not found.\n",party_id);
intif_party_leave(party_id,account_id,char_id);
intif_party_leave(party_id,account_id,char_id,"",PARTY_MEMBER_WITHDRAW_LEAVE);
return 0;
}
@ -559,7 +559,7 @@ int party_removemember(struct map_session_data* sd, uint32 account_id, char* nam
return 0; // no such char in party
party_trade_bound_cancel(sd);
intif_party_leave(p->party.party_id,account_id,p->party.member[i].char_id);
intif_party_leave(p->party.party_id,account_id,p->party.member[i].char_id,p->party.member[i].name,PARTY_MEMBER_WITHDRAW_EXPEL);
return 1;
}
@ -571,7 +571,7 @@ int party_removemember2(struct map_session_data *sd,uint32 char_id,int party_id)
return -3;
party_trade_bound_cancel(sd);
intif_party_leave(sd->status.party_id,sd->status.account_id,sd->status.char_id);
intif_party_leave(sd->status.party_id,sd->status.account_id,sd->status.char_id,sd->status.name,PARTY_MEMBER_WITHDRAW_EXPEL);
return 1;
} else {
int i;
@ -583,7 +583,7 @@ int party_removemember2(struct map_session_data *sd,uint32 char_id,int party_id)
ARR_FIND(0,MAX_PARTY,i,p->party.member[i].char_id == char_id );
if( i >= MAX_PARTY )
return -1;
intif_party_leave(party_id,p->party.member[i].account_id,char_id);
intif_party_leave(party_id,p->party.member[i].account_id,char_id,p->party.member[i].name,PARTY_MEMBER_WITHDRAW_EXPEL);
return 1;
}
}
@ -604,21 +604,21 @@ int party_leave(struct map_session_data *sd)
return 0;
party_trade_bound_cancel(sd);
intif_party_leave(p->party.party_id,sd->status.account_id,sd->status.char_id);
intif_party_leave(p->party.party_id,sd->status.account_id,sd->status.char_id,sd->status.name,PARTY_MEMBER_WITHDRAW_LEAVE);
return 1;
}
/// Invoked (from char-server) when a party member leaves the party.
int party_member_withdraw(int party_id, uint32 account_id, uint32 char_id)
int party_member_withdraw(int party_id, uint32 account_id, uint32 char_id, char *name, enum e_party_member_withdraw type)
{
struct map_session_data* sd = map_id2sd(account_id);
struct map_session_data* sd = map_charid2sd(char_id);
struct party_data* p = party_search(party_id);
if( p ) {
int i;
clif_party_withdraw(party_getavailablesd(p), account_id, name, type, PARTY);
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_withdraw(p,sd,account_id,p->party.member[i].name,0x0);
memset(&p->party.member[i], 0, sizeof(p->party.member[0]));
memset(&p->data[i], 0, sizeof(p->data[0]));
p->party.count--;
@ -626,7 +626,7 @@ int party_member_withdraw(int party_id, uint32 account_id, uint32 char_id)
}
}
if( sd && sd->status.party_id == party_id && sd->status.char_id == char_id ) {
if( sd && sd->status.party_id == party_id ) {
#ifdef BOUND_ITEMS
int idxlist[MAX_INVENTORY]; //or malloc to reduce consumtion
int j,i;
@ -673,7 +673,7 @@ int party_broken(int party_id)
for( i = 0; i < MAX_PARTY; i++ ) {
if( p->data[i].sd != NULL ) {
clif_party_withdraw(p,p->data[i].sd,p->party.member[i].account_id,p->party.member[i].name,0x10);
clif_party_withdraw(p->data[i].sd,p->party.member[i].account_id,p->party.member[i].name,PARTY_MEMBER_WITHDRAW_EXPEL,SELF);
p->data[i].sd->status.party_id=0;
}
}

View File

@ -65,7 +65,7 @@ int party_member_added(int party_id,uint32 account_id,uint32 char_id,int flag);
int party_leave(struct map_session_data *sd);
int party_removemember(struct map_session_data *sd,uint32 account_id,char *name);
int party_removemember2(struct map_session_data *sd,uint32 char_id,int party_id);
int party_member_withdraw(int party_id,uint32 account_id,uint32 char_id);
int party_member_withdraw(int party_id, uint32 account_id, uint32 char_id, char *name, enum e_party_member_withdraw type);
int party_reply_invite(struct map_session_data *sd,int party_id,int flag);
#define party_add_member(party_id,sd) party_reply_invite(sd,party_id,1)
int party_recv_noinfo(int party_id, uint32 char_id);

View File

@ -20591,9 +20591,9 @@ BUILDIN_FUNC(party_destroy)
for( j = 0; j < MAX_PARTY; j++ ) {
TBL_PC *sd = party->data[j].sd;
if(sd)
party_member_withdraw(party->party.party_id,sd->status.account_id,sd->status.char_id);
party_member_withdraw(party->party.party_id,sd->status.account_id,sd->status.char_id,sd->status.name,PARTY_MEMBER_WITHDRAW_LEAVE);
else if( party->party.member[j].char_id )
intif_party_leave(party->party.party_id,party->party.member[j].account_id,party->party.member[j].char_id);
intif_party_leave(party->party.party_id,party->party.member[j].account_id,party->party.member[j].char_id,party->party.member[j].name,PARTY_MEMBER_WITHDRAW_LEAVE);
}
party_broken(party->party.party_id);
script_pushint(st,1);