From 9c9dcc8cab67684d3ee1f506aa73ad7c3cdf14c2 Mon Sep 17 00:00:00 2001 From: Lemongrass3110 Date: Wed, 12 Jun 2024 14:47:52 +0200 Subject: [PATCH] Preparatory cleanup of guilds (#8417) --- src/map/atcommand.cpp | 7 +- src/map/clif.cpp | 424 +++++++++++++++++------------------- src/map/clif.hpp | 19 +- src/map/clif_packetdb.hpp | 22 +- src/map/guild.cpp | 447 ++++++++++++++++++++++---------------- src/map/guild.hpp | 17 +- src/map/intif.cpp | 18 +- src/map/intif.hpp | 6 +- src/map/packets.hpp | 77 +++++++ src/map/unit.cpp | 2 +- 10 files changed, 581 insertions(+), 458 deletions(-) diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp index f48755b030..5858508796 100644 --- a/src/map/atcommand.cpp +++ b/src/map/atcommand.cpp @@ -3841,7 +3841,7 @@ ACMD_FUNC(guild) prev = battle_config.guild_emperium_check; battle_config.guild_emperium_check = 0; - guild_create(sd, guild); + guild_create( *sd, guild ); battle_config.guild_emperium_check = prev; return 0; @@ -3854,8 +3854,9 @@ ACMD_FUNC(breakguild) if (sd->status.guild_id) { // Check if the player has a guild if (sd->guild) { // Check if guild was found if (sd->state.gmaster_flag) { // Check if player is guild master - int ret = 0; - ret = guild_break(sd, sd->guild->guild.name); // Break guild + // Break guild + int ret = guild_break( *sd, sd->guild->guild.name ); + if (ret) { // Check if anything went wrong return 0; // Guild was broken } else { diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 04f5bc184c..2cee6cf7e8 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -8586,24 +8586,20 @@ void clif_mvp_noitem(map_session_data* sd) } -/// Guild creation result (ZC_RESULT_MAKE_GUILD). -/// 0167 .B +/// Guild creation result. +/// 0167 .B (ZC_RESULT_MAKE_GUILD) /// result: /// 0 = "Guild has been created." /// 1 = "You are already in a Guild." /// 2 = "That Guild Name already exists." /// 3 = "You need the neccessary item to create a Guild." -void clif_guild_created(map_session_data *sd,int flag) -{ - int fd; +void clif_guild_created( map_session_data& sd, int flag ){ + PACKET_ZC_RESULT_MAKE_GUILD p = {}; - nullpo_retv(sd); + p.packetType = HEADER_ZC_RESULT_MAKE_GUILD; + p.result = static_cast( flag ); - fd=sd->fd; - WFIFOHEAD(fd,packet_len(0x167)); - WFIFOW(fd,0)=0x167; - WFIFOB(fd,2)=flag; - WFIFOSET(fd,packet_len(0x167)); + clif_send( &p, sizeof( p ), &sd.bl, SELF ); } @@ -8914,8 +8910,8 @@ void clif_guild_positioninfolist(map_session_data *sd) } -/// Notifies clients in a guild about updated position information (ZC_ACK_CHANGE_GUILD_POSITIONINFO). -/// 0174 .W { .L .L .L .L .24B }* +/// Notifies clients in a guild about updated position information. +/// 0174 .W { .L .L .L .L .24B }* (ZC_ACK_CHANGE_GUILD_POSITIONINFO) /// mode: /// &0x01 = allow invite /// &0x10 = allow expel @@ -8943,8 +8939,8 @@ void clif_guild_positionchanged(const struct mmo_guild &g,int idx) } -/// Notifies clients in a guild about updated member position assignments (ZC_ACK_REQ_CHANGE_MEMBERS). -/// 0156 .W { .L .L .L }* +/// Notifies clients in a guild about updated member position assignments. +/// 0156 .W { .L .L .L }* (ZC_ACK_REQ_CHANGE_MEMBERS) void clif_guild_memberpositionchanged(const struct mmo_guild &g, int idx) { // FIXME: This packet is intended to update the clients after a @@ -8965,8 +8961,8 @@ void clif_guild_memberpositionchanged(const struct mmo_guild &g, int idx) } -/// Sends emblems bitmap data to the client that requested it (ZC_GUILD_EMBLEM_IMG). -/// 0152 .W .L .L .?B +/// Sends emblems bitmap data to the client that requested it. +/// 0152 .W .L .L .?B (ZC_GUILD_EMBLEM_IMG) void clif_guild_emblem(const map_session_data &sd, const struct mmo_guild &g) { int fd = sd.fd; @@ -8983,9 +8979,10 @@ void clif_guild_emblem(const map_session_data &sd, const struct mmo_guild &g) } -/// Sends update of the guild id/emblem id to everyone in the area (ZC_CHANGE_GUILD). -/// 01b4 .L .L .W -/// 0b47 .L .L .L +/// Sends update of the guild id/emblem id to everyone in the area. +/// 01b4 .L .L .W (ZC_CHANGE_GUILD) +/// 0b1f .L .L .L (ZC_NEW_EMBLEM_DOWNLOAD) +/// 0b47 .L .L .L (ZC_ACK_ADD_NEW_EMBLEM) void clif_guild_emblem_area(struct block_list* bl) { // TODO this packet doesn't force the update of ui components that have the emblem visible @@ -9001,137 +8998,145 @@ void clif_guild_emblem_area(struct block_list* bl) } -/// Sends guild skills (ZC_GUILD_SKILLINFO). -/// 0162 .W .W { .W .L .W .W .W .24B .B }* -void clif_guild_skillinfo(map_session_data* sd) -{ - int fd; - int i,c; +/// Sends guild skills. +/// 0162 .W .W { .W .L .W .W .W .24B .B }* (ZC_GUILD_SKILLINFO) +void clif_guild_skillinfo( map_session_data& sd ){ + auto& g = sd.guild; - nullpo_retv(sd); - auto &g = sd->guild; - if (!g) + if( g == nullptr ){ return; - - fd = sd->fd; - WFIFOHEAD(fd, 6 + MAX_GUILDSKILL*37); - WFIFOW(fd,0) = 0x0162; - WFIFOW(fd,4) = g->guild.skill_point; - for(i = 0, c = 0; i < MAX_GUILDSKILL; i++) - { - if(g->guild.skill[i].id > 0 && guild_check_skill_require(g->guild, g->guild.skill[i].id)) - { - int id = g->guild.skill[i].id; - int p = 6 + c*37; - WFIFOW(fd,p+0) = id; - WFIFOL(fd,p+2) = skill_get_inf(id); - WFIFOW(fd,p+6) = g->guild.skill[i].lv; - WFIFOW(fd,p+8) = skill_get_sp(id, g->guild.skill[i].lv); - WFIFOW(fd,p+10) = skill_get_range(id, g->guild.skill[i].lv); - safestrncpy(WFIFOCP(fd,p+12), skill_get_name(id), NAME_LENGTH); - WFIFOB(fd,p+36)= (g->guild.skill[i].lv < guild_skill_get_max(id) && sd == g->guild.member[0].sd) ? 1 : 0; - c++; - } } - WFIFOW(fd,2) = 6 + c*37; - WFIFOSET(fd,WFIFOW(fd,2)); + + PACKET_ZC_GUILD_SKILLINFO* p = reinterpret_cast( packet_buffer ); + + p->PacketType = HEADER_ZC_GUILD_SKILLINFO; + p->PacketLength = sizeof( *p ); + p->skillPoint = g->guild.skill_point; + + for( size_t i = 0, c = 0; i < MAX_GUILDSKILL; i++ ){ + if( g->guild.skill[i].id <= 0 ){ + continue; + } + + if( !guild_check_skill_require( g->guild, g->guild.skill[i].id ) ){ + continue; + } + + GUILD_SKILLDATA& gs = p->skillInfo[c]; + int skill_id = g->guild.skill[i].id; + + gs.id = skill_id; + gs.inf = skill_get_inf(skill_id); + gs.level = g->guild.skill[i].lv; + if( g->guild.skill[i].lv > 0 ){ + gs.sp = skill_get_sp( skill_id, g->guild.skill[i].lv ); + gs.range2 = skill_get_range( skill_id, g->guild.skill[i].lv ); + }else{ + gs.sp = 0; + gs.range2 = 0; + } + safestrncpy( gs.name, skill_get_name( skill_id ), sizeof( gs.name ) ); + gs.upFlag = ( g->guild.skill[i].lv < guild_skill_get_max( skill_id ) && &sd == g->guild.member[0].sd ) ? 1 : 0; + + p->PacketLength += static_castPacketLength)>( sizeof( gs ) ); + c++; + } + + clif_send( p, p->PacketLength, &sd.bl, SELF ); } -/// Sends guild notice to client (ZC_GUILD_NOTICE). -/// 016f .60B .120B -void clif_guild_notice(map_session_data* sd) -{ - nullpo_retv(sd); +/// Sends guild notice to client. +/// 016f .60B .120B (ZC_GUILD_NOTICE) +void clif_guild_notice( map_session_data& sd ){ + auto& g = sd.guild; - auto &g = sd->guild; - - int fd = sd->fd; - - if ( !session_isActive(fd) ) + if( g == nullptr ){ return; + } - if(g->guild.mes1[0] == '\0' && g->guild.mes2[0] == '\0') + if( g->guild.mes1[0] == '\0' && g->guild.mes2[0] == '\0' ){ return; + } - WFIFOHEAD(fd,packet_len(0x16f)); - WFIFOW(fd,0) = 0x16f; - memcpy(WFIFOP(fd,2), g->guild.mes1, MAX_GUILDMES1); - memcpy(WFIFOP(fd,62), g->guild.mes2, MAX_GUILDMES2); - WFIFOSET(fd,packet_len(0x16f)); + PACKET_ZC_GUILD_NOTICE p = {}; + + p.packetType = HEADER_ZC_GUILD_NOTICE; + safestrncpy( p.subject, g->guild.mes1, sizeof( p.subject ) ); + safestrncpy( p.notice, g->guild.mes2, sizeof( p.notice ) ); + + clif_send( &p, sizeof( p ), &sd.bl, SELF ); } -/// Guild invite (ZC_REQ_JOIN_GUILD). -/// 016a .L .24B -void clif_guild_invite(const map_session_data &sd, const struct mmo_guild &g) -{ - int fd = sd.fd; - WFIFOHEAD(fd,packet_len(0x16a)); - WFIFOW(fd,0)=0x16a; - WFIFOL(fd,2)=g.guild_id; - safestrncpy(WFIFOCP(fd,6),g.name,NAME_LENGTH); - WFIFOSET(fd,packet_len(0x16a)); +/// Guild invite. +/// 016a .L .24B (ZC_REQ_JOIN_GUILD) +void clif_guild_invite( map_session_data& sd, const struct mmo_guild& g ){ + PACKET_ZC_REQ_JOIN_GUILD p = {}; + + p.packetType = HEADER_ZC_REQ_JOIN_GUILD; + p.guild_id = g.guild_id; + safestrncpy( p.guild_name, g.name, sizeof( p.guild_name ) ); + + clif_send( &p, sizeof( p ), &sd.bl, SELF ); } -/// Reply to invite request (ZC_ACK_REQ_JOIN_GUILD). -/// 0169 .B +/// Reply to invite request. +/// 0169 .B (ZC_ACK_REQ_JOIN_GUILD) /// answer: /// 0 = Already in guild. /// 1 = Offer rejected. /// 2 = Offer accepted. /// 3 = Guild full. -void clif_guild_inviteack(map_session_data *sd,int flag) -{ - int fd; +void clif_guild_inviteack( map_session_data& sd, int flag ){ + PACKET_ZC_ACK_REQ_JOIN_GUILD p = {}; - nullpo_retv(sd); + p.packetType = HEADER_ZC_ACK_REQ_JOIN_GUILD; + p.result = static_cast( flag ); - fd=sd->fd; - WFIFOHEAD(fd,packet_len(0x169)); - WFIFOW(fd,0)=0x169; - WFIFOB(fd,2)=flag; - WFIFOSET(fd,packet_len(0x169)); + clif_send( &p, sizeof( p ), &sd.bl, SELF ); } -/// Notifies clients of a guild of a leaving member (ZC_ACK_LEAVE_GUILD). -/// 015a .24B .40B -void clif_guild_leave(map_session_data *sd,const char *name,const char *mes) -{ - unsigned char buf[128]; +/// Notifies clients of a guild of a leaving member. +/// 015a .24B .40B (ZC_ACK_LEAVE_GUILD) +/// 0a83 .L .40B (ZC_ACK_LEAVE_GUILD_DELNAME) +void clif_guild_leave( map_session_data& sd, const char* name, uint32 char_id, const char* mes ){ + PACKET_ZC_ACK_LEAVE_GUILD p = {}; - nullpo_retv(sd); + p.packetType = guildLeave; +#if PACKETVER_MAIN_NUM >= 20161019 || PACKETVER_RE_NUM >= 20160921 || defined(PACKETVER_ZERO) + p.GID = char_id; +#else + safestrncpy( p.name, name, sizeof( p.name ) ); +#endif + safestrncpy( p.reason, mes, sizeof( p.reason ) ); - WBUFW(buf, 0)=0x15a; - safestrncpy(WBUFCP(buf, 2),name,NAME_LENGTH); - memcpy(WBUFP(buf,26),mes,40); - clif_send(buf,packet_len(0x15a),&sd->bl,GUILD_NOBG); + clif_send( &p, sizeof( p ), &sd.bl, GUILD_NOBG ); } /// Notifies clients of a guild of an expelled member. /// 015c .24B .40B .24B (ZC_ACK_BAN_GUILD) /// 0839 .24B .40B (ZC_ACK_BAN_GUILD_SSO) -void clif_guild_expulsion(map_session_data* sd, const char* name, const char* mes, uint32 account_id) -{ - unsigned char buf[128]; -#if PACKETVER < 20100803 - const unsigned short cmd = 0x15c; +/// 0a82 .L .40B (ZC_ACK_BAN_GUILD_DELNAME) +void clif_guild_expulsion( map_session_data& sd, const char* name, uint32 char_id, const char* mes ){ + PACKET_ZC_ACK_BAN_GUILD p = {}; + + p.packetType = guildExpulsion; +#if PACKETVER_MAIN_NUM >= 20161019 || PACKETVER_RE_NUM >= 20160921 || defined(PACKETVER_ZERO) + p.GID = char_id; #else - const unsigned short cmd = 0x839; + safestrncpy( p.name, name, sizeof( p.name ) ); #endif - - nullpo_retv(sd); - - WBUFW(buf,0) = cmd; - safestrncpy(WBUFCP(buf,2), name, NAME_LENGTH); - safestrncpy(WBUFCP(buf,26), mes, 40); + safestrncpy( p.reason, mes, sizeof( p.reason ) ); #if PACKETVER < 20100803 - memset(WBUFP(buf,66), 0, NAME_LENGTH); // account name (not used for security reasons) + // account name is not sent for security reasons + safestrncpy( p.account_name, "", sizeof( p.account_name ) ); #endif - clif_send(buf, packet_len(cmd), &sd->bl, GUILD_NOBG); + + clif_send( &p, sizeof( p ), &sd.bl, GUILD_NOBG ); } @@ -9302,22 +9307,18 @@ void clif_guild_allianceadded(struct guild *g,int idx) */ -/// Notifies the client about the result of a guild break (ZC_ACK_DISORGANIZE_GUILD_RESULT). -/// 015e .L +/// Notifies the client about the result of a guild break. +/// 015e .L (ZC_ACK_DISORGANIZE_GUILD_RESULT) /// 0 = success /// 1 = invalid key (guild name, @see clif_parse_GuildBreak) /// 2 = there are still members in the guild -void clif_guild_broken(map_session_data *sd,int flag) -{ - int fd; +void clif_guild_broken( map_session_data& sd, int flag ){ + PACKET_ZC_ACK_DISORGANIZE_GUILD_RESULT p = {}; - nullpo_retv(sd); + p.packetType = HEADER_ZC_ACK_DISORGANIZE_GUILD_RESULT; + p.result = flag; - fd=sd->fd; - WFIFOHEAD(fd,packet_len(0x15e)); - WFIFOW(fd,0)=0x15e; - WFIFOL(fd,2)=flag; - WFIFOSET(fd,packet_len(0x15e)); + clif_send( &p, sizeof( p ), &sd.bl, SELF ); } @@ -10952,7 +10953,8 @@ void clif_parse_LoadEndAck(int fd,map_session_data *sd) clif_reputation_list( *sd ); if (sd->guild && battle_config.guild_notice_changemap == 1){ - clif_guild_notice(sd); // Displays after VIP + // Displays after VIP + clif_guild_notice( *sd ); guild_notice = false; // Do not display it twice } @@ -11019,7 +11021,8 @@ void clif_parse_LoadEndAck(int fd,map_session_data *sd) } if( sd->guild && ( battle_config.guild_notice_changemap == 2 || guild_notice ) ){ - clif_guild_notice(sd); // Displays at end + // Displays at end + clif_guild_notice( *sd ); } mail_clear(sd); @@ -12356,19 +12359,16 @@ void clif_parse_ChatLeave(int fd, map_session_data* sd) } -//Handles notifying asker and rejecter of what has just ocurred. -//Type is used to determine the correct msg_txt to use: -//0: -static void clif_noask_sub(map_session_data *sd, map_session_data *tsd, int type) -{ - const char* msg; - char output[256]; +// Handles notifying asker and rejecter of what has just ocurred. +void clif_noask_sub( map_session_data& sd, map_session_data& tsd, int type ){ + char output[CHAT_SIZE_MAX]; + // Your request has been rejected by autoreject option. - msg = msg_txt(sd,392); - clif_messagecolor(&sd->bl, color_table[COLOR_LIGHT_GREEN], msg, false, SELF); - //Notice that a request was rejected. - snprintf(output, 256, msg_txt(tsd,393+type), sd->status.name, 256); - clif_messagecolor(&tsd->bl, color_table[COLOR_LIGHT_GREEN], output, false, SELF); + clif_messagecolor( &sd.bl, color_table[COLOR_LIGHT_GREEN], msg_txt( &sd, 392 ), false, SELF ); + + // Notice that a request was rejected. + safesnprintf( output, CHAT_SIZE_MAX, msg_txt( &tsd, type ), sd.status.name ); + clif_messagecolor( &tsd.bl, color_table[COLOR_LIGHT_GREEN], output, false, SELF); } @@ -12386,7 +12386,7 @@ void clif_parse_TradeRequest(int fd,map_session_data *sd) if(t_sd){ // @noask [LuzZza] if(t_sd->state.noask) { - clif_noask_sub(sd, t_sd, 0); + clif_noask_sub( *sd, *t_sd, 393 ); // Autorejected trade request from %s. return; } @@ -13667,7 +13667,7 @@ void clif_parse_PartyInvite(int fd, map_session_data *sd) t_sd = map_id2sd(RFIFOL(fd,packet_db[RFIFOW(fd,0)].pos[0])); if(t_sd && t_sd->state.noask) {// @noask [LuzZza] - clif_noask_sub(sd, t_sd, 1); + clif_noask_sub( *sd, *t_sd, 394 ); // Autorejected party invite from %s. return; } @@ -13688,7 +13688,7 @@ void clif_parse_PartyInvite2(int fd, map_session_data *sd){ t_sd = map_nick2sd(name,false); if(t_sd && t_sd->state.noask) {// @noask [LuzZza] - clif_noask_sub(sd, t_sd, 1); + clif_noask_sub( *sd, *t_sd, 394 ); // Autorejected party invite from %s. return; } @@ -14081,7 +14081,7 @@ void clif_parse_CreateGuild(int fd,map_session_data *sd){ return; } - guild_create(sd, name); + guild_create( *sd, name ); } @@ -14125,7 +14125,7 @@ void clif_parse_GuildRequestInfo(int fd, map_session_data *sd) clif_guild_positioninfolist(sd); break; case 3: // Skill list - clif_guild_skillinfo(sd); + clif_guild_skillinfo( *sd ); break; case 4: // Expulsion list clif_guild_expulsionlist(sd); @@ -14155,8 +14155,8 @@ void clif_parse_GuildChangePositionInfo(int fd, map_session_data *sd) } -/// Request to update the position of guild members (CZ_REQ_CHANGE_MEMBERPOS). -/// 0155 .W { .L .L .L }* +/// Request to update the position of guild members. +/// 0155 .W { .L .L .L }* (CZ_REQ_CHANGE_MEMBERPOS) void clif_parse_GuildChangeMemberPosition( int fd, map_session_data *sd ){ if(!sd->state.gmaster_flag) return; @@ -14319,99 +14319,74 @@ void clif_parse_GuildChangeNotice(int fd, map_session_data* sd){ guild_change_notice(sd, guild_id, msg1, msg2); } -// Helper function for guild invite functions -int clif_sub_guild_invite(int fd, map_session_data *sd, map_session_data *t_sd) -{ - if (t_sd == nullptr) // not online or does not exist - return 1; - - if (map_getmapflag(sd->bl.m, MF_GUILDLOCK)) {//Guild locked. - clif_displaymessage(fd, msg_txt(sd,228)); - return 1; - } - - if(t_sd && t_sd->state.noask) {// @noask [LuzZza] - clif_noask_sub(sd, t_sd, 2); - return 1; - } - - // Players in a clan can not join a guild - if(t_sd && t_sd->clan){ - return 1; - } - - guild_invite(sd, t_sd); - return 0; -} - -/// Guild invite request (CZ_REQ_JOIN_GUILD). -/// 0168 .L .L .L -void clif_parse_GuildInvite(int fd,map_session_data *sd){ - struct s_packet_db* info = &packet_db[RFIFOW(fd,0)]; - map_session_data *t_sd = map_id2sd(RFIFOL(fd,info->pos[0])); -// int inv_aid = RFIFOL(fd,info->pos[1]); -// int inv_cid = RFIFOL(fd,info->pos[2]); - - if (clif_sub_guild_invite(fd, sd, t_sd)) +/// Guild invite request. +/// 0168 .L .L .L (CZ_REQ_JOIN_GUILD) +void clif_parse_GuildInvite( int fd,map_session_data *sd ){ + if( sd == nullptr ){ return; + } + + PACKET_CZ_REQ_JOIN_GUILD* p = reinterpret_cast( RFIFOP( fd, 0 ) ); + + guild_invite( *sd, map_id2sd( p->AID ) ); } /// Guild invite request (/guildinvite) /// 0916 .24B (CZ_REQ_JOIN_GUILD2) -void -clif_parse_GuildInvite2(int fd, map_session_data *sd) { - map_session_data *t_sd = map_nick2sd(RFIFOCP(fd, packet_db[RFIFOW(fd,0)].pos[0]),false); - - if (clif_sub_guild_invite(fd, sd, t_sd)) +void clif_parse_GuildInvite2( int fd, map_session_data *sd ){ +#if PACKETVER >= 20120410 + if( sd == nullptr ){ return; + } + + PACKET_CZ_REQ_JOIN_GUILD2* p = reinterpret_cast( RFIFOP( fd, 0 ) ); + + char nick[NAME_LENGTH] = {0}; + + safestrncpy( nick, p->name, NAME_LENGTH ); + + guild_invite( *sd, map_nick2sd( nick, false ) ); +#endif } - -/// Answer to guild invitation (CZ_JOIN_GUILD). -/// 016b .L .L +/// Answer to guild invitation. +/// 016b .L .L (CZ_JOIN_GUILD) /// answer: /// 0 = refuse /// 1 = accept -void clif_parse_GuildReplyInvite(int fd,map_session_data *sd){ - struct s_packet_db* info = &packet_db[RFIFOW(fd,0)]; - guild_reply_invite(sd,RFIFOL(fd,info->pos[0]), - RFIFOL(fd,info->pos[1])); +void clif_parse_GuildReplyInvite( int fd, map_session_data *sd ){ + if( sd == nullptr ){ + return; + } + + PACKET_CZ_JOIN_GUILD* p = reinterpret_cast( RFIFOP( fd, 0 ) ); + + guild_reply_invite( *sd, p->guild_id, p->answer ); } - -/// Request to leave guild (CZ_REQ_LEAVE_GUILD). -/// 0159 .L .L .L .40B +/// Request to leave guild. +/// 0159 .L .L .L .40B (CZ_REQ_LEAVE_GUILD) void clif_parse_GuildLeave(int fd,map_session_data *sd){ - struct s_packet_db* info = &packet_db[RFIFOW(fd,0)]; - if(map_getmapflag(sd->bl.m, MF_GUILDLOCK)) { //Guild locked. - clif_displaymessage(fd, msg_txt(sd,228)); - return; - } - if( sd->bg_id ) { - clif_displaymessage(fd, msg_txt(sd,670)); //"You can't leave battleground guilds." + if( sd == nullptr ){ return; } - guild_leave(sd,RFIFOL(fd,info->pos[0]), - RFIFOL(fd,info->pos[1]), - RFIFOL(fd,info->pos[2]), - RFIFOCP(fd,info->pos[3])); + PACKET_CZ_REQ_LEAVE_GUILD* p = reinterpret_cast( RFIFOP( fd, 0 ) ); + + guild_leave( *sd, p->guild_id, p->AID, p->CID, p->message ); } -/// Request to expel a member of a guild (CZ_REQ_BAN_GUILD). -/// 015b .L .L .L .40B +/// Request to expel a member of a guild. +/// 015b .L .L .L .40B (CZ_REQ_BAN_GUILD) void clif_parse_GuildExpulsion(int fd,map_session_data *sd){ - struct s_packet_db* info = &packet_db[RFIFOW(fd,0)]; - if( map_getmapflag(sd->bl.m, MF_GUILDLOCK) || sd->bg_id ) - { // Guild locked. - clif_displaymessage(fd, msg_txt(sd,228)); + if( sd == nullptr ){ return; } - guild_expulsion(sd,RFIFOL(fd,info->pos[0]), - RFIFOL(fd,info->pos[1]), - RFIFOL(fd,info->pos[2]), - RFIFOCP(fd,info->pos[3])); + + PACKET_CZ_REQ_BAN_GUILD* p = reinterpret_cast( RFIFOP( fd, 0 ) ); + + guild_expulsion( *sd, p->guild_id, p->AID, p->CID, p->message ); } @@ -14451,7 +14426,7 @@ void clif_parse_GuildRequestAlliance(int fd, map_session_data *sd) // @noask [LuzZza] if(t_sd && t_sd->state.noask) { - clif_noask_sub(sd, t_sd, 3); + clif_noask_sub( *sd, *t_sd, 396 ); // Autorejected alliance request from %s. return; } @@ -14510,7 +14485,7 @@ void clif_parse_GuildOpposition(int fd, map_session_data *sd) // @noask [LuzZza] if(t_sd && t_sd->state.noask) { - clif_noask_sub(sd, t_sd, 4); + clif_noask_sub( *sd, *t_sd, 397 ); // Autorejected opposition request from %s. return; } @@ -14518,18 +14493,19 @@ void clif_parse_GuildOpposition(int fd, map_session_data *sd) } -/// Request to delete own guild (CZ_REQ_DISORGANIZE_GUILD). -/// 015d .40B +/// Request to delete own guild. +/// 015d .40B (CZ_REQ_DISORGANIZE_GUILD) /// key: /// now guild name; might have been (intended) email, since the /// field name and size is same as the one in CH_DELETE_CHAR. -void clif_parse_GuildBreak(int fd, map_session_data *sd) -{ - if( map_getmapflag(sd->bl.m, MF_GUILDLOCK) ) { //Guild locked. - clif_displaymessage(fd, msg_txt(sd,228)); +void clif_parse_GuildBreak( int fd, map_session_data *sd ){ + if( sd == nullptr ){ return; } - guild_break(sd,RFIFOCP(fd,packet_db[RFIFOW(fd,0)].pos[0])); + + PACKET_CZ_REQ_DISORGANIZE_GUILD* p = reinterpret_cast( RFIFOP( fd, 0 ) ); + + guild_break( *sd, p->key ); } @@ -15247,7 +15223,7 @@ void clif_parse_FriendsListAdd(int fd, map_session_data *sd) // @noask [LuzZza] if(f_sd->state.noask) { - clif_noask_sub(sd, f_sd, 5); + clif_noask_sub( *sd, *f_sd, 398 ); // Autorejected friend request from %s. return; } diff --git a/src/map/clif.hpp b/src/map/clif.hpp index cd950ce5cb..6ceb11b641 100644 --- a/src/map/clif.hpp +++ b/src/map/clif.hpp @@ -1017,35 +1017,34 @@ void clif_party_job_and_level( map_session_data& sd ); void clif_party_dead( map_session_data& sd ); // guild -void clif_guild_created(map_session_data *sd,int flag); +void clif_guild_created( map_session_data& sd, int flag ); void clif_guild_belonginfo( map_session_data& sd ); void clif_guild_masterormember(map_session_data *sd); void clif_guild_basicinfo( map_session_data& sd ); void clif_guild_allianceinfo(map_session_data *sd); void clif_guild_memberlist( map_session_data& sd ); -void clif_guild_skillinfo(map_session_data* sd); +void clif_guild_skillinfo( map_session_data& sd ); void clif_guild_send_onlineinfo(map_session_data *sd); //[LuzZza] void clif_guild_memberlogin_notice(const struct mmo_guild &g,int idx,int flag); -void clif_guild_invite(const map_session_data &sd, const struct mmo_guild &g); -void clif_guild_inviteack(map_session_data *sd,int flag); -void clif_guild_leave(map_session_data *sd,const char *name,const char *mes); -void clif_guild_expulsion(map_session_data* sd, const char* name, const char* mes, uint32 account_id); +void clif_guild_invite( map_session_data& sd, const struct mmo_guild& g ); +void clif_guild_inviteack( map_session_data& sd, int flag ); +void clif_guild_leave( map_session_data& sd, const char* name, uint32 char_id, const char* mes ); +void clif_guild_expulsion( map_session_data& sd, const char* name, uint32 char_id, const char* mes ); void clif_guild_positionchanged(const struct mmo_guild &g,int idx); void clif_guild_memberpositionchanged(const struct mmo_guild &g,int idx); void clif_guild_emblem(const map_session_data &sd, const struct mmo_guild &g); void clif_guild_emblem_area(struct block_list* bl); -void clif_guild_notice(map_session_data* sd); +void clif_guild_notice( map_session_data& sd ); void clif_guild_message( const struct mmo_guild& g, uint32 account_id, const char* mes, size_t len ); void clif_guild_reqalliance(map_session_data *sd,uint32 account_id,const char *name); void clif_guild_allianceack(map_session_data *sd,int flag); void clif_guild_delalliance(map_session_data *sd,int guild_id,int flag); void clif_guild_oppositionack(map_session_data *sd,int flag); -void clif_guild_broken(map_session_data *sd,int flag); +void clif_guild_broken( map_session_data& sd, int flag ); void clif_guild_xy( map_session_data& sd ); void clif_guild_xy_single( map_session_data& sd, map_session_data& tsd ); void clif_guild_xy_remove( map_session_data& sd ); void clif_guild_castle_list(map_session_data& sd); -void clif_guild_castle_info(map_session_data& sd, std::shared_ptr castle ); void clif_guild_castle_teleport_res(map_session_data& sd, enum e_siege_teleport_result result); // Battleground @@ -1434,4 +1433,6 @@ void clif_set_npc_window_size(map_session_data& sd, int width, int height); void clif_set_npc_window_pos(map_session_data& sd, int x, int y); void clif_set_npc_window_pos_percent(map_session_data& sd, int x, int y); +void clif_noask_sub( map_session_data& sd, map_session_data& tsd, int type ); + #endif /* CLIF_HPP */ diff --git a/src/map/clif_packetdb.hpp b/src/map/clif_packetdb.hpp index f4b5647edc..bb619b4625 100644 --- a/src/map/clif_packetdb.hpp +++ b/src/map/clif_packetdb.hpp @@ -185,29 +185,21 @@ packet(0x0156,-1); packet(0x0157,6); packet(0x0158,-1); - parseable_packet(0x0159,54,clif_parse_GuildLeave,2,6,10,14); - packet(0x015a,66); - parseable_packet(0x015b,54,clif_parse_GuildExpulsion,2,6,10,14); - packet(0x015c,90); - parseable_packet(0x015d,42,clif_parse_GuildBreak,2); - packet(0x015e,6); + parseable_packet( HEADER_CZ_REQ_LEAVE_GUILD, sizeof( PACKET_CZ_REQ_LEAVE_GUILD ), clif_parse_GuildLeave, 0 ); + parseable_packet( HEADER_CZ_REQ_BAN_GUILD, sizeof( PACKET_CZ_REQ_BAN_GUILD ), clif_parse_GuildExpulsion, 0 ); + parseable_packet( HEADER_CZ_REQ_DISORGANIZE_GUILD, sizeof( PACKET_CZ_REQ_DISORGANIZE_GUILD ), clif_parse_GuildBreak, 0 ); packet(0x015f,42); packet(0x0160,-1); parseable_packet(0x0161,-1,clif_parse_GuildChangePositionInfo,2,4); - packet(0x0162,-1); packet(0x0163,-1); packet(0x0164,-1); parseable_packet(0x0165,30,clif_parse_CreateGuild,2,6); packet(0x0166,-1); - packet(0x0167,3); - parseable_packet(0x0168,14,clif_parse_GuildInvite,2,6,10); - packet(0x0169,3); - packet(0x016a,30); - parseable_packet(0x016b,10,clif_parse_GuildReplyInvite,2,6); + parseable_packet( HEADER_CZ_REQ_JOIN_GUILD, sizeof( PACKET_CZ_REQ_JOIN_GUILD ), clif_parse_GuildInvite, 0 ); + parseable_packet( HEADER_CZ_JOIN_GUILD, sizeof( PACKET_CZ_JOIN_GUILD ), clif_parse_GuildReplyInvite, 0 ); packet(0x016c,43); packet(0x016d,14); parseable_packet(0x016e,186,clif_parse_GuildChangeNotice,2,6,66); - packet(0x016f,182); parseable_packet(0x0170,14,clif_parse_GuildRequestAlliance,2,6,10); packet(0x0171,30); parseable_packet(0x0172,10,clif_parse_GuildReplyAlliance,2,6); @@ -267,7 +259,6 @@ packet(0x01b0,11); packet(0x01b1,7); parseable_packet(0x01b2,-1,clif_parse_OpenVending,2,4,84,85); - packet(0x01b4,12); packet(0x01b5,18); packet(0x01b6,114); packet(0x01b7,6); @@ -1655,7 +1646,6 @@ // 2010-08-03aRagexeRE #if PACKETVER >= 20100803 - packet(0x0839,66); parseable_packet(0x0842,6,clif_parse_GMRecall2,2); parseable_packet(0x0843,6,clif_parse_GMRemove2,2); #endif @@ -1827,7 +1817,7 @@ parseable_packet(0x090A,26,clif_parse_bg_queue_request_queue_number,2); packet( HEADER_ZC_ENTRY_QUEUE_INIT , sizeof(PACKET_ZC_ENTRY_QUEUE_INIT) ); packet(0x0977,14); //Monster HP Bar - parseable_packet(0x0916,26,clif_parse_GuildInvite2,2); + parseable_packet( HEADER_CZ_REQ_JOIN_GUILD2, sizeof( PACKET_CZ_REQ_JOIN_GUILD2 ), clif_parse_GuildInvite2, 0 ); parseable_packet(0x091d,41,clif_parse_PartyBookingRegisterReq,2,4,6); // Merge Item parseable_packet( HEADER_CZ_REQ_MERGE_ITEM, -1, clif_parse_merge_item_req, 0 ); diff --git a/src/map/guild.cpp b/src/map/guild.cpp index b6ee4792e1..fb9126a8a2 100644 --- a/src/map/guild.cpp +++ b/src/map/guild.cpp @@ -13,6 +13,7 @@ #include #include #include +#include // session_isActive #include #include #include @@ -601,22 +602,19 @@ int guild_getposition(const map_session_data& sd) { } //Creation of member information -void guild_makemember(struct guild_member *m,map_session_data *sd) { - nullpo_retv(sd); - - memset(m,0,sizeof(struct guild_member)); - m->account_id = sd->status.account_id; - m->char_id = sd->status.char_id; - m->hair = sd->status.hair; - m->hair_color = sd->status.hair_color; - m->gender = sd->status.sex; - m->class_ = sd->status.class_; - m->lv = sd->status.base_level; - m->exp = 0; - m->online = 1; - m->position = MAX_GUILDPOSITION-1; - safestrncpy(m->name,sd->status.name,NAME_LENGTH); - m->last_login = (uint32)time(nullptr); +void guild_makemember( struct guild_member& m, map_session_data& sd ){ + m.account_id = sd.status.account_id; + m.char_id = sd.status.char_id; + m.hair = sd.status.hair; + m.hair_color = sd.status.hair_color; + m.gender = sd.status.sex; + m.class_ = sd.status.class_; + m.lv = sd.status.base_level; + m.exp = 0; + m.online = 1; + m.position = MAX_GUILDPOSITION - 1; + safestrncpy( m.name, sd.status.name, NAME_LENGTH ); + m.last_login = static_cast( time( nullptr ) ); } /** @@ -688,32 +686,36 @@ int guild_send_dot_remove(map_session_data *sd) { } //------------------------------------------------------------------------ -int guild_create(map_session_data *sd, const char *name) { +bool guild_create( map_session_data& sd, const char* name ){ char tname[NAME_LENGTH]; - struct guild_member m; - nullpo_ret(sd); safestrncpy(tname, name, NAME_LENGTH); trim(tname); - if( !tname[0] ) - return 0; // empty name + // empty name + if( !tname[0] ){ + return false; + } - if( sd->status.guild_id ) { + if( sd.status.guild_id ) { // already in a guild - clif_guild_created(sd,1); - return 0; - } - if( battle_config.guild_emperium_check && pc_search_inventory(sd,ITEMID_EMPERIUM) == -1 ) { - // item required - clif_guild_created(sd,3); - return 0; + clif_guild_created( sd, 1 ); + return false; } - guild_makemember(&m,sd); + if( battle_config.guild_emperium_check && pc_search_inventory( &sd, ITEMID_EMPERIUM ) == -1 ){ + // item required + clif_guild_created( sd, 3 ); + return false; + } + + struct guild_member m = {}; + + guild_makemember( m, sd ); m.position=0; intif_guild_create(name,&m); - return 1; + + return true; } //Whether or not to create guild @@ -723,12 +725,13 @@ int guild_created(uint32 account_id,int guild_id) { if(sd==nullptr) return 0; if(!guild_id) { - clif_guild_created(sd, 2); // Creation failure (presence of the same name Guild) + clif_guild_created( *sd, 2 ); // Creation failure (presence of the same name Guild) return 0; } sd->status.guild_id = guild_id; - clif_guild_created(sd,0); + clif_guild_created( *sd, 0 ); + if(battle_config.guild_emperium_check){ int index = pc_search_inventory(sd,ITEMID_EMPERIUM); @@ -769,13 +772,10 @@ int guild_npc_request_info(int guild_id,const char *event) { * Close trade window if party member is kicked when trade a party bound item * @param sd **/ -static void guild_trade_bound_cancel(map_session_data *sd) { +static void guild_trade_bound_cancel( map_session_data& sd ){ #ifdef BOUND_ITEMS - nullpo_retv(sd); - if (sd->state.isBoundTrading&(1<guild.skill_point) - clif_guild_skillinfo(sd); //Submit information skills + clif_guild_skillinfo( *sd ); // Submit information skills if (guild_new) { // Send information and affiliation if unsent clif_guild_belonginfo( *sd ); - clif_guild_notice(sd); + clif_guild_notice( *sd ); sd->guild_emblem_id = g->guild.emblem_id; } if (g->instance_id > 0) @@ -918,102 +918,138 @@ int guild_recv_info(const struct mmo_guild &sg) { /*============================================= * Player sd send a guild invatation to player tsd to join his guild *--------------------------------------------*/ -int guild_invite(map_session_data *sd, map_session_data *tsd) { - int i; - - nullpo_ret(sd); - - auto &g = sd->guild; - - if(tsd==nullptr || g==nullptr) - return 0; - - if( (i=guild_getposition(*sd))<0 || !(g->guild.position[i].mode&GUILD_PERM_INVITE) ) - return 0; //Invite permission. - - if(!battle_config.invite_request_check) { - if (tsd->party_invite > 0 || tsd->trade_partner || tsd->adopt_invite) { //checking if there no other invitation pending - clif_guild_inviteack(sd,0); - return 0; - } +bool guild_invite( map_session_data& sd, map_session_data* tsd ){ + // No nullpo_retr, because its valid that target players might not exist or are not online + if( tsd == nullptr ){ + return false; } - if (!tsd->fd) { //You can't invite someone who has already disconnected. + auto& g = sd.guild; + + if( g == nullptr ){ + return false; + } + + // Guild locked. + if( map_getmapflag( sd.bl.m, MF_GUILDLOCK ) ){ + clif_displaymessage( sd.fd, msg_txt( &sd, 228 ) ); // Guild modification is disabled on this map. + return false; + } + + // @noask [LuzZza] + if( tsd->state.noask ){ + clif_noask_sub( sd, *tsd, 395 ); // Autorejected guild invite from %s. + return false; + } + + // Players in a clan can not join a guild + if( tsd->clan ){ + // TODO: message? + return false; + } + + // Invite permission. + if( !guild_has_permission( sd, GUILD_PERM_INVITE ) ){ + // TODO: message? + return false; + } + + // Checking if there no other invitation pending + if( !battle_config.invite_request_check && ( tsd->party_invite > 0 || tsd->trade_partner || tsd->adopt_invite ) ){ + clif_guild_inviteack( sd, 0 ); + return false; + } + + // You can't invite someone who has already disconnected. + if( !session_isActive( tsd->fd ) ){ clif_guild_inviteack(sd,1); - return 0; + return false; } - if(tsd->status.guild_id>0 || - tsd->guild_invite>0 || - map_flag_gvg2(tsd->bl.m)) - { //Can't invite people inside castles. [Skotlex] + // Can't invite people inside castles. [Skotlex] + if( tsd->status.guild_id > 0 || tsd->guild_invite > 0 || map_flag_gvg2( tsd->bl.m ) ){ clif_guild_inviteack(sd,0); - return 0; + return false; } + int i; + //search an empty spot in guild ARR_FIND( 0, g->guild.max_member, i, g->guild.member[i].account_id == 0 ); - if(i==g->guild.max_member){ + if( i == g->guild.max_member ){ clif_guild_inviteack(sd,3); - return 0; + return false; } - tsd->guild_invite=sd->status.guild_id; - tsd->guild_invite_account=sd->status.account_id; + tsd->guild_invite = sd.status.guild_id; + tsd->guild_invite_account = sd.status.account_id; clif_guild_invite(*tsd, g->guild); - return 0; + + return true; } /// Guild invitation reply. /// flag: 0:rejected, 1:accepted -int guild_reply_invite(map_session_data* sd, int guild_id, int flag) { - map_session_data* tsd; - - nullpo_ret(sd); - +bool guild_reply_invite( map_session_data& sd, int guild_id, int flag ){ // subsequent requests may override the value - if( sd->guild_invite != guild_id ) - return 0; // mismatch + if( sd.guild_invite != guild_id ){ + return false; // mismatch + } // look up the person who sent the invite //NOTE: this can be nullptr because the person might have logged off in the meantime - tsd = map_id2sd(sd->guild_invite_account); + map_session_data* tsd = map_id2sd( sd.guild_invite_account ); - if ( sd->status.guild_id > 0 ) { - // [Paradox924X] - // Already in another guild. - if ( tsd ) clif_guild_inviteack(tsd,0); - return 0; - } else if( flag == 0 ) {// rejected - sd->guild_invite = 0; - sd->guild_invite_account = 0; - if( tsd ) clif_guild_inviteack(tsd,1); - } else {// accepted - struct guild_member m; - auto g = guild_search(guild_id); - int i; - - if (!g) { - sd->guild_invite = 0; - sd->guild_invite_account = 0; - return 0; - } - - ARR_FIND( 0, g->guild.max_member, i, g->guild.member[i].account_id == 0 ); - if( i == g->guild.max_member ) { - sd->guild_invite = 0; - sd->guild_invite_account = 0; - if( tsd ) clif_guild_inviteack(tsd,3); - return 0; - } - - guild_makemember(&m,sd); - intif_guild_addmember(guild_id, &m); - //TODO: send a minimap update to this player + // Already in another guild. + if( sd.status.guild_id > 0 ){ + // Set the flag to rejected, no matter what + flag = 0; } - return 0; + // rejected + if( flag == 0 ){ + sd.guild_invite = 0; + sd.guild_invite_account = 0; + + if( tsd != nullptr ){ + clif_guild_inviteack( *tsd, 1 ); + } + + return true; + } + + // accepted + auto g = guild_search( guild_id ); + + if( g == nullptr ){ + sd.guild_invite = 0; + sd.guild_invite_account = 0; + return false; + } + + int i; + + ARR_FIND( 0, g->guild.max_member, i, g->guild.member[i].account_id == 0 ); + + if( i == g->guild.max_member ){ + sd.guild_invite = 0; + sd.guild_invite_account = 0; + + if( tsd != nullptr ){ + clif_guild_inviteack( *tsd, 3 ); + } + + return true; + } + + struct guild_member m = {}; + + guild_makemember( m, sd ); + intif_guild_addmember( guild_id, m ); + //TODO: send a minimap update to this player + + return true; } //Invoked when a player joins. @@ -1072,7 +1108,7 @@ int guild_member_added(int guild_id,uint32 account_id,uint32 char_id,int flag) { if (flag == 1) { //failure if( sd2!=nullptr ) - clif_guild_inviteack(sd2,3); + clif_guild_inviteack( *sd2, 3 ); return 0; } @@ -1082,12 +1118,12 @@ int guild_member_added(int guild_id,uint32 account_id,uint32 char_id,int flag) { sd->guild = g; //Packets which were sent in the previous 'guild_sent' implementation. clif_guild_belonginfo( *sd ); - clif_guild_notice(sd); + clif_guild_notice( *sd ); //TODO: send new emblem info to others if( sd2!=nullptr ) - clif_guild_inviteack(sd2,2); + clif_guild_inviteack( *sd2, 2 ); //Next line commented because it do nothing, look at guild_recv_info [LuzZza] //clif_charnameupdate(sd); //Update display name [Skotlex] @@ -1101,57 +1137,80 @@ int guild_member_added(int guild_id,uint32 account_id,uint32 char_id,int flag) { /*========================================== * Player request leaving a given guild_id *----------------------------------------*/ -int guild_leave(map_session_data* sd, int guild_id, uint32 account_id, uint32 char_id, const char* mes) { - nullpo_ret(sd); +bool guild_leave( map_session_data& sd, int guild_id, uint32 account_id, uint32 char_id, const char* mes ){ + auto& g = sd.guild; - if (!sd->guild) - return 0; + if( g == nullptr ){ + return false; + } - if(sd->status.account_id!=account_id || - sd->status.char_id!=char_id || sd->status.guild_id!=guild_id || - map_flag_gvg2(sd->bl.m)) - return 0; + if( map_getmapflag( sd.bl.m, MF_GUILDLOCK ) ){ + clif_displaymessage( sd.fd, msg_txt( &sd, 228 ) ); // Guild modification is disabled on this map. + return false; + } + + if( sd.bg_id ){ + clif_displaymessage( sd.fd, msg_txt( &sd, 670 ) ); // You can't leave battleground guilds. + return false; + } + + if( sd.status.account_id != account_id || sd.status.char_id != char_id || sd.status.guild_id != guild_id || map_flag_gvg2( sd.bl.m ) ){ + return false; + } guild_trade_bound_cancel(sd); - intif_guild_leave(sd->status.guild_id, sd->status.account_id, sd->status.char_id,0,mes); - return 0; + + return intif_guild_leave( sd.status.guild_id, sd.status.account_id, sd.status.char_id, 0, mes ); } /*========================================== * Request remove a player to a given guild_id *----------------------------------------*/ -int guild_expulsion(map_session_data* sd, int guild_id, uint32 account_id, uint32 char_id, const char* mes) { - map_session_data *tsd; - int i,ps; +bool guild_expulsion( map_session_data& sd, int guild_id, uint32 account_id, uint32 char_id, const char* mes ){ + auto& g = sd.guild; - nullpo_ret(sd); - - auto &g = sd->guild; - - if (!g) - return 0; - - if(sd->status.guild_id!=guild_id) - return 0; - - if( (ps=guild_getposition(*sd))<0 || !(g->guild.position[ps].mode&GUILD_PERM_EXPEL) ) - return 0; //Expulsion permission - - //Can't leave inside guild castles. - if ((tsd = map_id2sd(account_id)) && - tsd->status.char_id == char_id && - map_flag_gvg2(tsd->bl.m)) - return 0; - - // find the member and perform expulsion - i = guild_getindex(g->guild, account_id, char_id); - if( i != -1 && strcmp(g->guild.member[i].name,g->guild.master) != 0 ) { //Can't expel the GL! - if (tsd) - guild_trade_bound_cancel(tsd); - intif_guild_leave(g->guild.guild_id,account_id,char_id,1,mes); + if( g == nullptr ){ + return false; } - return 0; + if( sd.status.guild_id != guild_id ){ + return false; + } + + if( !guild_has_permission( sd, GUILD_PERM_EXPEL ) ){ + return false; + } + + // TODO: for leave this is different messages + if( sd.bg_id || map_getmapflag( sd.bl.m, MF_GUILDLOCK ) ){ + clif_displaymessage( sd.fd, msg_txt( &sd, 228 ) ); // Guild modification is disabled on this map. + return false; + } + + map_session_data *tsd = map_id2sd( account_id ); + + //Can't leave inside guild castles. + if( tsd != nullptr && tsd->status.char_id == char_id && map_flag_gvg2( tsd->bl.m ) ){ + return false; + } + + // find the member and perform expulsion + int i = guild_getindex( g->guild, account_id, char_id ); + + if( i < 0 ){ + return false; + } + + // Can't expel the guild leader + if( strcmp( g->guild.member[i].name, g->guild.master ) == 0 ){ + return false; + } + + if( tsd != nullptr ){ + guild_trade_bound_cancel( *tsd ); + } + + return intif_guild_leave( g->guild.guild_id, account_id, char_id, 1, mes ); } /** @@ -1187,9 +1246,9 @@ int guild_member_withdraw(int guild_id, uint32 account_id, uint32 char_id, int f if(!flag) - clif_guild_leave(online_member_sd, name, mes); + clif_guild_leave( *online_member_sd, name, char_id, mes ); else - clif_guild_expulsion(online_member_sd, name, mes, account_id); + clif_guild_expulsion( *online_member_sd, name, char_id, mes ); // remove member from guild memset(&g->guild.member[i],0,sizeof(struct guild_member)); @@ -1473,7 +1532,7 @@ int guild_notice_changed(int guild_id,const char *mes1,const char *mes2) { for(i=0;iguild.max_member;i++){ map_session_data *sd = g->guild.member[i].sd; if(sd != nullptr) - clif_guild_notice(sd); + clif_guild_notice( *sd ); } return 0; } @@ -1689,7 +1748,7 @@ int guild_skillupack(int guild_id,uint16 skill_id,uint32 account_id) { // Inform all members for (i = 0; i < g->guild.max_member; i++) if ((sd = g->guild.member[i].sd) != nullptr) - clif_guild_skillinfo(sd); + clif_guild_skillinfo( *sd ); return 0; } @@ -2072,7 +2131,7 @@ int guild_broken(int guild_id,int flag) { sd->status.guild_id=0; sd->guild = nullptr; sd->state.gmaster_flag = 0; - clif_guild_broken(g->guild.member[i].sd,0); + clif_guild_broken( *sd, 0 ); clif_name_area(&sd->bl); // [LuzZza] status_change_end(&sd->bl,SC_LEADERSHIP); status_change_end(&sd->bl,SC_GLORYWOUNDS); @@ -2101,29 +2160,31 @@ int guild_broken(int guild_id,int flag) { * @param guild_id * @param sd New guild master */ -int guild_gm_change(int guild_id, uint32 char_id) { - char *name; +bool guild_gm_change( int guild_id, uint32 char_id, bool showMessage ){ + auto g = guild_search( guild_id ); + + if( g == nullptr ){ + return false; + } + int i; - auto g = guild_search(guild_id); - if (!g) - return 0; - - ARR_FIND(0, MAX_GUILD, i, g->guild.member[i].char_id == char_id); + ARR_FIND( 0, MAX_GUILD, i, g->guild.member[i].char_id == char_id ); if( i == MAX_GUILD ){ // Not part of the guild - return 0; + return false; } - name = g->guild.member[i].name; + char* name = g->guild.member[i].name; - if (strcmp(g->guild.master, name) == 0) //Nothing to change. - return 0; + // Nothing to change. + if( strcmp( g->guild.master, name ) == 0 ){ + return false; + } //Notify servers that master has changed. - intif_guild_change_gm(guild_id, name, strlen(name)+1); - return 1; + return intif_guild_change_gm( guild_id, name, strlen( name ) + 1 ); } /** Notification from Char server that a guild's master has changed. [Skotlex] @@ -2191,7 +2252,7 @@ int guild_gm_changed(int guild_id, uint32 account_id, uint32 char_id, time_t tim * @param sd Player who breaks the guild * @param name Guild name */ -int guild_break(map_session_data *sd,char *name) { +int guild_break( map_session_data& sd, char* name ){ struct unit_data *ud; int i; #ifdef BOUND_ITEMS @@ -2199,20 +2260,23 @@ int guild_break(map_session_data *sd,char *name) { int idxlist[MAX_INVENTORY]; #endif - nullpo_ret(sd); + auto& g = sd.guild; - auto &g = sd->guild; - - if (!g) + if( g == nullptr ){ return 0; + } + if (strcmp(g->guild.name,name) != 0) return 0; - if (!sd->state.gmaster_flag) + + if( !sd.state.gmaster_flag ){ return 0; + } + for (i = 0; i < g->guild.max_member; i++) { if( g->guild.member[i].account_id>0 && ( - g->guild.member[i].account_id!=sd->status.account_id || - g->guild.member[i].char_id!=sd->status.char_id )) + g->guild.member[i].account_id != sd.status.account_id || + g->guild.member[i].char_id != sd.status.char_id ) ) break; } if (i < g->guild.max_member) { @@ -2220,11 +2284,18 @@ int guild_break(map_session_data *sd,char *name) { return 0; } - if (g->instance_id) + // Guild locked. + if( map_getmapflag( sd.bl.m, MF_GUILDLOCK ) ){ + clif_displaymessage( sd.fd, msg_txt( &sd, 228 ) ); + return 0; + } + + if( g->instance_id ){ instance_destroy(g->instance_id); + } /* Regardless of char server allowing it, we clear the guild master's auras */ - if ((ud = unit_bl2ud(&sd->bl))) { + if( ( ud = unit_bl2ud( &sd.bl ) ) ){ std::vector> group; for (const auto su : ud->skillunits) { @@ -2245,9 +2316,9 @@ int guild_break(map_session_data *sd,char *name) { #ifdef BOUND_ITEMS //Guild bound item check - Removes the bound flag - j = pc_bound_chk(sd,BOUND_GUILD,idxlist); + j = pc_bound_chk( &sd, BOUND_GUILD, idxlist ); for(i = 0; i < j; i++) - pc_delitem(sd,idxlist[i],sd->inventory.u.items_inventory[idxlist[i]].amount,0,1,LOG_TYPE_BOUND_REMOVAL); + pc_delitem( &sd,idxlist[i], sd.inventory.u.items_inventory[idxlist[i]].amount, 0, 1, LOG_TYPE_BOUND_REMOVAL ); #endif intif_guild_break(g->guild.guild_id); @@ -2528,6 +2599,16 @@ bool guild_isallied(int guild_id, int guild_id2) { return( i < MAX_GUILDALLIANCE && g->guild.alliance[i].opposition == 0 ); } +bool guild_has_permission( map_session_data& sd, enum e_guild_permission permission ){ + int position = guild_getposition( sd ); + + if( position < 0 ){ + return false; + } + + return ( sd.guild->guild.position[position].mode & permission ) != 0; +} + void guild_flag_add(struct npc_data *nd) { int i; diff --git a/src/map/guild.hpp b/src/map/guild.hpp index 15c06feb26..16660ca42a 100644 --- a/src/map/guild.hpp +++ b/src/map/guild.hpp @@ -41,6 +41,7 @@ int guild_checkskill(const struct mmo_guild &g,int id); bool guild_check_skill_require(const struct mmo_guild &g,uint16 id); // [Komurka] int guild_checkcastles(const struct mmo_guild &g); // [MouseJstr] bool guild_isallied(int guild_id, int guild_id2); //Checks alliance based on guild Ids. [Skotlex] +bool guild_has_permission( map_session_data& sd, enum e_guild_permission permission ); void do_init_guild(void); std::shared_ptr guild_search(int guild_id); @@ -53,22 +54,20 @@ int guild_getposition(const map_session_data &sd); t_exp guild_payexp(map_session_data *sd,t_exp exp); t_exp guild_getexp(map_session_data *sd,t_exp exp); // [Celest] -int guild_create(map_session_data *sd, const char *name); +bool guild_create( map_session_data& sd, const char* name ); int guild_created(uint32 account_id,int guild_id); int guild_request_info(int guild_id); int guild_recv_noinfo(int guild_id); int guild_recv_info(const struct mmo_guild &sg); int guild_npc_request_info(int guild_id,const char *ev); -int guild_invite(map_session_data *sd,map_session_data *tsd); -int guild_reply_invite(map_session_data *sd,int guild_id,int flag); +bool guild_invite( map_session_data& sd, map_session_data* tsd ); +bool guild_reply_invite( map_session_data& sd, int guild_id, int flag ); void guild_member_joined(map_session_data *sd); int guild_member_added(int guild_id,uint32 account_id,uint32 char_id,int flag); -int guild_leave(map_session_data *sd,int guild_id, - uint32 account_id,uint32 char_id,const char *mes); +bool guild_leave( map_session_data& sd, int guild_id, uint32 account_id, uint32 char_id, const char *mes ); int guild_member_withdraw(int guild_id,uint32 account_id,uint32 char_id,int flag, const char *name,const char *mes); -int guild_expulsion(map_session_data *sd,int guild_id, - uint32 account_id,uint32 char_id,const char *mes); +bool guild_expulsion( map_session_data& sd, int guild_id, uint32 account_id, uint32 char_id, const char *mes ); void guild_skillup(map_session_data* sd, uint16 skill_id); void guild_block_skill(map_session_data *sd, int time); int guild_reqalliance(map_session_data *sd,map_session_data *tsd); @@ -94,9 +93,9 @@ int guild_send_message(map_session_data *sd, const char *mes, size_t len); int guild_recv_message( int guild_id, uint32 account_id, const char *mes, size_t len ); int guild_send_dot_remove(map_session_data *sd); int guild_skillupack(int guild_id,uint16 skill_id,uint32 account_id); -int guild_break(map_session_data *sd,char *name); +int guild_break( map_session_data& sd, char* name ); int guild_broken(int guild_id,int flag); -int guild_gm_change(int guild_id, uint32 char_id); +bool guild_gm_change(int guild_id, uint32 char_id, bool showMessage = false ); int guild_gm_changed(int guild_id, uint32 account_id, uint32 char_id, time_t time); void guild_castle_map_init(void); diff --git a/src/map/intif.cpp b/src/map/intif.cpp index aa8d8bff17..4838c4a3f8 100644 --- a/src/map/intif.cpp +++ b/src/map/intif.cpp @@ -846,15 +846,14 @@ int intif_guild_request_info(int guild_id) * @param m : Member to add to the guild * @return 0=error, 1=msg_sent */ -int intif_guild_addmember(int guild_id,struct guild_member *m) -{ +int intif_guild_addmember( int guild_id, struct guild_member& m ){ if (CheckForCharServer()) return 0; WFIFOHEAD(inter_fd,sizeof(struct guild_member)+8); WFIFOW(inter_fd,0) = 0x3032; WFIFOW(inter_fd,2) = sizeof(struct guild_member)+8; WFIFOL(inter_fd,4) = guild_id; - memcpy(WFIFOP(inter_fd,8),m,sizeof(struct guild_member)); + memcpy( WFIFOP( inter_fd, 8 ), &m, sizeof( struct guild_member ) ); WFIFOSET(inter_fd,WFIFOW(inter_fd,2)); return 1; } @@ -866,16 +865,16 @@ int intif_guild_addmember(int guild_id,struct guild_member *m) * @param len : size of the name * @return 0=error, 1=msg_sent */ -int intif_guild_change_gm( int guild_id, const char* name, size_t len ){ +bool intif_guild_change_gm( int guild_id, const char* name, size_t len ){ if (CheckForCharServer()) - return 0; + return false; WFIFOHEAD(inter_fd, len + 8); WFIFOW(inter_fd, 0)=0x3033; WFIFOW( inter_fd, 2 ) = static_cast( len + 8 ); WFIFOL(inter_fd, 4)=guild_id; safestrncpy(WFIFOCP(inter_fd,8),name,len); WFIFOSET(inter_fd,len+8); - return 1; + return true; } /** @@ -887,10 +886,9 @@ int intif_guild_change_gm( int guild_id, const char* name, size_t len ){ * @param mes : quitting message (max 40) * @return 0=error, 1=msg_sent */ -int intif_guild_leave(int guild_id,uint32 account_id,uint32 char_id,int flag,const char *mes) -{ +bool intif_guild_leave( int guild_id, uint32 account_id, uint32 char_id, int flag, const char *mes ){ if (CheckForCharServer()) - return 0; + return false; WFIFOHEAD(inter_fd, 55); WFIFOW(inter_fd, 0) = 0x3034; WFIFOL(inter_fd, 2) = guild_id; @@ -899,7 +897,7 @@ int intif_guild_leave(int guild_id,uint32 account_id,uint32 char_id,int flag,con WFIFOB(inter_fd,14) = flag; safestrncpy(WFIFOCP(inter_fd,15),mes,40); WFIFOSET(inter_fd,55); - return 1; + return true; } /** diff --git a/src/map/intif.hpp b/src/map/intif.hpp index ab52ae0b53..18a68561da 100644 --- a/src/map/intif.hpp +++ b/src/map/intif.hpp @@ -52,12 +52,12 @@ int intif_party_sharelvlupdate(unsigned int share_lvl); int intif_guild_create(const char *name, const struct guild_member *master); int intif_guild_request_info(int guild_id); -int intif_guild_addmember(int guild_id, struct guild_member *m); -int intif_guild_leave(int guild_id, uint32 account_id, uint32 char_id, int flag, const char *mes); +int intif_guild_addmember( int guild_id, struct guild_member& m ); +bool intif_guild_leave(int guild_id, uint32 account_id, uint32 char_id, int flag, const char *mes); int intif_guild_memberinfoshort(int guild_id, uint32 account_id, uint32 char_id, int online, int lv, int class_); int intif_guild_break(int guild_id); int intif_guild_message(int guild_id, uint32 account_id, const char *mes, size_t len); -int intif_guild_change_gm( int guild_id, const char* name, size_t len ); +bool intif_guild_change_gm( int guild_id, const char* name, size_t len ); int intif_guild_change_basicinfo(int guild_id, int type, const void *data, int len); int intif_guild_change_memberinfo(int guild_id, uint32 account_id, uint32 char_id, int type, const void *data, int len); int intif_guild_position(int guild_id, int idx, struct guild_position *p); diff --git a/src/map/packets.hpp b/src/map/packets.hpp index f571c44b92..e364600a6e 100644 --- a/src/map/packets.hpp +++ b/src/map/packets.hpp @@ -1039,6 +1039,83 @@ struct PACKET_ZC_DELETEITEM_FROM_MCSTORE { DEFINE_PACKET_HEADER(ZC_DELETEITEM_FROM_MCSTORE, 0x137); #endif +struct PACKET_CZ_REQ_BAN_GUILD{ + int16 packetType; + uint32 guild_id; + uint32 AID; + uint32 CID; + char message[40]; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(CZ_REQ_BAN_GUILD, 0x15b); + +struct PACKET_CZ_REQ_LEAVE_GUILD{ + int16 packetType; + uint32 guild_id; + uint32 AID; + uint32 CID; + char message[40]; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(CZ_REQ_LEAVE_GUILD, 0x159); + +struct PACKET_CZ_REQ_DISORGANIZE_GUILD{ + int16 packetType; + char key[40]; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(CZ_REQ_DISORGANIZE_GUILD, 0x15d); + +struct PACKET_ZC_ACK_DISORGANIZE_GUILD_RESULT{ + int16 packetType; + int32 result; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(ZC_ACK_DISORGANIZE_GUILD_RESULT, 0x15e); + +struct PACKET_ZC_RESULT_MAKE_GUILD{ + int16 packetType; + uint8 result; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(ZC_RESULT_MAKE_GUILD, 0x167); + +struct PACKET_CZ_REQ_JOIN_GUILD{ + int16 packetType; + uint32 AID; + uint32 inviter_AID; + uint32 inviter_CID; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(CZ_REQ_JOIN_GUILD, 0x168); + +struct PACKET_ZC_ACK_REQ_JOIN_GUILD{ + int16 packetType; + uint8 result; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(ZC_ACK_REQ_JOIN_GUILD, 0x169); + +struct PACKET_ZC_REQ_JOIN_GUILD{ + int16 packetType; + uint32 guild_id; + char guild_name[NAME_LENGTH]; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(ZC_REQ_JOIN_GUILD, 0x16a); + +struct PACKET_CZ_JOIN_GUILD{ + int16 packetType; + uint32 guild_id; + int32 answer; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(CZ_JOIN_GUILD, 0x16b); + +struct PACKET_ZC_GUILD_NOTICE{ + int16 packetType; + char subject[60]; + char notice[120]; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(ZC_GUILD_NOTICE, 0x16f); + +struct PACKET_CZ_REQ_JOIN_GUILD2{ + int16 packetType; + char name[NAME_LENGTH]; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(CZ_REQ_JOIN_GUILD2, 0x916); + // 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/unit.cpp b/src/map/unit.cpp index a0bf233621..2d66a7b269 100644 --- a/src/map/unit.cpp +++ b/src/map/unit.cpp @@ -3168,7 +3168,7 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file, party_reply_invite(sd,sd->party_invite,0); if(sd->guild_invite > 0) - guild_reply_invite(sd,sd->guild_invite,0); + guild_reply_invite( *sd, sd->guild_invite, 0 ); if(sd->guild_alliance > 0) guild_reply_reqalliance(sd,sd->guild_alliance_account,0);