From ce1e90170548e2c2f516943d99defaf06950f20e Mon Sep 17 00:00:00 2001 From: panikon Date: Fri, 18 Jul 2014 22:10:01 -0300 Subject: [PATCH 01/19] struct guild_storage cleanup (part 1) - Changed storage_status to bool, renamed to in_use. Signed-off-by: Haru --- src/common/mmo.h | 2 +- src/map/guild.c | 3 ++- src/map/intif.c | 5 +++-- src/map/storage.c | 32 ++++++++++++++++---------------- 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/common/mmo.h b/src/common/mmo.h index e762bd5bdbd..3e98f54e5fa 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -625,7 +625,7 @@ struct storage_data { struct guild_storage { int dirty; int guild_id; - short storage_status; + bool in_use; ///< Whether storage is in use by other guild members short storage_amount; struct item items[MAX_GUILD_STORAGE]; unsigned short lock; diff --git a/src/map/guild.c b/src/map/guild.c index 20f9ad5d176..16bdd9cee45 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -1089,7 +1089,8 @@ static void guild_retrieveitembound(int char_id, int aid, int guild_id) pc->bound_clear(sd,IBT_GUILD); } else { //Character is offline, ask char server to do the job struct guild_storage *gstor = idb_get(gstorage->db,guild_id); - if(gstor && gstor->storage_status == 1) { //Someone is in guild storage, close them + if (gstor != NULL && gstor->in_use) { + // Someone is in guild storage, close them struct s_mapiterator* iter = mapit_getallusers(); for (sd = BL_UCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); sd = BL_UCAST(BL_PC, mapit->next(iter))) { if(sd->status.guild_id == guild_id && sd->state.storage_flag == STORAGE_FLAG_GUILD) { diff --git a/src/map/intif.c b/src/map/intif.c index 3ae71a0be1d..0ff723fffc4 100644 --- a/src/map/intif.c +++ b/src/map/intif.c @@ -1125,7 +1125,8 @@ static void intif_parse_LoadGuildStorage(int fd) ShowWarning("intif_parse_LoadGuildStorage: error guild_id %d not exist\n",guild_id); return; } - if (gstor->storage_status == 1) { // Already open.. lets ignore this update + if (gstor->in_use) { + // Already open.. lets ignore this update ShowWarning("intif_parse_LoadGuildStorage: storage received for a client already open (User %d:%d)\n", flag?sd->status.account_id:0, flag?sd->status.char_id:0); return; } @@ -1135,7 +1136,7 @@ static void intif_parse_LoadGuildStorage(int fd) } if (RFIFOW(fd,2)-13 != sizeof(struct guild_storage)) { ShowError("intif_parse_LoadGuildStorage: data size mismatch %d != %"PRIuS"\n", RFIFOW(fd,2)-13, sizeof(struct guild_storage)); - gstor->storage_status = 0; + gstor->in_use = false; return; } diff --git a/src/map/storage.c b/src/map/storage.c index a9bf2195e33..289be1c45c9 100644 --- a/src/map/storage.c +++ b/src/map/storage.c @@ -83,7 +83,7 @@ static int storage_reconnect_sub(union DBKey key, struct DBData *data, va_list a { struct guild_storage *stor = DB->data2ptr(data); nullpo_ret(stor); - if (stor->dirty && stor->storage_status == 0) //Save closed storages. + if (stor->dirty && !stor->in_use) //Save closed storages. gstorage->save(0, stor->guild_id,0); return 0; @@ -503,13 +503,14 @@ static int storage_guild_storageopen(struct map_session_data *sd) intif->request_guild_storage(sd->status.account_id,sd->status.guild_id); return 0; } - if(gstor->storage_status) + + if (gstor->in_use) return 1; if( gstor->lock ) return 1; - gstor->storage_status = 1; + gstor->in_use = true; sd->state.storage_flag = STORAGE_FLAG_GUILD; storage->sortitem(gstor->items, ARRAYLENGTH(gstor->items)); clif->guildStorageList(sd, gstor->items, ARRAYLENGTH(gstor->items)); @@ -620,7 +621,7 @@ static int storage_guild_storageadd(struct map_session_data *sd, int index, int nullpo_ret(sd); nullpo_ret(stor=idb_get(gstorage->db,sd->status.guild_id)); - if( !stor->storage_status || stor->storage_amount > MAX_GUILD_STORAGE ) + if (!stor->in_use || stor->storage_amount > MAX_GUILD_STORAGE) return 0; if (index < 0 || index >= sd->status.inventorySize) @@ -660,7 +661,7 @@ static int storage_guild_storageget(struct map_session_data *sd, int index, int nullpo_ret(sd); nullpo_ret(stor=idb_get(gstorage->db,sd->status.guild_id)); - if(!stor->storage_status) + if(!stor->in_use) return 0; if(index<0 || index>=MAX_GUILD_STORAGE) @@ -700,7 +701,7 @@ static int storage_guild_storageaddfromcart(struct map_session_data *sd, int ind nullpo_ret(sd); nullpo_ret(stor=idb_get(gstorage->db,sd->status.guild_id)); - if( !stor->storage_status || stor->storage_amount > MAX_GUILD_STORAGE ) + if (!stor->in_use || stor->storage_amount > MAX_GUILD_STORAGE) return 0; if( index < 0 || index >= MAX_CART ) @@ -732,7 +733,7 @@ static int storage_guild_storagegettocart(struct map_session_data *sd, int index nullpo_ret(sd); nullpo_ret(stor=idb_get(gstorage->db,sd->status.guild_id)); - if(!stor->storage_status) + if(!stor->in_use) return 0; if(index<0 || index>=MAX_GUILD_STORAGE) @@ -760,10 +761,9 @@ static int storage_guild_storagesave(int account_id, int guild_id, int flag) { struct guild_storage *stor = idb_get(gstorage->db,guild_id); - if(stor) - { + if (stor != NULL) { if (flag) //Char quitting, close it. - stor->storage_status = 0; + stor->in_use = false; if (stor->dirty) intif->send_guild_storage(account_id,stor); return 1; @@ -782,7 +782,7 @@ static int storage_guild_storagesaved(int guild_id) struct guild_storage *stor; if((stor=idb_get(gstorage->db,guild_id)) != NULL) { - if (stor->dirty && stor->storage_status == 0) { + if (stor->dirty && !stor->in_use) { //Storage has been correctly saved. stor->dirty = 0; } @@ -800,12 +800,12 @@ static int storage_guild_storageclose(struct map_session_data *sd) nullpo_ret(stor=idb_get(gstorage->db,sd->status.guild_id)); clif->storageclose(sd); - if (stor->storage_status) { + if (stor->in_use) { if (map->save_settings&4) chrif->save(sd, 0); //This one also saves the storage. [Skotlex] else gstorage->save(sd->status.account_id, sd->status.guild_id,0); - stor->storage_status=0; + stor->in_use = false; } sd->state.storage_flag = STORAGE_FLAG_CLOSED; @@ -822,21 +822,21 @@ static int storage_guild_storage_quit(struct map_session_data *sd, int flag) if(flag) { //Only during a guild break flag is 1 (don't save storage) sd->state.storage_flag = STORAGE_FLAG_CLOSED; - stor->storage_status = 0; + stor->in_use = false; clif->storageclose(sd); if (map->save_settings&4) chrif->save(sd,0); return 0; } - if(stor->storage_status) { + if(stor->in_use) { if (map->save_settings&4) chrif->save(sd,0); else gstorage->save(sd->status.account_id,sd->status.guild_id,1); } sd->state.storage_flag = STORAGE_FLAG_CLOSED; - stor->storage_status = 0; + stor->in_use = false; return 0; } From c9d4f9c4efd4d1d10ca77611e7f58a7afdd1a5af Mon Sep 17 00:00:00 2001 From: panikon Date: Fri, 18 Jul 2014 22:10:01 -0300 Subject: [PATCH 02/19] struct guild_storage cleanup (part 2) - Changed dirty to bool Signed-off-by: Haru --- src/common/mmo.h | 2 +- src/map/storage.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/common/mmo.h b/src/common/mmo.h index 3e98f54e5fa..326b7c307dc 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -623,9 +623,9 @@ struct storage_data { }; struct guild_storage { - int dirty; int guild_id; bool in_use; ///< Whether storage is in use by other guild members + bool dirty; ///< Whether the struct was modified and needs to be saved short storage_amount; struct item items[MAX_GUILD_STORAGE]; unsigned short lock; diff --git a/src/map/storage.c b/src/map/storage.c index 289be1c45c9..5aea5e773c4 100644 --- a/src/map/storage.c +++ b/src/map/storage.c @@ -561,7 +561,7 @@ static int guild_storage_additem(struct map_session_data *sd, struct guild_stora return 1; stor->items[i].amount+=amount; clif->storageitemadded(sd,&stor->items[i],i,amount); - stor->dirty = 1; + stor->dirty = true; return 0; } } @@ -577,7 +577,7 @@ static int guild_storage_additem(struct map_session_data *sd, struct guild_stora stor->storage_amount++; clif->storageitemadded(sd,&stor->items[i],i,amount); clif->updatestorageamount(sd, stor->storage_amount, MAX_GUILD_STORAGE); - stor->dirty = 1; + stor->dirty = true; return 0; } @@ -603,7 +603,7 @@ static int guild_storage_delitem(struct map_session_data *sd, struct guild_stora clif->updatestorageamount(sd, stor->storage_amount, MAX_GUILD_STORAGE); } clif->storageitemremoved(sd,n,amount); - stor->dirty = 1; + stor->dirty = true; return 0; } @@ -784,7 +784,7 @@ static int storage_guild_storagesaved(int guild_id) if((stor=idb_get(gstorage->db,guild_id)) != NULL) { if (stor->dirty && !stor->in_use) { //Storage has been correctly saved. - stor->dirty = 0; + stor->dirty = false; } return 1; } From 4f1469c063203ea08e14f1c7d8c7f69e3f9191d6 Mon Sep 17 00:00:00 2001 From: panikon Date: Fri, 18 Jul 2014 22:10:01 -0300 Subject: [PATCH 03/19] struct guild_storage cleanup (part 3) - Changed lock to bool, renamed to locked. Signed-off-by: Haru --- src/common/mmo.h | 2 +- src/map/atcommand.c | 4 ++-- src/map/intif.c | 4 ++-- src/map/storage.c | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/common/mmo.h b/src/common/mmo.h index 326b7c307dc..8e081df4f7a 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -626,9 +626,9 @@ struct guild_storage { int guild_id; bool in_use; ///< Whether storage is in use by other guild members bool dirty; ///< Whether the struct was modified and needs to be saved + bool locked; ///< Whenever item retrieval is happening and the storage can't be accessed short storage_amount; struct item items[MAX_GUILD_STORAGE]; - unsigned short lock; }; /** diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 1debc59eb6e..9991e0522a4 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -5581,12 +5581,12 @@ ACMD(cleargstorage) } j = guild_storage->storage_amount; - guild_storage->lock = 1; // Lock @gstorage: do not allow any item to be retrieved or stored from any guild member + guild_storage->locked = true; // Lock @gstorage: do not allow any item to be retrieved or stored from any guild member for (i = 0; i < j; ++i) { gstorage->delitem(sd, guild_storage, i, guild_storage->items[i].amount); } gstorage->close(sd); - guild_storage->lock = 0; // Cleaning done, release lock + guild_storage->locked = false; // Cleaning done, release lock clif->message(fd, msg_fd(fd,1395)); // Your guild storage was cleaned. return true; diff --git a/src/map/intif.c b/src/map/intif.c index 0ff723fffc4..03c2d83be44 100644 --- a/src/map/intif.c +++ b/src/map/intif.c @@ -2339,7 +2339,7 @@ static void intif_itembound_req(int char_id, int aid, int guild_id) WFIFOW(inter_fd,10) = guild_id; WFIFOSET(inter_fd,12); if(gstor) - gstor->lock = 1; //Lock for retrieval process + gstor->locked = true; //Lock for retrieval process #endif } @@ -2352,7 +2352,7 @@ static void intif_parse_Itembound_ack(int fd) gstor = idb_get(gstorage->db,guild_id); if(gstor) - gstor->lock = 0; //Unlock now that operation is completed + gstor->locked = false; //Unlock now that operation is completed #endif } diff --git a/src/map/storage.c b/src/map/storage.c index 5aea5e773c4..4252be51172 100644 --- a/src/map/storage.c +++ b/src/map/storage.c @@ -507,7 +507,7 @@ static int storage_guild_storageopen(struct map_session_data *sd) if (gstor->in_use) return 1; - if( gstor->lock ) + if (gstor->locked) return 1; gstor->in_use = true; @@ -633,7 +633,7 @@ static int storage_guild_storageadd(struct map_session_data *sd, int index, int if( amount < 1 || amount > sd->status.inventory[index].amount ) return 0; - if( stor->lock ) { + if (stor->locked) { gstorage->close(sd); return 0; } @@ -673,7 +673,7 @@ static int storage_guild_storageget(struct map_session_data *sd, int index, int if(amount < 1 || amount > stor->items[index].amount) return 0; - if( stor->lock ) { + if (stor->locked) { gstorage->close(sd); return 0; } From 73e58473fdfb3e6f40520855e51f40f14e65e255 Mon Sep 17 00:00:00 2001 From: panikon Date: Fri, 18 Jul 2014 22:10:01 -0300 Subject: [PATCH 04/19] Updated SQL structure to support GD_GUILD_STORAGE Signed-off-by: Haru --- sql-files/main.sql | 4 +++- sql-files/upgrades/2016-11-26--17-26.sql | 4 ++++ sql-files/upgrades/index.txt | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 sql-files/upgrades/2016-11-26--17-26.sql diff --git a/sql-files/main.sql b/sql-files/main.sql index 315ebffdc0d..0b438e6ab56 100644 --- a/sql-files/main.sql +++ b/sql-files/main.sql @@ -389,6 +389,7 @@ CREATE TABLE IF NOT EXISTS `guild` ( `guild_lv` TINYINT UNSIGNED NOT NULL DEFAULT '0', `connect_member` TINYINT UNSIGNED NOT NULL DEFAULT '0', `max_member` TINYINT UNSIGNED NOT NULL DEFAULT '0', + `max_storage` SMALLINT UNSIGNED NOT NULL DEFAULT '0', `average_lv` SMALLINT UNSIGNED NOT NULL DEFAULT '1', `exp` BIGINT UNSIGNED NOT NULL DEFAULT '0', `next_exp` INT UNSIGNED NOT NULL DEFAULT '0', @@ -486,7 +487,7 @@ CREATE TABLE IF NOT EXISTS `guild_position` ( `guild_id` INT UNSIGNED NOT NULL DEFAULT '0', `position` TINYINT UNSIGNED NOT NULL DEFAULT '0', `name` VARCHAR(24) NOT NULL DEFAULT '', - `mode` TINYINT UNSIGNED NOT NULL DEFAULT '0', + `mode` SMALLINT UNSIGNED NOT NULL DEFAULT '0', `exp_mode` TINYINT UNSIGNED NOT NULL DEFAULT '0', PRIMARY KEY (`guild_id`,`position`) ) ENGINE=MyISAM; @@ -924,6 +925,7 @@ INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1467934919); -- 2016-07-0 INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1467935469); -- 2016-07-08--02-51.sql INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1475526420); -- 2016-10-03--20-27.sql INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1477434595); -- 2016-10-26--10-29.sql +INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1479662748); -- 2016-11-20--17-26.sql INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1488454834); -- 2017-03-02--11-40.sql INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1488744559); -- 2017-03-05--08-09.sql INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1489588190); -- 2017-03-15--14-29.sql diff --git a/sql-files/upgrades/2016-11-26--17-26.sql b/sql-files/upgrades/2016-11-26--17-26.sql new file mode 100644 index 00000000000..4fe19b27852 --- /dev/null +++ b/sql-files/upgrades/2016-11-26--17-26.sql @@ -0,0 +1,4 @@ +#1479662748 +ALTER TABLE `guild_position` CHANGE `mode` `mode` SMALLINT UNSIGNED NOT NULL DEFAULT '0'; +ALTER TABLE `guild` ADD `max_storage` SMALLINT UNSIGNED NOT NULL DEFAULT '0' AFTER `max_member`; +INSERT INTO `sql_updates` (`timestamp`) VALUES (1479662748); diff --git a/sql-files/upgrades/index.txt b/sql-files/upgrades/index.txt index 5c9b88bee9f..34992c72d07 100644 --- a/sql-files/upgrades/index.txt +++ b/sql-files/upgrades/index.txt @@ -37,6 +37,7 @@ 2016-07-08--02-51.sql 2016-10-03--20-27.sql 2016-10-26--10-29.sql +2016-11-26--17-26.sql 2017-03-02--11-40.sql 2017-03-05--08-09.sql 2017-03-15--14-29.sql From eb24d0ca6b3df2d757f5339aa6abd95c45b324a8 Mon Sep 17 00:00:00 2001 From: panikon Date: Fri, 18 Jul 2014 22:10:01 -0300 Subject: [PATCH 05/19] Added basic support to variable guild storage size - Added new field to struct guild: max_storage - Documented struct guild. Signed-off-by: Haru --- src/char/int_guild.c | 90 ++++++++++++++++++++++++++---------------- src/char/int_guild.h | 4 +- src/char/int_storage.c | 71 ++++++++++++++++++++++++--------- src/char/int_storage.h | 4 +- src/common/mmo.h | 52 +++++++++++++----------- src/map/clif.c | 7 +++- src/map/pc.c | 2 +- src/map/storage.c | 32 +++++++++------ 8 files changed, 169 insertions(+), 93 deletions(-) diff --git a/src/char/int_guild.c b/src/char/int_guild.c index f33896d3e33..ba310095af2 100644 --- a/src/char/int_guild.c +++ b/src/char/int_guild.c @@ -111,22 +111,29 @@ static int inter_guild_removemember_tosql(int account_id, int char_id) return 0; } -// Save guild into sql -static int inter_guild_tosql(struct guild *g, int flag) +/** + * Saves the requested guild information to SQL. + * + * @param g The guild data to save. + * @param flag Type of information to be saved (@see enum guild_save_types). + * @retval true in case of success. + * @retval false in case of error. + * + * Fields saved depending on the flag type: + * Table guild (GS_BASIC_MASK) + * GS_EMBLEM `emblem_len`,`emblem_id`,`emblem_data` + * GS_CONNECT `connect_member`,`average_lv` + * GS_MES `mes1`,`mes2` + * GS_LEVEL `guild_lv`,`max_member`,`exp`,`next_exp`,`skill_point`,`max_storage` + * GS_BASIC `name`,`master`,`char_id` + * GS_MEMBER `guild_member` (`guild_id`,`account_id`,`char_id`,`hair`,`hair_color`,`gender`,`class`,`lv`,`exp`,`exp_payper`,`online`,`position`,`name`) + * GS_POSITION `guild_position` (`guild_id`,`position`,`name`,`mode`,`exp_mode`) + * GS_ALLIANCE `guild_alliance` (`guild_id`,`opposition`,`alliance_id`,`name`) + * GS_EXPULSION `guild_expulsion` (`guild_id`,`account_id`,`name`,`mes`) + * GS_SKILL `guild_skill` (`guild_id`,`id`,`lv`) + */ +static bool inter_guild_tosql(struct guild *g, int flag) { - // Table guild (GS_BASIC_MASK) - // GS_EMBLEM `emblem_len`,`emblem_id`,`emblem_data` - // GS_CONNECT `connect_member`,`average_lv` - // GS_MES `mes1`,`mes2` - // GS_LEVEL `guild_lv`,`max_member`,`exp`,`next_exp`,`skill_point` - // GS_BASIC `name`,`master`,`char_id` - - // GS_MEMBER `guild_member` (`guild_id`,`account_id`,`char_id`,`hair`,`hair_color`,`gender`,`class`,`lv`,`exp`,`exp_payper`,`online`,`position`,`name`) - // GS_POSITION `guild_position` (`guild_id`,`position`,`name`,`mode`,`exp_mode`) - // GS_ALLIANCE `guild_alliance` (`guild_id`,`opposition`,`alliance_id`,`name`) - // GS_EXPULSION `guild_expulsion` (`guild_id`,`account_id`,`name`,`mes`) - // GS_SKILL `guild_skill` (`guild_id`,`id`,`lv`) - // temporary storage for str conversion. They must be twice the size of the // original string to ensure no overflows will occur. [Skotlex] char t_info[256]; @@ -135,8 +142,8 @@ static int inter_guild_tosql(struct guild *g, int flag) char new_guild = 0; int i=0; - nullpo_ret(g); - if (g->guild_id<=0 && g->guild_id != -1) return 0; + nullpo_retr(false, g); + Assert_retr(false, g->guild_id > 0 || g->guild_id == -1); #ifdef NOISY ShowInfo("Save guild request ("CL_BOLD"%d"CL_RESET" - flag 0x%x).\n",g->guild_id, flag); @@ -156,7 +163,7 @@ static int inter_guild_tosql(struct guild *g, int flag) "VALUES ('%s', '%s', '%d', '%d', '%d', '%d')", guild_db, esc_name, esc_master, g->guild_lv, g->max_member, g->average_lv, g->member[0].char_id)) { Sql_ShowDebug(inter->sql_handle); - return 0; //Failed to create guild! + return false; //Failed to create guild! } else { g->guild_id = (int)SQL->LastInsertId(inter->sql_handle); new_guild = 1; @@ -195,7 +202,8 @@ static int inter_guild_tosql(struct guild *g, int flag) StrBuf->AppendStr(&buf, ", "); else add_comma = true; - StrBuf->Printf(&buf, "`name`='%s', `master`='%s', `char_id`=%d", esc_name, esc_master, g->member[0].char_id); + StrBuf->Printf(&buf, "`name`='%s', `master`='%s', `char_id`=%d", + esc_name, esc_master, g->member[0].char_id); } if (flag & GS_CONNECT) { @@ -229,7 +237,8 @@ static int inter_guild_tosql(struct guild *g, int flag) else //last condition using add_coma setting add_comma = true; #endif // 0 - StrBuf->Printf(&buf, "`guild_lv`=%d, `skill_point`=%d, `exp`=%"PRIu64", `next_exp`=%u, `max_member`=%d", g->guild_lv, g->skill_point, g->exp, g->next_exp, g->max_member); + StrBuf->Printf(&buf, "`guild_lv`=%d, `skill_point`=%d, `exp`=%"PRIu64", `next_exp`=%u, `max_member`=%d, `max_storage`=%hd", + g->guild_lv, g->skill_point, g->exp, g->next_exp, g->max_member, g->max_storage); } StrBuf->Printf(&buf, " WHERE `guild_id`=%d", g->guild_id); if( SQL_ERROR == SQL->QueryStr(inter->sql_handle, StrBuf->Value(&buf)) ) @@ -340,10 +349,15 @@ static int inter_guild_tosql(struct guild *g, int flag) if (chr->show_save_log) ShowInfo("Saved guild (%d - %s):%s\n", g->guild_id, g->name, t_info); - return 1; + return true; } -// Read guild from sql +/** + * Retrieves a guild's information from SQL. + * + * @param guild_id The guild ID to look up. + * @return The guild data or NULL. + */ static struct guild *inter_guild_fromsql(int guild_id) { struct guild *g; @@ -363,7 +377,9 @@ static struct guild *inter_guild_fromsql(int guild_id) ShowInfo("Guild load request (%d)...\n", guild_id); #endif - if( SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT g.`name`,c.`name`,g.`guild_lv`,g.`connect_member`,g.`max_member`,g.`average_lv`,g.`exp`,g.`next_exp`,g.`skill_point`,g.`mes1`,g.`mes2`,g.`emblem_len`,g.`emblem_id`,g.`emblem_data` " + if( SQL_ERROR == SQL->Query(inter->sql_handle, + "SELECT g.`name`,c.`name`,g.`guild_lv`,g.`connect_member`,g.`max_member`,g.`max_storage`," + "g.`average_lv`,g.`exp`,g.`next_exp`,g.`skill_point`,g.`mes1`,g.`mes2`,g.`emblem_len`,g.`emblem_id`,g.`emblem_data` " "FROM `%s` g LEFT JOIN `%s` c ON c.`char_id` = g.`char_id` WHERE g.`guild_id`='%d'", guild_db, char_db, guild_id) ) { Sql_ShowDebug(inter->sql_handle); @@ -386,15 +402,16 @@ static struct guild *inter_guild_fromsql(int guild_id) ShowWarning("Guild %d:%s specifies higher capacity (%d) than MAX_GUILD (%d)\n", guild_id, g->name, g->max_member, MAX_GUILD); g->max_member = MAX_GUILD; } - SQL->GetData(inter->sql_handle, 5, &data, NULL); g->average_lv = atoi(data); - SQL->GetData(inter->sql_handle, 6, &data, NULL); g->exp = strtoull(data, NULL, 10); - SQL->GetData(inter->sql_handle, 7, &data, NULL); g->next_exp = (unsigned int)strtoul(data, NULL, 10); - SQL->GetData(inter->sql_handle, 8, &data, NULL); g->skill_point = atoi(data); - SQL->GetData(inter->sql_handle, 9, &data, &len); memcpy(g->mes1, data, min(len, sizeof(g->mes1))); - SQL->GetData(inter->sql_handle, 10, &data, &len); memcpy(g->mes2, data, min(len, sizeof(g->mes2))); - SQL->GetData(inter->sql_handle, 11, &data, &len); g->emblem_len = atoi(data); - SQL->GetData(inter->sql_handle, 12, &data, &len); g->emblem_id = atoi(data); - SQL->GetData(inter->sql_handle, 13, &data, &len); + SQL->GetData(inter->sql_handle, 5, &data, NULL); g->max_storage = atoi(data); + SQL->GetData(inter->sql_handle, 6, &data, NULL); g->average_lv = atoi(data); + SQL->GetData(inter->sql_handle, 7, &data, NULL); g->exp = strtoull(data, NULL, 10); + SQL->GetData(inter->sql_handle, 8, &data, NULL); g->next_exp = (unsigned int)strtoul(data, NULL, 10); + SQL->GetData(inter->sql_handle, 9, &data, NULL); g->skill_point = atoi(data); + SQL->GetData(inter->sql_handle, 10, &data, &len); memcpy(g->mes1, data, min(len, sizeof(g->mes1))); + SQL->GetData(inter->sql_handle, 11, &data, &len); memcpy(g->mes2, data, min(len, sizeof(g->mes2))); + SQL->GetData(inter->sql_handle, 12, &data, &len); g->emblem_len = atoi(data); + SQL->GetData(inter->sql_handle, 13, &data, &len); g->emblem_id = atoi(data); + SQL->GetData(inter->sql_handle, 14, &data, &len); // convert emblem data from hexadecimal to binary //TODO: why not store it in the db as binary directly? [ultramage] for( i = 0, p = g->emblem_data; i < g->emblem_len; ++i, ++p ) @@ -862,6 +879,8 @@ static int inter_guild_calcinfo(struct guild *g) // Save next exp step g->next_exp = nextexp; + // Set the max storage size + g->max_storage = MAX_GUILD_STORAGE; // Set the max number of members, Guild Extension skill - currently adds 6 to max per skill lv. g->max_member = BASE_GUILD_SIZE + inter_guild->checkskill(g, GD_EXTENSION) * 6; if(g->max_member > MAX_GUILD) @@ -895,7 +914,11 @@ static int inter_guild_calcinfo(struct guild *g) g->average_lv /= c; // Check if guild stats has change - if (g->max_member != before.max_member || g->guild_lv != before.guild_lv || g->skill_point != before.skill_point) { + if (g->max_member != before.max_member + || g->guild_lv != before.guild_lv + || g->skill_point != before.skill_point + || g->max_storage != before.max_storage + ) { g->save_flag |= GS_LEVEL; mapif->guild_info(-1,g); return 1; @@ -953,6 +976,7 @@ static struct guild *inter_guild_create(const char *name, const struct guild_mem g->average_lv = master->lv; g->connect_member = 1; g->guild_lv = 1; + g->max_storage = MAX_GUILD_STORAGE; for(i=0;iskill[i].id=i + GD_SKILLBASE; diff --git a/src/char/int_guild.h b/src/char/int_guild.h index 05071d82fed..d01468fd373 100644 --- a/src/char/int_guild.h +++ b/src/char/int_guild.h @@ -24,7 +24,7 @@ #include "common/db.h" #include "common/mmo.h" -enum { +enum guild_save_types { GS_BASIC = 0x0001, GS_MEMBER = 0x0002, GS_POSITION = 0x0004, @@ -50,7 +50,7 @@ struct inter_guild_interface { int (*save_timer) (int tid, int64 tick, int id, intptr_t data); int (*removemember_tosql) (int account_id, int char_id); - int (*tosql) (struct guild *g, int flag); + bool (*tosql) (struct guild *g, int flag); struct guild* (*fromsql) (int guild_id); int (*castle_tosql) (struct guild_castle *gc); struct guild_castle* (*castle_fromsql) (int castle_id); diff --git a/src/char/int_storage.c b/src/char/int_storage.c index eccdabd00cc..4871c27cff2 100644 --- a/src/char/int_storage.c +++ b/src/char/int_storage.c @@ -234,10 +234,21 @@ static int inter_storage_fromsql(int account_id, struct storage_data *p) return VECTOR_LENGTH(p->item); } -/// Save guild_storage data to sql -static bool inter_storage_guild_storage_tosql(int guild_id, const struct guild_storage *p) +/** + * Saves `guild_storage` data to SQL + * + * @param guild_id ID of the owner guild. + * @param gstor The guild storage to save. + * Used fields: + * .guild_id + * .storage_amount + * .items + * @return Number of errors encountered when saving + */ +static bool inter_storage_guild_storage_tosql(int guild_id, const struct guild_storage *gstor) { - nullpo_ret(p); + nullpo_retr(1, gstor); + Assert_retr(1, guild_id == gstor->guild_id); if (SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT `guild_id` FROM `%s` WHERE `guild_id`='%d'", guild_db, guild_id)) { Sql_ShowDebug(inter->sql_handle); @@ -249,23 +260,42 @@ static bool inter_storage_guild_storage_tosql(int guild_id, const struct guild_s } SQL->FreeResult(inter->sql_handle); - chr->memitemdata_to_sql(p->items, guild_id, TABLE_GUILD_STORAGE); - ShowInfo ("guild storage save to DB - guild: %d\n", guild_id); + int err_count = chr->memitemdata_to_sql(gstor->items, gstor->guild_id, TABLE_GUILD_STORAGE); + if (err_count != 0) { + ShowError("guild_storage_tosql: Couldn't save storage item data! (GID: %d)\n", gstor->guild_id); + return false; + } + + ShowInfo("guild storage save to DB - guild: %d\n", gstor->guild_id); + return true; } -/// Load guild_storage data to mem -static int inter_storage_guild_storage_fromsql(int guild_id, struct guild_storage* p) +/** + * Loads `guild_storage` data to memory + * + * @param[in] guild_id ID of the owner guild. + * @param[out] gstor Empty, allocated buffer to contain the loaded data. + * @return Error code + * @retval 0 in case of success + */ +static int inter_storage_guild_storage_fromsql(int guild_id, struct guild_storage *gstor) { StringBuf buf; - char* data; - int i; - int j; + char *data; + int num_rows; + int i, j; - nullpo_ret(p); - memset(p, 0, sizeof(struct guild_storage)); //clean up memory - p->storage_amount = 0; - p->guild_id = guild_id; + nullpo_retr(1, gstor); + + memset(gstor, 0, sizeof(struct guild_storage)); //clean up memory + gstor->guild_id = guild_id; + + if (SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT `guild_id` FROM `%s` WHERE `guild_id`='%d'", guild_db, guild_id)) { + Sql_ShowDebug(inter->sql_handle); + return 1; + } + SQL->FreeResult(inter->sql_handle); // storage {`guild_id`/`id`/`nameid`/`amount`/`equip`/`identify`/`refine`/`attribute`/`card0`/`card1`/`card2`/`card3`} StrBuf->Init(&buf); @@ -280,9 +310,14 @@ static int inter_storage_guild_storage_fromsql(int guild_id, struct guild_storag Sql_ShowDebug(inter->sql_handle); StrBuf->Destroy(&buf); + num_rows = (int)SQL->NumRows(inter->sql_handle); + if (num_rows > MAX_GUILD_STORAGE) { + ShowError("guild_storage_fromsql: Too many items in storage for guild %d!\n", guild_id); + num_rows = MAX_GUILD_STORAGE; + } - for (i = 0; i < MAX_GUILD_STORAGE && SQL_SUCCESS == SQL->NextRow(inter->sql_handle); ++i) { - struct item *item = &p->items[i]; + for (i = 0; i < num_rows && SQL_SUCCESS == SQL->NextRow(inter->sql_handle); ++i) { + struct item *item = &gstor->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); @@ -306,10 +341,10 @@ static int inter_storage_guild_storage_fromsql(int guild_id, struct guild_storag item->option[j].value = atoi(data); } } - p->storage_amount = i; + gstor->storage_amount = i; SQL->FreeResult(inter->sql_handle); - ShowInfo("guild storage load complete from DB - id: %d (total: %d)\n", guild_id, p->storage_amount); + ShowInfo("guild storage load complete from DB - id: %d (total: %d)\n", guild_id, gstor->storage_amount); return 0; } diff --git a/src/char/int_storage.h b/src/char/int_storage.h index 6b84ac13d0e..34e163edc69 100644 --- a/src/char/int_storage.h +++ b/src/char/int_storage.h @@ -33,8 +33,8 @@ struct guild_storage; struct inter_storage_interface { int (*tosql) (int account_id, const struct storage_data *p); int (*fromsql) (int account_id, struct storage_data *p); - bool (*guild_storage_tosql) (int guild_id, const struct guild_storage *p); - int (*guild_storage_fromsql) (int guild_id, struct guild_storage* p); + bool (*guild_storage_tosql) (int guild_id, const struct guild_storage *gstor); + int (*guild_storage_fromsql) (int guild_id, struct guild_storage *gstor); int (*sql_init) (void); void (*sql_final) (void); int (*delete_) (int account_id); diff --git a/src/common/mmo.h b/src/common/mmo.h index 8e081df4f7a..0342af78606 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -923,29 +923,35 @@ struct guild_skill { struct channel_data; struct guild { - int guild_id; - short guild_lv, connect_member, max_member, average_lv; - uint64 exp; - unsigned int next_exp; - int skill_point; - char name[NAME_LENGTH],master[NAME_LENGTH]; - struct guild_member member[MAX_GUILD]; - struct guild_position position[MAX_GUILDPOSITION]; - char mes1[MAX_GUILDMES1],mes2[MAX_GUILDMES2]; - int emblem_len,emblem_id; - char emblem_data[2048]; - struct guild_alliance alliance[MAX_GUILDALLIANCE]; - struct guild_expulsion expulsion[MAX_GUILDEXPULSION]; - struct guild_skill skill[MAX_GUILDSKILL]; - - /* used on char.c to state what kind of data is being saved/processed */ - unsigned short save_flag; - - short *instance; - unsigned short instances; - - struct channel_data *channel; - struct hplugin_data_store *hdata; ///< HPM Plugin Data Store + int guild_id; ///< Guild's unique identifier + int16 guild_lv; ///< Guild level + int16 connect_member; ///< Current online members + int16 max_member; ///< Total guild member slots + int16 average_lv; ///< Average level of guild members + int16 max_storage; ///< Maximum guild storage size + uint64 exp; ///< Current guild experience + unsigned int next_exp; ///< Experience needed for the next level + int skill_point; ///< Available skill points + char name[NAME_LENGTH]; ///< Guild name + char master[NAME_LENGTH]; ///< Guild leader's name + struct guild_member member[MAX_GUILD]; ///< Guild members data + struct guild_position position[MAX_GUILDPOSITION]; ///< Guild positions data + char mes1[MAX_GUILDMES1]; ///< Guild message (first line) + char mes2[MAX_GUILDMES2]; ///< Guild message (second line) + int emblem_id; ///< Sequential ID of the current emblem + int emblem_len; ///< Guild emblem data length + char emblem_data[2048]; ///< Guild emblem data + struct guild_alliance alliance[MAX_GUILDALLIANCE]; ///< Guild alliances data + struct guild_expulsion expulsion[MAX_GUILDEXPULSION]; ///< Guild expulsion records + struct guild_skill skill[MAX_GUILDSKILL]; ///< Guild skills data + + unsigned short save_flag; ///< Flag used in char.c to state what kind of data is being saved/processed + + short *instance; ///< Array of instances + unsigned short instances; ///< Amount of instances + + struct channel_data *channel; ///< Guild's `#ally` channel + struct hplugin_data_store *hdata; ///< HPM Plugin Data Store }; struct guild_castle { diff --git a/src/map/clif.c b/src/map/clif.c index 2918b438098..f1fdba87469 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -9443,9 +9443,14 @@ static void clif_refresh_storagewindow(struct map_session_data *sd) // Shouldn't happen... The information should already be at the map-server intif->request_guild_storage(sd->status.account_id,sd->status.guild_id); } else { + if (sd->guild == NULL) { + ShowWarning("clif_refreshstoragewindow: Trying to open guild storage without guild information! (AID: %d, GID: %d)\n", + sd->status.account_id, sd->status.guild_id); + return; + } storage->sortitem(gstor->items, ARRAYLENGTH(gstor->items)); clif->guildStorageList(sd, gstor->items, ARRAYLENGTH(gstor->items)); - clif->updatestorageamount(sd, gstor->storage_amount, MAX_GUILD_STORAGE); + clif->updatestorageamount(sd, gstor->storage_amount, sd->guild->max_storage); } } } diff --git a/src/map/pc.c b/src/map/pc.c index 32c1156f91c..bee66d727fb 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -10737,7 +10737,7 @@ static int pc_checkitem(struct map_session_data *sd) 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++) { + for (i = 0; i < guild_storage->storage_amount; i++) { if ((id = guild_storage->items[i].nameid) == 0) continue; diff --git a/src/map/storage.c b/src/map/storage.c index 4252be51172..242f61dedf4 100644 --- a/src/map/storage.c +++ b/src/map/storage.c @@ -513,8 +513,8 @@ static int storage_guild_storageopen(struct map_session_data *sd) gstor->in_use = true; sd->state.storage_flag = STORAGE_FLAG_GUILD; storage->sortitem(gstor->items, ARRAYLENGTH(gstor->items)); - clif->guildStorageList(sd, gstor->items, ARRAYLENGTH(gstor->items)); - clif->updatestorageamount(sd, gstor->storage_amount, MAX_GUILD_STORAGE); + clif->guildStorageList(sd, gstor->items, gstor->storage_amount); + clif->updatestorageamount(sd, gstor->storage_amount, sd->guild->max_storage); return 0; } @@ -530,6 +530,7 @@ static int guild_storage_additem(struct map_session_data *sd, struct guild_stora int i; nullpo_retr(1, sd); + nullpo_retr(1, sd->guild); nullpo_retr(1, stor); nullpo_retr(1, item_data); @@ -554,8 +555,8 @@ static int guild_storage_additem(struct map_session_data *sd, struct guild_stora return 1; } - if(itemdb->isstackable2(data)){ //Stackable - for(i=0;iisstackable2(data)) { // Stackable + for (i = 0; i < sd->guild->max_storage; i++) { if(compare_item(&stor->items[i], item_data)) { if( amount > MAX_AMOUNT - stor->items[i].amount || ( data->stack.guildstorage && amount > data->stack.amount - stor->items[i].amount ) ) return 1; @@ -566,17 +567,18 @@ static int guild_storage_additem(struct map_session_data *sd, struct guild_stora } } } - //Add item - for(i=0;iitems[i].nameid;i++); - if(i>=MAX_GUILD_STORAGE) + // Add item + ARR_FIND(0, sd->guild->max_storage, i, stor->items[i].nameid == 0); + + if (i >= sd->guild->max_storage) return 1; memcpy(&stor->items[i],item_data,sizeof(stor->items[0])); stor->items[i].amount=amount; stor->storage_amount++; clif->storageitemadded(sd,&stor->items[i],i,amount); - clif->updatestorageamount(sd, stor->storage_amount, MAX_GUILD_STORAGE); + clif->updatestorageamount(sd, stor->storage_amount, sd->guild->max_storage); stor->dirty = true; return 0; } @@ -600,7 +602,7 @@ static int guild_storage_delitem(struct map_session_data *sd, struct guild_stora if(stor->items[n].amount==0){ memset(&stor->items[n],0,sizeof(stor->items[0])); stor->storage_amount--; - clif->updatestorageamount(sd, stor->storage_amount, MAX_GUILD_STORAGE); + clif->updatestorageamount(sd, stor->storage_amount, sd->guild->max_storage); } clif->storageitemremoved(sd,n,amount); stor->dirty = true; @@ -619,9 +621,10 @@ static int storage_guild_storageadd(struct map_session_data *sd, int index, int struct guild_storage *stor; nullpo_ret(sd); + nullpo_ret(sd->guild); nullpo_ret(stor=idb_get(gstorage->db,sd->status.guild_id)); - if (!stor->in_use || stor->storage_amount > MAX_GUILD_STORAGE) + if (!stor->in_use || stor->storage_amount > sd->guild->max_storage) return 0; if (index < 0 || index >= sd->status.inventorySize) @@ -659,12 +662,13 @@ static int storage_guild_storageget(struct map_session_data *sd, int index, int int flag; nullpo_ret(sd); + nullpo_ret(sd->guild); nullpo_ret(stor=idb_get(gstorage->db,sd->status.guild_id)); if(!stor->in_use) return 0; - if(index<0 || index>=MAX_GUILD_STORAGE) + if (index < 0 || index >= sd->guild->max_storage) return 0; if(stor->items[index].nameid <= 0) @@ -699,9 +703,10 @@ static int storage_guild_storageaddfromcart(struct map_session_data *sd, int ind struct guild_storage *stor; nullpo_ret(sd); + nullpo_ret(sd->guild); nullpo_ret(stor=idb_get(gstorage->db,sd->status.guild_id)); - if (!stor->in_use || stor->storage_amount > MAX_GUILD_STORAGE) + if (!stor->in_use || stor->storage_amount > sd->guild->max_storage) return 0; if( index < 0 || index >= MAX_CART ) @@ -731,12 +736,13 @@ static int storage_guild_storagegettocart(struct map_session_data *sd, int index struct guild_storage *stor; nullpo_ret(sd); + nullpo_ret(sd->guild); nullpo_ret(stor=idb_get(gstorage->db,sd->status.guild_id)); if(!stor->in_use) return 0; - if(index<0 || index>=MAX_GUILD_STORAGE) + if (index < 0 || index >= sd->guild->max_storage) return 0; if(stor->items[index].nameid<=0) From 0543694cb703118ce566edafa59509b5f6475164 Mon Sep 17 00:00:00 2001 From: Haru Date: Thu, 16 Mar 2017 11:56:08 +0100 Subject: [PATCH 06/19] HPM Hooks Update Signed-off-by: Haru --- src/plugins/HPMHooking/HPMHooking.Defs.inc | 12 +++---- .../HPMHooking/HPMHooking_char.Hooks.inc | 32 +++++++++---------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/plugins/HPMHooking/HPMHooking.Defs.inc b/src/plugins/HPMHooking/HPMHooking.Defs.inc index 4ad047454a9..35c5c3aee67 100644 --- a/src/plugins/HPMHooking/HPMHooking.Defs.inc +++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc @@ -3394,8 +3394,8 @@ typedef int (*HPMHOOK_pre_inter_guild_save_timer) (int *tid, int64 *tick, int *i typedef int (*HPMHOOK_post_inter_guild_save_timer) (int retVal___, int tid, int64 tick, int id, intptr_t data); typedef int (*HPMHOOK_pre_inter_guild_removemember_tosql) (int *account_id, int *char_id); typedef int (*HPMHOOK_post_inter_guild_removemember_tosql) (int retVal___, int account_id, int char_id); -typedef int (*HPMHOOK_pre_inter_guild_tosql) (struct guild **g, int *flag); -typedef int (*HPMHOOK_post_inter_guild_tosql) (int retVal___, struct guild *g, int flag); +typedef bool (*HPMHOOK_pre_inter_guild_tosql) (struct guild **g, int *flag); +typedef bool (*HPMHOOK_post_inter_guild_tosql) (bool retVal___, struct guild *g, int flag); typedef struct guild* (*HPMHOOK_pre_inter_guild_fromsql) (int *guild_id); typedef struct guild* (*HPMHOOK_post_inter_guild_fromsql) (struct guild* retVal___, int guild_id); typedef int (*HPMHOOK_pre_inter_guild_castle_tosql) (struct guild_castle **gc); @@ -3672,10 +3672,10 @@ typedef int (*HPMHOOK_pre_inter_storage_tosql) (int *account_id, const struct st 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 bool (*HPMHOOK_pre_inter_storage_guild_storage_tosql) (int *guild_id, const struct guild_storage **p); -typedef bool (*HPMHOOK_post_inter_storage_guild_storage_tosql) (bool retVal___, int guild_id, const struct guild_storage *p); -typedef int (*HPMHOOK_pre_inter_storage_guild_storage_fromsql) (int *guild_id, struct guild_storage **p); -typedef int (*HPMHOOK_post_inter_storage_guild_storage_fromsql) (int retVal___, int guild_id, struct guild_storage *p); +typedef bool (*HPMHOOK_pre_inter_storage_guild_storage_tosql) (int *guild_id, const struct guild_storage **gstor); +typedef bool (*HPMHOOK_post_inter_storage_guild_storage_tosql) (bool retVal___, int guild_id, const struct guild_storage *gstor); +typedef int (*HPMHOOK_pre_inter_storage_guild_storage_fromsql) (int *guild_id, struct guild_storage **gstor); +typedef int (*HPMHOOK_post_inter_storage_guild_storage_fromsql) (int retVal___, int guild_id, struct guild_storage *gstor); typedef int (*HPMHOOK_pre_inter_storage_sql_init) (void); typedef int (*HPMHOOK_post_inter_storage_sql_init) (int retVal___); typedef void (*HPMHOOK_pre_inter_storage_sql_final) (void); diff --git a/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc index a25673c7cab..98fd4e007ea 100644 --- a/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc +++ b/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc @@ -6432,11 +6432,11 @@ int HP_inter_guild_removemember_tosql(int account_id, int char_id) { } return retVal___; } -int HP_inter_guild_tosql(struct guild *g, int flag) { +bool HP_inter_guild_tosql(struct guild *g, int flag) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if (HPMHooks.count.HP_inter_guild_tosql_pre > 0) { - int (*preHookFunc) (struct guild **g, int *flag); + bool (*preHookFunc) (struct guild **g, int *flag); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_inter_guild_tosql_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_inter_guild_tosql_pre[hIndex].func; @@ -6451,7 +6451,7 @@ int HP_inter_guild_tosql(struct guild *g, int flag) { retVal___ = HPMHooks.source.inter_guild.tosql(g, flag); } if (HPMHooks.count.HP_inter_guild_tosql_post > 0) { - int (*postHookFunc) (int retVal___, struct guild *g, int flag); + bool (*postHookFunc) (bool retVal___, struct guild *g, int flag); for (hIndex = 0; hIndex < HPMHooks.count.HP_inter_guild_tosql_post; hIndex++) { postHookFunc = HPMHooks.list.HP_inter_guild_tosql_post[hIndex].func; retVal___ = postHookFunc(retVal___, g, flag); @@ -9954,15 +9954,15 @@ int HP_inter_storage_fromsql(int account_id, struct storage_data *p) { } return retVal___; } -bool HP_inter_storage_guild_storage_tosql(int guild_id, const struct guild_storage *p) { +bool HP_inter_storage_guild_storage_tosql(int guild_id, const struct guild_storage *gstor) { int hIndex = 0; bool retVal___ = false; if (HPMHooks.count.HP_inter_storage_guild_storage_tosql_pre > 0) { - bool (*preHookFunc) (int *guild_id, const struct guild_storage **p); + bool (*preHookFunc) (int *guild_id, const struct guild_storage **gstor); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_inter_storage_guild_storage_tosql_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_inter_storage_guild_storage_tosql_pre[hIndex].func; - retVal___ = preHookFunc(&guild_id, &p); + retVal___ = preHookFunc(&guild_id, &gstor); } if (*HPMforce_return) { *HPMforce_return = false; @@ -9970,26 +9970,26 @@ bool HP_inter_storage_guild_storage_tosql(int guild_id, const struct guild_stora } } { - retVal___ = HPMHooks.source.inter_storage.guild_storage_tosql(guild_id, p); + retVal___ = HPMHooks.source.inter_storage.guild_storage_tosql(guild_id, gstor); } if (HPMHooks.count.HP_inter_storage_guild_storage_tosql_post > 0) { - bool (*postHookFunc) (bool retVal___, int guild_id, const struct guild_storage *p); + bool (*postHookFunc) (bool retVal___, int guild_id, const struct guild_storage *gstor); for (hIndex = 0; hIndex < HPMHooks.count.HP_inter_storage_guild_storage_tosql_post; hIndex++) { postHookFunc = HPMHooks.list.HP_inter_storage_guild_storage_tosql_post[hIndex].func; - retVal___ = postHookFunc(retVal___, guild_id, p); + retVal___ = postHookFunc(retVal___, guild_id, gstor); } } return retVal___; } -int HP_inter_storage_guild_storage_fromsql(int guild_id, struct guild_storage *p) { +int HP_inter_storage_guild_storage_fromsql(int guild_id, struct guild_storage *gstor) { int hIndex = 0; int retVal___ = 0; if (HPMHooks.count.HP_inter_storage_guild_storage_fromsql_pre > 0) { - int (*preHookFunc) (int *guild_id, struct guild_storage **p); + int (*preHookFunc) (int *guild_id, struct guild_storage **gstor); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_inter_storage_guild_storage_fromsql_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_inter_storage_guild_storage_fromsql_pre[hIndex].func; - retVal___ = preHookFunc(&guild_id, &p); + retVal___ = preHookFunc(&guild_id, &gstor); } if (*HPMforce_return) { *HPMforce_return = false; @@ -9997,13 +9997,13 @@ int HP_inter_storage_guild_storage_fromsql(int guild_id, struct guild_storage *p } } { - retVal___ = HPMHooks.source.inter_storage.guild_storage_fromsql(guild_id, p); + retVal___ = HPMHooks.source.inter_storage.guild_storage_fromsql(guild_id, gstor); } if (HPMHooks.count.HP_inter_storage_guild_storage_fromsql_post > 0) { - int (*postHookFunc) (int retVal___, int guild_id, struct guild_storage *p); + int (*postHookFunc) (int retVal___, int guild_id, struct guild_storage *gstor); for (hIndex = 0; hIndex < HPMHooks.count.HP_inter_storage_guild_storage_fromsql_post; hIndex++) { postHookFunc = HPMHooks.list.HP_inter_storage_guild_storage_fromsql_post[hIndex].func; - retVal___ = postHookFunc(retVal___, guild_id, p); + retVal___ = postHookFunc(retVal___, guild_id, gstor); } } return retVal___; From a6dfce627e5840bc4216c3fafb9d3392090ebcc1 Mon Sep 17 00:00:00 2001 From: panikon Date: Fri, 18 Jul 2014 22:10:01 -0300 Subject: [PATCH 07/19] Added basic support to dynamic guild storage - Changed guild_storage.items to a dynamic array. - Updated inter-server packets in order to send guild_storage.items dynamically Signed-off-by: Haru --- src/char/char.c | 7 +- src/char/int_storage.c | 38 +++++++---- src/char/mapif.c | 90 +++++++++++++++++++------- src/common/mmo.h | 17 +++-- src/map/atcommand.c | 4 +- src/map/clif.c | 6 +- src/map/intif.c | 108 ++++++++++++++++++++++--------- src/map/pc.c | 13 ++-- src/map/storage.c | 143 ++++++++++++++++++++++++++--------------- src/map/storage.h | 3 +- 10 files changed, 291 insertions(+), 138 deletions(-) diff --git a/src/char/char.c b/src/char/char.c index edab912d867..405be759758 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -746,12 +746,13 @@ static int char_getitemdata_from_sql(struct item *items, int max, int guid, enum StringBuf buf; struct item item = { 0 }; // temp storage variable - nullpo_retr(-1, items); + if (max > 0) + nullpo_retr(-1, items); Assert_retr(-1, guid > 0); - Assert_retr(-1, max > 0); // Initialize the array. - memset(items, 0x0, sizeof(struct item) * max); + if (max > 0) + memset(items, 0x0, sizeof(struct item) * max); switch (table) { case TABLE_INVENTORY: diff --git a/src/char/int_storage.c b/src/char/int_storage.c index 4871c27cff2..5922207935d 100644 --- a/src/char/int_storage.c +++ b/src/char/int_storage.c @@ -260,7 +260,7 @@ static bool inter_storage_guild_storage_tosql(int guild_id, const struct guild_s } SQL->FreeResult(inter->sql_handle); - int err_count = chr->memitemdata_to_sql(gstor->items, gstor->guild_id, TABLE_GUILD_STORAGE); + int err_count = chr->memitemdata_to_sql(gstor->items.data, gstor->guild_id, TABLE_GUILD_STORAGE); if (err_count != 0) { ShowError("guild_storage_tosql: Couldn't save storage item data! (GID: %d)\n", gstor->guild_id); return false; @@ -278,12 +278,14 @@ static bool inter_storage_guild_storage_tosql(int guild_id, const struct guild_s * @param[out] gstor Empty, allocated buffer to contain the loaded data. * @return Error code * @retval 0 in case of success + * + * @remark + * In case of errors, gstor->items.data is left NULL. */ static int inter_storage_guild_storage_fromsql(int guild_id, struct guild_storage *gstor) { StringBuf buf; char *data; - int num_rows; int i, j; nullpo_retr(1, gstor); @@ -310,14 +312,14 @@ static int inter_storage_guild_storage_fromsql(int guild_id, struct guild_storag Sql_ShowDebug(inter->sql_handle); StrBuf->Destroy(&buf); - num_rows = (int)SQL->NumRows(inter->sql_handle); - if (num_rows > MAX_GUILD_STORAGE) { - ShowError("guild_storage_fromsql: Too many items in storage for guild %d!\n", guild_id); - num_rows = MAX_GUILD_STORAGE; - } - - for (i = 0; i < num_rows && SQL_SUCCESS == SQL->NextRow(inter->sql_handle); ++i) { - struct item *item = &gstor->items[i]; + gstor->items.capacity = (int)SQL->NumRows(inter->sql_handle); + if (gstor->items.capacity > 0) + CREATE(gstor->items.data, struct item, gstor->items.capacity); + else + gstor->items.data = NULL; + + for (i = 0; i < gstor->items.capacity && SQL_SUCCESS == SQL->NextRow(inter->sql_handle); ++i) { + struct item *item = &gstor->items.data[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); @@ -341,10 +343,22 @@ static int inter_storage_guild_storage_fromsql(int guild_id, struct guild_storag item->option[j].value = atoi(data); } } - gstor->storage_amount = i; + gstor->items.amount = i; SQL->FreeResult(inter->sql_handle); - ShowInfo("guild storage load complete from DB - id: %d (total: %d)\n", guild_id, gstor->storage_amount); + if (gstor->items.amount < gstor->items.capacity) { + if (gstor->items.amount > 0) { + struct item *temp; + temp = aRealloc(gstor->items.data, sizeof(gstor->items.data[0])*gstor->items.amount); + if (temp != NULL) + gstor->items.data = temp; + } else { + aFree(gstor->items.data); + gstor->items.data = NULL; + } + gstor->items.capacity = gstor->items.amount; + } + ShowInfo("guild storage load complete from DB - id: %d (total: %d)\n", guild_id, gstor->items.amount); return 0; } diff --git a/src/char/mapif.c b/src/char/mapif.c index 7f2857b3bcf..e4fd3c4a33b 100644 --- a/src/char/mapif.c +++ b/src/char/mapif.c @@ -1776,23 +1776,49 @@ static void mapif_rodex_checkname(int fd, int reqchar_id, int target_char_id, in WFIFOSET(fd, 18 + NAME_LENGTH); } +/** + * Sends loaded guild storage to a map-server. + * + * Packets sent: + * 0x3818 .W .L .L .B .L .L {.P}* + * 0x3818 .W .L .L + * + * @param fd The map-server's fd. + * @param account_id The requesting character's account id. + * @param guild_id The requesting guild's ID. + * @param flag Additional options, passed through to the map server (1 = open storage) + * @return Error code + * @retval 0 in case of success. + */ static int mapif_load_guild_storage(int fd, int account_id, int guild_id, char flag) { if (SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT `guild_id` FROM `%s` WHERE `guild_id`='%d'", guild_db, guild_id)) { Sql_ShowDebug(inter->sql_handle); } else if (SQL->NumRows(inter->sql_handle) > 0) { // guild exists - WFIFOHEAD(fd, sizeof(struct guild_storage) + 13); - WFIFOW(fd, 0) = 0x3818; - WFIFOW(fd, 2) = sizeof(struct guild_storage)+13; - WFIFOL(fd, 4) = account_id; - WFIFOL(fd, 8) = guild_id; - WFIFOB(fd, 12) = flag; //1 open storage, 0 don't open - inter_storage->guild_storage_fromsql(guild_id, WFIFOP(fd, 13)); - WFIFOSET(fd, WFIFOW(fd, 2)); - return 0; + struct guild_storage *gs = aCalloc(1, sizeof(*gs)); + + if (inter_storage->guild_storage_fromsql(guild_id, gs) == 0) { + int size = 21 + sizeof gs->items.data[0] * gs->items.capacity; + WFIFOHEAD(fd, size); + WFIFOW(fd, 0) = 0x3818; + WFIFOW(fd, 2) = size; + WFIFOL(fd, 4) = account_id; + WFIFOL(fd, 8) = guild_id; + WFIFOB(fd, 12) = flag; + WFIFOL(fd, 13) = gs->items.capacity; + WFIFOL(fd, 17) = gs->items.amount; + if (gs->items.data != NULL) { + memcpy(WFIFOP(fd, 21), gs->items.data, sizeof gs->items.data[0] * gs->items.capacity); + aFree(gs->items.data); + } + WFIFOSET(fd, size); + aFree(gs); + return 0; + } + aFree(gs); } - // guild does not exist + // guild does not exist or there was an error SQL->FreeResult(inter->sql_handle); WFIFOHEAD(fd, 12); WFIFOW(fd, 0) = 0x3818; @@ -1946,7 +1972,7 @@ static int mapif_parse_LoadGuildStorage(int fd) * Parses a guild storage save request from the map server. * * @code{.unparsed} - * @packet 0x3019 [in] .W .L .L .P + * @packet 0x3019 [in] .W .L .L {.P}* * @endcode * * @attention If the size of packet 0x3019 changes, @@ -1961,21 +1987,41 @@ static int mapif_parse_LoadGuildStorage(int fd) **/ static int mapif_parse_SaveGuildStorage(int fd) { - int guild_id; - int len; - RFIFOHEAD(fd); - guild_id = RFIFOL(fd, 8); - len = RFIFOW(fd, 2); + int len = RFIFOW(fd, 2); + int account_id = RFIFOL(fd, 4); + int guild_id = RFIFOL(fd, 8); + int storage_capacity = RFIFOL(fd, 12); + int storage_amount = RFIFOL(fd, 16); + + int expected = 20 + sizeof(struct item) * storage_capacity; + if (expected != len) { + ShowError("mapif_parse_SaveGuildStorage: data size mismatch: %d != %d\n", len, expected); + + mapif->save_guild_storage_ack(fd, account_id, guild_id, 1); + return 1; + } - if (sizeof(struct guild_storage) != len - 12) { - ShowError("inter storage: data size mismatch: %d != %"PRIuS"\n", len - 12, sizeof(struct guild_storage)); - } else if (inter_storage->guild_storage_tosql(guild_id, RFIFOP(fd, 12))) { - mapif->save_guild_storage_ack(fd, RFIFOL(fd, 4), guild_id, 0); - return 0; + struct guild_storage gstor = { 0 }; + + if (storage_capacity > 0) { + gstor.items.data = aCalloc(storage_capacity, sizeof gstor.items.data[0]); + memcpy(&gstor.items.data, RFIFOP(fd, 20), sizeof gstor.items.data[0] * storage_capacity); + } + gstor.items.amount = storage_amount; + gstor.items.capacity = storage_capacity; + gstor.guild_id = guild_id; + + if (!inter_storage->guild_storage_tosql(guild_id, &gstor)) { + if (gstor.items.data != NULL) + aFree(gstor.items.data); + mapif->save_guild_storage_ack(fd, account_id, guild_id, 1); + return 1; } - mapif->save_guild_storage_ack(fd, RFIFOL(fd, 4), guild_id, 1); + if (gstor.items.data != NULL) + aFree(gstor.items.data); + mapif->save_guild_storage_ack(fd, RFIFOL(fd, 4), guild_id, 0); return 0; } diff --git a/src/common/mmo.h b/src/common/mmo.h index 0342af78606..93004081212 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -623,12 +623,15 @@ struct storage_data { }; struct guild_storage { - int guild_id; - bool in_use; ///< Whether storage is in use by other guild members - bool dirty; ///< Whether the struct was modified and needs to be saved - bool locked; ///< Whenever item retrieval is happening and the storage can't be accessed - short storage_amount; - struct item items[MAX_GUILD_STORAGE]; + int guild_id; ///< Owner guild ID + bool in_use; ///< Whether storage is in use by other guild members + bool dirty; ///< Whether the struct was modified and needs to be saved + bool locked; ///< Whenever item retrieval is happening and the storage can't be accessed + struct { + int amount; ///< Currently stored items (Note: the array is not compacted!) + int capacity; ///< Current size of the data array + struct item *data; ///< Data array + } items; ///< Items }; /** @@ -928,7 +931,7 @@ struct guild { int16 connect_member; ///< Current online members int16 max_member; ///< Total guild member slots int16 average_lv; ///< Average level of guild members - int16 max_storage; ///< Maximum guild storage size + int16 max_storage; ///< Current guild storage capacity (note: NOT the same as gstor->items.capacity) uint64 exp; ///< Current guild experience unsigned int next_exp; ///< Experience needed for the next level int skill_point; ///< Available skill points diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 9991e0522a4..e15716b11ef 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -5580,10 +5580,10 @@ ACMD(cleargstorage) return false; } - j = guild_storage->storage_amount; + j = guild_storage->items.capacity; guild_storage->locked = true; // Lock @gstorage: do not allow any item to be retrieved or stored from any guild member for (i = 0; i < j; ++i) { - gstorage->delitem(sd, guild_storage, i, guild_storage->items[i].amount); + gstorage->delitem(sd, guild_storage, i, guild_storage->items.data[i].amount); } gstorage->close(sd); guild_storage->locked = false; // Cleaning done, release lock diff --git a/src/map/clif.c b/src/map/clif.c index f1fdba87469..1b69d7f1377 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -9448,9 +9448,9 @@ static void clif_refresh_storagewindow(struct map_session_data *sd) sd->status.account_id, sd->status.guild_id); return; } - storage->sortitem(gstor->items, ARRAYLENGTH(gstor->items)); - clif->guildStorageList(sd, gstor->items, ARRAYLENGTH(gstor->items)); - clif->updatestorageamount(sd, gstor->storage_amount, sd->guild->max_storage); + storage->sortitem(gstor->items.data, gstor->items.capacity); + clif->guildStorageList(sd, gstor->items.data, gstor->items.capacity); + clif->updatestorageamount(sd, gstor->items.amount, sd->guild->max_storage); } } } diff --git a/src/map/intif.c b/src/map/intif.c index 03c2d83be44..d59df2ac5b4 100644 --- a/src/map/intif.c +++ b/src/map/intif.c @@ -448,7 +448,7 @@ static int intif_request_guild_storage(int account_id, int guild_id) * Sends guild storage information for saving to the character server. * * @code{.unparsed} - * @packet 0x3019 [out] .W .L .L .P + * @packet 0x3019 [out] .W .L .L {.P} * * @endcode * * @attention If the size of packet 0x3019 changes, @@ -461,19 +461,27 @@ static int intif_request_guild_storage(int account_id, int guild_id) * @param[in] gstor Pointer to the guild storage data containing the information to save. * @return Always 0. * - **/ + */ static int intif_send_guild_storage(int account_id, struct guild_storage *gstor) { + int size; + if (intif->CheckForCharServer()) - return 0; - nullpo_ret(gstor); - WFIFOHEAD(inter_fd,sizeof(struct guild_storage)+12); + return 1; + + nullpo_retr(1, gstor); + size = 20 + sizeof(gstor->items.data[0])*gstor->items.capacity; + + WFIFOHEAD(inter_fd, size); WFIFOW(inter_fd,0) = 0x3019; - WFIFOW(inter_fd,2) = (unsigned short)sizeof(struct guild_storage)+12; + WFIFOW(inter_fd,2) = size; WFIFOL(inter_fd,4) = account_id; WFIFOL(inter_fd,8) = gstor->guild_id; - memcpy( WFIFOP(inter_fd,12),gstor, sizeof(struct guild_storage) ); - WFIFOSET(inter_fd,WFIFOW(inter_fd,2)); + WFIFOL(inter_fd,12) = gstor->items.capacity; + WFIFOL(inter_fd,16) = gstor->items.amount; + if (gstor->items.data != NULL) + memcpy(WFIFOP(inter_fd, 20), gstor->items.data, sizeof(gstor->items.data[0])*gstor->items.capacity); + WFIFOSET(inter_fd, size); return 0; } @@ -1103,46 +1111,84 @@ static void intif_parse_Registers(int fd) pc->reg_received(sd); //Received all registry values, execute init scripts and what-not. [Skotlex] } +/** + * Loads received guild storage into memory. + * + * Expected packets: + * 0x3818 .W .L .L .B .L .L {.P}* + * 0x3818 .W .L .L + * 0: Don't open storage + * 1: Open storage + * + * @param fd The receiving fd. + */ static void intif_parse_LoadGuildStorage(int fd) { - struct guild_storage *gstor; - struct map_session_data *sd; - int guild_id, flag; + struct guild_storage *gstor = NULL; + struct map_session_data *sd = NULL; - guild_id = RFIFOL(fd,8); - flag = RFIFOL(fd,12); - if(guild_id <= 0) + int flag, storage_capacity, storage_amount, expected_size; + int account_id = RFIFOL(fd, 4); + int guild_id = RFIFOL(fd, 8); + + if (guild_id <= 0) + return; + + flag = RFIFOB(fd,12); + storage_capacity = RFIFOL(fd, 13); + storage_amount = RFIFOL(fd, 17); + if (storage_capacity < storage_amount) + storage_capacity = storage_amount; + + expected_size = 21 + (sizeof(gstor->items.data[0])*storage_capacity); + if (RFIFOW(fd,2) != expected_size) { + ShowError("intif_parse_LoadGuildStorage: data size mismatch! Expected: %d Received: %d\n", + expected_size, RFIFOW(fd,2)); return; - sd=map->id2sd( RFIFOL(fd,4) ); - if( flag ){ //If flag != 0, we attach a player and open the storage - if(sd==NULL){ - ShowError("intif_parse_LoadGuildStorage: user not found %u\n", RFIFOL(fd,4)); - return; - } } - gstor=gstorage->ensure(guild_id); - if(!gstor) { - ShowWarning("intif_parse_LoadGuildStorage: error guild_id %d not exist\n",guild_id); + + sd = map->id2sd(account_id); + // When flag is true a player should always be attached, otherwise it's not possible + // to open the storage later + if ((flag&1) == 1 && sd == NULL) // Player logged off/invalid data + return; + + gstor = gstorage->ensure(guild_id); + if (gstor == NULL) { + ShowWarning("intif_parse_LoadGuildStorage: Invalid guild_id (%d)!\n", guild_id); return; } if (gstor->in_use) { // Already open.. lets ignore this update - ShowWarning("intif_parse_LoadGuildStorage: storage received for a client already open (User %d:%d)\n", flag?sd->status.account_id:0, flag?sd->status.char_id:0); + ShowWarning("intif_parse_LoadGuildStorage: storage received for a client was already opened (User AID %d: CID %d)\n", + flag?sd->status.account_id:0, flag?sd->status.char_id:0); return; } + if (gstor->dirty) { // Already have storage, and it has been modified and not saved yet! Exploit! [Skotlex] - ShowWarning("intif_parse_LoadGuildStorage: received storage for an already modified non-saved storage! (User %d:%d)\n", flag?sd->status.account_id:0, flag?sd->status.char_id:0); + ShowWarning("intif_parse_LoadGuildStorage: received storage for an already modified non-saved storage! (User AID %d: CID%d)\n", + flag?sd->status.account_id:0, flag?sd->status.char_id:0); return; } - if (RFIFOW(fd,2)-13 != sizeof(struct guild_storage)) { - ShowError("intif_parse_LoadGuildStorage: data size mismatch %d != %"PRIuS"\n", RFIFOW(fd,2)-13, sizeof(struct guild_storage)); - gstor->in_use = false; - return; + + // Clear current storage information and fetch new data + gstor->in_use = false; + gstor->locked = false; + gstor->dirty = false; + gstor->items.capacity = max(storage_capacity, 1); + gstor->items.amount = storage_amount; + if (gstor->items.data != NULL) { + aFree(gstor->items.data); + } + gstor->items.data = aCalloc(gstor->items.capacity, sizeof(gstor->items.data[0])); + if (storage_capacity > 0) { + memcpy(gstor->items.data, RFIFOP(fd, 21), sizeof(gstor->items.data[0])*storage_capacity); } - memcpy(gstor,RFIFOP(fd,13),sizeof(struct guild_storage)); - if( flag ) + if ((flag&1) == 1) gstorage->open(sd); + + return; } // ACK guild_storage saved diff --git a/src/map/pc.c b/src/map/pc.c index bee66d727fb..89eb1d76372 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -10737,19 +10737,20 @@ static int pc_checkitem(struct map_session_data *sd) 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 < guild_storage->storage_amount; i++) { - if ((id = guild_storage->items[i].nameid) == 0) + for (i = 0; i < guild_storage->items.amount; i++) { + if ((id = guild_storage->items.data[i].nameid) == 0) continue; 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); + 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.data[i].amount, sd->status.char_id, sd->guild->guild_id); + gstorage->delitem(sd, guild_storage, i, guild_storage->items.data[i].amount); gstorage->close(sd); // force closing continue; } - if (guild_storage->items[i].unique_id == 0 && !itemdb->isstackable(id)) - guild_storage->items[i].unique_id = itemdb->unique_id(sd); + if (guild_storage->items.data[i].unique_id == 0 && !itemdb->isstackable(id)) + guild_storage->items.data[i].unique_id = itemdb->unique_id(sd); } } diff --git a/src/map/storage.c b/src/map/storage.c index 242f61dedf4..4fb97169af6 100644 --- a/src/map/storage.c +++ b/src/map/storage.c @@ -461,6 +461,13 @@ static struct DBData create_guildstorage(union DBKey key, va_list args) return DB->ptr2data(gs); } +/** + * Verifies if a guild's storage was already initialized, if not creates it. + * + * @param guild_id The target guild ID. + * @return a pointer to the guild's storage. + * @retval NULL in case of nonexistent guild. + */ static struct guild_storage *guild2storage_ensure(int guild_id) { struct guild_storage *gs = NULL; @@ -469,38 +476,51 @@ static struct guild_storage *guild2storage_ensure(int guild_id) return gs; } -static int guild_storage_delete(int guild_id) +/** + * Deletes a guild storage. + * + * @param guild_id The target guild ID. + */ +static void guild_storage_delete(int guild_id) { - idb_remove(gstorage->db,guild_id); - return 0; + struct guild_storage *gstor = idb_get(gstorage->db, guild_id); + if (gstor == NULL) + return; + + if (gstor->items.data != NULL) + aFree(gstor->items.data); + + idb_remove(gstorage->db, guild_id); } -/*========================================== - * Attempt to open guild storage for sd - * return - * 0 : success (open or req to create a new one) - * 1 : fail - * 2 : no guild for sd - *------------------------------------------*/ +/** + * Attempts to open guild storage for a character. + * + * @param sd The target character. + * @return Error code. + * @retval 0 success (open or req to create a new one). + * @retval 1 storage is already open (storage_flag). + * @retval 2 sd has no guild / guild information hasn't arrived yet. + */ static int storage_guild_storageopen(struct map_session_data *sd) { struct guild_storage *gstor; - nullpo_ret(sd); + nullpo_retr(2, sd); - if(sd->status.guild_id <= 0) + if (sd->status.guild_id <= 0 || sd->guild == NULL) return 2; if (sd->state.storage_flag != STORAGE_FLAG_CLOSED) - return 1; //Can't open both storages at a time. + return 1; // Can't open both storages at a time. - if( !pc_can_give_items(sd) ) { //check is this GM level can open guild storage and store items [Lupus] + if (!pc_can_give_items(sd)) { // check if this GM level can open guild storage and store items [Lupus] clif->message(sd->fd, msg_sd(sd,246)); // Your GM level doesn't authorize you to perform this action. return 1; } - if((gstor = idb_get(gstorage->db,sd->status.guild_id)) == NULL) { - intif->request_guild_storage(sd->status.account_id,sd->status.guild_id); + if ((gstor = idb_get(gstorage->db, sd->status.guild_id)) == NULL || gstor->items.data == NULL) { + intif->request_guild_storage(sd->status.account_id, sd->status.guild_id); return 0; } @@ -512,9 +532,9 @@ static int storage_guild_storageopen(struct map_session_data *sd) gstor->in_use = true; sd->state.storage_flag = STORAGE_FLAG_GUILD; - storage->sortitem(gstor->items, ARRAYLENGTH(gstor->items)); - clif->guildStorageList(sd, gstor->items, gstor->storage_amount); - clif->updatestorageamount(sd, gstor->storage_amount, sd->guild->max_storage); + storage->sortitem(gstor->items.data, gstor->items.capacity); + clif->guildStorageList(sd, gstor->items.data, gstor->items.capacity); + clif->updatestorageamount(sd, gstor->items.amount, sd->guild->max_storage); return 0; } @@ -556,12 +576,15 @@ static int guild_storage_additem(struct map_session_data *sd, struct guild_stora } if (itemdb->isstackable2(data)) { // Stackable - for (i = 0; i < sd->guild->max_storage; i++) { - if(compare_item(&stor->items[i], item_data)) { - if( amount > MAX_AMOUNT - stor->items[i].amount || ( data->stack.guildstorage && amount > data->stack.amount - stor->items[i].amount ) ) + for (i = 0; i < stor->items.capacity; i++) { + if (stor->items.data[i].nameid <= 0) + continue; + if (compare_item(&stor->items.data[i], item_data)) { + if (amount > MAX_AMOUNT - stor->items.data[i].amount + || (data->stack.guildstorage && amount > data->stack.amount - stor->items.data[i].amount)) return 1; - stor->items[i].amount+=amount; - clif->storageitemadded(sd,&stor->items[i],i,amount); + stor->items.data[i].amount += amount; + clif->storageitemadded(sd, &stor->items.data[i], i, amount); stor->dirty = true; return 0; } @@ -569,16 +592,18 @@ static int guild_storage_additem(struct map_session_data *sd, struct guild_stora } // Add item - ARR_FIND(0, sd->guild->max_storage, i, stor->items[i].nameid == 0); + ARR_FIND(0, stor->items.capacity, i, stor->items.data[i].nameid == 0); if (i >= sd->guild->max_storage) return 1; - - memcpy(&stor->items[i],item_data,sizeof(stor->items[0])); - stor->items[i].amount=amount; - stor->storage_amount++; - clif->storageitemadded(sd,&stor->items[i],i,amount); - clif->updatestorageamount(sd, stor->storage_amount, sd->guild->max_storage); + if (i == stor->items.capacity) + RECREATE(stor->items.data, struct item, ++stor->items.capacity); + + memcpy(&stor->items.data[i], item_data, sizeof(stor->items.data[i])); + stor->items.data[i].amount = amount; + stor->items.amount++; + clif->storageitemadded(sd,&stor->items.data[i], i, amount); + clif->updatestorageamount(sd, stor->items.amount, sd->guild->max_storage); stor->dirty = true; return 0; } @@ -595,14 +620,14 @@ static int guild_storage_delitem(struct map_session_data *sd, struct guild_stora nullpo_retr(1, stor); Assert_retr(1, n >= 0 && n < MAX_GUILD_STORAGE); - if(stor->items[n].nameid==0 || stor->items[n].amountitems.data[n].nameid == 0 || stor->items.data[n].amount < amount) return 1; - stor->items[n].amount-=amount; - if(stor->items[n].amount==0){ - memset(&stor->items[n],0,sizeof(stor->items[0])); - stor->storage_amount--; - clif->updatestorageamount(sd, stor->storage_amount, sd->guild->max_storage); + stor->items.data[n].amount -= amount; + if (stor->items.data[n].amount == 0) { + memset(&stor->items.data[n], 0, sizeof(stor->items.data[n])); + stor->items.amount--; + clif->updatestorageamount(sd, stor->items.amount, sd->guild->max_storage); } clif->storageitemremoved(sd,n,amount); stor->dirty = true; @@ -624,16 +649,16 @@ static int storage_guild_storageadd(struct map_session_data *sd, int index, int nullpo_ret(sd->guild); nullpo_ret(stor=idb_get(gstorage->db,sd->status.guild_id)); - if (!stor->in_use || stor->storage_amount > sd->guild->max_storage) + if (!stor->in_use || stor->items.amount > sd->guild->max_storage) return 0; if (index < 0 || index >= sd->status.inventorySize) return 0; - if( sd->status.inventory[index].nameid <= 0 ) + if (sd->status.inventory[index].nameid <= 0) return 0; - if( amount < 1 || amount > sd->status.inventory[index].amount ) + if (amount < 1 || amount > sd->status.inventory[index].amount) return 0; if (stor->locked) { @@ -641,7 +666,7 @@ static int storage_guild_storageadd(struct map_session_data *sd, int index, int return 0; } - if( gstorage->additem(sd,stor,&sd->status.inventory[index],amount) == 0 ) + if (gstorage->additem(sd, stor, &sd->status.inventory[index], amount) == 0) pc->delitem(sd, index, amount, 0, DELITEM_TOSTORAGE, LOG_TYPE_GSTORAGE); else clif->item_movefailed(sd, index); @@ -668,13 +693,13 @@ static int storage_guild_storageget(struct map_session_data *sd, int index, int if(!stor->in_use) return 0; - if (index < 0 || index >= sd->guild->max_storage) + if (index < 0 || index >= stor->items.capacity) return 0; - if(stor->items[index].nameid <= 0) + if (stor->items.data[index].nameid <= 0) return 0; - if(amount < 1 || amount > stor->items[index].amount) + if (amount < 1 || amount > stor->items.data[index].amount) return 0; if (stor->locked) { @@ -682,7 +707,7 @@ static int storage_guild_storageget(struct map_session_data *sd, int index, int return 0; } - if((flag = pc->additem(sd,&stor->items[index],amount,LOG_TYPE_GSTORAGE)) == 0) + if ((flag = pc->additem(sd, &stor->items.data[index], amount, LOG_TYPE_GSTORAGE)) == 0) gstorage->delitem(sd,stor,index,amount); else //inform fail clif->additem(sd,0,0,flag); @@ -706,7 +731,7 @@ static int storage_guild_storageaddfromcart(struct map_session_data *sd, int ind nullpo_ret(sd->guild); nullpo_ret(stor=idb_get(gstorage->db,sd->status.guild_id)); - if (!stor->in_use || stor->storage_amount > sd->guild->max_storage) + if (!stor->in_use || stor->items.amount > sd->guild->max_storage) return 0; if( index < 0 || index >= MAX_CART ) @@ -742,16 +767,16 @@ static int storage_guild_storagegettocart(struct map_session_data *sd, int index if(!stor->in_use) return 0; - if (index < 0 || index >= sd->guild->max_storage) + if (index < 0 || index >= stor->items.capacity) return 0; - if(stor->items[index].nameid<=0) + if (stor->items.data[index].nameid <= 0) return 0; - if(amount < 1 || amount > stor->items[index].amount) + if (amount < 1 || amount > stor->items.data[index].amount) return 0; - if(pc->cart_additem(sd,&stor->items[index],amount,LOG_TYPE_GSTORAGE)==0) + if (pc->cart_additem(sd, &stor->items.data[index], amount, LOG_TYPE_GSTORAGE) == 0) gstorage->delitem(sd,stor,index,amount); return 1; @@ -854,9 +879,24 @@ static void do_init_gstorage(bool minimal) gstorage->db = idb_alloc(DB_OPT_RELEASE_DATA); } +/** + * Destroys a guild storage. + * @see DBApply + */ +static int gstorage_final_sub(union DBKey key, struct DBData *data, va_list ap) +{ + struct guild_storage *gstor = DB->data2ptr(data); + if (gstor->items.data != NULL) + aFree(gstor->items.data); + return 0; +} + +/** + * Finalizes guild storage, freeing all memory. + */ static void do_final_gstorage(void) { - db_destroy(gstorage->db); + gstorage->db->destroy(gstorage->db, gstorage->final_sub); } void storage_defaults(void) @@ -887,6 +927,7 @@ void gstorage_defaults(void) /* */ gstorage->init = do_init_gstorage; gstorage->final = do_final_gstorage; + gstorage->final_sub = gstorage_final_sub; /* */ gstorage->ensure = guild2storage_ensure; gstorage->delete = guild_storage_delete; diff --git a/src/map/storage.h b/src/map/storage.h index c7cec3b0168..2003905431f 100644 --- a/src/map/storage.h +++ b/src/map/storage.h @@ -63,7 +63,8 @@ struct guild_storage_interface { void (*init) (bool minimal); void (*final) (void); /* */ - int (*delete) (int guild_id); + int (*final_sub) (union DBKey key, struct DBData *data, va_list ap); + void (*delete) (int guild_id); int (*open) (struct map_session_data *sd); int (*additem) (struct map_session_data *sd,struct guild_storage *stor,struct item *item_data,int amount); int (*delitem) (struct map_session_data *sd,struct guild_storage *stor,int n,int amount); From ac38844afa3eb2e11e645b5f02a7b65044b93e27 Mon Sep 17 00:00:00 2001 From: Haru Date: Thu, 16 Mar 2017 11:56:45 +0100 Subject: [PATCH 08/19] HPM Hooks Update Signed-off-by: Haru --- src/plugins/HPMHooking/HPMHooking.Defs.inc | 6 ++- .../HPMHooking_map.HPMHooksCore.inc | 4 ++ .../HPMHooking_map.HookingPoints.inc | 1 + .../HPMHooking/HPMHooking_map.Hooks.inc | 48 +++++++++++++++---- 4 files changed, 49 insertions(+), 10 deletions(-) diff --git a/src/plugins/HPMHooking/HPMHooking.Defs.inc b/src/plugins/HPMHooking/HPMHooking.Defs.inc index 35c5c3aee67..51ebd78e8f5 100644 --- a/src/plugins/HPMHooking/HPMHooking.Defs.inc +++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc @@ -3152,8 +3152,10 @@ typedef void (*HPMHOOK_pre_gstorage_init) (bool *minimal); typedef void (*HPMHOOK_post_gstorage_init) (bool minimal); typedef void (*HPMHOOK_pre_gstorage_final) (void); typedef void (*HPMHOOK_post_gstorage_final) (void); -typedef int (*HPMHOOK_pre_gstorage_delete) (int *guild_id); -typedef int (*HPMHOOK_post_gstorage_delete) (int retVal___, int guild_id); +typedef int (*HPMHOOK_pre_gstorage_final_sub) (union DBKey *key, struct DBData **data, va_list ap); +typedef int (*HPMHOOK_post_gstorage_final_sub) (int retVal___, union DBKey key, struct DBData *data, va_list ap); +typedef void (*HPMHOOK_pre_gstorage_delete) (int *guild_id); +typedef void (*HPMHOOK_post_gstorage_delete) (int guild_id); typedef int (*HPMHOOK_pre_gstorage_open) (struct map_session_data **sd); typedef int (*HPMHOOK_post_gstorage_open) (int retVal___, struct map_session_data *sd); typedef int (*HPMHOOK_pre_gstorage_additem) (struct map_session_data **sd, struct guild_storage **stor, struct item **item_data, int *amount); diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc index 73908beee65..4faa49fc8e3 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc @@ -2714,6 +2714,8 @@ struct { struct HPMHookPoint *HP_gstorage_init_post; struct HPMHookPoint *HP_gstorage_final_pre; struct HPMHookPoint *HP_gstorage_final_post; + struct HPMHookPoint *HP_gstorage_final_sub_pre; + struct HPMHookPoint *HP_gstorage_final_sub_post; struct HPMHookPoint *HP_gstorage_delete_pre; struct HPMHookPoint *HP_gstorage_delete_post; struct HPMHookPoint *HP_gstorage_open_pre; @@ -9829,6 +9831,8 @@ struct { int HP_gstorage_init_post; int HP_gstorage_final_pre; int HP_gstorage_final_post; + int HP_gstorage_final_sub_pre; + int HP_gstorage_final_sub_post; int HP_gstorage_delete_pre; int HP_gstorage_delete_post; int HP_gstorage_open_pre; diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc index f35d408f75e..281ac9096cd 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc @@ -1391,6 +1391,7 @@ struct HookingPointData HookingPoints[] = { { HP_POP(gstorage->ensure, HP_gstorage_ensure) }, { HP_POP(gstorage->init, HP_gstorage_init) }, { HP_POP(gstorage->final, HP_gstorage_final) }, + { HP_POP(gstorage->final_sub, HP_gstorage_final_sub) }, { HP_POP(gstorage->delete, HP_gstorage_delete) }, { HP_POP(gstorage->open, HP_gstorage_open) }, { HP_POP(gstorage->additem, HP_gstorage_additem) }, diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc index 3414de41521..bfaf5a700dd 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc @@ -35580,32 +35580,64 @@ void HP_gstorage_final(void) { } return; } -int HP_gstorage_delete(int guild_id) { +int HP_gstorage_final_sub(union DBKey key, struct DBData *data, va_list ap) { int hIndex = 0; int retVal___ = 0; + if (HPMHooks.count.HP_gstorage_final_sub_pre > 0) { + int (*preHookFunc) (union DBKey *key, struct DBData **data, va_list ap); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_gstorage_final_sub_pre; hIndex++) { + va_list ap___copy; va_copy(ap___copy, ap); + preHookFunc = HPMHooks.list.HP_gstorage_final_sub_pre[hIndex].func; + retVal___ = preHookFunc(&key, &data, ap___copy); + va_end(ap___copy); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return retVal___; + } + } + { + va_list ap___copy; va_copy(ap___copy, ap); + retVal___ = HPMHooks.source.gstorage.final_sub(key, data, ap___copy); + va_end(ap___copy); + } + if (HPMHooks.count.HP_gstorage_final_sub_post > 0) { + int (*postHookFunc) (int retVal___, union DBKey key, struct DBData *data, va_list ap); + for (hIndex = 0; hIndex < HPMHooks.count.HP_gstorage_final_sub_post; hIndex++) { + va_list ap___copy; va_copy(ap___copy, ap); + postHookFunc = HPMHooks.list.HP_gstorage_final_sub_post[hIndex].func; + retVal___ = postHookFunc(retVal___, key, data, ap___copy); + va_end(ap___copy); + } + } + return retVal___; +} +void HP_gstorage_delete(int guild_id) { + int hIndex = 0; if (HPMHooks.count.HP_gstorage_delete_pre > 0) { - int (*preHookFunc) (int *guild_id); + void (*preHookFunc) (int *guild_id); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_gstorage_delete_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_gstorage_delete_pre[hIndex].func; - retVal___ = preHookFunc(&guild_id); + preHookFunc(&guild_id); } if (*HPMforce_return) { *HPMforce_return = false; - return retVal___; + return; } } { - retVal___ = HPMHooks.source.gstorage.delete(guild_id); + HPMHooks.source.gstorage.delete(guild_id); } if (HPMHooks.count.HP_gstorage_delete_post > 0) { - int (*postHookFunc) (int retVal___, int guild_id); + void (*postHookFunc) (int guild_id); for (hIndex = 0; hIndex < HPMHooks.count.HP_gstorage_delete_post; hIndex++) { postHookFunc = HPMHooks.list.HP_gstorage_delete_post[hIndex].func; - retVal___ = postHookFunc(retVal___, guild_id); + postHookFunc(guild_id); } } - return retVal___; + return; } int HP_gstorage_open(struct map_session_data *sd) { int hIndex = 0; From 72f1314795dbc03b69fe24cc849b30d3547ec556 Mon Sep 17 00:00:00 2001 From: panikon Date: Fri, 18 Jul 2014 22:10:01 -0300 Subject: [PATCH 09/19] Implemented official guild storage (GD_GUILD_STORAGE) Signed-off-by: Haru --- conf/messages.conf | 3 ++- db/guild_skill_tree.txt | 1 + db/pre-re/skill_db.conf | 20 ++++++++++++++++++++ db/re/skill_db.conf | 20 ++++++++++++++++++++ doc/script_commands.txt | 14 ++++++-------- src/char/int_guild.c | 9 +++++++++ src/common/mmo.h | 23 ++++++++++++++++++----- src/map/atcommand.c | 11 +++++++++-- src/map/guild.c | 8 +++++++- src/map/storage.c | 6 ++++++ 10 files changed, 98 insertions(+), 17 deletions(-) diff --git a/conf/messages.conf b/conf/messages.conf index 761c1b63a4b..1d6a6e44676 100644 --- a/conf/messages.conf +++ b/conf/messages.conf @@ -349,7 +349,8 @@ // 334: Thirty-Four Castles 334: Total Domination -//335-342 FREE +335: Your guild doesn't have storage! +//336-342 FREE // Templates for @who output 343: Name: %s diff --git a/db/guild_skill_tree.txt b/db/guild_skill_tree.txt index 9c5d06c18df..9b836153fcb 100644 --- a/db/guild_skill_tree.txt +++ b/db/guild_skill_tree.txt @@ -26,3 +26,4 @@ 10012,1,10011,1,0,0,0,0,0,0,0,0 //GD_RESTORE#Restoration# 10013,1,10000,1,10002,1,10004,5,10010,1,10011,1 //GD_EMERGENCYCALL#Urgent Call# 10014,1,0,0,0,0,0,0,0,0,0,0 //GD_DEVELOPMENT#Permanent Development# +10016,5,0,0,0,0,0,0,0,0,0,0 //GD_GUILD_STORAGE#Guild Storage Expansion# diff --git a/db/pre-re/skill_db.conf b/db/pre-re/skill_db.conf index 9b62c8cbfdc..88f8bbfe04b 100644 --- a/db/pre-re/skill_db.conf +++ b/db/pre-re/skill_db.conf @@ -39501,4 +39501,24 @@ skill_db: ( } NumberOfHits: 0 }, +//{ +// Id: 10015 +// Name: "GD_ITEMEMERGENCYCALL" +// Description: "Unknown Skill" +// MaxLevel: 1 +// SkillInfo: { +// Guild: true +// } +// NumberOfHits: 0 +//}, +{ + Id: 10016 + Name: "GD_GUILD_STORAGE" + Description: "Guild Storage Expansion" + MaxLevel: 5 + SkillInfo: { + Guild: true + } + NumberOfHits: 0 +}, ) diff --git a/db/re/skill_db.conf b/db/re/skill_db.conf index a48a5827826..89a1f3ee618 100644 --- a/db/re/skill_db.conf +++ b/db/re/skill_db.conf @@ -40737,4 +40737,24 @@ conflicting with SJ_LIGHTOFMOON } NumberOfHits: 0 }, +//{ +// Id: 10015 +// Name: "GD_ITEMEMERGENCYCALL" +// Description: "Unknown Skill" +// MaxLevel: 1 +// SkillInfo: { +// Guild: true +// } +// NumberOfHits: 0 +//}, +{ + Id: 10016 + Name: "GD_GUILD_STORAGE" + Description: "Guild Storage Expansion" + MaxLevel: 5 + SkillInfo: { + Guild: true + } + NumberOfHits: 0 +}, ) diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 90108afd715..cee22d86e2a 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -6083,15 +6083,13 @@ Example: This function works the same as openstorage() but will open a guild storage window instead for the guild storage of the guild the invoking -character belongs to. This is a function because it returns a value - 0 if -the guild storage was opened successfully and 1 if it wasn't. (Notice, -it's a ZERO upon success.) -Since guild storage is only accessible to one character at one time, it -may fail if another character is accessing the guild storage at the same -time. +character belongs to. +Expected return values: -This will also fail and return 2 if the attached character does not belong -to any guild. + 0 Success (Opens storage) + 1 Storage is already open + 2 Player has no guild / guild information hasn't arrived yet + 3 Player's guild doesn't have GD_GUILD_STORAGE (only if OFFICIAL_GUILD_STORAGE is enabled - automatically enabled on PACKETVER >= 20131223) The mapflag 'nogstorage' when set to type '2' (or 3), will not open the guild storage. Unless the character group has the permission 'bypass_nostorage'. diff --git a/src/char/int_guild.c b/src/char/int_guild.c index ba310095af2..96d9a26447d 100644 --- a/src/char/int_guild.c +++ b/src/char/int_guild.c @@ -880,7 +880,12 @@ static int inter_guild_calcinfo(struct guild *g) g->next_exp = nextexp; // Set the max storage size +#ifdef OFFICIAL_GUILD_STORAGE + g->max_storage = inter_guild->checkskill(g, GD_GUILD_STORAGE)*100; +#else // ! OFFICIAL_GUILD_STORAGE g->max_storage = MAX_GUILD_STORAGE; +#endif // OFFICIAL_GUILD_STORAGE + // Set the max number of members, Guild Extension skill - currently adds 6 to max per skill lv. g->max_member = BASE_GUILD_SIZE + inter_guild->checkskill(g, GD_EXTENSION) * 6; if(g->max_member > MAX_GUILD) @@ -976,7 +981,11 @@ static struct guild *inter_guild_create(const char *name, const struct guild_mem g->average_lv = master->lv; g->connect_member = 1; g->guild_lv = 1; +#ifdef OFFICIAL_GUILD_STORAGE + g->max_storage = 0; +#else // ! OFFICIAL_GUILD_STORAGE g->max_storage = MAX_GUILD_STORAGE; +#endif // OFFICIAL_GUILD_STORAGE for(i=0;iskill[i].id=i + GD_SKILLBASE; diff --git a/src/common/mmo.h b/src/common/mmo.h index 93004081212..d2337b7f796 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -196,6 +196,10 @@ #error FIXED_INVENTORY_SIZE must be same or smaller than MAX_INVENTORY #endif +#if PACKETVER >= 20131223 + #define OFFICIAL_GUILD_STORAGE +#endif // PACKETVER >= 20131223 + //Max number of characters per account. Note that changing this setting alone is not enough if the client is not hexed to support more characters as well. #if PACKETVER >= 20100413 #ifndef MAX_CHARS @@ -237,7 +241,7 @@ #define MAX_SKILL_DB 1353 ///< Maximum number of skills in the skill DB (compacted array size) #endif #ifndef MAX_SKILL_ID -#define MAX_SKILL_ID 10015 // [Ind/Hercules] max used skill ID +#define MAX_SKILL_ID 10016 // [Ind/Hercules] max used skill ID #endif #ifndef MAX_SKILL_TREE // Update this max as necessary. 86 is the value needed for Expanded Super Novice. @@ -255,9 +259,16 @@ #ifndef MAX_STORAGE #define MAX_STORAGE 600 #endif -#ifndef MAX_GUILD_STORAGE -#define MAX_GUILD_STORAGE 600 -#endif +#ifndef OFFICIAL_GUILD_STORAGE + #ifndef MAX_GUILD_STORAGE + #define MAX_GUILD_STORAGE 600 + #endif +#else // ! OFFICIAL_GUILD_STORAGE + #ifdef MAX_GUILD_STORAGE + #error You cannot redefine MAX_GUILD_STORAGE when using the official guild storage system. + #endif + #define MAX_GUILD_STORAGE (-1) +#endif // OFFICIAL_GUILD_STORAGE #ifndef MAX_PARTY #define MAX_PARTY 12 #endif @@ -277,7 +288,7 @@ #define MAX_GUILDALLIANCE 16 #endif #ifndef MAX_GUILDSKILL -#define MAX_GUILDSKILL 15 // Increased max guild skills because of new skills [Sara-chan] +#define MAX_GUILDSKILL 17 // Increased max guild skills because of new skills [Sara-chan] #endif #ifndef MAX_GUILDLEVEL #define MAX_GUILDLEVEL 50 @@ -1148,6 +1159,8 @@ enum { GD_RESTORE=10012, GD_EMERGENCYCALL=10013, GD_DEVELOPMENT=10014, + GD_ITEMEMERGENCYCALL = 10015, + GD_GUILD_STORAGE = 10016, #ifndef GD_MAX GD_MAX, #endif diff --git a/src/map/atcommand.c b/src/map/atcommand.c index e15716b11ef..d3ef375fb9d 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -894,6 +894,8 @@ ACMD(storage) *------------------------------------------*/ ACMD(guildstorage) { + int retval; + if (!sd->status.guild_id) { clif->message(fd, msg_fd(fd,252)); // You are not in a guild. return false; @@ -917,8 +919,13 @@ ACMD(guildstorage) return false; } - if( gstorage->open(sd) ) { - clif->message(fd, msg_fd(fd,1201)); // Your guild's storage has already been opened by another member, try again later. + if ((retval = gstorage->open(sd)) != 0) { + if (retval == 2) + clif->message(fd, msg_fd(fd,252)); // You are not in a guild + else if (retval == 3) + clif->message(fd, msg_fd(fd,335)); // Your guild doesn't have storage! + else // retval == 1 or unknown results + clif->message(fd, msg_fd(fd,1201)); // Your guild's storage has already been opened by another member, try again later. return false; } diff --git a/src/map/guild.c b/src/map/guild.c index 16bdd9cee45..2299c91ef1a 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -1503,14 +1503,20 @@ static int guild_skillupack(int guild_id, uint16 skill_id, int account_id) if( sd != NULL ) { clif->skillup(sd,skill_id,g->skill[skill_id-GD_SKILLBASE].lv, 0); - /* Guild Aura handling */ switch( skill_id ) { + // Guild Aura handling case GD_LEADERSHIP: case GD_GLORYWOUNDS: case GD_SOULCOLD: case GD_HAWKEYES: guild->aura_refresh(sd,skill_id,g->skill[skill_id-GD_SKILLBASE].lv); break; + // Guild storage handling + case GD_GUILD_STORAGE: +#ifdef OFFICIAL_GUILD_STORAGE + g->max_storage = g->skill[skill_id-GD_SKILLBASE].lv * 100; +#endif // OFFICIAL_GUILD_STORAGE + break; } } diff --git a/src/map/storage.c b/src/map/storage.c index 4fb97169af6..5277b77b0b4 100644 --- a/src/map/storage.c +++ b/src/map/storage.c @@ -501,6 +501,7 @@ static void guild_storage_delete(int guild_id) * @retval 0 success (open or req to create a new one). * @retval 1 storage is already open (storage_flag). * @retval 2 sd has no guild / guild information hasn't arrived yet. + * @retval 3 sd's guild doesn't have GD_GUILD_STORAGE (msg_txt(335)) (if OFFICIAL_GUILD_STORAGE / PACKETVER >= 20131223) */ static int storage_guild_storageopen(struct map_session_data *sd) { @@ -514,6 +515,11 @@ static int storage_guild_storageopen(struct map_session_data *sd) if (sd->state.storage_flag != STORAGE_FLAG_CLOSED) return 1; // Can't open both storages at a time. +#ifdef OFFICIAL_GUILD_STORAGE + if (!guild->checkskill(sd->guild, GD_GUILD_STORAGE)) + return 3; // Can't open storage if guild has none +#endif // OFFICIAL_GUILD_STORAGE + if (!pc_can_give_items(sd)) { // check if this GM level can open guild storage and store items [Lupus] clif->message(sd->fd, msg_sd(sd,246)); // Your GM level doesn't authorize you to perform this action. return 1; From 80078b8adfbb4f4776f7103c9e0085279b21433c Mon Sep 17 00:00:00 2001 From: panikon Date: Fri, 18 Jul 2014 22:10:01 -0300 Subject: [PATCH 10/19] Added storage permissions to the enum guild_permission - Available in PACKETVER >= 20140205 Signed-off-by: Haru --- conf/messages.conf | 3 ++- doc/script_commands.txt | 1 + src/char/int_guild.c | 2 +- src/common/mmo.h | 14 ++++++++++---- src/map/atcommand.c | 2 ++ src/map/guild.c | 19 ++++++++++++++----- src/map/guild.h | 2 +- src/map/intif.c | 16 ++++++++++++---- src/map/intif.h | 2 +- src/map/storage.c | 9 +++++++++ 10 files changed, 53 insertions(+), 17 deletions(-) diff --git a/conf/messages.conf b/conf/messages.conf index 1d6a6e44676..af8330abd23 100644 --- a/conf/messages.conf +++ b/conf/messages.conf @@ -350,7 +350,8 @@ 334: Total Domination 335: Your guild doesn't have storage! -//336-342 FREE +336: You're not authorized to open your guild storage! +//337-342 FREE // Templates for @who output 343: Name: %s diff --git a/doc/script_commands.txt b/doc/script_commands.txt index cee22d86e2a..61c702831d9 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -6090,6 +6090,7 @@ Expected return values: 1 Storage is already open 2 Player has no guild / guild information hasn't arrived yet 3 Player's guild doesn't have GD_GUILD_STORAGE (only if OFFICIAL_GUILD_STORAGE is enabled - automatically enabled on PACKETVER >= 20131223) + 4 Player doesn't have permission to use storage (only on PACKETVER >= 20140205) The mapflag 'nogstorage' when set to type '2' (or 3), will not open the guild storage. Unless the character group has the permission 'bypass_nostorage'. diff --git a/src/char/int_guild.c b/src/char/int_guild.c index 96d9a26447d..3af8aee3eb7 100644 --- a/src/char/int_guild.c +++ b/src/char/int_guild.c @@ -967,7 +967,7 @@ static struct guild *inter_guild_create(const char *name, const struct guild_mem g->member[0].modified = GS_MEMBER_MODIFIED; // Set default positions - g->position[0].mode = GPERM_ALL; + g->position[0].mode = GPERM_DEFAULT; strcpy(g->position[0].name,"GuildMaster"); strcpy(g->position[MAX_GUILDPOSITION-1].name,"Newbie"); g->position[0].modified = g->position[MAX_GUILDPOSITION-1].modified = GS_POSITION_MODIFIED; diff --git a/src/common/mmo.h b/src/common/mmo.h index d2337b7f796..6597e539ccb 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -1136,10 +1136,16 @@ enum guild_member_info { //Change Member Infos }; enum guild_permission { // Guild permissions - GPERM_INVITE = 0x01, - GPERM_EXPEL = 0x10, - GPERM_ALL = GPERM_INVITE|GPERM_EXPEL, - GPERM_MASK = GPERM_ALL, + GPERM_INVITE = 0x001, + GPERM_EXPEL = 0x010, +#if PACKETVER >= 20140205 + GPERM_STORAGE = 0x100, + GPERM_ALL = GPERM_INVITE|GPERM_EXPEL|GPERM_STORAGE, +#else + GPERM_ALL = GPERM_INVITE|GPERM_EXPEL, +#endif + GPERM_MASK = GPERM_ALL, + GPERM_DEFAULT = GPERM_ALL, }; enum { diff --git a/src/map/atcommand.c b/src/map/atcommand.c index d3ef375fb9d..bb421b26bdf 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -924,6 +924,8 @@ ACMD(guildstorage) clif->message(fd, msg_fd(fd,252)); // You are not in a guild else if (retval == 3) clif->message(fd, msg_fd(fd,335)); // Your guild doesn't have storage! + else if (retval == 4) + clif->message(fd, msg_fd(fd,336)); // You're not authorized to open your guild storage! else // retval == 1 or unknown results clif->message(fd, msg_fd(fd,1201)); // Your guild's storage has already been opened by another member, try again later. return false; diff --git a/src/map/guild.c b/src/map/guild.c index 2299c91ef1a..ca206a9aaed 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -1247,16 +1247,25 @@ static int guild_memberposition_changed(struct guild *g, int idx, int pos) return 0; } -/*==================================================== - * Change guild title or member - *---------------------------------------------------*/ -static int guild_change_position(int guild_id, int idx, int mode, int exp_mode, const char *name) +/** + * Changes guild title or permission information of member with pos idx + * + * @param idx - Position id + * @param mode @see0x001 - Can invite + * @param mode 0x010 - Can expel + * @param mode 0x100 - Can use guild storage (PACKETVER >= 20140205) + * @param exp_mode - Exp tax (%) + * @param name - Title + * + * @retval true success + **/ +static bool guild_change_position(int guild_id, int idx, int mode, int exp_mode, const char *name) { struct guild_position p; nullpo_ret(name); exp_mode = cap_value(exp_mode, 0, battle_config.guild_exp_limit); - p.mode=mode&GPERM_MASK; + p.mode = mode&GPERM_MASK; p.exp_mode=exp_mode; safestrncpy(p.name,name,NAME_LENGTH); return intif->guild_position(guild_id,idx,&p); diff --git a/src/map/guild.h b/src/map/guild.h index d1ba7db530e..07b99fa48b8 100644 --- a/src/map/guild.h +++ b/src/map/guild.h @@ -129,7 +129,7 @@ struct guild_interface { int (*recv_memberinfoshort) (int guild_id, int account_id, int char_id, int online, int lv, int class, uint32 last_login); int (*change_memberposition) (int guild_id,int account_id,int char_id,short idx); int (*memberposition_changed) (struct guild *g,int idx,int pos); - int (*change_position) (int guild_id,int idx,int mode,int exp_mode,const char *name); + bool (*change_position) (int guild_id, int idx, int mode, int exp_mode, const char *name); int (*position_changed) (int guild_id, int idx, const struct guild_position *p); int (*change_notice) (struct map_session_data *sd,int guild_id,const char *mes1,const char *mes2); int (*notice_changed) (int guild_id,const char *mes1,const char *mes2); diff --git a/src/map/intif.c b/src/map/intif.c index d59df2ac5b4..f58e238f61c 100644 --- a/src/map/intif.c +++ b/src/map/intif.c @@ -835,12 +835,20 @@ static int intif_guild_change_memberinfo(int guild_id, int account_id, int char_ return 0; } -// Request a change of Guild title -static int intif_guild_position(int guild_id, int idx, struct guild_position *p) +/** + * Requests a change of Guild title. + * + * @param guild_id The guild ID. + * @param idx The guild position index. + * @param p The edited guild position data. + * @retval false in case of errors. + */ +static bool intif_guild_position(int guild_id, int idx, struct guild_position *p) { if (intif->CheckForCharServer()) - return 0; + return false; nullpo_ret(p); + WFIFOHEAD(inter_fd, sizeof(struct guild_position)+12); WFIFOW(inter_fd,0)=0x303b; WFIFOW(inter_fd,2)=sizeof(struct guild_position)+12; @@ -848,7 +856,7 @@ static int intif_guild_position(int guild_id, int idx, struct guild_position *p) WFIFOL(inter_fd,8)=idx; memcpy(WFIFOP(inter_fd,12),p,sizeof(struct guild_position)); WFIFOSET(inter_fd,WFIFOW(inter_fd,2)); - return 0; + return true; } // Request an update of Guildskill skill_id diff --git a/src/map/intif.h b/src/map/intif.h index bcdac249f28..36a326d994d 100644 --- a/src/map/intif.h +++ b/src/map/intif.h @@ -83,7 +83,7 @@ struct intif_interface { int (*guild_change_gm) (int guild_id, const char *name, int len); int (*guild_change_basicinfo) (int guild_id, int type, const void *data, int len); int (*guild_change_memberinfo) (int guild_id, int account_id, int char_id, int type, const void *data, int len); - int (*guild_position) (int guild_id, int idx, struct guild_position *p); + bool (*guild_position) (int guild_id, int idx, struct guild_position *p); int (*guild_skillup) (int guild_id, uint16 skill_id, int account_id, int max); int (*guild_alliance) (int guild_id1, int guild_id2, int account_id1, int account_id2, int flag); int (*guild_notice) (int guild_id, const char *mes1, const char *mes2); diff --git a/src/map/storage.c b/src/map/storage.c index 5277b77b0b4..5a9ffd53146 100644 --- a/src/map/storage.c +++ b/src/map/storage.c @@ -502,6 +502,7 @@ static void guild_storage_delete(int guild_id) * @retval 1 storage is already open (storage_flag). * @retval 2 sd has no guild / guild information hasn't arrived yet. * @retval 3 sd's guild doesn't have GD_GUILD_STORAGE (msg_txt(335)) (if OFFICIAL_GUILD_STORAGE / PACKETVER >= 20131223) + * @retval 4 sd doesn't have permission to use storage (msg_txt(336)) (PACKETVER >= 20140205) */ static int storage_guild_storageopen(struct map_session_data *sd) { @@ -520,6 +521,14 @@ static int storage_guild_storageopen(struct map_session_data *sd) return 3; // Can't open storage if guild has none #endif // OFFICIAL_GUILD_STORAGE +#if PACKETVER >= 20140205 + { + int pos; + if ((pos = guild->getposition(sd->guild, sd)) < 0 || (sd->guild->position[pos].mode & GPERM_STORAGE) == 0) + return 4; // Doesn't have permission + } +#endif // PACKETVER >= 20140205 + if (!pc_can_give_items(sd)) { // check if this GM level can open guild storage and store items [Lupus] clif->message(sd->fd, msg_sd(sd,246)); // Your GM level doesn't authorize you to perform this action. return 1; From 639f130b2bd8be20bd3e1d545dcaa6ff6cd9ab64 Mon Sep 17 00:00:00 2001 From: Haru Date: Thu, 16 Mar 2017 11:57:37 +0100 Subject: [PATCH 11/19] HPM Hooks Update Signed-off-by: Haru --- src/plugins/HPMHooking/HPMHooking.Defs.inc | 8 ++++---- src/plugins/HPMHooking/HPMHooking_map.Hooks.inc | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/plugins/HPMHooking/HPMHooking.Defs.inc b/src/plugins/HPMHooking/HPMHooking.Defs.inc index 51ebd78e8f5..60682c8707e 100644 --- a/src/plugins/HPMHooking/HPMHooking.Defs.inc +++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc @@ -3052,8 +3052,8 @@ typedef int (*HPMHOOK_pre_guild_change_memberposition) (int *guild_id, int *acco typedef int (*HPMHOOK_post_guild_change_memberposition) (int retVal___, int guild_id, int account_id, int char_id, short idx); typedef int (*HPMHOOK_pre_guild_memberposition_changed) (struct guild **g, int *idx, int *pos); typedef int (*HPMHOOK_post_guild_memberposition_changed) (int retVal___, struct guild *g, int idx, int pos); -typedef int (*HPMHOOK_pre_guild_change_position) (int *guild_id, int *idx, int *mode, int *exp_mode, const char **name); -typedef int (*HPMHOOK_post_guild_change_position) (int retVal___, int guild_id, int idx, int mode, int exp_mode, const char *name); +typedef bool (*HPMHOOK_pre_guild_change_position) (int *guild_id, int *idx, int *mode, int *exp_mode, const char **name); +typedef bool (*HPMHOOK_post_guild_change_position) (bool retVal___, int guild_id, int idx, int mode, int exp_mode, const char *name); typedef int (*HPMHOOK_pre_guild_position_changed) (int *guild_id, int *idx, const struct guild_position **p); typedef int (*HPMHOOK_post_guild_position_changed) (int retVal___, int guild_id, int idx, const struct guild_position *p); typedef int (*HPMHOOK_pre_guild_change_notice) (struct map_session_data **sd, int *guild_id, const char **mes1, const char **mes2); @@ -3742,8 +3742,8 @@ typedef int (*HPMHOOK_pre_intif_guild_change_basicinfo) (int *guild_id, int *typ typedef int (*HPMHOOK_post_intif_guild_change_basicinfo) (int retVal___, int guild_id, int type, const void *data, int len); typedef int (*HPMHOOK_pre_intif_guild_change_memberinfo) (int *guild_id, int *account_id, int *char_id, int *type, const void **data, int *len); typedef int (*HPMHOOK_post_intif_guild_change_memberinfo) (int retVal___, int guild_id, int account_id, int char_id, int type, const void *data, int len); -typedef int (*HPMHOOK_pre_intif_guild_position) (int *guild_id, int *idx, struct guild_position **p); -typedef int (*HPMHOOK_post_intif_guild_position) (int retVal___, int guild_id, int idx, struct guild_position *p); +typedef bool (*HPMHOOK_pre_intif_guild_position) (int *guild_id, int *idx, struct guild_position **p); +typedef bool (*HPMHOOK_post_intif_guild_position) (bool retVal___, int guild_id, int idx, struct guild_position *p); typedef int (*HPMHOOK_pre_intif_guild_skillup) (int *guild_id, uint16 *skill_id, int *account_id, int *max); typedef int (*HPMHOOK_post_intif_guild_skillup) (int retVal___, int guild_id, uint16 skill_id, int account_id, int max); typedef int (*HPMHOOK_pre_intif_guild_alliance) (int *guild_id1, int *guild_id2, int *account_id1, int *account_id2, int *flag); diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc index bfaf5a700dd..5a8347df494 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc @@ -34211,11 +34211,11 @@ int HP_guild_memberposition_changed(struct guild *g, int idx, int pos) { } return retVal___; } -int HP_guild_change_position(int guild_id, int idx, int mode, int exp_mode, const char *name) { +bool HP_guild_change_position(int guild_id, int idx, int mode, int exp_mode, const char *name) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if (HPMHooks.count.HP_guild_change_position_pre > 0) { - int (*preHookFunc) (int *guild_id, int *idx, int *mode, int *exp_mode, const char **name); + bool (*preHookFunc) (int *guild_id, int *idx, int *mode, int *exp_mode, const char **name); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_guild_change_position_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_guild_change_position_pre[hIndex].func; @@ -34230,7 +34230,7 @@ int HP_guild_change_position(int guild_id, int idx, int mode, int exp_mode, cons retVal___ = HPMHooks.source.guild.change_position(guild_id, idx, mode, exp_mode, name); } if (HPMHooks.count.HP_guild_change_position_post > 0) { - int (*postHookFunc) (int retVal___, int guild_id, int idx, int mode, int exp_mode, const char *name); + bool (*postHookFunc) (bool retVal___, int guild_id, int idx, int mode, int exp_mode, const char *name); for (hIndex = 0; hIndex < HPMHooks.count.HP_guild_change_position_post; hIndex++) { postHookFunc = HPMHooks.list.HP_guild_change_position_post[hIndex].func; retVal___ = postHookFunc(retVal___, guild_id, idx, mode, exp_mode, name); @@ -38601,11 +38601,11 @@ int HP_intif_guild_change_memberinfo(int guild_id, int account_id, int char_id, } return retVal___; } -int HP_intif_guild_position(int guild_id, int idx, struct guild_position *p) { +bool HP_intif_guild_position(int guild_id, int idx, struct guild_position *p) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if (HPMHooks.count.HP_intif_guild_position_pre > 0) { - int (*preHookFunc) (int *guild_id, int *idx, struct guild_position **p); + bool (*preHookFunc) (int *guild_id, int *idx, struct guild_position **p); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_intif_guild_position_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_intif_guild_position_pre[hIndex].func; @@ -38620,7 +38620,7 @@ int HP_intif_guild_position(int guild_id, int idx, struct guild_position *p) { retVal___ = HPMHooks.source.intif.guild_position(guild_id, idx, p); } if (HPMHooks.count.HP_intif_guild_position_post > 0) { - int (*postHookFunc) (int retVal___, int guild_id, int idx, struct guild_position *p); + bool (*postHookFunc) (bool retVal___, int guild_id, int idx, struct guild_position *p); for (hIndex = 0; hIndex < HPMHooks.count.HP_intif_guild_position_post; hIndex++) { postHookFunc = HPMHooks.list.HP_intif_guild_position_post[hIndex].func; retVal___ = postHookFunc(retVal___, guild_id, idx, p); From a4ef8c0c8269292d8d548578e9681a27ace5f6d4 Mon Sep 17 00:00:00 2001 From: Haru Date: Thu, 5 Aug 2021 00:50:32 +0200 Subject: [PATCH 12/19] Make it possible to disable the official guild storage system for recent packetvers If DISABLE_OFFICIAL_GUILD_STORAGE is defined, the official guild storage system won't be enabled and the custom one will be left in place, as to not to require additional skill points to access existing storages. if the OFFICIAL_GUILD_STORAGE flag is enabled on the command line, it is sanity checked against the current PACKETVER to avoid enabling an unsupported configuration. Signed-off-by: Haru --- src/common/mmo.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/common/mmo.h b/src/common/mmo.h index 6597e539ccb..6b019e2b1c5 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -199,6 +199,13 @@ #if PACKETVER >= 20131223 #define OFFICIAL_GUILD_STORAGE #endif // PACKETVER >= 20131223 +#ifdef DISABLE_OFFICIAL_GUILD_STORAGE + #undef OFFICIAL_GUILD_STORAGE + #undef DISABLE_OFFICIAL_GUILD_STORAGE +#endif // DISABLE_OFFICIAL_GUILD_STORAGE +#if PACKETVER < 20131223 && defined(OFFICIAL_GUILD_STORAGE) + #error The current PACKETVER does not support the official guild storage system. +#endif // PACKETVER >= 20131223 //Max number of characters per account. Note that changing this setting alone is not enough if the client is not hexed to support more characters as well. #if PACKETVER >= 20100413 From 6f57fc8a9e8e225faae1e30ce8afd379b26c16cb Mon Sep 17 00:00:00 2001 From: Haru Date: Thu, 5 Aug 2021 01:30:04 +0200 Subject: [PATCH 13/19] Make chr->memitemdata_to_sql() compatible with dynamically sized storages such as the guild storage Signed-off-by: Haru --- src/char/char.c | 78 ++++++++++++++++++++++-------------------- src/char/char.h | 2 +- src/char/int_storage.c | 2 +- 3 files changed, 43 insertions(+), 39 deletions(-) diff --git a/src/char/char.c b/src/char/char.c index 405be759758..4f698d366f8 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -441,7 +441,7 @@ static int char_mmo_char_tosql(int char_id, struct mmo_charstatus *p) //map inventory data if( memcmp(p->inventory, cp->inventory, sizeof(p->inventory)) ) { - if (!chr->memitemdata_to_sql(p->inventory, p->char_id, TABLE_INVENTORY)) + if (!chr->memitemdata_to_sql(p->inventory, -1, p->char_id, TABLE_INVENTORY)) strcat(save_status, " inventory"); else errors++; @@ -449,7 +449,7 @@ static int char_mmo_char_tosql(int char_id, struct mmo_charstatus *p) //map cart data if( memcmp(p->cart, cp->cart, sizeof(p->cart)) ) { - if (!chr->memitemdata_to_sql(p->cart, p->char_id, TABLE_CART)) + if (!chr->memitemdata_to_sql(p->cart, -1, p->char_id, TABLE_CART)) strcat(save_status, " cart"); else errors++; @@ -840,41 +840,37 @@ static int char_getitemdata_from_sql(struct item *items, int max, int guid, enum /** * Saves an array of 'item' entries into the specified table. [Smokexyz/Hercules] - * @param[in] items The items array. - * @param[in] guid The character/account/guild ID (depending on table). - * @param[in] tableswitch The type of table (@see enum inventory_table_type). + * @param[in] items The items array. + * @param[in] current_size The current size of the items array (-1 to automatically use the maximum size, for fixed size inventories). + * @param[in] guid The character/account/guild ID (depending on table). + * @param[in] table The type of table (@see enum inventory_table_type). * @retval -1 in case of failure, or number of changes made within the table. */ -static int char_memitemdata_to_sql(const struct item *p_items, int guid, enum inventory_table_type table) +static int char_memitemdata_to_sql(const struct item *p_items, int current_size, int guid, enum inventory_table_type table) { - StringBuf buf; - int i = 0, j = 0; const char *tablename = NULL; const char *selectoption = NULL; bool has_favorite = false; - struct item *cp_items = NULL; // temp item storage variable - bool *matched_p = NULL; int total_updates = 0, total_deletes = 0, total_inserts = 0, total_changes = 0; - int item_count = 0, db_max = 0; - - nullpo_ret(p_items); + int max_size = 0; + int db_size = 0; switch (table) { case TABLE_INVENTORY: tablename = inventory_db; selectoption = "char_id"; has_favorite = true; - item_count = MAX_INVENTORY; + max_size = MAX_INVENTORY; break; case TABLE_CART: tablename = cart_db; selectoption = "char_id"; - item_count = MAX_CART; + max_size = MAX_CART; break; case TABLE_GUILD_STORAGE: tablename = guild_storage_db; selectoption = "guild_id"; - item_count = MAX_GUILD_STORAGE; + max_size = MAX_GUILD_STORAGE; break; case TABLE_STORAGE: default: @@ -882,22 +878,31 @@ static int char_memitemdata_to_sql(const struct item *p_items, int guid, enum in Assert_retr(-1, table); return -1; } + if (current_size == -1) + current_size = max_size; + + bool *matched_p = NULL; + if (current_size > 0) { + nullpo_ret(p_items); - cp_items = aCalloc(item_count, sizeof(struct item)); - matched_p = aCalloc(item_count, sizeof(bool)); + matched_p = aCalloc(current_size, sizeof(bool)); + } + StringBuf buf; StrBuf->Init(&buf); /** * If the storage table is not empty, check for items and replace or delete where needed. */ - if ((db_max = chr->getitemdata_from_sql(cp_items, item_count, guid, table)) > 0) { - int *deletes = aCalloc(db_max, sizeof(struct item)); + struct item *cp_items = aCalloc(max_size, sizeof(struct item)); + if ((db_size = chr->getitemdata_from_sql(cp_items, max_size, guid, table)) > 0) { + int *deletes = aCalloc(db_size, sizeof(struct item)); - for (i = 0; i < db_max; i++) { - struct item *cp_it = &cp_items[i]; + for (int i = 0; i < db_size; i++) { + const struct item *cp_it = &cp_items[i]; - ARR_FIND(0, item_count, j, + int j = 0; + ARR_FIND(0, current_size, j, matched_p[j] != true && p_items[j].nameid != 0 && cp_it->nameid == p_items[j].nameid @@ -905,19 +910,17 @@ static int char_memitemdata_to_sql(const struct item *p_items, int guid, enum in && memcmp(p_items[j].card, cp_it->card, sizeof(int) * MAX_SLOTS) == 0 && memcmp(p_items[j].option, cp_it->option, 5 * MAX_ITEM_OPTIONS) == 0); - if (j < item_count) { // Item found. + if (j < current_size) { // Item found. matched_p[j] = true; // Mark the item as matched. // If the amount has changed, set for replacement with current item properties. if (memcmp(cp_it, &p_items[j], sizeof(struct item)) != 0) { - int k = 0; - if (total_updates == 0) { StrBuf->Clear(&buf); StrBuf->Printf(&buf, "REPLACE INTO `%s` (`id`, `%s`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`", tablename, selectoption); - for (k = 0; k < MAX_SLOTS; k++) + for (int k = 0; k < MAX_SLOTS; k++) StrBuf->Printf(&buf, ", `card%d`", k); - for (k = 0; k < MAX_ITEM_OPTIONS; k++) + for (int 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`"); if (has_favorite) @@ -929,9 +932,9 @@ static int char_memitemdata_to_sql(const struct item *p_items, int guid, enum in StrBuf->Printf(&buf, "%s('%d', '%d', '%d', '%d', '%u', '%d', '%d', '%d'", total_updates > 0 ? ", " : "", cp_it->id, guid, p_items[j].nameid, p_items[j].amount, p_items[j].equip, p_items[j].identify, p_items[j].refine, p_items[j].attribute); - for (k = 0; k < MAX_SLOTS; k++) + for (int k = 0; k < MAX_SLOTS; k++) StrBuf->Printf(&buf, ", '%d'", p_items[j].card[k]); - for (k = 0; k < MAX_ITEM_OPTIONS; ++k) + for (int k = 0; k < MAX_ITEM_OPTIONS; ++k) StrBuf->Printf(&buf, ", '%d', '%d'", p_items[j].option[k].index, p_items[j].option[k].value); StrBuf->Printf(&buf, ", '%u', '%d', '%"PRIu64"'", p_items[j].expire_time, p_items[j].bound, p_items[j].unique_id); if (has_favorite) @@ -955,7 +958,7 @@ static int char_memitemdata_to_sql(const struct item *p_items, int guid, enum in if (total_deletes > 0) { StrBuf->Clear(&buf); StrBuf->Printf(&buf, "DELETE FROM `%s` WHERE `id` IN (", tablename); - for (i = 0; i < total_deletes; i++) + for (int i = 0; i < total_deletes; i++) StrBuf->Printf(&buf, "%s'%d'", i == 0 ? "" : ", ", deletes[i]); StrBuf->AppendStr(&buf, ");"); @@ -970,7 +973,7 @@ static int char_memitemdata_to_sql(const struct item *p_items, int guid, enum in /** * Check for new items and add if required. */ - for (i = 0; i < item_count; i++) { + for (int i = 0; i < current_size; i++) { const struct item *p_it = &p_items[i]; if (matched_p[i] || p_it->nameid == 0) @@ -979,9 +982,9 @@ static int char_memitemdata_to_sql(const struct item *p_items, int guid, enum in if (total_inserts == 0) { StrBuf->Clear(&buf); StrBuf->Printf(&buf, "INSERT INTO `%s` (`%s`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`, `unique_id`", tablename, selectoption); - for (j = 0; j < MAX_SLOTS; ++j) + for (int j = 0; j < MAX_SLOTS; ++j) StrBuf->Printf(&buf, ", `card%d`", j); - for (j = 0; j < MAX_ITEM_OPTIONS; ++j) + for (int j = 0; j < MAX_ITEM_OPTIONS; ++j) StrBuf->Printf(&buf, ", `opt_idx%d`, `opt_val%d`", j, j); if (has_favorite) StrBuf->AppendStr(&buf, ", `favorite`"); @@ -992,9 +995,9 @@ static int char_memitemdata_to_sql(const struct item *p_items, int guid, enum in total_inserts > 0 ? ", " : "", guid, 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) + for (int j = 0; j < MAX_SLOTS; ++j) StrBuf->Printf(&buf, ", '%d'", p_it->card[j]); - for (j = 0; j < MAX_ITEM_OPTIONS; ++j) + for (int j = 0; j < MAX_ITEM_OPTIONS; ++j) StrBuf->Printf(&buf, ", '%d', '%d'", p_it->option[j].index, p_it->option[j].value); if (has_favorite) @@ -1011,7 +1014,8 @@ static int char_memitemdata_to_sql(const struct item *p_items, int guid, enum in StrBuf->Destroy(&buf); aFree(cp_items); - aFree(matched_p); + if (matched_p != NULL) + aFree(matched_p); ShowInfo("%s save complete - guid: %d (replace: %d, insert: %d, delete: %d)\n", tablename, guid, total_updates, total_inserts, total_deletes); diff --git a/src/char/char.h b/src/char/char.h index 3345e4319e1..8bc6bec2400 100644 --- a/src/char/char.h +++ b/src/char/char.h @@ -142,7 +142,7 @@ struct char_interface { struct DBData (*create_charstatus) (union DBKey key, va_list args); int (*mmo_char_tosql) (int char_id, struct mmo_charstatus* p); int (*getitemdata_from_sql) (struct item *items, int max, int guid, enum inventory_table_type table); - int (*memitemdata_to_sql) (const struct item items[], int id, enum inventory_table_type table); + int (*memitemdata_to_sql) (const struct item items[], int current_size, int guid, enum inventory_table_type table); int (*mmo_gender) (const struct char_session_data *sd, const struct mmo_charstatus *p, char sex); int (*mmo_chars_fromsql) (struct char_session_data* sd, uint8* buf, int *count); int (*mmo_char_fromsql) (int char_id, struct mmo_charstatus* p, bool load_everything); diff --git a/src/char/int_storage.c b/src/char/int_storage.c index 5922207935d..58ab9f3e3b8 100644 --- a/src/char/int_storage.c +++ b/src/char/int_storage.c @@ -260,7 +260,7 @@ static bool inter_storage_guild_storage_tosql(int guild_id, const struct guild_s } SQL->FreeResult(inter->sql_handle); - int err_count = chr->memitemdata_to_sql(gstor->items.data, gstor->guild_id, TABLE_GUILD_STORAGE); + int err_count = chr->memitemdata_to_sql(gstor->items.data, gstor->items.capacity, gstor->guild_id, TABLE_GUILD_STORAGE); if (err_count != 0) { ShowError("guild_storage_tosql: Couldn't save storage item data! (GID: %d)\n", gstor->guild_id); return false; From f65017919e663e427dfb0bd016c7d2f152b70d94 Mon Sep 17 00:00:00 2001 From: Haru Date: Thu, 5 Aug 2021 01:59:48 +0200 Subject: [PATCH 14/19] Address pull request review comments Signed-off-by: Haru --- src/map/pc.c | 2 +- src/map/storage.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/map/pc.c b/src/map/pc.c index 89eb1d76372..627467bb6b8 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -10737,7 +10737,7 @@ static int pc_checkitem(struct map_session_data *sd) 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 < guild_storage->items.amount; i++) { + for (i = 0; i < guild_storage->items.capacity; i++) { if ((id = guild_storage->items.data[i].nameid) == 0) continue; diff --git a/src/map/storage.c b/src/map/storage.c index 5a9ffd53146..c042a90f558 100644 --- a/src/map/storage.c +++ b/src/map/storage.c @@ -635,7 +635,7 @@ static int guild_storage_delitem(struct map_session_data *sd, struct guild_stora nullpo_retr(1, stor); Assert_retr(1, n >= 0 && n < MAX_GUILD_STORAGE); - if (stor->items.data[n].nameid == 0 || stor->items.data[n].amount < amount) + if (n items.capacity || stor->items.data[n].nameid == 0 || stor->items.data[n].amount < amount) return 1; stor->items.data[n].amount -= amount; From d8de65a1afeb5ff72c7d190919c8c950135df8eb Mon Sep 17 00:00:00 2001 From: Haru Date: Thu, 5 Aug 2021 02:16:45 +0200 Subject: [PATCH 15/19] Fix the value of MAX_GUILD_STORAGE when the official guild storage is enabled It is now set to the maximum achieval guild storage size Signed-off-by: Haru --- src/common/mmo.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/common/mmo.h b/src/common/mmo.h index 6b019e2b1c5..11e9c343ecb 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -274,7 +274,8 @@ #ifdef MAX_GUILD_STORAGE #error You cannot redefine MAX_GUILD_STORAGE when using the official guild storage system. #endif - #define MAX_GUILD_STORAGE (-1) + // 100 slots * 5 skill levels + #define MAX_GUILD_STORAGE (100 * 5) #endif // OFFICIAL_GUILD_STORAGE #ifndef MAX_PARTY #define MAX_PARTY 12 @@ -663,7 +664,7 @@ struct guild_storage { * @anchor MAX_GUILD_STORAGE_ASSERT * **/ -STATIC_ASSERT(sizeof(struct guild_storage) + 12 <= 0xFFFF, "The maximum amount of item slots per guild storage is limited by the inter-server communication layout. Use a smaller value!"); +STATIC_ASSERT(20 + sizeof(struct item) * MAX_GUILD_STORAGE <= 0xFFFF, "The maximum amount of item slots per guild storage is limited by the inter-server communication layout. Use a smaller value!"); struct s_pet { int account_id; From 97174177d3900e8a99160bd645764c6cff4f6680 Mon Sep 17 00:00:00 2001 From: Haru Date: Thu, 5 Aug 2021 02:21:48 +0200 Subject: [PATCH 16/19] Add a GUILD_STORAGE_EXPANSION_STEP macro to control the amount of guild storage slots gained per skill level (when using the official guild storage) Signed-off-by: Haru --- src/char/int_guild.c | 4 +++- src/common/mmo.h | 8 ++++++-- src/map/guild.c | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/char/int_guild.c b/src/char/int_guild.c index 3af8aee3eb7..71a58fcc479 100644 --- a/src/char/int_guild.c +++ b/src/char/int_guild.c @@ -881,7 +881,9 @@ static int inter_guild_calcinfo(struct guild *g) // Set the max storage size #ifdef OFFICIAL_GUILD_STORAGE - g->max_storage = inter_guild->checkskill(g, GD_GUILD_STORAGE)*100; + g->max_storage = inter_guild->checkskill(g, GD_GUILD_STORAGE) * GUILD_STORAGE_EXPANSION_STEP; + if (g->max_storage > MAX_GUILD_STORAGE) + g->max_storage = MAX_GUILD_STORAGE; #else // ! OFFICIAL_GUILD_STORAGE g->max_storage = MAX_GUILD_STORAGE; #endif // OFFICIAL_GUILD_STORAGE diff --git a/src/common/mmo.h b/src/common/mmo.h index 11e9c343ecb..d6279e7dba6 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -270,12 +270,16 @@ #ifndef MAX_GUILD_STORAGE #define MAX_GUILD_STORAGE 600 #endif + #undef GUILD_STORAGE_EXPANSION_STEP #else // ! OFFICIAL_GUILD_STORAGE #ifdef MAX_GUILD_STORAGE #error You cannot redefine MAX_GUILD_STORAGE when using the official guild storage system. #endif - // 100 slots * 5 skill levels - #define MAX_GUILD_STORAGE (100 * 5) + #ifndef GUILD_STORAGE_EXPANSION_STEP + #define GUILD_STORAGE_EXPANSION_STEP 100 + #endif + // GUILD_STORAGE_EXPANSION_STEP slots * 5 skill levels + #define MAX_GUILD_STORAGE (GUILD_STORAGE_EXPANSION_STEP * 5) #endif // OFFICIAL_GUILD_STORAGE #ifndef MAX_PARTY #define MAX_PARTY 12 diff --git a/src/map/guild.c b/src/map/guild.c index ca206a9aaed..fc56b327e3c 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -1523,7 +1523,7 @@ static int guild_skillupack(int guild_id, uint16 skill_id, int account_id) // Guild storage handling case GD_GUILD_STORAGE: #ifdef OFFICIAL_GUILD_STORAGE - g->max_storage = g->skill[skill_id-GD_SKILLBASE].lv * 100; + g->max_storage = min(g->skill[skill_id-GD_SKILLBASE].lv * GUILD_STORAGE_EXPANSION_STEP, MAX_GUILD_STORAGE); #endif // OFFICIAL_GUILD_STORAGE break; } From 1fa8c749843f40530fa73a095cb4f6b49ff29ac3 Mon Sep 17 00:00:00 2001 From: Haru Date: Thu, 5 Aug 2021 02:23:18 +0200 Subject: [PATCH 17/19] Rename the guild storage migration script Signed-off-by: Haru --- sql-files/main.sql | 2 +- .../upgrades/{2016-11-26--17-26.sql => 2021-08-04--23-56.sql} | 4 ++-- sql-files/upgrades/index.txt | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename sql-files/upgrades/{2016-11-26--17-26.sql => 2021-08-04--23-56.sql} (71%) diff --git a/sql-files/main.sql b/sql-files/main.sql index 0b438e6ab56..511db714811 100644 --- a/sql-files/main.sql +++ b/sql-files/main.sql @@ -925,7 +925,6 @@ INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1467934919); -- 2016-07-0 INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1467935469); -- 2016-07-08--02-51.sql INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1475526420); -- 2016-10-03--20-27.sql INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1477434595); -- 2016-10-26--10-29.sql -INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1479662748); -- 2016-11-20--17-26.sql INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1488454834); -- 2017-03-02--11-40.sql INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1488744559); -- 2017-03-05--08-09.sql INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1489588190); -- 2017-03-15--14-29.sql @@ -955,6 +954,7 @@ INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1588301040); -- 2020-05-0 INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1589145060); -- 2020-05-10--23-11.sql INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1597467600); -- 2020-08-15--13-00.sql INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1612286353); -- 2021-05-03--10-19.sql +INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1628121360); -- 2021-08-04--23-56.sql -- -- Table structure for table `storage` diff --git a/sql-files/upgrades/2016-11-26--17-26.sql b/sql-files/upgrades/2021-08-04--23-56.sql similarity index 71% rename from sql-files/upgrades/2016-11-26--17-26.sql rename to sql-files/upgrades/2021-08-04--23-56.sql index 4fe19b27852..ae907ce016a 100644 --- a/sql-files/upgrades/2016-11-26--17-26.sql +++ b/sql-files/upgrades/2021-08-04--23-56.sql @@ -1,4 +1,4 @@ -#1479662748 +#1628121360 ALTER TABLE `guild_position` CHANGE `mode` `mode` SMALLINT UNSIGNED NOT NULL DEFAULT '0'; ALTER TABLE `guild` ADD `max_storage` SMALLINT UNSIGNED NOT NULL DEFAULT '0' AFTER `max_member`; -INSERT INTO `sql_updates` (`timestamp`) VALUES (1479662748); +INSERT INTO `sql_updates` (`timestamp`) VALUES (1628121360); diff --git a/sql-files/upgrades/index.txt b/sql-files/upgrades/index.txt index 34992c72d07..5f57c6b17cd 100644 --- a/sql-files/upgrades/index.txt +++ b/sql-files/upgrades/index.txt @@ -37,7 +37,6 @@ 2016-07-08--02-51.sql 2016-10-03--20-27.sql 2016-10-26--10-29.sql -2016-11-26--17-26.sql 2017-03-02--11-40.sql 2017-03-05--08-09.sql 2017-03-15--14-29.sql @@ -67,3 +66,4 @@ 2020-05-10--23-11.sql 2020-08-15--13-00.sql 2021-05-03--10-19.sql +2021-08-04--23-56.sql From ac36ae66ae688c3a195f4e22916459e922d7ed3f Mon Sep 17 00:00:00 2001 From: Haru Date: Thu, 5 Aug 2021 02:27:44 +0200 Subject: [PATCH 18/19] Update the skill ranges to include the guild storage skill Signed-off-by: Haru --- src/common/mmo.h | 2 +- src/map/skill.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/mmo.h b/src/common/mmo.h index d6279e7dba6..badd8c86251 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -245,7 +245,7 @@ #define MAX_CART 100 #endif #ifndef MAX_SKILL_DB -#define MAX_SKILL_DB 1353 ///< Maximum number of skills in the skill DB (compacted array size) +#define MAX_SKILL_DB 1355 ///< Maximum number of skills in the skill DB (compacted array size) #endif #ifndef MAX_SKILL_ID #define MAX_SKILL_ID 10016 // [Ind/Hercules] max used skill ID diff --git a/src/map/skill.c b/src/map/skill.c index 85adfe98702..ee43c6f5f29 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -99,7 +99,7 @@ static const struct { { HLIF_HEAL, MH_VOLCANIC_ASH }, { MS_BASH, MER_INVINCIBLEOFF2 }, { EL_CIRCLE_OF_FIRE, EL_STONE_RAIN }, - { GD_APPROVAL, GD_DEVELOPMENT }, + { GD_APPROVAL, GD_GUILD_STORAGE }, CUSTOM_SKILL_RANGES }; From 8867d3bb41205ae213147e97f3fa1aa728a7c8b3 Mon Sep 17 00:00:00 2001 From: Haru Date: Thu, 5 Aug 2021 02:42:42 +0200 Subject: [PATCH 19/19] HPM Hooks Update Signed-off-by: Haru --- src/plugins/HPMHooking/HPMHooking.Defs.inc | 4 ++-- src/plugins/HPMHooking/HPMHooking_char.Hooks.inc | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/plugins/HPMHooking/HPMHooking.Defs.inc b/src/plugins/HPMHooking/HPMHooking.Defs.inc index 60682c8707e..089120c3946 100644 --- a/src/plugins/HPMHooking/HPMHooking.Defs.inc +++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc @@ -534,8 +534,8 @@ typedef int (*HPMHOOK_pre_chr_mmo_char_tosql) (int *char_id, struct mmo_charstat typedef int (*HPMHOOK_post_chr_mmo_char_tosql) (int retVal___, int char_id, struct mmo_charstatus *p); typedef int (*HPMHOOK_pre_chr_getitemdata_from_sql) (struct item **items, int *max, int *guid, enum inventory_table_type *table); typedef int (*HPMHOOK_post_chr_getitemdata_from_sql) (int retVal___, struct item *items, int max, int guid, enum inventory_table_type table); -typedef int (*HPMHOOK_pre_chr_memitemdata_to_sql) (const struct item *items[], int *id, enum inventory_table_type *table); -typedef int (*HPMHOOK_post_chr_memitemdata_to_sql) (int retVal___, const struct item items[], int id, enum inventory_table_type table); +typedef int (*HPMHOOK_pre_chr_memitemdata_to_sql) (const struct item *items[], int *current_size, int *guid, enum inventory_table_type *table); +typedef int (*HPMHOOK_post_chr_memitemdata_to_sql) (int retVal___, const struct item items[], int current_size, int guid, enum inventory_table_type table); typedef int (*HPMHOOK_pre_chr_mmo_gender) (const struct char_session_data **sd, const struct mmo_charstatus **p, char *sex); typedef int (*HPMHOOK_post_chr_mmo_gender) (int retVal___, const struct char_session_data *sd, const struct mmo_charstatus *p, char sex); typedef int (*HPMHOOK_pre_chr_mmo_chars_fromsql) (struct char_session_data **sd, uint8 **buf, int **count); diff --git a/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc index 98fd4e007ea..7baca8ac189 100644 --- a/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc +++ b/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc @@ -555,15 +555,15 @@ int HP_chr_getitemdata_from_sql(struct item *items, int max, int guid, enum inve } return retVal___; } -int HP_chr_memitemdata_to_sql(const struct item items[], int id, enum inventory_table_type table) { +int HP_chr_memitemdata_to_sql(const struct item items[], int current_size, int guid, enum inventory_table_type table) { int hIndex = 0; int retVal___ = 0; if (HPMHooks.count.HP_chr_memitemdata_to_sql_pre > 0) { - int (*preHookFunc) (const struct item *items[], int *id, enum inventory_table_type *table); + int (*preHookFunc) (const struct item *items[], int *current_size, int *guid, enum inventory_table_type *table); *HPMforce_return = false; for (hIndex = 0; hIndex < HPMHooks.count.HP_chr_memitemdata_to_sql_pre; hIndex++) { preHookFunc = HPMHooks.list.HP_chr_memitemdata_to_sql_pre[hIndex].func; - retVal___ = preHookFunc(&items, &id, &table); + retVal___ = preHookFunc(&items, ¤t_size, &guid, &table); } if (*HPMforce_return) { *HPMforce_return = false; @@ -571,13 +571,13 @@ int HP_chr_memitemdata_to_sql(const struct item items[], int id, enum inventory_ } } { - retVal___ = HPMHooks.source.chr.memitemdata_to_sql(items, id, table); + retVal___ = HPMHooks.source.chr.memitemdata_to_sql(items, current_size, guid, table); } if (HPMHooks.count.HP_chr_memitemdata_to_sql_post > 0) { - int (*postHookFunc) (int retVal___, const struct item items[], int id, enum inventory_table_type table); + int (*postHookFunc) (int retVal___, const struct item items[], int current_size, int guid, enum inventory_table_type table); for (hIndex = 0; hIndex < HPMHooks.count.HP_chr_memitemdata_to_sql_post; hIndex++) { postHookFunc = HPMHooks.list.HP_chr_memitemdata_to_sql_post[hIndex].func; - retVal___ = postHookFunc(retVal___, items, id, table); + retVal___ = postHookFunc(retVal___, items, current_size, guid, table); } } return retVal___;