Zesstra | 0caa8e4 | 2020-08-11 22:51:59 +0200 | [diff] [blame] | 1 | // /std/channel_supervisor.c |
| 2 | // |
| 3 | // Der Standard-Supervisor fuer Ebenen. Wird genutzt vom channeld fuer die |
| 4 | // Ebenen, die der verwaltet. |
| 5 | |
| 6 | #pragma strict_types,save_types, rtt_checks |
| 7 | #pragma no_shadow, no_clone |
| 8 | |
| 9 | #include <wizlevels.h> |
| 10 | #include "/p/daemon/channel.h" |
| 11 | #include <living/description.h> |
| 12 | |
| 13 | // Indizes fuer Zugriffe auf das Mapping <admin>. |
| 14 | #define RECV 0 |
| 15 | #define SEND 1 |
| 16 | #define FLAG 2 |
| 17 | |
| 18 | // Ebenenflags, gespeichert in admin[ch, FLAG] |
| 19 | // F_WIZARD kennzeichnet reine Magierebenen |
| 20 | #define F_WIZARD 1 |
| 21 | // Ebenen, auf denen keine Gaeste erlaubt sind, sind mit F_NOGUEST markiert. |
| 22 | #define F_NOGUEST 2 |
| 23 | |
| 24 | /* Speichert Sende- und Empfangslevel sowie Flags zu den einzelnen Channeln. |
| 25 | * Diese werden aber nur ausgewertet, wenn der Channeld die Rechtepruefung |
| 26 | * fuer die jeweilige Ebene macht, d.h. in der Praxis bei Ebenen, bei denen |
| 27 | * der CHANNELD der Supervisor ist. |
| 28 | * Deswegen sind diese Daten auch nicht in der struct (<channel_s>) drin. |
| 29 | * Wird beim Laden des Masters via create() -> initalize() -> setup() mit den |
| 30 | * Daten aus dem Init-File ./channeld.init befuellt. |
| 31 | mapping admin = ([ string channel_name : int RECV_LVL, |
| 32 | int SEND_LVL, |
| 33 | int FLAG ]) */ |
| 34 | private mapping admin = m_allocate(0, 3); |
| 35 | |
| 36 | // check_ch_access() prueft die Zugriffsberechtigungen auf Ebenen. |
| 37 | // |
| 38 | // Gibt 1 zurueck, wenn Aktion erlaubt, 0 sonst. |
| 39 | // Wird von access() gerufen; access() gibt das Ergebnis von |
| 40 | // check_ch_access() zurueck. |
| 41 | // |
| 42 | // Verlassen (C_LEAVE) ist immer erlaubt. Die anderen Aktionen sind in zwei |
| 43 | // Gruppen eingeteilt: |
| 44 | // 1) RECV. Die Aktionen dieser Gruppe sind Suchen (C_FIND), Auflisten |
| 45 | // (C_LIST) und Betreten (C_JOIN). |
| 46 | // 2) SEND. Die Aktion dieser Gruppe ist zur Zeit nur Senden (C_SEND). |
| 47 | // |
| 48 | // Aktionen werden zugelassen, wenn Spieler/MagierLevel groesser ist als die |
| 49 | // fuer die jeweilige Aktionsgruppe RECV oder SEND festgelegte Stufe. |
| 50 | // Handelt es sich um eine Magierebene (F_WIZARD), muss die Magierstufe |
| 51 | // des Spielers groesser sein als die Mindeststufe der Ebene. Ansonsten |
| 52 | // wird gegen den Spielerlevel geprueft. |
| 53 | // |
| 54 | // Wenn RECV_LVL oder SEND_LVL auf -1 gesetzt ist, sind die Aktionen der |
| 55 | // jeweiligen Gruppen komplett geblockt. |
| 56 | |
| 57 | public int check_ch_access(string ch, object pl, string cmd) |
| 58 | { |
| 59 | // <pl> ist Gast, es sind aber keine Gaeste zugelassen? Koennen wir |
| 60 | // direkt ablehnen. |
| 61 | if ((admin[ch, FLAG] & F_NOGUEST) && ({int})pl->QueryGuest()) |
| 62 | return 0; |
| 63 | |
| 64 | // Ebenso auf Magier- oder Seherebenen, wenn ein Spieler anfragt, der |
| 65 | // noch kein Seher ist. |
| 66 | if ((admin[ch, FLAG] & F_WIZARD) && query_wiz_level(pl) < SEER_LVL) |
| 67 | return 0; |
| 68 | |
| 69 | // Ebene ist Magierebene? Dann werden alle Stufenlimits gegen Magierlevel |
| 70 | // geprueft, ansonsten gegen Spielerlevel. |
| 71 | int level = (admin[ch, FLAG] & F_WIZARD |
| 72 | ? query_wiz_level(pl) |
| 73 | : ({int})pl->QueryProp(P_LEVEL)); |
| 74 | |
| 75 | switch (cmd) |
| 76 | { |
| 77 | case C_FIND: |
| 78 | case C_LIST: |
| 79 | case C_JOIN: |
| 80 | if (admin[ch, RECV] == -1) |
| 81 | return 0; |
| 82 | if (admin[ch, RECV] <= level) |
| 83 | return 1; |
| 84 | break; |
| 85 | |
| 86 | case C_SEND: |
| 87 | if (admin[ch, SEND] == -1) |
| 88 | return 0; |
| 89 | if (admin[ch, SEND] <= level) |
| 90 | return 1; |
| 91 | break; |
| 92 | |
| 93 | // Verlassen ist immer erlaubt |
| 94 | case C_LEAVE: |
| 95 | return 1; |
| 96 | |
| 97 | default: |
| 98 | break; |
| 99 | } |
| 100 | return 0; |
| 101 | } |
| 102 | |
| 103 | // ggf. zum ueberschreiben |
| 104 | protected int ch_caller_allowed(object caller) |
| 105 | { |
| 106 | if (caller == find_object(CHMASTER)) |
| 107 | return 1; |
| 108 | return 0; |
| 109 | } |
| 110 | |
| 111 | // stores the read and write levels and flags for a channel for |
| 112 | // usage in check_ch_access(). By default it is called by channeld::setup() |
| 113 | // during setup of a default channel in the supervisor configured for the |
| 114 | // channel. |
| 115 | // recv and send are minimum levels, flag is a combination of the F_* above. |
| 116 | visible void ch_supervisor_setup(string chname, int recv, int send, int flag) |
| 117 | { |
| 118 | if (!extern_call() || ch_caller_allowed(previous_object())) |
| 119 | { |
| 120 | admin[chname, FLAG] = flag; |
| 121 | admin[chname, SEND] = send; |
| 122 | admin[chname, RECV] = recv; |
| 123 | } |
| 124 | } |
| 125 | |