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
10 changes: 10 additions & 0 deletions src/multiplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@
#include "engine.h"
#include "multiplayer_internal.h"


void MultiplayerStaticReplicationBase::markChanged()
{
if (updated) return;
updated = true;
next = owner->staticMemberSendList;
owner->staticMemberSendList = this;
}


static PVector<Collisionable> collisionable_significant;
class CollisionableReplicationData
{
Expand Down
60 changes: 60 additions & 0 deletions src/multiplayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,56 @@ bool multiplayerReplicationFunctions<T>::isChanged(void* data, void* prev_data_p

template <> bool multiplayerReplicationFunctions<string>::isChanged(void* data, void* prev_data_ptr);

class MultiplayerStaticReplicationBase : sf::NonCopyable
{
public:
MultiplayerObject* owner{nullptr};
uint16_t replication_id{0};

bool updated{false};
MultiplayerStaticReplicationBase* next{nullptr};

virtual void send(sf::Packet& packet) = 0;
virtual void receive(sf::Packet& packet) = 0;

protected:
void markChanged();
};
template<typename T> class MultiplayerStaticReplication : public MultiplayerStaticReplicationBase
{
public:
MultiplayerStaticReplication(const T& initial_value)
: value(initial_value)
{}

operator T() const
{
return value;
}

MultiplayerStaticReplication<T>& operator=(T&& new_value)
{
if (value != new_value)
{
value = new_value;
markChanged();
}
return *this;
}

void send(sf::Packet& packet) override
{
packet << value;
}

void receive(sf::Packet& packet) override
{
packet >> value;
}

T value;
};

//In between class that handles all the nasty synchronization of objects between server and client.
//I'm assuming that it should be a pure virtual class though.
class MultiplayerObject : public virtual PObject
Expand All @@ -151,6 +201,8 @@ class MultiplayerObject : public virtual PObject
void(*cleanupFunction)(void* prev_data_ptr);
};
std::vector<MemberReplicationInfo> memberReplicationInfo;
std::vector<MultiplayerStaticReplicationBase*> staticMemberReplicationInfo;
MultiplayerStaticReplicationBase* staticMemberSendList{nullptr};
public:
MultiplayerObject(string multiplayerClassIdentifier);
virtual ~MultiplayerObject();
Expand Down Expand Up @@ -217,6 +269,13 @@ class MultiplayerObject : public virtual PObject
info.cleanupFunction = &multiplayerReplicationFunctions<T>::cleanupVector;
memberReplicationInfo.push_back(info);
}

template<typename T> void registerMemberReplication_(F_PARAM MultiplayerStaticReplication<T>* member)
{
member->owner = this;
member->replication_id = staticMemberReplicationInfo.size() | 0x8000;
staticMemberReplicationInfo.push_back(member);
}

void registerMemberReplication_(F_PARAM sf::Vector3f* member, float update_delay = 0.0)
{
Expand Down Expand Up @@ -251,6 +310,7 @@ class MultiplayerObject : public virtual PObject
private:
friend class GameServer;
friend class GameClient;
friend class MultiplayerStaticReplicationBase;

template <typename T>
static inline
Expand Down
8 changes: 6 additions & 2 deletions src/multiplayer_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,9 @@ void GameClient::update(float /*delta*/)
int16_t idx;
while(packet >> idx)
{
if (idx >= 0 && idx < int16_t(obj->memberReplicationInfo.size()))
if (idx & 0x8000 && (idx & 0x7FFF) < uint16_t(obj->staticMemberReplicationInfo.size()))
obj->staticMemberReplicationInfo[idx & 0x7FFF]->receive(packet);
else if (idx >= 0 && idx < int16_t(obj->memberReplicationInfo.size()))
(obj->memberReplicationInfo[idx].receiveFunction)(obj->memberReplicationInfo[idx].ptr, packet);
else
LOG(DEBUG) << "Odd index from server replication: " << idx;
Expand Down Expand Up @@ -157,7 +159,9 @@ void GameClient::update(float /*delta*/)
P<MultiplayerObject> obj = objectMap[id];
while(packet >> idx)
{
if (idx < int32_t(obj->memberReplicationInfo.size()))
if (idx & 0x8000 && (idx & 0x7FFF) < uint16_t(obj->staticMemberReplicationInfo.size()))
obj->staticMemberReplicationInfo[idx & 0x7FFF]->receive(packet);
else if (idx < int32_t(obj->memberReplicationInfo.size()))
(obj->memberReplicationInfo[idx].receiveFunction)(obj->memberReplicationInfo[idx].ptr, packet);
}
}
Expand Down
14 changes: 14 additions & 0 deletions src/multiplayer_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,15 @@ void GameServer::update(float /*gameDelta*/)
}
}
}
while(obj->staticMemberSendList)
{
packet << obj->staticMemberSendList->replication_id;
obj->staticMemberSendList->send(packet);
//TODO: Multiplayer stats
obj->staticMemberSendList->updated = false;
obj->staticMemberSendList = obj->staticMemberSendList->next;
cnt ++;
}
if (cnt > 0)
{
sendAll(packet);
Expand Down Expand Up @@ -529,6 +538,11 @@ void GameServer::generateCreatePacketFor(P<MultiplayerObject> obj, sf::Packet& p
packet << int16_t(n);
(obj->memberReplicationInfo[n].sendFunction)(obj->memberReplicationInfo[n].ptr, packet);
}
for(unsigned int n=0; n<obj->staticMemberReplicationInfo.size(); n++)
{
packet << int16_t(n | 0x8000);
obj->staticMemberReplicationInfo[n]->send(packet);
}
}

void GameServer::generateDeletePacketFor(int32_t id, sf::Packet& packet)
Expand Down