summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/char/char.c37
-rw-r--r--src/char/int_storage.c309
-rw-r--r--src/char/int_storage.h5
-rw-r--r--src/char/inter.c2
-rw-r--r--src/char/mapif.c8
-rw-r--r--src/char/mapif.h4
-rw-r--r--src/common/mmo.h8
-rw-r--r--src/login/lclif.c4
-rw-r--r--src/login/lclif.p.h8
-rw-r--r--src/map/atcommand.c66
-rw-r--r--src/map/atcommand.h6
-rw-r--r--src/map/battle.c2
-rw-r--r--src/map/chrif.c3
-rw-r--r--src/map/clif.c44
-rw-r--r--src/map/intif.c137
-rw-r--r--src/map/intif.h4
-rw-r--r--src/map/itemdb.c10
-rw-r--r--src/map/packets.h356
-rw-r--r--src/map/pc.c119
-rw-r--r--src/map/pc.h13
-rw-r--r--src/map/script.c118
-rw-r--r--src/map/script.h1
-rw-r--r--src/map/storage.c211
-rw-r--r--src/map/unit.c2
-rw-r--r--src/plugins/HPMHooking/HPMHooking.Defs.inc20
-rw-r--r--src/plugins/HPMHooking/HPMHooking_char.HPMHooksCore.inc16
-rw-r--r--src/plugins/HPMHooking/HPMHooking_char.HookingPoints.inc4
-rw-r--r--src/plugins/HPMHooking/HPMHooking_char.Hooks.inc113
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc16
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc4
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.Hooks.inc104
31 files changed, 1506 insertions, 248 deletions
diff --git a/src/char/char.c b/src/char/char.c
index 93078f8ee..069ccc481 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -287,8 +287,10 @@ void char_set_char_offline(int char_id, int account_id)
}
else
{
- struct mmo_charstatus* cp = (struct mmo_charstatus*)idb_get(chr->char_db_,char_id);
+ struct mmo_charstatus* cp = (struct mmo_charstatus*) idb_get(chr->char_db_,char_id);
+
inter_guild->CharOffline(char_id, cp?cp->guild_id:-1);
+
if (cp)
idb_remove(chr->char_db_,char_id);
@@ -442,14 +444,6 @@ int char_mmo_char_tosql(int char_id, struct mmo_charstatus* p)
errors++;
}
- //map storage data
- if( memcmp(p->storage.items, cp->storage.items, sizeof(p->storage.items)) ) {
- if (!chr->memitemdata_to_sql(p->storage.items, MAX_STORAGE, p->account_id, TABLE_STORAGE))
- strcat(save_status, " storage");
- else
- errors++;
- }
-
if (
(p->base_exp != cp->base_exp) || (p->base_level != cp->base_level) ||
(p->job_level != cp->job_level) || (p->job_exp != cp->job_exp) ||
@@ -1284,10 +1278,6 @@ int char_mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_every
strcat(t_msg, " cart");
- //read storage
- inter_storage->fromsql(p->account_id, &p->storage);
- strcat(t_msg, " storage");
-
//read skill
//`skill` (`char_id`, `id`, `lv`)
memset(&tmp_skill, 0, sizeof(tmp_skill));
@@ -4442,14 +4432,21 @@ void char_parse_char_connect(int fd, struct char_session_data* sd, uint32 ipl)
void char_send_map_info(int fd, int i, uint32 subnet_map_ip, struct mmo_charstatus *cd)
{
+#if PACKETVER < 20170329
+ const int cmd = 0x71;
+ const int len = 28;
+#else
+ const int cmd = 0xac5;
+ const int len = 156;
+#endif
nullpo_retv(cd);
- WFIFOHEAD(fd,28);
- WFIFOW(fd,0) = 0x71;
- WFIFOL(fd,2) = cd->char_id;
- mapindex->getmapname_ext(mapindex_id2name(cd->last_point.map), WFIFOP(fd,6));
- WFIFOL(fd,22) = htonl((subnet_map_ip) ? subnet_map_ip : chr->server[i].ip);
- WFIFOW(fd,26) = sockt->ntows(htons(chr->server[i].port)); // [!] LE byte order here [!]
- WFIFOSET(fd,28);
+ WFIFOHEAD(fd, len);
+ WFIFOW(fd, 0) = cmd;
+ WFIFOL(fd, 2) = cd->char_id;
+ mapindex->getmapname_ext(mapindex_id2name(cd->last_point.map), WFIFOP(fd, 6));
+ WFIFOL(fd, 22) = htonl((subnet_map_ip) ? subnet_map_ip : chr->server[i].ip);
+ WFIFOW(fd, 26) = sockt->ntows(htons(chr->server[i].port)); // [!] LE byte order here [!]
+ WFIFOSET(fd, len);
}
void char_send_wait_char_server(int fd)
diff --git a/src/char/int_storage.c b/src/char/int_storage.c
index b78ad9f0e..65301127f 100644
--- a/src/char/int_storage.c
+++ b/src/char/int_storage.c
@@ -41,24 +41,142 @@ struct inter_storage_interface inter_storage_s;
struct inter_storage_interface *inter_storage;
/// Save storage data to sql
-int inter_storage_tosql(int account_id, struct storage_data* p)
+int inter_storage_tosql(int account_id, 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);
- chr->memitemdata_to_sql(p->items, MAX_STORAGE, account_id, TABLE_STORAGE);
- return 0;
+
+ VECTOR_INIT(cp.item);
+ inter_storage->fromsql(account_id, &cp);
+
+ StrBuf->Init(&buf);
+
+ if (VECTOR_LENGTH(cp.item) > 0) {
+ /**
+ * Compare and update items, if any.
+ */
+ for (i = 0; i < VECTOR_LENGTH(cp.item); i++) {
+ struct item *cp_it = &VECTOR_INDEX(cp.item, i);
+ struct item *p_it = NULL;
+
+ ARR_FIND(0, VECTOR_LENGTH(p->item), j,
+ matched_p[j] != true
+ && (p_it = &VECTOR_INDEX(p->item, j)) != NULL
+ && cp_it->nameid == p_it->nameid
+ && cp_it->unique_id == p_it->unique_id
+ && memcmp(p_it->card, cp_it->card, sizeof(short) * MAX_SLOTS) == 0
+ && memcmp(p_it->option, cp_it->option, 5 * MAX_ITEM_OPTIONS) == 0);
+
+ if (j < VECTOR_LENGTH(p->item)) {
+ int k = 0;
+ if (memcmp(cp_it, p_it, sizeof(struct item)) != 0) {
+ if (total_updates == 0) {
+ StrBuf->Printf(&buf, "REPLACE INTO `%s` (`id`, `account_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`", storage_db);
+ for (k = 0; k < MAX_SLOTS; k++)
+ StrBuf->Printf(&buf, ", `card%d`", k);
+ for (k = 0; k < MAX_ITEM_OPTIONS; k++)
+ StrBuf->Printf(&buf, ", `opt_idx%d`, `opt_val%d`", k, k);
+ StrBuf->AppendStr(&buf, ", `expire_time`, `bound`, `unique_id`) VALUES");
+ }
+
+ StrBuf->Printf(&buf, "%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);
+ for (k = 0; k < MAX_SLOTS; k++)
+ StrBuf->Printf(&buf, ", '%d'", p_it->card[k]);
+ for (k = 0; k < MAX_ITEM_OPTIONS; ++k)
+ StrBuf->Printf(&buf, ", '%d', '%d'", p_it->option[k].index, p_it->option[k].value);
+ StrBuf->Printf(&buf, ", '%u', '%d', '%"PRIu64"')", p_it->expire_time, p_it->bound, p_it->unique_id);
+
+ total_updates++;
+ }
+ matched_p[j] = true;
+ } else { // Does not exist, so set for deletion.
+ delete[total_deletes++] = cp_it->id;
+ }
+ }
+
+ if (total_updates > 0 && SQL_ERROR == SQL->QueryStr(inter->sql_handle, StrBuf->Value(&buf)))
+ Sql_ShowDebug(inter->sql_handle);
+
+ /**
+ * Handle deletions, if any.
+ */
+ if (total_deletes > 0) {
+ StrBuf->Clear(&buf);
+ StrBuf->Printf(&buf, "DELETE FROM `%s` WHERE `id` IN (", storage_db);
+ for (i = 0; i < total_deletes; i++) {
+ StrBuf->Printf(&buf, "%s'%d'", i == 0 ? "" : ", ", delete[i]);
+ }
+ StrBuf->AppendStr(&buf, ");");
+
+ if (SQL_ERROR == SQL->QueryStr(inter->sql_handle, StrBuf->Value(&buf)))
+ Sql_ShowDebug(inter->sql_handle);
+ }
+ }
+
+ /**
+ * Check for new items.
+ */
+ for (i = 0; i < VECTOR_LENGTH(p->item); i++) {
+ struct item *p_it = &VECTOR_INDEX(p->item, i);
+
+ if (matched_p[i])
+ continue; // Item is not a new entry, so lets continue.
+
+ // Store the remaining items.
+ if (total_inserts == 0) {
+ StrBuf->Clear(&buf);
+ StrBuf->Printf(&buf, "INSERT INTO `%s` (`account_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`, `unique_id`", storage_db);
+ for (j = 0; j < MAX_SLOTS; ++j)
+ StrBuf->Printf(&buf, ", `card%d`", j);
+ for (j = 0; j < MAX_ITEM_OPTIONS; ++j)
+ StrBuf->Printf(&buf, ", `opt_idx%d`, `opt_val%d`", j, j);
+ StrBuf->AppendStr(&buf, ") VALUES ");
+ }
+
+ StrBuf->Printf(&buf, "%s('%d', '%d', '%d', '%u', '%d', '%d', '%d', '%u', '%d', '%"PRIu64"'",
+ total_inserts > 0 ? ", " : "", account_id, p_it->nameid, p_it->amount, p_it->equip, p_it->identify, p_it->refine,
+ p_it->attribute, p_it->expire_time, p_it->bound, p_it->unique_id);
+ for (j = 0; j < MAX_SLOTS; ++j)
+ StrBuf->Printf(&buf, ", '%d'", p_it->card[j]);
+ for (j = 0; j < MAX_ITEM_OPTIONS; ++j)
+ StrBuf->Printf(&buf, ", '%d', '%d'", p_it->option[j].index, p_it->option[j].value);
+ StrBuf->AppendStr(&buf, ")");
+
+ total_inserts++;
+ }
+
+ if (total_inserts > 0 && SQL_ERROR == SQL->QueryStr(inter->sql_handle, StrBuf->Value(&buf)))
+ Sql_ShowDebug(inter->sql_handle);
+
+ StrBuf->Destroy(&buf);
+ 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;
}
/// Load storage data to mem
-int inter_storage_fromsql(int account_id, struct storage_data* p)
+int inter_storage_fromsql(int account_id, struct storage_data *p)
{
StringBuf buf;
char* data;
int i;
int j;
+ int num_rows = 0;
nullpo_ret(p);
- memset(p, 0, sizeof(struct storage_data)); //clean up memory
- p->storage_amount = 0;
+
+ if (VECTOR_LENGTH(p->item) > 0)
+ VECTOR_CLEAR(p->item);
// storage {`account_id`/`id`/`nameid`/`amount`/`equip`/`identify`/`refine`/`attribute`/`card0`/`card1`/`card2`/`card3`}
StrBuf->Init(&buf);
@@ -74,36 +192,46 @@ int inter_storage_fromsql(int account_id, struct storage_data* p)
StrBuf->Destroy(&buf);
- for (i = 0; i < MAX_STORAGE && SQL_SUCCESS == SQL->NextRow(inter->sql_handle); ++i) {
- struct item *item = &p->items[i];
- SQL->GetData(inter->sql_handle, 0, &data, NULL); item->id = atoi(data);
- SQL->GetData(inter->sql_handle, 1, &data, NULL); item->nameid = atoi(data);
- SQL->GetData(inter->sql_handle, 2, &data, NULL); item->amount = atoi(data);
- SQL->GetData(inter->sql_handle, 3, &data, NULL); item->equip = atoi(data);
- SQL->GetData(inter->sql_handle, 4, &data, NULL); item->identify = atoi(data);
- SQL->GetData(inter->sql_handle, 5, &data, NULL); item->refine = atoi(data);
- SQL->GetData(inter->sql_handle, 6, &data, NULL); item->attribute = atoi(data);
- SQL->GetData(inter->sql_handle, 7, &data, NULL); item->expire_time = (unsigned int)atoi(data);
- SQL->GetData(inter->sql_handle, 8, &data, NULL); item->bound = atoi(data);
- SQL->GetData(inter->sql_handle, 9, &data, NULL); item->unique_id = strtoull(data, NULL, 10);
- /* Card Slots */
- for (j = 0; j < MAX_SLOTS; ++j) {
- SQL->GetData(inter->sql_handle, 10 + j, &data, NULL);
- item->card[j] = atoi(data);
- }
- /* Item Options */
- for (j = 0; j < MAX_ITEM_OPTIONS; ++j) {
- SQL->GetData(inter->sql_handle, 10 + MAX_SLOTS + j * 2, &data, NULL);
- item->option[j].index = atoi(data);
- SQL->GetData(inter->sql_handle, 11 + MAX_SLOTS + j * 2, &data, NULL);
- item->option[j].value = atoi(data);
+ if ((num_rows = (int)SQL->NumRows(inter->sql_handle)) != 0) {
+
+ VECTOR_ENSURE(p->item, num_rows > MAX_STORAGE ? MAX_STORAGE : num_rows, 1);
+
+ for (i = 0; i < MAX_STORAGE && SQL_SUCCESS == SQL->NextRow(inter->sql_handle); ++i) {
+ struct item item = { 0 };
+ SQL->GetData(inter->sql_handle, 0, &data, NULL); item.id = atoi(data);
+ SQL->GetData(inter->sql_handle, 1, &data, NULL); item.nameid = atoi(data);
+ SQL->GetData(inter->sql_handle, 2, &data, NULL); item.amount = atoi(data);
+ SQL->GetData(inter->sql_handle, 3, &data, NULL); item.equip = atoi(data);
+ SQL->GetData(inter->sql_handle, 4, &data, NULL); item.identify = atoi(data);
+ SQL->GetData(inter->sql_handle, 5, &data, NULL); item.refine = atoi(data);
+ SQL->GetData(inter->sql_handle, 6, &data, NULL); item.attribute = atoi(data);
+ SQL->GetData(inter->sql_handle, 7, &data, NULL); item.expire_time = (unsigned int)atoi(data);
+ SQL->GetData(inter->sql_handle, 8, &data, NULL); item.bound = atoi(data);
+ SQL->GetData(inter->sql_handle, 9, &data, NULL); item.unique_id = strtoull(data, NULL, 10);
+
+ /* Card Slots */
+ for (j = 0; j < MAX_SLOTS; ++j) {
+ SQL->GetData(inter->sql_handle, 10 + j, &data, NULL);
+ item.card[j] = atoi(data);
+ }
+
+ /* Item Options */
+ for (j = 0; j < MAX_ITEM_OPTIONS; ++j) {
+ SQL->GetData(inter->sql_handle, 10 + MAX_SLOTS + j * 2, &data, NULL);
+ item.option[j].index = atoi(data);
+ SQL->GetData(inter->sql_handle, 11 + MAX_SLOTS + j * 2, &data, NULL);
+ item.option[j].value = atoi(data);
+ }
+
+ VECTOR_PUSH(p->item, item);
}
}
- p->storage_amount = i;
+
SQL->FreeResult(inter->sql_handle);
- ShowInfo("storage load complete from DB - id: %d (total: %d)\n", account_id, p->storage_amount);
- return 1;
+ ShowInfo("storage load complete from DB - id: %d (total: %d)\n", account_id, VECTOR_LENGTH(p->item));
+
+ return VECTOR_LENGTH(p->item);
}
/// Save guild_storage data to sql
@@ -240,13 +368,125 @@ int mapif_save_guild_storage_ack(int fd, int account_id, int guild_id, int fail)
return 0;
}
+//=========================================================
+// Account Storage
//---------------------------------------------------------
-// packet from map server
+/**
+ * Parses account storage load request from map server.
+ * @packet 0x3010 [in] <account_id>.L
+ * @param fd [in] file/socket descriptor
+ * @return 1 on success, 0 on failure.
+ */
+int mapif_parse_AccountStorageLoad(int fd)
+{
+ int account_id = RFIFOL(fd, 2);
+
+ Assert_ret(fd > 0);
+ Assert_ret(account_id > 0);
+
+ mapif->account_storage_load(fd, account_id);
+
+ return 1;
+}
+
+/**
+ * Loads the account storage and send to the map server.
+ * @packet 0x3805 [out] <account_id>.L <struct item[]>.P
+ * @param fd [in] file/socket descriptor.
+ * @param account_id [in] account id of the session.
+ * @return 1 on success, 0 on failure.
+ */
+int mapif_account_storage_load(int fd, int account_id)
+{
+ struct storage_data stor = { 0 };
+ int count = 0, i = 0, len = 0;
+
+ Assert_ret(account_id > 0);
+
+ VECTOR_INIT(stor.item);
+ count = inter_storage->fromsql(account_id, &stor);
+
+ len = 8 + count * sizeof(struct item);
+
+ WFIFOHEAD(fd, len);
+ WFIFOW(fd, 0) = 0x3805;
+ WFIFOW(fd, 2) = (uint16) len;
+ WFIFOL(fd, 4) = account_id;
+ for (i = 0; i < count; i++)
+ memcpy(WFIFOP(fd, 8 + i * sizeof(struct item)), &VECTOR_INDEX(stor.item, i), sizeof(struct item));
+ WFIFOSET(fd, len);
+
+ VECTOR_CLEAR(stor.item);
+ return 1;
+}
+
+/**
+ * Parses an account storage save request from the map server.
+ * @packet 0x3011 [in] <packet_len>.W <account_id>.L <struct item[]>.P
+ * @param fd [in] file/socket descriptor.
+ * @return 1 on success, 0 on failure.
+ */
+int mapif_parse_AccountStorageSave(int fd)
+{
+ int payload_size = RFIFOW(fd, 2) - 8, account_id = RFIFOL(fd, 4);
+ int i = 0, count = 0;
+ struct storage_data p_stor = { 0 };
+
+ Assert_ret(fd > 0);
+ Assert_ret(account_id > 0);
+
+ count = payload_size/sizeof(struct item);
+
+ VECTOR_INIT(p_stor.item);
+
+ if (count > 0) {
+ VECTOR_ENSURE(p_stor.item, count, 1);
+
+ for (i = 0; i < count; i++) {
+ const struct item *it = RFIFOP(fd, 8 + i * sizeof(struct item));
+
+ VECTOR_PUSH(p_stor.item, *it);
+ }
+
+ p_stor.aggregate = count;
+ }
+
+ inter_storage->tosql(account_id, &p_stor);
+
+ VECTOR_CLEAR(p_stor.item);
+
+ mapif->sAccountStorageSaveAck(fd, account_id, true);
+
+ return 1;
+}
+
+/**
+ * Sends an acknowledgement for the save
+ * status of the account storage.
+ * @packet 0x3808 [out] <account_id>.L <save_flag>.B
+ * @param fd [in] File/Socket Descriptor.
+ * @param account_id [in] Account ID of the storage in question.
+ * @param flag [in] Save flag, true for success and false for failure.
+ */
+void mapif_send_AccountStorageSaveAck(int fd, int account_id, bool flag)
+{
+ WFIFOHEAD(fd, 7);
+ WFIFOW(fd, 0) = 0x3808;
+ WFIFOL(fd, 2) = account_id;
+ WFIFOB(fd, 6) = flag ? 1 : 0;
+ WFIFOSET(fd, 7);
+}
+
+//=========================================================
+// Guild Storage
+//---------------------------------------------------------
int mapif_parse_LoadGuildStorage(int fd)
{
RFIFOHEAD(fd);
+
mapif->load_guild_storage(fd,RFIFOL(fd,2),RFIFOL(fd,6),1);
+
return 0;
}
@@ -274,6 +514,7 @@ int mapif_parse_SaveGuildStorage(int fd)
SQL->FreeResult(inter->sql_handle);
}
mapif->save_guild_storage_ack(fd, RFIFOL(fd,4), guild_id, 1);
+
return 0;
}
@@ -487,6 +728,8 @@ int inter_storage_parse_frommap(int fd)
{
RFIFOHEAD(fd);
switch(RFIFOW(fd,0)){
+ case 0x3010: mapif->pAccountStorageLoad(fd); break;
+ case 0x3011: mapif->pAccountStorageSave(fd); break;
case 0x3018: mapif->parse_LoadGuildStorage(fd); break;
case 0x3019: mapif->parse_SaveGuildStorage(fd); break;
#ifdef GP_BOUND_ITEMS
diff --git a/src/char/int_storage.h b/src/char/int_storage.h
index 8c6341e85..46bb6910f 100644
--- a/src/char/int_storage.h
+++ b/src/char/int_storage.h
@@ -21,6 +21,7 @@
#ifndef CHAR_INT_STORAGE_H
#define CHAR_INT_STORAGE_H
+#include "common/db.h"
#include "common/hercules.h"
struct storage_data;
@@ -30,8 +31,8 @@ struct guild_storage;
* inter_storage interface
**/
struct inter_storage_interface {
- int (*tosql) (int account_id, struct storage_data* p);
- int (*fromsql) (int account_id, struct storage_data* p);
+ int (*tosql) (int account_id, const struct storage_data *p);
+ int (*fromsql) (int account_id, struct storage_data *p);
int (*guild_storage_tosql) (int guild_id, const struct guild_storage *p);
int (*guild_storage_fromsql) (int guild_id, struct guild_storage* p);
int (*sql_init) (void);
diff --git a/src/char/inter.c b/src/char/inter.c
index d076bb657..cfbc0fd4d 100644
--- a/src/char/inter.c
+++ b/src/char/inter.c
@@ -68,7 +68,7 @@ int party_share_level = 10;
// recv. packet list
int inter_recv_packet_length[] = {
-1,-1, 7,-1, -1,13,36, (2 + 4 + 4 + 4 + NAME_LENGTH), 0, 0, 0, 0, 0, 0, 0, 0, // 3000-
- 6,-1, 0, 0, 0, 0, 0, 0, 10,-1, 0, 0, 0, 0, 0, 0, // 3010-
+ 6,-1, 0, 0, 0, 0, 0, 0, 10,-1, 0, 0, 0, 0, 0, 0, // 3010- Account Storage [Smokexyz]
-1,10,-1,14, 14,19, 6,-1, 14,14, 0, 0, 0, 0, 0, 0, // 3020- Party
-1, 6,-1,-1, 55,19, 6,-1, 14,-1,-1,-1, 18,19,186,-1, // 3030-
-1, 9, 0, 0, 0, 0, 0, 0, 7, 6,10,10, 10,-1, 0, 0, // 3040-
diff --git a/src/char/mapif.c b/src/char/mapif.c
index 1dafb79c3..5fff96ba8 100644
--- a/src/char/mapif.c
+++ b/src/char/mapif.c
@@ -186,6 +186,10 @@ int mapif_load_guild_storage(int fd,int account_id,int guild_id, char flag);
int mapif_save_guild_storage_ack(int fd, int account_id, int guild_id, int fail);
int mapif_parse_LoadGuildStorage(int fd);
int mapif_parse_SaveGuildStorage(int fd);
+int mapif_account_storage_load(int fd, int account_id);
+int mapif_parse_AccountStorageLoad(int fd);
+int mapif_parse_AccountStorageSave(int fd);
+void mapif_send_AccountStorageSaveAck(int fd, int account_id, bool save);
int mapif_itembound_ack(int fd, int aid, int guild_id);
int mapif_parse_ItemBoundRetrieve_sub(int fd);
void mapif_parse_ItemBoundRetrieve(int fd);
@@ -363,6 +367,10 @@ void mapif_defaults(void) {
mapif->save_guild_storage_ack = mapif_save_guild_storage_ack;
mapif->parse_LoadGuildStorage = mapif_parse_LoadGuildStorage;
mapif->parse_SaveGuildStorage = mapif_parse_SaveGuildStorage;
+ mapif->pAccountStorageLoad = mapif_parse_AccountStorageLoad;
+ mapif->pAccountStorageSave = mapif_parse_AccountStorageSave;
+ mapif->sAccountStorageSaveAck = mapif_send_AccountStorageSaveAck;
+ mapif->account_storage_load = mapif_account_storage_load;
mapif->itembound_ack = mapif_itembound_ack;
mapif->parse_ItemBoundRetrieve_sub = mapif_parse_ItemBoundRetrieve_sub;
mapif->parse_ItemBoundRetrieve = mapif_parse_ItemBoundRetrieve;
diff --git a/src/char/mapif.h b/src/char/mapif.h
index ebbddead0..07fbed6c6 100644
--- a/src/char/mapif.h
+++ b/src/char/mapif.h
@@ -180,6 +180,10 @@ struct mapif_interface {
int (*save_guild_storage_ack) (int fd, int account_id, int guild_id, int fail);
int (*parse_LoadGuildStorage) (int fd);
int (*parse_SaveGuildStorage) (int fd);
+ int (*account_storage_load) (int fd, int account_id);
+ int (*pAccountStorageLoad) (int fd);
+ int (*pAccountStorageSave) (int fd);
+ void (*sAccountStorageSaveAck) (int fd, int account_id, bool save);
int (*itembound_ack) (int fd, int aid, int guild_id);
int (*parse_ItemBoundRetrieve_sub) (int fd);
void (*parse_ItemBoundRetrieve) (int fd);
diff --git a/src/common/mmo.h b/src/common/mmo.h
index 7bd5b7c06..276e0eb08 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -23,6 +23,7 @@
#include "config/core.h"
#include "common/cbasetypes.h"
+#include "common/db.h" // VECTORS
// server->client protocol version
// 0 - pre-?
@@ -480,8 +481,10 @@ struct status_change_data {
};
struct storage_data {
- int storage_amount;
- struct item items[MAX_STORAGE];
+ bool save; ///< save flag.
+ bool received; ///< received flag.
+ int aggregate; ///< total item count.
+ VECTOR_DECL(struct item) item; ///< item vector.
};
struct guild_storage {
@@ -617,7 +620,6 @@ struct mmo_charstatus {
struct point last_point,save_point,memo_point[MAX_MEMOPOINTS];
struct item inventory[MAX_INVENTORY],cart[MAX_CART];
- struct storage_data storage;
struct s_skill skill[MAX_SKILL];
struct s_friend friends[MAX_FRIENDS]; //New friend system [Skotlex]
diff --git a/src/login/lclif.c b/src/login/lclif.c
index 3ed257e85..f32538610 100644
--- a/src/login/lclif.c
+++ b/src/login/lclif.c
@@ -262,7 +262,11 @@ bool lclif_send_server_list(struct login_session_data *sd)
WFIFOHEAD(sd->fd, length);
packet = WP2PTR(sd->fd);
+#if PACKETVER < 20170315
packet->packet_id = PACKET_ID_AC_ACCEPT_LOGIN;
+#else
+ packet->packet_id = PACKET_ID_AC_ACCEPT_LOGIN2;
+#endif
packet->packet_len = length;
packet->auth_code = sd->login_id1;
packet->aid = sd->account_id;
diff --git a/src/login/lclif.p.h b/src/login/lclif.p.h
index ae9d1bc14..d28f1c587 100644
--- a/src/login/lclif.p.h
+++ b/src/login/lclif.p.h
@@ -56,7 +56,9 @@ enum login_packet_id {
//PACKET_ID_CA_SSO_LOGIN_REQa = 0x825a, /* unused */
// AC (Login to Client)
+
PACKET_ID_AC_ACCEPT_LOGIN = 0x0069,
+ PACKET_ID_AC_ACCEPT_LOGIN2 = 0x0ac4,
PACKET_ID_AC_REFUSE_LOGIN = 0x006a,
PACKET_ID_SC_NOTIFY_BAN = 0x0081,
PACKET_ID_AC_ACK_HASH = 0x01dc,
@@ -256,6 +258,9 @@ struct packet_AC_ACCEPT_LOGIN {
uint32 last_login_ip; ///< Last login IP
char last_login_time[26]; ///< Last login timestamp
uint8 sex; ///< Account sex
+#if PACKETVER >= 20170315
+ char unknown1[17];
+#endif
struct {
uint32 ip; ///< Server IP address
int16 port; ///< Server port
@@ -263,6 +268,9 @@ struct packet_AC_ACCEPT_LOGIN {
uint16 usercount; ///< Online users
uint16 state; ///< Server state
uint16 property; ///< Server property
+#if PACKETVER >= 20170315
+ char unknown2[128];
+#endif
} server_list[]; ///< List of charservers
} __attribute__((packed));
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 9f37a754f..19a7e360b 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -1408,7 +1408,7 @@ ACMD(baselevelup)
pc->baselevelchanged(sd);
if(sd->status.party_id)
party->send_levelup(sd);
-
+
if (level > 0 && battle_config.atcommand_levelup_events)
npc->script_event(sd, NPCE_BASELVUP); // Trigger OnPCBaseLvUpEvent
@@ -5159,6 +5159,11 @@ ACMD(storeall)
}
}
+ if (sd->storage.received == false) {
+ clif->message(fd, msg_fd(fd, 27)); // "Storage has not been loaded yet"
+ return false;
+ }
+
for (i = 0; i < MAX_INVENTORY; i++) {
if (sd->status.inventory[i].amount) {
if(sd->status.inventory[i].equip != 0)
@@ -5174,17 +5179,25 @@ ACMD(storeall)
ACMD(clearstorage)
{
- int i, j;
+ int i;
if (sd->state.storage_flag == STORAGE_FLAG_NORMAL) {
clif->message(fd, msg_fd(fd,250));
return false;
}
- j = sd->status.storage.storage_amount;
- for (i = 0; i < j; ++i) {
- storage->delitem(sd, i, sd->status.storage.items[i].amount);
+ if (sd->storage.received == false) {
+ 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)
+ continue; // we skip the already deleted items.
+
+ storage->delitem(sd, i, VECTOR_INDEX(sd->storage.item, i).amount);
+ }
+
storage->close(sd);
clif->message(fd, msg_fd(fd,1394)); // Your storage was cleaned.
@@ -8041,8 +8054,8 @@ ACMD(itemlist)
if( strcmpi(info->command, "storagelist") == 0 ) {
location = "storage";
- items = sd->status.storage.items;
- size = MAX_STORAGE;
+ items = VECTOR_DATA(sd->storage.item);
+ size = VECTOR_LENGTH(sd->storage.item);
} else if( strcmpi(info->command, "cartlist") == 0 ) {
location = "cart";
items = sd->status.cart;
@@ -8063,7 +8076,7 @@ ACMD(itemlist)
const struct item* it = &items[i];
struct item_data* itd;
- if( it->nameid == 0 || (itd = itemdb->exists(it->nameid)) == NULL )
+ if (it->nameid == 0 || (itd = itemdb->exists(it->nameid)) == NULL)
continue;
counter += it->amount;
@@ -8385,7 +8398,9 @@ void atcommand_commands_sub(struct map_session_data* sd, const int fd, AtCommand
int gm_lvl = pc_get_group_level(sd);
for (i = 0; i < atcommand->binding_count; i++) {
- if (gm_lvl >= ((type == COMMAND_ATCOMMAND) ? atcommand->binding[i]->group_lv : atcommand->binding[i]->group_lv_char)) {
+ if (gm_lvl >= ((type == COMMAND_ATCOMMAND) ? atcommand->binding[i]->group_lv : atcommand->binding[i]->group_lv_char)
+ || (type == COMMAND_ATCOMMAND && atcommand->binding[i]->at_groups[pcg->get_idx(sd->group)] > 0)
+ || (type == COMMAND_CHARCOMMAND && atcommand->binding[i]->char_groups[pcg->get_idx(sd->group)] > 0)) {
size_t slen = strlen(atcommand->binding[i]->command);
if (count_bind == 0) {
cur = line_buff;
@@ -9948,6 +9963,8 @@ bool atcommand_exec(const int fd, struct map_session_data *sd, const char *messa
&& (
(is_atcommand && pc_get_group_level(sd) >= binding->group_lv)
|| (!is_atcommand && pc_get_group_level(sd) >= binding->group_lv_char)
+ || (is_atcommand && binding->at_groups[pcg->get_idx(sd->group)] > 0)
+ || (!is_atcommand && binding->char_groups[pcg->get_idx(sd->group)] > 0)
)
) {
if (binding->log) /* log only if this command should be logged [Ind/Hercules] */
@@ -10211,31 +10228,34 @@ void atcommand_db_load_groups(GroupSettings **groups, struct config_setting_t **
}
bool atcommand_can_use(struct map_session_data *sd, const char *command) {
- AtCommandInfo *info = atcommand->get_info_byname(atcommand->check_alias(command + 1));
+ AtCommandInfo *acmd_d;
+ struct atcmd_binding_data *bcmd_d;
nullpo_retr(false, sd);
- nullpo_retr(false, command);
- if (info == NULL)
- return false;
- if ((*command == atcommand->at_symbol && info->at_groups[pcg->get_idx(sd->group)] != 0) ||
- (*command == atcommand->char_symbol && info->char_groups[pcg->get_idx(sd->group)] != 0) ) {
- return true;
+ if ((acmd_d = atcommand->get_info_byname(atcommand->check_alias(command + 1))) != NULL) {
+ return ((*command == atcommand->at_symbol && acmd_d->at_groups[pcg->get_idx(sd->group)] > 0) ||
+ (*command == atcommand->char_symbol && acmd_d->char_groups[pcg->get_idx(sd->group)] > 0));
+ } else if ((bcmd_d = atcommand->get_bind_byname(atcommand->check_alias(command + 1))) != NULL) {
+ return ((*command == atcommand->at_symbol && bcmd_d->at_groups[pcg->get_idx(sd->group)] > 0) ||
+ (*command == atcommand->char_symbol && bcmd_d->char_groups[pcg->get_idx(sd->group)] > 0));
}
return false;
}
+
bool atcommand_can_use2(struct map_session_data *sd, const char *command, AtCommandType type) {
- AtCommandInfo *info = atcommand->get_info_byname(atcommand->check_alias(command));
+ AtCommandInfo *acmd_d;
+ struct atcmd_binding_data *bcmd_d;
nullpo_retr(false, sd);
- nullpo_retr(false, command);
- if (info == NULL)
- return false;
- if ((type == COMMAND_ATCOMMAND && info->at_groups[pcg->get_idx(sd->group)] != 0) ||
- (type == COMMAND_CHARCOMMAND && info->char_groups[pcg->get_idx(sd->group)] != 0) ) {
- return true;
+ if ((acmd_d = atcommand->get_info_byname(atcommand->check_alias(command))) != NULL) {
+ return ((type == COMMAND_ATCOMMAND && acmd_d->at_groups[pcg->get_idx(sd->group)] > 0) ||
+ (type == COMMAND_CHARCOMMAND && acmd_d->char_groups[pcg->get_idx(sd->group)] > 0));
+ } else if ((bcmd_d = atcommand->get_bind_byname(atcommand->check_alias(command))) != NULL) {
+ return ((type == COMMAND_ATCOMMAND && bcmd_d->at_groups[pcg->get_idx(sd->group)] > 0) ||
+ (type == COMMAND_CHARCOMMAND && bcmd_d->char_groups[pcg->get_idx(sd->group)] > 0));
}
return false;
diff --git a/src/map/atcommand.h b/src/map/atcommand.h
index 35b3c382e..efcf6dd31 100644
--- a/src/map/atcommand.h
+++ b/src/map/atcommand.h
@@ -79,8 +79,10 @@ struct AtCommandInfo {
struct atcmd_binding_data {
char command[ATCOMMAND_LENGTH];
char npc_event[ATCOMMAND_LENGTH];
- int group_lv;
- int group_lv_char;
+ int group_lv; // DEPRECATED
+ int group_lv_char; // DEPRECATED
+ char *at_groups; // quick @commands "can-use" lookup
+ char *char_groups; // quick @charcommands "can-use" lookup
bool log;
};
diff --git a/src/map/battle.c b/src/map/battle.c
index 11425d4a9..57a74bba4 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -7034,7 +7034,7 @@ static const struct battle_data {
{ "max_heal_lv", &battle_config.max_heal_lv, 11, 1, INT_MAX, },
{ "max_heal", &battle_config.max_heal, 9999, 0, INT_MAX, },
{ "combo_delay_rate", &battle_config.combo_delay_rate, 100, 0, INT_MAX, },
- { "item_check", &battle_config.item_check, 0, 0, 1, },
+ { "item_check", &battle_config.item_check, 0, 0, 0xF, },
{ "item_use_interval", &battle_config.item_use_interval, 100, 0, INT_MAX, },
{ "wedding_modifydisplay", &battle_config.wedding_modifydisplay, 0, 0, 1, },
{ "wedding_ignorepalette", &battle_config.wedding_ignorepalette, 0, 0, 1, },
diff --git a/src/map/chrif.c b/src/map/chrif.c
index bf613b029..39aa046d7 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -324,6 +324,9 @@ bool chrif_save(struct map_session_data *sd, int flag) {
if( sd->save_quest )
intif->quest_save(sd);
+ if (sd->storage.received == true && sd->storage.save == true)
+ intif->send_account_storage(sd);
+
return true;
}
diff --git a/src/map/clif.c b/src/map/clif.c
index e70857ab6..524378439 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -4189,12 +4189,13 @@ void clif_storageitemremoved(struct map_session_data* sd, int index, int amount)
nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0xf6));
- WFIFOW(fd,0)=0xf6; // Storage item removed
- WFIFOW(fd,2)=index+1;
- WFIFOL(fd,4)=amount;
- WFIFOSET(fd,packet_len(0xf6));
+ fd = sd->fd;
+
+ WFIFOHEAD(fd, packet_len(0xf6));
+ WFIFOW(fd, 0) = 0xf6; // Storage item removed
+ WFIFOW(fd, 2) = index + 1;
+ WFIFOL(fd, 4) = amount;
+ WFIFOSET(fd, packet_len(0xf6));
}
/// Closes storage (ZC_CLOSE_STORE).
@@ -8431,9 +8432,11 @@ 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) {
- storage->sortitem(sd->status.storage.items, ARRAYLENGTH(sd->status.storage.items));
- clif->storagelist(sd, sd->status.storage.items, ARRAYLENGTH(sd->status.storage.items));
- clif->updatestorageamount(sd, sd->status.storage.storage_amount, MAX_STORAGE);
+ 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);
}
// Notify the client that the gstorage is open otherwise it will
// remain locked forever and nobody will be able to access it
@@ -9340,7 +9343,7 @@ void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) {
sd->state.warping = 0;
sd->state.dialog = 0;/* reset when warping, client dialog will go missing */
- // look
+ // Character Looks
#if PACKETVER < 4
clif->changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
clif->changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
@@ -9350,21 +9353,26 @@ void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) {
if(sd->vd.cloth_color)
clif->refreshlook(&sd->bl,sd->bl.id,LOOK_CLOTHES_COLOR,sd->vd.cloth_color,SELF);
+
if (sd->vd.body_style)
clif->refreshlook(&sd->bl,sd->bl.id,LOOK_BODY2,sd->vd.body_style,SELF);
- // item
- clif->inventorylist(sd); // inventory list first, otherwise deleted items in pc->checkitem show up as 'unknown item'
- pc->checkitem(sd);
- // cart
+ // Send character inventory to the client.
+ // call this before pc->checkitem() so that the client isn't called to delete a non-existent item.
+ clif->inventorylist(sd);
+
+ // Send the cart inventory, counts & weight to the client.
if(pc_iscarton(sd)) {
clif->cartlist(sd);
- clif->updatestatus(sd,SP_CARTINFO);
+ clif->updatestatus(sd, SP_CARTINFO);
}
- // weight
- clif->updatestatus(sd,SP_WEIGHT);
- clif->updatestatus(sd,SP_MAXWEIGHT);
+ // Check for and delete unavailable/disabled items.
+ pc->checkitem(sd);
+
+ // Send the character's weight to the client.
+ clif->updatestatus(sd, SP_WEIGHT);
+ clif->updatestatus(sd, SP_MAXWEIGHT);
// guild
// (needs to go before clif_spawn() to show guild emblems correctly)
diff --git a/src/map/intif.c b/src/map/intif.c
index 10a9ea8a9..61d2e3633 100644
--- a/src/map/intif.c
+++ b/src/map/intif.c
@@ -439,6 +439,135 @@ int intif_request_registry(struct map_session_data *sd, int flag)
return 0;
}
+//=================================================================
+// Account Storage
+//-----------------------------------------------------------------
+
+/**
+ * Request the inter-server for a character's storage data.
+ * @packet 0x3010 [out] <account_id>.L
+ * @param sd [in] pointer to session data.
+ */
+void intif_request_account_storage(const struct map_session_data *sd)
+{
+ nullpo_retv(sd);
+
+ /* Check for character server availability */
+ if (intif->CheckForCharServer())
+ return;
+
+ WFIFOHEAD(inter_fd, 6);
+ WFIFOW(inter_fd, 0) = 0x3010;
+ WFIFOL(inter_fd, 2) = sd->status.account_id;
+ WFIFOSET(inter_fd, 6);
+}
+
+/**
+ * Parse the reception of account storage from the inter-server.
+ * @packet 0x3805 [in] <packet_len>.W <account_id>.L <struct item[]>.P
+ * @param fd [in] file/socket descriptor.
+ */
+void intif_parse_account_storage(int fd)
+{
+ int account_id = 0, payload_size = 0, storage_count = 0;
+ int i = 0;
+ struct map_session_data *sd = NULL;
+
+ Assert_retv(fd > 0);
+
+ payload_size = RFIFOW(fd, 2) - 8;
+
+ 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) {
+ 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);
+
+ sd->storage.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);
+ }
+
+ sd->storage.received = true; // Mark the storage state as received.
+ sd->storage.save = false; // Initialize the save flag as false.
+
+ pc->checkitem(sd); // re-check remaining items.
+}
+
+/**
+ * Send account storage information for saving.
+ * @packet 0x3011 [out] <packet_len>.W <account_id>.L <struct item[]>.P
+ * @param sd [in] pointer to session data.
+ */
+void intif_send_account_storage(const struct map_session_data *sd)
+{
+ int len = 0, i = 0, c = 0;
+
+ nullpo_retv(sd);
+
+ // Assert that at this point in the code, both flags are true.
+ Assert_retv(sd->storage.save == true);
+ Assert_retv(sd->storage.received == true);
+
+ if (intif->CheckForCharServer())
+ return;
+
+ len = 8 + sd->storage.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)
+ continue;
+ memcpy(WFIFOP(inter_fd, 8 + c * sizeof(struct item)), &VECTOR_INDEX(sd->storage.item, i), sizeof(struct item));
+ c++;
+ }
+
+ WFIFOSET(inter_fd, len);
+}
+
+/**
+ * Parse acknowledgement packet for the saving of an account's storage.
+ * @packet 0x3808 [in] <account_id>.L <saved_flag>.B
+ * @param fd [in] file/socket descriptor.
+ */
+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;
+
+ Assert_retv(account_id > 0);
+ Assert_retv(fd > 0);
+
+ 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);
+ return;
+ }
+
+ sd->storage.save = false; // Storage has been saved.
+}
+
+//=================================================================
+// Guild Storage
+//-----------------------------------------------------------------
+
int intif_request_guild_storage(int account_id,int guild_id)
{
if (intif->CheckForCharServer())
@@ -2306,8 +2435,10 @@ int intif_parse(int fd)
case 0x3802: intif->pWisEnd(fd); break;
case 0x3803: intif->pWisToGM(fd); break;
case 0x3804: intif->pRegisters(fd); break;
+ case 0x3805: intif->pAccountStorage(fd); break;
case 0x3806: intif->pChangeNameOk(fd); break;
case 0x3807: intif->pMessageToFD(fd); break;
+ case 0x3808: intif->pAccountStorageSaveAck(fd); break;
case 0x3818: intif->pLoadGuildStorage(fd); break;
case 0x3819: intif->pSaveGuildStorage(fd); break;
case 0x3820: intif->pPartyCreated(fd); break;
@@ -2394,7 +2525,7 @@ int intif_parse(int fd)
*-------------------------------------*/
void intif_defaults(void) {
const int packet_len_table [INTIF_PACKET_LEN_TABLE_SIZE] = {
- -1,-1,27,-1, -1, 0,37,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3800-0x380f
+ -1,-1,27,-1, -1,-1,37,-1, 7, 0, 0, 0, 0, 0, 0, 0, //0x3800-0x380f
0, 0, 0, 0, 0, 0, 0, 0, -1,11, 0, 0, 0, 0, 0, 0, //0x3810
39,-1,15,15, 14,19, 7,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3820
10,-1,15, 0, 79,19, 7,-1, 0,-1,-1,-1, 14,67,186,-1, //0x3830
@@ -2421,6 +2552,8 @@ void intif_defaults(void) {
intif->wis_message_to_gm = intif_wis_message_to_gm;
intif->saveregistry = intif_saveregistry;
intif->request_registry = intif_request_registry;
+ intif->request_account_storage = intif_request_account_storage;
+ intif->send_account_storage = intif_send_account_storage;
intif->request_guild_storage = intif_request_guild_storage;
intif->send_guild_storage = intif_send_guild_storage;
intif->create_party = intif_create_party;
@@ -2497,6 +2630,8 @@ void intif_defaults(void) {
intif->pRegisters = intif_parse_Registers;
intif->pChangeNameOk = intif_parse_ChangeNameOk;
intif->pMessageToFD = intif_parse_MessageToFD;
+ intif->pAccountStorage = intif_parse_account_storage;
+ intif->pAccountStorageSaveAck = intif_parse_account_storage_save_ack;
intif->pLoadGuildStorage = intif_parse_LoadGuildStorage;
intif->pSaveGuildStorage = intif_parse_SaveGuildStorage;
intif->pPartyCreated = intif_parse_PartyCreated;
diff --git a/src/map/intif.h b/src/map/intif.h
index b20acf029..3d6a52440 100644
--- a/src/map/intif.h
+++ b/src/map/intif.h
@@ -66,6 +66,8 @@ struct intif_interface {
int (*wis_message_to_gm) (char *Wisp_name, int permission, char *mes);
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) (const struct map_session_data *sd);
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);
@@ -139,8 +141,10 @@ struct intif_interface {
int (*pWisToGM_sub) (struct map_session_data* sd,va_list va);
void (*pWisToGM) (int fd);
void (*pRegisters) (int fd);
+ void (*pAccountStorage) (int fd);
void (*pChangeNameOk) (int fd);
void (*pMessageToFD) (int fd);
+ void (*pAccountStorageSaveAck) (int fd);
void (*pLoadGuildStorage) (int fd);
void (*pSaveGuildStorage) (int fd);
void (*pPartyCreated) (int fd);
diff --git a/src/map/itemdb.c b/src/map/itemdb.c
index 4076e295c..9a43bae14 100644
--- a/src/map/itemdb.c
+++ b/src/map/itemdb.c
@@ -2490,16 +2490,20 @@ void itemdb_reload(void) {
for (sd = BL_UCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); sd = BL_UCAST(BL_PC, mapit->next(iter))) {
memset(sd->item_delay, 0, sizeof(sd->item_delay)); // reset item delays
pc->setinventorydata(sd);
- if( battle_config.item_check )
- sd->state.itemcheck = 1;
+
+ if (battle->bc->item_check != PCCHECKITEM_NONE) // Check and flag items for inspection.
+ sd->itemcheck = (enum pc_checkitem_types) battle->bc->item_check;
+
/* clear combo bonuses */
- if( sd->combo_count ) {
+ if (sd->combo_count) {
aFree(sd->combos);
sd->combos = NULL;
sd->combo_count = 0;
if( pc->load_combo(sd) > 0 )
status_calc_pc(sd,SCO_FORCE);
}
+
+ // Check for and delete unavailable/disabled items.
pc->checkitem(sd);
}
mapit->free(iter);
diff --git a/src/map/packets.h b/src/map/packets.h
index d1875f2f0..0a774561d 100644
--- a/src/map/packets.h
+++ b/src/map/packets.h
@@ -5711,6 +5711,40 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x0ab3,19);
#endif
+// 2017-01-25aRagexeRE
+#if PACKETVER == 20170125
+// shuffle packets
+ packet(0x0438,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0811,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x086e,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0876,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0877,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0879,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x087b,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x087d,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0881,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x0884,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0893,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x0894,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0895,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x0898,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x089b,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x08a5,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x091b,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x091c,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x091d,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0920,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0929,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x092b,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x0930,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x093c,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0943,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0944,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x095c,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0965,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+ packet(0x0968,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+#endif
+
// 2017-02-01aRagexeRE
#if PACKETVER >= 20170201
// new packets
@@ -5718,6 +5752,40 @@ packet(0x96e,-1,clif->ackmergeitems);
// changed packet sizes
#endif
+// 2017-02-08aRagexeRE
+#if PACKETVER == 20170208
+// shuffle packets
+ packet(0x02c4,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x035f,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0360,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0367,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x0368,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0369,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0437,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x0811,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0817,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0835,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x083c,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x085c,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0860,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x087a,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x088c,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x0892,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x08a1,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x08ac,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x0921,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0923,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x092d,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0932,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0937,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x096a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+#endif
+
// 2017-02-15aRagexeRE
#if PACKETVER >= 20170215
// new packets
@@ -5734,6 +5802,40 @@ packet(0x96e,-1,clif->ackmergeitems);
#endif
// 2017-02-28aRagexeRE
+#if PACKETVER == 20170228
+// shuffle packets
+ packet(0x022d,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0360,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0362,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0819,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x085e,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0863,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x086b,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x0873,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x0874,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0876,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0883,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0884,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0889,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x0893,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+ packet(0x089e,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x08a0,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x08a2,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x08a6,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x08a7,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x091f,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x092a,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x092e,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0937,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x093e,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0944,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0947,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0948,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0952,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x0955,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+#endif
+
+// 2017-02-28aRagexeRE
#if PACKETVER >= 20170228
// new packets
packet(0x0ac0,26);
@@ -5750,6 +5852,40 @@ packet(0x96e,-1,clif->ackmergeitems);
#endif
// 2017-03-08bRagexeRE
+#if PACKETVER == 20170308
+// shuffle packets
+ packet(0x0202,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x022d,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x023b,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0281,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x035f,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0360,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0361,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0362,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0363,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0364,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0365,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0368,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0369,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0436,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0437,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x07e4,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x07ec,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x0802,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0811,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0817,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0835,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x083c,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x087d,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x096a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+#endif
+
+// 2017-03-08bRagexeRE
#if PACKETVER >= 20170308
// new packets
packet(0x0ac8,2);
@@ -5757,6 +5893,74 @@ packet(0x96e,-1,clif->ackmergeitems);
// changed packet sizes
#endif
+// 2017-03-15cRagexeRE
+#if PACKETVER == 20170315
+// shuffle packets
+ packet(0x02c4,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x035f,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0360,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x0366,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x0367,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0436,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x07ec,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x085c,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0863,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x086a,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0872,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x087b,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0884,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x088b,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x088d,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x088f,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0892,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x089c,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x08aa,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x091a,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x091b,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x091d,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x0920,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0922,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x0944,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+ packet(0x094a,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x094e,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x0950,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0952,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+#endif
+
+// 2017-03-22aRagexeRE
+#if PACKETVER == 20170322
+// shuffle packets
+ packet(0x0202,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x022d,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x023b,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0281,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x035f,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0360,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0361,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0362,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0363,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0364,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0365,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0368,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0369,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0436,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0437,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x07e4,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x07ec,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x0802,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0811,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0817,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0835,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x083c,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x091a,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x096a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+#endif
+
// 2017-03-22aRagexeRE
#if PACKETVER >= 20170322
// new packets
@@ -5764,6 +5968,40 @@ packet(0x96e,-1,clif->ackmergeitems);
// changed packet sizes
#endif
+// 2017-03-29dRagexeRE
+#if PACKETVER == 20170329
+// shuffle packets
+ packet(0x0281,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x035f,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0360,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0362,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0363,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0368,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0369,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0437,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x0811,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0817,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0835,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x083c,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x085d,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x087a,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0888,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x08a8,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0917,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0926,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x0929,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x092e,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x0937,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x0939,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0949,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x095f,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x096a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+#endif
+
// 2017-03-29cRagexeRE
#if PACKETVER >= 20170329
// new packets
@@ -5772,6 +6010,40 @@ packet(0x96e,-1,clif->ackmergeitems);
#endif
// 2017-04-05bRagexeRE
+#if PACKETVER == 20170405
+// shuffle packets
+ packet(0x022d,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0281,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x035f,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0360,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0362,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0363,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0368,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0369,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x0437,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x0811,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0817,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0835,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x083c,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x085f,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x0860,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x0864,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0865,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x086f,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0893,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x08a5,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x094c,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x094f,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0964,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x096a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+#endif
+
+// 2017-04-05bRagexeRE
#if PACKETVER >= 20170405
// new packets
packet(0x0acb,12);
@@ -5787,6 +6059,55 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x0a99,4);
#endif
+// 2017-04-26dRagexeRE
+#if PACKETVER >= 20170426
+// new packets
+// changed packet sizes
+ packet(0x0a98,10);
+#endif
+
+// 2017-05-02dRagexeRE
+#if PACKETVER >= 20170502
+// new packets
+ packet(0x0ace,4);
+// changed packet sizes
+#endif
+
+// 2017-05-17aRagexeRE
+#if PACKETVER == 20170517
+// shuffle packets
+ packet(0x0364,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0367,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0437,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0802,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0815,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x0817,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x0868,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0875,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x087b,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x087d,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x088c,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x088d,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x0894,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+ packet(0x0896,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x0899,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x089e,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x089f,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x08a2,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x08a8,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x08aa,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x091b,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0923,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x093b,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0945,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x0946,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0947,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x0958,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0960,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0964,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+#endif
+
+
/* PacketKeys: http://herc.ws/board/topic/1105-hercules-wpe-free-june-14th-patch/ */
#if PACKETVER >= 20110817
packetKeys(0x053D5CED,0x3DED6DED,0x6DED6DED); /* Thanks to Shakto */
@@ -6240,6 +6561,41 @@ packet(0x96e,-1,clif->ackmergeitems);
packetKeys(0x69CB4F56,0x793C165E,0x673A2354); /* 4144 */
#endif
+#if PACKETVER == 20170125
+ packetKeys(0x066E04FE,0x3004224A,0x04FF0458); /* 4144 */
+#endif
+
+#if PACKETVER == 20170208
+ packetKeys(0x6A764E5F,0x0609570D,0x28AE07FA); /* 4144 */
+#endif
+
+#if PACKETVER == 20170228
+ packetKeys(0x771D4F2B,0x20EF1F4C,0x0D5135C8); /* 4144 */
+#endif
+
+#if PACKETVER == 20170308
+ packetKeys(0x653470A9,0x6B316A71,0x5C712C71); /* 4144 */
+#endif
+
+#if PACKETVER == 20170315
+ packetKeys(0x399A0856,0x56642A94,0x7F77157D); /* 4144 */
+#endif
+
+#if PACKETVER == 20170322
+ packetKeys(0x2050167B,0x01731233,0x40337033); /* 4144 */
+#endif
+
+#if PACKETVER == 20170329
+ packetKeys(0x18B31A80,0x1B0B1D56,0x16857D6A); /* 4144 */
+#endif
+
+#if PACKETVER == 20170405
+ packetKeys(0x1FDE7DAC,0x2F9F5B63,0x3F2062AF); /* 4144 */
+#endif
+
+#if PACKETVER == 20170517
+ packetKeys(0x2CC4749A,0x1FA954DC,0x72276857); /* 4144 */
+#endif
#if defined(OBFUSCATIONKEY1) && defined(OBFUSCATIONKEY2) && defined(OBFUSCATIONKEY3)
packetKeys(OBFUSCATIONKEY1,OBFUSCATIONKEY2,OBFUSCATIONKEY3);
diff --git a/src/map/pc.c b/src/map/pc.c
index f40fba8ae..2303a83ca 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -1251,13 +1251,14 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
sd->bg_queue.type = 0;
VECTOR_INIT(sd->script_queues);
+ VECTOR_INIT(sd->storage.item); // initialize storage item vector.
sd->state.dialog = 0;
sd->delayed_damage = 0;
- if( battle_config.item_check )
- sd->state.itemcheck = 1;
+ if (battle->bc->item_check != PCCHECKITEM_NONE) // Check and flag items for inspection.
+ sd->itemcheck = (enum pc_checkitem_types) battle->bc->item_check;
// Event Timers
for( i = 0; i < MAX_EVENTTIMER; i++ )
@@ -1483,6 +1484,9 @@ int pc_reg_received(struct map_session_data *sd)
status_calc_pc(sd,SCO_FIRST|SCO_FORCE);
chrif->scdata_request(sd->status.account_id, sd->status.char_id);
+ // Storage Request
+ intif->request_account_storage(sd);
+
intif->Mail_requestinbox(sd->status.char_id, 0); // MAIL SYSTEM - Request Mail Inbox
intif->request_questlog(sd);
@@ -10166,99 +10170,108 @@ int pc_checkitem(struct map_session_data *sd)
nullpo_ret(sd);
- if (sd->state.vending) //Avoid reorganizing items when we are vending, as that leads to exploits (pointed out by End of Exam)
+ if (sd->state.vending == 1) // Avoid reorganizing items when we are vending, as that leads to exploits (pointed out by End of Exam)
return 0;
- if (sd->state.itemcheck) { // check for invalid(ated) items
- int id;
- for (i = 0; i < MAX_INVENTORY; i++) {
- id = sd->status.inventory[i].nameid;
+ if (sd->itemcheck != PCCHECKITEM_NONE) { // check for invalid(ated) items
+ int id = 0;
- if (!id)
- continue;
+ if (sd->itemcheck & PCCHECKITEM_INVENTORY) {
+ for (i = 0; i < MAX_INVENTORY; i++) {
+ if ((id = sd->status.inventory[i].nameid) == 0)
+ continue;
- if (!itemdb_available(id)) {
- ShowWarning("Removed invalid/disabled item id %d from inventory (amount=%d, char_id=%d).\n", id, sd->status.inventory[i].amount, sd->status.char_id);
- pc->delitem(sd, i, sd->status.inventory[i].amount, 0, DELITEM_NORMAL, LOG_TYPE_INV_INVALID);
- continue;
+ if (!itemdb_available(id)) {
+ ShowWarning("pc_checkitem: Removed invalid/disabled item id %d from inventory (amount=%d, char_id=%d).\n", id, sd->status.inventory[i].amount, sd->status.char_id);
+ pc->delitem(sd, i, sd->status.inventory[i].amount, 0, DELITEM_NORMAL, LOG_TYPE_INV_INVALID);
+ continue;
+ }
+
+ if (sd->status.inventory[i].unique_id == 0 && !itemdb->isstackable(id))
+ sd->status.inventory[i].unique_id = itemdb->unique_id(sd);
}
- if (!sd->status.inventory[i].unique_id && !itemdb->isstackable(id))
- sd->status.inventory[i].unique_id = itemdb->unique_id(sd);
+ sd->itemcheck &= ~PCCHECKITEM_INVENTORY;
}
- for( i = 0; i < MAX_CART; i++ ) {
- id = sd->status.cart[i].nameid;
+ if (sd->itemcheck & PCCHECKITEM_CART) {
+ for (i = 0; i < MAX_CART; i++) {
+ if ((id = sd->status.cart[i].nameid) == 0)
+ continue;
- if (!id)
- continue;
+ if( !itemdb_available(id) ) {
+ ShowWarning("pc_checkitem: Removed invalid/disabled item id %d from cart (amount=%d, char_id=%d).\n", id, sd->status.cart[i].amount, sd->status.char_id);
+ pc->cart_delitem(sd, i, sd->status.cart[i].amount, 0, LOG_TYPE_CART_INVALID);
+ continue;
+ }
- if( !itemdb_available(id) ) {
- ShowWarning("Removed invalid/disabled item id %d from cart (amount=%d, char_id=%d).\n", id, sd->status.cart[i].amount, sd->status.char_id);
- pc->cart_delitem(sd, i, sd->status.cart[i].amount, 0, LOG_TYPE_CART_INVALID);
- continue;
+ if (sd->status.cart[i].unique_id == 0 && !itemdb->isstackable(id))
+ sd->status.cart[i].unique_id = itemdb->unique_id(sd);
}
- if ( !sd->status.cart[i].unique_id && !itemdb->isstackable(id) )
- sd->status.cart[i].unique_id = itemdb->unique_id(sd);
+ sd->itemcheck &= ~PCCHECKITEM_CART;
}
- for( i = 0; i < MAX_STORAGE; i++ ) {
- id = sd->status.storage.items[i].nameid;
+ 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 (!id)
- continue;
+ if ((id = it->nameid) == 0)
+ continue;
- if( id && !itemdb_available(id) ) {
- ShowWarning("Removed invalid/disabled item id %d from storage (amount=%d, char_id=%d).\n", id, sd->status.storage.items[i].amount, sd->status.char_id);
- storage->delitem(sd, i, sd->status.storage.items[i].amount);
- storage->close(sd);
- continue;
+ 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 (it->unique_id == 0 && itemdb->isstackable(id) == 0)
+ it->unique_id = itemdb->unique_id(sd);
}
- if ( !sd->status.storage.items[i].unique_id && !itemdb->isstackable(id) )
- sd->status.storage.items[i].unique_id = itemdb->unique_id(sd);
+ storage->close(sd);
+
+ sd->itemcheck &= ~PCCHECKITEM_STORAGE;
}
- if (sd->guild) {
+ if (sd->guild && sd->itemcheck & PCCHECKITEM_GSTORAGE) {
struct guild_storage *guild_storage = idb_get(gstorage->db,sd->guild->guild_id);
if (guild_storage) {
- for( i = 0; i < MAX_GUILD_STORAGE; i++ ) {
- id = guild_storage->items[i].nameid;
-
- if (!id)
+ for (i = 0; i < MAX_GUILD_STORAGE; i++) {
+ if ((id = guild_storage->items[i].nameid) == 0)
continue;
- if( !itemdb_available(id) ) {
- ShowWarning("Removed invalid/disabled item id %d from guild storage (amount=%d, char_id=%d, guild_id=%d).\n", id, guild_storage->items[i].amount, sd->status.char_id, sd->guild->guild_id);
+ if (!itemdb_available(id)) {
+ ShowWarning("pc_checkitem: Removed invalid/disabled item id %d from guild storage (amount=%d, char_id=%d, guild_id=%d).\n", id, guild_storage->items[i].amount, sd->status.char_id, sd->guild->guild_id);
gstorage->delitem(sd, guild_storage, i, guild_storage->items[i].amount);
gstorage->close(sd); // force closing
continue;
}
- if (!guild_storage->items[i].unique_id && !itemdb->isstackable(id))
+ if (guild_storage->items[i].unique_id == 0 && !itemdb->isstackable(id))
guild_storage->items[i].unique_id = itemdb->unique_id(sd);
}
}
+
+ sd->itemcheck &= ~PCCHECKITEM_GSTORAGE;
}
- sd->state.itemcheck = 0;
}
- for( i = 0; i < MAX_INVENTORY; i++) {
+ for (i = 0; i < MAX_INVENTORY; i++) {
- if( sd->status.inventory[i].nameid == 0 )
+ if (sd->status.inventory[i].nameid == 0)
continue;
- if( !sd->status.inventory[i].equip )
+ if (sd->status.inventory[i].equip == 0)
continue;
- if( sd->status.inventory[i].equip&~pc->equippoint(sd,i) ) {
+ if (sd->status.inventory[i].equip & ~pc->equippoint(sd,i)) {
pc->unequipitem(sd, i, PCUNEQUIPITEM_FORCE);
calc_flag = 1;
continue;
}
- if (battle_config.unequip_restricted_equipment&1) {
+ if (battle_config.unequip_restricted_equipment & 1) {
int j;
for (j = 0; j < map->list[sd->bl.m].zone->disabled_items_count; j++) {
if (map->list[sd->bl.m].zone->disabled_items[j] == sd->status.inventory[i].nameid) {
@@ -10268,7 +10281,7 @@ int pc_checkitem(struct map_session_data *sd)
}
}
- if (battle_config.unequip_restricted_equipment&2) {
+ if (battle_config.unequip_restricted_equipment & 2) {
if (!itemdb_isspecial(sd->status.inventory[i].card[0])) {
int j, slot;
for (slot = 0; slot < MAX_SLOTS; slot++) {
@@ -10284,9 +10297,9 @@ int pc_checkitem(struct map_session_data *sd)
}
- if( calc_flag && sd->state.active ) {
+ if (calc_flag != 0 && sd->state.active == 1) {
pc->checkallowskill(sd);
- status_calc_pc(sd,SCO_NONE);
+ status_calc_pc(sd, SCO_NONE);
}
return 0;
diff --git a/src/map/pc.h b/src/map/pc.h
index 482e30c41..af52f8946 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -94,6 +94,14 @@ enum pc_resetskill_flag {
PCRESETSKILL_CHSEX = 0x4, // just reset the skills if the player class is a bard/dancer type (for changesex.)
};
+enum pc_checkitem_types {
+ PCCHECKITEM_NONE = 0x0,
+ PCCHECKITEM_INVENTORY = 0x1,
+ PCCHECKITEM_CART = 0x2,
+ PCCHECKITEM_STORAGE = 0x4,
+ PCCHECKITEM_GSTORAGE = 0x8
+};
+
struct weapon_data {
int atkmods[3];
BEGIN_ZEROED_BLOCK; // all the variables within this block get zero'ed in each call of status_calc_pc
@@ -225,7 +233,6 @@ struct map_session_data {
unsigned int hold_recalc : 1;
unsigned int snovice_call_flag : 3; //Summon Angel (stage 1~3)
unsigned int hpmeter_visible : 1;
- unsigned int itemcheck : 1;
unsigned int standalone : 1;/* [Ind/Hercules <3] */
unsigned int loggingout : 1;
unsigned int warp_clean : 1;
@@ -251,7 +258,9 @@ struct map_session_data {
unsigned int extra_temp_permissions; /* permissions from @addperm */
struct mmo_charstatus status;
- struct item_data* inventory_data[MAX_INVENTORY]; // direct pointers to itemdb entries (faster than doing item_id lookups)
+ struct item_data *inventory_data[MAX_INVENTORY]; // direct pointers to itemdb entries (faster than doing item_id lookups)
+ struct storage_data storage; ///< Account Storage
+ enum pc_checkitem_types itemcheck;
short equip_index[EQI_MAX];
unsigned int weight,max_weight;
int cart_weight,cart_num,cart_weight_max;
diff --git a/src/map/script.c b/src/map/script.c
index f90df31d8..91f1d8cc9 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -136,6 +136,7 @@ const char* script_op2name(int op) {
RETURN_OP_NAME(C_ADD);
RETURN_OP_NAME(C_SUB);
RETURN_OP_NAME(C_MUL);
+ RETURN_OP_NAME(C_POW);
RETURN_OP_NAME(C_DIV);
RETURN_OP_NAME(C_MOD);
RETURN_OP_NAME(C_NEG);
@@ -1035,6 +1036,7 @@ const char* parse_variable(const char* p)
|| ( p[0] == '|' && p[1] == '=' && (type = C_OR, true) ) // |=
|| ( p[0] == '&' && p[1] == '=' && (type = C_AND, true) ) // &=
|| ( p[0] == '*' && p[1] == '=' && (type = C_MUL, true) ) // *=
+ || ( p[0] == '*' && p[1] == '*' && p[2] == '=' && (type = C_POW, true) ) // **=
|| ( p[0] == '/' && p[1] == '=' && (type = C_DIV, true) ) // /=
|| ( p[0] == '%' && p[1] == '=' && (type = C_MOD, true) ) // %=
|| ( p[0] == '+' && p[1] == '+' && (type = C_ADD_POST, true) ) // post ++
@@ -1058,6 +1060,7 @@ const char* parse_variable(const char* p)
case C_L_SHIFT: // <<=
case C_R_SHIFT: // >>=
+ case C_POW: // **=
p = script->skip_space( &p[3] );
break;
@@ -1424,6 +1427,7 @@ const char* script_parse_subexpr(const char* p,int limit)
(op=C_OP3, opl=0, len=1,*p=='?') // ?:
|| (op=C_ADD, opl=9, len=1,*p=='+') // +
|| (op=C_SUB, opl=9, len=1,*p=='-') // -
+ || (op=C_POW, opl=11,len=2,*p=='*' && p[1]=='*') // **
|| (op=C_MUL, opl=10,len=1,*p=='*') // *
|| (op=C_DIV, opl=10,len=1,*p=='/') // /
|| (op=C_MOD, opl=10,len=1,*p=='%') // %
@@ -4146,6 +4150,7 @@ void op_2num(struct script_state* st, int op, int i1, int i2)
case C_ADD: ret = i1 + i2; ret64 = (int64)i1 + i2; break;
case C_SUB: ret = i1 - i2; ret64 = (int64)i1 - i2; break;
case C_MUL: ret = i1 * i2; ret64 = (int64)i1 * i2; break;
+ case C_POW: ret = (int)pow((double)i1, (double)i2); ret64 = (int64)pow((double)i1, (double)i2); break;
default:
ShowError("script:op_2num: unexpected number operator %s i1=%d i2=%d\n", script->op2name(op), i1, i2);
script->reportsrc(st);
@@ -4683,6 +4688,7 @@ void run_script_main(struct script_state *st) {
case C_ADD:
case C_SUB:
case C_MUL:
+ case C_POW:
case C_DIV:
case C_MOD:
case C_EQ:
@@ -7314,6 +7320,22 @@ int script_array_index_cmp(const void *a, const void *b)
return (*(const unsigned int *)a - *(const unsigned int *)b); // FIXME: Is the unsigned difference really intended here?
}
+BUILDIN(getarrayindex)
+{
+ struct script_data *data = script_getdata(st, 2);
+
+ if (!data_isreference(data) || reference_toconstant(data))
+ {
+ ShowError("script:getarrayindex: not a variable\n");
+ script->reportdata(data);
+ st->state = END;
+ return false;// not a variable
+ }
+
+ script_pushint(st, reference_getindex(data));
+ return true;
+}
+
/// Deletes count or all the elements in an array, from the starting index.
/// ex: deletearray arr[4],2;
///
@@ -8568,20 +8590,26 @@ BUILDIN(disableitemuse)
BUILDIN(readparam) {
int type;
struct map_session_data *sd;
+ struct script_data *data = script_getdata(st, 2);
- type=script_getnum(st,2);
- if (script_hasdata(st,3))
- sd = script->nick2sd(st, script_getstr(st,3));
- else
- sd=script->rid2sd(st);
+ if (reference_toparam(data)) {
+ type = reference_getparamtype(data);
+ } else {
+ type = script->conv_num(st, data);
+ }
+
+ if (script_hasdata(st, 3)) {
+ sd = script->nick2sd(st, script_getstr(st, 3));
+ } else {
+ sd = script->rid2sd(st);
+ }
if (sd == NULL) {
- script_pushint(st,-1);
+ script_pushint(st, -1);
return true;
}
- script_pushint(st,pc->readparam(sd,type));
-
+ script_pushint(st, pc->readparam(sd, type));
return true;
}
@@ -10436,9 +10464,17 @@ BUILDIN(openstorage)
{
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
- return true;
+ return false;
+
+ if (sd->storage.received == false) {
+ script_pushint(st, 0);
+ ShowWarning("buildin_openstorage: Storage data for AID %d has not been loaded.\n", sd->bl.id);
+ return false;
+ }
storage->open(sd);
+
+ script_pushint(st, 1); // success flag.
return true;
}
@@ -16136,6 +16172,26 @@ BUILDIN(charat) {
}
//=======================================================
+// isstr <argument>
+//
+// returns type:
+// 0 - int
+// 1 - string
+// 2 - other
+//-------------------------------------------------------
+BUILDIN(isstr)
+{
+ if (script_isinttype(st, 2)) {
+ script_pushint(st, 0);
+ } else if (script_isstringtype(st, 2)) {
+ script_pushint(st, 1);
+ } else {
+ script_pushint(st, 2);
+ }
+ return true;
+}
+
+//=======================================================
// chr <int>
//-------------------------------------------------------
BUILDIN(chr)
@@ -21503,6 +21559,43 @@ BUILDIN(issit)
return true;
}
+BUILDIN(add_group_command)
+{
+ AtCommandInfo *acmd_d;
+ struct atcmd_binding_data *bcmd_d;
+ GroupSettings *group;
+ int group_index;
+ const char *atcmd = script_getstr(st, 2);
+ int group_id = script_getnum(st, 3);
+ bool self_perm = (script_getnum(st, 4) == 1);
+ bool char_perm = (script_getnum(st, 5) == 1);
+
+ if (!pcg->exists(group_id)) {
+ ShowWarning("script:add_group_command: group does not exist: %i\n", group_id);
+ script_pushint(st, 0);
+ return false;
+ }
+
+ group = pcg->id2group(group_id);
+ group_index = pcg->get_idx(group);
+
+ if ((bcmd_d = atcommand->get_bind_byname(atcmd)) != NULL) {
+ bcmd_d->at_groups[group_index] = self_perm;
+ bcmd_d->char_groups[group_index] = char_perm;
+ script_pushint(st, 1);
+ return true;
+ } else if ((acmd_d = atcommand->get_info_byname(atcmd)) != NULL) {
+ acmd_d->at_groups[group_index] = self_perm;
+ acmd_d->char_groups[group_index] = char_perm;
+ script_pushint(st, 1);
+ return true;
+ }
+
+ ShowWarning("script:add_group_command: command does not exist: %s\n", atcmd);
+ script_pushint(st, 0);
+ return false;
+}
+
/**
* @commands (script based)
**/
@@ -21552,6 +21645,8 @@ BUILDIN(bindatcmd)
atcommand->binding[i]->group_lv = group_lv;
atcommand->binding[i]->group_lv_char = group_lv_char;
atcommand->binding[i]->log = log;
+ CREATE(atcommand->binding[i]->at_groups, char, db_size(pcg->db));
+ CREATE(atcommand->binding[i]->char_groups, char, db_size(pcg->db));
}
return true;
@@ -23281,6 +23376,7 @@ void script_parse_builtin(void) {
BUILDIN_DEF(cleararray,"rvi"),
BUILDIN_DEF(copyarray,"rri"),
BUILDIN_DEF(getarraysize,"r"),
+ BUILDIN_DEF(getarrayindex,"r"),
BUILDIN_DEF(deletearray,"r?"),
BUILDIN_DEF(getelementofarray,"ri"),
BUILDIN_DEF(getitem,"vi?"),
@@ -23533,6 +23629,7 @@ void script_parse_builtin(void) {
BUILDIN_DEF(getstrlen,"s"), //strlen [Valaris]
BUILDIN_DEF(charisalpha,"si"), //isalpha [Valaris]
BUILDIN_DEF(charat,"si"),
+ BUILDIN_DEF(isstr,"v"),
BUILDIN_DEF(chr,"i"),
BUILDIN_DEF(ord,"s"),
BUILDIN_DEF(setchar,"ssi"),
@@ -23563,7 +23660,7 @@ void script_parse_builtin(void) {
// List of mathematics commands --->
BUILDIN_DEF(log10,"i"),
BUILDIN_DEF(sqrt,"i"), //[zBuffer]
- BUILDIN_DEF(pow,"ii"), //[zBuffer]
+ BUILDIN_DEF_DEPRECATED(pow,"ii"), //[zBuffer]
BUILDIN_DEF(distance,"iiii"), //[zBuffer]
// <--- List of mathematics commands
BUILDIN_DEF(min, "i*"),
@@ -23723,6 +23820,7 @@ void script_parse_builtin(void) {
BUILDIN_DEF(useatcmd, "s"),
BUILDIN_DEF(has_permission, "v?"),
BUILDIN_DEF(can_use_command, "s?"),
+ BUILDIN_DEF(add_group_command, "siii"),
/**
* Item bound [Xantara] [Akinari] [Mhalicot/Hercules]
diff --git a/src/map/script.h b/src/map/script.h
index 8caec961a..fddcf4908 100644
--- a/src/map/script.h
+++ b/src/map/script.h
@@ -235,6 +235,7 @@ typedef enum c_op {
C_SUB_PRE, // --a
C_RE_EQ, // ~=
C_RE_NE, // ~!
+ C_POW, // **
} c_op;
/// Script queue options
diff --git a/src/map/storage.c b/src/map/storage.c
index aacc7c053..01e7c7c27 100644
--- a/src/map/storage.c
+++ b/src/map/storage.c
@@ -107,6 +107,11 @@ int storage_storageopen(struct map_session_data *sd)
if (sd->state.storage_flag != STORAGE_FLAG_CLOSED)
return 1; //Already open?
+ if (sd->storage.received == false) {
+ clif->message(sd->fd, msg_sd(sd, 27)); // Storage has not been loaded yet.
+ return 1;
+ }
+
if( !pc_can_give_items(sd) ) {
//check is this GM level is allowed to put items to storage
clif->message(sd->fd, msg_sd(sd,246)); // Your GM level doesn't authorize you to perform this action.
@@ -114,9 +119,13 @@ int storage_storageopen(struct map_session_data *sd)
}
sd->state.storage_flag = STORAGE_FLAG_NORMAL;
- storage->sortitem(sd->status.storage.items, ARRAYLENGTH(sd->status.storage.items));
- clif->storagelist(sd, sd->status.storage.items, ARRAYLENGTH(sd->status.storage.items));
- clif->updatestorageamount(sd, sd->status.storage.storage_amount, MAX_STORAGE);
+
+ 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);
return 0;
}
@@ -148,61 +157,80 @@ int compare_item(struct item *a, struct item *b)
*------------------------------------------*/
int storage_additem(struct map_session_data* sd, struct item* item_data, int amount)
{
- struct storage_data* stor;
- struct item_data *data;
+ 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, item_data);
- stor = &sd->status.storage;
- if( item_data->nameid <= 0 || amount <= 0 )
- return 1;
+ Assert_retr(1, item_data->nameid > 0);
+
+ Assert_retr(1, amount > 0);
data = itemdb->search(item_data->nameid);
- if( data->stack.storage && amount > data->stack.amount )
- {// item stack limitation
+ if (data->stack.storage && amount > data->stack.amount) // item stack limitation
return 1;
- }
if (!itemdb_canstore(item_data, pc_get_group_level(sd))) {
//Check if item is storable. [Skotlex]
- clif->message (sd->fd, msg_sd(sd,264)); // This item cannot be stored.
+ clif->message (sd->fd, msg_sd(sd, 264)); // This item cannot be stored.
return 1;
}
- if( item_data->bound > IBT_ACCOUNT && !pc_can_give_bound_items(sd) ) {
- clif->message(sd->fd, msg_sd(sd,294)); // This bound item cannot be stored there.
+ if (item_data->bound > IBT_ACCOUNT && !pc_can_give_bound_items(sd)) {
+ clif->message(sd->fd, msg_sd(sd, 294)); // This bound item cannot be stored there.
return 1;
}
- if( itemdb->isstackable2(data) )
- {//Stackable
- for( i = 0; i < MAX_STORAGE; i++ )
- {
- if( compare_item(&stor->items[i], item_data) )
- {// existing items found, stack them
- if( amount > MAX_AMOUNT - stor->items[i].amount || ( data->stack.storage && amount > data->stack.amount - stor->items[i].amount ) )
+ if (itemdb->isstackable2(data)) {//Stackable
+ for (i = 0; i < VECTOR_LENGTH(sd->storage.item); i++) {
+ it = &VECTOR_INDEX(sd->storage.item, i);
+
+ if (it->nameid == 0)
+ continue;
+
+ if (compare_item(it, item_data)) { // existing items found, stack them
+ if (amount > MAX_AMOUNT - it->amount || (data->stack.storage && amount > data->stack.amount - it->amount))
return 1;
- stor->items[i].amount += amount;
- clif->storageitemadded(sd,&stor->items[i],i,amount);
+ it->amount += amount;
+
+ clif->storageitemadded(sd, it, i, amount);
+
+ sd->storage.save = true; // set a save flag.
+
return 0;
}
}
}
- // find free slot
- ARR_FIND( 0, MAX_STORAGE, i, stor->items[i].nameid == 0 );
- if( i >= MAX_STORAGE )
+ // Check if storage exceeds limit.
+ if (sd->storage.aggregate >= MAX_STORAGE)
return 1;
- // add item to slot
- memcpy(&stor->items[i],item_data,sizeof(stor->items[0]));
- stor->storage_amount++;
- stor->items[i].amount = amount;
- clif->storageitemadded(sd,&stor->items[i],i,amount);
- clif->updatestorageamount(sd, stor->storage_amount, MAX_STORAGE);
+ ARR_FIND(0, VECTOR_LENGTH(sd->storage.item), i, VECTOR_INDEX(sd->storage.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);
+ } else {
+ it = &VECTOR_INDEX(sd->storage.item, i);
+ *it = *item_data;
+ }
+
+ it->amount = amount;
+
+ sd->storage.aggregate++;
+
+ clif->storageitemadded(sd, it, i, amount);
+
+ clif->updatestorageamount(sd, sd->storage.aggregate, MAX_STORAGE);
+
+ sd->storage.save = true; // set a save flag.
return 0;
}
@@ -212,21 +240,32 @@ int storage_additem(struct map_session_data* sd, struct item* item_data, int amo
*------------------------------------------*/
int storage_delitem(struct map_session_data* sd, int n, int amount)
{
+ struct item *it = NULL;
+
nullpo_retr(1, sd);
- Assert_retr(1, n >= 0 && n < MAX_STORAGE);
- if( sd->status.storage.items[n].nameid == 0 || sd->status.storage.items[n].amount < amount )
- return 1;
- sd->status.storage.items[n].amount -= amount;
- if( sd->status.storage.items[n].amount == 0 )
- {
- memset(&sd->status.storage.items[n],0,sizeof(sd->status.storage.items[0]));
- sd->status.storage.storage_amount--;
- if( sd->state.storage_flag == STORAGE_FLAG_NORMAL )
- clif->updatestorageamount(sd, sd->status.storage.storage_amount, MAX_STORAGE);
+ Assert_retr(1, sd->storage.received == true);
+
+ Assert_retr(1, n >= 0 && n < VECTOR_LENGTH(sd->storage.item));
+
+ it = &VECTOR_INDEX(sd->storage.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);
}
- if( sd->state.storage_flag == STORAGE_FLAG_NORMAL )
- clif->storageitemremoved(sd,n,amount);
+
+ sd->storage.save = true;
+
+ if (sd->state.storage_flag == STORAGE_FLAG_NORMAL)
+ clif->storageitemremoved(sd, n, amount);
+
return 0;
}
@@ -237,23 +276,25 @@ int storage_delitem(struct map_session_data* sd, int n, int amount)
* 0 : fail
* 1 : success
*------------------------------------------*/
-int storage_storageadd(struct map_session_data* sd, int index, int amount)
+int storage_add_from_inventory(struct map_session_data* sd, int index, int amount)
{
nullpo_ret(sd);
- if( sd->status.storage.storage_amount > MAX_STORAGE )
+ Assert_ret(sd->storage.received == true);
+
+ if (sd->storage.aggregate > MAX_STORAGE)
return 0; // storage full
- if( index < 0 || index >= MAX_INVENTORY )
+ if (index < 0 || index >= MAX_INVENTORY)
return 0;
- if( sd->status.inventory[index].nameid <= 0 )
+ if (sd->status.inventory[index].nameid <= 0)
return 0; // No item on that spot
- if( amount < 1 || amount > sd->status.inventory[index].amount )
+ 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, &sd->status.inventory[index], amount) == 0)
pc->delitem(sd, index, amount, 0, DELITEM_TOSTORAGE, LOG_TYPE_STORAGE);
else
clif->dropitem(sd, index, 0);
@@ -268,24 +309,30 @@ int storage_storageadd(struct map_session_data* sd, int index, int amount)
* 0 : fail
* 1 : success
*------------------------------------------*/
-int storage_storageget(struct map_session_data* sd, int index, int amount)
+int storage_add_to_inventory(struct map_session_data* sd, int index, int amount)
{
int flag;
+ struct item *it = NULL;
nullpo_ret(sd);
- if( index < 0 || index >= MAX_STORAGE )
+
+ Assert_ret(sd->storage.received == true);
+
+ if (index < 0 || index >= VECTOR_LENGTH(sd->storage.item))
return 0;
- if( sd->status.storage.items[index].nameid <= 0 )
+ it = &VECTOR_INDEX(sd->storage.item, index);
+
+ if (it->nameid <= 0)
return 0; //Nothing there
- if( amount < 1 || amount > sd->status.storage.items[index].amount )
+ if (amount < 1 || amount > it->amount)
return 0;
- if( (flag = pc->additem(sd,&sd->status.storage.items[index],amount,LOG_TYPE_STORAGE)) == 0 )
- storage->delitem(sd,index,amount);
+ if ((flag = pc->additem(sd, it, amount, LOG_TYPE_STORAGE)) == 0)
+ storage->delitem(sd, index, amount);
else
- clif->additem(sd,0,0,flag);
+ clif->additem(sd, 0, 0, flag);
return 1;
}
@@ -301,19 +348,21 @@ int storage_storageaddfromcart(struct map_session_data* sd, int index, int amoun
{
nullpo_ret(sd);
- if( sd->status.storage.storage_amount > MAX_STORAGE )
+ Assert_ret(sd->storage.received == true);
+
+ if (sd->storage.aggregate > MAX_STORAGE)
return 0; // storage full / storage closed
- if( index < 0 || index >= MAX_CART )
+ if (index < 0 || index >= MAX_CART)
return 0;
if( sd->status.cart[index].nameid <= 0 )
return 0; //No item there.
- if( amount < 1 || amount > sd->status.cart[index].amount )
+ if (amount < 1 || amount > sd->status.cart[index].amount)
return 0;
- if( storage->additem(sd,&sd->status.cart[index],amount) == 0 )
+ if (storage->additem(sd,&sd->status.cart[index],amount) == 0)
pc->cart_delitem(sd,index,amount,0,LOG_TYPE_STORAGE);
return 1;
@@ -329,22 +378,28 @@ int storage_storageaddfromcart(struct map_session_data* sd, int index, int amoun
int storage_storagegettocart(struct map_session_data* sd, int index, int amount)
{
int flag = 0;
+ struct item *it = NULL;
+
nullpo_ret(sd);
- if( index < 0 || index >= MAX_STORAGE )
+ Assert_ret(sd->storage.received == true);
+
+ if (index < 0 || index >= VECTOR_LENGTH(sd->storage.item))
return 0;
- if( sd->status.storage.items[index].nameid <= 0 )
+ it = &VECTOR_INDEX(sd->storage.item, index);
+
+ if (it->nameid <= 0)
return 0; //Nothing there.
- if( amount < 1 || amount > sd->status.storage.items[index].amount )
+ if (amount < 1 || amount > it->amount)
return 0;
- if( (flag = pc->cart_additem(sd,&sd->status.storage.items[index],amount,LOG_TYPE_STORAGE)) == 0 )
- storage->delitem(sd,index,amount);
+ if ((flag = pc->cart_additem(sd, it, amount, LOG_TYPE_STORAGE)) == 0)
+ storage->delitem(sd, index, amount);
else {
clif->dropitem(sd, index,0);
- clif->cart_additem_ack(sd,flag == 1?0x0:0x1);
+ clif->cart_additem_ack(sd, flag == 1?0x0:0x1);
}
return 1;
@@ -356,12 +411,26 @@ int storage_storagegettocart(struct map_session_data* sd, int index, int amount)
*------------------------------------------*/
void storage_storageclose(struct map_session_data* sd)
{
+ int i = 0;
+
nullpo_retv(sd);
+ Assert_retv(sd->storage.received == true);
+
clif->storageclose(sd);
- if( map->save_settings&4 )
- chrif->save(sd,0); //Invokes the storage saving as well.
+ if (map->save_settings & 4)
+ chrif->save(sd, 0); //Invokes the storage saving as well.
+
+ /* 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);
+ } else {
+ i++;
+ }
+ }
sd->state.storage_flag = STORAGE_FLAG_CLOSED;
}
@@ -791,8 +860,8 @@ void storage_defaults(void)
/* */
storage->delitem = storage_delitem;
storage->open = storage_storageopen;
- storage->add = storage_storageadd;
- storage->get = storage_storageget;
+ storage->add = storage_add_from_inventory;
+ storage->get = storage_add_to_inventory;
storage->additem = storage_additem;
storage->addfromcart = storage_storageaddfromcart;
storage->gettocart = storage_storagegettocart;
diff --git a/src/map/unit.c b/src/map/unit.c
index 79abb8c6a..00c78054b 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -2757,6 +2757,8 @@ int unit_free(struct block_list *bl, clr_type clrtype)
sd->instance = NULL;
}
VECTOR_CLEAR(sd->script_queues);
+ VECTOR_CLEAR(sd->storage.item);
+ sd->storage.received = false;
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 d0cdc14c1..847edbbd8 100644
--- a/src/plugins/HPMHooking/HPMHooking.Defs.inc
+++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc
@@ -2962,8 +2962,8 @@ typedef int (*HPMHOOK_pre_inter_quest_parse_frommap) (int *fd);
typedef int (*HPMHOOK_post_inter_quest_parse_frommap) (int retVal___, int fd);
#endif // CHAR_INT_QUEST_H
#ifdef CHAR_INT_STORAGE_H /* inter_storage */
-typedef int (*HPMHOOK_pre_inter_storage_tosql) (int *account_id, struct storage_data **p);
-typedef int (*HPMHOOK_post_inter_storage_tosql) (int retVal___, int account_id, struct storage_data *p);
+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_guild_storage_tosql) (int *guild_id, const struct guild_storage **p);
@@ -3000,6 +3000,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) (const struct map_session_data **sd);
+typedef void (*HPMHOOK_post_intif_send_account_storage) (const struct map_session_data *sd);
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);
@@ -3130,10 +3134,14 @@ typedef void (*HPMHOOK_pre_intif_pWisToGM) (int *fd);
typedef void (*HPMHOOK_post_intif_pWisToGM) (int fd);
typedef void (*HPMHOOK_pre_intif_pRegisters) (int *fd);
typedef void (*HPMHOOK_post_intif_pRegisters) (int fd);
+typedef void (*HPMHOOK_pre_intif_pAccountStorage) (int *fd);
+typedef void (*HPMHOOK_post_intif_pAccountStorage) (int fd);
typedef void (*HPMHOOK_pre_intif_pChangeNameOk) (int *fd);
typedef void (*HPMHOOK_post_intif_pChangeNameOk) (int fd);
typedef void (*HPMHOOK_pre_intif_pMessageToFD) (int *fd);
typedef void (*HPMHOOK_post_intif_pMessageToFD) (int fd);
+typedef void (*HPMHOOK_pre_intif_pAccountStorageSaveAck) (int *fd);
+typedef void (*HPMHOOK_post_intif_pAccountStorageSaveAck) (int fd);
typedef void (*HPMHOOK_pre_intif_pLoadGuildStorage) (int *fd);
typedef void (*HPMHOOK_post_intif_pLoadGuildStorage) (int fd);
typedef void (*HPMHOOK_pre_intif_pSaveGuildStorage) (int *fd);
@@ -4366,6 +4374,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_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 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 int (*HPMHOOK_pre_mapif_parse_ItemBoundRetrieve_sub) (int *fd);
diff --git a/src/plugins/HPMHooking/HPMHooking_char.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_char.HPMHooksCore.inc
index eb5583035..21e136c2f 100644
--- a/src/plugins/HPMHooking/HPMHooking_char.HPMHooksCore.inc
+++ b/src/plugins/HPMHooking/HPMHooking_char.HPMHooksCore.inc
@@ -1104,6 +1104,14 @@ struct {
struct HPMHookPoint *HP_mapif_parse_LoadGuildStorage_post;
struct HPMHookPoint *HP_mapif_parse_SaveGuildStorage_pre;
struct HPMHookPoint *HP_mapif_parse_SaveGuildStorage_post;
+ struct HPMHookPoint *HP_mapif_account_storage_load_pre;
+ struct HPMHookPoint *HP_mapif_account_storage_load_post;
+ struct HPMHookPoint *HP_mapif_pAccountStorageLoad_pre;
+ struct HPMHookPoint *HP_mapif_pAccountStorageLoad_post;
+ struct HPMHookPoint *HP_mapif_pAccountStorageSave_pre;
+ struct HPMHookPoint *HP_mapif_pAccountStorageSave_post;
+ struct HPMHookPoint *HP_mapif_sAccountStorageSaveAck_pre;
+ struct HPMHookPoint *HP_mapif_sAccountStorageSaveAck_post;
struct HPMHookPoint *HP_mapif_itembound_ack_pre;
struct HPMHookPoint *HP_mapif_itembound_ack_post;
struct HPMHookPoint *HP_mapif_parse_ItemBoundRetrieve_sub_pre;
@@ -2581,6 +2589,14 @@ struct {
int HP_mapif_parse_LoadGuildStorage_post;
int HP_mapif_parse_SaveGuildStorage_pre;
int HP_mapif_parse_SaveGuildStorage_post;
+ int HP_mapif_account_storage_load_pre;
+ int HP_mapif_account_storage_load_post;
+ int HP_mapif_pAccountStorageLoad_pre;
+ int HP_mapif_pAccountStorageLoad_post;
+ int HP_mapif_pAccountStorageSave_pre;
+ int HP_mapif_pAccountStorageSave_post;
+ int HP_mapif_sAccountStorageSaveAck_pre;
+ int HP_mapif_sAccountStorageSaveAck_post;
int HP_mapif_itembound_ack_pre;
int HP_mapif_itembound_ack_post;
int HP_mapif_parse_ItemBoundRetrieve_sub_pre;
diff --git a/src/plugins/HPMHooking/HPMHooking_char.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_char.HookingPoints.inc
index 29720bf40..639cdbdd2 100644
--- a/src/plugins/HPMHooking/HPMHooking_char.HookingPoints.inc
+++ b/src/plugins/HPMHooking/HPMHooking_char.HookingPoints.inc
@@ -587,6 +587,10 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(mapif->save_guild_storage_ack, HP_mapif_save_guild_storage_ack) },
{ HP_POP(mapif->parse_LoadGuildStorage, HP_mapif_parse_LoadGuildStorage) },
{ HP_POP(mapif->parse_SaveGuildStorage, HP_mapif_parse_SaveGuildStorage) },
+ { HP_POP(mapif->account_storage_load, HP_mapif_account_storage_load) },
+ { HP_POP(mapif->pAccountStorageLoad, HP_mapif_pAccountStorageLoad) },
+ { HP_POP(mapif->pAccountStorageSave, HP_mapif_pAccountStorageSave) },
+ { HP_POP(mapif->sAccountStorageSaveAck, HP_mapif_sAccountStorageSaveAck) },
{ HP_POP(mapif->itembound_ack, HP_mapif_itembound_ack) },
{ HP_POP(mapif->parse_ItemBoundRetrieve_sub, HP_mapif_parse_ItemBoundRetrieve_sub) },
{ HP_POP(mapif->parse_ItemBoundRetrieve, HP_mapif_parse_ItemBoundRetrieve) },
diff --git a/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc
index d2853fcdc..96e068903 100644
--- a/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc
@@ -8032,11 +8032,11 @@ int HP_inter_quest_parse_frommap(int fd) {
return retVal___;
}
/* inter_storage_interface */
-int HP_inter_storage_tosql(int account_id, struct storage_data *p) {
+int HP_inter_storage_tosql(int account_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, struct storage_data **p);
+ int (*preHookFunc) (int *account_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;
@@ -8051,7 +8051,7 @@ int HP_inter_storage_tosql(int account_id, struct storage_data *p) {
retVal___ = HPMHooks.source.inter_storage.tosql(account_id, p);
}
if (HPMHooks.count.HP_inter_storage_tosql_post > 0) {
- int (*postHookFunc) (int retVal___, int account_id, struct storage_data *p);
+ int (*postHookFunc) (int retVal___, int account_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);
@@ -14430,6 +14430,113 @@ int HP_mapif_parse_SaveGuildStorage(int fd) {
}
return retVal___;
}
+int HP_mapif_account_storage_load(int fd, int account_id) {
+ int hIndex = 0;
+ int retVal___ = 0;
+ if (HPMHooks.count.HP_mapif_account_storage_load_pre > 0) {
+ int (*preHookFunc) (int *fd, int *account_id);
+ *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);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.mapif.account_storage_load(fd, account_id);
+ }
+ if (HPMHooks.count.HP_mapif_account_storage_load_post > 0) {
+ int (*postHookFunc) (int retVal___, int fd, int account_id);
+ 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);
+ }
+ }
+ return retVal___;
+}
+int HP_mapif_pAccountStorageLoad(int fd) {
+ int hIndex = 0;
+ int retVal___ = 0;
+ if (HPMHooks.count.HP_mapif_pAccountStorageLoad_pre > 0) {
+ int (*preHookFunc) (int *fd);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mapif_pAccountStorageLoad_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_mapif_pAccountStorageLoad_pre[hIndex].func;
+ retVal___ = preHookFunc(&fd);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.mapif.pAccountStorageLoad(fd);
+ }
+ if (HPMHooks.count.HP_mapif_pAccountStorageLoad_post > 0) {
+ int (*postHookFunc) (int retVal___, int fd);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mapif_pAccountStorageLoad_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_mapif_pAccountStorageLoad_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, fd);
+ }
+ }
+ return retVal___;
+}
+int HP_mapif_pAccountStorageSave(int fd) {
+ int hIndex = 0;
+ int retVal___ = 0;
+ if (HPMHooks.count.HP_mapif_pAccountStorageSave_pre > 0) {
+ int (*preHookFunc) (int *fd);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mapif_pAccountStorageSave_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_mapif_pAccountStorageSave_pre[hIndex].func;
+ retVal___ = preHookFunc(&fd);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.mapif.pAccountStorageSave(fd);
+ }
+ if (HPMHooks.count.HP_mapif_pAccountStorageSave_post > 0) {
+ int (*postHookFunc) (int retVal___, int fd);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mapif_pAccountStorageSave_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_mapif_pAccountStorageSave_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, fd);
+ }
+ }
+ return retVal___;
+}
+void HP_mapif_sAccountStorageSaveAck(int fd, int account_id, bool save) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_mapif_sAccountStorageSaveAck_pre > 0) {
+ void (*preHookFunc) (int *fd, int *account_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);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.mapif.sAccountStorageSaveAck(fd, account_id, save);
+ }
+ if (HPMHooks.count.HP_mapif_sAccountStorageSaveAck_post > 0) {
+ void (*postHookFunc) (int fd, int account_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);
+ }
+ }
+ return;
+}
int HP_mapif_itembound_ack(int fd, int aid, int guild_id) {
int hIndex = 0;
int retVal___ = 0;
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
index 762acb747..e84a9bd0d 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
@@ -2386,6 +2386,10 @@ struct {
struct HPMHookPoint *HP_intif_saveregistry_post;
struct HPMHookPoint *HP_intif_request_registry_pre;
struct HPMHookPoint *HP_intif_request_registry_post;
+ struct HPMHookPoint *HP_intif_request_account_storage_pre;
+ struct HPMHookPoint *HP_intif_request_account_storage_post;
+ struct HPMHookPoint *HP_intif_send_account_storage_pre;
+ struct HPMHookPoint *HP_intif_send_account_storage_post;
struct HPMHookPoint *HP_intif_request_guild_storage_pre;
struct HPMHookPoint *HP_intif_request_guild_storage_post;
struct HPMHookPoint *HP_intif_send_guild_storage_pre;
@@ -2516,10 +2520,14 @@ struct {
struct HPMHookPoint *HP_intif_pWisToGM_post;
struct HPMHookPoint *HP_intif_pRegisters_pre;
struct HPMHookPoint *HP_intif_pRegisters_post;
+ struct HPMHookPoint *HP_intif_pAccountStorage_pre;
+ struct HPMHookPoint *HP_intif_pAccountStorage_post;
struct HPMHookPoint *HP_intif_pChangeNameOk_pre;
struct HPMHookPoint *HP_intif_pChangeNameOk_post;
struct HPMHookPoint *HP_intif_pMessageToFD_pre;
struct HPMHookPoint *HP_intif_pMessageToFD_post;
+ struct HPMHookPoint *HP_intif_pAccountStorageSaveAck_pre;
+ struct HPMHookPoint *HP_intif_pAccountStorageSaveAck_post;
struct HPMHookPoint *HP_intif_pLoadGuildStorage_pre;
struct HPMHookPoint *HP_intif_pLoadGuildStorage_post;
struct HPMHookPoint *HP_intif_pSaveGuildStorage_pre;
@@ -8441,6 +8449,10 @@ struct {
int HP_intif_saveregistry_post;
int HP_intif_request_registry_pre;
int HP_intif_request_registry_post;
+ int HP_intif_request_account_storage_pre;
+ int HP_intif_request_account_storage_post;
+ int HP_intif_send_account_storage_pre;
+ int HP_intif_send_account_storage_post;
int HP_intif_request_guild_storage_pre;
int HP_intif_request_guild_storage_post;
int HP_intif_send_guild_storage_pre;
@@ -8571,10 +8583,14 @@ struct {
int HP_intif_pWisToGM_post;
int HP_intif_pRegisters_pre;
int HP_intif_pRegisters_post;
+ int HP_intif_pAccountStorage_pre;
+ int HP_intif_pAccountStorage_post;
int HP_intif_pChangeNameOk_pre;
int HP_intif_pChangeNameOk_post;
int HP_intif_pMessageToFD_pre;
int HP_intif_pMessageToFD_post;
+ int HP_intif_pAccountStorageSaveAck_pre;
+ int HP_intif_pAccountStorageSaveAck_post;
int HP_intif_pLoadGuildStorage_pre;
int HP_intif_pLoadGuildStorage_post;
int HP_intif_pSaveGuildStorage_pre;
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
index 65cd9ea82..a8ec0b4f5 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
@@ -1228,6 +1228,8 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(intif->wis_message_to_gm, HP_intif_wis_message_to_gm) },
{ HP_POP(intif->saveregistry, HP_intif_saveregistry) },
{ HP_POP(intif->request_registry, HP_intif_request_registry) },
+ { HP_POP(intif->request_account_storage, HP_intif_request_account_storage) },
+ { HP_POP(intif->send_account_storage, HP_intif_send_account_storage) },
{ HP_POP(intif->request_guild_storage, HP_intif_request_guild_storage) },
{ HP_POP(intif->send_guild_storage, HP_intif_send_guild_storage) },
{ HP_POP(intif->create_party, HP_intif_create_party) },
@@ -1293,8 +1295,10 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(intif->pWisToGM_sub, HP_intif_pWisToGM_sub) },
{ HP_POP(intif->pWisToGM, HP_intif_pWisToGM) },
{ HP_POP(intif->pRegisters, HP_intif_pRegisters) },
+ { HP_POP(intif->pAccountStorage, HP_intif_pAccountStorage) },
{ HP_POP(intif->pChangeNameOk, HP_intif_pChangeNameOk) },
{ HP_POP(intif->pMessageToFD, HP_intif_pMessageToFD) },
+ { HP_POP(intif->pAccountStorageSaveAck, HP_intif_pAccountStorageSaveAck) },
{ HP_POP(intif->pLoadGuildStorage, HP_intif_pLoadGuildStorage) },
{ HP_POP(intif->pSaveGuildStorage, HP_intif_pSaveGuildStorage) },
{ HP_POP(intif->pPartyCreated, HP_intif_pPartyCreated) },
diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
index bcff2cd79..c0b70bf60 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
@@ -31323,6 +31323,58 @@ 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) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_intif_request_account_storage_pre > 0) {
+ void (*preHookFunc) (const struct map_session_data **sd);
+ *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);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.intif.request_account_storage(sd);
+ }
+ if (HPMHooks.count.HP_intif_request_account_storage_post > 0) {
+ void (*postHookFunc) (const struct map_session_data *sd);
+ 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);
+ }
+ }
+ return;
+}
+void HP_intif_send_account_storage(const struct map_session_data *sd) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_intif_send_account_storage_pre > 0) {
+ void (*preHookFunc) (const struct map_session_data **sd);
+ *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);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.intif.send_account_storage(sd);
+ }
+ if (HPMHooks.count.HP_intif_send_account_storage_post > 0) {
+ void (*postHookFunc) (const struct map_session_data *sd);
+ 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);
+ }
+ }
+ return;
+}
int HP_intif_request_guild_storage(int account_id, int guild_id) {
int hIndex = 0;
int retVal___ = 0;
@@ -33077,6 +33129,32 @@ void HP_intif_pRegisters(int fd) {
}
return;
}
+void HP_intif_pAccountStorage(int fd) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_intif_pAccountStorage_pre > 0) {
+ void (*preHookFunc) (int *fd);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_intif_pAccountStorage_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_intif_pAccountStorage_pre[hIndex].func;
+ preHookFunc(&fd);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.intif.pAccountStorage(fd);
+ }
+ if (HPMHooks.count.HP_intif_pAccountStorage_post > 0) {
+ void (*postHookFunc) (int fd);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_intif_pAccountStorage_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_intif_pAccountStorage_post[hIndex].func;
+ postHookFunc(fd);
+ }
+ }
+ return;
+}
void HP_intif_pChangeNameOk(int fd) {
int hIndex = 0;
if (HPMHooks.count.HP_intif_pChangeNameOk_pre > 0) {
@@ -33129,6 +33207,32 @@ void HP_intif_pMessageToFD(int fd) {
}
return;
}
+void HP_intif_pAccountStorageSaveAck(int fd) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_intif_pAccountStorageSaveAck_pre > 0) {
+ void (*preHookFunc) (int *fd);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_intif_pAccountStorageSaveAck_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_intif_pAccountStorageSaveAck_pre[hIndex].func;
+ preHookFunc(&fd);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.intif.pAccountStorageSaveAck(fd);
+ }
+ if (HPMHooks.count.HP_intif_pAccountStorageSaveAck_post > 0) {
+ void (*postHookFunc) (int fd);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_intif_pAccountStorageSaveAck_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_intif_pAccountStorageSaveAck_post[hIndex].func;
+ postHookFunc(fd);
+ }
+ }
+ return;
+}
void HP_intif_pLoadGuildStorage(int fd) {
int hIndex = 0;
if (HPMHooks.count.HP_intif_pLoadGuildStorage_pre > 0) {