示例#1
0
bool test_userlist(plugin_pipe p)
{
	message m=p.blocking_read();
	if (m.type!="userlist")
		return false;
	auto u=dynamic_cast<userlist_message *>(m.getdata());
	if (!u)
		return false;
	if (!u->statuses.empty())
		return false;
	p.write(received_message::create(received_message_subtype::NORMAL, "POTUS", "James K Polk", "Invade Texas!", QHostAddress("3.4.18.45")));
	this_thread::sleep_for(chrono::seconds(11));
	m=p.read();
	if (m.type!="userlist")
		return false;
	u=dynamic_cast<userlist_message *>(m.getdata());
	if (!u)
		return false;
	if (u->statuses.size()!=1)
		return false;
	auto i=u->statuses.find("James K Polk");
	if (i==u->statuses.end())
		return false;
	if (i->second.nick!="James K Polk")
		return false;
	if (i->second.channels.size()!=1)
		return false;
	if (i->second.channels.find("POTUS")==i->second.channels.end())
		return false;
	if (i->second.ip!=QHostAddress("3.4.18.45"))
		return false;
	auto diff=time(NULL)-i->second.lastseen;
	if (diff<10 || diff>12)
		return false;
	this_thread::sleep_for(chrono::minutes(2));
	message mm=p.read();
	while (mm.type!="")
	{
		m=mm;
		mm=p.read();
	}
	if (m.type!="userlist")
		return false;
	u=dynamic_cast<userlist_message *>(m.getdata());
	if (!u)
		return false;
	if (!u->statuses.empty())
		return false;
	return true;
}
示例#2
0
void run(plugin_pipe p, string name)
{
	if (name=="userlist")
	{
		p.write(registration_message::create(0, name, "userlist"));
		bool ready=false;
		while (!ready)
		{
			message m=p.blocking_read();
			if (m.type!="registration_status")
				return;
			ready=dynamic_cast<registration_status *>(m.getdata())->status;
		}
		p.write(plugin_adder::create("real_userlist", "lib/libuserlist.so"));
		if (!test_userlist(p))
		{
			p.write(core_quit_message::create());
			return;
		}
	}
	p.write(core_quit_message::create());
	cout << "Success!" << endl;
}
示例#3
0
void run(plugin_pipe p, std::string name) {
    // Register for the messages that pertain to the GUI
    p.write(registration_message::create(LIRCH_MSG_PRI_REG_MAX, name, LIRCH_MSG_TYPE_DISPLAY));
    p.write(registration_message::create(LIRCH_MSG_PRI_REG_MAX, name, LIRCH_MSG_TYPE_USERLIST));
    p.write(registration_message::create(LIRCH_MSG_PRI_REG_MAX, name, LIRCH_MSG_TYPE_CHANGED_NICK));
    p.write(registration_message::create(LIRCH_MSG_PRI_REG_MAX, name, LIRCH_MSG_TYPE_SET_CHANNEL));
    p.write(registration_message::create(LIRCH_MSG_PRI_REG_MAX, name, LIRCH_MSG_TYPE_LEAVE_CHANNEL));
    extern LirchClientPipe mediator;
    mediator.open(p, QString::fromStdString(name));

    // The mediator will act as a courier to the GUI
    while (mediator.ready()) {
        // Fetch a message from the pipe whenever it arrives
        message m = p.blocking_read();
        // Determine what type of message it is
        if (m.type == LIRCH_MSG_TYPE_SHUTDOWN) {
            mediator.close(QObject::tr("core shutdown"));
            break;
        } else if (m.type == LIRCH_MSG_TYPE_REG_STAT) {
            // Recieved a registration status message
            auto reg = dynamic_cast<registration_status *>(m.getdata());
            if (reg && !reg->status) {
                int registration_priority = reg->priority;
                // Retry over 9000 times until we succeed
                if (registration_priority < LIRCH_MSG_PRI_REG_MIN) {
                  mediator.close(QObject::tr("failed to register with core"));
                  break;
		} else {
                  // Try again to register, if necessary
                  p.write(registration_message::create(--registration_priority, name, reg->type));
                }
            }
        } else if (m.type == LIRCH_MSG_TYPE_DISPLAY) {
            auto data = dynamic_cast<display_message *>(m.getdata());
            if (data) {
                mediator.display(*data);
            }
            p.write(m.decrement_priority());
        } else if (m.type == LIRCH_MSG_TYPE_USERLIST) {
            auto data = dynamic_cast<userlist_message *>(m.getdata());
            if (data) {
                mediator.userlist(*data);
            }
            p.write(m.decrement_priority());
        } else if (m.type == LIRCH_MSG_TYPE_CHANGED_NICK) {
            auto data = dynamic_cast<changed_nick_message *>(m.getdata());
            if (data) {
                mediator.nick(*data);
            }
            p.write(m.decrement_priority());
	} else if (m.type == LIRCH_MSG_TYPE_SET_CHANNEL) {
            auto data = dynamic_cast<set_channel_message *>(m.getdata());
            if (data) {
                mediator.channel(*data);
            }
            p.write(m.decrement_priority());
	} else if (m.type == LIRCH_MSG_TYPE_LEAVE_CHANNEL) {
            auto data = dynamic_cast<leave_channel_message *>(m.getdata());
            if (data) {
                mediator.channel(*data);
            }
            p.write(m.decrement_priority());
        } else {
            // By default, echo the message with decremented priority
            p.write(m.decrement_priority());
        }
    }

    // We only get here through anomalous behavior (though it is good to have a catch-all)
    if (mediator.ready()) {
        mediator.close();
    }
}
示例#4
0
void run(plugin_pipe p, string name)
{
	p.write(registration_message::create(0, name, "userlist_request"));
	p.write(registration_message::create(0, name, "userlist_timer"));
	p.write(registration_message::create(30000, name, "received"));
	p.write(registration_message::create(30000, name, "received_me"));
	unordered_map<QString, user_status> statuses;
	while (true)
	{
		message m=p.blocking_read();
		if (m.type=="shutdown")
		{
			return;
		}
		else if (m.type=="registration_status")
		{
			auto s=dynamic_cast<registration_status *>(m.getdata());
			if (!s)
				continue;
			if (!s->status)
			{
				if ((0>=s->priority && s->priority>-200) || (30000>=s->priority && s->priority>29000))
					p.write(registration_message::create(s->priority-1, name, s->type));
				else
					return;
			}
			else
			{
				if (s->type=="userlist_timer")
					p.write(userlist_timer::create(10000));
			}
		}
		else if (m.type=="userlist_request")
		{
			p.write(userlist_message::create(statuses));
		}
		else if (m.type=="userlist_timer")
		{
			auto s=dynamic_cast<userlist_timer *>(m.getdata());
			if (!s)
				continue;
			time_t now=time(NULL);
			//Remove all nicks that haven't been seen in 2 minutes
			decltype(statuses.begin()) i;
			while ((i=std::find_if(statuses.begin(), statuses.end(), [now](const std::pair<const QString &, const user_status &> &p) {return p.second.lastseen<now-2*60;}))!=statuses.end())
				statuses.erase(i);
			p.write(userlist_message::create(statuses));
			int msecs=s->msecs;
			thread th([&p,msecs]()
			{
				plugin_pipe pp;
				this_thread::sleep_for(chrono::milliseconds(msecs));
				pp.write(userlist_timer::create(msecs));
			});
			th.detach();
		}
		else if (m.type=="received")
		{
			auto s=dynamic_cast<received_message *>(m.getdata());
			if (!s)
				continue;
			p.write(m.decrement_priority());
			statuses[s->nick].nick=s->nick;
			statuses[s->nick].channels.insert(s->channel);
			statuses[s->nick].ip=s->ipAddress;
			statuses[s->nick].lastseen=time(NULL);
		}
		else if (m.type=="received_me")
		{
			auto s=dynamic_cast<received_me_message *>(m.getdata());
			if (!s)
				continue;
			p.write(m.decrement_priority());
			statuses[s->nick].nick=s->nick;
			statuses[s->nick].channels.insert(s->channel);
			statuses[s->nick].ip=s->ipAddress;
			statuses[s->nick].lastseen=time(NULL);
		}
		else
			p.write(m.decrement_priority());
	}
}
示例#5
0
文件: userlist.cpp 项目: m42a/Lirch
void run(plugin_pipe p, string name)
{
	p.write(registration_message::create(0, name, "userlist_request"));
	p.write(registration_message::create(0, name, "userlist_timer"));
	p.write(registration_message::create(30000, name, "received"));
	p.write(registration_message::create(30000, name, "received_status"));
	p.write(registration_message::create(0, name, "list_channels"));
	p.write(registration_message::create(0, name, "handler_ready"));
	p.write(registration_message::create(0, name, "leave_channel"));
	p.write(registration_message::create(0, name, "set_channel"));
	p.write(registration_message::create(-30000, name, "nick"));
	p.write(registration_message::create(-30000, name, "who_is"));
	p.write(registration_message::create(-30000, name, "block name"));

	bool firstTime=true;

	unordered_map<QString, user_status> userList;

	QString currentNick = LIRCH_DEFAULT_NICK;

	std::thread populate(populateDefaultChannel,p);
	populate.detach();


	while (true)
	{
		message m=p.blocking_read();
		if (m.type=="shutdown")
		{
			return;
		}
		else if (m.type=="registration_status")
		{
			auto s=dynamic_cast<registration_status *>(m.getdata());
			if (!s)
				continue;

			if (!s->status)
			{
				if ((0>=s->priority && s->priority>-200) || (30000>=s->priority && s->priority>29000))
					p.write(registration_message::create(s->priority-1, name, s->type));
				else
					return;
			}
			else
			{
				if (s->type=="userlist_timer")
				{
					p.write(userlist_timer::create());
				}
				else if (s->type=="handler_ready")
				{
					p.write(register_handler::create("/list", sendList));
					p.write(register_handler::create("/nick", sendNick));
					p.write(register_handler::create("/whois", sendWhois));
				}
			}
		}
		else if (m.type=="userlist_request")
		{
			p.write(userlist_message::create(currentNick, userList));
		}
		else if (m.type=="userlist_timer")
		{
			time_t now=time(NULL);
			//Remove all nicks that haven't been seen in 2 minutes
			decltype(userList.begin()) i;
			while ((i=std::find_if(userList.begin(), userList.end(), [now](const std::pair<const QString &, const user_status &> &p) {return p.second.lastseen<now-2*60;}))!=userList.end())
			{
				for(auto iter = i->second.channels.begin(); iter!=i->second.channels.end(); iter++)
					p.write(notify_message::create(*iter, i->first + " has logged off."));
				userList.erase(i);
			}
			p.write(userlist_message::create(currentNick, userList));
			thread([](plugin_pipe p)
					{
					this_thread::sleep_for(chrono::seconds(10));
					p.write(userlist_timer::create());
					}, p).detach();
		}
		else if (m.type=="handler_ready")
		{
			p.write(register_handler::create("/list", sendList));
			p.write(register_handler::create("/nick", sendNick));
			p.write(register_handler::create("/whois", sendWhois));
		}
		else if (m.type=="received" || m.type=="received_status")
		{
			p.write(m.decrement_priority());
			updateSenderStatus(p,m,userList,currentNick);
		}
		else if (m.type=="nick")
		{
			auto s=dynamic_cast<nick_message *>(m.getdata());
			if (!s)
				continue;
			p.write(m.decrement_priority());
			if (firstTime)
				p.write(set_channel_message::create("default"));
			p.write(setNick(userList,currentNick,*s,firstTime));

			//The userlist is no longer a virgin
			firstTime = false;

			if (s->changeDefault)
			{
				QSettings settings(QSettings::IniFormat, QSettings::UserScope, LIRCH_COMPANY_NAME, LIRCH_PRODUCT_NAME);
				settings.beginGroup("UserData");
				settings.setValue("nick", currentNick);
				settings.sync();
				settings.endGroup();
			}
		}
		else if (m.type=="list_channels")
		{
			auto s=dynamic_cast<list_channels *>(m.getdata());
			if (!s)
				continue;
			for (auto &i : userList)
			{
				if (s->filterChannel=="" || i.second.channels.count(s->filterChannel)!=0)
				{
					QStringList channelList;
					for (auto &c : i.second.channels)
						channelList.append(c);
					p.write(notify_message::create(s->destinationChannel, QObject::tr("User %1 (%2) was last seen at %3 and is in the following channels: %4").arg(i.second.nick, i.second.ip.toString(), QDateTime::fromTime_t(i.second.lastseen).toString(), channelList.join(" "))));
				}
			}
		}
		else if (m.type == "set_channel")
		{
			auto s=dynamic_cast<set_channel_message *>(m.getdata());
			if (!s)
				continue;
			p.write(m.decrement_priority());

			// If you can't in the channel yet, ask who's there
			if (userList[currentNick].channels.count(s->channel)==0)
				askForUsers(p,s->channel);
		}
		else if (m.type == "leave_channel")
		{
			auto s=dynamic_cast<leave_channel_message *>(m.getdata());
			if (!s)
				continue;
			p.write(m.decrement_priority());

			for(auto & person:userList)
			{
				person.second.channels.erase(s->channel);
			}
		}
		else if (m.type == "who_is")
		{
			auto s=dynamic_cast<who_is_message *>(m.getdata());
			if (!s)
				continue;
			p.write(m.decrement_priority());

			if (userList.count(s->nick)==0)
				continue;

			QStringList channelList;
			for (auto &c : userList[s->nick].channels)
				channelList.append(c);

			p.write(notify_message::create(s->channel, QObject::tr("User %1 (%2) was last seen at %3 and is in the following channels: %4").arg(userList[s->nick].nick, userList[s->nick].ip.toString(), QDateTime::fromTime_t(userList[s->nick].lastseen).toString(), channelList.join(" "))));
		}
		else
			p.write(m.decrement_priority());
	}
}