From 05c1c0552fe6c94d8835a58f4608d0402614ce39 Mon Sep 17 00:00:00 2001 From: Jesusaves Date: Mon, 8 Mar 2021 11:45:01 -0300 Subject: [TMW2] Hercules Ultimate Storage System --- src/char/int_storage.c | 58 +-- src/char/int_storage.h | 4 +- src/char/inter.c | 2 +- src/char/mapif.c | 52 ++- src/char/mapif.h | 4 +- src/common/HPMDataCheck.h | 1 + src/common/mmo.h | 8 + src/map/atcommand.c | 131 ++++++- src/map/chrif.c | 13 +- src/map/clif.c | 89 +++-- src/map/clif.h | 2 +- src/map/intif.c | 88 +++-- src/map/intif.h | 4 +- src/map/map.c | 20 + src/map/map.h | 1 + src/map/pc.c | 34 +- src/map/pc.h | 7 +- src/map/script.c | 40 +- src/map/storage.c | 401 ++++++++++++++++----- src/map/storage.h | 35 +- src/map/unit.c | 13 +- src/plugins/HPMHooking/HPMHooking.Defs.inc | 70 ++-- src/plugins/HPMHooking/HPMHooking_char.Hooks.inc | 48 +-- .../HPMHooking/HPMHooking_map.HPMHooksCore.inc | 28 ++ .../HPMHooking/HPMHooking_map.HookingPoints.inc | 7 + src/plugins/HPMHooking/HPMHooking_map.Hooks.inc | 306 +++++++++++++--- 26 files changed, 1107 insertions(+), 359 deletions(-) diff --git a/src/char/int_storage.c b/src/char/int_storage.c index 130df5515..7d2a69468 100644 --- a/src/char/int_storage.c +++ b/src/char/int_storage.c @@ -41,24 +41,25 @@ static struct inter_storage_interface inter_storage_s; struct inter_storage_interface *inter_storage; /// Save storage data to sql -static int inter_storage_tosql(int account_id, const struct storage_data *p) +static int inter_storage_tosql(int account_id, int storage_id, const struct storage_data *p) { - int i = 0, j = 0; - bool matched_p[MAX_STORAGE] = { false }; - int delete[MAX_STORAGE] = { 0 }; - int total_deletes = 0, total_updates = 0, total_inserts = 0; - int total_changes = 0; - struct storage_data cp = { 0 }; - StringBuf buf; - nullpo_ret(p); + struct storage_data cp = { 0 }; VECTOR_INIT(cp.item); - inter_storage->fromsql(account_id, &cp); + int cp_size = inter_storage->fromsql(account_id, storage_id, &cp, 0); + + bool *matched_p = aCalloc(VECTOR_LENGTH(p->item), sizeof(bool)); + + StringBuf buf; StrBuf->Init(&buf); + int total_deletes = 0, total_updates = 0, total_inserts = 0; + int i = 0, j = 0; if (VECTOR_LENGTH(cp.item) > 0) { + int *delete = aCalloc(cp_size, sizeof(int)); + /** * Compare and update items, if any. */ @@ -78,7 +79,7 @@ static int inter_storage_tosql(int account_id, const struct storage_data *p) 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); + StrBuf->Printf(&buf, "REPLACE INTO `%s` (`id`, `account_id`, `storage_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++) @@ -86,8 +87,8 @@ static int inter_storage_tosql(int account_id, const struct storage_data *p) StrBuf->AppendStr(&buf, ", `expire_time`, `bound`, `unique_id`) VALUES"); } - StrBuf->Printf(&buf, "%s('%d', '%d', '%d', '%d', '%u', '%d', '%d', '%d'", - total_updates > 0 ? ", " : "", cp_it->id, account_id, p_it->nameid, p_it->amount, p_it->equip, p_it->identify, p_it->refine, p_it->attribute); + StrBuf->Printf(&buf, "%s('%d', '%d', '%d', '%d', '%d', '%u', '%d', '%d', '%d'", + total_updates > 0 ? ", " : "", cp_it->id, account_id, storage_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) @@ -119,6 +120,8 @@ static int inter_storage_tosql(int account_id, const struct storage_data *p) if (SQL_ERROR == SQL->QueryStr(inter->sql_handle, StrBuf->Value(&buf))) Sql_ShowDebug(inter->sql_handle); } + + aFree(delete); } /** @@ -133,7 +136,7 @@ static int inter_storage_tosql(int account_id, const struct storage_data *p) // 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); + StrBuf->Printf(&buf, "INSERT INTO `%s` (`account_id`, `storage_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) @@ -141,8 +144,8 @@ static int inter_storage_tosql(int account_id, const struct storage_data *p) 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, + StrBuf->Printf(&buf, "%s('%d', '%d', '%d', '%d', '%u', '%d', '%d', '%d', '%u', '%d', '%"PRIu64"'", + total_inserts > 0 ? ", " : "", account_id, storage_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]); @@ -159,13 +162,15 @@ static int inter_storage_tosql(int account_id, const struct storage_data *p) StrBuf->Destroy(&buf); VECTOR_CLEAR(cp.item); - total_changes = total_inserts + total_updates + total_deletes; - ShowInfo("storage save complete - id: %d (total: %d)\n", account_id, total_changes); - return total_changes; + aFree(matched_p); + + ShowInfo("Storage #%d save complete - id: %d (replace: %d, insert: %d, delete: %d)\n", storage_id, account_id, total_updates, total_inserts, total_deletes); + + return total_inserts + total_updates + total_deletes; } /// Load storage data to mem -static int inter_storage_fromsql(int account_id, struct storage_data *p) +static int inter_storage_fromsql(int account_id, int storage_id, struct storage_data *p, int storage_size) { StringBuf buf; char* data; @@ -174,6 +179,7 @@ static int inter_storage_fromsql(int account_id, struct storage_data *p) int num_rows = 0; nullpo_ret(p); + Assert_ret(storage_size >= 0); if (VECTOR_LENGTH(p->item) > 0) VECTOR_CLEAR(p->item); @@ -185,7 +191,7 @@ static int inter_storage_fromsql(int account_id, struct storage_data *p) 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->Printf(&buf, " FROM `%s` WHERE `account_id`='%d' ORDER BY `nameid`", storage_db, account_id); + StrBuf->Printf(&buf, " FROM `%s` WHERE `account_id`='%d' AND `storage_id`='%d' ORDER BY `nameid`", storage_db, account_id, storage_id); if (SQL_ERROR == SQL->QueryStr(inter->sql_handle, StrBuf->Value(&buf))) Sql_ShowDebug(inter->sql_handle); @@ -194,10 +200,14 @@ static int inter_storage_fromsql(int account_id, struct storage_data *p) if ((num_rows = (int)SQL->NumRows(inter->sql_handle)) != 0) { - VECTOR_ENSURE(p->item, num_rows > MAX_STORAGE ? MAX_STORAGE : num_rows, 1); + VECTOR_ENSURE(p->item, storage_size > 0 ? min(num_rows, storage_size) : num_rows, 1); - for (i = 0; i < MAX_STORAGE && SQL_SUCCESS == SQL->NextRow(inter->sql_handle); ++i) { + for (i = 0; SQL_SUCCESS == SQL->NextRow(inter->sql_handle); ++i) { struct item item = { 0 }; + + if (storage_size > 0 && i > storage_size) + break; + 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); @@ -229,7 +239,7 @@ static int inter_storage_fromsql(int account_id, struct storage_data *p) SQL->FreeResult(inter->sql_handle); - ShowInfo("storage load complete from DB - id: %d (total: %d)\n", account_id, VECTOR_LENGTH(p->item)); + ShowInfo("Storage #%d load complete from DB - id: %d (total: %d)\n", storage_id, account_id, VECTOR_LENGTH(p->item)); return VECTOR_LENGTH(p->item); } diff --git a/src/char/int_storage.h b/src/char/int_storage.h index 918927620..912236856 100644 --- a/src/char/int_storage.h +++ b/src/char/int_storage.h @@ -31,8 +31,8 @@ struct guild_storage; * inter_storage interface **/ struct inter_storage_interface { - int (*tosql) (int account_id, const struct storage_data *p); - int (*fromsql) (int account_id, struct storage_data *p); + int (*tosql) (int account_id, int storage_id, const struct storage_data *p); + int (*fromsql) (int account_id, int storage_id, struct storage_data *p, int storage_size); bool (*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 264327289..963afd563 100644 --- a/src/char/inter.c +++ b/src/char/inter.c @@ -68,7 +68,7 @@ int party_share_level = 10; // recv. packet list static int inter_recv_packet_length[] = { 0, 0, 0, 0, -1,13,36, (2 + 4 + 4 + 4 + NAME_LENGTH), 0, 0, 0, 0, 0, 0, 0, 0, // 3000- - 6,-1, 6,-1, 0, 0, 0, 0, 10,-1, 0, 0, 0, 0, 0, 0, // 3010- Account Storage, Achievements [Smokexyz] + 10,-1, 6,-1, 0, 0, 0, 0, 10,-1, 0, 0, 0, 0, 0, 0, // 3010- Account Storage, Achievements [Smokexyz] -1,10,-1,14, 14,19, 6, 0, 14,14, 0, 0, 0, 0, 0, 0, // 3020- Party -1, 6,-1,-1, 55,23, 6, 0, 14,-1,-1,-1, 18,19,186,-1, // 3030- -1, 9, 0, 0, 10,10, 0, 0, 7, 6,10,10, 10,-1, 0, 0, // 3040- Clan System(3044-3045) diff --git a/src/char/mapif.c b/src/char/mapif.c index 5b265d3b4..8132c8575 100644 --- a/src/char/mapif.c +++ b/src/char/mapif.c @@ -1816,12 +1816,15 @@ static int mapif_save_guild_storage_ack(int fd, int account_id, int guild_id, in /** * Loads the account storage and send to the map server. - * @packet 0x3805 [out] .L .P - * @param fd [in] file/socket descriptor. - * @param account_id [in] account id of the session. + * + * @packet 0x3805 [out] .W .L .W .P + * @param fd [in] file/socket descriptor. + * @param account_id [in] account id of the session. + * @param storage_id [in] storage id to load + * @param storage_size [in] size of storage * @return 1 on success, 0 on failure. */ -static int mapif_account_storage_load(int fd, int account_id) +static int mapif_account_storage_load(int fd, int account_id, int storage_id, int storage_size) { struct storage_data stor = { 0 }; int count = 0, i = 0, len = 0; @@ -1829,16 +1832,17 @@ static int mapif_account_storage_load(int fd, int account_id) Assert_ret(account_id > 0); VECTOR_INIT(stor.item); - count = inter_storage->fromsql(account_id, &stor); + count = inter_storage->fromsql(account_id, storage_id, &stor, storage_size); - len = 8 + count * sizeof(struct item); + len = 10 + count * sizeof(struct item); WFIFOHEAD(fd, len); WFIFOW(fd, 0) = 0x3805; WFIFOW(fd, 2) = (uint16) len; WFIFOL(fd, 4) = account_id; + WFIFOW(fd, 8) = storage_id; for (i = 0; i < count; i++) - memcpy(WFIFOP(fd, 8 + i * sizeof(struct item)), &VECTOR_INDEX(stor.item, i), sizeof(struct item)); + memcpy(WFIFOP(fd, 10 + i * sizeof(struct item)), &VECTOR_INDEX(stor.item, i), sizeof(struct item)); WFIFOSET(fd, len); VECTOR_CLEAR(stor.item); @@ -1848,31 +1852,38 @@ static int mapif_account_storage_load(int fd, int account_id) /** * Parses account storage load request from map server. - * @packet 0x3010 [in] .L + * @packet 0x3010 [in] .L .W .W * @param fd [in] file/socket descriptor * @return 1 on success, 0 on failure. */ static int mapif_parse_AccountStorageLoad(int fd) { int account_id = RFIFOL(fd, 2); + int storage_id = RFIFOW(fd, 6); + int storage_size = RFIFOW(fd, 8); Assert_ret(fd > 0); Assert_ret(account_id > 0); + Assert_ret(storage_id >= 0); + Assert_ret(storage_size > 0); - mapif->account_storage_load(fd, account_id); + mapif->account_storage_load(fd, account_id, storage_id, storage_size); return 1; } /** * Parses an account storage save request from the map server. - * @packet 0x3011 [in] .W .L .P + * @packet 0x3011 [in] .W .L .L .P * @param fd [in] file/socket descriptor. * @return 1 on success, 0 on failure. */ static int mapif_parse_AccountStorageSave(int fd) { - int payload_size = RFIFOW(fd, 2) - 8, account_id = RFIFOL(fd, 4); + int payload_size = RFIFOW(fd, 2) - 10; + int account_id = RFIFOL(fd, 4); + int storage_id = RFIFOW(fd, 8); + int i = 0, count = 0; struct storage_data p_stor = { 0 }; @@ -1887,7 +1898,7 @@ static int mapif_parse_AccountStorageSave(int fd) VECTOR_ENSURE(p_stor.item, count, 1); for (i = 0; i < count; i++) { - const struct item *it = RFIFOP(fd, 8 + i * sizeof(struct item)); + const struct item *it = RFIFOP(fd, 10 + i * sizeof(struct item)); VECTOR_PUSH(p_stor.item, *it); } @@ -1895,11 +1906,11 @@ static int mapif_parse_AccountStorageSave(int fd) p_stor.aggregate = count; } - inter_storage->tosql(account_id, &p_stor); + inter_storage->tosql(account_id, storage_id, &p_stor); VECTOR_CLEAR(p_stor.item); - mapif->sAccountStorageSaveAck(fd, account_id, true); + mapif->sAccountStorageSaveAck(fd, account_id, storage_id, true); return 1; } @@ -1907,18 +1918,21 @@ static int mapif_parse_AccountStorageSave(int fd) /** * Sends an acknowledgement for the save * status of the account storage. - * @packet 0x3808 [out] .L .B + * + * @packet 0x3808 [out] .L .W .B * @param fd [in] File/Socket Descriptor. * @param account_id [in] Account ID of the storage in question. + * @param storage_id [in] acknowledgement of storage id. * @param flag [in] Save flag, true for success and false for failure. */ -static void mapif_send_AccountStorageSaveAck(int fd, int account_id, bool flag) +static void mapif_send_AccountStorageSaveAck(int fd, int account_id, int storage_id, bool flag) { - WFIFOHEAD(fd, 7); + WFIFOHEAD(fd, 9); WFIFOW(fd, 0) = 0x3808; WFIFOL(fd, 2) = account_id; - WFIFOB(fd, 6) = flag ? 1 : 0; - WFIFOSET(fd, 7); + WFIFOW(fd, 6) = storage_id; + WFIFOB(fd, 8) = flag ? 1 : 0; + WFIFOSET(fd, 9); } static int mapif_parse_LoadGuildStorage(int fd) diff --git a/src/char/mapif.h b/src/char/mapif.h index f5b54b6b7..8990ec40b 100644 --- a/src/char/mapif.h +++ b/src/char/mapif.h @@ -170,10 +170,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 (*account_storage_load) (int fd, int account_id, int storage_id, int storage_size); int (*pAccountStorageLoad) (int fd); int (*pAccountStorageSave) (int fd); - void (*sAccountStorageSaveAck) (int fd, int account_id, bool save); + void (*sAccountStorageSaveAck) (int fd, int account_id, int storage_id, bool save); int (*itembound_ack) (int fd, int aid, int guild_id); void (*parse_ItemBoundRetrieve) (int fd); void (*parse_accinfo) (int fd); diff --git a/src/common/HPMDataCheck.h b/src/common/HPMDataCheck.h index 3ef917a88..ccde005cd 100644 --- a/src/common/HPMDataCheck.h +++ b/src/common/HPMDataCheck.h @@ -243,6 +243,7 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = { { "script_reg_str", sizeof(struct script_reg_str), SERVER_TYPE_ALL }, { "status_change_data", sizeof(struct status_change_data), SERVER_TYPE_ALL }, { "storage_data", sizeof(struct storage_data), SERVER_TYPE_ALL }, + { "storage_settings", sizeof(struct storage_settings), SERVER_TYPE_ALL }, #else #define COMMON_MMO_H #endif // COMMON_MMO_H diff --git a/src/common/mmo.h b/src/common/mmo.h index a2e91626e..c8a59279c 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -585,7 +585,15 @@ struct status_change_data { int total_tick; ///< Total duration. }; +/* Hercules Ultimate Storage System [Smokexyz/Hercules] */ +struct storage_settings { + int uid; ///< Storage Identifier. + char name[NAME_LENGTH]; ///< Storage Name + int capacity; ///< Item Capacity. +}; + struct storage_data { + int uid; ///< Storage Identifier. bool save; ///< save flag. bool received; ///< received flag. int aggregate; ///< total item count. diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 6dae53720..540cea620 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -870,6 +870,41 @@ ACMD(speed) *------------------------------------------*/ ACMD(storage) { + char storage_name[NAME_LENGTH] = ""; + int storage_id = 0, intval = 0; + + if (*message != '\0' && sscanf(message, "%12d", &intval) == 1) { + if (storage->get_settings(intval) == NULL) { + safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd, 67), storage_name); + clif->message(fd, atcmd_output); // Invalid storage name or ID. + return false; + } + storage_id = intval; + } else if (*message != '\0' && sscanf(message, "%23s", storage_name) == 1) { + if ((storage_id = storage->get_id_by_name(storage_name)) == -1) { + safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd, 67), storage_name); + clif->message(fd, atcmd_output); // Invalid storage name or ID. + return false; + } + } else { + clif->message(fd, msg_fd(fd, 68)); // Please specify a storage name (usage: @storage ). + return false; + } + + sd->storage.access = STORAGE_ACCESS_ALL; // Default storage access for atcommands. + + struct storage_data *stor = NULL; + if ((stor = storage->ensure(sd, storage_id)) == NULL) { + ShowError("atcommand_storage: Error ensuring storage for player %d, storage_id %d\n", sd->bl.id, storage_id); + return false; + } + + if (!stor->received) { + safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd, 27), storage_name); + clif->message(fd, atcmd_output); // -- Storage '%s' has not been loaded yet. + return false; + } + if (sd->npc_id || sd->state.vending || sd->state.prevend || sd->state.buyingstore || sd->state.trading || sd->state.storage_flag) return false; @@ -878,12 +913,14 @@ ACMD(storage) return false; } - if (storage->open(sd) == 1) { //Already open. - clif->message(fd, msg_fd(fd,250)); // You have already opened your storage. Close it first. + if (storage->open(sd, stor) == 1) { // Already open. + clif->message(fd, msg_fd(fd, 250)); // You have already opened your storage. Close it first. return false; } - clif->message(fd, msg_fd(fd,919)); // Storage opened. + safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd, 919), storage_id); + + clif->message(fd, atcmd_output); // Storage #%d opened. return true; } @@ -5422,16 +5459,46 @@ ACMD(dropall) *------------------------------------------*/ ACMD(storeall) { + char storage_name[NAME_LENGTH] = ""; + int storage_id = 0, intval = 0; + + if (*message != '\0' && sscanf(message, "%12d", &intval) == 1) { + if (storage->get_settings(intval) == NULL) { + safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd, 67), storage_name); + clif->message(fd, atcmd_output); // Invalid storage name or ID. + return false; + } + storage_id = intval; + } else if (*message != '\0' && sscanf(message, "%23s", storage_name) == 1) { + if ((storage_id = storage->get_id_by_name(storage_name)) == -1) { + safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd, 67), storage_name); + clif->message(fd, atcmd_output); // Invalid storage name or ID. + return false; + } + } else { + clif->message(fd, msg_fd(fd, 65)); // Please specify a storage name (usage: @storeall ). + return false; + } + + sd->storage.access = STORAGE_ACCESS_ALL; // Default storage access for atcommands. + + struct storage_data *stor = NULL; + if ((stor = storage->ensure(sd, storage_id)) == NULL) { + ShowError("atcommand_storeall: Error ensuring storage for player %d, storage_id %d\n", sd->bl.id, storage_id); + return false; + } + if (sd->state.storage_flag != STORAGE_FLAG_NORMAL) { //Open storage. - if (storage->open(sd) == 1) { - clif->message(fd, msg_fd(fd,1161)); // You currently cannot open your storage. + if (storage->open(sd, stor) == 1) { + clif->message(fd, msg_fd(fd, 1161)); // You currently cannot open your storage. return false; } } - if (sd->storage.received == false) { - clif->message(fd, msg_fd(fd, 27)); // "Storage has not been loaded yet" + if (!stor->received) { + safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd, 27), storage_name); + clif->message(fd, atcmd_output); // -- Storage '%s' has not been loaded yet. return false; } @@ -5439,39 +5506,70 @@ ACMD(storeall) if (sd->status.inventory[i].amount) { if(sd->status.inventory[i].equip != 0) pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); - storage->add(sd, i, sd->status.inventory[i].amount); + storage->add(sd, stor, i, sd->status.inventory[i].amount); } } + storage->close(sd); clif->message(fd, msg_fd(fd,1162)); // All items stored. + return true; } ACMD(clearstorage) { - int i; + int i = 0; + char storage_name[NAME_LENGTH] = ""; + int storage_id = 0, intval = 0; + + if (*message != '\0' && sscanf(message, "%12d", &intval) == 1) { + if (storage->get_settings(intval) == NULL) { + safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd, 67), storage_name); + clif->message(fd, atcmd_output); // Invalid storage name or ID. + return false; + } + storage_id = intval; + } else if (*message != '\0' && sscanf(message, "%23s", storage_name) == 1) { + if ((storage_id = storage->get_id_by_name(storage_name)) == -1) { + safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd, 67), storage_name); + clif->message(fd, atcmd_output); // Invalid storage name or ID. + return false; + } + } else { + clif->message(fd, msg_fd(fd, 66)); // Please specify a storage name (usage: @clearstorage ). + return false; + } if (sd->state.storage_flag == STORAGE_FLAG_NORMAL) { - clif->message(fd, msg_fd(fd,250)); + clif->message(fd, msg_fd(fd, 250)); // You have already opened your storage. Close it first. + return false; + } + + sd->storage.access = STORAGE_ACCESS_ALL; // Default storage access for atcommands. + + struct storage_data *stor = NULL; + if ((stor = storage->ensure(sd, storage_id)) == NULL) { + ShowError("atcommand_clearstorage: Error ensuring storage for player %d, storage_id %d\n", sd->bl.id, storage_id); return false; } - if (sd->storage.received == false) { + if (!stor->received) { clif->message(fd, msg_fd(fd, 27)); // "Storage has not been loaded yet" return false; } - for (i = 0; i < VECTOR_LENGTH(sd->storage.item); ++i) { - if (VECTOR_INDEX(sd->storage.item, i).nameid == 0) + for (i = 0; i < VECTOR_LENGTH(stor->item); ++i) { + if (VECTOR_INDEX(stor->item, i).nameid == 0) continue; // we skip the already deleted items. - storage->delitem(sd, i, VECTOR_INDEX(sd->storage.item, i).amount); + storage->delitem(sd, stor, i, VECTOR_INDEX(stor->item, i).amount); } storage->close(sd); clif->message(fd, msg_fd(fd,1394)); // Your storage was cleaned. + return true; } @@ -8391,8 +8489,9 @@ ACMD(itemlist) if( strcmpi(info->command, "storagelist") == 0 ) { location = "storage"; - items = VECTOR_DATA(sd->storage.item); - size = VECTOR_LENGTH(sd->storage.item); + struct storage_data *stor = storage->ensure(sd, 1); + items = VECTOR_DATA(stor->item); + size = VECTOR_LENGTH(stor->item); } else if( strcmpi(info->command, "cartlist") == 0 ) { location = "cart"; items = sd->status.cart; diff --git a/src/map/chrif.c b/src/map/chrif.c index ddc106d0c..0622621bb 100644 --- a/src/map/chrif.c +++ b/src/map/chrif.c @@ -310,8 +310,12 @@ static bool chrif_save(struct map_session_data *sd, int flag) if (sd->state.storage_flag == STORAGE_FLAG_GUILD) gstorage->save(sd->status.account_id, sd->status.guild_id, flag); - if (flag) - sd->state.storage_flag = STORAGE_FLAG_CLOSED; //Force close it. + if (flag != 0 && sd->state.storage_flag != STORAGE_FLAG_CLOSED) { + if (sd->state.storage_flag == STORAGE_FLAG_NORMAL) + storage->close(sd); + else if (sd->state.storage_flag == STORAGE_FLAG_GUILD) + gstorage->close(sd); + } //Saving of registry values. if (sd->vars_dirty) @@ -339,8 +343,9 @@ static bool chrif_save(struct map_session_data *sd, int flag) if (VECTOR_LENGTH(sd->achievement) > 0) intif->achievements_save(sd); - if (sd->storage.received == true && sd->storage.save == true) - intif->send_account_storage(sd); + for (int i = 0; i < VECTOR_LENGTH(sd->storage.list); i++) + if (VECTOR_INDEX(sd->storage.list, i).received && VECTOR_INDEX(sd->storage.list, i).save) + intif->send_account_storage(sd, VECTOR_INDEX(sd->storage.list, i).uid); return true; } diff --git a/src/map/clif.c b/src/map/clif.c index 721f5fc37..6bffa5aa4 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -2922,17 +2922,21 @@ static void clif_equipItems(struct map_session_data *sd, enum inventory_type typ static void clif_storageList(struct map_session_data *sd, struct item *items, int items_length) { nullpo_retv(sd); - - clif->inventoryStart(sd, INVTYPE_STORAGE, "Storage"); - if (sd->storage.aggregate > 0) - clif->storageItems(sd, INVTYPE_STORAGE, items, items_length); + const struct storage_settings *stst = storage->get_settings(sd->storage.current); + nullpo_retv(stst); + struct storage_data *stor = storage->ensure(sd, sd->storage.current); + nullpo_retv(stor); + + clif->inventoryStart(sd, INVTYPE_STORAGE, stst->name); + if (stor->aggregate > 0) + clif->storageItems(sd, INVTYPE_STORAGE, items, items_length, stst->name); clif->inventoryEnd(sd, INVTYPE_STORAGE); } static void clif_guildStorageList(struct map_session_data *sd, struct item *items, int items_length) { clif->inventoryStart(sd, INVTYPE_GUILD_STORAGE, "Guild storage"); - clif->storageItems(sd, INVTYPE_GUILD_STORAGE, items, items_length); + clif->storageItems(sd, INVTYPE_GUILD_STORAGE, items, items_length, "Storage"); clif->inventoryEnd(sd, INVTYPE_GUILD_STORAGE); } @@ -2979,10 +2983,11 @@ static void clif_inventoryEnd(struct map_session_data *sd, enum inventory_type t #endif } -static void clif_storageItems(struct map_session_data *sd, enum inventory_type type, struct item *items, int items_length) +static void clif_storageItems(struct map_session_data *sd, enum inventory_type type, struct item *items, int items_length, const char *name) { nullpo_retv(sd); nullpo_retv(items); + nullpo_retv(name); int normal_count = 0, equip_count = 0; for (int i = 0; i < items_length; ++i) { @@ -3004,7 +3009,7 @@ static void clif_storageItems(struct map_session_data *sd, enum inventory_type t storelist_normal.invType = type; #endif #if PACKETVER >= 20120925 && PACKETVER_RE_NUM < 20180829 && PACKETVER_ZERO_NUM < 20180919 && PACKETVER_MAIN_NUM < 20181002 - safestrncpy(storelist_normal.name, "Storage", NAME_LENGTH); + safestrncpy(storelist_normal.name, name, NAME_LENGTH); #endif clif->send(&storelist_normal, storelist_normal.PacketLength, &sd->bl, SELF); @@ -3019,7 +3024,7 @@ static void clif_storageItems(struct map_session_data *sd, enum inventory_type t storelist_equip.invType = type; #endif #if PACKETVER >= 20120925 && PACKETVER_RE_NUM < 20180829 && PACKETVER_ZERO_NUM < 20180919 && PACKETVER_MAIN_NUM < 20181002 - safestrncpy(storelist_equip.name, "Storage", NAME_LENGTH); + safestrncpy(storelist_equip.name, name, NAME_LENGTH); #endif clif->send(&storelist_equip, storelist_equip.PacketLength, &sd->bl, SELF); @@ -3035,7 +3040,7 @@ static void clif_storageItems(struct map_session_data *sd, enum inventory_type t storelist_normal.invType = type; #endif #if PACKETVER >= 20120925 && PACKETVER_RE_NUM < 20180829 && PACKETVER_ZERO_NUM < 20180919 && PACKETVER_MAIN_NUM < 20181002 - safestrncpy(storelist_normal.name, "Storage", NAME_LENGTH); + safestrncpy(storelist_normal.name, name, NAME_LENGTH); #endif clif->send(&storelist_normal, storelist_normal.PacketLength, &sd->bl, SELF); @@ -3050,7 +3055,7 @@ static void clif_storageItems(struct map_session_data *sd, enum inventory_type t storelist_equip.invType = type; #endif #if PACKETVER >= 20120925 && PACKETVER_RE_NUM < 20180829 && PACKETVER_ZERO_NUM < 20180919 && PACKETVER_MAIN_NUM < 20181002 - safestrncpy(storelist_equip.name, "Storage", NAME_LENGTH); + safestrncpy(storelist_equip.name, name, NAME_LENGTH); #endif clif->send(&storelist_equip, storelist_equip.PacketLength, &sd->bl, SELF); @@ -9244,14 +9249,24 @@ static void clif_serviceMessageColor(struct map_session_data *sd, uint32 color, static void clif_refresh_storagewindow(struct map_session_data *sd) { nullpo_retv(sd); + // Notify the client that the storage is open if (sd->state.storage_flag == STORAGE_FLAG_NORMAL) { - if (sd->storage.aggregate > 0) { - storage->sortitem(VECTOR_DATA(sd->storage.item), VECTOR_LENGTH(sd->storage.item)); - } - clif->storageList(sd, VECTOR_DATA(sd->storage.item), VECTOR_LENGTH(sd->storage.item)); - clif->updatestorageamount(sd, sd->storage.aggregate, MAX_STORAGE); + const struct storage_settings* stst = storage->get_settings(sd->storage.current); + nullpo_retv(stst); + + struct storage_data* stor = NULL; + if ((stor = storage->ensure(sd, sd->storage.current)) == NULL) + return; + + if (stor->aggregate > 0) + storage->sortitem(VECTOR_DATA(stor->item), VECTOR_LENGTH(stor->item)); + + clif->storageList(sd, VECTOR_DATA(stor->item), VECTOR_LENGTH(stor->item)); + + clif->updatestorageamount(sd, stor->aggregate, MAX_STORAGE); } + // Notify the client that the gstorage is open otherwise it will // remain locked forever and nobody will be able to access it if (sd->state.storage_flag == STORAGE_FLAG_GUILD) { @@ -9327,7 +9342,12 @@ static void clif_refresh(struct map_session_data *sd) pc->disguise(sd, disguise); } - clif->refresh_storagewindow(sd); + // Close storage when refreshing the client + // to avoid an unnecessary complication of things. + if (sd->state.storage_flag == STORAGE_FLAG_NORMAL) + storage->close(sd); + else if (sd->state.storage_flag == STORAGE_FLAG_GUILD) + gstorage->close(sd); } static void clif_send_selforarea(int fd, struct block_list *bl, const void *buf, int len) @@ -13341,10 +13361,13 @@ static void clif_parse_MoveToKafra(int fd, struct map_session_data *sd) if (item_index < 0 || item_index >= sd->status.inventorySize || item_amount < 1) return; - if (sd->state.storage_flag == STORAGE_FLAG_NORMAL) - storage->add(sd, item_index, item_amount); - else if (sd->state.storage_flag == STORAGE_FLAG_GUILD) + if (sd->state.storage_flag == STORAGE_FLAG_NORMAL) { + struct storage_data *stor = storage->ensure(sd, sd->storage.current); + if (stor != NULL) + storage->add(sd, stor, item_index, item_amount); + } else if (sd->state.storage_flag == STORAGE_FLAG_GUILD) { gstorage->add(sd, item_index, item_amount); + } } static void clif_parse_MoveFromKafra(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); @@ -13359,13 +13382,17 @@ static void clif_parse_MoveFromKafra(int fd, struct map_session_data *sd) int item_index, item_amount; + item_index = RFIFOW(fd,packet_db[RFIFOW(fd,0)].pos[0])-1; item_amount = RFIFOL(fd,packet_db[RFIFOW(fd,0)].pos[1]); - if (sd->state.storage_flag == STORAGE_FLAG_NORMAL) - storage->get(sd, item_index, item_amount); - else if(sd->state.storage_flag == STORAGE_FLAG_GUILD) + if (sd->state.storage_flag == STORAGE_FLAG_NORMAL) { + struct storage_data *stor = storage->ensure(sd, sd->storage.current); + if (stor != NULL) + storage->get(sd, stor, item_index, item_amount); + } else if (sd->state.storage_flag == STORAGE_FLAG_GUILD) { gstorage->get(sd, item_index, item_amount); + } } static void clif_parse_MoveToKafraFromCart(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); @@ -13378,10 +13405,13 @@ static void clif_parse_MoveToKafraFromCart(int fd, struct map_session_data *sd) if (!pc_iscarton(sd)) return; - if (sd->state.storage_flag == STORAGE_FLAG_NORMAL) - storage->addfromcart(sd, RFIFOW(fd,2) - 2, RFIFOL(fd,4)); - else if (sd->state.storage_flag == STORAGE_FLAG_GUILD) + if (sd->state.storage_flag == STORAGE_FLAG_NORMAL) { + struct storage_data *stor = storage->ensure(sd, sd->storage.current); + if (stor != NULL) + storage->addfromcart(sd, stor, RFIFOW(fd, 2) - 2, RFIFOL(fd, 4)); + } else if (sd->state.storage_flag == STORAGE_FLAG_GUILD) { gstorage->addfromcart(sd, RFIFOW(fd,2) - 2, RFIFOL(fd,4)); + } } static void clif_parse_MoveFromKafraToCart(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); @@ -13394,10 +13424,13 @@ static void clif_parse_MoveFromKafraToCart(int fd, struct map_session_data *sd) if (!pc_iscarton(sd)) return; - if (sd->state.storage_flag == STORAGE_FLAG_NORMAL) - storage->gettocart(sd, RFIFOW(fd,2)-1, RFIFOL(fd,4)); - else if (sd->state.storage_flag == STORAGE_FLAG_GUILD) + if (sd->state.storage_flag == STORAGE_FLAG_NORMAL) { + struct storage_data *stor = storage->ensure(sd, sd->storage.current); + if (stor != NULL) + storage->gettocart(sd, stor, RFIFOW(fd,2) - 1, RFIFOL(fd, 4)); + } else if (sd->state.storage_flag == STORAGE_FLAG_GUILD) { gstorage->gettocart(sd, RFIFOW(fd,2)-1, RFIFOL(fd,4)); + } } static void clif_parse_CloseKafra(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); diff --git a/src/map/clif.h b/src/map/clif.h index 0dfc00c01..194194752 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -1091,7 +1091,7 @@ struct clif_interface { /* storage handling */ void (*storageList) (struct map_session_data* sd, struct item* items, int items_length); void (*guildStorageList) (struct map_session_data* sd, struct item* items, int items_length); - void (*storageItems) (struct map_session_data* sd, enum inventory_type type, struct item* items, int items_length); + void (*storageItems) (struct map_session_data *sd, enum inventory_type type, struct item *items, int items_length, const char *name); void (*inventoryStart) (struct map_session_data* sd, enum inventory_type type, const char* name); void (*inventoryEnd) (struct map_session_data* sd, enum inventory_type type); void (*updatestorageamount) (struct map_session_data* sd, int amount, int max_amount); diff --git a/src/map/intif.c b/src/map/intif.c index 5a62f9644..f211b9705 100644 --- a/src/map/intif.c +++ b/src/map/intif.c @@ -297,26 +297,33 @@ static int intif_request_registry(struct map_session_data *sd, int flag) /** * Request the inter-server for a character's storage data. - * @packet 0x3010 [out] .L - * @param sd [in] pointer to session data. + * + * @packet 0x3010 [out] .L .W .W + * @param sd [in] pointer to session data. + * @param storage_id [in] storage id to retrieve */ -static void intif_request_account_storage(const struct map_session_data *sd) +static void intif_request_account_storage(const struct map_session_data *sd, int storage_id) { nullpo_retv(sd); + const struct storage_settings *stst = storage->get_settings(storage_id); + nullpo_retv(stst); + /* Check for character server availability */ if (intif->CheckForCharServer()) return; - WFIFOHEAD(inter_fd, 6); + WFIFOHEAD(inter_fd, 10); WFIFOW(inter_fd, 0) = 0x3010; WFIFOL(inter_fd, 2) = sd->status.account_id; - WFIFOSET(inter_fd, 6); + WFIFOW(inter_fd, 6) = storage_id; + WFIFOW(inter_fd, 8) = stst->capacity; + WFIFOSET(inter_fd, 10); } /** * Parse the reception of account storage from the inter-server. - * @packet 0x3805 [in] .W .L .P + * @packet 0x3805 [in] .W .L .W .P * @param fd [in] file/socket descriptor. */ static void intif_parse_account_storage(int fd) @@ -327,94 +334,113 @@ static void intif_parse_account_storage(int fd) Assert_retv(fd > 0); - payload_size = RFIFOW(fd, 2) - 8; + payload_size = RFIFOW(fd, 2) - 10; if ((account_id = RFIFOL(fd, 4)) == 0 || (sd = map->id2sd(account_id)) == NULL) { ShowError("intif_parse_account_storage: Session pointer was null for account id %d!\n", account_id); return; } - if (sd->storage.received == true) { + struct storage_data *stor = NULL; + if ((stor = storage->ensure(sd, RFIFOW(fd, 8))) == NULL) + return; + + if (stor->received) { ShowError("intif_parse_account_storage: Multiple calls from the inter-server received.\n"); return; } storage_count = (payload_size/sizeof(struct item)); - VECTOR_ENSURE(sd->storage.item, storage_count, 1); + VECTOR_ENSURE(stor->item, storage_count, 1); - sd->storage.aggregate = storage_count; // Total items in storage. + stor->aggregate = storage_count; // Total items in storage. for (i = 0; i < storage_count; i++) { - const struct item *it = RFIFOP(fd, 8 + i * sizeof(struct item)); - VECTOR_PUSH(sd->storage.item, *it); + const struct item *it = RFIFOP(fd, 10 + i * sizeof(struct item)); + VECTOR_PUSH(stor->item, *it); } - sd->storage.received = true; // Mark the storage state as received. - sd->storage.save = false; // Initialize the save flag as false. + stor->received = true; // Mark the storage state as received. + stor->save = false; // Initialize the save flag as false. pc->checkitem(sd); // re-check remaining items. } /** * Send account storage information for saving. - * @packet 0x3011 [out] .W .L .P - * @param sd [in] pointer to session data. + * + * @packet 0x3011 [out] .W .L .W .P + * @param sd [in] pointer to session data. + * @param storage_id [in] storage id to be saved. */ -static void intif_send_account_storage(struct map_session_data *sd) +static void intif_send_account_storage(struct map_session_data *sd, int storage_id) { int len = 0, i = 0, c = 0; nullpo_retv(sd); + struct storage_data *stor = NULL; + if ((stor = storage->ensure(sd, storage_id)) == NULL) + return; + // Assert that at this point in the code, both flags are true. - Assert_retv(sd->storage.save == true); - Assert_retv(sd->storage.received == true); + Assert_retv(stor->save); + Assert_retv(stor->received); if (intif->CheckForCharServer()) return; - len = 8 + sd->storage.aggregate * sizeof(struct item); + len = 10 + stor->aggregate * sizeof(struct item); WFIFOHEAD(inter_fd, len); WFIFOW(inter_fd, 0) = 0x3011; WFIFOW(inter_fd, 2) = (uint16) len; WFIFOL(inter_fd, 4) = sd->status.account_id; - for (i = 0, c = 0; i < VECTOR_LENGTH(sd->storage.item); i++) { - if (VECTOR_INDEX(sd->storage.item, i).nameid == 0) + WFIFOW(inter_fd, 8) = storage_id; + + for (i = 0, c = 0; i < VECTOR_LENGTH(stor->item); i++) { + if (VECTOR_INDEX(stor->item, i).nameid == 0) continue; - memcpy(WFIFOP(inter_fd, 8 + c * sizeof(struct item)), &VECTOR_INDEX(sd->storage.item, i), sizeof(struct item)); + memcpy(WFIFOP(inter_fd, 10 + c * sizeof(struct item)), &VECTOR_INDEX(stor->item, i), sizeof(struct item)); c++; } WFIFOSET(inter_fd, len); - sd->storage.save = false; // Save request has been sent + stor->save = false; // Save request has been sent } /** * Parse acknowledgement packet for the saving of an account's storage. - * @packet 0x3808 [in] .L .B + * @packet 0x3808 [in] .L .W .B * @param fd [in] file/socket descriptor. */ static void intif_parse_account_storage_save_ack(int fd) { int account_id = RFIFOL(fd, 2); - uint8 saved = RFIFOB(fd, 6); - struct map_session_data *sd = NULL; + int storage_id = RFIFOW(fd, 6); + char saved = RFIFOB(fd, 8); Assert_retv(account_id > 0); Assert_retv(fd > 0); - + Assert_retv(storage_id >= 0); + + struct map_session_data *sd = NULL; if ((sd = map->id2sd(account_id)) == NULL) return; // character is most probably offline. if (saved == 0) { - ShowError("intif_parse_account_storage_save_ack: Storage has not been saved! (AID: %d)\n", account_id); - sd->storage.save = true; // Flag it as unsaved, to re-attempt later + ShowError("intif_parse_account_storage_save_ack: Storage id %d has not been saved! (AID: %d)\n", storage_id, account_id); return; } + + struct storage_data *stor = NULL; + if ((stor = storage->ensure(sd, storage_id)) == NULL) + return; + + stor->save = false; // Storage has been saved. } //================================================================= @@ -2718,7 +2744,7 @@ static int intif_parse(int fd) void intif_defaults(void) { const int packet_len_table [INTIF_PACKET_LEN_TABLE_SIZE] = { - 0, 0, 0, 0, -1,-1,37,-1, 7, 0, 0, 0, 0, 0, 0, 0, //0x3800-0x380f + 0, 0, 0, 0, -1,-1,37,-1, 9, 0, 0, 0, 0, 0, 0, 0, //0x3800-0x380f -1, 0, 0, 0, 0, 0, 0, 0, -1,11, 0, 0, 0, 0, 0, 0, //0x3810 Achievements [Smokexyz/Hercules] 39,-1,15,15, 14,19, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3820 10,-1,15, 0, 79,25, 7, 0, 0,-1,-1,-1, 14,67,186,-1, //0x3830 diff --git a/src/map/intif.h b/src/map/intif.h index ffac4a1c9..082f87a8b 100644 --- a/src/map/intif.h +++ b/src/map/intif.h @@ -62,8 +62,8 @@ struct intif_interface { int pet_equip, short intimate, short hungry, char rename_flag, char incubate, char *pet_name); int (*saveregistry) (struct map_session_data *sd); int (*request_registry) (struct map_session_data *sd, int flag); - void (*request_account_storage) (const struct map_session_data *sd); - void (*send_account_storage) (struct map_session_data *sd); + void (*request_account_storage) (const struct map_session_data *sd, int storage_id); + void (*send_account_storage) (struct map_session_data *sd, int storage_id); int (*request_guild_storage) (int account_id, int guild_id); int (*send_guild_storage) (int account_id, struct guild_storage *gstor); int (*create_party) (struct party_member *member, const char *name, int item, int item2); diff --git a/src/map/map.c b/src/map/map.c index 2161f7023..fefcc78c2 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -6193,6 +6193,7 @@ int do_final(void) script->final(); itemdb->final(); instance->final(); + storage->final(); gstorage->final(); guild->final(); party->final(); @@ -6255,6 +6256,7 @@ int do_final(void) aFree(map->GRF_PATH_FILENAME); aFree(map->INTER_CONF_NAME); aFree(map->LOG_CONF_NAME); + aFree(map->STORAGE_CONF_FILENAME); HPM->event(HPET_POST_FINAL); @@ -6509,6 +6511,19 @@ static CMDLINEARG(grfpath) map->GRF_PATH_FILENAME = aStrdup(params); return true; } +/** + * --storage-path handler + * + * Overrides the default grf configuration filename. + * @see cmdline->exec + */ +static CMDLINEARG(storagepath) +{ + aFree(map->STORAGE_CONF_FILENAME); + map->STORAGE_CONF_FILENAME = aStrdup(params); + return true; +} + /** * --inter-config handler * @@ -6571,6 +6586,7 @@ void cmdline_args_init_local(void) CMDLINEARG_DEF2(script-config, scriptconfig, "Alternative script configuration.", CMDLINE_OPT_NORMAL|CMDLINE_OPT_PARAM); CMDLINEARG_DEF2(msg-config, msgconfig, "Alternative message configuration.", CMDLINE_OPT_NORMAL|CMDLINE_OPT_PARAM); CMDLINEARG_DEF2(grf-path, grfpath, "Alternative GRF path configuration.", CMDLINE_OPT_NORMAL|CMDLINE_OPT_PARAM); + CMDLINEARG_DEF2(storage-path, storagepath, "Alternative Storage configuration path.", CMDLINE_OPT_NORMAL|CMDLINE_OPT_PARAM); CMDLINEARG_DEF2(inter-config, interconfig, "Alternative inter-server configuration.", CMDLINE_OPT_NORMAL|CMDLINE_OPT_PARAM); CMDLINEARG_DEF2(log-config, logconfig, "Alternative logging configuration.", CMDLINE_OPT_NORMAL|CMDLINE_OPT_PARAM); CMDLINEARG_DEF2(script-check, scriptcheck, "Doesn't run the server, only tests the scripts passed through --load-script.", CMDLINE_OPT_SILENT); @@ -6596,6 +6612,7 @@ int do_init(int argc, char *argv[]) map->SCRIPT_CONF_NAME = aStrdup("conf/map/script.conf"); map->MSG_CONF_NAME = aStrdup("conf/messages.conf"); map->GRF_PATH_FILENAME = aStrdup("conf/grf-files.txt"); + map->STORAGE_CONF_FILENAME = aStrdup("conf/map/storage.conf"); HPM_map_do_init(); cmdline->exec(argc, argv, CMDLINE_OPT_PREINIT); @@ -6661,6 +6678,7 @@ int do_init(int argc, char *argv[]) atcommand->msg_read(map->MSG_CONF_NAME, false); map->inter_config_read(map->INTER_CONF_NAME, false); logs->config_read(map->LOG_CONF_NAME, false); + storage->config_read(map->STORAGE_CONF_FILENAME, false); } script->config_read(map->SCRIPT_CONF_NAME, false); @@ -6733,6 +6751,7 @@ int do_init(int argc, char *argv[]) status->init(minimal); party->init(minimal); guild->init(minimal); + storage->init(minimal); gstorage->init(minimal); pet->init(minimal); homun->init(minimal); @@ -6834,6 +6853,7 @@ void map_defaults(void) map->SCRIPT_CONF_NAME = "conf/map/script.conf"; map->MSG_CONF_NAME = "conf/messages.conf"; map->GRF_PATH_FILENAME = "conf/grf-files.txt"; + map->STORAGE_CONF_FILENAME = "conf/map/storage.conf"; map->default_codepage[0] = '\0'; map->server_port = 3306; diff --git a/src/map/map.h b/src/map/map.h index b9199f3bb..450588fd2 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -1052,6 +1052,7 @@ struct map_interface { char *SCRIPT_CONF_NAME; char *MSG_CONF_NAME; char *GRF_PATH_FILENAME; + char *STORAGE_CONF_FILENAME; char autotrade_merchants_db[32]; char autotrade_data_db[32]; diff --git a/src/map/pc.c b/src/map/pc.c index e9332ee46..e1da6f69d 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -1268,9 +1268,11 @@ static bool pc_authok(struct map_session_data *sd, int login_id2, time_t expirat VECTOR_INIT(sd->channels); VECTOR_INIT(sd->script_queues); VECTOR_INIT(sd->achievement); // Achievements [Smokexyz/Hercules] - VECTOR_INIT(sd->storage.item); // initialize storage item vector. VECTOR_INIT(sd->hatEffectId); + // Storage + VECTOR_INIT(sd->storage.list); + sd->state.dialog = 0; sd->delayed_damage = 0; @@ -1505,7 +1507,8 @@ static int pc_reg_received(struct map_session_data *sd) sd->status.last_login = time(NULL); // Storage Request - intif->request_account_storage(sd); + for (i = 0; i < VECTOR_LENGTH(storage->configuration); i++) + intif->request_account_storage(sd, VECTOR_INDEX(storage->configuration, i).uid); intif->Mail_requestinbox(sd->status.char_id, 0); // MAIL SYSTEM - Request Mail Inbox intif->request_questlog(sd); @@ -10506,21 +10509,26 @@ static int pc_checkitem(struct map_session_data *sd) sd->itemcheck &= ~PCCHECKITEM_CART; } - if (sd->itemcheck & PCCHECKITEM_STORAGE && sd->storage.received == true) { - for (i = 0; i < VECTOR_LENGTH(sd->storage.item); i++) { - struct item *it = &VECTOR_INDEX(sd->storage.item, i); + if ((sd->itemcheck & PCCHECKITEM_STORAGE) != 0) { + for (i = 0; i < VECTOR_LENGTH(sd->storage.list); i++) { + struct storage_data *stor = &VECTOR_INDEX(sd->storage.list, i); - if ((id = it->nameid) == 0) - continue; + for (int j = 0; j < VECTOR_LENGTH(sd->storage.list); j++) { + struct item *it = &VECTOR_INDEX(stor->item, j); - if (!itemdb_available(id)) { - ShowWarning("pc_checkitem: Removed invalid/disabled item id %d from storage (amount=%d, char_id=%d).\n", id, it->amount, sd->status.char_id); - storage->delitem(sd, i, it->amount); - continue; + if ((id = it->nameid) == 0) + continue; + + if (itemdb_available(id) == 0) { + ShowWarning("pc_checkitem: Removed invalid/disabled item id %d from storage %d (amount=%d, char_id=%d).\n", id, stor->uid, it->amount, sd->status.char_id); + storage->delitem(sd, stor, i, it->amount); + continue; + } + + if (it->unique_id == 0 && itemdb->isstackable(id) == 0) + it->unique_id = itemdb->unique_id(sd); } - if (it->unique_id == 0 && itemdb->isstackable(id) == 0) - it->unique_id = itemdb->unique_id(sd); } storage->close(sd); diff --git a/src/map/pc.h b/src/map/pc.h index cc8d83b65..75ea3d359 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -32,6 +32,7 @@ #include "map/script.h" // struct reg_db #include "map/searchstore.h" // struct s_search_store_info #include "map/status.h" // enum sc_type, OPTION_* +#include "map/storage.h" #include "map/unit.h" // struct unit_data, struct view_data #include "map/vending.h" // struct s_vending #include "common/db.h" @@ -263,7 +264,11 @@ struct map_session_data { struct mmo_charstatus status; struct item_data *inventory_data[MAX_INVENTORY]; // direct pointers to itemdb entries (faster than doing item_id lookups) - struct storage_data storage; ///< Account Storage + struct { + int current; ///< Marker for the current storage ID in use. + enum storage_access_modes access; ///< Access level for the user. + VECTOR_DECL(struct storage_data) list; ///< Account Storage + } storage; enum pc_checkitem_types itemcheck; short equip_index[EQI_MAX]; unsigned int weight,max_weight; diff --git a/src/map/script.c b/src/map/script.c index e7c5eba0c..355735740 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -10894,10 +10894,30 @@ static BUILDIN(gettimestr) static BUILDIN(openstorage) { struct map_session_data *sd = script->rid2sd(st); - if (sd == NULL) + int storage_id = script_hasdata(st, 2) ? script_getnum(st, 2) : 1; + if (sd == NULL) { + script_pushint(st, 0); + ShowWarning("buildin_openstorage: Player not attached for Storage with ID %d!\n", storage_id); + return false; + } + + int storage_access = script_hasdata(st, 3) ? script_getnum(st, 3) : STORAGE_ACCESS_ALL; + struct storage_data *stor = NULL; + + if ((stor = storage->ensure(sd, storage_id)) == NULL) { + script_pushint(st, 0); + ShowError("buildin_openstorage: Error ensuring storage for player aid %d, storage id %d.\n", sd->bl.id, storage_id); return false; + } - if (sd->storage.received == false) { + const struct storage_settings *stst = NULL; + if ((stst = storage->get_settings(storage_id)) == NULL) { + script_pushint(st, 0); + ShowWarning("buildin_openstorage: Storage with ID %d was not found!\n", storage_id); + return false; + } + + if (stor == NULL || !stor->received) { script_pushint(st, 0); ShowWarning("buildin_openstorage: Storage data for AID %d has not been loaded.\n", sd->bl.id); return false; @@ -10909,9 +10929,13 @@ static BUILDIN(openstorage) return true; } - storage->open(sd); + sd->storage.access = storage_access; // Set storage access level. [Smokexyz/Hercules] - script_pushint(st, 1); // success flag. + if (storage->open(sd, stor) == 0) { + script_pushint(st, 1); // success + } else { + script_pushint(st, 0); + } return true; } @@ -26292,7 +26316,7 @@ static void script_parse_builtin(void) BUILDIN_DEF(gettimetick,"i"), BUILDIN_DEF(gettime,"i"), BUILDIN_DEF(gettimestr, "si?"), - BUILDIN_DEF(openstorage,""), + BUILDIN_DEF(openstorage,"??"), BUILDIN_DEF(guildopenstorage,""), BUILDIN_DEF(itemskill,"vi?"), BUILDIN_DEF(produce,"i"), @@ -27368,6 +27392,12 @@ static void script_hardcoded_constants(void) script->set_constant("GUILDINFO_MASTER_NAME", GUILDINFO_MASTER_NAME, false, false); script->set_constant("GUILDINFO_MASTER_CID", GUILDINFO_MASTER_CID, false, false); + script->constdb_comment("Storage Access Types"); + script->set_constant("STORAGE_ACCESS_VIEW", STORAGE_ACCESS_VIEW, false, false); + script->set_constant("STORAGE_ACCESS_GET", STORAGE_ACCESS_GET, false, false); + script->set_constant("STORAGE_ACCESS_PUT", STORAGE_ACCESS_PUT, false, false); + script->set_constant("STORAGE_ACCESS_ALL", STORAGE_ACCESS_ALL, false, false); + script->constdb_comment("Renewal"); #ifdef RENEWAL script->set_constant("RENEWAL", 1, false, false); diff --git a/src/map/storage.c b/src/map/storage.c index 90b620f63..5b9478d8a 100644 --- a/src/map/storage.c +++ b/src/map/storage.c @@ -33,9 +33,11 @@ #include "map/map.h" // struct map_session_data #include "map/pc.h" #include "common/cbasetypes.h" -#include "common/db.h" +#include "common/conf.h" #include "common/memmgr.h" +#include "common/mmo.h" #include "common/nullpo.h" +#include "common/showmsg.h" #include #include @@ -95,37 +97,109 @@ static void do_reconnect_storage(void) gstorage->db->foreach(gstorage->db, storage->reconnect_sub); } +/** + * Get a storage id by its name (through @commands etc...) + * + * @param[in] storage_name pointer to the storage name char array. + * @return id of the storage or -1 if not found. + */ +int storage_get_id_by_name(const char *storage_name) +{ + nullpo_chk(storage_name); + int i = 0; + + ARR_FIND(0, VECTOR_LENGTH(storage->configuration), i, strcmp(VECTOR_INDEX(storage->configuration, i).name, storage_name) == 0); + + if (i == VECTOR_LENGTH(storage->configuration)) + return -1; + + return VECTOR_INDEX(storage->configuration, i).uid; +} + +/** + * Get storage with a particular ID from a player. + * + * @param[in] sd pointer to map session data. + * @param[in] storage_id ID of the storage to receive. + * @return pointer to player's storage data structure or null if not found. + */ +struct storage_data *storage_ensure(struct map_session_data *sd, int storage_id) +{ + nullpo_retr(NULL, sd); + + int i = 0; + struct storage_data *stor = NULL; + + ARR_FIND(0, VECTOR_LENGTH(sd->storage.list), i, (stor = &VECTOR_INDEX(sd->storage.list, i)) != NULL && stor->uid == storage_id); + + if (i == VECTOR_LENGTH(sd->storage.list)) { + struct storage_data t_stor = { 0 }; + + t_stor.uid = storage_id; + VECTOR_INIT(t_stor.item); + VECTOR_ENSURE(sd->storage.list, 1, 1); + VECTOR_PUSH(sd->storage.list, t_stor); + stor = &VECTOR_LAST(sd->storage.list); + } + + return stor; +} + +/** + * Get a storage's settings through its ID. + * + * @param[in] storage_id the ID of the storage to find. + * @return storage settings of the storage in question. + */ +const struct storage_settings *storage_get_settings(int storage_id) +{ + int i = 0; + + ARR_FIND(0, VECTOR_LENGTH(storage->configuration), i, VECTOR_INDEX(storage->configuration, i).uid == storage_id); + + struct storage_settings *tmp_stor = NULL; + if (i < VECTOR_LENGTH(storage->configuration)) + tmp_stor = &VECTOR_INDEX(storage->configuration, i); + + return tmp_stor; +} + /*========================================== * Opens a storage. Returns: * 0 - success * 1 - fail *------------------------------------------*/ -static int storage_storageopen(struct map_session_data *sd) +static int storage_storageopen(struct map_session_data *sd, struct storage_data *stor) { - nullpo_ret(sd); + nullpo_retr(1, sd); + nullpo_retr(1, stor); + Assert_retr(1, stor->received); // Assert the availability of data. - if (sd->state.storage_flag != STORAGE_FLAG_CLOSED) - return 1; //Already open? + const struct storage_settings *stst = NULL; - if (sd->storage.received == false) { - clif->message(sd->fd, msg_sd(sd, 27)); // Storage has not been loaded yet. - return 1; - } + nullpo_retr(1, stst = storage->get_settings(stor->uid)); + + if (sd->state.storage_flag != STORAGE_FLAG_CLOSED) + return 1; // Storage is already open. - if( !pc_can_give_items(sd) ) { - //check is this GM level is allowed to put items to storage + // GM Permission check. + if (!pc_can_give_items(sd)) { clif->message(sd->fd, msg_sd(sd,246)); // Your GM level doesn't authorize you to perform this action. return 1; } - sd->state.storage_flag = STORAGE_FLAG_NORMAL; + sd->state.storage_flag = STORAGE_FLAG_NORMAL; // Set the storage use state. + sd->storage.current = stor->uid; // Set current storage ID used. - if (sd->storage.aggregate > 0) { - storage->sortitem(VECTOR_DATA(sd->storage.item), VECTOR_LENGTH(sd->storage.item)); + /* Send item list to client if available. */ + if (stor->aggregate > 0) { + storage->sortitem(VECTOR_DATA(stor->item), VECTOR_LENGTH(stor->item)); } - clif->storageList(sd, VECTOR_DATA(sd->storage.item), VECTOR_LENGTH(sd->storage.item)); + clif->storageList(sd, VECTOR_DATA(stor->item), VECTOR_LENGTH(stor->item)); - clif->updatestorageamount(sd, sd->storage.aggregate, MAX_STORAGE); + /* Send storage total items and max amount update. */ + clif->updatestorageamount(sd, stor->aggregate, stst->capacity); + return 0; } @@ -155,21 +229,19 @@ static int compare_item(struct item *a, struct item *b) /*========================================== * Internal add-item function. *------------------------------------------*/ -static int storage_additem(struct map_session_data *sd, struct item *item_data, int amount) +static int storage_additem(struct map_session_data *sd, struct storage_data *stor, struct item* item_data, int amount) { - struct item_data *data = NULL; - struct item *it = NULL; - int i; - nullpo_retr(1, sd); - Assert_retr(1, sd->storage.received == true); + nullpo_retr(1, stor); // Assert Storage + Assert_retr(1, stor->received); // Assert the availability of the storage. + nullpo_retr(1, item_data); // Assert availability of item data. + Assert_retr(1, item_data->nameid > 0); // Assert existence of item in the database. + Assert_retr(1, amount > 0); // Assert quantity of item. + + const struct storage_settings *stst = NULL; + nullpo_retr(1, (stst = storage->get_settings(stor->uid))); // Assert existence of storage configuration. - nullpo_retr(1, item_data); - Assert_retr(1, item_data->nameid > 0); - - Assert_retr(1, amount > 0); - - data = itemdb->search(item_data->nameid); + struct item_data *data = itemdb->search(item_data->nameid); if (data->stack.storage && amount > data->stack.amount) // item stack limitation return 1; @@ -185,9 +257,11 @@ static int storage_additem(struct map_session_data *sd, struct item *item_data, return 1; } + int i; + struct item *it = NULL; if (itemdb->isstackable2(data)) {//Stackable - for (i = 0; i < VECTOR_LENGTH(sd->storage.item); i++) { - it = &VECTOR_INDEX(sd->storage.item, i); + for (i = 0; i < VECTOR_LENGTH(stor->item); i++) { + it = &VECTOR_INDEX(stor->item, i); if (it->nameid == 0) continue; @@ -199,38 +273,37 @@ static int storage_additem(struct map_session_data *sd, struct item *item_data, it->amount += amount; clif->storageitemadded(sd, it, i, amount); - - sd->storage.save = true; // set a save flag. - + stor->save = true; // set a save flag. + return 0; } } } // Check if storage exceeds limit. - if (sd->storage.aggregate >= MAX_STORAGE) + if (stor->aggregate >= stst->capacity) return 1; - ARR_FIND(0, VECTOR_LENGTH(sd->storage.item), i, VECTOR_INDEX(sd->storage.item, i).nameid == 0); + ARR_FIND(0, VECTOR_LENGTH(stor->item), i, VECTOR_INDEX(stor->item, i).nameid == 0); - if (i == VECTOR_LENGTH(sd->storage.item)) { - VECTOR_ENSURE(sd->storage.item, 1, 1); - VECTOR_PUSH(sd->storage.item, *item_data); - it = &VECTOR_LAST(sd->storage.item); + if (i == VECTOR_LENGTH(stor->item)) { + VECTOR_ENSURE(stor->item, 1, 1); + VECTOR_PUSH(stor->item, *item_data); + it = &VECTOR_LAST(stor->item); } else { - it = &VECTOR_INDEX(sd->storage.item, i); + it = &VECTOR_INDEX(stor->item, i); *it = *item_data; } it->amount = amount; - sd->storage.aggregate++; + stor->aggregate++; clif->storageitemadded(sd, it, i, amount); - clif->updatestorageamount(sd, sd->storage.aggregate, MAX_STORAGE); + clif->updatestorageamount(sd, stor->aggregate, stst->capacity); - sd->storage.save = true; // set a save flag. + stor->save = true; // set a save flag. return 0; } @@ -238,30 +311,31 @@ static int storage_additem(struct map_session_data *sd, struct item *item_data, /*========================================== * Internal del-item function *------------------------------------------*/ -static int storage_delitem(struct map_session_data *sd, int n, int amount) +static int storage_delitem(struct map_session_data *sd, struct storage_data *stor, int n, int amount) { - struct item *it = NULL; nullpo_retr(1, sd); + nullpo_retr(1, stor); + Assert_retr(1, stor->received); - Assert_retr(1, sd->storage.received == true); - - Assert_retr(1, n >= 0 && n < VECTOR_LENGTH(sd->storage.item)); + const struct storage_settings* stst = NULL; + nullpo_retr(1, (stst = storage->get_settings(stor->uid))); - it = &VECTOR_INDEX(sd->storage.item, n); + Assert_retr(1, n >= 0 && n < VECTOR_LENGTH(stor->item)); + struct item *it = &VECTOR_INDEX(stor->item, n); + Assert_retr(1, amount <= it->amount); - Assert_retr(1, it->nameid > 0); it->amount -= amount; if (it->amount == 0) { memset(it, 0, sizeof(struct item)); - clif->updatestorageamount(sd, --sd->storage.aggregate, MAX_STORAGE); + clif->updatestorageamount(sd, --stor->aggregate, stst->capacity); } - sd->storage.save = true; + stor->save = true; if (sd->state.storage_flag == STORAGE_FLAG_NORMAL) clif->storageitemremoved(sd, n, amount); @@ -276,13 +350,22 @@ static int storage_delitem(struct map_session_data *sd, int n, int amount) * 0 : fail * 1 : success *------------------------------------------*/ -static int storage_add_from_inventory(struct map_session_data *sd, int index, int amount) +static int storage_add_from_inventory(struct map_session_data *sd, struct storage_data *stor, int index, int amount) { - nullpo_ret(sd); + nullpo_retr(0, sd); + nullpo_retr(0, stor); + Assert_retr(0, stor->received); + + const struct storage_settings *stst = NULL; + nullpo_retr(0, (stst = storage->get_settings(stor->uid))); - Assert_ret(sd->storage.received == true); + if ((sd->storage.access & STORAGE_ACCESS_PUT) == 0) { + clif->delitem(sd, index, amount, DELITEM_NORMAL); + clif->additem(sd, index, amount, 0); + return 0; + } - if (sd->storage.aggregate > MAX_STORAGE) + if (stor->aggregate >= stst->capacity) return 0; // storage full if (index < 0 || index >= sd->status.inventorySize) @@ -294,7 +377,7 @@ static int storage_add_from_inventory(struct map_session_data *sd, int index, in if (amount < 1 || amount > sd->status.inventory[index].amount) return 0; - if (storage->additem(sd, &sd->status.inventory[index], amount) == 0) + if (storage->additem(sd, stor, &sd->status.inventory[index], amount) == 0) pc->delitem(sd, index, amount, 0, DELITEM_TOSTORAGE, LOG_TYPE_STORAGE); else clif->item_movefailed(sd, index); @@ -309,19 +392,20 @@ static int storage_add_from_inventory(struct map_session_data *sd, int index, in * 0 : fail * 1 : success *------------------------------------------*/ -static int storage_add_to_inventory(struct map_session_data *sd, int index, int amount) +static int storage_add_to_inventory(struct map_session_data *sd, struct storage_data *stor, int index, int amount) { - int flag; - struct item *it = NULL; - nullpo_ret(sd); + nullpo_ret(stor); - Assert_ret(sd->storage.received == true); + Assert_ret(stor->received); - if (index < 0 || index >= VECTOR_LENGTH(sd->storage.item)) + if ((sd->storage.access & STORAGE_ACCESS_GET) == 0) return 0; - it = &VECTOR_INDEX(sd->storage.item, index); + if (index < 0 || index >= VECTOR_LENGTH(stor->item)) + return 0; + + struct item *it = &VECTOR_INDEX(stor->item, index); if (it->nameid <= 0) return 0; //Nothing there @@ -329,8 +413,9 @@ static int storage_add_to_inventory(struct map_session_data *sd, int index, int if (amount < 1 || amount > it->amount) return 0; + int flag; if ((flag = pc->additem(sd, it, amount, LOG_TYPE_STORAGE)) == 0) - storage->delitem(sd, index, amount); + storage->delitem(sd, stor, index, amount); else clif->additem(sd, 0, 0, flag); @@ -344,26 +429,36 @@ static int storage_add_to_inventory(struct map_session_data *sd, int index, int * 0 : fail * 1 : success *------------------------------------------*/ -static int storage_storageaddfromcart(struct map_session_data *sd, int index, int amount) +static int storage_storageaddfromcart(struct map_session_data *sd, struct storage_data *stor, int index, int amount) { nullpo_ret(sd); + nullpo_ret(stor); + Assert_ret(stor->received); + + const struct storage_settings *stst = NULL; + nullpo_ret(stst = storage->get_settings(stor->uid)); - Assert_ret(sd->storage.received == true); - if (sd->storage.aggregate > MAX_STORAGE) + if ((sd->storage.access & STORAGE_ACCESS_PUT) == 0) { + clif->delitem(sd, index, amount, DELITEM_NORMAL); + clif->additem(sd, index, amount, 0); + return 0; + } + + if (stor->aggregate >= stst->capacity) return 0; // storage full / storage closed if (index < 0 || index >= MAX_CART) return 0; - if( sd->status.cart[index].nameid <= 0 ) + if (sd->status.cart[index].nameid <= 0) return 0; //No item there. if (amount < 1 || amount > sd->status.cart[index].amount) return 0; - if (storage->additem(sd,&sd->status.cart[index],amount) == 0) - pc->cart_delitem(sd,index,amount,0,LOG_TYPE_STORAGE); + if (storage->additem(sd, stor, &sd->status.cart[index], amount) == 0) + pc->cart_delitem(sd, index, amount, 0, LOG_TYPE_STORAGE); return 1; } @@ -375,19 +470,19 @@ static int storage_storageaddfromcart(struct map_session_data *sd, int index, in * 0 : fail * 1 : success *------------------------------------------*/ -static int storage_storagegettocart(struct map_session_data *sd, int index, int amount) +static int storage_storagegettocart(struct map_session_data *sd, struct storage_data *stor, int index, int amount) { - int flag = 0; - struct item *it = NULL; + nullpo_retr(0, sd); + nullpo_retr(0, stor); + Assert_retr(0, stor->received); - nullpo_ret(sd); - - Assert_ret(sd->storage.received == true); + if ((sd->storage.access & STORAGE_ACCESS_GET) == 0) + return 0; - if (index < 0 || index >= VECTOR_LENGTH(sd->storage.item)) + if (index < 0 || index >= VECTOR_LENGTH(stor->item)) return 0; - it = &VECTOR_INDEX(sd->storage.item, index); + struct item *it = &VECTOR_INDEX(stor->item, index); if (it->nameid <= 0) return 0; //Nothing there. @@ -395,8 +490,9 @@ static int storage_storagegettocart(struct map_session_data *sd, int index, int if (amount < 1 || amount > it->amount) return 0; + int flag = 0; if ((flag = pc->cart_additem(sd, it, amount, LOG_TYPE_STORAGE)) == 0) - storage->delitem(sd, index, amount); + storage->delitem(sd, stor, index, amount); else { // probably this line is useless? it remove inventory lock but not storage [4144] clif->dropitem(sd, index,0); @@ -413,11 +509,12 @@ static int storage_storagegettocart(struct map_session_data *sd, int index, int *------------------------------------------*/ static void storage_storageclose(struct map_session_data *sd) { - int i = 0; - nullpo_retv(sd); - Assert_retv(sd->storage.received == true); + struct storage_data *curr_stor = NULL; + if ((curr_stor = storage->ensure(sd, sd->storage.current)) == NULL) + return; + clif->storageclose(sd); @@ -426,15 +523,18 @@ static void storage_storageclose(struct map_session_data *sd) /* Erase deleted account storage items from memory * and resize the vector. */ - while (i < VECTOR_LENGTH(sd->storage.item)) { - if (VECTOR_INDEX(sd->storage.item, i).nameid == 0) { - VECTOR_ERASE(sd->storage.item, i); + int i = 0; + while (i < VECTOR_LENGTH(curr_stor->item)) { + if (VECTOR_INDEX(curr_stor->item, i).nameid == 0) { + VECTOR_ERASE(curr_stor->item, i); } else { i++; } } sd->state.storage_flag = STORAGE_FLAG_CLOSED; + sd->storage.current = 0; // Reset current storage identifier. + sd->storage.access = STORAGE_ACCESS_ALL; // Reset access level to all levels. } /*========================================== @@ -841,10 +941,132 @@ static int storage_guild_storage_quit(struct map_session_data *sd, int flag) return 0; } +/** + * Read additional storage configuration fields for plugins. + * + * @param t [in] pointer to the config element being parsed. + * @param s_conf [in] pointer to the config struct being written to. + * @param filename [in] pointer to the filename string. + */ +static void storage_config_read_additional_fields(struct config_setting_t *t, struct storage_settings *s_conf, const char *filename) +{ + // plugins do their own thing. +} + +/** + * Dynamically reads storage configuration and initializes required variables. + * + * @param filename Path to configuration file. + * @param imported Whether the current config is imported from another file. + * @retval false in case of error. + */ +static bool storage_config_read(const char *filename, bool imported) +{ + nullpo_retr(false, filename); + + if (!imported) + VECTOR_INIT(storage->configuration); + + struct config_t stor_libconf; + if (libconfig->load_file(&stor_libconf, filename) == CONFIG_FALSE) + return false; // Error message is already shown by libconfig->load_file() + + const struct config_setting_t *setting = NULL; + if ((setting = libconfig->setting_get_member(stor_libconf.root, "storage_conf")) == NULL && !imported) { + ShowError("storage_config_read: Error in reading file '%s'\n", filename); + libconfig->destroy(&stor_libconf); + return false; + } + + struct config_setting_t *t = NULL; + int i = 0; + while ((t = libconfig->setting_get_elem(setting, i++)) != NULL) { + struct storage_settings s_conf = { 0 }; + + /* Id */ + if (libconfig->setting_lookup_int(t, "Id", &s_conf.uid) == CONFIG_FALSE) { + ShowError("storage_config_read: Id field not found for storage configuration in '%s'. Skipping...\n", filename); + continue; + } + + // Duplicate ID search and report... + int d = 0; + ARR_FIND(0, VECTOR_LENGTH(storage->configuration), d, VECTOR_INDEX(storage->configuration, d).uid == s_conf.uid); + if (d < VECTOR_LENGTH(storage->configuration)) { + ShowError("storage_config_read: Duplicate ID %d for storage. Skipping...\n", s_conf.uid); + continue; + } + + // Check for an invalid ID... + if (s_conf.uid <= 0) { + ShowError("storage_config_read: ID for storage cannot be less than or equal to zero. Skipping...\n"); + continue; + } + + /* Name */ + if (libconfig->setting_lookup_mutable_string(t, "Name", s_conf.name, NAME_LENGTH) == CONFIG_FALSE) { + ShowError("storage_config_read: Name field not found for storage configuration (Id: %d) in '%s'. Skipping...\n", s_conf.uid, filename); + continue; + } + + /* Capacity */ + if (libconfig->setting_lookup_int(t, "Capacity", &s_conf.capacity) == CONFIG_FALSE) { + ShowError("storage_config_read: Capacity field not found for storage configuration (Id: %d) in '%s'. Skipping...\n", s_conf.uid, filename); + continue; + } + + /* Additional Fields */ + struct config_setting_t *tt = NULL; + storage->config_read_additional_fields(tt, &s_conf, filename); + + if (imported) { + ARR_FIND(0, VECTOR_LENGTH(storage->configuration), i, VECTOR_INDEX(storage->configuration, i).uid == s_conf.uid); + if (i < VECTOR_LENGTH(storage->configuration)) + VECTOR_ERASE(storage->configuration, i); + } + + VECTOR_ENSURE(storage->configuration, 1, 1); + VECTOR_PUSH(storage->configuration, s_conf); + } + + // import should overwrite any previous configuration, so it should be called last + const char *import = NULL; + if (libconfig->lookup_string(&stor_libconf, "import", &import) == CONFIG_TRUE) { + if (strcmp(import, filename) == 0 || strcmp(import, map->STORAGE_CONF_FILENAME) == 0) { + ShowWarning("battle_config_read: Loop detected! Skipping 'import'...\n"); + libconfig->destroy(&stor_libconf); + return false; + } else if (storage->config_read(import, true) == false) { + libconfig->destroy(&stor_libconf); + return false; + } + } + + libconfig->destroy(&stor_libconf); + + ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", VECTOR_LENGTH(storage->configuration), map->STORAGE_CONF_FILENAME); + + return true; +} + +static void do_init_storage(bool minimal) +{ + if (minimal) + return; +} + +static void do_final_storage(void) +{ + // Clear storage configuration vector. + if (VECTOR_LENGTH(storage->configuration) > 0) + VECTOR_CLEAR(storage->configuration); +} + static void do_init_gstorage(bool minimal) { if (minimal) return; + gstorage->db = idb_alloc(DB_OPT_RELEASE_DATA); } @@ -857,9 +1079,16 @@ void storage_defaults(void) { storage = &storage_s; + storage->init = do_init_storage; + storage->final = do_final_storage; /* */ storage->reconnect = do_reconnect_storage; + storage->config_read = storage_config_read; + storage->config_read_additional_fields = storage_config_read_additional_fields; /* */ + storage->get_id_by_name = storage_get_id_by_name; + storage->ensure = storage_ensure; + storage->get_settings = storage_get_settings; storage->delitem = storage_delitem; storage->open = storage_storageopen; storage->add = storage_add_from_inventory; diff --git a/src/map/storage.h b/src/map/storage.h index 5c6152894..ec1ce4fe5 100644 --- a/src/map/storage.h +++ b/src/map/storage.h @@ -24,9 +24,12 @@ #include "common/hercules.h" #include "common/db.h" +struct config_setting_t; struct guild_storage; struct item; struct map_session_data; +struct storage_settings; +struct storage_data; /** * Acceptable values for map_session_data.state.storage_flag @@ -37,21 +40,37 @@ enum storage_flag { STORAGE_FLAG_GUILD = 2, // Guild Storage open }; +// Storage Access Modes [Smokexyz/Hercules] +enum storage_access_modes { + STORAGE_ACCESS_VIEW = 0x0, + STORAGE_ACCESS_GET = 0x1, + STORAGE_ACCESS_PUT = 0x2, + STORAGE_ACCESS_ALL = STORAGE_ACCESS_VIEW | STORAGE_ACCESS_GET | STORAGE_ACCESS_PUT +}; + struct storage_interface { + VECTOR_DECL(struct storage_settings) configuration; + void (*init) (bool minimal); + void (*final) (void); /* */ void (*reconnect) (void); + bool (*config_read) (const char *filename, bool imported); + void (*config_read_additional_fields) (struct config_setting_t *t, struct storage_settings *s_conf, const char *filename); /* */ - int (*delitem) (struct map_session_data* sd, int n, int amount); - int (*open) (struct map_session_data *sd); - int (*add) (struct map_session_data *sd,int index,int amount); - int (*get) (struct map_session_data *sd,int index,int amount); - int (*additem) (struct map_session_data* sd, struct item* item_data, int amount); - int (*addfromcart) (struct map_session_data *sd,int index,int amount); - int (*gettocart) (struct map_session_data *sd,int index,int amount); + int (*get_id_by_name) (const char *storage_name); + struct storage_data *(*ensure) (struct map_session_data *sd, int storage_id); + const struct storage_settings *(*get_settings) (int storage_id); + int (*delitem) (struct map_session_data *sd, struct storage_data *stor, int n, int amount); + int (*open) (struct map_session_data *sd, struct storage_data *stor); + int (*add) (struct map_session_data *sd, struct storage_data *stor, int index, int amount); + int (*get) (struct map_session_data *sd, struct storage_data *stor, int index, int amount); + int (*additem) (struct map_session_data *sd, struct storage_data *stor, struct item* item_data, int amount); + int (*addfromcart) (struct map_session_data *sd, struct storage_data *stor, int index,int amount); + int (*gettocart) (struct map_session_data *sd, struct storage_data *stor, int index,int amount); void (*close) (struct map_session_data *sd); void (*pc_quit) (struct map_session_data *sd, int flag); int (*comp_item) (const void *i1_, const void *i2_); - void (*sortitem) (struct item* items, unsigned int size); + void (*sortitem) (struct item *items, unsigned int size); int (*reconnect_sub) (union DBKey key, struct DBData *data, va_list ap); }; diff --git a/src/map/unit.c b/src/map/unit.c index 1e9433eaf..ba055da02 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -2750,8 +2750,7 @@ static int unit_free(struct block_list *bl, enum clr_type clrtype) sd->combo_count = 0; /* [Ind/Hercules] */ if( sd->sc_display_count ) { - int i; - for(i = 0; i < sd->sc_display_count; i++) { + for (int i = 0; i < sd->sc_display_count; i++) { ers_free(pc->sc_display_ers, sd->sc_display[i]); } sd->sc_display_count = 0; @@ -2767,10 +2766,16 @@ static int unit_free(struct block_list *bl, enum clr_type clrtype) VECTOR_CLEAR(sd->channels); VECTOR_CLEAR(sd->script_queues); VECTOR_CLEAR(sd->achievement); // Achievement [Smokexyz/Hercules] - VECTOR_CLEAR(sd->storage.item); VECTOR_CLEAR(sd->hatEffectId); VECTOR_CLEAR(sd->title_ids); // Title [Dastgir/Hercules] - sd->storage.received = false; + + /* Storages */ + for (int i = 0; i < VECTOR_LENGTH(sd->storage.list); i++) { + VECTOR_CLEAR(VECTOR_INDEX(sd->storage.list, i).item); + VECTOR_INDEX(sd->storage.list, i).received = false; + } + VECTOR_CLEAR(sd->storage.list); + if( sd->quest_log != NULL ) { aFree(sd->quest_log); sd->quest_log = NULL; diff --git a/src/plugins/HPMHooking/HPMHooking.Defs.inc b/src/plugins/HPMHooking/HPMHooking.Defs.inc index 83bbae1bf..4d9638494 100644 --- a/src/plugins/HPMHooking/HPMHooking.Defs.inc +++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc @@ -1690,8 +1690,8 @@ typedef void (*HPMHOOK_pre_clif_storageList) (struct map_session_data **sd, stru typedef void (*HPMHOOK_post_clif_storageList) (struct map_session_data *sd, struct item *items, int items_length); typedef void (*HPMHOOK_pre_clif_guildStorageList) (struct map_session_data **sd, struct item **items, int *items_length); typedef void (*HPMHOOK_post_clif_guildStorageList) (struct map_session_data *sd, struct item *items, int items_length); -typedef void (*HPMHOOK_pre_clif_storageItems) (struct map_session_data **sd, enum inventory_type *type, struct item **items, int *items_length); -typedef void (*HPMHOOK_post_clif_storageItems) (struct map_session_data *sd, enum inventory_type type, struct item *items, int items_length); +typedef void (*HPMHOOK_pre_clif_storageItems) (struct map_session_data **sd, enum inventory_type *type, struct item **items, int *items_length, const char **name); +typedef void (*HPMHOOK_post_clif_storageItems) (struct map_session_data *sd, enum inventory_type type, struct item *items, int items_length, const char *name); typedef void (*HPMHOOK_pre_clif_inventoryStart) (struct map_session_data **sd, enum inventory_type *type, const char **name); typedef void (*HPMHOOK_post_clif_inventoryStart) (struct map_session_data *sd, enum inventory_type type, const char *name); typedef void (*HPMHOOK_pre_clif_inventoryEnd) (struct map_session_data **sd, enum inventory_type *type); @@ -3614,10 +3614,10 @@ typedef int (*HPMHOOK_pre_inter_rodex_getitems) (int64 *mail_id, struct rodex_it typedef int (*HPMHOOK_post_inter_rodex_getitems) (int retVal___, int64 mail_id, struct rodex_item *items); #endif // CHAR_INT_RODEX_H #ifdef CHAR_INT_STORAGE_H /* inter_storage */ -typedef int (*HPMHOOK_pre_inter_storage_tosql) (int *account_id, const struct storage_data **p); -typedef int (*HPMHOOK_post_inter_storage_tosql) (int retVal___, int account_id, const struct storage_data *p); -typedef int (*HPMHOOK_pre_inter_storage_fromsql) (int *account_id, struct storage_data **p); -typedef int (*HPMHOOK_post_inter_storage_fromsql) (int retVal___, int account_id, struct storage_data *p); +typedef int (*HPMHOOK_pre_inter_storage_tosql) (int *account_id, int *storage_id, const struct storage_data **p); +typedef int (*HPMHOOK_post_inter_storage_tosql) (int retVal___, int account_id, int storage_id, const struct storage_data *p); +typedef int (*HPMHOOK_pre_inter_storage_fromsql) (int *account_id, int *storage_id, struct storage_data **p, int *storage_size); +typedef int (*HPMHOOK_post_inter_storage_fromsql) (int retVal___, int account_id, int storage_id, struct storage_data *p, int storage_size); typedef bool (*HPMHOOK_pre_inter_storage_guild_storage_tosql) (int *guild_id, const struct guild_storage **p); typedef bool (*HPMHOOK_post_inter_storage_guild_storage_tosql) (bool retVal___, int guild_id, const struct guild_storage *p); typedef int (*HPMHOOK_pre_inter_storage_guild_storage_fromsql) (int *guild_id, struct guild_storage **p); @@ -3644,10 +3644,10 @@ typedef int (*HPMHOOK_pre_intif_saveregistry) (struct map_session_data **sd); typedef int (*HPMHOOK_post_intif_saveregistry) (int retVal___, struct map_session_data *sd); typedef int (*HPMHOOK_pre_intif_request_registry) (struct map_session_data **sd, int *flag); typedef int (*HPMHOOK_post_intif_request_registry) (int retVal___, struct map_session_data *sd, int flag); -typedef void (*HPMHOOK_pre_intif_request_account_storage) (const struct map_session_data **sd); -typedef void (*HPMHOOK_post_intif_request_account_storage) (const struct map_session_data *sd); -typedef void (*HPMHOOK_pre_intif_send_account_storage) (struct map_session_data **sd); -typedef void (*HPMHOOK_post_intif_send_account_storage) (struct map_session_data *sd); +typedef void (*HPMHOOK_pre_intif_request_account_storage) (const struct map_session_data **sd, int *storage_id); +typedef void (*HPMHOOK_post_intif_request_account_storage) (const struct map_session_data *sd, int storage_id); +typedef void (*HPMHOOK_pre_intif_send_account_storage) (struct map_session_data **sd, int *storage_id); +typedef void (*HPMHOOK_post_intif_send_account_storage) (struct map_session_data *sd, int storage_id); typedef int (*HPMHOOK_pre_intif_request_guild_storage) (int *account_id, int *guild_id); typedef int (*HPMHOOK_post_intif_request_guild_storage) (int retVal___, int account_id, int guild_id); typedef int (*HPMHOOK_pre_intif_send_guild_storage) (int *account_id, struct guild_storage **gstor); @@ -5118,14 +5118,14 @@ typedef int (*HPMHOOK_pre_mapif_parse_LoadGuildStorage) (int *fd); typedef int (*HPMHOOK_post_mapif_parse_LoadGuildStorage) (int retVal___, int fd); typedef int (*HPMHOOK_pre_mapif_parse_SaveGuildStorage) (int *fd); typedef int (*HPMHOOK_post_mapif_parse_SaveGuildStorage) (int retVal___, int fd); -typedef int (*HPMHOOK_pre_mapif_account_storage_load) (int *fd, int *account_id); -typedef int (*HPMHOOK_post_mapif_account_storage_load) (int retVal___, int fd, int account_id); +typedef int (*HPMHOOK_pre_mapif_account_storage_load) (int *fd, int *account_id, int *storage_id, int *storage_size); +typedef int (*HPMHOOK_post_mapif_account_storage_load) (int retVal___, int fd, int account_id, int storage_id, int storage_size); typedef int (*HPMHOOK_pre_mapif_pAccountStorageLoad) (int *fd); typedef int (*HPMHOOK_post_mapif_pAccountStorageLoad) (int retVal___, int fd); typedef int (*HPMHOOK_pre_mapif_pAccountStorageSave) (int *fd); typedef int (*HPMHOOK_post_mapif_pAccountStorageSave) (int retVal___, int fd); -typedef void (*HPMHOOK_pre_mapif_sAccountStorageSaveAck) (int *fd, int *account_id, bool *save); -typedef void (*HPMHOOK_post_mapif_sAccountStorageSaveAck) (int fd, int account_id, bool save); +typedef void (*HPMHOOK_pre_mapif_sAccountStorageSaveAck) (int *fd, int *account_id, int *storage_id, bool *save); +typedef void (*HPMHOOK_post_mapif_sAccountStorageSaveAck) (int fd, int account_id, int storage_id, bool save); typedef int (*HPMHOOK_pre_mapif_itembound_ack) (int *fd, int *aid, int *guild_id); typedef int (*HPMHOOK_post_mapif_itembound_ack) (int retVal___, int fd, int aid, int guild_id); typedef void (*HPMHOOK_pre_mapif_parse_ItemBoundRetrieve) (int *fd); @@ -8008,22 +8008,36 @@ typedef int (*HPMHOOK_pre_status_base_matk_max) (const struct status_data **st); typedef int (*HPMHOOK_post_status_base_matk_max) (int retVal___, const struct status_data *st); #endif // MAP_STATUS_H #ifdef MAP_STORAGE_H /* storage */ +typedef void (*HPMHOOK_pre_storage_init) (bool *minimal); +typedef void (*HPMHOOK_post_storage_init) (bool minimal); +typedef void (*HPMHOOK_pre_storage_final) (void); +typedef void (*HPMHOOK_post_storage_final) (void); typedef void (*HPMHOOK_pre_storage_reconnect) (void); typedef void (*HPMHOOK_post_storage_reconnect) (void); -typedef int (*HPMHOOK_pre_storage_delitem) (struct map_session_data **sd, int *n, int *amount); -typedef int (*HPMHOOK_post_storage_delitem) (int retVal___, struct map_session_data *sd, int n, int amount); -typedef int (*HPMHOOK_pre_storage_open) (struct map_session_data **sd); -typedef int (*HPMHOOK_post_storage_open) (int retVal___, struct map_session_data *sd); -typedef int (*HPMHOOK_pre_storage_add) (struct map_session_data **sd, int *index, int *amount); -typedef int (*HPMHOOK_post_storage_add) (int retVal___, struct map_session_data *sd, int index, int amount); -typedef int (*HPMHOOK_pre_storage_get) (struct map_session_data **sd, int *index, int *amount); -typedef int (*HPMHOOK_post_storage_get) (int retVal___, struct map_session_data *sd, int index, int amount); -typedef int (*HPMHOOK_pre_storage_additem) (struct map_session_data **sd, struct item **item_data, int *amount); -typedef int (*HPMHOOK_post_storage_additem) (int retVal___, struct map_session_data *sd, struct item *item_data, int amount); -typedef int (*HPMHOOK_pre_storage_addfromcart) (struct map_session_data **sd, int *index, int *amount); -typedef int (*HPMHOOK_post_storage_addfromcart) (int retVal___, struct map_session_data *sd, int index, int amount); -typedef int (*HPMHOOK_pre_storage_gettocart) (struct map_session_data **sd, int *index, int *amount); -typedef int (*HPMHOOK_post_storage_gettocart) (int retVal___, struct map_session_data *sd, int index, int amount); +typedef bool (*HPMHOOK_pre_storage_config_read) (const char **filename, bool *imported); +typedef bool (*HPMHOOK_post_storage_config_read) (bool retVal___, const char *filename, bool imported); +typedef void (*HPMHOOK_pre_storage_config_read_additional_fields) (struct config_setting_t **t, struct storage_settings **s_conf, const char **filename); +typedef void (*HPMHOOK_post_storage_config_read_additional_fields) (struct config_setting_t *t, struct storage_settings *s_conf, const char *filename); +typedef int (*HPMHOOK_pre_storage_get_id_by_name) (const char **storage_name); +typedef int (*HPMHOOK_post_storage_get_id_by_name) (int retVal___, const char *storage_name); +typedef struct storage_data* (*HPMHOOK_pre_storage_ensure) (struct map_session_data **sd, int *storage_id); +typedef struct storage_data* (*HPMHOOK_post_storage_ensure) (struct storage_data* retVal___, struct map_session_data *sd, int storage_id); +typedef const struct storage_settings* (*HPMHOOK_pre_storage_get_settings) (int *storage_id); +typedef const struct storage_settings* (*HPMHOOK_post_storage_get_settings) (const struct storage_settings* retVal___, int storage_id); +typedef int (*HPMHOOK_pre_storage_delitem) (struct map_session_data **sd, struct storage_data **stor, int *n, int *amount); +typedef int (*HPMHOOK_post_storage_delitem) (int retVal___, struct map_session_data *sd, struct storage_data *stor, int n, int amount); +typedef int (*HPMHOOK_pre_storage_open) (struct map_session_data **sd, struct storage_data **stor); +typedef int (*HPMHOOK_post_storage_open) (int retVal___, struct map_session_data *sd, struct storage_data *stor); +typedef int (*HPMHOOK_pre_storage_add) (struct map_session_data **sd, struct storage_data **stor, int *index, int *amount); +typedef int (*HPMHOOK_post_storage_add) (int retVal___, struct map_session_data *sd, struct storage_data *stor, int index, int amount); +typedef int (*HPMHOOK_pre_storage_get) (struct map_session_data **sd, struct storage_data **stor, int *index, int *amount); +typedef int (*HPMHOOK_post_storage_get) (int retVal___, struct map_session_data *sd, struct storage_data *stor, int index, int amount); +typedef int (*HPMHOOK_pre_storage_additem) (struct map_session_data **sd, struct storage_data **stor, struct item **item_data, int *amount); +typedef int (*HPMHOOK_post_storage_additem) (int retVal___, struct map_session_data *sd, struct storage_data *stor, struct item *item_data, int amount); +typedef int (*HPMHOOK_pre_storage_addfromcart) (struct map_session_data **sd, struct storage_data **stor, int *index, int *amount); +typedef int (*HPMHOOK_post_storage_addfromcart) (int retVal___, struct map_session_data *sd, struct storage_data *stor, int index, int amount); +typedef int (*HPMHOOK_pre_storage_gettocart) (struct map_session_data **sd, struct storage_data **stor, int *index, int *amount); +typedef int (*HPMHOOK_post_storage_gettocart) (int retVal___, struct map_session_data *sd, struct storage_data *stor, int index, int amount); typedef void (*HPMHOOK_pre_storage_close) (struct map_session_data **sd); typedef void (*HPMHOOK_post_storage_close) (struct map_session_data *sd); typedef void (*HPMHOOK_pre_storage_pc_quit) (struct map_session_data **sd, int *flag); diff --git a/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc index b25025b1d..7552ef1f9 100644 --- a/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc +++ b/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc @@ -9846,15 +9846,15 @@ int HP_inter_rodex_getitems(int64 mail_id, struct rodex_item *items) { return retVal___; } /* inter_storage_interface */ -int HP_inter_storage_tosql(int account_id, const struct storage_data *p) { +int HP_inter_storage_tosql(int account_id, int storage_id, const struct storage_data *p) { int hIndex = 0; int retVal___ = 0; if (HPMHooks.count.HP_inter_storage_tosql_pre > 0) { - int (*preHookFunc) (int *account_id, const struct storage_data **p); + int (*preHookFunc) (int *account_id, int *storage_id, const struct storage_data **p); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_inter_storage_tosql_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_inter_storage_tosql_pre[hIndex].func; - retVal___ = preHookFunc(&account_id, &p); + retVal___ = preHookFunc(&account_id, &storage_id, &p); } if (*HPMforce_return) { *HPMforce_return = false; @@ -9862,26 +9862,26 @@ int HP_inter_storage_tosql(int account_id, const struct storage_data *p) { } } { - retVal___ = HPMHooks.source.inter_storage.tosql(account_id, p); + retVal___ = HPMHooks.source.inter_storage.tosql(account_id, storage_id, p); } if (HPMHooks.count.HP_inter_storage_tosql_post > 0) { - int (*postHookFunc) (int retVal___, int account_id, const struct storage_data *p); + int (*postHookFunc) (int retVal___, int account_id, int storage_id, const struct storage_data *p); for (hIndex = 0; hIndex < HPMHooks.count.HP_inter_storage_tosql_post; hIndex++) { postHookFunc = HPMHooks.list.HP_inter_storage_tosql_post[hIndex].func; - retVal___ = postHookFunc(retVal___, account_id, p); + retVal___ = postHookFunc(retVal___, account_id, storage_id, p); } } return retVal___; } -int HP_inter_storage_fromsql(int account_id, struct storage_data *p) { +int HP_inter_storage_fromsql(int account_id, int storage_id, struct storage_data *p, int storage_size) { int hIndex = 0; int retVal___ = 0; if (HPMHooks.count.HP_inter_storage_fromsql_pre > 0) { - int (*preHookFunc) (int *account_id, struct storage_data **p); + int (*preHookFunc) (int *account_id, int *storage_id, struct storage_data **p, int *storage_size); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_inter_storage_fromsql_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_inter_storage_fromsql_pre[hIndex].func; - retVal___ = preHookFunc(&account_id, &p); + retVal___ = preHookFunc(&account_id, &storage_id, &p, &storage_size); } if (*HPMforce_return) { *HPMforce_return = false; @@ -9889,13 +9889,13 @@ int HP_inter_storage_fromsql(int account_id, struct storage_data *p) { } } { - retVal___ = HPMHooks.source.inter_storage.fromsql(account_id, p); + retVal___ = HPMHooks.source.inter_storage.fromsql(account_id, storage_id, p, storage_size); } if (HPMHooks.count.HP_inter_storage_fromsql_post > 0) { - int (*postHookFunc) (int retVal___, int account_id, struct storage_data *p); + int (*postHookFunc) (int retVal___, int account_id, int storage_id, struct storage_data *p, int storage_size); for (hIndex = 0; hIndex < HPMHooks.count.HP_inter_storage_fromsql_post; hIndex++) { postHookFunc = HPMHooks.list.HP_inter_storage_fromsql_post[hIndex].func; - retVal___ = postHookFunc(retVal___, account_id, p); + retVal___ = postHookFunc(retVal___, account_id, storage_id, p, storage_size); } } return retVal___; @@ -16065,15 +16065,15 @@ int HP_mapif_parse_SaveGuildStorage(int fd) { } return retVal___; } -int HP_mapif_account_storage_load(int fd, int account_id) { +int HP_mapif_account_storage_load(int fd, int account_id, int storage_id, int storage_size) { int hIndex = 0; int retVal___ = 0; if (HPMHooks.count.HP_mapif_account_storage_load_pre > 0) { - int (*preHookFunc) (int *fd, int *account_id); + int (*preHookFunc) (int *fd, int *account_id, int *storage_id, int *storage_size); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_mapif_account_storage_load_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_mapif_account_storage_load_pre[hIndex].func; - retVal___ = preHookFunc(&fd, &account_id); + retVal___ = preHookFunc(&fd, &account_id, &storage_id, &storage_size); } if (*HPMforce_return) { *HPMforce_return = false; @@ -16081,13 +16081,13 @@ int HP_mapif_account_storage_load(int fd, int account_id) { } } { - retVal___ = HPMHooks.source.mapif.account_storage_load(fd, account_id); + retVal___ = HPMHooks.source.mapif.account_storage_load(fd, account_id, storage_id, storage_size); } if (HPMHooks.count.HP_mapif_account_storage_load_post > 0) { - int (*postHookFunc) (int retVal___, int fd, int account_id); + int (*postHookFunc) (int retVal___, int fd, int account_id, int storage_id, int storage_size); for (hIndex = 0; hIndex < HPMHooks.count.HP_mapif_account_storage_load_post; hIndex++) { postHookFunc = HPMHooks.list.HP_mapif_account_storage_load_post[hIndex].func; - retVal___ = postHookFunc(retVal___, fd, account_id); + retVal___ = postHookFunc(retVal___, fd, account_id, storage_id, storage_size); } } return retVal___; @@ -16146,14 +16146,14 @@ int HP_mapif_pAccountStorageSave(int fd) { } return retVal___; } -void HP_mapif_sAccountStorageSaveAck(int fd, int account_id, bool save) { +void HP_mapif_sAccountStorageSaveAck(int fd, int account_id, int storage_id, bool save) { int hIndex = 0; if (HPMHooks.count.HP_mapif_sAccountStorageSaveAck_pre > 0) { - void (*preHookFunc) (int *fd, int *account_id, bool *save); + void (*preHookFunc) (int *fd, int *account_id, int *storage_id, bool *save); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_mapif_sAccountStorageSaveAck_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_mapif_sAccountStorageSaveAck_pre[hIndex].func; - preHookFunc(&fd, &account_id, &save); + preHookFunc(&fd, &account_id, &storage_id, &save); } if (*HPMforce_return) { *HPMforce_return = false; @@ -16161,13 +16161,13 @@ void HP_mapif_sAccountStorageSaveAck(int fd, int account_id, bool save) { } } { - HPMHooks.source.mapif.sAccountStorageSaveAck(fd, account_id, save); + HPMHooks.source.mapif.sAccountStorageSaveAck(fd, account_id, storage_id, save); } if (HPMHooks.count.HP_mapif_sAccountStorageSaveAck_post > 0) { - void (*postHookFunc) (int fd, int account_id, bool save); + void (*postHookFunc) (int fd, int account_id, int storage_id, bool save); for (hIndex = 0; hIndex < HPMHooks.count.HP_mapif_sAccountStorageSaveAck_post; hIndex++) { postHookFunc = HPMHooks.list.HP_mapif_sAccountStorageSaveAck_post[hIndex].func; - postHookFunc(fd, account_id, save); + postHookFunc(fd, account_id, storage_id, save); } } return; diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc index 1196e3a99..fff6c6481 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc @@ -6528,8 +6528,22 @@ struct { struct HPMHookPoint *HP_status_base_matk_min_post; struct HPMHookPoint *HP_status_base_matk_max_pre; struct HPMHookPoint *HP_status_base_matk_max_post; + struct HPMHookPoint *HP_storage_init_pre; + struct HPMHookPoint *HP_storage_init_post; + struct HPMHookPoint *HP_storage_final_pre; + struct HPMHookPoint *HP_storage_final_post; struct HPMHookPoint *HP_storage_reconnect_pre; struct HPMHookPoint *HP_storage_reconnect_post; + struct HPMHookPoint *HP_storage_config_read_pre; + struct HPMHookPoint *HP_storage_config_read_post; + struct HPMHookPoint *HP_storage_config_read_additional_fields_pre; + struct HPMHookPoint *HP_storage_config_read_additional_fields_post; + struct HPMHookPoint *HP_storage_get_id_by_name_pre; + struct HPMHookPoint *HP_storage_get_id_by_name_post; + struct HPMHookPoint *HP_storage_ensure_pre; + struct HPMHookPoint *HP_storage_ensure_post; + struct HPMHookPoint *HP_storage_get_settings_pre; + struct HPMHookPoint *HP_storage_get_settings_post; struct HPMHookPoint *HP_storage_delitem_pre; struct HPMHookPoint *HP_storage_delitem_post; struct HPMHookPoint *HP_storage_open_pre; @@ -13357,8 +13371,22 @@ struct { int HP_status_base_matk_min_post; int HP_status_base_matk_max_pre; int HP_status_base_matk_max_post; + int HP_storage_init_pre; + int HP_storage_init_post; + int HP_storage_final_pre; + int HP_storage_final_post; int HP_storage_reconnect_pre; int HP_storage_reconnect_post; + int HP_storage_config_read_pre; + int HP_storage_config_read_post; + int HP_storage_config_read_additional_fields_pre; + int HP_storage_config_read_additional_fields_post; + int HP_storage_get_id_by_name_pre; + int HP_storage_get_id_by_name_post; + int HP_storage_ensure_pre; + int HP_storage_ensure_post; + int HP_storage_get_settings_pre; + int HP_storage_get_settings_post; int HP_storage_delitem_pre; int HP_storage_delitem_post; int HP_storage_open_pre; diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc index da72b688a..fd83e6100 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc @@ -3337,7 +3337,14 @@ struct HookingPointData HookingPoints[] = { { HP_POP(status->base_matk_min, HP_status_base_matk_min) }, { HP_POP(status->base_matk_max, HP_status_base_matk_max) }, /* storage_interface */ + { HP_POP(storage->init, HP_storage_init) }, + { HP_POP(storage->final, HP_storage_final) }, { HP_POP(storage->reconnect, HP_storage_reconnect) }, + { HP_POP(storage->config_read, HP_storage_config_read) }, + { HP_POP(storage->config_read_additional_fields, HP_storage_config_read_additional_fields) }, + { HP_POP(storage->get_id_by_name, HP_storage_get_id_by_name) }, + { HP_POP(storage->ensure, HP_storage_ensure) }, + { HP_POP(storage->get_settings, HP_storage_get_settings) }, { HP_POP(storage->delitem, HP_storage_delitem) }, { HP_POP(storage->open, HP_storage_open) }, { HP_POP(storage->add, HP_storage_add) }, diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc index a93d1e42e..8abbe934a 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc @@ -16694,14 +16694,14 @@ void HP_clif_guildStorageList(struct map_session_data *sd, struct item *items, i } return; } -void HP_clif_storageItems(struct map_session_data *sd, enum inventory_type type, struct item *items, int items_length) { +void HP_clif_storageItems(struct map_session_data *sd, enum inventory_type type, struct item *items, int items_length, const char *name) { int hIndex = 0; if (HPMHooks.count.HP_clif_storageItems_pre > 0) { - void (*preHookFunc) (struct map_session_data **sd, enum inventory_type *type, struct item **items, int *items_length); + void (*preHookFunc) (struct map_session_data **sd, enum inventory_type *type, struct item **items, int *items_length, const char **name); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_storageItems_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_clif_storageItems_pre[hIndex].func; - preHookFunc(&sd, &type, &items, &items_length); + preHookFunc(&sd, &type, &items, &items_length, &name); } if (*HPMforce_return) { *HPMforce_return = false; @@ -16709,13 +16709,13 @@ void HP_clif_storageItems(struct map_session_data *sd, enum inventory_type type, } } { - HPMHooks.source.clif.storageItems(sd, type, items, items_length); + HPMHooks.source.clif.storageItems(sd, type, items, items_length, name); } if (HPMHooks.count.HP_clif_storageItems_post > 0) { - void (*postHookFunc) (struct map_session_data *sd, enum inventory_type type, struct item *items, int items_length); + void (*postHookFunc) (struct map_session_data *sd, enum inventory_type type, struct item *items, int items_length, const char *name); for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_storageItems_post; hIndex++) { postHookFunc = HPMHooks.list.HP_clif_storageItems_post[hIndex].func; - postHookFunc(sd, type, items, items_length); + postHookFunc(sd, type, items, items_length, name); } } return; @@ -37338,14 +37338,14 @@ int HP_intif_request_registry(struct map_session_data *sd, int flag) { } return retVal___; } -void HP_intif_request_account_storage(const struct map_session_data *sd) { +void HP_intif_request_account_storage(const struct map_session_data *sd, int storage_id) { int hIndex = 0; if (HPMHooks.count.HP_intif_request_account_storage_pre > 0) { - void (*preHookFunc) (const struct map_session_data **sd); + void (*preHookFunc) (const struct map_session_data **sd, int *storage_id); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_intif_request_account_storage_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_intif_request_account_storage_pre[hIndex].func; - preHookFunc(&sd); + preHookFunc(&sd, &storage_id); } if (*HPMforce_return) { *HPMforce_return = false; @@ -37353,25 +37353,25 @@ void HP_intif_request_account_storage(const struct map_session_data *sd) { } } { - HPMHooks.source.intif.request_account_storage(sd); + HPMHooks.source.intif.request_account_storage(sd, storage_id); } if (HPMHooks.count.HP_intif_request_account_storage_post > 0) { - void (*postHookFunc) (const struct map_session_data *sd); + void (*postHookFunc) (const struct map_session_data *sd, int storage_id); for (hIndex = 0; hIndex < HPMHooks.count.HP_intif_request_account_storage_post; hIndex++) { postHookFunc = HPMHooks.list.HP_intif_request_account_storage_post[hIndex].func; - postHookFunc(sd); + postHookFunc(sd, storage_id); } } return; } -void HP_intif_send_account_storage(struct map_session_data *sd) { +void HP_intif_send_account_storage(struct map_session_data *sd, int storage_id) { int hIndex = 0; if (HPMHooks.count.HP_intif_send_account_storage_pre > 0) { - void (*preHookFunc) (struct map_session_data **sd); + void (*preHookFunc) (struct map_session_data **sd, int *storage_id); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_intif_send_account_storage_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_intif_send_account_storage_pre[hIndex].func; - preHookFunc(&sd); + preHookFunc(&sd, &storage_id); } if (*HPMforce_return) { *HPMforce_return = false; @@ -37379,13 +37379,13 @@ void HP_intif_send_account_storage(struct map_session_data *sd) { } } { - HPMHooks.source.intif.send_account_storage(sd); + HPMHooks.source.intif.send_account_storage(sd, storage_id); } if (HPMHooks.count.HP_intif_send_account_storage_post > 0) { - void (*postHookFunc) (struct map_session_data *sd); + void (*postHookFunc) (struct map_session_data *sd, int storage_id); for (hIndex = 0; hIndex < HPMHooks.count.HP_intif_send_account_storage_post; hIndex++) { postHookFunc = HPMHooks.list.HP_intif_send_account_storage_post[hIndex].func; - postHookFunc(sd); + postHookFunc(sd, storage_id); } } return; @@ -87343,6 +87343,58 @@ int HP_status_base_matk_max(const struct status_data *st) { return retVal___; } /* storage_interface */ +void HP_storage_init(bool minimal) { + int hIndex = 0; + if (HPMHooks.count.HP_storage_init_pre > 0) { + void (*preHookFunc) (bool *minimal); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_storage_init_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_storage_init_pre[hIndex].func; + preHookFunc(&minimal); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.storage.init(minimal); + } + if (HPMHooks.count.HP_storage_init_post > 0) { + void (*postHookFunc) (bool minimal); + for (hIndex = 0; hIndex < HPMHooks.count.HP_storage_init_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_storage_init_post[hIndex].func; + postHookFunc(minimal); + } + } + return; +} +void HP_storage_final(void) { + int hIndex = 0; + if (HPMHooks.count.HP_storage_final_pre > 0) { + void (*preHookFunc) (void); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_storage_final_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_storage_final_pre[hIndex].func; + preHookFunc(); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.storage.final(); + } + if (HPMHooks.count.HP_storage_final_post > 0) { + void (*postHookFunc) (void); + for (hIndex = 0; hIndex < HPMHooks.count.HP_storage_final_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_storage_final_post[hIndex].func; + postHookFunc(); + } + } + return; +} void HP_storage_reconnect(void) { int hIndex = 0; if (HPMHooks.count.HP_storage_reconnect_pre > 0) { @@ -87369,15 +87421,149 @@ void HP_storage_reconnect(void) { } return; } -int HP_storage_delitem(struct map_session_data *sd, int n, int amount) { +bool HP_storage_config_read(const char *filename, bool imported) { + int hIndex = 0; + bool retVal___ = false; + if (HPMHooks.count.HP_storage_config_read_pre > 0) { + bool (*preHookFunc) (const char **filename, bool *imported); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_storage_config_read_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_storage_config_read_pre[hIndex].func; + retVal___ = preHookFunc(&filename, &imported); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.storage.config_read(filename, imported); + } + if (HPMHooks.count.HP_storage_config_read_post > 0) { + bool (*postHookFunc) (bool retVal___, const char *filename, bool imported); + for (hIndex = 0; hIndex < HPMHooks.count.HP_storage_config_read_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_storage_config_read_post[hIndex].func; + retVal___ = postHookFunc(retVal___, filename, imported); + } + } + return retVal___; +} +void HP_storage_config_read_additional_fields(struct config_setting_t *t, struct storage_settings *s_conf, const char *filename) { + int hIndex = 0; + if (HPMHooks.count.HP_storage_config_read_additional_fields_pre > 0) { + void (*preHookFunc) (struct config_setting_t **t, struct storage_settings **s_conf, const char **filename); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_storage_config_read_additional_fields_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_storage_config_read_additional_fields_pre[hIndex].func; + preHookFunc(&t, &s_conf, &filename); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.storage.config_read_additional_fields(t, s_conf, filename); + } + if (HPMHooks.count.HP_storage_config_read_additional_fields_post > 0) { + void (*postHookFunc) (struct config_setting_t *t, struct storage_settings *s_conf, const char *filename); + for (hIndex = 0; hIndex < HPMHooks.count.HP_storage_config_read_additional_fields_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_storage_config_read_additional_fields_post[hIndex].func; + postHookFunc(t, s_conf, filename); + } + } + return; +} +int HP_storage_get_id_by_name(const char *storage_name) { + int hIndex = 0; + int retVal___ = 0; + if (HPMHooks.count.HP_storage_get_id_by_name_pre > 0) { + int (*preHookFunc) (const char **storage_name); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_storage_get_id_by_name_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_storage_get_id_by_name_pre[hIndex].func; + retVal___ = preHookFunc(&storage_name); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.storage.get_id_by_name(storage_name); + } + if (HPMHooks.count.HP_storage_get_id_by_name_post > 0) { + int (*postHookFunc) (int retVal___, const char *storage_name); + for (hIndex = 0; hIndex < HPMHooks.count.HP_storage_get_id_by_name_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_storage_get_id_by_name_post[hIndex].func; + retVal___ = postHookFunc(retVal___, storage_name); + } + } + return retVal___; +} +struct storage_data* HP_storage_ensure(struct map_session_data *sd, int storage_id) { + int hIndex = 0; + struct storage_data* retVal___ = NULL; + if (HPMHooks.count.HP_storage_ensure_pre > 0) { + struct storage_data* (*preHookFunc) (struct map_session_data **sd, int *storage_id); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_storage_ensure_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_storage_ensure_pre[hIndex].func; + retVal___ = preHookFunc(&sd, &storage_id); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.storage.ensure(sd, storage_id); + } + if (HPMHooks.count.HP_storage_ensure_post > 0) { + struct storage_data* (*postHookFunc) (struct storage_data* retVal___, struct map_session_data *sd, int storage_id); + for (hIndex = 0; hIndex < HPMHooks.count.HP_storage_ensure_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_storage_ensure_post[hIndex].func; + retVal___ = postHookFunc(retVal___, sd, storage_id); + } + } + return retVal___; +} +const struct storage_settings* HP_storage_get_settings(int storage_id) { + int hIndex = 0; + const struct storage_settings* retVal___ = NULL; + if (HPMHooks.count.HP_storage_get_settings_pre > 0) { + const struct storage_settings* (*preHookFunc) (int *storage_id); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_storage_get_settings_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_storage_get_settings_pre[hIndex].func; + retVal___ = preHookFunc(&storage_id); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.storage.get_settings(storage_id); + } + if (HPMHooks.count.HP_storage_get_settings_post > 0) { + const struct storage_settings* (*postHookFunc) (const struct storage_settings* retVal___, int storage_id); + for (hIndex = 0; hIndex < HPMHooks.count.HP_storage_get_settings_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_storage_get_settings_post[hIndex].func; + retVal___ = postHookFunc(retVal___, storage_id); + } + } + return retVal___; +} +int HP_storage_delitem(struct map_session_data *sd, struct storage_data *stor, int n, int amount) { int hIndex = 0; int retVal___ = 0; if (HPMHooks.count.HP_storage_delitem_pre > 0) { - int (*preHookFunc) (struct map_session_data **sd, int *n, int *amount); + int (*preHookFunc) (struct map_session_data **sd, struct storage_data **stor, int *n, int *amount); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_storage_delitem_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_storage_delitem_pre[hIndex].func; - retVal___ = preHookFunc(&sd, &n, &amount); + retVal___ = preHookFunc(&sd, &stor, &n, &amount); } if (*HPMforce_return) { *HPMforce_return = false; @@ -87385,26 +87571,26 @@ int HP_storage_delitem(struct map_session_data *sd, int n, int amount) { } } { - retVal___ = HPMHooks.source.storage.delitem(sd, n, amount); + retVal___ = HPMHooks.source.storage.delitem(sd, stor, n, amount); } if (HPMHooks.count.HP_storage_delitem_post > 0) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, int n, int amount); + int (*postHookFunc) (int retVal___, struct map_session_data *sd, struct storage_data *stor, int n, int amount); for (hIndex = 0; hIndex < HPMHooks.count.HP_storage_delitem_post; hIndex++) { postHookFunc = HPMHooks.list.HP_storage_delitem_post[hIndex].func; - retVal___ = postHookFunc(retVal___, sd, n, amount); + retVal___ = postHookFunc(retVal___, sd, stor, n, amount); } } return retVal___; } -int HP_storage_open(struct map_session_data *sd) { +int HP_storage_open(struct map_session_data *sd, struct storage_data *stor) { int hIndex = 0; int retVal___ = 0; if (HPMHooks.count.HP_storage_open_pre > 0) { - int (*preHookFunc) (struct map_session_data **sd); + int (*preHookFunc) (struct map_session_data **sd, struct storage_data **stor); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_storage_open_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_storage_open_pre[hIndex].func; - retVal___ = preHookFunc(&sd); + retVal___ = preHookFunc(&sd, &stor); } if (*HPMforce_return) { *HPMforce_return = false; @@ -87412,26 +87598,26 @@ int HP_storage_open(struct map_session_data *sd) { } } { - retVal___ = HPMHooks.source.storage.open(sd); + retVal___ = HPMHooks.source.storage.open(sd, stor); } if (HPMHooks.count.HP_storage_open_post > 0) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd); + int (*postHookFunc) (int retVal___, struct map_session_data *sd, struct storage_data *stor); for (hIndex = 0; hIndex < HPMHooks.count.HP_storage_open_post; hIndex++) { postHookFunc = HPMHooks.list.HP_storage_open_post[hIndex].func; - retVal___ = postHookFunc(retVal___, sd); + retVal___ = postHookFunc(retVal___, sd, stor); } } return retVal___; } -int HP_storage_add(struct map_session_data *sd, int index, int amount) { +int HP_storage_add(struct map_session_data *sd, struct storage_data *stor, int index, int amount) { int hIndex = 0; int retVal___ = 0; if (HPMHooks.count.HP_storage_add_pre > 0) { - int (*preHookFunc) (struct map_session_data **sd, int *index, int *amount); + int (*preHookFunc) (struct map_session_data **sd, struct storage_data **stor, int *index, int *amount); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_storage_add_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_storage_add_pre[hIndex].func; - retVal___ = preHookFunc(&sd, &index, &amount); + retVal___ = preHookFunc(&sd, &stor, &index, &amount); } if (*HPMforce_return) { *HPMforce_return = false; @@ -87439,26 +87625,26 @@ int HP_storage_add(struct map_session_data *sd, int index, int amount) { } } { - retVal___ = HPMHooks.source.storage.add(sd, index, amount); + retVal___ = HPMHooks.source.storage.add(sd, stor, index, amount); } if (HPMHooks.count.HP_storage_add_post > 0) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, int index, int amount); + int (*postHookFunc) (int retVal___, struct map_session_data *sd, struct storage_data *stor, int index, int amount); for (hIndex = 0; hIndex < HPMHooks.count.HP_storage_add_post; hIndex++) { postHookFunc = HPMHooks.list.HP_storage_add_post[hIndex].func; - retVal___ = postHookFunc(retVal___, sd, index, amount); + retVal___ = postHookFunc(retVal___, sd, stor, index, amount); } } return retVal___; } -int HP_storage_get(struct map_session_data *sd, int index, int amount) { +int HP_storage_get(struct map_session_data *sd, struct storage_data *stor, int index, int amount) { int hIndex = 0; int retVal___ = 0; if (HPMHooks.count.HP_storage_get_pre > 0) { - int (*preHookFunc) (struct map_session_data **sd, int *index, int *amount); + int (*preHookFunc) (struct map_session_data **sd, struct storage_data **stor, int *index, int *amount); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_storage_get_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_storage_get_pre[hIndex].func; - retVal___ = preHookFunc(&sd, &index, &amount); + retVal___ = preHookFunc(&sd, &stor, &index, &amount); } if (*HPMforce_return) { *HPMforce_return = false; @@ -87466,26 +87652,26 @@ int HP_storage_get(struct map_session_data *sd, int index, int amount) { } } { - retVal___ = HPMHooks.source.storage.get(sd, index, amount); + retVal___ = HPMHooks.source.storage.get(sd, stor, index, amount); } if (HPMHooks.count.HP_storage_get_post > 0) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, int index, int amount); + int (*postHookFunc) (int retVal___, struct map_session_data *sd, struct storage_data *stor, int index, int amount); for (hIndex = 0; hIndex < HPMHooks.count.HP_storage_get_post; hIndex++) { postHookFunc = HPMHooks.list.HP_storage_get_post[hIndex].func; - retVal___ = postHookFunc(retVal___, sd, index, amount); + retVal___ = postHookFunc(retVal___, sd, stor, index, amount); } } return retVal___; } -int HP_storage_additem(struct map_session_data *sd, struct item *item_data, int amount) { +int HP_storage_additem(struct map_session_data *sd, struct storage_data *stor, struct item *item_data, int amount) { int hIndex = 0; int retVal___ = 0; if (HPMHooks.count.HP_storage_additem_pre > 0) { - int (*preHookFunc) (struct map_session_data **sd, struct item **item_data, int *amount); + int (*preHookFunc) (struct map_session_data **sd, struct storage_data **stor, struct item **item_data, int *amount); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_storage_additem_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_storage_additem_pre[hIndex].func; - retVal___ = preHookFunc(&sd, &item_data, &amount); + retVal___ = preHookFunc(&sd, &stor, &item_data, &amount); } if (*HPMforce_return) { *HPMforce_return = false; @@ -87493,26 +87679,26 @@ int HP_storage_additem(struct map_session_data *sd, struct item *item_data, int } } { - retVal___ = HPMHooks.source.storage.additem(sd, item_data, amount); + retVal___ = HPMHooks.source.storage.additem(sd, stor, item_data, amount); } if (HPMHooks.count.HP_storage_additem_post > 0) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, struct item *item_data, int amount); + int (*postHookFunc) (int retVal___, struct map_session_data *sd, struct storage_data *stor, struct item *item_data, int amount); for (hIndex = 0; hIndex < HPMHooks.count.HP_storage_additem_post; hIndex++) { postHookFunc = HPMHooks.list.HP_storage_additem_post[hIndex].func; - retVal___ = postHookFunc(retVal___, sd, item_data, amount); + retVal___ = postHookFunc(retVal___, sd, stor, item_data, amount); } } return retVal___; } -int HP_storage_addfromcart(struct map_session_data *sd, int index, int amount) { +int HP_storage_addfromcart(struct map_session_data *sd, struct storage_data *stor, int index, int amount) { int hIndex = 0; int retVal___ = 0; if (HPMHooks.count.HP_storage_addfromcart_pre > 0) { - int (*preHookFunc) (struct map_session_data **sd, int *index, int *amount); + int (*preHookFunc) (struct map_session_data **sd, struct storage_data **stor, int *index, int *amount); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_storage_addfromcart_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_storage_addfromcart_pre[hIndex].func; - retVal___ = preHookFunc(&sd, &index, &amount); + retVal___ = preHookFunc(&sd, &stor, &index, &amount); } if (*HPMforce_return) { *HPMforce_return = false; @@ -87520,26 +87706,26 @@ int HP_storage_addfromcart(struct map_session_data *sd, int index, int amount) { } } { - retVal___ = HPMHooks.source.storage.addfromcart(sd, index, amount); + retVal___ = HPMHooks.source.storage.addfromcart(sd, stor, index, amount); } if (HPMHooks.count.HP_storage_addfromcart_post > 0) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, int index, int amount); + int (*postHookFunc) (int retVal___, struct map_session_data *sd, struct storage_data *stor, int index, int amount); for (hIndex = 0; hIndex < HPMHooks.count.HP_storage_addfromcart_post; hIndex++) { postHookFunc = HPMHooks.list.HP_storage_addfromcart_post[hIndex].func; - retVal___ = postHookFunc(retVal___, sd, index, amount); + retVal___ = postHookFunc(retVal___, sd, stor, index, amount); } } return retVal___; } -int HP_storage_gettocart(struct map_session_data *sd, int index, int amount) { +int HP_storage_gettocart(struct map_session_data *sd, struct storage_data *stor, int index, int amount) { int hIndex = 0; int retVal___ = 0; if (HPMHooks.count.HP_storage_gettocart_pre > 0) { - int (*preHookFunc) (struct map_session_data **sd, int *index, int *amount); + int (*preHookFunc) (struct map_session_data **sd, struct storage_data **stor, int *index, int *amount); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_storage_gettocart_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_storage_gettocart_pre[hIndex].func; - retVal___ = preHookFunc(&sd, &index, &amount); + retVal___ = preHookFunc(&sd, &stor, &index, &amount); } if (*HPMforce_return) { *HPMforce_return = false; @@ -87547,13 +87733,13 @@ int HP_storage_gettocart(struct map_session_data *sd, int index, int amount) { } } { - retVal___ = HPMHooks.source.storage.gettocart(sd, index, amount); + retVal___ = HPMHooks.source.storage.gettocart(sd, stor, index, amount); } if (HPMHooks.count.HP_storage_gettocart_post > 0) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, int index, int amount); + int (*postHookFunc) (int retVal___, struct map_session_data *sd, struct storage_data *stor, int index, int amount); for (hIndex = 0; hIndex < HPMHooks.count.HP_storage_gettocart_post; hIndex++) { postHookFunc = HPMHooks.list.HP_storage_gettocart_post[hIndex].func; - retVal___ = postHookFunc(retVal___, sd, index, amount); + retVal___ = postHookFunc(retVal___, sd, stor, index, amount); } } return retVal___; -- cgit v1.2.3-60-g2f50