예제 #1
0
void Commands::multiClientCheck(Player* player, const std::string& cmd, const std::string& param)
{
	player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Multiclient Check List:");
	std::map<uint32_t, std::vector<Player*>> ipMap;

	for (const auto& it : g_game.getPlayers()) {
		Player* tmpPlayer = it.second;
		if (tmpPlayer->getIP() == 0) {
			continue;
		}

		ipMap[tmpPlayer->getIP()].push_back(tmpPlayer);
	}

	for (const auto& it : ipMap) {
		if (it.second.size() < 2) {
			continue;
		}

		Player* tmpPlayer = it.second[0];
		std::ostringstream ss;
		ss << convertIPToString(it.first) << ": " << tmpPlayer->getName() << " [" << tmpPlayer->getLevel() << ']';

		for (std::vector<Player*>::size_type i = 1, size = it.second.size(); i < size; ++i) {
			tmpPlayer = it.second[i];
			ss << ", " << tmpPlayer->getName() << " [" << tmpPlayer->getLevel() << ']';
		}

		ss << '.';
		player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, ss.str());
	}
}
예제 #2
0
파일: admin.cpp 프로젝트: CkyLua/OTHire
static void addLogLine(ProtocolAdmin* conn, eLogType type, int level, std::string message)
{
	std::string logMsg;
	if(conn){
		uint32_t ip = conn->getIP();
		logMsg = convertIPToString(ip) +  "[" + logMsg + "] - ";
	}
	logMsg = logMsg + message;
	LOG_MESSAGE("OTADMIN", type, level, logMsg);
}
예제 #3
0
void Connection::parseHeader(const boost::system::error_code& error)
{
	m_connectionLock.lock();
	m_readTimer.cancel();

	int32_t size = m_msg.decodeHeader();
	if(error || size <= 0 || size >= NETWORKMESSAGE_MAXSIZE - 16){
		handleReadError(error);
	}

	if(m_connectionState != CONNECTION_STATE_OPEN || m_readError){
		closeConnection();
		m_connectionLock.unlock();
		return;
	}

 	if (g_config.getNumber(ConfigManager::MAX_PACKETS_PER_SECOND) != 0){
 		uint32_t timePassed = std::max<uint32_t>(1, (time(NULL) - m_timeConnected) + 1);
 		if ((++m_packetsSent / timePassed) > (uint32_t)g_config.getNumber(ConfigManager::MAX_PACKETS_PER_SECOND)){
 			std::cout << convertIPToString(getIP()) << " disconnected for exceeding packet per second limit." << std::endl;
 			closeConnection();
 			m_connectionLock.unlock();
 			return;
 		}
 
 		if (timePassed > 2){
 			m_timeConnected = time(NULL);
 			m_packetsSent = 0;
 		}
 	}

	--m_pendingRead;

	try{
		++m_pendingRead;
		m_readTimer.expires_from_now(boost::posix_time::seconds(Connection::read_timeout));
		m_readTimer.async_wait( boost::bind(&Connection::handleReadTimeout, boost::weak_ptr<Connection>(shared_from_this()),
			boost::asio::placeholders::error));

		// Read packet content
		m_msg.setMessageLength(size + NetworkMessage::header_length);
		boost::asio::async_read(getHandle(), boost::asio::buffer(m_msg.getBodyBuffer(), size),
			boost::bind(&Connection::parsePacket, shared_from_this(), boost::asio::placeholders::error));
	}
	catch(boost::system::system_error& e){
		if(m_logError){
			LOG_MESSAGE("NETWORK", LOGTYPE_ERROR, 1, e.what());
			m_logError = false;
			closeConnection();
		}
	}

	m_connectionLock.unlock();
}
예제 #4
0
파일: admin.cpp 프로젝트: Codex-NG/TFS-1.0
static void addLogLine(ProtocolAdmin* conn, eLogType type, int level, std::string message)
{
	if(g_config.getBoolean(ConfigManager::ADMIN_LOGS_ENABLED))
	{
		std::string logMsg;
		if(conn)
			logMsg = "[" + convertIPToString(conn->getIP()) + "] - ";

		logMsg += message;
		LOG_MESSAGE("OTADMIN", type, level, logMsg);
	}
}
예제 #5
0
void Commands::getInfo(Player* player, const std::string& cmd, const std::string& param)
{
	Player* paramPlayer = g_game.getPlayerByName(param);

	if (!paramPlayer) {
		player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Player not found.");
		return;
	}

	if (player->getAccountType() < paramPlayer->getAccountType()) {
		player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "You can not get info about this player.");
		return;
	}

	uint32_t playerIp = paramPlayer->getIP();

	std::ostringstream info;
	info << "Name: " << paramPlayer->name << std::endl <<
	     "Access: " << paramPlayer->group->access << std::endl <<
	     "Level: " << paramPlayer->level << std::endl <<
	     "Magic Level: " << paramPlayer->magLevel << std::endl <<
	     "Speed: " << paramPlayer->getSpeed() << std::endl <<
	     "Position: " << paramPlayer->getPosition() << std::endl <<
	     "IP: " << convertIPToString(playerIp) << std::endl;
	player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, info.str());

	if (playerIp != 0) {
		PlayerVector vec;

		for (const auto& it : g_game.getPlayers()) {
			if (it.second->getIP() != playerIp || it.second == paramPlayer) {
				continue;
			}

			vec.push_back(it.second);
		}

		if (!vec.empty()) {
			std::ostringstream ss;

			Player* tmpPlayer = vec[0];
			ss << "Other players on same IP: " << tmpPlayer->getName() << " [" << tmpPlayer->getLevel() << "]";

			for (PlayerVector::size_type i = 1, size = vec.size(); i < size; ++i) {
				tmpPlayer = vec[i];
				ss << ", " << tmpPlayer->getName() << " [" << tmpPlayer->getLevel() << "]";
			}

			ss << ".";
			player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, ss.str());
		}
	}
}
예제 #6
0
void Connection::parseHeader(const boost::system::error_code& error)
{
	std::lock_guard<std::recursive_mutex> lockClass(m_connectionLock);
	m_readTimer.cancel();

	int32_t size = m_msg.decodeHeader();
	if (error || size <= 0 || size >= NETWORKMESSAGE_MAXSIZE - 16) {
		handleReadError(error);
	}

	if (m_connectionState != CONNECTION_STATE_OPEN || m_readError) {
		close();
		return;
	}

	uint32_t timePassed = std::max<uint32_t>(1, (time(nullptr) - m_timeConnected) + 1);
	if ((++m_packetsSent / timePassed) > static_cast<uint32_t>(g_config.getNumber(ConfigManager::MAX_PACKETS_PER_SECOND))) {
		std::cout << convertIPToString(getIP()) << " disconnected for exceeding packet per second limit." << std::endl;
		close();
		return;
	}

	if (timePassed > 2) {
		m_timeConnected = time(nullptr);
		m_packetsSent = 0;
	}

	try {
		m_readTimer.expires_from_now(boost::posix_time::seconds(Connection::read_timeout));
		m_readTimer.async_wait( std::bind(&Connection::handleReadTimeout, std::weak_ptr<Connection>(shared_from_this()),
		                                    std::placeholders::_1));

		// Read packet content
		m_msg.setLength(size + NetworkMessage::header_length);
		boost::asio::async_read(getHandle(), boost::asio::buffer(m_msg.getBodyBuffer(), size),
		                        std::bind(&Connection::parsePacket, shared_from_this(), std::placeholders::_1));
	} catch (boost::system::system_error& e) {
		if (m_logError) {
			std::cout << "[Network error - Connection::parseHeader] " << e.what() << std::endl;
			m_logError = false;
		}

		close();
	}
}
예제 #7
0
void ProtocolStatus::onRecvFirstMessage(NetworkMessage& msg)
{
	uint32_t ip = getIP();
	if (ip != 0x0100007F) {
		std::string ipStr = convertIPToString(ip);
		if (ipStr != g_config.getString(ConfigManager::IP)) {
			std::map<uint32_t, int64_t>::const_iterator it = ipConnectMap.find(ip);
			if (it != ipConnectMap.end()) {
				if (OTSYS_TIME() < (it->second + g_config.getNumber(ConfigManager::STATUSQUERY_TIMEOUT))) {
					getConnection()->close();
					return;
				}
			}
		}
	}

	ipConnectMap[ip] = OTSYS_TIME();

	switch (msg.getByte()) {
		//XML info protocol
		case 0xFF: {
			if (msg.getString(4) == "info") {
				g_dispatcher.addTask(createTask(std::bind(&ProtocolStatus::sendStatusString, this)));
				return;
			}
			break;
		}

		//Another ServerInfo protocol
		case 0x01: {
			uint16_t requestedInfo = msg.get<uint16_t>(); // only a Byte is necessary, though we could add new info here
			std::string characterName;
			if (requestedInfo & REQUEST_PLAYER_STATUS_INFO) {
				characterName = msg.getString();
			}
			g_dispatcher.addTask(createTask(std::bind(&ProtocolStatus::sendInfo, this, requestedInfo, characterName)));
			return;
		}

		default:
			break;
	}
	getConnection()->close();
}
예제 #8
0
bool AdminProtocolConfig::allowIP(uint32_t ip)
{
	if (m_onlyLocalHost && ip != 0x0100007F) { //127.0.0.1
		addLogLine(NULL, LOGTYPE_WARNING, 1, std::string("forbidden connection try from ") + convertIPToString(ip));
		return false;
	}
	return true;
}
예제 #9
0
파일: admin.cpp 프로젝트: CkyLua/OTHire
bool AdminProtocolConfig::allowIP(uint32_t ip)
{
	if(m_onlyLocalHost){
		if(ip == 0x0100007F){ //127.0.0.1
			return true;
		}
		else{
			addLogLine(NULL, LOGTYPE_WARNING, 1, std::string("forbidden connection try from ") + convertIPToString(ip));
			return false;
		}
	}
	else{
		if(!g_bans.isIpDisabled(ip)){
			return true;
		}
		else{
			return false;
		}
	}
}
예제 #10
0
void Connection::parsePacket(const boost::system::error_code& error)
{
	m_connectionLock.lock();
	m_readTimer.cancel();

	if (error) {
		handleReadError(error);
	}

	if (m_connectionState != CONNECTION_STATE_OPEN || m_readError) {
		closeConnection();
		m_connectionLock.unlock();
		return;
	}

	uint32_t timePassed = std::max<uint32_t>(1, (time(nullptr) - m_timeConnected) + 1);
	if ((++m_packetsSent / timePassed) > (uint32_t)g_config.getNumber(ConfigManager::MAX_PACKETS_PER_SECOND)) {
		std::cout << convertIPToString(getIP()) << " disconnected for exceeding packet per second limit." << std::endl;
		closeConnection();
		m_connectionLock.unlock();
		return;
	}

	if (timePassed > 2) {
		m_timeConnected = time(nullptr);
		m_packetsSent = 0;
	}

	//Check packet checksum
	uint32_t checksum;
	int32_t len = m_msg.getMessageLength() - m_msg.getReadPos() - 4;
	if (len > 0) {
		checksum = adlerChecksum(m_msg.getBuffer() + m_msg.getReadPos() + 4, len);
	} else {
		checksum = 0;
	}

	uint32_t recvChecksum = m_msg.get<uint32_t>();
	if (recvChecksum != checksum) {
		// it might not have been the checksum, step back
		m_msg.SkipBytes(-4);
	}

	if (!m_receivedFirst) {
		// First message received
		m_receivedFirst = true;

		if (!m_protocol) {
			// Game protocol has already been created at this point
			m_protocol = m_service_port->make_protocol(recvChecksum == checksum, m_msg);
			if (!m_protocol) {
				closeConnection();
				m_connectionLock.unlock();
				return;
			}

			m_protocol->setConnection(shared_from_this());
		} else {
			m_msg.GetByte();    // Skip protocol ID
		}

		m_protocol->onRecvFirstMessage(m_msg);
	} else {
		m_protocol->onRecvMessage(m_msg);    // Send the packet to the current protocol
	}

	try {
		m_readTimer.expires_from_now(boost::posix_time::seconds(Connection::read_timeout));
		m_readTimer.async_wait( std::bind(&Connection::handleReadTimeout, std::weak_ptr<Connection>(shared_from_this()),
		                                    std::placeholders::_1));

		// Wait to the next packet
		boost::asio::async_read(getHandle(),
		                        boost::asio::buffer(m_msg.getBuffer(), NetworkMessage::header_length),
		                        std::bind(&Connection::parseHeader, shared_from_this(), std::placeholders::_1));
	} catch (boost::system::system_error& e) {
		if (m_logError) {
			std::cout << "[Network error - Connection::parsePacket] " << e.what() << std::endl;
			m_logError = false;
		}

		closeConnection();
	}

	m_connectionLock.unlock();
}