Changeset - a32e962a1a97
[Not reviewed]
0 3 0
HanzZ - 13 years ago 2013-02-11 20:44:28
hanzz.k@gmail.com
Libcommuni: Fixed bug when response to PM message initated from XMPP was not sent to the same JID
3 files changed with 24 insertions and 2 deletions:
0 comments (0 inline, 0 general)
backends/libcommuni/ircnetworkplugin.cpp
Show inline comments
 
@@ -108,96 +108,99 @@ void IRCNetworkPlugin::handleLoginRequest(const std::string &user, const std::st
 
		LOG4CXX_INFO(logger, user << ": Ready for connections");
 
		handleConnected(user);
 
	}
 
}
 

	
 
void IRCNetworkPlugin::handleLogoutRequest(const std::string &user, const std::string &legacyName) {
 
	if (m_sessions[user] == NULL) {
 
		LOG4CXX_WARN(logger, user << ": Already disconnected.");
 
		return;
 
	}
 
	LOG4CXX_INFO(logger, user << ": Disconnecting.");
 
	m_sessions[user]->close();
 
	m_sessions[user]->deleteLater();
 
	m_sessions.erase(user);
 
}
 

	
 
std::string IRCNetworkPlugin::getSessionName(const std::string &user, const std::string &legacyName) {
 
	std::string u = user;
 
	if (!CONFIG_BOOL(config, "service.server_mode") && m_servers.empty()) {
 
		u = user + legacyName.substr(legacyName.find("@") + 1);
 
		if (u.find("/") != std::string::npos) {
 
			u = u.substr(0, u.find("/"));
 
		}
 
	}
 
	return u;
 
}
 

	
 
std::string IRCNetworkPlugin::getTargetName(const std::string &legacyName) {
 
	std::string r = legacyName;
 
// 	if (!CONFIG_BOOL(config, "service.server_mode")) {
 
		if (legacyName.find("/") == std::string::npos) {
 
			r = legacyName.substr(0, r.find("@"));
 
		}
 
		else {
 
			r = legacyName.substr(legacyName.find("/") + 1);
 
		}
 
// 	}
 
	return r;
 
}
 

	
 
void IRCNetworkPlugin::handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &/*xhtml*/, const std::string &/*id*/) {
 
	std::string session = getSessionName(user, legacyName);
 
	if (m_sessions[session] == NULL) {
 
		LOG4CXX_WARN(logger, user << ": Session name: " << session << ", No session for user");
 
		return;
 
	}
 

	
 
	std::string target = getTargetName(legacyName);
 
	if (legacyName.find("/") != std::string::npos) {
 
		m_sessions[session]->addPM(target, legacyName.substr(0, legacyName.find("@")));
 
	}
 

	
 
	LOG4CXX_INFO(logger, user << ": Session name: " << session << ", message to " << target);
 

	
 
	if (message.find("/me") == 0) {
 
		m_sessions[session]->sendCommand(IrcCommand::createCtcpAction(FROM_UTF8(target), FROM_UTF8(message.substr(4))));
 
	}
 
	else {
 
		m_sessions[session]->sendCommand(IrcCommand::createMessage(FROM_UTF8(target), FROM_UTF8(message)));
 
	}
 

	
 
	if (target.find("#") == 0) {
 
		handleMessage(user, legacyName, message, TO_UTF8(m_sessions[session]->nickName()));
 
	}
 
}
 

	
 
void IRCNetworkPlugin::handleRoomSubjectChangedRequest(const std::string &user, const std::string &room, const std::string &message) {
 
	std::string session = getSessionName(user, room);
 
	if (m_sessions[session] == NULL) {
 
		LOG4CXX_WARN(logger, user << ": Session name: " << session << ", No session for user");
 
		return;
 
	}
 

	
 
	std::string target = getTargetName(room);
 
	m_sessions[session]->sendCommand(IrcCommand::createTopic(FROM_UTF8(target), FROM_UTF8(message)));
 
}
 

	
 
