[General] Add and implement new Worldstate packet type

pull/430/head
David Cernat 7 years ago
parent e8b22a2e5e
commit 43a944ddaf

@ -164,6 +164,7 @@ set(PROCESSORS
processors/PlayerProcessor.cpp
processors/ActorProcessor.cpp
processors/ObjectProcessor.cpp
processors/WorldstateProcessor.cpp
)
source_group(tes3mp-server\\processors FILES ${PROCESSORS})

@ -26,6 +26,7 @@
#include "processors/PlayerProcessor.hpp"
#include "processors/ActorProcessor.hpp"
#include "processors/ObjectProcessor.hpp"
#include "processors/WorldstateProcessor.hpp"
using namespace mwmp;
using namespace std;
@ -46,6 +47,7 @@ Networking::Networking(RakNet::RakPeerInterface *peer) : mclient(nullptr)
playerPacketController = new PlayerPacketController(peer);
actorPacketController = new ActorPacketController(peer);
objectPacketController = new ObjectPacketController(peer);
worldstatePacketController = new WorldstatePacketController(peer);
// Set send stream
playerPacketController->SetStream(0, &bsOut);
@ -193,6 +195,18 @@ void Networking::processObjectPacket(RakNet::Packet *packet)
}
void Networking::processWorldstatePacket(RakNet::Packet *packet)
{
Player *player = Players::getPlayer(packet->guid);
if (!player->isHandshaked() || player->getLoadState() != Player::POSTLOADED)
return;
if (!WorldstateProcessor::Process(*packet, baseWorldstate))
LOG_MESSAGE_SIMPLE(Log::LOG_WARN, "Unhandled WorldstatePacket with identifier %i has arrived", packet->data[0]);
}
void Networking::update(RakNet::Packet *packet)
{
Player *player = Players::getPlayer(packet->guid);
@ -280,6 +294,11 @@ void Networking::update(RakNet::Packet *packet)
objectPacketController->SetStream(&bsIn, 0);
processObjectPacket(packet);
}
else if (worldstatePacketController->ContainsPacket(packet->data[0]))
{
worldstatePacketController->SetStream(&bsIn, 0);
processWorldstatePacket(packet);
}
else
LOG_MESSAGE_SIMPLE(Log::LOG_WARN, "Unhandled RakNet packet with identifier %i has arrived", packet->data[0]);
}
@ -357,6 +376,11 @@ ObjectPacketController *Networking::getObjectPacketController() const
return objectPacketController;
}
WorldstatePacketController *Networking::getWorldstatePacketController() const
{
return worldstatePacketController;
}
BaseActorList *Networking::getLastActorList()
{
return &baseActorList;
@ -367,6 +391,11 @@ BaseObjectList *Networking::getLastObjectList()
return &baseObjectList;
}
BaseWorldstate *Networking::getLastWorldstate()
{
return &baseWorldstate;
}
int Networking::getCurrentMpNum()
{
return currentMpNum;

@ -1,13 +1,10 @@
//
// Created by koncord on 12.01.16.
//
#ifndef OPENMW_NETWORKING_HPP
#define OPENMW_NETWORKING_HPP
#include <components/openmw-mp/Controllers/PlayerPacketController.hpp>
#include <components/openmw-mp/Controllers/ActorPacketController.hpp>
#include <components/openmw-mp/Controllers/ObjectPacketController.hpp>
#include <components/openmw-mp/Controllers/WorldstatePacketController.hpp>
#include <components/openmw-mp/Packets/PacketPreInit.hpp>
#include "Player.hpp"
@ -31,6 +28,7 @@ namespace mwmp
void processPlayerPacket(RakNet::Packet *packet);
void processActorPacket(RakNet::Packet *packet);
void processObjectPacket(RakNet::Packet *packet);
void processWorldstatePacket(RakNet::Packet *packet);
void update(RakNet::Packet *packet);
unsigned short numberOfConnections() const;
@ -44,9 +42,11 @@ namespace mwmp
PlayerPacketController *getPlayerPacketController() const;
ActorPacketController *getActorPacketController() const;
ObjectPacketController *getObjectPacketController() const;
WorldstatePacketController *getWorldstatePacketController() const;
BaseActorList *getLastActorList();
BaseObjectList *getLastObjectList();
BaseWorldstate *getLastWorldstate();
int getCurrentMpNum();
void setCurrentMpNum(int value);
@ -76,10 +76,12 @@ namespace mwmp
BaseActorList baseActorList;
BaseObjectList baseObjectList;
BaseWorldstate baseWorldstate;
PlayerPacketController *playerPacketController;
ActorPacketController *actorPacketController;
ObjectPacketController *objectPacketController;
WorldstatePacketController *worldstatePacketController;
bool running;
int exitCode;

@ -0,0 +1,40 @@
#include "WorldstateProcessor.hpp"
#include "Networking.hpp"
using namespace mwmp;
template<class T>
typename BasePacketProcessor<T>::processors_t BasePacketProcessor<T>::processors;
void WorldstateProcessor::Do(WorldstatePacket &packet, Player &player, BaseWorldstate &worldstate)
{
packet.Send(true);
}
bool WorldstateProcessor::Process(RakNet::Packet &packet, BaseWorldstate &worldstate) noexcept
{
worldstate.guid = packet.guid;
for (auto &processor : processors)
{
if (processor.first == packet.data[0])
{
Player *player = Players::getPlayer(packet.guid);
WorldstatePacket *myPacket = Networking::get().getWorldstatePacketController()->GetPacket(packet.data[0]);
myPacket->setWorldstate(&worldstate);
worldstate.isValid = true;
if (!processor.second->avoidReading)
myPacket->Read();
if (worldstate.isValid)
processor.second->Do(*myPacket, *player, worldstate);
else
LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Received %s that failed integrity check and was ignored!", processor.second->strPacketID.c_str());
return true;
}
}
return false;
}

@ -0,0 +1,22 @@
#ifndef OPENMW_BASEWORLDSTATEPROCESSOR_HPP
#define OPENMW_BASEWORLDSTATEPROCESSOR_HPP
#include <components/openmw-mp/Base/BasePacketProcessor.hpp>
#include <components/openmw-mp/Packets/BasePacket.hpp>
#include <components/openmw-mp/Packets/Worldstate/WorldstatePacket.hpp>
#include <components/openmw-mp/NetworkMessages.hpp>
#include "Player.hpp"
namespace mwmp
{
class WorldstateProcessor : public BasePacketProcessor<WorldstateProcessor>
{
public:
virtual void Do(WorldstatePacket &packet, Player &player, BaseWorldstate &worldstate);
static bool Process(RakNet::Packet &packet, BaseWorldstate &worldstate) noexcept;
};
}
#endif //OPENMW_BASEWORLDSTATEPROCESSOR_HPP

@ -104,7 +104,8 @@ add_openmw_dir (mwmp Main Networking LocalPlayer DedicatedPlayer PlayerList Loca
add_openmw_dir (mwmp/GUI GUIChat GUILogin PlayerMarkerCollection GUIDialogList TextInputDialog
)
add_openmw_dir(mwmp/processors BaseClientPacketProcessor PlayerProcessor ObjectProcessor ActorProcessor ProcessorInitializer
add_openmw_dir(mwmp/processors BaseClientPacketProcessor PlayerProcessor ObjectProcessor ActorProcessor WorldstateProcessor
ProcessorInitializer
)
add_openmw_dir (mwmp/processors/actor ProcessorActorAI ProcessorActorAnimFlags ProcessorActorAnimPlay ProcessorActorAttack

@ -39,6 +39,7 @@
#include "processors/PlayerProcessor.hpp"
#include "processors/ObjectProcessor.hpp"
#include "processors/ActorProcessor.hpp"
#include "processors/WorldstateProcessor.hpp"
#include "GUIController.hpp"
#include "CellController.hpp"
@ -197,7 +198,7 @@ string listComparison(PacketPreInit::PluginContainer checksums, PacketPreInit::P
}
Networking::Networking(): peer(RakNet::RakPeerInterface::GetInstance()), playerPacketController(peer),
actorPacketController(peer), objectPacketController(peer)
actorPacketController(peer), objectPacketController(peer), worldstatePacketController(peer)
{
RakNet::SocketDescriptor sd;
@ -208,6 +209,7 @@ Networking::Networking(): peer(RakNet::RakPeerInterface::GetInstance()), playerP
playerPacketController.SetStream(0, &bsOut);
actorPacketController.SetStream(0, &bsOut);
objectPacketController.SetStream(0, &bsOut);
worldstatePacketController.SetStream(0, &bsOut);
connected = 0;
ProcessorInitializer();
@ -433,6 +435,11 @@ void Networking::receiveMessage(RakNet::Packet *packet)
if (!ObjectProcessor::Process(*packet, objectList))
LOG_MESSAGE_SIMPLE(Log::LOG_WARN, "Unhandled ObjectPacket with identifier %i has arrived", packet->data[0]);
}
else if (worldstatePacketController.ContainsPacket(packet->data[0]))
{
if (!WorldstateProcessor::Process(*packet, worldstate))
LOG_MESSAGE_SIMPLE(Log::LOG_WARN, "Unhandled WorldstatePacket with identifier %i has arrived", packet->data[0]);
}
}
PlayerPacket *Networking::getPlayerPacket(RakNet::MessageID id)
@ -450,6 +457,11 @@ ObjectPacket *Networking::getObjectPacket(RakNet::MessageID id)
return objectPacketController.GetPacket(id);
}
WorldstatePacket *Networking::getWorldstatePacket(RakNet::MessageID id)
{
return worldstatePacketController.GetPacket(id);
}
LocalPlayer *Networking::getLocalPlayer()
{
return mwmp::Main::get().getLocalPlayer();
@ -465,6 +477,11 @@ ObjectList *Networking::getObjectList()
return &objectList;
}
BaseWorldstate *Networking::getWorldstate()
{
return &worldstate;
}
bool Networking::isConnected()
{
return connected;

@ -16,6 +16,7 @@
#include <components/openmw-mp/Controllers/PlayerPacketController.hpp>
#include <components/openmw-mp/Controllers/ActorPacketController.hpp>
#include <components/openmw-mp/Controllers/ObjectPacketController.hpp>
#include <components/openmw-mp/Controllers/WorldstatePacketController.hpp>
#include <components/files/collections.hpp>
@ -34,6 +35,7 @@ namespace mwmp
PlayerPacket *getPlayerPacket(RakNet::MessageID id);
ActorPacket *getActorPacket(RakNet::MessageID id);
ObjectPacket *getObjectPacket(RakNet::MessageID id);
WorldstatePacket *getWorldstatePacket(RakNet::MessageID id);
RakNet::SystemAddress serverAddress()
{
@ -45,6 +47,7 @@ namespace mwmp
LocalPlayer *getLocalPlayer();
ActorList *getActorList();
ObjectList *getObjectList();
BaseWorldstate *getWorldstate();
private:
bool connected;
@ -55,9 +58,11 @@ namespace mwmp
PlayerPacketController playerPacketController;
ActorPacketController actorPacketController;
ObjectPacketController objectPacketController;
WorldstatePacketController worldstatePacketController;
ActorList actorList;
ObjectList objectList;
BaseWorldstate worldstate;
void receiveMessage(RakNet::Packet *packet);

@ -1,11 +1,6 @@
//
// Created by koncord on 31.03.17.
//
#include "ProcessorInitializer.hpp"
#include "PlayerProcessor.hpp"
#include "player/ProcessorChatMessage.hpp"
#include "player/ProcessorGUIMessageBox.hpp"
#include "player/ProcessorHandshake.hpp"
@ -80,6 +75,7 @@
#include "object/ProcessorScriptGlobalFloat.hpp"
#include "object/ProcessorVideoPlay.hpp"
#include "ActorProcessor.hpp"
#include "actor/ProcessorActorAI.hpp"
#include "actor/ProcessorActorAnimFlags.hpp"
#include "actor/ProcessorActorAnimPlay.hpp"
@ -95,6 +91,8 @@
#include "actor/ProcessorActorStatsDynamic.hpp"
#include "actor/ProcessorActorTest.hpp"
#include "WorldstateProcessor.hpp"
using namespace mwmp;
void ProcessorInitializer()

@ -0,0 +1,40 @@
#include "../Networking.hpp"
#include "WorldstateProcessor.hpp"
#include "../Main.hpp"
using namespace mwmp;
template<class T>
typename BasePacketProcessor<T>::processors_t BasePacketProcessor<T>::processors;
bool WorldstateProcessor::Process(RakNet::Packet &packet, BaseWorldstate &worldstate)
{
RakNet::BitStream bsIn(&packet.data[1], packet.length, false);
bsIn.Read(guid);
worldstate.guid = guid;
WorldstatePacket *myPacket = Main::get().getNetworking()->getWorldstatePacket(packet.data[0]);
myPacket->SetReadStream(&bsIn);
for (auto &processor : processors)
{
if (processor.first == packet.data[0])
{
myGuid = Main::get().getLocalPlayer()->guid;
request = packet.length == myPacket->headerSize();
worldstate.isValid = true;
if (!request && !processor.second->avoidReading)
myPacket->Read();
if (worldstate.isValid)
processor.second->Do(*myPacket, worldstate);
else
LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Received %s that failed integrity check and was ignored!", processor.second->strPacketID.c_str());
return true;
}
}
return false;
}

@ -0,0 +1,22 @@
#ifndef OPENMW_WORLDSTATEPROCESSOR_HPP
#define OPENMW_WORLDSTATEPROCESSOR_HPP
#include <components/openmw-mp/Log.hpp>
#include <components/openmw-mp/NetworkMessages.hpp>
#include <components/openmw-mp/Packets/Worldstate/WorldstatePacket.hpp>
#include "BaseClientPacketProcessor.hpp"
namespace mwmp
{
class WorldstateProcessor : public BasePacketProcessor<WorldstateProcessor>, public BaseClientPacketProcessor
{
public:
virtual void Do(WorldstatePacket &packet, BaseWorldstate &worldstate) = 0;
static bool Process(RakNet::Packet &packet, BaseWorldstate &worldstate);
};
}
#endif //OPENMW_WORLDSTATEPROCESSOR_HPP

@ -150,11 +150,11 @@ add_component_dir (openmw-mp
)
add_component_dir (openmw-mp/Base
BaseActor BaseObjectList BasePacketProcessor BasePlayer BaseStructs
BaseActor BaseObjectList BasePacketProcessor BasePlayer BaseStructs BaseWorldstate
)
add_component_dir (openmw-mp/Controllers
PlayerPacketController ActorPacketController ObjectPacketController
PlayerPacketController ActorPacketController ObjectPacketController WorldstatePacketController
)
add_component_dir(openmw-mp/Master
@ -196,6 +196,10 @@ add_component_dir (openmw-mp/Packets/Object
PacketScriptMemberFloat PacketScriptGlobalShort PacketScriptGlobalFloat
)
add_component_dir (openmw-mp/Packets/Worldstate
WorldstatePacket
)
add_component_dir (fallback
fallback validate
)

@ -0,0 +1,26 @@
#ifndef OPENMW_BASEWORLDSTATE_HPP
#define OPENMW_BASEWORLDSTATE_HPP
#include <components/openmw-mp/Base/BaseStructs.hpp>
#include <RakNetTypes.h>
namespace mwmp
{
class BaseWorldstate
{
public:
BaseWorldstate()
{
}
RakNet::RakNetGUID guid;
bool isValid;
};
}
#endif //OPENMW_BASEWORLDSTATE_HPP

@ -0,0 +1,36 @@
#include "WorldstatePacketController.hpp"
template <typename T>
inline void AddPacket(mwmp::WorldstatePacketController::packets_t *packets, RakNet::RakPeerInterface *peer)
{
T *packet = new T(peer);
typedef mwmp::WorldstatePacketController::packets_t::value_type value_t;
packets->insert(value_t(packet->GetPacketID(), value_t::second_type(packet)));
}
mwmp::WorldstatePacketController::WorldstatePacketController(RakNet::RakPeerInterface *peer)
{
}
mwmp::WorldstatePacket *mwmp::WorldstatePacketController::GetPacket(RakNet::MessageID id)
{
return packets[(unsigned char)id].get();
}
void mwmp::WorldstatePacketController::SetStream(RakNet::BitStream *inStream, RakNet::BitStream *outStream)
{
for(const auto &packet : packets)
packet.second->SetStreams(inStream, outStream);
}
bool mwmp::WorldstatePacketController::ContainsPacket(RakNet::MessageID id)
{
for(const auto &packet : packets)
{
if (packet.first == id)
return true;
}
return false;
}

@ -0,0 +1,27 @@
#ifndef OPENMW_WORLDSTATEPACKETCONTROLLER_HPP
#define OPENMW_WORLDSTATEPACKETCONTROLLER_HPP
#include <RakPeerInterface.h>
#include "../Packets/Worldstate/WorldstatePacket.hpp"
#include <unordered_map>
#include <memory>
namespace mwmp
{
class WorldstatePacketController
{
public:
WorldstatePacketController(RakNet::RakPeerInterface *peer);
WorldstatePacket *GetPacket(RakNet::MessageID id);
void SetStream(RakNet::BitStream *inStream, RakNet::BitStream *outStream);
bool ContainsPacket(RakNet::MessageID id);
typedef std::unordered_map<unsigned char, std::unique_ptr<WorldstatePacket> > packets_t;
private:
packets_t packets;
};
}
#endif //OPENMW_WORLDSTATEPACKETCONTROLLER_HPP

@ -116,7 +116,8 @@ enum OrderingChannel
CHANNEL_ACTOR,
CHANNEL_PLAYER,
CHANNEL_OBJECT,
CHANNEL_MASTER
CHANNEL_MASTER,
CHANNEL_WORLDSTATE
};

@ -0,0 +1,31 @@
#include <components/openmw-mp/NetworkMessages.hpp>
#include <PacketPriority.h>
#include <RakPeer.h>
#include "WorldstatePacket.hpp"
using namespace mwmp;
WorldstatePacket::WorldstatePacket(RakNet::RakPeerInterface *peer) : BasePacket(peer)
{
packetID = 0;
priority = HIGH_PRIORITY;
reliability = RELIABLE_ORDERED;
orderChannel = CHANNEL_WORLDSTATE;
this->peer = peer;
}
WorldstatePacket::~WorldstatePacket()
{
}
void WorldstatePacket::setWorldstate(BaseWorldstate *worldstate)
{
this->worldstate = worldstate;
guid = worldstate->guid;
}
BaseWorldstate *WorldstatePacket::getWorldstate()
{
return worldstate;
}

@ -0,0 +1,30 @@
#ifndef OPENMW_WORLDSTATEPACKET_HPP
#define OPENMW_WORLDSTATEPACKET_HPP
#include <string>
#include <RakNetTypes.h>
#include <BitStream.h>
#include <PacketPriority.h>
#include <components/openmw-mp/Base/BaseWorldstate.hpp>
#include <components/openmw-mp/Packets/BasePacket.hpp>
namespace mwmp
{
class WorldstatePacket : public BasePacket
{
public:
WorldstatePacket(RakNet::RakPeerInterface *peer);
~WorldstatePacket();
void setWorldstate(BaseWorldstate *worldstate);
BaseWorldstate *getWorldstate();
protected:
BaseWorldstate *worldstate;
};
}
#endif //OPENMW_WORLDSTATEPACKET_HPP
Loading…
Cancel
Save