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
|
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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -124,9 +124,17 @@ void Protocol::internalRecvData(uint8* buffer, uint16 size)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_xteaEncryptionEnabled && !xteaDecrypt(m_inputMessage)) {
|
if(m_xteaEncryptionEnabled) {
|
||||||
logTraceError("failed to decrypt message");
|
if(!xteaDecrypt(m_inputMessage)) {
|
||||||
return;
|
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);
|
onRecv(m_inputMessage);
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ struct ThingType
|
||||||
IsFullGround,
|
IsFullGround,
|
||||||
IgnoreLook,
|
IgnoreLook,
|
||||||
Cloth,
|
Cloth,
|
||||||
Animation,
|
Market,
|
||||||
LastProperty,
|
LastProperty,
|
||||||
LastPropertyValue = 255
|
LastPropertyValue = 255
|
||||||
};
|
};
|
||||||
|
|
|
@ -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>();
|
||||||
|
|
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -42,37 +42,22 @@ 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
|
parseMessage(inputMessage);
|
||||||
if(m_waitingLoginPacket) {
|
recv();
|
||||||
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)
|
void ProtocolGame::onError(const boost::system::error_code& error)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue