basic protocol 953 support, logging in real tibia!
This commit is contained in:
parent
abbd15b1c2
commit
fa9c942471
4
BUGS
4
BUGS
|
@ -2,6 +2,7 @@
|
|||
modules recursivity makes client crash, it should generate a warning
|
||||
|
||||
== P1 BUGS (affects game play)
|
||||
in some situations creatures may disappears while walking
|
||||
sometimes minimap desync Z pos
|
||||
follow and autowalk doesn't cancel when walking via hotkeys
|
||||
when reading invalid spr/dat the client crashs
|
||||
|
@ -27,5 +28,4 @@ hotkeys works while windows are locked, it shouldn't
|
|||
skulls is rendering outside map bounds
|
||||
party options does not work when re-logging inside a party
|
||||
sometimes we can still view hits from above/bottom floors from a fight that is not visible
|
||||
must removeThing in protocol parseTileAdd when stackpos is greater than 11
|
||||
|
||||
scroll does not follow characerlist selection when changing focus with up/down arrows
|
||||
|
|
|
@ -38,7 +38,7 @@ local function onContainerOpen(container, previousContainer)
|
|||
name = name:sub(1,1):upper() .. name:sub(2)
|
||||
containerWindow:setText(name)
|
||||
|
||||
containerItemWidget:setItemId(container:getItemId())
|
||||
containerItemWidget:setItem(container:getContainerItem())
|
||||
|
||||
containerPanel:destroyChildren()
|
||||
for slot=0,container:getCapacity()-1 do
|
||||
|
|
|
@ -223,6 +223,32 @@ uint64 FileStream::getU64()
|
|||
return v;
|
||||
}
|
||||
|
||||
std::string FileStream::getString()
|
||||
{
|
||||
std::string str;
|
||||
int len = getU16();
|
||||
if(len > 0 && len < 8192) {
|
||||
char buffer[8192];
|
||||
if(m_fileHandle) {
|
||||
if(PHYSFS_read(m_fileHandle, buffer, 1, len) == 0)
|
||||
logTraceError("operation failed on '", m_name, "': ", PHYSFS_getLastError());
|
||||
else
|
||||
str = std::string(buffer, len);
|
||||
} else {
|
||||
if(m_cacheReadPos+len > m_cacheBuffer.size()) {
|
||||
logTraceError("operation failed on '", m_name, "': reached file eof");
|
||||
return 0;
|
||||
}
|
||||
|
||||
str = std::string((char*)&m_cacheBuffer[m_cacheReadPos], len);
|
||||
m_cacheReadPos += len;
|
||||
}
|
||||
} else {
|
||||
logTraceError("operation failed on '", m_name, "': ", PHYSFS_getLastError());
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
void FileStream::addU8(uint8 v)
|
||||
{
|
||||
if(PHYSFS_write(m_fileHandle, &v, 1, 1) != 1)
|
||||
|
|
|
@ -53,6 +53,7 @@ public:
|
|||
uint16 getU16();
|
||||
uint32 getU32();
|
||||
uint64 getU64();
|
||||
std::string getString();
|
||||
void addU8(uint8 v);
|
||||
void addU16(uint8 v);
|
||||
void addU32(uint8 v);
|
||||
|
|
|
@ -124,10 +124,18 @@ void Protocol::internalRecvData(uint8* buffer, uint16 size)
|
|||
return;
|
||||
}
|
||||
|
||||
if(m_xteaEncryptionEnabled && !xteaDecrypt(m_inputMessage)) {
|
||||
if(m_xteaEncryptionEnabled) {
|
||||
if(!xteaDecrypt(m_inputMessage)) {
|
||||
logTraceError("failed to decrypt message");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
int size = m_inputMessage.getU16();
|
||||
if(size != m_inputMessage.getUnreadSize()) {
|
||||
logTraceError("invalid message size");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
onRecv(m_inputMessage);
|
||||
}
|
||||
|
|
|
@ -6,9 +6,14 @@ ENDIF(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 6)
|
|||
# otclient options
|
||||
OPTION(BOT_PROTECTION "Enable bot protection" ON)
|
||||
SET(PROTOCOL 860 CACHE "Protocol version" STRING)
|
||||
SET(CIPSOFT_RSA "Use cipsoft RSA to login into original tibia" OFF)
|
||||
ADD_DEFINITIONS(-DPROTOCOL=${PROTOCOL})
|
||||
MESSAGE(STATUS "Protocol: " ${PROTOCOL})
|
||||
|
||||
IF(CIPSOFT_RSA)
|
||||
ADD_DEFINITIONS(-DCIPSOFT_RSA)
|
||||
ENDIF()
|
||||
|
||||
IF(BOT_PROTECTION)
|
||||
ADD_DEFINITIONS(-DBOT_PROTECTION)
|
||||
MESSAGE(STATUS "Bot protection: ON")
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
Container::Container()
|
||||
{
|
||||
m_id = -1;
|
||||
m_itemId = 0;
|
||||
m_capacity = 20;
|
||||
m_name = "Container";
|
||||
m_hasParent = false;
|
||||
|
|
|
@ -46,14 +46,14 @@ public:
|
|||
void setId(int id) { m_id = id; }
|
||||
void setCapacity(int capacity) { m_capacity = capacity; }
|
||||
void setName(std::string name) { m_name = name; }
|
||||
void setItemId(uint16 itemId) { m_itemId = itemId; }
|
||||
void setContainerItem(const ItemPtr& containerItem) { m_containerItem = containerItem; }
|
||||
void setHasParent(bool hasParent) { m_hasParent = hasParent; }
|
||||
|
||||
std::string getName() { return m_name; }
|
||||
int getId() { return m_id; }
|
||||
int getCapacity() { return m_capacity; }
|
||||
int getItemsCount() { return m_items.size(); }
|
||||
uint16 getItemId() { return m_itemId; }
|
||||
ItemPtr getContainerItem() { return m_containerItem; }
|
||||
bool hasParent() { return m_hasParent; }
|
||||
|
||||
private:
|
||||
|
@ -61,7 +61,7 @@ private:
|
|||
|
||||
int m_id;
|
||||
int m_capacity;
|
||||
uint16 m_itemId;
|
||||
ItemPtr m_containerItem;
|
||||
std::string m_name;
|
||||
bool m_hasParent;
|
||||
std::deque<ItemPtr> m_items;
|
||||
|
|
|
@ -163,14 +163,14 @@ void Game::processCreatureSpeak(const std::string& name, int level, Otc::SpeakTy
|
|||
g_lua.callGlobalField("g_game", "onCreatureSpeak", name, level, type, message, channelId, creaturePos);
|
||||
}
|
||||
|
||||
void Game::processOpenContainer(int containerId, int itemId, const std::string& name, int capacity, bool hasParent, const std::vector<ItemPtr>& items)
|
||||
void Game::processOpenContainer(int containerId, const ItemPtr& containerItem, const std::string& name, int capacity, bool hasParent, const std::vector<ItemPtr>& items)
|
||||
{
|
||||
ContainerPtr previousContainer = getContainer(containerId);
|
||||
ContainerPtr container = ContainerPtr(new Container());
|
||||
container->setId(containerId);
|
||||
container->setCapacity(capacity);
|
||||
container->setName(name);
|
||||
container->setItemId(itemId);
|
||||
container->setContainerItem(containerItem);
|
||||
container->setHasParent(hasParent);
|
||||
m_containers[containerId] = container;
|
||||
container->addItems(items);
|
||||
|
|
|
@ -64,7 +64,7 @@ protected:
|
|||
void processCreatureSpeak(const std::string& name, int level, Otc::SpeakType type, const std::string& message, int channelId, const Position& creaturePos);
|
||||
|
||||
// container related
|
||||
void processOpenContainer(int containerId, int itemId, const std::string& name, int capacity, bool hasParent, const std::vector<ItemPtr>& items);
|
||||
void processOpenContainer(int containerId, const ItemPtr& containerItem, const std::string& name, int capacity, bool hasParent, const std::vector<ItemPtr>& items);
|
||||
void processCloseContainer(int containerId);
|
||||
void processContainerAddItem(int containerId, const ItemPtr& item);
|
||||
void processContainerUpdateItem(int containerId, int slot, const ItemPtr& item);
|
||||
|
|
|
@ -65,8 +65,9 @@ void ThingsType::parseThingType(const FileStreamPtr& fin, ThingType& thingType)
|
|||
{
|
||||
while(true) {
|
||||
int property = fin->getU8();
|
||||
if(property == ThingType::LastPropertyValue)
|
||||
if(property == ThingType::LastPropertyValue) {
|
||||
break;
|
||||
}
|
||||
|
||||
thingType.m_properties[property] = true;
|
||||
|
||||
|
@ -93,6 +94,16 @@ void ThingsType::parseThingType(const FileStreamPtr& fin, ThingType& thingType)
|
|||
#if PROTOCOL<=810
|
||||
else if(property == ThingType::IsRune)
|
||||
thingType.m_properties[ThingType::IsStackable] = true;
|
||||
#endif
|
||||
#if PROTOCOL>=944
|
||||
else if(property == ThingType::Market) {
|
||||
fin->getU16(); // category
|
||||
fin->getU16(); // trade as
|
||||
fin->getU16(); // show as
|
||||
fin->getString(); // name
|
||||
fin->getU16(); // restrict profession
|
||||
fin->getU16(); // level
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ struct ThingType
|
|||
IsFullGround,
|
||||
IgnoreLook,
|
||||
Cloth,
|
||||
Animation,
|
||||
Market,
|
||||
LastProperty,
|
||||
LastPropertyValue = 255
|
||||
};
|
||||
|
|
|
@ -187,13 +187,13 @@ void OTClient::registerLuaFunctions()
|
|||
g_lua.bindClassMemberFunction<Container>("setId", &Container::setId);
|
||||
g_lua.bindClassMemberFunction<Container>("setCapacity", &Container::setCapacity);
|
||||
g_lua.bindClassMemberFunction<Container>("setName", &Container::setName);
|
||||
g_lua.bindClassMemberFunction<Container>("setItemId", &Container::setItemId);
|
||||
g_lua.bindClassMemberFunction<Container>("setContainerItem", &Container::setContainerItem);
|
||||
g_lua.bindClassMemberFunction<Container>("setHasParent", &Container::setHasParent);
|
||||
g_lua.bindClassMemberFunction<Container>("getName", &Container::getName);
|
||||
g_lua.bindClassMemberFunction<Container>("getId", &Container::getId);
|
||||
g_lua.bindClassMemberFunction<Container>("getCapacity", &Container::getCapacity);
|
||||
g_lua.bindClassMemberFunction<Container>("getItemsCount", &Container::getItemsCount);
|
||||
g_lua.bindClassMemberFunction<Container>("getItemId", &Container::getItemId);
|
||||
g_lua.bindClassMemberFunction<Container>("getContainerItem", &Container::getContainerItem);
|
||||
g_lua.bindClassMemberFunction<Container>("hasParent", &Container::hasParent);
|
||||
|
||||
g_lua.registerClass<Thing>();
|
||||
|
|
|
@ -25,13 +25,11 @@
|
|||
|
||||
#include <otclient/global.h>
|
||||
|
||||
#if PROTOCOL != 810 && \
|
||||
PROTOCOL != 854 && \
|
||||
PROTOCOL != 860 && \
|
||||
PROTOCOL != 861 && \
|
||||
PROTOCOL != 862 && \
|
||||
PROTOCOL != 870 && \
|
||||
PROTOCOL != 910
|
||||
#if !(PROTOCOL == 810) && \
|
||||
!(PROTOCOL == 854) && \
|
||||
!(PROTOCOL >= 860 && PROTOCOL <= 862) && \
|
||||
!(PROTOCOL >= 870 && PROTOCOL <= 871) && \
|
||||
!(PROTOCOL >= 910 && PROTOCOL <= 953)
|
||||
#error "the supplied protocol version is not supported"
|
||||
#endif
|
||||
|
||||
|
@ -50,8 +48,8 @@ namespace Proto {
|
|||
"07119674283982419152118103759076030616683978566631413";
|
||||
#endif
|
||||
|
||||
constexpr int PicSignature = 0x4F8C231A; // 953 pic signature
|
||||
constexpr int ClientVersion = PROTOCOL;
|
||||
constexpr int PicSignature = 0x4E119CBF;
|
||||
|
||||
enum OsTypes {
|
||||
OsLinux = 1,
|
||||
|
@ -89,7 +87,13 @@ namespace Proto {
|
|||
GameServerLoginError = 20,
|
||||
GameServerLoginAdvice = 21,
|
||||
GameServerLoginWait = 22,
|
||||
#if PROTOCOL>=953
|
||||
GameServerPing = 29,
|
||||
GameServerPingBack = 30,
|
||||
#else
|
||||
GameServerPingBack = 29,
|
||||
GameServerPing = 30,
|
||||
#endif
|
||||
GameServerChallange = 31,
|
||||
GameServerDeath = 40,
|
||||
GameServerFullMap = 100,
|
||||
|
@ -130,6 +134,7 @@ namespace Proto {
|
|||
GameServerCreatureUnpass = 146,
|
||||
GameServerEditText = 150,
|
||||
GameServerEditList = 151,
|
||||
GameServerPlayerDataBasic = 159,
|
||||
GameServerPlayerData = 160,
|
||||
GameServerPlayerSkills = 161,
|
||||
GameServerPlayerState = 162,
|
||||
|
@ -162,6 +167,14 @@ namespace Proto {
|
|||
GameServerChannelEvent = 243,
|
||||
GameServerObjectInfo = 244, // 910
|
||||
GameServerPlayerInventory = 245, // 910
|
||||
GameServerMarketEnter = 246, // 944
|
||||
GameServerMarketLeave = 247, // 944
|
||||
GameServerMarketBrowseItem = 248, // 944
|
||||
GameServerMarketAcceptOffer = 249, // 944
|
||||
GameServerMarketOwnOffers = 250, // 944
|
||||
GameServerMarketCancelOffer = 251, // 944
|
||||
GameServerMarketBrowseOwnHistory = 252, // 944
|
||||
GameServerMarketMarketDetail = 253, // 944
|
||||
GameServerExtendedOpcode = 254 // otclient only
|
||||
};
|
||||
|
||||
|
@ -236,6 +249,11 @@ namespace Proto {
|
|||
ClientRequestQuestLine = 241,
|
||||
ClientRuleViolationReport = 242, // 910
|
||||
ClientGetObjectInfo = 243, // 910
|
||||
ClientMarketLeave = 244, // 944
|
||||
ClientMarketBrowse = 245, // 944
|
||||
ClientMarketCreateOffer = 246, // 944
|
||||
ClientMarketCancelOffer = 247, // 944
|
||||
ClientMarketAcceptOffer = 248, // 944
|
||||
ClientExtendedOpcode = 254 // otclient only
|
||||
};
|
||||
|
||||
|
|
|
@ -42,38 +42,23 @@ void ProtocolGame::login(const std::string& accountName, const std::string& acco
|
|||
|
||||
void ProtocolGame::onConnect()
|
||||
{
|
||||
recv();
|
||||
|
||||
// must create local player before parsing anything
|
||||
m_localPlayer = LocalPlayerPtr(new LocalPlayer);
|
||||
|
||||
#if PROTOCOL>=854
|
||||
m_waitingLoginPacket = true;
|
||||
enableChecksum();
|
||||
#else
|
||||
sendLoginPacket(0, 0);
|
||||
#endif
|
||||
|
||||
recv();
|
||||
}
|
||||
|
||||
void ProtocolGame::onRecv(InputMessage& inputMessage)
|
||||
{
|
||||
// only for protocol >= 860
|
||||
if(m_waitingLoginPacket) {
|
||||
inputMessage.skipBytes(3);
|
||||
uint32 timestamp = inputMessage.getU32();
|
||||
uint8 unknown = inputMessage.getU8();
|
||||
|
||||
m_waitingLoginPacket = false;
|
||||
|
||||
enableChecksum();
|
||||
|
||||
sendLoginPacket(timestamp, unknown);
|
||||
recv();
|
||||
}
|
||||
else {
|
||||
parseMessage(inputMessage);
|
||||
recv();
|
||||
}
|
||||
}
|
||||
|
||||
void ProtocolGame::onError(const boost::system::error_code& error)
|
||||
{
|
||||
|
|
|
@ -103,7 +103,7 @@ public:
|
|||
void sendExtendedOpcode(uint8 opcode, const std::string& buffer);
|
||||
|
||||
private:
|
||||
void sendLoginPacket(uint timestamp, uint8 unknown);
|
||||
void sendLoginPacket(uint challangeTimestamp, uint8 challangeRandom);
|
||||
|
||||
// Parse Messages
|
||||
void parseMessage(InputMessage& msg);
|
||||
|
@ -113,7 +113,8 @@ private:
|
|||
void parseLoginError(InputMessage& msg);
|
||||
void parseLoginAdvice(InputMessage& msg);
|
||||
void parseLoginWait(InputMessage& msg);
|
||||
void parsePing(InputMessage&);
|
||||
void parsePing(InputMessage& msg);
|
||||
void parseChallange(InputMessage& msg);
|
||||
void parseDeath(InputMessage& msg);
|
||||
void parseMapDescription(InputMessage& msg);
|
||||
void parseMapMoveNorth(InputMessage& msg);
|
||||
|
@ -150,6 +151,7 @@ private:
|
|||
void parseCreatureTurn(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);
|
||||
|
@ -198,8 +200,7 @@ private:
|
|||
Position parsePosition(InputMessage& msg);
|
||||
|
||||
private:
|
||||
Boolean<false> m_waitingLoginPacket;
|
||||
Boolean<true> m_firstPacket;
|
||||
Boolean<false> m_gameInitialized;
|
||||
std::string m_accountName;
|
||||
std::string m_accountPassword;
|
||||
std::string m_characterName;
|
||||
|
|
|
@ -41,13 +41,9 @@ void ProtocolGame::parseMessage(InputMessage& msg)
|
|||
try {
|
||||
while(!msg.eof()) {
|
||||
opcode = msg.getU8();
|
||||
//dump << opcode;
|
||||
|
||||
if(m_firstPacket) {
|
||||
if(opcode != Proto::GameServerInitGame)
|
||||
logWarning("first server network opcode is not GameServerInitGame");
|
||||
m_firstPacket = false;
|
||||
}
|
||||
if(!m_gameInitialized && opcode >= Proto::GameServerFullMap)
|
||||
logWarning("first game network opcode is not GameServerInitGame");
|
||||
|
||||
switch(opcode) {
|
||||
case Proto::GameServerInitGame:
|
||||
|
@ -68,6 +64,12 @@ void ProtocolGame::parseMessage(InputMessage& msg)
|
|||
case Proto::GameServerPing:
|
||||
parsePing(msg);
|
||||
break;
|
||||
case Proto::GameServerPingBack:
|
||||
// nothing todo
|
||||
break;
|
||||
case Proto::GameServerChallange:
|
||||
parseChallange(msg);
|
||||
break;
|
||||
case Proto::GameServerDeath:
|
||||
parseDeath(msg);
|
||||
break;
|
||||
|
@ -261,30 +263,44 @@ void ProtocolGame::parseMessage(InputMessage& msg)
|
|||
parseQuestLine(msg);
|
||||
break;
|
||||
#if PROTOCOL>=870
|
||||
case Proto::GameServerSpellDelay: // 870 only
|
||||
case Proto::GameServerSpellDelay:
|
||||
parseSpellDelay(msg);
|
||||
break;
|
||||
case Proto::GameServerSpellGroupDelay: // 870 only
|
||||
case Proto::GameServerSpellGroupDelay:
|
||||
parseSpellGroupDelay(msg);
|
||||
break;
|
||||
#endif
|
||||
#if PROTOCOL>=910
|
||||
case Proto::GameServerChannelEvent: // 910 only
|
||||
case Proto::GameServerPlayerDataBasic:
|
||||
parsePlayerInfo(msg);
|
||||
break;
|
||||
case Proto::GameServerChannelEvent:
|
||||
parseChannelEvent(msg);
|
||||
break;
|
||||
case Proto::GameServerObjectInfo: // 910 only
|
||||
case Proto::GameServerObjectInfo:
|
||||
parseObjectInfo(msg);
|
||||
break;
|
||||
case Proto::GameServerPlayerInventory: // 910 only
|
||||
case Proto::GameServerPlayerInventory:
|
||||
parsePlayerInventory(msg);
|
||||
break;
|
||||
#endif
|
||||
#if PROTOCOL>=944
|
||||
case Proto::GameServerMarketEnter:
|
||||
case Proto::GameServerMarketLeave:
|
||||
case Proto::GameServerMarketBrowseItem:
|
||||
case Proto::GameServerMarketAcceptOffer:
|
||||
case Proto::GameServerMarketOwnOffers:
|
||||
case Proto::GameServerMarketCancelOffer:
|
||||
case Proto::GameServerMarketBrowseOwnHistory:
|
||||
case Proto::GameServerMarketMarketDetail:
|
||||
//TODO
|
||||
break;
|
||||
#endif
|
||||
// additional opcode used by otclient only
|
||||
case Proto::GameServerExtendedOpcode:
|
||||
parseExtendedOpcode(msg);
|
||||
break;
|
||||
// not handled yet
|
||||
//case Proto::GameServerChallange:
|
||||
//case Proto::GameServerTrappers
|
||||
//case Proto::GameServerWait:
|
||||
default:
|
||||
|
@ -300,6 +316,7 @@ void ProtocolGame::parseMessage(InputMessage& msg)
|
|||
|
||||
void ProtocolGame::parseInitGame(InputMessage& msg)
|
||||
{
|
||||
m_gameInitialized = true;
|
||||
uint playerId = msg.getU32();
|
||||
int serverBeat = msg.getU16();
|
||||
bool canReportBugs = msg.getU8();
|
||||
|
@ -338,12 +355,19 @@ void ProtocolGame::parseLoginWait(InputMessage& msg)
|
|||
g_game.processLoginWait(message, time);
|
||||
}
|
||||
|
||||
void ProtocolGame::parsePing(InputMessage&)
|
||||
void ProtocolGame::parsePing(InputMessage& msg)
|
||||
{
|
||||
g_game.processPing();
|
||||
sendPingResponse();
|
||||
}
|
||||
|
||||
void ProtocolGame::parseChallange(InputMessage& msg)
|
||||
{
|
||||
uint32 timestamp = msg.getU32();
|
||||
uint8 random = msg.getU8();
|
||||
sendLoginPacket(timestamp, random);
|
||||
}
|
||||
|
||||
void ProtocolGame::parseDeath(InputMessage& msg)
|
||||
{
|
||||
int penality = 100;
|
||||
|
@ -474,7 +498,11 @@ void ProtocolGame::parseCreatureMove(InputMessage& msg)
|
|||
void ProtocolGame::parseOpenContainer(InputMessage& msg)
|
||||
{
|
||||
int containerId = msg.getU8();
|
||||
int itemId = msg.getU16();
|
||||
#if PROTOCOL>=920
|
||||
ItemPtr containerItem = internalGetItem(msg);
|
||||
#else
|
||||
ItemPtr containerItem = Item::create(msg.getU16());
|
||||
#endif
|
||||
std::string name = msg.getString();
|
||||
int capacity = msg.getU8();
|
||||
bool hasParent = (msg.getU8() != 0);
|
||||
|
@ -484,7 +512,7 @@ void ProtocolGame::parseOpenContainer(InputMessage& msg)
|
|||
for(int i = 0; i < itemCount; i++)
|
||||
items[i] = internalGetItem(msg);
|
||||
|
||||
g_game.processOpenContainer(containerId, itemId, name, capacity, hasParent, items);
|
||||
g_game.processOpenContainer(containerId, containerItem, name, capacity, hasParent, items);
|
||||
}
|
||||
|
||||
void ProtocolGame::parseCloseContainer(InputMessage& msg)
|
||||
|
@ -780,6 +808,16 @@ void ProtocolGame::parseEditList(InputMessage& msg)
|
|||
g_game.processEditList(id, doorId, text);
|
||||
}
|
||||
|
||||
void ProtocolGame::parsePlayerInfo(InputMessage& msg)
|
||||
{
|
||||
msg.getU8(); // is premium?
|
||||
msg.getU8(); // profession
|
||||
int numSpells = msg.getU16();
|
||||
for(int i=0;i<numSpells;++i) {
|
||||
msg.getU16(); // spell
|
||||
}
|
||||
}
|
||||
|
||||
void ProtocolGame::parsePlayerStats(InputMessage& msg)
|
||||
{
|
||||
double health = msg.getU16();
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include "protocolgame.h"
|
||||
#include <framework/net/rsa.h>
|
||||
|
||||
void ProtocolGame::sendLoginPacket(uint timestamp, uint8 unknown)
|
||||
void ProtocolGame::sendLoginPacket(uint challangeTimestamp, uint8 challangeRandom)
|
||||
{
|
||||
OutputMessage msg;
|
||||
|
||||
|
@ -48,12 +48,15 @@ void ProtocolGame::sendLoginPacket(uint timestamp, uint8 unknown)
|
|||
enableChecksum();
|
||||
|
||||
msg.addString(m_accountName);
|
||||
paddingBytes -= 2 + m_accountName.length();
|
||||
msg.addString(m_characterName);
|
||||
paddingBytes -= 2 + m_characterName.length();
|
||||
msg.addString(m_accountPassword);
|
||||
paddingBytes -= 2 + m_accountPassword.length();
|
||||
|
||||
msg.addU32(timestamp);
|
||||
msg.addU8(unknown);
|
||||
paddingBytes -= 11 + m_accountName.length() + m_characterName.length() + m_accountPassword.length();
|
||||
msg.addU32(challangeTimestamp);
|
||||
msg.addU8(challangeRandom);
|
||||
paddingBytes -= 5;
|
||||
#else // PROTOCOL>=810
|
||||
msg.addU32(Fw::fromstring<uint32>(m_accountName));
|
||||
msg.addString(m_characterName);
|
||||
|
|
Loading…
Reference in New Issue