void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override { MemoServ::MemoInfo *mi; ChanServ::Channel *ci = NULL; Anope::string numstr = params[0], chan; if (!numstr.empty() && numstr[0] == '#') { chan = numstr; numstr = params.size() > 1 ? params[1] : ""; ci = ChanServ::Find(chan); if (!ci) { source.Reply(_("Channel \002{0}\002 isn't registered."), chan); return; } if (!source.AccessFor(ci).HasPriv("MEMO")) { source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "MEMO", ci->GetName()); return; } mi = ci->GetMemos(); } else mi = source.nc->GetMemos(); if (numstr.empty() || (!numstr.equals_ci("LAST") && !numstr.equals_ci("NEW") && !numstr.is_number_only())) { this->OnSyntaxError(source, numstr); return; } if (!mi) return; auto memos = mi->GetMemos(); if (memos.empty()) { if (!chan.empty()) source.Reply(_("\002{0}\002 has no memos."), chan); else source.Reply(_("You have no memos.")); return; } int i, end; if (numstr.equals_ci("NEW")) { int readcount = 0; for (i = 0, end = memos.size(); i < end; ++i) if (mi->GetMemo(i)->GetUnread()) { DoRead(source, mi, ci, i); ++readcount; } if (!readcount) { if (!chan.empty()) source.Reply(_("\002{0}\002 has no new memos."), chan); else source.Reply(_("You have no new memos.")); } } else if (numstr.equals_ci("LAST")) { for (i = 0, end = memos.size() - 1; i < end; ++i); DoRead(source, mi, ci, i); } else /* number[s] */ { NumberList(numstr, false, [&](unsigned int number) { if (!number || number > memos.size()) return; DoRead(source, mi, ci, number - 1); }, []{}); } }
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override { Anope::string param = !params.empty() ? params[0] : "", chan; ChanServ::Channel *ci = NULL; MemoServ::MemoInfo *mi; if (!param.empty() && param[0] == '#') { chan = param; param = params.size() > 1 ? params[1] : ""; ci = ChanServ::Find(chan); if (!ci) { source.Reply(_("Channel \002{0}\002 isn't registered."), chan); return; } if (!source.AccessFor(ci).HasPriv("MEMO")) { source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "MEMO", ci->GetName()); return; } mi = ci->GetMemos(); } else { mi = source.nc->GetMemos(); } if (!param.empty() && !isdigit(param[0]) && !param.equals_ci("NEW")) { this->OnSyntaxError(source); return; } if (!mi) return; auto memos = mi->GetMemos(); if (!memos.size()) { if (!chan.empty()) source.Reply(_("\002{0}\002 has no memos."), chan); else source.Reply(_("You have no memos.")); return; } ListFormatter list(source.GetAccount()); list.AddColumn(_("Number")).AddColumn(_("Sender")).AddColumn(_("Date/Time")); if (!param.empty() && isdigit(param[0])) { NumberList(param, false, [&](unsigned int number) { if (!number || number > memos.size()) return; MemoServ::Memo *m = mi->GetMemo(number - 1); ListFormatter::ListEntry entry; entry["Number"] = (m->GetUnread() ? "* " : " ") + stringify(number); entry["Sender"] = m->GetSender(); entry["Date/Time"] = Anope::strftime(m->GetTime(), source.GetAccount()); list.AddEntry(entry); }, []{}); } else { if (!param.empty()) { unsigned i, end; for (i = 0, end = memos.size(); i < end; ++i) if (mi->GetMemo(i)->GetUnread()) break; if (i == end) { if (!chan.empty()) source.Reply(_("\002{0}\002 has no new memos."), chan); else source.Reply(_("You have no new memos.")); return; } } for (unsigned i = 0, end = memos.size(); i < end; ++i) { if (!param.empty() && !mi->GetMemo(i)->GetUnread()) continue; MemoServ::Memo *m = mi->GetMemo(i); ListFormatter::ListEntry entry; entry["Number"] = (m->GetUnread() ? "* " : " ") + stringify(i + 1); entry["Sender"] = m->GetSender(); entry["Date/Time"] = Anope::strftime(m->GetTime(), source.GetAccount()); list.AddEntry(entry); } } std::vector<Anope::string> replies; list.Process(replies); source.Reply(_("Memos for \002{0}\002:"), ci ? ci->GetName().c_str() : source.GetNick().c_str()); for (unsigned i = 0; i < replies.size(); ++i) source.Reply(replies[i]); }
MemoResult Send(const Anope::string &source, const Anope::string &target, const Anope::string &message, bool force) override { bool ischan, isregistered; MemoServ::MemoInfo *mi = GetMemoInfo(target, ischan, isregistered, true); if (mi == NULL) return MEMO_INVALID_TARGET; User *sender = User::Find(source); if (sender != NULL && !sender->HasPriv("memoserv/no-limit") && !force) { time_t send_delay = Config->GetModule("memoserv")->Get<time_t>("senddelay"); if (send_delay > 0 && sender->lastmemosend + send_delay > Anope::CurTime) return MEMO_TOO_FAST; else if (!mi->GetMemoMax()) return MEMO_TARGET_FULL; else if (mi->GetMemoMax() > 0 && mi->GetMemos().size() >= static_cast<unsigned>(mi->GetMemoMax())) return MEMO_TARGET_FULL; else if (mi->HasIgnore(sender)) return MEMO_SUCCESS; } if (sender != NULL) sender->lastmemosend = Anope::CurTime; MemoServ::Memo *m = Serialize::New<MemoServ::Memo *>(); m->SetMemoInfo(mi); m->SetSender(source); m->SetTime(Anope::CurTime); m->SetText(message); m->SetUnread(true); EventManager::Get()->Dispatch(&MemoServ::Event::MemoSend::OnMemoSend, source, target, mi, m); if (ischan) { ChanServ::Channel *ci = ChanServ::Find(target); if (ci->c) { for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) { ChanUserContainer *cu = it->second; if (ci->AccessFor(cu->user).HasPriv("MEMO")) { if (cu->user->Account() && cu->user->Account()->HasFieldS("MEMO_RECEIVE")) cu->user->SendMessage(*MemoServ, _("There is a new memo on channel \002{0}\002. Type \002{1}{2} READ {3} {4}\002 to read it."), ci->GetName(), Config->StrictPrivmsg, MemoServ->nick, ci->GetName(), mi->GetMemos().size()); // XXX } } } } else { NickServ::Account *nc = NickServ::FindNick(target)->GetAccount(); if (nc->HasFieldS("MEMO_RECEIVE")) for (User *u : nc->users) u->SendMessage(*MemoServ, _("You have a new memo from \002{0}\002. Type \002{1}{2} READ {3}\002 to read it."), source, Config->StrictPrivmsg, MemoServ->nick, mi->GetMemos().size());//XXX /* let's get out the mail if set in the nickcore - certus */ if (nc->HasFieldS("MEMO_MAIL")) SendMemoMail(nc, mi, m); } return MEMO_SUCCESS; }
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override { if (Anope::ReadOnly) { source.Reply(_("Services are in read-only mode.")); return; } MemoServ::MemoInfo *mi; ChanServ::Channel *ci = NULL; Anope::string numstr = !params.empty() ? params[0] : "", chan; if (!numstr.empty() && numstr[0] == '#') { chan = numstr; numstr = params.size() > 1 ? params[1] : ""; ci = ChanServ::Find(chan); if (!ci) { source.Reply(_("Channel \002{0}\002 isn't registered."), chan); return; } if (!source.AccessFor(ci).HasPriv("MEMO")) { source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "MEMO", ci->GetName()); return; } mi = ci->GetMemos(); } else { mi = source.nc->GetMemos(); } if (numstr.empty() || (!isdigit(numstr[0]) && !numstr.equals_ci("ALL") && !numstr.equals_ci("LAST"))) { this->OnSyntaxError(source, numstr); return; } if (!mi || mi->GetMemos().empty()) { if (!chan.empty()) source.Reply(_("\002{0}\002 has no memos."), chan); else source.Reply(_("You have no memos.")); return; } auto memos = mi->GetMemos(); if (isdigit(numstr[0])) { NumberList(numstr, true, [&](unsigned int number) { if (!number || number > memos.size()) return; EventManager::Get()->Dispatch(&MemoServ::Event::MemoDel::OnMemoDel, ci ? ci->GetName() : source.nc->GetDisplay(), mi, mi->GetMemo(number - 1)); mi->Del(number - 1); source.Reply(_("Memo \002{0}\002 has been deleted."), number); }, [](){}); } else if (numstr.equals_ci("LAST")) { /* Delete last memo. */ EventManager::Get()->Dispatch(&MemoServ::Event::MemoDel::OnMemoDel, ci ? ci->GetName() : source.nc->GetDisplay(), mi, mi->GetMemo(memos.size() - 1)); mi->Del(memos.size() - 1); source.Reply(_("Memo \002{0}\002 has been deleted."), memos.size() + 1); } else { /* Delete all memos. */ std::for_each(memos.begin(), memos.end(), [&](MemoServ::Memo *m) { EventManager::Get()->Dispatch(&MemoServ::Event::MemoDel::OnMemoDel, ci ? ci->GetName() : source.nc->GetDisplay(), mi, m); delete m; }); if (!chan.empty()) source.Reply(_("All memos for channel \002{0}\002 have been deleted."), chan); else source.Reply(_("All of your memos have been deleted.")); } }
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override { if (Anope::ReadOnly) { source.Reply(_("Services are in read-only mode.")); return; } const Anope::string &nname = params[0]; bool ischan, isregistered; MemoServ::MemoInfo *mi = MemoServ::service->GetMemoInfo(nname, ischan, isregistered, false); if (!isregistered) { if (ischan) source.Reply(_("Channel \002{0}\002 isn't registered."), nname); else source.Reply(_("\002{0}\002 isn't registered."), nname); return; } if (mi == nullptr) return; ChanServ::Channel *ci = NULL; NickServ::Nick *na = NULL; if (ischan) { ci = ChanServ::Find(nname); if (ci == nullptr) return; } else { na = NickServ::FindNick(nname); if (na == nullptr) return; } auto memos = mi->GetMemos(); for (int i = memos.size() - 1; i >= 0; --i) { MemoServ::Memo *m = memos[i]; if (!m->GetUnread()) continue; NickServ::Nick *sender = NickServ::FindNick(m->GetSender()); if (sender && sender->GetAccount() == source.GetAccount()) { EventManager::Get()->Dispatch(&MemoServ::Event::MemoDel::OnMemoDel, ischan ? ci->GetName() : na->GetAccount()->GetDisplay(), mi, m); mi->Del(i); source.Reply(_("Your last memo to \002{0}\002 has been cancelled."), ischan ? ci->GetName() : na->GetAccount()->GetDisplay()); return; } } source.Reply(_("No memo was cancelable.")); }