Initial release of the guild storage log (#3365)

Thanks to @aleos89 and @Everade
This commit is contained in:
Lemongrass3110 2018-10-10 17:51:49 +02:00 committed by GitHub
parent 10e7035beb
commit 55acdb9863
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 490 additions and 2 deletions

View File

@ -149,6 +149,7 @@ vending_table: vendings
vending_items_table: vending_items
market_table: market
roulette_table: db_roulette
guild_storage_log: guild_storage_log
// Use SQL item_db, mob_db and mob_skill_db for the map server? (yes/no)
use_sql_db: no

View File

@ -5502,6 +5502,32 @@ Return values:
---------------------------------------
*guildopenstorage_log({<char id>})
Opens the guild storage log window for the attached character or the given character id.
Possible return values:
GUILDSTORAGE_LOG_FINAL_SUCCESS Window was opened successfully.
GUILDSTORAGE_LOG_EMPTY Window was not opened, because no entries exist.
GUILDSTORAGE_LOG_FAILED Some database error occurred.
---------------------------------------
*guild_has_permission(<permission>{,<char id>})
Checks if the attached player or the player with the given character id has the given permission(s).
Permission can be a bitmask and allows to use multiple values at the same time.
Returns true if the player has all of the given permissions or false if the player does at least
miss one of the given permissions or is not in a guild at all.
Available permissions are:
GUILD_PERM_INVITE If a player is allowed to invite other players.
GUILD_PERM_EXPEL If a player is allowed to expel other guild members.
GUILD_PERM_STORAGE If a player is allowed to access the guild storage.
GUILD_PERM_ALL A combination of all permissions above.
---------------------------------------
*guildchangegm(<guild id>,<new master's name>)
This function will change the Guild Master of a guild. The ID is the guild's

View File

@ -0,0 +1,111 @@
//===== rAthena Script =======================================
//= Guild Warehouse Manager
//===== Description: =========================================
//= [Walkthrough Conversion]
//= Gives players access to their guild storage and log.
//===== Changelogs: ==========================================
//= 1.0 First Version. [Lemongrass]
//============================================================
- script GuildWarehouse -1,{
mes "[Warehouse Manager]";
mes "How are you? We are specialized in guild warehouses. This is our ^0000cdstory^000000:";
mes "Why can't guild members share a storage? We started off with that simple question.";
next;
mes "[Warehouse Manager]";
mes "You can open the warehouse for 1000 Zeny or look up the usage history of the guild.";
mes "How can I help you?";
next;
if( select( "Open guild warehouse:View warehouse usage history" ) == 1 ){
.@guildid = getcharid( 2 );
if( .@guildid == 0 ){
mes "[Warehouse Manager]";
mes "The guild storage is only available for guild members.";
close;
}
if( getgdskilllv( .@guildid, "GD_GUILD_STORAGE" ) == 0 || !guild_has_permission( GUILD_PERM_STORAGE ) ){
mes "[Warehouse Manager]";
mes "It seems that it is not yet possible for your guild to use the guild warehouse or you do not have access permissions for the warehouse.";
mes "Please come back after checking the guild skill and the permission to access the warehouse.";
close;
}
if( Zeny < 1000 ){
mes "[Warehouse Manager]";
mes "I am afraid you do not have enough money to settle the fee.";
mes "The fee is 1000 Zeny.";
close;
}
mes "[Warehouse Manager]";
mes "I will open the guild storage for you then. Have a memorable time!";
close2;
if( Zeny < 1000 ){
// Cheat prevention
end;
}
if( guildopenstorage() == GSTORAGE_OPEN ){
Zeny -= 1000;
end;
}else{
mes "[Warehouse Manager]";
mes "I am afraid someone else is using the warehouse right now.";
mes "Please try again after a while.";
close;
}
}else{
.@guildid = getcharid( 2 );
if( .@guildid == 0 ){
mes "[Warehouse Manager]";
mes "The guild storage is only available for guild members.";
close;
}
if( getgdskilllv( .@guildid, "GD_GUILD_STORAGE" ) == 0 || !guild_has_permission( GUILD_PERM_STORAGE ) ){
mes "[Warehouse Manager]";
mes "It seems that it is not yet possible for your guild to use the guild warehouse or you do not have access permissions for the warehouse.";
mes "Please come back after checking the guild skill and the permission to access the warehouse.";
close;
}
mes "[Warehouse Manager]";
mes "I will show you the usage history of the warehouse. Usage history will be retained for up to 3 months.";
mes "Have a memorable time!";
close2;
guildopenstorage_log();
end;
}
}
alberta,114,65,5 duplicate(GuildWarehouse) Guild Warehouse Manager#alberta 896
aldebaran,146,122,3 duplicate(GuildWarehouse) Guild Warehouse Manager#aldebaran 896
amatsu,100,156,5 duplicate(GuildWarehouse) Guild Warehouse Manager#amatsu 896
ayothaya,203,173,3 duplicate(GuildWarehouse) Guild Warehouse Manager#ayothaya 896
brasilis,204,227,3 duplicate(GuildWarehouse) Guild Warehouse Manager#brasilis 896
comodo,204,153,3 duplicate(GuildWarehouse) Guild Warehouse Manager#comodo 896
dewata,196,193,3 duplicate(GuildWarehouse) Guild Warehouse Manager#dewata 896
einbech,182,124,3 duplicate(GuildWarehouse) Guild Warehouse Manager#einbech 896
einbroch,238,203,3 duplicate(GuildWarehouse) Guild Warehouse Manager#einbroch 896
geffen,128,68,3 duplicate(GuildWarehouse) Guild Warehouse Manager#geffen 896
gonryun,164,127,5 duplicate(GuildWarehouse) Guild Warehouse Manager#gonryun 896
harboro1,288,212,5 duplicate(GuildWarehouse) Guild Warehouse Manager#harboro1 896
hugel,91,158,5 duplicate(GuildWarehouse) Guild Warehouse Manager#hugel 896
izlude,133,149,3 duplicate(GuildWarehouse) Guild Warehouse Manager#izlude 896
lighthalzen,162,102,3 duplicate(GuildWarehouse) Guild Warehouse Manager#lighthalzen 896
louyang,210,111,5 duplicate(GuildWarehouse) Guild Warehouse Manager#louyang 896
malaya,238,206,3 duplicate(GuildWarehouse) Guild Warehouse Manager#malaya 896
morocc,168,107,3 duplicate(GuildWarehouse) Guild Warehouse Manager#morocc 896
moscovia,211,200,5 duplicate(GuildWarehouse) Guild Warehouse Manager#moscovia 896
niflheim,200,184,3 duplicate(GuildWarehouse) Guild Warehouse Manager#niflheim 896
payon,180,106,3 duplicate(GuildWarehouse) Guild Warehouse Manager#payon 896
prontera,150,191,3 duplicate(GuildWarehouse) Guild Warehouse Manager#prontera 896
rachel,123,145,3 duplicate(GuildWarehouse) Guild Warehouse Manager#rachel 896
umbala,106,160,3 duplicate(GuildWarehouse) Guild Warehouse Manager#umbala 896
veins,205,130,3 duplicate(GuildWarehouse) Guild Warehouse Manager#veins 896
xmas,155,140,5 duplicate(GuildWarehouse) Guild Warehouse Manager#xmas 896
yuno,176,187,3 duplicate(GuildWarehouse) Guild Warehouse Manager#yuno 896

View File

@ -101,6 +101,7 @@ npc: npc/re/merchants/enchan_mora.txt
npc: npc/re/merchants/enchan_rockridge.txt
npc: npc/re/merchants/flute.txt
npc: npc/re/merchants/gld_mission_exchange.txt
npc: npc/re/merchants/guild_warehouse.txt
npc: npc/re/merchants/hd_refiner.txt
npc: npc/re/merchants/HorrorToyFactory_merchants.txt
npc: npc/re/merchants/inn.txt

View File

@ -580,6 +580,47 @@ CREATE TABLE IF NOT EXISTS `guild_storage` (
KEY `guild_id` (`guild_id`)
) ENGINE=MyISAM;
--
-- Table structure for table `guild_storage_log`
--
CREATE TABLE IF NOT EXISTS `guild_storage_log` (
`id` int(11) NOT NULL auto_increment,
`guild_id` int(11) unsigned NOT NULL default '0',
`time` datetime NOT NULL,
`char_id` int(11) NOT NULL default '0',
`name` varchar(24) NOT NULL default '',
`nameid` smallint(5) unsigned NOT NULL default '0',
`amount` int(11) NOT NULL default '1',
`identify` smallint(6) NOT NULL default '0',
`refine` tinyint(3) unsigned NOT NULL default '0',
`attribute` tinyint(4) unsigned NOT NULL default '0',
`card0` smallint(5) unsigned NOT NULL default '0',
`card1` smallint(5) unsigned NOT NULL default '0',
`card2` smallint(5) unsigned NOT NULL default '0',
`card3` smallint(5) unsigned NOT NULL default '0',
`option_id0` smallint(5) NOT NULL default '0',
`option_val0` smallint(5) NOT NULL default '0',
`option_parm0` tinyint(3) NOT NULL default '0',
`option_id1` smallint(5) NOT NULL default '0',
`option_val1` smallint(5) NOT NULL default '0',
`option_parm1` tinyint(3) NOT NULL default '0',
`option_id2` smallint(5) NOT NULL default '0',
`option_val2` smallint(5) NOT NULL default '0',
`option_parm2` tinyint(3) NOT NULL default '0',
`option_id3` smallint(5) NOT NULL default '0',
`option_val3` smallint(5) NOT NULL default '0',
`option_parm3` tinyint(3) NOT NULL default '0',
`option_id4` smallint(5) NOT NULL default '0',
`option_val4` smallint(5) NOT NULL default '0',
`option_parm4` tinyint(3) NOT NULL default '0',
`expire_time` int(11) unsigned NOT NULL default '0',
`unique_id` bigint(20) unsigned NOT NULL default '0',
`bound` tinyint(1) unsigned NOT NULL default '0',
PRIMARY KEY (`id`),
INDEX (`guild_id`)
) ENGINE=MyISAM AUTO_INCREMENT=1;
--
-- Table structure for table `homunculus`
--

View File

@ -0,0 +1,40 @@
--
-- Table structure for table `guild_storage_log`
--
CREATE TABLE IF NOT EXISTS `guild_storage_log` (
`id` int(11) NOT NULL auto_increment,
`guild_id` int(11) unsigned NOT NULL default '0',
`time` datetime NOT NULL,
`char_id` int(11) NOT NULL default '0',
`name` varchar(24) NOT NULL default '',
`nameid` smallint(5) unsigned NOT NULL default '0',
`amount` int(11) NOT NULL default '1',
`identify` smallint(6) NOT NULL default '0',
`refine` tinyint(3) unsigned NOT NULL default '0',
`attribute` tinyint(4) unsigned NOT NULL default '0',
`card0` smallint(5) unsigned NOT NULL default '0',
`card1` smallint(5) unsigned NOT NULL default '0',
`card2` smallint(5) unsigned NOT NULL default '0',
`card3` smallint(5) unsigned NOT NULL default '0',
`option_id0` smallint(5) NOT NULL default '0',
`option_val0` smallint(5) NOT NULL default '0',
`option_parm0` tinyint(3) NOT NULL default '0',
`option_id1` smallint(5) NOT NULL default '0',
`option_val1` smallint(5) NOT NULL default '0',
`option_parm1` tinyint(3) NOT NULL default '0',
`option_id2` smallint(5) NOT NULL default '0',
`option_val2` smallint(5) NOT NULL default '0',
`option_parm2` tinyint(3) NOT NULL default '0',
`option_id3` smallint(5) NOT NULL default '0',
`option_val3` smallint(5) NOT NULL default '0',
`option_parm3` tinyint(3) NOT NULL default '0',
`option_id4` smallint(5) NOT NULL default '0',
`option_val4` smallint(5) NOT NULL default '0',
`option_parm4` tinyint(3) NOT NULL default '0',
`expire_time` int(11) unsigned NOT NULL default '0',
`unique_id` bigint(20) unsigned NOT NULL default '0',
`bound` tinyint(1) unsigned NOT NULL default '0',
PRIMARY KEY (`id`),
INDEX (`guild_id`)
) ENGINE=MyISAM AUTO_INCREMENT=1;

View File

@ -705,13 +705,12 @@ struct guild_castle {
enum e_guild_permission {
GUILD_PERM_INVITE = 0x001,
GUILD_PERM_EXPEL = 0x010,
#if PACKETVER >= 20140205
GUILD_PERM_STORAGE = 0x100,
#if PACKETVER >= 20140205
GUILD_PERM_ALL = GUILD_PERM_INVITE|GUILD_PERM_EXPEL|GUILD_PERM_STORAGE,
#else
GUILD_PERM_ALL = GUILD_PERM_INVITE|GUILD_PERM_EXPEL,
#endif
GUILD_PERM_MASK = GUILD_PERM_ALL,
GUILD_PERM_DEFAULT = GUILD_PERM_ALL,
};

View File

@ -20501,6 +20501,53 @@ void clif_parse_private_airship_request( int fd, struct map_session_data* sd ){
#endif
}
/// Sends out the usage history of the guild storage
/// 09DA <size>.W <result>.W <count>.W { <id>.L <item id>.W <amount>.L <action>.B <refine>.L <unique id>.Q <identify>.B <item type>.W
/// { <card item id>.W }*4 <name>.24B <time>.24B <attribute>.B }*count (ZC_ACK_GUILDSTORAGE_LOG)
void clif_guild_storage_log( struct map_session_data* sd, std::vector<struct guild_log_entry>& log, enum e_guild_storage_log result ){
#if PACKETVER >= 20140205
nullpo_retv( sd );
int fd = sd->fd;
int size = 8;
int sub = 83;
if( result == GUILDSTORAGE_LOG_FINAL_SUCCESS ){
size += log.size() * sub;
}else{
log.clear();
}
WFIFOHEAD(fd, size);
WFIFOW(fd, 0) = 0x9DA;
WFIFOW(fd, 2) = size;
WFIFOW(fd, 4) = result;
WFIFOW(fd, 6) = (uint16)log.size();
if( result == GUILDSTORAGE_LOG_FINAL_SUCCESS ){
for (int offset = 8, i = 0; i < log.size(); i++, offset += sub) {
struct guild_log_entry& entry = log[i];
uint16 viewid = itemdb_viewid( entry.item.nameid );
WFIFOL(fd, offset) = entry.id;
WFIFOW(fd, offset + 4) = viewid > 0 ? viewid : entry.item.nameid;
WFIFOL(fd, offset + 6) = (uint16)(entry.amount > 0 ? entry.amount : (entry.amount * -1));
WFIFOB(fd, offset + 10) = entry.amount > 0; // action = true(put), false(get)
WFIFOL(fd, offset + 11) = entry.item.refine;
WFIFOQ(fd, offset + 15) = entry.item.unique_id;
WFIFOB(fd, offset + 23) = entry.item.identify;
WFIFOW(fd, offset + 24) = itemtype(entry.item.nameid);
clif_addcards(WFIFOP(fd, offset + 26), &entry.item);
safestrncpy(WFIFOCP(fd, offset + 34), entry.name, NAME_LENGTH);
safestrncpy(WFIFOCP(fd, offset + 34 + NAME_LENGTH), entry.time, NAME_LENGTH);
WFIFOB(fd, offset + 34 + 2 * NAME_LENGTH) = entry.item.attribute;
}
}
WFIFOSET(fd, size);
#endif
}
/*==========================================
* Main client packet processing function
*------------------------------------------*/

View File

@ -4,6 +4,8 @@
#ifndef CLIF_HPP
#define CLIF_HPP
#include <vector>
#include <stdarg.h>
#include "../common/cbasetypes.hpp"
@ -35,6 +37,8 @@ struct party_booking_ad_info;
struct sale_item_data;
struct mail_message;
struct achievement;
struct guild_log_entry;
enum e_guild_storage_log : uint16;
enum e_PacketDBVersion { // packet DB
MIN_PACKET_DB = 0x064,
@ -1095,4 +1099,6 @@ void clif_attendence_response( struct map_session_data *sd, int32 data );
void clif_weight_limit( struct map_session_data* sd );
void clif_guild_storage_log( struct map_session_data* sd, std::vector<struct guild_log_entry>& log, enum e_guild_storage_log result );
#endif /* CLIF_HPP */

View File

@ -2188,6 +2188,11 @@
packet(0x09DF,7); // ZC_ACK_WHISPER02
#endif
// 2014-02-05bRagexeRE
#if PACKETVER >= 20140205
packet(0x09DA,-1);
#endif
// 2014-10-16Ragexe
#if PACKETVER >= 20141016
packet(0x09DF,7);

View File

@ -87,6 +87,7 @@ char vendings_table[32] = "vendings";
char vending_items_table[32] = "vending_items";
char market_table[32] = "market";
char roulette_table[32] = "db_roulette";
char guild_storage_log_table[32] = "guild_storage_log";
// log database
char log_db_ip[32] = "127.0.0.1";
@ -4141,6 +4142,8 @@ int inter_config_read(const char *cfgName)
strcpy(market_table, w2);
else if (strcmpi(w1, "sales_table") == 0)
strcpy(sales_table, w2);
else if (strcmpi(w1, "guild_storage_log") == 0)
strcpy(guild_storage_log_table, w2);
else
//Map Server SQL DB
if(strcmpi(w1,"map_server_ip")==0)

View File

@ -1173,6 +1173,7 @@ extern char vendings_table[32];
extern char vending_items_table[32];
extern char market_table[32];
extern char roulette_table[32];
extern char guild_storage_log_table[32];
void do_shutdown(void);

View File

@ -9969,6 +9969,61 @@ BUILDIN_FUNC(guildopenstorage)
return SCRIPT_CMD_SUCCESS;
}
BUILDIN_FUNC(guildopenstorage_log){
#if PACKETVER < 20140205
ShowError( "buildin_guildopenstorage_log: This command requires PACKETVER 2014-02-05 or newer.\n" );
return SCRIPT_CMD_FAILURE;
#else
struct map_session_data* sd;
if( !script_charid2sd( 2, sd ) ){
return SCRIPT_CMD_FAILURE;
}
script_pushint( st, storage_guild_log_read( sd ) );
return SCRIPT_CMD_SUCCESS;
#endif
}
BUILDIN_FUNC(guild_has_permission){
struct map_session_data* sd;
if( !script_charid2sd( 3, sd ) ){
return SCRIPT_CMD_FAILURE;
}
int permission = script_getnum(st,2);
if( permission == 0 ){
ShowError( "buildin_guild_has_permission: No permission given.\n" );
return SCRIPT_CMD_FAILURE;
}
if( ( permission & GUILD_PERM_ALL ) == 0 ){
ShowError( "buildin_guild_has_permission: Invalid permission '%d'.\n", permission );
return SCRIPT_CMD_FAILURE;
}
if( !sd->guild ){
script_pushint( st, false );
return SCRIPT_CMD_SUCCESS;
}
int position = guild_getposition(sd);
if( position < 0 || ( sd->guild->position[position].mode&permission ) != permission ){
script_pushint( st, false );
return SCRIPT_CMD_SUCCESS;
}
script_pushint( st, true );
return SCRIPT_CMD_SUCCESS;
}
/*==========================================
* Make player use a skill trought item usage
*------------------------------------------*/
@ -24083,6 +24138,8 @@ struct script_function buildin_func[] = {
BUILDIN_DEF(gettimestr,"si?"),
BUILDIN_DEF(openstorage,""),
BUILDIN_DEF(guildopenstorage,""),
BUILDIN_DEF(guildopenstorage_log,"?"),
BUILDIN_DEF(guild_has_permission,"i?"),
BUILDIN_DEF(itemskill,"vi?"),
BUILDIN_DEF(produce,"i"),
BUILDIN_DEF(cooking,"i"),

View File

@ -7306,6 +7306,17 @@
export_constant(SKILLDMG_MAX);
export_constant(SKILLDMG_CASTER);
/* guild permissions */
export_constant(GUILD_PERM_INVITE);
export_constant(GUILD_PERM_EXPEL);
export_constant(GUILD_PERM_STORAGE);
export_constant(GUILD_PERM_ALL);
/* guild storage log */
export_constant(GUILDSTORAGE_LOG_FINAL_SUCCESS);
export_constant(GUILDSTORAGE_LOG_EMPTY);
export_constant(GUILDSTORAGE_LOG_FAILED);
#undef export_constant
#undef export_constant2
#undef export_parameter

View File

@ -627,6 +627,117 @@ char storage_guild_storageopen(struct map_session_data* sd)
return GSTORAGE_OPEN;
}
void storage_guild_log( struct map_session_data* sd, struct item* item, int16 amount ){
int i;
SqlStmt* stmt = SqlStmt_Malloc(mmysql_handle);
StringBuf buf;
StringBuf_Init(&buf);
StringBuf_Printf(&buf, "INSERT INTO `%s` (`time`, `guild_id`, `char_id`, `name`, `nameid`, `amount`, `identify`, `refine`, `attribute`, `unique_id`, `bound`", guild_storage_log_table);
for (i = 0; i < MAX_SLOTS; ++i)
StringBuf_Printf(&buf, ", `card%d`", i);
for (i = 0; i < MAX_ITEM_RDM_OPT; ++i) {
StringBuf_Printf(&buf, ", `option_id%d`", i);
StringBuf_Printf(&buf, ", `option_val%d`", i);
StringBuf_Printf(&buf, ", `option_parm%d`", i);
}
StringBuf_Printf(&buf, ") VALUES(NOW(),'%u','%u', '%s', '%d', '%d','%d','%d','%d','%" PRIu64 "','%d'",
sd->status.guild_id, sd->status.char_id, sd->status.name, item->nameid, amount, item->identify, item->refine,item->attribute, item->unique_id, item->bound);
for (i = 0; i < MAX_SLOTS; i++)
StringBuf_Printf(&buf, ",'%d'", item->card[i]);
for (i = 0; i < MAX_ITEM_RDM_OPT; i++)
StringBuf_Printf(&buf, ",'%d','%d','%d'", item->option[i].id, item->option[i].value, item->option[i].param);
StringBuf_Printf(&buf, ")");
if (SQL_SUCCESS != SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf)) || SQL_SUCCESS != SqlStmt_Execute(stmt))
SqlStmt_ShowDebug(stmt);
SqlStmt_Free(stmt);
StringBuf_Destroy(&buf);
}
enum e_guild_storage_log storage_guild_log_read_sub( struct map_session_data* sd, std::vector<struct guild_log_entry>& log, uint32 max ){
StringBuf buf;
int j;
StringBuf_Init(&buf);
StringBuf_AppendStr(&buf, "SELECT `id`, `time`, `name`, `amount`");
StringBuf_AppendStr(&buf, " , `nameid`, `identify`, `refine`, `attribute`, `expire_time`, `bound`, `unique_id`");
for (j = 0; j < MAX_SLOTS; ++j)
StringBuf_Printf(&buf, ", `card%d`", j);
for (j = 0; j < MAX_ITEM_RDM_OPT; ++j) {
StringBuf_Printf(&buf, ", `option_id%d`", j);
StringBuf_Printf(&buf, ", `option_val%d`", j);
StringBuf_Printf(&buf, ", `option_parm%d`", j);
}
StringBuf_Printf(&buf, " FROM `%s` WHERE `guild_id`='%u'", guild_storage_log_table, sd->status.guild_id );
StringBuf_Printf(&buf, " ORDER BY `time` DESC LIMIT %u", max);
SqlStmt* stmt = SqlStmt_Malloc(mmysql_handle);
if( SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf)) ||
SQL_ERROR == SqlStmt_Execute(stmt) )
{
SqlStmt_ShowDebug(stmt);
SqlStmt_Free(stmt);
StringBuf_Destroy(&buf);
return GUILDSTORAGE_LOG_FAILED;
}
struct guild_log_entry entry;
// General data
SqlStmt_BindColumn(stmt, 0, SQLDT_UINT, &entry.id, 0, NULL, NULL);
SqlStmt_BindColumn(stmt, 1, SQLDT_STRING, &entry.time, sizeof(entry.time), NULL, NULL);
SqlStmt_BindColumn(stmt, 2, SQLDT_STRING, &entry.name, sizeof(entry.name), NULL, NULL);
SqlStmt_BindColumn(stmt, 3, SQLDT_SHORT, &entry.amount, 0, NULL, NULL);
// Item data
SqlStmt_BindColumn(stmt, 4, SQLDT_USHORT, &entry.item.nameid, 0, NULL, NULL);
SqlStmt_BindColumn(stmt, 5, SQLDT_CHAR, &entry.item.identify, 0, NULL, NULL);
SqlStmt_BindColumn(stmt, 6, SQLDT_CHAR, &entry.item.refine, 0, NULL, NULL);
SqlStmt_BindColumn(stmt, 7, SQLDT_CHAR, &entry.item.attribute, 0, NULL, NULL);
SqlStmt_BindColumn(stmt, 8, SQLDT_UINT, &entry.item.expire_time, 0, NULL, NULL);
SqlStmt_BindColumn(stmt, 9, SQLDT_UINT, &entry.item.bound, 0, NULL, NULL);
SqlStmt_BindColumn(stmt, 10, SQLDT_UINT64, &entry.item.unique_id, 0, NULL, NULL);
for( j = 0; j < MAX_SLOTS; ++j )
SqlStmt_BindColumn(stmt, 11+j, SQLDT_USHORT, &entry.item.card[j], 0, NULL, NULL);
for( j = 0; j < MAX_ITEM_RDM_OPT; ++j ) {
SqlStmt_BindColumn(stmt, 11+MAX_SLOTS+j*3, SQLDT_SHORT, &entry.item.option[j].id, 0, NULL, NULL);
SqlStmt_BindColumn(stmt, 11+MAX_SLOTS+j*3+1, SQLDT_SHORT, &entry.item.option[j].value, 0, NULL, NULL);
SqlStmt_BindColumn(stmt, 11+MAX_SLOTS+j*3+2, SQLDT_CHAR, &entry.item.option[j].param, 0, NULL, NULL);
}
log.reserve(max);
while( SQL_SUCCESS == SqlStmt_NextRow(stmt) ){
log.push_back( entry );
}
Sql_FreeResult(mmysql_handle);
StringBuf_Destroy(&buf);
SqlStmt_Free(stmt);
if( log.empty() ){
return GUILDSTORAGE_LOG_EMPTY;
}
return GUILDSTORAGE_LOG_FINAL_SUCCESS;
}
enum e_guild_storage_log storage_guild_log_read( struct map_session_data* sd ){
std::vector<struct guild_log_entry> log;
// ( 65535(maximum packet size) - 8(header) ) / 83 (entry size) = 789 (-1 for safety)
enum e_guild_storage_log ret = storage_guild_log_read_sub( sd, log, 788 );
clif_guild_storage_log( sd, log, ret );
return ret;
}
/**
* Attempt to add an item in guild storage, then refresh it
* @param sd : player attempting to open the guild_storage
@ -671,6 +782,9 @@ bool storage_guild_additem(struct map_session_data* sd, struct s_storage* stor,
stor->u.items_guild[i].amount += amount;
clif_storageitemadded(sd,&stor->u.items_guild[i],i,amount);
stor->dirty = true;
storage_guild_log( sd, &stor->u.items_guild[i], amount );
return true;
}
}
@ -687,6 +801,9 @@ bool storage_guild_additem(struct map_session_data* sd, struct s_storage* stor,
clif_storageitemadded(sd,&stor->u.items_guild[i],i,amount);
clif_updatestorageamount(sd, stor->amount, stor->max_amount);
stor->dirty = true;
storage_guild_log( sd, &stor->u.items_guild[i], amount );
return true;
}
@ -752,6 +869,9 @@ bool storage_guild_delitem(struct map_session_data* sd, struct s_storage* stor,
if(!stor->u.items_guild[n].nameid || stor->u.items_guild[n].amount < amount)
return false;
// Log before removing it
storage_guild_log( sd, &stor->u.items_guild[n], -amount );
stor->u.items_guild[n].amount -= amount;
if(!stor->u.items_guild[n].amount) {

View File

@ -4,7 +4,10 @@
#ifndef STORAGE_HPP
#define STORAGE_HPP
#include <vector>
#include "../common/cbasetypes.hpp"
#include "../common/mmo.hpp"
struct s_storage;
struct item;
@ -30,6 +33,21 @@ enum e_guild_storage_flags : uint8 {
GSTORAGE_NO_PERMISSION
};
enum e_guild_storage_log : uint16 {
GUILDSTORAGE_LOG_SUCCESS,
GUILDSTORAGE_LOG_FINAL_SUCCESS,
GUILDSTORAGE_LOG_EMPTY,
GUILDSTORAGE_LOG_FAILED,
};
struct guild_log_entry{
uint32 id;
char name[NAME_LENGTH];
char time[NAME_LENGTH];
struct item item;
int16 amount;
};
const char *storage_getName(uint8 id);
bool storage_exists(uint8 id);
@ -51,6 +69,7 @@ struct s_storage* guild2storage(int guild_id);
struct s_storage* guild2storage2(int guild_id);
void storage_guild_delete(int guild_id);
char storage_guild_storageopen(struct map_session_data *sd);
enum e_guild_storage_log storage_guild_log_read( struct map_session_data* sd );
bool storage_guild_additem(struct map_session_data *sd,struct s_storage *stor,struct item *item_data,int amount);
bool storage_guild_additem2(struct s_storage* stor, struct item* item, int amount);
bool storage_guild_delitem(struct map_session_data *sd,struct s_storage *stor,int n,int amount);