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; }
void runplugin(plugin_pipe &p, const string &name) { text_line input; QString channel="default"; int maxx, maxy; getmaxyx(stdscr, maxy, maxx); //10000 lines of scrollback should be enough for anyone //WindowWrapper channel_output=newpad(10000, maxx); unordered_map<QString, WindowWrapper> channel_windows; if (channel_windows["default"]==nullptr) return; WindowWrapper input_display=newwin(1, maxx-1, maxy-1, 0); if (input_display==nullptr) return; //Be lazy and let the input scroll scrollok(input_display, TRUE); //p.write(registration_message::create(-30000, name, "display")); while (true) { wint_t key; int rc=get_wch(&key); if (rc==OK) { if (key=='\r' || key=='\n') { p.write(raw_edict_message::create(input.getQString(),channel)); input.kill_whole_line(); } else if (key==(unsigned char)CTRL('U')) { input.backward_kill_line(); } else if (key==(unsigned char)CTRL('H')) { input.backward_delete_char(); } else if (key==WEOF) { //Quit since we have no more input break; } else { //This conversion is always valid, since key's //only valid values are valid wchar_t values //and WEOF, and we know it's not WEOF. input.insert(key); } } else if (rc==KEY_CODE_YES) { if (key==KEY_BACKSPACE) { input.backward_delete_char(); } else if (key==KEY_ENTER) { p.write(raw_edict_message::create(input.getQString(),channel)); input.kill_whole_line(); } } while (p.has_message()) { message m=p.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 (s->priority>-32000) p.write(registration_message::create(s->priority-1, name, s->type)); } } else if (m.type=="display") { auto s=dynamic_cast<display_message *>(m.getdata()); if (!s) continue; p.write(m.decrement_priority()); QString message_channel=s->channel; string nick=s->nick.toLocal8Bit().constData(); string contents=s->contents.toLocal8Bit().constData(); if (s->channel=="") message_channel=channel; if (channel_windows.count(message_channel)!=0) { if(s->subtype==display_message_subtype::NORMAL) wprintu(channel_windows[message_channel], "<%s> %s\n", nick.c_str(), contents.c_str()); if(s->subtype==display_message_subtype::ME) wprintu(channel_windows[message_channel], "* %s %s\n", nick.c_str(), contents.c_str()); if(s->subtype==display_message_subtype::NOTIFY) wprintu(channel_windows[message_channel], QString((QChar[]){0x203C, 0x203D, ' ', '%', 's', '\n', 0}).toLocal8Bit().constData(), contents.c_str()); if(s->subtype==display_message_subtype::NOTIFY_CURRENT) wprintu(channel_windows[message_channel], QString((QChar[]){0x203C, 0x203C, 0x203D, ' ', '%', 's', '\n', 0}).toLocal8Bit().constData(), contents.c_str()); } } else if (m.type=="set_channel") { auto i=dynamic_cast<set_channel_message *>(m.getdata()); if (!i) continue; p.write(m.decrement_priority()); if (i->channel=="") p.write(notify_message::create(channel, "On channel "+channel)); else channel=i->channel; } else if (m.type=="leave_channel") { auto i=dynamic_cast<leave_channel_message *>(m.getdata()); if (!i) continue; p.write(m.decrement_priority()); if (i->channel=="") i->channel=channel; channel_windows.erase(i->channel); if (i->channel==channel) p.write(set_channel_message::create(channel)); } else p.write(m.decrement_priority()); }