From 1152ef720d3ef010a40ddf3cb5fc63fbc2f3e030 Mon Sep 17 00:00:00 2001 From: shennetsind Date: Thu, 11 Apr 2013 19:24:59 -0300 Subject: Fixed Bug #7158 http://hercules.ws/board/tracker/issue-7158-memory-leak/ Signed-off-by: shennetsind --- src/map/atcommand.c | 7 +----- src/map/clif.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/map/clif.h | 2 ++ src/map/guild.c | 8 ++---- src/map/map.c | 24 +----------------- 5 files changed, 76 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/map/atcommand.c b/src/map/atcommand.c index bc76859e9..1c0542066 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -5708,12 +5708,7 @@ ACMD_FUNC(autotrade) { } } - if( sd->channel_count ) { - for( i = 0; i < sd->channel_count; i++ ) { - if( sd->channels[i] != NULL ) - clif->chsys_left(sd->channels[i],sd); - } - } + clif->chsys_quit(sd); clif->authfail_fd(sd->fd, 15); diff --git a/src/map/clif.c b/src/map/clif.c index 56fdb4193..109ce7b9e 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -9901,6 +9901,74 @@ void clif_hercules_chsys_left(struct hChSysCh *channel, struct map_session_data } +void clif_hercules_chsys_quitg(struct map_session_data *sd) { + unsigned char i; + struct hChSysCh *channel = NULL; + + for( i = 0; i < sd->channel_count; i++ ) { + if( (channel = sd->channels[i] ) != NULL && channel->type == hChSys_ALLY ) { + idb_remove(channel->users,sd->status.char_id); + + if( channel == sd->gcbind ) + sd->gcbind = NULL; + + if( !db_size(channel->users) && channel->type == hChSys_PRIVATE ) { + clif->chsys_delete(channel); + } else if( !hChSys.closing && (channel->opt & hChSys_OPT_ANNOUNCE_JOIN) ) { + char message[60]; + sprintf(message, "#%s '%s' left",channel->name,sd->status.name); + clif->chsys_msg(channel,sd,message); + } + sd->channels[i] = NULL; + } + } + + if( i < sd->channel_count ) { + unsigned char cursor = 0; + for( i = 0; i < sd->channel_count; i++ ) { + if( sd->channels[i] == NULL ) + continue; + if( cursor != i ) { + sd->channels[cursor] = sd->channels[i]; + } + cursor++; + } + if ( !(sd->channel_count = cursor) ) { + aFree(sd->channels); + sd->channels = NULL; + } + } + +} + + +void clif_hercules_chsys_quit(struct map_session_data *sd) { + unsigned char i; + struct hChSysCh *channel = NULL; + + for( i = 0; i < sd->channel_count; i++ ) { + if( (channel = sd->channels[i] ) != NULL ) { + idb_remove(channel->users,sd->status.char_id); + + if( channel == sd->gcbind ) + sd->gcbind = NULL; + + if( !db_size(channel->users) && channel->type == hChSys_PRIVATE ) { + clif->chsys_delete(channel); + } else if( !hChSys.closing && (channel->opt & hChSys_OPT_ANNOUNCE_JOIN) ) { + char message[60]; + sprintf(message, "#%s '%s' left",channel->name,sd->status.name); + clif->chsys_msg(channel,sd,message); + } + + } + } + + sd->channel_count = 0; + aFree(sd->channels); + sd->channels = NULL; +} + /// Request for an action. /// 0089 .L .B (CZ_REQUEST_ACT) /// 0437 .L .B (CZ_REQUEST_ACT2) @@ -17160,6 +17228,8 @@ void clif_defaults(void) { clif->chsys_left = clif_hercules_chsys_left; clif->chsys_delete = clif_hercules_chsys_delete; clif->chsys_mjoin = clif_hercules_chsys_mjoin; + clif->chsys_quit = clif_hercules_chsys_quit; + clif->chsys_quitg = clif_hercules_chsys_quitg; clif->cashshop_load = clif_cashshop_db; /*------------------------ *- Parse Incoming Packet diff --git a/src/map/clif.h b/src/map/clif.h index 90915e1c9..ecdf17429 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -858,6 +858,8 @@ struct clif_interface { void (*chsys_left) (struct hChSysCh *channel, struct map_session_data *sd); void (*chsys_delete) (struct hChSysCh *channel); void (*chsys_mjoin) (struct map_session_data *sd); + void (*chsys_quit) (struct map_session_data *sd); + void (*chsys_quitg) (struct map_session_data *sd); /*------------------------ *- Parse Incoming Packet *------------------------*/ diff --git a/src/map/guild.c b/src/map/guild.c index 9b128c4e1..321560420 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -902,17 +902,13 @@ int guild_member_withdraw(int guild_id, int account_id, int char_id, int flag, c clif->guild_memberlist(online_member_sd); // update char, if online - if(sd != NULL && sd->status.guild_id == guild_id) - { + if(sd != NULL && sd->status.guild_id == guild_id) { // do stuff that needs the guild_id first, BEFORE we wipe it if (sd->state.storage_flag == 2) //Close the guild storage. storage_guild_storageclose(sd); guild_send_dot_remove(sd); if( hChSys.ally ) { - for (i = 0; i < sd->channel_count; i++) { - if( sd->channels[i] && sd->channels[i]->type == hChSys_ALLY ) - clif->chsys_left(sd->channels[i],sd); - } + clif->chsys_quitg(sd); } sd->status.guild_id = 0; sd->guild = NULL; diff --git a/src/map/map.c b/src/map/map.c index 03ed08f8b..cdbe591f5 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -1699,33 +1699,11 @@ int map_quit(struct map_session_data *sd) { unit_remove_map(&sd->ed->bl,CLR_TELEPORT); } - if( hChSys.ally && sd->status.guild_id ) { - struct guild *g = sd->guild, *sg; - if( g ) { - if( idb_exists(((struct hChSysCh *)g->channel)->users, sd->status.char_id) ) - clif->chsys_left((struct hChSysCh *)g->channel,sd); - for (i = 0; i < MAX_GUILDALLIANCE; i++) { - if( g->alliance[i].guild_id && (sg = guild_search(g->alliance[i].guild_id) ) ) { - if( idb_exists(((struct hChSysCh *)sg->channel)->users, sd->status.char_id) ) - clif->chsys_left((struct hChSysCh *)sg->channel,sd); - break; - } - } - } - } - if( hChSys.local && map[sd->bl.m].channel && idb_exists(map[sd->bl.m].channel->users, sd->status.char_id) ) { clif->chsys_left(map[sd->bl.m].channel,sd); } - if( sd->channel_count ) { - for( i = 0; i < sd->channel_count; i++ ) { - if( sd->channels[i] != NULL ) - clif->chsys_left(sd->channels[i],sd); - } - if( hChSys.closing ) - aFree(sd->channels); - } + clif->chsys_quit(sd); unit_remove_map_pc(sd,CLR_TELEPORT); -- cgit v1.2.3-60-g2f50