Implement initial expedition system

Add Expeditions logging category

Add handlers for all Dynamic Zone/Expedition related opcodes

Add FormatName string_util function to format character names

Add Zone::IsZone helper method

Add cross zone MessageString support with variable parameters

Add static Client method helpers for cross zone messaging

Add #dz gm command to debug expedition cache for current zone
This commit is contained in:
hg
2020-04-14 17:18:54 -04:00
parent a77f8b582e
commit da067be2fa
31 changed files with 4011 additions and 12 deletions
+118
View File
@@ -49,6 +49,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "../common/zone_numbers.h"
#include "data_bucket.h"
#include "event_codes.h"
#include "expedition.h"
#include "expedition_database.h"
#include "guild_mgr.h"
#include "merc.h"
#include "petitions.h"
@@ -191,6 +193,15 @@ void MapOpcodes()
ConnectedOpcodes[OP_DuelResponse2] = &Client::Handle_OP_DuelResponse2;
ConnectedOpcodes[OP_DumpName] = &Client::Handle_OP_DumpName;
ConnectedOpcodes[OP_Dye] = &Client::Handle_OP_Dye;
ConnectedOpcodes[OP_DzAddPlayer] = &Client::Handle_OP_DzAddPlayer;
ConnectedOpcodes[OP_DzChooseZoneReply] = &Client::Handle_OP_DzChooseZoneReply;
ConnectedOpcodes[OP_DzExpeditionInviteResponse] = &Client::Handle_OP_DzExpeditionInviteResponse;
ConnectedOpcodes[OP_DzListTimers] = &Client::Handle_OP_DzListTimers;
ConnectedOpcodes[OP_DzMakeLeader] = &Client::Handle_OP_DzMakeLeader;
ConnectedOpcodes[OP_DzPlayerList] = &Client::Handle_OP_DzPlayerList;
ConnectedOpcodes[OP_DzRemovePlayer] = &Client::Handle_OP_DzRemovePlayer;
ConnectedOpcodes[OP_DzSwapPlayer] = &Client::Handle_OP_DzSwapPlayer;
ConnectedOpcodes[OP_DzQuit] = &Client::Handle_OP_DzQuit;
ConnectedOpcodes[OP_Emote] = &Client::Handle_OP_Emote;
ConnectedOpcodes[OP_EndLootRequest] = &Client::Handle_OP_EndLootRequest;
ConnectedOpcodes[OP_EnvDamage] = &Client::Handle_OP_EnvDamage;
@@ -266,6 +277,7 @@ void MapOpcodes()
ConnectedOpcodes[OP_ItemViewUnknown] = &Client::Handle_OP_Ignore;
ConnectedOpcodes[OP_Jump] = &Client::Handle_OP_Jump;
ConnectedOpcodes[OP_KeyRing] = &Client::Handle_OP_KeyRing;
ConnectedOpcodes[OP_KickPlayers] = &Client::Handle_OP_KickPlayers;
ConnectedOpcodes[OP_LDoNButton] = &Client::Handle_OP_LDoNButton;
ConnectedOpcodes[OP_LDoNDisarmTraps] = &Client::Handle_OP_LDoNDisarmTraps;
ConnectedOpcodes[OP_LDoNInspect] = &Client::Handle_OP_LDoNInspect;
@@ -885,6 +897,8 @@ void Client::CompleteConnect()
guild_mgr.RequestOnlineGuildMembers(this->CharacterID(), this->GuildID());
}
UpdateExpeditionInfoAndLockouts();
/** Request adventure info **/
auto pack = new ServerPacket(ServerOP_AdventureDataRequest, 64);
strcpy((char*)pack->pBuffer, GetName());
@@ -1701,6 +1715,8 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
/* Task Packets */
LoadClientTaskState();
m_expedition_id = ExpeditionDatabase::GetExpeditionIDFromCharacterID(CharacterID());
/**
* DevTools Load Settings
*/
@@ -5604,6 +5620,91 @@ void Client::Handle_OP_Dye(const EQApplicationPacket *app)
return;
}
void Client::Handle_OP_DzAddPlayer(const EQApplicationPacket *app)
{
auto expedition = GetExpedition();
if (expedition)
{
auto dzcmd = reinterpret_cast<ExpeditionCommand_Struct*>(app->pBuffer);
expedition->DzAddPlayer(this, dzcmd->name);
}
else
{
// the only /dz command that sends an error message if no active expedition
Message(Chat::System, DZ_YOU_NOT_ASSIGNED);
}
}
void Client::Handle_OP_DzChooseZoneReply(const EQApplicationPacket *app)
{
// todo: implement
LogExpeditionsModerate("Handle_OP_DzChooseZoneReply");
auto dzmsg = reinterpret_cast<DynamicZoneChooseZoneReply_Struct*>(app->pBuffer);
}
void Client::Handle_OP_DzExpeditionInviteResponse(const EQApplicationPacket *app)
{
auto expedition = Expedition::FindCachedExpeditionByID(m_pending_expedition_invite_id);
m_pending_expedition_invite_id = 0;
if (expedition)
{
auto dzmsg = reinterpret_cast<ExpeditionInviteResponse_Struct*>(app->pBuffer);
expedition->DzInviteResponse(this, dzmsg->accepted, dzmsg->swapping, dzmsg->swap_name);
}
}
void Client::Handle_OP_DzListTimers(const EQApplicationPacket *app)
{
DzListTimers();
}
void Client::Handle_OP_DzMakeLeader(const EQApplicationPacket *app)
{
auto expedition = GetExpedition();
if (expedition)
{
auto dzcmd = reinterpret_cast<ExpeditionCommand_Struct*>(app->pBuffer);
expedition->DzMakeLeader(this, dzcmd->name);
}
}
void Client::Handle_OP_DzPlayerList(const EQApplicationPacket *app)
{
auto expedition = GetExpedition();
if (expedition) {
expedition->DzPlayerList(this);
}
}
void Client::Handle_OP_DzRemovePlayer(const EQApplicationPacket *app)
{
auto expedition = GetExpedition();
if (expedition)
{
auto dzcmd = reinterpret_cast<ExpeditionCommand_Struct*>(app->pBuffer);
expedition->DzRemovePlayer(this, dzcmd->name);
}
}
void Client::Handle_OP_DzSwapPlayer(const EQApplicationPacket *app)
{
auto expedition = GetExpedition();
if (expedition)
{
auto dzcmd = reinterpret_cast<ExpeditionCommandSwap_Struct*>(app->pBuffer);
expedition->DzSwapPlayer(this, dzcmd->rem_player_name, dzcmd->add_player_name);
}
}
void Client::Handle_OP_DzQuit(const EQApplicationPacket *app)
{
auto expedition = GetExpedition();
if (expedition) {
expedition->DzQuit(this);
}
}
void Client::Handle_OP_Emote(const EQApplicationPacket *app)
{
if (app->size != sizeof(Emote_Struct)) {
@@ -8874,6 +8975,23 @@ void Client::Handle_OP_KeyRing(const EQApplicationPacket *app)
KeyRingList();
}
void Client::Handle_OP_KickPlayers(const EQApplicationPacket *app)
{
auto buf = reinterpret_cast<KickPlayers_Struct*>(app->pBuffer);
if (buf->kick_expedition)
{
auto expedition = GetExpedition();
if (expedition)
{
expedition->DzKickPlayers(this);
}
}
else if (buf->kick_task)
{
// todo: shared tasks
}
}
void Client::Handle_OP_LDoNButton(const EQApplicationPacket *app)
{
if (app->size < sizeof(bool))