Ejemplo n.º 1
0
bool Manager::allow(uint32_t ip) const
{
	if(!g_config.getBool(ConfigManager::MANAGER_LOCALHOST_ONLY))
		return !ConnectionManager::getInstance()->isDisabled(ip, 0xFE);

	if(ip == 0x0100007F) //127.0.0.1
		return true;

	if(g_config.getBool(ConfigManager::MANAGER_LOGS))
		LOG_MESSAGE(LOGTYPE_EVENT, "forbidden connection try", "MANAGER " + convertIPAddress(ip));

	return false;
}
Ejemplo n.º 2
0
void Monster::onCreatureLeave(Creature* creature)
{
#ifdef __DEBUG__
	std::clog << "onCreatureLeave - " << creature->getName() << std::endl;
#endif
	if(isSummon() && master == creature)
	{
		if(!g_config.getBool(ConfigManager::TELEPORT_SUMMONS) && (!master->getPlayer()
			|| !g_config.getBool(ConfigManager::TELEPORT_PLAYER_SUMMONS)))
		{
			//Turn the monster off until its master comes back
			isMasterInRange = false;
			updateIdleStatus();
		}
		else if(!doTeleportToMaster())
			teleportToMaster = true;
	}

	//update friendList
	if(isFriend(creature))
	{
		CreatureList::iterator it = std::find(friendList.begin(), friendList.end(), creature);
		if(it != friendList.end())
		{
			(*it)->unRef();
			friendList.erase(it);
		}
#ifdef __DEBUG__
		else
			std::clog << "Monster: " << creature->getName() << " not found in the friendList." << std::endl;
#endif
	}

	//update targetList
	if(isOpponent(creature))
	{
		CreatureList::iterator it = std::find(targetList.begin(), targetList.end(), creature);
		if(it != targetList.end())
		{
			(*it)->unRef();
			targetList.erase(it);
			if(targetList.empty())
				updateIdleStatus();
		}
#ifdef __DEBUG__
		else
			std::clog << "Player: " << creature->getName() << " not found in the targetList." << std::endl;
#endif
	}
}
void ServicePort::open(uint16_t port)
{
	m_serverPort = port;
	m_pendingStart = false;
	try
	{
		if(g_config.getBool(ConfigManager::BIND_IP_ONLY))
			m_acceptor = new boost::asio::ip::tcp::acceptor(m_io_service, boost::asio::ip::tcp::endpoint(
				boost::asio::ip::address(boost::asio::ip::address_v4::from_string(
				g_config.getString(ConfigManager::IP))), m_serverPort));
		else
			m_acceptor = new boost::asio::ip::tcp::acceptor(m_io_service, boost::asio::ip::tcp::endpoint(
				boost::asio::ip::address(boost::asio::ip::address_v4(INADDR_ANY)), m_serverPort));

		accept();
	}
	catch(boost::system::system_error& e)
	{
		if(m_logError)
		{
			LOG_MESSAGE(LOGTYPE_ERROR, e.what(), "NETWORK")
			m_logError = false;
		}

		m_pendingStart = true;
		Scheduler::getInstance().addEvent(createSchedulerTask(5000, boost::bind(
			&ServicePort::onOpen, boost::weak_ptr<ServicePort>(shared_from_this()), m_serverPort)));
	}
}
Ejemplo n.º 4
0
bool IOMapSerialize::saveMap(Map* map)
{
	if(g_config.getBool(ConfigManager::HOUSE_STORAGE))
		return saveMapBinary(map);

	return saveMapRelational(map);
}
Ejemplo n.º 5
0
void House::updateDoorDescription()
{
	std::stringstream houseDescription;
	houseDescription << "It belongs to house '" << houseName << "'. " << std::endl;

	if(houseOwner != 0){
		houseDescription << houseOwnerName;
	}
	else{
		houseDescription << "Nobody";
	}
	houseDescription << " owns this house." << std::endl;

	if(getHouseOwner() == 0 && g_config.getBool(ConfigManager::SHOW_HOUSE_PRICE))
    {
		int price = 0;
		for(HouseTileList::iterator it = getHouseTileBegin(); it != getHouseTileEnd(); it++)
        {
			price += g_config.getNumber(ConfigManager::HOUSE_PRICE);
		}
		
		houseDescription << " This house costs " << price << " gold." << std::endl;
	}

	HouseDoorList::iterator it;
	for(it = doorList.begin(); it != doorList.end(); ++it){
		(*it)->setSpecialDescription(houseDescription.str());
	}
}
bool WaitingList::login(const Player* player)
{
	uint32_t online = g_game.getPlayersOnline(), max = g_config.getNumber(ConfigManager::MAX_PLAYERS);
	if(player->hasFlag(PlayerFlag_CanAlwaysLogin) || player->isAccountManager() || (waitList.empty()
		&& online < max) || (g_config.getBool(ConfigManager::PREMIUM_SKIP_WAIT) && player->isPremium()))
		return true;

	cleanup();
	uint32_t slot = 0;

	WaitList::iterator it = find(player, slot);
	if(it != waitList.end())
	{
		if((online + slot) > max)
		{
			//let them wait a bit longer
			(*it)->timeout = OTSYS_TIME() + getTimeout(slot) * 1000;
			return false;
		}

		//should be able to login now
		delete *it;
		waitList.erase(it);
		return true;
	}

	Wait* wait = new Wait();
	if(player->isPremium())
	{
		slot = 1;
		WaitList::iterator it = waitList.end();
		for(WaitList::iterator wit = waitList.begin(); wit != it; ++wit)
		{
			if(!(*wit)->premium)
			{
				it = wit;
				break;
			}

			++slot;
		}

		waitList.insert(it, wait);
	}
	else
	{
		waitList.push_back(wait);
		slot = waitList.size();
	}

	wait->name = player->getName();
	wait->ip = player->getIP();
	wait->premium = player->isPremium();

	wait->timeout = OTSYS_TIME() + getTimeout(slot) * 1000;
	return false;
}
Ejemplo n.º 7
0
void Creature::dropCorpse(DeathList deathList)
{
	if(master && !g_config.getBool(ConfigManager::SUMMONS_DROP_CORPSE))
	{
		g_game.addMagicEffect(getPosition(), MAGIC_EFFECT_POFF);
		return;
	}

	Item* corpse = createCorpse(deathList);
	if(corpse)
		corpse->setParent(VirtualCylinder::virtualCylinder);

	bool deny = false;
	CreatureEventList deathEvents = getCreatureEvents(CREATURE_EVENT_DEATH);
	for(CreatureEventList::iterator it = deathEvents.begin(); it != deathEvents.end(); ++it)
	{
		if(!(*it)->executeDeath(this, corpse, deathList) && !deny)
			deny = true;
	}

	if(!corpse)
		return;

	corpse->setParent(NULL);
	if(deny)
		return;

	Tile* tile = getTile();
	if(!tile)
		return;

	Item* splash = NULL;
	switch(getRace())
	{
		case RACE_VENOM:
			splash = Item::CreateItem(ITEM_FULLSPLASH, FLUID_GREEN);
			break;

		case RACE_BLOOD:
			splash = Item::CreateItem(ITEM_FULLSPLASH, FLUID_BLOOD);
			break;

		default:
			break;
	}

	if(splash)
	{
		g_game.internalAddItem(NULL, tile, splash, INDEX_WHEREEVER, FLAG_NOLIMIT);
		g_game.startDecay(splash);
	}

	g_game.internalAddItem(NULL, tile, corpse, INDEX_WHEREEVER, FLAG_NOLIMIT);
	dropLoot(corpse->getContainer());
	g_game.startDecay(corpse);
}
Ejemplo n.º 8
0
void Monster::onAttackedCreatureDisappear(bool)
{
#ifdef __DEBUG__
	std::clog << "Attacked creature disappeared." << std::endl;
#endif
	attackTicks = 0;
	extraMeleeAttack = true;
	if(g_config.getBool(ConfigManager::MONSTER_SPAWN_WALKBACK))
		g_game.internalTeleport(this, getMasterPosition(), false);
}
Ejemplo n.º 9
0
void ProtocolManager::addLogLine(LogType_t type, std::string message)
{
	if(!g_config.getBool(ConfigManager::MANAGER_LOGS))
		return;

	std::string tmp = "MANAGER";
	if(getIP())
		tmp += " " + convertIPAddress(getIP());

	LOG_MESSAGE(type, message, tmp)
}
Ejemplo n.º 10
0
uint16_t Admin::getPolicy() const
{
	uint16_t policy = 0;
	if(g_config.getBool(ConfigManager::ADMIN_REQUIRE_LOGIN))
		policy |= REQUIRE_LOGIN;

	if(m_encrypted)
		policy |= REQUIRE_ENCRYPTION;

	return policy;
}
Ejemplo n.º 11
0
bool Houses::reloadPrices()
{
	if(g_config.getBool(ConfigManager::HOUSE_RENTASPRICE))
		return true;

	const uint32_t tilePrice = g_config.getNumber(ConfigManager::HOUSE_PRICE);
	for(HouseMap::iterator it = houseMap.begin(); it != houseMap.end(); ++it)
		it->second->setPrice(tilePrice * it->second->getTilesCount(), true);

	return true;
}
Ejemplo n.º 12
0
DatabaseMySQL::DatabaseMySQL() :
	m_timeoutTask(0)
{
	m_connected = false;
	if(!mysql_init(&m_handle))
	{
		std::clog << std::endl << "Failed to initialize MySQL connection handler." << std::endl;
		return;
	}

	uint32_t timeout = g_config.getNumber(ConfigManager::MYSQL_READ_TIMEOUT);
	if(timeout)
		mysql_options(&m_handle, MYSQL_OPT_READ_TIMEOUT, (const char*)&timeout);

	timeout = g_config.getNumber(ConfigManager::MYSQL_WRITE_TIMEOUT);
	if(timeout)
		mysql_options(&m_handle, MYSQL_OPT_WRITE_TIMEOUT, (const char*)&timeout);

	my_bool reconnect = true;
	mysql_options(&m_handle, MYSQL_OPT_RECONNECT, &reconnect);
	if(!mysql_real_connect(&m_handle, g_config.getString(ConfigManager::SQL_HOST).c_str(), g_config.getString(
		ConfigManager::SQL_USER).c_str(), g_config.getString(ConfigManager::SQL_PASS).c_str(), g_config.getString(
		ConfigManager::SQL_DB).c_str(), g_config.getNumber(ConfigManager::SQL_PORT), NULL, 0))
	{
		std::clog << "Failed connecting to database - MYSQL ERROR: " << mysql_error(&m_handle) << " (" << mysql_errno(&m_handle) << ")" << std::endl;
		return;
	}

	m_connected = true;
	if(mysql_get_client_version() <= 50019)
		//MySQL servers <= 5.0.19 have a bug where MYSQL_OPT_RECONNECT option is reset by mysql_real_connect calls.
		//Read this http://dev.mysql.com/doc/refman/5.0/en/mysql-options.html for more information.
		std::clog << std::endl << "> WARNING: Outdated MySQL server detected, consider upgrading to a newer version." << std::endl;

	timeout = g_config.getNumber(ConfigManager::SQL_KEEPALIVE) * 1000;
	if(timeout)
		m_timeoutTask = Scheduler::getInstance().addEvent(createSchedulerTask(timeout,
			boost::bind(&DatabaseMySQL::keepAlive, this)));

	if(!g_config.getBool(ConfigManager::HOUSE_STORAGE))
		return;

	//we cannot lock mutex here :)
	DBResult* result = storeQuery("SHOW variables LIKE 'max_allowed_packet';");
	if(!result)
		return;

	if(result->getDataLong("Value") < 16776192)
		std::clog << std::endl << "> WARNING: max_allowed_packet might be set too low for binary map storage." << std::endl
			<< "Use the following query to raise max_allow_packet: SET GLOBAL max_allowed_packet = 16776192;" << std::endl;

	result->free();
}
Ejemplo n.º 13
0
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(DepotChest* depotChest = player->getDepotChest(town->getID(), true))
		paid = g_game.removeMoney(depotChest, 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;
}
Ejemplo n.º 14
0
bool Combat::isProtected(Player* attacker, Player* target)
{
	if(attacker->hasFlag(PlayerFlag_CannotAttackPlayer))
		return true;

	if(attacker->hasCustomFlag(PlayerCustomFlag_GamemasterPrivileges))
		return false;

	if(attacker->getZone() == ZONE_HARDCORE && target->getZone() == ZONE_HARDCORE && g_config.getBool(ConfigManager::PVP_TILE_IGNORE_PROTECTION))
		return false;

	return target->isProtected() || attacker->isProtected() || (attacker->checkLoginDelay() && !attacker->hasBeenAttacked(target->getID()));
}
Ejemplo n.º 15
0
void Combat::doCombatDispel(Creature* caster, Creature* target, const CombatParams& params, bool check/* = true*/)
{
	if(check && params.isAggressive && (caster == target || Combat::canDoCombat(caster, target, true) != RET_NOERROR))
		return;

	CombatDispelFunc(caster, target, params, NULL);
	if(params.targetCallback)
		params.targetCallback->onTargetCombat(caster, target);

	if(params.effects.impact != MAGIC_EFFECT_NONE && (!caster || !caster->isGhost()
		|| g_config.getBool(ConfigManager::GHOST_SPELL_EFFECTS)))
		g_game.addMagicEffect(target->getPosition(), params.effects.impact);

	if(caster && params.effects.distance != SHOOT_EFFECT_NONE)
		addDistanceEffect(caster, caster->getPosition(), target->getPosition(), params.effects.distance);
}
Ejemplo n.º 16
0
bool Creature::hasCondition(ConditionType_t type, int32_t subId/* = 0*/, bool checkTime/* = true*/) const
{
	if(isSuppress(type))
		return false;

	for(ConditionList::const_iterator it = conditions.begin(); it != conditions.end(); ++it)
	{
		if((*it)->getType() != type || (subId != -1 && (*it)->getSubId() != (uint32_t)subId))
			continue;

		if(!checkTime || g_config.getBool(ConfigManager::OLD_CONDITION_ACCURACY)
			|| !(*it)->getEndTime() || (*it)->getEndTime() >= OTSYS_TIME())
			return true;
	}

	return false;
}
Ejemplo n.º 17
0
bool BedItem::canUse(Player* player)
{
	if(!house || !player || player->isRemoved() || (!player->isPremium() && g_config.getBool(
		ConfigManager::BED_REQUIRE_PREMIUM)) || player->hasCondition(CONDITION_INFIGHT))
		return false;

	if(!sleeper || house->getHouseAccessLevel(player) == HOUSE_OWNER)
		return isBed();

	Player* _player = g_game.getPlayerByGuidEx(sleeper);
	if(!_player)
		return isBed();

	bool ret = house->getHouseAccessLevel(_player) <= house->getHouseAccessLevel(player);
	if(_player->isVirtual())
		delete _player;

	return ret;
}
Ejemplo n.º 18
0
void Combat::doCombatDefault(Creature* caster, Creature* target, const CombatParams& params)
{
	if(params.isAggressive && (caster == target || Combat::canDoCombat(caster, target, true) != RET_NOERROR))
		return;

	const SpectatorVec& list = g_game.getSpectators(target->getTile()->getPosition());
	CombatNullFunc(caster, target, params, NULL);

	combatTileEffects(list, caster, target->getTile(), params);
	if(params.targetCallback)
		params.targetCallback->onTargetCombat(caster, target);

	if(params.effects.impact != MAGIC_EFFECT_NONE && (!caster || !caster->isGhost()
		|| g_config.getBool(ConfigManager::GHOST_SPELL_EFFECTS)))
		g_game.addMagicEffect(target->getPosition(), params.effects.impact);

	if(caster && params.effects.distance != SHOOT_EFFECT_NONE)
		addDistanceEffect(caster, caster->getPosition(), target->getPosition(), params.effects.distance);
}
Ejemplo n.º 19
0
bool Connection::send(OutputMessage_ptr msg)
{
	#ifdef __DEBUG_NET_DETAIL__
	std::clog << "Connection::send init" << std::endl;
	#endif
	m_connectionLock.lock();
	if(m_connectionState != CONNECTION_STATE_OPEN || m_writeError)
	{
		m_connectionLock.unlock();
		return false;
	}

	TRACK_MESSAGE(msg);
	if(!m_pendingWrite)
	{
		if(msg->getProtocol())
			msg->getProtocol()->onSendMessage(msg);

		#ifdef __DEBUG_NET_DETAIL__
		std::clog << "Connection::send " << msg->size() << std::endl;
		#endif
		internalSend(msg);
	}
	else if(m_pendingWrite > 100 && g_config.getBool(ConfigManager::FORCE_CLOSE_SLOW_CONNECTION))
	{
		std::clog << "NOTICE: Forcing slow connection to disconnect!" << std::endl;
		close();
	}
	else
	{	
		#ifdef __DEBUG_NET__
		std::clog << "Connection::send Adding to queue " << msg->size() << std::endl;
		#endif
		OutputMessagePool::getInstance()->autoSend(msg);
	}

	m_connectionLock.unlock();
	return true;
}
Ejemplo n.º 20
0
bool IOMapSerialize::loadMap(Map* map)
{
	bool result = false;
	if(g_config.getBool(ConfigManager::HOUSE_STORAGE))
		result = loadMapBinary(map);
	else
		result = loadMapRelational(map);

	if(!result)
		return false;

	for(HouseMap::iterator it = Houses::getInstance()->getHouseBegin();
		it != Houses::getInstance()->getHouseEnd(); ++it)
	{
		if(!it->second->hasSyncFlag(House::HOUSE_SYNC_UPDATE))
			continue;

		it->second->resetSyncFlag(House::HOUSE_SYNC_UPDATE);
		it->second->updateDoorDescription();
	}

	return true;
}
Ejemplo n.º 21
0
void IOGuild::checkWars()
{
	if(!g_config.getBool(ConfigManager::EXTERNAL_GUILD_WARS_MANAGEMENT))
		return;

	Database* db = Database::getInstance();
	DBResult* result;

	DBQuery query;

	// I don't know if there any easier way to make it right.
	// If exists other solution just let me know.
	// NOTE:
	// status states 6,7,8,9 are additional only for external management, do not anything in talkaction, those states make possible to manage wars for example from webpage
	// status 6 means accepted invite, it's before proper start of war
	// status 7 means 'mend fences', related to signed an armistice declaration by enemy
	// status 8 means ended up, when guild ended up war without signed an armistice declaration by enemy
	// status 9 means signed an armistice declaration by enemy
	std::stringstream s;
	uint32_t tmpInterval = (uint32_t) (EVENT_WARSINTERVAL/1000)+10; //+10 for sure

	query << "SELECT `g`.`name` as `guild_name`, `e`.`name` as `enemy_name`, `guild_wars`.`frags` as `frags`  FROM `guild_wars` LEFT JOIN `guilds` as `g` ON `guild_wars`.`guild_id` = `g`.`id` LEFT JOIN `guilds` as `e` ON `guild_wars`.`enemy_id` = `e`.`id` WHERE (`begin` > 0 AND (`begin` + " << tmpInterval << ") > UNIX_TIMESTAMP()) AND `status` IN (0, 6)";
	if((result = db->storeQuery(query.str())))
	{
		do
		{
			s << result->getDataString("guild_name") << " has invited " << result->getDataString("enemy_name") << " to war till " << result->getDataInt("frags") << " frags.";
			g_game.broadcastMessage(s.str().c_str(), MSG_EVENT_ADVANCE);
			s.str("");
		}
		while(result->next());
		result->free();
	}

	query.str("");
	query << "UPDATE `guild_wars` SET `begin` = UNIX_TIMESTAMP(), `end` = ((`end` - `begin`) + UNIX_TIMESTAMP()), `status` = 1 WHERE `status` = 6";
	db->query(query.str());

	query.str("");
	query << "SELECT `g`.`name` as `guild_name`, `e`.`name` as `enemy_name`, `g`.`id` as `guild_id`, `e`.`id` as `enemy_id`, `guild_wars`.*  FROM `guild_wars` LEFT JOIN `guilds` as `g` ON `guild_wars`.`guild_id` = `g`.`id` LEFT JOIN `guilds` as `e` ON `guild_wars`.`enemy_id` = `e`.`id` WHERE (`begin` > 0 AND (`begin` + " << tmpInterval << ") > UNIX_TIMESTAMP()) AND `status` = 1";
	if((result = db->storeQuery(query.str())))
	{
		do
		{
			s << result->getDataString("enemy_name") << " accepted " << result->getDataString("guild_name") << " invitation to war.";
			g_game.broadcastMessage(s.str().c_str(), MSG_EVENT_ADVANCE);
			s.str("");

			War_t tmp;
			tmp.war = result->getDataInt("id");
			tmp.ids[WAR_GUILD] = result->getDataInt("guild_id");
			tmp.ids[WAR_ENEMY] = result->getDataInt("enemy_id");
			for(AutoList<Player>::iterator it = Player::autoList.begin(); it != Player::autoList.end(); ++it)
			{
				if(it->second->isRemoved())
					continue;

				bool update = false;
				if(it->second->getGuildId() == tmp.ids[WAR_GUILD])
				{
					tmp.type = WAR_ENEMY;
					it->second->addEnemy(tmp.ids[WAR_ENEMY], tmp);
					update = true;
				}
				else if(it->second->getGuildId() == tmp.ids[WAR_ENEMY])
				{
					tmp.type = WAR_ENEMY;
					it->second->addEnemy(tmp.ids[WAR_GUILD], tmp);
					update = true;
				}

				if(update)
					g_game.updateCreatureEmblem(it->second);
			}
		}
		while(result->next());
		result->free();
	}

	query.str("");

	query << "SELECT `g`.`name` as `guild_name`, `e`.`name` as `enemy_name`  FROM `guild_wars` LEFT JOIN `guilds` as `g` ON `guild_wars`.`guild_id` = `g`.`id` LEFT JOIN `guilds` as `e` ON `guild_wars`.`enemy_id` = `e`.`id` WHERE (`end` > 0 AND (`end` + " << tmpInterval << ") > UNIX_TIMESTAMP()) AND `status` = 2";
	if((result = db->storeQuery(query.str())))
	{
		do
		{
			s << result->getDataString("enemy_name") << " rejected " << result->getDataString("guild_name") << " invitation to war.";
			g_game.broadcastMessage(s.str().c_str(), MSG_EVENT_ADVANCE);
			s.str("");
		}
		while(result->next());
		result->free();
	}

	query.str("");
	query << "SELECT `g`.`name` as `guild_name`, `e`.`name` as `enemy_name`  FROM `guild_wars` LEFT JOIN `guilds` as `g` ON `guild_wars`.`guild_id` = `g`.`id` LEFT JOIN `guilds` as `e` ON `guild_wars`.`enemy_id` = `e`.`id` WHERE (`end` > 0 AND (`end` + " << tmpInterval << ") > UNIX_TIMESTAMP()) AND `status` = 3";
	if((result = db->storeQuery(query.str())))
	{
		do
		{
			s << result->getDataString("guild_name") << " canceled invitation to a war with " << result->getDataString("enemy_name") << ".";
			g_game.broadcastMessage(s.str().c_str(), MSG_EVENT_ADVANCE);
			s.str("");
		}
		while(result->next());
		result->free();
	}

	query.str("");
	query << "SELECT `g`.`name` as `guild_name`, `e`.`name` as `enemy_name`, `guild_wars`.`status` as `status`, `g`.`id` as `guild_id`, `e`.`id` as `enemy_id`, `guild_wars`.*   FROM `guild_wars` LEFT JOIN `guilds` as `g` ON `guild_wars`.`guild_id` = `g`.`id` LEFT JOIN `guilds` as `e` ON `guild_wars`.`enemy_id` = `e`.`id` WHERE (`end` > 0 AND (`end` + " << tmpInterval << ") > UNIX_TIMESTAMP()) AND `status` IN (7,8)";
	if((result = db->storeQuery(query.str())))
	{
		do
		{
			if(result->getDataInt("status") == 7)
				s << result->getDataString("guild_name") << " has mend fences with " << result->getDataString("enemy_name") << ".";
			else
				s << result->getDataString("guild_name") << " has ended up a war with " << result->getDataString("enemy_name") << ".";
			
			War_t tmp;
			tmp.war = result->getDataInt("id");
			tmp.ids[WAR_GUILD] = result->getDataInt("guild_id");
			tmp.ids[WAR_ENEMY] = result->getDataInt("enemy_id");
			for(AutoList<Player>::iterator it = Player::autoList.begin(); it != Player::autoList.end(); ++it)
			{
				if(it->second->isRemoved())
					continue;

				bool update = false;
				if(it->second->getGuildId() == tmp.ids[WAR_GUILD])
				{
					it->second->removeEnemy(tmp.ids[WAR_ENEMY]);
					update = true;
				}
				else if(it->second->getGuildId() == tmp.ids[WAR_ENEMY])
				{
					it->second->removeEnemy(tmp.ids[WAR_GUILD]);
					update = true;
				}

				if(update)
					g_game.updateCreatureEmblem(it->second);
			}

			g_game.broadcastMessage(s.str().c_str(), MSG_EVENT_ADVANCE);
			s.str("");
		}
		while(result->next());
		result->free();
	}

	query.str("");

	query << "UPDATE `guild_wars` SET `end` = UNIX_TIMESTAMP(), `status` = 5 WHERE `status` IN (7,8)";
	db->query(query.str());

	query.str("");

}
Ejemplo n.º 22
0
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(Item* letter = Item::CreateItem(ITEM_LETTER_STAMPED))
	{
		if(g_game.internalAddItem(NULL, player->getInbox(), 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;
}
Ejemplo n.º 23
0
bool Chat::talkToChannel(Player* player, MessageClasses type, const std::string& text, uint16_t channelId)
{
	if(text.empty())
		return false;

	ChatChannel* channel = getChannel(player, channelId);
	if(!channel)
		return false;

	if(!player->hasFlag(PlayerFlag_CannotBeMuted))
	{
		if(!channel->hasFlag(CHANNELFLAG_ACTIVE))
		{
			player->sendTextMessage(MSG_STATUS_SMALL, "You may not speak into this channel.");
			return true;
		}

		if(player->getLevel() < channel->getLevel())
		{
			char buffer[100];
			sprintf(buffer, "You may not speak into this channel as long as you are on level %d.", channel->getLevel());
			player->sendCancel(buffer);
			return true;
		}

		if(channel->getConditionId() >= 0 && player->hasCondition(CONDITION_MUTED, channel->getConditionId()))
		{
			player->sendCancel(channel->getConditionMessage().c_str());
			return true;
		}
	}

	if(isPublicChannel(channelId))
		Manager::getInstance()->talk(player->getID(), channelId, type, text);

	if(channelId != CHANNEL_GUILD || !g_config.getBool(ConfigManager::INGAME_GUILD_MANAGEMENT)
		|| (text[0] != '!' && text[0] != '/'))
	{
		if(channelId == CHANNEL_GUILD)
		{
			switch(player->getGuildLevel())
			{
				case GUILDLEVEL_VICE:
					return channel->talk(player, MSG_CHANNEL_HIGHLIGHT, text); // SPEAK_CHANNEL_O
				case GUILDLEVEL_LEADER:
					return channel->talk(player, MSG_GAMEMASTER_CHANNEL, text); // SPEAK_CHANNEL_RN
				default:
					break;
			}
		}

		return channel->talk(player, type, text);
	}

	if(!player->getGuildId())
	{
		player->sendCancel("You are not in a guild.");
		return true;
	}

	if(!IOGuild::getInstance()->guildExists(player->getGuildId()))
	{
		player->sendCancel("It seems like your guild does not exist anymore.");
		return true;
	}

	char buffer[350];
	if(text.substr(1) == "disband")
	{
		if(player->getGuildLevel() == GUILDLEVEL_LEADER)
		{
			IOGuild::getInstance()->disbandGuild(player->getGuildId());
			channel->talk(player, MSG_CHANNEL, "The guild has been disbanded.");
		}
		else
			player->sendCancel("You are not the leader of your guild.");
	}
	else if(text.substr(1, 6) == "invite")
	{
		if(player->getGuildLevel() > GUILDLEVEL_MEMBER)
		{
			if(text.length() > 7)
			{
				std::string param = text.substr(8);
				trimString(param);

				Player* paramPlayer = NULL;
				if(g_game.getPlayerByNameWildcard(param, paramPlayer) == RET_NOERROR)
				{
					if(paramPlayer->getGuildId() == 0)
					{
						if(!paramPlayer->isGuildInvited(player->getGuildId()))
						{
							sprintf(buffer, "%s has invited you to join the guild, %s. You may join this guild by writing: !joinguild %s", player->getName().c_str(), player->getGuildName().c_str(), player->getGuildName().c_str());
							paramPlayer->sendTextMessage(MSG_INFO_DESCR, buffer);
	
							sprintf(buffer, "%s has invited %s to the guild.", player->getName().c_str(), paramPlayer->getName().c_str());
							channel->talk(player, MSG_CHANNEL, buffer);
							paramPlayer->invitationsList.push_back(player->getGuildId());
						}
						else
							player->sendCancel("A player with that name has already been invited to your guild.");
					}
					else
						player->sendCancel("A player with that name is already in a guild.");
				}
				else if(IOLoginData::getInstance()->playerExists(param))
				{
					uint32_t guid;
					IOLoginData::getInstance()->getGuidByName(guid, param);
					if(!IOGuild::getInstance()->hasGuild(guid))
					{
						if(!IOGuild::getInstance()->isInvited(player->getGuildId(), guid))
						{
							if(IOGuild::getInstance()->guildExists(player->getGuildId()))
							{
								IOGuild::getInstance()->invitePlayer(player->getGuildId(), guid);
								sprintf(buffer, "%s has invited %s to the guild.", player->getName().c_str(), param.c_str());
								channel->talk(player, MSG_CHANNEL, buffer);
							}
							else
								player->sendCancel("Your guild does not exist anymore.");
						}
						else
							player->sendCancel("A player with that name has already been invited to your guild.");
					}
					else
						player->sendCancel("A player with that name is already in a guild.");
				}
				else
					player->sendCancel("A player with that name does not exist.");
			}
			else
				player->sendCancel("Invalid guildcommand parameters.");
		}
		else
			player->sendCancel("You don't have rights to invite players to your guild.");
	}
	else if(text.substr(1, 5) == "leave")
	{
		if(player->getGuildLevel() < GUILDLEVEL_LEADER)
		{
#ifdef __WAR_SYSTEM__
			if(!player->hasEnemy())
			{
#endif
				sprintf(buffer, "%s has left the guild.", player->getName().c_str());
				channel->talk(player, MSG_CHANNEL, buffer);
				player->leaveGuild();
#ifdef __WAR_SYSTEM__
			}
			else
				player->sendCancel("Your guild is currently at war, you cannot leave it right now.");
#endif
		}
		else
			player->sendCancel("You cannot leave your guild because you are the leader of it, you have to pass the leadership to another member of your guild or disband the guild.");
	}
	else if(text.substr(1, 6) == "revoke")
	{
		if(player->getGuildLevel() > GUILDLEVEL_MEMBER)
		{
			if(text.length() > 7)
			{
				std::string param = text.substr(8);
				trimString(param);

				Player* paramPlayer = NULL;
				if(g_game.getPlayerByNameWildcard(param, paramPlayer) == RET_NOERROR)
				{
					if(paramPlayer->getGuildId() == 0)
					{
						InvitationsList::iterator it = std::find(paramPlayer->invitationsList.begin(), paramPlayer->invitationsList.end(), player->getGuildId());
						if(it != paramPlayer->invitationsList.end())
						{
							sprintf(buffer, "%s has revoked your invite to %s guild.", player->getName().c_str(), (player->getSex(false) ? "his" : "her"));
							paramPlayer->sendTextMessage(MSG_INFO_DESCR, buffer);

							sprintf(buffer, "%s has revoked the guildinvite of %s.", player->getName().c_str(), paramPlayer->getName().c_str());
							channel->talk(player, MSG_CHANNEL, buffer);

							paramPlayer->invitationsList.erase(it);
							return true;
						}
						else
							player->sendCancel("A player with that name is not invited to your guild.");
					}
					else
						player->sendCancel("A player with that name is already in a guild.");
				}
				else if(IOLoginData::getInstance()->playerExists(param))
				{
					uint32_t guid;
					IOLoginData::getInstance()->getGuidByName(guid, param);
					if(IOGuild::getInstance()->isInvited(player->getGuildId(), guid))
					{
						if(IOGuild::getInstance()->guildExists(player->getGuildId()))
						{
							sprintf(buffer, "%s has revoked the guildinvite of %s.", player->getName().c_str(), param.c_str());
							channel->talk(player, MSG_CHANNEL, buffer);
							IOGuild::getInstance()->revokeInvite(player->getGuildId(), guid);
						}
						else
							player->sendCancel("It seems like your guild does not exist anymore.");
					}
					else
						player->sendCancel("A player with that name is not invited to your guild.");
				}
				else
					player->sendCancel("A player with that name does not exist.");
			}
			else
				player->sendCancel("Invalid guildcommand parameters.");
		}
		else
			player->sendCancel("You don't have rights to revoke an invite of someone in your guild.");
	}
	else if(text.substr(1, 7) == "promote" || text.substr(1, 6) == "demote" || text.substr(1, 14) == "passleadership" || text.substr(1, 4) == "kick")
	{
		if(player->getGuildLevel() == GUILDLEVEL_LEADER)
		{
			std::string param;
			uint32_t length = 0;
			if(text[2] == 'r')
				length = 9;
			else if(text[2] == 'e')
				length = 7;
			else if(text[2] == 'a')
				length = 16;
			else
				length = 6;

			if(text.length() < length)
			{
				player->sendCancel("Invalid guildcommand parameters.");
				return true;
			}

			param = text.substr(length);
			trimString(param);

			Player* paramPlayer = NULL;
			if(g_game.getPlayerByNameWildcard(param, paramPlayer) == RET_NOERROR)
			{
				if(paramPlayer->getGuildId())
				{
					if(IOGuild::getInstance()->guildExists(paramPlayer->getGuildId()))
					{
						if(player->getGuildId() == paramPlayer->getGuildId())
						{
							if(text[2] == 'r')
							{
								if(paramPlayer->getGuildLevel() == GUILDLEVEL_MEMBER)
								{
									if(paramPlayer->isPremium())
									{
										paramPlayer->setGuildLevel(GUILDLEVEL_VICE);
										sprintf(buffer, "%s has promoted %s to %s.", player->getName().c_str(), paramPlayer->getName().c_str(), paramPlayer->getRankName().c_str());
										channel->talk(player, MSG_CHANNEL, buffer);
									}
									else
										player->sendCancel("A player with that name does not have a premium account.");
								}
								else
									player->sendCancel("You can only promote Members to Vice-Leaders.");
							}
							else if(text[2] == 'e')
							{
								if(paramPlayer->getGuildLevel() == GUILDLEVEL_VICE)
								{
									paramPlayer->setGuildLevel(GUILDLEVEL_MEMBER);
									sprintf(buffer, "%s has demoted %s to %s.", player->getName().c_str(), paramPlayer->getName().c_str(), paramPlayer->getRankName().c_str());
									channel->talk(player, MSG_CHANNEL, buffer);
								}
								else
									player->sendCancel("You can only demote Vice-Leaders to Members.");
							}
							else if(text[2] == 'a')
							{
								if(paramPlayer->getGuildLevel() == GUILDLEVEL_VICE)
								{
									const uint32_t levelToFormGuild = g_config.getNumber(ConfigManager::LEVEL_TO_FORM_GUILD);
									if(paramPlayer->getLevel() >= levelToFormGuild)
									{
										paramPlayer->setGuildLevel(GUILDLEVEL_LEADER);
										player->setGuildLevel(GUILDLEVEL_VICE);

										IOGuild::getInstance()->updateOwnerId(paramPlayer->getGuildId(), paramPlayer->getGUID());
										sprintf(buffer, "%s has passed the guild leadership to %s.", player->getName().c_str(), paramPlayer->getName().c_str());
										channel->talk(player, MSG_CHANNEL, buffer);
									}
									else
									{
										sprintf(buffer, "The new guild leader has to be at least Level %d.", levelToFormGuild);
										player->sendCancel(buffer);
									}
								}
								else
									player->sendCancel("A player with that name is not a Vice-Leader.");
							}
							else
							{
								if(player->getGuildLevel() > paramPlayer->getGuildLevel())
								{
#ifdef __WAR_SYSTEM__
									if(!player->hasEnemy())
									{
#endif
										sprintf(buffer, "%s has been kicked from the guild by %s.", paramPlayer->getName().c_str(), player->getName().c_str());
										channel->talk(player, MSG_CHANNEL, buffer);
										paramPlayer->leaveGuild();
#ifdef __WAR_SYSTEM__
									}
									else
										player->sendCancel("Your guild is currently at war, you cannot kick right now.");
#endif
								}
								else
									player->sendCancel("You may only kick players with a guild rank below your.");
							}
						}
						else
							player->sendCancel("You are not in the same guild as a player with that name.");
					}
					else
						player->sendCancel("Could not find the guild of a player with that name.");
				}
				else
					player->sendCancel("A player with that name is not in a guild.");
			}
			else if(IOLoginData::getInstance()->playerExists(param))
			{
				uint32_t guid;
				IOLoginData::getInstance()->getGuidByName(guid, param);
				if(IOGuild::getInstance()->hasGuild(guid))
				{
					if(player->getGuildId() == IOGuild::getInstance()->getGuildId(guid))
					{
						if(text[2] == 'r')
						{
							if(IOGuild::getInstance()->getGuildLevel(guid) == GUILDLEVEL_MEMBER)
							{
								if(IOLoginData::getInstance()->isPremium(guid))
								{
									IOGuild::getInstance()->setGuildLevel(guid, GUILDLEVEL_VICE);
									sprintf(buffer, "%s has promoted %s to %s.", player->getName().c_str(), param.c_str(), IOGuild::getInstance()->getRank(guid).c_str());
									channel->talk(player, MSG_CHANNEL, buffer);
								}
								else
									player->sendCancel("A player with that name does not have a premium account.");
							}
							else
								player->sendCancel("You can only promote Members to Vice-Leaders.");
						}
						else if(text[2] == 'e')
						{
							if(IOGuild::getInstance()->getGuildLevel(guid) == GUILDLEVEL_VICE)
							{
								IOGuild::getInstance()->setGuildLevel(guid, GUILDLEVEL_MEMBER);
								sprintf(buffer, "%s has demoted %s to %s.", player->getName().c_str(), param.c_str(), IOGuild::getInstance()->getRank(guid).c_str());
								channel->talk(player, MSG_CHANNEL, buffer);
							}
							else
								player->sendCancel("You can only demote Vice-Leaders to Members.");
						}
						else if(text[2] == 'a')
						{
							if(IOGuild::getInstance()->getGuildLevel(guid) == GUILDLEVEL_VICE)
							{
								const uint32_t levelToFormGuild = g_config.getNumber(ConfigManager::LEVEL_TO_FORM_GUILD);
								if(IOLoginData::getInstance()->getLevel(guid) >= levelToFormGuild)
								{
									IOGuild::getInstance()->setGuildLevel(guid, GUILDLEVEL_LEADER);
									player->setGuildLevel(GUILDLEVEL_VICE);

									sprintf(buffer, "%s has passed the guild leadership to %s.", player->getName().c_str(), param.c_str());
									channel->talk(player, MSG_CHANNEL, buffer);
								}
								else
								{
									sprintf(buffer, "The new guild leader has to be at least Level %d.", levelToFormGuild);
									player->sendCancel(buffer);
								}
							}
							else
								player->sendCancel("A player with that name is not a Vice-Leader.");
						}
						else
						{
							sprintf(buffer, "%s has been kicked from the guild by %s.", param.c_str(), player->getName().c_str());
							channel->talk(player, MSG_CHANNEL, buffer);
							IOLoginData::getInstance()->resetGuildInformation(guid);
						}
					}
				}
				else
					player->sendCancel("A player with that name is not in a guild.");
			}
			else
				player->sendCancel("A player with that name does not exist.");
		}
		else
			player->sendCancel("You are not the leader of your guild.");
	}
	else if(text.substr(1, 4) == "nick" && text.length() > 5)
	{
		StringVec params = explodeString(text.substr(6), ",");
		if(params.size() >= 2)
		{
			std::string param1 = params[0], param2 = params[1];
			trimString(param1);
			trimString(param2);

			Player* paramPlayer = NULL;
			if(g_game.getPlayerByNameWildcard(param1, paramPlayer) == RET_NOERROR)
			{
				if(paramPlayer->getGuildId())
				{
					if(param2.length() > 2)
					{
						if(param2.length() < 21)
						{
							if(isValidName(param2, false))
							{
								if(IOGuild::getInstance()->guildExists(paramPlayer->getGuildId()))
								{
									if(player->getGuildId() == paramPlayer->getGuildId())
									{
										if(paramPlayer->getGuildLevel() < player->getGuildLevel() || (player == paramPlayer && player->getGuildLevel() > GUILDLEVEL_MEMBER))
										{
											paramPlayer->setGuildNick(param2);
											if(player != paramPlayer)
												sprintf(buffer, "%s has set the guildnick of %s to \"%s\".", player->getName().c_str(), paramPlayer->getName().c_str(), param2.c_str());
											else
												sprintf(buffer, "%s has set %s guildnick to \"%s\".", player->getName().c_str(), (player->getSex(false) ? "his" : "her"), param2.c_str());

											channel->talk(player, MSG_CHANNEL, buffer);
										}
										else
											player->sendCancel("You may only change the guild nick of players that have a lower rank than you.");
									}
									else
										player->sendCancel("A player with that name is not in your guild.");
								}
								else
									player->sendCancel("A player with that name's guild could not be found.");
							}
							else
								player->sendCancel("That guildnick is not valid.");
						}
						else
							player->sendCancel("That guildnick is too long, please select a shorter one.");
					}
					else
						player->sendCancel("That guildnick is too short, please select a longer one.");
				}
				else
					player->sendCancel("A player with that name is not in a guild.");
			}
			else if(IOLoginData::getInstance()->playerExists(param1))
			{
				uint32_t guid;
				IOLoginData::getInstance()->getGuidByName(guid, (std::string&)param1);
				if(IOGuild::getInstance()->hasGuild(guid))
				{
					if(param2.length() > 2)
					{
						if(param2.length() < 21)
						{
							if(isValidName(param2, false))
							{
								if(IOGuild::getInstance()->guildExists(guid))
								{
									if(player->getGuildId() == IOGuild::getInstance()->getGuildId(guid))
									{
										if(IOGuild::getInstance()->getGuildLevel(guid) < player->getGuildLevel())
										{
											IOGuild::getInstance()->setGuildNick(guid, param2);
											sprintf(buffer, "%s has set the guildnick of %s to \"%s\".", player->getName().c_str(), param1.c_str(), param2.c_str());
											channel->talk(player, MSG_CHANNEL, buffer);
										}
										else
											player->sendCancel("You may only change the guild nick of players that have a lower rank than you.");
									}
									else
										player->sendCancel("A player with that name is not in your guild.");
								}
								else
									player->sendCancel("A player with that name's guild could not be found.");
							}
							else
								player->sendCancel("That guildnick is not valid.");
						}
						else
							player->sendCancel("That guildnick is too long, please select a shorter one.");
					}
					else
						player->sendCancel("That guildnick is too short, please select a longer one.");
				}
				else
					player->sendCancel("A player with that name is not in any guild.");
			}
			else
				player->sendCancel("A player with that name does not exist.");
		}
		else
			player->sendCancel("Invalid guildcommand parameters.");
	}
	else if(text.substr(1, 11) == "setrankname" && text.length() > 12)
	{
		StringVec params = explodeString(text.substr(13), ",");
		if(params.size() >= 2)
		{
			std::string param1 = params[0], param2 = params[1];
			trimString(param1);
			trimString(param2);

			if(player->getGuildLevel() == GUILDLEVEL_LEADER)
			{
				if(param2.length() > 2)
				{
					if(param2.length() < 21)
					{
						if(isValidName(param2, false))
						{
							if(IOGuild::getInstance()->getRankIdByName(player->getGuildId(), param1))
							{
								if(!IOGuild::getInstance()->getRankIdByName(player->getGuildId(), param2))
								{
									IOGuild::getInstance()->changeRank(player->getGuildId(), param1, param2);
									sprintf(buffer, "%s has renamed the guildrank: \"%s\", to: \"%s\".", player->getName().c_str(), param1.c_str(), param2.c_str());
									channel->talk(player, MSG_CHANNEL, buffer);
								}
								else
									player->sendCancel("There is already a rank in your guild with that name.");
							}
							else
								player->sendCancel("There is no such rankname in your guild.");
						}
						else
							player->sendCancel("The new guildrank contains invalid characters.");
					}
					else
						player->sendCancel("The new rankname is too long.");
				}
				else
					player->sendCancel("The new rankname is too short.");
			}
			else
				player->sendCancel("You are not the leader of your guild.");
		}
		else
			player->sendCancel("Invalid guildcommand parameters");
	}
	else if(text.substr(1, 7) == "setmotd")
	{
		if(player->getGuildLevel() == GUILDLEVEL_LEADER)
		{
			if(text.length() > 8)
			{
				std::string param = text.substr(9);
				trimString(param);
				if(param.length() > 2)
				{
					if(param.length() < 225)
					{
						IOGuild::getInstance()->setMotd(player->getGuildId(), param);
						sprintf(buffer, "%s has set the Message of the Day to: %s", player->getName().c_str(), param.c_str());
						channel->talk(player, MSG_CHANNEL, buffer);
					}
					else
						player->sendCancel("That motd is too long.");
				}
				else
					player->sendCancel("That motd is too short.");
			}
			else
				player->sendCancel("Invalid guildcommand parameters.");
		}
		else
			player->sendCancel("Only the leader of your guild can set the guild motd.");
	}
	else if(text.substr(1, 9) == "cleanmotd")
	{
		if(player->getGuildLevel() == GUILDLEVEL_LEADER)
		{
			IOGuild::getInstance()->setMotd(player->getGuildId(), "");
			sprintf(buffer, "%s has cleaned the Message of the Day.", player->getName().c_str());
			channel->talk(player, MSG_CHANNEL, buffer);
		}
		else
			player->sendCancel("Only the leader of your guild can clean the guild motd.");
	}
	else if(text.substr(1, 8) == "commands")
		player->sendToChannel(player, MSG_CHANNEL, "Guild commands with parameters: disband, invite[name], leave, kick[name], revoke[name], demote[name], promote[name], passleadership[name], nick[name, nick], setrankname[oldName, newName], setmotd[text] and cleanmotd.", CHANNEL_GUILD);
	else
		return false;

	return true;
}
Ejemplo n.º 24
0
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;
}
Ejemplo n.º 25
0
bool House::isGuild() const
{
	return g_config.getBool(ConfigManager::GUILD_HALLS) && guild;
}
Ejemplo n.º 26
0
bool Houses::payHouses()
{
	if(rentPeriod == RENTPERIOD_NEVER) {
		return true;
	}
	uint32_t currentTime = std::time(NULL);

	for(HouseMap::iterator it = houseMap.begin(); it != houseMap.end(); ++it){
		House* house = it->second;

		if(house->getHouseOwner() != 0 && house->getPaidUntil() < currentTime &&
			 house->getRent() != 0){
			uint32_t ownerid = house->getHouseOwner();
			Town* town = Towns::getInstance().getTown(house->getTownId());
			if(!town){
				#ifdef __DEBUG_HOUSES__
				std::cout << "Warning: [Houses::payHouses] town = NULL, townid = " <<
					house->getTownId() << ", houseid = " << house->getHouseId() << std::endl;
				#endif
				continue;
			}

			std::string name;
			if(!IOPlayer::instance()->getNameByGuid(ownerid, name)){
				//player doesnt exist, remove it as house owner?
				//house->setHouseOwner(0);
				continue;
			}

			Player* player = g_game.getPlayerByName(name);

			if(!player){
				player = new Player(name, NULL);

				if(!IOPlayer::instance()->loadPlayer(player, name)){
		#ifdef __DEBUG__
					std::cout << "Failure: [Houses::payHouses], can not load player: " << name << std::endl;
		#endif
					delete player;
					continue;
				}
			}

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

			// savePlayerHere is an ugly hack
			// to avoid saving 2 times a not online player
			// when items are transferred to his depot
			bool savePlayerHere = true;
			if(depot){
				//get money from depot
				bool useAccBalance = g_config.getBool(ConfigManager::USE_ACCBALANCE) != 0;
				bool hasEnoughMoney = false;

				if(useAccBalance){
					if(player->balance >= house->getRent()){
						player->balance -= house->getRent();
						hasEnoughMoney = true;
					}
				}
				else{
					hasEnoughMoney = g_game.removeMoney(depot, house->getRent(), FLAG_NOLIMIT);
				}

				if(hasEnoughMoney){
					uint32_t paidUntil = currentTime;
					switch(rentPeriod){
					case RENTPERIOD_DAILY:
						paidUntil += 24 * 60 * 60;
						break;
					case RENTPERIOD_WEEKLY:
						paidUntil += 24 * 60 * 60 * 7;
						break;
					case RENTPERIOD_MONTHLY:
						paidUntil += 24 * 60 * 60 * 30;
						break;
					case RENTPERIOD_YEARLY:
						paidUntil += 24 * 60 * 60 * 365;
					case RENTPERIOD_NEVER:
						break;
					}

					house->setPaidUntil(paidUntil);
				}
				else if(currentTime >= house->getLastWarning() + 24 * 60 * 60){
					if(house->getPayRentWarnings() >= 7){
						house->setHouseOwner(0);
						// setHouseOwner will load the player,
						// transfer house items to his depot and then
						// will save it, so here should not be saved
						// again
						savePlayerHere = false;
					}
					else{
						int daysLeft = 7 - house->getPayRentWarnings();

						Item* letter = Item::CreateItem(ITEM_LETTER_STAMPED);
						std::string period = "";

						switch(rentPeriod){
							case RENTPERIOD_DAILY:
								period = "daily";
							break;

							case RENTPERIOD_WEEKLY:
								period = "weekly";
							break;

							case RENTPERIOD_MONTHLY:
								period = "monthly";
							break;

							case RENTPERIOD_YEARLY:
								period = "annual";
							break;

							case RENTPERIOD_NEVER:
								//
							break;
						}

						std::stringstream warningText;
						warningText << "Warning! \n" <<
							"The " << period << " rent of " << house->getRent() << " gold for your house \""
							<< house->getName() << "\" is payable. Have it available within " << daysLeft <<
							" days, or you will lose this house.";

						letter->setText(warningText.str());
						g_game.internalAddItem(depot, letter, INDEX_WHEREEVER, FLAG_NOLIMIT);

						house->setPayRentWarnings(house->getPayRentWarnings() + 1);
						house->setLastWarning(currentTime);
					}
				}
			}

			if(player->isOffline()){
				if(savePlayerHere){
					IOPlayer::instance()->savePlayer(player);
				}
				delete player;
			}
		}
	}

	return true;
}
Ejemplo n.º 27
0
int main(int argc, char *argv[])
{
	StringVec args = StringVec(argv, argv + argc);
	if(argc > 1 && !argumentsHandler(args))
		return 0;

#else
void serverMain(void* param)
{
	std::cout.rdbuf(&g_logger);
	std::cerr.rdbuf(&g_logger);

#endif
	std::set_new_handler(allocationHandler);
	ServiceManager servicer;
	g_config.startup();

	#ifdef __OTSERV_ALLOCATOR_STATS__
	boost::thread(boost::bind(&allocatorStatsThread, (void*)NULL));
	// TODO: destruct this thread...
	#endif
	#ifdef __EXCEPTION_TRACER__
	ExceptionHandler mainExceptionHandler;
	mainExceptionHandler.InstallHandler();
	#endif
	#ifndef WINDOWS

	// ignore sigpipe...
	struct sigaction sigh;
	sigh.sa_handler = SIG_IGN;
	sigh.sa_flags = 0;
	sigemptyset(&sigh.sa_mask);
	sigaction(SIGPIPE, &sigh, NULL);

	// register signals
	signal(SIGHUP, signalHandler); //save
	signal(SIGTRAP, signalHandler); //clean
	signal(SIGCHLD, signalHandler); //refresh
	signal(SIGUSR1, signalHandler); //close server
	signal(SIGUSR2, signalHandler); //open server
	signal(SIGCONT, signalHandler); //reload all
	signal(SIGQUIT, signalHandler); //save & shutdown
	signal(SIGTERM, signalHandler); //shutdown
	#endif

	Dispatcher::getInstance().addTask(createTask(boost::bind(otserv,
	#if !defined(WINDOWS) || defined(__CONSOLE__)
	args,
	#endif
	&servicer)));
	g_loaderSignal.wait(g_loaderUniqueLock);

	#if !defined(WINDOWS) || defined(__CONSOLE__)
	std::string outPath = g_config.getString(ConfigManager::OUT_LOG), errPath = g_config.getString(ConfigManager::ERROR_LOG);
	if(outPath.length() < 3)
		outPath = "";
	else if(outPath[0] != '/' && outPath[1] != ':')
	{
		outPath = getFilePath(FILE_TYPE_LOG, outPath);
		std::cout << "> Logging output to file: " << outPath << std::endl;
	}

	if(errPath.length() < 3)
		errPath = "";
	else if(errPath[0] != '/' && errPath[1] != ':')
	{
		errPath = getFilePath(FILE_TYPE_LOG, errPath);
		std::cout << "> Logging errors to file: " << errPath << std::endl;
	}

	if(outPath != "")
	{
		boost::shared_ptr<std::ofstream> outFile;
		outFile.reset(new std::ofstream(outPath.c_str(), (g_config.getBool(ConfigManager::TRUNCATE_LOGS) ?
			std::ios::trunc : std::ios::app) | std::ios::out));
		if(!outFile->is_open())
			startupErrorMessage("Could not open output log file for writing!");

		std::cout.rdbuf(outFile->rdbuf());
	}

	if(errPath != "")
	{
		boost::shared_ptr<std::ofstream> errFile;
		errFile.reset(new std::ofstream(errPath.c_str(), (g_config.getBool(ConfigManager::TRUNCATE_LOGS) ?
			std::ios::trunc : std::ios::app) | std::ios::out));
		if(!errFile->is_open())
			startupErrorMessage("Could not open error log file for writing!");

		std::cerr.rdbuf(errFile->rdbuf());
	}
	#endif

	if(servicer.isRunning())
	{
		std::cout << ">> " << g_config.getString(ConfigManager::SERVER_NAME) << " server Online!" << std::endl << std::endl;
		#if defined(WINDOWS) && !defined(__CONSOLE__)
		SendMessage(GUI::getInstance()->m_statusBar, WM_SETTEXT, 0, (LPARAM)">> Status: Online!");
		GUI::getInstance()->m_connections = true;
		#endif
		servicer.run();
	}
	else
	{
		std::cout << ">> " << g_config.getString(ConfigManager::SERVER_NAME) << " server Offline! No services available..." << std::endl << std::endl;
		#if defined(WINDOWS) && !defined(__CONSOLE__)
		SendMessage(GUI::getInstance()->m_statusBar, WM_SETTEXT, 0, (LPARAM)">> Status: Offline!");
		GUI::getInstance()->m_connections = true;
		#endif
	}

#ifdef __EXCEPTION_TRACER__
	mainExceptionHandler.RemoveHandler();
#endif
#if !defined(WINDOWS) || defined(__CONSOLE__)
	return 0;
#endif
}
Ejemplo n.º 28
0
ReturnValue Spells::onPlayerSay(Player* player, const std::string& words)
{
	std::string reWords = words;
	trimString(reWords);

	InstantSpell* instantSpell = getInstantSpell(reWords);
	if(!instantSpell)
		return RET_NOTPOSSIBLE;

	size_t size = instantSpell->getWords().length();
	std::string param = reWords.substr(size, reWords.length() - size), reParam = "";
	if(instantSpell->getHasParam() && !param.empty() && param[0] == ' ')
	{
		size_t quote = param.find('"', 1);
		if(quote != std::string::npos)
		{
			size_t tmp = param.find('"', quote + 1);
			if(tmp == std::string::npos)
				tmp = param.length();

			reParam = param.substr(quote + 1, tmp - quote - 1);
		}
		else if(param.find(' ', 1) == std::string::npos)
			reParam = param.substr(1, param.length());

		trimString(reParam);
	}

	Position pos = player->getPosition();
	if(!instantSpell->castInstant(player, reParam))
		return RET_NEEDEXCHANGE;

	SpeakClasses type = SPEAK_SAY;
	if(g_config.getBool(ConfigManager::EMOTE_SPELLS))
		type = SPEAK_MONSTER_SAY;

	if(!g_config.getBool(ConfigManager::SPELL_NAME_INSTEAD_WORDS))
	{
		if(g_config.getBool(ConfigManager::UNIFIED_SPELLS))
		{
			reWords = instantSpell->getWords();
			if(instantSpell->getHasParam())
				reWords += " \"" + param + "\"";
		}

		return g_game.internalCreatureSay(player, type, reWords, player->isGhost()) ?
			RET_NOERROR : RET_NOTPOSSIBLE;
	}

	std::string ret = instantSpell->getName();
	if(param.length())
	{
		trimString(param);
		size_t tmp = 0, rtmp = param.length();
		if(param[0] == '"')
			tmp = 1;

		if(param[rtmp] == '"')
			rtmp -= 1;

		ret += ": " + param.substr(tmp, rtmp);
	}

	return g_game.internalCreatureSay(player, type, ret, player->isGhost(),
		NULL, &pos) ? RET_NOERROR : RET_NOTPOSSIBLE;
}
Ejemplo n.º 29
0
void otserv(
#if !defined(WINDOWS) || defined(_CONSOLE)
StringVec,
#endif
ServiceManager* services)
{
	std::srand((uint32_t)OTSYS_TIME());
#if defined(WINDOWS)
#if defined(_CONSOLE)
	SetConsoleTitle(SOFTWARE_NAME);
#else
	GUI::getInstance()->m_connections = false;
#endif
#endif

	g_game.setGameState(GAMESTATE_STARTUP);
#if !defined(WINDOWS) && !defined(__ROOT_PERMISSION__)
	if(!getuid() || !geteuid())
	{
		std::clog << "> WARNING: " "The " << SOFTWARE_NAME << " has been executed as super user! It is "
			<< "recommended to run as a normal user." << std::endl << "Continue? (y/N)" << std::endl;
		char buffer = OTSYS_getch();
		if(buffer != 121 && buffer != 89)
			startupErrorMessage("Aborted.");
	}
#endif

	std::clog << "The " << SOFTWARE_NAME << " Version: (" << SOFTWARE_VERSION << "." << MINOR_VERSION << PATCH_VERSION << " - " << REVISION_VERSION << ") - Codename: (" << SOFTWARE_CODENAME << ")" << std::endl
		<< "Compilied with " << BOOST_COMPILER << " for arch "
		#if defined(__amd64__) || defined(_M_X64)
		"64 Bits"
		#elif defined(__i386__) || defined(_M_IX86) || defined(_X86_)
		"32 Bits"
		#else
		"unk"
		#endif
		" at " << __DATE__ << " " << __TIME__ << std::endl

		<< std::endl
		<< "A server developed by: "SOFTWARE_DEVELOPERS"." << std::endl
		<< "Visit our forums for updates, support, and resources:" << std::endl
		<< ""FORUMS"" << std::endl;
	std::stringstream ss;
#ifdef __DEBUG__
	ss << " GLOBAL";
#endif
#ifdef __DEBUG_MOVESYS__
	ss << " MOVESYS";
#endif
#ifdef __DEBUG_CHAT__
	ss << " CHAT";
#endif
#ifdef __DEBUG_HOUSES__
	ss << " HOUSES";
#endif
#ifdef __DEBUG_LUASCRIPTS__
	ss << " LUA-SCRIPTS";
#endif
#ifdef __DEBUG_MAILBOX__
	ss << " MAILBOX";
#endif
#ifdef __DEBUG_NET__
	ss << " NET";
#endif
#ifdef __DEBUG_NET_DETAIL__
	ss << " NET-DETAIL";
#endif
#ifdef __DEBUG_RAID__
	ss << " RAIDS";
#endif
#ifdef __DEBUG_SCHEDULER__
	ss << " SCHEDULER";
#endif
#ifdef __DEBUG_SPAWN__
	ss << " SPAWNS";
#endif
#ifdef __SQL_QUERY_DEBUG__
	ss << " SQL-QUERIES";
#endif

	std::string debug = ss.str();
	if(!debug.empty())
	{
		std::clog << ">> Debugging:";
		#if defined(WINDOWS) && !defined(_CONSOLE)
		SendMessage(GUI::getInstance()->m_statusBar, WM_SETTEXT, 0, (LPARAM)">> Debugging:");
		#endif
		std::clog << debug << "." << std::endl;
	}
	std::clog << std::endl;
	std::clog << ">> Loading config (" << g_config.getString(ConfigManager::CONFIG_FILE) << ")" << std::endl;
	#if defined(WINDOWS) && !defined(_CONSOLE)
	SendMessage(GUI::getInstance()->m_statusBar, WM_SETTEXT, 0, (LPARAM)">> Loading config");
	#endif
	if(!g_config.load())
		startupErrorMessage("Unable to load " + g_config.getString(ConfigManager::CONFIG_FILE) + "!");

#ifndef WINDOWS
	if(g_config.getBool(ConfigManager::DAEMONIZE))
	{
		std::clog << "> Daemonization... ";
		if(fork())
		{
			std::clog << "succeed, bye!" << std::endl;
			exit(0);
		}
		else
			std::clog << "failed, continuing." << std::endl;
	}

#endif
	// silently append trailing slash
	std::string path = g_config.getString(ConfigManager::DATA_DIRECTORY);
	g_config.setString(ConfigManager::DATA_DIRECTORY, path.erase(path.find_last_not_of("/") + 1) + "/");

	path = g_config.getString(ConfigManager::LOGS_DIRECTORY);
	g_config.setString(ConfigManager::LOGS_DIRECTORY, path.erase(path.find_last_not_of("/") + 1) + "/");

	std::clog << ">> Opening logs" << std::endl;
	#if defined(WINDOWS) && !defined(_CONSOLE)
	SendMessage(GUI::getInstance()->m_statusBar, WM_SETTEXT, 0, (LPARAM)">> Opening logs");
	#endif
	Logger::getInstance()->open();

	IntegerVec cores = vectorAtoi(explodeString(g_config.getString(ConfigManager::CORES_USED), ","));
	if(cores[0] != -1)
	{
#ifdef WINDOWS
		int32_t mask = 0;
		for(IntegerVec::iterator it = cores.begin(); it != cores.end(); ++it)
			mask += 1 << (*it);

		SetProcessAffinityMask(GetCurrentProcess(), mask);
	}

	std::stringstream mutexName;
	mutexName << "otxserver_" << g_config.getNumber(ConfigManager::WORLD_ID);

	CreateMutex(NULL, FALSE, mutexName.str().c_str());
	if(GetLastError() == ERROR_ALREADY_EXISTS)
		startupErrorMessage("Another instance of The OTX Server is already running with the same worldId.\nIf you want to run multiple servers, please change the worldId in configuration file.");

	std::string defaultPriority = asLowerCaseString(g_config.getString(ConfigManager::DEFAULT_PRIORITY));
	if(defaultPriority == "realtime" || defaultPriority == "real")
		SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
	else if(defaultPriority == "high" || defaultPriority == "regular")
		SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
	else if(defaultPriority == "higher" || defaultPriority == "above" || defaultPriority == "normal")
		SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS);

#else
#ifndef __APPLE__
		cpu_set_t mask;
		CPU_ZERO(&mask);
		for(IntegerVec::iterator it = cores.begin(); it != cores.end(); ++it)
			CPU_SET((*it), &mask);

		sched_setaffinity(getpid(), (int32_t)sizeof(mask), &mask);
	}
Ejemplo n.º 30
0
void ProtocolLogin::onRecvFirstMessage(NetworkMessage& msg)
{
	if(
#if defined(WINDOWS) && !defined(_CONSOLE)
		!GUI::getInstance()->m_connections ||
#endif
		g_game.getGameState() == GAMESTATE_SHUTDOWN)
	{
		getConnection()->close();
		return;
	}

	uint32_t clientIp = getConnection()->getIP();
	msg.get<uint16_t>();
	uint16_t version = msg.get<uint16_t>();

	msg.skip(12);
	#ifdef _MULTIPLATFORM77
	if(!RSA_decrypt(msg))
	{
		getConnection()->close();
		return;
	}

	uint32_t key[4] = {msg.get<uint32_t>(), msg.get<uint32_t>(), msg.get<uint32_t>(), msg.get<uint32_t>()};
	enableXTEAEncryption();
	setXTEAKey(key);
	#endif
	uint32_t name = msg.get<uint32_t>();
	std::string password = msg.getString();

	if(!name)
	{
		if(!g_config.getBool(ConfigManager::ACCOUNT_MANAGER))
		{
			disconnectClient(0x0A, "Invalid account name.");
			return;
		}

		name = 1;
		password = "******";
	}

	if(!g_config.getBool(ConfigManager::MANUAL_ADVANCED_CONFIG))
	{
		if(version < CLIENT_VERSION_MIN || version > CLIENT_VERSION_MAX)
		{
			disconnectClient(0x0A, CLIENT_VERSION_STRING);
			return;
		}
	else
		if(version < g_config.getNumber(ConfigManager::VERSION_MIN) || version > g_config.getNumber(ConfigManager::VERSION_MAX))
		{
			disconnectClient(0x0A, g_config.getString(ConfigManager::VERSION_MSG).c_str());
			return;
		}
	}
#ifdef CLIENT_VERSION_DATA

	if(sprSignature != CLIENT_VERSION_SPR)
	{
		disconnectClient(0x0A, CLIENT_VERSION_DATA);
		return;
	}

	if(datSignature != CLIENT_VERSION_DAT)
	{
		disconnectClient(0x0A, CLIENT_VERSION_DATA);
		return;
	}

	if(picSignature != CLIENT_VERSION_PIC)
	{
		disconnectClient(0x0A, CLIENT_VERSION_DATA);
		return;
	}
#endif

	if(g_game.getGameState() < GAMESTATE_NORMAL)
	{
		disconnectClient(0x0A, "Server is just starting up, please wait.");
		return;
	}

	if(g_game.getGameState() == GAMESTATE_MAINTAIN)
	{
		disconnectClient(0x0A, "Server is under maintenance, please re-connect in a while.");
		return;
	}

	if(ConnectionManager::getInstance()->isDisabled(clientIp, protocolId))
	{
		disconnectClient(0x0A, "Too many connections attempts from your IP address, please try again later.");
		return;
	}

	if(IOBan::getInstance()->isIpBanished(clientIp))
	{
		disconnectClient(0x0A, "Your IP is banished!");
		return;
	}

	uint32_t id = 1;
	if(!IOLoginData::getInstance()->getAccountId(name, id))
	{
		ConnectionManager::getInstance()->addAttempt(clientIp, protocolId, false);
		disconnectClient(0x0A, "Invalid account id.");
		return;
	}

	Account account = IOLoginData::getInstance()->loadAccount(id);
	if(!encryptTest(account.salt + password, account.password))
	{
		ConnectionManager::getInstance()->addAttempt(clientIp, protocolId, false);
		disconnectClient(0x0A, "Invalid password.");
		return;
	}

	Ban ban;
	ban.value = account.number;

	ban.type = BAN_ACCOUNT;
	if(IOBan::getInstance()->getData(ban) && !IOLoginData::getInstance()->hasFlag(account.number, PlayerFlag_CannotBeBanned))
	{
		bool deletion = ban.expires < 0;
		std::string name_ = "Automatic ";
		if(!ban.adminId)
			name_ += (deletion ? "deletion" : "banishment");
		else
			IOLoginData::getInstance()->getNameByGuid(ban.adminId, name_, true);

		std::stringstream ss;
		ss << "Your account has been " << (deletion ? "deleted" : "banished") << " at:\n" << formatDateEx(ban.added, "%d %b %Y").c_str()
			<< " by: " << name_.c_str() << "\nReason:\n" << getReason(ban.reason).c_str() << ".\nComment:\n" << ban.comment.c_str() << ".\nYour " << (deletion ?
			"account won't be undeleted" : "banishment will be lifted at:\n") << (deletion ? "" : formatDateEx(ban.expires).c_str());

		disconnectClient(0x0A, ss.str().c_str());
		return;
	}

	// remove premium days
	#ifndef __LOGIN_SERVER__
	IOLoginData::getInstance()->removePremium(account);
	if(!g_config.getBool(ConfigManager::ACCOUNT_MANAGER) && !account.charList.size())
	{
		disconnectClient(0x0A, std::string("This account does not contain any character yet.\nCreate a new character on the "
			+ g_config.getString(ConfigManager::SERVER_NAME) + " website at " + g_config.getString(ConfigManager::URL) + ".").c_str());
		return;
	}
	#else
	Characters charList;
	for(Characters::iterator it = account.charList.begin(); it != account.charList.end(); ++it)
	{
		if(version >= it->second.server->getVersionMin() && version <= it->second.server->getVersionMax())
			charList[it->first] = it->second;
	}

	IOLoginData::getInstance()->removePremium(account);
	if(!g_config.getBool(ConfigManager::ACCOUNT_MANAGER) && !charList.size())
	{
		disconnectClient(0x0A, std::string("This account does not contain any character on this client yet.\nCreate a new character on the "
			+ g_config.getString(ConfigManager::SERVER_NAME) + " website at " + g_config.getString(ConfigManager::URL) + ".").c_str());
		return;
	}
	#endif

	ConnectionManager::getInstance()->addAttempt(clientIp, protocolId, true);
	if(OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false))
	{
		TRACK_MESSAGE(output);
		output->put<char>(0x14);
		uint32_t serverIp = serverIps.front().first;
		for(std::list<std::pair<uint32_t, uint32_t> >::iterator it = serverIps.begin(); it != serverIps.end(); ++it)
		{
			if((it->first & it->second) != (clientIp & it->second))
				continue;

			serverIp = it->first;
			break;
		}

		char motd[1300];
		sprintf(motd, "%d\n%s", g_game.getMotdId(), g_config.getString(ConfigManager::MOTD).c_str());
		output->putString(motd);

		//Add char list
		output->put<char>(0x64);
		if(g_config.getBool(ConfigManager::ACCOUNT_MANAGER) && account.number != 1)
		{
			output->put<char>(account.charList.size() + 1);
			output->putString("Account Manager");

			output->putString(g_config.getString(ConfigManager::SERVER_NAME));
			output->put<uint32_t>(serverIp);

			output->put<uint16_t>(g_config.getNumber(ConfigManager::GAME_PORT));
		}
		else
			output->put<char>((uint8_t)account.charList.size());

		#ifndef __LOGIN_SERVER__
		for(Characters::iterator it = account.charList.begin(); it != account.charList.end(); ++it)
		{
			output->putString((*it));
			if(g_config.getBool(ConfigManager::ON_OR_OFF_CHARLIST)
				&& !g_config.getBool(ConfigManager::CHARLIST_INFO))
			{
				if(g_game.getPlayerByName((*it)))
					output->putString("Online");
				else
					output->putString("Offline");
			}
			else if(g_config.getBool(ConfigManager::CHARLIST_INFO))
			{
				std::stringstream str;
				Player *player = g_game.getPlayerByName((*it));
				bool v = false;
				if(g_config.getBool(ConfigManager::ON_OR_OFF_CHARLIST))
				{
					if(player)
						str << "On";
					else
						str << "Off";

					str << "/";
				}

				if(!player)
				{
					v = true;
					player = g_game.getPlayerByNameEx((*it));
				}

				str << player->getLevel();
				str << "/";
				str << player->getVocation()->getName();
				output->putString(str.str());
				if(v)
					delete player;
			}
			else
				output->putString(g_config.getString(ConfigManager::SERVER_NAME));

			output->put<uint32_t>(serverIp);
			output->put<uint16_t>(g_config.getNumber(ConfigManager::GAME_PORT));
		}
		#else
		for(Characters::iterator it = charList.begin(); it != charList.end(); ++it)
		{
			output->putString(it->second.name);
			if(!g_config.getBool(ConfigManager::ON_OR_OFF_CHARLIST) || it->second.status < 0)
				output->putString(it->second.server->getName());
			else if(it->second.status)
				output->putString("Online");
			else
				output->putString("Offline");

			output->put<uint32_t>(it->second.server->getAddress());
			IntegerVec games = it->second.server->getPorts();
			output->put<uint16_t>(games[random_range(0, games.size() - 1)]);
		}
		#endif

		//Add premium days
		if(g_config.getBool(ConfigManager::FREE_PREMIUM))
			output->put<uint16_t>(GRATIS_PREMIUM);
		else
			output->put<uint16_t>(account.premiumDays);

		OutputMessagePool::getInstance()->send(output);
	}

	getConnection()->close();
}