add lua flexibility for protocol

* use shared_ptr for InputMessage and OutputMessage and bind them
* allow sending network messages from lua
* implement extended opcode
* use own OS type  for otclient to allow server side detection
* fixes in input event bot protection
* move RSA to input/output network messages
* allow to capture opcodes before GameProtocol parsing with the event GameProtocol.onOpcode
* fixes in lua std::string pop/push to allow byte buffering
This commit is contained in:
Eduardo Bart 2012-05-14 18:36:54 -03:00
parent e7030a4995
commit 2478809945
26 changed files with 969 additions and 938 deletions

View File

@ -221,8 +221,10 @@ void Application::poll()
void Application::close()
{
m_onInputEvent = true;
if(!g_lua.callGlobalField<bool>("g_app", "onClose"))
exit();
m_onInputEvent = false;
}
void Application::render()
@ -235,11 +237,15 @@ void Application::render()
void Application::resize(const Size& size)
{
m_onInputEvent = true;
g_graphics.resize(size);
g_ui.resize(size);
m_onInputEvent = false;
}
void Application::inputEvent(const InputEvent& event)
{
m_onInputEvent = true;
g_ui.inputEvent(event);
m_onInputEvent = false;
}

View File

@ -47,6 +47,7 @@ public:
bool isRunning() { return m_running; }
bool isStopping() { return m_stopping; }
bool isOnInputEvent() { return m_onInputEvent; }
int getFrameSleep() { return m_frameSleep; }
const std::string& getName() { return m_appName; }
const std::string& getVersion() { return m_appVersion; }
@ -68,6 +69,7 @@ protected:
Boolean<false> m_initialized;
Boolean<false> m_running;
Boolean<false> m_stopping;
Boolean<false> m_onInputEvent;
};
extern Application *g_app;

View File

@ -397,6 +397,11 @@ void Application::registerLuaFunctions()
// Protocol
g_lua.registerClass<Protocol>();
//g_lua.bindClassMemberFunction<Protocol>("connect", &Protocol::connect);
g_lua.bindClassMemberFunction<Protocol>("disconnect", &Protocol::disconnect);
g_lua.bindClassMemberFunction<Protocol>("isConnected", &Protocol::isConnected);
g_lua.bindClassMemberFunction<Protocol>("isConnecting", &Protocol::isConnecting);
g_lua.bindClassMemberFunction<Protocol>("send", &Protocol::send);
// Module
g_lua.registerClass<Module>();
@ -415,20 +420,31 @@ void Application::registerLuaFunctions()
g_lua.bindClassMemberFunction<Module>("isAutoLoad", &Module::isAutoLoad);
g_lua.bindClassMemberFunction<Module>("getAutoLoadPriority", &Module::getAutoLoadPriority);
// network manipulation via lua is disabled for a while
/*
// InputMessage
g_lua.registerClass<InputMessage>();
g_lua.bindClassStaticFunction<InputMessage>("create", []{ return InputMessagePtr(new InputMessage); });
g_lua.bindClassMemberFunction<InputMessage>("skipBytes", &InputMessage::skipBytes);
g_lua.bindClassMemberFunction<InputMessage>("getU8", &InputMessage::getU8);
g_lua.bindClassMemberFunction<InputMessage>("getU16", &InputMessage::getU16);
g_lua.bindClassMemberFunction<InputMessage>("getU32", &InputMessage::getU32);
g_lua.bindClassMemberFunction<InputMessage>("getU64", &InputMessage::getU64);
g_lua.bindClassMemberFunction<InputMessage>("getString", &InputMessage::getString);
g_lua.bindClassMemberFunction<InputMessage>("decryptRSA", &InputMessage::decryptRSA);
g_lua.bindClassMemberFunction<InputMessage>("getReadSize", &InputMessage::getReadSize);
g_lua.bindClassMemberFunction<InputMessage>("getUnreadSize", &InputMessage::getUnreadSize);
g_lua.bindClassMemberFunction<InputMessage>("eof", &InputMessage::eof);
// OutputMessage
g_lua.registerClass<OutputMessage>();
g_lua.bindClassStaticFunction<OutputMessage>("new", []{ return OutputMessagePtr(new OutputMessage); });
g_lua.bindClassStaticFunction<OutputMessage>("create", []{ return OutputMessagePtr(new OutputMessage); });
g_lua.bindClassMemberFunction<OutputMessage>("reset", &OutputMessage::reset);
g_lua.bindClassMemberFunction<OutputMessage>("addU8", &OutputMessage::addU8);
g_lua.bindClassMemberFunction<OutputMessage>("addU16", &OutputMessage::addU16);
g_lua.bindClassMemberFunction<OutputMessage>("addU32", &OutputMessage::addU32);
g_lua.bindClassMemberFunction<OutputMessage>("addU64", &OutputMessage::addU64);
g_lua.bindClassMemberFunction<OutputMessage>("addString", (void(OutputMessage::*)(const std::string&))&OutputMessage::addString);
g_lua.bindClassStaticFunction<Protocol>("send", [](const ProtocolPtr proto, OutputMessagePtr msg) { proto->send(*msg.get()); });
*/
g_lua.bindClassMemberFunction<OutputMessage>("addString", &OutputMessage::addString);
g_lua.bindClassMemberFunction<OutputMessage>("addPaddingBytes", &OutputMessage::addPaddingBytes);
g_lua.bindClassMemberFunction<OutputMessage>("encryptRSA", &OutputMessage::encryptRSA);
// Application
g_lua.registerStaticClass("g_app");

View File

