mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-02 19:03:43 +00:00
Every game message still written or read by hand is now a NetGameMsg with Serialize and Deserialize, in per-domain files: - MovementMessages: teleport, platforms (resync and its request), orient to angle, node rotation lock, gravity scale, jetpack mode, control scheme, respawn checkpoint, rails (set/start, ready, cancel, arrived), mount inventory ID, dismount complete, possession ack, ghost reference override and position, camera cycling (eCameraTargetCyclingMode moves here). - ZoneMessages: player loaded (the old PLAYER_LOADED case), ready for updates, player ready, restore to post load stats, server done loading, invalid zone transfer list, zone summary display/dismissed, level processing complete, object world state, and the localized announcement WorldMigration wrote by hand. - PlayerMessages: chat mode, GM level, LEGO score, currency, reputation, GM invis, pickup currency, zone and player statistics, chat commands, bug reports, verify ack. - ObjectMessages: fire event client/server side, notify client (zone) object, notify object, script network vars, failed preconditions, terminate interaction, set name, request use, request server object info. - QuickBuildMessages: notify state, enable, cancel. - ActivityMessages gains match response/update/request, leaderboard request and data, shooting gallery score/rotation/fire, activity state change. - MissionMessages gains MissionDialogueCancelled (a no-op, as before). The wire structs left in GameMessages.h move to their domains (tooltip and emote to Effects, loot and item use to Inventory, model build to Building, behavior sound to Property, skill sets to Skill) and gain the missing direction. The dismount logic moves to PossessorComponent::OnDismountComplete. Every inbound message is registered in the GameMessageHandler map; the switch is gone, and GameMessages.cpp only holds the GameMsg/NetGameMsg base code. Call sites build the structs (NotifyClientObject, TerminateInteraction, Teleport, PlatformResync, FireEventClientSide, NotifyObject and NotifyClientZoneObject get convenience constructors like PlayFXEffect). Dead senders are dropped: SendSetShootingGalleryParams (no callers, field order was a guess), SendTeamPickupItem (the struct already existed), SendRequestActivitySummaryLeaderboardData (the struct covers it). Verified with RemainingMessagesTests: every old Send* function is frozen verbatim in Legacy/RemainingMessagesLegacy.h and compared byte for byte (same bits, destination and broadcast flag) over grids of inputs; every old Handle* read sequence is frozen as a Read* oracle and compared with the struct's Deserialize; round trips, truncation and a golden packet. PlayerLoaded (0x00dc36f0), SetGMLevel (0x00dd6230), MissionDialogueCancelled (0x00d9cc10) and LocalizedAnnouncementServerToSingleClient (0x00f23c50) were checked against the client. Behaviour notes: an inbound message that fails to deserialize is dropped, so ParseChatMessage over MAX_MESSAGE_LENGTH is dropped instead of truncated, and PLAYER_LOADED / READY_FOR_UPDATES / MISSION_DIALOGUE_CANCELLED now read their (unused) client fields. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
283 lines
11 KiB
C++
283 lines
11 KiB
C++
#ifndef MOVEMENTMESSAGES_H
|
|
#define MOVEMENTMESSAGES_H
|
|
|
|
#include "GameMessages.h"
|
|
#include "NiQuaternion.h"
|
|
#include "eControlScheme.h"
|
|
#include "eCyclingMode.h"
|
|
#include "eMovementPlatformState.h"
|
|
|
|
#include <string>
|
|
|
|
enum class eCameraTargetCyclingMode : int32_t {
|
|
ALLOW_CYCLE_TEAMMATES,
|
|
DISALLOW_CYCLING
|
|
};
|
|
|
|
// Game messages for moving things around: teleports, moving platforms, rails, mounts and possession, jetpacks,
|
|
// ghosting reference points, the camera and the control scheme.
|
|
// Fields are listed in wire order; names follow the client (legouniverse.exe 1.10.64) where known.
|
|
namespace GameMessages {
|
|
// Server -> client, to one client (UNASSIGNED broadcasts).
|
|
struct Teleport : public NetGameMsg {
|
|
Teleport() : NetGameMsg(MessageType::Game::TELEPORT) {}
|
|
// bIgnoreY is set when pos.y is 0, as DLU always did.
|
|
Teleport(const LWOOBJID _target, const NiPoint3& _pos, const NiQuaternion& _rot, const bool _bSetRotation = false) : Teleport() {
|
|
target = _target;
|
|
bIgnoreY = _pos.y == 0.0f;
|
|
bSetRotation = _bSetRotation;
|
|
pos = _pos;
|
|
rot = _rot;
|
|
}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
|
|
bool bIgnoreY{ true };
|
|
bool bSetRotation{ false };
|
|
bool bSkipAllChecks{ false };
|
|
NiPoint3 pos{};
|
|
bool bUseNavmesh{ false };
|
|
// w is optional (default 1.0f), then x, y, z always.
|
|
NiQuaternion rot{ QuatUtils::IDENTITY };
|
|
};
|
|
|
|
// Server -> client, broadcast. No payload.
|
|
struct StartPathing : public NetGameMsg {
|
|
StartPathing() : NetGameMsg(MessageType::Game::START_PATHING) {}
|
|
};
|
|
|
|
// Server -> client, to one client (UNASSIGNED broadcasts).
|
|
struct PlatformResync : public NetGameMsg {
|
|
PlatformResync() : NetGameMsg(MessageType::Game::PLATFORM_RESYNC) {}
|
|
// What DLU sends for a platform entity: the arguments, overridden for a few LOTs whose paths only have a
|
|
// start and an end (special is for the FV tree platform).
|
|
PlatformResync(const Entity& entity, bool bStopAtDesiredWaypoint = false,
|
|
int32_t iIndex = 0, int32_t iDesiredWaypointIndex = 1, int32_t nextIndex = 1,
|
|
eMovementPlatformState movementState = eMovementPlatformState::Moving, bool special = false);
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
|
|
bool bReverse{ false };
|
|
bool bStopAtDesiredWaypoint{ false };
|
|
int32_t eCommand{ 0 };
|
|
eMovementPlatformState eState{ eMovementPlatformState::Moving }; // written as int32_t
|
|
int32_t eUnexpectedCommand{ 0 };
|
|
float fIdleTimeElapsed{ 0.0f };
|
|
float fMoveTimeElapsed{ 0.0f };
|
|
float fPercentBetweenPoints{ 0.0f };
|
|
int32_t iDesiredWaypointIndex{ 1 };
|
|
int32_t iIndex{ 0 };
|
|
int32_t iNextIndex{ 1 };
|
|
NiPoint3 ptUnexpectedLocation{ NiPoint3Constant::ZERO };
|
|
// optional (default identity), written x, y, z, w
|
|
NiQuaternion qUnexpectedRotation{ QuatUtils::IDENTITY };
|
|
};
|
|
|
|
// Client -> server. No payload. Answered with a PlatformResync.
|
|
struct RequestPlatformResync : public NetGameMsg {
|
|
RequestPlatformResync() : NetGameMsg(MessageType::Game::REQUEST_PLATFORM_RESYNC) {}
|
|
void Handle(Entity& entity, const SystemAddress& sysAddr) override;
|
|
};
|
|
|
|
// Server -> client, to one client (UNASSIGNED broadcasts).
|
|
struct OrientToAngle : public NetGameMsg {
|
|
OrientToAngle() : NetGameMsg(MessageType::Game::ORIENT_TO_ANGLE) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
|
|
bool bRelativeToCurrent{};
|
|
float fAngle{};
|
|
};
|
|
|
|
// Server -> client, broadcast.
|
|
struct LockNodeRotation : public NetGameMsg {
|
|
LockNodeRotation() : NetGameMsg(MessageType::Game::LOCK_NODE_ROTATION) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
|
|
std::string nodeName{};
|
|
};
|
|
|
|
// Server -> client, to one client.
|
|
struct SetGravityScale : public NetGameMsg {
|
|
SetGravityScale() : NetGameMsg(MessageType::Game::SET_GRAVITY_SCALE) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
|
|
float scale{};
|
|
};
|
|
|
|
// Server -> client, broadcast.
|
|
struct SetJetPackMode : public NetGameMsg {
|
|
SetJetPackMode() : NetGameMsg(MessageType::Game::SET_JET_PACK_MODE) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
|
|
bool bBypassChecks{ false };
|
|
bool bDoHover{ false };
|
|
bool bUse{};
|
|
int32_t effectID{ -1 }; // optional
|
|
float fAirspeed{ 10.0f }; // optional
|
|
float fMaxAirspeed{ 15.0f }; // optional
|
|
float fVertVel{ 1.0f }; // optional
|
|
int32_t iWarningEffectID{ -1 }; // optional
|
|
};
|
|
|
|
// Server -> client, to one client.
|
|
struct SetPlayerControlScheme : public NetGameMsg {
|
|
SetPlayerControlScheme() : NetGameMsg(MessageType::Game::SET_PLAYER_CONTROL_SCHEME) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
|
|
bool bDelayCamSwitchIfInCinematic{ true };
|
|
bool bSwitchCam{ true };
|
|
eControlScheme iScheme{ eControlScheme::SCHEME_A }; // optional
|
|
};
|
|
|
|
// Server -> client, to one client.
|
|
struct PlayerReachedRespawnCheckpoint : public NetGameMsg {
|
|
PlayerReachedRespawnCheckpoint() : NetGameMsg(MessageType::Game::PLAYER_REACHED_RESPAWN_CHECKPOINT) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
|
|
NiPoint3 pos{};
|
|
// optional (default identity), written w, x, y, z
|
|
NiQuaternion rot{ QuatUtils::IDENTITY };
|
|
};
|
|
|
|
// Server -> client, to one client (UNASSIGNED broadcasts).
|
|
struct SetRailMovement : public NetGameMsg {
|
|
SetRailMovement() : NetGameMsg(MessageType::Game::SET_RAIL_MOVEMENT) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
|
|
bool pathGoForward{};
|
|
std::u16string pathName{};
|
|
uint32_t pathStart{};
|
|
int32_t railActivatorComponentID{ -1 }; // optional
|
|
LWOOBJID railActivatorObjectID{ LWOOBJID_EMPTY }; // optional
|
|
};
|
|
|
|
// Server -> client, to one client (UNASSIGNED broadcasts).
|
|
struct StartRailMovement : public NetGameMsg {
|
|
StartRailMovement() : NetGameMsg(MessageType::Game::START_RAIL_MOVEMENT) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
|
|
bool bDamageImmune{ true };
|
|
bool bNoAggro{ true };
|
|
bool bNotifyActor{ false };
|
|
bool bShowNameBillboard{ true };
|
|
bool bCameraLocked{ true };
|
|
bool bCollisionEnabled{ true };
|
|
std::u16string loopSound{};
|
|
bool goForward{ true };
|
|
std::u16string pathName{};
|
|
uint32_t pathStart{ 0 }; // optional
|
|
int32_t railActivatorComponentID{ -1 }; // optional
|
|
LWOOBJID railActivatorObjectID{ LWOOBJID_EMPTY }; // optional
|
|
std::u16string startSound{};
|
|
std::u16string stopSound{};
|
|
bool bUseDB{ true };
|
|
};
|
|
|
|
// Client -> server. No payload.
|
|
struct ClientRailMovementReady : public NetGameMsg {
|
|
ClientRailMovementReady() : NetGameMsg(MessageType::Game::CLIENT_RAIL_MOVEMENT_READY) {}
|
|
void Handle(Entity& entity, const SystemAddress& sysAddr) override;
|
|
};
|
|
|
|
// Client -> server.
|
|
struct CancelRailMovement : public NetGameMsg {
|
|
CancelRailMovement() : NetGameMsg(MessageType::Game::CANCEL_RAIL_MOVEMENT) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
void Handle(Entity& entity, const SystemAddress& sysAddr) override;
|
|
|
|
bool bImmediate{};
|
|
};
|
|
|
|
// Client -> server.
|
|
struct PlayerRailArrivedNotification : public NetGameMsg {
|
|
PlayerRailArrivedNotification() : NetGameMsg(MessageType::Game::PLAYER_RAIL_ARRIVED_NOTIFICATION) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
void Handle(Entity& entity, const SystemAddress& sysAddr) override;
|
|
|
|
std::u16string pathName{};
|
|
int32_t waypointNumber{};
|
|
};
|
|
|
|
// Server -> client, broadcast.
|
|
struct SetMountInventoryID : public NetGameMsg {
|
|
SetMountInventoryID() : NetGameMsg(MessageType::Game::SET_MOUNT_INVENTORY_ID) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
|
|
LWOOBJID inventoryMountID{ LWOOBJID_EMPTY }; // optional
|
|
};
|
|
|
|
// Client -> server.
|
|
struct DismountComplete : public NetGameMsg {
|
|
DismountComplete() : NetGameMsg(MessageType::Game::DISMOUNT_COMPLETE) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
void Handle(Entity& entity, const SystemAddress& sysAddr) override;
|
|
|
|
LWOOBJID mountID{};
|
|
};
|
|
|
|
// Client -> server.
|
|
struct AcknowledgePossession : public NetGameMsg {
|
|
AcknowledgePossession() : NetGameMsg(MessageType::Game::ACKNOWLEDGE_POSSESSION) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
void Handle(Entity& entity, const SystemAddress& sysAddr) override;
|
|
|
|
LWOOBJID possessedObjID{ LWOOBJID_EMPTY }; // optional
|
|
};
|
|
|
|
// Client -> server.
|
|
struct ToggleGhostReferenceOverride : public NetGameMsg {
|
|
ToggleGhostReferenceOverride() : NetGameMsg(MessageType::Game::TOGGLE_GHOST_REFERENCE_OVERRIDE) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
void Handle(Entity& entity, const SystemAddress& sysAddr) override;
|
|
|
|
bool bOverride{ false };
|
|
};
|
|
|
|
// Client -> server.
|
|
struct SetGhostReferencePosition : public NetGameMsg {
|
|
SetGhostReferencePosition() : NetGameMsg(MessageType::Game::SET_GHOST_REFERENCE_POSITION) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
void Handle(Entity& entity, const SystemAddress& sysAddr) override;
|
|
|
|
NiPoint3 pos{};
|
|
};
|
|
|
|
// Server -> client, to one client.
|
|
struct PlayerSetCameraCyclingMode : public NetGameMsg {
|
|
PlayerSetCameraCyclingMode() : NetGameMsg(MessageType::Game::PLAYER_SET_CAMERA_CYCLING_MODE) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
|
|
bool bAllowCyclingWhileDeadOnly{ true };
|
|
eCyclingMode cyclingMode{ eCyclingMode::ALLOW_CYCLE_TEAMMATES }; // optional
|
|
};
|
|
|
|
// Server -> client, to one client.
|
|
struct ForceCameraTargetCycle : public NetGameMsg {
|
|
ForceCameraTargetCycle() : NetGameMsg(MessageType::Game::FORCE_CAMERA_TARGET_CYCLE) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
|
|
bool bForceCycling{};
|
|
eCameraTargetCyclingMode cyclingMode{ eCameraTargetCyclingMode::ALLOW_CYCLE_TEAMMATES }; // optional
|
|
LWOOBJID optionalTargetID{};
|
|
};
|
|
}
|
|
|
|
#endif // MOVEMENTMESSAGES_H
|