瀏覽代碼

- 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://svn.code.sf.net/p/rathena/svn/trunk@7375 54d463be-8e91-2dee-dedb-b68131a5f0ec

skotlex 19 年之前
父節點
當前提交
07af745abf
共有 10 個文件被更改,包括 119 次插入67 次删除
  1. 7 0
      Changelog-Trunk.txt
  2. 12 0
      conf-tmpl/map_athena.conf
  3. 37 39
      src/map/atcommand.c
  4. 5 0
      src/map/map.c
  5. 1 0
      src/map/map.h
  6. 2 1
      src/map/pet.c
  7. 39 17
      src/map/storage.c
  8. 5 2
      src/map/trade.c
  9. 7 6
      src/map/unit.c
  10. 4 2
      src/map/vending.c

+ 7 - 0
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

+ 12 - 0
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
 

+ 37 - 39
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;
 }
 

+ 5 - 0
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) {

+ 1 - 0
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]

+ 2 - 1
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);

+ 39 - 17
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;
 }

+ 5 - 2
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);
+	}
 }

+ 7 - 6
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;

+ 4 - 2
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)
 	{