From ccf79c7d339dcfb1b95b1adbff5f26d80c013d16 Mon Sep 17 00:00:00 2001
From: Andrei Karas <akaras@inbox.ru>
Date: Thu, 15 Jun 2017 01:44:58 +0300
Subject: fix guild leader change in 2017 clients. Based on rathena commit:

commit b51617cb730cdc6d91bc03df16c887a060323f3a
Author: Lemongrass3110 <lemongrass@kstp.at>
Date:   Sat Jun 3 17:03:56 2017 +0200

    Added support for 2017's guild leader change
---
 src/map/atcommand.c |  2 +-
 src/map/clif.c      | 13 +++++++++++--
 src/map/guild.c     | 26 +++++++++++++++++---------
 src/map/guild.h     |  2 +-
 src/map/script.c    |  2 +-
 5 files changed, 31 insertions(+), 14 deletions(-)

(limited to 'src/map')

diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 19a7e360b..872c31330 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -5605,7 +5605,7 @@ ACMD(changegm) {
 		return false;
 	}
 
-	guild->gm_change(sd->status.guild_id, pl_sd);
+	guild->gm_change(sd->status.guild_id, pl_sd->status.char_id);
 	return true;
 }
 
diff --git a/src/map/clif.c b/src/map/clif.c
index 4791451fb..c990b11d1 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -13056,13 +13056,22 @@ void clif_parse_GuildChangeMemberPosition(int fd, struct map_session_data *sd) _
 void clif_parse_GuildChangeMemberPosition(int fd, struct map_session_data *sd)
 {
 	int i;
+	int len = RFIFOW(fd, 2);
 
 	if(!sd->state.gmaster_flag)
 		return;
 
+	// Guild leadership change
+	if (len == 16 && RFIFOL(fd, 12) == 0) {
+		guild->gm_change(sd->status.guild_id, RFIFOL(fd, 8));
+		return;
+	}
+
 	for(i=4;i<RFIFOW(fd,2);i+=12){
-		guild->change_memberposition(sd->status.guild_id,
-			RFIFOL(fd,i),RFIFOL(fd,i+4),RFIFOL(fd,i+8));
+		int position = RFIFOL(fd, i + 8);
+		if (position > 0) {
+			guild->change_memberposition(sd->status.guild_id, RFIFOL(fd, i), RFIFOL(fd, i + 4), position);
+		}
 	}
 }
 
diff --git a/src/map/guild.c b/src/map/guild.c
index 6e5b1c539..838df3943 100644
--- a/src/map/guild.c
+++ b/src/map/guild.c
@@ -1814,23 +1814,28 @@ int guild_broken(int guild_id,int flag)
 }
 
 //Changes the Guild Master to the specified player. [Skotlex]
-int guild_gm_change(int guild_id, struct map_session_data *sd)
+int guild_gm_change(int guild_id, int char_id)
 {
-	struct guild *g;
-	nullpo_ret(sd);
+	struct guild *g = guild->search(guild_id);
+	char *name;
+	int i;
 
-	if (sd->status.guild_id != guild_id)
-		return 0;
+	nullpo_ret(g);
 
-	g=guild->search(guild_id);
+	ARR_FIND(0, MAX_GUILD, i, g->member[i].char_id == char_id);
+	
+	if (i == MAX_GUILD ) {
+		// Not part of the guild
+		return 0;
+	}
 
-	nullpo_ret(g);
+	name = g->member[i].name;
 
-	if (strcmp(g->master, sd->status.name) == 0) //Nothing to change.
+	if (strcmp(g->master, name) == 0) //Nothing to change.
 		return 0;
 
 	//Notify servers that master has changed.
-	intif->guild_change_gm(guild_id, sd->status.name, (int)strlen(sd->status.name)+1);
+	intif->guild_change_gm(guild_id, name, (int)strlen(name) + 1);
 	return 1;
 }
 
@@ -1864,6 +1869,7 @@ int guild_gm_changed(int guild_id, int account_id, int char_id)
 	if (g->member[pos].sd && g->member[pos].sd->fd) {
 		clif->message(g->member[pos].sd->fd, msg_sd(g->member[pos].sd,878)); //"You no longer are the Guild Master."
 		g->member[pos].sd->state.gmaster_flag = 0;
+		clif->charnameack(0, &g->member[pos].sd->bl);
 	}
 
 	if (g->member[0].sd && g->member[0].sd->fd) {
@@ -1871,6 +1877,7 @@ int guild_gm_changed(int guild_id, int account_id, int char_id)
 		g->member[0].sd->state.gmaster_flag = 1;
 		//Block his skills for 5 minutes to prevent abuse.
 		guild->block_skill(g->member[0].sd, 300000);
+		clif->charnameack(0, &g->member[pos].sd->bl);
 	}
 
 	// announce the change to all guild members
@@ -1880,6 +1887,7 @@ int guild_gm_changed(int guild_id, int account_id, int char_id)
 		{
 			clif->guild_basicinfo(g->member[i].sd);
 			clif->guild_memberlist(g->member[i].sd);
+			clif->guild_belonginfo(g->member[i].sd, g); // Update clientside guildmaster flag
 		}
 	}
 
diff --git a/src/map/guild.h b/src/map/guild.h
index cdb28a37b..71e989870 100644
--- a/src/map/guild.h
+++ b/src/map/guild.h
@@ -141,7 +141,7 @@ struct guild_interface {
 	int (*skillupack) (int guild_id,uint16 skill_id,int account_id);
 	int (*dobreak) (struct map_session_data *sd, const char *name);
 	int (*broken) (int guild_id,int flag);
-	int (*gm_change) (int guild_id, struct map_session_data *sd);
+	int (*gm_change) (int guild_id, int char_id);
 	int (*gm_changed) (int guild_id, int account_id, int char_id);
 	/* */
 	void (*castle_map_init) (void);
diff --git a/src/map/script.c b/src/map/script.c
index f7104d255..d993f7547 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -10635,7 +10635,7 @@ BUILDIN(guildchangegm)
 	if (sd == NULL)
 		script_pushint(st,0);
 	else
-		script_pushint(st,guild->gm_change(guild_id, sd));
+		script_pushint(st, guild->gm_change(guild_id, sd->status.char_id));
 
 	return true;
 }
-- 
cgit v1.2.3-70-g09d2