summaryrefslogtreecommitdiff
path: root/src/map/map.c
diff options
context:
space:
mode:
authorskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2006-07-07 16:28:41 +0000
committerskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2006-07-07 16:28:41 +0000
commit959387743887e9a57cf31b950f23be9bd34b919f (patch)
tree8a472ad961a9d3df5dea73f84ae597735b02e52e /src/map/map.c
parentae287ef89682be736bf1281d758e5cd3bad56895 (diff)
downloadhercules-959387743887e9a57cf31b950f23be9bd34b919f.tar.gz
hercules-959387743887e9a57cf31b950f23be9bd34b919f.tar.bz2
hercules-959387743887e9a57cf31b950f23be9bd34b919f.tar.xz
hercules-959387743887e9a57cf31b950f23be9bd34b919f.zip
- Okay, added a chrif_save_ack packet to the char-server so now the map server will know once a character was "final saved", and only then the character will be removed from memory. On char-server reconnection, all chars that are in final-save state are resent to save (if they are still in memory, it's because the ack hasn't gotten here from the char-server). This should effectively block all dupe problems due to heavy inter-server lag, however as it's untested, it currently prints some debug messages when people are saved and then removed from memory. Need testers so this can be debugged and merged to stable!
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@7568 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map/map.c')
-rw-r--r--src/map/map.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/src/map/map.c b/src/map/map.c
index c5a4bb314..9c23215a2 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -1657,7 +1657,6 @@ int map_quit(struct map_session_data *sd) {
//nullpo_retr(0, sd); //Utterly innecessary, all invokations to this function already have an SD non-null check.
//Learn to use proper coding and stop relying on nullpo_'s for safety :P [Skotlex]
-
if(!sd->state.waitingdisconnect) {
if (sd->npc_timer_id != -1) //Cancel the event timer.
npc_timerevent_quit(sd);
@@ -1680,7 +1679,6 @@ int map_quit(struct map_session_data *sd) {
//Do we really need to remove the name?
idb_remove(charid_db,sd->status.char_id);
idb_remove(id_db,sd->bl.id);
- idb_remove(pc_db,sd->bl.id);
if(sd->reg)
{ //Double logout already freed pointer fix... [Skotlex]
@@ -1694,12 +1692,38 @@ int map_quit(struct map_session_data *sd) {
sd->regstr = NULL;
sd->regstr_num = 0;
}
+ if(sd->fd)
+ { //Player will be free'd on save-ack. [Skotlex]
+ if (session[sd->fd] && session[sd->fd]->session_data == sd)
+ session[sd->fd]->session_data = NULL;
+ sd->fd = 0;
+ }
+
+ return 0;
+}
- if(!sd->fd) //There is no session connected, and as such socket.c won't free the data, we must do it. [Skotlex]
+void map_quit_ack(struct map_session_data *sd) {
+ if (sd && sd->state.finalsave) {
+ idb_remove(pc_db,sd->status.account_id);
aFree(sd);
+ ShowDebug("Final Save Ack for character %d:%d\n", sd->status.account_id, sd->status.char_id);
+ }
+}
+
+static int do_reconnect_map_sub(DBKey key,void *data,va_list va) {
+ struct map_session_data *sd = (TBL_PC*)data;
+ if (sd->state.finalsave) {
+ sd->state.finalsave = 0;
+ chrif_save(sd, 1); //Resend to save!
+ return 1;
+ }
return 0;
}
+void do_reconnect_map(void) {
+ pc_db->foreach(pc_db,do_reconnect_map_sub);
+}
+
/*==========================================
* id番?のPCを探す。居なければNULL
*------------------------------------------