Administrador gutinha 1.280 Postado 5 de Dezembro 2023 Administrador Compartilhar Postado 5 de Dezembro 2023 Salve rapaziada, esse tutorial é pra você que odeia ter que ficar abrindo suas bags toda vez ao relogar no client. Bora lá, na source do server 1° Passo Spoiler No arquivo enums.h, procure por enum itemAttrTypes : uint32_t Dentro dele, no penúltimo item adicione ITEM_ATTRIBUTE_AUTOOPEN = 1 << 25, Vai ficar mais ou menos assim ITEM_ATTRIBUTE_DOORID = 1 << 22, ITEM_ATTRIBUTE_DECAYTO = 1 << 23, ITEM_ATTRIBUTE_WRAPID = 1 << 24, ITEM_ATTRIBUTE_AUTOOPEN = 1 << 25, ITEM_ATTRIBUTE_CUSTOM = 1U << 31 }; 2° Passo Spoiler No arquivo iologindata.cpp, procure pelo método bool IOLoginData::saveItems(const Player* player, const ItemBlockList& itemList, DBInsert& query_insert, PropWriteStream& propWriteStream) e altere ele para bool IOLoginData::saveItems(const Player* player, const ItemBlockList& itemList, DBInsert& query_insert, PropWriteStream& propWriteStream, std::map<Container*, int>& openContainers) Dentro do método procure por Item* item = it.second; ++runningId; E adicione em baixo if (Container* container = item->getContainer()) { auto it = openContainers.find(container); if (it == openContainers.end()) { container->resetAutoOpen(); } else { container->setAutoOpen(it->second); } queue.emplace_back(container, runningId); } Ficando mais ou menos assim for (const auto& it : itemList) { int32_t pid = it.first; Item* item = it.second; ++runningId; if (Container* container = item->getContainer()) { auto it = openContainers.find(container); if (it == openContainers.end()) { container->resetAutoOpen(); } else { container->setAutoOpen(it->second); } queue.emplace_back(container, runningId); } propWriteStream.clear(); item->serializeAttr(propWriteStream); Agora procure por if (!query_insert.addRow(ss)) { return false; } E em baixo dele remova o seguinte código if (Container* container = item->getContainer()) { queue.emplace_back(container, runningId); } Procure por for (Item* item : container->getItemList()) { ++runningId; Container* subContainer = item->getContainer(); if (subContainer) { E adicione dentro do if esse código auto it = openContainers.find(subContainer); if (it == openContainers.end()) { subContainer->resetAutoOpen(); } else { subContainer->setAutoOpen(it->second); } Ficando mais ou menos assim for (Item* item : container->getItemList()) { ++runningId; Container* subContainer = item->getContainer(); if (subContainer) { auto it = openContainers.find(subContainer); if (it == openContainers.end()) { subContainer->resetAutoOpen(); } else { subContainer->setAutoOpen(it->second); } queue.emplace_back(subContainer, runningId); } Procure por //item saving E adicione em baixo std::map<Container*, int> openContainers; for (auto container : player->getOpenContainers()) { if (!container.second.container) continue; openContainers[container.second.container] = container.first; } Ficando mais ou menos assim //item saving std::map<Container*, int> openContainers; for (auto container : player->getOpenContainers()) { if (!container.second.container) continue; openContainers[container.second.container] = container.first; } query << "DELETE FROM `player_items` WHERE `player_id` = " << player->getGUID(); if (!db.executeQuery(query.str())) { return false; Procure por todos if (!saveItems(player, itemList, itemsQuery, propWriteStream)) { E substitua todos por if (!saveItems(player, itemList, itemsQuery, propWriteStream, openContainers)) { Agora no arquivo iologindata.h, procure por static bool saveItems(const Player* player, const ItemBlockList& itemList, DBInsert& query_insert, PropWriteStream& propWriteStream); E substitua por static bool saveItems(const Player* player, const ItemBlockList& itemList, DBInsert& query_insert, PropWriteStream& propWriteStream, std::map<Container*, int>& openContainers); 3° Passo Spoiler Agora no arquivo item.cpp, procure por Item::readAttr(AttrTypes_t attr, PropStream& propStream) Dentro do método procure por case ATTR_WRAPID: Em baixo do bloco de código, adicione case ATTR_AUTOOPEN: { int8_t autoOpen; if (!propStream.read<int8_t>(autoOpen)) { return ATTR_READ_ERROR; } setIntAttr(ITEM_ATTRIBUTE_AUTOOPEN, autoOpen); break; } Ficando mais ou menos assim case ATTR_WRAPID: { uint16_t wrapId; if (!propStream.read<uint16_t>(wrapId)) { return ATTR_READ_ERROR; } setIntAttr(ITEM_ATTRIBUTE_WRAPID, wrapId); break; } case ATTR_AUTOOPEN: { int8_t autoOpen; if (!propStream.read<int8_t>(autoOpen)) { return ATTR_READ_ERROR; } setIntAttr(ITEM_ATTRIBUTE_AUTOOPEN, autoOpen); break; } Procure pelo método void Item::serializeAttr(PropWriteStream& propWriteStream) const e dentro do método procure por if (hasAttribute(ITEM_ATTRIBUTE_WRAPID)) { propWriteStream.write<uint8_t>(ATTR_WRAPID); propWriteStream.write<uint16_t>(getIntAttr(ITEM_ATTRIBUTE_WRAPID)); } Em baixo dele adicione if (hasAttribute(ITEM_ATTRIBUTE_AUTOOPEN)) { propWriteStream.write<uint8_t>(ATTR_AUTOOPEN); propWriteStream.write<int8_t>(getIntAttr(ITEM_ATTRIBUTE_AUTOOPEN)); } Agora em item.h procure por enum AttrTypes_t { e no final do enum adicione ATTR_AUTOOPEN = 37 Ficando mais ou menos assim ATTR_DECAYTO = 35, ATTR_WRAPID = 36, ATTR_AUTOOPEN = 37 Procure por const static uint32_t intAttributeTypes E adicione no final | ITEM_ATTRIBUTE_AUTOOPEN; Ficando mais ou menos assim const static uint32_t intAttributeTypes = ITEM_ATTRIBUTE_ACTIONID | ITEM_ATTRIBUTE_UNIQUEID | ITEM_ATTRIBUTE_DATE | ITEM_ATTRIBUTE_WEIGHT | ITEM_ATTRIBUTE_ATTACK | ITEM_ATTRIBUTE_DEFENSE | ITEM_ATTRIBUTE_EXTRADEFENSE | ITEM_ATTRIBUTE_ARMOR | ITEM_ATTRIBUTE_HITCHANCE | ITEM_ATTRIBUTE_SHOOTRANGE | ITEM_ATTRIBUTE_OWNER | ITEM_ATTRIBUTE_DURATION | ITEM_ATTRIBUTE_DECAYSTATE | ITEM_ATTRIBUTE_CORPSEOWNER | ITEM_ATTRIBUTE_CHARGES | ITEM_ATTRIBUTE_FLUIDTYPE | ITEM_ATTRIBUTE_DOORID | ITEM_ATTRIBUTE_DECAYTO | ITEM_ATTRIBUTE_WRAPID | ITEM_ATTRIBUTE_AUTOOPEN; Procure por bool isRemoved() const override { return !parent || parent->isRemoved(); } E adicione em baixo int8_t getAutoOpen() { if (hasAttribute(ITEM_ATTRIBUTE_AUTOOPEN)) { return getIntAttr(ITEM_ATTRIBUTE_AUTOOPEN); } return -1; } void setAutoOpen(int8_t value) { setIntAttr(ITEM_ATTRIBUTE_AUTOOPEN, value); } void resetAutoOpen() { removeAttribute(ITEM_ATTRIBUTE_AUTOOPEN); } 4° Passo Spoiler Agora em player.cpp, no final do arquivo. Adicione void Player::autoOpenContainers() { for (int32_t i = CONST_SLOT_FIRST; i <= CONST_SLOT_LAST; i++) { Item* item = inventory[i]; if (!item) { continue; } if (Container* container = item->getContainer()) { if (container->getAutoOpen() >= 0) { addContainer(container->getAutoOpen(), container); onSendContainer(container); } for (ContainerIterator it = container->iterator(); it.hasNext(); it.advance()) { if (Container* subContainer = (*it)->getContainer()) { if (subContainer->getAutoOpen() >= 0) { addContainer(subContainer->getAutoOpen(), subContainer); onSendContainer(subContainer); } } } } } } Em player.h, procure por void onUpdateTileItem(const Tile* tile, const Position& pos, const Item* oldItem, const ItemType& oldType, const Item* newItem, const ItemType& newType) override; Em cima adicione void autoOpenContainers(); Procure por bool hasLearnedInstantSpell(const std::string& spellName) const; Adicione em baixo const std::map<uint8_t, OpenContainer>& getOpenContainers() const { return openContainers; } 5° Passo Spoiler Em protocolgame.cpp procure por void ProtocolGame::login(const std::string& name, uint32_t accountId, OperatingSystem_t operatingSystem) Dentro do método procure por if (operatingSystem >= CLIENTOS_OTCLIENT_LINUX) { Adicione em cima player->autoOpenContainers(); Procure por void ProtocolGame::connect(uint32_t playerId, OperatingSystem_t operatingSystem) Dentro do método procure por sendAddCreature(player, player->getPosition(), 0, false); E em baixo adicione player->autoOpenContainers(); Feito isso, basta compilar e testar. Código retirado do github do v8 > This is the hidden content, please Entre ou Cadastre-se 21 Citar Link para o comentário Compartilhar em outros sites Mais opções de compartilhamento...
Posts Recomendados
Participe da Conversa
Você pode postar agora e se cadastrar mais tarde. Cadastre-se Agora para publicar com Sua Conta.