diff --git a/apps/openmw-mp/CMakeLists.txt b/apps/openmw-mp/CMakeLists.txt index 6da3aa52a..0c8974878 100644 --- a/apps/openmw-mp/CMakeLists.txt +++ b/apps/openmw-mp/CMakeLists.txt @@ -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}) diff --git a/apps/openmw-mp/Networking.cpp b/apps/openmw-mp/Networking.cpp index e740dc3f8..f6e7f6016 100644 --- a/apps/openmw-mp/Networking.cpp +++ b/apps/openmw-mp/Networking.cpp @@ -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; diff --git a/apps/openmw-mp/Networking.hpp b/apps/openmw-mp/Networking.hpp index 81cd5cb73..d378dced5 100644 --- a/apps/openmw-mp/Networking.hpp +++ b/apps/openmw-mp/Networking.hpp @@ -1,13 +1,10 @@ -// -// Created by koncord on 12.01.16. -// - #ifndef OPENMW_NETWORKING_HPP #define OPENMW_NETWORKING_HPP #include #include #include +#include #include #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; diff --git a/apps/openmw-mp/processors/WorldstateProcessor.cpp b/apps/openmw-mp/processors/WorldstateProcessor.cpp new file mode 100644 index 000000000..cbe4e010b --- /dev/null +++ b/apps/openmw-mp/processors/WorldstateProcessor.cpp @@ -0,0 +1,40 @@ +#include "WorldstateProcessor.hpp" +#include "Networking.hpp" + +using namespace mwmp; + +template +typename BasePacketProcessor::processors_t BasePacketProcessor::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; +} diff --git a/apps/openmw-mp/processors/WorldstateProcessor.hpp b/apps/openmw-mp/processors/WorldstateProcessor.hpp new file mode 100644 index 000000000..316744dde --- /dev/null +++ b/apps/openmw-mp/processors/WorldstateProcessor.hpp @@ -0,0 +1,22 @@ +#ifndef OPENMW_BASEWORLDSTATEPROCESSOR_HPP +#define OPENMW_BASEWORLDSTATEPROCESSOR_HPP + +#include +#include +#include +#include +#include "Player.hpp" + +namespace mwmp +{ + class WorldstateProcessor : public BasePacketProcessor + { + public: + + virtual void Do(WorldstatePacket &packet, Player &player, BaseWorldstate &worldstate); + + static bool Process(RakNet::Packet &packet, BaseWorldstate &worldstate) noexcept; + }; +} + +#endif //OPENMW_BASEWORLDSTATEPROCESSOR_HPP diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index de991998c..10384e004 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -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 diff --git a/apps/openmw/mwmp/Networking.cpp b/apps/openmw/mwmp/Networking.cpp index 5e3a0d34c..0d13ce95f 100644 --- a/apps/openmw/mwmp/Networking.cpp +++ b/apps/openmw/mwmp/Networking.cpp @@ -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; diff --git a/apps/openmw/mwmp/Networking.hpp b/apps/openmw/mwmp/Networking.hpp index c16c2cc28..fa8a83be8 100644 --- a/apps/openmw/mwmp/Networking.hpp +++ b/apps/openmw/mwmp/Networking.hpp @@ -16,6 +16,7 @@ #include #include #include +#include #include @@ -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); diff --git a/apps/openmw/mwmp/processors/ProcessorInitializer.cpp b/apps/openmw/mwmp/processors/ProcessorInitializer.cpp index 2b66ed3e4..38cbc0a9c 100644 --- a/apps/openmw/mwmp/processors/ProcessorInitializer.cpp +++ b/apps/openmw/mwmp/processors/ProcessorInitializer.cpp @@ -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() diff --git a/apps/openmw/mwmp/processors/WorldstateProcessor.cpp b/apps/openmw/mwmp/processors/WorldstateProcessor.cpp new file mode 100644 index 000000000..684e7d355 --- /dev/null +++ b/apps/openmw/mwmp/processors/WorldstateProcessor.cpp @@ -0,0 +1,40 @@ +#include "../Networking.hpp" +#include "WorldstateProcessor.hpp" +#include "../Main.hpp" + +using namespace mwmp; + +template +typename BasePacketProcessor::processors_t BasePacketProcessor::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; +} diff --git a/apps/openmw/mwmp/processors/WorldstateProcessor.hpp b/apps/openmw/mwmp/processors/WorldstateProcessor.hpp new file mode 100644 index 000000000..77a888e0d --- /dev/null +++ b/apps/openmw/mwmp/processors/WorldstateProcessor.hpp @@ -0,0 +1,22 @@ +#ifndef OPENMW_WORLDSTATEPROCESSOR_HPP +#define OPENMW_WORLDSTATEPROCESSOR_HPP + +#include +#include +#include +#include "BaseClientPacketProcessor.hpp" + +namespace mwmp +{ + class WorldstateProcessor : public BasePacketProcessor, public BaseClientPacketProcessor + { + public: + virtual void Do(WorldstatePacket &packet, BaseWorldstate &worldstate) = 0; + + static bool Process(RakNet::Packet &packet, BaseWorldstate &worldstate); + }; +} + + + +#endif //OPENMW_WORLDSTATEPROCESSOR_HPP diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 2eb4b5e5d..3516104ed 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -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 ) diff --git a/components/openmw-mp/Base/BaseWorldstate.hpp b/components/openmw-mp/Base/BaseWorldstate.hpp new file mode 100644 index 000000000..a823066f0 --- /dev/null +++ b/components/openmw-mp/Base/BaseWorldstate.hpp @@ -0,0 +1,26 @@ +#ifndef OPENMW_BASEWORLDSTATE_HPP +#define OPENMW_BASEWORLDSTATE_HPP + +#include + +#include + +namespace mwmp +{ + + class BaseWorldstate + { + public: + + BaseWorldstate() + { + + } + + RakNet::RakNetGUID guid; + + bool isValid; + }; +} + +#endif //OPENMW_BASEWORLDSTATE_HPP diff --git a/components/openmw-mp/Controllers/WorldstatePacketController.cpp b/components/openmw-mp/Controllers/WorldstatePacketController.cpp new file mode 100644 index 000000000..44d83c5c1 --- /dev/null +++ b/components/openmw-mp/Controllers/WorldstatePacketController.cpp @@ -0,0 +1,36 @@ +#include "WorldstatePacketController.hpp" + +template +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; +} diff --git a/components/openmw-mp/Controllers/WorldstatePacketController.hpp b/components/openmw-mp/Controllers/WorldstatePacketController.hpp new file mode 100644 index 000000000..256c1fcd7 --- /dev/null +++ b/components/openmw-mp/Controllers/WorldstatePacketController.hpp @@ -0,0 +1,27 @@ +#ifndef OPENMW_WORLDSTATEPACKETCONTROLLER_HPP +#define OPENMW_WORLDSTATEPACKETCONTROLLER_HPP + + +#include +#include "../Packets/Worldstate/WorldstatePacket.hpp" +#include +#include + +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 > packets_t; + private: + packets_t packets; + }; +} + +#endif //OPENMW_WORLDSTATEPACKETCONTROLLER_HPP diff --git a/components/openmw-mp/NetworkMessages.hpp b/components/openmw-mp/NetworkMessages.hpp index 0f4de487f..7bf23145b 100644 --- a/components/openmw-mp/NetworkMessages.hpp +++ b/components/openmw-mp/NetworkMessages.hpp @@ -116,7 +116,8 @@ enum OrderingChannel CHANNEL_ACTOR, CHANNEL_PLAYER, CHANNEL_OBJECT, - CHANNEL_MASTER + CHANNEL_MASTER, + CHANNEL_WORLDSTATE }; diff --git a/components/openmw-mp/Packets/Worldstate/WorldstatePacket.cpp b/components/openmw-mp/Packets/Worldstate/WorldstatePacket.cpp new file mode 100644 index 000000000..328eae26d --- /dev/null +++ b/components/openmw-mp/Packets/Worldstate/WorldstatePacket.cpp @@ -0,0 +1,31 @@ +#include +#include +#include +#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; +} diff --git a/components/openmw-mp/Packets/Worldstate/WorldstatePacket.hpp b/components/openmw-mp/Packets/Worldstate/WorldstatePacket.hpp new file mode 100644 index 000000000..f961dd82e --- /dev/null +++ b/components/openmw-mp/Packets/Worldstate/WorldstatePacket.hpp @@ -0,0 +1,30 @@ +#ifndef OPENMW_WORLDSTATEPACKET_HPP +#define OPENMW_WORLDSTATEPACKET_HPP + +#include +#include +#include +#include +#include + +#include + +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