summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog-Trunk.txt7
-rw-r--r--conf-tmpl/map_athena.conf12
-rw-r--r--src/map/atcommand.c76
-rw-r--r--src/map/map.c5
-rw-r--r--src/map/map.h1
-rw-r--r--src/map/pet.c3
-rw-r--r--src/map/storage.c56
-rw-r--r--src/map/trade.c7
-rw-r--r--src/map/unit.c13
-rw-r--r--src/map/vending.c6
10 files changed, 119 insertions, 67 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt
index acee5c4bb..532210a4d 100644
--- a/Changelog-Trunk.txt
+++ b/Changelog-Trunk.txt
@@ -4,6 +4,13 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
2006/05/28
+ * Cleaned up a bit the code for @item [Skotlex]
+ * Fixed character/storage being sent to be saved TWICE when you logged out
+ while the storage is opened. [Skotlex]
+ * Added save_settings map config. Specifies after which events do
+ characters get saved (defaults to all): 1 - Trade successful, 2 - Vending
+ transaction, 4 - Closing storage/guild storage, 8 - hatching a pet.
+ [Skotlex]
* Changed the mob drop rate adjust function to receive a signed int
argument. Probably will fix those drops with 0% becoming 100% [Skotlex]
* Corrected Musical Strike having a different damage equation from Throw
diff --git a/conf-tmpl/map_athena.conf b/conf-tmpl/map_athena.conf
index e320891cb..3277d7c73 100644
--- a/conf-tmpl/map_athena.conf
+++ b/conf-tmpl/map_athena.conf
@@ -95,6 +95,18 @@ console: off
// Database autosave time, in seconds.
autosave_time: 60
+// Apart from the autosave_time, players will also get saved when involved
+// in the following (add as needed):
+// 1: after every successful trade
+// 2: after very vending transaction
+// 4: after closing storage/guild storage.
+// 8: After hatching/returning to egg a pet.
+// NOTE: These settings decrease the chance of dupes/lost items when there's a
+// server crash at the expense of increasing the map/char server lag. If your
+// server rarely crashes, but experiences interserver lag, you may want to set
+// these off.
+save_settings: 15
+
// Message of the day file, when a character logs on, this message is displayed.
motd_txt: conf/motd.txt
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 192956bd3..9b8eda327 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -2556,50 +2556,48 @@ int atcommand_item(
if (number <= 0)
number = 1;
- item_id = 0;
- if ((item_data = itemdb_searchname(item_name)) != NULL ||
- (item_data = itemdb_exists(atoi(item_name))) != NULL)
- item_id = item_data->nameid;
-
- if (item_id >= 500) {
- get_count = number;
- // check pet egg
- pet_id = search_petDB_index(item_id, PET_EGG);
- if (item_data->type == 4 || item_data->type == 5 ||
- item_data->type == 7 || item_data->type == 8) {
- get_count = 1;
- }
- for (i = 0; i < number; i += get_count) {
- // if pet egg
- if (pet_id >= 0) {
- sd->catch_target_class = pet_db[pet_id].class_;
- intif_create_pet(sd->status.account_id, sd->status.char_id,
- (short)pet_db[pet_id].class_, (short)mob_db(pet_db[pet_id].class_)->lv,
- (short)pet_db[pet_id].EggID, 0, (short)pet_db[pet_id].intimate,
- 100, 0, 1, pet_db[pet_id].jname);
- // if not pet egg
- } else {
- memset(&item_tmp, 0, sizeof(item_tmp));
- item_tmp.nameid = item_id;
- item_tmp.identify = 1;
+ if ((item_data = itemdb_searchname(item_name)) == NULL &&
+ (item_data = itemdb_exists(atoi(item_name))) == NULL)
+ {
+ clif_displaymessage(fd, msg_table[19]); // Invalid item ID or name.
+ return -1;
+ }
- if ((flag = pc_additem((struct map_session_data*)sd, &item_tmp, get_count)))
- clif_additem((struct map_session_data*)sd, 0, 0, flag);
- }
- }
+ item_id = item_data->nameid;
+ get_count = number;
+ // check pet egg
+ pet_id = search_petDB_index(item_id, PET_EGG);
+ if (item_data->type == 4 || item_data->type == 5 ||
+ item_data->type == 7 || item_data->type == 8) {
+ get_count = 1;
+ }
+ for (i = 0; i < number; i += get_count) {
+ // if pet egg
+ if (pet_id >= 0) {
+ sd->catch_target_class = pet_db[pet_id].class_;
+ intif_create_pet(sd->status.account_id, sd->status.char_id,
+ (short)pet_db[pet_id].class_,
+ (short)mob_db(pet_db[pet_id].class_)->lv,
+ (short)pet_db[pet_id].EggID, 0,
+ (short)pet_db[pet_id].intimate,
+ 100, 0, 1, pet_db[pet_id].jname);
+ // if not pet egg
+ } else {
+ memset(&item_tmp, 0, sizeof(item_tmp));
+ item_tmp.nameid = item_id;
+ item_tmp.identify = 1;
- //Logs (A)dmins items [Lupus]
- if(log_config.pick > 0 ) {
- log_pick(sd, "A", 0, item_id, number, NULL);
+ if ((flag = pc_additem(sd, &item_tmp, get_count)))
+ clif_additem(sd, 0, 0, flag);
}
- //Logs
-
- clif_displaymessage(fd, msg_table[18]); // Item created.
- } else {
- clif_displaymessage(fd, msg_table[19]); // Invalid item ID or name.
- return -1;
}
+ //Logs (A)dmins items [Lupus]
+ if(log_config.pick > 0 )
+ log_pick(sd, "A", 0, item_id, number, NULL);
+ //Logs
+
+ clif_displaymessage(fd, msg_table[18]); // Item created.
return 0;
}
diff --git a/src/map/map.c b/src/map/map.c
index 0270b509d..98af550c2 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -168,6 +168,7 @@ int map_num = 0;
int map_port=0;
int autosave_interval = DEFAULT_AUTOSAVE_INTERVAL;
+int save_settings = 0xFFFF;
int charsave_method = 0; //Default 'OLD' Save method (SQL ONLY!) [Sirius]
int agit_flag = 0;
int night_flag = 0; // 0=day, 1=night [Yor]
@@ -1664,6 +1665,8 @@ int map_quit(struct map_session_data *sd) {
npc_timerevent_quit(sd);
if (sd->state.event_disconnect)
npc_script_event(sd, NPCE_LOGOUT);
+
+ sd->state.waitingdisconnect = 1;
if (sd->pd) unit_free(&sd->pd->bl);
unit_free(&sd->bl);
chrif_save(sd,1);
@@ -3306,6 +3309,8 @@ int map_config_read(char *cfgName) {
autosave_interval = atoi(w2) * 1000;
if (autosave_interval <= 0)
autosave_interval = DEFAULT_AUTOSAVE_INTERVAL;
+ } else if (strcmpi(w1, "save_settings") == 0) {
+ save_settings = atoi(w2);
} else if (strcmpi(w1, "motd_txt") == 0) {
strcpy(motd_txt, w2);
} else if (strcmpi(w1, "help_txt") == 0) {
diff --git a/src/map/map.h b/src/map/map.h
index 7cdbb00cf..a0d19f04e 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -1211,6 +1211,7 @@ struct chat_data {
extern struct map_data map[];
extern int map_num;
extern int autosave_interval;
+extern int save_settings;
extern int agit_flag;
extern int night_flag; // 0=day, 1=night [Yor]
extern int kick_on_disconnect; //To allow inter-server reconnections without kicking players out [Skotlex]
diff --git a/src/map/pet.c b/src/map/pet.c
index 2c21b85b8..0bde801ae8 100644
--- a/src/map/pet.c
+++ b/src/map/pet.c
@@ -450,7 +450,8 @@ int pet_birth_process(struct map_session_data *sd)
}
intif_save_petdata(sd->status.account_id,&sd->pet);
- chrif_save(sd,0); //FIXME: As before, is it REALLY Needed to save the char for hatching a pet? [Skotlex]
+ if (save_settings&8)
+ chrif_save(sd,0); //FIXME: As before, is it REALLY Needed to save the char for hatching a pet? [Skotlex]
map_addblock(&sd->pd->bl);
clif_spawn(&sd->pd->bl);
diff --git a/src/map/storage.c b/src/map/storage.c
index 211bdb9ec..0be5d756d 100644
--- a/src/map/storage.c
+++ b/src/map/storage.c
@@ -353,8 +353,12 @@ int storage_storageclose(struct map_session_data *sd)
clif_storageclose(sd);
if (stor->storage_status)
- chrif_save(sd,0); //This will invoke the storage save function as well. [Skotlex]
-
+ {
+ if (save_settings&4)
+ chrif_save(sd,0); //Invokes the storage saving as well.
+ else
+ storage_storage_save(sd->status.account_id, 0);
+ }
stor->storage_status=0;
sd->state.storage_flag=0;
return 0;
@@ -369,14 +373,17 @@ int storage_storage_quit(struct map_session_data *sd, int flag)
struct storage *stor;
nullpo_retr(0, sd);
-
- stor = account2storage2(sd->status.account_id);
- if(stor) {
- chrif_save(sd, flag); //Invokes the storage saving as well.
- stor->storage_status = 0;
- sd->state.storage_flag = 0;
+ nullpo_retr(0, stor=account2storage2(sd->status.account_id));
+
+ if (stor->storage_status)
+ {
+ if (save_settings&4)
+ chrif_save(sd, flag); //Invokes the storage saving as well.
+ else
+ storage_storage_save(sd->status.account_id, flag);
}
-
+ stor->storage_status = 0;
+ sd->state.storage_flag = 0;
return 0;
}
@@ -702,8 +709,13 @@ int storage_guild_storageclose(struct map_session_data *sd)
nullpo_retr(0, stor=guild2storage2(sd->status.guild_id));
clif_storageclose(sd);
- chrif_save(sd, 0); //This one also saves the storage. [Skotlex]
-
+ if (stor->storage_status)
+ {
+ if (save_settings&4)
+ chrif_save(sd, 0); //This one also saves the storage. [Skotlex]
+ else
+ storage_guild_storagesave(sd->status.account_id, sd->status.guild_id);
+ }
stor->storage_status=0;
sd->state.storage_flag = 0;
@@ -716,15 +728,25 @@ int storage_guild_storage_quit(struct map_session_data *sd,int flag)
nullpo_retr(0, sd);
nullpo_retr(0, stor=guild2storage2(sd->status.guild_id));
+
+ if(flag)
+ { //Only during a guild break flag is 1 (don't save storage)
+ sd->state.storage_flag = 0;
+ stor->storage_status = 0;
+ clif_storageclose(sd);
+ if (save_settings&4)
+ chrif_save(sd,0);
+ return 0;
+ }
+ if(stor->storage_status) {
+ if (save_settings&4)
+ chrif_save(sd,0);
+ else
+ storage_guild_storagesave(sd->status.account_id,sd->status.guild_id);
+ }
sd->state.storage_flag = 0;
stor->storage_status = 0;
- chrif_save(sd,flag);
- if(!flag) //Only during a guild break flag is 1.
- storage_guild_storagesave(sd->status.account_id,sd->status.guild_id);
- else //When the guild was broken, close the storage of he who has it open.
- clif_storageclose(sd);
-
return 0;
}
diff --git a/src/map/trade.c b/src/map/trade.c
index 236be38c2..26f2c03b0 100644
--- a/src/map/trade.c
+++ b/src/map/trade.c
@@ -531,6 +531,9 @@ void trade_tradecommit(struct map_session_data *sd) {
clif_tradecompleted(sd, 0);
clif_tradecompleted(tsd, 0);
// save both player to avoid crash: they always have no advantage/disadvantage between the 2 players
- chrif_save(sd,0); // do pc_makesavestatus and save storage too
- chrif_save(tsd,0); // do pc_makesavestatus and save storage too
+ if (save_settings&1)
+ {
+ chrif_save(sd,0);
+ chrif_save(tsd,0);
+ }
}
diff --git a/src/map/unit.c b/src/map/unit.c
index 0ca1e2559..5137d5f71 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -1508,11 +1508,13 @@ int unit_remove_map(struct block_list *bl, int clrtype) {
trade_tradecancel(sd);
if(sd->vender_id)
vending_closevending(sd);
- if(sd->state.storage_flag == 1)
- storage_storage_quit(sd,0);
- else if (sd->state.storage_flag == 2)
- storage_guild_storage_quit(sd,0);
-
+ if(!sd->state.waitingdisconnect)
+ { //when quitting, let the final chrif_save handle storage saving.
+ if(sd->state.storage_flag == 1)
+ storage_storage_quit(sd,0);
+ else if (sd->state.storage_flag == 2)
+ storage_guild_storage_quit(sd,0);
+ }
if(sd->party_invite>0)
party_reply_invite(sd,sd->party_invite_account,0);
if(sd->guild_invite>0)
@@ -1619,7 +1621,6 @@ int unit_free(struct block_list *bl) {
pc_delspiritball(sd,sd->spiritball,1);
chrif_save_scdata(sd); //Save status changes, then clear'em out from memory. [Skotlex]
pc_makesavestatus(sd);
- sd->state.waitingdisconnect = 1;
pc_clean_skilltree(sd);
} else if( bl->type == BL_PET ) {
struct pet_data *pd = (struct pet_data*)bl;
diff --git a/src/map/vending.c b/src/map/vending.c
index 38f5c848e..4a2de7ffc 100644
--- a/src/map/vending.c
+++ b/src/map/vending.c
@@ -180,8 +180,10 @@ void vending_purchasereq(struct map_session_data *sd,int len,int id,unsigned cha
}
//Always save BOTH: buyer and customer
- chrif_save(sd,0);
- chrif_save(vsd,0);
+ if (save_settings&2) {
+ chrif_save(sd,0);
+ chrif_save(vsd,0);
+ }
//check for @AUTOTRADE users [durf]
if (vsd->state.autotrade)
{