summaryrefslogtreecommitdiff
path: root/src/map/storage.c
diff options
context:
space:
mode:
authorultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec>2008-07-13 16:14:32 +0000
committerultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec>2008-07-13 16:14:32 +0000
commitfb45ace1b19f98add7e1d0a0fc6fe45bc1ebac63 (patch)
tree52b66f102c20e6b47e060efe0e7ceabd36d5aa29 /src/map/storage.c
parent2e7ba13554118cdc78c9bfa5a6f0e5e8e58baf7b (diff)
downloadhercules-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.c240
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)
{