blob: 05e941ed2cf3a99b2ac5738432196d6c04032cc5 [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>
6* \date <date>
7* \version $Id$
8*/
9/* Changelog:
10*/
11#pragma strong_types,save_types,rtt_checks
12#pragma no_clone,no_inherit,no_shadow
13#pragma pedantic, range_check
14
15#include <defines.h>
16#include <events.h>
17#include <wizlevels.h>
18#include <lepmaster.h>
19#include <properties.h>
20#include <userinfo.h>
21
22#define HOME(x) (__PATH__(0)+x)
23#include <living/comm.h>
24#define ZDEBUG(x) if (find_player("zesstra")) \
25 find_player("zesstra")->ReceiveMsg(x,MT_DEBUG,0,object_name()+":",this_object())
26//#define ZDEBUG(x)
27
28object *players = ({});
29
30protected void create()
31{
32 seteuid(getuid());
33 if (sl_open(HOME("ARCH/topliste.sqlite")) != 1)
34 {
35 raise_error("Datenbank konnte nicht geoeffnet werden.\n");
36 }
37 // Tabellen und Indices anlegen, falls die nicht existieren.
38 sl_exec("CREATE TABLE IF NOT EXISTS topliste(name TEXT PRIMARY KEY ASC, "
39 "gilde TEXT NOT NULL, rasse TEXT NOT NULL, "
40 "age DATETIME, wizlevel INTEGER, "
41 "lastupdate DATETIME DEFAULT current_timestamp, "
42 "lep INTEGER, qp INTEGER, xp INTEGER, level INTEGER"
43 "hardcore INTEGER);");
44 sl_exec("CREATE INDEX IF NOT EXISTS idx_gilde ON topliste(gilde);");
45 sl_exec("CREATE INDEX IF NOT EXISTS idx_rasse ON topliste(rasse);");
46 sl_exec("CREATE INDEX IF NOT EXISTS idx_hardcore ON topliste(hardcore);");
47
48 // Login-Event abonnieren
49 if (EVENTD->RegisterEvent(EVT_LIB_LOGIN,
50 "listen", this_object()) <= 0)
51 {
52 raise_error("Loginevent konnte nicht abonniert werden.\n");
53 }
54 if (EVENTD->RegisterEvent(EVT_LIB_ADVANCE,
55 "listen", this_object()) <= 0)
56 {
57 raise_error("EVT_LIB_ADVANCE konnte nicht abonniert werden.\n");
58 }
59 if (EVENTD->RegisterEvent(EVT_LIB_QUEST_SOLVED,
60 "listen", this_object()) <= 0)
61 {
62 raise_error("EVT_LIB_QUEST_SOLVED konnte nicht abonniert werden.\n");
63 }
64 if (EVENTD->RegisterEvent(EVT_LIB_MINIQUEST_SOLVED,
65 "listen", this_object()) <= 0)
66 {
67 raise_error("EVT_LIB_MINIQUEST_SOLVED konnte nicht abonniert werden.\n");
68 }
69}
70
71private void process()
72{
Zesstra10dd0c72017-01-28 13:37:57 +010073 players -= ({0});
MG Mud User88f12472016-06-24 23:31:02 +020074 foreach(object pl : &players)
75 {
76 if (get_eval_cost() < 200000)
77 {
78 call_out(#'process, 2);
MG Mud User88f12472016-06-24 23:31:02 +020079 return;
80 }
81 sl_exec("INSERT OR REPLACE INTO topliste(name, gilde, rasse, "
82 "age, wizlevel, lastupdate, lep, qp, xp, level, hardcore) "
83 "VALUES(?1,?2,?3,?4,?5,?6,?7,?8,?9,?10,?11);",
84 pl->query_real_name(),
85 pl->QueryProp(P_GUILD) || "unbekannt",
Zesstraebd3dae2017-01-28 13:39:29 +010086 pl->QueryProp(P_REAL_RACE),
MG Mud User88f12472016-06-24 23:31:02 +020087 pl->QueryProp(P_AGE),
88 query_wiz_level(pl),
89 time(),
90 LEPMASTER->QueryLEPForPlayer(pl),
91 pl->QueryProp(P_QP),
92 pl->QueryProp(P_XP),
93 pl->QueryProp(P_LEVEL),
94 pl->query_hc_play()
95 );
96 pl=0;
97 }
Zesstra10dd0c72017-01-28 13:37:57 +010098 players = ({});
MG Mud User88f12472016-06-24 23:31:02 +020099}
100
101public void listen(string eid, object trigob, mixed data)
102{
103 if (previous_object() != find_object(EVENTD)
104 || !trigob
105 || !query_once_interactive(trigob)
106 || IS_LEARNER(trigob)
Arathorn3129bef2019-12-03 00:33:17 +0100107 || trigob->QueryProp(P_TESTPLAYER)
MG Mud User88f12472016-06-24 23:31:02 +0200108 || trigob->QueryGuest()
109 || trigob->QueryProp(P_NO_TOPLIST)
110 )
111 return;
112
113 // Dieser handler hat nur 30k Ticks zur Verfuegung, dummerweise kann
114 // QueryLEPForPlayer() locker ueber 30k kosten, wenn der Spieler nicht in
115 // Caches drin ist. Daher muss das jetzt per call_out entkoppelt werden.
116 // *seufz*
117 if (member(players, trigob) == -1)
118 {
119 players += ({trigob});
120 if (find_call_out(#'process) == -1)
121 call_out(#'process, 2);
122 }
123}
124
Zesstradd2d1982017-01-28 14:03:19 +0100125// Falls ein Spieler sich aus Toplisten austragen will
126public varargs mixed DeletePlayer(string real_name)
127{
128 // (interaktive) Spielershells duerfen sich selber austragen, EM+ beliebige
129 // Spieler
130 if (!ARCH_SECURITY)
131 {
132 if (interactive(previous_object()))
133 real_name = previous_object()->query_real_name();
134 else
135 raise_error("Spieler aus Toplisten loeschen koennen nur Spieler "
136 "selber oder ein EM+.\n");
137 }
138 return sl_exec("DELETE FROM topliste WHERE name = ?1;", real_name);
139}
140
MG Mud User88f12472016-06-24 23:31:02 +0200141public varargs < <string|int>* >* Liste(string rasse, string gilde,
142 int limit, string sort)
143{
144 // Defaults:
145 sort ||= "lep";
146 if (!limit || limit > 100)
147 limit=100;
148 else if (limit < 1)
149 limit=1;
150 if (rasse && gilde)
151 return sl_exec(
152 "select name,lep,qp,xp,level,age,rasse,gilde,wizlevel,hardcore from topliste "
153 "WHERE rasse=?1 AND gilde=?2 "
154 "ORDER BY "+sort+" DESC LIMIT "+limit+";",
155 rasse, gilde);
156 else if (rasse)
157 return sl_exec(
158 "select name,lep,qp,xp,level,age,rasse,gilde,wizlevel,hardcore from topliste "
159 "WHERE rasse=?1 "
160 "ORDER BY "+sort+" DESC LIMIT "+limit+";",
161 rasse);
162 else if (gilde)
163 return sl_exec(
164 "select name,lep,qp,xp,level,age,rasse,gilde,wizlevel,hardcore from topliste "
165 "WHERE gilde=?1 "
166 "ORDER BY "+sort+" DESC LIMIT "+limit+";",
167 gilde);
168 return sl_exec(
169 "select name,lep,qp,xp,level,age,rasse,gilde,wizlevel,hardcore from topliste "
170 "ORDER BY "+sort+" DESC LIMIT "+limit+";");
171}
172
173public varargs < <string|int>* >* SpielerListe(string rasse, string gilde,
174 int limit, string sort)
175{
176 // Defaults:
177 sort ||= "lep";
178 if (!limit || limit > 100)
179 limit=100;
180 else if (limit < 1)
181 limit=1;
182 if (rasse && gilde)
183 return sl_exec(
184 "select name,lep,qp,xp,level,age,rasse,gilde,wizlevel,hardcore from topliste "
185 "WHERE rasse=?1 AND gilde=?2 AND wizlevel=0 "
186 "ORDER BY "+sort+" DESC LIMIT "+limit+";",
187 rasse, gilde);
188 else if (rasse)
189 return sl_exec(
190 "select name,lep,qp,xp,level,age,rasse,gilde,wizlevel,hardcore from topliste "
191 "WHERE rasse=?1 AND wizlevel=0 "
192 "ORDER BY "+sort+" DESC LIMIT "+limit+";",
193 rasse);
194 else if (gilde)
195 return sl_exec(
196 "select name,lep,qp,xp,level,age,rasse,gilde,wizlevel,hardcore from topliste "
197 "WHERE gilde=?1 AND wizlevel=0 "
198 "ORDER BY "+sort+" DESC LIMIT "+limit+";",
199 gilde);
200 return sl_exec(
201 "select name,lep,qp,xp,level,age,rasse,gilde,wizlevel,hardcore from topliste "
202 "WHERE wizlevel=0 "
203 "ORDER BY "+sort+" DESC LIMIT "+limit+";");
204}
205
206public varargs < <string|int>* >* SeherListe(string rasse, string gilde,
207 int limit, string sort)
208{
209 // Defaults:
210 sort ||= "lep";
211 if (!limit || limit > 100)
212 limit=100;
213 else if (limit < 1)
214 limit=1;
215 if (rasse && gilde)
216 return sl_exec(
217 "select name,lep,qp,xp,level,age,rasse,gilde,wizlevel,hardcore from topliste "
218 "WHERE rasse=?1 AND gilde=?2 AND wizlevel=1 "
219 "ORDER BY "+sort+" DESC LIMIT "+limit+";",
220 rasse, gilde);
221 else if (rasse)
222 return sl_exec(
223 "select name,lep,qp,xp,level,age,rasse,gilde,wizlevel,hardcore from topliste "
224 "WHERE rasse=?1 AND wizlevel=1 "
225 "ORDER BY "+sort+" DESC LIMIT "+limit+";",
226 rasse);
227 else if (gilde)
228 return sl_exec(
229 "select name,lep,qp,xp,level,age,rasse,gilde,wizlevel,hardcore from topliste "
230 "WHERE gilde=?1 AND wizlevel=1 "
231 "ORDER BY "+sort+" DESC LIMIT "+limit+";",
232 gilde);
233 return sl_exec(
234 "select name,lep,qp,xp,level,age,rasse,gilde,wizlevel,hardcore from topliste "
235 "WHERE wizlevel=1 "
236 "ORDER BY "+sort+" DESC LIMIT "+limit+";");
237}
238
239public varargs < <string|int>* >* HardcoreListe(string rasse, string gilde,
240 int limit, string sort)
241{
242 // Defaults:
243 sort ||= "lep";
244 if (!limit || limit > 100)
245 limit=100;
246 else if (limit < 1)
247 limit=1;
248 if (rasse && gilde)
249 return sl_exec(
250 "select name,lep,qp,xp,level,age,rasse,gilde,wizlevel,hardcore from topliste "
251 "WHERE rasse=?1 AND gilde=?2 AND hardcore>0 "
252 "ORDER BY "+sort+" DESC LIMIT "+limit+";",
253 rasse, gilde);
254 else if (rasse)
255 return sl_exec(
256 "select name,lep,qp,xp,level,age,rasse,gilde,wizlevel,hardcore from topliste "
257 "WHERE rasse=?1 AND hardcore>0 "
258 "ORDER BY "+sort+" DESC LIMIT "+limit+";",
259 rasse);
260 else if (gilde)
261 return sl_exec(
262 "select name,lep,qp,xp,level,age,rasse,gilde,wizlevel,hardcore from topliste "
263 "WHERE gilde=?1 AND hardcore>0 "
264 "ORDER BY "+sort+" DESC LIMIT "+limit+";",
265 gilde);
266 return sl_exec(
267 "select name,lep,qp,xp,level,age,rasse,gilde,wizlevel,hardcore from topliste "
268 "WHERE hardcore>0 "
269 "ORDER BY "+sort+" DESC LIMIT "+limit+";");
270}
271
272varargs int remove(int silent)
273{
274 EVENTD->UnregisterEvent(EVT_LIB_LOGIN, this_object());
275 sl_close();
276 destruct(ME);
277 return 1;
278}
279
280public mixed sql_query(string query)
281{
282 if (ARCH_SECURITY)
283 return sl_exec(query);
284 return 0;
285}
286
287void reset()
288{
289 // Alle Eintraege loeschen, die seit 90 nicht mehr aktualisiert wurden.
290// sl_exec("DELETE FROM topliste WHERE lastupdate<?1;",
291// time()-90*24*3600);
292 sl_exec("DELETE FROM topliste WHERE name IN (SELECT name FROM topliste "
293 "ORDER BY lep DESC LIMIT 1000, -1);");
294 set_next_reset(86400);
295}
296