Просмотр исходного кода

Modified storage data loading
* storage is now loaded/saved along with character status
* as a consequence, a lot of storage handling code was removed
* there is no more locking done within storage data
* mapservers no longer cache the data (solves muiltimapserver exploit)
* loading storage on char select may decrease charserver performance

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@12950 54d463be-8e91-2dee-dedb-b68131a5f0ec

ultramage 17 лет назад
Родитель
Сommit
4546c7fc0a

+ 7 - 1
Changelog-Trunk.txt

@@ -3,9 +3,15 @@ Date	Added
 AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
+2008/07/13
+	* Modified storage data loading (bugreport:1425) [ultramage]
+	- storage is now loaded/saved along with character status
+	- as a consequence, a lot of storage handling code was removed
+	- there is no more locking done within storage data
+	- mapservers no longer cache the data (solves muiltimapserver exploit)
+	- loading storage on char select may decrease charserver performance
 2008/07/12
 	* Fixed a bad check on NPC_EVILLAND, actually healing players instead of doing damage. [Brainstorm]
-
 2008/07/10
 	* Users can't click floating npcs directly. (quick fix for bugreport:1814) [FlavioJS]
 2008/07/09

+ 6 - 0
src/char/char.c

@@ -1003,6 +1003,8 @@ int mmo_char_init(void)
 
 		ret = mmo_char_fromstr(line, &char_dat[char_num].status, char_dat[char_num].global, &char_dat[char_num].global_num);
 
+		// load storage
+		storage_load(char_dat[char_num].status.account_id, &char_dat[char_num].status.storage);
 		// Initialize friends list
 		parse_friend_txt(&char_dat[char_num].status);  // Grab friends for the character
 		// Initialize hotkey list
@@ -2774,7 +2776,11 @@ int parse_frommap(int fd)
 					break;
 			}
 			if (i != char_num)
