MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame^] | 1 | /* Das Servicepaket der Morgengrauen-Presseagentur. Eine erweiterte Zeitung. |
| 2 | Teilweise zur alten Zeitung identisch. |
| 3 | |
| 4 | unter Verwendung der Zeitung von Jof, voellig umgeschrieben. |
| 5 | |
| 6 | (C) Nov 1993 - 1996 Loco@Morgengrauen |
| 7 | |
| 8 | Verwendung ausserhalb von Morgengrauen ist gestattet unter folgenden |
| 9 | Bedingungen: |
| 10 | - Benutzung erfolgt auf eigene Gefahr. Jegliche Verantwortung wird |
| 11 | abgelehnt. Bugs ausserhalb von MG sind nicht mein Problem. |
| 12 | - Auch in veraenderten oder abgeleiteten Objekten muss ein Hinweis auf |
| 13 | die Herkunft erhalten bleiben. |
| 14 | - Bitte fragt mich vorher! |
| 15 | Ein Update-Service besteht nicht. Ruecknahme dieser Lizenz ist jederzeit |
| 16 | moeglich. Und wer nicht in der Lage ist, neue Versionen selber anzupassen, |
| 17 | hat in der Administration eines Muds nichts zu suchen. |
| 18 | |
| 19 | |
| 20 | 04.11.93 Erste brauchbare Version |
| 21 | (... seitdem viele Aenderungen ...) |
| 22 | 13.09.95 ca 02:00 erwarte mpa |
| 23 | 13.09.95 ca 23:00 RebuildGroupList() |
| 24 | 15.09.95 vorlaeufig ausgebaut |
| 25 | 16.09. anders wieder eingebaut, und Kleinigkeiten |
| 26 | 05.12.95 ca 19:20 Spieler koennen nur noch eigene Artikel loeschen/verl. |
| 27 | 07.12.95 ca 23:00 Keine Anzeige der Statuszeile. Statuszeilen beginnen |
| 28 | mit ~#!, sind damit nicht mit dem Editor erzeugbar. |
| 29 | 20.12.95 ca 17:00 uebergehe thread/antworten |
| 30 | 31.01.96 wiederhole/uncatchup |
| 31 | 22.04.96 Aufraeumen ignorierter threads. ALPHA! |
| 32 | 24.04.96 + - . als Adressierungen, zeitungsmeldung |
| 33 | 02.10.96 Kleinigkeiten |
| 34 | 08.10.96 Kleinigkeiten |
| 35 | 05.12.96 antworte auf artikel <nr>, reply <neuer titel>, |
| 36 | versende artikel, Abkuerzungen fuer Rubrikennamen, |
| 37 | Layoutaenderungen, |
| 38 | Herkunft bei verlegten Artikeln in Statuszeile |
| 39 | |
| 40 | Letzte Aenderung: |
| 41 | 04.11.06 Zesstra Anpassung an das neue Verhalten von inherit_list() in LD |
| 42 | |
| 43 | */ |
| 44 | |
| 45 | #include <properties.h> |
| 46 | #include <language.h> |
| 47 | #include <news.h> |
| 48 | #include <wizlevels.h> |
| 49 | #include <ansi.h> |
| 50 | #include <input_to.h> |
| 51 | #include "/mail/post.h" |
| 52 | |
| 53 | inherit "/std/thing"; |
| 54 | inherit NEDIT; |
| 55 | /* |
| 56 | #define DEBUG(x) if (funcall(symbol_function('find_player),"zesstra"))\ |
| 57 | tell_object(funcall(symbol_function('find_player),"zesstra"),\ |
| 58 | "MPA: "+x+"\n") |
| 59 | #define DEBUGVAR(x) DEBUG(sprintf(x+":\n%O\n",x)) |
| 60 | */ |
| 61 | #define DEBUGVAR(x) |
| 62 | |
| 63 | // Konfiguration, ggf mudabhaengig |
| 64 | #define DEFAULTGROUP "allgemeines" |
| 65 | #define MINIHELPPAGE "p/service/loco/doc/mini-mpa.txt" |
| 66 | #define HELPPAGE "/p/service/loco/doc/mpa" |
| 67 | #define WIZHELPPAGE "/p/service/loco/doc/mpa.wiz" |
| 68 | #define SAVEMSGPATH(pl) ("/open/News/"+(geteuid(pl))+".news") |
| 69 | #define IS_POST(r) (member(inherit_list(r),STDPOST+".c")>=0) |
| 70 | #define INITIAL_SUBSCRIPTIONS \ |
| 71 | ({ "bekanntmachungen", \ |
| 72 | "d.ebene", \ |
| 73 | "d.wueste", \ |
| 74 | "d.inseln", \ |
| 75 | "d.unterwelt", \ |
| 76 | "d.dschungel", \ |
| 77 | "d.gebirge", \ |
| 78 | "d.polar", \ |
| 79 | "d.wald", \ |
| 80 | "d.fernwest", \ |
| 81 | "d.vland", \ |
| 82 | "d.anfaenger", \ |
| 83 | "entwicklung", \ |
| 84 | }) |
| 85 | |
| 86 | // Makros etc. |
| 87 | |
| 88 | #define TP this_player() |
| 89 | #define TI this_interactive() |
| 90 | #define STATUSESCAPE "~#!" |
| 91 | #define IS_STATUSLINE(s) ((s[0..1]=="#!")||(s[0..2]=="~#!")) |
| 92 | //#define IS_STATUSLINE(s) (s[0..2]=="~#!") |
| 93 | // in Rubrik muell fanden sich tatsaechlich noch solche uralten notes... |
| 94 | #define IGNOREGROUP "*ignored*" |
| 95 | #define NNADWMSG "*NNADWMSG*" |
| 96 | #define SYSTEMGROUPS ({IGNOREGROUP,NNADWMSG}) |
| 97 | |
| 98 | // Aufbau der ignoregroup: |
| 99 | // ([group1:([tid1:lasttime1,tid2:lasttime2,...]),group2:...]) |
| 100 | |
| 101 | // Flags fuer Message2string() |
| 102 | #define M2S_VT100 1 |
| 103 | #define M2S_ANSI M2S_VT100 |
| 104 | #define M2S_REMOTE 2 |
| 105 | |
| 106 | // Format von lasttitle |
| 107 | #define LAST_TITLE 0 |
| 108 | #define LAST_WRITER 1 |
| 109 | #define LAST_TIME 2 |
| 110 | #define LAST_TID 3 |
| 111 | #define LAST_GROUP 4 |
| 112 | #define LAST_NR 5 |
| 113 | #define LAST_SIZEOF 6 |
| 114 | |
| 115 | |
| 116 | mapping read_until; |
| 117 | mixed lasttitle; // Aufbau s.o. |
| 118 | mixed message; |
| 119 | int deadTID; |
| 120 | string GROUP; |
| 121 | |
| 122 | int GetTID(mixed message); |
| 123 | private void InitialSubscriptions(); |
| 124 | |
| 125 | create() |
| 126 | { |
| 127 | ::create(); |
| 128 | seteuid(getuid()); |
| 129 | GROUP="bekanntmachungen"; |
| 130 | SetProp(P_SHORT,"Die Zeitung"); |
| 131 | SetProp(P_NAME,"Zeitung"); |
| 132 | SetProp(P_WEIGHT, 50); |
| 133 | SetProp(P_SIZE, 35); |
| 134 | SetProp(P_MATERIAL, ([MAT_PAPER: 100]) ); |
| 135 | SetProp(P_GENDER, FEMALE); |
| 136 | AddId(({"nn","zeitung","servicepaket","mpa"})); |
| 137 | SetProp(P_NODROP, |
| 138 | "Das persoenliche Servicepaket der MPA kann man nicht wegwerfen.\n"); |
| 139 | SetProp(P_NEVERDROP, 1); |
| 140 | |
| 141 | if (!read_until) read_until=(["muell":-1]); |
| 142 | } |
| 143 | |
| 144 | static mixed _query_read_msg() { return long(); } |
| 145 | |
| 146 | long() { |
| 147 | return "\ |
| 148 | Dies ist das Servicepaket der MPA (Morgengrauens Presse Agentur) -\n\ |
| 149 | die Zeitung des Morgengrauens.\n\ |
| 150 | Du kannst damit aktuelle Artikel lesen und schreiben, mit folgenden Befehlen:\n\ |
| 151 | 'nn [rubrik]' (Neueste Nachrichten) wuehlt die Rubrik durch und schaut,\n\ |
| 152 | ob was neu ist. Der erste ungelesene Artikel wird angezeigt.\n\ |
| 153 | Ohne Argument werden alle Rubriken durchwuehlt.\n\ |
| 154 | 'hilfe mpa' Ausfuehrliche Hilfsseite. Lesen dringend empfohlen!\n\ |
| 155 | Weitere Befehle:\n\ |
| 156 | rubriken [neu] bestelle <rubrik> ab\n\ |
| 157 | [lies ]rubrik <rubrik> abonniere <rubrik>\n\ |
| 158 | inhalt [<rubrik>|neu|suche <text>] wiederhole ...\n\ |
| 159 | nn <rubriken>|<liste> uebergehe ...\n\ |
| 160 | [lies ]artikel <nummer>"+ |
| 161 | ( (IS_LEARNER(TP)) ? " speichere artikel <nr>" : "" )+"\n\ |
| 162 | schreib <titel> versende artikel [nr] an <adresse>\n\ |
| 163 | antworte [auf artikel <nr>] [titel] verlege artikel <nr> nach <rubrik>\n\ |
| 164 | loesche artikel <nr> zeitungsmeldung [neue Meldung]\n\ |
| 165 | verbrenne zeitung wenn Dir alles zuviel wird....\n\ |
| 166 | "+ (IS_SEER(TP) ? "\ |
| 167 | Mit 'mail' bzw 'mail <spieler>' kannst Du Post lesen und schreiben.\n\ |
| 168 | " : "" )+"\ |
| 169 | Eingebaute aliase: note, catchup, reply, unsubscribe, subscribe, uncatchup.\n\ |
| 170 | Viele Befehle geben mit '<befehl> ?' einige Syntaxhinweise.\n\ |
| 171 | Aktuelle Rubrik: "+GROUP+"\n\ |
| 172 | "; |
| 173 | } |
| 174 | |
| 175 | |
| 176 | init() |
| 177 | { |
| 178 | ::init(); |
| 179 | |
| 180 | add_action("schreib","schreib"); |
| 181 | add_action("schreib","schreibe"); |
| 182 | add_action("schreib","note"); |
| 183 | add_action("LiesArtikel","lies"); |
| 184 | add_action("artikel","artikel"); |
| 185 | add_action("loesche","loesch"); |
| 186 | add_action("loesche","loesche"); |
| 187 | add_action("rubrik","rubrik"); |
| 188 | add_action("inhalt","inhalt"); |
| 189 | add_action("rubriken","rubriken"); |
| 190 | add_action("ReadNextUnread","nn"); |
| 191 | add_action("Catchup","catchup"); |
| 192 | add_action("Catchup","uebergeh"); |
| 193 | add_action("Catchup","uebergehe"); |
| 194 | add_action("Uncatchup","wiederhol"); |
| 195 | add_action("Uncatchup","wiederhole"); |
| 196 | add_action("Uncatchup","uncatchup"); |
| 197 | add_action("Reply","antwort"); |
| 198 | add_action("Reply","antworte"); |
| 199 | add_action("Reply2","reply"); |
| 200 | add_action("HelpPage","hilfe"); |
| 201 | add_action("HelpPage","man"); |
| 202 | add_action("Unsubscribe","unsubscribe"); |
| 203 | add_action("Bestelle","bestell"); |
| 204 | add_action("Bestelle","bestelle"); |
| 205 | add_action("Subscribe","subscribe"); |
| 206 | add_action("Subscribe","abonnier"); |
| 207 | add_action("Subscribe","abonniere"); |
| 208 | add_action("MoveMessage","verleg"); |
| 209 | add_action("MoveMessage","verlege"); |
| 210 | add_action("SetNNADWMSG","zeitungsmeldung"); |
| 211 | add_action("Ignore","ignorier"); |
| 212 | add_action("Ignore","ignoriere"); |
| 213 | add_action("MailMessage","versende"); |
| 214 | add_action("verbrennen","verbrenne"); |
| 215 | |
| 216 | if (IS_SEER(TP)) { |
| 217 | add_action("Mail","mail"); |
| 218 | } |
| 219 | if (IS_LEARNER(TP)) { |
| 220 | add_action("SaveMessage","speicher"); |
| 221 | add_action("SaveMessage","speichere"); |
| 222 | add_action("ReadNextUnread","read"); /* NF Compatibility Special */ |
| 223 | } |
| 224 | if (IS_ELDER(TP)) |
| 225 | { |
| 226 | add_action("MoveTrash","trash"); |
| 227 | } |
| 228 | init_rescue(); |
| 229 | } |
| 230 | |
| 231 | verbrennen(str) { |
| 232 | if (!str || !id(str)) return 0; |
| 233 | write("Du verbrennst Deine Zeitung mit groesstem Vergnuegen.\n"); |
| 234 | say(TP->Name(WER)+" verbrennt "+ |
| 235 | TP->QueryPossPronoun(FEMALE, WEN, SINGULAR)+" Zeitung in einem " |
| 236 | "Freudenfeuer.\n"); |
| 237 | remove(1); |
| 238 | return 1; |
| 239 | } |
| 240 | |
| 241 | // KillGroup - loescht eine nicht mehr benoetigte Rubrik aus der Liste. |
| 242 | // Aufruf aus rubriken() und ReadNextUnread(), wenn die gueltige |
| 243 | // Rubrikenliste sowieso schon abgerufen wurde. |
| 244 | |
| 245 | static KillGroup(name) { read_until=m_copy_delete(read_until,name); } |
| 246 | |
| 247 | /* RebuildGroupList() - tut doch nicht so, weil /secure/news anders arbeitet. |
| 248 | * Bleibt vorerst zum Nachschlagen. |
| 249 | static RegisterGroup(name) { read_until[name]=1; } |
| 250 | static RebuildGroupList() { |
| 251 | mixed groups; |
| 252 | if ((pointerp(groups=NEWSSERVER->GetGroups()))&&(sizeof(groups))) { |
| 253 | map(m_indices(read_until)-groups-SYSTEMGROUPS,#'KillGroup); |
| 254 | map(groups-m_indices(read_until),#'RegisterGroup); |
| 255 | } |
| 256 | TP->SetProp(P_READ_NEWS,read_until); |
| 257 | } |
| 258 | */ |
| 259 | |
| 260 | |
| 261 | _set_autoloadobj(mixed arg) { |
| 262 | |
| 263 | if (pointerp(arg) && sizeof(arg)>=2) |
| 264 | { |
| 265 | read_until=arg[1]; |
| 266 | } |
| 267 | else { |
| 268 | if (TP) |
| 269 | read_until=((TP->QueryProp(P_READ_NEWS))||([])); |
| 270 | } |
| 271 | |
| 272 | if (TP) TP->SetProp(P_READ_NEWS,read_until); |
| 273 | } |
| 274 | |
| 275 | _query_autoloadobj() { |
| 276 | return 1; |
| 277 | } |
| 278 | |
| 279 | static Mail(str) { |
| 280 | object mailer; |
| 281 | if (this_interactive()!=this_player()) return 0; |
| 282 | mailer=clone_object(MAILER); |
| 283 | mailer->SetOfficeName("mpa Kurierdienst"); |
| 284 | mailer->do_mail( ((!str)||(str=="mail")) ? 0 : TP->_unparsed_args() ); |
| 285 | return 1; |
| 286 | } |
| 287 | |
| 288 | static varargs string Message2string(mixed msg,mixed messages,int flag,string group) { |
| 289 | // Aufrufe: (Nummer,Notes[,flag[,group]]) oder (Note,Notes[,flag[,group]]) |
| 290 | // flag: M2S_VT100 : ggf ANSI-Codes verwenden |
| 291 | // M2S_REMOTE: Rubrik und Artikelnummer ausgeben (speichern, versenden) |
| 292 | // Achtung: Wenn flag&M2S_REMOTE, muss msg int sein |
| 293 | // group: Name der Rubrik, wenn nicht aktuelle Rubrik. Nur bei M2S_REMOTE |
| 294 | |
| 295 | string txt,hs,s,*m,s2; |
| 296 | int i,hi,thisnr,ansiflag; |
| 297 | |
| 298 | if (flag&M2S_REMOTE) txt="Rubrik: "+(group?group:GROUP)+", Artikel: "+ |
| 299 | (intp(msg)?to_string(msg+1):"???")+" von "+sizeof(messages)+"\n"; |
| 300 | else txt=""; |
| 301 | |
| 302 | if (intp(msg)) { |
| 303 | thisnr=msg; |
| 304 | msg=messages[msg]; |
| 305 | } else thisnr=-1; |
| 306 | if (!msg) return 0; |
| 307 | |
| 308 | ansiflag=(flag&M2S_VT100)&&(this_player()->QueryProp(P_TTY)!="dumb"); |
| 309 | |
| 310 | txt += (ansiflag?ANSI_BOLD:"")+ msg[M_TITLE]+(ansiflag?ANSI_NORMAL:"")+ |
| 311 | " ("+msg[M_WRITER]+", "+ |
| 312 | dtime(msg[M_TIME])[5..26]+"):\n"; |
| 313 | // if (geteuid(TP)=="sitopanaki") txt+="TID="+GetTID(msg)+"\n"; // Debug |
| 314 | if (!IS_STATUSLINE(msg[M_MESSAGE])) |
| 315 | return txt+"\n"+msg[M_MESSAGE]; |
| 316 | m=explode(msg[M_MESSAGE],"\n"); |
| 317 | while (IS_STATUSLINE(m[0])) { |
| 318 | // txt+=m[0]+"\n"; // ### |
| 319 | if (sscanf(m[0],"%s rn=%s rt=%d rg=%s",hs,s,hi,hs)==4 || |
| 320 | sscanf(m[0],"%s rn=%s rt=%d",hs,s,hi)==3) |
| 321 | { |
| 322 | int nr,h; |
| 323 | nr=-1; |
| 324 | if (pointerp(messages)) |
| 325 | { |
| 326 | for (h=((thisnr>=0) ? thisnr-1 : sizeof(messages)-1); |
| 327 | (h>=0 && messages[h][M_TIME]>=hi);h--) |
| 328 | if (messages[h][M_TIME]==hi && |
| 329 | lower_case(messages[h][M_WRITER])==lower_case(s)) |
| 330 | nr=h; |
| 331 | } |
| 332 | txt+="[Bezug: Artikel "+((nr>=0) ? (nr+1) : |
| 333 | (hs==STATUSESCAPE||hs==(group?group:GROUP)?"(geloescht?)":"in "+hs))+ |
| 334 | " von "+capitalize(s)+" vom "+dtime(hi)[5..26]+"]\n"; |
| 335 | } |
| 336 | if (sscanf(m[0],"%s on=%s ot=%d og=%s",hs,s,hi,hs)==4) { |
| 337 | txt+="[Autor: "+s+", "+dtime(hi)[5..26]+", verlegt von "+hs+"]\n"; |
| 338 | } |
| 339 | m=m[1..]; |
| 340 | } |
| 341 | return txt+"\n"+implode(m,"\n"); |
| 342 | } |
| 343 | |
| 344 | static varargs lies(mixed str) { |
| 345 | mixed num; |
| 346 | mixed *messages; |
| 347 | int tid; |
| 348 | |
| 349 | if (str=="?"||str=="-?") return |
| 350 | write("Syntax: lies <nr>\n" |
| 351 | " artikel <nr>\n" |
| 352 | "Siehe auch: nn\n"),1; |
| 353 | |
| 354 | if (intp(str)) num=str; |
| 355 | if ((!num && (!str || str=="" || sscanf(str,"%d",num)!=1)) || num<=0) { |
| 356 | notify_fail("WELCHE Nachricht willst Du lesen?\n"); |
| 357 | return 0; |
| 358 | } |
| 359 | if (!pointerp(messages=NEWSSERVER->GetNotes(GROUP))) |
| 360 | return notify_fail("Seltsam, die Rubrik '"+GROUP+ |
| 361 | "' gibt es nicht mehr...\n"), 0; |
| 362 | num--; |
| 363 | if (sizeof(messages)<=num) { |
| 364 | notify_fail("So viele Artikel sind da nicht!\n"); |
| 365 | return 0; |
| 366 | } |
| 367 | |
| 368 | lasttitle=({messages[num][M_TITLE],messages[num][M_WRITER], |
| 369 | messages[num][M_TIME],GetTID(messages[num]),GROUP,num}); |
| 370 | this_player()->More(Message2string(messages[num],messages,M2S_VT100)); |
| 371 | if (this_player() && IS_LEARNER(this_player())) |
| 372 | this_player()->save_me(1); |
| 373 | return 1; |
| 374 | } |
| 375 | |
| 376 | static varargs mixed GetGroupName(mixed g,mixed groups) { |
| 377 | /* Name einer Rubrik. g ist int oder string, enthaelt Name oder Nummer |
| 378 | (ab 1 numeriert) */ |
| 379 | mixed i,expr,gg; |
| 380 | if (!g) return write("Du solltest schon die Rubrik angeben.\n"),0; |
| 381 | if (!groups) groups=NEWSSERVER->GetGroups(); |
| 382 | if (intp(i=g) || sscanf(g,"%d",i)) { |
| 383 | if (i>0 && i<=sizeof(groups)) return groups[i-1]; |
| 384 | write("Eine Rubrik mit der Nummer "+i+" gibt es leider nicht.\n"); |
| 385 | return 0; |
| 386 | } |
| 387 | g=lower_case(g); |
| 388 | switch(g){ |
| 389 | case ".": return GROUP; |
| 390 | case "+": return groups[(member(groups,GROUP)+1)%sizeof(groups)]; |
| 391 | case "-": |
| 392 | return groups[(member(groups,GROUP)-1+sizeof(groups))%sizeof(groups)]; |
| 393 | } |
| 394 | |
| 395 | // Existiert die Rubrik genau so? |
| 396 | if (member(groups,g)>-1) return g; |
| 397 | |
| 398 | g = regreplace(g,"[[\\]\\*()?]","",1); |
| 399 | // haerteres Kriterium: Alle Abschnitte angegeben |
| 400 | expr="^"+implode(explode(g,"."),"[^\\.]*\\.")+"[^\\.]*$"; |
| 401 | // write("REGEXP="+expr+"\n"); |
| 402 | gg=regexp(groups,expr); |
| 403 | if (sizeof(gg)==1) return gg[0]; |
| 404 | |
| 405 | // weicheres Kriterium: Nicht alle Abschnitte angegeben |
| 406 | expr="^(.*\\.)*"+implode(explode(g,"."),".*\\.")+".*$"; |
| 407 | // write("REGEXP="+expr+"\n"); |
| 408 | gg=regexp(groups,expr); |
| 409 | |
| 410 | if (!sizeof(gg)) { |
| 411 | write("Eine Rubrik '"+g+"' gibt es hier leider nicht.\n"); |
| 412 | return 0; |
| 413 | } |
| 414 | |
| 415 | if (sizeof(gg)==1) return gg[0]; |
| 416 | |
| 417 | write(break_string("Die Rubrik "+g+" ist nicht eindeutig. Wahrscheinlich " |
| 418 | "meinst Du eine der folgenden: "+implode(gg,", ")+".\n",78)); |
| 419 | return 0; |
| 420 | } |
| 421 | |
| 422 | static rubrik(str) |
| 423 | { |
| 424 | mixed *gruppen; |
| 425 | mixed news; |
| 426 | int anz,i; |
| 427 | |
| 428 | if (str=="?"||str=="-?") return |
| 429 | write("Syntax: rubrik <rubrik>\n" |
| 430 | " wechselt die aktuelle Rubrik. Es wird die Nummer der Rubrik,\n" |
| 431 | " ihr Name oder jede eindeutige Abkuerzung akzeptiert.\n"),1; |
| 432 | |
| 433 | if (!str || str==0) { |
| 434 | if (!pointerp(news=NEWSSERVER->GetNotes(GROUP))){ |
| 435 | GROUP=DEFAULTGROUP; |
| 436 | if (!pointerp(news=NEWSSERVER->GetNotes(GROUP))) |
| 437 | return notify_fail("Seltsam, irgendwie geht hier einiges schief...\n"),0; |
| 438 | } |
| 439 | return write("Aktuelle Rubrik: "+GROUP+" ("+sizeof(news)+" Artikel).\n"),1; |
| 440 | } |
| 441 | str=GetGroupName(str); |
| 442 | if (!str) return 1; |
| 443 | GROUP=str; |
| 444 | news=NEWSSERVER->GetNotes(GROUP); |
| 445 | write(break_string("Ok, Du hast die Rubrik "+GROUP+" mit "+sizeof(news)+ |
| 446 | " Artikel"+(sizeof(news)==1?"":"n")+" aufgeschlagen.\n", |
| 447 | 78)); |
| 448 | return 1; |
| 449 | } |
| 450 | |
| 451 | LiesArtikel(str) { |
| 452 | string s1; |
| 453 | int i1; |
| 454 | if ( !str ) return 0; |
| 455 | if (sscanf(str,"rubrik %s",s1)) |
| 456 | return rubrik(s1); |
| 457 | if (sscanf(str,"%d",i1)) |
| 458 | return lies(to_int(i1)); |
| 459 | if (sscanf(str,"artikel %s",s1)) |
| 460 | return lies(s1); |
| 461 | } |
| 462 | |
| 463 | |
| 464 | /* Ueberpruefe, ob in Rubrik tote threads ignoriert werden. Tot bedeutet, |
| 465 | dass der letzte darin uebergangene Artikel bereits expired ist UND |
| 466 | keine Artikel aus diesem thread mehr vorhanden sind. |
| 467 | ACHTUNG: Es kann passieren, dass dazwischen noch ein neuer Artikel |
| 468 | dazugekommen ist. |
| 469 | Hier wird auf expired geprueft und ggf Variable deadTID gesetzt. Wird beim |
| 470 | Lesen mit nn ein Artikel mit dieser TID gefunden (passiert direkt hinter |
| 471 | Pruefung), wird deadTID wieder auf 0 gesetzt. Ist deadTID beim Umschalten |
| 472 | auf naechste Rubrik !=0, ist der thread tot. |
| 473 | */ |
| 474 | |
| 475 | static int CheckThreads(string rubrik,int timeout) { |
| 476 | mixed tids; |
| 477 | int i; |
| 478 | |
| 479 | // deadTID=0; |
| 480 | tids=m_indices(read_until[IGNOREGROUP][rubrik]); |
| 481 | for (i=sizeof(tids)-1;i>=0&&!deadTID;i--) |
| 482 | if (read_until[IGNOREGROUP][rubrik][tids[i]]<timeout) deadTID=tids[i]; |
| 483 | return 1; |
| 484 | } |
| 485 | |
| 486 | static int rubriken(mixed arg) |
| 487 | { |
| 488 | mixed *gruppen, *messages; |
| 489 | mixed news; |
| 490 | int anz,i,lasttime,timeout,foundone; |
| 491 | string s; |
| 492 | |
| 493 | if (arg=="?"||arg=="-?") return |
| 494 | write("Syntax: rubriken listet alle Rubriken\n" |
| 495 | " rubriken neu nur Rubriken mit ungelesenen Artikeln\n"),1; |
| 496 | |
| 497 | gruppen=NEWSSERVER->GetGroups(); |
| 498 | map(m_indices(read_until)-gruppen-SYSTEMGROUPS,#'KillGroup); // '); |
| 499 | s="\nEs gibt zur Zeit "; |
| 500 | anz=sizeof(gruppen); |
| 501 | if (anz==0) { |
| 502 | write(s+"keine Rubriken (wie seltsam ...)\n"); |
| 503 | return 1; |
| 504 | } |
| 505 | s+=anz+" Rubrik"+(anz==1 ? "" : "en")+"."; |
| 506 | if (arg=="neu") s+="\nDavon enthalten neue Artikel:\n\n"; |
| 507 | else s+="\n(* oder x: enthaelt neue Artikel, x oder -: abbestellt, " |
| 508 | ">: aktuelle Rubrik)\n\n"; |
| 509 | for (i=0;i<anz;i++) { |
| 510 | timeout=read_until[gruppen[i]]; |
| 511 | /* GetNewsTime lieferte leider manchmal was falsches :-( */ |
| 512 | /* jetzt hoffentlich richtig? Wenn nicht, das if ausklammern */ |
| 513 | if ( arg!="neu" || (lasttime=NEWSSERVER->GetNewsTime(gruppen[i])) > timeout) { |
| 514 | messages=NEWSSERVER->GetNotes(gruppen[i]); |
| 515 | if (!messages || !sizeof(messages)) lasttime=0; |
| 516 | else lasttime=messages[sizeof(messages)-1][M_TIME]; |
| 517 | foundone=1; |
| 518 | } |
| 519 | if (arg!="neu" || (timeout>=0 && lasttime>abs(timeout))) |
| 520 | s+=sprintf("%s%s%3d\. %-39.39s: ", |
| 521 | ((gruppen[i]==GROUP)?">":" "), |
| 522 | ((lasttime>abs(timeout)) ? ((timeout<0) ? "x" : "*") |
| 523 | : ((timeout<0) ? "-" : " ") ), |
| 524 | i+1,gruppen[i])+ |
| 525 | (lasttime ? sprintf("%3d Artikel (%s)\n", |
| 526 | sizeof(messages), |
| 527 | // ((sizeof(messages)==1) ? ". " : "en."), |
| 528 | dtime(lasttime)[5..12]+ctime(lasttime)[<2..]) : |
| 529 | " - leer -\n"); |
| 530 | } |
| 531 | if (arg=="neu"&&!foundone) s+="Keine Rubrik enthaelt neue Artikel.\n"; |
| 532 | this_player()->More(s); |
| 533 | return 1; |
| 534 | } |
| 535 | |
| 536 | #define M_READNEXT 1 |
| 537 | #define M_LISTNEW 2 |
| 538 | #define M_LISTNEWGR 3 |
| 539 | #define M_READGR 4 |
| 540 | |
| 541 | static ReadNextUnread(str) |
| 542 | { |
| 543 | string *groups,group; |
| 544 | mixed *messages; |
| 545 | int curgr,curmsg,timeout,start,nrgroups,sog,mode; |
| 546 | |
| 547 | if (str=="mail") return Mail(0); /* NF Compatibility Special */ |
| 548 | |
| 549 | if (str=="?"||str=="-?") return |
| 550 | write("Syntax: nn naechster neuer Artikel\n" |
| 551 | " nn <rubrik> in entspr. Rubrik, wenn da was neu ist\n" |
| 552 | " nn rubriken Liste der Rubriken mit neuen Artikeln\n" |
| 553 | " nn liste Liste der ungelesenen Artikel\n"),1; |
| 554 | |
| 555 | groups=NEWSSERVER->GetGroups(); |
| 556 | deadTID=0; |
| 557 | map(m_indices(read_until)-groups-SYSTEMGROUPS,#'KillGroup); //' |
| 558 | nrgroups=sizeof(groups); |
| 559 | if (str && str!="rubriken" && str!="liste"){ |
| 560 | if (!group=GetGroupName(str)) return 1; |
| 561 | } |
| 562 | else |
| 563 | group=0; |
| 564 | if (group && (curgr=member(groups,group)+1)) { |
| 565 | --curgr; |
| 566 | if (curgr<0 || curgr>=sizeof(groups)) |
| 567 | return notify_fail("Nee... so eine Rubrik gibts hier nicht.\n"),0; |
| 568 | GROUP=group; |
| 569 | start=curgr+1; |
| 570 | mode=M_READGR; |
| 571 | write("Rubrik "+(curgr+1)+": "+GROUP+"\n"); |
| 572 | } else { |
| 573 | switch (str) { |
| 574 | case 0: mode=M_READNEXT; break; |
| 575 | case "liste": mode=M_LISTNEW; write("Du hast noch nicht gelesen:\n"); break; |
| 576 | case "rubriken": return rubriken("neu"); |
| 577 | default: |
| 578 | notify_fail("\ |
| 579 | Diesen Parameter verstehe ich nicht. Entweder gar nichts, \"liste\"\n\ |
| 580 | \"rubriken\", oder Name bzw. Nummer einer Rubrik.\n"); |
| 581 | return 0; |
| 582 | } |
| 583 | curgr=member(groups,GROUP); |
| 584 | start=curgr+nrgroups; |
| 585 | } |
| 586 | if (!pointerp(messages=NEWSSERVER->GetNotes(GROUP))){ |
| 587 | GROUP=DEFAULTGROUP; |
| 588 | if (!pointerp(messages=NEWSSERVER->GetNotes(GROUP))) |
| 589 | return notify_fail("Seltsam, irgendwie geht hier einiges schief...\n"),0; |
| 590 | } |
| 591 | timeout=read_until[GROUP]; |
| 592 | curmsg=0; |
| 593 | sog=sizeof(messages); |
| 594 | while (curgr<start) { |
| 595 | ++curmsg; |
| 596 | if (curmsg>sog) { |
| 597 | if (deadTID) |
| 598 | read_until[IGNOREGROUP][GROUP]= |
| 599 | m_copy_delete(read_until[IGNOREGROUP][GROUP],deadTID); |
| 600 | ++curgr; |
| 601 | deadTID=0; |
| 602 | if (mode!=M_READGR) { |
| 603 | GROUP=groups[curgr%nrgroups]; |
| 604 | timeout=read_until[GROUP]; |
| 605 | if (!timeout) read_until[GROUP]=1; // Nimm neue Gruppen in Liste auf |
| 606 | if (timeout<0 || timeout>=NEWSSERVER->GetNewsTime(GROUP)) { |
| 607 | sog=0; /* Ueberlistung: Gruppe hat nix neues oder */ |
| 608 | curmsg=1; /* ist unsubscribed */ |
| 609 | } |
| 610 | else { |
| 611 | messages=NEWSSERVER->GetNotes(GROUP); |
| 612 | curmsg=0; |
| 613 | sog=sizeof(messages); |
| 614 | } |
| 615 | } |
| 616 | } else { |
| 617 | if ((timeout>=0 || mode==M_READGR) && messages[curmsg-1][M_TIME] > abs(timeout)) { |
| 618 | if (pointerp(this_player()->QueryProp(P_IGNORE)) && |
| 619 | member(this_player()->QueryProp(P_IGNORE), |
| 620 | lower_case(messages[curmsg-1][M_WRITER])+".news") != -1) { |
| 621 | printf("Uebergehe ignorierten Artikel %d von %s in Rubrik %s.\n", |
| 622 | curmsg,messages[curmsg-1][M_WRITER],GROUP); |
| 623 | read_until[GROUP]=messages[curmsg-1][M_TIME]; |
| 624 | if (TP) TP->SetProp(P_READ_NEWS,read_until); |
| 625 | } else if |
| 626 | (read_until[IGNOREGROUP]&& |
| 627 | read_until[IGNOREGROUP][GROUP]&& |
| 628 | CheckThreads(GROUP,messages[0][M_TIME])&& /* Tote threads weg */ |
| 629 | read_until[IGNOREGROUP][GROUP][GetTID(messages[curmsg-1])]) { |
| 630 | printf("Uebergehe Artikel %d aus ignoriertem Thread.\n",curmsg); |
| 631 | read_until[IGNOREGROUP][GROUP][GetTID(messages[curmsg-1])]= |
| 632 | messages[curmsg-1][M_TIME]; |
| 633 | if (deadTID&&deadTID==GetTID(messages[curmsg-1])) deadTID=0; |
| 634 | read_until[GROUP]=messages[curmsg-1][M_TIME]; |
| 635 | if (TP) TP->SetProp(P_READ_NEWS,read_until); |
| 636 | } else { |
| 637 | write("\nRubrik "+(curgr%nrgroups+1)+": "+GROUP+", Artikel: "+curmsg+" von "+sog+"\n"); |
| 638 | if (mode==M_LISTNEW) { |
| 639 | write(sprintf(" %-45s [%-11s] %s\n",messages[curmsg-1][M_TITLE], |
| 640 | messages[curmsg-1][M_WRITER], |
| 641 | dtime(messages[curmsg-1][M_TIME])[5..16])); |
| 642 | } else { /* mode == M_READNEXT || mode==M_READGR */ |
| 643 | if (timeout>=0) read_until[GROUP]=messages[curmsg-1][M_TIME]; |
| 644 | else read_until[GROUP]=-messages[curmsg-1][M_TIME]; |
| 645 | if (TP) TP->SetProp(P_READ_NEWS,read_until); |
| 646 | return (lies(""+curmsg)); |
| 647 | } |
| 648 | } |
| 649 | } |
| 650 | /* sonst mach einfach garnix. Schleife laeuft weiter. */ |
| 651 | } |
| 652 | } |
| 653 | switch(mode) { |
| 654 | case M_LISTNEW: return 1; |
| 655 | case M_READNEXT: write((read_until[NNADWMSG]||"Nix Neues auf der Welt.") |
| 656 | +"\n"); break; |
| 657 | case M_READGR: write("Nix Neues in dieser Rubrik.\n"); break; |
| 658 | } |
| 659 | return 1; |
| 660 | } |
| 661 | |
| 662 | |
| 663 | static SetNNADWMSG(str) { |
| 664 | if (str=="?"||str=="-?") return |
| 665 | write("Syntax: zeitungsmeldung <neue Meldung> setzt Meldung\n" |
| 666 | " zeitungsmeldung loescht Meldung\n"),1; |
| 667 | if (!read_until[NNADWMSG]) { |
| 668 | write("Du hast zur Zeit keine eigene NNADW-Meldung definiert.\n"); |
| 669 | if (!str) return 1; |
| 670 | } |
| 671 | else write("Deine alte NNADW-Meldung war:\n"+read_until[NNADWMSG]+"\n"); |
| 672 | if (!str) { |
| 673 | read_until=m_copy_delete(read_until,NNADWMSG); |
| 674 | write("Meldung ist geloescht, es gilt wieder die Standardmeldung.\n"); |
| 675 | } else { |
| 676 | read_until[NNADWMSG]=this_player()->_unparsed_args(); |
| 677 | write("Deine neue Meldung lautet jetzt:\n"+read_until[NNADWMSG]+"\n"); |
| 678 | } |
| 679 | if (TP) TP->SetProp(P_READ_NEWS,read_until); |
| 680 | return 1; |
| 681 | } |
| 682 | |
| 683 | varargs int InterpretTime(mixed a,int flag) { |
| 684 | // string oder string * |
| 685 | // akzeptiert folgende Formate: |
| 686 | // dd.mm.jj (Rueckgabe: 0:00 des entsprechenden Tages) |
| 687 | // vor [<anz> d|tagen] [<anz> h|stunden] [<anz> m|minuten] |
| 688 | // flag=1: "inklusive": bei dd.mm.jj-Format 23:59:59 statt 0:00 Uhr |
| 689 | |
| 690 | int i,j,k,t,nrargs; |
| 691 | string s; |
| 692 | if (stringp(a)) a=explode(a," "); |
| 693 | |
| 694 | // printf("%O\n",a); |
| 695 | |
| 696 | if ((nrargs=sscanf(a[0],"%d.%d.%d",i,j,k))==3 || |
| 697 | (nrargs=sscanf(a[0],"%d.%d.",i,j))==2) { |
| 698 | // Datum -> Zeit: Funktioniert im Zeitraum 1973 - ca. 2090 |
| 699 | // in Zeitzonen mit ganzen Stunden ggue Rechneruhr. |
| 700 | if (nrargs==2) |
| 701 | k=70+time()/31536000; |
| 702 | if (k<70) k+=100; |
| 703 | if (k>1970) k-=1900; |
| 704 | if (k<70||k>150) return |
| 705 | write("Unzulaessiges Jahr (erlaubt: 70-heute).\n"),0; |
| 706 | t=(k-70)*31536000; |
| 707 | |
| 708 | if (i<1||i>31) return write("Unzulaessiger Tag (erlaubt: 1-31).\n"),0; |
| 709 | if (j<1||j>12) return write("Unzulaessiger Monat (erlaubt: 1-12).\n"),0; |
| 710 | // printf("%d.%d.%d\n",i,j,k); |
| 711 | s=ctime(t); |
| 712 | if ((j>2) && !(k%4)) t+=86400; // Schaltjahrkorrektur fuer Monate>=3 |
| 713 | t+=({ 0, 2678400, 5097600, 7776000, |
| 714 | 10368000, 13046400, 15638400, 18316800, |
| 715 | 20995200, 23587200, 26265600, 28857600})[j-1]; |
| 716 | t+=86400*(i-1); |
| 717 | t+=86400*(32-to_int(s[8..9])); // Schaltjahrkorrektur |
| 718 | t-=3600*to_int(s[11..12]); // Zeitzonenkorrektur |
| 719 | t-=3600*to_int(ctime(t)[11..12]); // Sommerzeitkorrektur |
| 720 | // write("Kontrolle: "+dtime(t)+"\n"); |
| 721 | if (nrargs==2 && t>time()) t-=31536000; |
| 722 | return (flag?t+86399:t); |
| 723 | } |
| 724 | |
| 725 | t=0; |
| 726 | if (a[0]=="vor") for (i=sizeof(a)-1;i>0;i--) { |
| 727 | switch (a[i]) { |
| 728 | case "m": |
| 729 | case "minuten": |
| 730 | case "min": |
| 731 | case "minute": |
| 732 | t+=60*to_int(a[i-1]); |
| 733 | break; |
| 734 | case "h": |
| 735 | case "stunde": |
| 736 | case "stunden": |
| 737 | case "s": |
| 738 | t+=3600*to_int(a[i-1]); |
| 739 | break; |
| 740 | case "d": |
| 741 | case "tag": |
| 742 | case "tage": |
| 743 | case "t": |
| 744 | t+=86400*to_int(a[i-1]); |
| 745 | break; |
| 746 | default: |
| 747 | if (!to_int(a[i])) |
| 748 | write("Argumentfehler: Kann nichts mit '"+a[i]+"' anfangen.\n"); |
| 749 | } |
| 750 | return time()-t; |
| 751 | } |
| 752 | else return write("Argumentfehler.\n"),0; |
| 753 | } |
| 754 | |
| 755 | static Catchup(string str) |
| 756 | { |
| 757 | int welche,zeit,i; |
| 758 | string gr; |
| 759 | mixed groups,news,args; |
| 760 | |
| 761 | if (!pointerp(NEWSSERVER->GetNotes(GROUP))) |
| 762 | return notify_fail("Seltsam, die Rubrik '"+GROUP+ |
| 763 | "' gibt es nicht mehr...\n"), 0; |
| 764 | |
| 765 | str=this_player()->_unparsed_args(); // wg. Datum |
| 766 | if (str) str=lower_case(str); |
| 767 | else str=GROUP; // default: aktuelle Rubrik komplett. |
| 768 | |
| 769 | if (str=="?"|| str=="-?") return CatchupSyntax(); |
| 770 | |
| 771 | // uebergehe Antworten (Thread ignorieren) |
| 772 | if (str&&(str[0..6]=="antwort"||str=="thread")) { |
| 773 | if (!pointerp(lasttitle)) return |
| 774 | write("Du hast bisher noch keinen Artikel gelesen, damit kann ich nicht wissen,\nwelchen Thread du uebergehen willst.\n"),1; |
| 775 | if (!read_until[IGNOREGROUP]) read_until[IGNOREGROUP]=([]); |
| 776 | if (!read_until[IGNOREGROUP][GROUP]) read_until[IGNOREGROUP][GROUP]=([]); |
| 777 | if (read_until[IGNOREGROUP][GROUP][lasttitle[3]]) { |
| 778 | read_until[IGNOREGROUP][GROUP]=m_copy_delete(read_until[IGNOREGROUP][GROUP],lasttitle[3]); |
| 779 | write("Dieser Thread wird jetzt nicht mehr uebergangen.\n"); |
| 780 | } else { |
| 781 | read_until[IGNOREGROUP][GROUP][lasttitle[3]]=lasttitle[2]; |
| 782 | write("Dieser Thread wird ab sofort uebergangen.\nFalls das ein Irrtum war, wiederhole den Befehl augenblicklich.\n"); |
| 783 | } |
| 784 | if (TP) TP->SetProp(P_READ_NEWS,read_until); |
| 785 | return 1; |
| 786 | } |
| 787 | |
| 788 | groups=NEWSSERVER->GetGroups(); |
| 789 | |
| 790 | args=explode(str," "); |
| 791 | |
| 792 | // Uebergehe alles |
| 793 | |
| 794 | if (args[0]=="alle" || args[0]=="alles" || args[0]=="all") { |
| 795 | if (sizeof(args)<=1) zeit=time()-1; |
| 796 | else if (args[1]!="bis") return CatchupSyntax(); |
| 797 | else if (sizeof(args)<3) return CatchupSyntax(); |
| 798 | |
| 799 | else zeit=InterpretTime(args[2..],1); |
| 800 | if (zeit>time()) zeit=time()-1; |
| 801 | write("Uebergehe alle Rubriken bis "+dtime(zeit)+".\n"); |
| 802 | for (welche=0;welche<sizeof(groups);++welche) { |
| 803 | gr=groups[welche]; |
| 804 | // zeit=NEWSSERVER->GetNewsTime(gr); |
| 805 | if (abs(read_until[gr])<zeit) |
| 806 | read_until[gr]=(read_until[gr]>=0)?zeit:-zeit; |
| 807 | if (TP) TP->SetProp(P_READ_NEWS,read_until); |
| 808 | } |
| 809 | return 1; |
| 810 | } |
| 811 | |
| 812 | // Anzahl Artikel |
| 813 | |
| 814 | if (sizeof(args)>=2 && args[1]=="artikel") { |
| 815 | if (!to_int(args[0])) return CatchupSyntax(); |
| 816 | news=NEWSSERVER->GetNotes(GROUP); |
| 817 | for (i=sizeof(news)-1;i>=0&&news[i][M_TIME]>read_until[GROUP];i--); |
| 818 | welche=i+to_int(args[0]); |
| 819 | if (welche>=sizeof(news)) welche=sizeof(news)-1; |
| 820 | write("Uebergehe die naechsten "+(welche-i)+" Artikel in Rubrik "+ |
| 821 | GROUP+"\n."); |
| 822 | if (welche>=0) { |
| 823 | zeit=news[welche][M_TIME]; |
| 824 | read_until[GROUP]=(read_until[GROUP]>=0)?zeit:-zeit; |
| 825 | if (TP) TP->SetProp(P_READ_NEWS,read_until); |
| 826 | } |
| 827 | return 1; |
| 828 | } |
| 829 | |
| 830 | // einzelne Rubrik. |
| 831 | |
| 832 | if (!(gr=GetGroupName(args[0]))) return 1; |
| 833 | news=NEWSSERVER->GetNotes(gr); |
| 834 | if (!sizeof(news)) { |
| 835 | write("Rubrik "+gr+" ist leer.\n"); |
| 836 | return 1; |
| 837 | } |
| 838 | // zeit=news[sizeof(news)-1][M_TIME]; |
| 839 | if (sizeof(args)<=1) |
| 840 | zeit=time(); |
| 841 | else |
| 842 | if (args[1]!="bis") return CatchupSyntax(); |
| 843 | else |
| 844 | zeit=InterpretTime(args[2..],1); |
| 845 | if (zeit>time()) zeit=time(); |
| 846 | read_until[gr]=zeit; |
| 847 | if (TP) TP->SetProp(P_READ_NEWS,read_until); |
| 848 | write("Uebergehe "+gr+" bis "+dtime(zeit)+",\nletzter Artikel war vom "+ |
| 849 | dtime(NEWSSERVER->GetNewsTime(gr))+"\n"); |
| 850 | return 1; |
| 851 | } |
| 852 | |
| 853 | |
| 854 | static Ignore(str) { |
| 855 | if (str=="thread"||str=="antworten") return Catchup(str); |
| 856 | return 0; |
| 857 | } |
| 858 | |
| 859 | static CatchupSyntax() { |
| 860 | write("Syntax des Befehls uebergehe (oder catchup):\n" |
| 861 | " uebergehe [rubrik] (default: aktuelle Rubrik)\n" |
| 862 | " uebergehe alles (in allen Rubriken)\n" |
| 863 | " uebergehe <anz> artikel (in akt. Rubrik)\n" |
| 864 | " uebergehe [rubrik]|alles bis <tag>.<monat>.[<jahr>]\n" |
| 865 | " uebergehe [rubrik]|alles bis vor <zeit> wobei\n" |
| 866 | " <zeit> = [<n> d|tage] [<n> h|stunden] [<n> m|min|minuten]\n" |
| 867 | " uebergehe thread|antworten (entspr. 'ignoriere thread')\n"); |
| 868 | |
| 869 | return 1; |
| 870 | } |
| 871 | |
| 872 | |
| 873 | static int UncatchupSyntax() |
| 874 | { |
| 875 | notify_fail( |
| 876 | "Syntax: wiederhole <anz> [artikel]\n" |
| 877 | " wiederhole [ab vor] [<anz> m|minute[n]] [<anz> h|stunde[n]] [<anz> d|tag[e]]\n" |
| 878 | " wiederhole ab tag.monat[.jahr]\n" |
| 879 | " wiederhole alles\n" |
| 880 | "Der wiederhole- oder uncatchup-Befehl bezieht sich immer auf die aktuelle\n" |
| 881 | "Rubrik und markiert die angegebenen Artikel wieder als ungelesen.\n" |
| 882 | "Zeiten (2. Syntax) sind rueckwaerts ab aktueller Uhrzeit gerechnet.\n"),0; |
| 883 | return 0; |
| 884 | } |
| 885 | |
| 886 | |
| 887 | static Uncatchup(string str) |
| 888 | { |
| 889 | mixed args; |
| 890 | int i,zeit; |
| 891 | int mode; // 0 = nix, 1=Anzahl Artikel, 2=Zeit, 3=alles |
| 892 | |
| 893 | str=this_player()->_unparsed_args(); // wg. Datum |
| 894 | if ( !TP || !str || !stringp(str) || str=="?" || str=="-?" ) |
| 895 | return UncatchupSyntax(); |
| 896 | |
| 897 | if (!pointerp(NEWSSERVER->GetNotes(GROUP))) |
| 898 | return notify_fail("Seltsam, die Rubrik '"+GROUP+ |
| 899 | "' gibt es nicht mehr...\n"), 0; |
| 900 | |
| 901 | args=({""})+explode(lower_case(str)," "); |
| 902 | if (args[1]=="ab") { |
| 903 | mode=2; |
| 904 | if (sizeof(args)<3) |
| 905 | return UncatchupSyntax(); |
| 906 | zeit=InterpretTime(args[2..]); |
| 907 | } else { |
| 908 | zeit=time(); |
| 909 | for (i=sizeof(args)-1;i>0;i--) { |
| 910 | switch(args[i]){ |
| 911 | case "alles": |
| 912 | case "alle": |
| 913 | case "all": |
| 914 | if (mode&&mode!=3) return |
| 915 | notify_fail("Bitte nur Zeit ODER alles ODER Anzahl angeben!\n"),0; |
| 916 | mode=3; |
| 917 | break; |
| 918 | case "minuten": |
| 919 | case "minute": |
| 920 | case "m": |
| 921 | case "stunden": |
| 922 | case "stunde": |
| 923 | case "h": |
| 924 | case "tage": |
| 925 | case "tag": |
| 926 | case "d": |
| 927 | if (mode&&mode!=2) return |
| 928 | notify_fail("Bitte nur Zeit/Datum ODER alles ODER " |
| 929 | "Anzahl angeben!\n"),0; |
| 930 | mode=2; |
| 931 | zeit-=(((args[i][0]=='m') ? 60 : |
| 932 | ((args[i][0]=='s' || args[i][0]=='h') ? 3600 : 86400)) |
| 933 | *to_int(args[i-1])); |
| 934 | i--; |
| 935 | break; |
| 936 | case "artikel": |
| 937 | if (mode&&mode!=1) return |
| 938 | notify_fail("Bitte nur Zeit/Datum ODER alles ODER " |
| 939 | "Anzahl angeben!\n"),0; |
| 940 | mode=1; |
| 941 | zeit=to_int(args[i-1]); |
| 942 | i--; |
| 943 | break; |
| 944 | case "ab": |
| 945 | return |
| 946 | notify_fail("Bitte nur Zeit/Datum ODER alles ODER " |
| 947 | "Anzahl angeben!\n"),0; |
| 948 | default: |
| 949 | if (!to_int(args[i])) |
| 950 | return notify_fail("Unbekanntes Argument '"+args[i]+ |
| 951 | "'! Aktion abgebrochen.\n"),0; |
| 952 | if (mode&&mode!=1) return |
| 953 | notify_fail("Bitte nur Zeit/Datum ODER alles ODER " |
| 954 | "Anzahl angeben!\n"),0; |
| 955 | mode=1; |
| 956 | zeit=to_int(args[i]); |
| 957 | } |
| 958 | } |
| 959 | } |
| 960 | |
| 961 | switch(mode){ |
| 962 | case 0: |
| 963 | return notify_fail("Gib bitte irgendeine Einheit an " |
| 964 | "(Hilfe mit wiederhole -?)!\n"); |
| 965 | case 2: |
| 966 | read_until[GROUP]=(read_until[GROUP]>=0)?zeit:-zeit; |
| 967 | write(break_string("Markiere alle Artikel in Rubrik "+GROUP+ |
| 968 | " seit "+dtime(zeit)+" als ungelesen.\n",78)); |
| 969 | break; |
| 970 | case 3: |
| 971 | read_until[GROUP]=(read_until[GROUP]>=0?1:-1); |
| 972 | write("Markiere die komplette Rubrik "+GROUP+" als ungelesen.\n"); |
| 973 | break; |
| 974 | case 1: |
| 975 | write(break_string("Markiere die letzten "+zeit+ |
| 976 | " gelesenen Artikel in Rubrik "+GROUP+" als ungelesen.\n",78)); |
| 977 | { int h; mixed notes; |
| 978 | notes=NEWSSERVER->GetNotes(GROUP); |
| 979 | h=sizeof(notes)-1; |
| 980 | while ( (h>=0) && (abs(read_until[GROUP]) < notes[h][M_TIME]) ) { |
| 981 | h--; |
| 982 | } |
| 983 | if (h==-1||h<zeit) |
| 984 | read_until[GROUP]= |
| 985 | (read_until[GROUP]>=0)?1:-1; |
| 986 | else |
| 987 | read_until[GROUP]=( |
| 988 | (read_until[GROUP]>=0)?notes[h-zeit][M_TIME] |
| 989 | :-notes[h-zeit][M_TIME]); |
| 990 | } |
| 991 | } |
| 992 | write("Ok. Du kannst die als ungelesen markierten Artikel " |
| 993 | "mit nn nochmal lesen.\n"); |
| 994 | |
| 995 | if (TP) TP->SetProp(P_READ_NEWS,read_until); |
| 996 | return 1; |
| 997 | } |
| 998 | |
| 999 | |
| 1000 | QueryRead() { |
| 1001 | return read_until; |
| 1002 | } |
| 1003 | |
| 1004 | static CatchNewsError(int err,string text4minus3) { |
| 1005 | switch (err) { |
| 1006 | case 1: return 1; |
| 1007 | case -1: write("Du darfst in dieser Rubrik nicht schreiben!\n"); return 0; |
| 1008 | case -2: write("Die Rubrik gibt es nicht mehr, sehr seltsam...\n"); return 0; |
| 1009 | case -3: write(text4minus3+"\n"); return 0; |
| 1010 | default: write("Interner Fehler "+err+", Erzmagier verstaendigen!\n"); return 0; |
| 1011 | } |
| 1012 | } |
| 1013 | |
| 1014 | static varargs schreib(str,pretext,called_by_itself,statuslines) { |
| 1015 | int err; |
| 1016 | |
| 1017 | if (str=="?"||str=="-?") { |
| 1018 | write("Syntax: schreib <Titel>\n" |
| 1019 | " beginnt einen neuen Artikel in der Zeitung.\n"); |
| 1020 | return 1; |
| 1021 | } |
| 1022 | |
| 1023 | if (!this_interactive() || !this_interactive()->query_real_name()) return 0; |
| 1024 | if (!called_by_itself && extern_call() && !pretext) |
| 1025 | str=this_interactive()->_unparsed_args()||""; |
| 1026 | if (called_by_itself && str=="~q") { |
| 1027 | write("Abgebrochen.\n"); |
| 1028 | return 1; |
| 1029 | } |
| 1030 | if (!CatchNewsError( |
| 1031 | NEWSSERVER->AskAllowedWrite(GROUP), |
| 1032 | "Diese Rubrik ist leider schon randvoll!")) return 1; |
| 1033 | if (!called_by_itself) |
| 1034 | write("Neuer Artikel in Rubrik "+GROUP+":\n"); |
| 1035 | if (!str || str=="" || str=="artikel") { |
| 1036 | input_to("schreib", INPUT_PROMPT, "Titel des Artikels: ", pretext,1); |
| 1037 | return 1; |
| 1038 | } |
| 1039 | // writer=this_interactive()->query_real_name(); |
| 1040 | message=allocate(6); |
| 1041 | message[M_BOARD]=GROUP; |
| 1042 | message[M_TITLE]=killctrl(str); |
| 1043 | message[M_MESSAGE]=statuslines; |
| 1044 | write("Titel ist: "+str+".\n\ |
| 1045 | Gib jetzt Deinen Text ein,\n\ |
| 1046 | ** oder . wenn Du fertig bist, ~q zum Abbrechen, ~h fuer eine Hilfsseite.\n"); |
| 1047 | nedit("PostNote",pretext); |
| 1048 | return 1; |
| 1049 | } |
| 1050 | |
| 1051 | static varargs Reply(string str,string newtitle) { |
| 1052 | mixed dummy,replytitle,s; |
| 1053 | int nr; |
| 1054 | |
| 1055 | if ((dummy=(str||newtitle))=="?"||dummy=="-?") { |
| 1056 | write("Der Antworte-Befehl ist doppelt belegt.\n" |
| 1057 | "1. (Zeitung): Schreibe Antwort auf einen Artikel in der Zeitung.\n" |
| 1058 | " Syntax: antworte\n" |
| 1059 | " antworte auf artikel <nr> [neuer Titel]\n" |
| 1060 | " reply [auf artikel <nr> | to note <nr>] [neuer Titel]\n" |
| 1061 | "2. aehnlich 'sage':\n" |
| 1062 | " Du tippst zum Beispiel:\n" |
| 1063 | " antworte ja, das weiss ich\n" |
| 1064 | " Alle Spieler im Raum sehen dann:\n" |
| 1065 | " <Dein Name> antwortet: ja, das weiss ich.\n" |
| 1066 | "Bitte beachte, dass jede Syntax, die auf den antworte-Befehl der " |
| 1067 | "Zeitung\npasst, auch von der Zeitung ausgewertet wird.\n"); |
| 1068 | return 1; |
| 1069 | } |
| 1070 | |
| 1071 | if (str&& |
| 1072 | ((sscanf(lower_case(str),"auf artikel %d",dummy)==1 && |
| 1073 | str=this_player()->_unparsed_args()[12..])|| |
| 1074 | (sscanf(lower_case(str),"to note %d",dummy)==1 && |
| 1075 | str=this_player()->_unparsed_args()[8..]))) { |
| 1076 | mixed notes; |
| 1077 | notes=NEWSSERVER->GetNotes(GROUP); |
| 1078 | if (dummy<1||dummy>sizeof(notes)) |
| 1079 | return write("Einen Artikel mit der Nummer "+dummy+ |
| 1080 | " gibt es in dieser Rubrik nicht.\n"),1; |
| 1081 | dummy--; |
| 1082 | replytitle=({notes[dummy][M_TITLE],notes[dummy][M_WRITER], |
| 1083 | notes[dummy][M_TIME],GetTID(notes[dummy]),GROUP}); |
| 1084 | DEBUGVAR(str); |
| 1085 | if (!newtitle&&str&&sizeof(str)&&sscanf(str,"%d %s",dummy,str)==2) |
| 1086 | newtitle=str; |
| 1087 | } |
| 1088 | else if (!str||!sizeof(str)) { |
| 1089 | if (!lasttitle) return |
| 1090 | write("Du hast noch gar nichts gelesen, worauf Du " |
| 1091 | "antworten koenntest.\n"),1; |
| 1092 | replytitle=lasttitle; |
| 1093 | } |
| 1094 | else return 0; |
| 1095 | |
| 1096 | // return ComposeReply(replytitle); |
| 1097 | //} |
| 1098 | // |
| 1099 | // |
| 1100 | //ComposeReply(mixed replytitle) { |
| 1101 | |
| 1102 | if (!newtitle) { |
| 1103 | if (replytitle[0][0..7]=="Re: Re: ") newtitle="Re^3: "+replytitle[0][8..]; |
| 1104 | else if (sscanf(replytitle[0],"Re^%d: %s",nr,newtitle)) |
| 1105 | newtitle="Re^"+(nr+1)+": "+newtitle; |
| 1106 | else newtitle="Re: "+replytitle[0]; |
| 1107 | } |
| 1108 | return schreib(newtitle,0,0, |
| 1109 | STATUSESCAPE+" rn="+replytitle[LAST_WRITER]+ |
| 1110 | " rt="+replytitle[LAST_TIME]+ |
| 1111 | " rg="+replytitle[LAST_GROUP]+"\n"+ |
| 1112 | STATUSESCAPE+" tid="+replytitle[LAST_TID]+"\n"); |
| 1113 | } |
| 1114 | |
| 1115 | static Reply2(str) { |
| 1116 | str = this_player()->_unparsed_args(); |
| 1117 | if (!str||str[0..11]=="auf artikel "||str[0..7]=="to note ") |
| 1118 | return Reply(str); |
| 1119 | return Reply(0,str); |
| 1120 | } |
| 1121 | |
| 1122 | static void InformPlayers(string group,string player,string text) |
| 1123 | { |
| 1124 | object *players; |
| 1125 | int i; |
| 1126 | mixed data; |
| 1127 | string ig; |
| 1128 | |
| 1129 | players=users(); |
| 1130 | ig=lower_case(player)+".news"; |
| 1131 | for (i=sizeof(players)-1;i>=0;i--) { |
| 1132 | data=players[i]->QueryProp(P_WAITFOR); |
| 1133 | if (pointerp(data)&&(member(data,"Mpa")>-1)) { |
| 1134 | data=players[i]->QueryProp(P_READ_NEWS); |
| 1135 | if (mappingp(data)&&(data[group]>0)) { |
| 1136 | data=players[i]->QueryProp(P_IGNORE); |
| 1137 | if ((!pointerp(data))||(member(data,ig)==-1)) |
| 1138 | tell_object(players[i],text); |
| 1139 | } |
| 1140 | } |
| 1141 | } |
| 1142 | } |
| 1143 | |
| 1144 | static PostNote(text) { |
| 1145 | int err; |
| 1146 | string sig; |
| 1147 | |
| 1148 | if (!text) { |
| 1149 | write("Abbruch! Artikel landet im Reisswolf.\n"); |
| 1150 | return 1; |
| 1151 | } |
| 1152 | if (!sizeof(old_explode(text,"\n")- |
| 1153 | ({"q","quit"," **","** ","ende","","exit"," "}) |
| 1154 | ) ) |
| 1155 | return write("\ |
| 1156 | ACHTUNG: Wolltest Du wirklich einen Artikel ohne Inhalt in die mpa setzen?\n\ |
| 1157 | Artikel ohne erkennbaren Inhalt werden NICHT veroeffentlicht. Bitte ueber-\n\ |
| 1158 | pruef Deine Syntax, falls Du keinen Artikel schreiben wolltest, oder schreib\n\ |
| 1159 | auch ein bisschen Text!\n\ |
| 1160 | Artikel landet im Reisswolf.\n"),1; |
| 1161 | if (!message[M_MESSAGE]) |
| 1162 | message[M_MESSAGE] = text; |
| 1163 | else |
| 1164 | message[M_MESSAGE]+=text; |
| 1165 | if (sig=read_file("/players/"+geteuid(this_interactive())+"/.signature")) |
| 1166 | message[M_MESSAGE]+=sig; |
| 1167 | if (!CatchNewsError(NEWSSERVER->WriteNote(message), |
| 1168 | "Diese Rubrik ist voll. Mist, da war jemand schneller...")) { |
| 1169 | write("Versuch, Platz in der Rubrik zu finden, dann kannst Du mir ~r nochmal\nin den Text einsteigen und ihn anschliessend veroeffentlichen.\n(Vorschlag: Einen veralteten Artikel abhaengen oder verlegen.\n"); |
| 1170 | return 0; |
| 1171 | } |
| 1172 | write("OK, Artikel ist veroeffentlicht.\n"); |
| 1173 | say(capitalize(TP->name())+ |
| 1174 | " hat einen Artikel in der Zeitung veroeffentlicht.\n"); |
| 1175 | if (geteuid(TP)!="sitopanaki") |
| 1176 | InformPlayers(message[M_BOARD],geteuid(this_interactive()), |
| 1177 | "* MPA: Neuer Artikel von "+ |
| 1178 | capitalize(geteuid(this_interactive()))+ |
| 1179 | " in Rubrik \""+message[M_BOARD]+"\".\n"); |
| 1180 | message=0; /* Platz sparen! */ |
| 1181 | return 1; |
| 1182 | } |
| 1183 | |
| 1184 | |
| 1185 | //static // allowing aliasing *Rumata* 5/8/96 |
| 1186 | inhalt(str) { |
| 1187 | int i,endflag,timeout; |
| 1188 | string *gruppen,s,txt,suche; |
| 1189 | mixed messages; |
| 1190 | |
| 1191 | if (str=="?"||str=="-?") return |
| 1192 | write("Syntax: inhalt [<rubrik>] [ende] [suche <text>]\n"),1; |
| 1193 | |
| 1194 | str=(!str)?({}):explode(str," "); |
| 1195 | |
| 1196 | if (sizeof(str) && (str[0]=="neu" || str[0]=="neues") ) |
| 1197 | return ReadNextUnread("liste"),1; |
| 1198 | |
| 1199 | if (endflag=member(str,"ende")+1) str-=({"ende"}); |
| 1200 | if (((i=member(str,"suche")) != -1) && (sizeof(str) > i)) { |
| 1201 | suche=lower_case(implode(str[i+1..]," ")); |
| 1202 | str=str[0..i-1]; |
| 1203 | } |
| 1204 | else |
| 1205 | suche=0; |
| 1206 | if (!sizeof(str)) { |
| 1207 | str=GROUP; |
| 1208 | if (!pointerp(messages=NEWSSERVER->GetNotes(str))){ |
| 1209 | str=GROUP=DEFAULTGROUP; |
| 1210 | if (!pointerp(messages=NEWSSERVER->GetNotes(str))) |
| 1211 | return notify_fail("Seltsam, irgendwie geht hier einiges schief...\n"),0; |
| 1212 | } |
| 1213 | } |
| 1214 | else { |
| 1215 | str=GetGroupName(str[0]); |
| 1216 | if (!str) return 1; |
| 1217 | messages=NEWSSERVER->GetNotes(str); |
| 1218 | } |
| 1219 | timeout=abs(read_until[str]); |
| 1220 | s="Inhalt der Rubrik "+str+":\n\n"; |
| 1221 | if (!pointerp(messages) || !sizeof(messages)) |
| 1222 | return |
| 1223 | write(s+"Zur Zeit befinden sich keine Artikel in dieser Rubrik.\n"),1; |
| 1224 | if (suche) |
| 1225 | s+="Suche nach '"+suche+"' in der Rubrik ergab folgende Treffer:\n\n"; |
| 1226 | else |
| 1227 | if (sizeof(messages)==1) |
| 1228 | s+="Zur Zeit befindet sich ein Artikel in der Rubrik:\n\n"; |
| 1229 | else |
| 1230 | s+="Zur Zeit befinden sich "+sizeof(messages)+ |
| 1231 | " Artikel in der Rubrik:\n\n"; |
| 1232 | if (endflag&&(sizeof(messages)>16)&& |
| 1233 | messages[sizeof(messages)-16][M_TIME]>=timeout) timeout=-1; |
| 1234 | for (i=(endflag?(((endflag=sizeof(messages)-15)<0)?0:endflag):0); |
| 1235 | i<sizeof(messages);i++) |
| 1236 | { |
| 1237 | txt=sprintf("%2d.%s%-48s%4d (%-11s) %s\n",i+1, |
| 1238 | (((timeout>=0) && timeout<messages[i][M_TIME] )? |
| 1239 | ( (timeout=-1),"*"):" "),messages[i][M_TITLE], |
| 1240 | sizeof(explode(messages[i][M_MESSAGE],"\n")), |
| 1241 | messages[i][M_WRITER], |
| 1242 | dtime(messages[i][M_TIME])[5..11]); |
| 1243 | if (!suche || (strstr(lower_case(txt), suche) != -1)) |
| 1244 | s+=txt; |
| 1245 | } |
| 1246 | if (endflag) write(s); |
| 1247 | else this_player()->More(s); |
| 1248 | return 1; |
| 1249 | } |
| 1250 | |
| 1251 | |
| 1252 | static artikel(str) { |
| 1253 | return lies(str); |
| 1254 | } |
| 1255 | |
| 1256 | |
| 1257 | static loesche(str) { |
| 1258 | int num; |
| 1259 | mixed *messages; |
| 1260 | |
| 1261 | if (str=="?"||str=="-?") return |
| 1262 | write("Syntax: loesche artikel <nr>\n" |
| 1263 | " (bezieht sich immer auf die aktuelle Rubrik.\n"),1; |
| 1264 | |
| 1265 | if (!str || sscanf(str,"artikel %d",num)!=1 || num<=0) |
| 1266 | return notify_fail("WELCHEN Artikel willst Du loeschen ?\n"),0; |
| 1267 | num--; |
| 1268 | messages=(NEWSSERVER->GetNotes(GROUP)); |
| 1269 | if (sizeof(messages)<=num) return |
| 1270 | notify_fail("So viele Artikel sind da nicht!\n"),0; |
| 1271 | |
| 1272 | write("Rubrik "+GROUP+", Artikel "+(num+1)+ |
| 1273 | " von "+capitalize(messages[num][M_WRITER])+ |
| 1274 | " vom "+dtime(messages[num][M_TIME])[5..26]+ |
| 1275 | ",\nTitel: "+messages[num][M_TITLE]+",\n\n"); |
| 1276 | |
| 1277 | /* (ueberfluessige Abfrage, macht schon /secure/news) |
| 1278 | if (!IS_LEARNER(TI) && lower_case(messages[num][M_WRITER])!=geteuid(TI)) |
| 1279 | return |
| 1280 | write("Nicht geloescht - du darfst nur eigene Artikel loeschen.\n"),1; |
| 1281 | */ |
| 1282 | |
| 1283 | switch (NEWSSERVER->RemoveNote(GROUP, num)){ |
| 1284 | case 1: write("Artikel ist geloescht.\n"); |
| 1285 | say(this_player()->name()+" loescht einen Artikel aus der Zeitung.\n"); |
| 1286 | return 1; |
| 1287 | case -1: write("Diesen Artikel darfst Du nicht loeschen.\n"); |
| 1288 | say(this_player()->name()+" versucht vergeblich, einen Artikel zu loeschen.\n"); |
| 1289 | return 1; |
| 1290 | case -3: write("So viele Artikel sind da nicht !\n"); |
| 1291 | return 1; |
| 1292 | default: write("Interner Fehler. Bitte Erzmagier verstaendigen !\n"); |
| 1293 | return 1; |
| 1294 | } |
| 1295 | } |
| 1296 | |
| 1297 | // Low-level Funktion zum Abonnieren/Abbestellen von Rubriken |
| 1298 | // bestellen==0 -> abbestellen, bestellen!=0 -> bestellen |
| 1299 | // Rueckgabe: 0, wenn der gewuenschte Zustand schon eingestellt war, sonst 1 |
| 1300 | private int _subscribe(string groupname, int bestellen) { |
| 1301 | |
| 1302 | int timeout = read_until[groupname]; |
| 1303 | // gar nicht abonniert/abbestellt? |
| 1304 | if (!bestellen && timeout < 0) |
| 1305 | return 0; |
| 1306 | else if (bestellen && timeout > 0) |
| 1307 | return 0; |
| 1308 | |
| 1309 | // wenn noch kein timeout, erstmal auf 1 setzen |
| 1310 | timeout ||= 1; |
| 1311 | |
| 1312 | // -1 fuer abbestellen, +1 fuer bestellen |
| 1313 | if (bestellen) |
| 1314 | read_until[groupname] = abs(timeout); |
| 1315 | else |
| 1316 | read_until[groupname] = -timeout; |
| 1317 | |
| 1318 | if (environment()) |
| 1319 | environment()->SetProp(P_READ_NEWS, read_until); |
| 1320 | |
| 1321 | return 1; |
| 1322 | } |
| 1323 | |
| 1324 | static Unsubscribe(str) { |
| 1325 | int timeout; |
| 1326 | if (str=="?"||str=="-?") return |
| 1327 | write("Syntax: unsubscribe <rubrik>" |
| 1328 | " oder: bestelle <rubrik> ab\n"),1; |
| 1329 | str=GetGroupName(str); |
| 1330 | if (!str) return 1; |
| 1331 | if (!_subscribe(str,0)) { |
| 1332 | notify_fail("Die Rubrik hast Du gar nicht abonniert!\n"); |
| 1333 | return 0; |
| 1334 | } |
| 1335 | else { |
| 1336 | write("Rubrik "+str+" abbestellt.\n"); |
| 1337 | } |
| 1338 | return 1; |
| 1339 | } |
| 1340 | |
| 1341 | |
| 1342 | static Bestelle(str) { /* ab ! */ |
| 1343 | if (!str || !sscanf(str,"%s ab",str)) return _notify_fail( |
| 1344 | "Die Syntax ist: 'bestelle <rubrik> ab', " |
| 1345 | "oder meinst Du 'abonniere'?\n"),0; |
| 1346 | return Unsubscribe(str); |
| 1347 | } |
| 1348 | |
| 1349 | static Subscribe(str) { |
| 1350 | int timeout; |
| 1351 | if (str=="?"||str=="-?") return |
| 1352 | write("Syntax: abonniere <rubrik>\n" |
| 1353 | " oder: subscribe <rubrik>\n"),1; |
| 1354 | str=GetGroupName(str); |
| 1355 | if (!str) return 1; |
| 1356 | if (!_subscribe(str,1)) { |
| 1357 | notify_fail("Die Rubrik hast Du doch schon abonniert!\n"); |
| 1358 | return 0; |
| 1359 | } |
| 1360 | else { |
| 1361 | write("Rubrik "+str+" abonniert.\n"); |
| 1362 | } |
| 1363 | return 1; |
| 1364 | } |
| 1365 | |
| 1366 | // Legt die anfaenglichen Abonnements eines Neulesers fest und bestellt alle |
| 1367 | // anderen ab. |
| 1368 | private void InitialSubscriptions() { |
| 1369 | // alle abbestellen. ;-) |
| 1370 | // Alternative: fuer alle _subscribe(,0) rufen |
| 1371 | if (!query_once_interactive(environment())) |
| 1372 | return; |
| 1373 | string *gruppen = NEWSSERVER->GetGroups(); |
| 1374 | int *vals = allocate(sizeof(gruppen),-1); |
| 1375 | read_until = mkmapping(gruppen,vals); |
| 1376 | |
| 1377 | // jetzt die vorausgewaehlten bestellen |
| 1378 | foreach(string gruppe : INITIAL_SUBSCRIPTIONS) { |
| 1379 | if (member(gruppen, gruppe) > -1) |
| 1380 | _subscribe(gruppe,1); |
| 1381 | } |
| 1382 | // und ggf. noch die eigene Gildenrubrik |
| 1383 | string gilde = environment()->QueryProp(P_GUILD); |
| 1384 | if (stringp(gilde) |
| 1385 | && member(gruppen, "gilden."+gilde) > -1) |
| 1386 | _subscribe("gilden."+gilde,1); |
| 1387 | |
| 1388 | environment()->SetProp(P_READ_NEWS, read_until); |
| 1389 | } |
| 1390 | |
| 1391 | static MoveMessage(str) { |
| 1392 | int num,i; |
| 1393 | mixed msg/*,expl*/; |
| 1394 | string gr; |
| 1395 | if (str=="?"||str=="-?") return |
| 1396 | write("Syntax: verlege artikel <nr> nach <rubrik>\n" |
| 1397 | " Artikel und Rubrik muessen explizit angegeben werden.\n"),1; |
| 1398 | if (!str || sscanf(str,"artikel %d nach %s",num,gr)!=2) return (int)notify_fail( |
| 1399 | "verlege artikel <nr> nach <rubrik>, oder was?\n"); |
| 1400 | if (!(gr=GetGroupName(gr))) return 1; |
| 1401 | if (!(CatchNewsError(NEWSSERVER->AskAllowedWrite(gr),"Die Rubrik ist leider voll.\n"))) return 1; |
| 1402 | |
| 1403 | if (!pointerp(msg=NEWSSERVER->GetNotes(GROUP))) |
| 1404 | return notify_fail("Seltsam, die Rubrik '"+GROUP+ |
| 1405 | "' gibt es nicht mehr...\n"), 0; |
| 1406 | |
| 1407 | num--; |
| 1408 | if (sizeof(msg)<=num) return |
| 1409 | notify_fail("So viele Nachrichten sind da nicht !\n"),0; |
| 1410 | msg=msg[num]; |
| 1411 | if (geteuid(TI) != lower_case(msg[M_WRITER])) { |
| 1412 | if (!IS_LEARNER(TI)) return |
| 1413 | write("Du darfst nur Deine eigenen Artikel verlegen.\n"),1; |
| 1414 | write("WARNUNG: Das ist nicht Dein eigener Artikel!\n"); |
| 1415 | } |
| 1416 | // return (int)notify_fail("Man darf zur Zeit nur eigene Artikel verlegen.\n"); |
| 1417 | if (!CatchNewsError(NEWSSERVER->RemoveNote(GROUP,num),"Dieser Fehler kann eigentlich nicht auftreten")) |
| 1418 | write("Warnung! Konnte Artikel an alter Position nicht loeschen.\n"); |
| 1419 | else write("Artikel von Rubrik "+GROUP+" entfernt.\n"); |
| 1420 | |
| 1421 | msg[M_MESSAGE]= |
| 1422 | sprintf("%s on=%s ot=%d og=%s\n", |
| 1423 | STATUSESCAPE,msg[M_WRITER],msg[M_TIME],msg[M_BOARD]) |
| 1424 | +msg[M_MESSAGE]; |
| 1425 | |
| 1426 | /* |
| 1427 | expl=explode(msg[M_MESSAGE],"\n"); |
| 1428 | for (i=0;(IS_STATUSLINE(expl[i][0..2]));i++); |
| 1429 | msg[M_MESSAGE]=( (i) ? implode(expl[0..i-1],"\n")+"\n" : "" ) + |
| 1430 | "[Verlegt von "+msg[M_BOARD]+", "+msg[M_WRITER]+", "+ |
| 1431 | dtime(msg[M_TIME])[5..26]+"]:\n"+ |
| 1432 | implode(expl[i..],"\n")+"\n"; |
| 1433 | */ |
| 1434 | |
| 1435 | msg[M_BOARD]=gr; |
| 1436 | NEWSSERVER->WriteNote(msg); |
| 1437 | write("Artikel nach Rubrik "+gr+" verlegt.\n"); |
| 1438 | return 1; |
| 1439 | } |
| 1440 | |
| 1441 | static MoveTrash() |
| 1442 | { |
| 1443 | if (!pointerp(lasttitle)||sizeof(lasttitle)<LAST_SIZEOF) return |
| 1444 | write("Was denn bitte? Du hast noch gar nichts gelesen!\n"),1; |
| 1445 | if (lasttitle[LAST_GROUP]!=GROUP) return |
| 1446 | write("Nix gibts! Du hast die Rubrik gewechselt!\n"),1; |
| 1447 | return MoveMessage(sprintf("artikel %d nach muell",lasttitle[LAST_NR]+1)); |
| 1448 | } |
| 1449 | |
| 1450 | static SaveMessage(str) { |
| 1451 | mixed num; |
| 1452 | mixed *messages; |
| 1453 | |
| 1454 | if (intp(str)) num=str; |
| 1455 | if ((!num && (!str || str=="" || sscanf(str,"artikel %d",num)!=1)) || num<=0) { |
| 1456 | notify_fail("Welchen Artikel willst Du abspeichern?\n"); |
| 1457 | return 0; |
| 1458 | } |
| 1459 | if (!pointerp(messages=NEWSSERVER->GetNotes(GROUP))) |
| 1460 | return notify_fail("Seltsam, die Rubrik '"+GROUP+ |
| 1461 | "' gibt es nicht mehr...\n"), 0; |
| 1462 | num--; |
| 1463 | if (sizeof(messages)<=num) { |
| 1464 | notify_fail("So viele Nachrichten sind da nicht !\n"); |
| 1465 | return 0; |
| 1466 | } |
| 1467 | if(write_file(SAVEMSGPATH(TP),Message2string(num,messages,M2S_REMOTE)+"\n")) |
| 1468 | write(break_string( |
| 1469 | "Inhalt des Artikels wurde nach "+SAVEMSGPATH(TP)+" gespeichert.\n")); |
| 1470 | else |
| 1471 | write(break_string( |
| 1472 | "Fehler beim Schreiben nach "+SAVEMSGPATH(TP)+"!\n")); |
| 1473 | return 1; |
| 1474 | } |
| 1475 | |
| 1476 | |
| 1477 | static MailMessage(str) { |
| 1478 | mixed num,rec,group; |
| 1479 | mixed *messages; |
| 1480 | |
| 1481 | // printf("%O\n",inherit_list(environment(TP))); |
| 1482 | // if (member(query_actions(this_player()),"mail")<0) |
| 1483 | // tut nicht wegen anderer Implemtierung von AddCmd in Raeumen |
| 1484 | |
| 1485 | if (str=="?"||str=="-?") return |
| 1486 | write("Syntax: versende artikel <nr> an <adresse>\n"),1; |
| 1487 | |
| 1488 | str=TP->_unparsed_args(); // wegen Mailadressen |
| 1489 | if (str) str=lower_case(str); |
| 1490 | |
| 1491 | if (!IS_SEER(TP) && !IS_POST(environment(TP))) |
| 1492 | return notify_fail("Du musst in ein Postamt gehen, " |
| 1493 | "um etwas versenden zu koennen.\n"),0; |
| 1494 | |
| 1495 | num=0; |
| 1496 | |
| 1497 | if (!str || (sscanf(str,"artikel %d an %s",num,rec)!=2 && |
| 1498 | sscanf(str,"note %d to %s",num,rec)!=2 && |
| 1499 | sscanf(str,"note to %s",rec)!=1 && |
| 1500 | sscanf(str,"artikel an %s",rec)!=1)){ |
| 1501 | if (!str || str[0..6]=="artikel"||str[0..3]=="note") return |
| 1502 | write("Welchen Artikel willst Du versenden, und wohin?\n"),1; |
| 1503 | else return |
| 1504 | notify_fail("Welchen Artikel willst Du versenden, und wohin?\n"),0; |
| 1505 | } |
| 1506 | if (!num&&(!pointerp(lasttitle)||sizeof(lasttitle)<LAST_SIZEOF)) |
| 1507 | return write("Du hast scheinbar noch nichts gelesen, worauf man sich " |
| 1508 | "beziehen kann.\nGib notfalls die Nummer des Artikels an.\n"),1; |
| 1509 | |
| 1510 | // printf("lasttitle= %O\nnum=%d\n",lasttitle,num); |
| 1511 | |
| 1512 | if (!pointerp(messages= |
| 1513 | NEWSSERVER->GetNotes(group=(num?GROUP:lasttitle[LAST_GROUP])))) |
| 1514 | return notify_fail("Seltsam, die Rubrik gibt es nicht mehr...\n"), 0; |
| 1515 | |
| 1516 | if (!pointerp(messages)||!sizeof(messages)) |
| 1517 | return write("Die Rubrik "+group+" ist leer.\n"),1; |
| 1518 | if (num<0||sizeof(messages)<num) return |
| 1519 | write("Einen Artikel mit Nummer "+num+" gibt es in Rubrik "+group+ |
| 1520 | " nicht!\n"),1; |
| 1521 | |
| 1522 | if (num) num--; |
| 1523 | else { |
| 1524 | int h; |
| 1525 | num=-1; |
| 1526 | if (pointerp(messages)) { |
| 1527 | for (h=sizeof(messages)-1; |
| 1528 | (h>=0 && messages[h][M_TIME]>=lasttitle[LAST_TIME]);h--) |
| 1529 | if (messages[h][M_TIME]==lasttitle[LAST_TIME] && |
| 1530 | lower_case(messages[h][M_WRITER])== |
| 1531 | lower_case(lasttitle[LAST_WRITER])) |
| 1532 | num=h; |
| 1533 | } |
| 1534 | if (num<0) |
| 1535 | return notify_fail("Konnte Artikel nicht wiederfinden, " |
| 1536 | "bitte gib die Nummer an.\n"),0; |
| 1537 | } |
| 1538 | MAILER->do_mail( rec, |
| 1539 | "MPA: "+messages[num][M_TITLE]+" ("+messages[num][M_WRITER]+")", |
| 1540 | Message2string(num,messages,M2S_REMOTE,group)+"\n"); |
| 1541 | return 1; |
| 1542 | } |
| 1543 | |
| 1544 | |
| 1545 | |
| 1546 | HelpPage(str) { |
| 1547 | if (str!="mpa"&&str!="zeitung") return 0; |
| 1548 | this_player()->More(read_file(HELPPAGE)+ |
| 1549 | (IS_LEARNER(TP) ? read_file(WIZHELPPAGE) : "")); |
| 1550 | return 1; |
| 1551 | } |
| 1552 | |
| 1553 | /*--------------------------------------------------------------------------*/ |
| 1554 | |
| 1555 | protected void NotifyMove(object dest, object oldenv, int method) { |
| 1556 | ::NotifyMove(dest, oldenv, method); |
| 1557 | |
| 1558 | // P_READ_NEWS aus dem Spieler holen. |
| 1559 | if (objectp(environment()) && query_once_interactive(environment())) { |
| 1560 | read_until=environment()->QueryProp(P_READ_NEWS); |
| 1561 | } |
| 1562 | |
| 1563 | if (!mappingp(read_until) || !sizeof(read_until)) |
| 1564 | InitialSubscriptions(); |
| 1565 | } |
| 1566 | |
| 1567 | int GetTID(mixed message) { |
| 1568 | string dummy; |
| 1569 | int tid; |
| 1570 | return (sscanf(message[M_MESSAGE],"%s" STATUSESCAPE " tid=%d",dummy,tid)==2) |
| 1571 | ? tid : message[M_TIME]; |
| 1572 | } |
| 1573 | |