@ -610,7 +610,7 @@ void LuaInterface::createLuaState()
// load lua standard libraries
luaL_openlibs(L);
// load bit32 lib for bitwise operations
luaopen_bit32(L);
@ -998,6 +998,11 @@ void LuaInterface::pushCString(const char* v)
lua_pushstring(L, v);
}
void LuaInterface::pushString(const std::string& v)
{
lua_pushlstring(L, v.c_str(), v.length());
}
void LuaInterface::pushLightUserdata(void* p)
{
lua_pushlightuserdata(L, p);
@ -1121,9 +1126,10 @@ std::string LuaInterface::toString(int index)
{
assert(hasIndex(index));
std::string str;
const char *c_str = lua_tostring(L, index);
if(c_str)
str = c_str;
size_t len;
const char *c_str = lua_tolstring(L, index, &len);
if(c_str && len > 0)
str.assign(c_str, len);
return str;
}

View File

@ -269,7 +269,7 @@ public:
void pushNumber(double v);
void pushBoolean(bool v);
void pushCString(const char* v);
void pushString(const std::string& v) { pushCString(v.c_str()); }
void pushString(const std::string& v);
void pushLightUserdata(void* p);
void pushThread();
void pushValue(int index = -1);

View File

@ -28,12 +28,14 @@
namespace asio = boost::asio;
class Connection;
class InputMessage;
class OutputMessage;
class Connection;
class Protocol;
class Server;
typedef std::shared_ptr<InputMessage> InputMessagePtr;
typedef std::shared_ptr<OutputMessage> OutputMessagePtr;
typedef std::shared_ptr<Connection> ConnectionPtr;
typedef std::weak_ptr<Connection> ConnectionWeakPtr;
typedef std::shared_ptr<Protocol> ProtocolPtr;

View File

@ -21,6 +21,7 @@
*/
#include "inputmessage.h"
#include "rsa.h"
InputMessage::InputMessage()
{
@ -106,6 +107,11 @@ std::string InputMessage::getString()
return std::string(v, stringLength);
}
void InputMessage::decryptRSA(int size, const std::string& p, const std::string& q, const std::string& d)
{
RSA::decrypt((char*)m_buffer + m_readPos, size, p.c_str(), q.c_str(), d.c_str());
}
bool InputMessage::canRead(int bytes)
{
if((m_readPos - m_headerPos + bytes > m_messageSize) || (m_readPos + bytes > BUFFER_MAXSIZE))

View File

@ -25,8 +25,9 @@
#include "declarations.h"
#include "networkexception.h"
#include <framework/luascript/luaobject.h>
class InputMessage
class InputMessage : public LuaObject
{
public:
enum {
@ -36,32 +37,38 @@ public:
InputMessage();
void reset();
void fillBuffer(uint8 *buffer, uint16 size);
uint16 readSize() { return getU16(); }
bool readChecksum();
void setHeaderSize(uint16 size);
void setMessageSize(uint16 size) { m_messageSize = size; }
void skipBytes(uint16 bytes) { m_readPos += bytes; }
uint8 getU8(bool peek = false);
uint16 getU16(bool peek = false);
uint32 getU32(bool peek = false);
uint64 getU64(bool peek = false);
std::string getString();
void decryptRSA(int size, const std::string& p, const std::string& q, const std::string& d);
int getReadSize() { return m_readPos - m_headerPos; }
int getUnreadSize() { return m_messageSize - (m_readPos - m_headerPos); }
bool eof() { return (m_readPos - m_headerPos) >= m_messageSize; }
protected:
void reset();
void fillBuffer(uint8 *buffer, uint16 size);
void setHeaderSize(uint16 size);
void setMessageSize(uint16 size) { m_messageSize = size; }
uint8* getReadBuffer() { return m_buffer + m_readPos; }
uint8* getHeaderBuffer() { return m_buffer + m_headerPos; }
uint8* getDataBuffer() { return m_buffer + MAX_HEADER_SIZE; }
uint16 getHeaderSize() { return (MAX_HEADER_SIZE - m_headerPos); }
uint16 getMessageSize() { return m_messageSize; }
int getReadSize() { return m_readPos - m_headerPos; }
int getUnreadSize() { return m_messageSize - (m_readPos - m_headerPos); }
bool eof() { return (m_readPos - m_headerPos) >= m_messageSize; }
uint16 readSize() { return getU16(); }
bool readChecksum();
friend class Protocol;
private:
bool canRead(int bytes);

View File

@ -21,6 +21,7 @@
*/
#include <framework/net/outputmessage.h>
#include "rsa.h"
OutputMessage::OutputMessage()
{
@ -66,20 +67,16 @@ void OutputMessage::addU64(uint64 value)
m_messageSize += 8;
}
void OutputMessage::addString(const char* value, int length)
void OutputMessage::addString(const std::string& buffer)
{
if(length > 65535)
throw NetworkException("[OutputMessage::addString] string length > 65535");
checkWrite(length + 2);
addU16(length);
memcpy((char*)(m_buffer + m_writePos), value, length);
m_writePos += length;
m_messageSize += length;
}
void OutputMessage::addString(const std::string& value)
{
addString(value.c_str(), value.length());
int len = buffer.length();
if(len > MAX_STRING_LENGTH)
throw NetworkException("string length > MAX_STRING_LENGTH");
checkWrite(len + 2);
addU16(len);
memcpy((char*)(m_buffer + m_writePos), buffer.c_str(), len);
m_writePos += len;
m_messageSize += len;
}
void OutputMessage::addPaddingBytes(int bytes, uint8 byte)
@ -92,6 +89,11 @@ void OutputMessage::addPaddingBytes(int bytes, uint8 byte)
m_messageSize += bytes;
}
void OutputMessage::encryptRSA(int size, const std::string& key)
{
RSA::encrypt((char*)m_buffer + m_writePos - size, size, key.c_str());
}
void OutputMessage::writeChecksum()
{
uint32 checksum = Fw::getAdlerChecksum(m_buffer + m_headerPos, m_messageSize);

View File

@ -27,13 +27,12 @@
#include "networkexception.h"
#include <framework/luascript/luaobject.h>
typedef std::shared_ptr<OutputMessage> OutputMessagePtr;
class OutputMessage : public LuaObject
{
public:
enum {
BUFFER_MAXSIZE = 1024,
MAX_STRING_LENGTH = 65536,
MAX_HEADER_SIZE = 8
};
@ -45,10 +44,12 @@ public:
void addU16(uint16 value);
void addU32(uint32 value);
void addU64(uint64 value);
void addString(const char* value, int length);
void addString(const std::string& value);
void addString(const std::string& buffer);
void addPaddingBytes(int bytes, uint8 byte = 0);
void encryptRSA(int size, const std::string& key);
protected:
uint8* getWriteBuffer() { return m_buffer + m_writePos; }
uint8* getHeaderBuffer() { return m_buffer + m_headerPos; }
uint8* getDataBuffer() { return m_buffer + MAX_HEADER_SIZE; }
@ -57,6 +58,8 @@ public:
void writeChecksum();
void writeMessageSize();
friend class Protocol;
private:
bool canWrite(int bytes);
void checkWrite(int bytes);

View File

@ -27,6 +27,7 @@ Protocol::Protocol()
{
m_xteaEncryptionEnabled = false;
m_checksumEnabled = false;
m_inputMessage = InputMessagePtr(new InputMessage);
}
Protocol::~Protocol()
@ -63,7 +64,7 @@ bool Protocol::isConnecting()
return false;
}
void Protocol::send(OutputMessage& outputMessage)
void Protocol::send(const OutputMessagePtr& outputMessage)
{
// encrypt
if(m_xteaEncryptionEnabled)
@ -71,19 +72,19 @@ void Protocol::send(OutputMessage& outputMessage)
// write checksum
if(m_checksumEnabled)
outputMessage.writeChecksum();
outputMessage->writeChecksum();
// wirte message size
outputMessage.writeMessageSize();
outputMessage->writeMessageSize();
// send
if(m_connection)
m_connection->write(outputMessage.getHeaderBuffer(), outputMessage.getMessageSize());
m_connection->write(outputMessage->getHeaderBuffer(), outputMessage->getMessageSize());
}
void Protocol::recv()
{
m_inputMessage.reset();
m_inputMessage->reset();
// first update message header size
int headerSize = 2; // 2 bytes for message size
@ -91,7 +92,7 @@ void Protocol::recv()
headerSize += 4; // 4 bytes for checksum
if(m_xteaEncryptionEnabled)
headerSize += 2; // 2 bytes for XTEA encrypted message size
m_inputMessage.setHeaderSize(headerSize);
m_inputMessage->setHeaderSize(headerSize);
// read the first 2 bytes which contain the message size
if(m_connection)
@ -101,8 +102,8 @@ void Protocol::recv()
void Protocol::internalRecvHeader(uint8* buffer, uint16 size)
{
// read message size
m_inputMessage.fillBuffer(buffer, size);
uint16 remainingSize = m_inputMessage.readSize();
m_inputMessage->fillBuffer(buffer, size);
uint16 remainingSize = m_inputMessage->readSize();
// read remaining message data
if(m_connection)
@ -117,9 +118,9 @@ void Protocol::internalRecvData(uint8* buffer, uint16 size)
return;
}
m_inputMessage.fillBuffer(buffer, size);
m_inputMessage->fillBuffer(buffer, size);
if(m_checksumEnabled && !m_inputMessage.readChecksum()) {
if(m_checksumEnabled && !m_inputMessage->readChecksum()) {
logTraceError("got a network message with invalid checksum");
return;
}
@ -130,8 +131,8 @@ void Protocol::internalRecvData(uint8* buffer, uint16 size)
return;
}
} else {
int size = m_inputMessage.getU16();
if(size != m_inputMessage.getUnreadSize()) {
int size = m_inputMessage->getU16();
if(size != m_inputMessage->getUnreadSize()) {
logTraceError("invalid message size");
return;
}
@ -150,15 +151,15 @@ void Protocol::generateXteaKey()
m_xteaKey[3] = unif(eng);
}
bool Protocol::xteaDecrypt(InputMessage& inputMessage)
bool Protocol::xteaDecrypt(const InputMessagePtr& inputMessage)
{
uint16 encryptedSize = inputMessage.getUnreadSize();
uint16 encryptedSize = inputMessage->getUnreadSize();
if(encryptedSize % 8 != 0) {
logTraceError("invalid encrypted network message");
return false;
}
uint32 *buffer = (uint32*)(inputMessage.getReadBuffer());
uint32 *buffer = (uint32*)(inputMessage->getReadBuffer());
int readPos = 0;
while(readPos < encryptedSize/4) {
@ -175,31 +176,31 @@ bool Protocol::xteaDecrypt(InputMessage& inputMessage)
readPos = readPos + 2;
}
uint16 decryptedSize = inputMessage.getU16() + 2;
uint16 decryptedSize = inputMessage->getU16() + 2;
int sizeDelta = decryptedSize - encryptedSize;
if(sizeDelta > 0 || -sizeDelta > encryptedSize) {
logTraceError("invalid decrypted a network message");
return false;
}
inputMessage.setMessageSize(inputMessage.getMessageSize() + sizeDelta);
inputMessage->setMessageSize(inputMessage->getMessageSize() + sizeDelta);
return true;
}
void Protocol::xteaEncrypt(OutputMessage& outputMessage)
void Protocol::xteaEncrypt(const OutputMessagePtr& outputMessage)
{
outputMessage.writeMessageSize();
uint16 encryptedSize = outputMessage.getMessageSize();
outputMessage->writeMessageSize();
uint16 encryptedSize = outputMessage->getMessageSize();
//add bytes until reach 8 multiple
if((encryptedSize % 8) != 0) {
uint16 n = 8 - (encryptedSize % 8);
outputMessage.addPaddingBytes(n);
outputMessage->addPaddingBytes(n);
encryptedSize += n;
}
int readPos = 0;
uint32 *buffer = (uint32*)(outputMessage.getDataBuffer() - 2);
uint32 *buffer = (uint32*)(outputMessage->getDataBuffer() - 2);
while(readPos < encryptedSize / 4) {
uint32 v0 = buffer[readPos], v1 = buffer[readPos + 1];
uint32 delta = 0x61C88647;

View File

@ -41,33 +41,34 @@ public:
bool isConnected();
bool isConnecting();
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) = 0;
virtual void send(const OutputMessagePtr& outputMessage);
ProtocolPtr asProtocol() { return std::static_pointer_cast<Protocol>(shared_from_this()); }
protected:
void recv();
virtual void onConnect() = 0;
virtual void onRecv(const InputMessagePtr& inputMessage) = 0;
virtual void onError(const boost::system::error_code& err) = 0;
void enableChecksum() { m_checksumEnabled = true; }
void enableXteaEncryption() { m_xteaEncryptionEnabled = true; }
void generateXteaKey();
uint32 m_xteaKey[4];
InputMessage m_inputMessage;
private:
bool xteaDecrypt(InputMessage& inputMessage);
void xteaEncrypt(OutputMessage& outputMessage);
void internalRecvHeader(uint8* buffer, uint16 size);
void internalRecvData(uint8* buffer, uint16 size);
bool xteaDecrypt(const InputMessagePtr& inputMessage);
void xteaEncrypt(const OutputMessagePtr& outputMessage);
bool m_checksumEnabled;
bool m_xteaEncryptionEnabled;
ConnectionPtr m_connection;
InputMessagePtr m_inputMessage;
};
#endif

View File

@ -21,56 +21,12 @@
*/
#include "rsa.h"
#include <gmp.h>
Rsa::Rsa()
void RSA::encrypt(char *msg, int size, const char* key)
{
m_keySet = false;
mpz_init2(m_p, 1024);
mpz_init2(m_q, 1024);
mpz_init2(m_d, 1024);
mpz_init2(m_u, 1024);
mpz_init2(m_dp, 1024);
mpz_init2(m_dq, 1024);
mpz_init2(m_mod, 1024);
}
assert(size <= 128);
Rsa::~Rsa()
{
mpz_clear(m_p);
mpz_clear(m_q);
mpz_clear(m_d);
mpz_clear(m_u);
mpz_clear(m_dp);
mpz_clear(m_dq);
mpz_clear(m_mod);
}
void Rsa::setKey(const char* p, const char* q, const char* d)
{
mpz_set_str(m_p, p, 10);
mpz_set_str(m_q, q, 10);
mpz_set_str(m_d, d, 10);
mpz_t pm1,qm1;
mpz_init2(pm1,520);
mpz_init2(qm1,520);
mpz_sub_ui(pm1, m_p, 1);
mpz_sub_ui(qm1, m_q, 1);
mpz_invert(m_u, m_p, m_q);
mpz_mod(m_dp, m_d, pm1);
mpz_mod(m_dq, m_d, qm1);
mpz_mul(m_mod, m_p, m_q);
mpz_clear(pm1);
mpz_clear(qm1);
m_keySet = true;
}
void Rsa::encrypt(char* msg, int32_t size, const char* key)
{
mpz_t plain, c;
mpz_init2(plain, 1024);
mpz_init2(c, 1024);
@ -83,12 +39,12 @@ void Rsa::encrypt(char* msg, int32_t size, const char* key)
mpz_init2(mod, 1024);
mpz_set_str(mod, key, 10);
mpz_import(plain, 128, 1, 1, 0, 0, msg);
mpz_import(plain, size, 1, 1, 0, 0, msg);
mpz_powm(c, plain, e, mod);
size_t count = (mpz_sizeinbase(c, 2) + 7)/8;
memset(msg, 0, 128 - count);
mpz_export(&msg[128 - count], NULL, 1, 1, 0, 0, c);
memset(msg, 0, size - count);
mpz_export(&msg[size - count], NULL, 1, 1, 0, 0, c);
mpz_clear(c);
mpz_clear(plain);
@ -96,43 +52,73 @@ void Rsa::encrypt(char* msg, int32_t size, const char* key)
mpz_clear(mod);
}
bool Rsa::decrypt(char* msg, int32_t size)
void RSA::decrypt(char *msg, int size, const char *p, const char *q, const char *d)
{
if(!m_keySet)
return false;
assert(size <= 128);
mpz_t c,v1,v2,u2,tmp;
mpz_t mp, mq, md, u, dp, dq, mod, c, v1, v2, u2, tmp;
mpz_init2(mp, 1024);
mpz_init2(mq, 1024);
mpz_init2(md, 1024);
mpz_init2(u, 1024);
mpz_init2(dp, 1024);
mpz_init2(dq, 1024);
mpz_init2(mod, 1024);
mpz_init2(c, 1024);
mpz_init2(v1, 1024);
mpz_init2(v2, 1024);
mpz_init2(u2, 1024);
mpz_init2(tmp, 1024);
mpz_import(c, 128, 1, 1, 0, 0, msg);
mpz_set_str(mp, p, 10);
mpz_set_str(mq, q, 10);
mpz_set_str(md, d, 10);
mpz_mod(tmp, c, m_p);
mpz_powm(v1, tmp, m_dp, m_p);
mpz_mod(tmp, c, m_q);
mpz_powm(v2, tmp, m_dq, m_q);
mpz_t pm1,qm1;
mpz_init2(pm1, 520);
mpz_init2(qm1, 520);
mpz_sub_ui(pm1, mp, 1);
mpz_sub_ui(qm1, mq, 1);
mpz_invert(u, mp, mq);
mpz_mod(dp, md, pm1);
mpz_mod(dq, md, qm1);
mpz_mul(mod, mp, mq);
mpz_import(c, size, 1, 1, 0, 0, msg);
mpz_mod(tmp, c, mp);
mpz_powm(v1, tmp, dp, mp);
mpz_mod(tmp, c, mq);
mpz_powm(v2, tmp, dq, mq);
mpz_sub(u2, v2, v1);
mpz_mul(tmp, u2, m_u);
mpz_mod(u2, tmp, m_q);
if(mpz_cmp_si(u2, 0) < 0){
mpz_add(tmp, u2, m_q);
mpz_set(u2, tmp);
mpz_mul(tmp, u2, u);
mpz_mod(u2, tmp, mq);
if(mpz_cmp_si(u2, 0) < 0) {
mpz_add(tmp, u2, mq);
mpz_set(u2, tmp);
}
mpz_mul(tmp, u2, m_p);
mpz_mul(tmp, u2, mp);
mpz_set_ui(c, 0);
mpz_add(c, v1, tmp);
size_t count = (mpz_sizeinbase(c, 2) + 7)/8;
memset(msg, 0, 128 - count);
mpz_export(&msg[128 - count], NULL, 1, 1, 0, 0, c);
memset(msg, 0, size - count);
mpz_export(&msg[size - count], NULL, 1, 1, 0, 0, c);
mpz_clear(c);
mpz_clear(v1);
mpz_clear(v2);
mpz_clear(u2);
mpz_clear(tmp);
return true;
mpz_clear(pm1);
mpz_clear(qm1);
mpz_clear(mp);
mpz_clear(mq);
mpz_clear(md);
mpz_clear(u);
mpz_clear(dp);
mpz_clear(dq);
mpz_clear(mod);
}

View File

@ -24,22 +24,11 @@
#define RSA_H
#include <framework/global.h>
#include <gmp.h>
class Rsa
namespace RSA
{
public:
Rsa();
~Rsa();
void setKey(const char* p, const char* q, const char* d);
bool decrypt(char* msg, int32_t size);
static void encrypt(char* msg, int32_t size, const char* key);
protected:
bool m_keySet;
mpz_t m_p, m_q, m_u, m_d, m_dp, m_dq, m_mod;
void encrypt(char *msg, int size, const char *key);
void decrypt(char *msg, int size, const char *p, const char *q, const char *d);
};
#endif

View File

@ -63,7 +63,6 @@ void UIManager::resize(const Size& size)
void UIManager::inputEvent(const InputEvent& event)
{
m_isOnInputEvent = true;
UIWidgetList widgetList;
switch(event.type) {
case Fw::KeyTextInputEvent:
@ -155,7 +154,6 @@ void UIManager::inputEvent(const InputEvent& event)
default:
break;
};
m_isOnInputEvent = false;
}
void UIManager::updatePressedWidget(const UIWidgetPtr& newPressedWidget, const Point& clickedPos)

View File

@ -62,7 +62,6 @@ public:
UIWidgetPtr getPressedWidget() { return m_pressedWidget; }
UIWidgetPtr getRootWidget() { return m_rootWidget; }
bool isOnInputEvent() { return m_isOnInputEvent; }
bool isDrawingDebugBoxes() { return m_drawDebugBoxes; }
protected:
@ -80,7 +79,6 @@ private:
UIWidgetPtr m_hoveredWidget;
UIWidgetPtr m_pressedWidget;
Boolean<false> m_hoverUpdateScheduled;
bool m_isOnInputEvent;
Boolean<false> m_drawDebugBoxes;
std::unordered_map<std::string, OTMLNodePtr> m_styles;
};

View File

@ -11,7 +11,7 @@ ADD_DEFINITIONS(-DPROTOCOL=${PROTOCOL})
MESSAGE(STATUS "Protocol: " ${PROTOCOL})
IF(CIPSOFT_RSA)
ADD_DEFINITIONS(-DCIPSOFT_RSA)
ADD_DEFINITIONS(-DCIPSOFT_RSA -DOSTYPE=2)
MESSAGE(STATUS "RSA: CipSoft")
ELSE()
MESSAGE(STATUS "RSA: OTServ")

View File

@ -29,6 +29,7 @@
#include "statictext.h"
#include <framework/core/eventdispatcher.h>
#include <framework/ui/uimanager.h>
#include <framework/application.h>
#include <otclient/luascript/luavaluecasts.h>
#include <otclient/net/protocolgame.h>
@ -993,7 +994,7 @@ bool Game::checkBotProtection()
#ifdef BOT_PROTECTION
// accepts calls comming from a stacktrace containing only C++ functions,
// if the stacktrace contains a lua function, then only accept if the engine is processing an input event
if(g_lua.isInCppCallback() && !g_ui.isOnInputEvent()) {
if(g_lua.isInCppCallback() && !g_app->isOnInputEvent()) {
logError(g_lua.traceback("caught a lua call to a bot protected game function, the call was canceled"));
return false;
}

View File

@ -175,6 +175,19 @@ void OTClient::registerLuaFunctions()
g_lua.bindClassMemberFunction<ProtocolLogin>("cancelLogin", &ProtocolLogin::cancelLogin);
g_lua.registerClass<ProtocolGame, Protocol>();
g_lua.bindClassStaticFunction<ProtocolGame>("create", []{ return ProtocolGamePtr(new ProtocolGame); });
g_lua.bindClassMemberFunction<ProtocolGame>("login", &ProtocolGame::login);
g_lua.bindClassMemberFunction<ProtocolGame>("send", &ProtocolGame::send);
g_lua.bindClassMemberFunction<ProtocolGame>("sendExtendedOpcode", &ProtocolGame::sendExtendedOpcode);
g_lua.bindClassMemberFunction<ProtocolGame>("addPosition", &ProtocolGame::addPosition);
g_lua.bindClassMemberFunction<ProtocolGame>("setMapDescription", &ProtocolGame::setMapDescription);
g_lua.bindClassMemberFunction<ProtocolGame>("setFloorDescription", &ProtocolGame::setFloorDescription);
g_lua.bindClassMemberFunction<ProtocolGame>("setTileDescription", &ProtocolGame::setTileDescription);
g_lua.bindClassMemberFunction<ProtocolGame>("getOutfit", &ProtocolGame::getOutfit);
g_lua.bindClassMemberFunction<ProtocolGame>("getThing", &ProtocolGame::getThing);
g_lua.bindClassMemberFunction<ProtocolGame>("getCreature", &ProtocolGame::getCreature);
g_lua.bindClassMemberFunction<ProtocolGame>("getItem", &ProtocolGame::getItem);
g_lua.bindClassMemberFunction<ProtocolGame>("getPosition", &ProtocolGame::getPosition);
g_lua.registerClass<Container>();
g_lua.bindClassStaticFunction<Container>("create", []{ return ContainerPtr(new Container); });
@ -256,7 +269,6 @@ void OTClient::registerLuaFunctions()
g_lua.bindClassMemberFunction<Item>("getId", &Item::getId);
g_lua.bindClassMemberFunction<Item>("isStackable", &Item::isStackable);
g_lua.registerClass<Effect, Thing>();
g_lua.registerClass<Missile, Thing>();
g_lua.registerClass<StaticText, Thing>();

View File

@ -55,15 +55,17 @@ namespace Proto {
OsLinux = 1,
OsWindows = 2,
OsFlash = 3,
OsMac = 4
OsOtclientLinux = 10,
OsOtclientWindows = 11,
OsOtclientMac = 12,
};
#ifdef OSTYPE
constexpr int ClientOs = OSTYPE;
#elif defined WIN32
constexpr int ClientOs = OsWindows;
constexpr int ClientOs = OsOtclientWindows;
#else
constexpr int ClientOs = OsLinux;
constexpr int ClientOs = OsOtclientLinux;
#endif
#if PROTOCOL>=860
@ -107,10 +109,9 @@ namespace Proto {
GameServerFirstGameOpcode = 50,
// NOTE: add any custom opcodes in this range
// 50 - 97
// 51 - 99
// otclient ONLY
GameServerExtendedP2POpcode = 98,
GameServerExtendedOpcode = 99,
// original tibia ONLY
@ -203,10 +204,9 @@ namespace Proto {
ClientFirstGameOpcode = 50,
// NOTE: add any custom opcodes in this range
// 50 - 97
// 50 - 98
// otclient ONLY
ClientExtendedP2POpcode = 98,
ClientExtendedOpcode = 99,
// original tibia ONLY

View File

@ -54,7 +54,7 @@ void ProtocolGame::onConnect()
recv();
}
void ProtocolGame::onRecv(InputMessage& inputMessage)
void ProtocolGame::onRecv(const InputMessagePtr& inputMessage)
{
parseMessage(inputMessage);
recv();

View File

@ -32,11 +32,18 @@ class ProtocolGame : public Protocol
{
public:
void login(const std::string& accountName, const std::string& accountPassword, const std::string& host, uint16 port, const std::string& characterName);
void send(const OutputMessagePtr& outputMessage);
void sendExtendedOpcode(uint8 opcode, const std::string& buffer);
protected:
void onConnect();
void onRecv(InputMessage& inputMessage);
void onRecv(const InputMessagePtr& inputMessage);
void onError(const boost::system::error_code& error);
friend class Game;
protected:
void sendLoginPacket(uint challangeTimestamp, uint8 challangeRandom);
void sendLogout();
void sendPing();
void sendPingBack();
@ -105,115 +112,105 @@ public:
void sendRequestQuestLine(int questId);
void sendNewNewRuleViolation(int reason, int action, const std::string& characterName, const std::string& comment, const std::string& translation);
void sendRequestItemInfo(int itemId, int index);
/*
void sendMarketLeave();
void sendMarketBrowse();
void sendMarketCreate();
void sendMarketCancel();
void sendMarketAccept();
*/
void sendExtendedOpcode(uint8 opcode, const std::string& buffer);
public:
void addPosition(const OutputMessagePtr& msg, const Position& position);
private:
void sendLoginPacket(uint challangeTimestamp, uint8 challangeRandom);
void parseMessage(const InputMessagePtr& msg);
void parseInitGame(const InputMessagePtr& msg);
void parseGMActions(const InputMessagePtr& msg);
void parseLoginError(const InputMessagePtr& msg);
void parseLoginAdvice(const InputMessagePtr& msg);
void parseLoginWait(const InputMessagePtr& msg);
void parsePing(const InputMessagePtr& msg);
void parsePingBack(const InputMessagePtr& msg);
void parseChallange(const InputMessagePtr& msg);
void parseDeath(const InputMessagePtr& msg);
void parseMapDescription(const InputMessagePtr& msg);
void parseMapMoveNorth(const InputMessagePtr& msg);
void parseMapMoveEast(const InputMessagePtr& msg);
void parseMapMoveSouth(const InputMessagePtr& msg);
void parseMapMoveWest(const InputMessagePtr& msg);
void parseUpdateTile(const InputMessagePtr& msg);
void parseTileAddThing(const InputMessagePtr& msg);
void parseTileTransformThing(const InputMessagePtr& msg);
void parseTileRemoveThing(const InputMessagePtr& msg);
void parseCreatureMove(const InputMessagePtr& msg);
void parseOpenContainer(const InputMessagePtr& msg);
void parseCloseContainer(const InputMessagePtr& msg);
void parseContainerAddItem(const InputMessagePtr& msg);
void parseContainerUpdateItem(const InputMessagePtr& msg);
void parseContainerRemoveItem(const InputMessagePtr& msg);
void parseAddInventoryItem(const InputMessagePtr& msg);
void parseRemoveInventoryItem(const InputMessagePtr& msg);
void parseOpenNpcTrade(const InputMessagePtr& msg);
void parsePlayerGoods(const InputMessagePtr& msg);
void parseCloseNpcTrade(const InputMessagePtr&);
void parseWorldLight(const InputMessagePtr& msg);
void parseMagicEffect(const InputMessagePtr& msg);
void parseAnimatedText(const InputMessagePtr& msg);
void parseDistanceMissile(const InputMessagePtr& msg);
void parseCreatureMark(const InputMessagePtr& msg);
void parseTrappers(const InputMessagePtr& msg);
void parseCreatureHealth(const InputMessagePtr& msg);
void parseCreatureLight(const InputMessagePtr& msg);
void parseCreatureOutfit(const InputMessagePtr& msg);
void parseCreatureSpeed(const InputMessagePtr& msg);
void parseCreatureSkulls(const InputMessagePtr& msg);
void parseCreatureShields(const InputMessagePtr& msg);
void parseCreatureUnpass(const InputMessagePtr& msg);
void parseEditText(const InputMessagePtr& msg);
void parseEditList(const InputMessagePtr& msg);
void parsePlayerInfo(const InputMessagePtr& msg);
void parsePlayerStats(const InputMessagePtr& msg);
void parsePlayerSkills(const InputMessagePtr& msg);
void parsePlayerState(const InputMessagePtr& msg);
void parsePlayerCancelAttack(const InputMessagePtr& msg);
void parseSpellDelay(const InputMessagePtr& msg);
void parseSpellGroupDelay(const InputMessagePtr& msg);
void parseMultiUseDelay(const InputMessagePtr& msg);
void parseCreatureSpeak(const InputMessagePtr& msg);
void parseChannelList(const InputMessagePtr& msg);
void parseOpenChannel(const InputMessagePtr& msg);
void parseOpenPrivateChannel(const InputMessagePtr& msg);
void parseOpenOwnPrivateChannel(const InputMessagePtr& msg);
void parseCloseChannel(const InputMessagePtr& msg);
void parseRuleViolationChannel(const InputMessagePtr& msg);
void parseRuleViolationRemove(const InputMessagePtr& msg);
void parseRuleViolationCancel(const InputMessagePtr& msg);
void parseRuleViolationLock(const InputMessagePtr& msg);
void parseOwnTrade(const InputMessagePtr& msg);
void parseCounterTrade(const InputMessagePtr& msg);
void parseCloseTrade(const InputMessagePtr&);
void parseTextMessage(const InputMessagePtr& msg);
void parseCancelWalk(const InputMessagePtr& msg);
void parseWalkWait(const InputMessagePtr& msg);
void parseFloorChangeUp(const InputMessagePtr& msg);
void parseFloorChangeDown(const InputMessagePtr& msg);
void parseOpenOutfitWindow(const InputMessagePtr& msg);
void parseVipAdd(const InputMessagePtr& msg);
void parseVipLogin(const InputMessagePtr& msg);
void parseVipLogout(const InputMessagePtr& msg);
void parseTutorialHint(const InputMessagePtr& msg);
void parseAutomapFlag(const InputMessagePtr& msg);
void parseQuestLog(const InputMessagePtr& msg);
void parseQuestLine(const InputMessagePtr& msg);
void parseChannelEvent(const InputMessagePtr& msg);
void parseItemInfo(const InputMessagePtr& msg);
void parsePlayerInventory(const InputMessagePtr& msg);
void parseExtendedOpcode(const InputMessagePtr& msg);
// Parse Messages
void parseMessage(InputMessage& msg);
public:
void setMapDescription(const InputMessagePtr& msg, int x, int y, int z, int width, int height);
int setFloorDescription(const InputMessagePtr& msg, int x, int y, int z, int width, int height, int offset, int skip);
void setTileDescription(const InputMessagePtr& msg, Position position);
void parseInitGame(InputMessage& msg);
void parseGMActions(InputMessage& msg);
void parseLoginError(InputMessage& msg);
void parseLoginAdvice(InputMessage& msg);
void parseLoginWait(InputMessage& msg);
void parsePing(InputMessage& msg);
void parsePingBack(InputMessage& msg);
void parseChallange(InputMessage& msg);
void parseDeath(InputMessage& msg);
void parseMapDescription(InputMessage& msg);
void parseMapMoveNorth(InputMessage& msg);
void parseMapMoveEast(InputMessage& msg);
void parseMapMoveSouth(InputMessage& msg);
void parseMapMoveWest(InputMessage& msg);
void parseUpdateTile(InputMessage& msg);
void parseTileAddThing(InputMessage& msg);
void parseTileTransformThing(InputMessage& msg);
void parseTileRemoveThing(InputMessage& msg);
void parseCreatureMove(InputMessage& msg);
void parseOpenContainer(InputMessage& msg);
void parseCloseContainer(InputMessage& msg);
void parseContainerAddItem(InputMessage& msg);
void parseContainerUpdateItem(InputMessage& msg);
void parseContainerRemoveItem(InputMessage& msg);
void parseAddInventoryItem(InputMessage& msg);
void parseRemoveInventoryItem(InputMessage& msg);
void parseOpenNpcTrade(InputMessage& msg);
void parsePlayerGoods(InputMessage& msg);
void parseCloseNpcTrade(InputMessage&);
void parseWorldLight(InputMessage& msg);
void parseMagicEffect(InputMessage& msg);
void parseAnimatedText(InputMessage& msg);
void parseDistanceMissile(InputMessage& msg);
void parseCreatureMark(InputMessage& msg);
void parseTrappers(InputMessage& msg);
void parseCreatureHealth(InputMessage& msg);
void parseCreatureLight(InputMessage& msg);
void parseCreatureOutfit(InputMessage& msg);
void parseCreatureSpeed(InputMessage& msg);
void parseCreatureSkulls(InputMessage& msg);
void parseCreatureShields(InputMessage& msg);
void parseCreatureUnpass(InputMessage& msg);
void parseEditText(InputMessage& msg);
void parseEditList(InputMessage& msg);
void parsePlayerInfo(InputMessage& msg);
void parsePlayerStats(InputMessage& msg);
void parsePlayerSkills(InputMessage& msg);
void parsePlayerState(InputMessage& msg);
void parsePlayerCancelAttack(InputMessage& msg);
void parseSpellDelay(InputMessage& msg);
void parseSpellGroupDelay(InputMessage& msg);
void parseMultiUseDelay(InputMessage& msg);
void parseCreatureSpeak(InputMessage& msg);
void parseChannelList(InputMessage& msg);
void parseOpenChannel(InputMessage& msg);
void parseOpenPrivateChannel(InputMessage& msg);
void parseOpenOwnPrivateChannel(InputMessage& msg);
void parseCloseChannel(InputMessage& msg);
void parseRuleViolationChannel(InputMessage& msg);
void parseRuleViolationRemove(InputMessage& msg);
void parseRuleViolationCancel(InputMessage& msg);
void parseRuleViolationLock(InputMessage& msg);
void parseOwnTrade(InputMessage& msg);
void parseCounterTrade(InputMessage& msg);
void parseCloseTrade(InputMessage&);
void parseTextMessage(InputMessage& msg);
void parseCancelWalk(InputMessage& msg);
void parseWalkWait(InputMessage& msg);
void parseFloorChangeUp(InputMessage& msg);
void parseFloorChangeDown(InputMessage& msg);
void parseOpenOutfitWindow(InputMessage& msg);
void parseVipAdd(InputMessage& msg);
void parseVipLogin(InputMessage& msg);
void parseVipLogout(InputMessage& msg);
void parseTutorialHint(InputMessage& msg);
void parseAutomapFlag(InputMessage& msg);
void parseQuestLog(InputMessage& msg);
void parseQuestLine(InputMessage& msg);
void parseChannelEvent(InputMessage& msg);
void parseItemInfo(InputMessage& msg);
void parsePlayerInventory(InputMessage& msg);
void parseExtendedOpcode(InputMessage& msg);
void setMapDescription(InputMessage& msg, int x, int y, int z, int width, int height);
void setFloorDescription(InputMessage& msg, int x, int y, int z, int width, int height, int offset, int* skipTiles);
void setTileDescription(InputMessage& msg, Position position);
Outfit internalGetOutfit(InputMessage& msg);
CreaturePtr internalGetCreature(InputMessage& msg, int type = 0);
ThingPtr internalGetThing(InputMessage& msg);
ItemPtr internalGetItem(InputMessage& msg, int id = 0);
void addPosition(OutputMessage& msg, const Position& position);
Position parsePosition(InputMessage& msg);
Outfit getOutfit(const InputMessagePtr& msg);
ThingPtr getThing(const InputMessagePtr& msg);
CreaturePtr getCreature(const InputMessagePtr& msg, int type = 0);
ItemPtr getItem(const InputMessagePtr& msg, int id = 0);
Position getPosition(const InputMessagePtr& msg);
private:
Boolean<false> m_gameInitialized;

File diff suppressed because it is too large Load Diff

View File

@ -21,68 +21,72 @@
*/
#include "protocolgame.h"
#include <framework/net/rsa.h>
#include <otclient/core/game.h>
void ProtocolGame::send(const OutputMessagePtr& outputMessage)
{
// avoid usage of automated sends (bot modules)
if(!g_game.checkBotProtection())
return;
Protocol::send(outputMessage);
}
void ProtocolGame::sendExtendedOpcode(uint8 opcode, const std::string& buffer)
{
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientExtendedOpcode);
msg->addU8(opcode);
msg->addString(buffer);
send(msg);
}
/*
ClientEquipObject
ClientRefreshContainer
ClientMount
ClientRuleViolationReport
ClientGetItemInfo
ClientMarketLeave
ClientMarketBrowse
ClientMarketCreate
ClientMarketCancel
ClientMarketAccept
ClientExtendedOpcode = 254 // otclient only
*/
void ProtocolGame::sendLoginPacket(uint challangeTimestamp, uint8 challangeRandom)
{
OutputMessage msg;
OutputMessagePtr msg(new OutputMessage);
msg.addU8(Proto::ClientEnterGame);
msg.addU16(Proto::ClientOs);
msg.addU16(Proto::ClientVersion);
msg->addU8(Proto::ClientEnterGame);
msg->addU16(Proto::ClientOs);
msg->addU16(Proto::ClientVersion);
int paddingBytes = 128;
msg.addU8(0); // first RSA byte must be 0
msg->addU8(0); // first RSA byte must be 0
paddingBytes -= 1;
// xtea key
generateXteaKey();
msg.addU32(m_xteaKey[0]);
msg.addU32(m_xteaKey[1]);
msg.addU32(m_xteaKey[2]);
msg.addU32(m_xteaKey[3]);
msg.addU8(0); // is gm set?
msg->addU32(m_xteaKey[0]);
msg->addU32(m_xteaKey[1]);
msg->addU32(m_xteaKey[2]);
msg->addU32(m_xteaKey[3]);
msg->addU8(0); // is gm set?
paddingBytes -= 17;
#if PROTOCOL>=854
enableChecksum();
msg.addString(m_accountName);
msg->addString(m_accountName);
paddingBytes -= 2 + m_accountName.length();
msg.addString(m_characterName);
msg->addString(m_characterName);
paddingBytes -= 2 + m_characterName.length();
msg.addString(m_accountPassword);
msg->addString(m_accountPassword);
paddingBytes -= 2 + m_accountPassword.length();
msg.addU32(challangeTimestamp);
msg.addU8(challangeRandom);
msg->addU32(challangeTimestamp);
msg->addU8(challangeRandom);
paddingBytes -= 5;
#else // PROTOCOL>=810
msg.addU32(Fw::fromstring<uint32>(m_accountName));
msg.addString(m_characterName);
msg.addString(m_accountPassword);
msg->addU32(Fw::fromstring<uint32>(m_accountName));
msg->addString(m_characterName);
msg->addString(m_accountPassword);
paddingBytes -= 8 + m_characterName.length() + m_accountPassword.length();
#endif
// complete the 128 bytes for rsa encryption with zeros
msg.addPaddingBytes(paddingBytes);
msg->addPaddingBytes(paddingBytes);
// encrypt with RSA
Rsa::encrypt((char*)msg.getWriteBuffer() - 128, 128, Proto::RSA);
msg->encryptRSA(128, Proto::RSA);
send(msg);
@ -91,30 +95,30 @@ void ProtocolGame::sendLoginPacket(uint challangeTimestamp, uint8 challangeRando
void ProtocolGame::sendLogout()
{
OutputMessage msg;
msg.addU8(Proto::ClientLeaveGame);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientLeaveGame);
send(msg);
}
void ProtocolGame::sendPing()
{
OutputMessage msg;
msg.addU8(Proto::ClientPing);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientPing);
send(msg);
}
void ProtocolGame::sendPingBack()
{
OutputMessage msg;
msg.addU8(Proto::ClientPingBack);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientPingBack);
send(msg);
}
void ProtocolGame::sendAutoWalk(const std::vector<Otc::Direction>& path)
{
OutputMessage msg;
msg.addU8(Proto::ClientAutoWalk);
msg.addU8(path.size());
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientAutoWalk);
msg->addU8(path.size());
for(Otc::Direction dir : path) {
uint8 byte;
switch(dir) {
@ -146,283 +150,283 @@ void ProtocolGame::sendAutoWalk(const std::vector<Otc::Direction>& path)
byte = 0;
break;
}
msg.addU8(byte);
msg->addU8(byte);
}
send(msg);
}
void ProtocolGame::sendWalkNorth()
{
OutputMessage msg;
msg.addU8(Proto::ClientWalkNorth);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientWalkNorth);
send(msg);
}
void ProtocolGame::sendWalkEast()
{
OutputMessage msg;
msg.addU8(Proto::ClientWalkEast);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientWalkEast);
send(msg);
}
void ProtocolGame::sendWalkSouth()
{
OutputMessage msg;
msg.addU8(Proto::ClientWalkSouth);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientWalkSouth);
send(msg);
}
void ProtocolGame::sendWalkWest()
{
OutputMessage msg;
msg.addU8(Proto::ClientWalkWest);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientWalkWest);
send(msg);
}
void ProtocolGame::sendStop()
{
OutputMessage msg;
msg.addU8(Proto::ClientStop);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientStop);
send(msg);
}
void ProtocolGame::sendWalkNorthEast()
{
OutputMessage msg;
msg.addU8(Proto::ClientWalkNorthEast);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientWalkNorthEast);
send(msg);
}
void ProtocolGame::sendWalkSouthEast()
{
OutputMessage msg;
msg.addU8(Proto::ClientWalkSouthEast);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientWalkSouthEast);
send(msg);
}
void ProtocolGame::sendWalkSouthWest()
{
OutputMessage msg;
msg.addU8(Proto::ClientWalkSouthWest);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientWalkSouthWest);
send(msg);
}
void ProtocolGame::sendWalkNorthWest()
{
OutputMessage msg;
msg.addU8(Proto::ClientWalkNorthWest);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientWalkNorthWest);
send(msg);
}
void ProtocolGame::sendTurnNorth()
{
OutputMessage msg;
msg.addU8(Proto::ClientTurnNorth);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientTurnNorth);
send(msg);
}
void ProtocolGame::sendTurnEast()
{
OutputMessage msg;
msg.addU8(Proto::ClientTurnEast);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientTurnEast);
send(msg);
}
void ProtocolGame::sendTurnSouth()
{
OutputMessage msg;
msg.addU8(Proto::ClientTurnSouth);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientTurnSouth);
send(msg);
}
void ProtocolGame::sendTurnWest()
{
OutputMessage msg;
msg.addU8(Proto::ClientTurnWest);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientTurnWest);
send(msg);
}
void ProtocolGame::sendEquipItem(int itemId, int countOrSubType)
{
OutputMessage msg;
msg.addU8(Proto::ClientEquipItem);
msg.addU16(itemId);
msg.addU8(countOrSubType);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientEquipItem);
msg->addU16(itemId);
msg->addU8(countOrSubType);
send(msg);
}
void ProtocolGame::sendMove(const Position& fromPos, int thingId, int stackpos, const Position& toPos, int count)
{
OutputMessage msg;
msg.addU8(Proto::ClientMove);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientMove);
addPosition(msg, fromPos);
msg.addU16(thingId);
msg.addU8(stackpos);
msg->addU16(thingId);
msg->addU8(stackpos);
addPosition(msg, toPos);
msg.addU8(count);
msg->addU8(count);
send(msg);
}
void ProtocolGame::sendInspectNpcTrade(int itemId, int count)
{
OutputMessage msg;
msg.addU8(Proto::ClientInspectNpcTrade);
msg.addU16(itemId);
msg.addU8(count);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientInspectNpcTrade);
msg->addU16(itemId);
msg->addU8(count);
send(msg);
}
void ProtocolGame::sendBuyItem(int itemId, int subType, int amount, bool ignoreCapacity, bool buyWithBackpack)
{
OutputMessage msg;
msg.addU8(Proto::ClientBuyItem);
msg.addU16(itemId);
msg.addU8(subType);
msg.addU8(amount);
msg.addU8(ignoreCapacity ? 0x01 : 0x00);
msg.addU8(buyWithBackpack ? 0x01 : 0x00);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientBuyItem);
msg->addU16(itemId);
msg->addU8(subType);
msg->addU8(amount);
msg->addU8(ignoreCapacity ? 0x01 : 0x00);
msg->addU8(buyWithBackpack ? 0x01 : 0x00);
send(msg);
}
void ProtocolGame::sendSellItem(int itemId, int subType, int amount, bool ignoreEquipped)
{
OutputMessage msg;
msg.addU8(Proto::ClientSellItem);
msg.addU16(itemId);
msg.addU8(subType);
msg.addU8(amount);
msg.addU8(ignoreEquipped ? 0x01 : 0x00);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientSellItem);
msg->addU16(itemId);
msg->addU8(subType);
msg->addU8(amount);
msg->addU8(ignoreEquipped ? 0x01 : 0x00);
send(msg);
}
void ProtocolGame::sendCloseNpcTrade()
{
OutputMessage msg;
msg.addU8(Proto::ClientCloseNpcTrade);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientCloseNpcTrade);
send(msg);
}
void ProtocolGame::sendRequestTrade(const Position& pos, int thingId, int stackpos, uint creatureId)
{
OutputMessage msg;
msg.addU8(Proto::ClientRequestTrade);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientRequestTrade);
addPosition(msg, pos);
msg.addU16(thingId);
msg.addU8(stackpos);
msg.addU32(creatureId);
msg->addU16(thingId);
msg->addU8(stackpos);
msg->addU32(creatureId);
send(msg);
}
void ProtocolGame::sendInspectTrade(bool counterOffer, int index)
{
OutputMessage msg;
msg.addU8(Proto::ClientInspectTrade);
msg.addU8(counterOffer ? 0x01 : 0x00);
msg.addU8(index);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientInspectTrade);
msg->addU8(counterOffer ? 0x01 : 0x00);
msg->addU8(index);
send(msg);
}
void ProtocolGame::sendAcceptTrade()
{
OutputMessage msg;
msg.addU8(Proto::ClientAcceptTrade);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientAcceptTrade);
send(msg);
}
void ProtocolGame::sendRejectTrade()
{
OutputMessage msg;
msg.addU8(Proto::ClientRejectTrade);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientRejectTrade);
send(msg);
}
void ProtocolGame::sendUseItem(const Position& position, int itemId, int stackpos, int index)
{
OutputMessage msg;
msg.addU8(Proto::ClientUseItem);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientUseItem);
addPosition(msg, position);
msg.addU16(itemId);
msg.addU8(stackpos);
msg.addU8(index);
msg->addU16(itemId);
msg->addU8(stackpos);
msg->addU8(index);
send(msg);
}
void ProtocolGame::sendUseItemWith(const Position& fromPos, int itemId, int fromStackpos, const Position& toPos, int toThingId, int toStackpos)
{
OutputMessage msg;
msg.addU8(Proto::ClientUseItemWith);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientUseItemWith);
addPosition(msg, fromPos);
msg.addU16(itemId);
msg.addU8(fromStackpos);
msg->addU16(itemId);
msg->addU8(fromStackpos);
addPosition(msg, toPos);
msg.addU16(toThingId);
msg.addU8(toStackpos);
msg->addU16(toThingId);
msg->addU8(toStackpos);
send(msg);
}
void ProtocolGame::sendUseOnCreature(const Position& pos, int thingId, int stackpos, uint creatureId)
{
OutputMessage msg;
msg.addU8(Proto::ClientUseOnCreature);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientUseOnCreature);
addPosition(msg, pos);
msg.addU16(thingId);
msg.addU8(stackpos);
msg.addU32(creatureId);
msg->addU16(thingId);
msg->addU8(stackpos);
msg->addU32(creatureId);
send(msg);
}
void ProtocolGame::sendRotateItem(const Position& pos, int thingId, int stackpos)
{
OutputMessage msg;
msg.addU8(Proto::ClientRotateItem);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientRotateItem);
addPosition(msg, pos);
msg.addU16(thingId);
msg.addU8(stackpos);
msg->addU16(thingId);
msg->addU8(stackpos);
send(msg);
}
void ProtocolGame::sendCloseContainer(int containerId)
{
OutputMessage msg;
msg.addU8(Proto::ClientCloseContainer);
msg.addU8(containerId);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientCloseContainer);
msg->addU8(containerId);
send(msg);
}
void ProtocolGame::sendUpContainer(int containerId)
{
OutputMessage msg;
msg.addU8(Proto::ClientUpContainer);
msg.addU8(containerId);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientUpContainer);
msg->addU8(containerId);
send(msg);
}
void ProtocolGame::sendEditText(uint id, const std::string& text)
{
OutputMessage msg;
msg.addU8(Proto::ClientEditText);
msg.addU32(id);
msg.addString(text);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientEditText);
msg->addU32(id);
msg->addString(text);
send(msg);
}
void ProtocolGame::sendEditList(uint id, int doorId, const std::string& text)
{
OutputMessage msg;
msg.addU8(Proto::ClientEditList);
msg.addU8(doorId);
msg.addU32(id);
msg.addString(text);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientEditList);
msg->addU8(doorId);
msg->addU32(id);
msg->addString(text);
send(msg);
}
void ProtocolGame::sendLook(const Position& position, int thingId, int stackpos)
{
OutputMessage msg;
msg.addU8(Proto::ClientLook);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientLook);
addPosition(msg, position);
msg.addU16(thingId);
msg.addU8(stackpos);
msg->addU16(thingId);
msg->addU8(stackpos);
send(msg);
}
@ -433,304 +437,295 @@ void ProtocolGame::sendTalk(Otc::SpeakType speakType, int channelId, const std::
int serverSpeakType = Proto::translateSpeakTypeToServer(speakType);
OutputMessage msg;
msg.addU8(Proto::ClientTalk);
msg.addU8(serverSpeakType);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientTalk);
msg->addU8(serverSpeakType);
switch(serverSpeakType) {
case Proto::ServerSpeakPrivateFrom:
case Proto::ServerSpeakPrivateRedFrom:
msg.addString(receiver);
msg->addString(receiver);
break;
case Proto::ServerSpeakChannelYellow:
case Proto::ServerSpeakChannelRed:
msg.addU16(channelId);
msg->addU16(channelId);
break;
}
msg.addString(message);
msg->addString(message);
send(msg);
}
void ProtocolGame::sendRequestChannels()
{
OutputMessage msg;
msg.addU8(Proto::ClientRequestChannels);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientRequestChannels);
send(msg);
}
void ProtocolGame::sendJoinChannel(int channelId)
{
OutputMessage msg;
msg.addU8(Proto::ClientJoinChannel);
msg.addU16(channelId);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientJoinChannel);
msg->addU16(channelId);
send(msg);
}
void ProtocolGame::sendLeaveChannel(int channelId)
{
OutputMessage msg;
msg.addU8(Proto::ClientLeaveChannel);
msg.addU16(channelId);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientLeaveChannel);
msg->addU16(channelId);
send(msg);
}
void ProtocolGame::sendOpenPrivateChannel(const std::string& receiver)
{
OutputMessage msg;
msg.addU8(Proto::ClientOpenPrivateChannel);
msg.addString(receiver);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientOpenPrivateChannel);
msg->addString(receiver);
send(msg);
}
void ProtocolGame::sendCloseNpcChannel()
{
OutputMessage msg;
msg.addU8(Proto::ClientCloseNpcChannel);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientCloseNpcChannel);
send(msg);
}
void ProtocolGame::sendChangeFightModes(Otc::FightModes fightMode, Otc::ChaseModes chaseMode, bool safeFight)
{
OutputMessage msg;
msg.addU8(Proto::ClientChangeFightModes);
msg.addU8(fightMode);
msg.addU8(chaseMode);
msg.addU8(safeFight ? 0x01: 0x00);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientChangeFightModes);
msg->addU8(fightMode);
msg->addU8(chaseMode);
msg->addU8(safeFight ? 0x01: 0x00);
send(msg);
}
void ProtocolGame::sendAttack(uint creatureId)
{
OutputMessage msg;
msg.addU8(Proto::ClientAttack);
msg.addU32(creatureId);
msg.addU32(0);
msg.addU32(0);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientAttack);
msg->addU32(creatureId);
msg->addU32(0);
msg->addU32(0);
send(msg);
}
void ProtocolGame::sendFollow(uint creatureId)
{
OutputMessage msg;
msg.addU8(Proto::ClientFollow);
msg.addU32(creatureId);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientFollow);
msg->addU32(creatureId);
send(msg);
}
void ProtocolGame::sendInviteToParty(uint creatureId)
{
OutputMessage msg;
msg.addU8(Proto::ClientInviteToParty);
msg.addU32(creatureId);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientInviteToParty);
msg->addU32(creatureId);
send(msg);
}
void ProtocolGame::sendJoinParty(uint creatureId)
{
OutputMessage msg;
msg.addU8(Proto::ClientJoinParty);
msg.addU32(creatureId);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientJoinParty);
msg->addU32(creatureId);
send(msg);
}
void ProtocolGame::sendRevokeInvitation(uint creatureId)
{
OutputMessage msg;
msg.addU8(Proto::ClientRevokeInvitation);
msg.addU32(creatureId);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientRevokeInvitation);
msg->addU32(creatureId);
send(msg);
}
void ProtocolGame::sendPassLeadership(uint creatureId)
{
OutputMessage msg;
msg.addU8(Proto::ClientPassLeadership);
msg.addU32(creatureId);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientPassLeadership);
msg->addU32(creatureId);
send(msg);
}
void ProtocolGame::sendLeaveParty()
{
OutputMessage msg;
msg.addU8(Proto::ClientLeaveParty);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientLeaveParty);
send(msg);
}
void ProtocolGame::sendShareExperience(bool active, int unknown)
{
OutputMessage msg;
msg.addU8(Proto::ClientShareExperience);
msg.addU8(active ? 0x01 : 0x00);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientShareExperience);
msg->addU8(active ? 0x01 : 0x00);
#if PROTOCOL<910
msg.addU8(unknown);
msg->addU8(unknown);
#endif
send(msg);
}
void ProtocolGame::sendOpenOwnChannel()
{
OutputMessage msg;
msg.addU8(Proto::ClientOpenOwnChannel);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientOpenOwnChannel);
send(msg);
}
void ProtocolGame::sendInviteToOwnChannel(const std::string& name)
{
OutputMessage msg;
msg.addU8(Proto::ClientInviteToOwnChannel);
msg.addString(name);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientInviteToOwnChannel);
msg->addString(name);
send(msg);
}
void ProtocolGame::sendExcludeFromOwnChannel(const std::string& name)
{
OutputMessage msg;
msg.addU8(Proto::ClientExcludeFromOwnChannel);
msg.addString(name);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientExcludeFromOwnChannel);
msg->addString(name);
send(msg);
}
void ProtocolGame::sendCancelAttackAndFollow()
{
OutputMessage msg;
msg.addU8(Proto::ClientCancelAttackAndFollow);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientCancelAttackAndFollow);
send(msg);
}
void ProtocolGame::sendRefreshContainer()
{
OutputMessage msg;
msg.addU8(Proto::ClientRefreshContainer);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientRefreshContainer);
send(msg);
}
void ProtocolGame::sendRequestOutfit()
{
OutputMessage msg;
msg.addU8(Proto::ClientRequestOutfit);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientRequestOutfit);
send(msg);
}
void ProtocolGame::sendChangeOutfit(const Outfit& outfit)
{
OutputMessage msg;
msg.addU8(Proto::ClientChangeOutfit);
msg.addU16(outfit.getId());
msg.addU8(outfit.getHead());
msg.addU8(outfit.getBody());
msg.addU8(outfit.getLegs());
msg.addU8(outfit.getFeet());
msg.addU8(outfit.getAddons());
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientChangeOutfit);
msg->addU16(outfit.getId());
msg->addU8(outfit.getHead());
msg->addU8(outfit.getBody());
msg->addU8(outfit.getLegs());
msg->addU8(outfit.getFeet());
msg->addU8(outfit.getAddons());
send(msg);
}
void ProtocolGame::sendMount(bool mount)
{
OutputMessage msg;
msg.addU8(Proto::ClientMount);
msg.addU8(mount);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientMount);
msg->addU8(mount);
send(msg);
}
void ProtocolGame::sendAddVip(const std::string& name)
{
OutputMessage msg;
msg.addU8(Proto::ClientAddVip);
msg.addString(name);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientAddVip);
msg->addString(name);
send(msg);
}
void ProtocolGame::sendRemoveVip(uint playerId)
{
OutputMessage msg;
msg.addU8(Proto::ClientRemoveVip);
msg.addU32(playerId);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientRemoveVip);
msg->addU32(playerId);
send(msg);
}
void ProtocolGame::sendBugReport(const std::string& comment)
{
OutputMessage msg;
msg.addU8(Proto::ClientBugReport);
msg.addString(comment);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientBugReport);
msg->addString(comment);
send(msg);
}
void ProtocolGame::sendRuleVilation(const std::string& target, int reason, int action, const std::string& comment, const std::string& statement, int statementId, bool ipBanishment)
{
OutputMessage msg;
msg.addU8(Proto::ClientRuleViolation);
msg.addString(target);
msg.addU8(reason);
msg.addU8(action);
msg.addString(comment);
msg.addString(statement);
msg.addU16(statementId);
msg.addU8(ipBanishment);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientRuleViolation);
msg->addString(target);
msg->addU8(reason);
msg->addU8(action);
msg->addString(comment);
msg->addString(statement);
msg->addU16(statementId);
msg->addU8(ipBanishment);
send(msg);
}
void ProtocolGame::sendDebugReport(const std::string& a, const std::string& b, const std::string& c, const std::string& d)
{
OutputMessage msg;
msg.addU8(Proto::ClientDebugReport);
msg.addString(a);
msg.addString(b);
msg.addString(c);
msg.addString(d);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientDebugReport);
msg->addString(a);
msg->addString(b);
msg->addString(c);
msg->addString(d);
send(msg);
}
void ProtocolGame::sendRequestQuestLog()
{
OutputMessage msg;
msg.addU8(Proto::ClientRequestQuestLog);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientRequestQuestLog);
send(msg);
}
void ProtocolGame::sendRequestQuestLine(int questId)
{
OutputMessage msg;
msg.addU8(Proto::ClientRequestQuestLine);
msg.addU16(questId);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientRequestQuestLine);
msg->addU16(questId);
send(msg);
}
void ProtocolGame::sendNewNewRuleViolation(int reason, int action, const std::string& characterName, const std::string& comment, const std::string& translation)
{
OutputMessage msg;
msg.addU8(Proto::ClientNewRuleViolation);
msg.addU8(reason);
msg.addU8(action);
msg.addString(characterName);
msg.addString(comment);
msg.addString(translation);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientNewRuleViolation);
msg->addU8(reason);
msg->addU8(action);
msg->addString(characterName);
msg->addString(comment);
msg->addString(translation);
send(msg);
}
void ProtocolGame::sendRequestItemInfo(int itemId, int index)
{
OutputMessage msg;
msg.addU8(Proto::ClientRequestItemInfo);
msg.addU8(1); // count, 1 for just one item
msg.addU16(itemId);
msg.addU8(index);
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientRequestItemInfo);
msg->addU8(1); // count, 1 for just one item
msg->addU16(itemId);
msg->addU8(index);
send(msg);
}
void ProtocolGame::sendExtendedOpcode(uint8 opcode, const std::string& buffer)
void ProtocolGame::addPosition(const OutputMessagePtr& msg, const Position& position)
{
OutputMessage msg;
msg.addU8(Proto::ClientExtendedOpcode);
msg.addU8(opcode);
msg.addString(buffer);
send(msg);
}
void ProtocolGame::addPosition(OutputMessage& msg, const Position& position)
{
msg.addU16(position.x);
msg.addU16(position.y);
msg.addU8(position.z);
msg->addU16(position.x);
msg->addU16(position.y);
msg->addU8(position.z);
}

