diff options
author | ultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2008-07-13 16:14:32 +0000 |
---|---|---|
committer | ultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2008-07-13 16:14:32 +0000 |
commit | fb45ace1b19f98add7e1d0a0fc6fe45bc1ebac63 (patch) | |
tree | 52b66f102c20e6b47e060efe0e7ceabd36d5aa29 /src/map/storage.c | |
parent | 2e7ba13554118cdc78c9bfa5a6f0e5e8e58baf7b (diff) | |
download | hercules-fb45ace1b19f98add7e1d0a0fc6fe45bc1ebac63.tar.gz hercules-fb45ace1b19f98add7e1d0a0fc6fe45bc1ebac63.tar.bz2 hercules-fb45ace1b19f98add7e1d0a0fc6fe45bc1ebac63.tar.xz hercules-fb45ace1b19f98add7e1d0a0fc6fe45bc1ebac63.zip |
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
Diffstat (limited to 'src/map/storage.c')
-rw-r--r-- | src/map/storage.c | 240 |
1 files changed, 48 insertions, 192 deletions
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 <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) { |