summaryrefslogtreecommitdiff
path: root/src/char
diff options
context:
space:
mode:
Diffstat (limited to 'src/char')
-rw-r--r--src/char/int_storage.c58
-rw-r--r--src/char/int_storage.h4
-rw-r--r--src/char/inter.c2
-rw-r--r--src/char/mapif.c52
-rw-r--r--src/char/mapif.h4
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);