… | |
… | |
51 | |
51 | |
52 | static f_plug_api gethook = cfapi_get_hooks; |
52 | static f_plug_api gethook = cfapi_get_hooks; |
53 | static f_plug_api object_set_property = cfapi_object_set_property; |
53 | static f_plug_api object_set_property = cfapi_object_set_property; |
54 | static f_plug_api object_insert = cfapi_object_insert; |
54 | static f_plug_api object_insert = cfapi_object_insert; |
55 | |
55 | |
56 | static HV *obj_cache; |
|
|
57 | static PerlInterpreter *perl; |
56 | static PerlInterpreter *perl; |
58 | |
57 | |
59 | static AV *cb_global, *cb_object, *cb_player, *cb_type, *cb_map; |
58 | static AV *cb_global, *cb_object, *cb_player, *cb_type, *cb_map; |
60 | |
59 | |
61 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
60 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
… | |
… | |
81 | |
80 | |
82 | if (!obj->self) |
81 | if (!obj->self) |
83 | obj->self = newSVptr (obj, klass); |
82 | obj->self = newSVptr (obj, klass); |
84 | |
83 | |
85 | return newSVsv (obj->self); |
84 | return newSVsv (obj->self); |
86 | } |
|
|
87 | |
|
|
88 | static void |
|
|
89 | SVptr_cache_set (void *ptr, SV *sv) |
|
|
90 | { |
|
|
91 | hv_store (obj_cache, (char *)&ptr, sizeof (ptr), sv, 0); |
|
|
92 | } |
|
|
93 | |
|
|
94 | static SV * |
|
|
95 | SVptr_cache_get (void *ptr) |
|
|
96 | { |
|
|
97 | SV **he = hv_fetch (obj_cache, (char *)&ptr, sizeof (ptr), 0); |
|
|
98 | |
|
|
99 | return he ? *he : 0; |
|
|
100 | } |
|
|
101 | |
|
|
102 | static SV * |
|
|
103 | newSVptr_cached (void *ptr, const char *klass) |
|
|
104 | { |
|
|
105 | SV *sv; |
|
|
106 | |
|
|
107 | if (!ptr) |
|
|
108 | return &PL_sv_undef; |
|
|
109 | |
|
|
110 | sv = SVptr_cache_get (ptr); |
|
|
111 | |
|
|
112 | if (!sv) |
|
|
113 | { |
|
|
114 | HV *hv = newHV (); |
|
|
115 | sv_magic ((SV *)hv, 0, PERL_MAGIC_ext, (char *)ptr, 0); |
|
|
116 | sv = sv_bless (newRV_noinc ((SV *)hv), gv_stashpv (klass, 1)); |
|
|
117 | |
|
|
118 | SVptr_cache_set (ptr, sv); |
|
|
119 | } |
|
|
120 | |
|
|
121 | return newSVsv (sv); |
|
|
122 | } |
85 | } |
123 | |
86 | |
124 | static void |
87 | static void |
125 | clearSVptr (SV *sv) |
88 | clearSVptr (SV *sv) |
126 | { |
89 | { |
… | |
… | |
182 | |
145 | |
183 | //TODO: |
146 | //TODO: |
184 | inline SV *to_sv (New_Face * v) { return to_sv (v->name); } |
147 | inline SV *to_sv (New_Face * v) { return to_sv (v->name); } |
185 | inline SV *to_sv (treasurelist * v) { return to_sv (v->name); } |
148 | inline SV *to_sv (treasurelist * v) { return to_sv (v->name); } |
186 | |
149 | |
|
|
150 | inline SV *to_sv (UUID v) |
|
|
151 | { |
|
|
152 | char buf[128]; |
|
|
153 | snprintf (buf, 128, "<1,%llx>", (unsigned long long)v.seq); |
|
|
154 | return newSVpv (buf, 0); |
|
|
155 | } |
|
|
156 | |
187 | inline void sv_to (SV *sv, shstr &v) { v = SvOK (sv) ? SvPV_nolen (sv) : 0; } |
157 | inline void sv_to (SV *sv, shstr &v) { v = SvOK (sv) ? SvPV_nolen (sv) : 0; } |
188 | inline void sv_to (SV *sv, char * &v) { free (v); v = SvOK (sv) ? strdup (SvPV_nolen (sv)) : 0; } //TODO: verify that all simple pointers are strdup-managed |
158 | inline void sv_to (SV *sv, char * &v) { free (v); v = SvOK (sv) ? strdup (SvPV_nolen (sv)) : 0; } //TODO: verify that all simple pointers are strdup-managed |
189 | inline void sv_to (SV *sv, bool &v) { v = SvIV (sv); } |
159 | inline void sv_to (SV *sv, bool &v) { v = SvIV (sv); } |
190 | inline void sv_to (SV *sv, signed char &v) { v = SvIV (sv); } |
160 | inline void sv_to (SV *sv, signed char &v) { v = SvIV (sv); } |
191 | inline void sv_to (SV *sv, unsigned char &v) { v = SvIV (sv); } |
161 | inline void sv_to (SV *sv, unsigned char &v) { v = SvIV (sv); } |
… | |
… | |
214 | inline void sv_to (SV *sv, refptr<T> &v) { T *tmp; sv_to (sv, tmp); v = tmp; } |
184 | inline void sv_to (SV *sv, refptr<T> &v) { T *tmp; sv_to (sv, tmp); v = tmp; } |
215 | |
185 | |
216 | template<int N> |
186 | template<int N> |
217 | inline void sv_to (SV *sv, char (&v)[N]) { assign (v, SvPV_nolen (sv)); } |
187 | inline void sv_to (SV *sv, char (&v)[N]) { assign (v, SvPV_nolen (sv)); } |
218 | |
188 | |
|
|
189 | inline void sv_to (SV *sv, UUID &v) |
|
|
190 | { |
|
|
191 | unsigned int version; |
|
|
192 | unsigned long long seq; |
|
|
193 | |
|
|
194 | if (2 != sscanf (SvPV_nolen (sv), "<%d.%llx>", &version, &seq) || 1 != version) |
|
|
195 | croak ("unparsable uuid: %s", SvPV_nolen (sv)); |
|
|
196 | |
|
|
197 | v.seq = seq; |
|
|
198 | } |
|
|
199 | |
219 | static SV * |
200 | static SV * |
220 | newSVdt_va (va_list &ap, data_type type) |
201 | newSVdt_va (va_list &ap, data_type type) |
221 | { |
202 | { |
222 | SV *sv; |
203 | SV *sv; |
223 | |
204 | |
… | |
… | |
479 | call_pv ("cf::object_freezer_save", G_VOID | G_DISCARD | G_EVAL); |
460 | call_pv ("cf::object_freezer_save", G_VOID | G_DISCARD | G_EVAL); |
480 | FREETMPS; |
461 | FREETMPS; |
481 | LEAVE; |
462 | LEAVE; |
482 | } |
463 | } |
483 | |
464 | |
|
|
465 | char *object_freezer::as_string () |
|
|
466 | { |
|
|
467 | dSP; |
|
|
468 | ENTER; |
|
|
469 | SAVETMPS; |
|
|
470 | PUSHMARK (SP); |
|
|
471 | EXTEND (SP, 3); |
|
|
472 | PUSHs (sv_2mortal (newRV_noinc (newSVpvn ((char *)linearise (), size ())))); |
|
|
473 | PUSHs (sv_2mortal (newRV_inc ((SV *)av))); |
|
|
474 | PUTBACK; |
|
|
475 | |
|
|
476 | char *res = call_pv ("cf::object_freezer_as_string", G_SCALAR | G_EVAL) > 0 |
|
|
477 | ? strdup (SvPVbyte_nolen (POPs)) |
|
|
478 | : strdup ("[fatal error]"); |
|
|
479 | |
|
|
480 | FREETMPS; |
|
|
481 | LEAVE; |
|
|
482 | |
|
|
483 | return res; |
|
|
484 | } |
|
|
485 | |
484 | int fprintf (object_freezer &freezer, const char *format, ...) |
486 | int fprintf (object_freezer &freezer, const char *format, ...) |
485 | { |
487 | { |
486 | va_list ap; |
488 | va_list ap; |
487 | |
489 | |
488 | va_start (ap, format); |
490 | va_start (ap, format); |
… | |
… | |
497 | |
499 | |
498 | int fputs (const char *s, object_freezer &freezer) |
500 | int fputs (const char *s, object_freezer &freezer) |
499 | { |
501 | { |
500 | freezer.add (s); |
502 | freezer.add (s); |
501 | } |
503 | } |
|
|
504 | |
|
|
505 | static const char thawer_eof[] = "\n\n\n\0\0\0"; |
502 | |
506 | |
503 | object_thawer::object_thawer (const char *filename) |
507 | object_thawer::object_thawer (const char *filename) |
504 | { |
508 | { |
505 | static const char eof[] = "\n\n\n\0\0\0"; |
509 | static const char eof[] = "\n\n\n\0\0\0"; |
506 | |
510 | |
… | |
… | |
544 | |
548 | |
545 | PUTBACK; |
549 | PUTBACK; |
546 | FREETMPS; |
550 | FREETMPS; |
547 | LEAVE; |
551 | LEAVE; |
548 | } |
552 | } |
|
|
553 | } |
|
|
554 | |
|
|
555 | object_thawer::object_thawer (const char *data, AV *perlav) |
|
|
556 | { |
|
|
557 | av = perlav; |
|
|
558 | text = newSVpv (data, 0); |
|
|
559 | sv_catpv (text, thawer_eof); |
|
|
560 | line = SvPVbyte_nolen (text); |
549 | } |
561 | } |
550 | |
562 | |
551 | void object_thawer::get (data_type type, void *obj, attachable_base *ext, int oid) |
563 | void object_thawer::get (data_type type, void *obj, attachable_base *ext, int oid) |
552 | { |
564 | { |
553 | if (!av || oid < 0) // this is actually an error of sorts |
565 | if (!av || oid < 0) // this is actually an error of sorts |
… | |
… | |
869 | if (perl_parse (perl, xs_init, 2, argv, (char **)NULL) || perl_run (perl)) |
881 | if (perl_parse (perl, xs_init, 2, argv, (char **)NULL) || perl_run (perl)) |
870 | { |
882 | { |
871 | printf ("unable to initialize perl-interpreter, aborting.\n"); |
883 | printf ("unable to initialize perl-interpreter, aborting.\n"); |
872 | exit (EXIT_FAILURE); |
884 | exit (EXIT_FAILURE); |
873 | } |
885 | } |
874 | |
|
|
875 | obj_cache = newHV (); |
|
|
876 | } |
886 | } |
877 | |
887 | |
878 | void cfperl_main () |
888 | void cfperl_main () |
879 | { |
889 | { |
880 | dSP; |
890 | dSP; |
… | |
… | |
1081 | MODULE = cf PACKAGE = cf PREFIX = cf_ |
1091 | MODULE = cf PACKAGE = cf PREFIX = cf_ |
1082 | |
1092 | |
1083 | BOOT: |
1093 | BOOT: |
1084 | { |
1094 | { |
1085 | HV *stash = gv_stashpv ("cf", 1); |
1095 | HV *stash = gv_stashpv ("cf", 1); |
|
|
1096 | |
|
|
1097 | newCONSTSUB (stash, "VERSION", newSVpv (VERSION, sizeof (VERSION) - 1)); |
1086 | |
1098 | |
1087 | static const struct { |
1099 | static const struct { |
1088 | const char *name; |
1100 | const char *name; |
1089 | IV iv; |
1101 | IV iv; |
1090 | } *civ, const_iv[] = { |
1102 | } *civ, const_iv[] = { |
… | |
… | |
2008 | void kill_player (object *op) |
2020 | void kill_player (object *op) |
2009 | |
2021 | |
2010 | void esrv_update_item (object *op, int what, object *item) |
2022 | void esrv_update_item (object *op, int what, object *item) |
2011 | C_ARGS: what, op, item |
2023 | C_ARGS: what, op, item |
2012 | |
2024 | |
|
|
2025 | void clear_los (object *op) |
|
|
2026 | |
|
|
2027 | int command_reset (object *op, char *params) |
|
|
2028 | |
|
|
2029 | int command_teleport (object *op, char *params) |
|
|
2030 | |
|
|
2031 | int command_summon (object *op, char *params) |
|
|
2032 | |
|
|
2033 | int command_arrest (object *op, char *params) |
|
|
2034 | |
|
|
2035 | int command_kick (object *op, char *params) |
|
|
2036 | |
|
|
2037 | int command_banish (object *op, char *params) |
|
|
2038 | |
|
|
2039 | |
2013 | MODULE = cf PACKAGE = cf::player PREFIX = cf_player_ |
2040 | MODULE = cf PACKAGE = cf::player PREFIX = cf_player_ |
2014 | |
2041 | |
2015 | INCLUDE: $PERL genacc player ../include/newserver.h ../include/player.h | |
2042 | INCLUDE: $PERL genacc player ../include/newserver.h ../include/player.h | |
2016 | |
2043 | |
2017 | char * |
2044 | char * |
… | |
… | |
2214 | get_connection (maptile *map, long connection) |
2241 | get_connection (maptile *map, long connection) |
2215 | PPCODE: |
2242 | PPCODE: |
2216 | oblinkpt *obp = get_connection_links (map, connection); |
2243 | oblinkpt *obp = get_connection_links (map, connection); |
2217 | if (obp) |
2244 | if (obp) |
2218 | for (objectlink *ol = obp->link; ol; ol = ol->next) |
2245 | for (objectlink *ol = obp->link; ol; ol = ol->next) |
2219 | XPUSHs (sv_2mortal (newSVcfapi (CFAPI_POBJECT, ol->ob))); |
2246 | XPUSHs (sv_2mortal (newSVcfapi (CFAPI_POBJECT, (object *)ol->ob))); |
2220 | |
2247 | |
2221 | object *cf_map_insert_object_there (maptile *where, object *op, object *originator, int flags) |
2248 | object *cf_map_insert_object_there (maptile *where, object *op, object *originator, int flags) |
2222 | |
2249 | |
2223 | object *cf_map_insert_object (maptile *where, object* op, int x, int y) |
2250 | object *cf_map_insert_object (maptile *where, object* op, int x, int y) |
2224 | |
2251 | |
… | |
… | |
2286 | case 7: RETVAL = newSVuv ( GET_MAP_MOVE_OFF (obj, x, y)); break; |
2313 | case 7: RETVAL = newSVuv ( GET_MAP_MOVE_OFF (obj, x, y)); break; |
2287 | } |
2314 | } |
2288 | OUTPUT: |
2315 | OUTPUT: |
2289 | RETVAL |
2316 | RETVAL |
2290 | |
2317 | |
|
|
2318 | void fix_walls (maptile *map, int x, int y) |
|
|
2319 | |
|
|
2320 | void fix_walls_around (maptile *map, int x, int y) |
2291 | |
2321 | |
2292 | MODULE = cf PACKAGE = cf::arch |
2322 | MODULE = cf PACKAGE = cf::arch |
2293 | |
2323 | |
2294 | archetype *find (const char *name) |
2324 | archetype *find (const char *name) |
2295 | CODE: |
2325 | CODE: |