diff options
author | Haru <haru@dotalux.com> | 2017-05-27 19:24:42 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-27 19:24:42 +0200 |
commit | cb3e2f5f3b91d0a1f7711eff9c10ae9a655a74f2 (patch) | |
tree | 1b1df55f4143bae6bed85093f3424b6af11e4a01 /src/char | |
parent | be118c7fad6df29dc691452ef511ac12fea37a06 (diff) | |
parent | d966a8e6860d418bb3a235e57928436127eba555 (diff) | |
download | hercules-cb3e2f5f3b91d0a1f7711eff9c10ae9a655a74f2.tar.gz hercules-cb3e2f5f3b91d0a1f7711eff9c10ae9a655a74f2.tar.bz2 hercules-cb3e2f5f3b91d0a1f7711eff9c10ae9a655a74f2.tar.xz hercules-cb3e2f5f3b91d0a1f7711eff9c10ae9a655a74f2.zip |
Merge pull request #1722 from Smokexyz/mmo_charstatus-fix
Dismemberment of `storage_data` from `mmo_charstatus`.
Diffstat (limited to 'src/char')
-rw-r--r-- | src/char/char.c | 20 | ||||
-rw-r--r-- | src/char/int_storage.c | 349 | ||||
-rw-r--r-- | src/char/int_storage.h | 11 | ||||
-rw-r--r-- | src/char/inter.c | 2 | ||||
-rw-r--r-- | src/char/mapif.c | 8 | ||||
-rw-r--r-- | src/char/mapif.h | 4 |
6 files changed, 345 insertions, 49 deletions
diff --git a/src/char/char.c b/src/char/char.c index 93078f8ee..487bec763 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -287,11 +287,17 @@ void char_set_char_offline(int char_id, int account_id) } else { - struct mmo_charstatus* cp = (struct mmo_charstatus*)idb_get(chr->char_db_,char_id); + struct mmo_charstatus* cp = (struct mmo_charstatus*) idb_get(chr->char_db_,char_id); + struct storage_data *stor = (struct storage_data *) idb_get(inter_storage->account_storage, account_id); + inter_guild->CharOffline(char_id, cp?cp->guild_id:-1); + if (cp) idb_remove(chr->char_db_,char_id); + if (stor) /* Remove inter-storage data. */ + idb_remove(inter_storage->account_storage, account_id); + if( SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `online`='0' WHERE `char_id`='%d' LIMIT 1", char_db, char_id) ) Sql_ShowDebug(inter->sql_handle); } @@ -442,14 +448,6 @@ int char_mmo_char_tosql(int char_id, struct mmo_charstatus* p) errors++; } - //map storage data - if( memcmp(p->storage.items, cp->storage.items, sizeof(p->storage.items)) ) { - if (!chr->memitemdata_to_sql(p->storage.items, MAX_STORAGE, p->account_id, TABLE_STORAGE)) - strcat(save_status, " storage"); - else - errors++; - } - if ( (p->base_exp != cp->base_exp) || (p->base_level != cp->base_level) || (p->job_level != cp->job_level) || (p->job_exp != cp->job_exp) || @@ -1284,10 +1282,6 @@ int char_mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_every strcat(t_msg, " cart"); - //read storage - inter_storage->fromsql(p->account_id, &p->storage); - strcat(t_msg, " storage"); - //read skill //`skill` (`char_id`, `id`, `lv`) memset(&tmp_skill, 0, sizeof(tmp_skill)); diff --git a/src/char/int_storage.c b/src/char/int_storage.c index b78ad9f0e..5f005005e 100644 --- a/src/char/int_storage.c +++ b/src/char/int_storage.c @@ -41,24 +41,145 @@ struct inter_storage_interface inter_storage_s; struct inter_storage_interface *inter_storage; /// Save storage data to sql -int inter_storage_tosql(int account_id, struct storage_data* p) +int inter_storage_tosql(int account_id, struct storage_data *cp, const struct storage_data *p) { + int i = 0, j = 0; + bool updated_p[MAX_STORAGE] = { false }; + int delete[MAX_STORAGE] = { 0 }; + int total_deletes = 0, total_updates = 0, total_inserts = 0; + int total_changes = 0; + StringBuf buf; + + nullpo_ret(cp); nullpo_ret(p); - chr->memitemdata_to_sql(p->items, MAX_STORAGE, account_id, TABLE_STORAGE); - return 0; + + StrBuf->Init(&buf); + + + if (VECTOR_LENGTH(cp->item) > 0) { + /** + * Compare and update items, if any. + */ + for (i = 0; i < VECTOR_LENGTH(cp->item); i++) { + struct item *cp_it = &VECTOR_INDEX(cp->item, i); + struct item *p_it = NULL; + + ARR_FIND(0, VECTOR_LENGTH(p->item), j, + updated_p[j] != true + && (p_it = &VECTOR_INDEX(p->item, j)) != NULL + && cp_it->nameid == p_it->nameid + && cp_it->unique_id == p_it->unique_id + && memcmp(p_it->card, cp_it->card, sizeof(short) * MAX_SLOTS) == 0 + && memcmp(p_it->option, cp_it->option, 5 * MAX_ITEM_OPTIONS) == 0); + + if (j < VECTOR_LENGTH(p->item)) { + int k = 0; + if (memcmp(cp_it, p_it, sizeof(struct item)) != 0) { + if (total_updates == 0) { + StrBuf->Printf(&buf, "REPLACE INTO `%s` (`id`, `account_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`", storage_db); + for (k = 0; k < MAX_SLOTS; k++) + StrBuf->Printf(&buf, ", `card%d`", k); + for (k = 0; k < MAX_ITEM_OPTIONS; k++) + StrBuf->Printf(&buf, ", `opt_idx%d`, `opt_val%d`", k, k); + StrBuf->AppendStr(&buf, ", `expire_time`, `bound`, `unique_id`) VALUES"); + } + + StrBuf->Printf(&buf, "('%d', '%d', '%d', '%d', '%u', '%d', '%d', '%d'", + cp_it->id, account_id, p_it->nameid, p_it->amount, p_it->equip, p_it->identify, p_it->refine, p_it->attribute); + for (k = 0; k < MAX_SLOTS; k++) + StrBuf->Printf(&buf, ", '%d'", p_it->card[k]); + for (k = 0; k < MAX_ITEM_OPTIONS; ++k) + StrBuf->Printf(&buf, ", '%d', '%d'", p_it->option[k].index, p_it->option[k].value); + StrBuf->Printf(&buf, ", '%u', '%d', '%"PRIu64"')%s", p_it->expire_time, p_it->bound, p_it->unique_id, total_updates > 0 ? ", " : ""); + + total_updates++; + updated_p[j] = true; + } + } else { // Does not exist, so set for deletion. + delete[total_deletes++] = cp_it->id; + } + } + + if (total_updates > 0 && SQL_ERROR == SQL->QueryStr(inter->sql_handle, StrBuf->Value(&buf))) + Sql_ShowDebug(inter->sql_handle); + + /** + * Handle deletions, if any. + */ + if (total_deletes > 0) { + StrBuf->Clear(&buf); + StrBuf->Printf(&buf, "DELETE FROM `%s` WHERE `id` IN (", storage_db); + for (i = 0; i < total_deletes; i++) { + StrBuf->Printf(&buf, "%s'%d'", i == 0 ? "" : ", ", delete[i]); + } + StrBuf->AppendStr(&buf, ");"); + + if (SQL_ERROR == SQL->QueryStr(inter->sql_handle, StrBuf->Value(&buf))) + Sql_ShowDebug(inter->sql_handle); + } + } + + /** + * Check for new items. + */ + for (i = 0; i < VECTOR_LENGTH(p->item); i++) { + struct item *p_it = &VECTOR_INDEX(p->item, i); + + if (p_it->id != 0) + continue; // Item is not a new entry, so lets continue. + + // Store the remaining items. + if (total_inserts == 0) { + StrBuf->Clear(&buf); + StrBuf->Printf(&buf, "INSERT INTO `%s` (`account_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`, `unique_id`", storage_db); + for (j = 0; j < MAX_SLOTS; ++j) + StrBuf->Printf(&buf, ", `card%d`", j); + for (j = 0; j < MAX_ITEM_OPTIONS; ++j) + StrBuf->Printf(&buf, ", `opt_idx%d`, `opt_val%d`", j, j); + StrBuf->AppendStr(&buf, ") VALUES "); + } + + StrBuf->Printf(&buf, "%s('%d', '%d', '%d', '%u', '%d', '%d', '%d', '%u', '%d', '%"PRIu64"'", + total_inserts > 0 ? ", " : "", account_id, p_it->nameid, p_it->amount, p_it->equip, p_it->identify, p_it->refine, + p_it->attribute, p_it->expire_time, p_it->bound, p_it->unique_id); + for (j = 0; j < MAX_SLOTS; ++j) + StrBuf->Printf(&buf, ", '%d'", p_it->card[j]); + for (j = 0; j < MAX_ITEM_OPTIONS; ++j) + StrBuf->Printf(&buf, ", '%d', '%d'", p_it->option[j].index, p_it->option[j].value); + StrBuf->AppendStr(&buf, ")"); + + total_inserts++; + } + + if (total_inserts > 0 && SQL_ERROR == SQL->QueryStr(inter->sql_handle, StrBuf->Value(&buf))) + Sql_ShowDebug(inter->sql_handle); + + StrBuf->Destroy(&buf); + + /* re-sync loaded data with current table data. */ + VECTOR_CLEAR(cp->item); + inter_storage->fromsql(account_id, cp); + + total_changes = total_inserts + total_updates + total_deletes; + + ShowInfo("storage save complete - id: %d (total: %d)\n", account_id, total_changes); + + return total_changes; } /// Load storage data to mem -int inter_storage_fromsql(int account_id, struct storage_data* p) +int inter_storage_fromsql(int account_id, struct storage_data *p) { StringBuf buf; char* data; int i; int j; + int num_rows = 0; nullpo_ret(p); - memset(p, 0, sizeof(struct storage_data)); //clean up memory - p->storage_amount = 0; + + if (VECTOR_LENGTH(p->item) > 0) + VECTOR_CLEAR(p->item); // storage {`account_id`/`id`/`nameid`/`amount`/`equip`/`identify`/`refine`/`attribute`/`card0`/`card1`/`card2`/`card3`} StrBuf->Init(&buf); @@ -74,36 +195,46 @@ int inter_storage_fromsql(int account_id, struct storage_data* p) StrBuf->Destroy(&buf); - for (i = 0; i < MAX_STORAGE && SQL_SUCCESS == SQL->NextRow(inter->sql_handle); ++i) { - struct item *item = &p->items[i]; - SQL->GetData(inter->sql_handle, 0, &data, NULL); item->id = atoi(data); - SQL->GetData(inter->sql_handle, 1, &data, NULL); item->nameid = atoi(data); - SQL->GetData(inter->sql_handle, 2, &data, NULL); item->amount = atoi(data); - SQL->GetData(inter->sql_handle, 3, &data, NULL); item->equip = atoi(data); - SQL->GetData(inter->sql_handle, 4, &data, NULL); item->identify = atoi(data); - SQL->GetData(inter->sql_handle, 5, &data, NULL); item->refine = atoi(data); - SQL->GetData(inter->sql_handle, 6, &data, NULL); item->attribute = atoi(data); - SQL->GetData(inter->sql_handle, 7, &data, NULL); item->expire_time = (unsigned int)atoi(data); - SQL->GetData(inter->sql_handle, 8, &data, NULL); item->bound = atoi(data); - SQL->GetData(inter->sql_handle, 9, &data, NULL); item->unique_id = strtoull(data, NULL, 10); - /* Card Slots */ - for (j = 0; j < MAX_SLOTS; ++j) { - SQL->GetData(inter->sql_handle, 10 + j, &data, NULL); - item->card[j] = atoi(data); - } - /* Item Options */ - for (j = 0; j < MAX_ITEM_OPTIONS; ++j) { - SQL->GetData(inter->sql_handle, 10 + MAX_SLOTS + j * 2, &data, NULL); - item->option[j].index = atoi(data); - SQL->GetData(inter->sql_handle, 11 + MAX_SLOTS + j * 2, &data, NULL); - item->option[j].value = atoi(data); + if ((num_rows = (int)SQL->NumRows(inter->sql_handle)) != 0) { + + VECTOR_ENSURE(p->item, num_rows > MAX_STORAGE ? MAX_STORAGE : num_rows, 1); + + for (i = 0; i < MAX_STORAGE && SQL_SUCCESS == SQL->NextRow(inter->sql_handle); ++i) { + struct item item = { 0 }; + SQL->GetData(inter->sql_handle, 0, &data, NULL); item.id = atoi(data); + SQL->GetData(inter->sql_handle, 1, &data, NULL); item.nameid = atoi(data); + SQL->GetData(inter->sql_handle, 2, &data, NULL); item.amount = atoi(data); + SQL->GetData(inter->sql_handle, 3, &data, NULL); item.equip = atoi(data); + SQL->GetData(inter->sql_handle, 4, &data, NULL); item.identify = atoi(data); + SQL->GetData(inter->sql_handle, 5, &data, NULL); item.refine = atoi(data); + SQL->GetData(inter->sql_handle, 6, &data, NULL); item.attribute = atoi(data); + SQL->GetData(inter->sql_handle, 7, &data, NULL); item.expire_time = (unsigned int)atoi(data); + SQL->GetData(inter->sql_handle, 8, &data, NULL); item.bound = atoi(data); + SQL->GetData(inter->sql_handle, 9, &data, NULL); item.unique_id = strtoull(data, NULL, 10); + + /* Card Slots */ + for (j = 0; j < MAX_SLOTS; ++j) { + SQL->GetData(inter->sql_handle, 10 + j, &data, NULL); + item.card[j] = atoi(data); + } + + /* Item Options */ + for (j = 0; j < MAX_ITEM_OPTIONS; ++j) { + SQL->GetData(inter->sql_handle, 10 + MAX_SLOTS + j * 2, &data, NULL); + item.option[j].index = atoi(data); + SQL->GetData(inter->sql_handle, 11 + MAX_SLOTS + j * 2, &data, NULL); + item.option[j].value = atoi(data); + } + + VECTOR_PUSH(p->item, item); } } - p->storage_amount = i; + SQL->FreeResult(inter->sql_handle); - ShowInfo("storage load complete from DB - id: %d (total: %d)\n", account_id, p->storage_amount); - return 1; + ShowInfo("storage load complete from DB - id: %d (total: %d)\n", account_id, VECTOR_LENGTH(p->item)); + + return VECTOR_LENGTH(p->item); } /// Save guild_storage data to sql @@ -174,15 +305,49 @@ int inter_storage_guild_storage_fromsql(int guild_id, struct guild_storage* p) return 0; } +/** + * Ensures storage data entity for a character. + * @see DBCreateData + */ +static struct DBData inter_storage_ensure_account_storage(union DBKey key, va_list args) +{ + struct storage_data *stor = NULL; + + CREATE(stor, struct storage_data, 1); + + stor->save = false; + stor->aggregate = 0; + + VECTOR_INIT(stor->item); + + return DB->ptr2data(stor); +} + +/** + * Cleaning function called through db_destroy() for vectors in storage_data. + */ +int inter_storage_clear_account_storage(union DBKey key, struct DBData *data, va_list args) +{ + struct storage_data *stor = DB->data2ptr(data); + + VECTOR_CLEAR(stor->item); + + return 0; +} + //--------------------------------------------------------- // storage data initialize int inter_storage_sql_init(void) { + inter_storage->account_storage = idb_alloc(DB_OPT_RELEASE_DATA); + return 1; } // storage data finalize void inter_storage_sql_final(void) { + inter_storage->account_storage->destroy(inter_storage->account_storage, inter_storage->clear_account_storage); + return; } @@ -240,13 +405,126 @@ int mapif_save_guild_storage_ack(int fd, int account_id, int guild_id, int fail) return 0; } +//========================================================= +// Account Storage //--------------------------------------------------------- -// packet from map server +/** + * Parses account storage load request from map server. + * @packet 0x3010 [in] <account_id>.L + * @param fd [in] file/socket descriptor + * @return 1 on success, 0 on failure. + */ +int mapif_parse_AccountStorageLoad(int fd) +{ + int account_id = RFIFOL(fd, 2); + + Assert_ret(fd > 0); + Assert_ret(account_id > 0); + + mapif->account_storage_load(fd, account_id); + + return 1; +} + +/** + * Loads the account storage and send to the map server. + * @packet 0x3805 [out] <account_id>.L <struct item[]>.P + * @param fd [in] file/socket descriptor. + * @param account_id [in] account id of the session. + * @return 1 on success, 0 on failure. + */ +int mapif_account_storage_load(int fd, int account_id) +{ + struct storage_data *stor = NULL; + int count = 0, i = 0, len = 0; + + Assert_ret(account_id > 0); + + stor = (struct storage_data *) idb_ensure(inter_storage->account_storage, account_id, inter_storage->ensure_account_storage); + + count = inter_storage->fromsql(account_id, stor); + + len = 8 + count * sizeof(struct item); + + WFIFOHEAD(fd, len); + WFIFOW(fd, 0) = 0x3805; + WFIFOW(fd, 2) = (uint16) len; + WFIFOL(fd, 4) = account_id; + for (i = 0; i < count; i++) + memcpy(WFIFOP(fd, 8 + i * sizeof(struct item)), &VECTOR_INDEX(stor->item, i), sizeof(struct item)); + WFIFOSET(fd, len); + + return 1; +} + +/** + * Parses an account storage save request from the map server. + * @packet 0x3011 [in] <packet_len>.W <account_id>.L <struct item[]>.P + * @param fd [in] file/socket descriptor. + * @return 1 on success, 0 on failure. + */ +int mapif_parse_AccountStorageSave(int fd) +{ + int payload_size = RFIFOW(fd, 2) - 8, account_id = RFIFOL(fd, 4); + int i = 0, count = 0; + struct storage_data *cp_stor = NULL, p_stor = { 0 }; + + Assert_ret(fd > 0); + Assert_ret(account_id > 0); + + cp_stor = (struct storage_data *) idb_ensure(inter_storage->account_storage, account_id, inter_storage->ensure_account_storage); + + count = payload_size/sizeof(struct item); + + VECTOR_INIT(p_stor.item); + + if (count > 0) { + VECTOR_ENSURE(p_stor.item, count, 1); + + for (i = 0; i < count; i++) { + const struct item *it = RFIFOP(fd, 8 + i * sizeof(struct item)); + + VECTOR_PUSH(p_stor.item, *it); + } + + p_stor.aggregate = count; + } + inter_storage->tosql(account_id, cp_stor, &p_stor); + + VECTOR_CLEAR(p_stor.item); + + mapif->sAccountStorageSaveAck(fd, account_id, true); + + return 1; +} + +/** + * Sends an acknowledgement for the save + * status of the account storage. + * @packet 0x3808 [out] <account_id>.L <save_flag>.B + * @param fd [in] File/Socket Descriptor. + * @param account_id [in] Account ID of the storage in question. + * @param flag [in] Save flag, true for success and false for failure. + */ +void mapif_send_AccountStorageSaveAck(int fd, int account_id, bool flag) +{ + WFIFOHEAD(fd, 7); + WFIFOW(fd, 0) = 0x3808; + WFIFOL(fd, 2) = account_id; + WFIFOB(fd, 6) = flag ? 1 : 0; + WFIFOSET(fd, 7); +} + +//========================================================= +// Guild Storage +//--------------------------------------------------------- int mapif_parse_LoadGuildStorage(int fd) { RFIFOHEAD(fd); + mapif->load_guild_storage(fd,RFIFOL(fd,2),RFIFOL(fd,6),1); + return 0; } @@ -274,6 +552,7 @@ int mapif_parse_SaveGuildStorage(int fd) SQL->FreeResult(inter->sql_handle); } mapif->save_guild_storage_ack(fd, RFIFOL(fd,4), guild_id, 1); + return 0; } @@ -487,6 +766,8 @@ int inter_storage_parse_frommap(int fd) { RFIFOHEAD(fd); switch(RFIFOW(fd,0)){ + case 0x3010: mapif->pAccountStorageLoad(fd); break; + case 0x3011: mapif->pAccountStorageSave(fd); break; case 0x3018: mapif->parse_LoadGuildStorage(fd); break; case 0x3019: mapif->parse_SaveGuildStorage(fd); break; #ifdef GP_BOUND_ITEMS @@ -502,6 +783,8 @@ void inter_storage_defaults(void) { inter_storage = &inter_storage_s; + inter_storage->ensure_account_storage = inter_storage_ensure_account_storage; + inter_storage->clear_account_storage = inter_storage_clear_account_storage; inter_storage->tosql = inter_storage_tosql; inter_storage->fromsql = inter_storage_fromsql; inter_storage->guild_storage_tosql = inter_storage_guild_storage_tosql; diff --git a/src/char/int_storage.h b/src/char/int_storage.h index 8c6341e85..1f6c03f13 100644 --- a/src/char/int_storage.h +++ b/src/char/int_storage.h @@ -21,6 +21,7 @@ #ifndef CHAR_INT_STORAGE_H #define CHAR_INT_STORAGE_H +#include "common/db.h" #include "common/hercules.h" struct storage_data; @@ -30,8 +31,14 @@ struct guild_storage; * inter_storage interface **/ struct inter_storage_interface { - int (*tosql) (int account_id, struct storage_data* p); - int (*fromsql) (int account_id, struct storage_data* p); + /* */ + struct DBMap *account_storage; + /* */ + /* */ + struct DBData (*ensure_account_storage) (union DBKey key, va_list args); + int (*clear_account_storage) (union DBKey key, struct DBData *data, va_list args); + int (*tosql) (int account_id, struct storage_data *cp, const struct storage_data *p); + int (*fromsql) (int account_id, struct storage_data *p); int (*guild_storage_tosql) (int guild_id, const struct guild_storage *p); int (*guild_storage_fromsql) (int guild_id, struct guild_storage* p); int (*sql_init) (void); diff --git a/src/char/inter.c b/src/char/inter.c index d076bb657..cfbc0fd4d 100644 --- a/src/char/inter.c +++ b/src/char/inter.c @@ -68,7 +68,7 @@ int party_share_level = 10; // recv. packet list int inter_recv_packet_length[] = { -1,-1, 7,-1, -1,13,36, (2 + 4 + 4 + 4 + NAME_LENGTH), 0, 0, 0, 0, 0, 0, 0, 0, // 3000- - 6,-1, 0, 0, 0, 0, 0, 0, 10,-1, 0, 0, 0, 0, 0, 0, // 3010- + 6,-1, 0, 0, 0, 0, 0, 0, 10,-1, 0, 0, 0, 0, 0, 0, // 3010- Account Storage [Smokexyz] -1,10,-1,14, 14,19, 6,-1, 14,14, 0, 0, 0, 0, 0, 0, // 3020- Party -1, 6,-1,-1, 55,19, 6,-1, 14,-1,-1,-1, 18,19,186,-1, // 3030- -1, 9, 0, 0, 0, 0, 0, 0, 7, 6,10,10, 10,-1, 0, 0, // 3040- diff --git a/src/char/mapif.c b/src/char/mapif.c index 1dafb79c3..5fff96ba8 100644 --- a/src/char/mapif.c +++ b/src/char/mapif.c @@ -186,6 +186,10 @@ int mapif_load_guild_storage(int fd,int account_id,int guild_id, char flag); int mapif_save_guild_storage_ack(int fd, int account_id, int guild_id, int fail); int mapif_parse_LoadGuildStorage(int fd); int mapif_parse_SaveGuildStorage(int fd); +int mapif_account_storage_load(int fd, int account_id); +int mapif_parse_AccountStorageLoad(int fd); +int mapif_parse_AccountStorageSave(int fd); +void mapif_send_AccountStorageSaveAck(int fd, int account_id, bool save); int mapif_itembound_ack(int fd, int aid, int guild_id); int mapif_parse_ItemBoundRetrieve_sub(int fd); void mapif_parse_ItemBoundRetrieve(int fd); @@ -363,6 +367,10 @@ void mapif_defaults(void) { mapif->save_guild_storage_ack = mapif_save_guild_storage_ack; mapif->parse_LoadGuildStorage = mapif_parse_LoadGuildStorage; mapif->parse_SaveGuildStorage = mapif_parse_SaveGuildStorage; + mapif->pAccountStorageLoad = mapif_parse_AccountStorageLoad; + mapif->pAccountStorageSave = mapif_parse_AccountStorageSave; + mapif->sAccountStorageSaveAck = mapif_send_AccountStorageSaveAck; + mapif->account_storage_load = mapif_account_storage_load; mapif->itembound_ack = mapif_itembound_ack; mapif->parse_ItemBoundRetrieve_sub = mapif_parse_ItemBoundRetrieve_sub; mapif->parse_ItemBoundRetrieve = mapif_parse_ItemBoundRetrieve; diff --git a/src/char/mapif.h b/src/char/mapif.h index ebbddead0..07fbed6c6 100644 --- a/src/char/mapif.h +++ b/src/char/mapif.h @@ -180,6 +180,10 @@ struct mapif_interface { int (*save_guild_storage_ack) (int fd, int account_id, int guild_id, int fail); int (*parse_LoadGuildStorage) (int fd); int (*parse_SaveGuildStorage) (int fd); + int (*account_storage_load) (int fd, int account_id); + int (*pAccountStorageLoad) (int fd); + int (*pAccountStorageSave) (int fd); + void (*sAccountStorageSaveAck) (int fd, int account_id, bool save); int (*itembound_ack) (int fd, int aid, int guild_id); int (*parse_ItemBoundRetrieve_sub) (int fd); void (*parse_ItemBoundRetrieve) (int fd); |