Ir para conteúdo
Propaganda

TFS 1.x Salvar backpacks abertas e enviar ao logar


Posts Recomendados

  • Administrador

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

  • Like 21
Link para o comentário
Compartilhar em outros sites

Participe da Conversa

Você pode postar agora e se cadastrar mais tarde. Cadastre-se Agora para publicar com Sua Conta.

Visitante
Responder

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.

×
  • Criar Novo...