blob: bb577176efcd987a1e2b4ec0d0ab1540f6577278 [file] [log] [blame]
Zesstra0caa8e42020-08-11 22:51:59 +02001// /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 ]) */
34private 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
57public 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
104protected 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.
116visible 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