diff options
Diffstat (limited to 'indra/newview')
-rw-r--r-- | indra/newview/app_settings/settings.xml | 11 | ||||
-rw-r--r-- | indra/newview/llagentlistener.cpp | 153 | ||||
-rw-r--r-- | indra/newview/llagentlistener.h | 5 | ||||
-rw-r--r-- | indra/newview/llfloaterluadebug.cpp | 4 | ||||
-rw-r--r-- | indra/newview/llinventorylistener.cpp | 6 | ||||
-rw-r--r-- | indra/newview/llluamanager.cpp | 9 | ||||
-rw-r--r-- | indra/newview/llviewerwindowlistener.cpp | 9 | ||||
-rw-r--r-- | indra/newview/scripts/lua/require/LLAgent.lua | 45 | ||||
-rw-r--r-- | indra/newview/scripts/lua/require/UI.lua | 8 | ||||
-rw-r--r-- | indra/newview/scripts/lua/test_LLChatListener.lua | 9 | ||||
-rw-r--r-- | indra/newview/scripts/lua/test_animation.lua | 18 | ||||
-rw-r--r-- | indra/newview/scripts/lua/test_luafloater_demo.lua | 2 | ||||
-rw-r--r-- | indra/newview/scripts/lua/test_nearby_avatars.lua | 25 | ||||
-rw-r--r-- | indra/newview/scripts/lua/test_screen_position.lua | 8 | ||||
-rw-r--r-- | indra/newview/scripts/lua/test_toolbars.lua | 4 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/floater_lua_debug.xml | 11 |
16 files changed, 299 insertions, 28 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index ea8d268721..35d1542c6c 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -4133,6 +4133,17 @@ <key>Value</key> <array /> </map> + <key>LuaDebugShowSource</key> + <map> + <key>Comment</key> + <string>Show source info in Lua Debug Console output</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>GridStatusRSS</key> <map> <key>Comment</key> diff --git a/indra/newview/llagentlistener.cpp b/indra/newview/llagentlistener.cpp index 14e443ec4e..9255a850e5 100644 --- a/indra/newview/llagentlistener.cpp +++ b/indra/newview/llagentlistener.cpp @@ -32,11 +32,14 @@ #include "llagent.h" #include "llagentcamera.h" +#include "llavatarname.h" +#include "llavatarnamecache.h" #include "llvoavatar.h" #include "llcommandhandler.h" #include "llinventorymodel.h" #include "llslurl.h" #include "llurldispatcher.h" +#include "llviewercontrol.h" #include "llviewernetwork.h" #include "llviewerobject.h" #include "llviewerobjectlist.h" @@ -46,7 +49,8 @@ #include "llsdutil_math.h" #include "lltoolgrab.h" #include "llhudeffectlookat.h" -#include "llagentcamera.h" +#include "llviewercamera.h" +#include "resultset.h" #include <functional> static const F64 PLAY_ANIM_THROTTLE_PERIOD = 1.f; @@ -176,6 +180,32 @@ LLAgentListener::LLAgentListener(LLAgent &agent) "Return information about [\"item_id\"] animation", &LLAgentListener::getAnimationInfo, llsd::map("item_id", LLSD(), "reply", LLSD())); + + add("getID", + "Return your own avatar ID", + &LLAgentListener::getID, + llsd::map("reply", LLSD())); + + add("getNearbyAvatarsList", + "Return result set key [\"result\"] for nearby avatars in a range of [\"dist\"]\n" + "if [\"dist\"] is not specified, 'RenderFarClip' setting is used\n" + "reply contains \"result\" table with \"id\", \"name\", \"global_pos\", \"region_pos\" fields", + &LLAgentListener::getNearbyAvatarsList, + llsd::map("reply", LLSD())); + + add("getNearbyObjectsList", + "Return result set key [\"result\"] for nearby objects in a range of [\"dist\"]\n" + "if [\"dist\"] is not specified, 'RenderFarClip' setting is used\n" + "reply contains \"result\" table with \"id\", \"global_pos\", \"region_pos\" fields", + &LLAgentListener::getNearbyObjectsList, + llsd::map("reply", LLSD())); + + add("getAgentScreenPos", + "Return screen position of the [\"avatar_id\"] avatar or own avatar if not specified\n" + "reply contains \"x\", \"y\" coordinates and \"onscreen\" flag to indicate if it's actually in within the current window\n" + "avatar render position is used as the point", + &LLAgentListener::getAgentScreenPos, + llsd::map("reply", LLSD())); } void LLAgentListener::requestTeleport(LLSD const & event_data) const @@ -693,3 +723,124 @@ void LLAgentListener::getAnimationInfo(LLSD const &event_data) "priority", motion->getPriority()); } } + +void LLAgentListener::getID(LLSD const& event_data) +{ + Response response(llsd::map("id", gAgentID), event_data); +} + +struct AvResultSet : public LL::ResultSet +{ + AvResultSet() : LL::ResultSet("nearby_avatars") {} + std::vector<LLCharacter*> mAvatars; + + int getLength() const override { return narrow(mAvatars.size()); } + LLSD getSingle(int index) const override + { + auto av = mAvatars[index]; + LLAvatarName av_name; + LLAvatarNameCache::get(av->getID(), &av_name); + LLVector3 region_pos = av->getCharacterPosition(); + return llsd::map("id", av->getID(), + "global_pos", ll_sd_from_vector3d(av->getPosGlobalFromAgent(region_pos)), + "region_pos", ll_sd_from_vector3(region_pos), + "name", av_name.getUserName()); + } +}; + +struct ObjResultSet : public LL::ResultSet +{ + ObjResultSet() : LL::ResultSet("nearby_objects") {} + std::vector<LLViewerObject*> mObjects; + + int getLength() const override { return narrow(mObjects.size()); } + LLSD getSingle(int index) const override + { + auto obj = mObjects[index]; + return llsd::map("id", obj->getID(), + "global_pos", ll_sd_from_vector3d(obj->getPositionGlobal()), + "region_pos", ll_sd_from_vector3(obj->getPositionRegion())); + } +}; + + +F32 get_search_radius(LLSD const& event_data) +{ + static LLCachedControl<F32> render_far_clip(gSavedSettings, "RenderFarClip", 64); + F32 dist = render_far_clip; + if (event_data.has("dist")) + { + dist = llclamp((F32)event_data["dist"].asReal(), 1, 512); + } + return dist * dist; +} + +void LLAgentListener::getNearbyAvatarsList(LLSD const& event_data) +{ + Response response(LLSD(), event_data); + auto avresult = new AvResultSet; + + F32 radius = get_search_radius(event_data); + LLVector3d agent_pos = gAgent.getPositionGlobal(); + for (LLCharacter* character : LLCharacter::sInstances) + { + LLVOAvatar* avatar = (LLVOAvatar*)character; + if (!avatar->isDead() && !avatar->isControlAvatar() && !avatar->isSelf()) + { + if ((dist_vec_squared(avatar->getPositionGlobal(), agent_pos) <= radius)) + { + avresult->mAvatars.push_back(avatar); + } + } + } + response["result"] = avresult->getKeyLength(); +} + +void LLAgentListener::getNearbyObjectsList(LLSD const& event_data) +{ + Response response(LLSD(), event_data); + auto objresult = new ObjResultSet; + + F32 radius = get_search_radius(event_data); + S32 num_objects = gObjectList.getNumObjects(); + LLVector3d agent_pos = gAgent.getPositionGlobal(); + for (S32 i = 0; i < num_objects; ++i) + { + LLViewerObject* object = gObjectList.getObject(i); + if (object && object->getVolume() && !object->isAttachment()) + { + if ((dist_vec_squared(object->getPositionGlobal(), agent_pos) <= radius)) + { + objresult->mObjects.push_back(object); + } + } + } + response["result"] = objresult->getKeyLength(); +} + +void LLAgentListener::getAgentScreenPos(LLSD const& event_data) +{ + Response response(LLSD(), event_data); + LLVector3 render_pos; + if (event_data.has("avatar_id")) + { + LLUUID avatar_id(event_data["avatar_id"]); + for (LLCharacter* character : LLCharacter::sInstances) + { + LLVOAvatar* avatar = (LLVOAvatar*)character; + if (!avatar->isDead() && (avatar->getID() == avatar_id)) + { + render_pos = avatar->getRenderPosition(); + break; + } + } + } + else if (gAgentAvatarp.notNull() && gAgentAvatarp->isValid()) + { + render_pos = gAgentAvatarp->getRenderPosition(); + } + LLCoordGL screen_pos; + response["onscreen"] = LLViewerCamera::getInstance()->projectPosAgentToScreen(render_pos, screen_pos, false); + response["x"] = screen_pos.mX; + response["y"] = screen_pos.mY; +} diff --git a/indra/newview/llagentlistener.h b/indra/newview/llagentlistener.h index 05724ff443..8801c9f7ea 100644 --- a/indra/newview/llagentlistener.h +++ b/indra/newview/llagentlistener.h @@ -67,6 +67,11 @@ private: void stopAnimation(LLSD const &event_data); void getAnimationInfo(LLSD const &event_data); + void getID(LLSD const& event_data); + void getNearbyAvatarsList(LLSD const& event_data); + void getNearbyObjectsList(LLSD const& event_data); + void getAgentScreenPos(LLSD const& event_data); + LLViewerObject * findObjectClosestTo( const LLVector3 & position, bool sit_target = false ) const; private: diff --git a/indra/newview/llfloaterluadebug.cpp b/indra/newview/llfloaterluadebug.cpp index 06877df816..f7f3b8d588 100644 --- a/indra/newview/llfloaterluadebug.cpp +++ b/indra/newview/llfloaterluadebug.cpp @@ -58,7 +58,9 @@ bool LLFloaterLUADebug::postBuild() .listen("LLFloaterLUADebug", [mResultOutput=mResultOutput](const LLSD& data) { - mResultOutput->pasteTextWithLinebreaks(data.asString()); + LLCachedControl<bool> show_source_info(gSavedSettings, "LuaDebugShowSource", false); + std::string source_info = show_source_info ? data["source_info"].asString() : ""; + mResultOutput->pasteTextWithLinebreaks(data["level"].asString() + source_info + data["msg"].asString()); mResultOutput->addLineBreakChar(true); return false; }); diff --git a/indra/newview/llinventorylistener.cpp b/indra/newview/llinventorylistener.cpp index 79726c3e0b..88b07c0b0b 100644 --- a/indra/newview/llinventorylistener.cpp +++ b/indra/newview/llinventorylistener.cpp @@ -116,7 +116,8 @@ struct CatResultSet: public LL::ResultSet LLSD getSingle(int index) const override { auto cat = mCategories[index]; - return llsd::map("name", cat->getName(), + return llsd::map("id", cat->getUUID(), + "name", cat->getName(), "parent_id", cat->getParentUUID(), "type", LLFolderType::lookup(cat->getPreferredType())); } @@ -133,7 +134,8 @@ struct ItemResultSet: public LL::ResultSet LLSD getSingle(int index) const override { auto item = mItems[index]; - return llsd::map("name", item->getName(), + return llsd::map("id", item->getUUID(), + "name", item->getName(), "parent_id", item->getParentUUID(), "desc", item->getDescription(), "inv_type", LLInventoryType::lookup(item->getInventoryType()), diff --git a/indra/newview/llluamanager.cpp b/indra/newview/llluamanager.cpp index 7fe5c1ece0..4a65276384 100644 --- a/indra/newview/llluamanager.cpp +++ b/indra/newview/llluamanager.cpp @@ -72,9 +72,10 @@ std::string lua_print_msg(lua_State* L, std::string_view level) lluau_checkstack(L, 2); luaL_where(L, 1); // start with the 'where' info at the top of the stack - std::ostringstream out; - out << lua_tostring(L, -1); + std::string source_info{ lua_tostring(L, -1) }; lua_pop(L, 1); + + std::ostringstream out; const char* sep = ""; // 'where' info ends with ": " // now iterate over arbitrary args, calling Lua tostring() on each and // concatenating with separators @@ -101,10 +102,10 @@ std::string lua_print_msg(lua_State* L, std::string_view level) // capture message string std::string msg{ out.str() }; // put message out there for any interested party (*koff* LLFloaterLUADebug *koff*) - LLEventPumps::instance().obtain("lua output").post(stringize(level, ": ", msg)); + LLEventPumps::instance().obtain("lua output").post(llsd::map("msg", msg, "level", stringize(level, ": "), "source_info", source_info)); llcoro::suspend(); - return msg; + return source_info + msg; } lua_function(print_debug, "print_debug(args...): DEBUG level logging") diff --git a/indra/newview/llviewerwindowlistener.cpp b/indra/newview/llviewerwindowlistener.cpp index 52f413792a..6ce5e68642 100644 --- a/indra/newview/llviewerwindowlistener.cpp +++ b/indra/newview/llviewerwindowlistener.cpp @@ -35,6 +35,7 @@ // std headers // external library headers // other Linden headers +#include "llcallbacklist.h" #include "llviewerwindow.h" LLViewerWindowListener::LLViewerWindowListener(LLViewerWindow* llviewerwindow): @@ -46,8 +47,7 @@ LLViewerWindowListener::LLViewerWindowListener(LLViewerWindow* llviewerwindow): add("saveSnapshot", "Save screenshot: [\"filename\"] (extension may be specified: bmp, jpeg, png)\n" "[\"width\"], [\"height\"], [\"showui\"], [\"showhud\"], [\"rebuild\"], [\"type\"]\n" - "type: \"COLOR\", \"DEPTH\"\n" - "Post on [\"reply\"] an event containing [\"result\"]", + "type: \"COLOR\", \"DEPTH\"\n", &LLViewerWindowListener::saveSnapshot, llsd::map("filename", LLSD::String(), "reply", LLSD())); add("requestReshape", @@ -117,7 +117,10 @@ void LLViewerWindowListener::saveSnapshot(const LLSD& event) const { return response.error(stringize("Unrecognized format. [\"png\"], [\"jpeg\"] or [\"bmp\"] is expected.")); } - response["result"] = mViewerWindow->saveSnapshot(filename, width, height, showui, showhud, rebuild, type, format); + // take snapshot on the main coro + doOnIdleOneTime([this, filename, width, height, showui, showhud, rebuild, type, format]() + { mViewerWindow->saveSnapshot(filename, width, height, showui, showhud, rebuild, type, format); }); + } void LLViewerWindowListener::requestReshape(LLSD const & event_data) const diff --git a/indra/newview/scripts/lua/require/LLAgent.lua b/indra/newview/scripts/lua/require/LLAgent.lua index 4a1132fe7e..b2be69dcdf 100644 --- a/indra/newview/scripts/lua/require/LLAgent.lua +++ b/indra/newview/scripts/lua/require/LLAgent.lua @@ -1,8 +1,26 @@ local leap = require 'leap' local mapargs = require 'mapargs' +local result_view = require 'result_view' + +local function result(keys) + local result_table = { + result=result_view(keys.result), + -- call result_table:close() to release result sets before garbage + -- collection or script completion + close = function(self) + result_view.close(keys.result[1]) + end + } + -- When the result_table is destroyed, close its result_views. + return LL.setdtor('LLAgent result', result_table, result_table.close) +end local LLAgent = {} +function LLAgent.getID() + return leap.request('LLAgent', {op = 'getID'}).id +end + function LLAgent.getRegionPosition() return leap.request('LLAgent', {op = 'getPosition'}).region end @@ -95,6 +113,33 @@ function LLAgent.requestStand() leap.send('LLAgent', {op = 'requestStand'}) end +-- Get the nearby avatars in a range of provided "dist", +-- if "dist" is not specified, "RenderFarClip" setting is used +-- reply will contain "result" table with following fields: +-- "id", "global_pos", "region_pos", "name" +function LLAgent.getNearbyAvatarsList(...) + local args = mapargs('dist', ...) + args.op = 'getNearbyAvatarsList' + return result(leap.request('LLAgent', args)) +end + +-- reply will contain "result" table with following fields: +-- "id", "global_pos", "region_pos" +function LLAgent.getNearbyObjectsList(...) + local args = mapargs('dist', ...) + args.op = 'getNearbyObjectsList' + return result(leap.request('LLAgent', args)) +end + +-- Get screen position of your own avatar or any other (if "avatar_id is specified) +-- reply contains "x", "y" coordinates and "onscreen" flag to indicate if it's actually in within the current window +-- avatar render position is used as the point +function LLAgent.getAgentScreenPos(...) + local args = mapargs('avatar_id', ...) + args.op = 'getAgentScreenPos' + return leap.request('LLAgent', args) +end + -- *************************************************************************** -- Autopilot -- *************************************************************************** diff --git a/indra/newview/scripts/lua/require/UI.lua b/indra/newview/scripts/lua/require/UI.lua index cf2695917e..86aa4095e0 100644 --- a/indra/newview/scripts/lua/require/UI.lua +++ b/indra/newview/scripts/lua/require/UI.lua @@ -141,7 +141,7 @@ end function UI.snapshot(...) local args = mapargs('filename,width,height,showui,showhud,rebuild,type', ...) args.op = 'saveSnapshot' - return leap.request('LLViewerWindow', args).result + return leap.request('LLViewerWindow', args) end -- *************************************************************************** @@ -222,8 +222,10 @@ function UI.hideFloater(floater_name) leap.send("LLFloaterReg", {op = "hideInstance", name = floater_name}) end -function UI.toggleFloater(floater_name) - leap.send("LLFloaterReg", {op = "toggleInstance", name = floater_name}) +function UI.toggleFloater(...) + local args = mapargs('name,key', ...) + args.op = 'toggleInstance' + leap.send("LLFloaterReg", args) end function UI.isFloaterVisible(floater_name) diff --git a/indra/newview/scripts/lua/test_LLChatListener.lua b/indra/newview/scripts/lua/test_LLChatListener.lua index 0f269b54e6..5679e9f98a 100644 --- a/indra/newview/scripts/lua/test_LLChatListener.lua +++ b/indra/newview/scripts/lua/test_LLChatListener.lua @@ -1,5 +1,6 @@ -local LLListener = require 'LLListener' +local LLAgent = require 'LLAgent' local LLChat = require 'LLChat' +local LLListener = require 'LLListener' local UI = require 'UI' -- Chat listener script allows to use the following commands in Nearby chat: @@ -23,9 +24,13 @@ function openOrEcho(message) end local listener = LLListener(LLChat.nearbyChatPump) +local ageint_id = LLAgent.getID() function listener:handleMessages(event_data) - if string.find(event_data.message, '[LUA]') then + -- ignore messages and commands from other avatars + if event_data.from_id ~= ageint_id then + return true + elseif string.find(event_data.message, '[LUA]') then return true elseif event_data.message == 'stop' then LLChat.sendNearby('Closing echo script.') diff --git a/indra/newview/scripts/lua/test_animation.lua b/indra/newview/scripts/lua/test_animation.lua index 37e7254a6c..ae5eabe148 100644 --- a/indra/newview/scripts/lua/test_animation.lua +++ b/indra/newview/scripts/lua/test_animation.lua @@ -7,8 +7,8 @@ animations_id = LLInventory.getBasicFolderID('animatn') anims = LLInventory.collectDescendentsIf{folder_id=animations_id, type="animatn"}.items local anim_ids = {} -for key in pairs(anims) do - table.insert(anim_ids, key) +for _, key in pairs(anims) do + table.insert(anim_ids, {id = key.id, name = key.name}) end if #anim_ids == 0 then @@ -16,17 +16,17 @@ if #anim_ids == 0 then else -- Start playing a random animation math.randomseed(os.time()) - local random_id = anim_ids[math.random(#anim_ids)] - local anim_info = LLAgent.getAnimationInfo(random_id) + local random_anim = anim_ids[math.random(#anim_ids)] + local anim_info = LLAgent.getAnimationInfo(random_anim.id) - print("Starting animation locally: " .. anims[random_id].name) - print("Loop: " .. anim_info.is_loop .. " Joints: " .. anim_info.num_joints .. " Duration " .. tonumber(string.format("%.2f", anim_info.duration))) - LLAgent.playAnimation{item_id=random_id} + print("Starting animation locally: " .. random_anim.name) + print("Loop: " .. tostring(anim_info.is_loop) .. " Joints: " .. anim_info.num_joints .. " Duration " .. tonumber(string.format("%.2f", anim_info.duration))) + LLAgent.playAnimation{item_id=random_anim.id} -- Stop animation after 3 sec if it's looped or longer than 3 sec - if anim_info.is_loop == 1 or anim_info.duration > 3 then + if anim_info.is_loop or anim_info.duration > 3 then LL.sleep(3) print("Stop animation.") - LLAgent.stopAnimation(random_id) + LLAgent.stopAnimation(random_anim.id) end end diff --git a/indra/newview/scripts/lua/test_luafloater_demo.lua b/indra/newview/scripts/lua/test_luafloater_demo.lua index 2158134511..23310c6176 100644 --- a/indra/newview/scripts/lua/test_luafloater_demo.lua +++ b/indra/newview/scripts/lua/test_luafloater_demo.lua @@ -14,7 +14,7 @@ function flt:handleEvents(event_data) end function flt:commit_disable_ctrl(event_data) - self:post({action="set_enabled", ctrl_name="open_btn", value = (1 - event_data.value)}) + self:post({action="set_enabled", ctrl_name="open_btn", value = not event_data.value}) end function flt:commit_title_cmb(event_data) diff --git a/indra/newview/scripts/lua/test_nearby_avatars.lua b/indra/newview/scripts/lua/test_nearby_avatars.lua new file mode 100644 index 0000000000..c7fa686076 --- /dev/null +++ b/indra/newview/scripts/lua/test_nearby_avatars.lua @@ -0,0 +1,25 @@ +inspect = require 'inspect' +LLAgent = require 'LLAgent' + +-- Get the list of nearby avatars and print the info +local nearby_avatars = LLAgent.getNearbyAvatarsList() +if nearby_avatars.result.length == 0 then + print("No avatars nearby") +else + print("Nearby avatars:") + for _, av in pairs(nearby_avatars.result) do + print(av.name ..' ID: ' .. av.id ..' Global pos:' .. inspect(av.global_pos)) + end +end + +-- Get the list of nearby objects in 3m range and print the info +local nearby_objects = LLAgent.getNearbyObjectsList(3) +if nearby_objects.result.length == 0 then + print("No objects nearby") +else + print("Nearby objects:") + local pos={} + for _, obj in pairs(nearby_objects.result) do + print('ID: ' .. obj.id ..' Global pos:' .. inspect(obj.global_pos)) + end +end diff --git a/indra/newview/scripts/lua/test_screen_position.lua b/indra/newview/scripts/lua/test_screen_position.lua new file mode 100644 index 0000000000..94d57339b1 --- /dev/null +++ b/indra/newview/scripts/lua/test_screen_position.lua @@ -0,0 +1,8 @@ +LLAgent = require 'LLAgent' + +local screen_pos = LLAgent.getAgentScreenPos() +if screen_pos.onscreen then + print("Avatar screen coordinates X: " .. screen_pos.x .. " Y: " .. screen_pos.y) +else + print("Avatar is not on the screen") +end diff --git a/indra/newview/scripts/lua/test_toolbars.lua b/indra/newview/scripts/lua/test_toolbars.lua index 7683fca8a3..9cd1043446 100644 --- a/indra/newview/scripts/lua/test_toolbars.lua +++ b/indra/newview/scripts/lua/test_toolbars.lua @@ -20,7 +20,7 @@ if response == 'OK' then UI.removeToolbarBtn(BUTTONS[i]) end end - popup:tip('Toolbars were reshuffled') + UI.popup:tip('Toolbars were reshuffled') else - popup:tip('Canceled') + UI.popup:tip('Canceled') end diff --git a/indra/newview/skins/default/xui/en/floater_lua_debug.xml b/indra/newview/skins/default/xui/en/floater_lua_debug.xml index 15027f1647..5efe1c958a 100644 --- a/indra/newview/skins/default/xui/en/floater_lua_debug.xml +++ b/indra/newview/skins/default/xui/en/floater_lua_debug.xml @@ -25,6 +25,17 @@ width="100"> LUA string: </text> + <check_box + control_name="LuaDebugShowSource" + follows="right|top" + height="15" + label="Show source info" + layout="topleft" + top="10" + right ="-70" + tool_tip="Show source info in Lua Debug Console output" + name="show_script_name" + width="70"/> <line_editor border_style="line" border_thickness="1" |