From bda40b218ad095cbab886d0c620a7f9bd96df78b Mon Sep 17 00:00:00 2001 From: Andre Antunes Date: Fri, 8 Apr 2011 15:18:26 -0300 Subject: [PATCH 1/4] using lambda --- src/framework/net/connection.cpp | 25 +++++++++++++------------ src/framework/net/connection.h | 23 +++++++++++++++-------- src/main.cpp | 4 ++-- src/teststate.cpp | 18 +++++++++++++++++- src/teststate.h | 8 ++++++++ 5 files changed, 55 insertions(+), 23 deletions(-) diff --git a/src/framework/net/connection.cpp b/src/framework/net/connection.cpp index 200612cd..44c26305 100644 --- a/src/framework/net/connection.cpp +++ b/src/framework/net/connection.cpp @@ -38,7 +38,7 @@ void Connection::stop() if(m_connecting){ m_resolver.cancel(); m_socket.cancel(); - + m_connecting = false; } } @@ -53,27 +53,23 @@ void Connection::connect(const std::string& ip, uint16 port) m_connecting = true; m_ip = ip; m_port = port; - - logDebug("connecting..."); - + //first resolve dns boost::asio::ip::tcp::resolver::query query(ip, convertType(port)); m_resolver.async_resolve(query, boost::bind(&Connection::onResolveDns, this, boost::asio::placeholders::error, boost::asio::placeholders::iterator)); } -void Connection::onResolveDns(const boost::system::error_code& error, boost::asio::ip::tcp::resolver::iterator endpoint_iterator) +void Connection::onResolveDns(const boost::system::error_code& error, boost::asio::ip::tcp::resolver::iterator endpointIt) { - logDebug("resolving dns.."); - m_lastError = error; - + if(error){ m_connecting = false; return; } - //lets connect - m_socket.async_connect(*endpoint_iterator, boost::bind(&Connection::onConnect, this, boost::asio::placeholders::error)); + //lets connect + m_socket.async_connect(*endpointIt, boost::bind(&Connection::onConnect, this, boost::asio::placeholders::error)); } void Connection::onConnect(const boost::system::error_code& error) @@ -86,6 +82,11 @@ void Connection::onConnect(const boost::system::error_code& error) } m_connected = true; - - logInfo("Connected on %s.", m_ip.c_str()); + + if(!m_callback){ + logError("onConnect::m_callback not set."); + return; + } + + m_callback(); } diff --git a/src/framework/net/connection.h b/src/framework/net/connection.h index d26c9386..beecc409 100644 --- a/src/framework/net/connection.h +++ b/src/framework/net/connection.h @@ -28,37 +28,44 @@ #include +class TestState; + class Connection { public: Connection(boost::asio::io_service& ioService); - + void connect(const std::string& ip, uint16 port); void stop(); - + bool isConnecting() const { return m_connecting; } bool isConnected() const { return m_connected; } - + const boost::system::error_code& getLastError() const { return m_lastError; } void resetLastError() { m_lastError = boost::system::error_code(); } - + + void setCallback(std::function f) { m_callback = f; } + private: - void onResolveDns(const boost::system::error_code& error, boost::asio::ip::tcp::resolver::iterator endpoint_iterator); + void onResolveDns(const boost::system::error_code& error, boost::asio::ip::tcp::resolver::iterator endpointIt); void onConnect(const boost::system::error_code& error); - + private: boost::asio::ip::tcp::socket m_socket; boost::asio::ip::tcp::resolver m_resolver; boost::system::error_code m_lastError; - + bool m_connecting; bool m_connected; - + std::string m_ip; uint16_t m_port; + + std::function m_callback; }; typedef std::shared_ptr ConnectionPtr; + #endif //CONNECTION_h diff --git a/src/main.cpp b/src/main.cpp index e94ece8a..ba41376d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -109,8 +109,8 @@ int main(int argc, const char *argv[]) // state scope { - std::shared_ptr initialState(new MenuState); - //std::shared_ptr initialState(new TestState); + //std::shared_ptr initialState(new MenuState); + std::shared_ptr initialState(new TestState); g_engine.changeState(initialState.get()); Platform::showWindow(); diff --git a/src/teststate.cpp b/src/teststate.cpp index 4d160dc6..f704a2eb 100644 --- a/src/teststate.cpp +++ b/src/teststate.cpp @@ -28,9 +28,26 @@ #include "framework/engine.h" #include "framework/input.h" +#include "framework/net/connections.h" + void TestState::onEnter() { + m_connection = g_connections.createConnection(); + m_connection->setCallback([this]() { + this->onConnect(); + }); + m_connection->connect("www.google.com.br", 80); +} + +void TestState::onConnect() +{ + if(m_connection->isConnected()){ + logInfo("Connected."); + } + else{ + logError("Not connected: %d", m_connection->getLastError().message().c_str()); + } } void TestState::onLeave() @@ -57,4 +74,3 @@ void TestState::update(int ticks, int elapsedTicks) { } - diff --git a/src/teststate.h b/src/teststate.h index ac294069..accedd2e 100644 --- a/src/teststate.h +++ b/src/teststate.h @@ -27,6 +27,8 @@ #include "framework/gamestate.h" +#include "framework/net/connection.h" + class TestState : public GameState { public: @@ -40,6 +42,12 @@ public: virtual void render(); virtual void update(int ticks, int elapsedTicks); + +private: + void onConnect(); + +private: + ConnectionPtr m_connection; }; #endif // TESTSTATE_H From 02c58f16cd4af81e99e075c249cb435e69a71232 Mon Sep 17 00:00:00 2001 From: Andre Antunes Date: Fri, 8 Apr 2011 20:24:51 -0300 Subject: [PATCH 2/4] connection update --- CMakeLists.txt | 7 ++- src/framework/net/connection.cpp | 87 ++++++++++++++++++++++++++----- src/framework/net/connection.h | 37 +++++++++---- src/framework/net/connections.cpp | 2 +- src/framework/prerequisites.h | 1 + src/teststate.cpp | 20 ++----- src/teststate.h | 8 +-- 7 files changed, 115 insertions(+), 47 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index aadf06dc..b5ad4d10 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,6 +55,9 @@ SET(SOURCES src/menustate.cpp src/teststate.cpp +# game net + src/net/protocoltibia87.cpp + # framework sources src/framework/dispatcher.cpp src/framework/framebuffer.cpp @@ -79,7 +82,9 @@ SET(SOURCES # network src/framework/net/connection.cpp - src/framework/net/connections.cpp) + src/framework/net/connections.cpp + src/framework/net/protocol.cpp + src/framework/net/networkmessage.cpp) IF(WIN32) SET(SOURCES ${SOURCES} src/framework/win32platform.cpp) diff --git a/src/framework/net/connection.cpp b/src/framework/net/connection.cpp index 44c26305..65da5ff5 100644 --- a/src/framework/net/connection.cpp +++ b/src/framework/net/connection.cpp @@ -43,13 +43,19 @@ void Connection::stop() } } -void Connection::connect(const std::string& ip, uint16 port) +bool Connection::connect(const std::string& ip, uint16 port, ConnectionCallback onConnect) { if(m_connecting){ logError("Already is connecting."); - return; + return false; + } + + if(m_connected){ + logError("Already is connected."); + return false; } + m_connectCallback = onConnect; m_connecting = true; m_ip = ip; m_port = port; @@ -57,14 +63,15 @@ void Connection::connect(const std::string& ip, uint16 port) //first resolve dns boost::asio::ip::tcp::resolver::query query(ip, convertType(port)); m_resolver.async_resolve(query, boost::bind(&Connection::onResolveDns, this, boost::asio::placeholders::error, boost::asio::placeholders::iterator)); + + return true; } void Connection::onResolveDns(const boost::system::error_code& error, boost::asio::ip::tcp::resolver::iterator endpointIt) { - m_lastError = error; - if(error){ m_connecting = false; + m_connectCallback(error); return; } @@ -74,19 +81,75 @@ void Connection::onResolveDns(const boost::system::error_code& error, boost::asi void Connection::onConnect(const boost::system::error_code& error) { - m_lastError = error; + if(!error){ + m_connected = true; + } + + m_connecting = false; + + m_connectCallback(error); +} + +void Connection::handleError(const boost::system::error_code& error) +{ + if(isConnected()){ + closeSocket(); + } + + stop(); +} + +void Connection::closeSocket() +{ + boost::system::error_code error; + m_socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, error); + + if(error) { + logError("Connection::closeSocket(): %s", error.message().c_str()); + } + + m_socket.close(error); + + if(error) { + logError("Connection::closeSocket(): %s", error.message().c_str()); + } +} + +void Connection::send(NetworkMessagePtr networkMessage, ConnectionCallback onSend) +{ + m_socket.async_send( + boost::asio::buffer(networkMessage->getBuffer(), NetworkMessage::header_length), + boost::bind(&Connection::onSendHeader, shared_from_this(), networkMessage, onSend, boost::asio::placeholders::error) + ); +} + +void Connection::onSendHeader(ConnectionPtr connection, NetworkMessagePtr networkMessage, ConnectionCallback onSend, const boost::system::error_code& error) +{ + if(!connection->isConnected()){ + return; + } if(error){ - m_connecting = false; + connection->handleError(error); + onSend(error); return; - } - - m_connected = true; + } + + connection->getSocket().async_send( + boost::asio::buffer(networkMessage->getBodyBuffer(), networkMessage->getMessageLength()), + boost::bind(&Connection::onSendBody, connection, networkMessage, onSend, boost::asio::placeholders::error) + ); +} - if(!m_callback){ - logError("onConnect::m_callback not set."); +void Connection::onSendBody(ConnectionPtr connection, NetworkMessagePtr networkMessage, ConnectionCallback onSend, const boost::system::error_code& error) +{ + if(!connection->isConnected()){ return; } - m_callback(); + if(error){ + connection->handleError(error); + } + + onSend(error); } diff --git a/src/framework/net/connection.h b/src/framework/net/connection.h index beecc409..a31c4d87 100644 --- a/src/framework/net/connection.h +++ b/src/framework/net/connection.h @@ -28,33 +28,46 @@ #include +#include "networkmessage.h" + class TestState; +class Protocol; +class Connections; -class Connection +class Connection : public std::enable_shared_from_this { public: + typedef std::function ConnectionCallback; + typedef std::shared_ptr ConnectionPtr; + +private: Connection(boost::asio::io_service& ioService); - void connect(const std::string& ip, uint16 port); + bool connect(const std::string& ip, uint16 port, ConnectionCallback onConnect); void stop(); + void send(NetworkMessagePtr networkMessage, ConnectionCallback onSend); - bool isConnecting() const { return m_connecting; } - bool isConnected() const { return m_connected; } + bool isConnecting() const { return m_connecting; } + bool isConnected() const { return m_connected; } - const boost::system::error_code& getLastError() const { return m_lastError; } + boost::asio::ip::tcp::socket& getSocket() { return m_socket; } - void resetLastError() { m_lastError = boost::system::error_code(); } - - void setCallback(std::function f) { m_callback = f; } +private: + static void onSendHeader(ConnectionPtr connection, NetworkMessagePtr networkMessage, ConnectionCallback onSend, const boost::system::error_code& error); + static void onSendBody(ConnectionPtr connection, NetworkMessagePtr networkMessage, ConnectionCallback onSend, const boost::system::error_code& error); private: void onResolveDns(const boost::system::error_code& error, boost::asio::ip::tcp::resolver::iterator endpointIt); void onConnect(const boost::system::error_code& error); private: + void closeSocket(); + +private: + void handleError(const boost::system::error_code& error); + boost::asio::ip::tcp::socket m_socket; boost::asio::ip::tcp::resolver m_resolver; - boost::system::error_code m_lastError; bool m_connecting; bool m_connected; @@ -62,10 +75,12 @@ private: std::string m_ip; uint16_t m_port; - std::function m_callback; + ConnectionCallback m_connectCallback; + + friend class Protocol; + friend class Connections; }; typedef std::shared_ptr ConnectionPtr; - #endif //CONNECTION_h diff --git a/src/framework/net/connections.cpp b/src/framework/net/connections.cpp index 59be8619..75e1b17d 100644 --- a/src/framework/net/connections.cpp +++ b/src/framework/net/connections.cpp @@ -34,6 +34,6 @@ ConnectionPtr Connections::createConnection() { ConnectionPtr connection(new Connection(m_ioService)); m_connections.push_back(connection); - + return connection; } diff --git a/src/framework/prerequisites.h b/src/framework/prerequisites.h index 0e4d2753..866fb5a3 100644 --- a/src/framework/prerequisites.h +++ b/src/framework/prerequisites.h @@ -31,6 +31,7 @@ typedef unsigned char uchar; typedef unsigned short ushort; typedef unsigned int uint; typedef unsigned long ulong; +typedef uint64_t uint64; typedef uint32_t uint32; typedef uint16_t uint16; typedef uint8_t uint8; diff --git a/src/teststate.cpp b/src/teststate.cpp index f704a2eb..32115185 100644 --- a/src/teststate.cpp +++ b/src/teststate.cpp @@ -30,24 +30,12 @@ #include "framework/net/connections.h" -void TestState::onEnter() -{ - m_connection = g_connections.createConnection(); - m_connection->setCallback([this]() { - this->onConnect(); - }); +#include "net/protocoltibia87.h" - m_connection->connect("www.google.com.br", 80); -} - -void TestState::onConnect() +void TestState::onEnter() { - if(m_connection->isConnected()){ - logInfo("Connected."); - } - else{ - logError("Not connected: %d", m_connection->getLastError().message().c_str()); - } + m_protocol = ProtocolTibia87Ptr(new ProtocolTibia87); + m_protocol->begin(); } void TestState::onLeave() diff --git a/src/teststate.h b/src/teststate.h index accedd2e..989929a5 100644 --- a/src/teststate.h +++ b/src/teststate.h @@ -26,8 +26,7 @@ #define TESTSTATE_H #include "framework/gamestate.h" - -#include "framework/net/connection.h" +#include "net/protocoltibia87.h" class TestState : public GameState { @@ -44,10 +43,7 @@ public: virtual void update(int ticks, int elapsedTicks); private: - void onConnect(); - -private: - ConnectionPtr m_connection; + ProtocolTibia87Ptr m_protocol; }; #endif // TESTSTATE_H From 2805a342674a8389d3be407f083f504fb3167ba1 Mon Sep 17 00:00:00 2001 From: Andre Antunes Date: Sat, 9 Apr 2011 22:25:13 -0300 Subject: [PATCH 3/4] begining tibia protocol --- CMakeLists.txt | 8 +++- src/framework/net/connection.cpp | 67 ++++++++++++++++++++++---------- src/framework/net/connection.h | 17 +++++++- 3 files changed, 69 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b5ad4d10..3f1df164 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,7 @@ FIND_PACKAGE(Lua51 REQUIRED) FIND_PACKAGE(YamlCpp REQUIRED) FIND_PACKAGE(PhysFS REQUIRED) FIND_PACKAGE(PNG REQUIRED) +FIND_PACKAGE(GMP REQUIRED) # choose a default build type if not specified IF(NOT CMAKE_BUILD_TYPE) @@ -33,6 +34,7 @@ INCLUDE_DIRECTORIES( ${LUA_INCLUDE_DIRS} ${YAMLCPP_INCLUDE_DIRS} ${PHYSFS_INCLUDE_DIRS} + ${GMP_INCLUDE_DIR} ${PNG_INCLUDE_DIRS}) LINK_DIRECTORIES( @@ -84,7 +86,10 @@ SET(SOURCES src/framework/net/connection.cpp src/framework/net/connections.cpp src/framework/net/protocol.cpp - src/framework/net/networkmessage.cpp) + src/framework/net/networkmessage.cpp + +# util + src/framework/util/rsa.cpp) IF(WIN32) SET(SOURCES ${SOURCES} src/framework/win32platform.cpp) @@ -106,4 +111,5 @@ TARGET_LINK_LIBRARIES(otclient ${YAMLCPP_LIBRARY} ${PHYSFS_LIBRARY} ${PNG_LIBRARY} + ${GMP_LIBRARIES} ${ADDITIONAL_LIBRARIES}) diff --git a/src/framework/net/connection.cpp b/src/framework/net/connection.cpp index 65da5ff5..ad807392 100644 --- a/src/framework/net/connection.cpp +++ b/src/framework/net/connection.cpp @@ -71,7 +71,7 @@ void Connection::onResolveDns(const boost::system::error_code& error, boost::asi { if(error){ m_connecting = false; - m_connectCallback(error); + m_errorCallback(error, __FUNCTION__); return; } @@ -81,22 +81,24 @@ void Connection::onResolveDns(const boost::system::error_code& error, boost::asi void Connection::onConnect(const boost::system::error_code& error) { - if(!error){ - m_connected = true; + if(error){ + m_connecting = false; + m_errorCallback(error, __FUNCTION__); + return; } - m_connecting = false; + m_connected = true; - m_connectCallback(error); + m_connectCallback(); } void Connection::handleError(const boost::system::error_code& error) { + stop(); + if(isConnected()){ closeSocket(); } - - stop(); } void Connection::closeSocket() @@ -117,39 +119,64 @@ void Connection::closeSocket() void Connection::send(NetworkMessagePtr networkMessage, ConnectionCallback onSend) { - m_socket.async_send( + boost::asio::async_write(m_socket, boost::asio::buffer(networkMessage->getBuffer(), NetworkMessage::header_length), - boost::bind(&Connection::onSendHeader, shared_from_this(), networkMessage, onSend, boost::asio::placeholders::error) - ); + boost::bind(&Connection::onSendHeader, shared_from_this(), networkMessage, onSend, boost::asio::placeholders::error)); } -void Connection::onSendHeader(ConnectionPtr connection, NetworkMessagePtr networkMessage, ConnectionCallback onSend, const boost::system::error_code& error) +void Connection::recv(RecvCallback onRecv) +{ + NetworkMessagePtr networkMessage(new NetworkMessage); + + boost::asio::async_read(m_socket, + boost::asio::buffer(networkMessage->getBuffer(), NetworkMessage::header_length), + boost::bind(&Connection::onRecvHeader, shared_from_this(), networkMessage, onRecv, boost::asio::placeholders::error)); +} + +void Connection::onRecvHeader(ConnectionPtr connection, NetworkMessagePtr networkMessage, RecvCallback onRecv, const boost::system::error_code& error) { - if(!connection->isConnected()){ + if(error){ + connection->handleError(error); + connection->onError(error, __FUNCTION__); return; } + boost::asio::async_read(connection->getSocket(), + boost::asio::buffer(networkMessage->getBodyBuffer(), networkMessage->getMessageLength()), + boost::bind(&Connection::onRecvBody, connection, networkMessage, onRecv, boost::asio::placeholders::error)); +} + +void Connection::onRecvBody(ConnectionPtr connection, NetworkMessagePtr networkMessage, RecvCallback onRecv, const boost::system::error_code& error) +{ if(error){ connection->handleError(error); - onSend(error); + connection->onError(error, __FUNCTION__); return; } - connection->getSocket().async_send( - boost::asio::buffer(networkMessage->getBodyBuffer(), networkMessage->getMessageLength()), - boost::bind(&Connection::onSendBody, connection, networkMessage, onSend, boost::asio::placeholders::error) - ); + onRecv(networkMessage); } -void Connection::onSendBody(ConnectionPtr connection, NetworkMessagePtr networkMessage, ConnectionCallback onSend, const boost::system::error_code& error) +void Connection::onSendHeader(ConnectionPtr connection, NetworkMessagePtr networkMessage, ConnectionCallback onSend, const boost::system::error_code& error) { - if(!connection->isConnected()){ + if(error){ + connection->handleError(error); + connection->onError(error, __FUNCTION__); return; } + boost::asio::async_write(connection->getSocket(), + boost::asio::buffer(networkMessage->getBodyBuffer(), networkMessage->getMessageLength()), + boost::bind(&Connection::onSendBody, connection, networkMessage, onSend, boost::asio::placeholders::error)); +} + +void Connection::onSendBody(ConnectionPtr connection, NetworkMessagePtr networkMessage, ConnectionCallback onSend, const boost::system::error_code& error) +{ if(error){ connection->handleError(error); + connection->onError(error, __FUNCTION__); + return; } - onSend(error); + onSend(); } diff --git a/src/framework/net/connection.h b/src/framework/net/connection.h index a31c4d87..53bb03f4 100644 --- a/src/framework/net/connection.h +++ b/src/framework/net/connection.h @@ -37,7 +37,10 @@ class Connections; class Connection : public std::enable_shared_from_this { public: - typedef std::function ConnectionCallback; + typedef std::function ConnectionCallback; + typedef std::function RecvCallback; + typedef std::function ErrorCallback; + typedef std::shared_ptr ConnectionPtr; private: @@ -45,17 +48,26 @@ private: bool connect(const std::string& ip, uint16 port, ConnectionCallback onConnect); void stop(); - void send(NetworkMessagePtr networkMessage, ConnectionCallback onSend); + + void setErrorCallback(ErrorCallback c) { m_errorCallback = c; } + + void recv(RecvCallback onSend); + void send(NetworkMessagePtr networkMessage, ConnectionCallback onRecv); bool isConnecting() const { return m_connecting; } bool isConnected() const { return m_connected; } boost::asio::ip::tcp::socket& getSocket() { return m_socket; } + void onError(const boost::system::error_code& error, const std::string& msg) { m_errorCallback(error, msg); } + private: static void onSendHeader(ConnectionPtr connection, NetworkMessagePtr networkMessage, ConnectionCallback onSend, const boost::system::error_code& error); static void onSendBody(ConnectionPtr connection, NetworkMessagePtr networkMessage, ConnectionCallback onSend, const boost::system::error_code& error); + static void onRecvHeader(ConnectionPtr connection, NetworkMessagePtr networkMessage, RecvCallback onRecv, const boost::system::error_code& error); + static void onRecvBody(ConnectionPtr connection, NetworkMessagePtr networkMessage, RecvCallback onRecv, const boost::system::error_code& error); + private: void onResolveDns(const boost::system::error_code& error, boost::asio::ip::tcp::resolver::iterator endpointIt); void onConnect(const boost::system::error_code& error); @@ -76,6 +88,7 @@ private: uint16_t m_port; ConnectionCallback m_connectCallback; + ErrorCallback m_errorCallback; friend class Protocol; friend class Connections; From 296d613f3b95b7d947401b4306af5dc0048f79dd Mon Sep 17 00:00:00 2001 From: Andre Antunes Date: Sat, 9 Apr 2011 22:26:57 -0300 Subject: [PATCH 4/4] adding net files --- src/framework/net/networkmessage.cpp | 178 +++++++++++++++++++++++++++ src/framework/net/networkmessage.h | 97 +++++++++++++++ src/framework/net/protocol.cpp | 50 ++++++++ src/framework/net/protocol.h | 48 ++++++++ src/main.cpp | 4 +- 5 files changed, 375 insertions(+), 2 deletions(-) create mode 100644 src/framework/net/networkmessage.cpp create mode 100644 src/framework/net/networkmessage.h create mode 100644 src/framework/net/protocol.cpp create mode 100644 src/framework/net/protocol.h diff --git a/src/framework/net/networkmessage.cpp b/src/framework/net/networkmessage.cpp new file mode 100644 index 00000000..38789abf --- /dev/null +++ b/src/framework/net/networkmessage.cpp @@ -0,0 +1,178 @@ +/* The MIT License + * + * Copyright (c) 2010 OTClient, https://github.com/edubart/otclient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "networkmessage.h" + +void NetworkMessage::updateHeaderLength() +{ + uint16 size = m_msgSize; + memcpy(m_msgBuf, &size, 2); +} + +bool NetworkMessage::canAdd(int size) { + return (size + m_readPos < NETWORKMESSAGE_MAXSIZE - 16); +} + +std::string NetworkMessage::getString() +{ + uint16 stringlen = getU16(); + if(stringlen >= (16384 - m_readPos)) + return std::string(); + + char* v = (char*)(m_msgBuf + m_readPos); + m_readPos += stringlen; + return std::string(v, stringlen); +} + +std::string NetworkMessage::getRaw() +{ + uint16 stringlen = m_msgSize - m_readPos; + if(stringlen >= (16384 - m_readPos)) + return std::string(); + + char* v = (char*)(m_msgBuf + m_readPos); + m_readPos += stringlen; + return std::string(v, stringlen); +} + +void NetworkMessage::addString(const char* value) +{ + uint32 stringlen = (uint32)strlen(value); + if(!canAdd(stringlen + 2) || stringlen > 8192) + return; + + addU16(stringlen); + strcpy((char*)(m_msgBuf + m_readPos), value); + m_readPos += stringlen; + m_msgSize += stringlen; +} + +void NetworkMessage::addBytes(const char* bytes, uint32 size) +{ + if(!canAdd(size) || size > 8192) + return; + + memcpy(m_msgBuf + m_readPos, bytes, size); + m_readPos += size; + m_msgSize += size; +} + +void NetworkMessage::addPaddingBytes(uint32 n) +{ + if(!canAdd(n)) + return; + + memset((void*)&m_msgBuf[m_readPos], 0x33, n); + m_msgSize = m_msgSize + n; +} + +void NetworkMessage::skipBytes(int count) { + m_readPos += count; +} + +// simply write functions for outgoing message +void NetworkMessage::addByte(uint8 value) { + if(!canAdd(1)) + return; + + m_msgBuf[m_readPos++] = value; + m_msgSize++; +} + +void NetworkMessage::addU16(uint16 value) { + if(!canAdd(2)) + return; + + *(uint16*)(m_msgBuf + m_readPos) = value; + m_readPos += 2; + m_msgSize += 2; +} + +void NetworkMessage::addU32(uint32 value) { + if(!canAdd(4)) + return; + + *(uint32*)(m_msgBuf + m_readPos) = value; + m_readPos += 4; + m_msgSize += 4; +} + +void NetworkMessage::addU64(uint64 value) { + if(!canAdd(8)) + return; + + *(uint64*)(m_msgBuf + m_readPos) = value; + m_readPos += 8; + m_msgSize += 8; +} + +void NetworkMessage::addString(const std::string &value) { + addString(value.c_str()); +} + +int32 NetworkMessage::getMessageLength() const { + return m_msgSize; +} + +void NetworkMessage::setMessageLength(int32 newSize) { + m_msgSize = newSize; +} + +int32 NetworkMessage::getReadPos() const { + return m_readPos; +} + +uint8 NetworkMessage::getByte() +{ + return m_msgBuf[m_readPos++]; +} + +uint16 NetworkMessage::getU16() +{ + uint16 v = *(uint16*)(m_msgBuf + m_readPos); + m_readPos += 2; + return v; +} + +uint32 NetworkMessage::getU32() +{ + uint32 v = *(uint32*)(m_msgBuf + m_readPos); + m_readPos += 4; + return v; +} + +uint64 NetworkMessage::getU64() +{ + uint64 v = *(uint64*)(m_msgBuf + m_readPos); + m_readPos += 8; + return v; +} + +char* NetworkMessage::getBuffer() { + return (char*)&m_msgBuf[0]; +} + +char* NetworkMessage::getBodyBuffer() { + m_readPos = 2; + return (char*)&m_msgBuf[header_length]; +} diff --git a/src/framework/net/networkmessage.h b/src/framework/net/networkmessage.h new file mode 100644 index 00000000..29d75e08 --- /dev/null +++ b/src/framework/net/networkmessage.h @@ -0,0 +1,97 @@ +/* The MIT License + * + * Copyright (c) 2010 OTClient, https://github.com/edubart/otclient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef NETWORKMESSAGE_H +#define NETWORKMESSAGE_H + +#include "../prerequisites.h" + +class Rsa; + +class NetworkMessage +{ +public: + enum { + header_length = 2, + NETWORKMESSAGE_MAXSIZE = 1500 + }; + + enum { + max_body_length = NETWORKMESSAGE_MAXSIZE - header_length + }; + + // constructor/destructor + NetworkMessage() { + reset(); + } + + // resets the internal buffer to an empty message +protected: + void reset() { + m_msgSize = 0; + m_readPos = 2; + } +public: + // simply read functions for incoming message + uint8 getByte(); + uint16 getU16(); + uint32 getU32(); + uint64 getU64(); + + std::string getString(); + std::string getRaw(); + + // skips count unknown/unused bytes in an incoming message + void skipBytes(int count); + + // simply write functions for outgoing message + void addByte(uint8 value); + void addU16(uint16 value); + void addU32(uint32 value); + void addU64(uint64 value); + void addBytes(const char* bytes, uint32_t size); + void addPaddingBytes(uint32 n); + void addString(const std::string &value); + void addString(const char* value); + int32 getMessageLength() const; + + void setMessageLength(int32 newSize); + int32 getReadPos() const; + int32 getHeaderSize(); + char* getBuffer(); + char* getBodyBuffer(); + + void updateHeaderLength(); + +protected: + inline bool canAdd(int size); + + int32 m_msgSize; + int32 m_readPos; + + uint8 m_msgBuf[NETWORKMESSAGE_MAXSIZE]; +}; + +typedef std::shared_ptr NetworkMessagePtr; + +#endif //NETWORKMESSAGE_H \ No newline at end of file diff --git a/src/framework/net/protocol.cpp b/src/framework/net/protocol.cpp new file mode 100644 index 00000000..dbf5aefe --- /dev/null +++ b/src/framework/net/protocol.cpp @@ -0,0 +1,50 @@ +/* The MIT License + * + * Copyright (c) 2010 OTClient, https://github.com/edubart/otclient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "protocol.h" +#include "connections.h" + +Protocol::Protocol() +{ + m_connection = g_connections.createConnection(); + m_connection->setErrorCallback( + [this](const boost::system::error_code& error, const std::string& msg){ + this->onError(error, msg); + } + ); +} + +void Protocol::send(NetworkMessagePtr networkMessage, Connection::ConnectionCallback onSend) +{ + m_connection->send(networkMessage, onSend); +} + +bool Protocol::connect(const std::string& ip, uint16 port, Connection::ConnectionCallback onConnect) +{ + return m_connection->connect(ip, port, onConnect); +} + +void Protocol::recv(Connection::RecvCallback onRecv) +{ + m_connection->recv(onRecv); +} diff --git a/src/framework/net/protocol.h b/src/framework/net/protocol.h new file mode 100644 index 00000000..38539a79 --- /dev/null +++ b/src/framework/net/protocol.h @@ -0,0 +1,48 @@ +/* The MIT License + * + * Copyright (c) 2010 OTClient, https://github.com/edubart/otclient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef PROTOCOL_H +#define PROTOCOL_H + +#include "../prerequisites.h" +#include "connection.h" + +class Protocol +{ +public: + Protocol(); + + virtual void begin() = 0; + +protected: + void send(NetworkMessagePtr networkMessage, Connection::ConnectionCallback onSend); + void recv(Connection::RecvCallback onRecv); + + bool connect(const std::string& ip, uint16 port, Connection::ConnectionCallback onConnect); + + virtual void onError(const boost::system::error_code& error, const std::string& msg) = 0; + + ConnectionPtr m_connection; +}; + +#endif //PROTOCOL_H diff --git a/src/main.cpp b/src/main.cpp index ba41376d..e94ece8a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -109,8 +109,8 @@ int main(int argc, const char *argv[]) // state scope { - //std::shared_ptr initialState(new MenuState); - std::shared_ptr initialState(new TestState); + std::shared_ptr initialState(new MenuState); + //std::shared_ptr initialState(new TestState); g_engine.changeState(initialState.get()); Platform::showWindow();