From cc6dce25ad3c7eb768f816651bbe0db2f90a843d Mon Sep 17 00:00:00 2001 From: SecretsOTheP Date: Sat, 17 May 2014 23:33:35 -0400 Subject: [PATCH] Identified the opcode/struct for guild ranks in Rain of Fear+ clients and created a temporary workaround for permissions until full DB support is added for the new permissions system. --- changelog.txt | 4 ++++ common/eq_packet_structs.h | 20 ++++++++++++++++++++ zone/client.h | 1 + zone/client_packet.cpp | 6 ++++++ zone/guild.cpp | 36 ++++++++++++++++++++++++++++++++++++ 5 files changed, 67 insertions(+) diff --git a/changelog.txt b/changelog.txt index fde7ca6b2..9d66bcfd8 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,9 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 05/17/2014 == +Secrets: Identified the opcode/struct for guild ranks in Rain of Fear+ clients. +Secrets: Implemented a work-around for Rain of Fear clients to have all guild permissions until proper database support is added for newer ranks. + == 05/12/2014 == Uleat: Re-arranged functions in Item.cpp to somewhat match the order they are declared in Item.h. Should make finding their location a little easier when using declarations as a guide. (This will facilitate readability of an upcoming change...) diff --git a/common/eq_packet_structs.h b/common/eq_packet_structs.h index e0c4a1563..674ed15b7 100644 --- a/common/eq_packet_structs.h +++ b/common/eq_packet_structs.h @@ -3163,6 +3163,26 @@ struct GuildUpdateURLAndChannel_Struct /*4176*/ }; +//Case 5 in Rain of Fear and higher clients for guild permissions. +//RankID is the internal guild rank. There are 8 in Rain of Fear as opposed to the 3 in Titanium. +//PermissionID is the type of permission. There are 32 total, with some unused. Live May 2014 sends and uses 26 of them. Varies through client version. +//Permission value is a char that is either 0 or 1. Enabled for that rank/disabled for that rank. +//The client sends this struct on changing a guild rank. The server sends each rank in 32 or less packets upon zonein if you are in a guild. +struct GuildUpdateRanks_Struct +{ +/*0000*/ uint32 Action; // 0 = Update URL, 1 = Update Channel, 5 = RoF Ranks +/*0004*/ uint32 Unknown0004; //Seen 00 00 00 00 +/*0008*/ uint32 Unknown0008; //Seen 96 29 00 00 +/*0008*/ char Unknown0012[64]; //Seen "CharacterName" +/*0076*/ uint32 GuildID; //Guild ID of "CharacterName" +/*0080*/ uint32 RankID; +/*0084*/ uint32 PermissionID; +/*0088*/ char PermissionVal; +/*0089*/ char Unknown0089[3]; //Seen 2c 01 00 ? +/*0092*/ +}; + + struct GuildStatus_Struct { /*000*/ char Name[64]; diff --git a/zone/client.h b/zone/client.h index a97671c20..9e2503df2 100644 --- a/zone/client.h +++ b/zone/client.h @@ -621,6 +621,7 @@ public: void SendGuildURL(); void SendGuildChannel(); void SendGuildSpawnAppearance(); + void SendGuildRanks(); void SendGuildMembers(); void SendGuildList(); void SendGuildJoin(GuildJoin_Struct* gj); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index cc5414ac4..ff79fd317 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -4431,6 +4431,7 @@ void Client::Handle_OP_GuildInviteAccept(const EQApplicationPacket *app) } if(zone->GetZoneID() == RuleI(World, GuildBankZoneID) && GuildBanks) GuildBanks->SendGuildBank(this); + SendGuildRanks(); } } @@ -8128,7 +8129,10 @@ void Client::Handle_OP_ClientError(const EQApplicationPacket *app) void Client::Handle_OP_ReloadUI(const EQApplicationPacket *app) { if(IsInAGuild()) + { + SendGuildRanks(); SendGuildMembers(); + } return; } @@ -9603,6 +9607,7 @@ void Client::CompleteConnect() if(IsInAGuild()) { + SendGuildRanks(); guild_mgr.SendGuildMemberUpdateToWorld(GetName(), GuildID(), zone->GetZoneID(), time(nullptr)); guild_mgr.RequestOnlineGuildMembers(this->CharacterID(), this->GuildID()); } @@ -12528,6 +12533,7 @@ void Client::Handle_OP_GuildCreate(const EQApplicationPacket *app) if(zone->GetZoneID() == RuleI(World, GuildBankZoneID) && GuildBanks) GuildBanks->SendGuildBank(this); + SendGuildRanks(); } } } diff --git a/zone/guild.cpp b/zone/guild.cpp index 66ff4946c..21e350cdf 100644 --- a/zone/guild.cpp +++ b/zone/guild.cpp @@ -115,6 +115,42 @@ void Client::SendGuildChannel() } } +void Client::SendGuildRanks() +{ + if(GetClientVersion() < EQClientRoF) + return; + + int permissions = 30 + 1; //Static number of permissions in all EQ clients as of May 2014 + int ranks = 8 + 1; // Static number of RoF+ ranks as of May 2014 + int j = 1; + int i = 1; + if(IsInAGuild()) + { + while(j < ranks) + { + while(i < permissions) + { + EQApplicationPacket *outapp = new EQApplicationPacket(OP_GuildUpdateURLAndChannel, sizeof(GuildUpdateRanks_Struct)); + GuildUpdateRanks_Struct *guuacs = (GuildUpdateRanks_Struct*) outapp->pBuffer; + //guuacs->Unknown0008 = this->GuildID(); + strncpy(guuacs->Unknown0012, this->GetCleanName(), 64); + guuacs->Action = 5; + guuacs->RankID = j; + guuacs->GuildID = this->GuildID(); + guuacs->PermissionID = i; + guuacs->PermissionVal = 1; + guuacs->Unknown0089[0] = 0x2c; + guuacs->Unknown0089[1] = 0x01; + guuacs->Unknown0089[2] = 0x00; + FastQueuePacket(&outapp); + i++; + } + j++; + i = 1; + } + } +} + void Client::SendGuildSpawnAppearance() { if (!IsInAGuild()) { // clear guildtag