blob: 7e76a11a2731e1925ae8855b08c844aebc225502 [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001// MorgenGrauen MUDlib
2//
3// secure/master/destruct.inc -- module of the master object: stuff for destruct.
4//
5// $Id: master.c 7041 2008-10-13 18:18:27Z Zesstra $
6
7#include "/sys/object_info.h"
8
9// privilegierte Objekte, die das destruct() abbrechen duerfen (root objekte
10// duerfen auch ohne, dass sie in dieser Liste erfasst sind):
11private nosave string *deny_destruct_list = ({
12 "/obj/shut", "/room/void", "/room/netztot", "/room/jail" });
13
14// Helferfunktion fuer prepare_destruct()
15private void recursive_remove(object ob, int immediate_destruct) {
16
17 if (efun::object_info(ob, OI_ONCE_INTERACTIVE)) {
18 // Spieler werden ins Void bewegt.
19 int res;
20 tell_object(ob, "Ploetzlich loest sich deine Welt in ihre " +
21 "Bestandteile auf. Zum Glueck wirst\nDu irgendwo " +
22 "hin geschleudert ...\n");
23 // wenn Bewegung buggt oder nicht funktioniert und ob noch existiert,
24 // rekursiv zerstoeren.
25 object oldenv=environment(ob);
26 if ( (catch(res=(int)ob->move("/room/void",M_TPORT|M_NOCHECK,0,"faellt");
27 publish) || (ob && environment(ob) == oldenv) )
28 && ob) {
29 // Spieler speichern, dann erst Inventar entleeren, dann remove() und
30 // und destruct() anwenden.
31 catch(ob->save_me(1); publish);
32 filter(all_inventory(ob), #'recursive_remove, immediate_destruct);
33 if (!immediate_destruct)
34 catch(ob->remove(0);publish);
35 if (ob)
36 destruct(ob);
37 }
38 }
39 else {
40 // kein Spieler. Rekursiv entfernen. Hierbei _zuerst_ rekursiv das
41 // Inventar entfernen und dann ob selber, damit nicht erst das Inventar in
42 // das Environment bewegt wird (soll ja eh zerstoert werden).
43 filter(all_inventory(ob), #'recursive_remove, immediate_destruct);
44 // ggf. zuerst remove versuchen
45 if (!immediate_destruct)
46 catch(ob->remove(1);publish);
47 if (ob)
48 destruct(ob);
49 }
50}
51
52// Zerstoerung von ob vorbereiten
53protected mixed prepare_destruct(object ob)
54{
55 object old_env,env,item;
56 mixed res;
57
58 // zuerst das notify_destruct() rufen und ggf. abbrechen, falls ob
59 // privilegiert ist.
60 catch(res = (mixed)ob->NotifyDestruct(previous_object()); publish);
61 if (res &&
62 (getuid(ob) == ROOTID ||
63 (IS_ARCH(ob)) ||
64 member(deny_destruct_list, object_name(ob)) >= 0)) {
65 if (stringp(res) && sizeof(res))
66 return res;
67 else
68 return sprintf("%O verweigert die Zerstoerung mittels destruct(). "
69 "Fehlende Rechte von %O?\n",ob, previous_object());
70 }
71
72 env = environment(ob);
73
74 // Objekt hat kein Env: Alles zerstoeren, Spieler ins Void
75 if (!env) {
76 filter(all_inventory(ob), #'recursive_remove, 1);
77 }
78 else {
79 // Ansonsten alles ins Environment
80 foreach(item : all_inventory(ob))
81 {
82 old_env=environment(item);
83 // M_MOVE_ALL, falls item nen Unitobjekt ist. Sonst clonen die u.U. noch
84 // wieder nen neues Objekt im alten Env.
85 if(catch(item->move(env, M_NOCHECK|M_MOVE_ALL);publish))
86 recursive_remove(item, 1);
87 else if (item && environment(item) == old_env)
88 recursive_remove(item, 1);
89 }
90 }
91
92 return 0; // Erfolg
93}
94
95// Anmerkung: liefert 0 zurueck, wenn die sefuns gerade geladen werden.
96string NotifyDestruct(object caller) {
97 // Nicht jeder Magier muss den Master entsorgen koennen.
98 if ((caller != this_object() &&
99 call_sefun("secure_level") < ARCH_LVL)
100 || call_sefun("process_call") ) {
101 return "Du darfst den Mudlib-Master nicht zerstoeren!\n";
102 }
103 return 0;
104}
105