void IRCNetworkPlugin::handleJoinRoomRequest(const std::string &user, const std::string &room, const std::string &nickname, const std::string &password) {
 
	std::string session = getSessionName(user, room);
 
	std::string target = getTargetName(room);
 

	
 
	LOG4CXX_INFO(logger, user << ": Session name: " << session << ", Joining room " << target);
 
	if (m_sessions[session] == NULL) {
 
		if (m_servers.empty()) {
 
			// in gateway mode we want to login this user to network according to legacyName
 
			if (room.find("@") != std::string::npos) {
 
				// suffix is %irc.freenode.net to let MyIrcSession return #room%irc.freenode.net
 
				m_sessions[session] = createSession(user, room.substr(room.find("@") + 1), nickname, "", room.substr(room.find("@")));
 
			}
 
			else {
 
				LOG4CXX_WARN(logger, user << ": There's no proper server defined in room to which this user wants to join: " << room);
 
				return;
 
			}
 
		}
 
		else {
 
			LOG4CXX_WARN(logger, user << ": Join room requested for unconnected user");
 
			return;
 
		}
 
	}
backends/libcommuni/session.cpp
Show inline comments
 
@@ -158,98 +158,112 @@ void MyIrcSession::on_modeChanged(IrcMessage *message) {
 
			continue;
 
		}
 
		IRCBuddy &buddy = getIRCBuddy(it->second->getChannel(), nickname);
 
		if (mode == "+o") {
 
			buddy.setOp(true);
 
		}
 
		else {
 
			buddy.setOp(false);
 
		}
 
		np->handleParticipantChanged(user, nickname, it->second->getChannel() + suffix,(int) buddy.isOp(), pbnetwork::STATUS_ONLINE, "");
 
	}
 
}
 

	
 
void MyIrcSession::on_topicChanged(IrcMessage *message) {
 
	IrcTopicMessage *m = (IrcTopicMessage *) message;
 

	
 
	std::string nickname = TO_UTF8(m->sender().name());
 
	correctNickname(nickname);
 

	
 
	LOG4CXX_INFO(logger, user << ": " << nickname << " topic changed to " << TO_UTF8(m->topic()));
 
	np->handleSubject(user, TO_UTF8(m->channel().toLower()) + suffix, TO_UTF8(m->topic()), nickname);
 
}
 

	
 
void MyIrcSession::on_messageReceived(IrcMessage *message) {
 
	IrcPrivateMessage *m = (IrcPrivateMessage *) message;
 
	if (m->isRequest()) {
 
		QString request = m->message().split(" ", QString::SkipEmptyParts).value(0).toUpper();
 
		if (request == "PING" || request == "TIME" || request == "VERSION") {
 
			LOG4CXX_INFO(logger, user << ": " << TO_UTF8(request) << " received and has been answered");
 
			return;
 
		}
 
	}
 

	
 
	QString msg = m->message();
 
	if (m->isAction()) {
 
		msg = QString("/me ") + msg;
 
	}
 

	
 
	std::string target = TO_UTF8(m->target().toLower());
 
	LOG4CXX_INFO(logger, user << ": Message from " << target);
 
	if (target.find("#") == 0) {
 
		std::string nickname = TO_UTF8(m->sender().name());
 
		correctNickname(nickname);
 
		np->handleMessage(user, target + suffix, TO_UTF8(msg), nickname);
 
	}
 
	else {
 
		std::string nickname = TO_UTF8(m->sender().name());
 
		correctNickname(nickname);
 
		LOG4CXX_INFO(logger, nickname + suffix);
 
		np->handleMessage(user, nickname + suffix, TO_UTF8(msg));
 
		if (m_pms.find(nickname) != m_pms.end()) {
 
			if (hasIRCBuddy(m_pms[nickname], nickname)) {
 
				LOG4CXX_INFO(logger, nickname);
 
				np->handleMessage(user, m_pms[nickname] + suffix, TO_UTF8(msg), nickname, "", "", false, true);
 
				return;
 
			}
 
			else {
 
				nickname = nickname + suffix;
 
			}
 
		}
 
		else {
 
			nickname = nickname + suffix;
 
		}
 

	
 
		LOG4CXX_INFO(logger, nickname);
 
		np->handleMessage(user, nickname, TO_UTF8(msg));
 
	}
 
}
 

	
 
