Added info toast as a reminder that there is a followcam script holding camera controls when trying to use shift+esc to reset camera view.
parent
7c0f0a2dfc
commit
fdb2e35f0b
|
|
@ -857,6 +857,7 @@ set(viewer_SOURCE_FILES
|
|||
llxmlrpctransaction.cpp
|
||||
noise.cpp
|
||||
particleeditor.cpp
|
||||
permissionstracker.cpp
|
||||
piemenu.cpp
|
||||
pieseparator.cpp
|
||||
pieslice.cpp
|
||||
|
|
@ -1630,6 +1631,7 @@ set(viewer_HEADER_FILES
|
|||
macmain.h
|
||||
noise.h
|
||||
particleeditor.h
|
||||
permissionstracker.h
|
||||
piemenu.h
|
||||
pieseparator.h
|
||||
pieslice.h
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@
|
|||
#include "llfollowcam.h"
|
||||
#include "llagent.h"
|
||||
|
||||
#include "permissionstracker.h"
|
||||
|
||||
//-------------------------------------------------------
|
||||
// constants
|
||||
//-------------------------------------------------------
|
||||
|
|
@ -829,11 +831,13 @@ void LLFollowCamMgr::setCameraActive( const LLUUID& source, bool active )
|
|||
if (found_it != mParamStack.end())
|
||||
{
|
||||
mParamStack.erase(found_it);
|
||||
PermissionsTracker::instance().removePermissionsEntry(source, PermissionsTracker::PERM_FOLLOWCAM);
|
||||
}
|
||||
// put on top of stack
|
||||
if(active)
|
||||
{
|
||||
mParamStack.push_back(params);
|
||||
PermissionsTracker::instance().addPermissionsEntry(source, PermissionsTracker::PERM_FOLLOWCAM);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -843,6 +847,8 @@ void LLFollowCamMgr::removeFollowCamParams(const LLUUID& source)
|
|||
LLFollowCamParams* params = getParamsForID(source);
|
||||
mParamMap.erase(source);
|
||||
delete params;
|
||||
|
||||
PermissionsTracker::instance().removePermissionsEntry(source, PermissionsTracker::PERM_FOLLOWCAM);
|
||||
}
|
||||
|
||||
bool LLFollowCamMgr::isScriptedCameraSource(const LLUUID& source)
|
||||
|
|
|
|||
|
|
@ -166,6 +166,7 @@
|
|||
#include "lltexturecache.h"
|
||||
#include "llvovolume.h"
|
||||
#include "particleeditor.h"
|
||||
#include "permissionstracker.h"
|
||||
|
||||
using namespace LLAvatarAppearanceDefines;
|
||||
|
||||
|
|
@ -5424,6 +5425,9 @@ void handle_reset_camera_angles()
|
|||
// Camera focus and offset with CTRL/SHIFT + Scroll wheel
|
||||
gSavedSettings.getControl("FocusOffsetRearView")->resetToDefault();
|
||||
gSavedSettings.getControl("CameraOffsetRearView")->resetToDefault();
|
||||
|
||||
// warn the user if there is a scripted followcam active that might stop a camera reset
|
||||
PermissionsTracker::instance().warnFollowcam();
|
||||
}
|
||||
// </FS:Zi>
|
||||
|
||||
|
|
|
|||
|
|
@ -150,6 +150,7 @@
|
|||
#include "llfloaterbump.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llfriendcard.h"
|
||||
#include "permissionstracker.h" // <FS:Zi> Permissions Tracker
|
||||
#include "tea.h" // <FS:AW opensim currency support>
|
||||
#include "NACLantispam.h"
|
||||
#include "chatbar_as_cmdline.h"
|
||||
|
|
@ -4733,6 +4734,8 @@ void process_object_properties(LLMessageSystem *msg, void**user_data)
|
|||
{
|
||||
explorer->requestNameCallback(msg);
|
||||
}
|
||||
|
||||
PermissionsTracker::instance().objectPropertiesCallback(msg);
|
||||
}
|
||||
// </FS:Techwolf Lupindo> area search
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,274 @@
|
|||
/**
|
||||
* @file permissionstracker.cpp
|
||||
* @brief Permissions Tracker implementation - Initially it's only tracking
|
||||
* camera control permissions, to warn users about attachments or seats that
|
||||
* took camera control permissions and might interfere with resetting the
|
||||
* camera view.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
* Copyright (C) 2022, Zi Ree @ Second Life
|
||||
*
|
||||
* 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 "llagentdata.h" // for gAgentID anf gAgentSessionID
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llslurl.h"
|
||||
#include "lltrans.h"
|
||||
#include "llviewermenu.h" // for handle_object_edit()
|
||||
#include "llviewerregion.h"
|
||||
#include "llviewerobject.h"
|
||||
#include "llviewerobjectlist.h" // for gObjectList
|
||||
#include "llvoavatarself.h" // for gAgentAvatarp
|
||||
#include "llworld.h"
|
||||
|
||||
#include "permissionstracker.h"
|
||||
|
||||
#define PERMISSION_ENTRY_EXPIRY_TIME 3600.0
|
||||
|
||||
PermissionsTracker::PermissionsTracker()
|
||||
: LLSingleton<PermissionsTracker>()
|
||||
{
|
||||
}
|
||||
|
||||
PermissionsTracker::~PermissionsTracker()
|
||||
{
|
||||
}
|
||||
|
||||
void PermissionsTracker::addPermissionsEntry(const LLUUID& source_id, PermissionsTracker::PERM_TYPE permission_type)
|
||||
{
|
||||
// find out if this is a new entry in the list
|
||||
if (mPermissionsList.find(source_id) == mPermissionsList.end())
|
||||
{
|
||||
LL_DEBUGS("PermissionsTracker") << "Creating list entry for source " << source_id << LL_ENDL;
|
||||
mPermissionsList[source_id].objectName = LLTrans::getString("LoadingData");
|
||||
|
||||
// find out if the object is still in reach
|
||||
LLViewerObject* vo = gObjectList.findObject(source_id);
|
||||
if (!vo)
|
||||
{
|
||||
mPermissionsList[source_id].objectName = LLTrans::getString("ObjectOutOfRange");
|
||||
}
|
||||
else
|
||||
{
|
||||
mPermissionsList[source_id].attachmentID = vo->getAttachmentItemID();
|
||||
LL_DEBUGS("PermissionsTracker") << "Requesting ObjectProperties for source " << source_id << LL_ENDL;
|
||||
|
||||
// remember which object names we already requested
|
||||
mRequestedIDs.push_back(source_id);
|
||||
|
||||
// send a request out to get this object's details
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
|
||||
msg->newMessageFast(_PREHASH_ObjectSelect);
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
msg->addUUIDFast(_PREHASH_AgentID, gAgentID);
|
||||
msg->addUUIDFast(_PREHASH_SessionID, gAgentSessionID);
|
||||
msg->nextBlockFast(_PREHASH_ObjectData);
|
||||
msg->addU32Fast(_PREHASH_ObjectLocalID, vo->getLocalID());
|
||||
msg->sendReliable(gAgentAvatarp->getRegion()->getHost());
|
||||
|
||||
msg->newMessageFast(_PREHASH_ObjectDeselect);
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
msg->addUUIDFast(_PREHASH_AgentID, gAgentID);
|
||||
msg->addUUIDFast(_PREHASH_SessionID, gAgentSessionID);
|
||||
msg->nextBlockFast(_PREHASH_ObjectData);
|
||||
msg->addU32Fast(_PREHASH_ObjectLocalID, vo->getLocalID());
|
||||
msg->sendReliable(gAgentAvatarp->getRegion()->getHost());
|
||||
}
|
||||
}
|
||||
|
||||
LL_DEBUGS("PermissionsTracker") << "Adding permission type " << permission_type << " to source " << source_id << LL_ENDL;
|
||||
mPermissionsList[source_id].type |= permission_type;
|
||||
mPermissionsList[source_id].time = LLDate(LLTimer::getTotalSeconds());
|
||||
|
||||
purgePermissionsEntries();
|
||||
}
|
||||
|
||||
void PermissionsTracker::removePermissionsEntry(const LLUUID& source_id, PermissionsTracker::PERM_TYPE permission_type)
|
||||
{
|
||||
if (mPermissionsList.find(source_id) == mPermissionsList.end())
|
||||
{
|
||||
LL_DEBUGS("PermissionsTracker") << "Could not find list entry for source " << source_id << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
LL_DEBUGS("PermissionsTracker") << "Removing permissions type " << permission_type << " from source " << source_id << LL_ENDL;
|
||||
mPermissionsList[source_id].type &= ~permission_type;
|
||||
mPermissionsList[source_id].time = LLDate(LLTimer::getTotalSeconds());
|
||||
|
||||
purgePermissionsEntries();
|
||||
}
|
||||
|
||||
void PermissionsTracker::purgePermissionsEntries()
|
||||
{
|
||||
F64 expiry_time = LLDate(LLTimer::getTotalSeconds()).secondsSinceEpoch() - PERMISSION_ENTRY_EXPIRY_TIME;
|
||||
|
||||
auto it = mPermissionsList.begin();
|
||||
while (it != mPermissionsList.end())
|
||||
{
|
||||
if (it->second.type == PERM_TYPE::PERM_NONE && it->second.time.secondsSinceEpoch() < expiry_time)
|
||||
{
|
||||
LL_DEBUGS("PermissionsTracker") << "Erasing list entry for source " << it->first << LL_ENDL;
|
||||
it = mPermissionsList.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PermissionsTracker::warnFollowcam()
|
||||
{
|
||||
std::string followcamList;
|
||||
for (auto entry : mPermissionsList)
|
||||
{
|
||||
if (entry.second.type & PermissionsTracker::PERM_FOLLOWCAM)
|
||||
{
|
||||
if (entry.second.attachmentID.notNull())
|
||||
{
|
||||
std::string attachment_point = "???";
|
||||
gAgentAvatarp->getAttachedPointName(entry.second.attachmentID, attachment_point);
|
||||
|
||||
LLSD args;
|
||||
args["ATTACHMENT_POINT"] = attachment_point;
|
||||
|
||||
std::string verb = "select?name=" + LLURI::escape(entry.second.objectName);
|
||||
followcamList += LLSLURL("inventory", entry.second.attachmentID, verb.c_str()).getSLURLString() + " " +
|
||||
LLTrans::getString("WornOnAttachmentPoint", args) + "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
followcamList += LLSLURL("objectim", entry.first, "").getSLURLString() +
|
||||
"?name=" + LLURI::escape(entry.second.objectName) +
|
||||
"&owner=" + entry.second.ownerID.asString();
|
||||
|
||||
LLSD args;
|
||||
std::string slurl = args["slurl"].asString();
|
||||
if (slurl.empty())
|
||||
{
|
||||
LLViewerRegion* region = LLWorld::instance().getRegionFromPosAgent(gAgentAvatarp->getPositionAgent());
|
||||
if(region)
|
||||
{
|
||||
LLSLURL region_slurl(region->getName(), gAgentAvatarp->getPositionAgent());
|
||||
slurl = region_slurl.getLocationString();
|
||||
}
|
||||
}
|
||||
|
||||
followcamList += "&slurl=" + LLURI::escape(slurl) + "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (followcamList.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLSD args;
|
||||
args["SOURCES"] = followcamList;
|
||||
LLNotificationsUtil::add("WarnScriptedCamera", args);
|
||||
}
|
||||
|
||||
void PermissionsTracker::objectPropertiesCallback(LLMessageSystem* msg)
|
||||
{
|
||||
LL_DEBUGS("PermissionsTracker") << "Received ObjectProperties message." << LL_ENDL;
|
||||
|
||||
// if we weren't looking for any IDs, ignore this callback
|
||||
if (mRequestedIDs.empty())
|
||||
{
|
||||
LL_DEBUGS("PermissionsTracker") << "No objects in request list." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
// we might have received more than one answer in one block
|
||||
S32 num = msg->getNumberOfBlocksFast(_PREHASH_ObjectData);
|
||||
for (S32 index = 0; index < num; ++index)
|
||||
{
|
||||
LLUUID source_id;
|
||||
msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID, source_id, index);
|
||||
|
||||
auto iter = std::find(mRequestedIDs.begin(), mRequestedIDs.end(), source_id);
|
||||
// if this is one of the objects we were looking for, process the data
|
||||
if (iter != mRequestedIDs.end())
|
||||
{
|
||||
// get the name of the object
|
||||
std::string object_name;
|
||||
msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Name, object_name, index);
|
||||
|
||||
LLUUID object_owner;
|
||||
msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_OwnerID, object_owner, index);
|
||||
|
||||
LL_DEBUGS("PermissionsTracker") << "Received object name " << object_name
|
||||
<< " and owner " << object_owner.asString() << " for source " << source_id << LL_ENDL;
|
||||
|
||||
// remove the object from the lookup list and add it to the known names list
|
||||
mRequestedIDs.erase(iter);
|
||||
|
||||
mPermissionsList[source_id].objectName = object_name;
|
||||
mPermissionsList[source_id].ownerID = object_owner;
|
||||
|
||||
LLAvatarName avatar_name;
|
||||
if (LLAvatarNameCache::get(object_owner, &avatar_name))
|
||||
{
|
||||
LL_DEBUGS("PermissionsTracker") << "Found cached entry for owner " << object_owner.asString()
|
||||
<< ": " << avatar_name.getCompleteName() << LL_ENDL;
|
||||
mPermissionsList[source_id].ownerName = avatar_name.getCompleteName();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mAvatarNameCacheConnections.find(object_owner) != mAvatarNameCacheConnections.end())
|
||||
{
|
||||
boost::signals2::connection cb_connection = LLAvatarNameCache::get(object_owner, boost::bind(&PermissionsTracker::avatarNameCallback, this, _1, _2));
|
||||
mAvatarNameCacheConnections.insert(std::make_pair(object_owner, cb_connection));
|
||||
|
||||
LL_DEBUGS("PermissionsTracker") << "Requesting avatar name for owner " << object_owner.asString() << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PermissionsTracker::avatarNameCallback(const LLUUID& avatar_id, const LLAvatarName& avatar_name)
|
||||
{
|
||||
LL_DEBUGS("PermissionsTracker") << "Received avatar name " << avatar_name.getCompleteName() << LL_ENDL;
|
||||
|
||||
auto iter = mAvatarNameCacheConnections.find(avatar_id);
|
||||
if (iter != mAvatarNameCacheConnections.end())
|
||||
{
|
||||
if (iter->second.connected())
|
||||
{
|
||||
iter->second.disconnect();
|
||||
}
|
||||
mAvatarNameCacheConnections.erase(iter);
|
||||
}
|
||||
|
||||
for (auto entry : mPermissionsList)
|
||||
{
|
||||
if (entry.second.ownerID == avatar_id)
|
||||
{
|
||||
LL_DEBUGS("PermissionsTracker") << "Saved avatar name " << avatar_name.getCompleteName()<< " for source " << entry.first.asString() << LL_ENDL;
|
||||
entry.second.ownerName = avatar_name.getCompleteName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
/**
|
||||
* @file permissionstracker.h
|
||||
* @brief Permissions Tracker declaration
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
* Copyright (C) 2022, Zi Ree @ Second Life
|
||||
*
|
||||
* 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 PERMISSIONSTRACKER_H
|
||||
#define PERMISSIONSTRACKER_H
|
||||
|
||||
#include "llfloater.h"
|
||||
#include "llsingleton.h"
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// PermissionsTracker: holds a list of requested script permissions to be
|
||||
// referred to e.g. when trying to reset the camera view and a script is
|
||||
// holding a follow cam which micht prevent it from working.
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
class PermissionsTracker
|
||||
: public LLSingleton<PermissionsTracker>
|
||||
{
|
||||
LLSINGLETON(PermissionsTracker);
|
||||
~PermissionsTracker();
|
||||
|
||||
public:
|
||||
enum PERM_TYPE
|
||||
{
|
||||
PERM_NONE = 0,
|
||||
PERM_FOLLOWCAM = 1,
|
||||
};
|
||||
|
||||
struct PermissionsEntry
|
||||
{
|
||||
LLUUID ownerID; // agent who owns the requesting object
|
||||
LLUUID attachmentID; // attachment ID in inventory for attached objects
|
||||
std::string ownerName;
|
||||
std::string objectName;
|
||||
LLDate time; // time when the permission was granted
|
||||
U32 type; // what kind of permissions were granted
|
||||
};
|
||||
|
||||
std::map<LLUUID, PermissionsEntry> mPermissionsList; // UUID of the requesting object
|
||||
|
||||
void addPermissionsEntry(
|
||||
const LLUUID& source_id,
|
||||
PermissionsTracker::PERM_TYPE permission_type); // called in llviewermessage.cpp
|
||||
|
||||
void removePermissionsEntry(
|
||||
const LLUUID& source_id,
|
||||
PermissionsTracker::PERM_TYPE permission_type); // called in llviewermessage.cpp
|
||||
|
||||
void purgePermissionsEntries();
|
||||
|
||||
void objectPropertiesCallback(LLMessageSystem* msg);
|
||||
void avatarNameCallback(const LLUUID& avatar_id, const LLAvatarName& av_name);
|
||||
|
||||
void warnFollowcam(); // Warn the user if a script is holding followcam parameters
|
||||
|
||||
std::vector<LLUUID> mRequestedIDs; // list of object IDs we requested named for
|
||||
|
||||
typedef std::map<LLUUID, boost::signals2::connection> avatar_name_cache_connection_map_t;
|
||||
avatar_name_cache_connection_map_t mAvatarNameCacheConnections;
|
||||
};
|
||||
|
||||
#endif // PERMISSIONSTRACKER_H
|
||||
|
|
@ -13790,4 +13790,14 @@ Reset the URL to default?
|
|||
notext="Remind me next time"
|
||||
yestext="Reset"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="notifytip.tga"
|
||||
name="WarnScriptedCamera"
|
||||
type="notifytip">
|
||||
Camera reset might be inhibited by the following objects:
|
||||
|
||||
[SOURCES]
|
||||
</notification>
|
||||
|
||||
</notifications>
|
||||
|
|
|
|||
Loading…
Reference in New Issue