blob: fdb36412d42ff86ed8f9eee3dd9d91e411500bb9 [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001// MorgenGrauen MUDlib
2/** \file /file.c
3* Kurzbeschreibung.
4* Langbeschreibung...
5* \author <Autor>
MG Mud User88f12472016-06-24 23:31:02 +02006*/
7#pragma strong_types,save_types,rtt_checks
8#pragma no_clone,no_inherit,no_shadow
9#pragma pedantic, range_check
10
11#include <defines.h>
12#include <events.h>
13#include <wizlevels.h>
14#include <player/base.h>
15#include <userinfo.h>
Zesstra3c093512019-01-07 22:55:26 +010016#include <config.h>
MG Mud User88f12472016-06-24 23:31:02 +020017
Zesstra3c093512019-01-07 22:55:26 +010018#define DBPATH "/"LIBDATADIR"/"SECUREDIR"/ARCH/second.sqlite"
19
MG Mud User88f12472016-06-24 23:31:02 +020020#define ZDEBUG(x) tell_room("/players/zesstra/workroom",\
21 sprintf("second: %O\n",x));
22
23protected void create()
24{
25 seteuid(getuid());
Zesstra3c093512019-01-07 22:55:26 +010026 if (sl_open(DBPATH) != 1)
MG Mud User88f12472016-06-24 23:31:02 +020027 {
28 raise_error("Datenbank konnte nicht geoeffnet werden.\n");
29 }
Zesstradd66c632019-05-06 21:04:16 +020030 sl_exec("PRAGMA foreign_keys = ON; PRAGMA temp_store = 2; ");
MG Mud User88f12472016-06-24 23:31:02 +020031 // Tabellen und Indices anlegen, falls die nicht existieren.
32 sl_exec("CREATE TABLE IF NOT EXISTS zweities(uuid TEXT PRIMARY KEY ASC, "
33 "name TEXT NOT NULL, erstieuuid TEXT NOT NULL, "
34 "erstie TEXT NOT NULL);");
35 sl_exec("CREATE TABLE IF NOT EXISTS testies(name TEXT PRIMARY KEY ASC, "
36 "magier TEXT NOT NULL, "
37 "lastlogin DATETIME DEFAULT current_timestamp);");
38 sl_exec("CREATE TABLE IF NOT EXISTS familien("
39 "erstieuuid TEXT PRIMARY KEY ASC, familie TEXT NOT NULL);");
Zesstradd66c632019-05-06 21:04:16 +020040 sl_exec("CREATE TABLE IF NOT EXISTS aliases("
41 "familie TEXT NOT NULL, "
42 "verb TEXT NOT NULL, alias TEXT NOT NULL,"
43 "UNIQUE(familie,verb));");
MG Mud User88f12472016-06-24 23:31:02 +020044 sl_exec("CREATE INDEX IF NOT EXISTS idx_erstie ON zweities(erstie);");
45 sl_exec("CREATE INDEX IF NOT EXISTS idx_name ON zweities(name);");
46 sl_exec("CREATE INDEX IF NOT EXISTS idx_magiername ON testies(magier);");
47 sl_exec("CREATE INDEX IF NOT EXISTS idx_familie ON familien(familie);");
Zesstradd66c632019-05-06 21:04:16 +020048 sl_exec("CREATE INDEX IF NOT EXISTS idx_aliasverb ON aliases(verb);");
49 sl_exec("CREATE INDEX IF NOT EXISTS idx_aliasfamilie ON aliases(familie);");
MG Mud User88f12472016-06-24 23:31:02 +020050
51 // Login-Event abonnieren
52 if (EVENTD->RegisterEvent(EVT_LIB_LOGIN,
53 "listen", this_object()) <= 0)
54 {
55 raise_error("Loginevent konnte nicht abonniert werden.\n");
56 }
57}
58
59public void listen(string eid, object trigob, mixed data)
60{
61 if (previous_object() != find_object(EVENTD)
62 || !trigob
63 || !query_once_interactive(trigob)
64 || IS_LEARNER(trigob))
65 return;
66 // wenn testie, wird der Char als Testie behandelt und P_SECOND ignoriert.
67 mixed testie=trigob->QueryProp(P_TESTPLAYER);
68 if (stringp(testie)
69 && strstr(testie,"Gilde")==-1)
70 {
Zesstrac5cbd082019-01-07 23:06:13 +010071 testie=lower_case(testie);
72 mixed plinfo = master()->get_userinfo(testie);
MG Mud User88f12472016-06-24 23:31:02 +020073 if (pointerp(plinfo))
74 {
75 sl_exec("INSERT OR REPLACE INTO testies(name, magier, lastlogin) "
76 "VALUES(?1,?2,?3);",
77 trigob->query_real_name(),
78 testie, time());
79 return; // zweitie jetzt auf jeden Fall ignorieren.
80 }
81 }
82
83 mixed erstie=trigob->QueryProp(P_SECOND);
84 if (stringp(erstie))
85 {
Zesstrac5cbd082019-01-07 23:06:13 +010086 erstie=lower_case(erstie);
87 mixed plinfo = master()->get_userinfo(erstie);
MG Mud User88f12472016-06-24 23:31:02 +020088 if (pointerp(plinfo))
89 {
90 sl_exec("INSERT OR REPLACE INTO zweities(uuid, name, erstieuuid, erstie) "
91 "VALUES(?1,?2,?3,?4);",
92 getuuid(trigob),
93 trigob->query_real_name(),
94 erstie + "_" + plinfo[USER_CREATION_DATE+1],
95 erstie);
96 }
97 //ZDEBUG(sprintf("%O, %O, %O\n",eid,trigob,data));
98 }
99}
100
101varargs int remove(int silent)
102{
103 EVENTD->UnregisterEvent(EVT_LIB_LOGIN, this_object());
104 sl_close();
105 destruct(ME);
106 return 1;
107}
108
109public mixed sql_query(string query)
110{
111 if (ARCH_SECURITY)
112 return sl_exec(query);
113 return 0;
114}
115
116private string get_erstie_data(string datum, object zweitie)
117{
118 if (!zweitie) return 0;
119 mixed res = sl_exec("SELECT " + datum + " FROM zweities WHERE uuid=?1",
120 getuuid(zweitie));
121 if (sizeof(res))
122 return res[0][0];
123
124 return 0;
125}
126
127public varargs string QueryErstieName(object zweitie)
128{
129 return get_erstie_data("erstie", zweitie || previous_object());
130}
131
132public varargs string QueryErstieUUID(object zweitie)
133{
134 return get_erstie_data("erstieuuid", zweitie || previous_object());
135}
136
137private string* get_zweitie_data(string datum, object erstie)
138{
139 if (!erstie) return 0;
140 mixed tmp = sl_exec("SELECT " + datum + " FROM zweities WHERE erstieuuid=?1",
141 getuuid(erstie));
142 if (sizeof(tmp))
143 {
144 string *res=({});
145 foreach(string *row: tmp)
146 res+=({row[0]});
147 return res;
148 }
149 return 0;
150}
151
152public varargs string* QueryZweities(object erstie)
153{
154 return get_zweitie_data("name", erstie || previous_object());
155}
156
157public varargs string QueryFamilie(object pl)
158{
Zesstrac0b56a32019-01-09 00:23:33 +0100159 if (!pl || !query_once_interactive(pl))
160 return 0;
MG Mud User88f12472016-06-24 23:31:02 +0200161 string erstie = get_erstie_data("erstieuuid",
162 pl || previous_object());
163 // Wenn !erstie, dann ist pl kein Zweitie, also ist er selber erstie
164 erstie ||= getuuid(pl);
165 // jetzt noch gucken, ob ne explizite Familie fuer den erstie erfasst ist.
166 mixed tmp = sl_exec("SELECT familie FROM familien WHERE "
167 "erstieuuid=?1",erstie);
168 if (sizeof(tmp))
169 return tmp[0][0];
170 // wenn nicht, dann ist die Familie die Zweitieuuid
171 return erstie;
172}
173
Zesstra60ec4972019-01-08 21:07:16 +0100174public string SetFamilie(object|string pl, string familie)
175{
176 if (!ARCH_SECURITY)
177 return 0;
178
179 // Wenn Spielerobjekt, UUID ermitteln
180 if (objectp(pl) && query_once_interactive(pl))
181 pl = getuuid(pl);
182
183 sl_exec("INSERT OR REPLACE INTO familien(erstieuuid, familie) "
184 "VALUES(?1, ?2);", pl, familie);
185
186 mixed tmp = sl_exec("SELECT familie FROM familien WHERE "
187 "erstieuuid=?1", pl);
188 if (sizeof(tmp))
189 return tmp[0][0];
190
191 return 0;
192}
193
194public int DeleteFamilie(object|string pl)
195{
196 if (!ARCH_SECURITY)
197 return 0;
198
199 // Wenn Spielerobjekt, UUID ermitteln
200 if (objectp(pl) && query_once_interactive(pl))
201 pl = getuuid(pl);
202
203 sl_exec("DELETE FROM familien WHERE erstieuuid=?1;",
204 pl);
205
206 mixed tmp = sl_exec("SELECT familie FROM familien WHERE "
207 "erstieuuid=?1", pl);
208 if (sizeof(tmp))
209 return -1;
210
211 return 1;
212}
213
Zesstrab9dc01d2019-01-08 21:22:21 +0100214public int DeleteZweitie(object|string pl)
215{
216 if (!ARCH_SECURITY)
217 return 0;
218
219 // Wenn Spielerobjekt, UUID ermitteln
220 if (objectp(pl) && query_once_interactive(pl))
221 pl = getuuid(pl);
222
223 sl_exec("DELETE FROM zweities WHERE uuid=?1;", pl);
224
225 mixed tmp = sl_exec("SELECT name FROM zweities WHERE "
226 "uuid=?1", pl);
227 if (sizeof(tmp))
228 return -1;
229
230 return 1;
231}
232
233public int DeleteTestie(object|string pl)
234{
235 if (!ARCH_SECURITY)
236 return 0;
237
238 // Wenn Spielerobjekt, UID ermitteln
239 if (objectp(pl) && query_once_interactive(pl))
240 pl = getuid(pl);
241
242 sl_exec("DELETE FROM testies WHERE name=?1;", pl);
243
244 mixed tmp = sl_exec("SELECT magier FROM testies WHERE "
245 "name=?1", pl);
246 if (sizeof(tmp))
247 return -1;
248
249 return 1;
250}
251
Zesstradd66c632019-05-06 21:04:16 +0200252// *************** Aliase *******************************
253
254// Nur die eigene Familie darf abgefragt/geaendert werden.
255private int alias_access(string familie)
256{
257 if (ARCH_SECURITY)
258 return 1;
259 if (QueryFamilie(previous_object()) == familie)
260 return 1;
261 return 0;
262}
263
264// Familie ermitteln und ggf. Zugriffsrecht pruefen.
265private string get_family(string familie)
266{
267 // Wenn Familie angegeben, darf das nur jemand abfragen, der dieser Familie
268 // angehoert (oder EM+).
269 if (familie)
270 {
271 if (!alias_access(familie))
272 return 0;
273 return familie;
274 }
275 else
276 return QueryFamilie(previous_object());
277 return 0;
278}
279
280// Die Familienaliase abfragen. Entweder ein bestimmtes oder alle. Eine
281// Filterung ist hier (vorlaeufig) nicht eingebaut, das macht ggf. das
282// Spielerobjekt.
283public varargs mapping QueryFamilyAlias(string verb, string familie)
284{
285 // Familie ermitteln und Zugriffsrecht pruefen.
286 familie = get_family(familie);
287 if (!familie || !sizeof(familie))
288 return 0;
289
290 mixed tmp;
291 if (verb)
292 tmp = sl_exec("SELECT verb, alias FROM aliases WHERE "
293 "familie=?1 AND verb=?2", familie, verb);
294 else
295 tmp = sl_exec("SELECT verb,alias FROM aliases WHERE "
296 "familie=?1",familie);
297
298 if (sizeof(tmp))
299 {
300 // Das Alias muss noch in das Aliasarray gesplittet werden.
301 mapping res = m_allocate(sizeof(tmp));
302 foreach(string* row : tmp)
303 {
304 m_add(res, row[0], restore_value(row[1]));
305 }
306 return res;
307 }
308 return ([]);
309}
310
311public varargs int AddOrReplaceFamilyAlias(string verb, <string|int>* alias,
312 string familie)
313{
314 // Familie ermitteln und Zugriffsrecht pruefen.
315 familie = get_family(familie);
316 if (!familie || !sizeof(familie))
317 return -1;
318
319 // max. 100 Familienaliase fuer den Moment.
320 mixed* tmp = sl_exec("SELECT COUNT(*) FROM aliases WHERE "
321 "familie=?1",familie);
322 if (tmp[0][0] > 100)
323 return -2;
324
325 sl_exec("INSERT OR REPLACE INTO aliases(familie, verb, alias) "
326 "VALUES(?1, ?2, ?3);", familie, verb, save_value(alias));
327 return 1;
328}
329
330public varargs int DeleteFamilyAlias(string verb, string familie)
331{
332 // Familie ermitteln und Zugriffsrecht pruefen.
333 familie = get_family(familie);
334 if (!familie || !sizeof(familie))
335 return -1;
336
337 if (verb)
338 sl_exec("DELETE FROM aliases WHERE familie=?1 AND verb=?2;",
339 familie, verb);
340 else // alle loeschen
341 sl_exec("DELETE FROM aliases WHERE familie=?1;", familie);
342 return 1;
343}
344