Ir para conteúdo
  • Cadastre-se

8.5x - 8.7x Baiak-PvP [8.60] - Watch System + Cast Look


Posts Recomendados

  • Respostas 68
  • Created
  • Última resposta

Top Posters In This Topic

Top Posters In This Topic

Popular Posts

Baiak-PvP A algum tempo atrás este servidor esteve online e atingiu um grande numero de jogadores, foi projeto de um amigo meu, porem com o passar do tempo ele decidiu seguir adiante com ou

Bem simples de resolver ao criar o banco de dados para o server coloca como: utf8mb4_unicode_ci Galera vou fazer a minha boa ação de fim de ano.   Explicando: essa base do Baiak PVP é r

Alguma alma poderia colocar o download da source compilada para windows?

Posted Images

Sempre quando tento importa a TD que veio no servidor pelo phpmyadmin da isso.

 

consulta SQL:

/*!40101 SET NAMES utf8mb4 */;
 

Mensagens do MySQL : 

#1115 - Unknown character set: 'utf8mb4'

Meu novo projeto.

 

http://oi58.tinypic.com/2yplmrk.jpg

 

 

 

Link para o post
Compartilhar em outros sites
Em 30/12/2020 em 07:28, paulo thush disse:

Sempre quando tento importa a TD que veio no servidor pelo phpmyadmin da isso.

 

consulta SQL:

/*!40101 SET NAMES utf8mb4 */;
 

Mensagens do MySQL : 

#1115 - Unknown character set: 'utf8mb4'

Bem simples de resolver ao criar o banco de dados para o server coloca como: utf8mb4_unicode_ci

Galera vou fazer a minha boa ação de fim de ano.

 

Explicando: essa base do Baiak PVP é realmente muito boa e bem estável eu estou a quase 2 meses ininterruptos com o server online e sem problemas de crash, rollback ou qualquer coisa do tipo, já testei diversos bugs conhecidos de derrubar servidor e nada acontece com essas sources, é uma base realmente muito sólida e ótima para um servidor 8.6.

 

Porém recentemente descobri um bug que é o seguinte, ao player utilizar !leavehouse ou perder a house e afins, os seus itens não vão para o depot, eles simplesmente somem.

 

O distro quem compilou foi eu com base nas sources disponibilizadas aqui mesmo, no caso compilei para ubuntu 14.04.

 

Ao testar no testserver que possuo, e utilizando outra distro com sources acredito ser de outra revisão do TFS 0.4 esse bug não acontece, os itens são entregue normalmente ao depot do jogador.

 

Descobri então que se trata de um bug nas sources, no caso a house.cpp

 

Fiz uma alteração no arquivo e após isso ficou 100%, para tal vou disponibilizar o arquivo editado aqui para vocês.

 

Troque todo o código do arquivo house.cpp por esse:

 

////////////////////////////////////////////////////////////////////////
// OpenTibia - an opensource roleplaying game
////////////////////////////////////////////////////////////////////////
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
////////////////////////////////////////////////////////////////////////
#include "otpch.h"
#include "house.h"

#include "tools.h"
#include "database.h"
#include "beds.h"
#include "town.h"

#include "iologindata.h"
#include "ioguild.h"
#include "iomapserialize.h"

#include "configmanager.h"
#include "game.h"

extern ConfigManager g_config;
extern Game g_game;

House::House(uint32_t houseId)
{
	guild = pendingTransfer = isprotected = false;
	name = "OTX headquarter (Flat 1, Area 42)";
	entry = Position();
	id = houseId;
	rent = price = townId = paidUntil = owner = rentWarnings = lastWarning = 0;
	syncFlags = HOUSE_SYNC_NAME | HOUSE_SYNC_TOWN | HOUSE_SYNC_SIZE | HOUSE_SYNC_PRICE | HOUSE_SYNC_RENT | HOUSE_SYNC_GUILD;
}

void House::addTile(HouseTile* tile)
{
	tile->setFlag(TILESTATE_PROTECTIONZONE);
	houseTiles.push_back(tile);
}

void House::addBed(BedItem* bed)
{
	bedsList.push_back(bed);
	bed->setHouse(this);
}

void House::addDoor(Door* door)
{
	door->addRef();
	doorList.push_back(door);

	door->setHouse(this);
	updateDoorDescription("", door);
}

void House::removeDoor(Door* door)
{
	HouseDoorList::iterator it = std::find(doorList.begin(), doorList.end(), door);
	if(it != doorList.end())
	{
		(*it)->unRef();
		doorList.erase(it);
	}
}

Door* House::getDoorByNumber(uint8_t doorId) const
{
	for(HouseDoorList::const_iterator it = doorList.begin(); it != doorList.end(); ++it)
	{
		if((*it)->getDoorId() == doorId)
			return (*it);
	}

	return NULL;
}

Door* House::getDoorByPosition(const Position& pos)
{
	for(HouseDoorList::iterator it = doorList.begin(); it != doorList.end(); ++it)
	{
		if((*it)->getPosition() == pos)
			return (*it);
	}

	return NULL;
}

void House::setOwner(uint32_t guid)
{
	owner = guid;
	updateDoorDescription();
}

bool House::setOwnerEx(uint32_t guid, bool transfer)
{
	if(owner == guid)
		return true;

	if(isGuild() && guid)
	{
		Player* player = g_game.getPlayerByGuidEx(guid);
		if(!player)
			return false;

		guid = player->getGuildId();
		if(player->isVirtual())
			delete player;
	}

	if(owner)
	{
		rentWarnings = paidUntil = 0;
		if(transfer)
			clean();

		setAccessList(SUBOWNER_LIST, "", !transfer);
		setAccessList(GUEST_LIST, "", !transfer);
		for(HouseDoorList::iterator it = doorList.begin(); it != doorList.end(); ++it)
			(*it)->setAccessList("");
	}

	setOwner(guid);
	lastWarning = guid ? time(NULL) : 0;

	Database* db = Database::getInstance();
	DBTransaction trans;
	if(!trans.begin())
		return false;

	IOMapSerialize::getInstance()->saveHouse(db, this);
	return trans.commit();
}

