--- deliantra/server/plugins/cfperl/cfperl.xs 2006/02/07 23:29:55 1.14 +++ deliantra/server/plugins/cfperl/cfperl.xs 2006/02/10 07:37:13 1.22 @@ -30,8 +30,8 @@ #undef save_long // clashes with libproto.h -#define PLUGIN_NAME "cfperl" -#define PLUGIN_VERSION "cfperl 0.0" +#define PLUGIN_NAME "perl" +#define PLUGIN_VERSION "cfperl 0.1" #ifndef __CEXTRACT__ #include @@ -49,12 +49,16 @@ #include "perlxsi.c" +typedef object object_ornull; +typedef mapstruct mapstruct_ornull; + static f_plug_api gethook; static f_plug_api registerGlobalEvent; static f_plug_api unregisterGlobalEvent; static f_plug_api systemDirectory; static f_plug_api object_set_property; static f_plug_api map_get_map; +static f_plug_api object_insert; typedef struct { @@ -64,7 +68,8 @@ char message[1024]; int fix; int event_code; - char options[1024]; + char extension[1024]; // name field, should invoke specific perl extension + char options[1024]; // slaying field of event_connectors int returnvalue; } CFPContext; @@ -81,7 +86,12 @@ void clean_obj_cache () { - int todo = 10; + static int count; + + if (++count & 7) + return; + + int todo = 1000; do { I32 klen; @@ -90,10 +100,10 @@ if (he) { - SV *sv = SvRV (hv_iterval (obj_cache, he)); + SV *sv = hv_iterval (obj_cache, he); - // emopty and unreferened? nuke it - if (SvREFCNT (sv) == 1 && !HvFILL ((HV *)sv)) + // empty and unreferenced? nuke it + if (SvREFCNT (sv) == 1 && SvREFCNT (SvRV (sv)) == 1 && !HvFILL ((HV *)(SvRV (sv)))) { hv_delete (obj_cache, HeKEY (he), HeKLEN (he), G_DISCARD); todo++; @@ -108,12 +118,14 @@ static SV * newSVptr (void *ptr, const char *klass) { + SV *sv; + if (!ptr) return &PL_sv_undef; - HV *hv = newHV (); - sv_magic ((SV *)hv, 0, PERL_MAGIC_ext, (char *)ptr, 0); - return sv_bless (newRV_noinc ((SV *)hv), gv_stashpv (klass, 1)); + sv = newSV (0); + sv_magic (sv, 0, PERL_MAGIC_ext, (char *)ptr, 0); + return sv_bless (newRV_noinc (sv), gv_stashpv (klass, 1)); } static SV * @@ -130,7 +142,9 @@ sv = *he; else { - sv = newSVptr (ptr, klass); + HV *hv = newHV (); + sv_magic ((SV *)hv, 0, PERL_MAGIC_ext, (char *)ptr, 0); + sv = sv_bless (newRV_noinc ((SV *)hv), gv_stashpv (klass, 1)); hv_store (obj_cache, (char *)&ptr, sizeof (ptr), sv, 0); } @@ -161,6 +175,15 @@ return (long)mg->mg_ptr; } +static long +SvPTR_ornull (SV *sv, const char *klass) +{ + if (SvOK (sv)) + return SvPTR (sv, klass); + else + return 0; +} + SV * newSVcfapi (int type, ...) { @@ -246,7 +269,7 @@ ///////////////////////////////////////////////////////////////////////////// void -inject_event (CFPContext *context) +inject_event (const char *func, CFPContext *context) { dSP; @@ -255,9 +278,6 @@ PUSHMARK (SP); - EXTEND (SP, 2); - //PUSHs (sv_2mortal (newSViv (type))); - HV *hv = newHV (); #define hv_context(type,addr,expr) hv_store (hv, #expr, sizeof (#expr) - 1, newSVcfapi (type, addr context->expr), 0) hv_context (CFAPI_POBJECT, ,who); @@ -267,11 +287,12 @@ hv_context (CFAPI_INT ,&,fix); hv_context (CFAPI_INT ,&,event_code); hv_context (CFAPI_STRING , ,options); + hv_context (CFAPI_STRING , ,extension); - PUSHs (sv_2mortal (newRV_noinc ((SV *)hv))); + XPUSHs (sv_2mortal (newRV_noinc ((SV *)hv))); PUTBACK; - int count = call_pv ("cf::inject_event", G_SCALAR | G_EVAL); + int count = call_pv (func, G_SCALAR | G_EVAL); SPAGAIN; if (SvTRUE (ERRSV)) @@ -392,6 +413,7 @@ systemDirectory = gethook (&rtype, hooktype, "cfapi_system_directory"); object_set_property = gethook (&rtype, hooktype, "cfapi_object_set_property"); map_get_map = gethook (&rtype, hooktype, "cfapi_map_get_map"); + object_insert = gethook (&rtype, hooktype, "cfapi_object_insert"); cf_init_plugin (gethook); @@ -490,7 +512,7 @@ context.activator = pl->ob; buf = va_arg (args, char *); if (buf != 0) - strcpy (context.message, buf); + strncpy (context.message, buf, sizeof (context.message)); break; case EVENT_SHOUT: @@ -499,7 +521,7 @@ context.activator = va_arg (args, object *); buf = va_arg (args, char *); if (buf != 0) - strcpy (context.message, buf); + strncpy (context.message, buf, sizeof (context.message)); break; case EVENT_CLOCK: @@ -512,7 +534,7 @@ case EVENT_MAPRESET: buf = va_arg (args, char *); if (buf != 0) - strcpy (context.message, buf); + strncpy (context.message, buf, sizeof (context.message)); break; } @@ -520,16 +542,13 @@ if (context.event_code == EVENT_FREE_OB) { - SV *sv = hv_delete (obj_cache, (char *)&context.activator, sizeof (object *), 0); + SV *sv = hv_delete (obj_cache, (char *)&context.activator, sizeof (void *), 0); if (sv) - { - clearSVptr (sv); - SvREFCNT_dec (sv); - } + clearSVptr (sv); } else - inject_event (&context); + inject_event ("cf::inject_global_event", &context); rv = context.returnvalue; @@ -555,17 +574,18 @@ context.event_code = va_arg (args, int); context.activator = va_arg (args, object *); context.third = va_arg (args, object *); - buf = va_arg (args, char *); + buf = va_arg (args, char *); if (buf != 0) - strcpy (context.message, buf); + strncpy (context.message, buf, sizeof (context.message)); context.fix = va_arg (args, int); - strcpy (context.options, va_arg (args, char *)); + strncpy (context.extension, va_arg (args, char *), sizeof (context.extension)); + strncpy (context.options, va_arg (args, char *), sizeof (context.options)); context.returnvalue = 0; va_end (args); - inject_event (&context); + inject_event ("cf::inject_event", &context); rv = context.returnvalue; return &rv; @@ -1176,7 +1196,7 @@ void cf_object_set_flag (object *op, int flag, int value) -void cf_object_move (object *op, object *originator, int dir) +void cf_object_move (object *op, int dir, object *originator = op) void cf_object_apply (object *op, object *author, int flags = 0) @@ -1192,7 +1212,7 @@ int cf_object_change_map (object *op, int x, int y, mapstruct *map) -object *cf_object_clone (object *op, int clonetype) +object *cf_object_clone (object *op, int clonetype = 0) int cf_object_pay_item (object *op, object *buyer) @@ -1246,15 +1266,14 @@ void cf_object_set_key (object *op, char *keyname, char *value) -char * -base_name (object *ob, int plural) - CODE: - RETVAL = cf_query_base_name (ob, plural); - OUTPUT: RETVAL +MODULE = cf PACKAGE = cf::object PREFIX = cf_ -MODULE = cf PACKAGE = cf::object PREFIX = cf_object_ +void cf_fix_object (object *pl) + ALIAS: fix = 0 + +object *cf_insert_ob_in_ob (object *ob, object *where) -object *cf_create_object_by_name (const char *name = 0) +object *create_object_by_name (const char *name = 0) PROTOTYPE: ;$ ALIAS: create_object = 0 @@ -1264,10 +1283,43 @@ OUTPUT: RETVAL -void cf_fix_object (object *pl) - ALIAS: fix = 0 +object *insert_ob_in_map_at (object *ob, mapstruct *where, object_ornull *orig, int flag, int x, int y) + PROTOTYPE: $$$$$$ + CODE: +{ + int unused_type; + RETVAL = (object *)object_insert (&unused_type, ob, 0, where, orig, flag, x, y); +} -object *cf_insert_ob_in_ob (object *ob, object *where) +object *get_nearest_player (object *ob) + ALIAS: nearest_player = 0 + PREINIT: + extern object *get_nearest_player (object *); + +void rangevector (object *ob, object *other, int flags = 0) + PROTOTYPE: $$;$ + PPCODE: +{ + rv_vector rv; + get_rangevector (ob, other, &rv, flags); + EXTEND (SP, 5); + PUSHs (newSVuv (rv.distance)); + PUSHs (newSViv (rv.distance_x)); + PUSHs (newSViv (rv.distance_y)); + PUSHs (newSViv (rv.direction)); + PUSHs (newSVcfapi (CFAPI_POBJECT, rv.part)); +} + +bool on_same_map_as (object *ob, object *other) + CODE: + RETVAL = on_same_map (ob, other); + OUTPUT: RETVAL + +char * +base_name (object *ob, int plural) + CODE: + RETVAL = cf_query_base_name (ob, plural); + OUTPUT: RETVAL MODULE = cf PACKAGE = cf::object::player PREFIX = cf_player_ @@ -1281,6 +1333,11 @@ object *cf_player_send_inventory (object *op) +player *contr (object *op) + CODE: + RETVAL = op->contr; + OUTPUT: RETVAL + char *cf_player_get_ip (object *op) ALIAS: ip = 0 @@ -1304,12 +1361,33 @@ void cf_player_move (player *pl, int dir) +void MapNewmapCmd (player *pl) + # nonstandard object *ob (player *pl) CODE: RETVAL = pl->ob; OUTPUT: RETVAL +player *first () + CODE: + RETVAL = first_player; + OUTPUT: RETVAL + +player *next (player *pl) + CODE: + RETVAL = pl->next; + OUTPUT: RETVAL + +void +list () + PPCODE: +{ + player *pl; + for (pl = first_player; pl; pl = pl->next) + XPUSHs (newSVcfapi (CFAPI_PPLAYER, pl)); +} + MODULE = cf PACKAGE = cf::map PREFIX = cf_map_