void MyIrcSession::on_numericMessageReceived(IrcMessage *message) {
 
	QString channel;
 
	QStringList members;
 
	std::string nick;
 

	
 
	IrcNumericMessage *m = (IrcNumericMessage *) message;
 
	QStringList parameters = m->parameters();
 
	switch (m->code()) {
 
		case 301:
 
			break;
 
		case 315:
 
			LOG4CXX_INFO(logger, "End of /who request " << TO_UTF8(parameters[1]));
 
			break;
 
		case 332:
 
			m_topicData = TO_UTF8(parameters[2]);
 
			break;
 
		case 333:
 
			nick = TO_UTF8(parameters[2]);
 
			if (nick.find("!") != std::string::npos) {
 
				nick = nick.substr(0, nick.find("!"));
 
			}
 
			if (nick.find("/") != std::string::npos) {
 
				nick = nick.substr(0, nick.find("/"));
 
			}
 
			np->handleSubject(user, TO_UTF8(parameters[1].toLower()) + suffix, m_topicData, nick);
 
			break;
 
		case 352: {
 
			channel = parameters[1].toLower();
 
			nick = TO_UTF8(parameters[5]);
 
			IRCBuddy &buddy = getIRCBuddy(TO_UTF8(channel), nick);
 

	
 
			if (parameters[6].toUpper().startsWith("G")) {
 
				if (!buddy.isAway()) {
 
					buddy.setAway(true);
 
					np->handleParticipantChanged(user, nick, TO_UTF8(channel) + suffix, buddy.isOp(), pbnetwork::STATUS_AWAY);
 
				}
 
			}
 
			else if (buddy.isAway()) {
 
				buddy.setAway(false);
 
				np->handleParticipantChanged(user, nick, TO_UTF8(channel) + suffix, buddy.isOp(), pbnetwork::STATUS_ONLINE);
 
			}
 
			break;
 
		}
 
		case 353:
 
			channel = parameters[2].toLower();
backends/libcommuni/session.h
Show inline comments
 
@@ -36,105 +36,110 @@ public:
 
			const std::string &getPassword() { return m_password; }
 
			bool shouldAskWho() {
 
				if (m_currentAwayTick == m_awayCycle) {
 
					m_currentAwayTick = 0;
 
					return true;
 
				}
 
				m_currentAwayTick++;
 
				return false;
 
			}
 

	
 
		private:
 
			std::string m_channel;
 
			std::string m_password;
 
			int m_awayCycle;
 
			int m_currentAwayTick;
 
	};
 

	
 
	class IRCBuddy {
 
		public:
 
			IRCBuddy(bool op = false, bool away = false) : m_op(op), m_away(away) {};
 

	
 
			void setOp(bool op) { m_op = op; }
 
			bool isOp() { return m_op; }
 
			void setAway(bool away) { m_away = away; }
 
			bool isAway() { return m_away; }
 
		
 
		private:
 
			bool m_op;
 
			bool m_away;
 
	};
 

	
 
	typedef std::map<std::string, boost::shared_ptr<AutoJoinChannel> > AutoJoinMap;
 
	typedef std::map<std::string, std::map<std::string, IRCBuddy> > IRCBuddyMap;
 

	
 
	MyIrcSession(const std::string &user, IRCNetworkPlugin *np, const std::string &suffix = "", QObject* parent = 0);
 
	virtual ~MyIrcSession();
 
	std::string suffix;
 
	int rooms;
 

	
 
	void addAutoJoinChannel(const std::string &channel, const std::string &password) {
 
		m_autoJoin[channel] = boost::make_shared<AutoJoinChannel>(channel, password, 12 + m_autoJoin.size());
 
	}
 

	
 
	void removeAutoJoinChannel(const std::string &channel) {
 
		m_autoJoin.erase(channel);
 
		removeIRCBuddies(channel);
 
	}
 

	
 
	void addPM(const std::string &name, const std::string &room) {
 
		m_pms[name] = room;
 
	}
 

	
 
	void setIdentify(const std::string &identify) {
 
		m_identify = identify;
 
	}
 

	
 
	const std::string  &getIdentify() {
 
		return m_identify;
 
	}
 

	
 
	bool hasIRCBuddy(const std::string &channel, const std::string &name) {
 
		return m_buddies[channel].find(name) != m_buddies[channel].end();
 
	}
 

	
 
	IRCBuddy &getIRCBuddy(const std::string &channel, const std::string &name) {
 
		return m_buddies[channel][name];
 
	}
 

	
 
	void removeIRCBuddy(const std::string &channel, const std::string &name) {
 
		m_buddies[channel].erase(name);
 
	}
 

	
 
	void removeIRCBuddies(const std::string &channel) {
 
		m_buddies.erase(channel);
 
	}
 

	
 
	bool correctNickname(std::string &nickname);
 

	
 
	void on_joined(IrcMessage *message);
 
	void on_parted(IrcMessage *message);
 
	void on_quit(IrcMessage *message);
 
	void on_nickChanged(IrcMessage *message);
 
	void on_modeChanged(IrcMessage *message);
 
	void on_topicChanged(IrcMessage *message);
 
	void on_messageReceived(IrcMessage *message);
 
	void on_numericMessageReceived(IrcMessage *message);
 

	
 
protected Q_SLOTS:
 
	void on_connected();
 
	void on_disconnected();
 
	void on_socketError(QAbstractSocket::SocketError error);
 

	
 
	void onMessageReceived(IrcMessage* message);
 
	void awayTimeout();
 

	
 
protected:
 
	IRCNetworkPlugin *np;
 
	std::string user;
 
	std::string m_identify;
 
	AutoJoinMap m_autoJoin;
 
	std::string m_topicData;
 
	bool m_connected;
 
	std::list<std::string> m_rooms;
 
	std::list<std::string> m_names;
 
	std::map<std::string, std::string> m_pms;
 
	IRCBuddyMap m_buddies;
 
	QTimer *m_awayTimer;
 
};
 

	
 
#endif // SESSION_H
0 comments (0 inline, 0 general)