|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
09-06-2010, 07:25 PM
|
Fire Beetle
|
|
Join Date: May 2010
Posts: 9
|
|
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
|
|
|
|
09-10-2010, 05:16 PM
|
Developer
|
|
Join Date: Feb 2004
Location: UK
Posts: 1,540
|
|
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
|
09-11-2010, 07:30 AM
|
|
Developer
|
|
Join Date: Mar 2003
Posts: 1,497
|
|
Excellent work! Cheers!
|
09-12-2010, 01:11 PM
|
Fire Beetle
|
|
Join Date: May 2010
Posts: 9
|
|
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
|
09-12-2010, 02:04 PM
|
Developer
|
|
Join Date: Feb 2004
Location: UK
Posts: 1,540
|
|
No problem Fix is in Rev1659. Thanks.
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -4. The time now is 10:19 AM.
|
|
|
|
|
|
|
|
|
|
|
|
|