From 9422b0d9ca9a333f3f7a0541767a5deb5e99edfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20W=2E=20Urba=C5=84czyk?= Date: Thu, 3 Jul 2008 15:03:32 +0000 Subject: [PATCH] Experimantal parts of netcode --- CAdvmapInterface.cpp | 1 - CMT.cpp | 32 ++++----------- CPlayerInterface.cpp | 1 - client/VCMI_client.vcproj | 2 +- global.h | 17 ++------ lib/Connection.cpp | 72 +++++++++++++++++++++++++++++++++ lib/Connection.h | 84 +++++++++++++++++++++++++++++++++++++++ lib/VCMI_lib.vcproj | 10 ++++- server/VCMI_server.vcproj | 4 ++ server/server_main.cpp | 45 ++++++++------------- 10 files changed, 196 insertions(+), 72 deletions(-) create mode 100644 lib/Connection.cpp create mode 100644 lib/Connection.h diff --git a/CAdvmapInterface.cpp b/CAdvmapInterface.cpp index baba2a7c5..4e708bd3b 100644 --- a/CAdvmapInterface.cpp +++ b/CAdvmapInterface.cpp @@ -262,7 +262,6 @@ void CTerrainRect::deactivate() }; void CTerrainRect::clickLeft(tribool down) { - LOGE("Left mouse button down2"); if ((down==false) || indeterminate(down)) return; if (LOCPLINT->adventureInt->selection.type != HEROI_TYPE) diff --git a/CMT.cpp b/CMT.cpp index 475f09b6a..db4b48dd8 100644 --- a/CMT.cpp +++ b/CMT.cpp @@ -42,11 +42,10 @@ #include "CLua.h" #include "CAdvmapInterface.h" #include "client/Graphics.h" -#include #include +#include "lib/Connection.h" std::string NAME = NAME_VER + std::string(" (client)"); DLL_EXPORT void initDLL(CLodHandler *b); -using boost::asio::ip::tcp; SDL_Surface * screen, * screen2; extern SDL_Surface * CSDL_Ext::std32bppSurface; TTF_Font * TNRB16, *TNR, *GEOR13, *GEORXX, *GEORM, *GEOR16; @@ -61,30 +60,13 @@ void handleCPPObjS(std::map * mapa, CCPPObjectScript * sc } int _tmain(int argc, _TCHAR* argv[]) { - boost::thread servthr(boost::bind(system,"VCMI_server.exe")); - /* - boost::asio::io_service io_service; - boost::system::error_code error = boost::asio::error::host_not_found; - tcp::socket socket(io_service); - tcp::resolver resolver(io_service); - tcp::resolver::query query("127.0.0.1", "3030"); - tcp::resolver::iterator endpoint_iterator = resolver.resolve(tcp::resolver::query("127.0.0.1", "3030")); - socket.connect(*endpoint_iterator, error); - - boost::array buf; - - size_t len = socket.read_some(boost::asio::buffer(buf), error); - - if (error == boost::asio::error::eof) - ; // Connection closed cleanly by peer. - else if (error) - throw boost::system::system_error(error); // Some other error. - - std::cout.write(buf.data(), len); - len = socket.read_some(boost::asio::buffer(buf), error); - std::cout.write(buf.data(), len);*/ - + //boost::thread servthr(boost::bind(system,"VCMI_server.exe")); //runs server executable; + //TODO: add versions for other platforms + CConnection c("localhost","3030",NAME,std::cout); + int r; + c >> r; + std::cout << NAME << std::endl; srand ( time(NULL) ); CPG=NULL; atexit(SDL_Quit); diff --git a/CPlayerInterface.cpp b/CPlayerInterface.cpp index c94cb6ab7..1141aa50c 100644 --- a/CPlayerInterface.cpp +++ b/CPlayerInterface.cpp @@ -1756,7 +1756,6 @@ void CPlayerInterface::handleEvent(SDL_Event *sEvent) else if ((sEvent->type==SDL_MOUSEBUTTONDOWN) && (sEvent->button.button == SDL_BUTTON_LEFT)) { - LOGE("Left mouse button down1"); for(int i=0; ipos,sEvent->motion.x,sEvent->motion.y)) diff --git a/client/VCMI_client.vcproj b/client/VCMI_client.vcproj index 86a03d6fa..cbeb50a17 100644 --- a/client/VCMI_client.vcproj +++ b/client/VCMI_client.vcproj @@ -17,7 +17,7 @@ #include "int3.h" #define THC -#else -#define THC // #endif + +#define NAME_VER ("VCMI \"Altanatse\" 0.7") + enum Ecolor {RED, BLUE, TAN, GREEN, ORANGE, PURPLE, TEAL, PINK}; //player's colors enum EterrainType {border=-1, dirt, sand, grass, snow, swamp, rough, subterranean, lava, water, rock}; enum Eriver {noRiver=0, clearRiver, icyRiver, muddyRiver, lavaRiver}; @@ -31,18 +32,6 @@ extern CGameInfo* CGI; #define HEROI_TYPE (0) #define TOWNI_TYPE (1) -//#define LOGUJ - -#ifdef LOGUJ -#define LOG(x) std::cout< +using namespace boost; +using namespace boost::asio::ip; + +#define LOG(a) \ + if(logging)\ + out << a +#if defined(__hppa__) || \ + defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \ + (defined(__MIPS__) && defined(__MISPEB__)) || \ + defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \ + defined(__sparc__) +#define BIG_ENDIAN +#else +#define LIL_ENDIAN +#endif + + +CConnection::CConnection(std::string host, std::string port, std::string Name, std::ostream & Out) +:io_service(new asio::io_service), name(Name), out(Out) +{ +#ifdef LIL_ENDIAN + myEndianess = true; +#else + myEndianess = false; +#endif + system::error_code error = asio::error::host_not_found; + socket = new tcp::socket(*io_service); + tcp::resolver resolver(*io_service); + tcp::resolver::iterator endpoint_iterator = resolver.resolve(tcp::resolver::query(host,port)); + socket->connect(*endpoint_iterator, error); + if(error) + { + connected = false; + return; + } + std::string pom; + //we got connection + (*this) << std::string("Aiya!\n") << name << myEndianess; //identify ourselves + (*this) >> pom >> pom >> contactEndianess; +} +CConnection::CConnection( + boost::asio::basic_stream_socket > * Socket, + boost::asio::io_service *Io_service, + std::string Name, + std::ostream & Out ) +:socket(Socket),io_service(Io_service), out(Out), name(Name) +{ + std::string pom; + //we start with just connected socket + (*this) << std::string("Aiya!\n") << name << myEndianess; //identify ourselves + (*this) >> pom >> pom >> contactEndianess; +} +int CConnection::write(const void * data, unsigned size) +{ + LOG("wysylam dane o rozmiarze " << size << std::endl); + int ret; + ret = asio::write(*socket,asio::const_buffers_1(asio::const_buffer(data,size))); + return ret; +} +int CConnection::read(void * data, unsigned size) +{ + int ret = asio::read(*socket,asio::mutable_buffers_1(asio::mutable_buffer(data,size))); + return ret; +} +CConnection::~CConnection(void) +{ + delete io_service; + delete socket; +} diff --git a/lib/Connection.h b/lib/Connection.h new file mode 100644 index 000000000..9e262ca6a --- /dev/null +++ b/lib/Connection.h @@ -0,0 +1,84 @@ +#pragma once +#include "../global.h" +#include +#include +namespace boost +{ + namespace asio + { + namespace ip + { + class tcp; + } + class io_service; + + template class stream_socket_service; + template + class basic_stream_socket; + } +}; + +class DLL_EXPORT CConnection +{ + std::ostream &out; + CConnection(void); +public: + boost::asio::basic_stream_socket < boost::asio::ip::tcp , boost::asio::stream_socket_service > * socket; + bool logging; + bool connected; + bool myEndianess, contactEndianess; //true if little endian, if ednianess is different we'll have to revert recieved multi-byte vars + boost::asio::io_service *io_service; + std::string name; //who uses this connection + + CConnection(std::string host, std::string port, std::string Name, std::ostream & Out); + CConnection(boost::asio::basic_stream_socket < boost::asio::ip::tcp , boost::asio::stream_socket_service > * Socket, boost::asio::io_service *Io_service, std::string Name, std::ostream & Out); //use immediately after accepting connection into socket + int write(const void * data, unsigned size); + int read(void * data, unsigned size); + int readLine(void * data, unsigned maxSize); + ~CConnection(void); +}; + + +template CConnection & operator<<(CConnection &c, const T &data); +template CConnection & operator>>(CConnection &c, T &data); +CConnection & operator<<(CConnection &c, const std::string &data) +{ + boost::uint32_t length = data.size(); + c << length; + c.write(data.c_str(),length); + return c; +} +CConnection & operator>>(CConnection &c, std::string &data) +{ + boost::uint32_t length; + c >> length; + data.reserve(length); + c.read((void*)data.c_str(),length); + return c; +} +CConnection & operator<<(CConnection &c, const char * &data) +{ + boost::uint32_t length = strlen(data); + c << length; + c.write(data,length); + return c; +} +CConnection & operator>>(CConnection &c, char * &data) +{ + boost::uint32_t length; + c >> length; + data = new char[length]; + c.read(data,length); + return c; +} +template CConnection & operator<<(CConnection &c, const T &data) +{ + c.write(&data,sizeof(data)); + return c; +} +template CConnection & operator>>(CConnection &c, T &data) +{ + c.read(&data,sizeof(data)); + return c; +} \ No newline at end of file diff --git a/lib/VCMI_lib.vcproj b/lib/VCMI_lib.vcproj index 0d1c12fb8..c85598afc 100644 --- a/lib/VCMI_lib.vcproj +++ b/lib/VCMI_lib.vcproj @@ -17,7 +17,7 @@ + + @@ -421,6 +425,10 @@ RelativePath="..\hch\CObjectHandler.h" > + + diff --git a/server/VCMI_server.vcproj b/server/VCMI_server.vcproj index 0303b1bc8..f05aa6e97 100644 --- a/server/VCMI_server.vcproj +++ b/server/VCMI_server.vcproj @@ -57,6 +57,8 @@ /> @@ -125,6 +127,8 @@ /> #include #include "../global.h" +#include "../lib/Connection.h" std::string NAME = NAME_VER + std::string(" (server)"); using boost::asio::ip::tcp; using namespace boost; using namespace boost::asio; - -class CConnection -{ -public: - int ID; - tcp::socket socket; - void witaj() - { - char message[50]; strcpy(message,NAME.c_str());message[NAME.size()]='\n'; - write(socket,buffer("Aiya!\n")); - write(socket,buffer(message,NAME.size()+1)); - } - CConnection(io_service& io_service, int id=-1) - : socket(io_service), ID(id) - { - } -}; +using namespace boost::asio::ip; class CVCMIServer { @@ -38,27 +23,29 @@ public: private: void start_accept() { + boost::system::error_code error; std::cout<<"Listening for connections at port " << acceptor.local_endpoint().port() << std::endl; - CConnection * new_connection = new CConnection(acceptor.io_service()); - acceptor.accept(new_connection->socket); - new_connection->witaj(); - acceptor.async_accept(new_connection->socket, - boost::bind(&CVCMIServer::gotConnection, this, new_connection, - placeholders::error)); - } - - void gotConnection(CConnection * connection,const boost::system::error_code& error) - { + tcp::socket s(acceptor.io_service()); + acceptor.accept(s,error); if (!error) { + CConnection *connection = new CConnection(&s,&s.io_service(),NAME,std::cout); std::cout<<"Got connection!" << std::endl; - connection->witaj(); - start_accept(); } else { std::cout<<"Got connection but there is an error " << std::endl; } + + //asio::write(s,asio::buffer("570")); + //new_connection->witaj(); + //acceptor.async_accept(s, + // boost::bind(&CVCMIServer::gotConnection, this, &s, + // placeholders::error)); + } + + void gotConnection(tcp::socket *s,const boost::system::error_code& error) + { } };