// Executes script code in this environment. void ScriptEnvironment::execute(const Script *script) { // initialize engine to work with Cursor and Range objects m_engine->evaluate(m_enginePluginCode,i18n("Cursor/Range plugin")); if ( m_engine->hasUncaughtException() ) { scriptError(i18n("Cursor/Range plugin")); return; } else { KILE_DEBUG() << "Cursor/Range plugin successfully installed "; } // set global objects if ( m_scriptView->view() ) { m_engine->globalObject().setProperty("view", m_engine->newQObject(m_scriptView)); m_engine->globalObject().setProperty("document", m_engine->newQObject(m_scriptDocument)); } m_engine->globalObject().setProperty("kile", m_engine->newQObject(m_kileScriptObject)); // export debug function m_engine->globalObject().setProperty("debug", m_engine->newFunction(KileScript::debug)); // start engine m_engine->evaluate(script->getCode()); // success or error if ( m_engine->hasUncaughtException() ) { scriptError(script->getName()); } else { KILE_DEBUG() << "script finished without errors"; } //FIXME: add time execution limit once it becomes available // bool useGuard = KileConfig::timeLimitEnabled(); // uint timeLimit = (uint)KileConfig::timeLimit(); // KJSCPUGuard guard; // if(useGuard) { // guard.start(timeLimit*1000); // } // KJS::Completion completion = m_interpreter->evaluate(QString(), 0, s); // if(useGuard) { // guard.stop(); // } QTimer::singleShot(0, m_scriptView->view(), SLOT(setFocus())); // remove global objects m_engine->globalObject().setProperty("view", QScriptValue()); m_engine->globalObject().setProperty("document", QScriptValue()); m_engine->globalObject().setProperty("kile", QScriptValue()); }
// Push the list of callbacks (a lua table). // Then push nargs arguments. // Then call this function, which // - runs the callbacks // - replaces the table and arguments with the return value, // computed depending on mode void ScriptApiBase::runCallbacksRaw(int nargs, RunCallbacksMode mode, const char *fxn) { lua_State *L = getStack(); FATAL_ERROR_IF(lua_gettop(L) < nargs + 1, "Not enough arguments"); // Insert error handler lua_pushcfunction(L, script_error_handler); int errorhandler = lua_gettop(L) - nargs - 1; lua_insert(L, errorhandler); // Insert run_callbacks between error handler and table lua_getglobal(L, "core"); lua_getfield(L, -1, "run_callbacks"); lua_remove(L, -2); lua_insert(L, errorhandler + 1); // Insert mode after table lua_pushnumber(L, (int)mode); lua_insert(L, errorhandler + 3); // Stack now looks like this: // ... <error handler> <run_callbacks> <table> <mode> <arg#1> <arg#2> ... <arg#n> int result = lua_pcall(L, nargs + 2, 1, errorhandler); if (result != 0) scriptError(result, fxn); lua_remove(L, -2); // Remove error handler }
// Calls entity:on_punch(ObjectRef puncher, time_from_last_punch, // tool_capabilities, direction) void ScriptApiEntity::luaentity_Punch(u16 id, ServerActiveObject *puncher, float time_from_last_punch, const ToolCapabilities *toolcap, v3f dir) { SCRIPTAPI_PRECHECKHEADER //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl; // Get minetest.luaentities[id] luaentity_get(L,id); int object = lua_gettop(L); // State: object is at top of stack // Get function lua_getfield(L, -1, "on_punch"); if(lua_isnil(L, -1)) return; luaL_checktype(L, -1, LUA_TFUNCTION); lua_pushvalue(L, object); // self objectrefGetOrCreate(puncher); // Clicker reference lua_pushnumber(L, time_from_last_punch); push_tool_capabilities(L, *toolcap); push_v3f(L, dir); // Call with 5 arguments, 0 results if(lua_pcall(L, 5, 0, 0)) scriptError("error running function 'on_punch': %s\n", lua_tostring(L, -1)); }
void ScriptApiMainMenu::handleMainMenuButtons(std::map<std::string, std::string> fields) { SCRIPTAPI_PRECHECKHEADER lua_pushcfunction(L, script_error_handler); int errorhandler = lua_gettop(L); // Get handler function lua_getglobal(L, "engine"); lua_getfield(L, -1, "button_handler"); lua_remove(L, -2); // Remove engine if(lua_isnil(L, -1)) { lua_pop(L, 1); // Pop button handler return; } luaL_checktype(L, -1, LUA_TFUNCTION); // Convert fields to lua table lua_newtable(L); for(std::map<std::string, std::string>::const_iterator i = fields.begin(); i != fields.end(); i++){ const std::string &name = i->first; const std::string &value = i->second; lua_pushstring(L, name.c_str()); lua_pushlstring(L, value.c_str(), value.size()); lua_settable(L, -3); } // Call it if(lua_pcall(L, 1, 0, errorhandler)) scriptError(); lua_pop(L, 1); // Pop error handler }
void ScriptApiEntity::luaentity_Activate(u16 id, const std::string &staticdata, u32 dtime_s) { SCRIPTAPI_PRECHECKHEADER verbosestream<<"scriptapi_luaentity_activate: id="<<id<<std::endl; // Get minetest.luaentities[id] luaentity_get(L,id); int object = lua_gettop(L); // Get on_activate function lua_pushvalue(L, object); lua_getfield(L, -1, "on_activate"); if(!lua_isnil(L, -1)){ luaL_checktype(L, -1, LUA_TFUNCTION); lua_pushvalue(L, object); // self lua_pushlstring(L, staticdata.c_str(), staticdata.size()); lua_pushinteger(L, dtime_s); // Call with 3 arguments, 0 results if(lua_pcall(L, 3, 0, 0)) scriptError("error running function on_activate: %s\n", lua_tostring(L, -1)); } }
// Return number of accepted items to be put int ScriptApiNodemeta::nodemeta_inventory_AllowPut(v3s16 p, const std::string &listname, int index, ItemStack &stack, ServerActiveObject *player) { SCRIPTAPI_PRECHECKHEADER INodeDefManager *ndef = getServer()->ndef(); // If node doesn't exist, we don't know what callback to call MapNode node = getEnv()->getMap().getNodeNoEx(p); if (node.getContent() == CONTENT_IGNORE) return 0; // Push callback function on stack std::string nodename = ndef->get(node).name; if (!getItemCallback(nodename.c_str(), "allow_metadata_inventory_put")) return stack.count; // Call function(pos, listname, index, stack, player) push_v3s16(L, p); // pos lua_pushstring(L, listname.c_str()); // listname lua_pushinteger(L, index + 1); // index LuaItemStack::create(L, stack); // stack objectrefGetOrCreate(L, player); // player if (lua_pcall(L, 5, 1, m_errorhandler)) scriptError(); if(!lua_isnumber(L, -1)) throw LuaError("allow_metadata_inventory_put should" " return a number, guilty node: " + nodename); int num = luaL_checkinteger(L, -1); lua_pop(L, 1); // Pop integer return num; }
void ScriptApiEntity::luaentity_Step(u16 id, float dtime) { SCRIPTAPI_PRECHECKHEADER lua_pushcfunction(L, script_error_handler); int errorhandler = lua_gettop(L); //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl; // Get minetest.luaentities[id] luaentity_get(L, id); int object = lua_gettop(L); // State: object is at top of stack // Get step function lua_getfield(L, -1, "on_step"); if(lua_isnil(L, -1)) return; luaL_checktype(L, -1, LUA_TFUNCTION); lua_pushvalue(L, object); // self lua_pushnumber(L, dtime); // dtime // Call with 2 arguments, 0 results if(lua_pcall(L, 2, 0, errorhandler)) scriptError(); lua_remove(L, object); // Remove object lua_remove(L, errorhandler); // Remove error handler }
// Report moved items void ScriptApiNodemeta::nodemeta_inventory_OnMove(v3s16 p, const std::string &from_list, int from_index, const std::string &to_list, int to_index, int count, ServerActiveObject *player) { SCRIPTAPI_PRECHECKHEADER lua_pushcfunction(L, script_error_handler); int errorhandler = lua_gettop(L); INodeDefManager *ndef = getServer()->ndef(); // If node doesn't exist, we don't know what callback to call MapNode node = getEnv()->getMap().getNodeNoEx(p); if(node.getContent() == CONTENT_IGNORE) return; // Push callback function on stack if(!getItemCallback(ndef->get(node).name.c_str(), "on_metadata_inventory_move")) return; // function(pos, from_list, from_index, to_list, to_index, count, player) push_v3s16(L, p); // pos lua_pushstring(L, from_list.c_str()); // from_list lua_pushinteger(L, from_index + 1); // from_index lua_pushstring(L, to_list.c_str()); // to_list lua_pushinteger(L, to_index + 1); // to_index lua_pushinteger(L, count); // count objectrefGetOrCreate(player); // player if(lua_pcall(L, 7, 0, errorhandler)) scriptError(); lua_pop(L, 1); // Pop error handler }
// Report taken items void ScriptApiNodemeta::nodemeta_inventory_OnTake(v3s16 p, const std::string &listname, int index, ItemStack &stack, ServerActiveObject *player) { SCRIPTAPI_PRECHECKHEADER lua_pushcfunction(L, script_error_handler); int errorhandler = lua_gettop(L); INodeDefManager *ndef = getServer()->ndef(); // If node doesn't exist, we don't know what callback to call MapNode node = getEnv()->getMap().getNodeNoEx(p); if(node.getContent() == CONTENT_IGNORE) return; // Push callback function on stack if(!getItemCallback(ndef->get(node).name.c_str(), "on_metadata_inventory_take")) return; // Call function(pos, listname, index, stack, player) push_v3s16(L, p); // pos lua_pushstring(L, listname.c_str()); // listname lua_pushinteger(L, index + 1); // index LuaItemStack::create(L, stack); // stack objectrefGetOrCreate(player); // player if(lua_pcall(L, 5, 0, errorhandler)) scriptError(); lua_pop(L, 1); // Pop error handler }
bool ScriptApiItem::item_CraftPredict(ItemStack &item, ServerActiveObject *user, const InventoryList *old_craft_grid, const InventoryLocation &craft_inv) { SCRIPTAPI_PRECHECKHEADER lua_pushcfunction(L, script_error_handler); int errorhandler = lua_gettop(L); lua_getglobal(L, "minetest"); lua_getfield(L, -1, "craft_predict"); LuaItemStack::create(L, item); objectrefGetOrCreate(user); //Push inventory list std::vector<ItemStack> items; for(u32 i=0; i<old_craft_grid->getSize(); i++) items.push_back(old_craft_grid->getItem(i)); push_items(L, items); InvRef::create(L, craft_inv); if(lua_pcall(L, 4, 1, errorhandler)) scriptError(); if(!lua_isnil(L, -1)) { try { item = read_item(L,-1, getServer()); } catch (LuaError &e) { throw LuaError(std::string(e.what()) + ". item=" + item.name); } } lua_pop(L, 2); // Pop item and error handler return true; }
std::string ScriptApiEntity::luaentity_GetStaticdata(u16 id) { SCRIPTAPI_PRECHECKHEADER //infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl; // Get minetest.luaentities[id] luaentity_get(L,id); int object = lua_gettop(L); // Get get_staticdata function lua_pushvalue(L, object); lua_getfield(L, -1, "get_staticdata"); if(lua_isnil(L, -1)) return ""; luaL_checktype(L, -1, LUA_TFUNCTION); lua_pushvalue(L, object); // self // Call with 1 arguments, 1 results if(lua_pcall(L, 1, 1, 0)) scriptError("error running function get_staticdata: %s\n", lua_tostring(L, -1)); size_t len=0; const char *s = lua_tolstring(L, -1, &len); return std::string(s, len); }
void ScriptApiNode::node_on_receive_fields(v3s16 p, const std::string &formname, const std::map<std::string, std::string> &fields, ServerActiveObject *sender) { SCRIPTAPI_PRECHECKHEADER INodeDefManager *ndef = getServer()->ndef(); // If node doesn't exist, we don't know what callback to call MapNode node = getEnv()->getMap().getNodeNoEx(p); if (node.getContent() == CONTENT_IGNORE) return; // Push callback function on stack if (!getItemCallback(ndef->get(node).name.c_str(), "on_receive_fields")) return; // Call function push_v3s16(L, p); // pos lua_pushstring(L, formname.c_str()); // formname lua_newtable(L); // fields std::map<std::string, std::string>::const_iterator it; for (it = fields.begin(); it != fields.end(); it++){ const std::string &name = it->first; const std::string &value = it->second; lua_pushstring(L, name.c_str()); lua_pushlstring(L, value.c_str(), value.size()); lua_settable(L, -3); } objectrefGetOrCreate(sender); // player if (lua_pcall(L, 4, 0, m_errorhandler)) scriptError(); }
bool ScriptApiItem::item_OnUse(ItemStack &item, ServerActiveObject *user, const PointedThing &pointed) { SCRIPTAPI_PRECHECKHEADER lua_pushcfunction(L, script_error_handler); int errorhandler = lua_gettop(L); // Push callback function on stack if(!getItemCallback(item.name.c_str(), "on_use")) return false; // Call function LuaItemStack::create(L, item); objectrefGetOrCreate(user); pushPointedThing(pointed); if(lua_pcall(L, 3, 1, errorhandler)) scriptError(); if(!lua_isnil(L, -1)) { try { item = read_item(L,-1, getServer()); } catch (LuaError &e) { throw LuaError(std::string(e.what()) + ". item=" + item.name); } } lua_pop(L, 2); // Pop item and error handler return true; }
// Calls entity:on_rightclick(ObjectRef clicker) void ScriptApiEntity::luaentity_Rightclick(u16 id, ServerActiveObject *clicker) { SCRIPTAPI_PRECHECKHEADER //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl; // Get core.luaentities[id] luaentity_get(L, id); int object = lua_gettop(L); // State: object is at top of stack // Get function lua_getfield(L, -1, "on_rightclick"); if (lua_isnil(L, -1)) { lua_pop(L, 2); // Pop on_rightclick and entity return; } luaL_checktype(L, -1, LUA_TFUNCTION); lua_pushvalue(L, object); // self objectrefGetOrCreate(L, clicker); // Clicker reference // Call with 2 arguments, 0 results if (lua_pcall(L, 2, 0, m_errorhandler)) scriptError(); lua_pop(L, 1); // Pop object }
std::string ScriptApiEntity::luaentity_GetStaticdata(u16 id) { SCRIPTAPI_PRECHECKHEADER //infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl; // Get core.luaentities[id] luaentity_get(L, id); int object = lua_gettop(L); // Get get_staticdata function lua_getfield(L, -1, "get_staticdata"); if (lua_isnil(L, -1)) { lua_pop(L, 2); // Pop entity and get_staticdata return ""; } luaL_checktype(L, -1, LUA_TFUNCTION); lua_pushvalue(L, object); // self // Call with 1 arguments, 1 results if (lua_pcall(L, 1, 1, m_errorhandler)) scriptError(); lua_remove(L, object); // Remove object size_t len = 0; const char *s = lua_tolstring(L, -1, &len); lua_pop(L, 1); // Pop static data return std::string(s, len); }
void ScriptApiBase::realityCheck() { int top = lua_gettop(m_luastack); if(top >= 30){ dstream<<"Stack is over 30:"<<std::endl; stackDump(dstream); scriptError("Stack is over 30 (reality check)"); } }
void ScriptApiNode::node_falling_update_single(v3s16 p) { SCRIPTAPI_PRECHECKHEADER lua_getglobal(L, "nodeupdate_single"); push_v3s16(L, p); if (lua_pcall(L, 1, 0, m_errorhandler)) scriptError(); }
void TarryTown::emitScriptError() { if (p_engine->hasUncaughtException()) { QStringList backtrace = p_engine->uncaughtExceptionBacktrace(); fprintf (stderr, " %s\n\n", qPrintable(backtrace.join("\n"))); emit scriptError(p_engine->uncaughtException()); } }
void parseScriptLine(char *str) { char *line = strdup(str); char *pch = strtok(str, " "); if (pch == NULL) scriptError("No command given in script"); else { if (strcmp(pch, "set") == 0) parseScriptSet(line); else if (strcmp(pch, "int") == 0) parseScriptNewInt(line); else if (strcmp(pch, "float") == 0) parseScriptNewFloat(line); else scriptError("Unknown command: %s", str); } free(line); }
//! [0] Window::Window(QWidget *parent) : QWidget(parent) { m_env = new Environment(this); QObject::connect(m_env, SIGNAL(scriptError(QScriptValue)), this, SLOT(reportScriptError(QScriptValue))); Context2D *context = new Context2D(this); context->setSize(150, 150); m_canvas = new QContext2DCanvas(context, m_env, this); m_canvas->setFixedSize(context->size()); m_canvas->setObjectName("tutorial"); m_env->addCanvas(m_canvas); //! [0] #ifndef QT_NO_SCRIPTTOOLS QVBoxLayout *vbox = new QVBoxLayout(); vbox->addWidget(m_canvas); m_debugButton = new QPushButton(tr("Run in Debugger")); connect(m_debugButton, SIGNAL(clicked()), this, SLOT(runInDebugger())); vbox->addWidget(m_debugButton); #endif QHBoxLayout *hbox = new QHBoxLayout(this); m_view = new QListWidget(this); m_view->setEditTriggers(QAbstractItemView::NoEditTriggers); hbox->addWidget(m_view); #ifndef QT_NO_SCRIPTTOOLS hbox->addLayout(vbox); #else hbox->addWidget(m_canvas); #endif //! [1] QDir dir(scriptsDir()); QFileInfoList entries = dir.entryInfoList(QStringList() << "*.js"); for (int i = 0; i < entries.size(); ++i) m_view->addItem(entries.at(i).fileName()); connect(m_view, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), this, SLOT(selectScript(QListWidgetItem*))); //! [1] #ifndef QT_NO_SCRIPTTOOLS m_debugger = new QScriptEngineDebugger(this); m_debugger->attachTo(m_env->engine()); m_debugWindow = m_debugger->standardWindow(); m_debugWindow->setWindowModality(Qt::ApplicationModal); m_debugWindow->resize(1280, 704); #endif setWindowTitle(tr("Context 2D")); }
void parseScriptNewInt(char *str) { char *pch = strtok(NULL, " "); if (pch == NULL) scriptError("No name defined for variable"); else { script_var<int> *var = new script_var<int>; var->name = strdup(pch); var->value = 0; script_ivars.push_back(var); } }
void ScriptApiNode::node_falling_update_single(v3s16 p) { SCRIPTAPI_PRECHECKHEADER lua_pushcfunction(L, script_error_handler); int errorhandler = lua_gettop(L); lua_getglobal(L, "nodeupdate_single"); push_v3s16(L, p); if(lua_pcall(L, 1, 0, errorhandler)) scriptError(); lua_pop(L, 1); // Pop error handler }
void ScriptApiNode::node_drop(v3s16 p, int fast = 0) { SCRIPTAPI_PRECHECKHEADER lua_pushcfunction(L, script_error_handler); int errorhandler = lua_gettop(L); lua_getglobal(L, "node_drop"); push_v3s16(L, p); lua_pushinteger(L, fast); if(lua_pcall(L, 2, 0, errorhandler)) scriptError(); lua_pop(L, 1); // Pop error handler }
void ScriptApiNode::node_on_destruct(v3s16 p, MapNode node) { SCRIPTAPI_PRECHECKHEADER INodeDefManager *ndef = getServer()->ndef(); // Push callback function on stack if(!getItemCallback(ndef->get(node).name.c_str(), "on_destruct")) return; // Call function push_v3s16(L, p); if(lua_pcall(L, 1, 0, 0)) scriptError("error: %s", lua_tostring(L, -1)); }
void ScriptApiNode::node_after_destruct(v3s16 p, MapNode node) { SCRIPTAPI_PRECHECKHEADER INodeDefManager *ndef = getServer()->ndef(); // Push callback function on stack if (!getItemCallback(ndef->get(node).name.c_str(), "after_destruct")) return; // Call function push_v3s16(L, p); pushnode(L, node, ndef); if (lua_pcall(L, 2, 0, m_errorhandler)) scriptError(); }
bool ScriptApiNode::node_on_timer(v3s16 p, MapNode node, f32 dtime) { SCRIPTAPI_PRECHECKHEADER INodeDefManager *ndef = getServer()->ndef(); // Push callback function on stack if (!getItemCallback(ndef->get(node).name.c_str(), "on_timer")) return false; // Call function push_v3s16(L, p); lua_pushnumber(L,dtime); if (lua_pcall(L, 2, 1, m_errorhandler)) scriptError(); return (bool) lua_isboolean(L, -1) && (bool) lua_toboolean(L, -1) == true; }
s16 ScriptApiPlayer::on_player_hpchange(ServerActiveObject *player, s16 hp_change) { SCRIPTAPI_PRECHECKHEADER // Get core.registered_on_player_hpchange lua_getglobal(L, "core"); lua_getfield(L, -1, "registered_on_player_hpchange"); lua_remove(L, -2); objectrefGetOrCreate(L, player); lua_pushnumber(L, hp_change); if (lua_pcall(L, 2, 1, m_errorhandler)) scriptError(); hp_change = lua_tointeger(L, -1); lua_pop(L, -1); return hp_change; }
void ScriptApiNode::node_on_deactivate(v3s16 p, MapNode node) { SCRIPTAPI_PRECHECKHEADER lua_pushcfunction(L, script_error_handler); int errorhandler = lua_gettop(L); INodeDefManager *ndef = getServer()->ndef(); // Push callback function on stack if(!getItemCallback(ndef->get(node).name.c_str(), "on_deactivate")) return; // Call function push_v3s16(L, p); if(lua_pcall(L, 1, 0, errorhandler)) scriptError(); lua_pop(L, 1); // Pop error handler }
bool ScriptApiNode::node_on_punch(v3s16 p, MapNode node, ServerActiveObject *puncher) { SCRIPTAPI_PRECHECKHEADER INodeDefManager *ndef = getServer()->ndef(); // Push callback function on stack if(!getItemCallback(ndef->get(node).name.c_str(), "on_punch")) return false; // Call function push_v3s16(L, p); pushnode(L, node, ndef); objectrefGetOrCreate(puncher); if(lua_pcall(L, 3, 0, 0)) scriptError("error: %s", lua_tostring(L, -1)); return true; }
// Calls entity:on_rightclick(ObjectRef clicker) void ScriptApiEntity::luaentity_Rightclick(u16 id, ServerActiveObject *clicker) { SCRIPTAPI_PRECHECKHEADER //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl; // Get minetest.luaentities[id] luaentity_get(L,id); int object = lua_gettop(L); // State: object is at top of stack // Get function lua_getfield(L, -1, "on_rightclick"); if(lua_isnil(L, -1)) return; luaL_checktype(L, -1, LUA_TFUNCTION); lua_pushvalue(L, object); // self objectrefGetOrCreate(clicker); // Clicker reference // Call with 2 arguments, 0 results if(lua_pcall(L, 2, 0, 0)) scriptError("error running function 'on_rightclick': %s\n", lua_tostring(L, -1)); }