From 5d1386932462a741df698cef5f5e2d907922552f Mon Sep 17 00:00:00 2001 From: Vladislav Khorev Date: Tue, 26 Feb 2013 13:57:00 +0000 Subject: [PATCH] Added server + network stuff --- Android_Salmon_Engine.mk | 1 + UtilsEngine/UtilsEngine.vcxproj | 9 +- include/ModelManager/ModelManager.h | 2 +- include/Utils/DataTypes/DataTypes.h | 2 +- include/Utils/Network/Network.h | 49 ++++++-- include/Utils/Network/Server.h | 127 ++++++++++++++++++++ include/Utils/Utils.h | 1 + src/ModelManager/ModelManager.cpp | 2 +- src/SalmonEngineInterface.cpp | 5 +- src/SoundManager/SoundManagerWindows.cpp | 4 +- src/Utils/Console/Console.cpp | 1 - src/Utils/FileUtils/FileUtils.cpp | 7 +- src/Utils/Network/Network.cpp | 103 +++++++++++++--- src/Utils/Network/Server.cpp | 144 +++++++++++++++++++++++ 14 files changed, 417 insertions(+), 40 deletions(-) create mode 100644 include/Utils/Network/Server.h create mode 100644 src/Utils/Network/Server.cpp diff --git a/Android_Salmon_Engine.mk b/Android_Salmon_Engine.mk index 2c996af..45a2804 100644 --- a/Android_Salmon_Engine.mk +++ b/Android_Salmon_Engine.mk @@ -308,6 +308,7 @@ LOCAL_SRC_FILES += src/Utils/JniApi/JniApi.cpp LOCAL_SRC_FILES += src/Utils/JniApi/JniApplication.cpp LOCAL_SRC_FILES += src/Utils/Console/Console.cpp LOCAL_SRC_FILES += src/Utils/SerializeInterface/SerializeInterface.cpp +LOCAL_SRC_FILES += src/Utils/Network/Network.cpp LOCAL_SRC_FILES += src/Utils/PngHelper.cpp LOCAL_SRC_FILES += src/Utils/SimpleTimer.cpp LOCAL_SRC_FILES += src/Utils/ThreadUtils.cpp diff --git a/UtilsEngine/UtilsEngine.vcxproj b/UtilsEngine/UtilsEngine.vcxproj index b60ec6f..6e0552e 100644 --- a/UtilsEngine/UtilsEngine.vcxproj +++ b/UtilsEngine/UtilsEngine.vcxproj @@ -36,7 +36,12 @@ - + + $(SalmonEnginePath)$(Configuration)\ + + + $(SalmonEnginePath)$(Configuration)\ + Level3 @@ -69,6 +74,7 @@ + @@ -83,6 +89,7 @@ + diff --git a/include/ModelManager/ModelManager.h b/include/ModelManager/ModelManager.h index c6ed24f..2939328 100644 --- a/include/ModelManager/ModelManager.h +++ b/include/ModelManager/ModelManager.h @@ -37,7 +37,7 @@ public: TLiteModelResource() : TriangleCount(0), PathToResource("") { } ~TLiteModelResource(); - bool LoadModel(boost::shared_array filePointer, cardinal fileSize); + bool LoadModel(boost::shared_array filePointer, cardinal fileSize); void FreeModel(); diff --git a/include/Utils/DataTypes/DataTypes.h b/include/Utils/DataTypes/DataTypes.h index f9ea8e5..cfec80e 100644 --- a/include/Utils/DataTypes/DataTypes.h +++ b/include/Utils/DataTypes/DataTypes.h @@ -18,7 +18,7 @@ namespace SE typedef unsigned int cardinal; typedef unsigned short int word; -typedef unsigned char byte; +//typedef unsigned char byte; typedef cardinal* pcardinal; diff --git a/include/Utils/Network/Network.h b/include/Utils/Network/Network.h index 86e260e..ba0d62e 100644 --- a/include/Utils/Network/Network.h +++ b/include/Utils/Network/Network.h @@ -25,24 +25,50 @@ const int CONST_CONNECTION_TIMEOUT_SECONDS = 300; void SendPropertyTree(boost::asio::io_service& ioService, boost::asio::ip::tcp::socket& socket, boost::property_tree::ptree pTree); -//Must be stored in shared_ptr only -struct TDataReader : public boost::enable_shared_from_this +class TDataReadSignalMap { +protected: + std::map>> SignalMap; +public: + + void AddSlot(const std::string& nodeName, boost::function f); + + bool SignalExists(const std::string& signalName); + + void EmitSignal(const std::string& signalName, const boost::property_tree::ptree& pt); + + void Clear(); + +}; + + +//Must be stored in shared_ptr only +class TDataReader : public boost::enable_shared_from_this +{ +protected: + bool Nonstop; + + void InnerStartRead(); +public: + boost::asio::ip::tcp::socket& Socket; int DataSize; std::vector Data; + TDataReadSignalMap DataReadSignalMap; + TDataReader(boost::asio::ip::tcp::socket& socket); - void StartRead(); + void StartReadOnce(); + + void StartReadNonstop(); void HandleReadDataSize(const boost::system::error_code& error); void HandleReadData(const boost::system::error_code& error); - - boost::signal DataReadSignal; + boost::signal ErrorSignal; }; @@ -52,6 +78,8 @@ class TAuthorizationInterface { public: virtual void Authorize() = 0; + + virtual ~TAuthorizationInterface() { } }; class TSimpleAuthorization : public TAuthorizationInterface @@ -62,8 +90,6 @@ public: boost::asio::ip::tcp::socket& Socket; - //std::shared_ptr DataReader; - std::string Login; std::string Password; @@ -105,6 +131,8 @@ public: boost::signal OnConnectedSignal; boost::signal OnAutorizedSignal; boost::signal OnDisconnectedSignal; + + boost::shared_ptr ClientDataReader; TAuthorizationVariant Authorization; @@ -122,16 +150,11 @@ public: void HandleAuthorized(); void HandleAuthorizationError(); -}; -class TServerSocket -{ -protected: -public: + void SendPropertyTree(boost::property_tree::ptree pTree); }; - } //namespace SE diff --git a/include/Utils/Network/Server.h b/include/Utils/Network/Server.h new file mode 100644 index 0000000..13641e4 --- /dev/null +++ b/include/Utils/Network/Server.h @@ -0,0 +1,127 @@ +#ifndef SERVER_H_INCLUDED +#define SERVER_H_INCLUDED + +#include +#include +#include +#include "boost/shared_array.hpp" +#include "boost/property_tree/ptree.hpp" +#include "boost/foreach.hpp" + +#include "boost/asio.hpp" +#include "boost/date_time/posix_time/posix_time.hpp" +#include "boost/signal.hpp" +#include "boost/variant.hpp" + +#include "include/Utils/Network/SignalSender.h" + + +namespace SE +{ + +class TAutorizatorInterface +{ +protected: +public: + virtual void StartListen() = 0; + + virtual ~TAutorizatorInterface() { } + +}; + +class TSimpleAutorizator : public TAutorizatorInterface +{ +protected: + + + static std::vector UserPasswords; + static boost::mutex UserPasswordsMutex; + +public: + + boost::asio::io_service& IoService; + + boost::asio::ip::tcp::socket& Socket; + + TSimpleAutorizator(boost::asio::io_service& ioService, boost::asio::ip::tcp::socket& socket); + + virtual void StartListen(); + + void HandleGetData(boost::property_tree::ptree pTree); + + boost::signal ErrorSignal; + boost::signal AllowedSignal; + boost::signal DeniedSignal; +}; + +typedef boost::variant> TAuthorizatorVariant; + +class TServerSocket; + +class TConnectedUser : public boost::enable_shared_from_this +{ +protected: + + TServerSocket& Server; + std::string Login; //Need to generalize this + +public: + boost::asio::ip::tcp::socket Socket; + + TAuthorizatorVariant Autorizator; + + boost::shared_ptr UserDataReader; + + TConnectedUser(TServerSocket& server); + + ~TConnectedUser(); + + std::string GetLogin() { return Login; } + + void HandleAllowed(std::string login); //Need to generalize this + + void SendPropertyTree(boost::property_tree::ptree pTree); + +}; + + +class TServerSocket +{ +protected: + std::vector> UserArr; + + boost::thread ServiceThread; + + std::shared_ptr Acceptor; + + +public: + + boost::asio::io_service IoService; + + + TServerSocket(); + ~TServerSocket(); + + void Open(int port); + void Close(); + + void UpdateInThread(); + void JoinServiceThread(); + + void StartAccept(); + void HandleAccept(boost::shared_ptr user, const boost::system::error_code& error); + + //Need to generalize this + boost::signal)> OnUserAuthorizedSignal; + //boost::signal OnUserDisconnectedSignal; + +}; + + + + +} //namespace SE + + +#endif \ No newline at end of file diff --git a/include/Utils/Utils.h b/include/Utils/Utils.h index 9ee52b7..255459c 100644 --- a/include/Utils/Utils.h +++ b/include/Utils/Utils.h @@ -27,6 +27,7 @@ This code combines additional routines (such as console/log, exceptions, math ut #include "include/Utils/SimpleTimer.h" #include "include/Utils/ThreadUtils.h" #include "include/Utils/Network/Network.h" +#include "include/Utils/Network/Server.h" #ifdef TARGET_WIN32 #include "WinApi/WinApi.h" diff --git a/src/ModelManager/ModelManager.cpp b/src/ModelManager/ModelManager.cpp index 27dabaa..f8c0837 100644 --- a/src/ModelManager/ModelManager.cpp +++ b/src/ModelManager/ModelManager.cpp @@ -16,7 +16,7 @@ TLiteModelResource::~TLiteModelResource() *Console<<"ResourceManager::ModelManager::LiteModelResource deleting"; } -bool TLiteModelResource::LoadModel(boost::shared_array filePointer, cardinal fileSize) +bool TLiteModelResource::LoadModel(boost::shared_array filePointer, cardinal fileSize) { FreeModel(); diff --git a/src/SalmonEngineInterface.cpp b/src/SalmonEngineInterface.cpp index 5a6d16e..6877321 100644 --- a/src/SalmonEngineInterface.cpp +++ b/src/SalmonEngineInterface.cpp @@ -29,9 +29,10 @@ void TResourceManager::Update(cardinal timer) GUIManager.Update(timer); - ST::MainThreadIoService.run(); + //ST::MainThreadIoService.run(); + ST::MainThreadIoService.run_one(); - ST::MainThreadIoService.reset(); + //ST::MainThreadIoService.reset(); } TResourceManager::~TResourceManager() diff --git a/src/SoundManager/SoundManagerWindows.cpp b/src/SoundManager/SoundManagerWindows.cpp index dd45704..de162d5 100644 --- a/src/SoundManager/SoundManagerWindows.cpp +++ b/src/SoundManager/SoundManagerWindows.cpp @@ -633,7 +633,7 @@ void TSoundManagerWindows::LoadSound(const std::string& soundFileName) HRESULT result; - std::string fileName = ResourceManager->PathToResources + soundFileName; + std::string fileName = ST::PathToResources + soundFileName; TWaveFile waveFile; @@ -748,7 +748,7 @@ void TSoundManagerWindows::LoadMusic(const std::string& musicFileName) StreamMap[musicName] = ptr; - StreamMap[musicName]->Load(ResourceManager->PathToResources + musicFileName); + StreamMap[musicName]->Load(ST::PathToResources + musicFileName); } } diff --git a/src/Utils/Console/Console.cpp b/src/Utils/Console/Console.cpp index 93172ff..10f8afa 100644 --- a/src/Utils/Console/Console.cpp +++ b/src/Utils/Console/Console.cpp @@ -13,7 +13,6 @@ const int CONST_ROW_WIDTH = 14; const std::string CONST_CONSOLE_TEX_NAME = "console_bkg.bmp"; #ifndef UTILS_ENGINE - void TSimpleConsole::Draw() { diff --git a/src/Utils/FileUtils/FileUtils.cpp b/src/Utils/FileUtils/FileUtils.cpp index ede7022..54f8356 100644 --- a/src/Utils/FileUtils/FileUtils.cpp +++ b/src/Utils/FileUtils/FileUtils.cpp @@ -8,7 +8,12 @@ namespace SE { - + + //Xperimental HACK!!! + #ifdef UTILS_ENGINE +TFileConsole* Console; +#endif + namespace ST { diff --git a/src/Utils/Network/Network.cpp b/src/Utils/Network/Network.cpp index d740795..0e54548 100644 --- a/src/Utils/Network/Network.cpp +++ b/src/Utils/Network/Network.cpp @@ -18,17 +18,72 @@ void SendPropertyTree(boost::asio::io_service& ioService, boost::asio::ip::tcp:: boost::shared_ptr signalSender(new TSignalSender(socket, len, data)); - ioService.post(boost::bind(&TSignalSender::Send, signalSender)); + signalSender->Send(); + //ioService.post(boost::bind(&TSignalSender::Send, signalSender)); } + + +void TDataReadSignalMap::AddSlot(const std::string& nodeName, boost::function f) +{ + if (SignalMap.count(nodeName) == 0) + { + SignalMap[nodeName] = std::shared_ptr>(new boost::signal); + SignalMap[nodeName]->connect(f); + } + else + { + SignalMap[nodeName]->connect(f); + } +} + +bool TDataReadSignalMap::SignalExists(const std::string& signalName) +{ + return SignalMap.count(signalName) != 0; +} + +void TDataReadSignalMap::EmitSignal(const std::string& signalName, const boost::property_tree::ptree& pt) +{ + if (SignalMap.count(signalName) == 0) + { + throw ErrorToLog("Signal " + signalName + " does not exist!"); + } + + (*SignalMap[signalName])(pt); +} + + + +void TDataReadSignalMap::Clear() +{ + SignalMap.clear(); +} + + + + + TDataReader::TDataReader(boost::asio::ip::tcp::socket& socket) : Socket(socket) { } -void TDataReader::StartRead() +void TDataReader::InnerStartRead() { boost::asio::async_read(Socket, boost::asio::buffer(&DataSize, 4), boost::bind(&TDataReader::HandleReadDataSize, shared_from_this(), boost::asio::placeholders::error)); + +} + +void TDataReader::StartReadOnce() +{ + InnerStartRead(); + Nonstop = false; +} + +void TDataReader::StartReadNonstop() +{ + InnerStartRead(); + Nonstop = true; } void TDataReader::HandleReadDataSize(const boost::system::error_code& error) @@ -73,7 +128,19 @@ void TDataReader::HandleReadData(const boost::system::error_code& error) boost::property_tree::read_xml(stream, propertyTree); - DataReadSignal(propertyTree); + BOOST_FOREACH(auto i, propertyTree) + { + if (DataReadSignalMap.SignalExists(i.first)) + { + DataReadSignalMap.EmitSignal(i.first, i.second); + } + } + + if (Nonstop) + { + InnerStartRead(); + } + } catch(boost::property_tree::ptree_error) @@ -82,7 +149,6 @@ void TDataReader::HandleReadData(const boost::system::error_code& error) } } - TSimpleAuthorization::TSimpleAuthorization(boost::asio::io_service& ioService, boost::asio::ip::tcp::socket& socket) : Socket(socket) , IoService(ioService) @@ -95,8 +161,8 @@ void TSimpleAuthorization::Authorize() { boost::shared_ptr dataReader(new TDataReader(Socket)); - dataReader->DataReadSignal.connect(boost::bind(&TSimpleAuthorization::HandleGetData, this, _1)); - + dataReader->DataReadSignalMap.AddSlot("OnHello", boost::bind(&TSimpleAuthorization::HandleGetData, this, _1)); + dataReader->ErrorSignal.connect(ErrorSignal); boost::property_tree::ptree pt; @@ -105,7 +171,7 @@ void TSimpleAuthorization::Authorize() SendPropertyTree(IoService, Socket, pt); - dataReader->StartRead(); + dataReader->StartReadOnce(); } @@ -113,18 +179,12 @@ void TSimpleAuthorization::Authorize() void TSimpleAuthorization::HandleGetData(boost::property_tree::ptree pTree) { - if (pTree.find("OnHello") != pTree.not_found()) - { - Login = pTree.get("OnHello.Login"); - Password = pTree.get("OnHello.Password"); + Login = pTree.get("Login"); + Password = pTree.get("Password"); - SaveLoginPasswordSignal(Login, Password); - AuthorizedSignal(); - - return; - } + SaveLoginPasswordSignal(Login, Password); - ErrorSignal(); + AuthorizedSignal(); } TClientSocket::TClientSocket() @@ -192,6 +252,8 @@ void TClientSocket::Close() Socket.close(); + ClientDataReader->DataReadSignalMap.Clear(); + OnDisconnectedSignal(); } } @@ -231,7 +293,9 @@ void TClientSocket::HandleConnect(const boost::system::error_code& error) void TClientSocket::HandleAuthorized() { + ClientDataReader = boost::shared_ptr(new TDataReader(Socket)); OnAutorizedSignal(); + ClientDataReader->StartReadNonstop(); } void TClientSocket::HandleAuthorizationError() @@ -239,4 +303,9 @@ void TClientSocket::HandleAuthorizationError() } +void TClientSocket::SendPropertyTree(boost::property_tree::ptree pTree) +{ + SE::SendPropertyTree(IoService, Socket, pTree); +} + } //namspace SE \ No newline at end of file diff --git a/src/Utils/Network/Server.cpp b/src/Utils/Network/Server.cpp new file mode 100644 index 0000000..e6b4752 --- /dev/null +++ b/src/Utils/Network/Server.cpp @@ -0,0 +1,144 @@ +#include "include/Utils/Utils.h" + + +namespace SE +{ + std::vector TSimpleAutorizator::UserPasswords; + + boost::mutex TSimpleAutorizator::UserPasswordsMutex; + + + TSimpleAutorizator::TSimpleAutorizator(boost::asio::io_service& ioService, boost::asio::ip::tcp::socket& socket) + : IoService(ioService) + , Socket(socket) + { + + } + + + void TSimpleAutorizator::StartListen() + { + boost::shared_ptr dataReader(new TDataReader(Socket)); + + dataReader->DataReadSignalMap.AddSlot("Hello", boost::bind(&TSimpleAutorizator::HandleGetData, this, _1)); + + dataReader->ErrorSignal.connect(ErrorSignal); + + dataReader->StartReadOnce(); + + } + + + void TSimpleAutorizator::HandleGetData(boost::property_tree::ptree pTree) + { + + std::string Login = boost::lexical_cast(UserPasswords.size()); + std::string Password = "12345"; + + UserPasswordsMutex.lock(); + UserPasswords.push_back(Password); + UserPasswordsMutex.unlock(); + + boost::property_tree::ptree pt; + + pt.put("OnHello.Login", Login); + pt.put("OnHello.Password", Password); + + SendPropertyTree(IoService, Socket, pt); + + AllowedSignal(Login); + + } + + + TConnectedUser::TConnectedUser(TServerSocket& server) + : Server(server) + , Socket(server.IoService) + , Autorizator(std::shared_ptr(new TSimpleAutorizator(server.IoService, Socket))) + { + } + + TConnectedUser::~TConnectedUser() + { + } + + void TConnectedUser::HandleAllowed(std::string login) + { + UserDataReader = boost::shared_ptr(new TDataReader(Socket)); + + Login = login; + + Server.OnUserAuthorizedSignal(shared_from_this()); + + UserDataReader->StartReadNonstop(); + } + + void TConnectedUser::SendPropertyTree(boost::property_tree::ptree pTree) + { + SE::SendPropertyTree(Server.IoService, Socket, pTree); + } + + + + + TServerSocket::TServerSocket() + { + } + + TServerSocket::~TServerSocket() + { + } + + void TServerSocket::Open(int port) + { + boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port); + + Acceptor = std::shared_ptr(new boost::asio::ip::tcp::acceptor(IoService, endpoint)); + + StartAccept(); + + ServiceThread = boost::thread(boost::bind(&TServerSocket::UpdateInThread, this)); + + } + + void TServerSocket::Close() + { + } + + void TServerSocket::UpdateInThread() + { + IoService.run(); + IoService.reset(); + } + + void TServerSocket::JoinServiceThread() + { + ServiceThread.join(); + } + + void TServerSocket::StartAccept() + { + boost::shared_ptr newUser(new TConnectedUser(*this)); + + Acceptor->async_accept(newUser->Socket, boost::bind(&TServerSocket::HandleAccept, this, newUser, boost::asio::placeholders::error)); + } + + + void TServerSocket::HandleAccept(boost::shared_ptr user, const boost::system::error_code& error) + { + if (!error) + { + + UserArr.push_back(user); + + boost::get>(user->Autorizator)->AllowedSignal.connect(boost::bind(&TConnectedUser::HandleAllowed, user, _1)); + + boost::get>(user->Autorizator)->StartListen(); + + } + + StartAccept(); + } + + +} //namspace SE \ No newline at end of file