Go Back   EQEmulator Home > EQEmulator Forums > Development > Development::Server Code Submissions

Reply
 
Thread Tools Display Modes
  #1  
Old 09-06-2010, 07:25 PM
Vanicae
Fire Beetle
 
Join Date: May 2010
Posts: 9
Default COMMITTED: Fix for guild management window updates

This code fixes the problem where the guild management window does not show online players unless they have zoned after you.

A new function has been added to ZoneGuildManager to send a ServerOP_RequestOnlineGuildMembers for a client. A call to this function is in Client::CompleteConnect(), which is run when a client is fully zoned in.

The server then sends a ServerOP_OnlineGuildMembersResponse back to the zone server that the requesting client is on, and that zone server relays that information to the client through a OP_GuildMemberUpdate for each online guild member.

There is another function already in place that sends a ServerOP_RequestOnlineGuildMembers, when guild related things are changed. This also gets called when zoning in, but it is too early in the zoning process, and the client doesn't get the online guild member information.

Edit: This has only been tested on SoD.

Here is the diff for the /world files changed:

Code:
Index: world/clientlist.cpp
===================================================================
--- world/clientlist.cpp	(revision 1641)
+++ world/clientlist.cpp	(working copy)
@@ -231,8 +231,20 @@
 	}
 	return 0;
 }
+ClientListEntry* ClientList::FindCLEByCharacterID(int32 iCharID) {
+	LinkedListIterator<ClientListEntry*> iterator(clientlist);
 
+	iterator.Reset();
+	while(iterator.MoreElements()) {
+		if (iterator.GetData()->CharID() == iCharID) {
+			return iterator.GetData();
+		}
+		iterator.Advance();
+	}
+	return 0;
+}
 
+
 void ClientList::SendCLEList(const sint16& admin, const char* to, WorldTCPConnection* connection, const char* iName) {
 	LinkedListIterator<ClientListEntry*> iterator(clientlist);
 	char* output = 0;
@@ -389,12 +401,11 @@
 	return 0;
 }
 
-void ClientList::SendOnlineGuildMembers(uint32 FromID, uint32 GuildID, uint16 ZoneID, uint16 InstanceID)
+void ClientList::SendOnlineGuildMembers(uint32 FromID, uint32 GuildID)
 {
 	int PacketLength = 8;
-
-	int Count = 0;
-
+	uint32 Count = 0;
+	ClientListEntry* from = this->FindCLEByCharacterID(FromID);
 	LinkedListIterator<ClientListEntry*> Iterator(clientlist);
 
 	Iterator.Reset();
@@ -434,8 +445,7 @@
 
 		Iterator.Advance();
 	}
-	zoneserver_list.SendPacket(ZoneID, InstanceID, pack);
-
+	zoneserver_list.SendPacket(from->zone(),from->instance(),pack);
 	safe_delete(pack);
 }
 
Index: world/clientlist.h
===================================================================
--- world/clientlist.h	(revision 1641)
+++ world/clientlist.h	(working copy)
@@ -37,7 +37,7 @@
 	
 	void	SendWhoAll(int32 fromid,const char* to, sint16 admin, Who_All_Struct* whom, WorldTCPConnection* connection);
 	void	SendFriendsWho(ServerFriendsWho_Struct *FriendsWho, WorldTCPConnection* connection);
-	void	SendOnlineGuildMembers(uint32 FromID, uint32 GuildID, uint16 ZoneID, uint16 InstanceID);
+	void	SendOnlineGuildMembers(uint32 FromID, uint32 GuildID);
 	void	SendClientVersionSummary(const char *Name);
 	void	SendLFGMatches(ServerLFGMatchesRequest_Struct *LFGMatchesRequest);
 	void    ConsoleSendWhoAll(const char* to, sint16 admin, Who_All_Struct* whom, WorldTCPConnection* connection);
@@ -53,7 +53,7 @@
 	ClientListEntry* CheckAuth(int32 id, const char* iKey, int32 ip);
 	ClientListEntry* FindCharacter(const char* name);
 	ClientListEntry* FindCLEByAccountID(int32 iAccID);
-	ClientListEntry* FindCLEByCharacterID(int32 iAccID);
+	ClientListEntry* FindCLEByCharacterID(int32 iCharID);
 	ClientListEntry* GetCLE(int32 iID);
 	void	GetCLEIP(int32 iIP);
 	void	EnforceSessionLimit(int32 iLSAccountID);
