anope- supernets anope source code & configuration |
git clone git://git.acid.vegas/anope.git |
Log | Files | Refs | Archive | README |
ms_read.cpp (6006B)
1 /* MemoServ core functions 2 * 3 * (C) 2003-2022 Anope Team 4 * Contact us at team@anope.org 5 * 6 * Please read COPYING and README for further details. 7 * 8 * Based on the original code of Epona by Lara. 9 * Based on the original code of Services by Andy Church. 10 */ 11 12 #include "module.h" 13 14 static ServiceReference<MemoServService> MemoServService("MemoServService", "MemoServ"); 15 16 static void rsend_notify(CommandSource &source, MemoInfo *mi, Memo *m, const Anope::string &targ) 17 { 18 /* Only send receipt if memos are allowed */ 19 if (MemoServService && !Anope::ReadOnly) 20 { 21 /* Get nick alias for sender */ 22 const NickAlias *na = NickAlias::Find(m->sender); 23 24 if (!na) 25 return; 26 27 /* Get nick core for sender */ 28 const NickCore *nc = na->nc; 29 30 if (!nc) 31 return; 32 33 /* Text of the memo varies if the recipient was a 34 nick or channel */ 35 Anope::string text = Anope::printf(Language::Translate(na->nc, _("\002[auto-memo]\002 The memo you sent to %s has been viewed.")), targ.c_str()); 36 37 /* Send notification */ 38 MemoServService->Send(source.GetNick(), m->sender, text, true); 39 40 /* Notify recipient of the memo that a notification has 41 been sent to the sender */ 42 source.Reply(_("A notification memo has been sent to %s informing him/her you have\n" 43 "read his/her memo."), nc->display.c_str()); 44 } 45 46 /* Remove receipt flag from the original memo */ 47 m->receipt = false; 48 } 49 50 class MemoListCallback : public NumberList 51 { 52 CommandSource &source; 53 MemoInfo *mi; 54 const ChannelInfo *ci; 55 bool found; 56 public: 57 MemoListCallback(CommandSource &_source, MemoInfo *_mi, const ChannelInfo *_ci, const Anope::string &numlist) : NumberList(numlist, false), source(_source), mi(_mi), ci(_ci) 58 { 59 found = false; 60 } 61 62 ~MemoListCallback() 63 { 64 if (!found) 65 source.Reply(_("No memos to display.")); 66 } 67 68 void HandleNumber(unsigned number) anope_override 69 { 70 if (!number || number > mi->memos->size()) 71 return; 72 73 MemoListCallback::DoRead(source, mi, ci, number - 1); 74 found = true; 75 } 76 77 static void DoRead(CommandSource &source, MemoInfo *mi, const ChannelInfo *ci, unsigned index) 78 { 79 Memo *m = mi->GetMemo(index); 80 if (!m) 81 return; 82 83 if (ci) 84 source.Reply(_("Memo %d from %s (%s)."), index + 1, m->sender.c_str(), Anope::strftime(m->time, source.GetAccount()).c_str()); 85 else 86 source.Reply(_("Memo %d from %s (%s)."), index + 1, m->sender.c_str(), Anope::strftime(m->time, source.GetAccount()).c_str()); 87 88 BotInfo *bi; 89 Anope::string cmd; 90 if (Command::FindCommandFromService("memoserv/del", bi, cmd)) 91 { 92 if (ci) 93 source.Reply(_("To delete, type: \002%s%s %s %s %d\002"), Config->StrictPrivmsg.c_str(), bi->nick.c_str(), cmd.c_str(), ci->name.c_str(), index + 1); 94 else 95 source.Reply(_("To delete, type: \002%s%s %s %d\002"), Config->StrictPrivmsg.c_str(), bi->nick.c_str(), cmd.c_str(), index + 1); 96 } 97 98 source.Reply("%s", m->text.c_str()); 99 m->unread = false; 100 101 /* Check if a receipt notification was requested */ 102 if (m->receipt) 103 rsend_notify(source, mi, m, ci ? ci->name : source.GetNick()); 104 } 105 }; 106 107 class CommandMSRead : public Command 108 { 109 public: 110 CommandMSRead(Module *creator) : Command(creator, "memoserv/read", 1, 2) 111 { 112 this->SetDesc(_("Read a memo or memos")); 113 this->SetSyntax(_("[\037channel\037] {\037num\037 | \037list\037 | LAST | NEW | ALL}")); 114 } 115 116 void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override 117 { 118 119 MemoInfo *mi; 120 ChannelInfo *ci = NULL; 121 Anope::string numstr = params[0], chan; 122 123 if (!numstr.empty() && numstr[0] == '#') 124 { 125 chan = numstr; 126 numstr = params.size() > 1 ? params[1] : ""; 127 128 ci = ChannelInfo::Find(chan); 129 if (!ci) 130 { 131 source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str()); 132 return; 133 } 134 else if (!source.AccessFor(ci).HasPriv("MEMO")) 135 { 136 source.Reply(ACCESS_DENIED); 137 return; 138 } 139 mi = &ci->memos; 140 } 141 else 142 mi = &source.nc->memos; 143 144 if (numstr.empty() || (!numstr.equals_ci("LAST") && !numstr.equals_ci("NEW") && !numstr.equals_ci("ALL") && numstr.find_first_not_of("0123456789.,-") != Anope::string::npos)) 145 this->OnSyntaxError(source, numstr); 146 else if (mi->memos->empty()) 147 { 148 if (!chan.empty()) 149 source.Reply(MEMO_X_HAS_NO_MEMOS, chan.c_str()); 150 else 151 source.Reply(MEMO_HAVE_NO_MEMOS); 152 } 153 else 154 { 155 int i, end; 156 157 if (numstr.equals_ci("NEW")) 158 { 159 int readcount = 0; 160 for (i = 0, end = mi->memos->size(); i < end; ++i) 161 if (mi->GetMemo(i)->unread) 162 { 163 MemoListCallback::DoRead(source, mi, ci, i); 164 ++readcount; 165 } 166 if (!readcount) 167 { 168 if (!chan.empty()) 169 source.Reply(MEMO_X_HAS_NO_NEW_MEMOS, chan.c_str()); 170 else 171 source.Reply(MEMO_HAVE_NO_NEW_MEMOS); 172 } 173 } 174 else if (numstr.equals_ci("LAST")) 175 { 176 for (i = 0, end = mi->memos->size() - 1; i < end; ++i); 177 MemoListCallback::DoRead(source, mi, ci, i); 178 } 179 else if (numstr.equals_ci("ALL")) 180 { 181 for (i = 0, end = mi->memos->size(); i < end; ++i) 182 { 183 MemoListCallback::DoRead(source, mi, ci, i); 184 } 185 } 186 else /* number[s] */ 187 { 188 MemoListCallback list(source, mi, ci, numstr); 189 list.Process(); 190 } 191 } 192 return; 193 } 194 195 bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override 196 { 197 this->SendSyntax(source); 198 source.Reply(" "); 199 source.Reply(_("Sends you the text of the memos specified. If LAST is\n" 200 "given, sends you the memo you most recently received. If\n" 201 "NEW is given, sends you all of your new memos. If ALL is\n" 202 "given, sends you all of your memos. Otherwise, sends you\n" 203 "memo number \037num\037. You can also give a list of numbers,\n" 204 "as in this example:\n" 205 " \n" 206 " \002READ 2-5,7-9\002\n" 207 " Displays memos numbered 2 through 5 and 7 through 9.")); 208 return true; 209 } 210 }; 211 212 class MSRead : public Module 213 { 214 CommandMSRead commandmsread; 215 216 public: 217 MSRead(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), 218 commandmsread(this) 219 { 220 221 } 222 }; 223 224 MODULE_INIT(MSRead)