basic protocol 953 support, logging in real tibia!

This commit is contained in:
Eduardo Bart 2012-05-12 01:52:16 -03:00
parent abbd15b1c2
commit fa9c942471
18 changed files with 163 additions and 68 deletions

4
BUGS
View File

@ -2,6 +2,7 @@
modules recursivity makes client crash, it should generate a warning modules recursivity makes client crash, it should generate a warning
== P1 BUGS (affects game play) == P1 BUGS (affects game play)
in some situations creatures may disappears while walking
sometimes minimap desync Z pos sometimes minimap desync Z pos
follow and autowalk doesn't cancel when walking via hotkeys follow and autowalk doesn't cancel when walking via hotkeys
when reading invalid spr/dat the client crashs 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 skulls is rendering outside map bounds
party options does not work when re-logging inside a party 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 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

View File

@ -38,7 +38,7 @@ local function onContainerOpen(container, previousContainer)
name = name:sub(1,1):upper() .. name:sub(2) name = name:sub(1,1):upper() .. name:sub(2)
containerWindow:setText(name) containerWindow:setText(name)
containerItemWidget:setItemId(container:getItemId()) containerItemWidget:setItem(container:getContainerItem())
containerPanel:destroyChildren() containerPanel:destroyChildren()
for slot=0,container:getCapacity()-1 do for slot=0,container:getCapacity()-1 do

View File

@ -223,6 +223,32 @@ uint64 FileStream::getU64()
return v; 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) void FileStream::addU8(uint8 v)
{ {
if(PHYSFS_write(m_fileHandle, &v, 1, 1) != 1) if(PHYSFS_write(m_fileHandle, &v, 1, 1) != 1)

View File

@ -53,6 +53,7 @@ public:
uint16 getU16(); uint16 getU16();
uint32 getU32(); uint32 getU32();
uint64 getU64(); uint64 getU64();
std::string getString();
void addU8(uint8 v); void addU8(uint8 v);
void addU16(uint8 v); void addU16(uint8 v);
void addU32(uint8 v); void addU32(uint8 v);

View File

@ -124,10 +124,18 @@ void Protocol::internalRecvData(uint8* buffer, uint16 size)
return; return;
} }
if(m_xteaEncryptionEnabled && !xteaDecrypt(m_inputMessage)) { if(m_xteaEncryptionEnabled) {
if(!xteaDecrypt(m_inputMessage)) {
logTraceError("failed to decrypt message"); logTraceError("failed to decrypt message");
return; return;
} }
} else {
int size = m_inputMessage.getU16();
if(size != m_inputMessage.getUnreadSize()) {
logTraceError("invalid message size");
return;
}
}
onRecv(m_inputMessage); onRecv(m_inputMessage);
} }

View File

@ -6,9 +6,14 @@ ENDIF(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 6)
# otclient options # otclient options
OPTION(BOT_PROTECTION "Enable bot protection" ON) OPTION(BOT_PROTECTION "Enable bot protection" ON)
SET(PROTOCOL 860 CACHE "Protocol version" STRING) SET(PROTOCOL 860 CACHE "Protocol version" STRING)
SET(CIPSOFT_RSA "Use cipsoft RSA to login into original tibia" OFF)
ADD_DEFINITIONS(-DPROTOCOL=${PROTOCOL}) ADD_DEFINITIONS(-DPROTOCOL=${PROTOCOL})
MESSAGE(STATUS "Protocol: " ${PROTOCOL}) MESSAGE(STATUS "Protocol: " ${PROTOCOL})
IF(CIPSOFT_RSA)
ADD_DEFINITIONS(-DCIPSOFT_RSA)
ENDIF()
IF(BOT_PROTECTION) IF(BOT_PROTECTION)
ADD_DEFINITIONS(-DBOT_PROTECTION) ADD_DEFINITIONS(-DBOT_PROTECTION)
MESSAGE(STATUS "Bot protection: ON") MESSAGE(STATUS "Bot protection: ON")

View File