bool House::isGuild() const
{
	return g_config.getBool(ConfigManager::GUILD_HALLS) && guild;
}

bool House::isBidded() const
{
	Database* db = Database::getInstance();
	DBResult_ptr result;

	DBQuery query;
	query << "SELECT `house_id` FROM `house_auctions` WHERE `house_id` = " << id << " LIMIT 1";
	if(!(result = db->storeQuery(query.str())))
		return false;

	return true;
}

void House::updateDoorDescription(std::string _name/* = ""*/, Door* door/* = NULL*/)
{
	std::string tmp = "house";
	if(isGuild())
		tmp = "hall";

	char houseDescription[200];
	if(owner)
	{
		if(isGuild())
			IOGuild::getInstance()->getGuildById(_name, owner);
		else if(_name.empty())
			IOLoginData::getInstance()->getNameByGuid(owner, _name);

		sprintf(houseDescription, "It belongs to %s '%s'. %s owns this %s.", tmp.c_str(), name.c_str(), _name.c_str(), tmp.c_str());
	}
	else
		sprintf(houseDescription, "It belongs to %s '%s'. Nobody owns this %s. It costs %d gold coins.", tmp.c_str(), name.c_str(), tmp.c_str(), price);

	if(!door)
	{
		for(HouseDoorList::iterator it = doorList.begin(); it != doorList.end(); ++it)
			(*it)->setSpecialDescription(houseDescription);
	}
	else
		door->setSpecialDescription(houseDescription);
}

void House::removePlayer(Player* player, bool ignoreRights)
{
	if(!ignoreRights && player->hasFlag(PlayerFlag_CanEditHouses))
		return;

	Position curPos = player->getPosition(), newPos = g_game.getClosestFreeTile(player, entry, false, false);
	if(g_game.internalTeleport(player, newPos, false) == RET_NOERROR && !player->isGhost())
	{
		g_game.addMagicEffect(curPos, MAGIC_EFFECT_POFF);
		g_game.addMagicEffect(newPos, MAGIC_EFFECT_TELEPORT);
	}
}

void House::removePlayers(bool ignoreInvites)
{
	PlayerVector kickList;
	for(HouseTileList::iterator it = houseTiles.begin(); it != houseTiles.end(); ++it)
	{
		CreatureVector* creatures = (*it)->getCreatures();
		if(!creatures)
			continue;

		Player* player = NULL;
		for(CreatureVector::iterator cit = creatures->begin(); cit != creatures->end(); ++cit)
		{
			if((player = (*cit)->getPlayer()) && !player->isRemoved()
				&& (ignoreInvites || !isInvited(player)))
				kickList.push_back(player);
		}
	}

	if(kickList.empty())
		return;

	for(PlayerVector::iterator it = kickList.begin(); it != kickList.end(); ++it)
		removePlayer((*it), false);
}

bool House::kickPlayer(Player* player, Player* target)
{
	if(!target || target->isRemoved())
		return false;

	HouseTile* houseTile = target->getTile()->getHouseTile();
	if(!houseTile || houseTile->getHouse() != this)
		return false;

	bool self = player == target;
	if(getHouseAccessLevel(player) < getHouseAccessLevel(target) && !self)
		return false;

	removePlayer(target, self);
	return true;
}

void House::clean()

{

    for(HouseBedList::iterator bit = bedsList.begin(); bit != bedsList.end(); ++bit)

    {

        if((*bit)->getSleeper())

            (*bit)->wakeUp();

    }


    removePlayers(true);

    transferToDepot();

}


bool House::transferToDepot()

{

    if(!townId)

        return false;


    Player* player = NULL;

    if(owner)

    {

        uint32_t tmp = owner;

        if(isGuild() && !IOGuild::getInstance()->swapGuildIdToOwner(tmp))

            tmp = 0;


        if(tmp)

            player = g_game.getPlayerByGuidEx(tmp);

    }


    Item* item = NULL;

    Container* tmpContainer = NULL;


    ItemList moveList;

    for(HouseTileList::iterator it = houseTiles.begin(); it != houseTiles.end(); ++it)

    {

        for(uint32_t i = 0; i < (*it)->getThingCount(); ++i)

        {

            if(!(item = (*it)->__getThing(i)->getItem()))

                continue;


            if(item->isPickupable())

                moveList.push_back(item);

            else if((tmpContainer = item->getContainer()))

            {

                for(ItemList::const_iterator it = tmpContainer->getItems(); it != tmpContainer->getEnd(); ++it)

                    moveList.push_back(*it);

            }

        }

    }


    if(player)

    {

        Depot* depot = player->getDepot(townId, true);

        for(ItemList::iterator it = moveList.begin(); it != moveList.end(); ++it)

            g_game.internalMoveItem(NULL, (*it)->getParent(), depot, INDEX_WHEREEVER, (*it), (*it)->getItemCount(), NULL, FLAG_NOLIMIT);


        if(player->isVirtual())

        {

            IOLoginData::getInstance()->savePlayer(player);

            delete player;

        }

    }

    else

    {

        for(ItemList::iterator it = moveList.begin(); it != moveList.end(); ++it)

            g_game.internalRemoveItem(NULL, (*it), (*it)->getItemCount(), false, FLAG_NOLIMIT);

    }


    return true;

}


bool House::isInvited(const Player* player)
{
	return getHouseAccessLevel(player) != HOUSE_NO_INVITED;
}

AccessHouseLevel_t House::getHouseAccessLevel(const Player* player)
{
	if(!player)
		return HOUSE_NO_INVITED;

	if(player->hasFlag(PlayerFlag_CanEditHouses))
		return HOUSE_OWNER;

	if(!owner)
		return HOUSE_NO_INVITED;

	AccessHouseLevel_t tmp = HOUSE_NO_INVITED;
	if(isGuild())
	{
		if(player->getGuildId() == owner)
		{
			switch(player->getGuildLevel())
			{
				case GUILDLEVEL_LEADER:
					return HOUSE_OWNER;
				case GUILDLEVEL_VICE:
					return HOUSE_SUBOWNER;
				default:
					tmp = HOUSE_GUEST;
			}
		}
	}
	else if(player->getGUID() == owner/* || player->marriage == owner*/)
		return HOUSE_OWNER;

	if(subOwnerList.isInList(player))
		return HOUSE_SUBOWNER;

	if(guestList.isInList(player))
		return HOUSE_GUEST;

	return tmp;
}

bool House::canEditAccessList(uint32_t listId, const Player* player)
{
	switch(getHouseAccessLevel(player))
	{
		case HOUSE_OWNER:
			return true;
		case HOUSE_SUBOWNER:
			return listId == GUEST_LIST;
		default:
			break;
	}

	return false;
}

bool House::getAccessList(uint32_t listId, std::string& list) const
{
	if(listId == GUEST_LIST)
	{
		guestList.getList(list);
		return true;
	}

	if(listId == SUBOWNER_LIST)
	{
		subOwnerList.getList(list);
		return true;
	}

	if(Door* door = getDoorByNumber(listId))
		return door->getAccessList(list);

	#ifdef __DEBUG_HOUSES__
	std::clog << "[Failure - House::getAccessList] door == NULL, listId = " << listId <<std::endl;
	#endif
	return false;
}

void House::setAccessList(uint32_t listId, const std::string& textlist, bool teleport/* = true*/)
{
	if(listId == GUEST_LIST)
		guestList.parseList(textlist);
	else if(listId == SUBOWNER_LIST)
		subOwnerList.parseList(textlist);
	else
	{
		if(Door* door = getDoorByNumber(listId))
			door->setAccessList(textlist);
		#ifdef __DEBUG_HOUSES__
		else
			std::clog << "[Failure - House::setAccessList] door == NULL, listId = " << listId <<std::endl;
		#endif

		return;
	}

	if(teleport)
		removePlayers(false);
}

TransferItem* TransferItem::createTransferItem(House* house)
{
	TransferItem* transferItem = new TransferItem(house);
	transferItem->addRef();
	transferItem->setID(ITEM_HOUSE_TRANSFER);

	char buffer[150];
	sprintf(buffer, "It is a %s transfer document for '%s'.", house->isGuild() ? "guild hall" : "house", house->getName().c_str());
	transferItem->setSpecialDescription(buffer);

	transferItem->setSubType(1);
	return transferItem;
}

bool TransferItem::onTradeEvent(TradeEvents_t event, Player* owner, Player* seller)
{
	switch(event)
	{
		case ON_TRADE_TRANSFER:
		{
			if(house)
				house->setOwnerEx(owner->getGUID(), true);

			g_game.internalRemoveItem(NULL, this, getItemCount());
			seller->transferContainer.setParent(NULL);
			break;
		}

		case ON_TRADE_CANCEL:
		{
			owner->transferContainer.setParent(NULL);
			owner->transferContainer.__removeThing(this, getItemCount());
			g_game.freeThing(this);
			break;
		}

		default:
			return false;
	}

	return true;
}

void AccessList::getList(std::string& _list) const
{
	_list = list;
}

bool AccessList::parseList(const std::string& _list)
{
	playerList.clear();
	guildList.clear();
	expressionList.clear();
	regexList.clear();

	list = _list;
	if(_list.empty())
		return true;

	std::stringstream listStream(_list);
	std::string line;
	while(getline(listStream, line))
	{
		trimString(line);
		trim_left(line, "\t");

		trim_right(line, "\t");
		trimString(line);

		toLowerCaseString(line);
		if(line.empty())
			break;
		
		if(line.substr(0, 1) == "#" || line.length() > 100)
			continue;

		if(line.find("@") != std::string::npos)
		{
			std::string::size_type pos = line.find("@");
			addGuild(line.substr(pos + 1), line.substr(0, pos));
		}
		else if(line.find("!") != std::string::npos || line.find("*") != std::string::npos || line.find("?") != std::string::npos)
			addExpression(line);
		else
			addPlayer(line);
	}

	return true;
}

bool AccessList::isInList(const Player* player)
{
	std::string name = player->getName();
	boost::cmatch what;
	try
	{
		toLowerCaseString(name);
		for(RegexList::iterator it = regexList.begin(); it != regexList.end(); ++it)
		{
			if(boost::regex_match(name.c_str(), what, it->first))
				return it->second;
		}
	}
	catch(...) {}

	if(playerList.find(player->getGUID()) != playerList.end())
		return true;

	for(GuildList::iterator git = guildList.begin(); git != guildList.end(); ++git)
	{
		if(git->first == player->getGuildId() && ((uint32_t)git->second == player->getRankId() || git->second == -1))
			return true;
	}

	return false;
}

bool AccessList::addPlayer(std::string& name)
{
	std::string tmp = name;
	uint32_t guid;
	if(!IOLoginData::getInstance()->getGuidByName(guid, tmp) || playerList.find(guid) != playerList.end())
		return false;

	playerList.insert(guid);
	return true;
}

bool AccessList::addGuild(const std::string& guildName, const std::string& rankName)
{
	uint32_t guildId;
	if(!IOGuild::getInstance()->getGuildId(guildId, guildName))
		return false;

	std::string tmp = rankName;
	int32_t rankId = IOGuild::getInstance()->getRankIdByName(guildId, tmp);
	if(!rankId && (tmp.find("?") == std::string::npos || tmp.find("!") == std::string::npos || tmp.find("*") == std::string::npos))
		rankId = -1;

	if(!rankId)
		return false;

	for(GuildList::iterator git = guildList.begin(); git != guildList.end(); ++git)
	{
		if(git->first == guildId && git->second == rankId)
			return true;
	}

	guildList.push_back(std::make_pair(guildId, rankId));
	return true;
}

bool AccessList::addExpression(const std::string& expression)
{
	for(ExpressionList::iterator it = expressionList.begin(); it != expressionList.end(); ++it)
	{
		if((*it) == expression)
			return false;
	}

	std::string out, meta = ".[{}()\\+|^$";
	for(std::string::const_iterator it = expression.begin(); it != expression.end(); ++it)
	{
		if(meta.find(*it) != std::string::npos)
			out += "\\";

		out += (*it);
	}

	replaceString(out, "**", "");
	replaceString(out, "*", ".*");
	replaceString(out, "?", ".?");

	try
	{
		if(out.length() > 0)
		{
			expressionList.push_back(out);
			if(out.substr(0, 1) == "!")
			{
				if(out.length() > 1)
					regexList.push_front(std::make_pair(boost::regex(out.substr(1)), false));
			}
			else
				regexList.push_back(std::make_pair(boost::regex(out), true));
		}
	}
	catch(...) {}
	return true;
}

Door::~Door()
{
	delete accessList;
}

Attr_ReadValue Door::readAttr(AttrTypes_t attr, PropStream& propStream)
{
	if(attr != ATTR_HOUSEDOORID)
		return Item::readAttr(attr, propStream);

	uint8_t _doorId = 0;
	if(!propStream.getByte(_doorId))
		return ATTR_READ_ERROR;

	doorId = _doorId;
	return ATTR_READ_CONTINUE;
}

void Door::copyAttributes(Item* item)
{
	Item::copyAttributes(item);
	if(Door* door = item->getDoor())
	{
		doorId = door->getDoorId();
		std::string list;
		if(door->getAccessList(list))
			setAccessList(list);
	}
}

void Door::onRemoved()
{
	Item::onRemoved();
	if(house)
		house->removeDoor(this);
}

bool Door::canUse(const Player* player)
{
	if(!house || house->getHouseAccessLevel(player) >= HOUSE_SUBOWNER)
		return true;

	return accessList->isInList(player);
}

void Door::setHouse(House* _house)
{
	if(house)
		return;

	house = _house;
	if(!accessList)
		accessList = new AccessList();
}

bool Door::getAccessList(std::string& list) const
{
	if(!house)
		return false;

	accessList->getList(list);
	return true;
}

void Door::setAccessList(const std::string& textlist)
{
	if(!accessList)
		accessList = new AccessList();

	accessList->parseList(textlist);
}

Houses::Houses()
{
	rentPeriod = RENTPERIOD_NEVER;
	std::string strValue = asLowerCaseString(g_config.getString(ConfigManager::HOUSE_RENT_PERIOD));
	if(strValue == "yearly")
		rentPeriod = RENTPERIOD_YEARLY;
	else if(strValue == "monthly")
		rentPeriod = RENTPERIOD_MONTHLY;
	else if(strValue == "weekly")
		rentPeriod = RENTPERIOD_WEEKLY;
	else if(strValue == "daily")
		rentPeriod = RENTPERIOD_DAILY;
}

bool Houses::loadFromXml(std::string filename)
{
	xmlDocPtr doc = xmlParseFile(filename.c_str());
	if(!doc)
	{
		std::clog << "[Warning - Houses::loadFromXml] Cannot load houses file." << std::endl;
		std::clog << getLastXMLError() << std::endl;
		return false;
	}

	xmlNodePtr houseNode, root = xmlDocGetRootElement(doc);
	if(xmlStrcmp(root->name,(const xmlChar*)"houses"))
	{
		std::clog << "[Error - Houses::loadFromXml] Malformed houses file." << std::endl;
		xmlFreeDoc(doc);
		return false;
	}

	int32_t intValue;
	std::string strValue;

	houseNode = root->children;
	while(houseNode)
	{
		if(xmlStrcmp(houseNode->name,(const xmlChar*)"house"))
		{
			houseNode = houseNode->next;
			continue;
		}

		int32_t houseId = 0;
		if(!readXMLInteger(houseNode, "houseid", houseId))
		{
			std::clog << "[Error - Houses::loadFromXml] Could not read houseId" << std::endl;
			xmlFreeDoc(doc);
			return false;
		}

		House* house = Houses::getInstance()->getHouse(houseId);
		if(!house)
		{
			std::clog << "[Error - Houses::loadFromXml] Unknown house with id: " << houseId << std::endl;
			xmlFreeDoc(doc);
			return false;
		}

		Position entry(0, 0, 0);
		if(readXMLInteger(houseNode, "entryx", intValue))
			entry.x = intValue;

		if(readXMLInteger(houseNode, "entryy", intValue))
			entry.y = intValue;

		if(readXMLInteger(houseNode, "entryz", intValue))
			entry.z = intValue;

		if(readXMLString(houseNode, "name", strValue))
			house->setName(strValue);
		else
			house->resetSyncFlag(House::HOUSE_SYNC_NAME);

		house->setEntry(entry);
		if(!entry.x || !entry.y)
		{
			std::clog << "[Warning - Houses::loadFromXml] House entry not set for: "
				<< house->getName() << " (" << houseId << ")" << std::endl;
		}

		if(readXMLInteger(houseNode, "townid", intValue))
			house->setTownId(intValue);
		else
			house->resetSyncFlag(House::HOUSE_SYNC_TOWN);

		if(readXMLInteger(houseNode, "size", intValue))
			house->setSize(intValue);
		else
			house->resetSyncFlag(House::HOUSE_SYNC_SIZE);

		if(readXMLString(houseNode, "guildhall", strValue))
			house->setGuild(booleanString(strValue));
		else
			house->resetSyncFlag(House::HOUSE_SYNC_GUILD);

		uint32_t rent = 0;
		if(readXMLInteger(houseNode, "rent", intValue))
			rent = intValue;

		uint32_t price = (house->getSize() + house->getBedsCount()) * g_config.getNumber(ConfigManager::HOUSE_PRICE);
		// we should let players to pay only for walkable tiles + beds as single units not two items.
		if(g_config.getBool(ConfigManager::HOUSE_RENTASPRICE) && rent)
			price = rent;

		house->setPrice(price);
		if(g_config.getBool(ConfigManager::HOUSE_PRICEASRENT))
			house->setRent(price);
		else
			house->setRent(rent);

		house->setOwner(0);
		houseNode = houseNode->next;
	}

	xmlFreeDoc(doc);
	return true;
}

void Houses::check()
{
	uint64_t start = OTSYS_TIME();
	std::clog << "> Checking houses..." << std::endl;

	time_t currentTime = time(NULL);
	for(HouseMap::iterator it = houseMap.begin(); it != houseMap.end(); ++it)
		payHouse(it->second, currentTime, 0);

	std::clog << "Houses checked in " << (OTSYS_TIME() - start) / (1000.) << " seconds." << std::endl;
}

bool Houses::payRent(Player* player, House* house, uint32_t bid, time_t _time/* = 0*/)
{
	if(rentPeriod == RENTPERIOD_NEVER || !house->getOwner() ||
		house->getPaidUntil() > _time || !house->getRent() ||
		player->hasCustomFlag(PlayerCustomFlag_IgnoreHouseRent))
		return true;

	Town* town = Towns::getInstance()->getTown(house->getTownId());
	if(!town)
		return false;

	bool paid = false;
	uint32_t amount = house->getRent() + bid;
	if(g_config.getBool(ConfigManager::BANK_SYSTEM) && player->balance >= amount)
	{
		player->balance -= amount;
		paid = true;
	}
	else if(Depot* depot = player->getDepot(town->getID(), true))
		paid = g_game.removeMoney(depot, amount, FLAG_NOLIMIT);

	if(!paid)
		return false;

	if(!_time)
		_time = time(NULL);

	uint32_t paidUntil = _time;
	switch(rentPeriod)
	{
		case RENTPERIOD_DAILY:
			paidUntil += 86400;
			break;
		case RENTPERIOD_WEEKLY:
			paidUntil += 7 * 86400;
			break;
		case RENTPERIOD_MONTHLY:
			paidUntil += 30 * 86400;
			break;
		case RENTPERIOD_YEARLY:
			paidUntil += 365 * 86400;
			break;
		default:
			break;
	}

	house->setLastWarning(0);
	house->setRentWarnings(0);

	house->setPaidUntil(paidUntil);
	return true;
}

bool Houses::payHouse(House* house, time_t _time, uint32_t bid)
{
	if(rentPeriod == RENTPERIOD_NEVER || !house->getOwner() ||
		house->getPaidUntil() > _time || !house->getRent())
		return true;

	Town* town = Towns::getInstance()->getTown(house->getTownId());
	if(!town)
		return false;

	uint32_t owner = house->getOwner();
	if(house->isGuild() && !IOGuild::getInstance()->swapGuildIdToOwner(owner))
	{
		house->setOwnerEx(0, true);
		return false;
	}

	std::string name;
	if(!IOLoginData::getInstance()->getNameByGuid(owner, name))
	{
		house->setOwnerEx(0, true);
		return false;
	}

	Player* player = g_game.getPlayerByNameEx(name);
	if(!player)
		return false;

	if(!player->isPremium() && g_config.getBool(ConfigManager::HOUSE_NEED_PREMIUM))
	{
		house->setOwnerEx(0, true);
		if(player->isVirtual())
			delete player;

		return false;
	}

	int32_t loginClean = g_config.getNumber(ConfigManager::HOUSE_CLEAN_OLD);
	if(loginClean && _time >= (player->getLastLogin() + loginClean))
	{
		house->setOwnerEx(0, true);
		if(player->isVirtual())
			delete player;

		return false;
	}

	if(payRent(player, house, bid, _time) || _time < (house->getLastWarning() + 86400))
	{
		if(player->isVirtual())
		{
			IOLoginData::getInstance()->savePlayer(player);
			delete player;
		}

		return true;
	}

	uint32_t warningsLimit = 7;
	switch(rentPeriod)
	{
		case RENTPERIOD_DAILY:
			warningsLimit = 1;
			break;
		case RENTPERIOD_WEEKLY:
			warningsLimit = 3;
			break;
		case RENTPERIOD_YEARLY:
			warningsLimit = 14;
			break;
		default:
			break;
	}

	uint32_t warnings = house->getRentWarnings();
	if(warnings >= warningsLimit)
	{
		house->setOwnerEx(0, true);
		if(player->isVirtual())
			delete player;

		return false;
	}

	if(Depot* depot = player->getDepot(town->getID(), true))
	{
		if(Item* letter = Item::CreateItem(ITEM_LETTER_STAMPED))
		{
			if(g_game.internalAddItem(NULL, depot, letter, INDEX_WHEREEVER, FLAG_NOLIMIT) == RET_NOERROR)
			{
				letter->setWriter(g_config.getString(ConfigManager::SERVER_NAME));
				letter->setDate(std::time(NULL));
				std::stringstream s;

				s << "Warning!\nThe ";
				switch(rentPeriod)
				{
					case RENTPERIOD_DAILY:
						s << "daily";
						break;
					case RENTPERIOD_WEEKLY:
						s << "weekly";
						break;
					case RENTPERIOD_MONTHLY:
						s << "monthly";
						break;
					case RENTPERIOD_YEARLY:
						s << "annual";
						break;
					default:
						break;
				}

				s << " rent of " << house->getRent() << " gold for your "
					<< (house->isGuild() ? "guild hall" : "house") << " \"" << house->getName()
					<< "\" has to be paid. Have it within " << (warningsLimit - warnings)
					<< " days or you will lose your " << (house->isGuild() ? "guild hall" : "house") << ".";

				letter->setText(s.str().c_str());
				if(player->isVirtual())
					IOLoginData::getInstance()->savePlayer(player);
			}

			else
				g_game.freeThing(letter);
		}
	}

	house->setLastWarning(_time);
	house->setRentWarnings(++warnings);
	if(player->isVirtual())
		delete player;

	return false;
}

House* Houses::getHouse(uint32_t houseId, bool add/*= false*/)
{
	HouseMap::iterator it = houseMap.find(houseId);
	if(it != houseMap.end())
		return it->second;

	if(!add)
		return NULL;

	houseMap[houseId] = new House(houseId);
	return houseMap[houseId];
}

House* Houses::getHouseByPlayer(Player* player)
{
	if(!player || player->isRemoved())
		return NULL;

	HouseTile* houseTile = player->getTile()->getHouseTile();
	if(!houseTile)
		return NULL;

	if(House* house = houseTile->getHouse())
		return house;

	return NULL;
}

House* Houses::getHouseByPlayerId(uint32_t playerId)
{
	for(HouseMap::iterator it = houseMap.begin(); it != houseMap.end(); ++it)
	{
		if(!it->second->isGuild() && it->second->getOwner() == playerId)
			return it->second;
	}

	return NULL;
}

House* Houses::getHouseByGuildId(uint32_t guildId)
{
	for(HouseMap::iterator it = houseMap.begin(); it != houseMap.end(); ++it)
	{
		if(it->second->isGuild() && it->second->getOwner() == guildId)
			return it->second;
	}

	return NULL;
}

uint32_t Houses::getHousesCount(uint32_t accId)
{
	Account account = IOLoginData::getInstance()->loadAccount(accId);
	uint32_t guid, count = 0;
	for(Characters::iterator it = account.charList.begin(); it != account.charList.end(); ++it)
	{
#ifndef __LOGIN_SERVER__
		if(IOLoginData::getInstance()->getGuidByName(guid, (*it)) && getHouseByPlayerId(guid))
#else
		if(IOLoginData::getInstance()->getGuidByName(guid, (std::string&)it->first) && getHouseByPlayerId(guid))
#endif
			count++;
	}

	return count;
}

Após recompile e o server não vai mais possuir este bug xD, feliz ano novo a todos!

Editado por vine96 (veja o histórico de edições)
Link para o post
Compartilhar em outros sites
  • 4 months later...
Em 07/05/2021 em 12:01, Dyego disse:

Alguém sabe porque ele fica dando shutdown? e quando abre ele está em close server?

eu sei resolver, chama no orçamento ksks

 

Link para o post
Compartilhar em outros sites
  • 1 month later...
Em 07/05/2021 em 12:01, Dyego disse:

Alguém sabe porque ele fica dando shutdown? e quando abre ele está em close server?

Pra resolver o shutdown eu criei um arquivo ./restart.sh 

Tutorial abaixo:

 

Para resolver o close server eu fui em globalevents>scripts>start.lua

e aonde tiver doSetGameState(GAMESTATE_CLOSED)

deixa assim --doSetGameState(GAMESTATE_CLOSED)

Aqui resolveu!

Editado por msousay.94 (veja o histórico de edições)
Link para o post
Compartilhar em outros sites
  • 2 months later...
  • 1 month later...

Alguém sabe quais são os itens donates do site? A database veio clean, então não tem nada adicionado ao site.. Os itens como Wand, Sword, Armor, legs, etc.. esses sei quais são, mas queria saber se existem outros items utilitários que entram no site como donate... Outra dúvida, alguém sabe dizer se é possível colocar o sistema de VIP direto pelo site? Em vez do player ter que dar user no item no jogo.

Link para o post
Compartilhar em outros sites
Em 09/10/2021 em 04:06, Kamolos disse:

qual fonte de trabalho operacional liunx otx este servidor versão ubuntu ou versão debian

A source e Otx porem ela pode ser compilada no ubuntu 14,16,18  

Link para o post
Compartilhar em outros sites
  • 1 month later...
  • 3 months later...
  • 4 weeks later...
Em 13/06/2021 em 22:56, msousay.94 disse:

Alguém sabe pq o server só abre como closedserver?

 

globalevents, start.lua

 

remover 

 

doSetGameState(GAMESTATE_CLOSED)

Link para o post
Compartilhar em outros sites

Participe da conversa

Você pode postar agora e se cadastrar mais tarde. Se você tem uma conta, faça o login para postar com sua conta.

Visitante
Responder

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

  Apenas 75 emojis são permitidos.

×   Seu link foi automaticamente incorporado.   Mostrar como link

×   Seu conteúdo anterior foi restaurado.   Limpar o editor

