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
This commit is contained in:
ultramage 2008-07-13 16:14:32 +00:00
parent 89579bd5df
commit 4546c7fc0a
17 changed files with 185 additions and 481 deletions

View File

@ -3,9 +3,15 @@ Date Added
AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK. 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. 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 2008/07/12
* Fixed a bad check on NPC_EVILLAND, actually healing players instead of doing damage. [Brainstorm] * Fixed a bad check on NPC_EVILLAND, actually healing players instead of doing damage. [Brainstorm]
2008/07/10 2008/07/10
* Users can't click floating npcs directly. (quick fix for bugreport:1814) [FlavioJS] * Users can't click floating npcs directly. (quick fix for bugreport:1814) [FlavioJS]
2008/07/09 2008/07/09

View File

@ -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); 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 // Initialize friends list
parse_friend_txt(&char_dat[char_num].status); // Grab friends for the character parse_friend_txt(&char_dat[char_num].status); // Grab friends for the character
// Initialize hotkey list // Initialize hotkey list
@ -2774,7 +2776,11 @@ int parse_frommap(int fd)
break; break;
} }
if (i != char_num) if (i != char_num)
{
memcpy(&char_dat[i].status, RFIFOP(fd,13), sizeof(struct mmo_charstatus)); 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)) if (RFIFOB(fd,12))
{ //Flag, set character offline. [Skotlex] { //Flag, set character offline. [Skotlex]
set_char_offline(RFIFOL(fd,8),RFIFOL(fd,4)); set_char_offline(RFIFOL(fd,8),RFIFOL(fd,4));

View File

@ -32,7 +32,7 @@ int storage_tostr(char* str, struct storage_data* p)
{ {
int i,j,f=0; int i,j,f=0;
char *str_p = str; 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++) for(i=0;i<MAX_STORAGE;i++)
if( (p->items[i].nameid) && (p->items[i].amount) ) 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) 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) { static void* create_guildstorage(DBKey key, va_list args) {
@ -194,6 +194,24 @@ struct guild_storage *guild2storage(int guild_id)
return gs; 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() int inter_storage_init()
@ -359,29 +377,6 @@ int inter_guild_storage_delete(int guild_id)
//--------------------------------------------------------- //---------------------------------------------------------
// map serverへの通信 // 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) int mapif_load_guild_storage(int fd,int account_id,int guild_id)
{ {
struct guild_storage *gs=guild2storage(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からの通信 // 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) int mapif_parse_LoadGuildStorage(int fd)
{ {
RFIFOHEAD(fd); RFIFOHEAD(fd);
@ -481,8 +450,6 @@ int inter_storage_parse_frommap(int fd)
{ {
RFIFOHEAD(fd); RFIFOHEAD(fd);
switch(RFIFOW(fd,0)){ 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 0x3018: mapif_parse_LoadGuildStorage(fd); break;
case 0x3019: mapif_parse_SaveGuildStorage(fd); break; case 0x3019: mapif_parse_SaveGuildStorage(fd); break;
default: default:

View File

@ -22,4 +22,7 @@ extern char guild_storage_txt[1024];
int storage_fromstr(char *str,struct storage_data *p); int storage_fromstr(char *str,struct storage_data *p);
int guild_storage_fromstr(char *str,struct guild_storage *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_ */ #endif /* _INT_STORAGE_H_ */

View File

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

View File

@ -21,7 +21,6 @@
int storage_tosql(int account_id, struct storage_data* p) int storage_tosql(int account_id, struct storage_data* p)
{ {
memitemdata_to_sql(p->items, MAX_STORAGE, account_id, TABLE_STORAGE); memitemdata_to_sql(p->items, MAX_STORAGE, account_id, TABLE_STORAGE);
//ShowInfo ("storage save to DB - account: %d\n", account_id);
return 0; return 0;
} }
@ -159,29 +158,6 @@ int inter_guild_storage_delete(int guild_id)
//--------------------------------------------------------- //---------------------------------------------------------
// packet from map server // 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) 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) ) 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 // 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) int mapif_parse_LoadGuildStorage(int fd)
{ {
RFIFOHEAD(fd); RFIFOHEAD(fd);
@ -285,8 +239,6 @@ int inter_storage_parse_frommap(int fd)
{ {
RFIFOHEAD(fd); RFIFOHEAD(fd);
switch(RFIFOW(fd,0)){ 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 0x3018: mapif_parse_LoadGuildStorage(fd); break;
case 0x3019: mapif_parse_SaveGuildStorage(fd); break; case 0x3019: mapif_parse_SaveGuildStorage(fd); break;
default: default:

View File

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

View File

@ -178,6 +178,20 @@ struct status_change_data {
int val1, val2, val3, val4, tick; //Remaining duration. 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 { struct s_pet {
int account_id; int account_id;
int char_id; int char_id;
@ -264,6 +278,7 @@ struct mmo_charstatus {
struct point last_point,save_point,memo_point[MAX_MEMOPOINTS]; struct point last_point,save_point,memo_point[MAX_MEMOPOINTS];
struct item inventory[MAX_INVENTORY],cart[MAX_CART]; struct item inventory[MAX_INVENTORY],cart[MAX_CART];
struct storage_data storage;
struct skill skill[MAX_SKILL]; struct skill skill[MAX_SKILL];
struct s_friend friends[MAX_FRIENDS]; //New friend system [Skotlex] struct s_friend friends[MAX_FRIENDS]; //New friend system [Skotlex]
@ -329,22 +344,6 @@ struct registry {
struct global_reg account2[ACCOUNT_REG2_NUM]; 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 { struct gm_account {
int account_id; int account_id;
int level; int level;

View File

@ -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) 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); nullpo_retr(-1, sd);
if (!sd->status.guild_id) { if (!sd->status.guild_id) {
@ -1163,18 +1162,19 @@ int atcommand_guildstorage(const int fd, struct map_session_data* sd, const char
return -1; 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; return -1;
if (sd->state.storage_flag) { if (sd->state.storage_flag == 1) {
clif_displaymessage(fd, msg_txt(250));
return -1;
}
if (sd->state.storage_flag == 2) {
clif_displaymessage(fd, msg_txt(251)); clif_displaymessage(fd, msg_txt(251));
return -1; return -1;
} }
if ((stor = account2storage2(sd->status.account_id)) != NULL && stor->storage_status == 1) {
clif_displaymessage(fd, msg_txt(251));
return -1;
}
storage_guild_storageopen(sd); storage_guild_storageopen(sd);
clif_displaymessage(fd, "Guild storage opened."); clif_displaymessage(fd, "Guild storage opened.");
return 0; 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) if (sd->state.storage_flag != 1)
{ //Open storage. { //Open storage.
switch (storage_storageopen(sd)) { if( storage_storageopen(sd) == 1 ) {
case 2: //Try again
clif_displaymessage(fd, "run this command again..");
return 0;
case 1: //Failure
clif_displaymessage(fd, "You can't open the storage currently."); clif_displaymessage(fd, "You can't open the storage currently.");
return -1; return -1;
} }
} }
for (i = 0; i < MAX_INVENTORY; i++) { for (i = 0; i < MAX_INVENTORY; i++) {
if (sd->status.inventory[i].amount) { if (sd->status.inventory[i].amount) {
if(sd->status.inventory[i].equip != 0) if(sd->status.inventory[i].equip != 0)

View File

@ -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) 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 map_session_data *pl_sd;
struct item_data *item_data, *item_temp; 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]; char character[NAME_LENGTH], output[200], outputtmp[200];
nullpo_retr(-1, sd); nullpo_retr(-1, sd);
@ -634,27 +633,28 @@ int charcommand_storagelist(const int fd, struct map_session_data* sd, const cha
return -1; return -1;
} }
if((stor = account2storage2(pl_sd->status.account_id)) != NULL) { for (i = 0; i < MAX_STORAGE; i++)
counter = 0; {
count = 0; struct item* it = &sd->status.storage.items[i];
for (i = 0; i < MAX_STORAGE; i++) { if( it->nameid > 0 && (item_data = itemdb_search(it->nameid)) != NULL )
if (stor->items[i].nameid > 0 && (item_data = itemdb_search(stor->items[i].nameid)) != NULL) { {
counter = counter + stor->items[i].amount; counter = counter + it->amount;
count++; count++;
if (count == 1) { if (count == 1) {
sprintf(output, "------ Storage items list of '%s' ------", pl_sd->status.name); sprintf(output, "------ Storage items list of '%s' ------", pl_sd->status.name);
clif_displaymessage(fd, output); clif_displaymessage(fd, output);
} }
if (stor->items[i].refine) if (it->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); sprintf(output, "%d %s %+d (%s %+d, id: %d)", it->amount, item_data->name, it->refine, item_data->jname, it->refine, it->nameid);
else else
sprintf(output, "%d %s (%s, id: %d)", stor->items[i].amount, item_data->name, item_data->jname, stor->items[i].nameid); sprintf(output, "%d %s (%s, id: %d)", it->amount, item_data->name, item_data->jname, it->nameid);
clif_displaymessage(fd, output); clif_displaymessage(fd, output);
memset(output, '\0', sizeof(output)); memset(output, '\0', sizeof(output));
counter2 = 0; counter2 = 0;
for (j = 0; j < item_data->slot; j++) { for (j = 0; j < item_data->slot; j++) {
if (stor->items[i].card[j]) { if (it->card[j]) {
if ((item_temp = itemdb_search(stor->items[i].card[j])) != NULL) { if ((item_temp = itemdb_search(it->card[j])) != NULL) {
if (output[0] == '\0') if (output[0] == '\0')
sprintf(outputtmp, " -> (card(s): #%d %s (%s), ", ++counter2, item_temp->name, item_temp->jname); sprintf(outputtmp, " -> (card(s): #%d %s (%s), ", ++counter2, item_temp->name, item_temp->jname);
else else
@ -670,16 +670,13 @@ int charcommand_storagelist(const int fd, struct map_session_data* sd, const cha
} }
} }
} }
if (count == 0) if (count == 0)
clif_displaymessage(fd, "No item found in the storage of this player."); clif_displaymessage(fd, "No item found in the storage of this player.");
else { else {
sprintf(output, "%d item(s) found in %d kind(s) of items.", counter, count); sprintf(output, "%d item(s) found in %d kind(s) of items.", counter, count);
clif_displaymessage(fd, output); clif_displaymessage(fd, output);
} }
} else {
clif_displaymessage(fd, "This player has no storage.");
return 0;
}
return 0; 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) 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]; char character[NAME_LENGTH];
struct map_session_data *pl_sd; struct map_session_data *pl_sd;
@ -1665,23 +1661,20 @@ int charcommand_guildstorage(const int fd, struct map_session_data* sd, const ch
return -1; 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; return -1;
if (pl_sd->status.guild_id > 0) { 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) { if (pl_sd->state.storage_flag) {
clif_displaymessage(fd, "Guild storage is currently in use."); clif_displaymessage(fd, "Guild storage is currently in use.");
return -1; 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); storage_guild_storageopen(pl_sd);
} else {
clif_displaymessage(fd, "Target player is not in a guild.");
return -1;
}
clif_displaymessage(pl_sd->fd, "Guild storage opened."); clif_displaymessage(pl_sd->fd, "Guild storage opened.");
if (pl_sd->fd != fd) if (pl_sd->fd != fd)
@ -3190,12 +3183,7 @@ int charcommand_storeall(const int fd, struct map_session_data* sd, const char*
if (pl_sd->state.storage_flag != 1) if (pl_sd->state.storage_flag != 1)
{ //Open storage. { //Open storage.
switch (storage_storageopen(pl_sd)) { if( storage_storageopen(pl_sd) == 1 ) {
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
clif_displaymessage(fd, "The character currently can't use the storage."); clif_displaymessage(fd, "The character currently can't use the storage.");
return 1; return 1;
} }

View File

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

View File

@ -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; struct item_data *id;
int i,n,ne,fd=sd->fd; 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) 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); storage_storageclose(sd);
else else
if (sd->state.storage_flag == 2) if( sd->state.storage_flag == 2 )
storage_guild_storageclose(sd); storage_guild_storageclose(sd);
} }

View File

@ -32,7 +32,7 @@
static const int packet_len_table[]={ 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,-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 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 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 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; 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) int intif_request_guild_storage(int account_id,int guild_id)
{ {
if (CheckForCharServer()) if (CheckForCharServer())
@ -968,53 +942,6 @@ int intif_parse_Registers(int fd)
return 1; 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) int intif_parse_LoadGuildStorage(int fd)
{ {
struct guild_storage *gstor; struct guild_storage *gstor;
@ -1988,8 +1915,6 @@ int intif_parse(int fd)
case 0x3803: mapif_parse_WisToGM(fd); break; case 0x3803: mapif_parse_WisToGM(fd); break;
case 0x3804: intif_parse_Registers(fd); break; case 0x3804: intif_parse_Registers(fd); break;
case 0x3806: intif_parse_ChangeNameOk(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 0x3818: intif_parse_LoadGuildStorage(fd); break;
case 0x3819: intif_parse_SaveGuildStorage(fd); break; case 0x3819: intif_parse_SaveGuildStorage(fd); break;
case 0x3820: intif_parse_PartyCreated(fd); break; case 0x3820: intif_parse_PartyCreated(fd); break;

View File

@ -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_saveregistry(struct map_session_data *sd, int type);
int intif_request_registry(struct map_session_data *sd, int flag); 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_request_guild_storage(int account_id, int guild_id);
int intif_send_guild_storage(int account_id, struct guild_storage *gstor); int intif_send_guild_storage(int account_id, struct guild_storage *gstor);

View File

@ -24,7 +24,6 @@
#include <string.h> #include <string.h>
static DBMap* storage_db; // int account_id -> struct storage*
static DBMap* guild_storage_db; // int guild_id -> struct guild_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; return i1->nameid - i2->nameid;
} }
static void storage_sortitem (struct storage_data *stor) static void storage_sortitem(struct storage_data* stor)
{ {
nullpo_retv(stor); nullpo_retv(stor);
qsort(stor->items, MAX_STORAGE, sizeof(struct item), storage_comp_item); 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); nullpo_retv(gstor);
qsort(gstor->storage_, MAX_GUILD_STORAGE, sizeof(struct item), storage_comp_item); 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()‚©‚çŒÄ‚΂ê‚é 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); guild_storage_db=idb_alloc(DB_OPT_RELEASE_DATA);
return 1; return 1;
} }
void do_final_storage(void) // by [MC Cameri] void do_final_storage(void) // by [MC Cameri]
{ {
storage_db->destroy(storage_db,NULL);
guild_storage_db->destroy(guild_storage_db,NULL); guild_storage_db->destroy(guild_storage_db,NULL);
} }
static int storage_reconnect_sub(DBKey key,void *data,va_list ap) static int storage_reconnect_sub(DBKey key,void *data,va_list ap)
{ //Parses storage and saves 'dirty' ones upon reconnect. [Skotlex] { //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; struct guild_storage* stor = (struct guild_storage*) data;
if (stor->dirty && stor->storage_status == 0) //Save closed storages. if (stor->dirty && stor->storage_status == 0) //Save closed storages.
storage_guild_storagesave(0, stor->guild_id,0); 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);
}
return 0; return 0;
} }
//Function to be invoked upon server reconnection to char. To save all 'dirty' storages [Skotlex] //Function to be invoked upon server reconnection to char. To save all 'dirty' storages [Skotlex]
void do_reconnect_storage(void) void do_reconnect_storage(void)
{ {
storage_db->foreach(storage_db, storage_reconnect_sub, 0); guild_storage_db->foreach(guild_storage_db, storage_reconnect_sub);
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;
} }
/*========================================== /*==========================================
* Opens a storage. Returns: * Opens a storage. Returns:
* 0 - success * 0 - success
* 1 - fail * 1 - fail
* 2 - Storage requested from char-server (will open automatically later)
*------------------------------------------*/ *------------------------------------------*/
int storage_storageopen(struct map_session_data *sd) int storage_storageopen(struct map_session_data *sd)
{ {
struct storage_data *stor;
nullpo_retr(0, sd); nullpo_retr(0, sd);
if(sd->state.storage_flag) if(sd->state.storage_flag)
@ -141,19 +103,9 @@ int storage_storageopen(struct map_session_data *sd)
return 1; 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; sd->state.storage_flag = 1;
clif_storagelist(sd,stor); clif_storagelist(sd,&sd->status.storage);
clif_updatestorageamount(sd,stor->storage_amount); clif_updatestorageamount(sd,sd->status.storage.storage_amount);
return 0; return 0;
} }
@ -175,8 +127,9 @@ int compare_item(struct item *a, struct item *b)
/*========================================== /*==========================================
* Internal add-item function. * 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; struct item_data *data;
int i; int i;
@ -195,13 +148,12 @@ static int storage_additem(struct map_session_data* sd, struct storage_data* sto
{//Stackable {//Stackable
for( i = 0; i < MAX_STORAGE; i++ ) 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 {// existing items found, stack them
if( amount > MAX_AMOUNT - stor->items[i].amount ) if( amount > MAX_AMOUNT - stor->items[i].amount )
return 1; return 1;
stor->items[i].amount+=amount; stor->items[i].amount += amount;
clif_storageitemadded(sd,&stor->items[i],i,amount); clif_storageitemadded(sd,&stor->items[i],i,amount);
stor->dirty = 1;
if(log_config.enable_logs&0x800) if(log_config.enable_logs&0x800)
log_pick_pc(sd, "R", item_data->nameid, -amount, item_data); log_pick_pc(sd, "R", item_data->nameid, -amount, item_data);
return 0; return 0;
@ -216,11 +168,10 @@ static int storage_additem(struct map_session_data* sd, struct storage_data* sto
// add item to slot // add item to slot
memcpy(&stor->items[i],item_data,sizeof(stor->items[0])); memcpy(&stor->items[i],item_data,sizeof(stor->items[0]));
stor->items[i].amount=amount;
stor->storage_amount++; stor->storage_amount++;
stor->items[i].amount = amount;
clif_storageitemadded(sd,&stor->items[i],i,amount); clif_storageitemadded(sd,&stor->items[i],i,amount);
clif_updatestorageamount(sd,stor->storage_amount); clif_updatestorageamount(sd,stor->storage_amount);
stor->dirty = 1;
if(log_config.enable_logs&0x800) if(log_config.enable_logs&0x800)
log_pick_pc(sd, "R", item_data->nameid, -amount, item_data); 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 * 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; return 1;
stor->items[n].amount -= amount; sd->status.storage.items[n].amount -= amount;
if( log_config.enable_logs&0x800 ) if(log_config.enable_logs&0x800)
log_pick_pc(sd, "R", stor->items[n].nameid, amount, &stor->items[n]); 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])); memset(&sd->status.storage.items[n],0,sizeof(sd->status.storage.items[0]));
stor->storage_amount--; sd->status.storage.storage_amount--;
clif_updatestorageamount(sd,stor->storage_amount); clif_updatestorageamount(sd,sd->status.storage.storage_amount);
} }
clif_storageitemremoved(sd,n,amount); clif_storageitemremoved(sd,n,amount);
stor->dirty = 1;
return 0; 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) int storage_storageadd(struct map_session_data* sd, int index, int amount)
{ {
struct storage_data *stor;
nullpo_retr(0, sd); 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 return 0; // storage full
if( index < 0 || index >= MAX_INVENTORY ) if( index < 0 || index >= MAX_INVENTORY )
return 0; 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 ) if( amount < 1 || amount > sd->status.inventory[index].amount )
return 0; 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); pc_delitem(sd,index,amount,0);
return 1; 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) int storage_storageget(struct map_session_data* sd, int index, int amount)
{ {
struct storage_data *stor;
int flag; int flag;
nullpo_retr(0, sd);
nullpo_retr(0, stor=account2storage2(sd->status.account_id));
if( index < 0 || index >= MAX_STORAGE ) if( index < 0 || index >= MAX_STORAGE )
return 0; return 0;
if( stor->items[index].nameid <= 0 ) if( sd->status.storage.items[index].nameid <= 0 )
return 0; //Nothing there return 0; //Nothing there
if( amount < 1 || amount > stor->items[index].amount ) if( amount < 1 || amount > sd->status.storage.items[index].amount )
return 0; return 0;
if( (flag = pc_additem(sd,&stor->items[index],amount)) == 0 ) if( (flag = pc_additem(sd,&sd->status.storage.items[index],amount)) == 0 )
storage_delitem(sd,stor,index,amount); storage_delitem(sd,index,amount);
else else
clif_additem(sd,0,0,flag); 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) int storage_storageaddfromcart(struct map_session_data* sd, int index, int amount)
{ {
struct storage_data *stor;
nullpo_retr(0, sd); 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 return 0; // storage full / storage closed
if( index < 0 || index >= MAX_CART ) 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 ) if( amount < 1 || amount > sd->status.cart[index].amount )
return 0; 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); pc_cart_delitem(sd,index,amount,0);
return 1; 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) int storage_storagegettocart(struct map_session_data* sd, int index, int amount)
{ {
struct storage_data *stor;
nullpo_retr(0, sd); 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 ) if( index < 0 || index >= MAX_STORAGE )
return 0; return 0;
if( stor->items[index].nameid <= 0 ) if( sd->status.storage.items[index].nameid <= 0 )
return 0; //Nothing there. return 0; //Nothing there.
if( amount < 1 || amount > stor->items[index].amount ) if( amount < 1 || amount > sd->status.storage.items[index].amount )
return 0; return 0;
if( pc_cart_additem(sd,&stor->items[index],amount) == 0 ) if( pc_cart_additem(sd,&sd->status.storage.items[index],amount) == 0 )
storage_delitem(sd,stor,index,amount); storage_delitem(sd,index,amount);
return 1; 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] * 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_retv(sd);
nullpo_retr(0, sd);
nullpo_retr(0, stor=account2storage2(sd->status.account_id));
clif_storageclose(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. * 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_retv(sd);
nullpo_retr(0, sd);
nullpo_retr(0, stor=account2storage2(sd->status.account_id));
if( stor->storage_status )
{
if (save_settings&4) if (save_settings&4)
chrif_save(sd, flag); //Invokes the storage saving as well. 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; 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;
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;
}
//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) static void* create_guildstorage(DBKey key, va_list args)
{ {

View File

@ -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_storageget(struct map_session_data *sd,int index,int amount);
int storage_storageaddfromcart(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_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); int do_init_storage(void);
void do_final_storage(void); void do_final_storage(void);
void do_reconnect_storage(void); void do_reconnect_storage(void);
struct storage_data* account2storage(int account_id); void storage_storage_quit(struct map_session_data *sd, int flag);
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);
struct guild_storage* guild2storage(int guild_id); struct guild_storage* guild2storage(int guild_id);
int guild_storage_delete(int guild_id); int guild_storage_delete(int guild_id);

View File

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