Send expedition re-invite to clients that zone

Moves expedition message handling in world to Expedition method
for messages that need special handling
This commit is contained in:
hg 2020-05-18 23:26:00 -04:00
parent 50f9a49911
commit 89c6d1e258
10 changed files with 121 additions and 18 deletions

View File

@ -155,6 +155,8 @@
#define ServerOP_ExpeditionDzSafeReturn 0x040b
#define ServerOP_ExpeditionDzZoneIn 0x040c
#define ServerOP_ExpeditionRemoveCharLockouts 0x040d
#define ServerOP_ExpeditionSaveInvite 0x040e
#define ServerOP_ExpeditionRequestInvite 0x040f
#define ServerOP_DzCharacterChange 0x0450
#define ServerOP_DzRemoveAllCharacters 0x0451
@ -2057,6 +2059,10 @@ struct ServerExpeditionCharacterName_Struct {
char expedition_name[128];
};
struct ServerExpeditionCharacterID_Struct {
uint32_t character_id;
};
struct ServerDzCommand_Struct {
uint32 expedition_id;
uint8 is_char_online; // 0: target name is offline, 1: online

View File

@ -127,6 +127,9 @@ public:
inline void PushToTellQueue(ServerChannelMessage_Struct *scm) { tell_queue.push_back(scm); }
void ProcessTellQueue();
void SetPendingExpeditionInvite(ServerPacket* pack) { p_pending_expedition_invite.reset(pack->Copy()); };
std::unique_ptr<ServerPacket> GetPendingExpeditionInvite() { return std::move(p_pending_expedition_invite); }
private:
void ClearVars(bool iAll = false);
@ -171,6 +174,8 @@ private:
// Tell Queue -- really a vector :D
std::vector<ServerChannelMessage_Struct *> tell_queue;
std::unique_ptr<ServerPacket> p_pending_expedition_invite = nullptr;
};
#endif /*CLIENTENTRY_H_*/

View File

@ -68,6 +68,44 @@ void Expedition::PurgeExpiredCharacterLockouts()
}
}
void Expedition::HandleZoneMessage(ServerPacket* pack)
{
switch (pack->opcode)
{
case ServerOP_ExpeditionGetOnlineMembers:
{
Expedition::GetOnlineMembers(pack);
break;
}
case ServerOP_ExpeditionDzAddPlayer:
{
Expedition::AddPlayer(pack);
break;
}
case ServerOP_ExpeditionDzMakeLeader:
{
Expedition::MakeLeader(pack);
break;
}
case ServerOP_ExpeditionRemoveCharLockouts:
{
auto buf = reinterpret_cast<ServerExpeditionCharacterName_Struct*>(pack->pBuffer);
client_list.SendPacket(buf->character_name, pack);
break;
}
case ServerOP_ExpeditionSaveInvite:
{
Expedition::SaveInvite(pack);
break;
}
case ServerOP_ExpeditionRequestInvite:
{
Expedition::RequestInvite(pack);
break;
}
}
}
void Expedition::AddPlayer(ServerPacket* pack)
{
auto buf = reinterpret_cast<ServerDzCommand_Struct*>(pack->pBuffer);
@ -138,3 +176,31 @@ void Expedition::GetOnlineMembers(ServerPacket* pack)
zoneserver_list.SendPacket(buf->sender_zone_id, buf->sender_instance_id, pack);
}
void Expedition::SaveInvite(ServerPacket* pack)
{
auto buf = reinterpret_cast<ServerDzCommand_Struct*>(pack->pBuffer);
ClientListEntry* invited_cle = client_list.FindCharacter(buf->target_name);
if (invited_cle)
{
// store packet on cle and re-send it when client requests it
buf->is_char_online = true;
pack->opcode = ServerOP_ExpeditionDzAddPlayer;
invited_cle->SetPendingExpeditionInvite(pack);
}
}
void Expedition::RequestInvite(ServerPacket* pack)
{
auto buf = reinterpret_cast<ServerExpeditionCharacterID_Struct*>(pack->pBuffer);
ClientListEntry* cle = client_list.FindCLEByCharacterID(buf->character_id);
if (cle)
{
auto invite_pack = cle->GetPendingExpeditionInvite();
if (invite_pack && cle->Server())
{
cle->Server()->SendPacket(invite_pack.get());
}
}
}

View File

@ -27,9 +27,12 @@ namespace Expedition
{
void PurgeExpiredExpeditions();
void PurgeExpiredCharacterLockouts();
void HandleZoneMessage(ServerPacket* pack);
void AddPlayer(ServerPacket* pack);
void MakeLeader(ServerPacket* pack);
void GetOnlineMembers(ServerPacket* pack);
void SaveInvite(ServerPacket* pack);
void RequestInvite(ServerPacket* pack);
};
#endif

View File

@ -1383,24 +1383,13 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
break;
}
case ServerOP_ExpeditionGetOnlineMembers:
{
Expedition::GetOnlineMembers(pack);
break;
}
case ServerOP_ExpeditionDzAddPlayer:
{
Expedition::AddPlayer(pack);
break;
}
case ServerOP_ExpeditionDzMakeLeader:
{
Expedition::MakeLeader(pack);
break;
}
case ServerOP_ExpeditionRemoveCharLockouts:
case ServerOP_ExpeditionSaveInvite:
case ServerOP_ExpeditionRequestInvite:
{
auto buf = reinterpret_cast<ServerExpeditionCharacterName_Struct*>(pack->pBuffer);
client_list.SendPacket(buf->character_name, pack);
Expedition::HandleZoneMessage(pack);
break;
}
case ServerOP_DzCharacterChange:

View File