Index: world/zoneserver.cpp
===================================================================
--- world/zoneserver.cpp	(revision 1641)
+++ world/zoneserver.cpp	(working copy)
@@ -740,7 +740,8 @@
 		case ServerOP_RequestOnlineGuildMembers:
 		{
 			ServerRequestOnlineGuildMembers_Struct *srogms = (ServerRequestOnlineGuildMembers_Struct*) pack->pBuffer;
-			client_list.SendOnlineGuildMembers(srogms->FromID, srogms->GuildID, GetID(), GetInstanceID());
+			zlog(GUILDS__IN_PACKETS, "ServerOP_RequestOnlineGuildMembers Recieved. FromID=%i GuildID=%i",srogms->FromID,srogms->GuildID);
+			client_list.SendOnlineGuildMembers(srogms->FromID, srogms->GuildID);
 			break;
 		}
 		case ServerOP_ClientVersionSummary:
And the diff for the /zone files changed:
Code:
Index: zone/client_packet.cpp
===================================================================
--- zone/client_packet.cpp	(revision 1641)
+++ zone/client_packet.cpp	(working copy)
@@ -8872,8 +8872,10 @@
 		entity_list.SendFindableNPCList(this);
 
 	if(IsInAGuild())
+	{
 		guild_mgr.SendGuildMemberUpdateToWorld(GetName(), GuildID(), zone->GetZoneID(), time(NULL));
-
+		guild_mgr.RequestOnlineGuildMembers(this->CharacterID(), this->GuildID());
+	}
 	/** Request adventure info **/
 	ServerPacket *pack = new ServerPacket(ServerOP_AdventureDataRequest, 64);
 	strcpy((char*)pack->pBuffer, GetName());
Index: zone/guild_mgr.cpp
===================================================================
--- zone/guild_mgr.cpp	(revision 1641)
+++ zone/guild_mgr.cpp	(working copy)
@@ -455,6 +455,44 @@
 		}
 		break;
 	}
+	case ServerOP_OnlineGuildMembersResponse:
+		if (ZoneLoaded)
+		{
+			char *Buffer = (char *)pack->pBuffer;
+
+			uint32 FromID = VARSTRUCT_DECODE_TYPE(uint32, Buffer);
+			uint32 Count  = VARSTRUCT_DECODE_TYPE(uint32, Buffer);
+			Client *c = entity_list.GetClientByCharID(FromID);
+			
+			if (!c || !c->IsInAGuild())
+			{
+				_log(GUILDS__ERROR,"Invalid Client or not in guild. ID=%i", FromID);
+				break;
+			}
+			_log(GUILDS__IN_PACKETS,"Processing ServerOP_OnlineGuildMembersResponse");
+			EQApplicationPacket *outapp = new EQApplicationPacket(OP_GuildMemberUpdate, sizeof(GuildMemberUpdate_Struct));
+			GuildMemberUpdate_Struct *gmus = (GuildMemberUpdate_Struct*)outapp->pBuffer;
+			char Name[64];
+			gmus->LastSeen = time(NULL);
+			gmus->InstanceID = 0;
+			gmus->GuildID = c->GuildID();
+			for (int i=0;i<Count;i++)
+			{
+				// Just make the packet once and swap out name/zone and send
+				VARSTRUCT_DECODE_STRING(Name, Buffer);
+				strn0cpy(gmus->MemberName, Name, sizeof(gmus->MemberName));
+				gmus->ZoneID = VARSTRUCT_DECODE_TYPE(uint32, Buffer);
+				_log(GUILDS__OUT_PACKETS,"Sending OP_GuildMemberUpdate to %i. Name=%s ZoneID=%i",FromID,Name,gmus->ZoneID);
+				c->QueuePacket(outapp);
+			}
+			safe_delete(outapp);
+
+		}
+		else
+		{
+			_log(GUILDS__ERROR,"Zone not yet loaded, aborting ServerOP_RequestOnlineGuildMembers");
+		}
+		break;
 	}
 }
 
@@ -471,7 +509,17 @@
 
 	safe_delete(pack);
 }
