mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-03 19:33:43 +00:00
refactor: activity game messages as structs
Converts ActivityEnter, ActivityExit, ActivityStart, ActivityStop,
ActivityPause, StartActivityTime, RequestActivityEnter,
RequestActivityExit and ShowActivityCountdown to NetGameMsgs in
ActivityMessages.{h,cpp}, switches their callers (racing, shooting
gallery, survival, waves, AG course, NT combat challenge) and deletes
the old GameMessages::Send* / HandleRequestActivityExit functions.
REQUEST_ACTIVITY_EXIT is registered in GameMessageHandler's map.
No wire change. Verified by comparing every struct byte for byte with a
frozen verbatim copy of the old functions (tests/.../Legacy) over a
grid of inputs, both to one client and as a broadcast (a temporary test
proved the copy matched production before it was deleted), plus hand
computed golden bytes, round trips and a deliberate field mutation that
made the tests fail. Layouts confirmed against the 1.10.64 client in
Ghidra. Only difference: a broadcast no longer makes
the extra Send(UNASSIGNED, false) that RakNet already rejected.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#include "DestroyableComponent.h"
|
||||
#include "EntityManager.h"
|
||||
#include "GameMessages.h"
|
||||
#include "ActivityMessages.h"
|
||||
#include "InventoryComponent.h"
|
||||
#include "Item.h"
|
||||
#include "MissionComponent.h"
|
||||
@@ -700,8 +701,9 @@ void RacingControlComponent::Update(float deltaTime) {
|
||||
}
|
||||
|
||||
// Start the race
|
||||
GameMessages::SendActivityStart(m_Parent->GetObjectID(),
|
||||
UNASSIGNED_SYSTEM_ADDRESS);
|
||||
GameMessages::ActivityStart activityStart;
|
||||
activityStart.target = m_Parent->GetObjectID();
|
||||
activityStart.Send(UNASSIGNED_SYSTEM_ADDRESS);
|
||||
|
||||
m_Started = true;
|
||||
|
||||
|
||||
82
dGame/dGameMessages/ActivityMessages.cpp
Normal file
82
dGame/dGameMessages/ActivityMessages.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
#include "ActivityMessages.h"
|
||||
|
||||
#include "BitStreamUtils.h"
|
||||
#include "Entity.h"
|
||||
#include "EntityManager.h"
|
||||
#include "Game.h"
|
||||
|
||||
namespace GameMessages {
|
||||
void ActivityStop::Serialize(RakNet::BitStream& bitStream) const {
|
||||
bitStream.Write(bExit);
|
||||
bitStream.Write(bUserCancel);
|
||||
}
|
||||
|
||||
bool ActivityStop::Deserialize(RakNet::BitStream& bitStream) {
|
||||
VALIDATE_READ(bitStream.Read(bExit));
|
||||
VALIDATE_READ(bitStream.Read(bUserCancel));
|
||||
return true;
|
||||
}
|
||||
|
||||
void ActivityPause::Serialize(RakNet::BitStream& bitStream) const {
|
||||
bitStream.Write(bPause);
|
||||
}
|
||||
|
||||
bool ActivityPause::Deserialize(RakNet::BitStream& bitStream) {
|
||||
VALIDATE_READ(bitStream.Read(bPause));
|
||||
return true;
|
||||
}
|
||||
|
||||
void StartActivityTime::Serialize(RakNet::BitStream& bitStream) const {
|
||||
bitStream.Write(startTime);
|
||||
}
|
||||
|
||||
bool StartActivityTime::Deserialize(RakNet::BitStream& bitStream) {
|
||||
VALIDATE_READ(bitStream.Read(startTime));
|
||||
return true;
|
||||
}
|
||||
|
||||
void RequestActivityEnter::Serialize(RakNet::BitStream& bitStream) const {
|
||||
bitStream.Write(bStart);
|
||||
bitStream.Write(userID);
|
||||
}
|
||||
|
||||
bool RequestActivityEnter::Deserialize(RakNet::BitStream& bitStream) {
|
||||
VALIDATE_READ(bitStream.Read(bStart));
|
||||
VALIDATE_READ(bitStream.Read(userID));
|
||||
return true;
|
||||
}
|
||||
|
||||
void RequestActivityExit::Serialize(RakNet::BitStream& bitStream) const {
|
||||
bitStream.Write(bUserCancel);
|
||||
bitStream.Write(userID);
|
||||
}
|
||||
|
||||
bool RequestActivityExit::Deserialize(RakNet::BitStream& bitStream) {
|
||||
VALIDATE_READ(bitStream.Read(bUserCancel));
|
||||
VALIDATE_READ(bitStream.Read(userID));
|
||||
return true;
|
||||
}
|
||||
|
||||
void RequestActivityExit::Handle(Entity& entity, const SystemAddress& sysAddr) {
|
||||
if (!bUserCancel) return;
|
||||
|
||||
auto* player = Game::entityManager->GetEntity(userID);
|
||||
if (!player) return;
|
||||
entity.RequestActivityExit(&entity, userID, bUserCancel);
|
||||
}
|
||||
|
||||
void ShowActivityCountdown::Serialize(RakNet::BitStream& bitStream) const {
|
||||
bitStream.Write(bPlayAdditionalSound);
|
||||
bitStream.Write(bPlayCountdownSound);
|
||||
BitStreamUtils::WriteLengthPrefixed<uint32_t>(bitStream, sndName);
|
||||
bitStream.Write(stateToPlaySoundOn);
|
||||
}
|
||||
|
||||
bool ShowActivityCountdown::Deserialize(RakNet::BitStream& bitStream) {
|
||||
VALIDATE_READ(bitStream.Read(bPlayAdditionalSound));
|
||||
VALIDATE_READ(bitStream.Read(bPlayCountdownSound));
|
||||
VALIDATE_READ(BitStreamUtils::ReadLengthPrefixed<uint32_t>(bitStream, sndName));
|
||||
VALIDATE_READ(bitStream.Read(stateToPlaySoundOn));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
88
dGame/dGameMessages/ActivityMessages.h
Normal file
88
dGame/dGameMessages/ActivityMessages.h
Normal file
@@ -0,0 +1,88 @@
|
||||
#ifndef ACTIVITYMESSAGES_H
|
||||
#define ACTIVITYMESSAGES_H
|
||||
|
||||
#include "GameMessages.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
// Game messages for the activity lifecycle (minigames, races, shooting galleries, survival...).
|
||||
// Field names and wire order match the client (legouniverse.exe 1.10.64). Fields are listed in wire order.
|
||||
namespace GameMessages {
|
||||
// Server -> client. No payload.
|
||||
struct ActivityEnter : public NetGameMsg {
|
||||
ActivityEnter() : NetGameMsg(MessageType::Game::ACTIVITY_ENTER) {}
|
||||
};
|
||||
|
||||
// Server -> client. No payload.
|
||||
struct ActivityExit : public NetGameMsg {
|
||||
ActivityExit() : NetGameMsg(MessageType::Game::ACTIVITY_EXIT) {}
|
||||
};
|
||||
|
||||
// Server -> client. No payload.
|
||||
struct ActivityStart : public NetGameMsg {
|
||||
ActivityStart() : NetGameMsg(MessageType::Game::ACTIVITY_START) {}
|
||||
};
|
||||
|
||||
// Server -> client.
|
||||
struct ActivityStop : public NetGameMsg {
|
||||
ActivityStop() : NetGameMsg(MessageType::Game::ACTIVITY_STOP) {}
|
||||
void Serialize(RakNet::BitStream& bitStream) const override;
|
||||
bool Deserialize(RakNet::BitStream& bitStream) override;
|
||||
|
||||
bool bExit{};
|
||||
bool bUserCancel{};
|
||||
};
|
||||
|
||||
// Server -> client.
|
||||
struct ActivityPause : public NetGameMsg {
|
||||
ActivityPause() : NetGameMsg(MessageType::Game::ACTIVITY_PAUSE) {}
|
||||
void Serialize(RakNet::BitStream& bitStream) const override;
|
||||
bool Deserialize(RakNet::BitStream& bitStream) override;
|
||||
|
||||
bool bPause{};
|
||||
};
|
||||
|
||||
// Server -> client.
|
||||
struct StartActivityTime : public NetGameMsg {
|
||||
StartActivityTime() : NetGameMsg(MessageType::Game::START_ACTIVITY_TIME) {}
|
||||
void Serialize(RakNet::BitStream& bitStream) const override;
|
||||
bool Deserialize(RakNet::BitStream& bitStream) override;
|
||||
|
||||
float startTime{};
|
||||
};
|
||||
|
||||
// Client -> server in the client, but historically also sent by DLU. Kept for completeness.
|
||||
struct RequestActivityEnter : public NetGameMsg {
|
||||
RequestActivityEnter() : NetGameMsg(MessageType::Game::REQUEST_ACTIVITY_ENTER) {}
|
||||
void Serialize(RakNet::BitStream& bitStream) const override;
|
||||
bool Deserialize(RakNet::BitStream& bitStream) override;
|
||||
|
||||
bool bStart{};
|
||||
LWOOBJID userID{};
|
||||
};
|
||||
|
||||
// Client -> server. Sent when the player leaves an activity (e.g. closes the minigame UI).
|
||||
struct RequestActivityExit : public NetGameMsg {
|
||||
RequestActivityExit() : NetGameMsg(MessageType::Game::REQUEST_ACTIVITY_EXIT) {}
|
||||
void Serialize(RakNet::BitStream& bitStream) const override;
|
||||
bool Deserialize(RakNet::BitStream& bitStream) override;
|
||||
void Handle(Entity& entity, const SystemAddress& sysAddr) override;
|
||||
|
||||
bool bUserCancel{};
|
||||
LWOOBJID userID{};
|
||||
};
|
||||
|
||||
// Server -> client.
|
||||
struct ShowActivityCountdown : public NetGameMsg {
|
||||
ShowActivityCountdown() : NetGameMsg(MessageType::Game::SHOW_ACTIVITY_COUNTDOWN) {}
|
||||
void Serialize(RakNet::BitStream& bitStream) const override;
|
||||
bool Deserialize(RakNet::BitStream& bitStream) override;
|
||||
|
||||
bool bPlayAdditionalSound{};
|
||||
bool bPlayCountdownSound{};
|
||||
std::u16string sndName{};
|
||||
int32_t stateToPlaySoundOn{};
|
||||
};
|
||||
};
|
||||
|
||||
#endif // ACTIVITYMESSAGES_H
|
||||
@@ -1,4 +1,5 @@
|
||||
set(DGAME_DGAMEMESSAGES_SOURCES
|
||||
"ActivityMessages.cpp"
|
||||
"GameMessageHandler.cpp"
|
||||
"GameMessages.cpp"
|
||||
"PropertyDataMessage.cpp"
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "StartSkill.h"
|
||||
#include "EchoStartSkill.h"
|
||||
#include "EchoSyncSkill.h"
|
||||
#include "ActivityMessages.h"
|
||||
#include "eMissionTaskType.h"
|
||||
#include "eReplicaComponentType.h"
|
||||
#include "ServiceType.h"
|
||||
@@ -49,6 +50,7 @@ namespace {
|
||||
{ REQUEST_SERVER_OBJECT_INFO, []() { return std::make_unique<RequestServerObjectInfo>(); } },
|
||||
{ SHOOTING_GALLERY_FIRE, []() { return std::make_unique<ShootingGalleryFire>(); } },
|
||||
{ PICKUP_ITEM, []() { return std::make_unique<PickupItem>(); } },
|
||||
{ REQUEST_ACTIVITY_EXIT, []() { return std::make_unique<RequestActivityExit>(); } },
|
||||
};
|
||||
};
|
||||
|
||||
@@ -718,9 +720,6 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream& inStream, const System
|
||||
case MessageType::Game::ZONE_SUMMARY_DISMISSED:
|
||||
GameMessages::HandleZoneSummaryDismissed(inStream, entity);
|
||||
break;
|
||||
case MessageType::Game::REQUEST_ACTIVITY_EXIT:
|
||||
GameMessages::HandleRequestActivityExit(inStream, entity);
|
||||
break;
|
||||
case MessageType::Game::ADD_DONATION_ITEM:
|
||||
GameMessages::HandleAddDonationItem(inStream, entity, sysAddr);
|
||||
break;
|
||||
|
||||
@@ -1460,43 +1460,6 @@ void GameMessages::SendRequestActivitySummaryLeaderboardData(const LWOOBJID& obj
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
void GameMessages::SendActivityPause(LWOOBJID objectId, bool pause, const SystemAddress& sysAddr) {
|
||||
CBITSTREAM;
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(objectId);
|
||||
bitStream.Write(MessageType::Game::ACTIVITY_PAUSE);
|
||||
bitStream.Write(pause);
|
||||
|
||||
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST;
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
void GameMessages::SendStartActivityTime(LWOOBJID objectId, float_t startTime, const SystemAddress& sysAddr) {
|
||||
CBITSTREAM;
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(objectId);
|
||||
bitStream.Write(MessageType::Game::START_ACTIVITY_TIME);
|
||||
bitStream.Write<float_t>(startTime);
|
||||
|
||||
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST;
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
void GameMessages::SendRequestActivityEnter(LWOOBJID objectId, const SystemAddress& sysAddr, bool bStart, LWOOBJID userID) {
|
||||
CBITSTREAM;
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(objectId);
|
||||
bitStream.Write(MessageType::Game::REQUEST_ACTIVITY_ENTER);
|
||||
bitStream.Write<bool>(bStart);
|
||||
bitStream.Write<LWOOBJID>(userID);
|
||||
|
||||
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST;
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
void GameMessages::NotifyLevelRewards(LWOOBJID objectID, const SystemAddress& sysAddr, int level, bool sending_rewards) {
|
||||
CBITSTREAM;
|
||||
CMSGHEADER;
|
||||
@@ -4394,55 +4357,8 @@ void GameMessages::SendNotifyRacingClient(LWOOBJID objectId, int32_t eventType,
|
||||
}
|
||||
|
||||
|
||||
void GameMessages::SendActivityEnter(LWOOBJID objectId, const SystemAddress& sysAddr) {
|
||||
CBITSTREAM;
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(objectId);
|
||||
bitStream.Write(MessageType::Game::ACTIVITY_ENTER);
|
||||
|
||||
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST;
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
|
||||
void GameMessages::SendActivityStart(LWOOBJID objectId, const SystemAddress& sysAddr) {
|
||||
CBITSTREAM;
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(objectId);
|
||||
bitStream.Write(MessageType::Game::ACTIVITY_START);
|
||||
|
||||
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST;
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
|
||||
void GameMessages::SendActivityExit(LWOOBJID objectId, const SystemAddress& sysAddr) {
|
||||
CBITSTREAM;
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(objectId);
|
||||
bitStream.Write(MessageType::Game::ACTIVITY_EXIT);
|
||||
|
||||
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST;
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
|
||||
void GameMessages::SendActivityStop(LWOOBJID objectId, bool bExit, bool bUserCancel, const SystemAddress& sysAddr) {
|
||||
CBITSTREAM;
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(objectId);
|
||||
bitStream.Write(MessageType::Game::ACTIVITY_STOP);
|
||||
|
||||
bitStream.Write(bExit);
|
||||
bitStream.Write(bUserCancel);
|
||||
|
||||
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST;
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
|
||||
void GameMessages::SendVehicleAddPassiveBoostAction(LWOOBJID objectId, const SystemAddress& sysAddr) {
|
||||
@@ -4603,28 +4519,6 @@ void GameMessages::SendResponseMoveItemBetweenInventoryTypes(LWOOBJID objectId,
|
||||
}
|
||||
|
||||
|
||||
void GameMessages::SendShowActivityCountdown(LWOOBJID objectId, bool bPlayAdditionalSound, bool bPlayCountdownSound, std::u16string sndName, int32_t stateToPlaySoundOn, const SystemAddress& sysAddr) {
|
||||
CBITSTREAM;
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(objectId);
|
||||
bitStream.Write(MessageType::Game::SHOW_ACTIVITY_COUNTDOWN);
|
||||
|
||||
bitStream.Write(bPlayAdditionalSound);
|
||||
|
||||
bitStream.Write(bPlayCountdownSound);
|
||||
|
||||
bitStream.Write<uint32_t>(sndName.size());
|
||||
for (auto character : sndName) {
|
||||
bitStream.Write(character);
|
||||
}
|
||||
|
||||
bitStream.Write(stateToPlaySoundOn);
|
||||
|
||||
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST;
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------- Handlers ------------------------------------------------------------------
|
||||
@@ -6061,18 +5955,6 @@ void GameMessages::SendShowBillboardInteractIcon(const SystemAddress& sysAddr, L
|
||||
else SEND_PACKET
|
||||
}
|
||||
|
||||
void GameMessages::HandleRequestActivityExit(RakNet::BitStream& inStream, Entity* entity) {
|
||||
bool canceled = false;
|
||||
inStream.Read(canceled);
|
||||
if (!canceled) return;
|
||||
|
||||
LWOOBJID player_id = LWOOBJID_EMPTY;
|
||||
inStream.Read(player_id);
|
||||
auto player = Game::entityManager->GetEntity(player_id);
|
||||
if (!entity || !player) return;
|
||||
entity->RequestActivityExit(entity, player_id, canceled);
|
||||
}
|
||||
|
||||
void GameMessages::HandleAddDonationItem(RakNet::BitStream& inStream, Entity* entity, const SystemAddress& sysAddr) {
|
||||
uint32_t count = 1;
|
||||
bool hasCount = false;
|
||||
|
||||
@@ -618,13 +618,6 @@ namespace GameMessages {
|
||||
|
||||
void SendNotifyRacingClient(LWOOBJID objectId, int32_t eventType, int32_t param1, LWOOBJID paramObj, std::u16string paramStr, LWOOBJID singleClient, const SystemAddress& sysAddr);
|
||||
|
||||
void SendActivityEnter(LWOOBJID objectId, const SystemAddress& sysAddr);
|
||||
void SendActivityStart(LWOOBJID objectId, const SystemAddress& sysAddr);
|
||||
void SendActivityExit(LWOOBJID objectId, const SystemAddress& sysAddr);
|
||||
void SendActivityStop(LWOOBJID objectId, bool bExit, bool bUserCancel, const SystemAddress& sysAddr);
|
||||
void SendActivityPause(LWOOBJID objectId, bool pause = false, const SystemAddress& sysAddr = UNASSIGNED_SYSTEM_ADDRESS);
|
||||
void SendStartActivityTime(LWOOBJID objectId, float_t startTime, const SystemAddress& sysAddr = UNASSIGNED_SYSTEM_ADDRESS);
|
||||
void SendRequestActivityEnter(LWOOBJID objectId, const SystemAddress& sysAddr, bool bStart, LWOOBJID userID);
|
||||
void SendUseItemRequirementsResponse(LWOOBJID objectID, const SystemAddress& sysAddr, eUseItemResponse itemResponse);
|
||||
|
||||
// SG:
|
||||
@@ -675,8 +668,6 @@ namespace GameMessages {
|
||||
void HandleRequestMoveItemBetweenInventoryTypes(RakNet::BitStream& inStream, Entity* entity, const SystemAddress& sysAddr);
|
||||
void SendResponseMoveItemBetweenInventoryTypes(LWOOBJID objectId, const SystemAddress& sysAddr, eInventoryType inventoryTypeDestination, eInventoryType inventoryTypeSource, eReponseMoveItemBetweenInventoryTypeCode response);
|
||||
|
||||
void SendShowActivityCountdown(LWOOBJID objectId, bool bPlayAdditionalSound, bool bPlayCountdownSound, std::u16string sndName, int32_t stateToPlaySoundOn, const SystemAddress& sysAddr);
|
||||
|
||||
//Handlers:
|
||||
|
||||
void HandleToggleGhostReferenceOverride(RakNet::BitStream& inStream, Entity* entity, const SystemAddress& sysAddr);
|
||||
@@ -741,7 +732,6 @@ namespace GameMessages {
|
||||
void SendDeactivateBubbleBuffFromServer(LWOOBJID objectId, const SystemAddress& sysAddr);
|
||||
|
||||
void HandleZoneSummaryDismissed(RakNet::BitStream& inStream, Entity* entity);
|
||||
void HandleRequestActivityExit(RakNet::BitStream& inStream, Entity* entity);
|
||||
|
||||
// Donation vendor
|
||||
void HandleAddDonationItem(RakNet::BitStream& inStream, Entity* entity, const SystemAddress& sysAddr);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "EntityManager.h"
|
||||
#include "ScriptedActivityComponent.h"
|
||||
#include "GameMessages.h"
|
||||
#include "ActivityMessages.h"
|
||||
#include "LeaderboardManager.h"
|
||||
#include "dServer.h"
|
||||
#include "eMissionTaskType.h"
|
||||
@@ -43,7 +44,9 @@ void NpcAgCourseStarter::OnMessageBoxResponse(Entity* self, Entity* sender, int3
|
||||
Game::entityManager->SerializeEntity(self);
|
||||
} else if (identifier == u"player_dialog_start_course" && button == 1) {
|
||||
GameMessages::SendNotifyClientObject(selfId, u"start_timer", 0, 0, LWOOBJID_EMPTY, "", senderSysAddr);
|
||||
GameMessages::SendActivityStart(selfId, senderSysAddr);
|
||||
GameMessages::ActivityStart activityStart;
|
||||
activityStart.target = selfId;
|
||||
activityStart.Send(senderSysAddr);
|
||||
|
||||
const auto score = scriptedActivityComponent->GetActivityValue(senderId, 1);
|
||||
if (score != 0 && score != -1.0f) return;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "NtCombatChallengeServer.h"
|
||||
#include "GameMessages.h"
|
||||
#include "ActivityMessages.h"
|
||||
#include "EntityManager.h"
|
||||
#include "EntityInfo.h"
|
||||
#include "InventoryComponent.h"
|
||||
@@ -58,7 +59,9 @@ void NtCombatChallengeServer::OnMessageBoxResponse(Entity* self, Entity* sender,
|
||||
|
||||
self->AddTimer("start_delay", 2.0f);
|
||||
|
||||
GameMessages::SendShowActivityCountdown(self->GetObjectID(), false, false, u"", 0, sender->GetSystemAddress());
|
||||
GameMessages::ShowActivityCountdown countdown;
|
||||
countdown.target = self->GetObjectID();
|
||||
countdown.Send(sender->GetSystemAddress());
|
||||
|
||||
self->SetNetworkVar(u"toggle", true);
|
||||
} else if (identifier == u"CloseButton") {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "BaseSurvivalServer.h"
|
||||
#include "GameMessages.h"
|
||||
#include "ActivityMessages.h"
|
||||
#include "DestroyableComponent.h"
|
||||
#include "EntityManager.h"
|
||||
#include "dZoneManager.h"
|
||||
@@ -278,7 +279,9 @@ void BaseSurvivalServer::PlayerAccepted(Entity* self, LWOOBJID playerID) {
|
||||
}
|
||||
|
||||
void BaseSurvivalServer::StartWaves(Entity* self) {
|
||||
GameMessages::SendActivityStart(self->GetObjectID(), UNASSIGNED_SYSTEM_ADDRESS);
|
||||
GameMessages::ActivityStart activityStart;
|
||||
activityStart.target = self->GetObjectID();
|
||||
activityStart.Send(UNASSIGNED_SYSTEM_ADDRESS);
|
||||
|
||||
self->SetVar<bool>(PlayersReadyVariable, true);
|
||||
self->SetVar<uint32_t>(BaseMobSetIndexVariable, 0);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "BaseWavesServer.h"
|
||||
#include "GameMessages.h"
|
||||
#include "ActivityMessages.h"
|
||||
#include "DestroyableComponent.h"
|
||||
#include "EntityManager.h"
|
||||
#include "dZoneManager.h"
|
||||
@@ -273,7 +274,9 @@ void BaseWavesServer::PlayerAccepted(Entity* self, LWOOBJID playerID) {
|
||||
|
||||
// Done
|
||||
void BaseWavesServer::StartWaves(Entity* self) {
|
||||
GameMessages::SendActivityStart(self->GetObjectID(), UNASSIGNED_SYSTEM_ADDRESS);
|
||||
GameMessages::ActivityStart activityStart;
|
||||
activityStart.target = self->GetObjectID();
|
||||
activityStart.Send(UNASSIGNED_SYSTEM_ADDRESS);
|
||||
|
||||
self->SetNetworkVar<std::string>(WatchingIntroVariable, "");
|
||||
self->SetVar<bool>(PlayersReadyVariable, true);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "SGCannon.h"
|
||||
#include "EntityManager.h"
|
||||
#include "GameMessages.h"
|
||||
#include "ActivityMessages.h"
|
||||
#include "dZoneManager.h"
|
||||
#include "Character.h"
|
||||
#include "ShootingGalleryComponent.h"
|
||||
@@ -83,7 +84,9 @@ void SGCannon::OnActivityStateChangeRequest(Entity* self, LWOOBJID senderID, int
|
||||
if (player != nullptr) {
|
||||
LOG("Player is ready");
|
||||
|
||||
GameMessages::SendActivityEnter(self->GetObjectID(), player->GetSystemAddress());
|
||||
GameMessages::ActivityEnter activityEnter;
|
||||
activityEnter.target = self->GetObjectID();
|
||||
activityEnter.Send(player->GetSystemAddress());
|
||||
|
||||
auto* shootingGalleryComponent = self->GetComponent<ShootingGalleryComponent>();
|
||||
|
||||
@@ -186,10 +189,16 @@ void SGCannon::SpawnWaveTimerFunc(Entity* self) {
|
||||
if (player != nullptr) {
|
||||
GameMessages::SendPlayFXEffect(player->GetObjectID(), -1, u"SG-start", "");
|
||||
|
||||
GameMessages::SendStartActivityTime(self->GetObjectID(), timeLimit, player->GetSystemAddress());
|
||||
GameMessages::StartActivityTime startActivityTime;
|
||||
startActivityTime.target = self->GetObjectID();
|
||||
startActivityTime.startTime = timeLimit;
|
||||
startActivityTime.Send(player->GetSystemAddress());
|
||||
LOG("Sending ActivityPause false");
|
||||
|
||||
GameMessages::SendActivityPause(self->GetObjectID(), false, player->GetSystemAddress());
|
||||
GameMessages::ActivityPause activityPause;
|
||||
activityPause.target = self->GetObjectID();
|
||||
activityPause.bPause = false;
|
||||
activityPause.Send(player->GetSystemAddress());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -199,8 +208,12 @@ void SGCannon::EndWaveTimerFunc(Entity* self) {
|
||||
TimerToggle(self);
|
||||
RecordPlayerScore(self);
|
||||
|
||||
GameMessages::ActivityPause activityPause;
|
||||
activityPause.target = self->GetObjectID();
|
||||
activityPause.bPause = true;
|
||||
|
||||
if (self->GetVar<uint32_t>(ThisWaveVariable) >= 2) {
|
||||
GameMessages::SendActivityPause(self->GetObjectID(), true);
|
||||
activityPause.Send(UNASSIGNED_SYSTEM_ADDRESS);
|
||||
ActivityTimerStart(self, GameOverTimer, 0.1, 0.1);
|
||||
return;
|
||||
}
|
||||
@@ -220,7 +233,7 @@ void SGCannon::EndWaveTimerFunc(Entity* self) {
|
||||
|
||||
LOG("Sending ActivityPause true");
|
||||
|
||||
GameMessages::SendActivityPause(self->GetObjectID(), true);
|
||||
activityPause.Send(UNASSIGNED_SYSTEM_ADDRESS);
|
||||
if (self->GetVar<bool>(SuperChargeActiveVariable) && !self->GetVar<bool>(SuperChargePausedVariable)) {
|
||||
PauseChargeCannon(self);
|
||||
}
|
||||
@@ -231,7 +244,10 @@ void SGCannon::GameOverTimerFunc(Entity* self) {
|
||||
if (player != nullptr) {
|
||||
LOG_DEBUG("Sending ActivityPause true");
|
||||
|
||||
GameMessages::SendActivityPause(self->GetObjectID(), true, player->GetSystemAddress());
|
||||
GameMessages::ActivityPause activityPause;
|
||||
activityPause.target = self->GetObjectID();
|
||||
activityPause.bPause = true;
|
||||
activityPause.Send(player->GetSystemAddress());
|
||||
|
||||
ActivityTimerStart(self, EndGameBufferTimer, 1, 1);
|
||||
|
||||
@@ -342,7 +358,9 @@ void SGCannon::StartGame(Entity* self) {
|
||||
// The client cant accept more than 10 results.
|
||||
GetLeaderboardData(self, player->GetObjectID(), GetConstants().activityID, 10);
|
||||
LOG("Sending ActivityStart");
|
||||
GameMessages::SendActivityStart(self->GetObjectID(), player->GetSystemAddress());
|
||||
GameMessages::ActivityStart activityStart;
|
||||
activityStart.target = self->GetObjectID();
|
||||
activityStart.Send(player->GetSystemAddress());
|
||||
|
||||
GameMessages::SendPlayFXEffect(self->GetObjectID(), -1, u"start", "");
|
||||
|
||||
@@ -602,7 +620,11 @@ void SGCannon::StopGame(Entity* self, bool cancel) {
|
||||
self->SetNetworkVar<std::u16string>(u"UI_Rewards", GeneralUtils::ASCIIToUTF16(stream.str()));
|
||||
}
|
||||
|
||||
GameMessages::SendActivityStop(self->GetObjectID(), false, cancel, player->GetSystemAddress());
|
||||
GameMessages::ActivityStop activityStop;
|
||||
activityStop.target = self->GetObjectID();
|
||||
activityStop.bExit = false;
|
||||
activityStop.bUserCancel = cancel;
|
||||
activityStop.Send(player->GetSystemAddress());
|
||||
self->SetVar<bool>(GameStartedVariable, false);
|
||||
ActivityTimerStopAllTimers(self);
|
||||
|
||||
|
||||
222
tests/dGameTests/dGameMessagesTests/ActivityMessagesTests.cpp
Normal file
222
tests/dGameTests/dGameMessagesTests/ActivityMessagesTests.cpp
Normal file
@@ -0,0 +1,222 @@
|
||||
#include "ActivityMessages.h"
|
||||
#include "GameDependencies.h"
|
||||
#include "PacketTestUtils.h"
|
||||
#include "Legacy/ActivityMessagesLegacy.h"
|
||||
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using namespace PacketTestUtils;
|
||||
|
||||
namespace {
|
||||
SystemAddress ClientAddress() {
|
||||
SystemAddress address;
|
||||
address.binaryAddress = 0x0100007f;
|
||||
address.port = 2003;
|
||||
return address;
|
||||
}
|
||||
|
||||
const std::array<LWOOBJID, 3> g_Targets = { LWOOBJID_EMPTY, 0x1000000000000001LL, 0x0102030405060708LL };
|
||||
const std::array<SystemAddress, 2> g_Addresses = { ClientAddress(), UNASSIGNED_SYSTEM_ADDRESS };
|
||||
|
||||
PacketBytes StructPacket(const GameMessages::NetGameMsg& msg) {
|
||||
RakNet::BitStream bitStream;
|
||||
msg.WritePacket(bitStream);
|
||||
return FromBitStream(bitStream);
|
||||
}
|
||||
|
||||
// Sends the same message through the frozen legacy function and through the struct, to one client and as a
|
||||
// broadcast, and requires identical bytes and the same effective destination.
|
||||
void ExpectSameAsLegacy(const std::function<void(const SystemAddress&)>& legacySend, const GameMessages::NetGameMsg& msg) {
|
||||
for (const auto& address : g_Addresses) {
|
||||
SCOPED_TRACE(address == UNASSIGNED_SYSTEM_ADDRESS ? "broadcast" : "single client");
|
||||
const auto legacyPackets = Capture([&] { legacySend(address); });
|
||||
const auto newPackets = Capture([&] { msg.Send(address); });
|
||||
|
||||
ASSERT_FALSE(legacyPackets.empty());
|
||||
ASSERT_EQ(newPackets.size(), 1);
|
||||
// The legacy broadcast path also did a second Send(UNASSIGNED_SYSTEM_ADDRESS, broadcast = false),
|
||||
// which RakPeer::Send rejects without sending anything. Every copy must still match byte for byte.
|
||||
for (const auto& legacyPacket : legacyPackets) {
|
||||
EXPECT_PACKET_EQ(FromCapture(legacyPacket), FromCapture(newPackets[0]));
|
||||
}
|
||||
EXPECT_EQ(legacyPackets[0].broadcast, newPackets[0].broadcast);
|
||||
EXPECT_EQ(legacyPackets[0].sysAddr, newPackets[0].sysAddr);
|
||||
EXPECT_PACKET_EQ(FromCapture(newPackets[0]), StructPacket(msg));
|
||||
}
|
||||
}
|
||||
|
||||
// Serializes msg, reads it back into a fresh T and checks the fresh copy serializes to the same bytes.
|
||||
template<typename T>
|
||||
T RoundTrip(const T& msg) {
|
||||
RakNet::BitStream bitStream;
|
||||
msg.Serialize(bitStream);
|
||||
T copy;
|
||||
EXPECT_TRUE(copy.Deserialize(bitStream));
|
||||
EXPECT_EQ(bitStream.GetNumberOfUnreadBits(), 0);
|
||||
RakNet::BitStream again;
|
||||
copy.Serialize(again);
|
||||
EXPECT_PACKET_EQ(FromBitStream(bitStream), FromBitStream(again));
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
|
||||
class ActivityMessagesTests : public GameDependenciesTest {
|
||||
protected:
|
||||
void SetUp() override { SetUpDependencies(); }
|
||||
void TearDown() override { TearDownDependencies(); }
|
||||
};
|
||||
|
||||
TEST_F(ActivityMessagesTests, NoPayloadMessagesMatchLegacy) {
|
||||
for (const auto target : g_Targets) {
|
||||
GameMessages::ActivityEnter enter;
|
||||
enter.target = target;
|
||||
ExpectSameAsLegacy([&](const SystemAddress& a) { LegacyGameMessages::SendActivityEnter(target, a); }, enter);
|
||||
|
||||
GameMessages::ActivityStart start;
|
||||
start.target = target;
|
||||
ExpectSameAsLegacy([&](const SystemAddress& a) { LegacyGameMessages::SendActivityStart(target, a); }, start);
|
||||
|
||||
GameMessages::ActivityExit exit;
|
||||
exit.target = target;
|
||||
ExpectSameAsLegacy([&](const SystemAddress& a) { LegacyGameMessages::SendActivityExit(target, a); }, exit);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ActivityMessagesTests, ActivityStopMatchesLegacy) {
|
||||
for (const auto target : g_Targets) {
|
||||
for (const bool bExit : { false, true }) {
|
||||
for (const bool bUserCancel : { false, true }) {
|
||||
GameMessages::ActivityStop msg;
|
||||
msg.target = target;
|
||||
msg.bExit = bExit;
|
||||
msg.bUserCancel = bUserCancel;
|
||||
ExpectSameAsLegacy([&](const SystemAddress& a) { LegacyGameMessages::SendActivityStop(target, bExit, bUserCancel, a); }, msg);
|
||||
|
||||
const auto copy = RoundTrip(msg);
|
||||
EXPECT_EQ(copy.bExit, bExit);
|
||||
EXPECT_EQ(copy.bUserCancel, bUserCancel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ActivityMessagesTests, ActivityPauseMatchesLegacy) {
|
||||
for (const auto target : g_Targets) {
|
||||
for (const bool bPause : { false, true }) {
|
||||
GameMessages::ActivityPause msg;
|
||||
msg.target = target;
|
||||
msg.bPause = bPause;
|
||||
ExpectSameAsLegacy([&](const SystemAddress& a) { LegacyGameMessages::SendActivityPause(target, bPause, a); }, msg);
|
||||
EXPECT_EQ(RoundTrip(msg).bPause, bPause);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ActivityMessagesTests, StartActivityTimeMatchesLegacy) {
|
||||
for (const auto target : g_Targets) {
|
||||
for (const float startTime : { 0.0f, 30.0f, -1.5f, 1e-30f, std::numeric_limits<float>::max() }) {
|
||||
GameMessages::StartActivityTime msg;
|
||||
msg.target = target;
|
||||
msg.startTime = startTime;
|
||||
ExpectSameAsLegacy([&](const SystemAddress& a) { LegacyGameMessages::SendStartActivityTime(target, startTime, a); }, msg);
|
||||
EXPECT_EQ(RoundTrip(msg).startTime, startTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ActivityMessagesTests, RequestActivityEnterMatchesLegacy) {
|
||||
for (const auto target : g_Targets) {
|
||||
for (const bool bStart : { false, true }) {
|
||||
for (const LWOOBJID userID : g_Targets) {
|
||||
GameMessages::RequestActivityEnter msg;
|
||||
msg.target = target;
|
||||
msg.bStart = bStart;
|
||||
msg.userID = userID;
|
||||
ExpectSameAsLegacy([&](const SystemAddress& a) { LegacyGameMessages::SendRequestActivityEnter(target, a, bStart, userID); }, msg);
|
||||
|
||||
const auto copy = RoundTrip(msg);
|
||||
EXPECT_EQ(copy.bStart, bStart);
|
||||
EXPECT_EQ(copy.userID, userID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ActivityMessagesTests, ShowActivityCountdownMatchesLegacy) {
|
||||
const std::u16string longName(300, u'é');
|
||||
for (const auto target : g_Targets) {
|
||||
for (const bool bPlayAdditionalSound : { false, true }) {
|
||||
for (const bool bPlayCountdownSound : { false, true }) {
|
||||
for (const std::u16string& sndName : { std::u16string(), std::u16string(u"sfx/minigame/countdown"), longName }) {
|
||||
for (const int32_t state : { 0, 3, -1 }) {
|
||||
GameMessages::ShowActivityCountdown msg;
|
||||
msg.target = target;
|
||||
msg.bPlayAdditionalSound = bPlayAdditionalSound;
|
||||
msg.bPlayCountdownSound = bPlayCountdownSound;
|
||||
msg.sndName = sndName;
|
||||
msg.stateToPlaySoundOn = state;
|
||||
ExpectSameAsLegacy([&](const SystemAddress& a) {
|
||||
LegacyGameMessages::SendShowActivityCountdown(target, bPlayAdditionalSound, bPlayCountdownSound, sndName, state, a);
|
||||
}, msg);
|
||||
|
||||
const auto copy = RoundTrip(msg);
|
||||
EXPECT_EQ(copy.bPlayAdditionalSound, bPlayAdditionalSound);
|
||||
EXPECT_EQ(copy.bPlayCountdownSound, bPlayCountdownSound);
|
||||
EXPECT_EQ(copy.sndName, sndName);
|
||||
EXPECT_EQ(copy.stateToPlaySoundOn, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Independent of the legacy code: pins the layout against hand computed bytes.
|
||||
TEST_F(ActivityMessagesTests, GoldenBytes) {
|
||||
// 53 | 05 00 (CLIENT) | 0c 00 00 00 (GAME_MSG) | 00 | target (LE i64) | msgId (LE u16) | payload
|
||||
GameMessages::ActivityStop stop;
|
||||
stop.target = 0x0102030405060708LL;
|
||||
stop.bExit = true;
|
||||
stop.bUserCancel = false;
|
||||
EXPECT_PACKET_EQ(FromHex("53 05 00 0c 00 00 00 00 08 07 06 05 04 03 02 01 98 01 80", 146), StructPacket(stop));
|
||||
|
||||
GameMessages::StartActivityTime time;
|
||||
time.target = 0x0102030405060708LL;
|
||||
time.startTime = 1.5f;
|
||||
EXPECT_PACKET_EQ(FromHex("53 05 00 0c 00 00 00 00 08 07 06 05 04 03 02 01 40 02 00 00 c0 3f"), StructPacket(time));
|
||||
}
|
||||
|
||||
TEST_F(ActivityMessagesTests, RequestActivityExitReadsLikeLegacy) {
|
||||
for (const bool bUserCancel : { false, true }) {
|
||||
for (const LWOOBJID userID : g_Targets) {
|
||||
RakNet::BitStream wire;
|
||||
wire.Write(bUserCancel);
|
||||
wire.Write(userID);
|
||||
|
||||
RakNet::BitStream legacyStream(wire.GetData(), wire.GetNumberOfBytesUsed(), false);
|
||||
const auto legacy = LegacyGameMessages::ReadRequestActivityExit(legacyStream);
|
||||
|
||||
RakNet::BitStream newStream(wire.GetData(), wire.GetNumberOfBytesUsed(), false);
|
||||
GameMessages::RequestActivityExit msg;
|
||||
ASSERT_TRUE(msg.Deserialize(newStream));
|
||||
|
||||
EXPECT_EQ(msg.bUserCancel, legacy.canceled);
|
||||
// The legacy handler only read userID (and only acted) when the exit was a user cancel.
|
||||
if (legacy.canceled) EXPECT_EQ(msg.userID, legacy.player_id);
|
||||
|
||||
RakNet::BitStream reserialized;
|
||||
msg.Serialize(reserialized);
|
||||
EXPECT_PACKET_EQ(FromBitStream(wire), FromBitStream(reserialized));
|
||||
}
|
||||
}
|
||||
|
||||
RakNet::BitStream truncated;
|
||||
truncated.Write(true);
|
||||
GameMessages::RequestActivityExit msg;
|
||||
EXPECT_FALSE(msg.Deserialize(truncated));
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
SET(DGAMEMESSAGES_TESTS
|
||||
"ActivityMessagesTests.cpp"
|
||||
"GameMessageTests.cpp"
|
||||
"GameMsgSplitTests.cpp"
|
||||
"UnSmashTests.cpp"
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
#ifndef ACTIVITYMESSAGESLEGACY_H
|
||||
#define ACTIVITYMESSAGESLEGACY_H
|
||||
|
||||
// FROZEN ORACLE - DO NOT EDIT.
|
||||
// Verbatim copies of the hand written GameMessages::Send* functions that ActivityMessages.h replaced
|
||||
// (dGame/dGameMessages/GameMessages.cpp at origin/main 129199e4). Only the namespace changed.
|
||||
// The byte-equality tests send the same inputs through these and through the new structs and require
|
||||
// identical bytes, so the wire format is pinned even after the production code is deleted.
|
||||
|
||||
#include "BitStreamUtils.h"
|
||||
#include "dCommonVars.h"
|
||||
#include "dServer.h"
|
||||
#include "Game.h"
|
||||
#include "MessageType/Client.h"
|
||||
#include "MessageType/Game.h"
|
||||
#include "ServiceType.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
|
||||
namespace LegacyGameMessages {
|
||||
inline void SendActivityPause(LWOOBJID objectId, bool pause = false, const SystemAddress& sysAddr = UNASSIGNED_SYSTEM_ADDRESS) {
|
||||
CBITSTREAM;
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(objectId);
|
||||
bitStream.Write(MessageType::Game::ACTIVITY_PAUSE);
|
||||
bitStream.Write(pause);
|
||||
|
||||
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST;
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
inline void SendStartActivityTime(LWOOBJID objectId, float_t startTime, const SystemAddress& sysAddr = UNASSIGNED_SYSTEM_ADDRESS) {
|
||||
CBITSTREAM;
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(objectId);
|
||||
bitStream.Write(MessageType::Game::START_ACTIVITY_TIME);
|
||||
bitStream.Write<float_t>(startTime);
|
||||
|
||||
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST;
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
inline void SendRequestActivityEnter(LWOOBJID objectId, const SystemAddress& sysAddr, bool bStart, LWOOBJID userID) {
|
||||
CBITSTREAM;
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(objectId);
|
||||
bitStream.Write(MessageType::Game::REQUEST_ACTIVITY_ENTER);
|
||||
bitStream.Write<bool>(bStart);
|
||||
bitStream.Write<LWOOBJID>(userID);
|
||||
|
||||
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST;
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
inline void SendActivityEnter(LWOOBJID objectId, const SystemAddress& sysAddr) {
|
||||
CBITSTREAM;
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(objectId);
|
||||
bitStream.Write(MessageType::Game::ACTIVITY_ENTER);
|
||||
|
||||
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST;
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
inline void SendActivityStart(LWOOBJID objectId, const SystemAddress& sysAddr) {
|
||||
CBITSTREAM;
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(objectId);
|
||||
bitStream.Write(MessageType::Game::ACTIVITY_START);
|
||||
|
||||
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST;
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
inline void SendActivityExit(LWOOBJID objectId, const SystemAddress& sysAddr) {
|
||||
CBITSTREAM;
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(objectId);
|
||||
bitStream.Write(MessageType::Game::ACTIVITY_EXIT);
|
||||
|
||||
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST;
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
inline void SendActivityStop(LWOOBJID objectId, bool bExit, bool bUserCancel, const SystemAddress& sysAddr) {
|
||||
CBITSTREAM;
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(objectId);
|
||||
bitStream.Write(MessageType::Game::ACTIVITY_STOP);
|
||||
|
||||
bitStream.Write(bExit);
|
||||
bitStream.Write(bUserCancel);
|
||||
|
||||
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST;
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
inline void SendShowActivityCountdown(LWOOBJID objectId, bool bPlayAdditionalSound, bool bPlayCountdownSound, std::u16string sndName, int32_t stateToPlaySoundOn, const SystemAddress& sysAddr) {
|
||||
CBITSTREAM;
|
||||
CMSGHEADER;
|
||||
|
||||
bitStream.Write(objectId);
|
||||
bitStream.Write(MessageType::Game::SHOW_ACTIVITY_COUNTDOWN);
|
||||
|
||||
bitStream.Write(bPlayAdditionalSound);
|
||||
|
||||
bitStream.Write(bPlayCountdownSound);
|
||||
|
||||
bitStream.Write<uint32_t>(sndName.size());
|
||||
for (auto character : sndName) {
|
||||
bitStream.Write(character);
|
||||
}
|
||||
|
||||
bitStream.Write(stateToPlaySoundOn);
|
||||
|
||||
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) SEND_PACKET_BROADCAST;
|
||||
SEND_PACKET;
|
||||
}
|
||||
|
||||
// Inbound: the read sequence of the old GameMessages::HandleRequestActivityExit, returning what it read.
|
||||
struct LegacyRequestActivityExitRead {
|
||||
bool canceled = false;
|
||||
LWOOBJID player_id = LWOOBJID_EMPTY;
|
||||
};
|
||||
inline LegacyRequestActivityExitRead ReadRequestActivityExit(RakNet::BitStream& inStream) {
|
||||
LegacyRequestActivityExitRead result;
|
||||
inStream.Read(result.canceled);
|
||||
if (!result.canceled) return result;
|
||||
|
||||
inStream.Read(result.player_id);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // ACTIVITYMESSAGESLEGACY_H
|
||||
Reference in New Issue
Block a user