diff --git a/src/framework/core/eventdispatcher.h b/src/framework/core/eventdispatcher.h index 46022c3e..074c0034 100644 --- a/src/framework/core/eventdispatcher.h +++ b/src/framework/core/eventdispatcher.h @@ -33,7 +33,7 @@ public: Event(const SimpleCallback& callback) : m_callback(callback), m_canceled(false), m_executed(false) { } void execute() { - if(!m_canceled) { + if(!m_canceled && !m_executed) { m_callback(); m_executed = true; } diff --git a/src/framework/net/connection.cpp b/src/framework/net/connection.cpp index efa99e52..c30eb986 100644 --- a/src/framework/net/connection.cpp +++ b/src/framework/net/connection.cpp @@ -35,6 +35,7 @@ Connection::Connection() : { m_connected = false; m_connecting = false; + m_sendBufferSize = 0; } Connection::~Connection() @@ -104,17 +105,30 @@ void Connection::close() void Connection::write(uint8* buffer, uint16 size) { - m_writeTimer.cancel(); - if(!m_connected) return; - asio::async_write(m_socket, - asio::buffer(buffer, size), - std::bind(&Connection::onWrite, shared_from_this(), _1, _2)); + // we can't send right, otherwise we could create tcp congestion + memcpy(m_sendBuffer + m_sendBufferSize, buffer, size); + m_sendBufferSize += size; + + if(!m_sendEvent || m_sendEvent->isExecuted() || m_sendEvent->isCanceled()) { + auto weakSelf = ConnectionWeakPtr(shared_from_this()); + m_sendEvent = g_dispatcher.scheduleEvent([=] { + if(!weakSelf.lock()) + return; + //m_writeTimer.cancel(); - m_writeTimer.expires_from_now(boost::posix_time::seconds(WRITE_TIMEOUT)); - m_writeTimer.async_wait(std::bind(&Connection::onTimeout, shared_from_this(), _1)); + asio::async_write(m_socket, + asio::buffer(m_sendBuffer, m_sendBufferSize), + std::bind(&Connection::onWrite, shared_from_this(), _1, _2)); + + m_writeTimer.expires_from_now(boost::posix_time::seconds(WRITE_TIMEOUT)); + m_writeTimer.async_wait(std::bind(&Connection::onTimeout, shared_from_this(), _1)); + + m_sendBufferSize = 0; + }, SEND_INTERVAL); + } } void Connection::read(uint16 bytes, const RecvCallback& callback) @@ -158,6 +172,7 @@ void Connection::onConnect(const boost::system::error_code& error) m_connected = true; // disable nagle's algorithm + //TODO: implement custom cache boost::asio::ip::tcp::no_delay option(true); m_socket.set_option(option); diff --git a/src/framework/net/connection.h b/src/framework/net/connection.h index 0ee2975f..07d548df 100644 --- a/src/framework/net/connection.h +++ b/src/framework/net/connection.h @@ -25,6 +25,8 @@ #include "declarations.h" #include +#include +#include class Connection : public std::enable_shared_from_this, boost::noncopyable { @@ -34,6 +36,8 @@ class Connection : public std::enable_shared_from_this, boost::nonco enum { READ_TIMEOUT = 30, WRITE_TIMEOUT = 30, + SEND_INTERVAL = 1, + SEND_BUFFER_SIZE = 65536, RECV_BUFFER_SIZE = 65536 }; @@ -72,9 +76,13 @@ protected: asio::ip::tcp::resolver m_resolver; asio::ip::tcp::socket m_socket; + uint8 m_sendBuffer[SEND_BUFFER_SIZE]; uint8 m_recvBuffer[RECV_BUFFER_SIZE]; bool m_connected; bool m_connecting; + int m_sendBufferSize; + Timer m_sendTimer; + ScheduledEventPtr m_sendEvent; friend class Server; }; diff --git a/src/otclient/core/map.cpp b/src/otclient/core/map.cpp index dbff3918..0f0baae8 100644 --- a/src/otclient/core/map.cpp +++ b/src/otclient/core/map.cpp @@ -307,6 +307,7 @@ std::vector Map::getSpectatorsInRangeEx(const Position& centerPos, } //TODO: get creatures from other floors corretly + //TODO: delivery creatures in distance order for(int iz=-minZRange; iz<=maxZRange; ++iz) { for(int iy=-minYRange; iy<=maxYRange; ++iy) { diff --git a/src/otclient/luafunctions.cpp b/src/otclient/luafunctions.cpp index ba26b2e1..5ddb1551 100644 --- a/src/otclient/luafunctions.cpp +++ b/src/otclient/luafunctions.cpp @@ -138,6 +138,7 @@ void OTClient::registerLuaFunctions() g_lua.registerClass(); g_lua.registerClass(); + g_lua.bindClassMemberFunction("isWalking", &Creature::isWalking); g_lua.registerClass(); g_lua.registerClass(); g_lua.registerClass();