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()); } }
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); }
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(); }
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); } }
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()); } } }
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(); } }
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(); }
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; }
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; } } }
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(); }