@ -26,7 +26,6 @@
Container::Container() Container::Container()
{ {
m_id = -1; m_id = -1;
m_itemId = 0;
m_capacity = 20; m_capacity = 20;
m_name = "Container"; m_name = "Container";
m_hasParent = false; m_hasParent = false;

View File

@ -46,14 +46,14 @@ public:
void setId(int id) { m_id = id; } void setId(int id) { m_id = id; }
void setCapacity(int capacity) { m_capacity = capacity; } void setCapacity(int capacity) { m_capacity = capacity; }
void setName(std::string name) { m_name = name; } 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; } void setHasParent(bool hasParent) { m_hasParent = hasParent; }
std::string getName() { return m_name; } std::string getName() { return m_name; }
int getId() { return m_id; } int getId() { return m_id; }
int getCapacity() { return m_capacity; } int getCapacity() { return m_capacity; }
int getItemsCount() { return m_items.size(); } int getItemsCount() { return m_items.size(); }
uint16 getItemId() { return m_itemId; } ItemPtr getContainerItem() { return m_containerItem; }
bool hasParent() { return m_hasParent; } bool hasParent() { return m_hasParent; }
private: private:
@ -61,7 +61,7 @@ private:
int m_id; int m_id;
int m_capacity; int m_capacity;
uint16 m_itemId; ItemPtr m_containerItem;
std::string m_name; std::string m_name;
bool m_hasParent; bool m_hasParent;
std::deque<ItemPtr> m_items; std::deque<ItemPtr> m_items;

View File

@ -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); 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 previousContainer = getContainer(containerId);
ContainerPtr container = ContainerPtr(new Container()); ContainerPtr container = ContainerPtr(new Container());
container->setId(containerId); container->setId(containerId);
container->setCapacity(capacity); container->setCapacity(capacity);
container->setName(name); container->setName(name);
container->setItemId(itemId); container->setContainerItem(containerItem);
container->setHasParent(hasParent); container->setHasParent(hasParent);
m_containers[containerId] = container; m_containers[containerId] = container;
container->addItems(items); container->addItems(items);

View File

@ -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); void processCreatureSpeak(const std::string& name, int level, Otc::SpeakType type, const std::string& message, int channelId, const Position& creaturePos);
// container related // 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 processCloseContainer(int containerId);
void processContainerAddItem(int containerId, const ItemPtr& item); void processContainerAddItem(int containerId, const ItemPtr& item);
void processContainerUpdateItem(int containerId, int slot, const ItemPtr& item); void processContainerUpdateItem(int containerId, int slot, const ItemPtr& item);

View File

@ -65,8 +65,9 @@ void ThingsType::parseThingType(const FileStreamPtr& fin, ThingType& thingType)
{ {
while(true) { while(true) {
int property = fin->getU8(); int property = fin->getU8();
if(property == ThingType::LastPropertyValue) if(property == ThingType::LastPropertyValue) {
break; break;
}
thingType.m_properties[property] = true; thingType.m_properties[property] = true;
@ -93,6 +94,16 @@ void ThingsType::parseThingType(const FileStreamPtr& fin, ThingType& thingType)
#if PROTOCOL<=810 #if PROTOCOL<=810
else if(property == ThingType::IsRune) else if(property == ThingType::IsRune)
thingType.m_properties[ThingType::IsStackable] = true; 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 #endif
} }

View File

@ -78,7 +78,7 @@ struct ThingType
IsFullGround, IsFullGround,
IgnoreLook, IgnoreLook,
Cloth, Cloth,
Animation, Market,
LastProperty, LastProperty,
LastPropertyValue = 255 LastPropertyValue = 255
}; };

View File

@ -187,13 +187,13 @@ void OTClient::registerLuaFunctions()
g_lua.bindClassMemberFunction<Container>("setId", &Container::setId); g_lua.bindClassMemberFunction<Container>("setId", &Container::setId);
g_lua.bindClassMemberFunction<Container>("setCapacity", &Container::setCapacity); g_lua.bindClassMemberFunction<Container>("setCapacity", &Container::setCapacity);
g_lua.bindClassMemberFunction<Container>("setName", &Container::setName); 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>("setHasParent", &Container::setHasParent);
g_lua.bindClassMemberFunction<Container>("getName", &Container::getName); g_lua.bindClassMemberFunction<Container>("getName", &Container::getName);
g_lua.bindClassMemberFunction<Container>("getId", &Container::getId); g_lua.bindClassMemberFunction<Container>("getId", &Container::getId);
g_lua.bindClassMemberFunction<Container>("getCapacity", &Container::getCapacity); g_lua.bindClassMemberFunction<Container>("getCapacity", &Container::getCapacity);
g_lua.bindClassMemberFunction<Container>("getItemsCount", &Container::getItemsCount); 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.bindClassMemberFunction<Container>("hasParent", &Container::hasParent);
g_lua.registerClass<Thing>(); g_lua.registerClass<Thing>();

