diff options
| author | Mnikolenko Productengine <mnikolenko@productengine.com> | 2025-04-03 12:34:51 +0300 | 
|---|---|---|
| committer | Mnikolenko Productengine <mnikolenko@productengine.com> | 2025-04-03 12:34:51 +0300 | 
| commit | 46fca6f5bbafcdb2942114ccccdadc1e769955e4 (patch) | |
| tree | 482a6442d9fe44f4319f5b3c6d27b33ff155a9b0 /indra | |
| parent | db2c45ba23a10d34d89f556533f80a8b42600bf6 (diff) | |
#3857 second batch of new or updated LEAP functions
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llcommon/llsdutil.h | 55 | ||||
| -rw-r--r-- | indra/newview/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | indra/newview/groupchatlistener.cpp | 84 | ||||
| -rw-r--r-- | indra/newview/groupchatlistener.h | 15 | ||||
| -rw-r--r-- | indra/newview/llagentlistener.h | 1 | ||||
| -rw-r--r-- | indra/newview/llappearancelistener.cpp | 158 | ||||
| -rw-r--r-- | indra/newview/llappearancelistener.h | 46 | ||||
| -rw-r--r-- | indra/newview/llappearancemgr.cpp | 8 | ||||
| -rw-r--r-- | indra/newview/llappearancemgr.h | 1 | ||||
| -rw-r--r-- | indra/newview/llgroupactions.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llwearableitemslist.cpp | 10 | ||||
| -rw-r--r-- | indra/newview/llwearableitemslist.h | 9 | 
12 files changed, 345 insertions, 46 deletions
| diff --git a/indra/llcommon/llsdutil.h b/indra/llcommon/llsdutil.h index 38bbe19ddd..c31030c5ea 100644 --- a/indra/llcommon/llsdutil.h +++ b/indra/llcommon/llsdutil.h @@ -553,6 +553,61 @@ LLSD shallow(LLSD value, LLSD filter=LLSD()) { return llsd_shallow(value, filter  } // namespace llsd +/***************************************************************************** + *   toArray(), toMap() + *****************************************************************************/ +namespace llsd +{ + +// For some T convertible to LLSD, given std::vector<T> myVec, +// toArray(myVec) returns an LLSD array whose entries correspond to the +// items in myVec. +// For some U convertible to LLSD, given function U xform(const T&), +// toArray(myVec, xform) returns an LLSD array whose every entry is +// xform(item) of the corresponding item in myVec. +// toArray() actually works with any container<C> usable with range +// 'for', not just std::vector. +// (Once we get C++20 we can use std::identity instead of this default lambda.) +template<typename C, typename FUNC> +LLSD toArray(const C& container, FUNC&& func = [](const auto& arg) { return arg; }) +{ +    LLSD array; +    for (const auto& item : container) +    { +        array.append(std::forward<FUNC>(func)(item)); +    } +    return array; +} + +// For some T convertible to LLSD, given std::map<std::string, T> myMap, +// toMap(myMap) returns an LLSD map whose entries correspond to the +// (key, value) pairs in myMap. +// For some U convertible to LLSD, given function +// std::pair<std::string, U> xform(const std::pair<std::string, T>&), +// toMap(myMap, xform) returns an LLSD map whose every entry is +// xform(pair) of the corresponding (key, value) pair in myMap. +// toMap() actually works with any container usable with range 'for', not +// just std::map. It need not even be an associative container, as long as +// you pass an xform function that returns std::pair<std::string, U>. +// (Once we get C++20 we can use std::identity instead of this default lambda.) +template<typename C, typename FUNC> +LLSD toMap(const C& container, FUNC&& func = [](const auto& arg) { return arg; }) +{ +    LLSD map; +    for (const auto& pair : container) +    { +        const auto& [key, value] = std::forward<FUNC>(func)(pair); +        map[key] = value; +    } +    return map; +} + +} // namespace llsd + +/***************************************************************************** + *   boost::hash<LLSD> + *****************************************************************************/ +  // Specialization for generating a hash value from an LLSD block.  namespace boost  { diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index ed29911a43..fff1597fd9 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -92,6 +92,7 @@ set(viewer_SOURCE_FILES      llagentwearables.cpp      llanimstatelabels.cpp      llappcorehttp.cpp +    llappearancelistener.cpp      llappearancemgr.cpp      llappviewer.cpp      llappviewerlistener.cpp @@ -761,6 +762,7 @@ set(viewer_HEADER_FILES      llanimstatelabels.h      llappcorehttp.h      llappearance.h +    llappearancelistener.h      llappearancemgr.h      llappviewer.h      llappviewerlistener.h diff --git a/indra/newview/groupchatlistener.cpp b/indra/newview/groupchatlistener.cpp index 43507f13e9..ed9e34d1bf 100644 --- a/indra/newview/groupchatlistener.cpp +++ b/indra/newview/groupchatlistener.cpp @@ -2,11 +2,11 @@   * @file   groupchatlistener.cpp   * @author Nat Goodspeed   * @date   2011-04-11 - * @brief  Implementation for groupchatlistener. + * @brief  Implementation for LLGroupChatListener.   * - * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * $LicenseInfo:firstyear=2024&license=viewerlgpl$   * Second Life Viewer Source Code - * Copyright (C) 2011, Linden Research, Inc. + * Copyright (C) 2024, Linden Research, Inc.   *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public @@ -34,43 +34,69 @@  // std headers  // external library headers  // other Linden headers +#include "llchat.h"  #include "llgroupactions.h"  #include "llimview.h" +LLGroupChatListener::LLGroupChatListener(): +    LLEventAPI("GroupChat", +               "API to enter, leave, send and intercept group chat messages") +{ +    add("startGroupChat", +        "Enter a group chat in group with UUID [\"group_id\"]\n" +        "Assumes the logged-in agent is already a member of this group.", +        &LLGroupChatListener::startGroupChat, +        llsd::map("group_id", LLSD())); +    add("leaveGroupChat", +        "Leave a group chat in group with UUID [\"group_id\"]\n" +        "Assumes a prior successful startIM request.", +        &LLGroupChatListener::leaveGroupChat, +        llsd::map("group_id", LLSD())); +    add("sendGroupIM", +        "send a [\"message\"] to group with UUID [\"group_id\"]", +        &LLGroupChatListener::sendGroupIM, +        llsd::map("message", LLSD(), "group_id", LLSD())); +} -namespace { -    void startIm_wrapper(LLSD const & event) +bool is_in_group(LLEventAPI::Response &response, const LLSD &data) +{ +    if (!LLGroupActions::isInGroup(data["group_id"]))      { -        LLUUID session_id = LLGroupActions::startIM(event["id"].asUUID()); -        sendReply(LLSDMap("session_id", LLSD(session_id)), event); +        response.error(stringize("You are not the member of the group:", std::quoted(data["group_id"].asString()))); +        return false;      } +    return true; +} -    void send_message_wrapper(const std::string& text, const LLUUID& session_id, const LLUUID& group_id) +void LLGroupChatListener::startGroupChat(LLSD const &data) +{ +    Response response(LLSD(), data); +    if (!is_in_group(response, data)) +    { +        return; +    } +    if (LLGroupActions::startIM(data["group_id"]).isNull())      { -        LLIMModel::sendMessage(text, session_id, group_id, IM_SESSION_GROUP_START); +        return response.error(stringize("Failed to start group chat session ", std::quoted(data["group_id"].asString())));      }  } +void LLGroupChatListener::leaveGroupChat(LLSD const &data) +{ +    Response response(LLSD(), data); +    if (is_in_group(response, data)) +    { +        LLGroupActions::endIM(data["group_id"].asUUID()); +    } +} -GroupChatListener::GroupChatListener(): -    LLEventAPI("GroupChat", -               "API to enter, leave, send and intercept group chat messages") +void LLGroupChatListener::sendGroupIM(LLSD const &data)  { -    add("startIM", -        "Enter a group chat in group with UUID [\"id\"]\n" -        "Assumes the logged-in agent is already a member of this group.", -        &startIm_wrapper); -    add("endIM", -        "Leave a group chat in group with UUID [\"id\"]\n" -        "Assumes a prior successful startIM request.", -        &LLGroupActions::endIM, -        llsd::array("id")); -    add("sendIM", -        "send a groupchat IM", -        &send_message_wrapper, -        llsd::array("text", "session_id", "group_id")); +    Response response(LLSD(), data); +    if (!is_in_group(response, data)) +    { +        return; +    } +    LLUUID group_id(data["group_id"]); +    LLIMModel::sendMessage(data["message"], gIMMgr->computeSessionID(IM_SESSION_GROUP_START, group_id), group_id, IM_SESSION_SEND);  } -/* -    static void sendMessage(const std::string& utf8_text, const LLUUID& im_session_id, -                                const LLUUID& other_participant_id, EInstantMessage dialog); -*/ diff --git a/indra/newview/groupchatlistener.h b/indra/newview/groupchatlistener.h index 3819ac59b7..14cd7266a3 100644 --- a/indra/newview/groupchatlistener.h +++ b/indra/newview/groupchatlistener.h @@ -26,15 +26,20 @@   * $/LicenseInfo$   */ -#if ! defined(LL_GROUPCHATLISTENER_H) -#define LL_GROUPCHATLISTENER_H +#if ! defined(LL_LLGROUPCHATLISTENER_H) +#define LL_LLGROUPCHATLISTENER_H  #include "lleventapi.h" -class GroupChatListener: public LLEventAPI +class LLGroupChatListener: public LLEventAPI  {  public: -    GroupChatListener(); +    LLGroupChatListener(); + +private: +    void startGroupChat(LLSD const &data); +    void leaveGroupChat(LLSD const &data); +    void sendGroupIM(LLSD const &data);  }; -#endif /* ! defined(LL_GROUPCHATLISTENER_H) */ +#endif /* ! defined(LL_LLGROUPCHATLISTENER_H) */ diff --git a/indra/newview/llagentlistener.h b/indra/newview/llagentlistener.h index 31f50a653f..b5bea8c0bd 100644 --- a/indra/newview/llagentlistener.h +++ b/indra/newview/llagentlistener.h @@ -62,7 +62,6 @@ private:      void removeFollowCamParams(LLSD const & event_data) const;      void playAnimation(LLSD const &event_data); -    void playAnimation_(const LLUUID& asset_id, const bool inworld);      void stopAnimation(LLSD const &event_data);      void getAnimationInfo(LLSD const &event_data); diff --git a/indra/newview/llappearancelistener.cpp b/indra/newview/llappearancelistener.cpp new file mode 100644 index 0000000000..65cdf2e11b --- /dev/null +++ b/indra/newview/llappearancelistener.cpp @@ -0,0 +1,158 @@ +/** + * @file llappearancelistener.cpp + * + * $LicenseInfo:firstyear=2024&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2024, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llappearancelistener.h" + +#include "llappearancemgr.h" +#include "llinventoryfunctions.h" +#include "lltransutil.h" +#include "llwearableitemslist.h" +#include "stringize.h" + +LLAppearanceListener::LLAppearanceListener() +  : LLEventAPI("LLAppearance", +               "API to wear a specified outfit and wear/remove individual items") +{ +    add("wearOutfit", +        "Wear outfit by folder id: [\"folder_id\"] OR by folder name: [\"folder_name\"]\n" +        "When [\"append\"] is true, outfit will be added to COF\n" +        "otherwise it will replace current oufit", +        &LLAppearanceListener::wearOutfit); + +    add("wearItems", +        "Wear items by id: [items_id]", +        &LLAppearanceListener::wearItems, +        llsd::map("items_id", LLSD(), "replace", LLSD())); + +    add("detachItems", +        "Detach items by id: [items_id]", +        &LLAppearanceListener::detachItems, +        llsd::map("items_id", LLSD())); + +    add("getOutfitsList", +        "Return the table with Outfits info(id and name)", +         &LLAppearanceListener::getOutfitsList); + +    add("getOutfitItems", +        "Return the table of items with info(id : name, wearable_type, is_worn) inside specified outfit folder", +         &LLAppearanceListener::getOutfitItems); +} + + +void LLAppearanceListener::wearOutfit(LLSD const &data) +{ +    Response response(LLSD(), data); +    if (!data.has("folder_id") && !data.has("folder_name")) +    { +        return response.error("Either [folder_id] or [folder_name] is required"); +    } + +    bool append = data.has("append") ? data["append"].asBoolean() : false; +    if (!LLAppearanceMgr::instance().wearOutfit(data, append)) +    { +        response.error("Failed to wear outfit"); +    } +} + +void LLAppearanceListener::wearItems(LLSD const &data) +{ +    const LLSD& items_id{ data["items_id"] }; +    uuid_vec_t  ids; +    if (!items_id.isArray()) +    { +        ids.push_back(items_id.asUUID()); +    } +    else // array +    { +        for (const auto& id : llsd::inArray(items_id)) +        { +            ids.push_back(id); +        } +    } +    LLAppearanceMgr::instance().wearItemsOnAvatar(ids, true, data["replace"].asBoolean()); +} + +void LLAppearanceListener::detachItems(LLSD const &data) +{ +    const LLSD& items_id{ data["items_id"] }; +    uuid_vec_t  ids; +    if (!items_id.isArray()) +    { +        ids.push_back(items_id.asUUID()); +    } +    else // array +    { +        for (const auto& id : llsd::inArray(items_id)) +        { +            ids.push_back(id); +        } +    } +    LLAppearanceMgr::instance().removeItemsFromAvatar(ids); +} + +void LLAppearanceListener::getOutfitsList(LLSD const &data) +{ +    Response response(LLSD(), data); +    const LLUUID outfits_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); + +    LLInventoryModel::cat_array_t cat_array; +    LLInventoryModel::item_array_t item_array; + +    LLIsType is_category(LLAssetType::AT_CATEGORY); +    gInventory.collectDescendentsIf(outfits_id, cat_array, item_array, LLInventoryModel::EXCLUDE_TRASH, is_category); + +    response["outfits"] = llsd::toMap(cat_array, +        [](const LLPointer<LLViewerInventoryCategory> &cat) +        { return std::make_pair(cat->getUUID().asString(), cat->getName()); }); +} + +void LLAppearanceListener::getOutfitItems(LLSD const &data) +{ +    Response response(LLSD(), data); +    LLUUID outfit_id(data["outfit_id"].asUUID()); +    LLViewerInventoryCategory *cat = gInventory.getCategory(outfit_id); +    if (!cat || cat->getPreferredType() != LLFolderType::FT_OUTFIT) +    { +        return response.error(stringize(LLTrans::getString("OutfitNotFound"), outfit_id.asString())); +    } +    LLInventoryModel::cat_array_t  cat_array; +    LLInventoryModel::item_array_t item_array; + +    LLFindOutfitItems collector = LLFindOutfitItems(); +    gInventory.collectDescendentsIf(outfit_id, cat_array, item_array, LLInventoryModel::EXCLUDE_TRASH, collector); + +    response["items"] = llsd::toMap(item_array, +        [](const LLPointer<LLViewerInventoryItem> &it) +        { +            return std::make_pair( +                it->getUUID().asString(), +                llsd::map( +                    "name", it->getName(), +                    "wearable_type", LLWearableType::getInstance()->getTypeName(it->isWearableType() ? it->getWearableType() : LLWearableType::WT_NONE), +                    "is_worn", get_is_item_worn(it))); +        }); +} diff --git a/indra/newview/llappearancelistener.h b/indra/newview/llappearancelistener.h new file mode 100644 index 0000000000..04c5eac2eb --- /dev/null +++ b/indra/newview/llappearancelistener.h @@ -0,0 +1,46 @@ +/** + * @file llappearancelistener.h + * + * $LicenseInfo:firstyear=2024&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2024, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + + +#ifndef LL_LLAPPEARANCELISTENER_H +#define LL_LLAPPEARANCELISTENER_H + +#include "lleventapi.h" + +class LLAppearanceListener : public LLEventAPI +{ +public: +    LLAppearanceListener(); + +private: +    void wearOutfit(LLSD const &data); +    void wearItems(LLSD const &data); +    void detachItems(LLSD const &data); +    void getOutfitsList(LLSD const &data); +    void getOutfitItems(LLSD const &data); +}; + +#endif // LL_LLAPPEARANCELISTENER_H + diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 101aca3823..e9d455ae53 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -31,6 +31,7 @@  #include "llagent.h"  #include "llagentcamera.h"  #include "llagentwearables.h" +#include "llappearancelistener.h"  #include "llappearancemgr.h"  #include "llattachmentsmgr.h"  #include "llcommandhandler.h" @@ -66,6 +67,8 @@  #include "llavatarpropertiesprocessor.h" +LLAppearanceListener sAppearanceListener; +  namespace  {      const S32   BAKE_RETRY_MAX_COUNT = 5; @@ -4762,6 +4765,11 @@ bool wear_category(const LLSD& query_map, bool append)      return false;  } +bool LLAppearanceMgr::wearOutfit(const LLSD& query_map, bool append) +{ +    return wear_category(query_map, append); +} +  class LLWearFolderHandler : public LLCommandHandler  {  public: diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 6c45a32856..bc7dc9506b 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -60,6 +60,7 @@ public:      void wearInventoryCategoryOnAvatar(LLInventoryCategory* category, bool append);      void wearCategoryFinal(const LLUUID& cat_id, bool copy_items, bool append);      void wearOutfitByName(const std::string& name); +    bool wearOutfit(const LLSD& query_map, bool append = false);      void changeOutfit(bool proceed, const LLUUID& category, bool append);      void replaceCurrentOutfit(const LLUUID& new_outfit);      void renameOutfit(const LLUUID& outfit_id); diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index ba9c9fa13f..34d96aa024 100644 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -46,7 +46,7 @@  //  // Globals  // -static GroupChatListener sGroupChatListener; +static LLGroupChatListener sGroupChatListener;  class LLGroupHandler : public LLCommandHandler  { diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index 8ce1a745c3..c708e804b2 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -33,7 +33,6 @@  #include "llagentwearables.h"  #include "llappearancemgr.h" -#include "llinventoryfunctions.h"  #include "llinventoryicon.h"  #include "llgesturemgr.h"  #include "lltransutil.h" @@ -41,15 +40,6 @@  #include "llviewermenu.h"  #include "llvoavatarself.h" -class LLFindOutfitItems : public LLInventoryCollectFunctor -{ -public: -    LLFindOutfitItems() {} -    virtual ~LLFindOutfitItems() {} -    virtual bool operator()(LLInventoryCategory* cat, -                            LLInventoryItem* item); -}; -  bool LLFindOutfitItems::operator()(LLInventoryCategory* cat,                                     LLInventoryItem* item)  { diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h index 3fe1059176..7a5f29020e 100644 --- a/indra/newview/llwearableitemslist.h +++ b/indra/newview/llwearableitemslist.h @@ -32,6 +32,7 @@  #include "llsingleton.h"  // newview +#include "llinventoryfunctions.h"  #include "llinventoryitemslist.h"  #include "llinventorylistitem.h"  #include "lllistcontextmenu.h" @@ -507,4 +508,12 @@ protected:      LLWearableType::EType mMenuWearableType;  }; +class LLFindOutfitItems : public LLInventoryCollectFunctor +{ +public: +    LLFindOutfitItems() {} +    virtual ~LLFindOutfitItems() {} +    virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item); +}; +  #endif //LL_LLWEARABLEITEMSLIST_H | 
