From e07b2da8d90f955dbe01737e9bfdb73ddaa3bd83 Mon Sep 17 00:00:00 2001 From: skotlex Date: Wed, 28 Jun 2006 16:09:13 +0000 Subject: - Cleaned up a bit the code for @item - Fixed character/storage being sent to be saved TWICE when you logged out while the storage is opened. - 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. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@7375 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-Trunk.txt | 7 +++++ conf-tmpl/map_athena.conf | 12 ++++++++ src/map/atcommand.c | 76 +++++++++++++++++++++++------------------------ src/map/map.c | 5 ++++ src/map/map.h | 1 + src/map/pet.c | 3 +- src/map/storage.c | 56 +++++++++++++++++++++++----------- src/map/trade.c | 7 +++-- src/map/unit.c | 13 ++++---- src/map/vending.c | 6 ++-- 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) { -- cgit v1.2.3-70-g09d2