From 34eb4be25b51f534759769323be9011ec437aa3c Mon Sep 17 00:00:00 2001 From: Lemongrass3110 Date: Wed, 12 Jun 2024 15:39:24 +0200 Subject: [PATCH] Preparatory cleanup of parties (#8418) --- src/common/mmo.hpp | 4 +- src/map/atcommand.cpp | 2 +- src/map/clif.cpp | 124 ++++++++-------- src/map/clif.hpp | 2 +- src/map/clif_packetdb.hpp | 12 +- src/map/packets.hpp | 38 +++++ src/map/party.cpp | 294 +++++++++++++++++++++----------------- src/map/party.hpp | 14 +- src/map/pc.cpp | 2 +- src/map/script.cpp | 6 +- src/map/unit.cpp | 2 +- 11 files changed, 284 insertions(+), 216 deletions(-) diff --git a/src/common/mmo.hpp b/src/common/mmo.hpp index 4a00641239..819d1472be 100644 --- a/src/common/mmo.hpp +++ b/src/common/mmo.hpp @@ -1123,8 +1123,8 @@ enum e_pc_reg_loading { 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 + PARTY_MEMBER_WITHDRAW_CANT_LEAVE, ///< Cannot /leave + PARTY_MEMBER_WITHDRAW_CANT_EXPEL, ///< Cannot be kicked }; enum e_rank { diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp index 5858508796..ef821c6487 100644 --- a/src/map/atcommand.cpp +++ b/src/map/atcommand.cpp @@ -3813,7 +3813,7 @@ ACMD_FUNC(party) return -1; } - party_create(sd, party, 0, 0); + party_create( *sd, party, 0, 0 ); return 0; } diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 2cee6cf7e8..950988e6c8 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -12371,7 +12371,6 @@ void clif_noask_sub( map_session_data& sd, map_session_data& tsd, int type ){ clif_messagecolor( &tsd.bl, color_table[COLOR_LIGHT_GREEN], output, false, SELF); } - /// Request to begin a trade (CZ_REQ_EXCHANGE_ITEM). /// 00e4 .L void clif_parse_TradeRequest(int fd,map_session_data *sd) @@ -13625,7 +13624,7 @@ void clif_parse_CreateParty(int fd, map_session_data *sd){ return; } - party_create(sd,name,0,0); + party_create( *sd, name, 0, 0 ); } /// 01e8 .24B .B .B (CZ_MAKE_GROUP2) @@ -13649,97 +13648,97 @@ void clif_parse_CreateParty2(int fd, map_session_data *sd){ return; } - party_create(sd,name,item1,item2); + party_create( *sd, name, item1, item2 ); } -/// Party invitation request +/// Party invitation request by account id /// 00fc .L (CZ_REQ_JOIN_GROUP) -void clif_parse_PartyInvite(int fd, map_session_data *sd) -{ - map_session_data *t_sd; - - if(map_getmapflag(sd->bl.m, MF_PARTYLOCK)) {// Party locked. - clif_displaymessage(fd, msg_txt(sd,227)); +void clif_parse_PartyInvite( int fd, map_session_data *sd ){ + if( sd == nullptr ){ return; } - t_sd = map_id2sd(RFIFOL(fd,packet_db[RFIFOW(fd,0)].pos[0])); + PACKET_CZ_REQ_JOIN_GROUP* p = reinterpret_cast( RFIFOP( fd, 0 ) ); - if(t_sd && t_sd->state.noask) {// @noask [LuzZza] - clif_noask_sub( *sd, *t_sd, 394 ); // Autorejected party invite from %s. - return; - } - - party_invite(sd, t_sd); + party_invite( *sd, map_id2sd( p->AID ) ); } +/// Party invitation request by name /// 02c4 .24B (CZ_PARTY_JOIN_REQ) -void clif_parse_PartyInvite2(int fd, map_session_data *sd){ - map_session_data *t_sd; - char *name = RFIFOCP(fd,packet_db[RFIFOW(fd,0)].pos[0]); - name[NAME_LENGTH-1] = '\0'; - - if(map_getmapflag(sd->bl.m, MF_PARTYLOCK)) {// Party locked. - clif_displaymessage(fd, msg_txt(sd,227)); +void clif_parse_PartyInvite2( int fd, map_session_data *sd ){ +#if PACKETVER >= 20070227 + if( sd == nullptr ){ return; } - t_sd = map_nick2sd(name,false); + PACKET_CZ_PARTY_JOIN_REQ* p = reinterpret_cast( RFIFOP( fd, 0 ) ); - if(t_sd && t_sd->state.noask) {// @noask [LuzZza] - clif_noask_sub( *sd, *t_sd, 394 ); // Autorejected party invite from %s. - return; - } + char name[NAME_LENGTH]; - party_invite(sd, t_sd); + safestrncpy( name, p->name, sizeof( name ) ); + + party_invite( *sd, map_nick2sd( name, false ) ); +#endif } /// Party invitation reply /// 00ff .L .L (CZ_JOIN_GROUP) +/// flag: +/// 0 = reject +/// 1 = accept +void clif_parse_ReplyPartyInvite( int fd, map_session_data *sd ){ + if( sd == nullptr ){ + return; + } + + PACKET_CZ_JOIN_GROUP* p = reinterpret_cast( RFIFOP( fd, 0 ) ); + + party_reply_invite( *sd, p->party_id, p->flag ); +} + +/// Party invitation reply /// 02c7 .L .B (CZ_PARTY_JOIN_REQ_ACK) /// flag: /// 0 = reject /// 1 = accept -void clif_parse_ReplyPartyInvite(int fd,map_session_data *sd) -{ - struct s_packet_db* info = &packet_db[RFIFOW(fd,0)]; - party_reply_invite(sd,RFIFOL(fd,info->pos[0]), - RFIFOL(fd,info->pos[1])); -} -//(CZ_PARTY_JOIN_REQ_ACK) -void clif_parse_ReplyPartyInvite2(int fd,map_session_data *sd) -{ - struct s_packet_db* info = &packet_db[RFIFOW(fd,0)]; - party_reply_invite(sd,RFIFOL(fd,info->pos[0]), - RFIFOB(fd,info->pos[1])); -} - - -/// Request to leave party (CZ_REQ_LEAVE_GROUP). -/// 0100 -void clif_parse_LeaveParty(int fd, map_session_data *sd) -{ - if(map_getmapflag(sd->bl.m, MF_PARTYLOCK)) {// Party locked. - clif_displaymessage(fd, msg_txt(sd,227)); +void clif_parse_ReplyPartyInvite2( int fd, map_session_data *sd ){ +#if PACKETVER >= 20070227 + if( sd == nullptr ){ return; } - party_leave(sd); + + PACKET_CZ_PARTY_JOIN_REQ_ACK* p = reinterpret_cast( RFIFOP( fd, 0 ) ); + + party_reply_invite( *sd, p->party_id, p->flag ); +#endif } -/// Request to expel a party member (CZ_REQ_EXPEL_GROUP_MEMBER). -/// 0103 .L .24B -void clif_parse_RemovePartyMember(int fd, map_session_data *sd) -{ - struct s_packet_db* info = &packet_db[RFIFOW(fd,0)]; - if(map_getmapflag(sd->bl.m, MF_PARTYLOCK)) {// Party locked. - clif_displaymessage(fd, msg_txt(sd,227)); +/// Request to leave party. +/// 0100 (CZ_REQ_LEAVE_GROUP) +void clif_parse_LeaveParty( int fd, map_session_data *sd ){ + if( sd == nullptr ){ return; } - party_removemember(sd,RFIFOL(fd,info->pos[0]), - RFIFOCP(fd,info->pos[1])); + + //PACKET_CZ_REQ_LEAVE_GROUP* p = reinterpret_cast( RFIFOP( fd, 0 ) ); + + party_leave( *sd, true ); +} + + +/// Request to expel a party member. +/// 0103 .L .24B (CZ_REQ_EXPEL_GROUP_MEMBER) +void clif_parse_RemovePartyMember( int fd, map_session_data* sd ){ + if( sd == nullptr ){ + return; + } + + PACKET_CZ_REQ_EXPEL_GROUP_MEMBER* p = reinterpret_cast( RFIFOP( fd, 0 ) ); + + party_removemember( *sd, p->AID, p->name ); } @@ -17488,6 +17487,7 @@ void clif_parse_configuration( int fd, map_session_data* sd ){ } /// Request to change party invitation tick. +/// 02C8 .B (CZ_PARTY_CONFIG) /// value: /// 0 = disabled (triggered by /accept) /// 1 = enabled (triggered by /refuse) @@ -25043,7 +25043,7 @@ void clif_parse_partybooking_reply( int fd, map_session_data* sd ){ } if( p->accept ){ - party_join( tsd, sd->status.party_id ); + party_join( *tsd, sd->status.party_id ); } clif_partybooking_reply( tsd, sd, p->accept ); diff --git a/src/map/clif.hpp b/src/map/clif.hpp index 6ceb11b641..d7d931d3ce 100644 --- a/src/map/clif.hpp +++ b/src/map/clif.hpp @@ -158,7 +158,7 @@ enum e_party_invite_reply { PARTY_REPLY_ACCEPTED, ///< result=2 : "Request for party accepted." -> MsgStringTable[82] PARTY_REPLY_FULL, ///< result=3 : "Party Capacity exceeded." -> MsgStringTable[83] PARTY_REPLY_DUAL, ///< result=4 : "Character in the same account already joined." -> MsgStringTable[608] - PARTY_REPLY_JOINMSG_REFUSE, ///< result=5 : !TODO "The character blocked the party invitation." -> MsgStringTable[1324] (since 20070904) + PARTY_REPLY_JOINMSG_REFUSE, ///< result=5 : "The character blocked the party invitation." -> MsgStringTable[1324] (since 20070904) PARTY_REPLY_UNKNOWN_ERROR, ///< result=6 : ?? PARTY_REPLY_OFFLINE, ///< result=7 : "The Character is not currently online or does not exist." -> MsgStringTable[71] (since 20070904) PARTY_REPLY_INVALID_MAPPROPERTY, ///< result=8 : !TODO "Unable to organize a party in this map" -> MsgStringTable[1388] (since 20080527) diff --git a/src/map/clif_packetdb.hpp b/src/map/clif_packetdb.hpp index bb619b4625..856a222471 100644 --- a/src/map/clif_packetdb.hpp +++ b/src/map/clif_packetdb.hpp @@ -118,13 +118,13 @@ parseable_packet(0x00f7,2,clif_parse_CloseKafra,0); parseable_packet(0x00f9,26,clif_parse_CreateParty,2); packet(0x00fb,-1); - parseable_packet(0x00fc,6,clif_parse_PartyInvite,2); + parseable_packet( HEADER_CZ_REQ_JOIN_GROUP, sizeof( PACKET_CZ_REQ_JOIN_GROUP ), clif_parse_PartyInvite, 0 ); packet(0x00fd,27); - parseable_packet(0x00ff,10,clif_parse_ReplyPartyInvite,2,6); - parseable_packet(0x0100,2,clif_parse_LeaveParty,0); + parseable_packet( HEADER_CZ_JOIN_GROUP, sizeof( PACKET_CZ_JOIN_GROUP ), clif_parse_ReplyPartyInvite, 0 ); + parseable_packet( HEADER_CZ_REQ_LEAVE_GROUP, sizeof( PACKET_CZ_REQ_LEAVE_GROUP ), clif_parse_LeaveParty, 0 ); packet(0x0101,6); parseable_packet(0x0102,6,clif_parse_PartyChangeOption,2); - parseable_packet(0x0103,30,clif_parse_RemovePartyMember,2,6); + parseable_packet( HEADER_CZ_REQ_EXPEL_GROUP_MEMBER, sizeof( PACKET_CZ_REQ_EXPEL_GROUP_MEMBER ), clif_parse_RemovePartyMember, 0 ); packet(0x0104,79); parseable_packet(0x0108,-1,clif_parse_PartyMessage,2,4); packet(0x0109,-1); @@ -987,9 +987,9 @@ packet(0x02c0,2); packet(0x02c1,-1); packet(0x02c2,-1); - parseable_packet(0x02c4,26,clif_parse_PartyInvite2,2); + parseable_packet( HEADER_CZ_PARTY_JOIN_REQ, sizeof( PACKET_CZ_PARTY_JOIN_REQ ), clif_parse_PartyInvite2, 0 ); packet(0x02c5,30); - parseable_packet(0x02c7,7,clif_parse_ReplyPartyInvite2,2,6); + parseable_packet( HEADER_CZ_PARTY_JOIN_REQ_ACK, sizeof( PACKET_CZ_PARTY_JOIN_REQ_ACK ), clif_parse_ReplyPartyInvite2, 0 ); parseable_packet( HEADER_CZ_PARTY_CONFIG, sizeof( PACKET_CZ_PARTY_CONFIG ), clif_parse_PartyTick, 0 ); packet(0x02ca,3); packet(0x02cb,20); diff --git a/src/map/packets.hpp b/src/map/packets.hpp index e364600a6e..8e577ba15d 100644 --- a/src/map/packets.hpp +++ b/src/map/packets.hpp @@ -1116,6 +1116,44 @@ struct PACKET_CZ_REQ_JOIN_GUILD2{ } __attribute__((packed)); DEFINE_PACKET_HEADER(CZ_REQ_JOIN_GUILD2, 0x916); +struct PACKET_CZ_REQ_JOIN_GROUP{ + int16 packetType; + uint32 AID; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(CZ_REQ_JOIN_GROUP, 0xfc); + +struct PACKET_CZ_JOIN_GROUP{ + int16 packetType; + uint32 party_id; + int32 flag; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(CZ_JOIN_GROUP, 0xff); + +struct PACKET_CZ_REQ_LEAVE_GROUP{ + int16 packetType; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(CZ_REQ_LEAVE_GROUP, 0x100); + +struct PACKET_CZ_REQ_EXPEL_GROUP_MEMBER{ + int16 packetType; + uint32 AID; + char name[NAME_LENGTH]; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(CZ_REQ_EXPEL_GROUP_MEMBER, 0x103); + +struct PACKET_CZ_PARTY_JOIN_REQ{ + int16 packetType; + char name[NAME_LENGTH]; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(CZ_PARTY_JOIN_REQ, 0x2c4); + +struct PACKET_CZ_PARTY_JOIN_REQ_ACK{ + int16 packetType; + uint32 party_id; + uint8 flag; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(CZ_PARTY_JOIN_REQ_ACK, 0x2c7); + // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute #if !defined( sun ) && ( !defined( __NETBSD__ ) || __NetBSD_Version__ >= 600000000 ) #pragma pack( pop ) diff --git a/src/map/party.cpp b/src/map/party.cpp index f958e8585d..e3ad127873 100644 --- a/src/map/party.cpp +++ b/src/map/party.cpp @@ -10,7 +10,7 @@ #include #include #include -#include // last_tick +#include // last_tick, session_isActive #include #include #include @@ -40,16 +40,15 @@ int party_create_byscript; * 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, map_session_data* sd, unsigned int leader) -{ - member->account_id = sd->status.account_id; - member->char_id = sd->status.char_id; - safestrncpy(member->name, sd->status.name, NAME_LENGTH); - member->class_ = sd->status.class_; - safestrncpy( member->map, mapindex_id2name( sd->mapindex ), sizeof( member->map ) ); - member->lv = sd->status.base_level; - member->online = 1; - member->leader = leader; +static void party_fill_member( struct party_member& member, map_session_data& sd, unsigned int leader ){ + member.account_id = sd.status.account_id; + member.char_id = sd.status.char_id; + safestrncpy(member.name, sd.status.name, NAME_LENGTH); + member.class_ = sd.status.class_; + safestrncpy( member.map, mapindex_id2name( sd.mapindex ), sizeof( member.map ) ); + member.lv = sd.status.base_level; + member.online = 1; + member.leader = leader; } /// Get the member_id of a party member. @@ -142,9 +141,8 @@ struct party_data* party_searchname(const char* str) return p; } -int party_create(map_session_data *sd,char *name,int item,int item2) -{ - struct party_member leader; +int party_create( map_session_data& sd, char *name, int item, int item2 ){ + struct party_member leader = {}; char tname[NAME_LENGTH]; safestrncpy(tname, name, NAME_LENGTH); @@ -153,14 +151,16 @@ int party_create(map_session_data *sd,char *name,int item,int item2) if( !tname[0] ) // empty name return 0; - if( sd->status.party_id > 0 || sd->party_joining || sd->party_creating ) { // already associated with a party - clif_party_created( *sd, 2 ); + // already associated with a party + if( sd.status.party_id > 0 || sd.party_joining || sd.party_creating ){ + clif_party_created( sd, 2 ); return -2; } - sd->party_creating = true; - party_fill_member(&leader, sd, 1); + sd.party_creating = true; + party_fill_member( leader, sd, 1 ); intif_create_party(&leader,name,item,item2); + return 1; } @@ -202,13 +202,10 @@ int party_request_info(int party_id, uint32 char_id) * Close trade window if party member is kicked when trade a party bound item * @param sd **/ -static void party_trade_bound_cancel(map_session_data *sd) { +static void party_trade_bound_cancel( map_session_data& sd ){ #ifdef BOUND_ITEMS - nullpo_retv(sd); - if (sd->state.isBoundTrading&(1<status.party_id) ) == nullptr ) - return 0; - - // confirm if this player is a party leader - ARR_FIND(0, MAX_PARTY, i, p->data[i].sd == sd); - - if( i == MAX_PARTY || !p->party.member[i].leader ) { - clif_displaymessage(sd->fd, msg_txt(sd,282)); - return 0; + if( p == nullptr ){ + return false; } - if (tsd && battle_config.block_account_in_same_party) { + int i; + + // confirm if this player is a party leader + ARR_FIND( 0, MAX_PARTY, i, p->data[i].sd == &sd ); + + if( i == MAX_PARTY || !p->party.member[i].leader ) { + clif_displaymessage( sd.fd, msg_txt( &sd, 282 ) ); + return false; + } + + // Party locked. + if( map_getmapflag( sd.bl.m, MF_PARTYLOCK ) ){ + clif_displaymessage( sd.fd, msg_txt( &sd, 227 ) ); + return false; + } + + if( tsd == NULL ){ + clif_party_invite_reply( sd, "", PARTY_REPLY_OFFLINE ); + return false; + } + + if( tsd->status.disable_partyinvite ){ + clif_party_invite_reply( sd, tsd->status.name, PARTY_REPLY_JOINMSG_REFUSE ); + return false; + } + + // @noask [LuzZza] + if( tsd->state.noask ){ + clif_noask_sub( sd, *tsd, 394 ); // Autorejected party invite from %s. + return false; + } + + if( battle_config.block_account_in_same_party ){ ARR_FIND(0, MAX_PARTY, i, p->party.member[i].account_id == tsd->status.account_id); if (i < MAX_PARTY) { - clif_party_invite_reply( *sd, tsd->status.name, PARTY_REPLY_DUAL ); - return 0; + clif_party_invite_reply( sd, tsd->status.name, PARTY_REPLY_DUAL ); + return false; } } @@ -413,44 +431,39 @@ int party_invite(map_session_data *sd,map_session_data *tsd) ARR_FIND(0, MAX_PARTY, i, p->party.member[i].account_id == 0); if( i == MAX_PARTY ) { - clif_party_invite_reply( *sd, ( tsd ? tsd->status.name : "" ), PARTY_REPLY_FULL ); - return 0; + clif_party_invite_reply( sd, tsd->status.name, PARTY_REPLY_FULL ); + return false; } // confirm whether the account has the ability to invite before checking the player - if( !pc_has_permission(sd, PC_PERM_PARTY) || (tsd && !pc_has_permission(tsd, PC_PERM_PARTY)) ) { - clif_displaymessage(sd->fd, msg_txt(sd,81)); // "Your GM level doesn't authorize you to perform this action on the specified player." - return 0; + if( !pc_has_permission( &sd, PC_PERM_PARTY ) || !pc_has_permission( tsd, PC_PERM_PARTY ) ) { + clif_displaymessage( sd.fd, msg_txt( &sd, 81 ) ); // Your GM level doesn't authorize you to perform this action on the specified player. + return false; } - if( tsd == nullptr) { - clif_party_invite_reply( *sd, "", PARTY_REPLY_OFFLINE ); - return 0; + if( !battle_config.invite_request_check && ( tsd->guild_invite > 0 || tsd->trade_partner || tsd->adopt_invite ) ){ + clif_party_invite_reply( sd, tsd->status.name, PARTY_REPLY_JOIN_OTHER_PARTY ); + return false; } - if(!battle_config.invite_request_check) { - if (tsd->guild_invite>0 || tsd->trade_partner || tsd->adopt_invite) { - clif_party_invite_reply( *sd, tsd->status.name, PARTY_REPLY_JOIN_OTHER_PARTY ); - return 0; - } + // You can't invite someone who has already disconnected. + if( !session_isActive( tsd->fd ) ){ + clif_party_invite_reply( sd, tsd->status.name, PARTY_REPLY_REJECTED ); + return false; } - if (!tsd->fd) { //You can't invite someone who has already disconnected. - clif_party_invite_reply( *sd, tsd->status.name, PARTY_REPLY_REJECTED ); - return 0; + // Already associated with a party + if( tsd->status.party_id > 0 || tsd->party_invite > 0 ){ + clif_party_invite_reply( sd, tsd->status.name, PARTY_REPLY_JOIN_OTHER_PARTY ); + return false; } - if( tsd->status.party_id > 0 || tsd->party_invite > 0 ) - {// already associated with a party - clif_party_invite_reply( *sd, tsd->status.name, PARTY_REPLY_JOIN_OTHER_PARTY ); - return 0; - } + tsd->party_invite = sd.status.party_id; + tsd->party_invite_account = sd.status.account_id; - tsd->party_invite=sd->status.party_id; - tsd->party_invite_account=sd->status.account_id; + clif_party_invite( sd, *tsd ); - clif_party_invite( *sd, *tsd ); - return 1; + return true; } bool party_isleader( map_session_data* sd ){ @@ -477,16 +490,14 @@ bool party_isleader( map_session_data* sd ){ return false; } -void party_join( map_session_data* sd, int party_id ){ - nullpo_retv( sd ); - +void party_join( map_session_data& sd, int party_id ){ // Player is in a party already now - if( sd->status.party_id != 0 ){ + if( sd.status.party_id != 0 ){ return; } // Player is already associated with a party - if( sd->party_creating || sd->party_joining ){ + if( sd.party_creating || sd.party_joining ){ return; } @@ -499,7 +510,7 @@ void party_join( map_session_data* sd, int party_id ){ int i; if( battle_config.block_account_in_same_party ){ - ARR_FIND( 0, MAX_PARTY, i, party->party.member[i].account_id == sd->status.account_id ); + ARR_FIND( 0, MAX_PARTY, i, party->party.member[i].account_id == sd.status.account_id ); if( i < MAX_PARTY ){ // Player is in the party with a different character already @@ -517,8 +528,8 @@ void party_join( map_session_data* sd, int party_id ){ struct party_member member = {}; - sd->party_joining = true; - party_fill_member( &member, sd, 0 ); + sd.party_joining = true; + party_fill_member( member, sd, 0 ); intif_party_addmember( party_id, &member ); } @@ -552,63 +563,66 @@ bool party_booking_load( uint32 account_id, uint32 char_id, struct s_party_booki return true; } -int party_reply_invite(map_session_data *sd,int party_id,int flag) -{ - map_session_data* tsd; - struct party_member member; - - if( sd->party_invite != party_id ) { // forged - sd->party_invite = 0; - sd->party_invite_account = 0; - return 0; +bool party_reply_invite( map_session_data& sd, int party_id, int flag ){ + // forged + if( sd.party_invite != party_id ) { + sd.party_invite = 0; + sd.party_invite_account = 0; + return false; } // The character is already in a party, possibly left a party invite open and created his own party - if( sd->status.party_id != 0 ){ + if( sd.status.party_id != 0 ){ // On Aegis no rejection packet is sent to the inviting player - sd->party_invite = 0; - sd->party_invite_account = 0; - return 0; + sd.party_invite = 0; + sd.party_invite_account = 0; + return false; } - tsd = map_id2sd(sd->party_invite_account); + // accepted and allowed + if( flag == 1 && !sd.party_creating && !sd.party_joining ) { + struct party_data* party = party_search( party_id ); + struct party_member member = {}; - if( flag == 1 && !sd->party_creating && !sd->party_joining ) { // accepted and allowed - sd->party_joining = true; - party_fill_member(&member, sd, 0); - intif_party_addmember(sd->party_invite, &member); - return 1; - } else { // rejected or failure - sd->party_invite = 0; - sd->party_invite_account = 0; + sd.party_joining = true; + party_fill_member( member, sd, 0 ); + intif_party_addmember( sd.party_invite, &member ); - if( tsd != nullptr ) - clif_party_invite_reply( *tsd, sd->status.name, PARTY_REPLY_REJECTED ); + return true; } - return 0; + // rejected or failure + map_session_data* tsd = map_id2sd( sd.party_invite_account ); + + sd.party_invite = 0; + sd.party_invite_account = 0; + + if( tsd != nullptr ) { + clif_party_invite_reply( *tsd, sd.status.name, PARTY_REPLY_REJECTED ); + } + + return false; } //Invoked when a player joins: //- Loads up party data if not in server //- Sets up the pointer to him //- Player must be authed/active and belong to a party before calling this method -void party_member_joined(map_session_data *sd) -{ - struct party_data* p = party_search(sd->status.party_id); +void party_member_joined( map_session_data& sd ){ + struct party_data* p = party_search( sd.status.party_id ); int i; if (!p) { - party_request_info(sd->status.party_id, sd->status.char_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 ); + 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) { - p->data[i].sd = sd; + p->data[i].sd = &sd; } else - sd->status.party_id = 0; //He does not belongs to the party really? + sd.status.party_id = 0; //He does not belongs to the party really? } /// Invoked (from char-server) when a new member is added to the party. @@ -670,31 +684,35 @@ int party_member_added(int party_id,uint32 account_id,uint32 char_id, int flag) } /// Party member 'sd' requesting kick of member with . -int party_removemember(map_session_data* sd, uint32 account_id, char* name) -{ - struct party_data *p; - int i; +bool party_removemember( map_session_data& sd, uint32 account_id, char* name ){ + // Party locked. + if( map_getmapflag( sd.bl.m, MF_PARTYLOCK ) ){ + clif_displaymessage( sd.fd, msg_txt( &sd, 227 ) ); + return false; + } - p = party_search(sd->status.party_id); + struct party_data* p = party_search( sd.status.party_id ); if( p == nullptr ) - return 0; + return false; + + int i; // 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 ); + 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 + return false; // request from someone not in party? o.O if( !p->party.member[i].leader ) - return 0; // only party leader may remove members + return false; // 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 + return false; // 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,p->party.member[i].name,PARTY_MEMBER_WITHDRAW_EXPEL); - return 1; + return true; } int party_removemember2(map_session_data *sd,uint32 char_id,int party_id) @@ -703,7 +721,7 @@ int party_removemember2(map_session_data *sd,uint32 char_id,int party_id) if( !sd->status.party_id ) return -3; - party_trade_bound_cancel(sd); + party_trade_bound_cancel( *sd ); 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 { @@ -722,23 +740,35 @@ int party_removemember2(map_session_data *sd,uint32 char_id,int party_id) } /// Party member 'sd' requesting exit from party. -int party_leave(map_session_data *sd) -{ - struct party_data *p; +bool party_leave( map_session_data& sd, bool showMessage ){ + // Party locked. + if( map_getmapflag( sd.bl.m, MF_PARTYLOCK ) ){ + // If it was not triggered by the user itself, but from a script for example + if( showMessage ){ + clif_displaymessage( sd.fd, msg_txt( &sd,227 ) ); + } + + return false; + } + + struct party_data* p = party_search( sd.status.party_id ); + + if( p == nullptr ){ + return false; + } + int i; - p = party_search(sd->status.party_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 ); - if( p == nullptr ) - return 0; + if( i == MAX_PARTY ){ + return false; + } - 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; + party_trade_bound_cancel( sd ); + intif_party_leave( p->party.party_id, sd.status.account_id, sd.status.char_id, sd.status.name, PARTY_MEMBER_WITHDRAW_LEAVE ); - party_trade_bound_cancel(sd); - intif_party_leave(p->party.party_id,sd->status.account_id,sd->status.char_id,sd->status.name,PARTY_MEMBER_WITHDRAW_LEAVE); - return 1; + return true; } /// Invoked (from char-server) when a party member leaves the party. @@ -769,7 +799,7 @@ int party_member_withdraw(int party_id, uint32 account_id, uint32 char_id, char int idxlist[MAX_INVENTORY]; //or malloc to reduce consumtion int j,i; - party_trade_bound_cancel(sd); + party_trade_bound_cancel( *sd ); j = pc_bound_chk(sd,BOUND_PARTY,idxlist); for(i = 0; i < j; i++) diff --git a/src/map/party.hpp b/src/map/party.hpp index c3faf48649..da197f3ffc 100644 --- a/src/map/party.hpp +++ b/src/map/party.hpp @@ -62,20 +62,20 @@ struct party_data* party_searchname(const char* str); int party_getmemberid(struct party_data* p, map_session_data* sd); map_session_data* party_getavailablesd(struct party_data *p); -int party_create(map_session_data *sd,char *name, int item, int item2); +int party_create( map_session_data& sd, char *name, int item, int item2 ); void party_created(uint32 account_id,uint32 char_id,int fail,int party_id,char *name); int party_request_info(int party_id, uint32 char_id); -int party_invite(map_session_data *sd,map_session_data *tsd); -void party_member_joined(map_session_data *sd); +bool party_invite( map_session_data& sd, map_session_data* tsd ); +void party_member_joined( map_session_data& sd ); int party_member_added(int party_id,uint32 account_id,uint32 char_id,int flag); -int party_leave(map_session_data *sd); -int party_removemember(map_session_data *sd,uint32 account_id,char *name); +bool party_leave( map_session_data& sd, bool showMessage = false ); +bool party_removemember( map_session_data& sd, uint32 account_id, char *name ); int party_removemember2(map_session_data *sd,uint32 char_id,int party_id); int party_member_withdraw(int party_id, uint32 account_id, uint32 char_id, char *name, enum e_party_member_withdraw type); bool party_isleader( map_session_data* sd ); -void party_join( map_session_data* sd, int party_id ); +void party_join( map_session_data& sd, int party_id ); bool party_booking_load( uint32 account_id, uint32 char_id, struct s_party_booking_requirement* booking ); -int party_reply_invite(map_session_data *sd,int party_id,int flag); +bool party_reply_invite( 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); int party_recv_info(struct party* sp, uint32 char_id); diff --git a/src/map/pc.cpp b/src/map/pc.cpp index 5b723dd8cb..14a1d7641d 100755 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -2384,7 +2384,7 @@ void pc_reg_received(map_session_data *sd) } if (sd->status.party_id > 0) - party_member_joined(sd); + party_member_joined( *sd ); if (sd->status.guild_id > 0) guild_member_joined(sd); if (sd->status.clan_id > 0) diff --git a/src/map/script.cpp b/src/map/script.cpp index e3cdc79453..56c9bf24ba 100644 --- a/src/map/script.cpp +++ b/src/map/script.cpp @@ -23161,7 +23161,7 @@ BUILDIN_FUNC(party_create) item2 = 1; party_create_byscript = 1; - script_pushint(st,party_create(sd,party_name,item1,item2)); + script_pushint( st, party_create( *sd, party_name, item1, item2 ) ); return SCRIPT_CMD_SUCCESS; } @@ -23213,7 +23213,7 @@ BUILDIN_FUNC(party_addmember) return SCRIPT_CMD_FAILURE; } sd->party_invite = party_id; - script_pushint(st,party_add_member(party_id,sd)); + script_pushint( st, party_add_member( party_id, *sd ) ); return SCRIPT_CMD_SUCCESS; } @@ -23336,7 +23336,7 @@ BUILDIN_FUNC(party_destroy) script_pushint(st,1); } else //leader leave = party broken - script_pushint(st,party_leave(party->data[i].sd)); + script_pushint( st, party_leave( *party->data[i].sd ) ); return SCRIPT_CMD_SUCCESS; } diff --git a/src/map/unit.cpp b/src/map/unit.cpp index 2d66a7b269..ef70d646f4 100644 --- a/src/map/unit.cpp +++ b/src/map/unit.cpp @@ -3165,7 +3165,7 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file, } if(sd->party_invite > 0) - party_reply_invite(sd,sd->party_invite,0); + party_reply_invite( *sd, sd->party_invite, 0 ); if(sd->guild_invite > 0) guild_reply_invite( *sd, sd->guild_invite, 0 );