ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/plugins.C
Revision: 1.52
Committed: Sun Sep 30 16:24:32 2007 UTC (16 years, 7 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.51: +0 -0 lines
State: FILE REMOVED
Log Message:
finally remove the old buggy plug-in cruft

File Contents

# Content
1 /*
2 * This file is part of Crossfire TRT, the Roguelike Realtime MORPG.
3 *
4 * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team
5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992,2007 Frank Tore Johansen
7 *
8 * Crossfire TRT is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 * The authors can be reached via e-mail to <crossfire@schmorp.de>
22 */
23
24 /*****************************************************************************/
25 /* This is the server-side plugin management part. */
26 /*****************************************************************************/
27 /* Original code by Yann Chachkoff (yann.chachkoff@mailandnews.com). */
28 /* Special thanks to: */
29 /* David Delbecq (david.delbecq@mailandnews.com); */
30 /* Joris Bontje (jbontje@suespammers.org); */
31 /* Philip Currlin (?); */
32 /*****************************************************************************/
33
34 /*****************************************************************************/
35 /* First, the headers. We only include plugin.h, because all other includes */
36 /* are done into it, and plugproto.h (which is used only by this file). */
37 /*****************************************************************************/
38
39 #include <plugin.h>
40
41 #ifndef __CEXTRACT__
42 # include <sproto.h>
43 #endif
44
45 #define NR_OF_HOOKS 74
46
47 static const hook_entry plug_hooks[NR_OF_HOOKS] = {
48 {cfapi_system_register_global_event, 1, "cfapi_system_register_global_event"},
49 {cfapi_system_unregister_global_event, 3, "cfapi_system_unregister_global_event"},
50 {NULL, 4, "cfapi_system_check_path"},
51 {NULL, 5, "cfapi_system_re_cmp"},
52 {cfapi_system_strdup, 6, "cfapi_system_strdup"},
53 {cfapi_system_directory, 7, "cfapi_system_directory"},
54 {cfapi_system_find_animation, 8, "cfapi_system_find_animation"},
55 {cfapi_object_clean_object, 9, "cfapi_object_clean_object"},
56 {cfapi_object_on_same_map, 10, "cfapi_object_on_same_map"},
57 {cfapi_object_get_key, 11, "cfapi_object_get_key"},
58 {cfapi_object_set_key, 12, "cfapi_object_set_key"},
59 {cfapi_object_get_property, 13, "cfapi_object_get_property"},
60 {cfapi_object_set_property, 14, "cfapi_object_set_property"},
61 {cfapi_object_apply, 15, "cfapi_object_apply"},
62 {cfapi_object_identify, 16, "cfapi_object_identify"},
63 {cfapi_object_describe, 17, "cfapi_object_describe"},
64 {cfapi_object_drain, 18, "cfapi_object_drain"},
65 {cfapi_object_fix, 19, "cfapi_object_fix"},
66 {cfapi_object_give_skill, 20, "cfapi_object_give_skill"},
67 {cfapi_object_transmute, 21, "cfapi_object_transmute"},
68 {cfapi_object_remove, 22, "cfapi_object_remove"},
69 {cfapi_object_delete, 23, "cfapi_object_delete"},
70 {cfapi_object_clone, 24, "cfapi_object_clone"},
71 {cfapi_object_find, 25, "cfapi_object_find"},
72 {cfapi_object_create, 26, "cfapi_object_create"},
73 {cfapi_object_insert, 27, "cfapi_object_insert"},
74 {cfapi_object_split, 28, "cfapi_object_split"},
75 {cfapi_object_merge, 29, "cfapi_object_merge"},
76 {cfapi_object_distance, 30, "cfapi_object_distance"},
77 {cfapi_object_update, 31, "cfapi_object_update"},
78 {cfapi_object_clear, 32, "cfapi_object_clear"},
79 {cfapi_object_reset, 33, "cfapi_object_reset"},
80 {cfapi_object_check_inventory, 34, "cfapi_object_check_inventory"},
81 {cfapi_object_spring_trap, 35, "cfapi_object_spring_trap"},
82 {cfapi_object_check_trigger, 36, "cfapi_object_check_trigger"},
83 {cfapi_object_query_cost, 37, "cfapi_object_query_cost"},
84 {cfapi_object_query_money, 38, "cfapi_object_query_money"},
85 {cfapi_object_cast, 39, "cfapi_object_cast"},
86 {cfapi_object_learn_spell, 40, "cfapi_object_learn_spell"},
87 {cfapi_object_forget_spell, 41, "cfapi_object_forget_spell"},
88 {cfapi_object_check_spell, 42, "cfapi_object_check_spell"},
89 {cfapi_object_pay_amount, 43, "cfapi_object_pay_amount"},
90 {cfapi_object_pay_item, 44, "cfapi_object_pay_item"},
91 {cfapi_object_transfer, 45, "cfapi_object_transfer"},
92 {cfapi_object_drop, 46, "cfapi_object_drop"},
93 {cfapi_object_take, 47, "cfapi_object_take"},
94 {cfapi_object_find_archetype_inside, 48, "cfapi_object_find_archetype_inside"},
95 {cfapi_object_say, 49, "cfapi_object_say"},
96 {cfapi_map_get_map, 50, "cfapi_map_get_map"},
97 {cfapi_map_has_been_loaded, 51, "cfapi_map_has_been_loaded"},
98 {cfapi_map_create_path, 52, "cfapi_map_create_path"},
99 {cfapi_map_get_map_property, 53, "cfapi_map_get_property"},
100 {cfapi_map_set_map_property, 54, "cfapi_map_set_property"},
101 {cfapi_map_out_of_map, 55, "cfapi_map_out_of_map"},
102 {cfapi_map_update_position, 56, "cfapi_map_update_position"},
103 {cfapi_map_delete_map, 57, "cfapi_map_delete_map"},
104 {cfapi_map_message, 58, "cfapi_map_message"},
105 {cfapi_map_get_object_at, 59, "cfapi_map_get_object_at"},
106 {cfapi_map_get_flags, 60, "cfapi_map_get_flags"},
107 {cfapi_map_present_arch_by_name, 61, "cfapi_map_present_arch_by_name"},
108 {cfapi_player_find, 62, "cfapi_player_find"},
109 {cfapi_player_message, 63, "cfapi_player_message"},
110 {cfapi_player_send_inventory, 64, "cfapi_player_send_inventory"},
111 {cfapi_object_teleport, 65, "cfapi_object_teleport"},
112 {cfapi_object_speak, 66, "cfapi_object_speak"},
113 {cfapi_object_pickup, 67, "cfapi_object_pickup"},
114 {cfapi_object_move, 68, "cfapi_object_move"},
115 {cfapi_object_apply_below, 69, "cfapi_object_apply_below"},
116 {cfapi_archetype_get_first, 70, "cfapi_archetype_get_first"},
117 {cfapi_archetype_get_property, 71, "cfapi_archetype_get_property"},
118 {cfapi_party_get_property, 72, "cfapi_party_get_property"},
119 {cfapi_region_get_property, 73, "cfapi_region_get_property"},
120 };
121 int plugin_number = 0;
122 crossfire_plugin *plugins_list = NULL;
123
124 /*****************************************************************************/
125
126 /* NEW PLUGIN STUFF STARTS HERE */
127
128 /*****************************************************************************/
129
130 /**
131 * Notify clients about a removed object.
132 *
133 * @param op the object about to be removed from its environment; it must still
134 * be present in its environment
135 */
136 static void
137 send_removed_object (object *op)
138 {
139 object *tmp;
140
141 if (op->env == NULL)
142 {
143 /* no action necessary: remove_ob() notifies the client */
144 return;
145 }
146
147 tmp = op->in_player ();
148 if (!tmp)
149 {
150 for_all_players (pl)
151 if (pl->ob->container == op->env)
152 {
153 tmp = pl->ob;
154 break;
155 }
156 }
157
158 if (tmp)
159 esrv_del_item (tmp->contr, op->count);
160 }
161
162 extern "C" int cfperl_initPlugin (const char *iversion, f_plug_api gethooksptr);
163 extern "C" void *cfperl_getPluginProperty (int *type, ...);
164 extern "C" int cfperl_postInitPlugin ();
165 extern "C" int cfperl_closePlugin ();
166
167 // this is a temporary hack till the old plugin stuff is removed
168 int
169 plugins_init_perl ()
170 {
171 f_plug_init initfunc;
172 f_plug_api propfunc;
173 f_plug_postinit postfunc;
174 f_plug_postinit closefunc;
175 int i;
176 crossfire_plugin *cp;
177 crossfire_plugin *ccp;
178
179 initfunc = (f_plug_init) cfperl_initPlugin;
180 propfunc = (f_plug_api) cfperl_getPluginProperty;
181 postfunc = (f_plug_postinit) cfperl_postInitPlugin;
182 closefunc = (f_plug_postinit) cfperl_closePlugin;
183 i = initfunc ("2.0", cfapi_get_hooks);
184 cp = (crossfire_plugin *) malloc (sizeof (crossfire_plugin));
185 for (i = 0; i < NR_EVENTS; i++)
186 cp->gevent[i] = NULL;
187 cp->eventfunc = 0;
188 cp->propfunc = propfunc;
189 cp->closefunc = closefunc;
190 cp->libptr = 0;
191 strcpy (cp->id, (const char *) propfunc (&i, "Identification"));
192 strcpy (cp->fullname, (const char *) propfunc (&i, "FullName"));
193 cp->next = NULL;
194 cp->prev = NULL;
195 if (plugins_list == NULL)
196 {
197 plugins_list = cp;
198 }
199 else
200 {
201 for (ccp = plugins_list; ccp->next != NULL; ccp = ccp->next)
202 ;
203 ccp->next = cp;
204 cp->prev = ccp;
205 }
206 postfunc ();
207 plugin_number++;
208 return 0;
209 }
210
211 int
212 plugins_init_plugin (const char *libfile)
213 {
214 return 0;
215
216 LIBPTRTYPE ptr;
217 f_plug_init initfunc;
218 f_plug_api propfunc;
219 f_plug_api eventfunc;
220 f_plug_postinit postfunc;
221 f_plug_postinit closefunc;
222 int i;
223 crossfire_plugin *cp;
224 crossfire_plugin *ccp;
225
226 /* Open the plugin lib and load the required functions */
227 ptr = plugins_dlopen (libfile);
228 if (ptr == NULL)
229 {
230 LOG (llevError, "Error trying to load %s: %s\n", libfile, plugins_dlerror ());
231 return -1;
232 }
233 initfunc = (f_plug_init) plugins_dlsym (ptr, "initPlugin");
234 if (initfunc == NULL)
235 {
236 LOG (llevError, "Plugin error while requesting %s.initPlugin: %s\n", libfile, plugins_dlerror ());
237 plugins_dlclose (ptr);
238 return -1;
239 }
240 propfunc = (f_plug_api) plugins_dlsym (ptr, "getPluginProperty");
241 if (propfunc == NULL)
242 {
243 LOG (llevError, "Plugin error while requesting %s.getPluginProperty: %s\n", libfile, plugins_dlerror ());
244 plugins_dlclose (ptr);
245 return -1;
246 }
247 eventfunc = (f_plug_api) plugins_dlsym (ptr, "eventListener");
248 if (eventfunc == NULL)
249 {
250 LOG (llevError, "Plugin error while requesting %s.eventListener: %s\n", libfile, plugins_dlerror ());
251 plugins_dlclose (ptr);
252 return -1;
253 }
254 postfunc = (f_plug_postinit) plugins_dlsym (ptr, "postInitPlugin");
255 if (postfunc == NULL)
256 {
257 LOG (llevError, "Plugin error while requesting %s.postInitPlugin: %s\n", libfile, plugins_dlerror ());
258 plugins_dlclose (ptr);
259 return -1;
260 }
261 closefunc = (f_plug_postinit) plugins_dlsym (ptr, "closePlugin");
262 if (postfunc == NULL)
263 {
264 LOG (llevError, "Plugin error while requesting %s.closePlugin: %s\n", libfile, plugins_dlerror ());
265 plugins_dlclose (ptr);
266 return -1;
267 }
268 i = initfunc ("2.0", cfapi_get_hooks);
269 cp = (crossfire_plugin *) malloc (sizeof (crossfire_plugin));
270 for (i = 0; i < NR_EVENTS; i++)
271 cp->gevent[i] = NULL;
272 cp->eventfunc = eventfunc;
273 cp->propfunc = propfunc;
274 cp->closefunc = closefunc;
275 cp->libptr = ptr;
276 strcpy (cp->id, (const char *) propfunc (&i, "Identification"));
277 strcpy (cp->fullname, (const char *) propfunc (&i, "FullName"));
278 cp->next = NULL;
279 cp->prev = NULL;
280 if (plugins_list == NULL)
281 {
282 plugins_list = cp;
283 }
284 else
285 {
286 for (ccp = plugins_list; ccp->next != NULL; ccp = ccp->next)
287 ;
288 ccp->next = cp;
289 cp->prev = ccp;
290 }
291 postfunc ();
292 plugin_number++;
293 return 0;
294 }
295
296 void *
297 cfapi_get_hooks (int *type, ...)
298 {
299 va_list args;
300 int request_type;
301 char *buf;
302 int fid;
303 f_plug_api rv;
304 int i;
305
306 va_start (args, type);
307 request_type = va_arg (args, int);
308
309 if (request_type == 0)
310 { /* By nr */
311 fid = va_arg (args, int);
312
313 if (fid < 0 || fid >= NR_OF_HOOKS)
314 {
315 rv = NULL;
316 *type = CFAPI_NONE;
317 }
318 else
319 {
320 rv = plug_hooks[fid].func;
321 *type = CFAPI_FUNC;
322 }
323 }
324 else
325 { /* by name */
326 buf = va_arg (args, char *);
327
328 rv = NULL;
329 for (i = 0; i < NR_OF_HOOKS; i++)
330 {
331 if (!strcmp (buf, plug_hooks[i].fname))
332 {
333 rv = plug_hooks[i].func;
334 *type = CFAPI_FUNC;
335 break;
336 }
337 }
338 if (rv == NULL)
339 {
340 *type = CFAPI_NONE;
341 }
342 }
343 va_end (args);
344 return (void *) rv;
345 }
346
347 int
348 plugins_remove_plugin (const char *id)
349 {
350 crossfire_plugin *cp;
351
352 if (plugins_list == NULL)
353 return -1;
354
355 for (cp = plugins_list; cp != NULL; cp = cp->next)
356 {
357 if (!strcmp (id, cp->id) && cp->libptr)
358 {
359 crossfire_plugin *n;
360 crossfire_plugin *p;
361
362 n = cp->next;
363 p = cp->prev;
364 plugins_dlclose (cp->libptr);
365 if (n != NULL)
366 {
367 if (p != NULL)
368 {
369 n->prev = p;
370 p->next = n;
371 }
372 else
373 {
374 n->prev = NULL;
375 plugins_list = n;
376 }
377 }
378 else
379 {
380 if (p != NULL)
381 p->next = NULL;
382 else
383 plugins_list = NULL;
384 }
385 free (cp);
386 plugin_number--;
387 return 0;
388 }
389 }
390 return -1;
391 }
392
393 crossfire_plugin *
394 plugins_find_plugin (const char *id)
395 {
396 crossfire_plugin *cp;
397
398 if (plugins_list == NULL)
399 return NULL;
400
401 for (cp = plugins_list; cp != NULL; cp = cp->next)
402 {
403 if (!strcmp (id, cp->id))
404 {
405 return cp;
406 }
407 }
408 return NULL;
409 }
410
411 /*****************************************************************************/
412
413 /* Displays a list of loaded plugins (keystrings and description) in the */
414
415 /* game log window. */
416
417 /*****************************************************************************/
418 void
419 plugins_display_list (object *op)
420 {
421 crossfire_plugin *cp;
422
423 new_draw_info (NDI_UNIQUE, 0, op, "List of loaded plugins:");
424 new_draw_info (NDI_UNIQUE, 0, op, "-----------------------");
425
426 if (plugins_list == NULL)
427 return;
428
429 for (cp = plugins_list; cp != NULL; cp = cp->next)
430 {
431 new_draw_info_format (NDI_UNIQUE, 0, op, "%s, %s", cp->id, cp->fullname);
432 }
433 }
434
435 /* SYSTEM-RELATED HOOKS */
436
437 void *
438 cfapi_system_find_animation (int *type, ...)
439 {
440 va_list args;
441 static int rv;
442 char *anim;
443
444 va_start (args, type);
445 anim = va_arg (args, char *);
446
447 va_end (args);
448
449 rv = find_animation (anim);
450 *type = CFAPI_INT;
451 return &rv;
452 }
453
454 void *
455 cfapi_system_strdup (int *type, ...)
456 {
457 va_list args;
458 char *txt;
459
460 va_start (args, type);
461 txt = va_arg (args, char *);
462
463 va_end (args);
464 *type = CFAPI_STRING;
465 return strdup (txt);
466 }
467
468 void *
469 cfapi_system_register_global_event (int *type, ...)
470 {
471 va_list args;
472 int eventcode;
473 char *pname;
474 f_plug_api hook;
475 crossfire_plugin *cp;
476
477 va_start (args, type);
478 eventcode = va_arg (args, int);
479 pname = va_arg (args, char *);
480
481 hook = va_arg (args, f_plug_api);
482
483 va_end (args);
484 cp = plugins_find_plugin (pname);
485 cp->gevent[eventcode] = hook;
486 return NULL;
487 }
488
489 void *
490 cfapi_system_unregister_global_event (int *type, ...)
491 {
492 va_list args;
493 int eventcode;
494 char *pname;
495 crossfire_plugin *cp;
496
497 va_start (args, type);
498 eventcode = va_arg (args, int);
499 pname = va_arg (args, char *);
500
501 cp = plugins_find_plugin (pname);
502 cp->gevent[eventcode] = NULL;
503
504 va_end (args);
505 return NULL;
506 }
507
508 void *
509 cfapi_system_check_path (int *type, ...)
510 {
511 abort ();
512 }
513
514 void *
515 cfapi_system_directory (int *type, ...)
516 {
517 va_list args;
518 int dirtype;
519
520 va_start (args, type);
521
522 dirtype = va_arg (args, int);
523
524 va_end (args);
525
526 *type = CFAPI_STRING;
527
528 switch (dirtype)
529 {
530 case 0:
531 return (char *)settings.mapdir;
532 break;
533
534 case 1:
535 return (char *)settings.uniquedir;
536 break;
537
538 case 2:
539 return (char *)settings.tmpdir;
540 break;
541
542 case 3:
543 return (char *)settings.confdir;
544 break;
545
546 case 4:
547 return (char *)settings.localdir;
548 break;
549
550 case 5:
551 return (char *)settings.playerdir;
552 break;
553
554 case 6:
555 return (char *)settings.datadir;
556 break;
557 }
558
559 *type = CFAPI_NONE;
560 return NULL;
561 }
562
563
564 /* MAP RELATED HOOKS */
565
566 void *
567 cfapi_map_get_map (int *type, ...)
568 {
569 abort ();
570 }
571
572 void *
573 cfapi_map_has_been_loaded (int *type, ...)
574 {
575 abort ();
576 }
577
578 void *
579 cfapi_map_create_path (int *type, ...)
580 {
581 abort ();
582 }
583
584 void *
585 cfapi_map_get_map_property (int *type, ...)
586 {
587 abort ();
588 }
589
590 void *
591 cfapi_map_set_map_property (int *type, ...)
592 {
593 abort ();
594 }
595
596 void *
597 cfapi_map_out_of_map (int *type, ...)
598 {
599 abort ();
600 }
601
602 void *
603 cfapi_map_update_position (int *type, ...)
604 {
605 va_list args;
606 maptile *map;
607 int x, y;
608
609 va_start (args, type);
610
611 map = va_arg (args, maptile *);
612 x = va_arg (args, int);
613 y = va_arg (args, int);
614
615 map->at (x, y).flags_ &= ~P_UPTODATE;
616
617 va_end (args);
618 *type = CFAPI_NONE;
619 return NULL;
620 }
621
622 void *
623 cfapi_map_delete_map (int *type, ...)
624 {
625 abort ();
626 }
627
628 void *
629 cfapi_map_message (int *type, ...)
630 {
631 va_list args;
632 maptile *map;
633 char *string;
634 int color;
635
636 va_start (args, type);
637 map = va_arg (args, maptile *);
638 string = va_arg (args, char *);
639 color = va_arg (args, int);
640
641 va_end (args);
642
643 new_info_map (color, map, string);
644 *type = CFAPI_NONE;
645 return NULL;
646 }
647
648 void *
649 cfapi_map_get_object_at (int *type, ...)
650 {
651 va_list args;
652 maptile *map;
653 int x, y;
654 object *rv;
655
656 va_start (args, type);
657 map = va_arg (args, maptile *);
658 x = va_arg (args, int);
659 y = va_arg (args, int);
660
661 va_end (args);
662
663 rv = GET_MAP_OB (map, x, y);
664 *type = CFAPI_POBJECT;
665 return rv;
666 }
667
668 void *
669 cfapi_map_get_flags (int *type, ...)
670 {
671 va_list args;
672 sint16 x, y;
673 sint16 *nx, *ny;
674 static maptile *map;
675 maptile **newmap;
676 static int rv;
677
678 va_start (args, type);
679
680 map = va_arg (args, maptile *);
681 newmap = va_arg (args, maptile **);
682 x = va_arg (args, int);
683 y = va_arg (args, int);
684
685 nx = va_arg (args, sint16 *);
686 ny = va_arg (args, sint16 *);
687 va_end (args);
688
689 rv = get_map_flags (map, newmap, x, y, nx, ny);
690
691 *type = CFAPI_INT;
692 return &rv;
693 }
694
695 void *
696 cfapi_map_present_arch_by_name (int *type, ...)
697 {
698 va_list args;
699 object *rv;
700 int x, y;
701 maptile *map;
702 char *msg;
703
704 va_start (args, type);
705
706 msg = va_arg (args, char *);
707 map = va_arg (args, maptile *);
708 x = va_arg (args, int);
709 y = va_arg (args, int);
710
711 va_end (args);
712
713 rv = present_arch (archetype::find (msg), map, x, y);
714 *type = CFAPI_POBJECT;
715 return rv;
716 }
717
718 /* OBJECT-RELATED HOOKS */
719
720 void *
721 cfapi_object_move (int *type, ...)
722 {
723 va_list args;
724 int kind;
725 object *op;
726 object *activator;
727 player *pl;
728 int direction;
729 static int rv = 0;
730
731 va_start (args, type);
732 kind = va_arg (args, int);
733
734 switch (kind)
735 {
736 case 0:
737 op = va_arg (args, object *);
738 direction = va_arg (args, int);
739 activator = va_arg (args, object *);
740
741 va_end (args);
742 rv = move_ob (op, direction, activator);
743 break;
744
745 case 1:
746 pl = va_arg (args, player *);
747 direction = va_arg (args, int);
748
749 va_end (args);
750 rv = move_player (pl->ob, direction);
751 break;
752 }
753 *type = CFAPI_INT;
754 return &rv;
755 }
756
757 void *
758 cfapi_object_get_key (int *type, ...)
759 {
760 va_list args;
761 char *rv;
762 char *keyname;
763 object *op;
764
765 va_start (args, type);
766 op = va_arg (args, object *);
767 keyname = va_arg (args, char *);
768
769 va_end (args);
770
771 rv = (char *) get_ob_key_value (op, keyname);
772 *type = CFAPI_STRING;
773 return rv;
774 }
775
776 void *
777 cfapi_object_set_key (int *type, ...)
778 {
779 va_list args;
780 char *keyname;
781 char *value;
782 object *op;
783
784 va_start (args, type);
785 op = va_arg (args, object *);
786 keyname = va_arg (args, char *);
787 value = va_arg (args, char *);
788
789 va_end (args);
790
791 set_ob_key_value (op, keyname, value, 0);
792 *type = CFAPI_NONE;
793 return NULL;
794 }
795
796 void *
797 cfapi_object_get_property (int *type, ...)
798 {
799 abort ();
800 }
801
802 void *
803 cfapi_object_set_property (int *type, ...)
804 {
805 abort ();
806 }
807
808 void *
809 cfapi_object_apply_below (int *type, ...)
810 {
811 va_list args;
812 object *applier;
813
814 va_start (args, type);
815
816 applier = va_arg (args, object *);
817
818 va_end (args);
819
820 player_apply_below (applier);
821 *type = CFAPI_NONE;
822 return NULL;
823 }
824
825 void *
826 cfapi_object_apply (int *type, ...)
827 {
828 va_list args;
829 object *applied;
830 object *applier;
831 int aflags;
832 static int rv;
833
834 va_start (args, type);
835
836 applied = va_arg (args, object *);
837 applier = va_arg (args, object *);
838 aflags = va_arg (args, int);
839
840 va_end (args);
841
842 *type = CFAPI_INT;
843 rv = manual_apply (applier, applied, aflags);
844 return &rv;
845 }
846
847 void *
848 cfapi_object_identify (int *type, ...)
849 {
850 va_list args;
851 object *op;
852
853 va_start (args, type);
854
855 op = va_arg (args, object *);
856
857 va_end (args);
858
859 identify (op);
860 *type = CFAPI_NONE;
861 return NULL;
862 }
863
864 void *
865 cfapi_object_describe (int *type, ...)
866 {
867 va_list args;
868 object *op;
869 object *owner;
870
871 va_start (args, type);
872
873 op = va_arg (args, object *);
874 owner = va_arg (args, object *);
875
876 va_end (args);
877
878 *type = CFAPI_STRING;
879 return (char *)describe_item (op, owner);
880 }
881
882 void *
883 cfapi_object_drain (int *type, ...)
884 {
885 abort ();
886 }
887
888 void *
889 cfapi_object_fix (int *type, ...)
890 {
891 va_list args;
892 object *op;
893
894 va_start (args, type);
895
896 op = va_arg (args, object *);
897
898 va_end (args);
899
900 op->update_stats ();
901
902 *type = CFAPI_NONE;
903 return NULL;
904 }
905
906 void *
907 cfapi_object_give_skill (int *type, ...)
908 {
909 va_list args;
910
911 object *op;
912 char *skillname;
913
914 va_start (args, type);
915
916 op = va_arg (args, object *);
917 skillname = va_arg (args, char *);
918
919 va_end (args);
920
921 *type = CFAPI_POBJECT;
922 return give_skill_by_name (op, skillname);
923 }
924
925 void *
926 cfapi_object_transmute (int *type, ...)
927 {
928 va_list args;
929
930 object *op;
931 object *chg;
932
933 va_start (args, type);
934
935 op = va_arg (args, object *);
936 chg = va_arg (args, object *);
937
938 va_end (args);
939
940 transmute_materialname (op, chg);
941 *type = CFAPI_NONE;
942 return NULL;
943 }
944
945 void *
946 cfapi_object_remove (int *type, ...)
947 {
948 va_list args;
949 object *op;
950
951 va_start (args, type);
952
953 op = va_arg (args, object *);
954
955 va_end (args);
956
957 send_removed_object (op);
958 op->remove ();
959 *type = CFAPI_NONE;
960 return NULL;
961 }
962
963 void *
964 cfapi_object_delete (int *type, ...)
965 {
966 va_list args;
967 object *op;
968
969 va_start (args, type);
970
971 op = va_arg (args, object *);
972
973 va_end (args);
974
975 op->destroy ();
976
977 *type = CFAPI_NONE;
978 return NULL;
979 }
980
981 void *
982 cfapi_object_clone (int *type, ...)
983 {
984 va_list args;
985 object *op;
986 int kind;
987
988 va_start (args, type);
989
990 op = va_arg (args, object *);
991 kind = va_arg (args, int);
992
993 va_end (args);
994
995 if (kind == 0)
996 {
997 *type = CFAPI_POBJECT;
998 return object_create_clone (op);
999 }
1000 else
1001 {
1002 object *tmp = op->clone ();
1003 *type = CFAPI_POBJECT;
1004 return tmp;
1005 }
1006 }
1007 void *
1008 cfapi_object_find (int *type, ...)
1009 {
1010 va_list args;
1011 int ftype;
1012 void *rv;
1013 int ival;
1014 int ival2;
1015 char *sval;
1016 object *op;
1017
1018 va_start (args, type);
1019
1020 *type = CFAPI_POBJECT;
1021 ftype = va_arg (args, int);
1022
1023 switch (ftype)
1024 {
1025 case 0:
1026 ival = va_arg (args, int);
1027
1028 rv = find_object (ival);
1029 break;
1030
1031 case 1:
1032 sval = va_arg (args, char *);
1033
1034 rv = find_object_name (sval);
1035 break;
1036
1037 case 2:
1038 op = va_arg (args, object *);
1039 ival = va_arg (args, int);
1040 ival2 = va_arg (args, int);
1041
1042 rv = find_obj_by_type_subtype (op, ival, ival2);
1043 break;
1044
1045 case 3:
1046 op = va_arg (args, object *);
1047
1048 rv = op->in_player ();
1049 break;
1050
1051 default:
1052 rv = NULL;
1053 *type = CFAPI_NONE;
1054 break;
1055 }
1056
1057 va_end (args);
1058
1059 return rv;
1060 }
1061
1062 void *
1063 cfapi_object_create (int *type, ...)
1064 {
1065 abort ();
1066 }
1067
1068 void *
1069 cfapi_object_insert (int *type, ...)
1070 {
1071 va_list args;
1072 object *op;
1073 object *orig;
1074 maptile *map;
1075 int flag, x, y;
1076 int itype;
1077 char *arch_string;
1078 void *rv = NULL;
1079
1080 va_start (args, type);
1081
1082 op = va_arg (args, object *);
1083 itype = va_arg (args, int);
1084
1085 switch (itype)
1086 {
1087 case 0:
1088 map = va_arg (args, maptile *);
1089 orig = va_arg (args, object *);
1090 flag = va_arg (args, int);
1091 x = va_arg (args, int);
1092 y = va_arg (args, int);
1093
1094 rv = insert_ob_in_map_at (op, map, orig, flag, x, y);
1095 *type = CFAPI_POBJECT;
1096 break;
1097
1098 case 1:
1099 map = va_arg (args, maptile *);
1100 orig = va_arg (args, object *);
1101 flag = va_arg (args, int);
1102
1103 rv = insert_ob_in_map (op, map, orig, flag);
1104 *type = CFAPI_POBJECT;
1105 break;
1106
1107 case 2:
1108 arch_string = va_arg (args, char *);
1109
1110 replace_insert_ob_in_map (arch_string, op);
1111 *type = CFAPI_NONE;
1112 break;
1113
1114 case 3:
1115 orig = va_arg (args, object *);
1116
1117 rv = insert_ob_in_ob (op, orig);
1118 if (orig->type == PLAYER)
1119 {
1120 esrv_send_item (orig, op);
1121 }
1122 *type = CFAPI_POBJECT;
1123 break;
1124 }
1125
1126 va_end (args);
1127
1128 return rv;
1129 }
1130
1131 void *
1132 cfapi_object_split (int *type, ...)
1133 {
1134 va_list args;
1135
1136 int nr;
1137 object *op;
1138
1139 va_start (args, type);
1140
1141 op = va_arg (args, object *);
1142 nr = va_arg (args, int);
1143
1144 va_end (args);
1145 *type = CFAPI_POBJECT;
1146 return get_split_ob (op, nr);
1147 }
1148
1149 void *
1150 cfapi_object_merge (int *type, ...)
1151 {
1152 va_list args;
1153 object *op;
1154 object *op2;
1155
1156 va_start (args, type);
1157
1158 op = va_arg (args, object *);
1159 op2 = va_arg (args, object *);
1160
1161 va_end (args);
1162
1163
1164 *type = CFAPI_POBJECT;
1165 return merge_ob (op, op2);
1166 }
1167
1168 void *
1169 cfapi_object_distance (int *type, ...)
1170 {
1171 va_list args;
1172 static int rv;
1173 object *op;
1174 object *op2;
1175
1176 va_start (args, type);
1177
1178 op = va_arg (args, object *);
1179 op2 = va_arg (args, object *);
1180
1181 va_end (args);
1182
1183 *type = CFAPI_INT;
1184 rv = distance (op, op2);
1185 return &rv;
1186 }
1187
1188 void *
1189 cfapi_object_update (int *type, ...)
1190 {
1191 va_list args;
1192 int action;
1193 object *op;
1194
1195 va_start (args, type);
1196
1197 op = va_arg (args, object *);
1198 action = va_arg (args, int);
1199
1200 va_end (args);
1201
1202 update_object (op, action);
1203 *type = CFAPI_NONE;
1204 return NULL;
1205 }
1206
1207 void *
1208 cfapi_object_clear (int *type, ...)
1209 {
1210 abort ();
1211 }
1212
1213 void *
1214 cfapi_object_reset (int *type, ...)
1215 {
1216 abort ();
1217 }
1218
1219 void *
1220 cfapi_object_check_inventory (int *type, ...)
1221 {
1222 va_list args;
1223 object *op;
1224 object *op2;
1225 int checktype;
1226 object *ret = NULL;
1227
1228 va_start (args, type);
1229
1230 op = va_arg (args, object *);
1231 op2 = va_arg (args, object *);
1232 checktype = va_arg (args, int);
1233
1234 if (checktype == 0)
1235 {
1236 check_inv (op, op2);
1237 *type = CFAPI_NONE;
1238 }
1239 else
1240 {
1241 ret = check_inv_recursive (op, op2);
1242 *type = CFAPI_POBJECT;
1243 }
1244
1245 va_end (args);
1246
1247 return ret;
1248 }
1249
1250 void *
1251 cfapi_object_clean_object (int *type, ...)
1252 {
1253 abort ();
1254 }
1255
1256 void *
1257 cfapi_object_on_same_map (int *type, ...)
1258 {
1259 va_list args;
1260 static int rv;
1261 object *op1;
1262 object *op2;
1263
1264 va_start (args, type);
1265 op1 = va_arg (args, object *);
1266 op2 = va_arg (args, object *);
1267
1268 rv = on_same_map (op1, op2);
1269 va_end (args);
1270
1271 *type = CFAPI_INT;
1272 return &rv;
1273 }
1274
1275 void *
1276 cfapi_object_spring_trap (int *type, ...)
1277 {
1278 object *trap;
1279 object *victim;
1280 va_list args;
1281
1282 va_start (args, type);
1283 trap = va_arg (args, object *);
1284 victim = va_arg (args, object *);
1285
1286 va_end (args);
1287
1288 spring_trap (trap, victim);
1289 *type = CFAPI_NONE;
1290 return NULL;
1291 }
1292
1293 void *
1294 cfapi_object_check_trigger (int *type, ...)
1295 {
1296 object *op;
1297 object *cause;
1298 va_list args;
1299 static int rv;
1300
1301 va_start (args, type);
1302 op = va_arg (args, object *);
1303 cause = va_arg (args, object *);
1304
1305 va_end (args);
1306
1307 rv = check_trigger (op, cause);
1308 *type = CFAPI_INT;
1309 return &rv;
1310 }
1311
1312 void *
1313 cfapi_object_query_cost (int *type, ...)
1314 {
1315 object *op;
1316 object *who;
1317 int flags;
1318 va_list args;
1319 static int rv;
1320
1321 va_start (args, type);
1322 op = va_arg (args, object *);
1323 who = va_arg (args, object *);
1324 flags = va_arg (args, int);
1325
1326 va_end (args);
1327
1328 rv = query_cost (op, who, flags);
1329 *type = CFAPI_INT;
1330 return &rv;
1331 }
1332
1333 void *
1334 cfapi_object_query_money (int *type, ...)
1335 {
1336 object *op;
1337 va_list args;
1338 static int rv;
1339
1340 va_start (args, type);
1341 op = va_arg (args, object *);
1342
1343 va_end (args);
1344
1345 rv = query_money (op);
1346 *type = CFAPI_INT;
1347 return &rv;
1348 }
1349
1350 void *
1351 cfapi_object_cast (int *type, ...)
1352 {
1353 object *op;
1354 object *sp;
1355 int dir;
1356 char *str;
1357 object *caster;
1358 va_list args;
1359 static int rv;
1360
1361 va_start (args, type);
1362 op = va_arg (args, object *);
1363 caster = va_arg (args, object *);
1364 dir = va_arg (args, int);
1365 sp = va_arg (args, object *);
1366 str = va_arg (args, char *);
1367
1368 va_end (args);
1369 rv = cast_spell (op, caster, dir, sp, str);
1370 *type = CFAPI_INT;
1371 return &rv;
1372 }
1373
1374 void *
1375 cfapi_object_learn_spell (int *type, ...)
1376 {
1377 object *op;
1378 object *sp;
1379 int prayer;
1380 va_list args;
1381
1382 va_start (args, type);
1383 op = va_arg (args, object *);
1384 sp = va_arg (args, object *);
1385 prayer = va_arg (args, int);
1386
1387 va_end (args);
1388 do_learn_spell (op, sp, prayer);
1389 *type = CFAPI_NONE;
1390 return NULL;
1391 }
1392
1393 void *
1394 cfapi_object_forget_spell (int *type, ...)
1395 {
1396 object *op;
1397 object *sp;
1398 va_list args;
1399
1400 va_start (args, type);
1401 op = va_arg (args, object *);
1402 sp = va_arg (args, object *);
1403
1404 va_end (args);
1405 do_forget_spell (op, query_name (sp));
1406 *type = CFAPI_NONE;
1407 return NULL;
1408 }
1409
1410 void *
1411 cfapi_object_check_spell (int *type, ...)
1412 {
1413 object *op;
1414 char *spellname;
1415 va_list args;
1416 object *rv;
1417
1418 va_start (args, type);
1419 op = va_arg (args, object *);
1420 spellname = va_arg (args, char *);
1421
1422 va_end (args);
1423 rv = check_spell_known (op, spellname);
1424 *type = CFAPI_POBJECT;
1425 return rv;
1426 }
1427
1428 void *
1429 cfapi_object_pay_amount (int *type, ...)
1430 {
1431 object *op;
1432 uint64 amount;
1433 va_list args;
1434 static int rv;
1435
1436 va_start (args, type);
1437 op = va_arg (args, object *);
1438
1439 amount = va_arg (args, uint64);
1440 va_end (args);
1441
1442 rv = pay_for_amount (amount, op);
1443 *type = CFAPI_INT;
1444 return &rv;
1445 }
1446
1447 void *
1448 cfapi_object_pay_item (int *type, ...)
1449 {
1450 object *op;
1451 object *tobuy;
1452
1453 va_list args;
1454 static int rv;
1455
1456 va_start (args, type);
1457 tobuy = va_arg (args, object *);
1458 op = va_arg (args, object *);
1459
1460 va_end (args);
1461
1462 rv = pay_for_item (tobuy, op);
1463 *type = CFAPI_INT;
1464 return &rv;
1465 }
1466
1467 void *
1468 cfapi_object_transfer (int *type, ...)
1469 {
1470 object *op;
1471 object *originator;
1472 int x, y, randompos, ttype;
1473 va_list args;
1474 static int rv = 0;
1475 maptile *map;
1476
1477 va_start (args, type);
1478 op = va_arg (args, object *);
1479 ttype = va_arg (args, int);
1480
1481 switch (ttype)
1482 {
1483 case 0:
1484 x = va_arg (args, int);
1485 y = va_arg (args, int);
1486 randompos = va_arg (args, int);
1487 originator = va_arg (args, object *);
1488
1489 va_end (args);
1490
1491 rv = transfer_ob (op, x, y, randompos, originator);
1492 *type = CFAPI_INT;
1493 return &rv;
1494 break;
1495
1496 case 1:
1497 x = va_arg (args, int);
1498 y = va_arg (args, int);
1499 map = va_arg (args, maptile *);
1500
1501 va_end (args);
1502 if (x < 0 || y < 0)
1503 {
1504 x = map->enter_x;
1505 y = map->enter_y;
1506 }
1507
1508 /*
1509 originator = object::create();
1510 EXIT_PATH(originator) = map->path;
1511 EXIT_X(originator) = x;
1512 EXIT_Y(originator) = y;
1513 printf("B Transfer: X=%d, Y=%d, OP=%s\n", x, y, op->name);*/
1514 /*enter_exit(op, originator); */
1515 insert_ob_in_map_at (op, map, NULL, 0, x, y);
1516 /*printf("A Transfer: X=%d, Y=%d, MAP=%s\n", x, y, op->map->name);
1517 originator->destroy ();
1518 */
1519 *type = CFAPI_INT;
1520 return &rv;
1521 break;
1522
1523 default:
1524 *type = CFAPI_NONE;
1525 return NULL;
1526 break;
1527 }
1528 }
1529
1530 void *
1531 cfapi_object_find_archetype_inside (int *type, ...)
1532 {
1533 object *op;
1534 int critera;
1535 char *str;
1536 va_list args;
1537 object *rv;
1538
1539 *type = CFAPI_POBJECT;
1540 va_start (args, type);
1541 op = va_arg (args, object *);
1542 critera = va_arg (args, int);
1543
1544 switch (critera)
1545 {
1546 case 0: /* By name, either exact or from query_name */
1547 str = va_arg (args, char *);
1548
1549 rv = present_arch_in_ob (archetype::find (str), op);
1550 if (rv == NULL)
1551 {
1552 object *tmp;
1553
1554 /* Search by query_name instead */
1555 for (tmp = op->inv; tmp; tmp = tmp->below)
1556 {
1557 if (!strncmp (query_name (tmp), str, strlen (str)))
1558 rv = tmp;
1559 if (!strncmp (tmp->name, str, strlen (str)))
1560 rv = tmp;
1561 if (rv != NULL)
1562 break;
1563 }
1564 }
1565 break;
1566
1567 default:
1568 rv = NULL;
1569 break;
1570 }
1571 va_end (args);
1572
1573 if (rv == NULL)
1574 {
1575 *type = CFAPI_NONE;
1576 }
1577 return rv;
1578 }
1579
1580 void *
1581 cfapi_object_drop (int *type, ...)
1582 {
1583 object *op;
1584 object *author;
1585 va_list args;
1586
1587 va_start (args, type);
1588 op = va_arg (args, object *);
1589 author = va_arg (args, object *);
1590
1591 va_end (args);
1592
1593 if (QUERY_FLAG (op, FLAG_NO_DROP))
1594 return NULL;
1595 drop (author, op);
1596
1597 if (author->type == PLAYER)
1598 {
1599 author->contr->count = 0;
1600 author->contr->ns->floorbox_update ();
1601 }
1602
1603 *type = CFAPI_NONE;
1604 return NULL;
1605 }
1606
1607 void *
1608 cfapi_object_take (int *type, ...)
1609 {
1610 object *op;
1611 object *author;
1612 va_list args;
1613
1614 va_start (args, type);
1615 op = va_arg (args, object *);
1616 author = va_arg (args, object *);
1617
1618 va_end (args);
1619 pick_up (author, op);
1620
1621 *type = CFAPI_NONE;
1622 return NULL;
1623 }
1624
1625 void *
1626 cfapi_object_say (int *type, ...)
1627 {
1628 abort ();
1629 }
1630
1631 void *
1632 cfapi_object_speak (int *type, ...)
1633 {
1634 abort ();
1635 }
1636
1637 /* PLAYER SUBCLASS */
1638 void *
1639 cfapi_player_find (int *type, ...)
1640 {
1641 abort ();
1642 }
1643
1644 void *
1645 cfapi_player_message (int *type, ...)
1646 {
1647 va_list args;
1648 int flags;
1649 int pri;
1650 object *pl;
1651 char *buf;
1652
1653 va_start (args, type);
1654
1655 flags = va_arg (args, int);
1656 pri = va_arg (args, int);
1657 pl = va_arg (args, object *);
1658 buf = va_arg (args, char *);
1659
1660 va_end (args);
1661
1662 new_draw_info (flags, pri, pl, buf);
1663 *type = CFAPI_NONE;
1664 return NULL;
1665 }
1666
1667 void *
1668 cfapi_player_send_inventory (int *type, ...)
1669 {
1670 /* Currently a stub. Do we really need this anymore ? */
1671 *type = CFAPI_NONE;
1672 return NULL;
1673 }
1674
1675 void *
1676 cfapi_object_teleport (int *type, ...)
1677 {
1678 maptile *map;
1679 int x, y;
1680 object *who;
1681 static int result;
1682 va_list args;
1683
1684 va_start (args, type);
1685 who = va_arg (args, object *);
1686 map = va_arg (args, maptile *);
1687 x = va_arg (args, int);
1688 y = va_arg (args, int);
1689
1690 if (!out_of_map (map, x, y))
1691 {
1692 int k;
1693 object *tmp;
1694
1695 k = find_first_free_spot (who, map, x, y);
1696 if (k == -1)
1697 {
1698 result = 1;
1699 return &result;
1700 }
1701
1702 send_removed_object (who);
1703 who->remove ();
1704
1705 for (tmp = who; tmp != NULL; tmp = tmp->more)
1706 tmp->x = x + freearr_x[k] + (tmp->arch == NULL ? 0 : tmp->arch->x),
1707 tmp->y = y + freearr_y[k] + (tmp->arch == NULL ? 0 : tmp->arch->y);
1708
1709 insert_ob_in_map (who, map, NULL, 0);
1710 result = 0;
1711 }
1712
1713 return &result;
1714 }
1715
1716 void *
1717 cfapi_object_pickup (int *type, ...)
1718 {
1719 object *who;
1720 object *what;
1721 va_list args;
1722
1723 va_start (args, type);
1724 who = va_arg (args, object *);
1725 what = va_arg (args, object *);
1726
1727 va_end (args);
1728
1729 pick_up (who, what);
1730 *type = CFAPI_NONE;
1731 return NULL;
1732 }
1733
1734 /* Archetype-related functions */
1735 void *
1736 cfapi_archetype_get_first (int *type, ...)
1737 {
1738 abort ();
1739 }
1740
1741 void *
1742 cfapi_archetype_get_property (int *type, ...)
1743 {
1744 abort ();
1745 }
1746
1747 /* Party-related functions */
1748 void *
1749 cfapi_party_get_property (int *type, ...)
1750 {
1751 abort ();
1752 }
1753
1754 /* Regions-related functions */
1755 void *
1756 cfapi_region_get_property (int *type, ...)
1757 {
1758 abort ();
1759 }
1760
1761 /*****************************************************************************/
1762
1763 /* NEW PLUGIN STUFF ENDS HERE */
1764
1765 /*****************************************************************************/
1766
1767
1768 /*****************************************************************************/
1769
1770 /* Tries to find if a given command is handled by a plugin. */
1771
1772 /* Note that find_plugin_command is called *before* the internal commands are*/
1773
1774 /* checked, meaning that you can "overwrite" them. */
1775
1776 /*****************************************************************************/
1777 CommArray_s *
1778 find_plugin_command (char *cmd, object *op)
1779 {
1780 int i;
1781 crossfire_plugin *cp;
1782 CommArray_s *rtn_cmd;
1783
1784 if (plugins_list == NULL)
1785 return NULL;
1786
1787 for (cp = plugins_list; cp != NULL; cp = cp->next)
1788 {
1789 rtn_cmd = (CommArray_s *) cp->propfunc (&i, "command?", cmd);
1790 if (rtn_cmd)
1791 return rtn_cmd;
1792 }
1793 return NULL;
1794 }
1795
1796 /*****************************************************************************/
1797
1798 /* Plugins initialisation. Browses the plugins directory and call */
1799
1800 /* initOnePlugin for each file found. */
1801
1802 /* Returns 0 if at least one plugin was successfully loaded, -1 if not */
1803
1804 /*****************************************************************************/
1805 int
1806 initPlugins (void)
1807 {
1808 struct dirent *currentfile;
1809 DIR *plugdir;
1810 size_t l;
1811 char buf[MAX_BUF];
1812 char buf2[MAX_BUF];
1813 int result;
1814
1815 LOG (llevInfo, "Initialising plugins\n");
1816 strcpy (buf, LIBDIR);
1817 strcat (buf, "/plugins/");
1818 LOG (llevInfo, "Plugins directory is %s\n", buf);
1819
1820 plugins_init_perl ();
1821
1822 plugdir = opendir (buf);
1823 if (plugdir == NULL)
1824 return -1;
1825
1826 result = -1;
1827 while ((currentfile = readdir (plugdir)) != NULL)
1828 {
1829 l = strlen (currentfile->d_name);
1830 if (l > strlen (PLUGIN_SUFFIX))
1831 {
1832 if (strcmp (currentfile->d_name + l - strlen (PLUGIN_SUFFIX), PLUGIN_SUFFIX) == 0)
1833 {
1834 strcpy (buf2, buf);
1835 strcat (buf2, currentfile->d_name);
1836 LOG (llevInfo, " -> Loading plugin : %s\n", currentfile->d_name);
1837 if (plugins_init_plugin (buf2) == 0)
1838 result = 0;
1839 }
1840 }
1841 }
1842
1843 closedir (plugdir);
1844 return result;
1845 }