View File

@ -25,13 +25,11 @@
#include <otclient/global.h> #include <otclient/global.h>
#if PROTOCOL != 810 && \ #if !(PROTOCOL == 810) && \
PROTOCOL != 854 && \ !(PROTOCOL == 854) && \
PROTOCOL != 860 && \ !(PROTOCOL >= 860 && PROTOCOL <= 862) && \
PROTOCOL != 861 && \ !(PROTOCOL >= 870 && PROTOCOL <= 871) && \
PROTOCOL != 862 && \ !(PROTOCOL >= 910 && PROTOCOL <= 953)
PROTOCOL != 870 && \
PROTOCOL != 910
#error "the supplied protocol version is not supported" #error "the supplied protocol version is not supported"
#endif #endif
@ -50,8 +48,8 @@ namespace Proto {
"07119674283982419152118103759076030616683978566631413"; "07119674283982419152118103759076030616683978566631413";
#endif #endif
constexpr int PicSignature = 0x4F8C231A; // 953 pic signature
constexpr int ClientVersion = PROTOCOL; constexpr int ClientVersion = PROTOCOL;
constexpr int PicSignature = 0x4E119CBF;
enum OsTypes { enum OsTypes {
OsLinux = 1, OsLinux = 1,
@ -89,7 +87,13 @@ namespace Proto {
GameServerLoginError = 20, GameServerLoginError = 20,
GameServerLoginAdvice = 21, GameServerLoginAdvice = 21,
GameServerLoginWait = 22, GameServerLoginWait = 22,
#if PROTOCOL>=953
GameServerPing = 29,
GameServerPingBack = 30,
#else
GameServerPingBack = 29,
GameServerPing = 30, GameServerPing = 30,
#endif
GameServerChallange = 31, GameServerChallange = 31,
GameServerDeath = 40, GameServerDeath = 40,
GameServerFullMap = 100, GameServerFullMap = 100,
@ -130,6 +134,7 @@ namespace Proto {
GameServerCreatureUnpass = 146, GameServerCreatureUnpass = 146,
GameServerEditText = 150, GameServerEditText = 150,
GameServerEditList = 151, GameServerEditList = 151,
GameServerPlayerDataBasic = 159,
GameServerPlayerData = 160, GameServerPlayerData = 160,
GameServerPlayerSkills = 161, GameServerPlayerSkills = 161,
GameServerPlayerState = 162, GameServerPlayerState = 162,
@ -162,6 +167,14 @@ namespace Proto {
GameServerChannelEvent = 243, GameServerChannelEvent = 243,
GameServerObjectInfo = 244, // 910 GameServerObjectInfo = 244, // 910
GameServerPlayerInventory = 245, // 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 GameServerExtendedOpcode = 254 // otclient only
}; };
@ -236,6 +249,11 @@ namespace Proto {
ClientRequestQuestLine = 241, ClientRequestQuestLine = 241,
ClientRuleViolationReport = 242, // 910 ClientRuleViolationReport = 242, // 910
ClientGetObjectInfo = 243, // 910 ClientGetObjectInfo = 243, // 910
ClientMarketLeave = 244, // 944
ClientMarketBrowse = 245, // 944
ClientMarketCreateOffer = 246, // 944
ClientMarketCancelOffer = 247, // 944
ClientMarketAcceptOffer = 248, // 944
ClientExtendedOpcode = 254 // otclient only ClientExtendedOpcode = 254 // otclient only
}; };

View File

@ -42,38 +42,23 @@ void ProtocolGame::login(const std::string& accountName, const std::string& acco
void ProtocolGame::onConnect() void ProtocolGame::onConnect()
{ {
recv();
// must create local player before parsing anything // must create local player before parsing anything
m_localPlayer = LocalPlayerPtr(new LocalPlayer); m_localPlayer = LocalPlayerPtr(new LocalPlayer);
#if PROTOCOL>=854 #if PROTOCOL>=854
m_waitingLoginPacket = true; enableChecksum();
#else #else
sendLoginPacket(0, 0); sendLoginPacket(0, 0);
#endif #endif
recv();
} }
void ProtocolGame::onRecv(InputMessage& inputMessage) 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); parseMessage(inputMessage);
recv(); recv();
} }
}
void ProtocolGame::onError(const boost::system::error_code& error) void ProtocolGame::onError(const boost::system::error_code& error)
{ {

View File

@ -103,7 +103,7 @@ public:
void sendExtendedOpcode(uint8 opcode, const std::string& buffer); void sendExtendedOpcode(uint8 opcode, const std::string& buffer);
private: private:
void sendLoginPacket(uint timestamp, uint8 unknown); void sendLoginPacket(uint challangeTimestamp, uint8 challangeRandom);
// Parse Messages // Parse Messages
void parseMessage(InputMessage& msg); void parseMessage(InputMessage& msg);
@ -113,7 +113,8 @@ private:
void parseLoginError(InputMessage& msg); void parseLoginError(InputMessage& msg);
void parseLoginAdvice(InputMessage& msg); void parseLoginAdvice(InputMessage& msg);
void parseLoginWait(InputMessage& msg); void parseLoginWait(InputMessage& msg);
void parsePing(InputMessage&); void parsePing(InputMessage& msg);
void parseChallange(InputMessage& msg);
void parseDeath(InputMessage& msg); void parseDeath(InputMessage& msg);
void parseMapDescription(InputMessage& msg); void parseMapDescription(InputMessage& msg);
void parseMapMoveNorth(InputMessage& msg); void parseMapMoveNorth(InputMessage& msg);
@ -150,6 +151,7 @@ private:
void parseCreatureTurn(InputMessage& msg); void parseCreatureTurn(InputMessage& msg);
void parseEditText(InputMessage& msg); void parseEditText(InputMessage& msg);
void parseEditList(InputMessage& msg); void parseEditList(InputMessage& msg);
void parsePlayerInfo(InputMessage& msg);
void parsePlayerStats(InputMessage& msg); void parsePlayerStats(InputMessage& msg);
void parsePlayerSkills(InputMessage& msg); void parsePlayerSkills(InputMessage& msg);
void parsePlayerState(InputMessage& msg); void parsePlayerState(InputMessage& msg);
@ -198,8 +200,7 @@ private:
Position parsePosition(InputMessage& msg); Position parsePosition(InputMessage& msg);
private: private:
Boolean<false> m_waitingLoginPacket; Boolean<false> m_gameInitialized;
Boolean<true> m_firstPacket;
std::string m_accountName; std::string m_accountName;
std::string m_accountPassword; std::string m_accountPassword;
std::string m_characterName; std::string m_characterName;

View File

@ -41,13 +41,9 @@ void ProtocolGame::parseMessage(InputMessage& msg)
try { try {
while(!msg.eof()) { while(!msg.eof()) {
opcode = msg.getU8(); opcode = msg.getU8();
//dump << opcode;
if(m_firstPacket) { if(!m_gameInitialized && opcode >= Proto::GameServerFullMap)
if(opcode != Proto::GameServerInitGame) logWarning("first game network opcode is not GameServerInitGame");
logWarning("first server network opcode is not GameServerInitGame");
m_firstPacket = false;
}
switch(opcode) { switch(opcode) {
case Proto::GameServerInitGame: case Proto::GameServerInitGame:
@ -68,6 +64,12 @@ void ProtocolGame::parseMessage(InputMessage& msg)
case Proto::GameServerPing: case Proto::GameServerPing:
parsePing(msg); parsePing(msg);
break; break;
case Proto::GameServerPingBack:
// nothing todo
break;
case Proto::GameServerChallange:
parseChallange(msg);
break;
case Proto::GameServerDeath: case Proto::GameServerDeath:
parseDeath(msg); parseDeath(msg);
break; break;
@ -261,30 +263,44 @@ void ProtocolGame::parseMessage(InputMessage& msg)
parseQuestLine(msg); parseQuestLine(msg);
break; break;
#if PROTOCOL>=870 #if PROTOCOL>=870
case Proto::GameServerSpellDelay: // 870 only case Proto::GameServerSpellDelay:
parseSpellDelay(msg); parseSpellDelay(msg);
break; break;
case Proto::GameServerSpellGroupDelay: // 870 only case Proto::GameServerSpellGroupDelay:
parseSpellGroupDelay(msg); parseSpellGroupDelay(msg);
break; break;
#endif #endif
#if PROTOCOL>=910 #if PROTOCOL>=910
case Proto::GameServerChannelEvent: // 910 only case Proto::GameServerPlayerDataBasic:
parsePlayerInfo(msg);
break;
case Proto::GameServerChannelEvent:
parseChannelEvent(msg); parseChannelEvent(msg);
break; break;
case Proto::GameServerObjectInfo: // 910 only case Proto::GameServerObjectInfo:
parseObjectInfo(msg); parseObjectInfo(msg);
break; break;
case Proto::GameServerPlayerInventory: // 910 only case Proto::GameServerPlayerInventory:
parsePlayerInventory(msg); parsePlayerInventory(msg);
break; 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 #endif
// additional opcode used by otclient only // additional opcode used by otclient only
case Proto::GameServerExtendedOpcode: case Proto::GameServerExtendedOpcode:
parseExtendedOpcode(msg); parseExtendedOpcode(msg);
break; break;
// not handled yet // not handled yet
//case Proto::GameServerChallange:
//case Proto::GameServerTrappers //case Proto::GameServerTrappers
//case Proto::GameServerWait: //case Proto::GameServerWait:
default: default:
@ -300,6 +316,7 @@ void ProtocolGame::parseMessage(InputMessage& msg)
void ProtocolGame::parseInitGame(InputMessage& msg) void ProtocolGame::parseInitGame(InputMessage& msg)
{ {
m_gameInitialized = true;
uint playerId = msg.getU32(); uint playerId = msg.getU32();
int serverBeat = msg.getU16(); int serverBeat = msg.getU16();
bool canReportBugs = msg.getU8(); bool canReportBugs = msg.getU8();
@ -338,12 +355,19 @@ void ProtocolGame::parseLoginWait(InputMessage& msg)
g_game.processLoginWait(message, time); g_game.processLoginWait(message, time);
} }
void ProtocolGame::parsePing(InputMessage&) void ProtocolGame::parsePing(InputMessage& msg)
{ {
g_game.processPing(); g_game.processPing();
sendPingResponse(); sendPingResponse();
} }
void ProtocolGame::parseChallange(InputMessage& msg)
{
uint32 timestamp = msg.getU32();
uint8 random = msg.getU8();
sendLoginPacket(timestamp, random);
}
void ProtocolGame::parseDeath(InputMessage& msg) void ProtocolGame::parseDeath(InputMessage& msg)
{ {
int penality = 100; int penality = 100;
@ -474,7 +498,11 @@ void ProtocolGame::parseCreatureMove(InputMessage& msg)
void ProtocolGame::parseOpenContainer(InputMessage& msg) void ProtocolGame::parseOpenContainer(InputMessage& msg)
{ {
int containerId = msg.getU8(); 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(); std::string name = msg.getString();
int capacity = msg.getU8(); int capacity = msg.getU8();
bool hasParent = (msg.getU8() != 0); bool hasParent = (msg.getU8() != 0);
@ -484,7 +512,7 @@ void ProtocolGame::parseOpenContainer(InputMessage& msg)
for(int i = 0; i < itemCount; i++) for(int i = 0; i < itemCount; i++)
items[i] = internalGetItem(msg); 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) void ProtocolGame::parseCloseContainer(InputMessage& msg)
@ -780,6 +808,16 @@ void ProtocolGame::parseEditList(InputMessage& msg)
g_game.processEditList(id, doorId, text); 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) void ProtocolGame::parsePlayerStats(InputMessage& msg)
{ {
double health = msg.getU16(); double health = msg.getU16();

View File

@ -23,7 +23,7 @@
#include "protocolgame.h" #include "protocolgame.h"
#include <framework/net/rsa.h> #include <framework/net/rsa.h>
void ProtocolGame::sendLoginPacket(uint timestamp, uint8 unknown) void ProtocolGame::sendLoginPacket(uint challangeTimestamp, uint8 challangeRandom)
{ {
OutputMessage msg; OutputMessage msg;
@ -48,12 +48,15 @@ void ProtocolGame::sendLoginPacket(uint timestamp, uint8 unknown)
enableChecksum(); 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(timestamp); msg.addU32(challangeTimestamp);
msg.addU8(unknown); msg.addU8(challangeRandom);
paddingBytes -= 11 + m_accountName.length() + m_characterName.length() + m_accountPassword.length(); paddingBytes -= 5;
#else // PROTOCOL>=810 #else // PROTOCOL>=810
msg.addU32(Fw::fromstring<uint32>(m_accountName)); msg.addU32(Fw::fromstring<uint32>(m_accountName));
msg.addString(m_characterName); msg.addString(m_characterName);