blob: 82ec5e371216b3a7bf97fbcf7a7d41f968420ab8 [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001// MorgenGrauen MUDlib
2//
3// master/misc.c -- Diverses: (T)Banish, Projektverwaltung, Levelaufstieg, ...
4//
5// $Id: misc.c 9467 2016-02-19 19:48:24Z Zesstra $
6
Zesstra3bee4f92019-11-28 20:17:36 +01007#pragma strict_types,rtt_checks,pedantic
MG Mud User88f12472016-06-24 23:31:02 +02008
9#include "/sys/functionlist.h"
10#include "/sys/lpctypes.h"
11#include "/sys/object_info.h"
12#include "/sys/interactive_info.h"
Bugfix05c09d72017-02-14 21:26:20 +010013#include "/sys/files.h"
MG Mud User88f12472016-06-24 23:31:02 +020014
15#include "/secure/master.h"
16#include "/mail/post.h"
17#include "/sys/thing/language.h"
18#include "/sys/thing/description.h"
Zesstra86607bb2017-06-17 19:02:40 +020019#include "/sys/configuration.h"
MG Mud User88f12472016-06-24 23:31:02 +020020
21// Fuer CIDR-Notatio im sbanish
22#include "/secure/master/cidr.c"
23
24static mixed *banished;
25static mapping tbanished, sbanished;
26static string *deputies;
27
28// TODO: muss ggf. Fakeobjekt erzeugen+uebergeben, wenn sender kein object
29protected void send_channel_msg(string channel,mixed sendername,string msg)
30{
31 object sender;
32 if (objectp(sendername))
33 sender=sendername;
34 else
35 {
36 // wenn kein Objekt uebergeben, erstmal schauen, ob ein Spielerobject
37 // existiert... Wenn ja, das nehmen.
38 sender = call_sefun("find_player", sendername)
39 || call_sefun("find_netdead", sendername);
40 if (!objectp(sender))
41 {
42 // sonst faken wir eins. *seufz*
43 sender=clone_object("/p/daemon/namefake");
44 sender->SetProp(P_NAME, sendername);
45 sender->SetProp(P_ARTICLE,0);
46 // Dieses Objekt zerstoert sich nach 3s automatisch.
47 }
48 }
49 CHMASTER->send(channel, sender, msg);
50}
51
52static string *explode_files(string file) {
53 string data;
54 mixed *exploded;
55 int i;
56
57 data=read_file(file);
58 if (!data || !stringp(data) || data == "") return ({});
59 exploded = efun::explode(data,"\n");
60 for (i=sizeof(exploded);i--;)
61 if (!stringp(exploded[i]) || exploded[i]=="" || exploded[i][0]=='#')
62 exploded[i]=0;
63 exploded-=({0});
Zesstrad77ab422019-09-27 17:39:27 +020064 debug_message(
65 sprintf("%-30s: %3d Objekt%s\n",file,i=sizeof(exploded),(i==1?"":"e")),
66 DMSG_STAMP);
MG Mud User88f12472016-06-24 23:31:02 +020067 return exploded;
68}
69
70void UpdateTBanish();
71
72mixed QueryBanished(string str){
73 int i;
74
75 if (!str) return 0;
76 if (!pointerp(banished)) return 0;
77 for (i=sizeof(banished)-1;i>=0;i--)
78 if (sizeof(regexp(({str}),"^"+banished[i][0]+"$")))
79 {
80 if (!banished[i][1] || banished[i][1]=="")
81 return "Dieser Name ist gesperrt.";
82 else
83 return banished[i][1];
84 }
85 return 0;
86}
87
88mixed QueryTBanished(string str) {
89 int i;
90
91 if (!str || !mappingp(tbanished) || !(i=tbanished[str]))
92 return 0;
93
94 if (i == -1 || i > time())
95 return sprintf("Es gibt schon einen Spieler diesen Namens.\n"
96 +"Allerdings kann er/sie erst am %s wieder ins Mud kommen.\n",
97 (i == -1 ? "St. Nimmerleinstag" :
98 call_sefun("dtime",i)[0..16]));
99
100// Ansonsten: die Zeit ist abgelaufen, Spieler darf wieder...
101 m_delete(tbanished, str);
102 UpdateTBanish();
103 return 0;
104}
105
106void ReloadBanishFile(){
107 int i, t;
108 string s1, s2, *s;
109
110 banished = efun::explode( read_file("/secure/BANISH") || "", "\n" );
111 banished = banished - ({""});
112 for ( i = sizeof(banished); i--; ){
113 s = efun::explode( banished[i], " " );
114 s1 = s[0];
115 s2 = implode( s[1..], " " );
116 banished[i] = ({ s1, s2 });
117 }
118
119 if ( !mappingp(tbanished) ){
120 tbanished = ([]);
121
122 s = efun::explode( read_file("/secure/TBANISH") || "", "\n" );
123 s -= ({""});
124
125 for ( i = sizeof(s); i--; ){
126 sscanf( s[i], "%s:%d", s1, t );
127 tbanished += ([ s1 : t ]);
128 }
129 }
130
131 if ( !mappingp(sbanished) ){
132 sbanished = m_allocate(3, 2);
133
134 s = efun::explode( read_file("/secure/SITEBANISH") || "", "\n" );
135 s -= ({""});
136
137 for ( i = sizeof(s); i--; ) {
138 int int_ip;
139 sscanf( s[i], "%s:%d:%s", s1, t, s2 );
140 int_ip = IPv4_addr2int(s1);
141 m_add(sbanished, int_ip, t, s2);
142 }
143 }
144}
145
146int IsDeputy(mixed name)
147{
148 if ( IS_ARCH(name) )
149 return 1;
150
151 if ( objectp(name) )
152 name = getuid(name);
153
154 if ( member( deputies || ({}), name ) >= 0 )
155 return 1;
156
157 return 0;
158}
159
160
161varargs void BanishName( string name, string reason, int force )
162{
163 string *names;
164 int i;
165
166 if ( PO != TO && call_sefun("secure_level") < LORD_LVL
167 && !IsDeputy( call_sefun("secure_euid") ) )
168 return;
169
170 if ( !stringp(name) || !sizeof(name) )
171 return;
172
173 name = lower_case(name);
174
175 if ( !reason || !stringp(reason) )
176 reason = "";
177
178 if ( QueryBanished(name) && lower_case(reason) != "loeschen" ){
179 write("Der Name ist schon gebannt.\n");
180 return;
181 }
182
Zesstra85576452017-01-30 15:43:21 +0100183 if ( !force && find_userinfo(name))
184 {
MG Mud User88f12472016-06-24 23:31:02 +0200185 write("Es existiert bereits ein Spieler dieses Namens.\n");
186 return;
187 }
188
189/* if (!("/secure/login"->valid_name(name))) return;*/
190 if ( lower_case(reason) != "loeschen" ){
191 names = ({ name + " " + reason });
192
193 for ( i = sizeof(banished); i--; )
194 names += ({ banished[i][0] + " " + banished[i][1] });
195 }
196 else{
197 names = ({});
198
199 for ( i = sizeof(banished); i--; )
200 if ( banished[i][0] != name )
201 names += ({ banished[i][0] + " " + banished[i][1] });
202 }
203
204 names = sort_array( names, #'> );
205 rm("/secure/BANISH");
206 write_file( "/secure/BANISH", implode(names, "\n") );
207 write( "Okay, '"+capitalize(name)+"' ist jetzt "+
208 (lower_case(reason) == "loeschen" ? "nicht mehr " : "")+"gebanisht.\n" );
209 ReloadBanishFile();
210}
211
212void UpdateTBanish()
213{
214 int i;
215 string *names;
216
217 for (i=sizeof(names = sort_array(m_indices(tbanished), #'</*'*/))-1;i>=0;i--)
218 names[i] = sprintf("%s:%d", names[i], tbanished[names[i]]);
219
220 rm("/secure/TBANISH");
221 write_file("/secure/TBANISH", implode(names, "\n"));
222}
223
224void UpdateSBanish()
225{
226 int i;
227 mapping lines = m_allocate(sizeof(sbanished),0);
228
229 foreach(int ip, int tstamp, string user : sbanished) {
230 m_add(lines, sprintf("%s:%d:%s",
231 IPv4_int2addr(ip), tstamp, user));
232 }
233
234 write_file( "/secure/SITEBANISH",
235 implode( sort_array (m_indices(lines), #'<), "\n" ), 1);
236}
237
238int TBanishName(string name, int days)
239{
240 int t;
241
242 if ( (getuid(TI) != name) &&
243 !IsDeputy( call_sefun("secure_euid") ) )
244 return 0;
245
246 if (days && QueryTBanished(name)){
247 write("Der Name ist schon gebannt.\n");
248 return 0;
249 }
250
Zesstra85576452017-01-30 15:43:21 +0100251 if (!find_userinfo(name))
252 {
MG Mud User88f12472016-06-24 23:31:02 +0200253 write("Es existiert kein Spieler dieses Namens!\n");
254 return 0;
255 }
256
257 if (!days && member(tbanished, name))
258 m_delete(tbanished, name);
259 else {
260 if (!mappingp(tbanished))
261 tbanished = ([]);
262 if (days <= -1)
263 t = -1;
264 else
265 t = (time()/86400)*86400 + days*86400;
266 tbanished += ([ name : t ]);
267 }
268
269 UpdateTBanish();
270 return 1;
271}
272
273
274mixed QuerySBanished( string ip )
275{
276 int save_me, site;
277 string banished_meldung =
278 "\nSorry, von Deiner Adresse kamen ein paar Idioten, die "
279 "ausschliesslich\nAerger machen wollten. Deshalb haben wir "
280 "die Moeglichkeit,\neinfach neue Charaktere "
281 "anzulegen, kurzzeitig fuer diese Adresse gesperrt.\n\n"
282 "Falls Du bei uns spielen moechtest, schicke bitte eine Email "
283 "an\n\n mud@mg.mud.de\n\n"
284 "mit der Bitte, einen Charakter fuer Dich anzulegen.\n" ;
285
286 if ( !ip || !stringp(ip) || !mappingp(sbanished) || !sizeof(sbanished) )
287 return 0;
288
289 foreach(site, int tstamp: sbanished) {
290 if ( tstamp > 0 && tstamp < time() ) {
291 m_delete( sbanished, site );
292 save_me=1;
293 }
294 }
295 if (save_me)
296 UpdateSBanish();
297
298 if ( !sizeof(sbanished) )
299 return 0;
300
301 site = IPv4_addr2int(ip);
302 if (!site)
303 return 0;
304 // direkt drin?
305 if (member(sbanished, site))
306 return banished_meldung;
307 // oder Netz dieser IP gesperrt?
308 foreach(int locked_site : sbanished) {
309 if ((locked_site & site) == locked_site)
310 return banished_meldung;
311 }
312
313 return 0;
314}
315
316
317private int _sbanished_by( int key, string name )
318{
319 return sbanished[key, 1] == name;
320}
321
322
323mixed SiteBanish( string ip, int days )
324{
325 string *s, tmp, euid;
326 int t, level;
327
328 euid = call_sefun("secure_euid");
329 level = call_sefun("secure_level");
330
331 // Unter L26 gibt's gar nix.
332 if ( level <= DOMAINMEMBER_LVL )
333 return -1;
334
335 // Die Liste der gesperrten IPs anschauen darf jeder ab L26.
336 if ( !ip && !days )
337 return copy(sbanished);
338
339
340 if ( !stringp(ip) || !intp(days) )
341 return 0;
342
343 if ( days && QuerySBanished(ip) ){
344 write( "Diese Adresse ist schon gebannt.\n" );
345 return 0;
346 }
347
348 if ( !days ) {
349 int int_ip = IPv4_addr2int(ip);
350
351 if( member(sbanished, int_ip) ){
352 // Fremde Sitebanishs duerfen nur Deputies loeschen.
353 if ( sbanished[int_ip, 1] != euid && !IsDeputy(euid) )
354 return -1;
355
356 call_sefun("log_file", "ARCH/SBANISH",
357 sprintf( "%s: %s hebt die Sperrung der Adresse %s von %s "
358 + "auf.\n",
359 ctime(time()), capitalize(euid), ip,
360 capitalize(sbanished[int_ip, 1]) ) );
361
362 m_delete( sbanished, int_ip );
363 }
364 else
365 return 0;
366 }
367 else {
368 // Alles, was nicht Deputy ist, darf nur fuer einen Tag sbanishen.
369 if ( days != 1 && !IsDeputy(euid) )
370 return -1;
371
372 // Nur Deputies duerfen mehr als 10 Sperrungen vornehmen.
373 if ( sizeof(filter_indices(sbanished, #'_sbanished_by, euid)) >= 10
374 && !IsDeputy(euid) )
375 return -2;
376
377 int int_ip = IPv4_addr2int(ip);
378
379 if(!int_ip) {
380 write( "Ungueltige Adresse!\n" );
381 return 0;
382 }
383
384 // L26 duerfen exakt eine IP sperren, RMs ganze Class C-Subnetze
385 // und Deputies auch Class B-Subnetze.
386 int nsize=IPv4_net_size(ip);
387 if ( nsize > 1 && level < LORD_LVL
388 || nsize > 255 && !IsDeputy(euid) )
389 return -1;
390
391 if ( !mappingp(sbanished) )
392 sbanished = m_allocate(1, 2);
393
394 if ( days < 0 )
395 t = -1;
396 else
397 t = (time() / 86400) * 86400 + days * 86400;
398
399 m_add(sbanished, int_ip, t, euid);
400
401 call_sefun("log_file", "ARCH/SBANISH",
402 sprintf( "%s: %s sperrt die Adresse %s %s.\n",
403 ctime(time()), capitalize(euid),
404 ip,
405 days > 0 ? (days > 1 ? "fuer " + days + " Tage"
406 : "fuer einen Tag")
407 : "bis zum St. Nimmerleinstag" ) );
408 }
409
410 UpdateSBanish();
411 return 1;
412}
413
414static void CheckDeputyRights()
415{
416 object ob;
417 mixed *ginfo;
418
419 // Lese- und Schreibberechtigungen fuer die Rubrik 'polizei' setzen
Zesstrad872d182019-11-28 20:13:02 +0100420 ob = load_object("secure/news");
421 ginfo = (({mixed*})ob->GetGroup("polizei"))[5..6];
MG Mud User88f12472016-06-24 23:31:02 +0200422 ob->RemoveAllowed( "polizei", 0, ginfo[0], ginfo[1] );
423 ob->AddAllowed( "polizei", 0, deputies, deputies );
424 LoadDeputyFileList();
425}
426
427int ReloadDeputyFile()
428{
429 deputies = efun::explode( read_file("/secure/DEPUTIES") || "", "\n" );
430 deputies -= ({""});
431 deputies = map( deputies, #'lower_case/*'*/ );
432 call_out( "CheckDeputyRights", 2 );
433 return(1);
434}
435
436
437static int create_home(string owner, int level)
438{
439 string def_castle;
440 string dest, castle, wizard;
441 object player;
442 string *domains;
443 int i;
444
445 player = call_sefun("find_player",owner);
446 if (!player)
447 return -5;
448 domains=get_domain_homes(owner);
449 if (!sizeof(domains) && level >= DOMAINMEMBER_LVL)
450 {
451 tell_object(player,"Du gehoerst noch keiner Region an !\n");
452 return -6;
453 }
454 tell_object(player,"Du bist Mitarbeiter der folgenden Regionen:\n");
455 for (i=0;i<sizeof(domains);i++)
456 {
457 if (i) tell_object(player,", ");
458 tell_object(player,domains[i]);
459 }
460 tell_object(player,".\n");
461 update_wiz_level(owner, level);
462 wizard = "/players/" + owner;
463 castle = "/players/" + owner + "/workroom.c";
464 if (file_size(wizard) == -1) {
465 tell_object(player, "Verzeichnis " + wizard + " angelegt\n");
466 mkdir(wizard);
467 }
468 dest = object_name(environment(player));
469 def_castle = read_file("/std/def_workroom.c");
470 if (file_size(castle) > 0) {
471 tell_object(player, "Du HATTEST ja schon ein Arbeitszimmer !\n");
472 } else {
473 if (write_file(castle, def_castle))
474 {
475 tell_object(player, "Arbeitszimmer " + castle + " erzeugt.\n");
476 // Arbeitszimmer als Home setzen
477 player->SetProp(P_START_HOME,castle[0..<3]);
478 }
479 else
480 tell_object(player, "Arbeitszimmer konnte nicht erzeugt werden !\n");
481 }
482 return 1;
483}
484
485// Sendet dem befoerderten Magier eine Hilfemail zu.
486protected void SendWizardHelpMail(string name, int level) {
487
488 object pl=call_sefun("find_player",name);
489 if (!objectp(pl)) return;
490
491 string file=sprintf("%sinfo_ml%d", WIZ_HELP_MAIL_DIR, level);
492 // wenn kein Hilfetext fuer den Level da ist: raus
493 if (file_size(file) <= 0)
494 return;
495
496 string subject = read_file(file,1,1);
497 string text = call_sefun("replace_personal",
498 read_file(file,2), ({pl}));
499
500 mixed mail = ({"Merlin", "<Master>", name, 0, 0, subject,
501 call_sefun("dtime",time()),
502 MUDNAME+time(), text });
503 MAILDEMON->DeliverMail(mail, 0);
504}
505
506int allowed_advance_wizlevel(mixed ob)
507{
508 string what;
509
510 if (objectp(ob) && geteuid(ob)==ROOTID) return 1;
511
512 if (!stringp(ob))
513 what=efun::explode(object_name(ob),"#")[0];
514 else
515 what=ob;
516
517 if (what=="/secure/merlin") return 1;
518
519 return 0;
520}
521
522int advance_wizlevel(string name, int level)
523{
524 int answer;
525 mixed *user;
526
527 if (!allowed_advance_wizlevel(PO))
528 return -1;
529
530 if (level>80) return -2;
531
532 if (!find_userinfo(name)) return -3;
533
534 user=get_full_userinfo(name);
535
536 if (user[USER_LEVEL+1]>level) return -4;
537
538 if (user[USER_LEVEL+1]==level) return 1;
539
540 if (level>=10 && level<20)
541 {
542 update_wiz_level(name, level);
543 SendWizardHelpMail(name, level);
544 return 1;
545 }
546 if (level>=20 && user[USER_LEVEL+1]<21)
547 {
548 answer = create_home(name, level);
549 if ( answer > 0 ) {
550 answer = update_wiz_level(name, level);
551 SendWizardHelpMail(name, level);
552 }
553 return answer;
554 }
555
556 update_wiz_level(name, level);
557 SendWizardHelpMail(name, level);
558
559 return 1;
560}
561
562void restart_heart_beat(object heart_beat)
563{
564 if (heart_beat) heart_beat->_restart_beat();
565}
566
Zesstrad872d182019-11-28 20:13:02 +0100567int renew_player_object(string|object who)
MG Mud User88f12472016-06-24 23:31:02 +0200568{
569 object newob;
570 object *obs, *obs2;
571 mixed err;
572 string ob_name;
573 object *armours, weapon;
574 object tp;
575 int i,active,j;
576
577 if (stringp(who))
578 {
579 who=call_sefun("find_player",who);
580 if (!who)
581 {
582 who=call_sefun("find_netdead",who);
583 if (!who)
584 return -1;
585 }
586 }
587 if (!objectp(who))
588 return -2;
589 if (!object_info(who, OI_ONCE_INTERACTIVE))
590 return -3;
591 if (who->QueryGuest())
592 {
593 printf("Can't renew guests!\n");
594 return -6;
595 }
596 active=interactive(who);
597 printf("OK, renewing %O\n",who);
Zesstra86607bb2017-06-17 19:02:40 +0200598 efun::configure_object(this_object(), OC_EUID, geteuid(who));
MG Mud User88f12472016-06-24 23:31:02 +0200599 err=catch(newob=clone_object(query_player_object(getuid(who))); publish);
Zesstra86607bb2017-06-17 19:02:40 +0200600 efun::configure_object(this_object(), OC_EUID, getuid(TO));
MG Mud User88f12472016-06-24 23:31:02 +0200601 if (err)
602 {
603 printf("%O\n",err);
604 return -4;
605 }
606 if (!newob)
607 return -5;
608 /* Ok, the object is here now ... lets go for it ... */
609 who->save_me(0);
610 /* SSL ip weiterreichen */
611 if( call_sefun("query_ip_number", who) != efun::interactive_info(who,II_IP_NUMBER) )
612 {
613 newob->set_realip( call_sefun("query_ip_number",who) );
614 }
zesstraf06f57a2016-07-06 20:36:05 +0200615 efun::configure_object(who, OC_COMMANDS_ENABLED, 0);
MG Mud User88f12472016-06-24 23:31:02 +0200616 efun::set_this_player(0);
Zesstrad872d182019-11-28 20:13:02 +0100617 armours=({object*})who->QueryProp(P_ARMOURS);
618 weapon=({object})who->QueryProp(P_WEAPON);
MG Mud User88f12472016-06-24 23:31:02 +0200619
620 if ( previous_object() && object_name(previous_object()) == "/secure/merlin" )
621 send_channel_msg("Debug",
622 previous_object(),
623 sprintf("RENEWING: %O %O\n",newob,who));
624 else
625 send_channel_msg("Entwicklung",
626 previous_object(),
627 sprintf("RENEWING: %O %O\n",newob,who));
628
629 ob_name=explode(object_name(newob),"#")[0];
630 if (sizeof(ob_name)>11 && ob_name[0..11]=="/std/shells/")
631 ob_name=ob_name[11..];
Zesstrad872d182019-11-28 20:13:02 +0100632 ob_name=ob_name+":"+getuid(who);
MG Mud User88f12472016-06-24 23:31:02 +0200633 if (active)
634 exec(newob,who);
635 if (active && (interactive(who)||!interactive(newob)))
636 {
637 send_channel_msg("Debug",previous_object(),
638 "ERROR: still active !\n");
639 newob->remove();
640 return 0;
641 }
642// newob->start_player(capitalize(getuid(who)),who->_query_my_ip());
643 funcall(
644 bind_lambda(
645 unbound_lambda( ({'x, 'y}),
646 ({#'call_other/*'*/,
647 newob,
648 "start_player",
649 'x, 'y
650 })
651 ), who
652 ),
653 capitalize(getuid(who)), who->_query_my_ip() );
654
655 newob->move(environment(who),M_TPORT|M_NOCHECK|M_NO_SHOW|M_SILENT
656 |M_NO_ATTACK);
657 obs=all_inventory(who);
658 foreach(object tob: all_inventory(who)) {
659 if (!tob->QueryProp(P_AUTOLOADOBJ))
660 {
661 // kein Autoloader...
662 foreach(object ob: deep_inventory(tob))
663 {
664 // aber enthaltene Autoloader entsorgen...
665 if (ob->QueryProp(P_AUTOLOADOBJ))
666 {
667 catch(ob->remove();publish);
668 if (ob) destruct(ob);
669 }
670 }
671 // objekt ohne die AL bewegen.
672 catch(tob->move(newob,M_NOCHECK);publish);
673 }
674 else {
675 // Inhalt von Autoloadern retten.
676 // neue instanz des ALs im neuen Objekt.
677 object new_al_instance = present_clone(tob, newob);
678 foreach(object ob: deep_inventory(tob)) {
679 if (ob->QueryProp(P_AUTOLOADOBJ)) {
680 // autoloader in Autoloadern zerstoeren...
681 catch(ob->remove(1);publish);
682 if (ob) destruct(ob);
683 }
684 // alle nicht autoloader in die AL-Instanz im neuen Objekt oder
685 // notfalls ins Inv.
686 else {
687 if (objectp(new_al_instance))
688 catch(ob->move(new_al_instance, M_NOCHECK);publish);
689 else
690 catch(ob->move(newob, M_NOCHECK);publish);
691 }
692 }
693 // Autoloader zerstoeren. Wird nicht vom Spielerobjekt im remove()
694 // gemacht, wenn nicht NODROP.
695 catch(tob->remove(1);publish);
696 if (tob) destruct(tob);
697 }
698 }
699 who->remove();
700 if ( objectp(who) )
701 destruct(who);
702 rename_object(newob,ob_name);
703 newob->__reload_explore();
704 tp=this_player();
705 efun::set_this_player(newob);
706 if (objectp(weapon))
707 weapon->DoWield();
708 if (pointerp(armours))
709 for (i=sizeof(armours)-1;i>=0;i--)
710 if (objectp(armours[i]))
711 armours[i]->do_wear("alles");
712 efun::set_this_player(tp);
713 //Rueckgabewert noetig, weil Funktion vom Typ 'int'
714 return(1);
715}
716
717mixed __query_variable(object ob, string var)
718{
719 if (!PO || !IS_ARCH(geteuid(PO)) || !this_interactive() ||
720 !IS_ARCH(this_interactive()) || getuid(ob)==ROOTID )
721 {
722 write("Du bist kein EM oder Gott!\n");
723 return 0;
724 }
725 if (efun::object_info(ob, OI_ONCE_INTERACTIVE) && (PO!=ob) &&
726 (var=="history" || var=="hist2"))
727 send_channel_msg("Snoop", previous_object(),
728 sprintf("%s -> %s (history).",
729 capitalize(getuid(PO)),capitalize(getuid(ob))));
730
731 call_sefun("log_file", "ARCH/QV",
732 sprintf("%s: %O inquires var %s in %O\n",
733 ctime(time()),this_interactive(),var,ob) );
734 mixed res = variable_list(ob, RETURN_FUNCTION_NAME|RETURN_FUNCTION_FLAGS|
735 RETURN_FUNCTION_TYPE|RETURN_VARIABLE_VALUE);
736 int index = member(res,var);
737 if (index > -1)
738 {
739 return ({res[index],res[index+1],res[index+2],res[index+3]});
740 }
741 return 0;
742}
743
Bugfix05c09d72017-02-14 21:26:20 +0100744protected void CreateDataDirectories()
745{
746 if(file_size("/"LIBDATADIR)==FSIZE_NOFILE)
747 {
748 mkdir("/"LIBDATADIR);
749 }
750
751 if(file_size(SAVEPATH)==FSIZE_NOFILE)
752 {
753 mkdir(SAVEPATH);
754 // Die Ordner von a bis z erstellen
755 foreach(int n : 'a'..'z')
756 {
757 mkdir(sprintf(SAVEPATH+"%c",n));
758 }
759 }
760
761 if(file_size(SECURESAVEPATH)==FSIZE_NOFILE)
762 {
763 mkdir("/"LIBDATADIR"/"SECUREDIR);
764 mkdir(SECURESAVEPATH);
765 // Die Ordner von a bis z erstellen
766 foreach(int n : 'a'..'z')
767 {
768 mkdir(sprintf(SECURESAVEPATH+"%c",n));
769 }
770 }
771}