void WorldServer::ProcessMessage(uint16 opcode, EQ::Net::Packet &p) { ServerPacket tpack(opcode, p); ServerPacket *pack = &tpack; Log(Logs::Detail, Logs::UCS_Server, "Received Opcode: %4X", opcode); switch (opcode) { case 0: { break; } case ServerOP_KeepAlive: { break; } case ServerOP_UCSMessage: { char *Buffer = (char *)pack->pBuffer; auto From = new char[strlen(Buffer) + 1]; VARSTRUCT_DECODE_STRING(From, Buffer); std::string Message = Buffer; Log(Logs::Detail, Logs::UCS_Server, "Player: %s, Sent Message: %s", From, Message.c_str()); Client *c = g_Clientlist->FindCharacter(From); safe_delete_array(From); if (Message.length() < 2) break; if (!c) { Log(Logs::Detail, Logs::UCS_Server, "Client not found."); break; } if (Message[0] == ';') { std::string new_message; switch (c->GetClientVersion()) { case EQEmu::versions::ClientVersion::Titanium: Client45ToServerSayLink(new_message, Message.substr(1, std::string::npos)); break; case EQEmu::versions::ClientVersion::SoF: case EQEmu::versions::ClientVersion::SoD: case EQEmu::versions::ClientVersion::UF: Client50ToServerSayLink(new_message, Message.substr(1, std::string::npos)); break; case EQEmu::versions::ClientVersion::RoF: Client55ToServerSayLink(new_message, Message.substr(1, std::string::npos)); break; case EQEmu::versions::ClientVersion::RoF2: default: new_message = Message.substr(1, std::string::npos); break; } c->SendChannelMessageByNumber(new_message); } else if (Message[0] == '[') { g_Clientlist->ProcessOPMailCommand(c, Message.substr(1, std::string::npos)); } break; } case ServerOP_UCSMailMessage: { ServerMailMessageHeader_Struct *mail = (ServerMailMessageHeader_Struct*)pack->pBuffer; database.SendMail(std::string("SOE.EQ.") + Config->ShortName + std::string(".") + std::string(mail->to), std::string(mail->from), mail->subject, mail->message, std::string()); break; } } }
void ZoneGuildManager::ProcessWorldPacket(ServerPacket *pack) { switch(pack->opcode) { case ServerOP_RefreshGuild: { if(pack->size != sizeof(ServerGuildRefresh_Struct)) { Log.Out(Logs::General, Logs::Error, "Received ServerOP_RefreshGuild of incorrect size %d, expected %d", pack->size, sizeof(ServerGuildRefresh_Struct)); return; } ServerGuildRefresh_Struct *s = (ServerGuildRefresh_Struct *) pack->pBuffer; Log.Out(Logs::Detail, Logs::Guilds, "Received guild refresh from world for %d, changes: name=%d, motd=%d, rank=%d, relation=%d", s->guild_id, s->name_change, s->motd_change, s->rank_change, s->relation_change); //reload all the guild details from the database. RefreshGuild(s->guild_id); if(s->motd_change) { //resend guild MOTD to all guild members in this zone. entity_list.SendGuildMOTD(s->guild_id); } if(s->name_change) { //until we figure out the guild update packet, we resend the whole guild list. entity_list.SendGuildList(); } if(s->rank_change) { //we need to send spawn appearance packets for all members of this guild in the zone, to everybody. entity_list.SendGuildSpawnAppearance(s->guild_id); } if(s->relation_change) { //unknown until we implement guild relations. } break; } case ServerOP_GuildCharRefresh: { if(pack->size != sizeof(ServerGuildCharRefresh_Struct)) { Log.Out(Logs::General, Logs::Error, "Received ServerOP_RefreshGuild of incorrect size %d, expected %d", pack->size, sizeof(ServerGuildCharRefresh_Struct)); return; } ServerGuildCharRefresh_Struct *s = (ServerGuildCharRefresh_Struct *) pack->pBuffer; Log.Out(Logs::Detail, Logs::Guilds, "Received guild member refresh from world for char %d from guild %d", s->char_id, s->guild_id); Client *c = entity_list.GetClientByCharID(s->char_id); if(c != nullptr) { //this reloads the char's guild info from the database and sends appearance updates c->RefreshGuildInfo(); } //it would be nice if we had the packet to send just a one-person update if(s->guild_id == GUILD_NONE) { if(c != nullptr) c->SendGuildMembers(); //only need to update this player's list (trying to clear it) } else { entity_list.SendGuildMembers(s->guild_id); //even send GUILD_NONE (empty) } if(s->old_guild_id != 0 && s->old_guild_id != GUILD_NONE && s->old_guild_id != s->guild_id) entity_list.SendGuildMembers(s->old_guild_id); else if(c != nullptr && s->guild_id != GUILD_NONE) { //char is in zone, and has changed into a new guild, send MOTD. c->SendGuildMOTD(); if(c->GetClientVersion() >= ClientVersion::RoF) { c->SendGuildRanks(); } } break; } case ServerOP_GuildRankUpdate: { if(ZoneLoaded) { if(pack->size != sizeof(ServerGuildRankUpdate_Struct)) { Log.Out(Logs::General, Logs::Error, "Received ServerOP_RankUpdate of incorrect size %d, expected %d", pack->size, sizeof(ServerGuildRankUpdate_Struct)); return; } ServerGuildRankUpdate_Struct *sgrus = (ServerGuildRankUpdate_Struct*)pack->pBuffer; EQApplicationPacket *outapp = new EQApplicationPacket(OP_SetGuildRank, sizeof(GuildSetRank_Struct)); GuildSetRank_Struct *gsrs = (GuildSetRank_Struct*)outapp->pBuffer; gsrs->Rank = sgrus->Rank; strn0cpy(gsrs->MemberName, sgrus->MemberName, sizeof(gsrs->MemberName)); gsrs->Banker = sgrus->Banker; entity_list.QueueClientsGuild(nullptr, outapp, false, sgrus->GuildID); safe_delete(outapp); } break; } case ServerOP_DeleteGuild: { if(pack->size != sizeof(ServerGuildID_Struct)) { Log.Out(Logs::General, Logs::Error, "Received ServerOP_DeleteGuild of incorrect size %d, expected %d", pack->size, sizeof(ServerGuildID_Struct)); return; } ServerGuildID_Struct *s = (ServerGuildID_Struct *) pack->pBuffer; Log.Out(Logs::Detail, Logs::Guilds, "Received guild delete from world for guild %d", s->guild_id); //clear all the guild tags. entity_list.RefreshAllGuildInfo(s->guild_id); //remove the guild data from the local guild manager guild_mgr.LocalDeleteGuild(s->guild_id); //if we stop forcing guild list to send on guild create, we need to do this: //in the case that we delete a guild and add a new one. //entity_list.SendGuildList(); break; } case ServerOP_GuildMemberUpdate: { ServerGuildMemberUpdate_Struct *sgmus = (ServerGuildMemberUpdate_Struct*)pack->pBuffer; if(ZoneLoaded) { EQApplicationPacket *outapp = new EQApplicationPacket(OP_GuildMemberUpdate, sizeof(GuildMemberUpdate_Struct)); GuildMemberUpdate_Struct *gmus = (GuildMemberUpdate_Struct*)outapp->pBuffer; gmus->GuildID = sgmus->GuildID; strn0cpy(gmus->MemberName, sgmus->MemberName, sizeof(gmus->MemberName)); gmus->ZoneID = sgmus->ZoneID; gmus->InstanceID = 0; // I don't think we care what Instance they are in, for the Guild Management Window. gmus->LastSeen = sgmus->LastSeen; entity_list.QueueClientsGuild(nullptr, outapp, false, sgmus->GuildID); safe_delete(outapp); } 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.Out(Logs::Detail, Logs::Guilds,"Invalid Client or not in guild. ID=%i", FromID); break; } Log.Out(Logs::Detail, Logs::Guilds,"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(nullptr); 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.Out(Logs::Detail, Logs::Guilds,"Sending OP_GuildMemberUpdate to %i. Name=%s ZoneID=%i",FromID,Name,gmus->ZoneID); c->QueuePacket(outapp); } safe_delete(outapp); } break; case ServerOP_LFGuildUpdate: { if(ZoneLoaded) { char GuildName[33]; char Comments[257]; uint32 FromLevel, ToLevel, Classes, AACount, TimeZone, TimePosted, Toggle; pack->ReadString(GuildName); pack->ReadString(Comments); FromLevel = pack->ReadUInt32(); ToLevel = pack->ReadUInt32(); Classes = pack->ReadUInt32(); AACount = pack->ReadUInt32(); TimeZone = pack->ReadUInt32(); TimePosted = pack->ReadUInt32(); Toggle = pack->ReadUInt32(); uint32 GuildID = GetGuildIDByName(GuildName); if(GuildID == GUILD_NONE) break; EQApplicationPacket *outapp = new EQApplicationPacket(OP_LFGuild, sizeof(LFGuild_GuildToggle_Struct)); LFGuild_GuildToggle_Struct *gts = (LFGuild_GuildToggle_Struct *)outapp->pBuffer; gts->Command = 1; strcpy(gts->Comment, Comments); gts->FromLevel = FromLevel; gts->ToLevel = ToLevel; gts->Classes = Classes; gts->AACount = AACount; gts->TimeZone = TimeZone; gts->Toggle = Toggle; gts->TimePosted = TimePosted; gts->Name[0] = 0; entity_list.QueueClientsGuild(nullptr, outapp, false, GuildID); safe_delete(outapp); break; } } } }