revise network system
This commit is contained in:
parent
be15b1820d
commit
f87b475f49
|
@ -77,6 +77,7 @@ SET(SOURCES
|
|||
src/framework/thirdparty/apngloader.cpp
|
||||
|
||||
# framework net
|
||||
src/framework/net/networkmanager.cpp
|
||||
src/framework/net/connection.cpp
|
||||
src/framework/net/inputmessage.cpp
|
||||
src/framework/net/outputmessage.cpp
|
||||
|
|
|
@ -47,4 +47,7 @@
|
|||
#include "util/rect.h"
|
||||
#include "util/size.h"
|
||||
|
||||
// easy typing for _1, _2, ...
|
||||
using namespace std::placeholders;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -6,9 +6,6 @@
|
|||
|
||||
void LuaInterface::registerFunctions()
|
||||
{
|
||||
// easy typing _1, _2, ...
|
||||
using namespace std::placeholders;
|
||||
|
||||
// UIWidget
|
||||
g_lua.registerClass<UIWidget>();
|
||||
g_lua.bindClassStaticFunction<UIWidget>("create", &UIWidget::create);
|
||||
|
|
|
@ -1,125 +1,147 @@
|
|||
#include "connection.h"
|
||||
#include "networkmanager.h"
|
||||
|
||||
#include <framework/core/eventdispatcher.h>
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
static asio::io_service ioService;
|
||||
asio::io_service g_ioService;
|
||||
|
||||
Connection::Connection() :
|
||||
m_timer(ioService),
|
||||
m_resolver(ioService),
|
||||
m_socket(ioService)
|
||||
m_readTimer(g_ioService),
|
||||
m_writeTimer(g_ioService),
|
||||
m_resolver(g_ioService),
|
||||
m_socket(g_ioService)
|
||||
{
|
||||
}
|
||||
|
||||
Connection::~Connection()
|
||||
{
|
||||
disconnect();
|
||||
m_connected = false;
|
||||
}
|
||||
|
||||
void Connection::poll()
|
||||
{
|
||||
ioService.poll();
|
||||
ioService.reset();
|
||||
g_ioService.poll();
|
||||
g_ioService.reset();
|
||||
}
|
||||
|
||||
void Connection::connect(const std::string& host, uint16 port, const ConnectCallback& connectCallback)
|
||||
void Connection::terminate()
|
||||
{
|
||||
g_ioService.stop();
|
||||
}
|
||||
|
||||
void Connection::connect(const std::string& host, uint16 port, const SimpleCallback& connectCallback)
|
||||
{
|
||||
m_connected = false;
|
||||
m_connectCallback = connectCallback;
|
||||
|
||||
asio::ip::tcp::resolver::query query(host, fw::unsafe_cast<std::string>(port));
|
||||
m_resolver.async_resolve(query, std::bind(&Connection::onResolve, shared_from_this(), std::placeholders::_1, std::placeholders::_2));
|
||||
m_resolver.async_resolve(query, std::bind(&Connection::onResolve, shared_from_this(), _1, _2));
|
||||
|
||||
m_timer.expires_from_now(boost::posix_time::seconds(2));
|
||||
m_timer.async_wait(std::bind(&Connection::onTimeout, shared_from_this(), std::placeholders::_1));
|
||||
m_readTimer.expires_from_now(boost::posix_time::seconds(READ_TIMEOUT));
|
||||
m_readTimer.async_wait(std::bind(&Connection::onTimeout, shared_from_this(), _1));
|
||||
}
|
||||
|
||||
void Connection::disconnect()
|
||||
void Connection::close()
|
||||
{
|
||||
if(!m_connected)
|
||||
return;
|
||||
|
||||
m_readTimer.cancel();
|
||||
m_writeTimer.cancel();
|
||||
|
||||
if(m_socket.is_open()) {
|
||||
m_socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
|
||||
m_socket.close();
|
||||
}
|
||||
|
||||
m_connected = false;
|
||||
}
|
||||
|
||||
void Connection::send(uint8* buffer, uint16 size)
|
||||
void Connection::write(uint8* buffer, uint16 size)
|
||||
{
|
||||
if(!m_connected)
|
||||
return;
|
||||
|
||||
m_writeTimer.cancel();
|
||||
|
||||
asio::async_write(m_socket,
|
||||
asio::buffer(buffer, size),
|
||||
std::bind(&Connection::onSend, shared_from_this(), std::placeholders::_1, std::placeholders::_2));
|
||||
std::bind(&Connection::onWrite, shared_from_this(), _1, _2));
|
||||
|
||||
m_timer.expires_from_now(boost::posix_time::seconds(2));
|
||||
m_timer.async_wait(std::bind(&Connection::onTimeout, shared_from_this(), std::placeholders::_1));
|
||||
m_writeTimer.expires_from_now(boost::posix_time::seconds(WRITE_TIMEOUT));
|
||||
m_writeTimer.async_wait(std::bind(&Connection::onTimeout, shared_from_this(), _1));
|
||||
}
|
||||
|
||||
void Connection::recv(uint16 bytes, uint32 timeout, const RecvCallback& callback)
|
||||
void Connection::read(uint16 bytes, const RecvCallback& callback)
|
||||
{
|
||||
m_readTimer.cancel();
|
||||
|
||||
if(!m_connected)
|
||||
return;
|
||||
|
||||
m_recvCallback = callback;
|
||||
m_recvSize = bytes;
|
||||
|
||||
asio::async_read(m_socket,
|
||||
asio::buffer(m_recvBuffer, bytes),
|
||||
std::bind(&Connection::onRecv, shared_from_this(), std::placeholders::_1));
|
||||
std::bind(&Connection::onRecv, shared_from_this(), _1));
|
||||
|
||||
if(timeout > 0) {
|
||||
m_timer.expires_from_now(boost::posix_time::seconds(timeout));
|
||||
m_timer.async_wait(std::bind(&Connection::onTimeout, shared_from_this(), std::placeholders::_1));
|
||||
}
|
||||
m_readTimer.expires_from_now(boost::posix_time::seconds(READ_TIMEOUT));
|
||||
m_readTimer.async_wait(std::bind(&Connection::onTimeout, shared_from_this(), _1));
|
||||
}
|
||||
|
||||
void Connection::onResolve(const boost::system::error_code& error, asio::ip::tcp::resolver::iterator endpointIterator)
|
||||
{
|
||||
m_readTimer.cancel();
|
||||
|
||||
if(!error) {
|
||||
m_socket.async_connect(*endpointIterator, std::bind(&Connection::onConnect, shared_from_this(), _1));
|
||||
|
||||
m_readTimer.expires_from_now(boost::posix_time::seconds(READ_TIMEOUT));
|
||||
m_readTimer.async_wait(std::bind(&Connection::onTimeout, shared_from_this(), _1));
|
||||
} else
|
||||
handleError(error);
|
||||
}
|
||||
|
||||
void Connection::onConnect(const boost::system::error_code& error)
|
||||
{
|
||||
m_readTimer.cancel();
|
||||
m_connected = true;
|
||||
|
||||
if(!error) {
|
||||
if(m_connectCallback)
|
||||
g_dispatcher.addEvent(m_connectCallback);
|
||||
} else
|
||||
handleError(error);
|
||||
}
|
||||
|
||||
void Connection::onWrite(const boost::system::error_code& error, size_t)
|
||||
{
|
||||
m_writeTimer.cancel();
|
||||
|
||||
if(error)
|
||||
handleError(error);
|
||||
}
|
||||
|
||||
void Connection::onRecv(const boost::system::error_code& error)
|
||||
{
|
||||
m_readTimer.cancel();
|
||||
|
||||
if(!error) {
|
||||
if(m_recvCallback)
|
||||
g_dispatcher.addEvent(std::bind(m_recvCallback, m_recvBuffer, m_recvSize));
|
||||
} else
|
||||
handleError(error);
|
||||
}
|
||||
|
||||
void Connection::onTimeout(const boost::system::error_code& error)
|
||||
{
|
||||
if(error != asio::error::operation_aborted)
|
||||
g_dispatcher.addEvent(std::bind(m_errorCallback, error));
|
||||
handleError(error);
|
||||
}
|
||||
|
||||
void Connection::onResolve(const boost::system::error_code& error, asio::ip::tcp::resolver::iterator endpointIterator)
|
||||
void Connection::handleError(const boost::system::error_code& error)
|
||||
{
|
||||
m_timer.cancel();
|
||||
|
||||
if(error) {
|
||||
logTraceDebug(error.message());
|
||||
close();
|
||||
if(m_errorCallback)
|
||||
g_dispatcher.addEvent(std::bind(m_errorCallback, error));
|
||||
return;
|
||||
}
|
||||
|
||||
m_socket.async_connect(*endpointIterator, std::bind(&Connection::onConnect, shared_from_this(), std::placeholders::_1));
|
||||
|
||||
m_timer.expires_from_now(boost::posix_time::seconds(2));
|
||||
m_timer.async_wait(std::bind(&Connection::onTimeout, shared_from_this(), std::placeholders::_1));
|
||||
}
|
||||
|
||||
void Connection::onConnect(const boost::system::error_code& error)
|
||||
{
|
||||
m_timer.cancel();
|
||||
|
||||
if(error) {
|
||||
if(m_errorCallback)
|
||||
g_dispatcher.addEvent(std::bind(m_errorCallback, error));
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_connectCallback)
|
||||
g_dispatcher.addEvent(m_connectCallback);
|
||||
}
|
||||
|
||||
void Connection::onSend(const boost::system::error_code& error, size_t)
|
||||
{
|
||||
m_timer.cancel();
|
||||
|
||||
if(error) {
|
||||
if(m_errorCallback)
|
||||
g_dispatcher.addEvent(std::bind(m_errorCallback, error));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Connection::onRecv(const boost::system::error_code& error)
|
||||
{
|
||||
m_timer.cancel();
|
||||
|
||||
if(error) {
|
||||
if(m_errorCallback)
|
||||
g_dispatcher.addEvent(std::bind(m_errorCallback, error));
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_recvCallback)
|
||||
g_dispatcher.addEvent(std::bind(m_recvCallback, m_recvBuffer, m_recvSize));
|
||||
}
|
||||
|
|
|
@ -8,40 +8,49 @@ class Connection : public std::enable_shared_from_this<Connection>, boost::nonco
|
|||
{
|
||||
typedef std::function<void(boost::system::error_code&)> ErrorCallback;
|
||||
typedef std::function<void(uint8*, uint16)> RecvCallback;
|
||||
typedef std::function<void()> ConnectCallback;
|
||||
|
||||
enum {
|
||||
READ_TIMEOUT = 10,
|
||||
WRITE_TIMEOUT = 10
|
||||
};
|
||||
|
||||
public:
|
||||
Connection();
|
||||
virtual ~Connection();
|
||||
|
||||
static void init();
|
||||
static void poll();
|
||||
static void terminate();
|
||||
|
||||
void connect(const std::string& host, uint16 port, const ConnectCallback& connectCallback);
|
||||
void disconnect();
|
||||
void send(uint8* buffer, uint16 size);
|
||||
void recv(uint16 bytes, uint32 timeout, const RecvCallback& callback);
|
||||
void connect(const std::string& host, uint16 port, const SimpleCallback& connectCallback);
|
||||
void close();
|
||||
|
||||
void write(uint8* buffer, uint16 size);
|
||||
void read(uint16 bytes, const RecvCallback& callback);
|
||||
|
||||
void setErrorCallback(const ErrorCallback& errorCallback) { m_errorCallback = errorCallback; }
|
||||
void setRecvCallback(const RecvCallback& recvCallback) { m_recvCallback = recvCallback; }
|
||||
|
||||
bool isConnected() const { return m_connected; }
|
||||
|
||||
private:
|
||||
void onTimeout(const boost::system::error_code& error);
|
||||
void onResolve(const boost::system::error_code& error, asio::ip::tcp::resolver::iterator endpointIterator);
|
||||
void onConnect(const boost::system::error_code& error);
|
||||
void onSend(const boost::system::error_code& error, size_t);
|
||||
void onWrite(const boost::system::error_code& error, size_t);
|
||||
void onRecv(const boost::system::error_code& error);
|
||||
void onTimeout(const boost::system::error_code& error);
|
||||
void handleError(const boost::system::error_code& error);
|
||||
|
||||
|
||||
SimpleCallback m_connectCallback;
|
||||
ErrorCallback m_errorCallback;
|
||||
ConnectCallback m_connectCallback;
|
||||
RecvCallback m_recvCallback;
|
||||
|
||||
asio::deadline_timer m_timer;
|
||||
asio::deadline_timer m_readTimer;
|
||||
asio::deadline_timer m_writeTimer;
|
||||
asio::ip::tcp::resolver m_resolver;
|
||||
asio::ip::tcp::socket m_socket;
|
||||
|
||||
uint8 m_recvBuffer[65538];
|
||||
uint16 m_recvSize;
|
||||
RecvCallback m_recvCallback;
|
||||
bool m_connected;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
#include "protocol.h"
|
||||
#include "connection.h"
|
||||
|
||||
Protocol::Protocol() :
|
||||
m_connection(new Connection)
|
||||
Protocol::Protocol() : m_connection(new Connection)
|
||||
{
|
||||
m_connection->setErrorCallback(std::bind(&Protocol::onError, this, std::placeholders::_1));
|
||||
m_connection->setErrorCallback(std::bind(&Protocol::onError, this, _1));
|
||||
m_xteaEncryptionEnabled = false;
|
||||
m_checksumEnabled = true;
|
||||
}
|
||||
|
@ -14,41 +13,48 @@ void Protocol::connect(const std::string& host, uint16 port)
|
|||
m_connection->connect(host, port, std::bind(&Protocol::onConnect, asProtocol()));
|
||||
}
|
||||
|
||||
void Protocol::disconnect()
|
||||
{
|
||||
m_connection->close();
|
||||
}
|
||||
|
||||
void Protocol::send(OutputMessage& outputMessage)
|
||||
{
|
||||
// Encrypt
|
||||
// encrypt
|
||||
if(m_xteaEncryptionEnabled)
|
||||
xteaEncrypt(outputMessage);
|
||||
|
||||
// Set checksum
|
||||
// set checksum
|
||||
uint32 checksum = getAdlerChecksum(outputMessage.getBuffer() + OutputMessage::DATA_POS, outputMessage.getMessageSize());
|
||||
outputMessage.setWritePos(OutputMessage::CHECKSUM_POS);
|
||||
outputMessage.addU32(checksum);
|
||||
|
||||
// Set size
|
||||
// set size
|
||||
uint16 messageSize = outputMessage.getMessageSize();
|
||||
outputMessage.setWritePos(OutputMessage::HEADER_POS);
|
||||
outputMessage.addU16(messageSize);
|
||||
|
||||
// Send
|
||||
m_connection->send(outputMessage.getBuffer(), outputMessage.getMessageSize());
|
||||
// send
|
||||
m_connection->write(outputMessage.getBuffer(), outputMessage.getMessageSize());
|
||||
}
|
||||
|
||||
void Protocol::recv()
|
||||
{
|
||||
m_inputMessage.reset();
|
||||
|
||||
m_connection->recv(InputMessage::HEADER_LENGTH, 2, std::bind(&Protocol::internalRecvHeader, asProtocol(), std::placeholders::_1, std::placeholders::_2));
|
||||
m_connection->read(InputMessage::HEADER_LENGTH, std::bind(&Protocol::internalRecvHeader, asProtocol(), _1, _2));
|
||||
}
|
||||
|
||||
void Protocol::internalRecvHeader(uint8* buffer, uint16 size)
|
||||
{
|
||||
memcpy(m_inputMessage.getBuffer() + InputMessage::HEADER_POS, buffer, size);
|
||||
|
||||
// read message size
|
||||
uint16 dataSize = m_inputMessage.getU16();
|
||||
m_inputMessage.setMessageSize(dataSize);
|
||||
|
||||
m_connection->recv(dataSize, 5, std::bind(&Protocol::internalRecvData, asProtocol(), std::placeholders::_1, std::placeholders::_2));
|
||||
// schedule read for message data
|
||||
m_connection->read(dataSize, std::bind(&Protocol::internalRecvData, asProtocol(), _1, _2));
|
||||
}
|
||||
|
||||
void Protocol::internalRecvData(uint8* buffer, uint16 size)
|
||||
|
@ -59,7 +65,7 @@ void Protocol::internalRecvData(uint8* buffer, uint16 size)
|
|||
uint32 checksum = getAdlerChecksum(m_inputMessage.getBuffer() + InputMessage::DATA_POS, m_inputMessage.getMessageSize() - InputMessage::CHECKSUM_LENGTH);
|
||||
if(m_inputMessage.getU32() != checksum) {
|
||||
// error
|
||||
logError("Checksum is invalid.");
|
||||
logError("ERROR: got a network message with invalid checksum");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -70,27 +76,12 @@ void Protocol::internalRecvData(uint8* buffer, uint16 size)
|
|||
onRecv(m_inputMessage);
|
||||
}
|
||||
|
||||
void Protocol::onError(const boost::system::error_code& err)
|
||||
{
|
||||
std::stringstream message;
|
||||
|
||||
logError("PROTOCOL ERROR: ", err.message());
|
||||
message << "Boost error: " << err.message();
|
||||
|
||||
// invalid hostname
|
||||
// connection timeouted
|
||||
|
||||
// displays a dialog, finish protocol
|
||||
|
||||
callLuaField("onError", message.str());
|
||||
}
|
||||
|
||||
bool Protocol::xteaDecrypt(InputMessage& inputMessage)
|
||||
{
|
||||
// FIXME: this function has not been tested yet
|
||||
uint16 messageSize = inputMessage.getMessageSize() - InputMessage::CHECKSUM_LENGTH;
|
||||
if(messageSize % 8 != 0) {
|
||||
logDebug("not valid encrypted message size");
|
||||
logError("ERROR: invalid encrypted network message");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -113,7 +104,7 @@ bool Protocol::xteaDecrypt(InputMessage& inputMessage)
|
|||
|
||||
int tmp = inputMessage.getU16();
|
||||
if(tmp > inputMessage.getMessageSize() - 4) {
|
||||
logDebug("not valid unencrypted message size");
|
||||
logDebug("ERROR: invalid decrypted a network message");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,14 +13,17 @@ public:
|
|||
Protocol();
|
||||
|
||||
void connect(const std::string& host, uint16 port);
|
||||
void disconnect();
|
||||
|
||||
void send(OutputMessage& outputMessage);
|
||||
void recv();
|
||||
|
||||
void internalRecvHeader(uint8* buffer, uint16 size);
|
||||
void internalRecvData(uint8* buffer, uint16 size);
|
||||
|
||||
virtual void onConnect() = 0;
|
||||
virtual void onRecv(InputMessage& inputMessage) = 0;
|
||||
virtual void onError(const boost::system::error_code& err);
|
||||
virtual void onError(const boost::system::error_code& err) = 0;
|
||||
|
||||
ProtocolPtr asProtocol() { return std::static_pointer_cast<Protocol>(shared_from_this()); }
|
||||
|
||||
|
|
|
@ -26,4 +26,11 @@ enum ThingType {
|
|||
THING_SHOT
|
||||
};
|
||||
|
||||
enum Direction {
|
||||
DIRECTION_NORTH,
|
||||
DIRECTION_EAST,
|
||||
DIRECTION_SOUTH,
|
||||
DIRECTION_WEST
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -13,10 +13,10 @@ public:
|
|||
void parseThingAttributes(std::stringstream& fin, ThingAttributes& thingAttributes);
|
||||
void parseThingAttributesOpt(std::stringstream& fin, ThingAttributes& thingAttributes, uint8 opt);
|
||||
|
||||
const ThingAttributes& getItemAttributes(uint16 id) { return m_itemsAttributes[id - 100]; }
|
||||
const ThingAttributes& getCreatureAttributes(uint16 id) { return m_creaturesAttributes[id - 1]; }
|
||||
const ThingAttributes& getEffectAttributes(uint16 id) { return m_effectsAttributes[id - 100]; }
|
||||
const ThingAttributes& getShotAttributes(uint16 id) { return m_shotsAttributes[id - 1]; }
|
||||
ThingAttributes& getItemAttributes(uint16 id) { return m_itemsAttributes[id - 100]; }
|
||||
ThingAttributes& getCreatureAttributes(uint16 id) { return m_creaturesAttributes[id - 1]; }
|
||||
ThingAttributes& getEffectAttributes(uint16 id) { return m_effectsAttributes[id - 100]; }
|
||||
ThingAttributes& getShotAttributes(uint16 id) { return m_shotsAttributes[id - 1]; }
|
||||
|
||||
uint32 getSignature() { return m_signature; }
|
||||
|
||||
|
|
|
@ -1,13 +1,32 @@
|
|||
#include "game.h"
|
||||
#include "localplayer.h"
|
||||
#include <otclient/net/protocolgame.h>
|
||||
|
||||
Game g_game;
|
||||
|
||||
Game::Game()
|
||||
void Game::init()
|
||||
{
|
||||
m_online = false;
|
||||
}
|
||||
|
||||
void Game::terminate()
|
||||
{
|
||||
if(m_online)
|
||||
logout();
|
||||
}
|
||||
|
||||
void Game::loginWorld(const std::string& account, const std::string& password, uint32 worldIp, uint16 worldPort, const std::string& characterName)
|
||||
{
|
||||
m_protocolGame = ProtocolGamePtr(new ProtocolGame);
|
||||
m_protocolGame->login(account, password, worldIp, worldPort, characterName);
|
||||
}
|
||||
|
||||
void Game::logout()
|
||||
{
|
||||
m_protocolGame->sendLogout();
|
||||
onLogout();
|
||||
}
|
||||
|
||||
void Game::onLogin()
|
||||
{
|
||||
m_localPlayer = LocalPlayerPtr(new LocalPlayer);
|
||||
|
@ -16,6 +35,7 @@ void Game::onLogin()
|
|||
|
||||
void Game::onLogout()
|
||||
{
|
||||
m_protocolGame.reset();
|
||||
m_localPlayer.reset();
|
||||
m_online = false;
|
||||
}
|
||||
|
|
|
@ -7,17 +7,22 @@
|
|||
class Game
|
||||
{
|
||||
public:
|
||||
Game();
|
||||
void init();
|
||||
void terminate();
|
||||
|
||||
void loginWorld(const std::string& account,
|
||||
const std::string& password,
|
||||
uint32 worldIp, uint16 worldPort,
|
||||
const std::string& characterName);
|
||||
void logout();
|
||||
|
||||
void onLogin();
|
||||
void onLogout();
|
||||
|
||||
void setProtocol(ProtocolGamePtr protocolGame) { m_protocolGame = protocolGame; }
|
||||
|
||||
bool isOnline() { return m_online; }
|
||||
|
||||
ProtocolGamePtr getProtocol() { return m_protocolGame; }
|
||||
LocalPlayerPtr getLocalPlayer() { return m_localPlayer; }
|
||||
ProtocolGamePtr getProtocolGame() { return m_protocolGame; }
|
||||
|
||||
private:
|
||||
LocalPlayerPtr m_localPlayer;
|
||||
|
|
|
@ -11,7 +11,7 @@ public:
|
|||
|
||||
void draw(int x, int y);
|
||||
|
||||
void setCount(uint8 count) { m_count = count; }
|
||||
void setCount(int count) { m_count = count; }
|
||||
|
||||
int getCount() { return m_count; }
|
||||
const ThingAttributes& getAttributes();
|
||||
|
@ -19,7 +19,7 @@ public:
|
|||
ItemPtr asItem() { return std::static_pointer_cast<Item>(shared_from_this()); }
|
||||
|
||||
private:
|
||||
uint8 m_count;
|
||||
int m_count;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,12 +5,6 @@
|
|||
#include "effect.h"
|
||||
#include <framework/graphics/declarations.h>
|
||||
|
||||
struct MapPositionHasher : std::unary_function<Position, std::size_t> {
|
||||
std::size_t operator()(const Position& pos) const {
|
||||
return ((((pos.x * 65536) + pos.y) * 15) + pos.z) % 1000000;
|
||||
}
|
||||
};
|
||||
|
||||
class Map
|
||||
{
|
||||
public:
|
||||
|
@ -19,7 +13,7 @@ public:
|
|||
void draw(int x, int y);
|
||||
|
||||
private:
|
||||
std::unordered_map<Position, TilePtr, MapPositionHasher> m_tiles;
|
||||
std::unordered_map<Position, TilePtr, PositionHasher> m_tiles;
|
||||
std::list<ThingPtr> m_effects;
|
||||
|
||||
FrameBufferPtr m_framebuffer;
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
#include "spritemanager.h"
|
||||
#include <framework/graphics/graphics.h>
|
||||
|
||||
Thing::Thing(ThingType type) : m_id(0), m_type(type)
|
||||
{
|
||||
}
|
||||
|
||||
void Thing::internalDraw(int x, int y, int blendframes, int xdiv, int ydiv, int zdiv, int anim)
|
||||
{
|
||||
const ThingAttributes& attributes = getAttributes();
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
class Thing : public LuaObject
|
||||
{
|
||||
public:
|
||||
Thing(ThingType type) : m_id(0), m_type(type) { }
|
||||
Thing(ThingType type);
|
||||
virtual ~Thing() { }
|
||||
|
||||
virtual void draw(int x, int y) = 0;
|
||||
|
|
|
@ -19,7 +19,7 @@ void Tile::addThing(ThingPtr thing, uint8 stackpos)
|
|||
if(thingAttributes.alwaysOnTop)
|
||||
m_itemsTop.push_back(thing);
|
||||
else
|
||||
m_itemsBot.push_back(thing);
|
||||
m_itemsBottom.push_back(thing);
|
||||
}
|
||||
} else if(thing->asCreature()) {
|
||||
m_creatures.push_back(thing);
|
||||
|
@ -31,7 +31,7 @@ void Tile::draw(int x, int y)
|
|||
if(m_ground)
|
||||
m_ground->draw(x, y);
|
||||
|
||||
for(const ThingPtr& thing : m_itemsBot)
|
||||
for(const ThingPtr& thing : m_itemsBottom)
|
||||
thing->draw(x, y);
|
||||
|
||||
for(const ThingPtr& thing : m_creatures)
|
||||
|
@ -46,7 +46,7 @@ int Tile::getStackSize()
|
|||
int ret = 0;
|
||||
if(m_ground)
|
||||
ret++;
|
||||
ret += m_itemsBot.size();
|
||||
ret += m_itemsBottom.size();
|
||||
ret += m_creatures.size();
|
||||
ret += m_itemsTop.size();
|
||||
return ret;
|
||||
|
|
|
@ -19,7 +19,7 @@ public:
|
|||
|
||||
private:
|
||||
ThingPtr m_ground;
|
||||
std::deque<ThingPtr> m_itemsBot;
|
||||
std::deque<ThingPtr> m_itemsBottom;
|
||||
std::deque<ThingPtr> m_creatures;
|
||||
std::deque<ThingPtr> m_itemsTop;
|
||||
};
|
||||
|
|
|
@ -1,17 +1,10 @@
|
|||
#include <otclient/net/protocolgame.h>
|
||||
#include <otclient/core/game.h>
|
||||
#include <framework/net/rsa.h>
|
||||
|
||||
ProtocolGame::ProtocolGame()
|
||||
{
|
||||
m_checksumEnabled = false;
|
||||
g_game.setProtocol(ProtocolGamePtr(this));
|
||||
}
|
||||
|
||||
ProtocolGame::~ProtocolGame()
|
||||
{
|
||||
sendLogout();
|
||||
g_game.setProtocol(NULL);
|
||||
m_waitingLoginPacket = false;
|
||||
}
|
||||
|
||||
void ProtocolGame::login(const std::string& accountName, const std::string& accountPassword, uint32 ip, uint16 port, const std::string& characterName)
|
||||
|
@ -21,6 +14,7 @@ void ProtocolGame::login(const std::string& accountName, const std::string& acco
|
|||
return;
|
||||
}
|
||||
|
||||
m_waitingLoginPacket = true;
|
||||
m_accountName = accountName;
|
||||
m_accountPassword = accountPassword;
|
||||
m_characterName = characterName;
|
||||
|
@ -36,64 +30,27 @@ void ProtocolGame::onConnect()
|
|||
recv();
|
||||
}
|
||||
|
||||
void ProtocolGame::sendLoginPacket(uint32 timestamp, uint8 unknown)
|
||||
{
|
||||
OutputMessage oMsg;
|
||||
|
||||
oMsg.addU8(0x0A); // Protocol id
|
||||
oMsg.addU16(0x02); // OS
|
||||
oMsg.addU16(862); // Client version
|
||||
|
||||
oMsg.addU8(0); // First RSA byte must be 0x00 // 1
|
||||
|
||||
// Generete xtea key.
|
||||
m_xteaKey[0] = 432324;
|
||||
m_xteaKey[1] = 24324;
|
||||
m_xteaKey[2] = 423432;
|
||||
m_xteaKey[3] = 234324;
|
||||
|
||||
// Add xtea key
|
||||
oMsg.addU32(m_xteaKey[0]); // 5
|
||||
oMsg.addU32(m_xteaKey[1]); // 9
|
||||
oMsg.addU32(m_xteaKey[2]); // 13
|
||||
oMsg.addU32(m_xteaKey[3]); // 17
|
||||
|
||||
oMsg.addU8(0); // is gm set?
|
||||
oMsg.addString(m_accountName); // Account Name // 20
|
||||
oMsg.addString(m_characterName); // Character Name // 22
|
||||
oMsg.addString(m_accountPassword); // Password // 24
|
||||
|
||||
oMsg.addU32(timestamp); // 28
|
||||
oMsg.addU8(unknown); // 29
|
||||
|
||||
// Packet data must have since byte 0, start, 128 bytes
|
||||
oMsg.addPaddingBytes(128 - (29 + m_accountName.length() + m_characterName.length() + m_accountPassword.length()));
|
||||
|
||||
// Encrypt msg with RSA
|
||||
if(!Rsa::encrypt((char*)oMsg.getBuffer() + 6 + oMsg.getMessageSize() - 128, 128, OTSERV_PUBLIC_RSA))
|
||||
return;
|
||||
|
||||
send(oMsg);
|
||||
|
||||
m_xteaEncryptionEnabled = true;
|
||||
|
||||
recv();
|
||||
}
|
||||
|
||||
void ProtocolGame::onRecv(InputMessage& inputMessage)
|
||||
{
|
||||
static bool firstRecv = true;
|
||||
if(firstRecv) {
|
||||
if(m_waitingLoginPacket) {
|
||||
inputMessage.skipBytes(3);
|
||||
uint32 timestamp = inputMessage.getU32();
|
||||
uint8 unknown = inputMessage.getU8();
|
||||
|
||||
m_waitingLoginPacket = false;
|
||||
m_checksumEnabled = true;
|
||||
sendLoginPacket(timestamp, unknown);
|
||||
|
||||
firstRecv = false;
|
||||
recv();
|
||||
}
|
||||
else {
|
||||
parseMessage(inputMessage);
|
||||
recv();
|
||||
}
|
||||
}
|
||||
|
||||
void ProtocolGame::onError(const boost::system::error_code& error)
|
||||
{
|
||||
// already disconnected, just send onLogout
|
||||
g_game.onLogout();
|
||||
}
|
||||
|
||||
|
|
|
@ -9,16 +9,15 @@
|
|||
|
||||
class ProtocolGame : public Protocol
|
||||
{
|
||||
|
||||
public:
|
||||
ProtocolGame();
|
||||
~ProtocolGame();
|
||||
|
||||
public:
|
||||
void login(const std::string& accountName, const std::string& accountPassword, uint32 ip, uint16 port, const std::string& characterName);
|
||||
|
||||
void onConnect();
|
||||
void onRecv(InputMessage& inputMessage);
|
||||
void onError(const boost::system::error_code& error);
|
||||
|
||||
void sendLogout();
|
||||
void sendPing();
|
||||
|
@ -115,6 +114,7 @@ private:
|
|||
Position parsePosition(InputMessage& msg);
|
||||
|
||||
private:
|
||||
bool m_waitingLoginPacket;
|
||||
std::string m_accountName;
|
||||
std::string m_accountPassword;
|
||||
std::string m_characterName;
|
||||
|
|
|
@ -226,7 +226,6 @@ void ProtocolGame::parseMessage(InputMessage& msg)
|
|||
break;
|
||||
}
|
||||
}
|
||||
recv();
|
||||
}
|
||||
|
||||
void ProtocolGame::parsePlayerLogin(InputMessage& msg)
|
||||
|
@ -629,7 +628,6 @@ void ProtocolGame::parseCreatureSpeak(InputMessage& msg)
|
|||
msg.getU32(); // time
|
||||
break;
|
||||
default:
|
||||
//qDebug() << "Unknown speak type. opt: 0xAA, type: " << type;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -691,7 +689,7 @@ void ProtocolGame::parseTextMessage(InputMessage& msg)
|
|||
{
|
||||
msg.getU8(); // messageType
|
||||
std::string message = msg.getString();
|
||||
logDebug(message);
|
||||
//logDebug(message);
|
||||
}
|
||||
|
||||
void ProtocolGame::parseCancelWalk(InputMessage& msg)
|
||||
|
@ -813,8 +811,6 @@ void ProtocolGame::setMapDescription(InputMessage& msg, int32 x, int32 y, int32
|
|||
zstep = -1;
|
||||
}
|
||||
|
||||
logDebug((int)startz);
|
||||
|
||||
for(int nz = startz; nz != endz + zstep; nz += zstep)
|
||||
setFloorDescription(msg, x, y, nz, width, height, z - nz, &skip);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,47 @@
|
|||
#include "protocolgame.h"
|
||||
#include <framework/net/rsa.h>
|
||||
|
||||
void ProtocolGame::sendLoginPacket(uint32 timestamp, uint8 unknown)
|
||||
{
|
||||
OutputMessage oMsg;
|
||||
|
||||
oMsg.addU8(0x0A); // Protocol id
|
||||
oMsg.addU16(0x02); // OS
|
||||
oMsg.addU16(862); // Client version
|
||||
|
||||
oMsg.addU8(0); // First RSA byte must be 0x00 // 1
|
||||
|
||||
// Generete xtea key.
|
||||
m_xteaKey[0] = 432324;
|
||||
m_xteaKey[1] = 24324;
|
||||
m_xteaKey[2] = 423432;
|
||||
m_xteaKey[3] = 234324;
|
||||
|
||||
// Add xtea key
|
||||
oMsg.addU32(m_xteaKey[0]); // 5
|
||||
oMsg.addU32(m_xteaKey[1]); // 9
|
||||
oMsg.addU32(m_xteaKey[2]); // 13
|
||||
oMsg.addU32(m_xteaKey[3]); // 17
|
||||
|
||||
oMsg.addU8(0); // is gm set?
|
||||
oMsg.addString(m_accountName); // Account Name // 20
|
||||
oMsg.addString(m_characterName); // Character Name // 22
|
||||
oMsg.addString(m_accountPassword); // Password // 24
|
||||
|
||||
oMsg.addU32(timestamp); // 28
|
||||
oMsg.addU8(unknown); // 29
|
||||
|
||||
// Packet data must have since byte 0, start, 128 bytes
|
||||
oMsg.addPaddingBytes(128 - (29 + m_accountName.length() + m_characterName.length() + m_accountPassword.length()));
|
||||
|
||||
// Encrypt msg with RSA
|
||||
if(!Rsa::encrypt((char*)oMsg.getBuffer() + 6 + oMsg.getMessageSize() - 128, 128, OTSERV_PUBLIC_RSA))
|
||||
return;
|
||||
|
||||
send(oMsg);
|
||||
|
||||
m_xteaEncryptionEnabled = true;
|
||||
}
|
||||
|
||||
void ProtocolGame::sendLogout()
|
||||
{
|
||||
|
|
|
@ -6,15 +6,10 @@
|
|||
|
||||
// TODO just testing
|
||||
#include "protocolgame.h"
|
||||
#include <otclient/core/game.h>
|
||||
|
||||
ProtocolLogin::ProtocolLogin()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ProtocolLogin::~ProtocolLogin()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ProtocolLogin::login(const std::string& accountName, const std::string& accountPassword)
|
||||
|
@ -99,7 +94,6 @@ void ProtocolLogin::onRecv(InputMessage& inputMessage)
|
|||
{
|
||||
while(!inputMessage.end()) {
|
||||
uint8 opt = inputMessage.getU8();
|
||||
logDebug("opt:",(uint)opt);
|
||||
switch(opt) {
|
||||
case 0x0A:
|
||||
parseError(inputMessage);
|
||||
|
@ -117,17 +111,22 @@ void ProtocolLogin::onRecv(InputMessage& inputMessage)
|
|||
}
|
||||
}
|
||||
|
||||
void ProtocolLogin::onError(const boost::system::error_code& error)
|
||||
{
|
||||
// already disconnected, just send onLogout
|
||||
callLuaField("onError", error.message());
|
||||
}
|
||||
|
||||
void ProtocolLogin::parseError(InputMessage& inputMessage)
|
||||
{
|
||||
std::string error = inputMessage.getString();
|
||||
logDebug(error);
|
||||
callLuaField("onError", error);
|
||||
disconnect();
|
||||
}
|
||||
|
||||
void ProtocolLogin::parseMOTD(InputMessage& inputMessage)
|
||||
{
|
||||
std::string motd = inputMessage.getString();
|
||||
logDebug(motd);
|
||||
callLuaField("onMotd", motd);
|
||||
}
|
||||
|
||||
|
@ -140,14 +139,12 @@ void ProtocolLogin::parseCharacterList(InputMessage& inputMessage)
|
|||
uint32 ip = inputMessage.getU32();
|
||||
uint16 port = inputMessage.getU16();
|
||||
|
||||
logDebug("character: ", name.c_str(), world.c_str(), ip, " ", port);
|
||||
|
||||
// TODO just test
|
||||
if(i == 0) {
|
||||
ProtocolGamePtr protocolGame = ProtocolGamePtr(new ProtocolGame);
|
||||
protocolGame->login(m_accountName, m_accountPassword, ip, port, name);
|
||||
g_game.loginWorld(m_accountName, m_accountPassword, ip, port, name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
uint16 premiumDays = inputMessage.getU16();
|
||||
logDebug("prem days: ", premiumDays);
|
||||
/*uint16 premiumDays =*/ inputMessage.getU16();
|
||||
disconnect();
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ class ProtocolLogin : public Protocol
|
|||
{
|
||||
public:
|
||||
ProtocolLogin();
|
||||
~ProtocolLogin();
|
||||
|
||||
static ProtocolLoginPtr create() { return ProtocolLoginPtr(new ProtocolLogin); }
|
||||
|
||||
|
@ -19,6 +18,7 @@ public:
|
|||
|
||||
void onConnect();
|
||||
void onRecv(InputMessage& inputMessage);
|
||||
void onError(const boost::system::error_code& error);
|
||||
|
||||
void cancel() { /* TODO: this func */ }
|
||||
|
||||
|
|
|
@ -62,6 +62,8 @@ void OTClient::init(std::vector<std::string> args)
|
|||
// initialize the ui
|
||||
g_ui.init();
|
||||
|
||||
g_game.init();
|
||||
|
||||
// discover and load modules
|
||||
g_modules.discoverAndLoadModules();
|
||||
|
||||
|
@ -146,6 +148,8 @@ void OTClient::terminate()
|
|||
// run modules unload event
|
||||
g_modules.unloadModules();
|
||||
|
||||
g_game.terminate();
|
||||
|
||||
// terminate ui
|
||||
g_ui.terminate();
|
||||
|
||||
|
@ -156,6 +160,7 @@ void OTClient::terminate()
|
|||
poll();
|
||||
|
||||
// terminate network
|
||||
Connection::terminate();
|
||||
//g_network.terminate();
|
||||
|
||||
// terminate dispatcher
|
||||
|
@ -263,7 +268,7 @@ void OTClient::onPlatformEvent(const PlatformEvent& event)
|
|||
{
|
||||
g_ui.inputEvent(event);
|
||||
|
||||
ProtocolGamePtr protocol = g_game.getProtocol();
|
||||
ProtocolGamePtr protocol = g_game.getProtocolGame();
|
||||
if(protocol) {
|
||||
if(event.type == EventKeyDown) {
|
||||
if(event.keycode == KC_UP)
|
||||
|
|
|
@ -8,9 +8,6 @@
|
|||
|
||||
void OTClient::registerLuaFunctions()
|
||||
{
|
||||
// easy typing _1, _2, ...
|
||||
using namespace std::placeholders;
|
||||
|
||||
g_lua.bindGlobalFunction("exit", std::bind(&OTClient::exit, &g_client));
|
||||
g_lua.bindGlobalFunction("setOnClose", std::bind(&OTClient::setOnClose, &g_client, _1));
|
||||
g_lua.bindGlobalFunction("importDat", std::bind(&DatManager::load, &g_dat, _1));
|
||||
|
|
|
@ -3,14 +3,6 @@
|
|||
|
||||
#include <framework/util/types.h>
|
||||
|
||||
enum Direction
|
||||
{
|
||||
DIRECTION_NORTH,
|
||||
DIRECTION_EAST,
|
||||
DIRECTION_SOUTH,
|
||||
DIRECTION_WEST
|
||||
};
|
||||
|
||||
class Position
|
||||
{
|
||||
public:
|
||||
|
@ -33,6 +25,12 @@ public:
|
|||
int z;
|
||||
};
|
||||
|
||||
struct PositionHasher : std::unary_function<Position, std::size_t> {
|
||||
std::size_t operator()(const Position& pos) const {
|
||||
return ((((pos.x * 65536) + pos.y) * 15) + pos.z) % 1000000;
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
std::ostream& operator<<(std::ostream& out, const Position& pos)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue