Ir para conteúdo
  • Cadastre-se

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


Posts Recomendados

  • Respostas 69
  • 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

Em 18/12/2020 em 18:47, Thsilverio disse:

Voce já conseguiu? 

Não, acabei deixando

3 horas atrás, Brum disse:

alguem consegue me ajudar com isso

 

image.thumb.png.c9589e072075c3f4e92a660623179d62.png

Você ta usando a DB que veio com o servidor?

Link para o post
Compartilhar em outros sites
3 minutos atrás, FearWar disse:

Não, acabei deixando

Você ta usando a DB que veio com o servidor?

ja testei varias, mas sempre tem table faltando ou duplicada

Link para o post
Compartilhar em outros sites

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...

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

 

Zenfia.png.278005607bb4ab7487f8d6504416d875.png

 

horizontallogoblue.png.aa21fb2bb7e9cb1092aa00c635f9bb36.png

Link para o post
Compartilhar em outros sites
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
16 minutos atrás, vine96 disse:

eu sei resolver, chama no orçamento ksks

 

Excerto esse problema, de resto ele é estavel msm ne?

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...
  • Moderador
41 minutos atrás, luancanela23 disse:

Qual rate de xp fica bom pra esse ot?

400x

Link para o post
Compartilhar em outros sites
  • 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 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 luanluciano93
      STYLLER OT - 2023 - TFS 1.5 (8.60)
       
      Olá pessoal, hoje venho apresentar meu projeto open para vocês. Sou muito fã do mapa STYLLER, sempre em horas vagas procurava joga-lo, para quem não conhece: é um servidor estilo baiak com mais RPG, e como tenho me interessado pelas engines 1.X, resolvi criar um projeto de servidor Styller usando o TFS 1.5 para versão 8.60. O projeto está sendo desenvolvido no github (projeto github) onde posto atualizações diárias (changelog). Vocês podem postar dúvidas, erros/bugs, dicas e qualquer outra coisa aqui no tópico ou criar um issue no github. Lembre-se de dar FOLLOW no projeto no github e SEGUIR o projeto aqui no fórum para acompanhar as atualizações.
      Informações do Servidor e Sistemas:
      Versão: 8.60 Engine: TFS 1.5 MillhioreBT Downgrade - Branch: main (Nov 11, 2023, 104 commits) Informações. Atualizações. Server Info:
      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.
      Website compatível:
      ZnoteACC - ranch: v2 (Jul 10, 2022, 613 commits) Créditos:
      luanluciano93 GOD Bon (mapa yourots) MillhioreBT, Nekiro e TFS team (pela engine do servidor) leoloko12 (mapa styller) outros Download:
      Todos os arquivos, libs e executável (para windows) estão no repositório do projeto no github (que é onde eu atualizo constantemente), basta fazer o download lá e juntar com a primeira parte.
       
      - LINK GITHUB DO PROJETO STYLLER: https://github.com/luanluciano93/styller
       
      Clique em CODE e depois Download ZIP
       

       
      Imagens: 
       
       
       

    • Por Mateus Robeerto
      Para aqueles que estão interessados em adotar a base do Nekiro, gostaria de anunciar que as montarias e a modal widow agora estão disponíveis. Se você deseja implementar sistemas como o de crafting com modal e outros recursos, sinta-se à vontade para fazer o download e testar.
      É importante observar que o Nekiro não incluiu mapas nesta versão. Portanto, será necessário migrar seus próprios mapas para o TFS 1.5 8.6. Alternativamente, você pode considerar utilizar a base do Luciano, conhecida como STYLLER OT. Após realizar testes, posso confirmar que essa é uma opção bastante interessante. Esta versão já está completa, permitindo que você utilize seus próprios mapas sem dificuldades significativas.
      Além disso, estou disponibilizando os sprites no formato 13x para a versão 8.6, juntamente com os arquivos items.otb e XML. Quanto à correção de eventuais erros, isso fica a seu critério, mas gostaria de ressaltar que não é uma tarefa difícil de realizar.
       
      É com satisfação que compartilho que a source está agora disponível para acesso público. Caso você deseje, pode realizar atualizações através dos commits. Estou preparando uma lista abrangente de atualizações necessárias, pois há muitas modificações a serem feitas.
      Para acessar a source, por favor, clique no link abaixo:
      https://www.mediafire.com/file/0680a4b624163pd/TFS-1.5-Downgrades-8.60.rar/file
       
      Dentro da SRC que implementei, você encontrará os seguintes recursos:
      Sistema de Montaria: Agora você pode adicionar essa funcionalidade ao seu servidor.
      Modal Window: Esta é uma janela modal, proporcionando uma experiência mais interativa para os jogadores.
       
      Custom Attributes(Boost e Relfect:: https://github.com/otland/forgottenserver/pull/2807/commits/18f5afa52a36a02ea56dae97b29e683233d15c25.
       
      Além disso, gostaria de compartilhar três repositórios no GitHub que podem ser valiosos para você. Três deles são mantidos pelos usuários @Movie e @ralke23 e a Sarah (MillhioreBT). Esses repositórios contêm recursos e scripts úteis que podem aprimorar a experiência do seu servidor. Sinta-se à vontade para explorar e utilizar esses recursos conforme necessário.
      https://github.com/moviebr/TFS-1.5-Downgrades
      https://github.com/ralke23/Greed-TFS-1.5-Downgrades
      https://github.com/MillhioreBT/forgottenserver-downgrade
       
      Para os interessados nos sprites 13x para a versão 8.6, estou disponibilizando o link para download abaixo:
      https://mega.nz/folder/5FQEnT4R#pAbmAAhpBhmcP1jaVkXm8Q
       
      Recomendo também o uso do ObjectBuilder_0_5_5-dev para facilitar o processo:
      https://github.com/punkice3407/ObjectBuilder/releases/tag/v0.5.5
       
      Para aqueles que enfrentam dificuldades na compilação do executável, estou disponibilizando um arquivo para download que pode ajudar:
      https://www.mediafire.com/file/cxirgq7n1cm2p3i/dlls+e+exe.rar/file
       
       
      Quanto à ativação do sistema de montarias via OTClient, basta acessar o arquivo game_features/features.lua e localizar a linha: 'if(version >= 860) then!' e adicionar abaixo 'g_game.enableFeature(GamePlayerMounts)'.
       
      É necessário baixar ambos os arquivos, mounts.xml e outfits.xml, para que o OtClient funcione corretamente. Sem esses arquivos, o cliente pode apresentar bugs ou até mesmo crashar sozinho. É obrigatório o uso desses arquivos. Basta fazer o download e colocá-los na base do Luciano. Basta ir até a pasta data/xml e inserir os arquivos lá. Se você estiver usando seu próprio mapa, os arquivos são igualmente necessários, independentemente de suas preferências.
      outfits.xml
      mounts.xml
       

      ATENÇÃO: Sobre a base do Luciano ou do Nekiro downgrade que você baixou (schemas.sql), ela está totalmente limpa, sem implementações adicionais. Cabe a você implementar por conta própria. Por exemplo, se você for usar o Znote, ele solicitará o esquema e as colunas necessárias. Isso não são erros, são apenas avisos. Você deve procurar pelas colunas necessárias e inseri-las para que funcione corretamente. Isso não é difícil de fazer.
      https://github.com/slawkens/myaac
      https://github.com/gesior/Gesior2012
      https://github.com/Znote/ZnoteAAC/tree/v2
       
       
      Antes de prosseguir com o download, sugiro que realize uma verificação de vírus nos arquivos. Seguem os links para o scan:
       
      Scan da SRC
      https://www.virustotal.com/gui/file/1364b14cab10a34ca7102d3581e427396f8224cc5156d6bc3859b4ebcb155de6?nocache=1
      Scan das DLLs e Executável
      https://www.virustotal.com/gui/file/603c853dbd5b40ff21b0b0004c129e5039c9954277da22722b2980fcbfcbe0ce?nocache=1
       
      IMPORTANTE: Por favor, note que a funcionalidade de montaria e janela modal não está disponível para versão old do client (CipSoft). Infelizmente, não estou oferecendo suporte para essas versões no momento. No entanto, é possível adquirir uma DLL especial que pode ser injetada no client old (CipSoft) para habilitar essas funcionalidades. Caso esteja interessado, conheço um vendedor confiável que oferece essa DLL. Para mais informações, por favor, entre em contato através do Discord: Sharingan.



×
×
  • Criar Novo...

Informação Importante

Confirmação de Termo