#include <stdlib.h> #include "scripting.h" #include "mud.h" lua_State * lua; void stackDump (lua_State *L) { int i; int top = lua_gettop(L); for (i = 1; i <= top; i++) { /* repeat for each level */ int t = lua_type(L, i); switch (t) { case LUA_TSTRING: /* strings */ printf("`%s'", lua_tostring(L, i)); break; case LUA_TBOOLEAN: /* booleans */ printf(lua_toboolean(L, i) ? "true" : "false"); break; case LUA_TNUMBER: /* numbers */ printf("%g", lua_tonumber(L, i)); break; default: /* other values */ printf("%s", lua_typename(L, t)); break; } printf(" "); /* put a separator */ } printf("\n"); /* end the listing */ } /* Two arguments, Filename to load, int indicating where file goes.*/ int lua_load_data( lua_State *L) { FILE * fp; char filename[MAX_BUFFER]; const char *text = luaL_checkstring(L, 1); char *key; char *data; int location = luaL_checkint(L, 2); bool found; bool done; int type; char * word; lua_pop(L, 2); switch(location) { case 1: /*Will be a constant later.*/ sprintf(filename, "../players/%s.luadat", text); break; } if ((fp = fopen(filename, "r")) == NULL) { lua_pushnil(L); return 1; } lua_newtable(L); word = fread_word(fp); done = FALSE; while (!done) { found = FALSE; switch (word[0]) { case 'K': key = fread_string(fp); type = fread_number(fp); data = fread_string(fp); switch(type) { case LUA_TSTRING: lua_pushstring(L, data); break; case LUA_TNUMBER: lua_pushinteger(L, atoi(data)); break; case LUA_TBOOLEAN: lua_pushboolean(L, atoi(data)); break; } lua_setfield(L, 1, key); found = TRUE; free(key); free(data); break; case 'E': if (!strcasecmp(word, "EOF")) {done = TRUE; found = TRUE; break;} break; } if (!found) { bug("read_dirfile: unexpected '%s' in file %s.", word, filename); } /* read one more */ if (!done) { word = fread_word(fp); } } fclose(fp); return 1; } /* Three arguments, filename to save to, int indicating where file goes. (Ignored for now), table of data,*/ int lua_save_data( lua_State *L) { FILE * fp; char filename[MAX_BUFFER]; const char *text = luaL_checkstring(L, 1); const char *key; int location = luaL_checkint(L, 2); int type; luaL_checktype(L, 3, LUA_TTABLE); switch (location) { case 1: /*Will be a constant later.*/ sprintf(filename, "../players/%s.luadat", text); break; } if ((fp = fopen(filename, "w")) == NULL) { bug("Unable to write to %s in lua_save_data, file type %d", text, type); lua_pop(L, 3); return 0; } /* table is in the stack at index 't' */ lua_pushnil(L); /* first key */ while (lua_next(L, 3) != 0) { /* uses 'key' (at index -2) and 'value' (at index -1) */ key = luaL_checkstring(L, -2); type = lua_type(L, -1); fprintf(fp, "Key %s~%d %s~\n", key, type,luaL_checkstring(L, -1)); /* removes 'value'; keeps 'key' for next iteration */ lua_pop(L, 1); } fprintf(fp, "%s\n", FILE_TERMINATOR); fclose(fp); lua_pop(L, 3); return 0; } /*One argument in lua. the string to be logged. */ int lua_log_string(lua_State * L) { const char *text = luaL_checkstring(L,1); lua_pop(L, 1); log_string(text); return 0; } /* Two arguments from lua. dMob (brain:plr), and arg. */ int lua_help(lua_State * l) { const char *text; char * arg; D_MOBILE *dMob; text = luaL_checkstring(l, -1); dMob = (D_MOBILE *)luaL_checkudata(l, 1, "dMobile"); lua_pop(l, 2); arg= strdup(text); cmd_help(dMob, arg); free(arg); return 0; } /* Two arguments from lua. dMob (brain:plr), and arg. */ int lua_linkdead(lua_State * l) { const char *text; char * arg; D_MOBILE *dMob; text = luaL_checkstring(l, -1); dMob = (D_MOBILE *)luaL_checkudata(l, 1, "dMobile"); lua_pop(l, 2); arg= strdup(text); cmd_linkdead(dMob, arg); free(arg); return 0; } /* Two arguments in lua. dMob (brain:plr), and arg, the text to be sent to the player*/ int lua_text_to_mobile(lua_State *l) { const char *text; D_MOBILE *dMob; text = luaL_checkstring(l, -1); dMob = (D_MOBILE *)luaL_checkudata(l, 1, "dMobile"); lua_pop(l, 2); text_to_mobile(dMob, text); return 0; } int lua_quit(lua_State *l) { const char *text; D_MOBILE *dMob; text = luaL_checkstring(l, -1); dMob = (D_MOBILE *)luaL_checkudata(l, 1, "dMobile"); lua_pop(l, 2); text_to_mobile(dMob, "Dream until the dream comes true.\n\r"); lua_getglobal(lua, "unregister_player"); dMobile_to_lua(dMob, lua); if (lua_pcall(lua, 1, 0, 0) != 0) { log_string("Error in unregister_player: %s", luaL_checkstring(lua,-1)); lua_pop(l, 1); return 0; } cmd_quit(dMob, NULL); return 0; } void register_func(const char * name, lua_CFunction func) { lua_pushcfunction(lua, func); lua_setglobal(lua, name); } void function_hook(lua_State * l , lua_Debug * ar) { char buf[MAX_BUFFER]; lua_getinfo(l, "n", ar); lua_getinfo(l, "S", ar); sprintf(buf, "function hook caught: %s, %s, %s, %s", ar->name, ar->namewhat, ar->what, ar->source ); puts(buf); } void dMobile_to_lua(D_MOBILE *dMob, lua_State *l) { lua_pushlightuserdata(l, dMob); luaL_getmetatable(l, "dMobile"); lua_setmetatable(l, -2); } void register_dMobile(D_MOBILE *dMob) { lua_getglobal(lua, "register_player"); dMobile_to_lua(dMob, lua); lua_pushstring(lua, dMob->name); if (lua_pcall(lua, 2, 0, 0) != 0) { log_string("Error in register_dMobile: %s", luaL_checkstring(lua,-1)); lua_pop(lua, 1); } } /* Two arguments in lua. dMob (brain:plr), and arg, which is ignored.*/ int lua_enter_shell(lua_State *l) { D_MOBILE *dMob; const char * text; char * arg; dMob = (D_MOBILE *)luaL_checkudata(l, 1, "dMobile"); text = luaL_checkstring(l, -1); if (IS_ADMIN(dMob)) { if (text[0] == '\0') { dMob->shell = TRUE; text_to_mobile(dMob, "Entering shell.\n\r"); } else { arg = strdup(text); dMob->shell = TRUE; handle_cmd_input(dMob->socket , arg); free(arg); dMob->shell = FALSE; } } else { text_to_mobile(dMob, "Insufficent security to enter the shell.\n\r"); } return 0; } void input_to_lua(D_MOBILE *dMob, char * command, char * arg) { lua_getglobal(lua, "player_input"); dMobile_to_lua(dMob, lua); lua_pushstring(lua, command); lua_pushstring(lua, arg); if (lua_pcall(lua, 3, 0, 0) != 0) { log_string("Error in input_to_lua: %s", luaL_checkstring(lua,-1)); lua_pop(lua, 1); } } int lua_code_level(lua_State *l) { lua_Debug debug_info; int level= 0; int rlevel = 5; DIRFILE_ENTRY *targ; lua_pop(l, 1); while (lua_getstack(l, level++, &debug_info) == 1) { lua_getinfo(l, "n", &debug_info); lua_getinfo(l, "S", &debug_info); lua_getinfo(l, "l", &debug_info); /*sprintf(buf, "Stack Frame %d: %s, %s, %s, %s %d",level, debug_info.name, debug_info.namewhat, debug_info.what, debug_info.source, debug_info.currentline ); puts(buf); */ if (strcasecmp(debug_info.source, "=[C]") && strcasecmp(debug_info.source, "=(tail call)")) { targ = get_dirfile_from_real_path(debug_info.source, NULL); if (rlevel < targ->eSecurity) rlevel = targ->eSecurity; } } lua_pushinteger(l, rlevel); return 1; } bool is_code_core(lua_State *l) { lua_Debug debug_info; int level= 0; bool core = TRUE; DIRFILE_ENTRY *targ; lua_pop(l, 1); while (lua_getstack(l, level++, &debug_info) == 1) { lua_getinfo(l, "n", &debug_info); lua_getinfo(l, "S", &debug_info); lua_getinfo(l, "l", &debug_info); /*sprintf(buf, "Stack Frame %d: %s, %s, %s, %s %d",level, debug_info.name, debug_info.namewhat, debug_info.what, debug_info.source, debug_info.currentline ); puts(buf);*/ if (strcasecmp(debug_info.source, "=[C]") && strcasecmp(debug_info.source, "=(tail call)")) { targ = get_dirfile_from_real_path(debug_info.source, NULL); if (!strcasecmp(targ->creator, "core")) { core = TRUE; } else { core = FALSE; break; } } else { core = TRUE; } } return core; } /*No arguments. */ int lua_is_code_core(lua_State *l) { if (is_code_core(l) == TRUE) { lua_pushboolean(l, TRUE); } else { lua_pushboolean(l,FALSE); } return 1; } void init_lua() { lua = lua_open(); luaL_openlibs(lua); log_string("Lua Initied"); register_func("log_string", lua_log_string); register_func("text_to_player", lua_text_to_mobile); register_func("enter_shell", lua_enter_shell); register_func("save_data", lua_save_data); register_func("do_quit", lua_quit); register_func("load_data", lua_load_data); register_func("is_core", lua_is_code_core); register_func("help", lua_help); register_func("linkdead", lua_linkdead); register_func("code_level", lua_code_level); luaL_newmetatable(lua, "dMobile" ); }