+			{
 				memcpy(&char_dat[i].status, RFIFOP(fd,13), sizeof(struct mmo_charstatus));
+				storage_save(char_dat[i].status.account_id, &char_dat[i].status.storage);
+			}
+
 			if (RFIFOB(fd,12))
 			{	//Flag, set character offline. [Skotlex]
 				set_char_offline(RFIFOL(fd,8),RFIFOL(fd,4));

+ 20 - 53
src/char/int_storage.c

@@ -32,7 +32,7 @@ int storage_tostr(char* str, struct storage_data* p)
 {
 	int i,j,f=0;
 	char *str_p = str;
-	str_p += sprintf(str_p,"%d,%d\t",p->account_id,p->storage_amount);
+	str_p += sprintf(str_p, "%d,%d\t", p->account_id, p->storage_amount);
 
 	for(i=0;i<MAX_STORAGE;i++)
 		if( (p->items[i].nameid) && (p->items[i].amount) )
@@ -176,7 +176,7 @@ static void* create_storage(DBKey key, va_list args)
 // アカウントから倉庫データインデックスを得る(新規倉庫追加可能)
 struct storage_data *account2storage(int account_id)
 {
-	return (struct storage_data*)idb_ensure(storage_db, account_id, create_storage);
+	return (struct storage_data*)idb_get(storage_db, account_id);
 }
 
 static void* create_guildstorage(DBKey key, va_list args) {
@@ -194,6 +194,24 @@ struct guild_storage *guild2storage(int guild_id)
 	return gs;
 }
 
+// loads storage data into the provided data structure
+bool storage_load(int account_id, struct storage_data* storage)
+{
+	struct storage_data* s = account2storage(account_id);
+	if( s != NULL )
+		memcpy(storage, s, sizeof(struct storage_data));
+	return( s != NULL );
+}
+
+// writes provided data into storage cache
+bool storage_save(int account_id, struct storage_data* storage)
+{
+	struct storage_data* s = account2storage(account_id);
+	if( s != NULL )
+		memcpy(s, storage, sizeof(struct storage_data));
+	return( s != NULL );
+}
+
 //---------------------------------------------------------
 // 倉庫データを読み込む
 int inter_storage_init()
@@ -359,29 +377,6 @@ int inter_guild_storage_delete(int guild_id)
 //---------------------------------------------------------
 // map serverへの通信
 
-// 倉庫データの送信
-int mapif_load_storage(int fd,int account_id)
-{
-	struct storage_data *s=account2storage(account_id);
-	WFIFOHEAD(fd, sizeof(struct storage_data)+8);
-	WFIFOW(fd,0)=0x3810;
-	WFIFOW(fd,2)=sizeof(struct storage_data)+8;
-	WFIFOL(fd,4)=account_id;
-	memcpy(WFIFOP(fd,8),s,sizeof(struct storage_data));
-	WFIFOSET(fd,WFIFOW(fd,2));
-	return 0;
-}
-// 倉庫データ保存完了送信
-int mapif_save_storage_ack(int fd,int account_id)
-{
-	WFIFOHEAD(fd,7);
-	WFIFOW(fd,0)=0x3811;
-	WFIFOL(fd,2)=account_id;
-	WFIFOB(fd,6)=0;
-	WFIFOSET(fd,7);
-	return 0;
-}
-
 int mapif_load_guild_storage(int fd,int account_id,int guild_id)
 {
 	struct guild_storage *gs=guild2storage(guild_id);
@@ -417,32 +412,6 @@ int mapif_save_guild_storage_ack(int fd,int account_id,int guild_id,int fail)
 //---------------------------------------------------------
 // map serverからの通信
 
-// 倉庫データ要求受信
-int mapif_parse_LoadStorage(int fd)
-{
-	RFIFOHEAD(fd);
-	mapif_load_storage(fd,RFIFOL(fd,2));
-	return 0;
-}
-// 倉庫データ受信&保存
-int mapif_parse_SaveStorage(int fd)
-{
-	struct storage_data *s;
-	int account_id, len;
-	RFIFOHEAD(fd);
-	account_id=RFIFOL(fd,4);
-	len=RFIFOW(fd,2);
-	if(sizeof(struct storage_data)!=len-8){
-		ShowError("inter storage: data size error %d %d\n",sizeof(struct storage_data),len-8);
-	}
-	else {
-		s=account2storage(account_id);
-		memcpy(s,RFIFOP(fd,8),sizeof(struct storage_data));
-		mapif_save_storage_ack(fd,account_id);
-	}
-	return 0;
-}
-
 int mapif_parse_LoadGuildStorage(int fd)
 {
 	RFIFOHEAD(fd);
@@ -481,8 +450,6 @@ int inter_storage_parse_frommap(int fd)
 {
 	RFIFOHEAD(fd);
 	switch(RFIFOW(fd,0)){
-	case 0x3010: mapif_parse_LoadStorage(fd); break;
-	case 0x3011: mapif_parse_SaveStorage(fd); break;
 	case 0x3018: mapif_parse_LoadGuildStorage(fd); break;
 	case 0x3019: mapif_parse_SaveGuildStorage(fd); break;
 	default:

+ 3 - 0
src/char/int_storage.h

@@ -22,4 +22,7 @@ extern char guild_storage_txt[1024];
 int storage_fromstr(char *str,struct storage_data *p);
 int guild_storage_fromstr(char *str,struct guild_storage *p);
 
+bool storage_load(int account_id, struct storage_data* storage);
+bool storage_save(int account_id, struct storage_data* storage);
+
 #endif /* _INT_STORAGE_H_ */

+ 12 - 0
src/char_sql/char.c

@@ -17,6 +17,7 @@
 #include "int_guild.h"
 #include "int_homun.h"
 #include "int_party.h"
+#include "int_storage.h"
 #include "char.h"
 
 #include <sys/types.h>
@@ -483,6 +484,13 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
 		strcat(save_status, " cart");
 	}
 
+	//map storage data
+	if( memcmp(p->storage.items, cp->storage.items, sizeof(p->storage.items)) )
+	{
+		memitemdata_to_sql(p->storage.items, MAX_STORAGE, p->account_id, TABLE_STORAGE);
+		strcat(save_status, " storage");
+	}
+
 #ifdef TXT_SQL_CONVERT
 {	//Insert the barebones to then update the rest.
 	char esc_name[NAME_LENGTH*2+1];
@@ -1102,6 +1110,10 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything
 		memcpy(&p->cart[i], &tmp_item, sizeof(tmp_item));
 	strcat(t_msg, " cart");
 
+	//read storage
+	storage_fromsql(p->account_id, &p->storage);
+	strcat(t_msg, " storage");
+
 	//read skill
 	//`skill` (`char_id`, `id`, `lv`)
 	if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `id`, `lv` FROM `%s` WHERE `char_id`=? LIMIT %d", skill_db, MAX_SKILL)

+ 0 - 48
src/char_sql/int_storage.c

@@ -21,7 +21,6 @@
 int storage_tosql(int account_id, struct storage_data* p)
 {
 	memitemdata_to_sql(p->items, MAX_STORAGE, account_id, TABLE_STORAGE);
-	//ShowInfo ("storage save to DB - account: %d\n", account_id);
 	return 0;
 }
 
@@ -159,29 +158,6 @@ int inter_guild_storage_delete(int guild_id)
 //---------------------------------------------------------
 // packet from map server
 
-// recive packet about storage data
-int mapif_load_storage(int fd,int account_id)
-{
-	//load from DB
-	WFIFOHEAD(fd, sizeof(struct storage_data)+8);
-	WFIFOW(fd,0)=0x3810;
-	WFIFOW(fd,2)=sizeof(struct storage_data)+8;
-	WFIFOL(fd,4)=account_id;
-	storage_fromsql(account_id, (struct storage_data*)WFIFOP(fd,8));
-	WFIFOSET(fd,WFIFOW(fd,2));
-	return 0;
-}
-// send ack to map server which is "storage data save ok."
-int mapif_save_storage_ack(int fd,int account_id)
-{
-	WFIFOHEAD(fd, 7);
-	WFIFOW(fd,0)=0x3811;
-	WFIFOL(fd,2)=account_id;
-	WFIFOB(fd,6)=0;
-	WFIFOSET(fd,7);
-	return 0;
-}
-
 int mapif_load_guild_storage(int fd,int account_id,int guild_id)
 {
 	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `guild_id` FROM `%s` WHERE `guild_id`='%d'", guild_db, guild_id) )
@@ -221,28 +197,6 @@ int mapif_save_guild_storage_ack(int fd,int account_id,int guild_id,int fail)
 //---------------------------------------------------------
 // packet from map server
 
-// recive request about storage data
-int mapif_parse_LoadStorage(int fd)
-{
-	RFIFOHEAD(fd);
-	mapif_load_storage(fd,RFIFOL(fd,2));
-	return 0;
-}
-// storage data recive and save
-int mapif_parse_SaveStorage(int fd)
-{
-	int len = RFIFOW(fd,2);
-	int account_id = RFIFOL(fd,4);
-
-	if(sizeof(struct storage_data)!=len-8){
-		ShowError("inter storage: data size error %d %d\n",sizeof(struct storage_data),len-8);
-	}else{
-		storage_tosql(account_id, (struct storage_data*)RFIFOP(fd,8));
-		mapif_save_storage_ack(fd,account_id);
-	}
-	return 0;
-}
-
 int mapif_parse_LoadGuildStorage(int fd)
 {
 	RFIFOHEAD(fd);
@@ -285,8 +239,6 @@ int inter_storage_parse_frommap(int fd)
 {
 	RFIFOHEAD(fd);
 	switch(RFIFOW(fd,0)){
-	case 0x3010: mapif_parse_LoadStorage(fd); break;
-	case 0x3011: mapif_parse_SaveStorage(fd); break;
 	case 0x3018: mapif_parse_LoadGuildStorage(fd); break;
 	case 0x3019: mapif_parse_SaveGuildStorage(fd); break;
 	default:

+ 1 - 0
src/char_sql/int_storage.h

@@ -15,6 +15,7 @@ int inter_guild_storage_delete(int guild_id);
 int inter_storage_parse_frommap(int fd);
 
 //Exported for use in the TXT-SQL converter.
+int storage_fromsql(int account_id, struct storage_data* p);
 int storage_tosql(int account_id,struct storage_data *p);
 int guild_storage_tosql(int guild_id, struct guild_storage *p);
 

+ 15 - 16
src/common/mmo.h

@@ -178,6 +178,20 @@ struct status_change_data {
 	int val1, val2, val3, val4, tick; //Remaining duration.
 };
 
+struct storage_data {
+	int account_id; // used by charserver
+	int storage_amount;
+	struct item items[MAX_STORAGE];
+};
+
+struct guild_storage {
+	int dirty;
+	int guild_id;
+	short storage_status;
+	short storage_amount;
+	struct item storage_[MAX_GUILD_STORAGE];
+};
+
 struct s_pet {
 	int account_id;
 	int char_id;
@@ -264,6 +278,7 @@ struct mmo_charstatus {
 
 	struct point last_point,save_point,memo_point[MAX_MEMOPOINTS];
 	struct item inventory[MAX_INVENTORY],cart[MAX_CART];
+	struct storage_data storage;
 	struct skill skill[MAX_SKILL];
 
 	struct s_friend friends[MAX_FRIENDS]; //New friend system [Skotlex]
@@ -329,22 +344,6 @@ struct registry {
 	struct global_reg account2[ACCOUNT_REG2_NUM];
 };
 
-struct storage_data {
-	int dirty;
-	int account_id;
-	short storage_status;
-	short storage_amount;
-	struct item items[MAX_STORAGE];
-};
-
-struct guild_storage {
-	int dirty;
-	int guild_id;
-	short storage_status;
-	short storage_amount;
-	struct item storage_[MAX_GUILD_STORAGE];
-};
-
 struct gm_account {
 	int account_id;
 	int level;

+ 7 - 10
src/map/atcommand.c

@@ -1155,7 +1155,6 @@ int atcommand_storage(const int fd, struct map_session_data* sd, const char* com
  *------------------------------------------*/
 int atcommand_guildstorage(const int fd, struct map_session_data* sd, const char* command, const char* message)
 {
-	struct storage_data *stor; //changes from Freya/Yor
 	nullpo_retr(-1, sd);
 
 	if (!sd->status.guild_id) {
@@ -1163,18 +1162,19 @@ int atcommand_guildstorage(const int fd, struct map_session_data* sd, const char
 		return -1;
 	}
 
-	if (sd->npc_id || sd->vender_id || sd->state.trading || sd->state.storage_flag)
+	if (sd->npc_id || sd->vender_id || sd->state.trading)
 		return -1;
 
-	if (sd->state.storage_flag) {
-		clif_displaymessage(fd, msg_txt(251));
+	if (sd->state.storage_flag == 1) {
+		clif_displaymessage(fd, msg_txt(250));
 		return -1;
 	}
 
-	if ((stor = account2storage2(sd->status.account_id)) != NULL && stor->storage_status == 1) {
+	if (sd->state.storage_flag == 2) {
 		clif_displaymessage(fd, msg_txt(251));
 		return -1;
 	}
+
 	storage_guild_storageopen(sd);
 	clif_displaymessage(fd, "Guild storage opened.");
 	return 0;
@@ -5547,15 +5547,12 @@ int atcommand_storeall(const int fd, struct map_session_data* sd, const char* co
 
 	if (sd->state.storage_flag != 1)
   	{	//Open storage.
-		switch (storage_storageopen(sd)) {
-		case 2: //Try again
-			clif_displaymessage(fd, "run this command again..");
-			return 0;
-		case 1: //Failure
+		if( storage_storageopen(sd) == 1 ) {
 			clif_displaymessage(fd, "You can't open the storage currently.");
 			return -1;
 		}
 	}
+
 	for (i = 0; i < MAX_INVENTORY; i++) {
 		if (sd->status.inventory[i].amount) {
 			if(sd->status.inventory[i].equip != 0)

+ 49 - 61
src/map/charcommand.c

@@ -606,10 +606,9 @@ int charcommand_effect(const int fd, struct map_session_data* sd, const char* co
  *------------------------------------------*/
 int charcommand_storagelist(const int fd, struct map_session_data* sd, const char* command, const char* message)
 {
-	struct storage_data *stor;
 	struct map_session_data *pl_sd;
 	struct item_data *item_data, *item_temp;
-	int i, j, count, counter, counter2;
+	int i, j, count = 0, counter = 0, counter2 = 0;
 	char character[NAME_LENGTH], output[200], outputtmp[200];
 	nullpo_retr(-1, sd);
 
@@ -634,51 +633,49 @@ int charcommand_storagelist(const int fd, struct map_session_data* sd, const cha
 		return -1;
 	}
 
-	if((stor = account2storage2(pl_sd->status.account_id)) != NULL) {
-		counter = 0;
-		count = 0;
-		for (i = 0; i < MAX_STORAGE; i++) {
-			if (stor->items[i].nameid > 0 && (item_data = itemdb_search(stor->items[i].nameid)) != NULL) {
-				counter = counter + stor->items[i].amount;
-				count++;
-				if (count == 1) {
-					sprintf(output, "------ Storage items list of '%s' ------", pl_sd->status.name);
-					clif_displaymessage(fd, output);
-				}
-				if (stor->items[i].refine)
-					sprintf(output, "%d %s %+d (%s %+d, id: %d)", stor->items[i].amount, item_data->name, stor->items[i].refine, item_data->jname, stor->items[i].refine, stor->items[i].nameid);
-				else
-					sprintf(output, "%d %s (%s, id: %d)", stor->items[i].amount, item_data->name, item_data->jname, stor->items[i].nameid);
+	for (i = 0; i < MAX_STORAGE; i++)
+	{
+		struct item* it = &sd->status.storage.items[i];
+		if( it->nameid > 0 && (item_data = itemdb_search(it->nameid)) != NULL )
+		{
+			counter = counter + it->amount;
+			count++;
+			if (count == 1) {
+				sprintf(output, "------ Storage items list of '%s' ------", pl_sd->status.name);
 				clif_displaymessage(fd, output);
-				memset(output, '\0', sizeof(output));
-				counter2 = 0;
-				for (j = 0; j < item_data->slot; j++) {
-					if (stor->items[i].card[j]) {
-						if ((item_temp = itemdb_search(stor->items[i].card[j])) != NULL) {
-							if (output[0] == '\0')
-								sprintf(outputtmp, " -> (card(s): #%d %s (%s), ", ++counter2, item_temp->name, item_temp->jname);
-							else
-								sprintf(outputtmp, "#%d %s (%s), ", ++counter2, item_temp->name, item_temp->jname);
-							strcat(output, outputtmp);
-						}
+			}
+			if (it->refine)
+				sprintf(output, "%d %s %+d (%s %+d, id: %d)", it->amount, item_data->name, it->refine, item_data->jname, it->refine, it->nameid);
+			else
+				sprintf(output, "%d %s (%s, id: %d)", it->amount, item_data->name, item_data->jname, it->nameid);
+			clif_displaymessage(fd, output);
+
+			memset(output, '\0', sizeof(output));
+			counter2 = 0;
+			for (j = 0; j < item_data->slot; j++) {
+				if (it->card[j]) {
+					if ((item_temp = itemdb_search(it->card[j])) != NULL) {
+						if (output[0] == '\0')
+							sprintf(outputtmp, " -> (card(s): #%d %s (%s), ", ++counter2, item_temp->name, item_temp->jname);
+						else
+							sprintf(outputtmp, "#%d %s (%s), ", ++counter2, item_temp->name, item_temp->jname);
+						strcat(output, outputtmp);
 					}
 				}
-				if (output[0] != '\0') {
-					output[strlen(output) - 2] = ')';
-					output[strlen(output) - 1] = '\0';
-					clif_displaymessage(fd, output);
-				}
+			}
+			if (output[0] != '\0') {
+				output[strlen(output) - 2] = ')';
+				output[strlen(output) - 1] = '\0';
+				clif_displaymessage(fd, output);
 			}
 		}
-		if (count == 0)
-			clif_displaymessage(fd, "No item found in the storage of this player.");
-		else {
-			sprintf(output, "%d item(s) found in %d kind(s) of items.", counter, count);
-			clif_displaymessage(fd, output);
-		}
-	} else {
-		clif_displaymessage(fd, "This player has no storage.");
-		return 0;
+	}
+
+	if (count == 0)
+		clif_displaymessage(fd, "No item found in the storage of this player.");
+	else {
+		sprintf(output, "%d item(s) found in %d kind(s) of items.", counter, count);
+		clif_displaymessage(fd, output);
 	}
 
 	return 0;
@@ -1643,7 +1640,6 @@ int charcommand_storage(const int fd, struct map_session_data* sd, const char* c
  *------------------------------------------*/
 int charcommand_guildstorage(const int fd, struct map_session_data* sd, const char* command, const char* message)
 {
-	struct storage_data *stor; //changes from Freya/Yor
 	char character[NAME_LENGTH];
 
 	struct map_session_data *pl_sd;
@@ -1665,24 +1661,21 @@ int charcommand_guildstorage(const int fd, struct map_session_data* sd, const ch
 		return -1;
 	}
 	
-	if (pl_sd->npc_id || pl_sd->vender_id || pl_sd->state.trading || pl_sd->state.storage_flag)
+	if (pl_sd->npc_id || pl_sd->vender_id || pl_sd->state.trading)
 		return -1;
 
-	if (pl_sd->status.guild_id > 0) {
-		if (pl_sd->state.storage_flag) {
-			clif_displaymessage(fd, "Guild storage is currently in use.");
-			return -1;
-		}
-		if ((stor = account2storage2(pl_sd->status.account_id)) != NULL && stor->storage_status == 1) {
-			clif_displaymessage(fd, "Guild storage is currently in use.");
-			return -1;
-		}
-		storage_guild_storageopen(pl_sd);
-	} else {
+	if (pl_sd->status.guild_id == 0) {
 		clif_displaymessage(fd, "Target player is not in a guild.");
 		return -1;
 	}
 
+	if (pl_sd->state.storage_flag) {
+		clif_displaymessage(fd, "Guild storage is currently in use.");
+		return -1;
+	}
+
+	storage_guild_storageopen(pl_sd);
+
 	clif_displaymessage(pl_sd->fd, "Guild storage opened.");
 	if (pl_sd->fd != fd)
 		clif_displaymessage(fd, "Player's guild storage opened.");
@@ -3190,12 +3183,7 @@ int charcommand_storeall(const int fd, struct map_session_data* sd, const char*
 
 	if (pl_sd->state.storage_flag != 1)
   	{	//Open storage.
-		switch (storage_storageopen(pl_sd)) {
-		case 2: //Try again
-			clif_displaymessage(fd, "Had to open the characters storage window...");
-			clif_displaymessage(fd, "run this command again..");
-			return 0;
-		case 1: //Failure
+		if( storage_storageopen(pl_sd) == 1 ) {
 			clif_displaymessage(fd, "The character currently can't use the storage.");
 			return 1;
 		}

+ 4 - 4
src/map/chrif.c

@@ -257,11 +257,11 @@ int chrif_save(struct map_session_data *sd, int flag)
 		return -1; //Character is saved on reconnect.
 
 	//For data sync
-	if (sd->state.storage_flag == 1)
-		storage_storage_save(sd->status.account_id, flag);
-	else if (sd->state.storage_flag == 2)
+	if (sd->state.storage_flag == 2)
 		storage_guild_storagesave(sd->status.account_id, sd->status.guild_id, flag);
-	if (flag) sd->state.storage_flag = 0; //Force close it.
+
+	if (flag)
+		sd->state.storage_flag = 0; //Force close it.
 
 	//Saving of registry values. 
 	if (sd->state.reg_dirty&4)

+ 3 - 4
src/map/clif.c

@@ -1867,8 +1867,7 @@ void clif_equiplist(struct map_session_data *sd)
 	}
 }
 
-//Unified storage function which sends all of the storage (requires two packets, one for equipable items and one for stackable ones. [Skotlex]
-void clif_storagelist(struct map_session_data *sd,struct storage_data *stor)
+void clif_storagelist(struct map_session_data* sd, struct storage_data* stor)
 {
 	struct item_data *id;
 	int i,n,ne,fd=sd->fd;
@@ -9736,10 +9735,10 @@ void clif_parse_MoveFromKafraToCart(int fd, struct map_session_data *sd)
  *------------------------------------------*/
 void clif_parse_CloseKafra(int fd, struct map_session_data *sd)
 {
-	if (sd->state.storage_flag == 1)
+	if( sd->state.storage_flag == 1 )
 		storage_storageclose(sd);
 	else
-	if (sd->state.storage_flag == 2)
+	if( sd->state.storage_flag == 2 )
 		storage_guild_storageclose(sd);
 }
 

+ 1 - 76
src/map/intif.c

@@ -32,7 +32,7 @@
 
 static const int packet_len_table[]={
 	-1,-1,27,-1, -1, 0,37, 0,  0, 0, 0, 0,  0, 0,  0, 0, //0x3800-0x380f
-	-1, 7, 0, 0,  0, 0, 0, 0, -1,11, 0, 0,  0, 0,  0, 0, //0x3810
+	 0, 0, 0, 0,  0, 0, 0, 0, -1,11, 0, 0,  0, 0,  0, 0, //0x3810
 	39,-1,15,15, 14,19, 7,-1,  0, 0, 0, 0,  0, 0,  0, 0, //0x3820
 	10,-1,15, 0, 79,19, 7,-1,  0,-1,-1,-1, 14,67,186,-1, //0x3830
 	 9, 9,-1,14,  0, 0, 0, 0, -1,74,-1,11, 11,-1,  0, 0, //0x3840
@@ -326,32 +326,6 @@ int intif_request_registry(struct map_session_data *sd, int flag)
 	return 0;
 }
 
-// 倉庫データ要求
-int intif_request_storage(int account_id)
-{
-	if (CheckForCharServer())
-		return 0;
-	WFIFOHEAD(inter_fd,6);
-	WFIFOW(inter_fd,0) = 0x3010;
-	WFIFOL(inter_fd,2) = account_id;
-	WFIFOSET(inter_fd,6);
-	return 0;
-}
-// 倉庫データ送信
-int intif_send_storage(struct storage_data *stor)
-{
-	if (CheckForCharServer())
-		return 0;
-	nullpo_retr(0, stor);
-	WFIFOHEAD(inter_fd,sizeof(struct storage_data)+8);
-	WFIFOW(inter_fd,0) = 0x3011;
-	WFIFOW(inter_fd,2) = sizeof(struct storage_data)+8;
-	WFIFOL(inter_fd,4) = stor->account_id;
-	memcpy( WFIFOP(inter_fd,8),stor, sizeof(struct storage_data) );
-	WFIFOSET(inter_fd,WFIFOW(inter_fd,2));
-	return 0;
-}
-
 int intif_request_guild_storage(int account_id,int guild_id)
 {
 	if (CheckForCharServer())
@@ -968,53 +942,6 @@ int intif_parse_Registers(int fd)
 	return 1;
 }
 
-// 倉庫データ受信
-int intif_parse_LoadStorage(int fd)
-{
-	struct storage_data *stor;
-	struct map_session_data *sd;
-
-	sd=map_id2sd( RFIFOL(fd,4) );
-	if(sd==NULL){
-		ShowError("intif_parse_LoadStorage: user not found %d\n",RFIFOL(fd,4));
-		return 1;
-	}
-
-	stor = account2storage( RFIFOL(fd,4));
-
-	if (stor->storage_status == 1) { // Already open.. lets ignore this update
-		ShowWarning("intif_parse_LoadStorage: storage received for a client already open (User %d:%d)\n", sd->status.account_id, sd->status.char_id);
-		return 1;
-	}
-	if (stor->dirty) { // Already have storage, and it has been modified and not saved yet! Exploit! [Skotlex]
-		ShowWarning("intif_parse_LoadStorage: received storage for an already modified non-saved storage! (User %d:%d)\n", sd->status.account_id, sd->status.char_id);
-		return 1;
-	}
-	if (RFIFOW(fd,2)-8 != sizeof(struct storage_data)) {
-		ShowError("intif_parse_LoadStorage: data size error %d %d\n", RFIFOW(fd,2)-8, sizeof(struct storage_data));
-		return 1;
-	}
-	if(battle_config.save_log)
-		ShowInfo("intif_openstorage: %d\n",RFIFOL(fd,4) );
-	memcpy(stor,RFIFOP(fd,8),sizeof(struct storage_data));
-	stor->dirty=0;
-	stor->storage_status=1;
-	sd->state.storage_flag = 1;
-	clif_storagelist(sd,stor);
-	clif_updatestorageamount(sd,stor->storage_amount);
-
-	return 0;
-}
-
-// 倉庫データ送信成功
-int intif_parse_SaveStorage(int fd)
-{
-	if(battle_config.save_log)
-		ShowInfo("intif_savestorage: done %d %d\n",RFIFOL(fd,2),RFIFOB(fd,6) );
-	storage_storage_saved(RFIFOL(fd,2));
-	return 0;
-}
-
 int intif_parse_LoadGuildStorage(int fd)
 {
 	struct guild_storage *gstor;
@@ -1988,8 +1915,6 @@ int intif_parse(int fd)
 	case 0x3803:	mapif_parse_WisToGM(fd); break;
 	case 0x3804:	intif_parse_Registers(fd); break;
 	case 0x3806:	intif_parse_ChangeNameOk(fd); break;
-	case 0x3810:	intif_parse_LoadStorage(fd); break;
-	case 0x3811:	intif_parse_SaveStorage(fd); break;
 	case 0x3818:	intif_parse_LoadGuildStorage(fd); break;
 	case 0x3819:	intif_parse_SaveGuildStorage(fd); break;
 	case 0x3820:	intif_parse_PartyCreated(fd); break;

+ 0 - 2
src/map/intif.h

@@ -24,8 +24,6 @@ int intif_wis_message_to_gm(char *Wisp_name, int min_gm_level, char *mes);
 int intif_saveregistry(struct map_session_data *sd, int type);
 int intif_request_registry(struct map_session_data *sd, int flag);
 
-int intif_request_storage(int account_id);
-int intif_send_storage(struct storage_data *stor);
 int intif_request_guild_storage(int account_id, int guild_id);
 int intif_send_guild_storage(int account_id, struct guild_storage *gstor);
 

+ 48 - 192
src/map/storage.c

@@ -24,7 +24,6 @@
 #include <string.h>
 
 
-static DBMap* storage_db; // int account_id -> struct storage*
 static DBMap* guild_storage_db; // int guild_id -> struct guild_storage*
 
 /*==========================================
@@ -44,13 +43,13 @@ static int storage_comp_item(const void *_i1, const void *_i2)
 	return i1->nameid - i2->nameid;
 }
  
-static void storage_sortitem (struct storage_data *stor)
+static void storage_sortitem(struct storage_data* stor)
 {
 	nullpo_retv(stor);
 	qsort(stor->items, MAX_STORAGE, sizeof(struct item), storage_comp_item);
 }
 
-static void storage_gsortitem (struct guild_storage* gstor)
+static void storage_gsortitem(struct guild_storage* gstor)
 {
 	nullpo_retv(gstor);
 	qsort(gstor->storage_, MAX_GUILD_STORAGE, sizeof(struct item), storage_comp_item);
@@ -61,75 +60,38 @@ static void storage_gsortitem (struct guild_storage* gstor)
  *------------------------------------------*/
 int do_init_storage(void) // map.c::do_init()‚©‚çŒÄ‚΂ê‚é
 {
-	storage_db=idb_alloc(DB_OPT_RELEASE_DATA);
 	guild_storage_db=idb_alloc(DB_OPT_RELEASE_DATA);
 	return 1;
 }
 void do_final_storage(void) // by [MC Cameri]
 {
-	storage_db->destroy(storage_db,NULL);
 	guild_storage_db->destroy(guild_storage_db,NULL);
 }
 
 
 static int storage_reconnect_sub(DBKey key,void *data,va_list ap)
 { //Parses storage and saves 'dirty' ones upon reconnect. [Skotlex]
-	int type = va_arg(ap, int);
-	if (type)
-	{	//Guild Storage
-		struct guild_storage* stor = (struct guild_storage*) data;
-		if (stor->dirty && stor->storage_status == 0) //Save closed storages.
-			storage_guild_storagesave(0, stor->guild_id,0);
-	}
-	else
-	{	//Account Storage
-		struct storage_data* stor = (struct storage_data*) data;
-		if (stor->dirty && stor->storage_status == 0) //Save closed storages.
-			storage_storage_save(stor->account_id, stor->dirty==2?1:0);
-	}
+
+	struct guild_storage* stor = (struct guild_storage*) data;
+	if (stor->dirty && stor->storage_status == 0) //Save closed storages.
+		storage_guild_storagesave(0, stor->guild_id,0);
+
 	return 0;
 }
 
 //Function to be invoked upon server reconnection to char. To save all 'dirty' storages [Skotlex]
 void do_reconnect_storage(void)
 {
-	storage_db->foreach(storage_db, storage_reconnect_sub, 0);
-	guild_storage_db->foreach(guild_storage_db, storage_reconnect_sub, 1);
-}
-
-static void* create_storage(DBKey key, va_list args)
-{
-	struct storage_data *stor;
-	stor = (struct storage_data *) aCallocA (sizeof(struct storage_data), 1);
-	stor->account_id = key.i;
-	return stor;
-}
-struct storage_data *account2storage(int account_id)
-{
-	return (struct storage_data*)idb_ensure(storage_db,account_id,create_storage);
-}
-
-// Just to ask storage, without creation
-struct storage_data *account2storage2(int account_id)
-{
-	return (struct storage_data*)idb_get(storage_db, account_id);
-}
-
-int storage_delete(int account_id)
-{
-	idb_remove(storage_db,account_id);
-	return 0;
+	guild_storage_db->foreach(guild_storage_db, storage_reconnect_sub);
 }
 
 /*==========================================
  * Opens a storage. Returns:
  * 0 - success
  * 1 - fail
- * 2 - Storage requested from char-server (will open automatically later)
  *------------------------------------------*/
 int storage_storageopen(struct map_session_data *sd)
 {
-	struct storage_data *stor;
 	nullpo_retr(0, sd);
 
 	if(sd->state.storage_flag)
@@ -141,19 +103,9 @@ int storage_storageopen(struct map_session_data *sd)
 		return 1;
 	}
 	
-	if((stor = (struct storage_data*)idb_get(storage_db,sd->status.account_id)) == NULL)
-  	{	//Request storage.
-		intif_request_storage(sd->status.account_id);
-		return 2;
-	}
-  
-	if (stor->storage_status)
-  		return 1; //Already open/player already has it open...
-
-	stor->storage_status = 1;
 	sd->state.storage_flag = 1;
-	clif_storagelist(sd,stor);
-	clif_updatestorageamount(sd,stor->storage_amount);
+	clif_storagelist(sd,&sd->status.storage);
+	clif_updatestorageamount(sd,sd->status.storage.storage_amount);
 	return 0;
 }
 
@@ -175,8 +127,9 @@ int compare_item(struct item *a, struct item *b)
 /*==========================================
  * Internal add-item function.
  *------------------------------------------*/
-static int storage_additem(struct map_session_data* sd, struct storage_data* stor,struct item *item_data,int amount)
+static int storage_additem(struct map_session_data* sd, struct item* item_data, int amount)
 {
+	struct storage_data* stor = &sd->status.storage;
 	struct item_data *data;
 	int i;
 
@@ -195,13 +148,12 @@ static int storage_additem(struct map_session_data* sd, struct storage_data* sto
 	{//Stackable
 		for( i = 0; i < MAX_STORAGE; i++ )
 		{
-			if( compare_item (&stor->items[i], item_data))
+			if( compare_item(&stor->items[i], item_data) )
 			{// existing items found, stack them
 				if( amount > MAX_AMOUNT - stor->items[i].amount )
 					return 1;
-				stor->items[i].amount+=amount;
+				stor->items[i].amount += amount;
 				clif_storageitemadded(sd,&stor->items[i],i,amount);
-				stor->dirty = 1;
 				if(log_config.enable_logs&0x800)
 					log_pick_pc(sd, "R", item_data->nameid, -amount, item_data);
 				return 0;
@@ -216,11 +168,10 @@ static int storage_additem(struct map_session_data* sd, struct storage_data* sto
 
 	// add item to slot
 	memcpy(&stor->items[i],item_data,sizeof(stor->items[0]));
-	stor->items[i].amount=amount;
 	stor->storage_amount++;
+	stor->items[i].amount = amount;
 	clif_storageitemadded(sd,&stor->items[i],i,amount);
 	clif_updatestorageamount(sd,stor->storage_amount);
-	stor->dirty = 1;
 	if(log_config.enable_logs&0x800)
 		log_pick_pc(sd, "R", item_data->nameid, -amount, item_data);
 
@@ -230,25 +181,23 @@ static int storage_additem(struct map_session_data* sd, struct storage_data* sto
 /*==========================================
  * Internal del-item function
  *------------------------------------------*/
-static int storage_delitem(struct map_session_data* sd, struct storage_data* stor, int n, int amount)
+static int storage_delitem(struct map_session_data* sd, int n, int amount)
 {
-	if( stor->items[n].nameid == 0 || stor->items[n].amount < amount )
+	if( sd->status.storage.items[n].nameid == 0 || sd->status.storage.items[n].amount < amount )
 		return 1;
 
-	stor->items[n].amount -= amount;
+	sd->status.storage.items[n].amount -= amount;
 
-	if( log_config.enable_logs&0x800 )
-		log_pick_pc(sd, "R", stor->items[n].nameid, amount, &stor->items[n]);
+	if(log_config.enable_logs&0x800)
+		log_pick_pc(sd, "R", sd->status.storage.items[n].nameid, amount, &sd->status.storage.items[n]);
 
-	if( stor->items[n].amount == 0 )
+	if( sd->status.storage.items[n].amount == 0 )
 	{
-		memset(&stor->items[n],0,sizeof(stor->items[0]));
-		stor->storage_amount--;
-		clif_updatestorageamount(sd,stor->storage_amount);
+		memset(&sd->status.storage.items[n],0,sizeof(sd->status.storage.items[0]));
+		sd->status.storage.storage_amount--;
+		clif_updatestorageamount(sd,sd->status.storage.storage_amount);
 	}
 	clif_storageitemremoved(sd,n,amount);
-
-	stor->dirty = 1;
 	return 0;
 }
 
@@ -257,13 +206,10 @@ static int storage_delitem(struct map_session_data* sd, struct storage_data* sto
  *------------------------------------------*/
 int storage_storageadd(struct map_session_data* sd, int index, int amount)
 {
-	struct storage_data *stor;
-
 	nullpo_retr(0, sd);
-	nullpo_retr(0, stor=account2storage2(sd->status.account_id));
 
-	if( stor->storage_amount > MAX_STORAGE || !stor->storage_status )
-		return 0; // storage full / storage closed
+	if( sd->status.storage.storage_amount > MAX_STORAGE )
+		return 0; // storage full
 
 	if( index < 0 || index >= MAX_INVENTORY )
 		return 0;
@@ -274,7 +220,7 @@ int storage_storageadd(struct map_session_data* sd, int index, int amount)
 	if( amount < 1 || amount > sd->status.inventory[index].amount )
   		return 0;
 
-	if( storage_additem(sd,stor,&sd->status.inventory[index],amount) == 0 )
+	if( storage_additem(sd,&sd->status.inventory[index],amount) == 0 )
 		pc_delitem(sd,index,amount,0);
 
 	return 1;
@@ -285,24 +231,19 @@ int storage_storageadd(struct map_session_data* sd, int index, int amount)
  *------------------------------------------*/
 int storage_storageget(struct map_session_data* sd, int index, int amount)
 {
-	struct storage_data *stor;
 	int flag;
 
-	nullpo_retr(0, sd);
-	nullpo_retr(0, stor=account2storage2(sd->status.account_id));
-
-	
 	if( index < 0 || index >= MAX_STORAGE )
 		return 0;
 
-	if( stor->items[index].nameid <= 0 )
+	if( sd->status.storage.items[index].nameid <= 0 )
 		return 0; //Nothing there
 	
-	if( amount < 1 || amount > stor->items[index].amount )
+	if( amount < 1 || amount > sd->status.storage.items[index].amount )
 		return 0;
 
-	if( (flag = pc_additem(sd,&stor->items[index],amount)) == 0 )
-		storage_delitem(sd,stor,index,amount);
+	if( (flag = pc_additem(sd,&sd->status.storage.items[index],amount)) == 0 )
+		storage_delitem(sd,index,amount);
 	else
 		clif_additem(sd,0,0,flag);
 
@@ -314,12 +255,9 @@ int storage_storageget(struct map_session_data* sd, int index, int amount)
  *------------------------------------------*/
 int storage_storageaddfromcart(struct map_session_data* sd, int index, int amount)
 {
-	struct storage_data *stor;
-
 	nullpo_retr(0, sd);
-	nullpo_retr(0, stor=account2storage2(sd->status.account_id));
 
-	if( stor->storage_amount > MAX_STORAGE || !stor->storage_status )
+	if( sd->status.storage.storage_amount > MAX_STORAGE )
   		return 0; // storage full / storage closed
 
 	if( index < 0 || index >= MAX_CART )
@@ -331,7 +269,7 @@ int storage_storageaddfromcart(struct map_session_data* sd, int index, int amoun
 	if( amount < 1 || amount > sd->status.cart[index].amount )
 		return 0;
 
-	if( storage_additem(sd,stor,&sd->status.cart[index],amount) == 0 )
+	if( storage_additem(sd,&sd->status.cart[index],amount) == 0 )
 		pc_cart_delitem(sd,index,amount,0);
 
 	return 1;
@@ -342,25 +280,19 @@ int storage_storageaddfromcart(struct map_session_data* sd, int index, int amoun
  *------------------------------------------*/
 int storage_storagegettocart(struct map_session_data* sd, int index, int amount)
 {
-	struct storage_data *stor;
-
 	nullpo_retr(0, sd);
-	nullpo_retr(0, stor=account2storage2(sd->status.account_id));
 
-	if( !stor->storage_status )
-		return 0;
- 
 	if( index < 0 || index >= MAX_STORAGE )
 		return 0;
 	
-	if( stor->items[index].nameid <= 0 )
+	if( sd->status.storage.items[index].nameid <= 0 )
 		return 0; //Nothing there.
 	
-	if( amount < 1 || amount > stor->items[index].amount )
+	if( amount < 1 || amount > sd->status.storage.items[index].amount )
 		return 0;
 	
-	if( pc_cart_additem(sd,&stor->items[index],amount) == 0 )
-		storage_delitem(sd,stor,index,amount);
+	if( pc_cart_additem(sd,&sd->status.storage.items[index],amount) == 0 )
+		storage_delitem(sd,index,amount);
 
 	return 1;
 }
@@ -369,107 +301,31 @@ int storage_storagegettocart(struct map_session_data* sd, int index, int amount)
 /*==========================================
  * Modified By Valaris to save upon closing [massdriller]
  *------------------------------------------*/
-int storage_storageclose(struct map_session_data* sd)
+void storage_storageclose(struct map_session_data* sd)
 {
-	struct storage_data *stor;
-
-	nullpo_retr(0, sd);
-	nullpo_retr(0, stor=account2storage2(sd->status.account_id));
+	nullpo_retv(sd);
 
 	clif_storageclose(sd);
-	if (stor->storage_status)
-  	{
-		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;
+	if( save_settings&4 )
+		chrif_save(sd,0); //Invokes the storage saving as well.
+
+	sd->state.storage_flag = 0;
 }
 
 /*==========================================
  * When quitting the game.
  *------------------------------------------*/
-int storage_storage_quit(struct map_session_data* sd, int flag)
+void storage_storage_quit(struct map_session_data* sd, int flag)
 {
-	struct storage_data *stor;
-
-	nullpo_retr(0, sd);
-	nullpo_retr(0, stor=account2storage2(sd->status.account_id));
+	nullpo_retv(sd);
 	
-	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;
-}
-
-void storage_storage_dirty(struct map_session_data* sd)
-{
-	struct storage_data *stor;
-
-	stor=account2storage2(sd->status.account_id);
-
-	if(stor)
-		stor->dirty = 1;
-}
-
-int storage_storage_save(int account_id, int final)
-{
-	struct storage_data *stor;
+	if (save_settings&4)
+		chrif_save(sd, flag); //Invokes the storage saving as well.
 
-	stor=account2storage2(account_id);
-	if(!stor) return 0;
-
-	if(stor->dirty)
-	{
-		if (final) {
-			stor->dirty = 2;
-			stor->storage_status = 0; //To prevent further manipulation of it.
-		}
-		intif_send_storage(stor);
-		return 1;
-	}
-	if (final) 
-	{	//Clear storage from memory. Nothing to save.
-		storage_delete(account_id);
-		return 1;
-	}
-
-	return 0;
+	sd->state.storage_flag = 0;
 }
 
-//Ack from Char-server indicating the storage was saved. [Skotlex]
-int storage_storage_saved(int account_id)
-{
-	struct storage_data *stor;
-	
-	if((stor=account2storage2(account_id)) == NULL)
-		return 0;
-
-	if (stor->dirty == 2)
-	{	//Final save of storage. Remove from memory.
-	  	storage_delete(account_id);
-		return 1;
-	}
-
-	if (stor->dirty && stor->storage_status == 0)
-	{	//Only mark it clean if it's not in use. [Skotlex]
-		stor->dirty = 0;
-		storage_sortitem(stor);
-		return 1;
-	}
-	return 0;
-}
 
 static void* create_guildstorage(DBKey key, va_list args)
 {

+ 2 - 7
src/map/storage.h

@@ -16,16 +16,11 @@ int storage_storageadd(struct map_session_data *sd,int index,int amount);
 int storage_storageget(struct map_session_data *sd,int index,int amount);
 int storage_storageaddfromcart(struct map_session_data *sd,int index,int amount);
 int storage_storagegettocart(struct map_session_data *sd,int index,int amount);
-int storage_storageclose(struct map_session_data *sd);
+void storage_storageclose(struct map_session_data *sd);
 int do_init_storage(void);
 void do_final_storage(void);
 void do_reconnect_storage(void);
-struct storage_data* account2storage(int account_id);
-struct storage_data* account2storage2(int account_id);
-int storage_storage_quit(struct map_session_data *sd, int flag);
-int storage_storage_save(int account_id, int final);
-int storage_storage_saved(int account_id); //Ack from char server that guild store was saved.
-void storage_storage_dirty(struct map_session_data *sd);
+void storage_storage_quit(struct map_session_data *sd, int flag);
 
 struct guild_storage* guild2storage(int guild_id);
 int guild_storage_delete(int guild_id);

+ 5 - 5
src/txt-converter/char-converter.c

@@ -107,7 +107,7 @@ int convert_init(void)
 	input = getchar();
 	if(input == 'y' || input == 'Y')
 	{
-		struct storage_data storage_;
+		struct storage_data storage;
 		ShowMessage("\n");
 		ShowStatus("Converting Storage Database...\n");
 		if( (fp = fopen(storage_txt,"r")) == NULL )
@@ -121,11 +121,11 @@ int convert_init(void)
 			lineno++;
 			set=sscanf(line,"%d,%d",&tmp_int[0],&tmp_int[1]);
 			if(set==2) {
-				memset(&storage_, 0, sizeof(struct storage_data));
-				storage_.account_id=tmp_int[0];
-				if (storage_fromstr(line,&storage_) == 0) {
+				memset(&storage, 0, sizeof(struct storage_data));
+				storage.account_id = tmp_int[0];
+				if (storage_fromstr(line,&storage) == 0) {
 					count++;
-					storage_tosql(storage_.account_id,&storage_); //to sql. (dump)
+					storage_tosql(storage.account_id,&storage); //to sql. (dump)
 				} else {
 					ShowError("Error parsing storage line [%s] (at %s:%d)\n", line, storage_txt, lineno);
 				}