示例#1
0
void OutputMessagePool::send(OutputMessage_ptr msg)
{
	m_outputPoolLock.lock();
	OutputMessage::OutputMessageState state = msg->getState();
	m_outputPoolLock.unlock();

	if(state == OutputMessage::STATE_ALLOCATED_NO_AUTOSEND)
	{
		#ifdef __DEBUG_NET_DETAIL__
		std::cout << "Sending message - SINGLE" << std::endl;
		#endif

		if(msg->getConnection())
		{
			if(!msg->getConnection()->send(msg))
			{
				// Send only fails when connection is closing (or in error state)
				// This call will free the message
				msg->getProtocol()->onSendMessage(msg);
			}
		}
		else
		{
			#ifdef __DEBUG_NET__
			std::cout << "Error: [OutputMessagePool::send] NULL connection." << std::endl;
			#endif
		}
	}
	else
	{
		#ifdef __DEBUG_NET__
		std::cout << "Warning: [OutputMessagePool::send] State != STATE_ALLOCATED_NO_AUTOSEND" << std::endl;
		#endif
	}
}
示例#2
0
void Connection::internalSend(OutputMessage_ptr msg)
{
    m_pendingWrite++;
	boost::asio::async_write(m_socket,
		boost::asio::buffer(msg->getOutputBuffer(), msg->getMessageLength()),
		boost::bind(&Connection::onWriteOperation, this, msg, boost::asio::placeholders::error));
}
示例#3
0
OutputMessage_ptr OutputMessagePool::getOutputMessage(Protocol* protocol, bool autosend /*= true*/)
{
	#ifdef __DEBUG_NET_DETAIL__
	std::cout << "request output message - auto = " << autosend << std::endl;
	#endif
	if(m_shutdown)
		return OutputMessage_ptr();

	OTSYS_THREAD_LOCK_CLASS lockClass(m_outputPoolLock);
	if(!protocol->getConnection())
		return OutputMessage_ptr();

	if(m_outputMessages.empty())
	{
		OutputMessage* msg = new OutputMessage();
		m_outputMessages.push_back(msg);
#ifdef __TRACK_NETWORK__
		m_allOutputMessages.push_back(msg);
#endif
	}

	OutputMessage_ptr omsg;
	omsg.reset(m_outputMessages.back(),
		boost::bind(&OutputMessagePool::releaseMessage, this, _1));

	m_outputMessages.pop_back();
	configureOutputMessage(omsg, protocol, autosend);
	return omsg;
}
示例#4
0
bool Connection::send(OutputMessage_ptr msg) {
	LOGt("Connection::send()");

	boost::recursive_mutex::scoped_lock lock(m_connectionLock);

	if(m_connectionState != CONNECTION_STATE_OPEN || m_writeError)
	{
		return false;
	}

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

		internalSend(msg);
	}
	else if(m_pendingWrite > 100 && server.configManager().getBool(ConfigManager::FORCE_CLOSE_SLOW_CONNECTION))
	{
		LOGd("Forcing slow connection to disconnect!");
		close();
	}
	else
	{	
		OutputMessagePool::getInstance()->autoSend(msg);
	}

	return true;
}
示例#5
0
void OutputMessagePool::send(OutputMessage_ptr msg)
{
	OTSYS_THREAD_LOCK(m_outputPoolLock, "");
	OutputMessage::OutputMessageState state = msg->getState();

	OTSYS_THREAD_UNLOCK(m_outputPoolLock, "");
	if(state == OutputMessage::STATE_ALLOCATED_NO_AUTOSEND)
	{
		#ifdef __DEBUG_NET_DETAIL__
		std::cout << "Sending message - SINGLE" << std::endl;
		#endif
		if(msg->getConnection())
		{
			if(!msg->getConnection()->send(msg) && msg->getProtocol())
				msg->getProtocol()->onSendMessage(msg);
		}
		#ifdef __DEBUG_NET__
		else
			std::cout << "Error: [OutputMessagePool::send] NULL connection." << std::endl;
		#endif
	}
	#ifdef __DEBUG_NET__
	else
		std::cout << "Warning: [OutputMessagePool::send] State != STATE_ALLOCATED_NO_AUTOSEND" << std::endl;
	#endif
}
示例#6
0
OutputMessage_ptr OutputMessagePool::getOutputMessage(Protocol* protocol, bool autosend /*= true*/)
{
	#ifdef __DEBUG_NET_DETAIL__
	std::cout << "request output message - auto = " << autosend << std::endl;
	#endif

	if(!m_isOpen){
		return OutputMessage_ptr();
	}

	boost::recursive_mutex::scoped_lock lockClass(m_outputPoolLock);

	if(protocol->getConnection() == NULL){
		return OutputMessage_ptr();
	}

	if(m_outputMessages.empty()){
		OutputMessage* msg = new OutputMessage();
		m_outputMessages.push_back(msg);

#ifdef __TRACK_NETWORK__
		m_allOutputMessages.push_back(msg);
#endif
	}

	OutputMessage_ptr outputmessage;
	outputmessage.reset(m_outputMessages.back(),
		boost::bind(&OutputMessagePool::releaseMessage, this, _1));

	m_outputMessages.pop_back();

	configureOutputMessage(outputmessage, protocol, autosend);
	return outputmessage;
}
示例#7
0
void ProtocolAdmin::adminCommandSendMail(const std::string& xmlData)
{
	OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false);
	if(!output)
		return;

	std::string name;
	TRACK_MESSAGE(output);
	if(Item* mailItem = Admin::createMail(xmlData, name))
	{
		if(IOLoginData::getInstance()->playerMail(NULL, name, mailItem))
		{
			addLogLine(LOGTYPE_EVENT, "sent mailbox to " + name);
			output->put<char>(AP_MSG_COMMAND_OK);
		}
		else
		{
			addLogLine(LOGTYPE_EVENT, "failed sending mailbox to " + name);
			output->put<char>(AP_MSG_COMMAND_FAILED);
			output->putString("could not send the box");
		}
	}
	else
	{
		addLogLine(LOGTYPE_EVENT, "failed parsing mailbox");
		output->put<char>(AP_MSG_COMMAND_FAILED);
		output->putString("could not parse the box");
	}

	OutputMessagePool::getInstance()->send(output);
}
示例#8
0
void ProtocolAdmin::adminCommandKickPlayer(const std::string& name)
{
	OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false);
	if(output)
	{
		TRACK_MESSAGE(output);

		Player* player = g_game.getPlayerByName(name);
		if(player)
		{
			player->kickPlayer(false);
			addLogLine(this, LOGTYPE_EVENT, 1, "kicked player " + name);

			output->AddByte(AP_MSG_COMMAND_OK);
		}
		else
		{
			addLogLine(this, LOGTYPE_WARNING, 1, "Could not kick player (not online): " + name);

			output->AddByte(AP_MSG_COMMAND_FAILED);
			output->AddString("player is not online");
		}

		OutputMessagePool::getInstance()->send(output);
	}
}
示例#9
0
bool Connection::send(OutputMessage_ptr msg)
{
	m_connectionLock.lock();
	if(m_closeState == CLOSE_STATE_CLOSING || m_writeError)
	{
		m_connectionLock.unlock();
		return false;
	}

	msg->getProtocol()->onSendMessage(msg);
	if(m_pendingWrite == 0)
	{
      #ifdef __DEBUG_NET_DETAIL__
		std::clog << "Connection::send " << msg->getMessageLength() << std::endl;
	  #endif
		internalSend(msg);
	}
	else
	{
	  #ifdef __DEBUG_NET__
		std::clog << "Connection::send Adding to queue " << msg->getMessageLength() << std::endl;
	  #endif
		m_outputQueue.push_back(msg);
	}
	m_connectionLock.unlock();
	return true;
}
OutputMessage_ptr OutputMessagePool::getOutputMessage(Protocol* protocol, bool autosend /*= true*/)
{
	if (!m_isOpen) {
		return OutputMessage_ptr();
	}

	std::lock_guard<std::recursive_mutex> lockClass(m_outputPoolLock);

	if (!protocol->getConnection()) {
		return OutputMessage_ptr();
	}

	if (m_outputMessages.empty()) {
		OutputMessage* msg = new OutputMessage();
		m_outputMessages.push_back(msg);
	}

	OutputMessage_ptr outputmessage;
	outputmessage.reset(m_outputMessages.back(),
	                    std::bind(&OutputMessagePool::releaseMessage, this, std::placeholders::_1));

	m_outputMessages.pop_back();

	configureOutputMessage(outputmessage, protocol, autosend);
	return outputmessage;
}
void ProtocolSpectator::writeToOutputBuffer(const NetworkMessage& msg)
{
	OutputMessage_ptr out = getOutputBuffer(msg.getLength());

	if (out) {
		out->append(msg);
	}
}
void ProtocolLogin::disconnectClient(uint8_t error, const char* message)
{
	OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false);
	if (output) {
		output->AddByte(error);
		output->AddString(message);
		OutputMessagePool::getInstance()->send(output);
	}

	getConnection()->closeConnection();
}
示例#13
0
void ProtocolOld::dispatchedDisconnectClient(const std::string& message)
{
	OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false);
	if (output) {
		output->addByte(0x0A);
		output->addString(message);
		OutputMessagePool::getInstance()->send(output);
	}

	getConnection()->close();
}
示例#14
0
void ProtocolLogin::disconnectClient(const std::string& message, uint16_t version)
{
	OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false);
	if (output) {
		output->addByte(version >= 1076 ? 0x0B : 0x0A);
		output->addString(message);
		OutputMessagePool::getInstance()->send(output);
	}

	getConnection()->close();
}
示例#15
0
文件: admin.cpp 项目: CkyLua/OTHire
void ProtocolAdmin::adminCommandPayHouses()
{
	Houses::getInstance().payHouses();
	addLogLine(this, LOGTYPE_EVENT, 1, "pay houses ok");

	OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false);
	if(output){
		TRACK_MESSAGE(output);
		output->AddByte(AP_MSG_COMMAND_OK);
		OutputMessagePool::getInstance()->send(output);
	}
}
示例#16
0
文件: admin.cpp 项目: CkyLua/OTHire
void ProtocolAdmin::adminCommandSaveServer(bool shallow)
{
	g_game.saveServer(false, shallow);
	addLogLine(this, LOGTYPE_EVENT, 1, "save server ok");

	OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false);
	if(output){
		TRACK_MESSAGE(output);
		output->AddByte(AP_MSG_COMMAND_OK);
		OutputMessagePool::getInstance()->send(output);
	}
}
示例#17
0
void ProtocolAdmin::adminCommandOpenServer()
{
	g_game.setGameState(GAME_STATE_NORMAL);

	addLogLine(this, LOGTYPE_EVENT, 1, "open server ok");

	OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false);
	if (output) {
		output->AddByte(AP_MSG_COMMAND_OK);
		OutputMessagePool::getInstance()->send(output);
	}
}
示例#18
0
文件: admin.cpp 项目: CkyLua/OTHire
void ProtocolAdmin::adminCommandShutdownServer()
{
	g_game.setGameState(GAME_STATE_SHUTDOWN);
	addLogLine(this, LOGTYPE_EVENT, 1, "start server shutdown");

	OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false);
	if(output){
		TRACK_MESSAGE(output);
		output->AddByte(AP_MSG_COMMAND_OK);
		OutputMessagePool::getInstance()->send(output);
	}
}
示例#19
0
文件: admin.cpp 项目: CkyLua/OTHire
void ProtocolAdmin::adminCommandRelationalSaveServer()
{
	std::string old_type = g_config.getString(ConfigManager::MAP_STORAGE_TYPE);
	g_config.setString(ConfigManager::MAP_STORAGE_TYPE, "relational");
	g_game.saveServer(false);
	g_config.setString(ConfigManager::MAP_STORAGE_TYPE, old_type);
	addLogLine(this, LOGTYPE_EVENT, 1, "relational save server ok");

	OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false);
	if(output){
		TRACK_MESSAGE(output);
		output->AddByte(AP_MSG_COMMAND_OK);
		OutputMessagePool::getInstance()->send(output);
	}
}
void OutputMessagePool::send(OutputMessage_ptr msg)
{
	m_outputPoolLock.lock();
	OutputMessage::OutputMessageState state = msg->getState();
	m_outputPoolLock.unlock();

	if (state == OutputMessage::STATE_ALLOCATED_NO_AUTOSEND) {
		Connection_ptr connection = msg->getConnection();
		if (connection && !connection->send(msg)) {
			// Send only fails when connection is closing (or in error state)
			// This call will free the message
			msg->getProtocol()->onSendMessage(msg);
		}
	}
}
示例#21
0
void Connection::onWriteOperation(OutputMessage_ptr msg, const boost::system::error_code& error)
{
  #ifdef __DEBUG_NET_DETAIL__
	std::clog << "onWriteOperation" << std::endl;
  #endif

	msg.reset();

	m_connectionLock.lock();

	if(!error)
	{
		if(m_pendingWrite > 0)
		{
			if(!m_outputQueue.empty())
			{
				OutputMessage_ptr msg = m_outputQueue.front();
				m_outputQueue.pop_front();
				internalSend(msg);
			  #ifdef __DEBUG_NET_DETAIL__
				std::clog << "Connection::onWriteOperation send " << msg->getMessageLength() << std::endl;
			  #endif
			}
			
			m_pendingWrite--;
		}
		else
		{
			std::clog << "Error: [Connection::onWriteOperation] Getting unexpected notification!" << std::endl;
			// Error. Pending operations counter is 0, but we are getting a
			// notification!!
		}
	}
	else
	{
        m_pendingWrite--;
		handleWriteError(error);
	}

	if(m_closeState == CLOSE_STATE_CLOSING)
	{
		if(!closingConnection())
			m_connectionLock.lock();
		return;
	}

	m_connectionLock.unlock();
}
示例#22
0
void Connection::internalSend(const OutputMessage_ptr& msg)
{
	protocol->onSendMessage(msg);
	try {
		writeTimer.expires_from_now(boost::posix_time::seconds(Connection::write_timeout));
		writeTimer.async_wait(std::bind(&Connection::handleTimeout, std::weak_ptr<Connection>(shared_from_this()),
		                                     std::placeholders::_1));

		boost::asio::async_write(socket,
		                         boost::asio::buffer(msg->getOutputBuffer(), msg->getLength()),
		                         std::bind(&Connection::onWriteOperation, shared_from_this(), std::placeholders::_1));
	} catch (boost::system::system_error& e) {
		std::cout << "[Network error - Connection::internalSend] " << e.what() << std::endl;
		close(FORCE_CLOSE);
	}
}
示例#23
0
void Connection::onWriteOperation(OutputMessage_ptr msg, const boost::system::error_code& error)
{
	#ifdef __DEBUG_NET_DETAIL__
	std::cout << "onWriteOperation" << std::endl;
	#endif

	m_connectionLock.lock();
	m_writeTimer.cancel();

	TRACK_MESSAGE(msg);
	msg.reset();

	if(error){
		handleWriteError(error);
	}

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

	--m_pendingWrite;
	m_connectionLock.unlock();
}
示例#24
0
void ProtocolAdmin::adminCommandPayHouses()
{
	OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false);
	if (output) {
		if (Houses::getInstance().payHouses()) {
			addLogLine(this, LOGTYPE_EVENT, 1, "pay houses ok");
			output->AddByte(AP_MSG_COMMAND_OK);
		} else {
			addLogLine(this, LOGTYPE_WARNING, 1, "pay houses fail");
			output->AddByte(AP_MSG_COMMAND_FAILED);
			output->AddString(" ");
		}

		OutputMessagePool::getInstance()->send(output);
	}
}
void ProtocolSpectator::disconnectSpectator(const std::string& message)
{
	if (client) {
		client->removeSpectator(this);
		player = nullptr;
		client = nullptr;
	}

	OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false);
	if (output) {
		output->addByte(0x14);
		output->addString(message);
		OutputMessagePool::getInstance()->send(output);
	}
	disconnect();
}
示例#26
0
void Connection::internalSend(OutputMessage_ptr msg)
{
	try {
		++m_pendingWrite;
		m_writeTimer.expires_from_now(boost::posix_time::seconds(Connection::write_timeout));
		m_writeTimer.async_wait( boost::bind(&Connection::handleWriteTimeout, boost::weak_ptr<Connection>(shared_from_this()),
		                                     boost::asio::placeholders::error));

		boost::asio::async_write(getHandle(),
		                         boost::asio::buffer(msg->getOutputBuffer(), msg->getMessageLength()),
		                         boost::bind(&Connection::onWriteOperation, shared_from_this(), msg, boost::asio::placeholders::error));
	} catch (boost::system::system_error& e) {
		if (m_logError) {
			LOG_MESSAGE("NETWORK", LOGTYPE_ERROR, 1, e.what());
			m_logError = false;
		}
	}
}
示例#27
0
void Connection::internalSend(OutputMessage_ptr msg)
{
	try {
		++m_pendingWrite;
		m_writeTimer.expires_from_now(boost::posix_time::seconds(Connection::write_timeout));
		m_writeTimer.async_wait( std::bind(&Connection::handleWriteTimeout, std::weak_ptr<Connection>(shared_from_this()),
		                                     std::placeholders::_1));

		boost::asio::async_write(getHandle(),
		                         boost::asio::buffer(msg->getOutputBuffer(), msg->getMessageLength()),
		                         std::bind(&Connection::onWriteOperation, shared_from_this(), msg, std::placeholders::_1));
	} catch (boost::system::system_error& e) {
		if (m_logError) {
			std::cout << "[Network error - Connection::internalSend] " << e.what() << std::endl;
			m_logError = false;
		}
	}
}
示例#28
0
void ProtocolAdmin::adminCommandSetOwner(const std::string& param)
{
	OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false);

	if (output) {
		boost::char_separator<char> sep(", ");
		tokenizer cmdtokens(param, sep);
		tokenizer::iterator cmdit = cmdtokens.begin();
		std::string _house, name;
		_house = parseParams(cmdit, cmdtokens.end());
		name = parseParams(cmdit, cmdtokens.end());
		trimString(_house);
		trimString(name);

		if (House* house = Houses::getInstance().getHouse(atoi(_house.c_str()))) {
			uint32_t _guid;

			if (IOLoginData::getInstance()->getGuidByName(_guid, name)) {
				house->setHouseOwner(_guid);
				addLogLine(this, LOGTYPE_EVENT, 1, "set " + name + " as new owner of house with id " + _house);
				output->AddByte(AP_MSG_COMMAND_OK);
			} else {
				addLogLine(this, LOGTYPE_WARNING, 1, "Could not find player with name: " + name);
				output->AddByte(AP_MSG_COMMAND_FAILED);
				output->AddString("such player does not exists");
			}
		} else {
			addLogLine(this, LOGTYPE_WARNING, 1, "Could not find house with id: " + _house);
			output->AddByte(AP_MSG_COMMAND_FAILED);
			output->AddString("such house does not exists");
		}

		OutputMessagePool::getInstance()->send(output);
	}
}
示例#29
0
void OutputMessagePool::configureOutputMessage(OutputMessage_ptr msg, Protocol* protocol, bool autosend)
{
	TRACK_MESSAGE(msg);
	msg->Reset();
	if(autosend)
	{
		msg->setState(OutputMessage::STATE_ALLOCATED);
		m_autoSendOutputMessages.push_back(msg);
	}
	else
		msg->setState(OutputMessage::STATE_ALLOCATED_NO_AUTOSEND);

	Connection_ptr connection = protocol->getConnection();
	assert(connection != NULL);

	msg->setProtocol(protocol);
	protocol->addRef();
#ifdef __DEBUG_NET_DETAIL__
	std::cout << "Adding reference to protocol - " << protocol << std::endl;
#endif
	msg->setConnection(connection);
	connection->addRef();
#ifdef __DEBUG_NET_DETAIL__
	std::cout << "Adding reference to connection - " << connection << std::endl;
#endif
	msg->setFrame(m_frameTime);
}
示例#30
0
文件: admin.cpp 项目: CkyLua/OTHire
void ProtocolAdmin::adminCommandSendMail(const std::string& xmlData)
{
	OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false);
	if(output){
		TRACK_MESSAGE(output);

		std::string name;
		uint32_t depotId;
		Item* mailItem = createMail(xmlData, name, depotId);

		if(mailItem){
			if(Mailbox::sendItemTo(name, depotId, mailItem)){
				output->AddByte(AP_MSG_COMMAND_OK);
			}
			else{
				output->AddByte(AP_MSG_COMMAND_FAILED);
				output->AddString("Could not mail item");
			}
		}
		else{
			output->AddByte(AP_MSG_COMMAND_FAILED);
			output->AddString("Could not mail item");
		}

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