blob: 160fcee860288c108f4813429bf4898298674403 [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001// * living_name-Behandlung
2
3#define clean_log(s)
4//#define clean_log(s) log_file("CLEAN_SIM",ctime(time())[4..18]+": "+(s));
5
6private nosave mapping living_name_m, name_living_m, netdead;
7
8private void InitLivingData(mixed wizinfo) {
9 // living_name ist ein Pointer der auch in der extra_wizinfo gehalten
10 // wird, so kann die simul_efun neu geladen werden, ohne dass dieses
11 // Mapping verloren geht
12 if (!mappingp(living_name_m = wizinfo[LIVING_NAME]))
13 living_name_m = wizinfo[LIVING_NAME] = m_allocate(0, 1);
14
15 // Gleiches gilt fuer das Mapping Name-Living
16 if (!mappingp(name_living_m = wizinfo[NAME_LIVING]))
17 name_living_m = wizinfo[NAME_LIVING] = m_allocate(0, 1);
18
19 // Netztote sind ebenfalls in der extra_wizinfo
20 if (!mappingp(netdead = wizinfo[NETDEAD_MAP]))
21 netdead = wizinfo[NETDEAD_MAP] = ([]);
22}
23
24public varargs string getuuid( object ob )
25{
26 mixed *ret;
27
28 if ( !objectp(ob) )
29 ob = previous_object();
30
31 if ( !query_once_interactive(ob) )
32 return getuid(ob);
33
34 ret = (mixed)master()->get_userinfo( getuid(ob) );
35
36 if ( !pointerp(ret) || sizeof(ret) < 5 )
37 return getuid(ob);
38
39 // Username + "_" + CreationDate
40 return ret[0] + "_" + ret[5];
41}
42
43void set_object_living_name(string livname, object obj)
44{
45 string old;
46 mixed a;
47 int i;
48
49 if (previous_object()==obj || previous_object()==this_object() ||
50 previous_object()==master())
51 {
52 if(!livname || !stringp(livname)) {
53 set_this_object(previous_object());
54 raise_error(sprintf("%O: illegal living name: %O\n", obj, livname));
55 }
56 if (old = living_name_m[obj]) {
57 if (pointerp(a = name_living_m[old])) {
58 a[member(a, obj)] = 0;
59 } else {
60 m_delete(name_living_m, old);
61 }
62 }
63 living_name_m[obj] = livname;
64 if (a = name_living_m[livname]) {
65 if (!pointerp(a)) {
66 name_living_m[livname] = ({a, obj});
67 return;
68 }
69 /* Try to reallocate entry from destructed object */
70 if ((i = member(a, 0)) >= 0) {
71 a[i] = obj;
72 return;
73 }
74 name_living_m[livname] = a + ({obj});
75 return;
76 }
77 name_living_m[livname] = obj;
78 }
79}
80
81void set_living_name(string livname)
82{
83 set_object_living_name(livname,previous_object());
84}
85
86void remove_living_name()
87{
88 string livname;
89
90 if (!previous_object())
91 return;
92 if (livname=living_name_m[previous_object()])
93 {
94 m_delete(living_name_m,previous_object());
95 if (objectp(name_living_m[livname]))
96 {
97 if (name_living_m[livname]==previous_object())
98 m_delete(name_living_m,livname);
99 return;
100 }
101 if (pointerp(name_living_m[livname]))
102 {
103 name_living_m[livname]-=({previous_object()});
104 if (!sizeof(name_living_m[livname]))
105 m_delete(name_living_m,livname);
106 }
107 }
108}
109
110void _set_netdead()
111{
112 if (query_once_interactive(previous_object()))
113 netdead[getuid(previous_object())]=previous_object();
114}
115
116void _remove_netdead()
117{
118 m_delete(netdead,getuid(previous_object()));
119}
120
121object find_netdead(string uuid)
122{
123 int i;
124 string uid;
125 // Wenn sscanf() 2 liefert, ist uuid auch ne uuid.
126 int is_uuid = sscanf(uuid, "%s_%d", uid, i) == 2;
127 if (!is_uuid)
128 uid = uuid;
129
130 if (is_uuid && getuuid(netdead[uid]) != uuid)
131 return 0;
132
133 return netdead[uid];
134}
135
136string *dump_netdead()
137{
138 return m_indices(netdead);
139}
140
141object find_living(string livname) {
142 mixed *a, r;
143 int i;
144
145 if (pointerp(r = name_living_m[livname])) {
146 if (member(r,0)>=0)
147 r-=({0});
148 if (!sizeof(r)){
149 m_delete(name_living_m,livname);
150 clean_log(sprintf("find_living loescht %s\n",livname));
151 return 0;
152 }
153 if ( !living(r = (a = r)[0])) {
154 for (i = sizeof(a); --i;) {
155 if (living(a[<i])) {
156 r = a[<i];
157 a[<i] = a[0];
158 return a[0] = r;
159 }
160 }
161 }
162 return r;
163 }
164 return living(r) && r;
165}
166
167object *find_livings(string livname)
168{
169 mixed r;
170
171 if (pointerp(r=name_living_m[livname]))
172 r-=({0});
173 else
174 if (objectp(r))
175 r=({r});
176 if (!pointerp(r)||!sizeof(r))
177 return 0;
178 return r;
179}
180
181object find_player(string uuid) {
182 object *objs;
183 mixed res;
184 int i;
185 string uid;
186
187 if (!stringp(uuid))
188 return 0;
189 // Wenn sscanf() 2 liefert, ist uuid auch ne uuid.
190 int is_uuid = sscanf(uuid, "%s_%d", uid, i) == 2;
191 if (!is_uuid)
192 uid = uuid;
193
194 if (pointerp(res = name_living_m[uid])) {
195 // zerstoerte Objekte ggf. entfernen
196 if (member(res,0)>=0) {
197 res-=({0});
198 name_living_m[uid] = res;
199 }
200 // ggf. Namen ohne Objekte entfernen.
201 if (!sizeof(res)){
202 m_delete(name_living_m,uid);
203 clean_log(sprintf("find_player loescht %s\n",uid));
204 return 0;
205 }
206 objs = res;
207 res = objs[0];
208 // Wenn das 0. Element der Spieler ist, sind wir fertig. Ansonsten suchen
209 // wir den Spieler und schieben ihn an die 0. Stelle im Array.
210 if ( !query_once_interactive(res)) {
211 for (i = sizeof(objs); --i;) {
212 if (objs[<i] && query_once_interactive(objs[<i])) {
213 res = objs[<i];
214 objs[<i] = objs[0];
215 objs[0] = res;
216 break;
217 }
218 }
219 res = (objectp(res) && query_once_interactive(res)) ? res : 0;
220 }
221 // else: in res steht der Spieler schon.
222 }
223 else if (objectp(res)) // r ist nen Einzelobjekt
224 res = query_once_interactive(res) ? res : 0;
225
226 // res ist jetzt ggf. der Spieler. Aber wenn der ne andere als die gesuchte
227 // UUID hat, ist das Ergebnis trotzdem 0.
228 if (is_uuid && getuuid(res)!=uuid)
229 return 0;
230
231 // endlich gefunden
232 return res;
233}
234
235private int check_match( string str, int players_only )
236{
237 mixed match;
238
239 if ( !(match = name_living_m[str]) )
240 return 0;
241
242 if ( !pointerp(match) )
243 match = ({ match });
244
245 match -= ({0});
246
247 if ( sizeof(match) ){
248 if ( players_only )
249 return sizeof(filter( match, #'query_once_interactive/*'*/ ))
250 > 0;
251 else
252 return 1;
253 }
254
255 m_delete( name_living_m, str );
256 clean_log( sprintf("check_match loescht %s\n", str) );
257 return 0;
258}
259
260//TODO:: string|string* exclude
261varargs mixed match_living( string str, int players_only, mixed exclude )
262{
263 int i, s;
264 mixed match, *user;
265
266 if ( !str || str == "" )
267 return 0;
268
269 if ( !pointerp(exclude) )
270 exclude = ({ exclude });
271
272 if ( member(exclude, str) < 0 && check_match(str, players_only) )
273 return str;
274
275 user = m_indices(name_living_m);
276 s = sizeof(str);
277 match = 0;
278
279 for ( i = sizeof(user); i--; )
280 if ( str == user[i][0..s-1] && member( exclude, user[i] ) < 0 )
281 if ( match )
282 return -1;
283 else
284 if ( check_match(user[i], players_only) )
285 match = user[i];
286
287 if ( !match )
288 return -2;
289
290 return match;
291}
292
293mixed *dump_livings()
294{
295 return sort_array(m_indices(name_living_m),#'>);
296}
297
298// * regelmaessig Listen von Ballast befreien
299private void clean_name_living_m(string *keys, int left, int num)
300{
301 int i, j;
302 mixed a;
303
304 while (left && num--)
305 {
306 if (pointerp(a = name_living_m[keys[--left]]) && member(a, 0)>=0)
307 {
308 a-=({0});
309 name_living_m[keys[left]] = a;
310 }
311 if (!a || (pointerp(a) && !sizeof(a)))
312 {
313 clean_log("Toasting "+keys[left]+"\n");
314 m_delete(name_living_m, keys[left]);
315 } else clean_log(sprintf("KEEPING %s (%O)\n",keys[left],pointerp(a)?sizeof(a):a));
316 }
317 if (left)
318 efun::call_out(#'clean_name_living_m, 1, keys, left, 80);
319 else
320 clean_log("Clean process finished\n");
321}
322
323private void clean_netdead() {
324 int i;
325 string *s;
326 object ob;
327
328 s=m_indices(netdead);
329 for (i=sizeof(s)-1;i>=0;i--)
330 if (!objectp(ob=netdead[s[i]]) || interactive(ob))
331 m_delete(netdead,s[i]);
332}
333
334private void CleanLivingData() {
335 if (find_call_out(#'clean_name_living_m) < 0) {
336 clean_log("Starting clean process\n");
337 efun::call_out(#'clean_name_living_m,
338 1,
339 m_indices(name_living_m),
340 sizeof(name_living_m),
341 80
342 );
343 }
344 efun::call_out(#'clean_netdead,2);
345}
346
347#undef clean_log
348