Pārlūkot izejas kodu

Preparatory cleanup of parties (#8418)

Lemongrass3110 11 mēneši atpakaļ
vecāks
revīzija
34eb4be25b

+ 2 - 2
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 {

+ 1 - 1
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;
 }

+ 59 - 59
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 <account id>.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 <party name>.24B <item pickup rule>.B <item share rule>.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 <account id>.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<PACKET_CZ_REQ_JOIN_GROUP*>( 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 <char name>.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<PACKET_CZ_PARTY_JOIN_REQ*>( 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];
+
+	safestrncpy( name, p->name, sizeof( name ) );
 
-	party_invite(sd, t_sd);
+	party_invite( *sd, map_nick2sd( name, false ) );
+#endif
 }
 
 
 /// Party invitation reply
 /// 00ff <party id>.L <flag>.L (CZ_JOIN_GROUP)
-/// 02c7 <party id>.L <flag>.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]));
+void clif_parse_ReplyPartyInvite( int fd, map_session_data *sd ){
+	if( sd == nullptr ){
+		return;
+	}
+
+	PACKET_CZ_JOIN_GROUP* p = reinterpret_cast<PACKET_CZ_JOIN_GROUP*>( RFIFOP( fd, 0 ) );
+
+	party_reply_invite( *sd, p->party_id, p->flag );
 }
-//(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]));
+
+/// Party invitation reply
+/// 02c7 <party id>.L <flag>.B (CZ_PARTY_JOIN_REQ_ACK)
+/// flag:
+///     0 = reject
+///     1 = accept
+void clif_parse_ReplyPartyInvite2( int fd, map_session_data *sd ){
+#if PACKETVER >= 20070227
+	if( sd == nullptr ){
+		return;
+	}
+
+	PACKET_CZ_PARTY_JOIN_REQ_ACK* p = reinterpret_cast<PACKET_CZ_PARTY_JOIN_REQ_ACK*>( RFIFOP( fd, 0 ) );
+
+	party_reply_invite( *sd, p->party_id, p->flag );
+#endif
 }
 
 
-/// 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));
+/// Request to leave party.
+/// 0100 (CZ_REQ_LEAVE_GROUP)
+void clif_parse_LeaveParty( int fd, map_session_data *sd ){
+	if( sd == nullptr ){
 		return;
 	}
-	party_leave(sd);
+
+	//PACKET_CZ_REQ_LEAVE_GROUP* p = reinterpret_cast<PACKET_CZ_REQ_LEAVE_GROUP*>( RFIFOP( fd, 0 ) );
+
+	party_leave( *sd, true );
 }
 
 
-/// Request to expel a party member (CZ_REQ_EXPEL_GROUP_MEMBER).
-/// 0103 <account id>.L <char name>.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 expel a party member.
+/// 0103 <account id>.L <char name>.24B (CZ_REQ_EXPEL_GROUP_MEMBER)
+void clif_parse_RemovePartyMember( 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_EXPEL_GROUP_MEMBER* p = reinterpret_cast<PACKET_CZ_REQ_EXPEL_GROUP_MEMBER*>( 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 <enabled>.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 );

+ 1 - 1
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)

+ 6 - 6
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);

+ 38 - 0
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 )

+ 157 - 127
src/map/party.cpp

@@ -10,7 +10,7 @@
 #include <common/nullpo.hpp>
 #include <common/random.hpp>
 #include <common/showmsg.hpp>
-#include <common/socket.hpp> // last_tick
+#include <common/socket.hpp> // last_tick, session_isActive
 #include <common/strlib.hpp>
 #include <common/timer.hpp>
 #include <common/utils.hpp>
@@ -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<<BOUND_PARTY))
-		trade_tradecancel(sd);
-#else
-	;
+	if (sd.state.isBoundTrading&(1<<BOUND_PARTY))
+		trade_tradecancel( &sd );
 #endif
 }
 
@@ -383,29 +380,50 @@ int party_recv_info(struct party* sp, uint32 char_id)
 }
 
 ///! TODO: Party invitation cross map-server through inter-server, so does with the reply.
-int party_invite(map_session_data *sd,map_session_data *tsd)
-{
-	struct party_data *p;
-	int i;
+bool party_invite( map_session_data& sd, map_session_data *tsd ){
+	struct party_data* p = party_search( sd.status.party_id );
 
-	nullpo_ret(sd);
+	if( p == nullptr ){
+		return false;
+	}
 
-	if( ( p = party_search(sd->status.party_id) ) == nullptr )
-		return 0;
+	int i;
 
 	// confirm if this player is a party leader
-	ARR_FIND(0, MAX_PARTY, i, p->data[i].sd == sd);
+	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;
+		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;
 	}
 
-	if (tsd && battle_config.block_account_in_same_party) {
+	// @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 <account_id, name>.
-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++)

+ 7 - 7
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);

+ 1 - 1
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)

+ 3 - 3
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;
 }
 

+ 1 - 1
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 );