+void ZoneGuildManager::RequestOnlineGuildMembers(uint32 FromID, uint32 GuildID)
+{
+	ServerPacket* pack = new ServerPacket(ServerOP_RequestOnlineGuildMembers, sizeof(ServerRequestOnlineGuildMembers_Struct));
+	ServerRequestOnlineGuildMembers_Struct *srogm = (ServerRequestOnlineGuildMembers_Struct*)pack->pBuffer;
 
+	srogm->FromID = FromID;
+	srogm->GuildID = GuildID;
+	worldserver.SendPacket(pack);
+
+	safe_delete(pack);
+}
 void ZoneGuildManager::ProcessApproval()
 {
 	LinkedListIterator<GuildApproval*> iterator(list);
Index: zone/guild_mgr.h
===================================================================
--- zone/guild_mgr.h	(revision 1641)
+++ zone/guild_mgr.h	(working copy)
@@ -92,7 +92,7 @@
 	void RecordInvite(int32 char_id, int32 guild_id, int8 rank);
 	bool VerifyAndClearInvite(int32 char_id, int32 guild_id, int8 rank);
 	void SendGuildMemberUpdateToWorld(const char *MemberName, uint32 GuildID, uint16 ZoneID, uint32 LastSeen);
-
+	void RequestOnlineGuildMembers(uint32 FromID, uint32 GuildID);
 protected:
 	virtual void SendGuildRefresh(int32 guild_id, bool name, bool motd, bool rank, bool relation);
 	virtual void SendCharRefresh(int32 old_guild_id, int32 guild_id, int32 charid);
Index: zone/worldserver.cpp
===================================================================
--- zone/worldserver.cpp	(revision 1641)
+++ zone/worldserver.cpp	(working copy)
@@ -567,6 +567,7 @@
 		}
 		
 		//hand all the guild related packets to the guild manager for processing.
+		case ServerOP_OnlineGuildMembersResponse:
 		case ServerOP_RefreshGuild:
 //		case ServerOP_GuildInvite:
 		case ServerOP_DeleteGuild:
@@ -579,7 +580,7 @@
 			guild_mgr.ProcessWorldPacket(pack);
 			break;
 
-		case ServerOP_OnlineGuildMembersResponse:
+		/*case ServerOP_OnlineGuildMembersResponse:
 		{
 			char *Buffer = (char *)pack->pBuffer;
 
@@ -616,7 +617,7 @@
 			}
 			safe_delete(outapp);
 			break;
-		}
+		}*/
 		
 		case ServerOP_FlagUpdate: {
 			Client* client = entity_list.GetClientByAccID(*((int32*) pack->pBuffer));

Vanicae@PEQ
Reply With Quote
  #2  
Old 09-10-2010, 05:16 PM
Derision
Developer
 
Join Date: Feb 2004
Location: UK
Posts: 1,540
Default

Thanks for this

I'll try to get to this and the other recent submissions (by you and others) in the forum over the weekend. Sorry about the delay, please don't feel your submissions aren't very much appreciated
Reply With Quote
  #3  
Old 09-11-2010, 07:30 AM
joligario's Avatar
joligario
Developer
 
Join Date: Mar 2003
Posts: 1,497
Default

Excellent work! Cheers!
Reply With Quote
  #4  
Old 09-12-2010, 01:11 PM
Vanicae
Fire Beetle
 
Join Date: May 2010
Posts: 9
Default

This actually needs an addition ASAP. Gaeorn helped identify the problem yesterday and has this fix, but didn't get around to adding it yet.

I didn't verify the return was valid and World doesn't like null pointers =/

I've been unable to reproduce the conditions that would cause this to not return a valid client, it seems to have happened yesterday with some larger guilds, which isn't easily testable on a personal test server.

Code:
Index: clientlist.cpp 
=================================================================== 
--- clientlist.cpp   (revision 1655) 
+++ clientlist.cpp   (working copy) 
@@ -407,6 +407,10 @@ 
  
    uint32 Count = 0; 
    ClientListEntry* from = this->FindCLEByCharacterID(FromID); 
+   if (!from) { 
+      _log(WORLD__CLIENT_ERR,"Invalid client. FromID=%i GuildID=%i", FromID, GuildID); 
+      return; 
+   } 
    LinkedListIterator<ClientListEntry*> Iterator(clientlist); 
  
    Iterator.Reset();

Sorry!
Van
Reply With Quote
  #5  
Old 09-12-2010, 02:04 PM
Derision
Developer
 
Join Date: Feb 2004
Location: UK
Posts: 1,540
Default

No problem Fix is in Rev1659. Thanks.
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 10:19 AM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3