diff options
Diffstat (limited to 'src/char')
-rw-r--r-- | src/char/int_storage.c | 58 | ||||
-rw-r--r-- | src/char/int_storage.h | 4 | ||||
-rw-r--r-- | src/char/inter.c | 2 | ||||
-rw-r--r-- | src/char/mapif.c | 52 | ||||
-rw-r--r-- | src/char/mapif.h | 4 |
5 files changed, 72 insertions, 48 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] <account_id>.L <struct item[]>.P - * @param fd [in] file/socket descriptor. - * @param account_id [in] account id of the session. + * + * @packet 0x3805 [out] <packet_len>.W <account_id>.L <storage_id>.W <struct item[]>.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] <account_id>.L + * @packet 0x3010 [in] <account_id>.L <storage_id>.W <storage_size>.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] <packet_len>.W <account_id>.L <struct item[]>.P + * @packet 0x3011 [in] <packet_len>.W <account_id>.L <storage_id>.L <struct item[]>.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] <account_id>.L <save_flag>.B + * + * @packet 0x3808 [out] <account_id>.L <storage_id>.W <save_flag>.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); |