TileDef read_tiledef(lua_State *L, int index, u8 drawtype) { if(index < 0) index = lua_gettop(L) + 1 + index; TileDef tiledef; bool default_tiling = true; bool default_culling = true; switch (drawtype) { case NDT_PLANTLIKE: case NDT_FIRELIKE: default_tiling = false; // "break" is omitted here intentionaly, as PLANTLIKE // FIRELIKE drawtype both should default to having // backface_culling to false. case NDT_MESH: case NDT_LIQUID: default_culling = false; break; default: break; } // key at index -2 and value at index if(lua_isstring(L, index)){ // "default_lava.png" tiledef.name = lua_tostring(L, index); tiledef.tileable_vertical = default_tiling; tiledef.tileable_horizontal = default_tiling; tiledef.backface_culling = default_culling; } else if(lua_istable(L, index)) { // {name="default_lava.png", animation={}} tiledef.name = ""; getstringfield(L, index, "name", tiledef.name); getstringfield(L, index, "image", tiledef.name); // MaterialSpec compat. tiledef.backface_culling = getboolfield_default( L, index, "backface_culling", default_culling); tiledef.tileable_horizontal = getboolfield_default( L, index, "tileable_horizontal", default_tiling); tiledef.tileable_vertical = getboolfield_default( L, index, "tileable_vertical", default_tiling); // animation = {} lua_getfield(L, index, "animation"); if(lua_istable(L, -1)){ // {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0} tiledef.animation.type = (TileAnimationType) getenumfield(L, -1, "type", es_TileAnimationType, TAT_NONE); tiledef.animation.aspect_w = getintfield_default(L, -1, "aspect_w", 16); tiledef.animation.aspect_h = getintfield_default(L, -1, "aspect_h", 16); tiledef.animation.length = getfloatfield_default(L, -1, "length", 1.0); } lua_pop(L, 1); } return tiledef; }
/*** Encrypt a plain string. Use Argon2i (by default) or Argon2d to hash a string. @function encrypt @param[type=string] plain Plain string to encrypt. @param[type=string] salt Salt to use to hash pwd. @param[type=table] options Options with which to hash the plain string. See `options`. This parameter is optional, if values are omitted the default ones will be used. @treturn string `hash`: Hash computed by Argon2 or nil if an error occurred. @treturn string `error`: `nil` or a string describing the error if any. @usage local hash, err = argon2.encrypt("password", "somesalt") local hash, err = argon2.encrypt("password", "somesalt", {t_cost = 4}) */ static int largon2_encrypt(lua_State *L) { largon2_config *cfg = largon2_arg_init(L, 3); char encoded[ENCODED_LEN]; int ret_code; const char *plain, *salt; size_t plainlen, saltlen; uint32_t t_cost; uint32_t m_cost; uint32_t parallelism; argon2_type argon2_t; plain = luaL_checklstring(L, 1, &plainlen); salt = luaL_checklstring(L, 2, &saltlen); t_cost = cfg->t_cost; m_cost = cfg->m_cost; parallelism = cfg->parallelism; argon2_t = cfg->argon2_t; if (!lua_isnil(L, 3)) { if (!lua_istable(L, 3)) { luaL_argerror(L, 3, "expected to be a table"); } lua_getfield(L, 3, "t_cost"); largon2_integer_opt(L, -1, 3, &t_cost, "t_cost"); lua_pop(L, 1); lua_getfield(L, 3, "m_cost"); largon2_integer_opt(L, -1, 3, &m_cost, "m_cost"); lua_pop(L, 1); lua_getfield(L, 3, "parallelism"); largon2_integer_opt(L, -1, 3, ¶llelism, "parallelism"); lua_pop(L, 1); lua_getfield(L, -1, "argon2d"); if (!lua_isnil(L, -1) && lua_isboolean(L, -1)) { // reverse checking to allow overriding the module settings argon2_t = lua_toboolean(L, -1) ? Argon2_d : Argon2_i; } lua_pop(L, 1); } if (argon2_t == Argon2_i) ret_code = argon2i_hash_encoded(t_cost, m_cost, parallelism, plain, plainlen, salt, saltlen, HASH_LEN, encoded, ENCODED_LEN); else ret_code = argon2d_hash_encoded(t_cost, m_cost, parallelism, plain, plainlen, salt, saltlen, HASH_LEN, encoded, ENCODED_LEN); if (ret_code != ARGON2_OK) { const char *err_msg = argon2_error_message(ret_code); lua_pushnil(L); lua_pushstring(L, err_msg); return 2; } lua_pushstring(L, encoded); return 1; }
static int getboolfield (lua_State *L, const char *key) { int res; res = (lua_getfield(L, -1, key) == LUA_TNIL) ? -1 : lua_toboolean(L, -1); lua_pop(L, 1); return res; }
static int lua_module_upload(lua_State* state, const void* bytecode, size_t size) { string_const_t errmsg = {0, 0}; lua_readbuffer_t read_buffer = { .buffer = bytecode, .size = size, .offset = 0 }; log_debugf(HASH_LUA, STRING_CONST("Loading %u bytes of module bytecode"), read_buffer.size); if (lua_load(state, lua_read_buffer, &read_buffer, "module") != 0) { errmsg.str = lua_tolstring(state, -1, &errmsg.length); log_errorf(HASH_LUA, ERROR_INTERNAL_FAILURE, STRING_CONST("Lua load failed (module): %.*s"), STRING_FORMAT(errmsg)); lua_pop(state, 1); return -1; } if (lua_pcall(state, 0, 1, 0) != 0) { errmsg.str = lua_tolstring(state, -1, &errmsg.length); log_errorf(HASH_LUA, ERROR_INTERNAL_FAILURE, STRING_CONST("Lua pcall failed (module): %.*s"), STRING_FORMAT(errmsg)); return -1; } return 0; } int lua_module_loader(lua_State* state) { lua_modulemap_entry_t* entry = lua_touserdata(state, lua_upvalueindex(2)); if (!entry) return 0; size_t name_length = 0; const char* name = luaL_checklstring(state, lua_upvalueindex(1), &name_length); int stacksize = lua_gettop(state); if (entry->preload) entry->preload(); lua_module_t module = lua_module_load_resource(entry->uuid); if (module.size) { if (lua_module_upload(state, module.bytecode, module.size) == 0) { lua_module_registry_add(state, entry); if (lua_istable(state, -1)) { /* Modules are never garbage collected anyway, since lib_package keeps a global registry reference in _LOADED table, and we keep a reference in loaded-modules table for reload functionality lua_pushlstring(state, STRING_CONST("__gcproxy")); //Proxy table index lua_newuserdata(state, 8); //New proxy object lua_newtable(state); //New metatable for proxy lua_pushlstring(state, STRING_CONST("__gc")); lua_pushlightuserdata(state, entry); lua_pushcclosure(state, lua_module_gc, 1); lua_rawset(state, -3); //Set __gc metatable method lua_setmetatable(state, -2); //Set metatable on proxy lua_rawset(state, -3); //Set proxy in table index __gcproxy */ lua_pushlstring(state, STRING_CONST(BUILD_REGISTRY_LOADED_MODULES)); lua_gettable(state, LUA_REGISTRYINDEX); lua_pushlightuserdata(state, entry); //entry is key lua_pushvalue(state, -3); //copy the loaded module table as value lua_pushlstring(state, STRING_CONST("__modulename")); lua_pushlstring(state, name, name_length); lua_settable(state, -3); //set moduletable["__modulename"] = name lua_settable(state, -3); //set table loaded-modules[entry] = moduletable lua_pop(state, 1); } } memory_deallocate(module.bytecode); } else { string_const_t uuidstr = string_from_uuid_static(entry->uuid); lua_pushfstring(state, "unable to load module '%s'", uuidstr.str); lua_error(state); } return lua_gettop(state) - stacksize; }
int main (int argc, char* argv[]) { lua_State* L = lua_open(0); lua_baselibopen(L); lua_iolibopen(L); lua_strlibopen(L); lua_pushstring(L,TOLUA_VERSION); lua_setglobal(L,"TOLUA_VERSION"); if (argc==1) { help(); return 0; } else { int i, t; lua_newtable(L); lua_pushvalue(L,-1); lua_setglobal(L,"flags"); t = lua_gettop(L); for (i=1; i<argc; ++i) { if (*argv[i] == '-') { switch (argv[i][1]) { case 'v': version(); return 0; case 'h': help(); return 0; case 'p': setfield(L,t,"p",""); break; case 'P': setfield(L,t,"P",""); break; case 'o': setfield(L,t,"o",argv[++i]); break; case 'n': setfield(L,t,"n",argv[++i]); break; case 'H': setfield(L,t,"H",argv[++i]); break; default: error(argv[i]); break; } } else { setfield(L,t,"f",argv[i]); break; } } lua_pop(L,1); } #if 1 { int tolua_tolualua_open(lua_State* L); tolua_tolualua_open(L); } #else { int i; char* p; char path[BUFSIZ]; char* files[] = { "basic.lua", "feature.lua", "verbatim.lua", "code.lua", "typedef.lua", "container.lua", "package.lua", "module.lua", "define.lua", "enumerate.lua", "declaration.lua", "variable.lua", "array.lua", "function.lua", "operator.lua", "class.lua", "clean.lua", "doit.lua", NULL }; strcpy(path,argv[0]); p = strrchr(path,'/'); p = (p==NULL) ? path : p+1; for (i=0; files[i]; ++i) { sprintf(p,"%s",files[i]); lua_dofile(L,path); } } #endif return 0; }
/** * @brief Mods player using the power of Lua. */ static void faction_modPlayerLua( int f, double mod, const char *source, int secondary ) { Faction *faction; lua_State *L; int errf; double old, delta; HookParam hparam[3]; faction = &faction_stack[f]; /* Make sure it's not static. */ if (faction_isFlag(faction, FACTION_STATIC)) return; L = faction->state; old = faction->player; if (L == NULL) faction->player += mod; else { #if DEBUGGING lua_pushcfunction(L, nlua_errTrace); errf = -6; #else /* DEBUGGING */ errf = 0; #endif /* DEBUGGING */ /* Set up the function: * faction_hit( current, amount, source, secondary ) */ lua_getglobal( L, "faction_hit" ); lua_pushnumber( L, faction->player ); lua_pushnumber( L, mod ); lua_pushstring( L, source ); lua_pushboolean( L, secondary ); /* Call function. */ if (lua_pcall( L, 4, 1, errf )) { /* An error occurred. */ WARN("Faction '%s': %s", faction->name, lua_tostring(L,-1)); #if DEBUGGING lua_pop( L, 2 ); #else /* DEBUGGING */ lua_pop( L, 1 ); #endif /* DEBUGGING */ return; } /* Parse return. */ if (!lua_isnumber( L, -1 )) WARN( "Lua script for faction '%s' did not return a number from 'faction_hit(...)'.", faction->name ); else faction->player = lua_tonumber( L, -1 ); #if DEBUGGING lua_pop( L, 2 ); #else /* DEBUGGING */ lua_pop( L, 1 ); #endif /* DEBUGGING */ } /* Sanitize just in case. */ faction_sanitizePlayer( faction ); /* Run hook if necessary. */ delta = faction->player - old; if (fabs(delta) > 1e-10) { hparam[0].type = HOOK_PARAM_FACTION; hparam[0].u.lf = f; hparam[1].type = HOOK_PARAM_NUMBER; hparam[1].u.num = delta; hparam[2].type = HOOK_PARAM_SENTINEL; hooks_runParam( "standing", hparam ); /* Tell space the faction changed. */ space_factionChange(); } }
static int luaopen_hexchat(lua_State *L) { lua_newtable(L); luaL_setfuncs(L, api_hexchat, 0); lua_pushinteger(L, HEXCHAT_PRI_HIGHEST); lua_setfield(L, -2, "PRI_HIGHEST"); lua_pushinteger(L, HEXCHAT_PRI_HIGH); lua_setfield(L, -2, "PRI_HIGH"); lua_pushinteger(L, HEXCHAT_PRI_NORM); lua_setfield(L, -2, "PRI_NORM"); lua_pushinteger(L, HEXCHAT_PRI_LOW); lua_setfield(L, -2, "PRI_LOW"); lua_pushinteger(L, HEXCHAT_PRI_LOWEST); lua_setfield(L, -2, "PRI_LOWEST"); lua_pushinteger(L, HEXCHAT_EAT_NONE); lua_setfield(L, -2, "EAT_NONE"); lua_pushinteger(L, HEXCHAT_EAT_HEXCHAT); lua_setfield(L, -2, "EAT_HEXCHAT"); lua_pushinteger(L, HEXCHAT_EAT_PLUGIN); lua_setfield(L, -2, "EAT_PLUGIN"); lua_pushinteger(L, HEXCHAT_EAT_ALL); lua_setfield(L, -2, "EAT_ALL"); lua_newtable(L); lua_newtable(L); luaL_setfuncs(L, api_hexchat_prefs_meta, 0); lua_setmetatable(L, -2); lua_setfield(L, -2, "prefs"); lua_newtable(L); lua_newtable(L); luaL_setfuncs(L, api_hexchat_props_meta, 0); lua_setmetatable(L, -2); lua_setfield(L, -2, "props"); lua_newtable(L); lua_newtable(L); luaL_setfuncs(L, api_hexchat_pluginprefs_meta, 0); lua_setmetatable(L, -2); lua_setfield(L, -2, "pluginprefs"); luaL_newmetatable(L, "hook"); lua_newtable(L); luaL_setfuncs(L, api_hook_meta_index, 0); lua_setfield(L, -2, "__index"); lua_pop(L, 1); luaL_newmetatable(L, "context"); lua_newtable(L); lua_pushcfunction(L, api_hexchat_set_context); lua_setfield(L, -2, "set"); wrap_context(L, "find_context", api_hexchat_find_context); wrap_context(L, "print", api_hexchat_print); wrap_context(L, "emit_print", api_hexchat_emit_print); wrap_context(L, "emit_print_attrs", api_hexchat_emit_print_attrs); wrap_context(L, "command", api_hexchat_command); wrap_context(L, "nickcmp", api_hexchat_nickcmp); wrap_context(L, "get_info", api_hexchat_get_info); wrap_context(L, "iterate", api_hexchat_iterate); lua_setfield(L, -2, "__index"); lua_pushcfunction(L, api_hexchat_context_meta_eq); lua_setfield(L, -2, "__eq"); lua_pop(L, 1); luaL_newmetatable(L, "attrs"); luaL_setfuncs(L, api_attrs_meta, 0); lua_pop(L, 1); luaL_newmetatable(L, "list"); luaL_setfuncs(L, api_list_meta, 0); lua_pop(L, 1); return 1; }
void register_zlib(lua_State *L) { const luaL_Reg lzstream_meta[] = { {"write", lzstream_compress }, {"read", lzstream_decompress }, {"lines", lzstream_lines }, {"flush", lzstream_flush }, {"close", lzstream_close }, {"adler", lzstream_adler }, {"__tostring", lzstream_tostring }, {"__gc", lzstream_gc }, {NULL, NULL} }; const luaL_Reg zlib[] = { {"version", lzlib_version }, {"adler32", lzlib_adler32 }, {"crc32", lzlib_crc32 }, {"deflate", lzlib_deflate }, {"inflate", lzlib_inflate }, {"compress", lzlib_compress }, {"decompress", lzlib_decompress }, {NULL, NULL} }; /* ====================================================================== */ /* create new metatable for zlib compression structures */ luaL_newmetatable(L, ZSTREAMMETA); lua_pushliteral(L, "__index"); lua_pushvalue(L, -2); /* push metatable */ lua_rawset(L, -3); /* metatable.__index = metatable */ /* ** Stack: metatable */ luaL_register(L, NULL, lzstream_meta); lua_pop(L, 1); /* remove metatable from stack */ /* ** Stack: */ lua_newtable(L); lua_pushliteral (L, "_COPYRIGHT"); lua_pushliteral (L, "Copyright (C) 2003-2010 Tiago Dionizio"); lua_settable (L, -3); lua_pushliteral (L, "_DESCRIPTION"); lua_pushliteral (L, "Lua 5 interface to access zlib library functions"); lua_settable (L, -3); lua_pushliteral (L, "_VERSION"); lua_pushliteral (L, "lzlib 0.4-work3"); lua_settable (L, -3); #define PUSH_LITERAL(name) \ lua_pushliteral (L, #name); \ lua_pushinteger (L, Z_##name); \ lua_settable (L, -3); #define PUSH_NUMBER(name, value) \ lua_pushliteral (L, #name); \ lua_pushinteger (L, value); \ lua_settable (L, -3); PUSH_LITERAL(NO_COMPRESSION) PUSH_LITERAL(BEST_SPEED) PUSH_LITERAL(BEST_COMPRESSION) PUSH_LITERAL(DEFAULT_COMPRESSION) PUSH_LITERAL(FILTERED) PUSH_LITERAL(HUFFMAN_ONLY) PUSH_LITERAL(RLE) PUSH_LITERAL(FIXED) PUSH_LITERAL(DEFAULT_STRATEGY) PUSH_NUMBER(MINIMUM_MEMLEVEL, 1) PUSH_NUMBER(MAXIMUM_MEMLEVEL, 9) PUSH_NUMBER(DEFAULT_MEMLEVEL, 8) PUSH_NUMBER(DEFAULT_WINDOWBITS, 15) PUSH_NUMBER(MINIMUM_WINDOWBITS, 8) PUSH_NUMBER(MAXIMUM_WINDOWBITS, 15) PUSH_NUMBER(GZIP_WINDOWBITS, 16) PUSH_NUMBER(RAW_WINDOWBITS, -1) luaL_register(L, NULL, zlib); lua_setglobal(L, "zlib"); }
void tolua_pushusertype_internal (lua_State* L, void* value, const char* type, int addToRoot) { if (value == NULL) lua_pushnil(L); else { luaL_getmetatable(L, type); /* stack: mt */ if (lua_isnil(L, -1)) { /* NOT FOUND metatable */ lua_pop(L, 1); return; } lua_pushstring(L,"tolua_ubox"); lua_rawget(L,-2); /* stack: mt ubox */ if (lua_isnil(L, -1)) { lua_pop(L, 1); lua_pushstring(L, "tolua_ubox"); lua_rawget(L, LUA_REGISTRYINDEX); }; lua_pushlightuserdata(L,value); /* stack: mt ubox key<value> */ lua_rawget(L,-2); /* stack: mt ubox ubox[value] */ if (lua_isnil(L,-1)) { lua_pop(L,1); /* stack: mt ubox */ lua_pushlightuserdata(L,value); *(void**)lua_newuserdata(L,sizeof(void *)) = value; /* stack: mt ubox value newud */ lua_pushvalue(L,-1); /* stack: mt ubox value newud newud */ lua_insert(L,-4); /* stack: mt newud ubox value newud */ lua_rawset(L,-3); /* ubox[value] = newud, stack: mt newud ubox */ lua_pop(L,1); /* stack: mt newud */ /*luaL_getmetatable(L,type);*/ lua_pushvalue(L, -2); /* stack: mt newud mt */ lua_setmetatable(L,-2); /* update mt, stack: mt newud */ #ifdef LUA_VERSION_NUM lua_pushvalue(L, TOLUA_NOPEER); /* stack: mt newud peer */ lua_setfenv(L, -2); /* stack: mt newud */ #endif } else { /* check the need of updating the metatable to a more specialized class */ lua_insert(L,-2); /* stack: mt ubox[u] ubox */ lua_pop(L,1); /* stack: mt ubox[u] */ lua_pushstring(L,"tolua_super"); lua_rawget(L,LUA_REGISTRYINDEX); /* stack: mt ubox[u] super */ lua_getmetatable(L,-2); /* stack: mt ubox[u] super mt */ lua_rawget(L,-2); /* stack: mt ubox[u] super super[mt] */ if (lua_istable(L,-1)) { lua_pushstring(L,type); /* stack: mt ubox[u] super super[mt] type */ lua_rawget(L,-2); /* stack: mt ubox[u] super super[mt] flag */ if (lua_toboolean(L,-1) == 1) /* if true */ { lua_pop(L,3); /* mt ubox[u]*/ lua_remove(L, -2); return; } } /* type represents a more specilized type */ /*luaL_getmetatable(L,type); // stack: mt ubox[u] super super[mt] flag mt */ lua_pushvalue(L, -5); /* stack: mt ubox[u] super super[mt] flag mt */ lua_setmetatable(L,-5); /* stack: mt ubox[u] super super[mt] flag */ lua_pop(L,3); /* stack: mt ubox[u] */ } lua_remove(L, -2); /* stack: ubox[u]*/ if (0 != addToRoot) { lua_pushvalue(L, -1); tolua_add_value_to_root(L, value); } } }
static int checkint (lua_State *L, int topop) { int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1; lua_pop(L, topop); return n; }
int pklua_lua_pkm_get_metrics(lua_State* L) { struct pk_global_state* state = &pk_state; pk_log(PK_LOG_LUA_DEBUG, "pklua_lua_pkm_get_metrics(%p)", L); int n = lua_gettop(L); if (n != 1 || !lua_istable(L, 1)) { lua_pushstring(L, "Incorrect arguments in get_metrics"); return lua_error(L); } lua_getfield(L, 1, "_pkm"); if (!lua_islightuserdata(L, -1)) { lua_pushstring(L, "Incorrect arguments in get_metrics (2)"); return lua_error(L); } struct pk_manager* manager = lua_touserdata(L, -1); lua_remove(L, -1); lua_newtable(L); int metrics = lua_gettop(L); /* Relatives offsets would break below */ lua_pushstring(L, PK_VERSION); lua_setfield(L, metrics, "libpagekite_version"); #define PKM_INT(s, n) lua_pushinteger(L, s->n);\ lua_setfield(L, metrics, #s"_"#n) #define PKM_STR(s, n) lua_pushstring(L, (s->n == NULL) ? "(null)" : s->n);\ lua_setfield(L, metrics, #s"_"#n) PKM_INT(manager, status); PKM_INT(manager, last_world_update); PKM_INT(manager, next_tick); PKM_INT(manager, enable_timer); PKM_INT(manager, last_dns_update); PKM_INT(manager, kite_max); PKM_INT(manager, tunnel_max); PKM_INT(manager, be_conn_max); PKM_INT(manager, fancy_pagekite_net_rejection); PKM_INT(manager, enable_watchdog); PKM_INT(manager, want_spare_frontends); PKM_INT(manager, housekeeping_interval_min); PKM_INT(manager, housekeeping_interval_max); PKM_INT(manager, check_world_interval); PKM_STR(manager, dynamic_dns_url); PKM_INT(state, live_streams); PKM_INT(state, live_tunnels); PKM_INT(state, live_listeners); PKM_STR(state, app_id_short); PKM_STR(state, app_id_long); PKM_INT(state, quota_days); PKM_INT(state, quota_conns); PKM_INT(state, quota_mb); /* Copy Lua metrics from master Lua context */ pk_lua_t* mgr_lua; if ((mgr_lua = pklua_lock_lua(manager->lua)) != NULL) { lua_State* ML = mgr_lua->lua; lua_getfield(ML, LUA_GLOBALSINDEX, "pklua"); lua_getfield(ML, -1, "metrics"); /* ML stack: -1=metrics, -2=pklua */ lua_pushnil(ML); while (lua_next(ML, -2)) { /* copy key and value so lua_tostring doesn't corrupt */ lua_pushvalue(ML, -2); lua_pushvalue(ML, -2); /* ML stack: -1=value copy, -2=key copy, -3=value, -4=key, -5=metrics */ lua_pushinteger(L, lua_tointeger(ML, -1)); lua_setfield(L, metrics, lua_tostring(ML, -2)); lua_pop(ML, 3); /* ML stack: -1=key, -2=metrics */ } lua_remove(ML, -1); lua_remove(ML, -1); pklua_unlock_lua(mgr_lua); } /* L stack: -1 = new table */ return 1; }
ToolCapabilities read_tool_capabilities( lua_State *L, int table) { ToolCapabilities toolcap; getfloatfield(L, table, "full_punch_interval", toolcap.full_punch_interval); getintfield(L, table, "max_drop_level", toolcap.max_drop_level); lua_getfield(L, table, "groupcaps"); if(lua_istable(L, -1)){ int table_groupcaps = lua_gettop(L); lua_pushnil(L); while(lua_next(L, table_groupcaps) != 0){ // key at index -2 and value at index -1 std::string groupname = luaL_checkstring(L, -2); if(lua_istable(L, -1)){ int table_groupcap = lua_gettop(L); // This will be created ToolGroupCap groupcap; // Read simple parameters getintfield(L, table_groupcap, "maxlevel", groupcap.maxlevel); getintfield(L, table_groupcap, "uses", groupcap.uses); // DEPRECATED: maxwear float maxwear = 0; if (getfloatfield(L, table_groupcap, "maxwear", maxwear)){ if (maxwear != 0) groupcap.uses = 1.0/maxwear; else groupcap.uses = 0; warningstream << "Field \"maxwear\" is deprecated; " << "replace with uses=1/maxwear" << std::endl; infostream << script_get_backtrace(L) << std::endl; } // Read "times" table lua_getfield(L, table_groupcap, "times"); if(lua_istable(L, -1)){ int table_times = lua_gettop(L); lua_pushnil(L); while(lua_next(L, table_times) != 0){ // key at index -2 and value at index -1 int rating = luaL_checkinteger(L, -2); float time = luaL_checknumber(L, -1); groupcap.times[rating] = time; // removes value, keeps key for next iteration lua_pop(L, 1); } } lua_pop(L, 1); // Insert groupcap into toolcap toolcap.groupcaps[groupname] = groupcap; } // removes value, keeps key for next iteration lua_pop(L, 1); } } lua_pop(L, 1); lua_getfield(L, table, "damage_groups"); if(lua_istable(L, -1)){ int table_damage_groups = lua_gettop(L); lua_pushnil(L); while(lua_next(L, table_damage_groups) != 0){ // key at index -2 and value at index -1 std::string groupname = luaL_checkstring(L, -2); u16 value = luaL_checkinteger(L, -1); toolcap.damageGroups[groupname] = value; // removes value, keeps key for next iteration lua_pop(L, 1); } } lua_pop(L, 1); return toolcap; }
ItemDefinition read_item_definition(lua_State* L,int index, ItemDefinition default_def) { if(index < 0) index = lua_gettop(L) + 1 + index; // Read the item definition ItemDefinition def = default_def; def.type = (ItemType)getenumfield(L, index, "type", es_ItemType, ITEM_NONE); getstringfield(L, index, "name", def.name); getstringfield(L, index, "description", def.description); getstringfield(L, index, "inventory_image", def.inventory_image); getstringfield(L, index, "wield_image", def.wield_image); lua_getfield(L, index, "wield_scale"); if(lua_istable(L, -1)){ def.wield_scale = check_v3f(L, -1); } lua_pop(L, 1); def.stack_max = getintfield_default(L, index, "stack_max", def.stack_max); if(def.stack_max == 0) def.stack_max = 1; lua_getfield(L, index, "on_use"); def.usable = lua_isfunction(L, -1); lua_pop(L, 1); getboolfield(L, index, "liquids_pointable", def.liquids_pointable); warn_if_field_exists(L, index, "tool_digging_properties", "Deprecated; use tool_capabilities"); lua_getfield(L, index, "tool_capabilities"); if(lua_istable(L, -1)){ def.tool_capabilities = new ToolCapabilities( read_tool_capabilities(L, -1)); } // If name is "" (hand), ensure there are ToolCapabilities // because it will be looked up there whenever any other item has // no ToolCapabilities if(def.name == "" && def.tool_capabilities == NULL){ def.tool_capabilities = new ToolCapabilities(); } lua_getfield(L, index, "groups"); read_groups(L, -1, def.groups); lua_pop(L, 1); lua_getfield(L, index, "sounds"); if(lua_istable(L, -1)){ lua_getfield(L, -1, "place"); read_soundspec(L, -1, def.sound_place); lua_pop(L, 1); lua_getfield(L, -1, "place_failed"); read_soundspec(L, -1, def.sound_place_failed); lua_pop(L, 1); } lua_pop(L, 1); def.range = getfloatfield_default(L, index, "range", def.range); // Client shall immediately place this node when player places the item. // Server will update the precise end result a moment later. // "" = no prediction getstringfield(L, index, "node_placement_prediction", def.node_placement_prediction); return def; }
ContentFeatures read_content_features(lua_State *L, int index) { if(index < 0) index = lua_gettop(L) + 1 + index; ContentFeatures f; /* Cache existence of some callbacks */ lua_getfield(L, index, "on_construct"); if(!lua_isnil(L, -1)) f.has_on_construct = true; lua_pop(L, 1); lua_getfield(L, index, "on_destruct"); if(!lua_isnil(L, -1)) f.has_on_destruct = true; lua_pop(L, 1); lua_getfield(L, index, "after_destruct"); if(!lua_isnil(L, -1)) f.has_after_destruct = true; lua_pop(L, 1); lua_getfield(L, index, "on_rightclick"); f.rightclickable = lua_isfunction(L, -1); lua_pop(L, 1); /* Name */ getstringfield(L, index, "name", f.name); /* Groups */ lua_getfield(L, index, "groups"); read_groups(L, -1, f.groups); lua_pop(L, 1); /* Visual definition */ f.drawtype = (NodeDrawType)getenumfield(L, index, "drawtype", ScriptApiNode::es_DrawType,NDT_NORMAL); getfloatfield(L, index, "visual_scale", f.visual_scale); /* Meshnode model filename */ getstringfield(L, index, "mesh", f.mesh); // tiles = {} lua_getfield(L, index, "tiles"); // If nil, try the deprecated name "tile_images" instead if(lua_isnil(L, -1)){ lua_pop(L, 1); warn_if_field_exists(L, index, "tile_images", "Deprecated; new name is \"tiles\"."); lua_getfield(L, index, "tile_images"); } if(lua_istable(L, -1)){ int table = lua_gettop(L); lua_pushnil(L); int i = 0; while(lua_next(L, table) != 0){ // Read tiledef from value f.tiledef[i] = read_tiledef(L, -1, f.drawtype); // removes value, keeps key for next iteration lua_pop(L, 1); i++; if(i==6){ lua_pop(L, 1); break; } } // Copy last value to all remaining textures if(i >= 1){ TileDef lasttile = f.tiledef[i-1]; while(i < 6){ f.tiledef[i] = lasttile; i++; } } } lua_pop(L, 1); // special_tiles = {} lua_getfield(L, index, "special_tiles"); // If nil, try the deprecated name "special_materials" instead if(lua_isnil(L, -1)){ lua_pop(L, 1); warn_if_field_exists(L, index, "special_materials", "Deprecated; new name is \"special_tiles\"."); lua_getfield(L, index, "special_materials"); } if(lua_istable(L, -1)){ int table = lua_gettop(L); lua_pushnil(L); int i = 0; while(lua_next(L, table) != 0){ // Read tiledef from value f.tiledef_special[i] = read_tiledef(L, -1, f.drawtype); // removes value, keeps key for next iteration lua_pop(L, 1); i++; if(i==CF_SPECIAL_COUNT){ lua_pop(L, 1); break; } } } lua_pop(L, 1); f.alpha = getintfield_default(L, index, "alpha", 255); bool usealpha = getboolfield_default(L, index, "use_texture_alpha", false); if (usealpha) f.alpha = 0; /* Other stuff */ lua_getfield(L, index, "post_effect_color"); read_color(L, -1, &f.post_effect_color); lua_pop(L, 1); f.param_type = (ContentParamType)getenumfield(L, index, "paramtype", ScriptApiNode::es_ContentParamType, CPT_NONE); f.param_type_2 = (ContentParamType2)getenumfield(L, index, "paramtype2", ScriptApiNode::es_ContentParamType2, CPT2_NONE); // Warn about some deprecated fields warn_if_field_exists(L, index, "wall_mounted", "Deprecated; use paramtype2 = 'wallmounted'"); warn_if_field_exists(L, index, "light_propagates", "Deprecated; determined from paramtype"); warn_if_field_exists(L, index, "dug_item", "Deprecated; use 'drop' field"); warn_if_field_exists(L, index, "extra_dug_item", "Deprecated; use 'drop' field"); warn_if_field_exists(L, index, "extra_dug_item_rarity", "Deprecated; use 'drop' field"); warn_if_field_exists(L, index, "metadata_name", "Deprecated; use on_add and metadata callbacks"); // True for all ground-like things like stone and mud, false for eg. trees getboolfield(L, index, "is_ground_content", f.is_ground_content); f.light_propagates = (f.param_type == CPT_LIGHT); getboolfield(L, index, "sunlight_propagates", f.sunlight_propagates); // This is used for collision detection. // Also for general solidness queries. getboolfield(L, index, "walkable", f.walkable); // Player can point to these getboolfield(L, index, "pointable", f.pointable); // Player can dig these getboolfield(L, index, "diggable", f.diggable); // Player can climb these getboolfield(L, index, "climbable", f.climbable); // Player can build on these getboolfield(L, index, "buildable_to", f.buildable_to); // Liquids flow into and replace node getboolfield(L, index, "floodable", f.floodable); // Whether the node is non-liquid, source liquid or flowing liquid f.liquid_type = (LiquidType)getenumfield(L, index, "liquidtype", ScriptApiNode::es_LiquidType, LIQUID_NONE); // If the content is liquid, this is the flowing version of the liquid. getstringfield(L, index, "liquid_alternative_flowing", f.liquid_alternative_flowing); // If the content is liquid, this is the source version of the liquid. getstringfield(L, index, "liquid_alternative_source", f.liquid_alternative_source); // Viscosity for fluid flow, ranging from 1 to 7, with // 1 giving almost instantaneous propagation and 7 being // the slowest possible f.liquid_viscosity = getintfield_default(L, index, "liquid_viscosity", f.liquid_viscosity); f.liquid_range = getintfield_default(L, index, "liquid_range", f.liquid_range); f.leveled = getintfield_default(L, index, "leveled", f.leveled); getboolfield(L, index, "liquid_renewable", f.liquid_renewable); f.drowning = getintfield_default(L, index, "drowning", f.drowning); // Amount of light the node emits f.light_source = getintfield_default(L, index, "light_source", f.light_source); f.damage_per_second = getintfield_default(L, index, "damage_per_second", f.damage_per_second); lua_getfield(L, index, "node_box"); if(lua_istable(L, -1)) f.node_box = read_nodebox(L, -1); lua_pop(L, 1); lua_getfield(L, index, "selection_box"); if(lua_istable(L, -1)) f.selection_box = read_nodebox(L, -1); lua_pop(L, 1); lua_getfield(L, index, "collision_box"); if(lua_istable(L, -1)) f.collision_box = read_nodebox(L, -1); lua_pop(L, 1); f.waving = getintfield_default(L, index, "waving", f.waving); // Set to true if paramtype used to be 'facedir_simple' getboolfield(L, index, "legacy_facedir_simple", f.legacy_facedir_simple); // Set to true if wall_mounted used to be set to true getboolfield(L, index, "legacy_wallmounted", f.legacy_wallmounted); // Sound table lua_getfield(L, index, "sounds"); if(lua_istable(L, -1)){ lua_getfield(L, -1, "footstep"); read_soundspec(L, -1, f.sound_footstep); lua_pop(L, 1); lua_getfield(L, -1, "dig"); read_soundspec(L, -1, f.sound_dig); lua_pop(L, 1); lua_getfield(L, -1, "dug"); read_soundspec(L, -1, f.sound_dug); lua_pop(L, 1); } lua_pop(L, 1); return f; }
bool LuaScriptEngine::init() { // Lua-State initialisation, as well as standard libaries initialisation _state = luaL_newstate(); if (!_state || ! registerStandardLibs() || !registerStandardLibExtensions()) { error("Lua could not be initialized."); return false; } // Register panic callback function lua_atpanic(_state, panicCB); // Error handler for lua_pcall calls // The code below contains a local error handler function const char errorHandlerCode[] = "local function ErrorHandler(message) " " return message .. '\\n' .. debug.traceback('', 2) " "end " "return ErrorHandler"; // Compile the code if (luaL_loadbuffer(_state, errorHandlerCode, strlen(errorHandlerCode), "PCALL ERRORHANDLER") != 0) { // An error occurred, so dislay the reason and exit error("Couldn't compile luaL_pcall errorhandler:\n%s", lua_tostring(_state, -1)); lua_pop(_state, 1); return false; } // Running the code, the error handler function sets the top of the stack if (lua_pcall(_state, 0, 1, 0) != 0) { // An error occurred, so dislay the reason and exit error("Couldn't prepare luaL_pcall errorhandler:\n%s", lua_tostring(_state, -1)); lua_pop(_state, 1); return false; } // Place the error handler function in the Lua registry, and remember the index _pcallErrorhandlerRegistryIndex = luaL_ref(_state, LUA_REGISTRYINDEX); // Initialize the Pluto-Persistence library luaopen_pluto(_state); lua_pop(_state, 1); // Initialize debugging callback if (DebugMan.isDebugChannelEnabled(kDebugScript)) { int mask = 0; if ((gDebugLevel & 1) != 0) mask |= LUA_MASKCALL; if ((gDebugLevel & 2) != 0) mask |= LUA_MASKRET; if ((gDebugLevel & 4) != 0) mask |= LUA_MASKLINE; if (mask != 0) lua_sethook(_state, debugHook, mask, 0); } debugC(kDebugScript, "Lua initialized."); return true; }
int slurm_container_plugin_get_pids (uint64_t cont_id, pid_t **pids, int *npids) { int rc = SLURM_ERROR; int i = 0; int t = 0; pid_t *p; *npids = 0; slurm_mutex_lock (&lua_lock); lua_getglobal (L, "slurm_container_get_pids"); if (lua_isnil (L, -1)) goto out; lua_pushnumber (L, cont_id); if (lua_pcall (L, 1, 1, 0) != 0) { error ("%s: %s: %s", "proctrack/lua", __func__, lua_tostring (L, -1)); goto out; } /* * list of PIDs should be returned in a table from the lua * script. If a table wasn't returned then generate an error: */ if (!lua_istable(L, -1)) { error ("%s: %s: function should return a table", "proctrack/lua", __func__); goto out; } /* * Save absolute position of table in lua stack */ t = lua_gettop (L); /* * Get table size and create array for slurm */ *npids = lua_objlen (L, t); p = (pid_t *) xmalloc (*npids * sizeof (pid_t)); /* * Traverse table/array at position t on the stack: */ lua_pushnil (L); while (lua_next (L, t)) { p [i++] = lua_tonumber (L, -1); /* * pop value off stack, leave key for lua_next() */ lua_pop (L, 1); } lua_pop (L, 1); *pids = p; rc = SLURM_SUCCESS; out: slurm_mutex_unlock (&lua_lock); return rc; }
static void push_bindings(lua_State *l, const KeyBindings::BindingPrototype *protos) { LUA_DEBUG_START(l); lua_newtable(l); // [-1] bindings lua_pushnil(l); // [-2] bindings, [-1] group (no current group) assert(!protos[0].function); // first entry should be a group header int group_idx = 1; int binding_idx = 1; for (const KeyBindings::BindingPrototype *proto = protos; proto->label; ++proto) { if (! proto->function) { // start a new named binding group // [-2] bindings, [-1] group lua_pop(l, 1); // [-1] bindings lua_newtable(l); lua_pushstring(l, proto->label); lua_setfield(l, -2, "label"); // [-2] bindings, [-1] group lua_pushvalue(l, -1); // [-3] bindings, [-2] group, [-1] group copy lua_rawseti(l, -3, group_idx); ++group_idx; binding_idx = 1; } else { // key or axis binding prototype // [-2] bindings, [-1] group lua_createtable(l, 0, 5); // [-3] bindings, [-2] group, [-1] binding // fields: type ('KEY' or 'AXIS'), id ('BindIncreaseSpeed'), label ('Increase Speed'), binding ('Key13'), bindingDescription ('') lua_pushstring(l, (proto->kb ? "KEY" : "AXIS")); lua_setfield(l, -2, "type"); lua_pushstring(l, proto->function); lua_setfield(l, -2, "id"); lua_pushstring(l, proto->label); lua_setfield(l, -2, "label"); if (proto->kb) { const KeyBindings::KeyBinding kb1 = proto->kb->binding1; if (kb1.Enabled()) { lua_pushstring(l, kb1.ToString().c_str()); lua_setfield(l, -2, "binding1"); lua_pushstring(l, kb1.Description().c_str()); lua_setfield(l, -2, "bindingDescription1"); } const KeyBindings::KeyBinding kb2 = proto->kb->binding2; if (kb2.Enabled()) { lua_pushstring(l, kb2.ToString().c_str()); lua_setfield(l, -2, "binding2"); lua_pushstring(l, kb2.Description().c_str()); lua_setfield(l, -2, "bindingDescription2"); } } else if (proto->ab) { const KeyBindings::AxisBinding &ab = *proto->ab; lua_pushstring(l, ab.ToString().c_str()); lua_setfield(l, -2, "binding1"); lua_pushstring(l, ab.Description().c_str()); lua_setfield(l, -2, "bindingDescription1"); } else { assert(0); // invalid prototype binding } // [-3] bindings, [-2] group, [-1] binding lua_rawseti(l, -2, binding_idx); ++binding_idx; } LUA_DEBUG_CHECK(l, 2); // [-2] bindings, [-1] group } // pop the group table (which should already have been put in the bindings table) lua_pop(l, 1); LUA_DEBUG_END(l, 1); }
int create_class::stage1(lua_State* L) { #ifndef LUABIND_NO_ERROR_CHECKING if (lua_gettop(L) != 1 || lua_type(L, 1) != LUA_TSTRING || lua_isnumber(L, 1)) { lua_pushstring(L, "invalid construct, expected class name"); lua_error(L); } if (std::strlen(lua_tostring(L, 1)) != lua_strlen(L, 1)) { lua_pushstring(L, "luabind does not support class names with extra nulls"); lua_error(L); } #endif const char* name = lua_tostring(L, 1); int stack_level = lua_gettop(L); ////////////////////////////////////////////////////////////////////////// // Here we are trying to add the class to the namespace in the local variable "this" if exist ////////////////////////////////////////////////////////////////////////// int index = LUA_GLOBALSINDEX; lua_Debug ar; if ( lua_getstack (L, 1, &ar) ) { int i = 1; const char *name; while ((name = lua_getlocal(L, &ar, i++)) != NULL) { if (!strcmp("this",name)) { if (lua_istable(L,-1)) index = lua_gettop(L); else lua_pop(L, 1); break; } lua_pop(L, 1); /* remove variable value */ } } ////////////////////////////////////////////////////////////////////////// // End of change ////////////////////////////////////////////////////////////////////////// void* c = lua_newuserdata(L, sizeof(class_rep)); new(c) class_rep(L, name); // make the class globally available lua_pushstring(L, name); lua_pushvalue(L, -2); lua_settable(L, index); if (index != LUA_GLOBALSINDEX) lua_remove(L,index); // also add it to the closure as return value lua_pushcclosure(L, &stage2, 1); int stack_level2 = lua_gettop(L); return 1; }
LUA_API lua_FireBulletsInfo_t lua_tofirebulletsinfo (lua_State *L, int idx) { luaL_checktype(L, idx, LUA_TTABLE); FireBulletsInfo_t info; lua_getfield(L, idx, "m_bPrimaryAttack"); if (!lua_isnil(L, -1)) info.m_bPrimaryAttack = luaL_checkboolean(L, -1); lua_pop(L, 1); lua_getfield(L, idx, "m_flDamageForceScale"); if (!lua_isnil(L, -1)) info.m_flDamageForceScale = luaL_checknumber(L, -1); lua_pop(L, 1); lua_getfield(L, idx, "m_flDistance"); if (!lua_isnil(L, -1)) info.m_flDistance = luaL_checknumber(L, -1); lua_pop(L, 1); lua_getfield(L, idx, "m_iAmmoType"); if (!lua_isnil(L, -1)) info.m_iAmmoType = luaL_checkint(L, -1); lua_pop(L, 1); lua_getfield(L, idx, "m_iDamage"); if (!lua_isnil(L, -1)) info.m_iDamage = luaL_checkint(L, -1); lua_pop(L, 1); lua_getfield(L, idx, "m_iPlayerDamage"); if (!lua_isnil(L, -1)) info.m_iPlayerDamage = luaL_checkint(L, -1); lua_pop(L, 1); lua_getfield(L, idx, "m_iShots"); if (!lua_isnil(L, -1)) info.m_iShots = luaL_checkint(L, -1); lua_pop(L, 1); lua_getfield(L, idx, "m_iTracerFreq"); if (!lua_isnil(L, -1)) info.m_iTracerFreq = luaL_checkint(L, -1); lua_pop(L, 1); lua_getfield(L, idx, "m_nFlags"); if (!lua_isnil(L, -1)) info.m_nFlags = luaL_checkint(L, -1); lua_pop(L, 1); lua_getfield(L, idx, "m_pAdditionalIgnoreEnt"); if (!lua_isnil(L, -1)) info.m_pAdditionalIgnoreEnt = lua_toentity(L, -1); lua_pop(L, 1); lua_getfield(L, idx, "m_pAttacker"); if (!lua_isnil(L, -1)) info.m_pAttacker = lua_toentity(L, -1); lua_pop(L, 1); lua_getfield(L, idx, "m_vecDirShooting"); if (!lua_isnil(L, -1)) info.m_vecDirShooting = luaL_checkvector(L, -1); lua_pop(L, 1); lua_getfield(L, idx, "m_vecSpread"); if (!lua_isnil(L, -1)) info.m_vecSpread = luaL_checkvector(L, -1); lua_pop(L, 1); lua_getfield(L, idx, "m_vecSrc"); if (!lua_isnil(L, -1)) info.m_vecSrc = luaL_checkvector(L, -1); lua_pop(L, 1); return info; }
int CCLuaStack::executeFunctionReturnArray(int nHandler,int nNumArgs,int nNummResults,CCArray* pResultArray) { if (NULL == pResultArray) return 0; if (pushFunctionByHandler(nHandler)) /* L: ... arg1 arg2 ... func */ { if (nNumArgs > 0) { lua_insert(m_state, -(nNumArgs + 1)); /* L: ... func arg1 arg2 ... */ int functionIndex = -(nNumArgs + 1); if (!lua_isfunction(m_state, functionIndex)) { CCLOG("value at stack [%d] is not function", functionIndex); lua_pop(m_state, nNumArgs + 1); // remove function and arguments return 0; } int traceback = 0; lua_getglobal(m_state, "__G__TRACKBACK__"); /* L: ... func arg1 arg2 ... G */ if (!lua_isfunction(m_state, -1)) { lua_pop(m_state, 1); /* L: ... func arg1 arg2 ... */ } else { lua_insert(m_state, functionIndex - 1); /* L: ... G func arg1 arg2 ... */ traceback = functionIndex - 1; } int error = 0; ++m_callFromLua; error = lua_pcall(m_state, nNumArgs, nNummResults, traceback); /* L: ... [G] ret1 ret2 ... retResults*/ --m_callFromLua; if (error) { if (traceback == 0) { CCLOG("[LUA ERROR] %s", lua_tostring(m_state, - 1)); /* L: ... error */ lua_pop(m_state, 1); // remove error message from stack } else /* L: ... G error */ { lua_pop(m_state, 2); // remove __G__TRACKBACK__ and error message from stack } return 0; } // get return value,don't pass LUA_MULTRET to numResults, if (nNummResults <= 0) return 0; for (int i = 0 ; i < nNummResults; i++) { if (lua_type(m_state, -1) == LUA_TBOOLEAN) { bool value = lua_toboolean(m_state, -1); pResultArray->addObject(CCBool::create(value)) ; }else if (lua_type(m_state, -1) == LUA_TNUMBER) { double value = lua_tonumber(m_state, -1); pResultArray->addObject(CCDouble::create(value)); }else if (lua_type(m_state, -1) == LUA_TSTRING) { const char* value = lua_tostring(m_state, -1); pResultArray->addObject(CCString::create(value)); }else{ pResultArray->addObject(static_cast<CCObject*>(tolua_tousertype(m_state, -1, NULL))); } // remove return value from stack lua_pop(m_state, 1); /* L: ... [G] ret1 ret2 ... ret*/ } /* L: ... [G]*/ if (traceback) { lua_pop(m_state, 1); // remove __G__TRACKBACK__ from stack /* L: ... */ } } } lua_settop(m_state, 0); return 1; }
/* End module * It pops the module (or class) from the stack */ TOLUA_API void tolua_endmodule (lua_State* L) { lua_pop(L,1); }
/* * Method: GetNearbySystems * * Get a list of nearby <StarSystems> that match some criteria * * > systems = system:GetNearbySystems(range, filter) * * Parameters: * * range - distance from this system to search, in light years * * filter - an optional function. If specified the function will be called * once for each candidate system with the <StarSystem> object * passed as the only parameter. If the filter function returns * true then the system will be included in the array returned by * <GetNearbySystems>, otherwise it will be omitted. If no filter * function is specified then all systems in range are returned. * * Return: * * systems - an array of systems in range that matched the filter * * Availability: * * alpha 10 * * Status: * * experimental */ static int l_starsystem_get_nearby_systems(lua_State *l) { LUA_DEBUG_START(l); StarSystem *s = LuaStarSystem::GetFromLua(1); double dist_ly = luaL_checknumber(l, 2); bool filter = false; if (lua_gettop(l) >= 3) { luaL_checktype(l, 3, LUA_TFUNCTION); // any type of function filter = true; } lua_newtable(l); pi_lua_table_ro(l); SystemPath here = s->GetPath(); int here_x = here.sectorX; int here_y = here.sectorY; int here_z = here.sectorZ; Uint32 here_idx = here.systemIndex; Sector here_sec(here_x, here_y, here_z); int diff_sec = int(ceil(dist_ly/Sector::SIZE)); for (int x = here_x-diff_sec; x <= here_x+diff_sec; x++) { for (int y = here_y-diff_sec; y <= here_y+diff_sec; y++) { for (int z = here_z-diff_sec; z <= here_z+diff_sec; z++) { Sector sec(x, y, z); for (unsigned int idx = 0; idx < sec.m_systems.size(); idx++) { if (x == here_x && y == here_y && z == here_z && idx == here_idx) continue; if (Sector::DistanceBetween(&here_sec, here_idx, &sec, idx) > dist_ly) continue; RefCountedPtr<StarSystem> sys = StarSystem::GetCached(SystemPath(x, y, z, idx)); if (filter) { lua_pushvalue(l, 3); LuaStarSystem::PushToLua(sys.Get()); lua_call(l, 1, 1); if (!lua_toboolean(l, -1)) { lua_pop(l, 1); continue; } lua_pop(l, 1); } lua_pushinteger(l, lua_rawlen(l, -1)+1); LuaStarSystem::PushToLua(sys.Get()); lua_rawset(l, -3); } } } } LUA_DEBUG_END(l, 1); return 1; }
int lua_module_reload(lua_t* lua, const uuid_t uuid) { int ret = -1; lua_State* state = lua_state(lua); lua_modulemap_entry_t* entry = lua_module_registry_lookup(state, uuid); if (entry) { int stacksize = lua_gettop(state); lua_module_t module = lua_module_load_resource(uuid); if (module.size) { string_const_t uuidstr = string_from_uuid_static(uuid); log_debugf(HASH_LUA, STRING_CONST("Reloading module: %.*s"), STRING_FORMAT(uuidstr)); if (lua_module_upload(state, module.bytecode, module.size) == 0) { //Check if module loaded as a table if (lua_istable(state, -1)) { lua_pushlstring(state, STRING_CONST(BUILD_REGISTRY_LOADED_MODULES)); lua_gettable(state, LUA_REGISTRYINDEX); //Get and replace the old loaded module table lua_pushlightuserdata(state, entry); lua_gettable(state, -2); lua_replace(state, -2); //Get rid of loaded-modules registry table from stack if (lua_istable(state, -1)) { lua_pushlstring(state, STRING_CONST("__modulename")); lua_gettable(state, -2); size_t name_length = 0; const char* modulename = lua_isnil(state, -1) ? nullptr : luaL_checklstring(state, -1, &name_length); log_debugf(HASH_LUA, STRING_CONST("Replacing module table: %.*s (%.*s)"), STRING_FORMAT(uuidstr), (int)name_length, modulename); lua_pop(state, 1); //Get rid of name from stack //Clear previous loaded-modules table lua_pushnil(state); while (lua_next(state, -2) != 0) { lua_pop(state, 1); //Old value lua_pushnil(state); //Replace with nil lua_settable(state, -3); //Erase in previous loaded-modules table lua_pushnil(state); //Restart lua_next } //Copy new module table to previous loaded-modules table lua_pushnil(state); while (lua_next(state, -3) != 0) { //Lookup in new module table lua_pushvalue(state, -2); //Copy key lua_pushvalue(state, -2); //Copy value lua_settable(state, -5); //Set in previous loaded-modules table lua_pop(state, 1); //Pop value, leaving key for lua_next iteration } lua_pushlstring(state, STRING_CONST("__modulename")); lua_pushlstring(state, modulename, name_length); lua_settable(state, -3); } } ret = 0; } else { uuidstr = string_from_uuid_static(uuid); log_warnf(HASH_LUA, WARNING_RESOURCE, STRING_CONST("Unable to reload module '%.*s'"), STRING_FORMAT(uuidstr)); } } else { string_const_t uuidstr = string_from_uuid_static(uuid); log_warnf(HASH_LUA, WARNING_RESOURCE, STRING_CONST("Unable to load module '%.*s'"), STRING_FORMAT(uuidstr)); } lua_settop(state, stacksize); } else { string_const_t uuidstr = string_from_uuid_static(uuid); log_debugf(HASH_LUA, STRING_CONST("Reloading module ignored, not loaded: %.*s"), STRING_FORMAT(uuidstr)); } return ret; }
tagi_t* luasofia_tags_table_to_taglist(lua_State *L, int index, su_home_t *home) { int i = 0; int maxtags = TAGS_LIST_SIZE; tagi_t* tags = su_zalloc(home, sizeof(tagi_t) * maxtags); if(!lua_istable(L, index)) { tags[0].t_tag = NULL; tags[0].t_value = 0; return tags; } /* put the tag table at the stack */ lua_rawgeti(L, LUA_REGISTRYINDEX, tag_table_ref); if (lua_isnil(L, -1)) { su_free(home, tags); luaL_error(L, "Failed to get tag table!"); } if (index < 0) index--; /* first key */ lua_pushnil(L); while(lua_next(L, index) != 0) { /* 'key' at index -2 and 'value' at index -1 */ tag_type_t t_tag = NULL; tag_value_t return_value; char const *s = NULL; /* if 'value' is nil not use this tag */ if(lua_isnil(L, -1)) { /* remove 'value' and 'key' is used on the next iteration */ lua_pop(L, 1); continue; } s = lua_tostring(L, -1); /* lookup key in the tag table and push tag_type_t */ lua_pushvalue(L, -2); lua_rawget(L, -4); t_tag = lua_touserdata(L, -1); lua_pop(L, 1); if(t_scan(t_tag, home, s, &return_value) == -1) { su_free(home, tags); luaL_error(L, "Tag '%s' doesn't exist!", lua_tostring(L, -2)); } tags[i].t_tag = t_tag; tags[i++].t_value = return_value; if(i == maxtags - 1) { maxtags *= 2; tags = su_realloc(home, tags, sizeof(tagi_t) * maxtags); } /* remove 'value' and 'key' is used on the next iteration */ lua_pop(L, 1); } /* remove tag table from stack */ lua_pop(L, 1); tags[i].t_tag = NULL; tags[i].t_value = 0; return tags; }
/** * @param: the table (at stack 1) * @param: the cycle table (at stack 2) * @return: the table string */ static int l_pretty_repr_table(lua_State *L) { lua_pushvalue(L, 1); /* duplicate the table in stack 3 */ lua_rawget(L, 2); /* get from the cycle table 2 */ if (lua_isnil(L, -1)) { lua_pop(L, 1); /* save the table item into cycle table */ lua_pushfstring(L, "table_(%p)", lua_topointer(L, 1)); /* put in stack 3 */ lua_pushvalue(L, 1); /* push key in stack 4 */ lua_pushvalue(L, 3); /* push value in stack 5 */ lua_rawset(L, 2); /* adjust the cycle table and pop 4,5 */ /* save the level into cycle table */ lua_pushliteral(L, "level"); lua_rawget(L, 2); /* get the level into stack 4 */ int level = 1; if (!lua_isnil(L, -1)) { level += lua_tointeger(L, -1); } lua_pushliteral(L, "level"); lua_pushinteger(L, level); lua_rawset(L, 2); /* save the level and pop 5,6 */ /* luaL_Buffer START */ luaL_Buffer b; luaL_buffinit(L, &b); if (1) { luaL_addlstring(&b, "{\n", 2); } else { /* optional: suffix a pointer behind */ lua_pushfstring(L, "{ -- %p\n", lua_topointer(L, 1)); luaL_addvalue(&b); /* add the pointer value into buffer */ } /* iterate the table */ for (lua_pushnil(L); lua_next(L, 1) != 0; lua_pushvalue(L, 4)) { lua_replace(L, 3); /* backups the value in stack 3 */ lua_replace(L, 4); /* backups the key in stack 4 */ for (int i=level; i--; ) luaL_addchar(&b, '\t'); /* repr the key */ lua_pushcfunction(L, l_repr_key); lua_pushvalue(L, 4); lua_pushvalue(L, 2); lua_call(L, 2, 1); luaL_addvalue(&b); /* add the return value into buffer */ luaL_addlstring(&b, " = ", 3); /* repr the value */ lua_pushcfunction(L, l_pretty_repr_slice); lua_pushvalue(L, 3); lua_pushvalue(L, 2); lua_call(L, 2, 1); luaL_addvalue(&b); /* add the return value into buffer */ luaL_addlstring(&b, ",\n", 2); } --level; /* decrease level when table finished */ for (int i=level; i--; ) luaL_addchar(&b, '\t'); luaL_addchar(&b, '}'); luaL_pushresult(&b); /* luaL_Buffer END */ lua_pushliteral(L, "level"); lua_pushinteger(L, level); lua_rawset(L, 2); /* save the level and pop */ } else { /* just use the return value of gettable as the result */ } return 1; }
void ScriptApiEnv::initializeEnvironment(ServerEnvironment *env) { SCRIPTAPI_PRECHECKHEADER verbosestream<<"scriptapi_add_environment"<<std::endl; setEnv(env); /* Add ActiveBlockModifiers to environment */ // Get minetest.registered_abms lua_getglobal(L, "minetest"); lua_getfield(L, -1, "registered_abms"); luaL_checktype(L, -1, LUA_TTABLE); int registered_abms = lua_gettop(L); if(lua_istable(L, registered_abms)){ int table = lua_gettop(L); lua_pushnil(L); while(lua_next(L, table) != 0){ // key at index -2 and value at index -1 int id = lua_tonumber(L, -2); int current_abm = lua_gettop(L); std::set<std::string> trigger_contents; lua_getfield(L, current_abm, "nodenames"); if(lua_istable(L, -1)){ int table = lua_gettop(L); lua_pushnil(L); while(lua_next(L, table) != 0){ // key at index -2 and value at index -1 luaL_checktype(L, -1, LUA_TSTRING); trigger_contents.insert(lua_tostring(L, -1)); // removes value, keeps key for next iteration lua_pop(L, 1); } } else if(lua_isstring(L, -1)){ trigger_contents.insert(lua_tostring(L, -1)); } lua_pop(L, 1); std::set<std::string> required_neighbors; lua_getfield(L, current_abm, "neighbors"); if(lua_istable(L, -1)){ int table = lua_gettop(L); lua_pushnil(L); while(lua_next(L, table) != 0){ // key at index -2 and value at index -1 luaL_checktype(L, -1, LUA_TSTRING); required_neighbors.insert(lua_tostring(L, -1)); // removes value, keeps key for next iteration lua_pop(L, 1); } } else if(lua_isstring(L, -1)){ required_neighbors.insert(lua_tostring(L, -1)); } lua_pop(L, 1); float trigger_interval = 10.0; getfloatfield(L, current_abm, "interval", trigger_interval); int trigger_chance = 50; getintfield(L, current_abm, "chance", trigger_chance); LuaABM *abm = new LuaABM(L, id, trigger_contents, required_neighbors, trigger_interval, trigger_chance); env->addActiveBlockModifier(abm); // removes value, keeps key for next iteration lua_pop(L, 1); } } lua_pop(L, 1); }
int update_client_cont1(void) { int quitflag = 0; // skip while still loading if(mod_basedir == NULL || (boot_mode & 8)) return 0; #ifdef USE_OPENGL if (render_map_visible_chunks_count_dirty(clmap) > 0) force_redraw = 1; #endif // redraw scene if necessary if(force_redraw || fabsf(tcam.mpx-ompx) > 0.001f || fabsf(tcam.mpy-ompy) > 0.01f || fabsf(tcam.mpz-ompz) > 0.001f) { #ifdef RENDER_FACE_COUNT render_face_remain = 6; #else render_vxl_redraw(&tcam, clmap); #endif ompx = tcam.mpx; ompy = tcam.mpy; ompz = tcam.mpz; force_redraw = 0; } #ifdef RENDER_FACE_COUNT if(render_face_remain > 0) render_vxl_redraw(&tcam, clmap); #endif //printf("%.2f",); // draw scene to cubemap SDL_LockSurface(screen); //memset(screen->pixels, 0x51, screen->h*screen->pitch); render_cubemap((uint32_t*)screen->pixels, screen->w, screen->h, screen->pitch/4, &tcam, clmap); // apply Lua HUD / model stuff lua_getglobal(lstate_client, "client"); lua_getfield(lstate_client, -1, "hook_render"); lua_remove(lstate_client, -2); if(!lua_isnil(lstate_client, -1)) { if(lua_pcall(lstate_client, 0, 0, 0) != 0) { printf("Lua Client Error (render): %s\n", lua_tostring(lstate_client, -1)); lua_pop(lstate_client, 1); return 1; } } SDL_UnlockSurface(screen); #ifdef USE_OPENGL SDL_GL_SwapBuffers(); #else SDL_Flip(screen); #endif int msec_wait = 10*(int)(sec_wait*100.0f+0.5f); if(msec_wait > 0) { sec_wait -= msec_wait; SDL_Delay(msec_wait); } SDL_Event ev; while(SDL_PollEvent(&ev)) switch(ev.type) { case SDL_KEYUP: case SDL_KEYDOWN: // inform Lua client lua_getglobal(lstate_client, "client"); lua_getfield(lstate_client, -1, "hook_key"); lua_remove(lstate_client, -2); if(lua_isnil(lstate_client, -1)) { // not hooked? ignore! lua_pop(lstate_client, 1); break; } { char ch = ev.key.keysym.sym; if ((ev.key.keysym.unicode & 0xFF80) == 0) ch = ev.key.keysym.unicode & 0x1FF; lua_pushinteger(lstate_client, ev.key.keysym.sym); lua_pushboolean(lstate_client, (ev.type == SDL_KEYDOWN)); lua_pushinteger(lstate_client, (int)(ev.key.keysym.mod)); lua_pushinteger(lstate_client, ch); if(lua_pcall(lstate_client, 4, 0, 0) != 0) { printf("Lua Client Error (key): %s\n", lua_tostring(lstate_client, -1)); lua_pop(lstate_client, 1); quitflag = 1; break; } } break; case SDL_MOUSEBUTTONUP: case SDL_MOUSEBUTTONDOWN: // inform Lua client lua_getglobal(lstate_client, "client"); lua_getfield(lstate_client, -1, "hook_mouse_button"); lua_remove(lstate_client, -2); if(lua_isnil(lstate_client, -1)) { // not hooked? ignore! lua_pop(lstate_client, 1); break; } lua_pushinteger(lstate_client, ev.button.button); lua_pushboolean(lstate_client, (ev.type == SDL_MOUSEBUTTONDOWN)); if(lua_pcall(lstate_client, 2, 0, 0) != 0) { printf("Lua Client Error (mouse_button): %s\n", lua_tostring(lstate_client, -1)); lua_pop(lstate_client, 1); quitflag = 1; break; } break; case SDL_MOUSEMOTION: // inform Lua client lua_getglobal(lstate_client, "client"); lua_getfield(lstate_client, -1, "hook_mouse_motion"); lua_remove(lstate_client, -2); if(lua_isnil(lstate_client, -1)) { // not hooked? ignore! lua_pop(lstate_client, 1); break; } lua_pushinteger(lstate_client, ev.motion.x); lua_pushinteger(lstate_client, ev.motion.y); lua_pushinteger(lstate_client, ev.motion.xrel); lua_pushinteger(lstate_client, ev.motion.yrel); if(lua_pcall(lstate_client, 4, 0, 0) != 0) { printf("Lua Client Error (mouse_motion): %s\n", lua_tostring(lstate_client, -1)); lua_pop(lstate_client, 1); quitflag = 1; break; } break; case SDL_ACTIVEEVENT: if( ev.active.state & SDL_APPACTIVE || ev.active.state & SDL_APPINPUTFOCUS ) { lua_getglobal(lstate_client, "client"); lua_getfield(lstate_client, -1, "hook_window_activate"); lua_remove(lstate_client, -2); if(lua_isnil(lstate_client, -1)) { // not hooked? ignore! lua_pop(lstate_client, 1); break; } lua_pushboolean(lstate_client, ev.active.gain == 1); if(lua_pcall(lstate_client, 1, 0, 0) != 0) { printf("Lua Client Error (window_activate): %s\n", lua_tostring(lstate_client, -1)); lua_pop(lstate_client, 1); quitflag = 1; break; } } break; case SDL_QUIT: quitflag = 1; break; default: break; } return quitflag; }
bool LuaScriptEngine::unpersist(InputPersistenceBlock &reader) { // Empty the Lua stack. pluto_persist() xepects that the stack is empty except for its parameters lua_settop(_state, 0); // Permanents table is placed on the stack. This has already happened at this point, because // to create the table all permanents must be accessible. This is the case only for the // beginning of the function, because the global table is emptied below pushPermanentsTable(_state, PTT_UNPERSIST); // All items from global table of _G and __METATABLES are removed. // After a garbage collection is performed, and thus all managed objects deleted // __METATABLES is not immediately removed becausen the Metatables are needed // for the finalisers of objects. static const char *clearExceptionsFirstPass[] = { "_G", "__METATABLES", 0 }; clearGlobalTable(_state, clearExceptionsFirstPass); // In the second pass, the Metatables are removed static const char *clearExceptionsSecondPass[] = { "_G", 0 }; clearGlobalTable(_state, clearExceptionsSecondPass); // Persisted Lua data Common::Array<byte> chunkData; reader.readByteArray(chunkData); // Chunk-Reader initialisation. It is used with pluto_unpersist to restore read data ChunkreaderData cd; cd.BufferPtr = &chunkData[0]; cd.Size = chunkData.size(); cd.BufferReturned = false; pluto_unpersist(_state, chunkreader, &cd); // Permanents-Table is removed from stack lua_remove(_state, -2); // The read elements in the global table about lua_pushnil(_state); while (lua_next(_state, -2) != 0) { // The referenec to the global table (_G) must not be overwritten, or ticks from Lua total bool isGlobalReference = lua_isstring(_state, -2) && strcmp(lua_tostring(_state, -2), "_G") == 0; if (!isGlobalReference) { lua_pushvalue(_state, -2); lua_pushvalue(_state, -2); lua_settable(_state, LUA_GLOBALSINDEX); } // Pop value from the stack. The index is then ready for the next call to lua_next() lua_pop(_state, 1); } // The table with the loaded data is popped from the stack lua_pop(_state, 1); // Force garbage collection lua_gc(_state, LUA_GCCOLLECT, 0); return true; }
static int readconfigfile(void) { lua_State *L; char *string; xlog(2, "Reading Configuration file %s", _configfile); L = lua_open(); /* We don't open any librarires because we don't really want any function calls in the configuration file. It's just for setting a few globals. */ luaopen_base(L); lua_pushstring(L, "tagserver"); lua_setglobal(L, CONFIG_GLOBALNAME); /* load and run the configuration file */ if(luaL_loadfile(L, _configfile) || lua_pcall(L, 0, 0, 0)) { xerror("Problem executing configuration file - %s", lua_tostring(L, -1)); return 1; } /* tell lua to push these variables onto the stack */ // lua_getglobal(L, "daemonize"); // if(_daemonize < 0) { /* negative if not already set */ // _daemonize = lua_toboolean(L, -1); // } // lua_pop(L, 1); lua_getglobal(L, "statustag"); /* Do I really need to do this???? */ if(_statustag == NULL) { if( (string = (char *)lua_tostring(L, -1)) ) { _statustag = strdup(string); } } lua_pop(L, 1); lua_getglobal(L, "pidfile"); if(_pidfile == NULL) { if( (string = (char *)lua_tostring(L, -1)) ) { _pidfile = strdup(string); } } lua_pop(L, 1); lua_getglobal(L, "min_buffers"); if(_min_buffers == 0) { /* Make sure we didn't get anything on the commandline */ _min_buffers = (int)lua_tonumber(L, -1); } lua_pop(L, 1); lua_getglobal(L, "start_timeout"); if(_start_timeout == 0) { _start_timeout = (int)lua_tonumber(L, -1); } lua_pop(L, 1); /* TODO: This needs to be changed to handle the new topic handlers */ if(_verbosity == 0) { /* Make sure we didn't get anything on the commandline */ //_verbosity = (int)lua_tonumber(L, 4); //set_log_topic(_verbosity); set_log_topic(0xFFFFFFFF); } /* Clean up and get out */ lua_close(L); return 0; }
void read_object_properties(lua_State *L, int index, ObjectProperties *prop) { if(index < 0) index = lua_gettop(L) + 1 + index; if(!lua_istable(L, index)) return; prop->hp_max = getintfield_default(L, -1, "hp_max", 10); getboolfield(L, -1, "physical", prop->physical); getboolfield(L, -1, "collide_with_objects", prop->collideWithObjects); getfloatfield(L, -1, "weight", prop->weight); lua_getfield(L, -1, "collisionbox"); if(lua_istable(L, -1)) prop->collisionbox = read_aabb3f(L, -1, 1.0); lua_pop(L, 1); getstringfield(L, -1, "visual", prop->visual); getstringfield(L, -1, "mesh", prop->mesh); lua_getfield(L, -1, "visual_size"); if(lua_istable(L, -1)) prop->visual_size = read_v2f(L, -1); lua_pop(L, 1); lua_getfield(L, -1, "textures"); if(lua_istable(L, -1)){ prop->textures.clear(); int table = lua_gettop(L); lua_pushnil(L); while(lua_next(L, table) != 0){ // key at index -2 and value at index -1 if(lua_isstring(L, -1)) prop->textures.push_back(lua_tostring(L, -1)); else prop->textures.push_back(""); // removes value, keeps key for next iteration lua_pop(L, 1); } } lua_pop(L, 1); lua_getfield(L, -1, "colors"); if (lua_istable(L, -1)) { int table = lua_gettop(L); prop->colors.clear(); for (lua_pushnil(L); lua_next(L, table); lua_pop(L, 1)) { video::SColor color(255, 255, 255, 255); read_color(L, -1, &color); prop->colors.push_back(color); } } lua_pop(L, 1); lua_getfield(L, -1, "spritediv"); if(lua_istable(L, -1)) prop->spritediv = read_v2s16(L, -1); lua_pop(L, 1); lua_getfield(L, -1, "initial_sprite_basepos"); if(lua_istable(L, -1)) prop->initial_sprite_basepos = read_v2s16(L, -1); lua_pop(L, 1); getboolfield(L, -1, "is_visible", prop->is_visible); getboolfield(L, -1, "makes_footstep_sound", prop->makes_footstep_sound); getfloatfield(L, -1, "automatic_rotate", prop->automatic_rotate); if (getfloatfield(L, -1, "stepheight", prop->stepheight)) prop->stepheight *= BS; lua_getfield(L, -1, "automatic_face_movement_dir"); if (lua_isnumber(L, -1)) { prop->automatic_face_movement_dir = true; prop->automatic_face_movement_dir_offset = luaL_checknumber(L, -1); } else if (lua_isboolean(L, -1)) { prop->automatic_face_movement_dir = lua_toboolean(L, -1); prop->automatic_face_movement_dir_offset = 0.0; } lua_pop(L, 1); getboolfield(L, -1, "backface_culling", prop->backface_culling); getstringfield(L, -1, "nametag", prop->nametag); lua_getfield(L, -1, "nametag_color"); if (!lua_isnil(L, -1)) { video::SColor color = prop->nametag_color; if (read_color(L, -1, &color)) prop->nametag_color = color; } lua_pop(L, 1); lua_getfield(L, -1, "automatic_face_movement_max_rotation_per_sec"); if (lua_isnumber(L, -1)) { prop->automatic_face_movement_max_rotation_per_sec = luaL_checknumber(L, -1); } lua_pop(L, 1); getstringfield(L, -1, "infotext", prop->infotext); }