×   Não é possível colar imagens diretamente. Carregar ou inserir imagens do URL.

  • Quem Está Navegando   0 membros estão online

    Nenhum usuário registrado visualizando esta página.


  • Conteúdo Similar

    • Por Mateus Robeerto
      Vi que muitas pessoas estão reclamando e que não funciona, bugs, erros no console, etc. Então, resolvi baixar a base do Thunder feita por MovieBr, atualizei do TFS 1.3 para o TFS 1.5 e corrigi cerca de 80% dos problemas. No entanto, ainda não consigo encontrar alguns bugs. Quem encontrar os bugs pode me relatar pelo Discord: 82mateusroberto. Dependendo do meu dia, pode levar alguns dias para eu responder e corrigir ou não. Acredito que vocês conseguem corrigir os erros, apenas precisam aprender a consertá-los. Não é difícil. Aproveitem para usar como base do seu mapa ou mesmo do projeto Thunder futuramente! Seguem as imagens que mostram a implementação de montaria e modal widow.
       
      Obs: Alguns mapas/cavernas podem estar vazios por falta de adição. Eu não tinha boas ideias para adicionar, mas vocês podem adicionar ao seu gosto. Tenham uma boa utilização e sucesso com o projeto no futuro!
       
      https://www.mediafire.com/file/0jtn2slt2j67666/baiakthunder-master.rar/file
      https://www.mediafire.com/file/bougg0q6dlpu2fq/tfs+1.5+source.rar/file
      https://www.mediafire.com/file/yq1s63xo6np9v53/860.rar/file
       
      Este servidor só usa o OtClient. Abra o arquivo otclient/modules/game_feature/feature.lua e procure por esta linha.
      if (versão >= 860) then adicione abaixo e salve.. pronto
      g_game.enableFeature(GamePlayerMounts)  
       
      Aqui estão os GIFs
      https://imgur.com/UGdQoSS
      https://imgur.com/OwJ4hpp
      https://imgur.com/7sN1MaJ
       
       
       
      Para quem deseja usar uma gamestore personalizada, há uma disponível para TFS 1.5 e 8.6. Já a compartilhei há alguns dias. Dê uma olhada aqui.
       
       
    • Por GM Antica
      Olá galera tudo bem?
      Achei esse mapa aqui no fórum, porém ele nao estava funcional. Foi retirado alguns bugs visuais, e certificado que não ocorra PVP dentro dos Treiners:
      Modificações:
      ● Capacidade total = 76 players
      ● Treiners divididos com "Wall" para o bom funcionamento e evitar que ocorra mortes dentro dos Treiners...
      ● Paisagens refeitas, um andar "Lobby" foi adicionado para interação e comércio
      ● Teleport adicionado no final de cada corredor para uma possível extensão
      CRÉDITOS: Alissow + GM Antica
       
      Segue alguns Prints:







       
       
      Scan Vírus Total: https://www.virustotal.com/gui/file/456c5959bd38bd7bd61f8c46af1117e0425963da0f8e5afce0bf411bdd366171?nocache=1
       
      Download:
       
      Training Room 8.60 - by Alissow & GM Antica.rar
    • Por FeeTads
      Opa rapaziadaa beleza?
      Hoje estou disponibilizando uma source OTX 2, baseada na otx 2.x do mattyx - aqui, essa source que estou disponibilizando é um pouco diferente, com algumas features a mais do que a OTX padrão, como muitos sabem, a OTX serve apenas para abrir o seu OT, essa estou disponibilizando com algumas features, onde disponibilizei até scripts do TK, ou usando scripts do TK, tais como o autoloot na source do Naze, o projeto é pra Otserv 8.60. 
      Está sendo desenvolvido no github (projeto github) onde posto atualizações diárias do datapack e source. Vocês podem postar dúvidas, erros/bugs, dicas e qualquer outra coisa aqui no tópico ou no próprio github. Lembre-se de dar FOLLOW no projeto no github e SEGUIR o projeto aqui no fórum para acompanhar as atualizações.

      Edit
      systems Added:
      Max Absorb All: (protect SSA + Might Ring, você coloca o máximo de protect all que pode ser atingido, caso o player passe disso é ignorado, o maximo de protect vai ser o que está no config.lua)
      Commit max absorb all edit: fixed all system

      Delete Players With Monster Name: Deleta o player com nome de monstro, ou com nome proibido (alteravel pelo config.lua), caso vc deixe "deletePlayersWithMonsterName = false", irá apenas renomear o player aleatóriamente sem deleta-lo, ele não conseguirá logar com nome de monstro ou nome proibido.
      ps: Esse script pega o monster.xml todo, então mesmo que você adicione novos monstros, não precisar mexer em nada, ele ja vai pegar o novo monstro, mesmo sem precisar derrubar o Ot etc..
       
      deletePlayersWithMonsterName = true forbiddenNames = "gm;adm;cm;support;god;tutor;god ; god; adm;adm ; gm;gm ; cm;cm ;" --// other names here
      edit: 30/10
          modifyDamageInK = true   (essa função ativada irá modificar a saida do dano pra K, por exemplo 219000 > 219.0K / 2.000.000 > 2.00 KK).
          modifyExperienceInK = true  (esas função também mudará a saida normal pra K, isso é bom em high EXP pra arrumar aquela exp "-2147483647", de muita EXP, irá mudar pra "+2.14 Bi Exp").

      17/01 Last Changes:
      displayBroadcastLog = true - Desabilita os logs de broadcast do server na distro, aqueles logs de eventos etc... deixa a distro mais limpa. (by kizuno18)
      enableCriticalAndDodgeSource = true - (Sistema de Dodge E Critical de StatsChange pra source, deixa mais clean, mais leve, e o sistema pega em monstros, sem a necessidade de registrar o evento, previne bugs.)
      pushInProtectZone = false -   Sistema para desabilitar o push de player em PZ, impossibilitando que players empurrem outros players dentro do PZ.

      SpyCast: Sistema de SPY, pra GM+ ver a tela dos jogadores, como se eles estivessem de cast aberto, GM spy não mostra aviso nenhum que vc está monitorando o player, (sistema de telescope, se o player clicar no item com actionId configurado, mostra os players com cast on), Para GM+ mostra todos os players logados, independente se estão de cast on, para players mostra somente players com cast on.

      SendProgressbar: Sistema para feature do OTC, necessário saber usar e compilar o otcv8 com a modificação

      SetCreatureSpeed: Sistema usado pra setar a quantidade exata de speed de alguma criatura/player, usado no sistema de roleta (ainda não disponivel do datapack).

      (Projeto github)

      Informações:
      º  8.60
      º Baseado na OTX 2.x mattyx
      º Lib global (sistema pesadex)
      º Informações / changelog
      Dúvidas, erros, dicas e contribuições:
      Caso tenha dúvidas, ou queira resolver algum bug/erro, dar dicas para o projeto, ou também ajudar em sua construção, crie um issue / pull requests pelo github ou use esse tópico.


      Créditos:
      FeTads (FeeTads#0246) mattyx (source base e datapack) Reason182 (fixes e mais) Luxx (meu sócio de servidor, ajudou com teste) Daniel (spriter e dev junior) ADM Mario (cara brabo dos mapas e testes, achador de bug profissional) Luan Luciano (cara brabo que no inicio me ajudou d++)  
       
       
      Download:
       
      O download pode ser feito diretamente no github, ou clonando o projeto via git.
       
      How Compile:
      Windows Tutorial - Linux(Ubuntu) Tutorial

      Sistemas adicionado até o momento, todos 100% e sem bug.
       
       

    • Por Underewar
      https://www.eternalglobal.online/
      Server Features
      Protocol 8.60 and 12.30 Features (working 100%) Bestiary -> Janela  Em Contrução para Client 8.60 ja funcional no servidor. Charm -> Janela Em Contrução para Client 8.60 ja funcional no servidor. Store -> Janela  Em construção para CLIENT 8.60 Quickloot -> Janela  Em Contrução para Client 8.60 ja funcional no servidor. Cast system Wrap system  Custom spawns loading syste WarSystem RaidSystem Offline Trainers Sala de Trainers Stamina Refil Itens Donate Boosted Boss Boosted Creature 5 Eventos Automaticos.
      12x Updates

      NEW ITEMS
      Umbral Items ,Cobra Items,Falcon Items,Warzone Items,Gnome Item

       
      NEW AREAS

      Issavi


       
      Roshamuul

      Oramond

      Cobras

       
       
      Falcons



       
      Warzone 1,2,3


      Warzones 4,5,6


       
       

       

       
       
       
       
       
       
    • Por Heyron
      Olá membros, estou disponibilizando com vocês uma ótima base para servidores 8.60, no qual é bem estável e sem erros. Ideal para quem quer começar um projeto.
      Se trata de um servidor totalmente limpo, sem gambiarras e scripts desnecessários. Contém apenas o essencial para o bom funcionamento de um servidor.
       
      Utilizei como base o TFS 0.4 publicado pelo membro @Fir3element, no qual ele contribuiu bastante e fez diversas melhorias no TFS original.
       
      Entretanto, nessa edição que fiz resolvi acrescentar melhorias que julgo interessantes. Confira as novidades abaixo.
       
      * Link da base utilizada: 
       
      ALTERAÇÕES E MELHORIAS DO @Heyron:
      ✔ spoofPlayers adicionado ao config.lua (via sources)
      ✔ Players não bloqueia spawn de monstros (via sources)
      ✔ Variação de dano reformulada (via sources)
      ✔ Monstros com efeito de Teleport antes de nascer, semelhante ao Tibia Global (via sources)
      ✔ Summons não ganha XP (via sources)
      ✔ Summons teleporta mais próximo e em qualquer andar (via sources)
      ✔ Regenerar Hp e Mana em PZ (via sources)
      ✔ Dano das spells melhorados, inclui runas de ataque
      ✔ Cura das spells melhoradas, inclui runas de cura
      ✔ Anti-MC com limite de 3 personagens com mesmo IP
      ✔ Regenerar todo Hp e Mana ao upar
      ✔ Recompensa em itens ao upar
      ✔ Poções de HP e Mana melhorados. Inclui Berserk, Mastermind e Bullseye Potion
      ✔ Paladins podem atacar correndo e usar spells ao mesmo tempo (melhoria no weapons.xml)
      ✔ Itens iniciais por vocação
       
      ALTERAÇÕES E MELHORIAS DO @Fir3element:
      ✔ Servidor compatível com sqlite e mysql
      ✔ Opcode adicionado
      ✔ Monstros andando em cima de corpos
      ✔ War system arrumado
      ✔ Anti-divulgação melhorado
      ✔ Cast system arrumado
      ✔ Crash bugs arrumados
      ✔ Adicionado exhaust ao comprar/vender items
      ✔ Account manager com opção para cidades
      ✔ /ghost stacking arrumado
      ✔ /disband arrumado
      ✔ Erros no linux arrumado
      ✔ Aleta Som arrumado
      ✔ Bug nos rings arrumado
      ✔ Adicionado suporte para Visual Studio
      ✔ Remover battle ao entrar em PZ
      ✔ Não pode jogar lixo em casas
      ✔ Salt removido
       
      MAS PORQUE O ANTIGO TFS 0.4?
      Porque essa versão é para quem busca comodidade em relação a encontrar scripts e mods em geral.
      Em qualquer fórum de Tibia e OTServer você sempre achará ótimos conteúdos para baixar, e totalmente de graça.
      Esse é o principal motivo pelo qual eu julgo interessante você considerar o TFS 0.4.
       
      DOWNLOAD:
      https://www.4shared.com/s/fT3UPvY3Ajq
      * Inclui datapack, sources e o executável compilado em 64bits.
      * Para evitar erros, recomendo utilizar 100% dessa base em seu projeto.
       
      SCAN:
      https://www.virustotal.com/gui/file/04e6594aaacd02ab6e9e3fa01733905028e3df6ee78954e60abb2d5c03f2512a?nocache=1
       

×
×
  • Criar Novo...

Informação Importante

Confirmação de Termo