Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
508 changes: 508 additions & 0 deletions client/src/CWorldObjectSync.cpp

Large diffs are not rendered by default.

59 changes: 59 additions & 0 deletions client/src/CWorldObjectSync.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#pragma once

#include "stdafx.h"
#include <CObject.h>
#include <unordered_map>
#include <vector>

// breakable and movable map objects (lamp posts, petrol pumps, bins, boxes) look the same for every player. An object
// is made from its dummy when a player comes within 80 m and turned back (as new) when it goes away, so the server
// keeps what happened to it and streams it to the players around; a new object gets the known state before it is
// rendered. Damage is reported by whoever sees it, the motion by the one who pushed the object
class CWorldObjectSync
{
public:
static void Reset();
static void Process();
static void HandlePacket(Packets::World::WorldObjectStates* pPacket);
static void HandlePacket(Packets::World::WorldObjectMotion* pPacket);

private:
static constexpr uint32_t MOTION_INTERVAL = 100;
// the local physics of an object isn't ours: until the mover's rest state (or its motion stops coming), and a bit
// after it while ours settles. A background window of the mover may run a frame a second
static constexpr uint32_t REMOTE_MOTION_TIME = 5000;
static constexpr uint32_t REMOTE_REST_TIME = 1000;

struct SSlot
{
int ref = 0; // CPools::GetObjectRef + 1, 0 - no map object in the slot
CObject* pObject = nullptr;
Packets::World::WorldObjectKey key;
uint8_t flags = 0; // the damage flags last seen
bool bMoving = false;
bool bMover = false; // we pushed it: we send its motion and where it stopped
uint32_t lastMotionTime = 0;
uint32_t remoteUntil = 0;
Packets::World::WorldObjectTransform original; // the dummy's: the object or the dummy may be gone later
Packets::World::WorldObjectTransform lastTransform;
};

using KeyMap = std::unordered_map<Packets::World::WorldObjectKey, int, Packets::World::WorldObjectKeyHash>;
using StateMap = std::unordered_map<Packets::World::WorldObjectKey, Packets::World::WorldObjectState,
Packets::World::WorldObjectKeyHash>;

static SSlot* FindSlot(const Packets::World::WorldObjectKey& key);
static void OnObjectAppeared(SSlot& slot);
static void OnObjectGone(SSlot& slot);
static void ProcessSlot(SSlot& slot, uint32_t now);
static bool ShouldBecomeMover(CObject* pObject);

static void Apply(SSlot& slot, const Packets::World::WorldObjectState& state, bool bLive, bool bTransform);
static void SendState(const SSlot& slot, bool bTransform, uint8_t flags);
static void Remember(const Packets::World::WorldObjectKey& key, bool bTransform,
const Packets::World::WorldObjectState& state);

static std::vector<SSlot> ms_slots; // by the object pool index
static KeyMap ms_slotByKey;
static StateMap ms_states; // what the server told us, and our own changes
};
3 changes: 3 additions & 0 deletions client/src/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <CKeySync.h>
#include <CCompatibilityChecker.h>
#include <CWeatherSync.h>
#include <CWorldObjectSync.h>
#include <network/packets/scripts.h>
#include <CNetworkEntityBlip.h>

Expand Down Expand Up @@ -74,6 +75,7 @@ class CoopAndreas
else if (bBeenConnected && !CNetwork::m_bConnected)
{
bBeenConnected = false;
CWorldObjectSync::Reset();
CChat::AddMessage("{d6dce8}[Network] Disconnected from the server.");
}
};
Expand All @@ -86,6 +88,7 @@ class CoopAndreas

if (/*CNetwork::m_bConnected*/ CNetwork::m_bAuthenticated)
{
CWorldObjectSync::Process();
// TODO: refactor
if (COpCodeSync::ms_bLoadingCutscene && !CLocalPlayer::m_bIsHost && CCutsceneMgr::ms_cutsceneName[0] &&
CCutsceneMgr::ms_cutsceneLoadStatus == 2)
Expand Down
2 changes: 2 additions & 0 deletions client/src/PacketHandlers/system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "stdafx.h"
#include <CWeatherSync.h>
#include <CMoonSync.h>
#include <CWorldObjectSync.h>
#include <game_sa/CTagManager.h>

PACKET_HANDLER(ePacketType::PLAYER_CONNECTED, Packets::System::PlayerConnected* pPlayerConnected)
Expand Down Expand Up @@ -76,6 +77,7 @@ PACKET_HANDLER(ePacketType::PLAYER_HANDSHAKE, Packets::System::PlayerHandshake*

CNetwork::m_bAuthenticated = true;
CPatch::RevertTemporaryPatches();
CWorldObjectSync::Reset();
logger::info("Authenticated, playerid %s", to_string(pPlayerHandshake->yourid).c_str());
}

Expand Down
13 changes: 12 additions & 1 deletion client/src/PacketHandlers/world.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "stdafx.h"
#include <CWeatherSync.h>
#include <CMoonSync.h>
#include <CWorldObjectSync.h>
#include <game_sa/CTagManager.h>

PACKET_HANDLER(ePacketType::GAME_WEATHER_TIME, Packets::World::GameWeatherTime* pGameWeatherTime)
Expand Down Expand Up @@ -66,4 +67,14 @@ PACKET_HANDLER(ePacketType::UPDATE_ALL_TAGS, Packets::World::UpdateAllTags* pUpd
PACKET_HANDLER(ePacketType::UPDATE_MOON_SIZE, Packets::World::UpdateMoonSize* pUpdateMoonSize)
{
CMoonSync::HandlePacket(pUpdateMoonSize);
}
}

PACKET_HANDLER(ePacketType::WORLD_OBJECT_STATES, Packets::World::WorldObjectStates* pWorldObjectStates)
{
CWorldObjectSync::HandlePacket(pWorldObjectStates);
}

PACKET_HANDLER(ePacketType::WORLD_OBJECT_MOTION, Packets::World::WorldObjectMotion* pWorldObjectMotion)
{
CWorldObjectSync::HandlePacket(pWorldObjectMotion);
}
3 changes: 3 additions & 0 deletions server/src/CNetwork.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <network/packets/vehicles.h>
#include <network/packets/peds.h>
#include <network/packets/scripts.h>
#include "CWorldObjects.h"

bool CNetwork::Init(unsigned short port)
{
Expand Down Expand Up @@ -40,6 +41,7 @@ bool CNetwork::Init(unsigned short port)
{
CServerTime::Update();
CRTTBroadcastManager::Update();
CWorldObjects::Update();

while (enet_host_service(pENetHost, &eNetEvent, 1) > 0)
{
Expand Down Expand Up @@ -116,6 +118,7 @@ void CNetwork::HandlePlayerDisconnected(ENetEvent& event)

CNetworkPedManager::RemoveAllHostedAndNotify(pNetworkPlayer);
CNetworkVehicleManager::RemoveAllHostedAndNotify(pNetworkPlayer);
CWorldObjects::OnPlayerDisconnected(pNetworkPlayer);

CNetworkPlayerManager::Remove(pNetworkPlayer);

Expand Down
2 changes: 2 additions & 0 deletions server/src/CNetworkPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ class CNetworkPlayer
int8_t m_nSeatId = -1;
vehicleid_t m_vehicleId{};
bool m_bCorrectVersion = false;
CVector m_vecPosition{}; // last known, from the player's own updates
bool m_bHasPosition = false;
float m_afStats[14]{};
Packets::Players::PlayerPlaceWaypoint m_waypointState{};
CPedClothesDesc m_pPedClothesDesc{};
Expand Down
Loading