@ -9560,7 +9560,6 @@ void Client::SendCrossZoneMessageString(
void Client::UpdateExpeditionInfoAndLockouts()
{
// this is processed by client after entering a zone
// todo: live re-invites if client zoned with a pending invite window open
SendDzCompassUpdate();
auto expedition = GetExpedition();
@ -9582,6 +9581,9 @@ void Client::UpdateExpeditionInfoAndLockouts()
}
LoadAllExpeditionLockouts();
// ask world for any pending invite we saved from a previous zone
RequestPendingExpeditionInvite();
}
Expedition* Client::CreateExpedition(DynamicZone& dz_instance, ExpeditionRequest& request)
@ -9775,6 +9777,15 @@ void Client::SendExpeditionLockoutTimers()
QueuePacket(outapp.get());
}
void Client::RequestPendingExpeditionInvite()
{
uint32_t packsize = sizeof(ServerExpeditionCharacterID_Struct);
auto pack = std::unique_ptr<ServerPacket>(new ServerPacket(ServerOP_ExpeditionRequestInvite, packsize));
auto packbuf = reinterpret_cast<ServerExpeditionCharacterID_Struct*>(pack->pBuffer);
packbuf->character_id = CharacterID();
worldserver.SendPacket(pack.get());
}
void Client::DzListTimers()
{
// only lists player's current replay timer lockouts, not all event lockouts

View File

@ -1131,6 +1131,7 @@ public:
bool IsInExpedition() const { return m_expedition_id != 0; }
void RemoveAllExpeditionLockouts(std::string expedition_name = {});
void RemoveExpeditionLockout(const std::string& expedition_name, const std::string& event_name, bool update_db = false, bool update_client = true);
void RequestPendingExpeditionInvite();
void SendExpeditionLockoutTimers();
void SetExpeditionID(uint32 expedition_id) { m_expedition_id = expedition_id; };
void SetPendingExpeditionInvite(ExpeditionInvite&& invite) { m_pending_expedition_invite = invite; }

View File

@ -1269,6 +1269,16 @@ void Expedition::SendClientExpeditionInfo(Client* client)
}
}
void Expedition::SendWorldPendingInvite(const ExpeditionInvite& invite, const std::string& add_name)
{
LogExpeditions(
"Character [{}] saving pending invite from [{}] to expedition [{}] in world",
add_name, invite.inviter_name, invite.expedition_id
);
SendWorldAddPlayerInvite(invite.inviter_name, invite.swap_remove_name, add_name, true);
}
std::unique_ptr<EQApplicationPacket> Expedition::CreateInfoPacket(bool clear)
{
uint32_t outsize = sizeof(ExpeditionInfo_Struct);
@ -1375,10 +1385,11 @@ void Expedition::SendWorldExpeditionUpdate(bool destroyed)
}
void Expedition::SendWorldAddPlayerInvite(
const std::string& inviter_name, const std::string& swap_remove_name, const std::string& add_name)
const std::string& inviter_name, const std::string& swap_remove_name, const std::string& add_name, bool pending)
{
auto server_opcode = pending ? ServerOP_ExpeditionSaveInvite : ServerOP_ExpeditionDzAddPlayer;
uint32_t pack_size = sizeof(ServerDzCommand_Struct);
auto pack = std::unique_ptr<ServerPacket>(new ServerPacket(ServerOP_ExpeditionDzAddPlayer, pack_size));
auto pack = std::unique_ptr<ServerPacket>(new ServerPacket(server_opcode, pack_size));
auto buf = reinterpret_cast<ServerDzCommand_Struct*>(pack->pBuffer);
buf->expedition_id = GetID();
buf->is_char_online = false;

View File

@ -115,6 +115,7 @@ public:
void RemoveLockout(const std::string& event_name);
void SendClientExpeditionInfo(Client* client);
void SendWorldPendingInvite(const ExpeditionInvite& invite, const std::string& add_name);
void DzAddPlayer(Client* requester, std::string add_char_name, std::string swap_remove_name = {});
void DzAddPlayerContinue(std::string leader_name, std::string add_char_name, std::string swap_remove_name = {});
@ -155,7 +156,7 @@ private:
void SendWorldDzLocationUpdate(uint16_t server_opcode, const DynamicZoneLocation& location);
void SendWorldExpeditionUpdate(bool destroyed = false);
void SendWorldGetOnlineMembers();
void SendWorldAddPlayerInvite(const std::string& inviter_name, const std::string& swap_remove_name, const std::string& add_name);
void SendWorldAddPlayerInvite(const std::string& inviter_name, const std::string& swap_remove_name, const std::string& add_name, bool pending = false);
void SendWorldLeaderChanged();
void SendWorldLockoutUpdate(const std::string& event_name, uint64_t expire_time, uint32_t duration, bool remove = false);
void SendWorldMakeLeaderRequest(const std::string& requester_name, const std::string& new_leader_name);

View File

@ -404,6 +404,16 @@ void Client::DoZoneSuccess(ZoneChange_Struct *zc, uint16 zone_id, uint32 instanc
if(this->GetPet())
entity_list.RemoveFromHateLists(this->GetPet());
if (GetPendingExpeditionInviteID() != 0)
{
// live re-invites if client zoned with a pending invite, save pending invite info in world
auto expedition = Expedition::FindCachedExpeditionByID(GetPendingExpeditionInviteID());
if (expedition)
{
expedition->SendWorldPendingInvite(m_pending_expedition_invite, GetName());
}
}
LogInfo("Zoning [{}] to: [{}] ([{}]) - ([{}]) x [{}] y [{}] z [{}]", m_pp.name, ZoneName(zone_id), zone_id, instance_id, dest_x, dest_y, dest_z);
//set the player's coordinates in the new zone so they have them