Added some checks to guild leader change

Introduces two new configurations:
1) Allow guild leader changes in WoE (yes/no)
	Default: no
2) Delay between the changes (in minutes)
	Default: 1440 minutes = 1 day

Follow up to b51617c
This commit is contained in:
Lemongrass3110 2017-07-02 23:40:30 +02:00
parent 2072fe3643
commit a3c0590508
13 changed files with 56 additions and 14 deletions

View File

@ -61,3 +61,13 @@ guild_notice_changemap: 2
// Should maprespawnguildid kill clones too?
// Default: no
guild_maprespawn_clones: no
// How long (in minutes) should a guild have to wait between guild master changes?
// Default: 1440 (1 day)
// Use 0 minutes to disable the delay.
//guild_leaderchange_delay: 1440
guild_leaderchange_delay: 0
// Is changing the guild leader allowed during WoE?
// Default: no
guild_leaderchange_woe: no

View File

@ -1967,14 +1967,15 @@ Currently the max packet size is 0xFFFF (see 'WFIFOSET()' in 'src/common/socket.
0x3843
Type: IZ
Structure: <cmd>.W <guild_id>.L <aid>.L <cid>.L
index: 0,2,6,10
len: 14
Structure: <cmd>.W <guild_id>.L <aid>.L <cid>.L <time>.L
index: 0,2,6,10,14
len: 18
parameter:
- cmd : packet identification (0x3843)
- guild_id
- aid
- cid
- time of change
desc:
- mapif_guild_master_changed

View File

@ -412,6 +412,7 @@ CREATE TABLE IF NOT EXISTS `guild` (
`emblem_len` int(11) unsigned NOT NULL default '0',
`emblem_id` int(11) unsigned NOT NULL default '0',
`emblem_data` blob,
`last_master_change` datetime,
PRIMARY KEY (`guild_id`,`char_id`),
UNIQUE KEY `guild_id` (`guild_id`),
KEY `char_id` (`char_id`)

View File

@ -0,0 +1,2 @@
alter table `guild`
add column `last_master_change` datetime;

View File

@ -183,6 +183,9 @@ int inter_guild_tosql(struct guild *g,int flag)
else
add_comma = true;
StringBuf_Printf(&buf, "`name`='%s', `master`='%s', `char_id`=%d", esc_name, esc_master, g->member[0].char_id);
if (g->last_leader_change)
StringBuf_Printf(&buf, ", `last_master_change`=FROM_UNIXTIME(%d)", g->last_leader_change);
}
if (flag & GS_CONNECT)
{
@ -348,7 +351,7 @@ struct guild * inter_guild_fromsql(int guild_id)
ShowInfo("Guild load request (%d)...\n", guild_id);
#endif
if( SQL_ERROR == Sql_Query(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(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`,COALESCE(UNIX_TIMESTAMP(g.`last_master_change`),0), g.`emblem_data` "
"FROM `%s` g LEFT JOIN `%s` c ON c.`char_id` = g.`char_id` WHERE g.`guild_id`='%d'", schema_config.guild_db, schema_config.char_db, guild_id) )
{
Sql_ShowDebug(sql_handle);
@ -379,7 +382,8 @@ struct guild * inter_guild_fromsql(int guild_id)
Sql_GetData(sql_handle, 10, &data, &len); memcpy(g->mes2, data, zmin(len, sizeof(g->mes2)));
Sql_GetData(sql_handle, 11, &data, &len); g->emblem_len = atoi(data);
Sql_GetData(sql_handle, 12, &data, &len); g->emblem_id = atoi(data);
Sql_GetData(sql_handle, 13, &data, &len);
Sql_GetData(sql_handle, 13, &data, NULL); g->last_leader_change = atoi(data);
Sql_GetData(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 )
@ -1085,14 +1089,15 @@ int mapif_guild_emblem(struct guild *g)
return 0;
}
int mapif_guild_master_changed(struct guild *g, int aid, int cid)
int mapif_guild_master_changed(struct guild *g, int aid, int cid, time_t time)
{
unsigned char buf[14];
unsigned char buf[18];
WBUFW(buf,0)=0x3843;
WBUFL(buf,2)=g->guild_id;
WBUFL(buf,6)=aid;
WBUFL(buf,10)=cid;
chmapif_sendall(buf,14);
WBUFL(buf,14)=time;
chmapif_sendall(buf,18);
return 0;
}
@ -1825,13 +1830,16 @@ int mapif_parse_GuildMasterChange(int fd, int guild_id, const char* name, int le
g->member[0].position = 0; //Position 0: guild Master.
g->member[0].modified = GS_MEMBER_MODIFIED;
// Store changing time
g->last_leader_change = time(NULL);
safestrncpy(g->master, name, len);
if (len < NAME_LENGTH)
g->master[len] = '\0';
ShowInfo("int_guild: Guildmaster Changed to %s (Guild %d - %s)\n",g->master, guild_id, g->name);
g->save_flag |= (GS_BASIC|GS_MEMBER); //Save main data and member data.
return mapif_guild_master_changed(g, g->member[0].account_id, g->member[0].char_id);
return mapif_guild_master_changed(g, g->member[0].account_id, g->member[0].char_id, g->last_leader_change);
}
// Communication from the map server

View File

@ -637,6 +637,7 @@ struct guild {
struct guild_skill skill[MAX_GUILDSKILL];
struct Channel *channel;
unsigned short instance_id;
time_t last_leader_change;
/* Used by char-server to save events for guilds */
unsigned short save_flag;

View File

@ -8412,6 +8412,8 @@ static const struct _battle_data {
{ "mail_attachment_price", &battle_config.mail_attachment_price, 2500, 0, INT32_MAX, },
{ "mail_attachment_weight", &battle_config.mail_attachment_weight, 2000, 0, INT32_MAX, },
{ "banana_bomb_duration", &battle_config.banana_bomb_duration, 0, 0, UINT16_MAX, },
{ "guild_leaderchange_delay", &battle_config.guild_leaderchange_delay, 1440, 0, INT32_MAX, },
{ "guild_leaderchange_woe", &battle_config.guild_leaderchange_woe, 0, 0, 1, },
#include "../custom/battle_config_init.inc"
};

View File

@ -627,6 +627,8 @@ extern struct Battle_Config
int mail_attachment_price;
int mail_attachment_weight;
int banana_bomb_duration;
int guild_leaderchange_delay;
int guild_leaderchange_woe;
#include "../custom/battle_config_struct.inc"
} battle_config;

View File

@ -13368,6 +13368,16 @@ void clif_parse_GuildChangeMemberPosition(int fd, struct map_session_data *sd)
// Guild leadership change
if( len == 16 && RFIFOL(fd,12) == 0 ){
if( !battle_config.guild_leaderchange_woe && is_agit_start() ){
clif_msg(sd, GUILD_MASTER_WOE);
return;
}
if( battle_config.guild_leaderchange_delay && DIFF_TICK(time(NULL),sd->guild->last_leader_change) < battle_config.guild_leaderchange_delay ){
clif_msg(sd, GUILD_MASTER_DELAY);
return;
}
guild_gm_change(sd->status.guild_id, RFIFOL(fd, 8));
return;
}

View File

@ -486,7 +486,7 @@ enum clif_messages {
ITEM_PARTY_NO_MEMBER_IN_MAP = 0x4c6, ///< "There is no party member to summon in the current map."
MERC_MSG_BASE = 0x4f2,
SKILL_CANT_USE_AREA = 0x536,
ITEM_CANT_USE_AREA = 0x537,
ITEM_CANT_USE_AREA = 0x537,
VIEW_EQUIP_FAIL = 0x54d,
RUNE_CANT_CREATE = 0x61b,
ITEM_CANT_COMBINE = 0x623,
@ -499,6 +499,8 @@ enum clif_messages {
NEED_REINS_OF_MOUNT = 0x78c,
PARTY_MASTER_CHANGE_SAME_MAP = 0x82e, ///< "It is only possible to change the party leader while on the same map."
MERGE_ITEM_NOT_AVAILABLE = 0x887,
GUILD_MASTER_WOE = 0xb93, /// <"Currently in WoE hours, unable to delegate Guild leader"
GUILD_MASTER_DELAY = 0xb94, /// <"You have to wait for one day before delegating a new Guild leader"
};
enum e_personalinfo {

View File

@ -1791,7 +1791,7 @@ int guild_gm_change(int guild_id, uint32 char_id) {
* @param account_id
* @param char_id
*/
int guild_gm_changed(int guild_id, uint32 account_id, uint32 char_id) {
int guild_gm_changed(int guild_id, uint32 account_id, uint32 char_id, time_t time) {
struct guild *g;
struct guild_member gm;
int pos, i;
@ -1840,6 +1840,9 @@ int guild_gm_changed(int guild_id, uint32 account_id, uint32 char_id) {
}
}
// Store changing time
g->last_leader_change = time;
return 1;
}

View File

@ -91,7 +91,7 @@ int guild_skillupack(int guild_id,uint16 skill_id,uint32 account_id);
int guild_break(struct map_session_data *sd,char *name);
int guild_broken(int guild_id,int flag);
int guild_gm_change(int guild_id, uint32 char_id);
int guild_gm_changed(int guild_id, uint32 account_id, uint32 char_id);
int guild_gm_changed(int guild_id, uint32 account_id, uint32 char_id, time_t time);
void guild_castle_map_init(void);
int guild_castledatasave(int castle_id,int index,int value);

View File

@ -32,7 +32,7 @@ static const int packet_len_table[] = {
0, 0, 0, 0, 0, 0, 0, 0, -1,11, 0, 0, 0, 0, 0, 0, //0x3810
39,-1,15,15, 15+NAME_LENGTH,19, 7,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3820
10,-1,15, 0, 79,19, 7,-1, 0,-1,-1,-1, 14,67,186,-1, //0x3830
-1, 0, 0,14, 0, 0, 0, 0, -1,75,-1,11, 11,-1, 38, 0, //0x3840
-1, 0, 0,18, 0, 0, 0, 0, -1,75,-1,11, 11,-1, 38, 0, //0x3840
-1,-1, 7, 7, 7,11, 8,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3850 Auctions [Zephyrus] itembound[Akinari]
-1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3860 Quests [Kevin] [Inkfish]
-1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 3, 3, 0, //0x3870 Mercenaries [Zephyrus] / Elemental [pakpil]
@ -1811,7 +1811,7 @@ int intif_parse_GuildCastleDataLoad(int fd)
*/
int intif_parse_GuildMasterChanged(int fd)
{
return guild_gm_changed(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10));
return guild_gm_changed(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOL(fd,14));
}
/**