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