From eb7b04ae7129fb3ccc583fb4181e3ca43c714af3 Mon Sep 17 00:00:00 2001 From: Rick Date: Mon, 13 Jul 2020 06:57:31 -0300 Subject: [PATCH] Protocol 12.20 (#1396) You'll need to change accountname to email in your login.php This PR will only work with client 12.20 Credits to SaiyansKing & R1Ck Thanks to majesty for login by email Client 12.20: https://mega.nz/file/7ip32B5T#uHrJwJWiMu6fLNtNqPHDdMdt2P8BUwmWMnCqYZnjIDg Login.php to test: GesiorAAC: https://github.com/opentibiabr/gesioraac-tibia12-login/releases/tag/1.1 MyAAC: https://github.com/opentibiabr/myaac-tibia12-login/releases/tag/1.4 --- data/modules/scripts/blessings/blessings.lua | 1 + src/definitions.h | 4 +- src/enums.h | 9 ++++ src/game.cpp | 14 +++++- src/game.h | 1 + src/iologindata.cpp | 4 +- src/player.h | 2 +- src/protocolgame.cpp | 45 +++++++++++++++----- src/protocolgame.h | 2 +- src/tile.cpp | 19 +++++++++ src/tile.h | 1 + 11 files changed, 85 insertions(+), 17 deletions(-) diff --git a/data/modules/scripts/blessings/blessings.lua b/data/modules/scripts/blessings/blessings.lua index 68e4519a4..7edc28bc5 100644 --- a/data/modules/scripts/blessings/blessings.lua +++ b/data/modules/scripts/blessings/blessings.lua @@ -135,6 +135,7 @@ Blessings.sendBlessDialog = function(player) if v.type ~= Blessings.Types.PvP or Blessings.Config.HasToF then msg:addU16(Blessings.BitWiseTable[v.id]) msg:addByte(player:getBlessingCount(v.id)) + msg:addByte(0) -- Store Blessings Count end end diff --git a/src/definitions.h b/src/definitions.h index b507d5f1c..ffbbc64ca 100644 --- a/src/definitions.h +++ b/src/definitions.h @@ -24,8 +24,8 @@ static constexpr auto STATUS_SERVER_NAME = "OTServBR - Global"; static constexpr auto STATUS_SERVER_VERSION = "TFS 1.3"; static constexpr auto STATUS_SERVER_DEVELOPERS = "OTServBR, Mark Samman and The Forgotten Server Developers"; -static constexpr auto CLIENT_VERSION = 1200; -static constexpr auto CLIENT_VERSION_STR = "12.00"; +static constexpr auto CLIENT_VERSION = 1220; +static constexpr auto CLIENT_VERSION_STR = "12.20"; static constexpr auto AUTHENTICATOR_DIGITS = 6U; static constexpr auto AUTHENTICATOR_PERIOD = 30U; diff --git a/src/enums.h b/src/enums.h index 12f853078..82eac0283 100644 --- a/src/enums.h +++ b/src/enums.h @@ -680,4 +680,13 @@ enum Resource_t : uint8_t RESOURCE_PREY = 0x0A, }; +enum MagicEffectsType_t : uint8_t { + MAGIC_EFFECTS_END_LOOP = 0,//ends magic effect loop + MAGIC_EFFECTS_DELTA = 1,//needs uint8_t delta after type to adjust position + MAGIC_EFFECTS_DELAY = 2,//needs uint16_t delay after type to delay in miliseconds effect display + MAGIC_EFFECTS_CREATE_EFFECT = 3,//needs uint8_t effectid after type + MAGIC_EFFECTS_CREATE_DISTANCEEFFECT = 4,//needs uint8_t and deltaX(int8_t), deltaY(int8_t) after type + MAGIC_EFFECTS_CREATE_DISTANCEEFFECT_REVERSED = 5,//needs uint8_t and deltaX(int8_t), deltaY(int8_t) after type +}; + #endif diff --git a/src/game.cpp b/src/game.cpp index e66c41f44..873f55330 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -308,6 +308,18 @@ Thing* Game::internalGetThing(Player* player, const Position& pos, int32_t index break; } + case STACKPOS_FIND_THING: { + thing = tile->getUseItem(index); + if (!thing) { + thing = tile->getDoorItem(); + } + + if (!thing) { + thing = tile->getTopDownItem(); + } + break; + } + default: { thing = nullptr; break; @@ -2164,7 +2176,7 @@ void Game::playerUseItem(uint32_t playerId, const Position& pos, uint8_t stackPo return; } - Thing* thing = internalGetThing(player, pos, stackPos, spriteId, STACKPOS_USEITEM); + Thing* thing = internalGetThing(player, pos, stackPos, spriteId, STACKPOS_FIND_THING); if (!thing) { player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); return; diff --git a/src/game.h b/src/game.h index c3a095079..95e129203 100644 --- a/src/game.h +++ b/src/game.h @@ -45,6 +45,7 @@ enum stackPosType_t { STACKPOS_TOPDOWN_ITEM, STACKPOS_USEITEM, STACKPOS_USETARGET, + STACKPOS_FIND_THING, }; enum WorldType_t { diff --git a/src/iologindata.cpp b/src/iologindata.cpp index c734db5a2..56dd61894 100644 --- a/src/iologindata.cpp +++ b/src/iologindata.cpp @@ -46,12 +46,12 @@ bool IOLoginData::LoginServerAuthentication(const std::string& name, return true; } -uint32_t IOLoginData::gameworldAuthentication(const std::string& accountName, const std::string& password, std::string& characterName) +uint32_t IOLoginData::gameworldAuthentication(const std::string& email, const std::string& password, std::string& characterName) { Database& db = Database::getInstance(); std::ostringstream query; - query << "SELECT `id`, `password` FROM `accounts` WHERE `name` = " << db.escapeString(accountName); + query << "SELECT `id`, `password` FROM `accounts` WHERE `email` = " << db.escapeString(email); DBResult_ptr result = db.storeQuery(query.str()); if (!result) { std::cout << "[IOLoginData::gameworldAuthentication] Account not found!" << std::endl; diff --git a/src/player.h b/src/player.h index 3ee596b63..00a771ede 100644 --- a/src/player.h +++ b/src/player.h @@ -1609,7 +1609,7 @@ class Player final : public Creature, public Cylinder tradestate_t tradeState = TRADE_NONE; fightMode_t fightMode = FIGHTMODE_ATTACK; account::AccountType accountType = - account::AccountType::ACCOUNT_TYPE_NORMAL; + account::AccountType::ACCOUNT_TYPE_NORMAL; bool chaseMode = false; bool secureMode = true; diff --git a/src/protocolgame.cpp b/src/protocolgame.cpp index c47f928f6..112c78be2 100644 --- a/src/protocolgame.cpp +++ b/src/protocolgame.cpp @@ -792,6 +792,8 @@ void ProtocolGame::parseSetOutfit(NetworkMessage& msg) } if(msg.getBufferPosition() == startBufferPosition) { + uint8_t outfitType = 0; + outfitType = msg.getByte(); Outfit_t newOutfit; newOutfit.lookType = msg.get(); newOutfit.lookHead = msg.getByte(); @@ -799,9 +801,16 @@ void ProtocolGame::parseSetOutfit(NetworkMessage& msg) newOutfit.lookLegs = msg.getByte(); newOutfit.lookFeet = msg.getByte(); newOutfit.lookAddons = msg.getByte(); - newOutfit.lookMount = msg.get(); + if (outfitType == 0) { + newOutfit.lookMount = msg.get(); + } else if (outfitType == 1) { + //This value probably has something to do with try outfit variable inside outfit window dialog + //if try outfit is set to 2 it expects uint32_t value after mounted and disable mounts from outfit window dialog + newOutfit.lookMount = 0; + msg.get(); + } addGameTask(&Game::playerChangeOutfit, player->getID(), newOutfit); - } + } } void ProtocolGame::parseToggleMount(NetworkMessage& msg) @@ -1716,6 +1725,8 @@ void ProtocolGame::sendContainer(uint8_t cid, const Container* container, bool h msg.addByte(hasParent ? 0x01 : 0x00); + msg.addByte(0x00); // To-do: Depot Find (boolean) + msg.addByte(container->isUnlocked() ? 0x01 : 0x00); // Drag and drop msg.addByte(container->hasPagination() ? 0x01 : 0x00); // Pagination @@ -1750,6 +1761,7 @@ void ProtocolGame::sendShop(Npc* npc, const ShopInfoList& itemList) NetworkMessage msg; msg.addByte(0x7A); msg.addString(npc->getName()); + msg.add(3031); // TO-DO Coin used uint16_t itemsToSend = std::min(itemList.size(), std::numeric_limits::max()); msg.add(itemsToSend); @@ -1970,6 +1982,7 @@ void ProtocolGame::sendCoinBalance() msg.add(player->coinBalance); //total coins msg.add(player->coinBalance); //transferable coins + msg.add(0); // Tournament Coins writeToOutputBuffer(msg); } @@ -2569,10 +2582,13 @@ void ProtocolGame::sendPingBack() void ProtocolGame::sendDistanceShoot(const Position& from, const Position& to, uint8_t type) { NetworkMessage msg; - msg.addByte(0x85); + msg.addByte(0x83); msg.addPosition(from); - msg.addPosition(to); + msg.addByte(MAGIC_EFFECTS_CREATE_DISTANCEEFFECT); msg.addByte(type); + msg.addByte(static_cast(static_cast(static_cast(to.x) - static_cast(from.x)))); + msg.addByte(static_cast(static_cast(static_cast(to.y) - static_cast(from.y)))); + msg.addByte(MAGIC_EFFECTS_END_LOOP); writeToOutputBuffer(msg); } @@ -2585,7 +2601,9 @@ void ProtocolGame::sendMagicEffect(const Position& pos, uint8_t type) NetworkMessage msg; msg.addByte(0x83); msg.addPosition(pos); + msg.addByte(MAGIC_EFFECTS_CREATE_EFFECT); msg.addByte(type); + msg.addByte(MAGIC_EFFECTS_END_LOOP); writeToOutputBuffer(msg); } @@ -2770,7 +2788,7 @@ void ProtocolGame::sendAddCreature(const Creature* creature, const Position& pos msg.add(static_cast(g_config.getNumber(ConfigManager::STORE_COIN_PACKET))); msg.addByte(shouldAddExivaRestrictions ? 0x01 : 0x00); // exiva button enabled - // msg.addByte(0x01); // tournament button enabled + msg.addByte(0x00); // tournament button writeToOutputBuffer(msg); @@ -3035,9 +3053,11 @@ void ProtocolGame::sendOutfitWindow() NetworkMessage msg; msg.addByte(0xC8); + bool mounted = false; Outfit_t currentOutfit = player->getDefaultOutfit(); Mount* currentMount = g_game.mounts.getMountByID(player->getCurrentMount()); if (currentMount) { + mounted = (currentOutfit.lookMount == currentMount->clientId); currentOutfit.lookMount = currentMount->clientId; } @@ -3088,8 +3108,8 @@ void ProtocolGame::sendOutfitWindow() msg.addByte(0x00); } - msg.addByte(0x00); - msg.addByte(0x00); + msg.addByte(0x00); //Try outfit + msg.addByte(mounted ? 0x01 : 0x00); writeToOutputBuffer(msg); } @@ -3444,6 +3464,10 @@ void ProtocolGame::AddCreature(NetworkMessage& msg, const Creature* creature, bo } } + if (creatureType == CREATURETYPE_PLAYER) { + msg.addByte(0); + } + msg.addByte(creature->getSpeechBubble()); msg.addByte(0xFF); // MARK_UNMARKED msg.addByte(0x00); // inspection type @@ -3521,10 +3545,9 @@ void ProtocolGame::AddPlayerSkills(NetworkMessage& msg) msg.add(player->getBaseCapacity()); // base total capacity } -void ProtocolGame::AddOutfit(NetworkMessage& msg, const Outfit_t& outfit) +void ProtocolGame::AddOutfit(NetworkMessage& msg, const Outfit_t& outfit, bool addMount/* = true*/) { msg.add(outfit.lookType); - if (outfit.lookType != 0) { msg.addByte(outfit.lookHead); msg.addByte(outfit.lookBody); @@ -3535,7 +3558,9 @@ void ProtocolGame::AddOutfit(NetworkMessage& msg, const Outfit_t& outfit) msg.addItemId(outfit.lookTypeEx); } - msg.add(outfit.lookMount); + if (addMount) { + msg.add(outfit.lookMount); + } } void ProtocolGame::addImbuementInfo(NetworkMessage& msg, uint32_t imbuid) diff --git a/src/protocolgame.h b/src/protocolgame.h index dee03e861..3a41a1306 100644 --- a/src/protocolgame.h +++ b/src/protocolgame.h @@ -332,7 +332,7 @@ class ProtocolGame final : public Protocol void AddCreature(NetworkMessage& msg, const Creature* creature, bool known, uint32_t remove); void AddPlayerStats(NetworkMessage& msg); - void AddOutfit(NetworkMessage& msg, const Outfit_t& outfit); + void AddOutfit(NetworkMessage& msg, const Outfit_t& outfit, bool addMount = true); void AddPlayerSkills(NetworkMessage& msg); void sendBlessStatus(); void sendPremiumTrigger(); diff --git a/src/tile.cpp b/src/tile.cpp index 81bf8fd0c..e538b9850 100644 --- a/src/tile.cpp +++ b/src/tile.cpp @@ -1647,3 +1647,22 @@ Item* Tile::getUseItem(int32_t index) const return nullptr; } + +Item* Tile::getDoorItem() const +{ + const TileItemVector* items = getItemList(); + if (!items || items->size() == 0) { + return ground; + } + + if (items) { + for (Item* item : *items) { + const ItemType& it = Item::items[item->getID()]; + if (it.isDoor()) { + return item; + } + } + } + + return nullptr; +} diff --git a/src/tile.h b/src/tile.h index 6b3dfc5e0..abd6b391b 100644 --- a/src/tile.h +++ b/src/tile.h @@ -279,6 +279,7 @@ class Tile : public Cylinder } Item* getUseItem(int32_t index) const; + Item* getDoorItem() const; Item* getGround() const { return ground;