Merge branch 'release/2025.03' of https://github.com/secondlife/viewer
# Conflicts: # indra/newview/llcallingcard.cpp # indra/newview/llinventorybridge.cpp # indra/newview/skins/default/xui/en/menu_inventory.xml # indra/newview/skins/default/xui/en/menu_viewer.xml # indra/newview/skins/default/xui/ja/strings.xml # indra/newview/skins/default/xui/zh/strings.xmlmaster
commit
4e2bfd7327
|
|
@ -95,6 +95,8 @@ LLExperienceCache::LLExperienceCache()
|
|||
|
||||
LLExperienceCache::~LLExperienceCache()
|
||||
{
|
||||
// can exit without cleanup()
|
||||
sShutdown = true;
|
||||
}
|
||||
|
||||
void LLExperienceCache::initSingleton()
|
||||
|
|
|
|||
|
|
@ -344,6 +344,12 @@ bool LLPacketRing::expandRing()
|
|||
return true;
|
||||
}
|
||||
|
||||
F32 LLPacketRing::getBufferLoadRate() const
|
||||
{
|
||||
// goes up to MAX_BUFFER_RING_SIZE
|
||||
return (F32)mNumBufferedPackets / (F32)DEFAULT_BUFFER_RING_SIZE;
|
||||
}
|
||||
|
||||
void LLPacketRing::dumpPacketRingStats()
|
||||
{
|
||||
mNumDroppedPacketsTotal += mNumDroppedPackets;
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ public:
|
|||
S32 getNumBufferedBytes() const { return mNumBufferedBytes; }
|
||||
S32 getNumDroppedPackets() const { return mNumDroppedPacketsTotal + mNumDroppedPackets; }
|
||||
|
||||
F32 getBufferLoadRate() const; // from 0 to 4 (0 - empty, 1 - default size is full)
|
||||
void dumpPacketRingStats();
|
||||
protected:
|
||||
// returns 'true' if we should intentionally drop a packet
|
||||
|
|
|
|||
|
|
@ -538,7 +538,6 @@ public:
|
|||
|
||||
//void buildMessage();
|
||||
|
||||
S32 zeroCode(U8 **data, S32 *data_size);
|
||||
S32 zeroCodeExpand(U8 **data, S32 *data_size);
|
||||
S32 zeroCodeAdjustCurrentSendTotal();
|
||||
|
||||
|
|
@ -755,6 +754,7 @@ public:
|
|||
S32 getReceiveBytes() const;
|
||||
|
||||
S32 getUnackedListSize() const { return mUnackedListSize; }
|
||||
F32 getBufferLoadRate() const { return mPacketRing.getBufferLoadRate(); }
|
||||
|
||||
//const char* getCurrentSMessageName() const { return mCurrentSMessageName; }
|
||||
//const char* getCurrentSBlockName() const { return mCurrentSBlockName; }
|
||||
|
|
@ -845,12 +845,10 @@ private:
|
|||
LLUUID mSessionID;
|
||||
|
||||
void addTemplate(LLMessageTemplate *templatep);
|
||||
bool decodeTemplate( const U8* buffer, S32 buffer_size, LLMessageTemplate** msg_template );
|
||||
|
||||
void logMsgFromInvalidCircuit( const LLHost& sender, bool recv_reliable );
|
||||
void logTrustedMsgFromUntrustedCircuit( const LLHost& sender );
|
||||
void logValidMsg(LLCircuitData *cdp, const LLHost& sender, bool recv_reliable, bool recv_resent, bool recv_acks );
|
||||
void logRanOffEndOfPacket( const LLHost& sender );
|
||||
|
||||
class LLMessageCountInfo
|
||||
{
|
||||
|
|
|
|||
|
|
@ -413,6 +413,7 @@ set(viewer_SOURCE_FILES
|
|||
llfloatersettingscolor.cpp
|
||||
llfloatersettingsdebug.cpp
|
||||
llfloatersidepanelcontainer.cpp
|
||||
llfloaterslapptest.cpp
|
||||
llfloatersnapshot.cpp
|
||||
llfloatersounddevices.cpp
|
||||
llfloaterspellchecksettings.cpp
|
||||
|
|
@ -1233,6 +1234,7 @@ set(viewer_HEADER_FILES
|
|||
llfloatersettingscolor.h
|
||||
llfloatersettingsdebug.h
|
||||
llfloatersidepanelcontainer.h
|
||||
llfloaterslapptest.h
|
||||
llfloatersnapshot.h
|
||||
llfloatersounddevices.h
|
||||
llfloaterspellchecksettings.h
|
||||
|
|
|
|||
|
|
@ -6267,6 +6267,17 @@
|
|||
<key>Value</key>
|
||||
<integer>5000</integer>
|
||||
</map>
|
||||
<key>InventoryExposeFolderID</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Allows copying folder id from context menu</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>MarketplaceListingsSortOrder</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
|
|||
|
|
@ -5187,48 +5187,64 @@ void wear_multiple(const uuid_vec_t& ids, bool replace)
|
|||
LLAppearanceMgr::instance().wearItemsOnAvatar(ids, true, replace, cb);
|
||||
}
|
||||
|
||||
// SLapp for easy-wearing of a stock (library) avatar
|
||||
//
|
||||
bool wear_category(const LLSD& query_map, bool append)
|
||||
{
|
||||
LLUUID folder_uuid;
|
||||
|
||||
if (query_map.has("folder_name"))
|
||||
{
|
||||
std::string outfit_folder_name = query_map["folder_name"];
|
||||
folder_uuid = findDescendentCategoryIDByName(gInventory.getLibraryRootFolderID(), outfit_folder_name);
|
||||
if (folder_uuid.isNull())
|
||||
LL_WARNS() << "Couldn't find " << std::quoted(outfit_folder_name) << " in the Library" << LL_ENDL;
|
||||
}
|
||||
if (folder_uuid.isNull() && query_map.has("folder_id"))
|
||||
{
|
||||
folder_uuid = query_map["folder_id"].asUUID();
|
||||
}
|
||||
|
||||
if (folder_uuid.notNull())
|
||||
{
|
||||
if (LLViewerInventoryCategory* cat = gInventory.getCategory(folder_uuid))
|
||||
{
|
||||
if (bool is_library = gInventory.isObjectDescendentOf(folder_uuid, gInventory.getRootFolderID()))
|
||||
{
|
||||
LLPointer<LLInventoryCategory> new_category = new LLInventoryCategory(folder_uuid, LLUUID::null, LLFolderType::FT_CLOTHING, "Quick Appearance");
|
||||
LLAppearanceMgr::getInstance()->wearInventoryCategory(new_category, true, append);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLAppearanceMgr::getInstance()->wearInventoryCategory(cat, true, append);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << "Couldn't find folder id" << folder_uuid << " in Inventory" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
class LLWearFolderHandler : public LLCommandHandler
|
||||
{
|
||||
public:
|
||||
// not allowed from outside the app
|
||||
LLWearFolderHandler() : LLCommandHandler("wear_folder", UNTRUSTED_BLOCK) { }
|
||||
LLWearFolderHandler() : LLCommandHandler("wear_folder", UNTRUSTED_BLOCK) {}
|
||||
|
||||
bool handle(const LLSD& tokens,
|
||||
const LLSD& query_map,
|
||||
const std::string& grid,
|
||||
LLMediaCtrl* web)
|
||||
{
|
||||
LLSD::UUID folder_uuid;
|
||||
|
||||
if (folder_uuid.isNull() && query_map.has("folder_name"))
|
||||
if (wear_category(query_map, false))
|
||||
{
|
||||
std::string outfit_folder_name = query_map["folder_name"];
|
||||
folder_uuid = findDescendentCategoryIDByName(
|
||||
gInventory.getLibraryRootFolderID(),
|
||||
outfit_folder_name);
|
||||
}
|
||||
if (folder_uuid.isNull() && query_map.has("folder_id"))
|
||||
{
|
||||
folder_uuid = query_map["folder_id"].asUUID();
|
||||
}
|
||||
// Assume this is coming from the predefined avatars web floater
|
||||
LLUIUsage::instance().logCommand("Avatar.WearPredefinedAppearance");
|
||||
|
||||
if (folder_uuid.notNull())
|
||||
{
|
||||
LLPointer<LLInventoryCategory> category = new LLInventoryCategory(folder_uuid,
|
||||
LLUUID::null,
|
||||
LLFolderType::FT_CLOTHING,
|
||||
"Quick Appearance");
|
||||
if ( gInventory.getCategory( folder_uuid ) != NULL )
|
||||
{
|
||||
// Assume this is coming from the predefined avatars web floater
|
||||
LLUIUsage::instance().logCommand("Avatar.WearPredefinedAppearance");
|
||||
LLAppearanceMgr::getInstance()->wearInventoryCategory(category, true, false);
|
||||
|
||||
// *TODOw: This may not be necessary if initial outfit is chosen already -- josh
|
||||
gAgent.setOutfitChosen(true);
|
||||
}
|
||||
// *TODOw: This may not be necessary if initial outfit is chosen already -- josh
|
||||
gAgent.setOutfitChosen(true);
|
||||
}
|
||||
|
||||
// release avatar picker keyboard focus
|
||||
|
|
@ -5238,4 +5254,46 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class LLAddFolderHandler : public LLCommandHandler
|
||||
{
|
||||
public:
|
||||
// not allowed from outside the app
|
||||
LLAddFolderHandler() : LLCommandHandler("add_folder", UNTRUSTED_BLOCK) {}
|
||||
|
||||
bool handle(const LLSD& tokens, const LLSD& query_map, const std::string& grid, LLMediaCtrl* web)
|
||||
{
|
||||
wear_category(query_map, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class LLRemoveFolderHandler : public LLCommandHandler
|
||||
{
|
||||
public:
|
||||
LLRemoveFolderHandler() : LLCommandHandler("remove_folder", UNTRUSTED_BLOCK) {}
|
||||
|
||||
bool handle(const LLSD& tokens, const LLSD& query_map, const std::string& grid, LLMediaCtrl* web)
|
||||
{
|
||||
if (query_map.has("folder_id"))
|
||||
{
|
||||
LLUUID folder_id = query_map["folder_id"].asUUID();
|
||||
if (folder_id.notNull())
|
||||
{
|
||||
if (LLViewerInventoryCategory* cat = gInventory.getCategory(folder_id))
|
||||
{
|
||||
LLAppearanceMgr::instance().takeOffOutfit(cat->getLinkedUUID());
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << "Couldn't find folder id" << folder_id << " in Inventory" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
LLWearFolderHandler gWearFolderHandler;
|
||||
LLAddFolderHandler gAddFolderHandler;
|
||||
LLRemoveFolderHandler gRemoveFolderHandler;
|
||||
|
|
|
|||
|
|
@ -6359,6 +6359,7 @@ void LLAppViewer::idleNetwork()
|
|||
// Retransmit unacknowledged packets.
|
||||
gXferManager->retransmitUnackedPackets();
|
||||
gAssetStorage->checkForTimeouts();
|
||||
gViewerThrottle.setBufferLoadRate(gMessageSystem->getBufferLoadRate());
|
||||
gViewerThrottle.updateDynamicThrottle();
|
||||
|
||||
// Check that the circuit between the viewer and the agent's current
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
#include "llinventorymodel.h"
|
||||
#include "llnotifications.h"
|
||||
#include "llslurl.h"
|
||||
#include "llstartup.h"
|
||||
#include "llimview.h"
|
||||
#include "lltrans.h"
|
||||
#include "llviewercontrol.h"
|
||||
|
|
@ -279,6 +280,22 @@ S32 LLAvatarTracker::addBuddyList(const LLAvatarTracker::buddy_map_t& buds)
|
|||
<< "]" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
// It's possible that the buddy list getting propagated from the inventory may have happened after we actually got the buddy list.
|
||||
// Any buddies that we got prior will reside in a special queue that we must process and update statuses accordingly with.
|
||||
// Do that here.
|
||||
// -Geenz 2025-03-12
|
||||
while (!mBuddyStatusQueue.empty())
|
||||
{
|
||||
auto buddyStatus = mBuddyStatusQueue.front();
|
||||
mBuddyStatusQueue.pop();
|
||||
|
||||
if (mBuddyInfo.find(buddyStatus.first) != mBuddyInfo.end())
|
||||
{
|
||||
setBuddyOnline(buddyStatus.first, buddyStatus.second);
|
||||
}
|
||||
}
|
||||
|
||||
// do not notify observers here - list can be large so let it be done on idle.
|
||||
|
||||
return new_buddy_count;
|
||||
|
|
@ -343,9 +360,12 @@ void LLAvatarTracker::setBuddyOnline(const LLUUID& id, bool is_online)
|
|||
{
|
||||
//<FS:LO> Fix possible log spam with a large friendslist when SL messes up.
|
||||
//LL_WARNS() << "!! No buddy info found for " << id
|
||||
LL_WARNS() << "Did we receive a buddy status update before the buddy info?" << LL_ENDL;
|
||||
LL_DEBUGS() << "!! No buddy info found for " << id
|
||||
<< ", setting to " << (is_online ? "Online" : "Offline") << LL_ENDL;
|
||||
LL_DEBUGS() << "Did we receive a buddy status update before the buddy info?" << LL_ENDL;
|
||||
//</FS:LO>
|
||||
mBuddyStatusQueue.push(std::make_pair(id, is_online));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -790,6 +810,8 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online)
|
|||
{
|
||||
LL_WARNS() << "Received online notification for unknown buddy: "
|
||||
<< agent_id << " is " << (online ? "ONLINE" : "OFFLINE") << LL_ENDL;
|
||||
LL_WARNS() << "Adding buddy to buddy queue." << LL_ENDL;
|
||||
mBuddyStatusQueue.push(std::make_pair(agent_id, true));
|
||||
}
|
||||
|
||||
if(tracking_id == agent_id)
|
||||
|
|
@ -812,7 +834,11 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online)
|
|||
|
||||
mModifyMask |= LLFriendObserver::ONLINE;
|
||||
instance().notifyObservers();
|
||||
gInventory.notifyObservers();
|
||||
// Skip if we had received the friends list before the inventory callbacks were properly initialized
|
||||
if (LLStartUp::getStartupState() > STATE_INVENTORY_CALLBACKS)
|
||||
{
|
||||
gInventory.notifyObservers();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ public:
|
|||
// add or remove agents from buddy list. Each method takes a set
|
||||
// of buddies and returns how many were actually added or removed.
|
||||
typedef std::map<LLUUID, LLRelationship*> buddy_map_t;
|
||||
typedef std::queue<std::pair<LLUUID, bool>> buddy_status_queue_t;
|
||||
|
||||
S32 addBuddyList(const buddy_map_t& buddies);
|
||||
//S32 removeBuddyList(const buddy_list_t& exes);
|
||||
|
|
@ -200,6 +201,7 @@ protected:
|
|||
//LLInventoryObserver* mInventoryObserver;
|
||||
|
||||
buddy_map_t mBuddyInfo;
|
||||
buddy_status_queue_t mBuddyStatusQueue;
|
||||
|
||||
typedef std::set<LLUUID> changed_buddy_t;
|
||||
changed_buddy_t mChangedBuddyIDs;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
/**
|
||||
* @file llfloaterslapptest.cpp
|
||||
*
|
||||
* $LicenseInfo:firstyear=2025&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2025, 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 "llfloaterslapptest.h"
|
||||
#include "lluictrlfactory.h"
|
||||
|
||||
#include "lllineeditor.h"
|
||||
#include "lltextbox.h"
|
||||
|
||||
LLFloaterSLappTest::LLFloaterSLappTest(const LLSD& key)
|
||||
: LLFloater("floater_test_slapp")
|
||||
{
|
||||
}
|
||||
|
||||
LLFloaterSLappTest::~LLFloaterSLappTest()
|
||||
{}
|
||||
|
||||
bool LLFloaterSLappTest::postBuild()
|
||||
{
|
||||
getChild<LLLineEditor>("remove_folder_id")->setKeystrokeCallback([this](LLLineEditor* editor, void*)
|
||||
{
|
||||
std::string slapp(getString("remove_folder_slapp"));
|
||||
getChild<LLTextBox>("remove_folder_txt")->setValue(slapp + editor->getValue().asString());
|
||||
}, NULL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
* @file llfloaterslapptest.h
|
||||
*
|
||||
* $LicenseInfo:firstyear=2025&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2025, 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_LLFLOATERSLAPPTEST_H
|
||||
#define LL_LLFLOATERSLAPPTEST_H
|
||||
|
||||
#include "llfloater.h"
|
||||
|
||||
class LLFloaterSLappTest:
|
||||
public LLFloater
|
||||
{
|
||||
friend class LLFloaterReg;
|
||||
virtual bool postBuild() override;
|
||||
|
||||
private:
|
||||
LLFloaterSLappTest(const LLSD& key);
|
||||
~LLFloaterSLappTest();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -353,6 +353,18 @@ void LLGLTFMaterialList::queueApply(const LLViewerObject* obj, S32 side, const L
|
|||
}
|
||||
}
|
||||
|
||||
void LLGLTFMaterialList::queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id, const std::string &override_json)
|
||||
{
|
||||
if (asset_id.isNull() || override_json.empty())
|
||||
{
|
||||
queueApply(obj, side, asset_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
sApplyQueue.push_back({ obj->getID(), side, asset_id, nullptr, override_json });
|
||||
}
|
||||
}
|
||||
|
||||
void LLGLTFMaterialList::queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id, const LLGLTFMaterial* material_override)
|
||||
{
|
||||
if (asset_id.isNull() || material_override == nullptr)
|
||||
|
|
@ -456,6 +468,10 @@ void LLGLTFMaterialList::flushUpdatesOnce(std::shared_ptr<CallbackHolder> callba
|
|||
{
|
||||
data[i]["gltf_json"] = e.override_data->asJSON();
|
||||
}
|
||||
if (!e.override_json.empty())
|
||||
{
|
||||
data[i]["gltf_json"] = e.override_json;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Clear all overrides
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ public:
|
|||
//
|
||||
// NOTE: Implicitly clears most override data if present
|
||||
static void queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id);
|
||||
static void queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id, const std::string& override_json);
|
||||
|
||||
// Queue an application of a material asset we want to send to the simulator.
|
||||
// Call "flushUpdates" to flush pending updates immediately.
|
||||
|
|
@ -160,6 +161,7 @@ protected:
|
|||
S32 side = -1;
|
||||
LLUUID asset_id;
|
||||
LLPointer<LLGLTFMaterial> override_data;
|
||||
std::string override_json;
|
||||
};
|
||||
|
||||
typedef std::list<ApplyMaterialAssetData> apply_queue_t;
|
||||
|
|
|
|||
|
|
@ -3920,6 +3920,13 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
|
|||
const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
|
||||
move_folder_to_marketplacelistings(cat, marketplacelistings_id, ("move_to_marketplace_listings" != action), (("copy_or_move_to_marketplace_listings" == action)));
|
||||
}
|
||||
else if ("copy_folder_uuid" == action)
|
||||
{
|
||||
LLInventoryCategory* cat = gInventory.getCategory(mUUID);
|
||||
if (!cat) return;
|
||||
gViewerWindow->getWindow()->copyTextToClipboard(utf8str_to_wstring(mUUID.asString()));
|
||||
return;
|
||||
}
|
||||
// <FS:Ansariel> FIRE-29342: Protect folder option
|
||||
else if ("protect_folder" == action)
|
||||
{
|
||||
|
|
@ -4925,6 +4932,14 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
|
|||
{
|
||||
disabled_items.push_back(std::string("Delete System Folder"));
|
||||
}
|
||||
else
|
||||
{
|
||||
static LLCachedControl<bool> show_copy_id(gSavedSettings, "InventoryExposeFolderID", false);
|
||||
if (show_copy_id())
|
||||
{
|
||||
items.push_back(std::string("Copy UUID"));
|
||||
}
|
||||
}
|
||||
|
||||
// <FS:AH/SJ> Don't offer sharing of trash folder (FIRE-1642, FIRE-6547)
|
||||
//if (isAgentInventory() && !isMarketplaceListingsFolder())
|
||||
|
|
|
|||
|
|
@ -4572,21 +4572,14 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te)
|
|||
tep->setGLTFRenderMaterial(nullptr);
|
||||
tep->setGLTFMaterialOverride(nullptr);
|
||||
|
||||
LLSD override_data;
|
||||
override_data["object_id"] = objectp->getID();
|
||||
override_data["side"] = te;
|
||||
if (te_data["te"].has("pbr_override"))
|
||||
{
|
||||
override_data["gltf_json"] = te_data["te"]["pbr_override"];
|
||||
LLGLTFMaterialList::queueApply(objectp, te, te_data["te"]["pbr"].asUUID(), te_data["te"]["pbr_override"]);
|
||||
}
|
||||
else
|
||||
{
|
||||
override_data["gltf_json"] = "";
|
||||
LLGLTFMaterialList::queueApply(objectp, te, te_data["te"]["pbr"].asUUID());
|
||||
}
|
||||
|
||||
override_data["asset_id"] = te_data["te"]["pbr"].asUUID();
|
||||
|
||||
LLGLTFMaterialList::queueUpdate(override_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2150,7 +2150,7 @@ void LLPanelMainInventory::initInventoryViews()
|
|||
|
||||
void LLPanelMainInventory::toggleViewMode()
|
||||
{
|
||||
if(mSingleFolderMode && isCombinationViewMode())
|
||||
if(mSingleFolderMode && isCombinationViewMode() && mCombinationGalleryPanel->getRootFolder().notNull())
|
||||
{
|
||||
mCombinationInventoryPanel->getRootFolder()->setForceArrange(false);
|
||||
}
|
||||
|
|
@ -2633,7 +2633,8 @@ bool LLPanelMainInventory::isSaveTextureEnabled(const LLSD& userdata)
|
|||
}
|
||||
else
|
||||
{
|
||||
LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
|
||||
LLFolderView* root_folder = getActivePanel() ? getActivePanel()->getRootFolder() : nullptr;
|
||||
LLFolderViewItem* current_item = root_folder ? root_folder->getCurSelectedItem() : nullptr;
|
||||
if (current_item)
|
||||
{
|
||||
inv_item = dynamic_cast<LLViewerInventoryItem*>(static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getInventoryObject());
|
||||
|
|
@ -3243,8 +3244,6 @@ void LLPanelMainInventory::updateCombinationVisibility()
|
|||
mCombinationGalleryPanel->handleModifiedFilter();
|
||||
}
|
||||
|
||||
getActivePanel()->getRootFolder();
|
||||
|
||||
if (mReshapeInvLayout
|
||||
&& show_inv_pane
|
||||
&& (mCombinationGalleryPanel->hasVisibleItems() || mCombinationGalleryPanel->areViewsInitialized())
|
||||
|
|
@ -3301,8 +3300,12 @@ void LLPanelMainInventory::updateCombinationVisibility()
|
|||
&& mCombinationInventoryPanel->areViewsInitialized())
|
||||
{
|
||||
mCombinationInventoryPanel->setSelectionByID(mCombInvUUIDNeedsRename, true);
|
||||
mCombinationInventoryPanel->getRootFolder()->scrollToShowSelection();
|
||||
mCombinationInventoryPanel->getRootFolder()->setNeedsAutoRename(true);
|
||||
LLFolderView* root = mCombinationInventoryPanel->getRootFolder();
|
||||
if (root)
|
||||
{
|
||||
root->scrollToShowSelection();
|
||||
root->setNeedsAutoRename(true);
|
||||
}
|
||||
mCombInvUUIDNeedsRename.setNull();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,13 +80,6 @@ class LLClassifiedHandler : public LLCommandHandler, public LLAvatarPropertiesOb
|
|||
public:
|
||||
// throttle calls from untrusted browsers
|
||||
LLClassifiedHandler() : LLCommandHandler("classified", UNTRUSTED_THROTTLE) {}
|
||||
virtual ~LLClassifiedHandler()
|
||||
{
|
||||
if (LLAvatarPropertiesProcessor::instanceExists())
|
||||
{
|
||||
LLAvatarPropertiesProcessor::getInstance()->removeObserver(LLUUID(), this);
|
||||
}
|
||||
}
|
||||
|
||||
std::set<LLUUID> mClassifiedIds;
|
||||
std::string mRequestVerb;
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@
|
|||
static LLPanelInjector<LLPanelProfilePicks> t_panel_profile_picks("panel_profile_picks");
|
||||
static LLPanelInjector<LLPanelProfilePick> t_panel_profile_pick("panel_profile_pick");
|
||||
|
||||
constexpr F32 REQUEST_TIMOUT = 60;
|
||||
constexpr F32 REQUEST_TIMEOUT = 60;
|
||||
constexpr F32 LOCATION_CACHE_TIMOUT = 900;
|
||||
|
||||
class LLPickHandler : public LLCommandHandler
|
||||
|
|
@ -981,7 +981,7 @@ std::string LLPanelProfilePick::getLocationNotice()
|
|||
|
||||
void LLPanelProfilePick::sendParcelInfoRequest()
|
||||
{
|
||||
if (mParcelId != mRequestedId || mLastRequestTimer.getElapsedTimeF32() > REQUEST_TIMOUT)
|
||||
if (mParcelId != mRequestedId || mLastRequestTimer.getElapsedTimeF32() > REQUEST_TIMEOUT)
|
||||
{
|
||||
if (mRequestedId.notNull())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -102,7 +102,15 @@ void LLRemoteParcelInfoProcessor::processParcelInfoReply(LLMessageSystem* msg, v
|
|||
msg->getS32 ("Data", "SalePrice", parcel_data.sale_price);
|
||||
msg->getS32 ("Data", "AuctionID", parcel_data.auction_id);
|
||||
|
||||
LLRemoteParcelInfoProcessor::observer_multimap_t & observers = LLRemoteParcelInfoProcessor::getInstance()->mObservers;
|
||||
LLRemoteParcelInfoProcessor* inst = LLRemoteParcelInfoProcessor::getInstance();
|
||||
|
||||
requests_map_t::const_iterator found = inst->mPendingParcelRequests.find(parcel_data.parcel_id);
|
||||
if (found != inst->mPendingParcelRequests.end())
|
||||
{
|
||||
inst->mPendingParcelRequests.erase(found);
|
||||
}
|
||||
|
||||
LLRemoteParcelInfoProcessor::observer_multimap_t & observers = inst->mObservers;
|
||||
|
||||
typedef std::vector<observer_multimap_t::iterator> deadlist_t;
|
||||
deadlist_t dead_iters;
|
||||
|
|
@ -151,6 +159,15 @@ void LLRemoteParcelInfoProcessor::processParcelInfoReply(LLMessageSystem* msg, v
|
|||
|
||||
void LLRemoteParcelInfoProcessor::sendParcelInfoRequest(const LLUUID& parcel_id)
|
||||
{
|
||||
constexpr F32 DUPPLICATE_TIMEOUT = 0.5f;
|
||||
requests_map_t::const_iterator found = mPendingParcelRequests.find(parcel_id);
|
||||
if (found != mPendingParcelRequests.end() && found->second.getElapsedTimeF32() < DUPPLICATE_TIMEOUT)
|
||||
{
|
||||
// recently requested
|
||||
return;
|
||||
}
|
||||
mPendingParcelRequests[parcel_id].reset();
|
||||
|
||||
LLMessageSystem *msg = gMessageSystem;
|
||||
|
||||
msg->newMessage("ParcelInfoRequest");
|
||||
|
|
|
|||
|
|
@ -91,6 +91,8 @@ public:
|
|||
private:
|
||||
typedef std::multimap<LLUUID, LLHandle<LLRemoteParcelInfoObserver> > observer_multimap_t;
|
||||
observer_multimap_t mObservers;
|
||||
typedef std::map<LLUUID, LLTimer> requests_map_t;
|
||||
requests_map_t mPendingParcelRequests; // Dupplicate request avoidance
|
||||
|
||||
void regionParcelInfoCoro(std::string url, LLUUID regionId, LLVector3 posRegion, LLVector3d posGlobal, LLHandle<LLRemoteParcelInfoObserver> observerHandle);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2467,6 +2467,15 @@ bool idle_startup()
|
|||
#endif
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
|
||||
// It is entirely possible that we may get the friends list _before_ we have the callbacks registered to process that.
|
||||
// This will lead to the friends list not being processed properly and online statuses not being updated appropriately at login.
|
||||
// So, we need to make sure that we have the callbacks registered before we get the friends list.
|
||||
// This appears to crop up on some systems somewhere between STATE_AGENT_SEND and STATE_INVENTORY_SEND. It's happened to me a few times now.
|
||||
// -Geenz 2025-03-12
|
||||
LL_INFOS() << " AvatarTracker" << LL_ENDL;
|
||||
LLAvatarTracker::instance().registerCallbacks(gMessageSystem);
|
||||
|
||||
do_startup_frame();
|
||||
|
||||
// Create login effect
|
||||
|
|
@ -2786,8 +2795,6 @@ bool idle_startup()
|
|||
LLMessageSystem* msg = gMessageSystem;
|
||||
LL_INFOS() << " Inventory" << LL_ENDL;
|
||||
LLInventoryModel::registerCallbacks(msg);
|
||||
LL_INFOS() << " AvatarTracker" << LL_ENDL;
|
||||
LLAvatarTracker::instance().registerCallbacks(msg);
|
||||
LL_INFOS() << " Landmark" << LL_ENDL;
|
||||
LLLandmark::registerCallbacks(msg);
|
||||
do_startup_frame();
|
||||
|
|
|
|||
|
|
@ -139,6 +139,7 @@
|
|||
#include "llfloatersettingscolor.h"
|
||||
#include "llfloatersettingsdebug.h"
|
||||
#include "llfloatersidepanelcontainer.h"
|
||||
#include "llfloaterslapptest.h"
|
||||
#include "llfloatersnapshot.h"
|
||||
#include "llfloatersounddevices.h"
|
||||
#include "llfloaterspellchecksettings.h"
|
||||
|
|
@ -336,7 +337,8 @@ public:
|
|||
"upload_model",
|
||||
"upload_script",
|
||||
"upload_sound",
|
||||
"bulk_upload"
|
||||
"bulk_upload",
|
||||
"slapp_test"
|
||||
};
|
||||
return std::find(blacklist_untrusted.begin(), blacklist_untrusted.end(), fl_name) == blacklist_untrusted.end();
|
||||
}
|
||||
|
|
@ -601,6 +603,7 @@ void LLViewerFloaterReg::registerFloaters()
|
|||
//LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>);
|
||||
LLFloaterReg::add("profile", "floater_profile.xml",(LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterProfile>);
|
||||
LLFloaterReg::add("guidebook", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHowTo>);
|
||||
LLFloaterReg::add("slapp_test", "floater_test_slapp.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSLappTest>);
|
||||
|
||||
LLFloaterReg::add("big_preview", "floater_big_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBigPreview>);
|
||||
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@ const F32 MIN_FRACTIONAL = 0.2f;
|
|||
const F32 MIN_BANDWIDTH = 50.f;
|
||||
const F32 MAX_BANDWIDTH = 6000.f;
|
||||
const F32 STEP_FRACTIONAL = 0.1f;
|
||||
const F32 HIGH_BUFFER_LOAD_TRESHOLD = 1.f;
|
||||
const F32 LOW_BUFFER_LOAD_TRESHOLD = 0.8f;
|
||||
const LLUnit<F32, LLUnits::Percent> TIGHTEN_THROTTLE_THRESHOLD(3.0f); // packet loss % per s
|
||||
const LLUnit<F32, LLUnits::Percent> EASE_THROTTLE_THRESHOLD(0.5f); // packet loss % per s
|
||||
const F32 DYNAMIC_UPDATE_DURATION = 5.0f; // seconds
|
||||
|
|
@ -146,7 +148,7 @@ LLViewerThrottleGroup LLViewerThrottleGroup::operator-(const LLViewerThrottleGro
|
|||
|
||||
void LLViewerThrottleGroup::sendToSim() const
|
||||
{
|
||||
LL_INFOS() << "Sending throttle settings, total BW " << mThrottleTotal << LL_ENDL;
|
||||
LL_DEBUGS("Throttle") << "Sending throttle settings, total BW " << mThrottleTotal << LL_ENDL;
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
|
||||
msg->newMessageFast(_PREHASH_AgentThrottle);
|
||||
|
|
@ -305,7 +307,10 @@ void LLViewerThrottle::updateDynamicThrottle()
|
|||
mUpdateTimer.reset();
|
||||
|
||||
LLUnit<F32, LLUnits::Percent> mean_packets_lost = LLViewerStats::instance().getRecording().getMean(LLStatViewer::PACKETS_LOST_PERCENT);
|
||||
if (mean_packets_lost > TIGHTEN_THROTTLE_THRESHOLD)
|
||||
if (
|
||||
mean_packets_lost > TIGHTEN_THROTTLE_THRESHOLD // already losing packets
|
||||
|| mBufferLoadRate >= HIGH_BUFFER_LOAD_TRESHOLD // let viewer sort through the backlog before it starts dropping packets
|
||||
)
|
||||
{
|
||||
if (mThrottleFrac <= MIN_FRACTIONAL || mCurrentBandwidth / 1024.0f <= MIN_BANDWIDTH)
|
||||
{
|
||||
|
|
@ -318,7 +323,8 @@ void LLViewerThrottle::updateDynamicThrottle()
|
|||
mCurrent.sendToSim();
|
||||
LL_INFOS() << "Tightening network throttle to " << mCurrentBandwidth << LL_ENDL;
|
||||
}
|
||||
else if (mean_packets_lost <= EASE_THROTTLE_THRESHOLD)
|
||||
else if (mean_packets_lost <= EASE_THROTTLE_THRESHOLD
|
||||
&& mBufferLoadRate < LOW_BUFFER_LOAD_TRESHOLD)
|
||||
{
|
||||
if (mThrottleFrac >= MAX_FRACTIONAL || mCurrentBandwidth / 1024.0f >= MAX_BANDWIDTH)
|
||||
{
|
||||
|
|
@ -331,4 +337,6 @@ void LLViewerThrottle::updateDynamicThrottle()
|
|||
mCurrent.sendToSim();
|
||||
LL_INFOS() << "Easing network throttle to " << mCurrentBandwidth << LL_ENDL;
|
||||
}
|
||||
|
||||
mBufferLoadRate = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,12 +70,15 @@ public:
|
|||
void updateDynamicThrottle();
|
||||
void resetDynamicThrottle();
|
||||
|
||||
void setBufferLoadRate(F32 rate) { mBufferLoadRate = llmax(mBufferLoadRate, rate); }
|
||||
|
||||
LLViewerThrottleGroup getThrottleGroup(const F32 bandwidth_kbps);
|
||||
|
||||
static const std::string sNames[TC_EOF];
|
||||
protected:
|
||||
F32 mMaxBandwidth;
|
||||
F32 mCurrentBandwidth;
|
||||
F32 mBufferLoadRate = 0;
|
||||
|
||||
LLViewerThrottleGroup mCurrent;
|
||||
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@
|
|||
<menu_item_call label="Schutz aufheben" name="UnprotectFolder"/>
|
||||
<menu_item_call label="Ordner neu laden" name="ReloadFolder"/>
|
||||
<menu_item_call label="Asset-UUID kopieren" name="Copy Asset UUID"/>
|
||||
<menu_item_call label="UUID kopieren" name="Copy UUID"/>
|
||||
<menu_item_call label="Wiederherstellen an letzter Position" name="Restore to Last Position"/>
|
||||
<menu_item_call label="Ausschneiden" name="Cut"/>
|
||||
<menu_item_call label="Kopieren" name="Copy"/>
|
||||
|
|
|
|||
|
|
@ -620,6 +620,7 @@
|
|||
<menu_item_call label="Farbeinstellungen anzeigen" name="Color Settings"/>
|
||||
<menu_item_call label="Farbeinstellungen neu laden" name="Reload Color Settings"/>
|
||||
<menu_item_call label="Schriftarttest anzeigen" name="Show Font Test"/>
|
||||
<menu_item_call label="SLapps-Test anzeigen" name="Show SLapps Test"/>
|
||||
<menu_item_call label="Aus XML-Datei laden" name="Load from XML"/>
|
||||
<menu_item_call label="In XML-Datei speichern" name="Save to XML"/>
|
||||
<menu_item_check label="XUI-Namen anzeigen" name="Show XUI Names"/>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,123 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<floater
|
||||
legacy_header_height="18"
|
||||
height="300"
|
||||
layout="topleft"
|
||||
name="slapp_test"
|
||||
title="SLAPP TEST"
|
||||
width="500">
|
||||
<floater.string
|
||||
name="remove_folder_slapp">
|
||||
secondlife://app/remove_folder/?folder_id=
|
||||
</floater.string>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
top="20"
|
||||
follows="left|top|right"
|
||||
height="16"
|
||||
name="trusted_txt"
|
||||
font="SansSerifMedium"
|
||||
text_color="white"
|
||||
layout="topleft"
|
||||
left="16">
|
||||
Trusted source
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
top_pad="8"
|
||||
follows="left|top|right"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
left="16">
|
||||
/wear_folder
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
top_pad="5"
|
||||
follows="left|top|right"
|
||||
height="16"
|
||||
width="450"
|
||||
layout="topleft"
|
||||
left="16">
|
||||
secondlife://app/wear_folder/?folder_name=Daisy
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
top_pad="8 "
|
||||
follows="left|top|right"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
left="16">
|
||||
/add_folder
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
top_pad="5"
|
||||
follows="left|top|right"
|
||||
height="16"
|
||||
width="450"
|
||||
layout="topleft"
|
||||
left="16">
|
||||
secondlife://app/add_folder/?folder_name=Cardboard%20Boxbot
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
top_pad="5"
|
||||
follows="left|top|right"
|
||||
height="16"
|
||||
width="450"
|
||||
layout="topleft">
|
||||
secondlife://app/add_folder/?folder_id=59219db2-c260-87d3-213d-bb3bc298a3d8
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
top_pad="8 "
|
||||
follows="left|top|right"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
left="16">
|
||||
/remove_folder
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
top_pad="5"
|
||||
follows="left|top|right"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
left="16">
|
||||
Folder ID:
|
||||
</text>
|
||||
<line_editor
|
||||
border_style="line"
|
||||
border_thickness="1"
|
||||
follows="left|top"
|
||||
font="SansSerif"
|
||||
height="18"
|
||||
layout="topleft"
|
||||
left="75"
|
||||
max_length_bytes="50"
|
||||
prevalidate_callback="ascii"
|
||||
name="remove_folder_id"
|
||||
top_delta="-2"
|
||||
width="270" />
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
top_pad="5"
|
||||
follows="left|top|right"
|
||||
height="16"
|
||||
width="450"
|
||||
name="remove_folder_txt"
|
||||
layout="topleft"
|
||||
left="16">
|
||||
secondlife://app/remove_folder/?folder_id=
|
||||
</text>
|
||||
</floater>
|
||||
|
|
@ -678,6 +678,14 @@
|
|||
function="Inventory.DoToSelected"
|
||||
parameter="copy_uuid" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Copy UUID"
|
||||
layout="topleft"
|
||||
name="Copy UUID">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="copy_folder_uuid" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Restore to Last Position"
|
||||
layout="topleft"
|
||||
|
|
|
|||
|
|
@ -5272,6 +5272,13 @@
|
|||
function="Floater.Show"
|
||||
parameter="font_test" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Show SLapps Test"
|
||||
name="Show SLapps Test">
|
||||
<menu_item_call.on_click
|
||||
function="Floater.Show"
|
||||
parameter="slapp_test" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Load from XML"
|
||||
name="Load from XML">
|
||||
|
|
|
|||
Loading…
Reference in New Issue