From fb45ace1b19f98add7e1d0a0fc6fe45bc1ebac63 Mon Sep 17 00:00:00 2001 From: ultramage Date: Sun, 13 Jul 2008 16:14:32 +0000 Subject: 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://rathena.svn.sourceforge.net/svnroot/rathena/trunk@12950 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-Trunk.txt | 8 +- src/char/char.c | 6 + src/char/int_storage.c | 73 ++++------- src/char/int_storage.h | 3 + src/char_sql/char.c | 12 ++ src/char_sql/int_storage.c | 48 -------- src/char_sql/int_storage.h | 1 + src/common/mmo.h | 31 +++-- src/map/atcommand.c | 17 ++- src/map/charcommand.c | 110 ++++++++--------- src/map/chrif.c | 8 +- src/map/clif.c | 7 +- src/map/intif.c | 77 +----------- src/map/intif.h | 2 - src/map/storage.c | 240 ++++++++----------------------------- src/map/storage.h | 9 +- src/txt-converter/char-converter.c | 10 +- 17 files changed, 183 insertions(+), 479 deletions(-) diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index 0e130261b..9c3eeeb9a 100644 --- a/Changelog-Trunk.txt +++ b/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 diff --git a/src/char/char.c b/src/char/char.c index c57ba86fa..19887b737 100644 --- a/src/char/char.c +++ b/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)); diff --git a/src/char/int_storage.c b/src/char/int_storage.c index a1b4d33f1..d2e1f0403 100644 --- a/src/char/int_storage.c +++ b/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;iitems[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: diff --git a/src/char/int_storage.h b/src/char/int_storage.h index 44054079a..79e436093 100644 --- a/src/char/int_storage.h +++ b/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_ */ diff --git a/src/char_sql/char.c b/src/char_sql/char.c index 50a1a7ba9..0ce2aecf6 100644 --- a/src/char_sql/char.c +++ b/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 @@ -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) diff --git a/src/char_sql/int_storage.c b/src/char_sql/int_storage.c index cce358d76..f0118047d 100644 --- a/src/char_sql/int_storage.c +++ b/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: diff --git a/src/char_sql/int_storage.h b/src/char_sql/int_storage.h index 4a17a0442..811608f82 100644 --- a/src/char_sql/int_storage.h +++ b/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); diff --git a/src/common/mmo.h b/src/common/mmo.h index 61cd6266c..2e96e8910 100644 --- a/src/common/mmo.h +++ b/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; diff --git a/src/map/atcommand.c b/src/map/atcommand.c index b47665bf5..3db3bb9f8 100644 --- a/src/map/atcommand.c +++ b/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) diff --git a/src/map/charcommand.c b/src/map/charcommand.c index 7afcabc15..ccbf0cadc 100644 --- a/src/map/charcommand.c +++ b/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; } diff --git a/src/map/chrif.c b/src/map/chrif.c index 57fef3863..725fbcc07 100644 --- a/src/map/chrif.c +++ b/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) diff --git a/src/map/clif.c b/src/map/clif.c index 21cf8d208..bf9655aff 100644 --- a/src/map/clif.c +++ b/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); } diff --git a/src/map/intif.c b/src/map/intif.c index 705171f7f..7b79fe452 100644 --- a/src/map/intif.c +++ b/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; diff --git a/src/map/intif.h b/src/map/intif.h index be0bc8d72..b4cc6792f 100644 --- a/src/map/intif.h +++ b/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); diff --git a/src/map/storage.c b/src/map/storage.c index 964d3008c..e4bdfe414 100644 --- a/src/map/storage.c +++ b/src/map/storage.c @@ -24,7 +24,6 @@ #include -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) { diff --git a/src/map/storage.h b/src/map/storage.h index 221bc109d..25848d0db 100644 --- a/src/map/storage.h +++ b/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); diff --git a/src/txt-converter/char-converter.c b/src/txt-converter/char-converter.c index a5943729a..a43520f20 100644 --- a/src/txt-converter/char-converter.c +++ b/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); } -- cgit v1.2.3-60-g2f50