View File

@ -22,7 +22,6 @@
#include "protocollogin.h"
#include <framework/net/outputmessage.h>
#include <framework/net/rsa.h>
#include <framework/luascript/luainterface.h>
#include <boost/bind.hpp>
#include <otclient/core/thingstype.h>
@ -46,23 +45,23 @@ void ProtocolLogin::onConnect()
sendLoginPacket();
}
void ProtocolLogin::onRecv(InputMessage& inputMessage)
void ProtocolLogin::onRecv(const InputMessagePtr& msg)
{
try {
while(!inputMessage.eof()) {
int opcode = inputMessage.getU8();
while(!msg->eof()) {
int opcode = msg->getU8();
switch(opcode) {
case Proto::LoginServerError:
parseError(inputMessage);
parseError(msg);
break;
case Proto::LoginServerMotd:
parseMOTD(inputMessage);
parseMOTD(msg);
break;
case Proto::LoginServerUpdateNeeded:
callLuaField("onError", "Client needs update.");
break;
case Proto::LoginServerCharacterList:
parseCharacterList(inputMessage);
parseCharacterList(msg);
break;
default:
Fw::throwException("unknown opt byte ", opcode);
@ -83,76 +82,76 @@ void ProtocolLogin::onError(const boost::system::error_code& error)
void ProtocolLogin::sendLoginPacket()
{
OutputMessage msg;
OutputMessagePtr msg(new OutputMessage);
msg.addU8(Proto::ClientEnterAccount);
msg.addU16(Proto::ClientOs);
msg.addU16(Proto::ClientVersion);
msg->addU8(Proto::ClientEnterAccount);
msg->addU16(Proto::ClientOs);
msg->addU16(Proto::ClientVersion);
msg.addU32(g_thingsType.getSignature()); // data signature
msg.addU32(g_sprites.getSignature()); // sprite signature
msg.addU32(Proto::PicSignature); // pic signature
msg->addU32(g_thingsType.getSignature()); // data signature
msg->addU32(g_sprites.getSignature()); // sprite signature
msg->addU32(Proto::PicSignature); // pic signature
int paddingBytes = 128;
msg.addU8(0); // first RSA byte must be 0
msg->addU8(0); // first RSA byte must be 0
paddingBytes -= 1;
// xtea key
generateXteaKey();
msg.addU32(m_xteaKey[0]);
msg.addU32(m_xteaKey[1]);
msg.addU32(m_xteaKey[2]);
msg.addU32(m_xteaKey[3]);
msg->addU32(m_xteaKey[0]);
msg->addU32(m_xteaKey[1]);
msg->addU32(m_xteaKey[2]);
msg->addU32(m_xteaKey[3]);
paddingBytes -= 16;
#if PROTOCOL>=854
enableChecksum();
msg.addString(m_accountName);
msg.addString(m_accountPassword);
msg->addString(m_accountName);
msg->addString(m_accountPassword);
paddingBytes -= 4 + m_accountName.length() + m_accountPassword.length();
#elif PROTOCOL>=810
msg.addU32(Fw::fromstring<uint32>(m_accountName));
msg.addString(m_accountPassword);
msg->addU32(Fw::fromstring<uint32>(m_accountName));
msg->addString(m_accountPassword);
paddingBytes -= 6 + m_accountPassword.length();
#endif
msg.addPaddingBytes(paddingBytes); // complete the 128 bytes for rsa encryption with zeros
Rsa::encrypt((char*)msg.getWriteBuffer() - 128, 128, Proto::RSA);
msg->addPaddingBytes(paddingBytes); // complete the 128 bytes for rsa encryption with zeros
msg->encryptRSA(128, Proto::RSA);
send(msg);
enableXteaEncryption();
recv();
}
void ProtocolLogin::parseError(InputMessage& inputMessage)
void ProtocolLogin::parseError(const InputMessagePtr& msg)
{
std::string error = inputMessage.getString();
std::string error = msg->getString();
callLuaField("onError", error, false);
}
void ProtocolLogin::parseMOTD(InputMessage& inputMessage)
void ProtocolLogin::parseMOTD(const InputMessagePtr& msg)
{
std::string motd = inputMessage.getString();
std::string motd = msg->getString();
callLuaField("onMotd", motd);
}
void ProtocolLogin::parseCharacterList(InputMessage& inputMessage)
void ProtocolLogin::parseCharacterList(const InputMessagePtr& msg)
{
typedef std::tuple<std::string, std::string, std::string, int> CharacterInfo;
typedef std::vector<CharacterInfo> CharaterList;
CharaterList charList;
int numCharacters = inputMessage.getU8();
int numCharacters = msg->getU8();
for(int i = 0; i < numCharacters; ++i) {
std::string name = inputMessage.getString();
std::string world = inputMessage.getString();
uint32 ip = inputMessage.getU32();
uint16 port = inputMessage.getU16();
std::string name = msg->getString();
std::string world = msg->getString();
uint32 ip = msg->getU32();
uint16 port = msg->getU16();
charList.push_back(CharacterInfo(name, world, Fw::ip2str(ip), port));
}
int premDays = inputMessage.getU16();
int premDays = msg->getU16();
callLuaField("onCharacterList", charList, premDays);
}

View File

@ -38,7 +38,7 @@ public:
void cancelLogin() { disconnect(); }
void onConnect();
void onRecv(InputMessage& inputMessage);
void onRecv(const InputMessagePtr& inputMessage);
void onError(const boost::system::error_code& error);
ProtocolLoginPtr asProtocolLogin() { return std::static_pointer_cast<ProtocolLogin>(shared_from_this()); }
@ -46,9 +46,9 @@ public:
private:
void sendLoginPacket();
void parseError(InputMessage& inputMessage);
void parseMOTD(InputMessage& inputMessage);
void parseCharacterList(InputMessage& inputMessage);
void parseError(const InputMessagePtr& inputMessage);
void parseMOTD(const InputMessagePtr& inputMessage);
void parseCharacterList(const InputMessagePtr& inputMessage);
std::string m_accountName, m_accountPassword;