blob: afcef4171f1b4e71cbd88579591f37a7f1bc44f8 [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);
Zesstracd25d262020-01-21 19:36:39 +010072 if (master()->find_userinfo(testie))
MG Mud User88f12472016-06-24 23:31:02 +020073 {
74 sl_exec("INSERT OR REPLACE INTO testies(name, magier, lastlogin) "
75 "VALUES(?1,?2,?3);",
76 trigob->query_real_name(),
77 testie, time());
78 return; // zweitie jetzt auf jeden Fall ignorieren.
79 }
80 }
81
82 mixed erstie=trigob->QueryProp(P_SECOND);
83 if (stringp(erstie))
84 {
Zesstrac5cbd082019-01-07 23:06:13 +010085 erstie=lower_case(erstie);
Zesstracd25d262020-01-21 19:36:39 +010086 if (master()->find_userinfo(erstie))
MG Mud User88f12472016-06-24 23:31:02 +020087 {
88 sl_exec("INSERT OR REPLACE INTO zweities(uuid, name, erstieuuid, erstie) "
89 "VALUES(?1,?2,?3,?4);",
90 getuuid(trigob),
91 trigob->query_real_name(),
Zesstracd25d262020-01-21 19:36:39 +010092 erstie + "_"
93 + master()->query_userlist(erstie,USER_CREATION_DATE),
MG Mud User88f12472016-06-24 23:31:02 +020094 erstie);
95 }
96 //ZDEBUG(sprintf("%O, %O, %O\n",eid,trigob,data));
97 }
98}
99
100varargs int remove(int silent)
101{
102 EVENTD->UnregisterEvent(EVT_LIB_LOGIN, this_object());
103 sl_close();
104 destruct(ME);
105 return 1;
106}
107
108public mixed sql_query(string query)
109{
110 if (ARCH_SECURITY)
111 return sl_exec(query);
112 return 0;
113}
114
115private string get_erstie_data(string datum, object zweitie)
116{
117 if (!zweitie) return 0;
118 mixed res = sl_exec("SELECT " + datum + " FROM zweities WHERE uuid=?1",
119 getuuid(zweitie));
120 if (sizeof(res))
121 return res[0][0];
122
123 return 0;
124}
125
126public varargs string QueryErstieName(object zweitie)
127{
128 return get_erstie_data("erstie", zweitie || previous_object());
129}
130
131public varargs string QueryErstieUUID(object zweitie)
132{
133 return get_erstie_data("erstieuuid", zweitie || previous_object());
134}
135
136private string* get_zweitie_data(string datum, object erstie)
137{
138 if (!erstie) return 0;
139 mixed tmp = sl_exec("SELECT " + datum + " FROM zweities WHERE erstieuuid=?1",
140 getuuid(erstie));
141 if (sizeof(tmp))
142 {
143 string *res=({});
144 foreach(string *row: tmp)
145 res+=({row[0]});
146 return res;
147 }
148 return 0;
149}
150
151public varargs string* QueryZweities(object erstie)
152{
153 return get_zweitie_data("name", erstie || previous_object());
154}
155
156public varargs string QueryFamilie(object pl)
157{
Zesstrac0b56a32019-01-09 00:23:33 +0100158 if (!pl || !query_once_interactive(pl))
159 return 0;
MG Mud User88f12472016-06-24 23:31:02 +0200160 string erstie = get_erstie_data("erstieuuid",
161 pl || previous_object());
162 // Wenn !erstie, dann ist pl kein Zweitie, also ist er selber erstie
163 erstie ||= getuuid(pl);
164 // jetzt noch gucken, ob ne explizite Familie fuer den erstie erfasst ist.
165 mixed tmp = sl_exec("SELECT familie FROM familien WHERE "
166 "erstieuuid=?1",erstie);
167 if (sizeof(tmp))
168 return tmp[0][0];
169 // wenn nicht, dann ist die Familie die Zweitieuuid
170 return erstie;
171}
172
Zesstra60ec4972019-01-08 21:07:16 +0100173public string SetFamilie(object|string pl, string familie)
174{
175 if (!ARCH_SECURITY)
176 return 0;
177
178 // Wenn Spielerobjekt, UUID ermitteln
179 if (objectp(pl) && query_once_interactive(pl))
180 pl = getuuid(pl);
181
182 sl_exec("INSERT OR REPLACE INTO familien(erstieuuid, familie) "
183 "VALUES(?1, ?2);", pl, familie);
184
185 mixed tmp = sl_exec("SELECT familie FROM familien WHERE "
186 "erstieuuid=?1", pl);
187 if (sizeof(tmp))
188 return tmp[0][0];
189
190 return 0;
191}
192
193public int DeleteFamilie(object|string pl)
194{
195 if (!ARCH_SECURITY)
196 return 0;
197
198 // Wenn Spielerobjekt, UUID ermitteln
199 if (objectp(pl) && query_once_interactive(pl))
200 pl = getuuid(pl);
201
202 sl_exec("DELETE FROM familien WHERE erstieuuid=?1;",
203 pl);
204
205 mixed tmp = sl_exec("SELECT familie FROM familien WHERE "
206 "erstieuuid=?1", pl);
207 if (sizeof(tmp))
208 return -1;
209
210 return 1;
211}
212
Zesstrab9dc01d2019-01-08 21:22:21 +0100213public int DeleteZweitie(object|string pl)
214{
215 if (!ARCH_SECURITY)
216 return 0;
217
218 // Wenn Spielerobjekt, UUID ermitteln
219 if (objectp(pl) && query_once_interactive(pl))
220 pl = getuuid(pl);
221
222 sl_exec("DELETE FROM zweities WHERE uuid=?1;", pl);
223
224 mixed tmp = sl_exec("SELECT name FROM zweities WHERE "
225 "uuid=?1", pl);
226 if (sizeof(tmp))
227 return -1;
228
229 return 1;
230}
231
232public int DeleteTestie(object|string pl)
233{
234 if (!ARCH_SECURITY)
235 return 0;
236
237 // Wenn Spielerobjekt, UID ermitteln
238 if (objectp(pl) && query_once_interactive(pl))
239 pl = getuid(pl);
240
241 sl_exec("DELETE FROM testies WHERE name=?1;", pl);
242
243 mixed tmp = sl_exec("SELECT magier FROM testies WHERE "
244 "name=?1", pl);
245 if (sizeof(tmp))
246 return -1;
247
248 return 1;
249}
250
Zesstradd66c632019-05-06 21:04:16 +0200251// *************** Aliase *******************************
252
253// Nur die eigene Familie darf abgefragt/geaendert werden.
254private int alias_access(string familie)
255{
256 if (ARCH_SECURITY)
257 return 1;
258 if (QueryFamilie(previous_object()) == familie)
259 return 1;
260 return 0;
261}
262
263// Familie ermitteln und ggf. Zugriffsrecht pruefen.
264private string get_family(string familie)
265{
266 // Wenn Familie angegeben, darf das nur jemand abfragen, der dieser Familie
267 // angehoert (oder EM+).
268 if (familie)
269 {
270 if (!alias_access(familie))
271 return 0;
272 return familie;
273 }
274 else
275 return QueryFamilie(previous_object());
Zesstradd66c632019-05-06 21:04:16 +0200276}
277
278// Die Familienaliase abfragen. Entweder ein bestimmtes oder alle. Eine
279// Filterung ist hier (vorlaeufig) nicht eingebaut, das macht ggf. das
280// Spielerobjekt.
281public varargs mapping QueryFamilyAlias(string verb, string familie)
282{
283 // Familie ermitteln und Zugriffsrecht pruefen.
284 familie = get_family(familie);
285 if (!familie || !sizeof(familie))
286 return 0;
287
288 mixed tmp;
289 if (verb)
290 tmp = sl_exec("SELECT verb, alias FROM aliases WHERE "
291 "familie=?1 AND verb=?2", familie, verb);
292 else
293 tmp = sl_exec("SELECT verb,alias FROM aliases WHERE "
294 "familie=?1",familie);
295
296 if (sizeof(tmp))
297 {
298 // Das Alias muss noch in das Aliasarray gesplittet werden.
299 mapping res = m_allocate(sizeof(tmp));
300 foreach(string* row : tmp)
301 {
302 m_add(res, row[0], restore_value(row[1]));
303 }
304 return res;
305 }
306 return ([]);
307}
308
309public varargs int AddOrReplaceFamilyAlias(string verb, <string|int>* alias,
310 string familie)
311{
312 // Familie ermitteln und Zugriffsrecht pruefen.
313 familie = get_family(familie);
314 if (!familie || !sizeof(familie))
315 return -1;
316
Zesstra8df39b52020-10-19 22:01:50 +0200317 // max. 250 Familienaliase fuer den Moment.
Zesstradd66c632019-05-06 21:04:16 +0200318 mixed* tmp = sl_exec("SELECT COUNT(*) FROM aliases WHERE "
319 "familie=?1",familie);
Zesstra1b98da72020-10-19 21:50:22 +0200320 if (tmp[0][0] > 250)
Zesstradd66c632019-05-06 21:04:16 +0200321 return -2;
322
323 sl_exec("INSERT OR REPLACE INTO aliases(familie, verb, alias) "
324 "VALUES(?1, ?2, ?3);", familie, verb, save_value(alias));
325 return 1;
326}
327
328public varargs int DeleteFamilyAlias(string verb, string familie)
329{
330 // Familie ermitteln und Zugriffsrecht pruefen.
331 familie = get_family(familie);
332 if (!familie || !sizeof(familie))
333 return -1;
334
335 if (verb)
336 sl_exec("DELETE FROM aliases WHERE familie=?1 AND verb=?2;",
337 familie, verb);
338 else // alle loeschen
339 sl_exec("DELETE FROM aliases WHERE familie=?1;", familie);
340 return 1;
341}
342