merge snowstorm repo

Tank_Master 2013-10-19 23:48:44 -07:00
commit 6007d1235e
66 changed files with 1710 additions and 311 deletions

View File

@ -480,3 +480,4 @@ fe4f7c5e9fd27e09d03deb1cc9ab3e5093f6309e 3.6.3-release
83357f31d8dbf048a8bfdc323f363bf4d588aca1 CHOP-951-a
91ed595b716f14f07409595b734fda891a59379e 3.6.4-release
bf6d453046011a11de2643fac610cc5258650f82 3.6.5-release
ae457ece77001767ae9613148c495e7b98cc0f4a 3.6.7-release

View File

@ -27,9 +27,6 @@ Linux.distcc_version =
Linux.gcc_version = /usr/bin/gcc-4.6
Linux.cxx_version = /usr/bin/g++-4.6
# Setup default sourceid so Windows can pick up the TeamCity override
sourceid = ""
################################################################
#### Examples of how to set the viewer_channel ####
#
@ -50,6 +47,18 @@ sourceid = ""
################################################################
viewer_channel = "Second Life Test"
# Setup default packaging parameters.
sourceid = ""
additional_packages = "Amazon Desura B C"
Amazon_sourceid = "1207v_Amazon"
Amazon_viewer_channel_suffix = " Amazon"
Desura_sourceid = "1208_desura"
Desura_viewer_channel_suffix = " Desura"
B_sourceid = "1301_B"
B_viewer_channel_suffix = " B"
C_sourceid = "1302_C"
C_viewer_channel_suffix = " C"
# Report changes since...
viewer-development.show_changes_since = last_sprint

View File

@ -38,22 +38,22 @@ build_dir_CYGWIN()
installer_Darwin()
{
ls -1td "$(build_dir_Darwin ${last_built_variant:-Release})/newview/"*.dmg 2>/dev/null | sed 1q
ls -1tr "$(build_dir_Darwin ${last_built_variant:-Release})/newview/"*"$additional_package_name"*.dmg 2>/dev/null | sed 1q
}
installer_Linux()
{
ls -1td "$(build_dir_Linux ${last_built_variant:-Release})/newview/"*.tar.bz2 2>/dev/null | sed 1q
ls -1tr "$(build_dir_Linux ${last_built_variant:-Release})/newview/"*"$additional_package_name"*.tar.bz2 2>/dev/null | grep -v symbols | sed 1q
}
installer_CYGWIN()
{
v=${last_built_variant:-Release}
d=$(build_dir_CYGWIN $v)
if [ -r "$d/newview/$v/touched.bat" ]
if [ -r "$d/newview/$additional_package_name$v/touched.bat" ]
then
p=$(sed 's:.*=::' "$d/newview/$v/touched.bat")
echo "$d/newview/$v/$p"
p=$(sed 's:.*=::' "$d/newview/$additional_package_name$v/touched.bat")
echo "$d/newview/$additional_package_name$v/$p"
fi
}
@ -367,10 +367,28 @@ then
# Coverity doesn't package, so it's ok, anything else is fail
succeeded=$build_coverity
else
# Upload base package.
upload_item installer "$package" binary/octet-stream
upload_item quicklink "$package" binary/octet-stream
[ -f $build_dir/summary.json ] && upload_item installer $build_dir/summary.json text/plain
# Upload additional packages.
for package_id in $additional_packages
do
case $arch in
CYGWIN) export additional_package_name="$package_id/" ;;
*) export additional_package_name=$package_id ;;
esac
package=$(installer_$arch)
if [ x"$package" != x ]
then
upload_item installer "$package" binary/octet-stream
else
record_failure "Failed to upload $package_id package."
fi
done
export additional_package_name=""
case "$last_built_variant" in
Release)
# Upload crash reporter files

View File

@ -175,8 +175,11 @@ Ansariel Hiller
STORM-1685
STORM-1713
STORM-1899
STORM-1932
STORM-1933
MAINT-2368
STORM-1931
MAINT-2773
Aralara Rajal
Arare Chantilly
CHUIBUG-191
@ -304,9 +307,13 @@ Christopher Organiser
Ciaran Laval
Cinder Roxley
BUG-2326
OPEN-185
STORM-1703
STORM-1948
STORM-1888
STORM-1958
STORM-1952
STORM-1951
Clara Young
Coaldust Numbers
VWR-1095
@ -653,7 +660,7 @@ Jonathan Yap
STORM-1809
STORM-1793
STORM-1810
STORM-1877
STORM-1838
STORM-1892
STORM-1894
STORM-1860
@ -663,8 +670,11 @@ Jonathan Yap
STORM-1858
STORM-1862
STORM-1918
STORM-1929
STORM-1953
OPEN-161
STORM-1953
STORM-1957
Kadah Coba
STORM-1060
STORM-1843
@ -680,6 +690,7 @@ Kagehi Kohn
Kaimen Takahe
Katharine Berry
STORM-1900
OPEN-149
STORM-1940
STORM-1941
Keklily Longfall
@ -929,6 +940,7 @@ Nicky Dasmijn
STORM-1936
BUG-3605
CHUIBUG-197
OPEN-187
STORM-1937
Nicky Perian
OPEN-1
@ -1298,6 +1310,7 @@ Westley Streeter
Whimsy Winx
Whirly Fizzle
STORM-1895
VWR-29543
MAINT-873
STORM-1930
Whoops Babii
@ -1361,6 +1374,7 @@ YongYong Francois
Zak Westminster
Zai Lynch
VWR-19505
STORM-1902
Zana Kohime
Zaren Alexander
Zarkonnen Decosta

View File

@ -16,7 +16,9 @@ if (NOT DEFINED VIEWER_SHORT_VERSION) # will be true in indra/, false in indra/n
else (DEFINED ENV{revision})
find_program(MERCURIAL hg)
if (DEFINED MERCURIAL)
find_program(WORDCOUNT wc)
find_program(SED sed)
if (DEFINED MERCURIAL AND DEFINED WORDCOUNT AND DEFINED SED)
execute_process(
# <FS:TS> FIRE-11737: Reverting to old revisions shows tip in build string
# This command gets the revision number of the current
@ -24,7 +26,9 @@ if (NOT DEFINED VIEWER_SHORT_VERSION) # will be true in indra/, false in indra/n
# building an earlier revision. Instead, we use
# "hg identify -n" to get the local revision number
# of the actual state of the repository.
#COMMAND ${MERCURIAL} log -r tip --template "{rev}"
#COMMAND ${MERCURIAL} log -r tip:0 --template '\\n'
#COMMAND ${WORDCOUNT} -l
#COMMAND ${SED} "s/ //g"
COMMAND ${MERCURIAL} identify -n
OUTPUT_VARIABLE VIEWER_VERSION_REVISION
OUTPUT_STRIP_TRAILING_WHITESPACE
@ -36,13 +40,13 @@ if (NOT DEFINED VIEWER_SHORT_VERSION) # will be true in indra/, false in indra/n
if ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$")
message("Revision (from hg) ${VIEWER_VERSION_REVISION}")
else ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$")
message("Revision not set (repository not found?); using 0")
set(VIEWER_VERSION_REVISION 0 )
message("Revision not set, repository not found, using ${VIEWER_VERSION_REVISION}")
endif ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$")
else (DEFINED MERCURIAL)
else (DEFINED MERCURIAL AND DEFINED WORDCOUNT AND DEFINED SED)
message("Revision not set: 'hg', 'wc' or 'sed' not found; using 0")
set(VIEWER_VERSION_REVISION 0)
message("Revision not set, 'hg' not found (${MERCURIAL}), using ${VIEWER_VERSION_REVISION}")
endif (DEFINED MERCURIAL)
endif (DEFINED MERCURIAL AND DEFINED WORDCOUNT AND DEFINED SED)
endif (DEFINED ENV{revision})
message("Building '${VIEWER_CHANNEL}' Version ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}")
else ( EXISTS ${VIEWER_VERSION_BASE_FILE} )

View File

@ -229,15 +229,98 @@ def main():
for opt in args:
print "Option:", opt, "=", args[opt]
# pass in sourceid as an argument now instead of an environment variable
try:
args['sourceid'] = os.environ["sourceid"]
except KeyError:
args['sourceid'] = ""
# Build base package.
touch = args.get('touch')
if touch:
print 'Creating base package'
args['package_id'] = "" # base package has no package ID
wm = LLManifest.for_platform(args['platform'], args.get('arch'))(args)
wm.do(*args['actions'])
# Store package file for later if making touched file.
base_package_file = ""
if touch:
print 'Created base package ', wm.package_file
base_package_file = "" + wm.package_file
# handle multiple packages if set
try:
additional_packages = os.environ["additional_packages"]
except KeyError:
additional_packages = ""
if additional_packages:
# Determine destination prefix / suffix for additional packages.
base_dest_postfix = args['dest']
base_dest_prefix = ""
base_dest_parts = args['dest'].split(os.sep)
if len(base_dest_parts) > 1:
base_dest_postfix = base_dest_parts[len(base_dest_parts) - 1]
base_dest_prefix = base_dest_parts[0]
i = 1
while i < len(base_dest_parts) - 1:
base_dest_prefix = base_dest_prefix + os.sep + base_dest_parts[i]
i = i + 1
# Determine touched prefix / suffix for additional packages.
base_touch_postfix = ""
base_touch_prefix = ""
if touch:
base_touch_postfix = touch
base_touch_parts = touch.split('/')
if "arwin" in args['platform']:
if len(base_touch_parts) > 1:
base_touch_postfix = base_touch_parts[len(base_touch_parts) - 1]
base_touch_prefix = base_touch_parts[0]
i = 1
while i < len(base_touch_parts) - 1:
base_touch_prefix = base_touch_prefix + '/' + base_touch_parts[i]
i = i + 1
else:
if len(base_touch_parts) > 2:
base_touch_postfix = base_touch_parts[len(base_touch_parts) - 2] + '/' + base_touch_parts[len(base_touch_parts) - 1]
base_touch_prefix = base_touch_parts[0]
i = 1
while i < len(base_touch_parts) - 2:
base_touch_prefix = base_touch_prefix + '/' + base_touch_parts[i]
i = i + 1
# Store base channel name.
base_channel_name = args['channel']
# Build each additional package.
package_id_list = additional_packages.split(" ")
for package_id in package_id_list:
try:
args['package_id'] = package_id
args['channel'] = base_channel_name + os.environ[package_id + "_viewer_channel_suffix"]
if package_id + "_sourceid" in os.environ:
args['sourceid'] = os.environ[package_id + "_sourceid"]
else:
args['sourceid'] = ""
args['dest'] = base_dest_prefix + os.sep + package_id + os.sep + base_dest_postfix
except KeyError:
sys.stderr.write("Failed to create package for package_id: %s" % package_id)
sys.stderr.flush()
continue
if touch:
print 'Creating additional package for ', package_id, ' in ', args['dest']
wm = LLManifest.for_platform(args['platform'], args.get('arch'))(args)
wm.do(*args['actions'])
if touch:
print 'Created additional package ', wm.package_file, ' for ', package_id
faketouch = base_touch_prefix + '/' + package_id + '/' + base_touch_postfix
fp = open(faketouch, 'w')
fp.write('set package_file=%s\n' % wm.package_file)
fp.close()
# Write out the package file in this format, so that it can easily be called
# and used in a .bat file - yeah, it sucks, but this is the simplest...
touch = args.get('touch')
if touch:
fp = open(touch, 'w')
fp.write('set package_file=%s\n' % wm.package_file)
fp.write('set package_file=%s\n' % base_package_file)
fp.close()
print 'touched', touch
return 0

View File

@ -50,7 +50,7 @@ class LLColor4
LLColor4(F32 r, F32 g, F32 b); // Initializes LLColor4 to (r, g, b, 1)
LLColor4(F32 r, F32 g, F32 b, F32 a); // Initializes LLColor4 to (r. g, b, a)
LLColor4(U32 clr); // Initializes LLColor4 to (r=clr>>24, etc))
LLColor4(const F32 *vec); // Initializes LLColor4 to (vec[0]. vec[1], vec[2], 1)
LLColor4(const F32 *vec); // Initializes LLColor4 to (vec[0]. vec[1], vec[2], vec[3])
LLColor4(const LLColor3 &vec, F32 a = 1.f); // Initializes LLColor4 to (vec, a)
explicit LLColor4(const LLSD& sd);
explicit LLColor4(const LLColor4U& color4u); // "explicit" to avoid automatic conversion

View File

@ -126,7 +126,7 @@ enum EInstantMessage
IM_LURE_ACCEPTED = 23,
IM_LURE_DECLINED = 24,
IM_GODLIKE_LURE_USER = 25,
IM_YET_TO_BE_USED = 26,
IM_TELEPORT_REQUEST = 26,
// IM that notifie of a new group election.
// Name is name of person who called vote.

View File

@ -79,6 +79,7 @@ set(llui_SOURCE_FILES
llmultislider.cpp
llmultisliderctrl.cpp
llnotifications.cpp
llnotificationslistener.cpp
llnotificationsutil.cpp
llpanel.cpp
llprogressbar.cpp
@ -132,6 +133,7 @@ set(llui_SOURCE_FILES
llviewmodel.cpp
llview.cpp
llviewquery.cpp
llviewereventrecorder.cpp
llwindowshade.cpp
llxuiparser.cpp
)
@ -189,6 +191,7 @@ set(llui_HEADER_FILES
llmultislider.h
llnotificationptr.h
llnotifications.h
llnotificationslistener.h
llnotificationsutil.h
llnotificationtemplate.h
llnotificationvisibilityrule.h
@ -246,6 +249,7 @@ set(llui_HEADER_FILES
llviewinject.h
llviewmodel.h
llview.h
llviewereventrecorder.h
llviewquery.h
llwindowshade.h
llxuiparser.h

View File

@ -49,6 +49,7 @@
#include "lluictrlfactory.h"
#include "llhelp.h"
#include "lldockablefloater.h"
#include "llviewereventrecorder.h"
#include "llcheckboxctrl.h" // <FS:Zi> Add checkbox control toggle
@ -479,6 +480,8 @@ BOOL LLButton::handleMouseDown(S32 x, S32 y, MASK mask)
*/
LLUICtrl::handleMouseDown(x, y, mask);
LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname());
if(mMouseDownSignal) (*mMouseDownSignal)(this, LLSD());
mMouseDownTimer.start();
@ -509,6 +512,7 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask)
* by calling LLUICtrl::mMouseUpSignal(x, y, mask);
*/
LLUICtrl::handleMouseUp(x, y, mask);
LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname());
// Regardless of where mouseup occurs, handle callback
if(mMouseUpSignal) (*mMouseUpSignal)(this, LLSD());

View File

@ -29,7 +29,7 @@
// mini-map floater, etc.
#include "linden_common.h"
#include "llviewereventrecorder.h"
#include "llfloater.h"
#include "llfocusmgr.h"
@ -671,7 +671,10 @@ void LLFloater::handleVisibilityChange ( BOOL new_visibility )
void LLFloater::openFloater(const LLSD& key)
{
llinfos << "Opening floater " << getName() << llendl;
llinfos << "Opening floater " << getName() << " full path: " << getPathname() << llendl;
LLViewerEventRecorder::instance().logVisibilityChange( getPathname(), getName(), true,"floater"); // Last param is event subtype or empty string
mKey = key; // in case we need to open ourselves again
if (getSoundFlags() != SILENT
@ -741,6 +744,7 @@ void LLFloater::openFloater(const LLSD& key)
void LLFloater::closeFloater(bool app_quitting)
{
llinfos << "Closing floater " << getName() << llendl;
LLViewerEventRecorder::instance().logVisibilityChange( getPathname(), getName(), false,"floater"); // Last param is event subtype or empty string
if (app_quitting)
{
LLFloater::sQuitting = true;
@ -1607,6 +1611,17 @@ BOOL LLFloater::handleScrollWheel(S32 x, S32 y, S32 clicks)
return TRUE;//always
}
// virtual
BOOL LLFloater::handleMouseUp(S32 x, S32 y, MASK mask)
{
lldebugs << "LLFloater::handleMouseUp calling LLPanel (really LLView)'s handleMouseUp (first initialized xui to: " << getPathname() << " )" << llendl;
BOOL handled = LLPanel::handleMouseUp(x,y,mask); // Not implemented in LLPanel so this actually calls LLView
if (handled) {
LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname());
}
return handled;
}
// virtual
BOOL LLFloater::handleMouseDown(S32 x, S32 y, MASK mask)
{
@ -1627,7 +1642,11 @@ BOOL LLFloater::handleMouseDown(S32 x, S32 y, MASK mask)
else
{
bringToFront( x, y );
return LLPanel::handleMouseDown( x, y, mask );
BOOL handled = LLPanel::handleMouseDown( x, y, mask );
if (handled) {
LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname());
}
return handled;
}
}

View File

@ -291,6 +291,7 @@ public:
S32 getHeaderHeight() const { return mHeaderHeight; }
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
virtual BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask);

View File

@ -1214,6 +1214,7 @@ LLNotifications::LLNotifications()
: LLNotificationChannelBase(LLNotificationFilters::includeEverything),
mIgnoreAllNotifications(false)
{
mListener.reset(new LLNotificationsListener(*this));
LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Notification.Show", boost::bind(&LLNotifications::addFromCallback, this, _2));
}

View File

@ -98,6 +98,8 @@
#include "llrefcount.h"
#include "llsdparam.h"
#include "llnotificationslistener.h"
class LLAvatarName;
typedef enum e_notification_priority
{
@ -983,6 +985,8 @@ private:
bool mIgnoreAllNotifications;
boost::scoped_ptr<LLNotificationsListener> mListener;
std::vector<LLNotificationChannelPtr> mDefaultChannels;
};

View File

@ -0,0 +1,359 @@
/**
* @file llnotificationslistener.cpp
* @author Brad Kittenbrink
* @date 2009-07-08
* @brief Implementation for llnotificationslistener.
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, 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 "linden_common.h"
#include "llnotificationslistener.h"
#include "llnotifications.h"
#include "llnotificationtemplate.h"
#include "llsd.h"
#include "llui.h"
LLNotificationsListener::LLNotificationsListener(LLNotifications & notifications) :
LLEventAPI("LLNotifications",
"LLNotifications listener to (e.g.) pop up a notification"),
mNotifications(notifications)
{
add("requestAdd",
"Add a notification with specified [\"name\"], [\"substitutions\"] and [\"payload\"].\n"
"If optional [\"reply\"] specified, arrange to send user response on that LLEventPump.",
&LLNotificationsListener::requestAdd);
/* add("listChannels",
"Post to [\"reply\"] a map of info on existing channels",
&LLNotificationsListener::listChannels,
LLSD().with("reply", LLSD()));
*/
add("listChannelNotifications",
"Post to [\"reply\"] an array of info on notifications in channel [\"channel\"]",
&LLNotificationsListener::listChannelNotifications,
LLSD().with("reply", LLSD()).with("channel", LLSD()));
add("respond",
"Respond to notification [\"uuid\"] with data in [\"response\"]",
&LLNotificationsListener::respond,
LLSD().with("uuid", LLSD()));
add("cancel",
"Cancel notification [\"uuid\"]",
&LLNotificationsListener::cancel,
LLSD().with("uuid", LLSD()));
add("ignore",
"Ignore future notification [\"name\"]\n"
"(from <notification name= > in notifications.xml)\n"
"according to boolean [\"ignore\"].\n"
"If [\"name\"] is omitted or undefined, [un]ignore all future notifications.\n"
"Note that ignored notifications are not forwarded unless intercepted before\n"
"the \"Ignore\" channel.",
&LLNotificationsListener::ignore);
add("forward",
"Forward to [\"pump\"] future notifications on channel [\"channel\"]\n"
"according to boolean [\"forward\"]. When enabled, only types matching\n"
"[\"types\"] are forwarded, as follows:\n"
"omitted or undefined: forward all notifications\n"
"string: forward only the specific named [sig]type\n"
"array of string: forward any notification matching any named [sig]type.\n"
"When boolean [\"respond\"] is true, we auto-respond to each forwarded\n"
"notification.",
&LLNotificationsListener::forward,
LLSD().with("channel", LLSD()));
}
// This is here in the .cpp file so we don't need the definition of class
// Forwarder in the header file.
LLNotificationsListener::~LLNotificationsListener()
{
}
void LLNotificationsListener::requestAdd(const LLSD& event_data) const
{
if(event_data.has("reply"))
{
mNotifications.add(event_data["name"],
event_data["substitutions"],
event_data["payload"],
boost::bind(&LLNotificationsListener::NotificationResponder,
this,
event_data["reply"].asString(),
_1, _2
)
);
}
else
{
mNotifications.add(event_data["name"],
event_data["substitutions"],
event_data["payload"]);
}
}
void LLNotificationsListener::NotificationResponder(const std::string& reply_pump,
const LLSD& notification,
const LLSD& response) const
{
LLSD reponse_event;
reponse_event["notification"] = notification;
reponse_event["response"] = response;
LLEventPumps::getInstance()->obtain(reply_pump).post(reponse_event);
}
/*
void LLNotificationsListener::listChannels(const LLSD& params) const
{
LLReqID reqID(params);
LLSD response(reqID.makeResponse());
for (LLNotifications::
for (LLNotifications::ChannelMap::const_iterator cmi(mNotifications.mChannels.begin()),
cmend(mNotifications.mChannels.end());
cmi != cmend; ++cmi)
{
LLSD channelInfo;
channelInfo["parent"] = cmi->second->getParentChannelName();
response[cmi->first] = channelInfo;
}
LLEventPumps::instance().obtain(params["reply"]).post(response);
}
*/
void LLNotificationsListener::listChannelNotifications(const LLSD& params) const
{
LLReqID reqID(params);
LLSD response(reqID.makeResponse());
LLNotificationChannelPtr channel(mNotifications.getChannel(params["channel"]));
if (channel)
{
LLSD notifications(LLSD::emptyArray());
for (LLNotificationChannel::Iterator ni(channel->begin()), nend(channel->end());
ni != nend; ++ni)
{
notifications.append(asLLSD(*ni));
}
response["notifications"] = notifications;
}
LLEventPumps::instance().obtain(params["reply"]).post(response);
}
void LLNotificationsListener::respond(const LLSD& params) const
{
LLNotificationPtr notification(mNotifications.find(params["uuid"]));
if (notification)
{
notification->respond(params["response"]);
}
}
void LLNotificationsListener::cancel(const LLSD& params) const
{
LLNotificationPtr notification(mNotifications.find(params["uuid"]));
if (notification)
{
mNotifications.cancel(notification);
}
}
void LLNotificationsListener::ignore(const LLSD& params) const
{
// Calling a method named "ignore", but omitting its "ignore" Boolean
// argument, should by default cause something to be ignored. Explicitly
// pass ["ignore"] = false to cancel ignore.
bool ignore = true;
if (params.has("ignore"))
{
ignore = params["ignore"].asBoolean();
}
// This method can be used to affect either a single notification name or
// all future notifications. The two use substantially different mechanisms.
if (params["name"].isDefined())
{
// ["name"] was passed: ignore just that notification
LLNotificationTemplatePtr templatep = mNotifications.getTemplate(params["name"]);
if (templatep)
{
templatep->mForm->setIgnored(ignore);
}
}
else
{
// no ["name"]: ignore all future notifications
mNotifications.setIgnoreAllNotifications(ignore);
}
}
class LLNotificationsListener::Forwarder: public LLEventTrackable
{
LOG_CLASS(LLNotificationsListener::Forwarder);
public:
Forwarder(LLNotifications& llnotifications, const std::string& channel):
mNotifications(llnotifications),
mRespond(false)
{
// Connect to the specified channel on construction. Because
// LLEventTrackable is a base, we should automatically disconnect when
// destroyed.
LLNotificationChannelPtr channelptr(llnotifications.getChannel(channel));
if (channelptr)
{
// Insert our processing as a "passed filter" listener. This way
// we get to run before all the "changed" listeners, and we get to
// swipe it (hide it from the other listeners) if desired.
channelptr->connectPassedFilter(boost::bind(&Forwarder::handle, this, _1));
}
}
void setPumpName(const std::string& name) { mPumpName = name; }
void setTypes(const LLSD& types) { mTypes = types; }
void setRespond(bool respond) { mRespond = respond; }
private:
bool handle(const LLSD& notification) const;
bool matchType(const LLSD& filter, const std::string& type) const;
LLNotifications& mNotifications;
std::string mPumpName;
LLSD mTypes;
bool mRespond;
};
void LLNotificationsListener::forward(const LLSD& params)
{
std::string channel(params["channel"]);
// First decide whether we're supposed to start forwarding or stop it.
// Default to true.
bool forward = true;
if (params.has("forward"))
{
forward = params["forward"].asBoolean();
}
if (! forward)
{
// This is a request to stop forwarding notifications on the specified
// channel. The rest of the params don't matter.
// Because mForwarders contains scoped_ptrs, erasing the map entry
// DOES delete the heap Forwarder object. Because Forwarder derives
// from LLEventTrackable, destroying it disconnects it from the
// channel.
mForwarders.erase(channel);
return;
}
// From here on, we know we're being asked to start (or modify) forwarding
// on the specified channel. Find or create an appropriate Forwarder.
ForwarderMap::iterator
entry(mForwarders.insert(ForwarderMap::value_type(channel, ForwarderMap::mapped_type())).first);
if (! entry->second)
{
entry->second.reset(new Forwarder(mNotifications, channel));
}
// Now, whether this Forwarder is brand-new or not, update it with the new
// request info.
Forwarder& fwd(*entry->second);
fwd.setPumpName(params["pump"]);
fwd.setTypes(params["types"]);
fwd.setRespond(params["respond"]);
}
bool LLNotificationsListener::Forwarder::handle(const LLSD& notification) const
{
LL_INFOS("LLNotificationsListener") << "handle(" << notification << ")" << LL_ENDL;
if (notification["sigtype"].asString() == "delete")
{
LL_INFOS("LLNotificationsListener") << "ignoring delete" << LL_ENDL;
// let other listeners see the "delete" operation
return false;
}
LLNotificationPtr note(mNotifications.find(notification["id"]));
if (! note)
{
LL_INFOS("LLNotificationsListener") << notification["id"] << " not found" << LL_ENDL;
return false;
}
if (! matchType(mTypes, note->getType()))
{
LL_INFOS("LLNotificationsListener") << "didn't match types " << mTypes << LL_ENDL;
// We're not supposed to intercept this particular notification. Let
// other listeners process it.
return false;
}
LL_INFOS("LLNotificationsListener") << "sending via '" << mPumpName << "'" << LL_ENDL;
// This is a notification we care about. Forward it through specified
// LLEventPump.
LLEventPumps::instance().obtain(mPumpName).post(asLLSD(note));
// Are we also being asked to auto-respond?
if (mRespond)
{
LL_INFOS("LLNotificationsListener") << "should respond" << LL_ENDL;
note->respond(LLSD::emptyMap());
// Did that succeed in removing the notification? Only cancel() if
// it's still around -- otherwise we get an LL_ERRS crash!
note = mNotifications.find(notification["id"]);
if (note)
{
LL_INFOS("LLNotificationsListener") << "respond() didn't clear, canceling" << LL_ENDL;
mNotifications.cancel(note);
}
}
// If we've auto-responded to this notification, then it's going to be
// deleted. Other listeners would get the change operation, try to look it
// up and be baffled by lookup failure. So when we auto-respond, suppress
// this notification: don't pass it to other listeners.
return mRespond;
}
bool LLNotificationsListener::Forwarder::matchType(const LLSD& filter, const std::string& type) const
{
// Decide whether this notification matches filter:
// undefined: forward all notifications
if (filter.isUndefined())
{
return true;
}
// array of string: forward any notification matching any named type
if (filter.isArray())
{
for (LLSD::array_const_iterator ti(filter.beginArray()), tend(filter.endArray());
ti != tend; ++ti)
{
if (ti->asString() == type)
{
return true;
}
}
// Didn't match any entry in the array
return false;
}
// string: forward only the specific named type
return (filter.asString() == type);
}
LLSD LLNotificationsListener::asLLSD(LLNotificationPtr note)
{
LLSD notificationInfo(note->asLLSD());
// For some reason the following aren't included in LLNotification::asLLSD().
notificationInfo["summary"] = note->summarize();
notificationInfo["id"] = note->id();
notificationInfo["type"] = note->getType();
notificationInfo["message"] = note->getMessage();
notificationInfo["label"] = note->getLabel();
return notificationInfo;
}

View File

@ -0,0 +1,69 @@
/**
* @file llnotificationslistener.h
* @author Brad Kittenbrink
* @date 2009-07-08
* @brief Wrap subset of LLNotifications API in event API for test scripts.
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, 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_LLNOTIFICATIONSLISTENER_H
#define LL_LLNOTIFICATIONSLISTENER_H
#include "lleventapi.h"
#include "llnotificationptr.h"
#include <boost/shared_ptr.hpp>
#include <map>
#include <string>
class LLNotifications;
class LLSD;
class LLNotificationsListener : public LLEventAPI
{
public:
LLNotificationsListener(LLNotifications & notifications);
~LLNotificationsListener();
private:
void requestAdd(LLSD const & event_data) const;
void NotificationResponder(const std::string& replypump,
const LLSD& notification,
const LLSD& response) const;
void listChannels(const LLSD& params) const;
void listChannelNotifications(const LLSD& params) const;
void respond(const LLSD& params) const;
void cancel(const LLSD& params) const;
void ignore(const LLSD& params) const;
void forward(const LLSD& params);
static LLSD asLLSD(LLNotificationPtr);
class Forwarder;
typedef std::map<std::string, boost::shared_ptr<Forwarder> > ForwarderMap;
ForwarderMap mForwarders;
LLNotifications & mNotifications;
};
#endif // LL_LLNOTIFICATIONSLISTENER_H

View File

@ -27,7 +27,7 @@
#include "linden_common.h"
#include "lltabcontainer.h"
#include "llviewereventrecorder.h"
#include "llfocusmgr.h"
#include "lllocalcliprect.h"
#include "llrect.h"
@ -632,6 +632,11 @@ BOOL LLTabContainer::handleMouseDown( S32 x, S32 y, MASK mask )
tab_button->setFocus(TRUE);
}
}
if (handled) {
// Note: May need to also capture local coords right here ?
LLViewerEventRecorder::instance().update_xui(getPathname( ));
}
return handled;
}
@ -683,30 +688,33 @@ BOOL LLTabContainer::handleMouseUp( S32 x, S32 y, MASK mask )
BOOL handled = FALSE;
BOOL has_scroll_arrows = (getMaxScrollPos() > 0) && !getTabsHidden();
S32 local_x = x - getRect().mLeft;
S32 local_y = y - getRect().mBottom;
if (has_scroll_arrows)
{
if (mJumpPrevArrowBtn && mJumpPrevArrowBtn->getRect().pointInRect(x, y))
{
S32 local_x = x - mJumpPrevArrowBtn->getRect().mLeft;
S32 local_y = y - mJumpPrevArrowBtn->getRect().mBottom;
local_x = x - mJumpPrevArrowBtn->getRect().mLeft;
local_y = y - mJumpPrevArrowBtn->getRect().mBottom;
handled = mJumpPrevArrowBtn->handleMouseUp(local_x, local_y, mask);
}
else if (mJumpNextArrowBtn && mJumpNextArrowBtn->getRect().pointInRect(x, y))
{
S32 local_x = x - mJumpNextArrowBtn->getRect().mLeft;
S32 local_y = y - mJumpNextArrowBtn->getRect().mBottom;
local_x = x - mJumpNextArrowBtn->getRect().mLeft;
local_y = y - mJumpNextArrowBtn->getRect().mBottom;
handled = mJumpNextArrowBtn->handleMouseUp(local_x, local_y, mask);
}
else if (mPrevArrowBtn && mPrevArrowBtn->getRect().pointInRect(x, y))
{
S32 local_x = x - mPrevArrowBtn->getRect().mLeft;
S32 local_y = y - mPrevArrowBtn->getRect().mBottom;
local_x = x - mPrevArrowBtn->getRect().mLeft;
local_y = y - mPrevArrowBtn->getRect().mBottom;
handled = mPrevArrowBtn->handleMouseUp(local_x, local_y, mask);
}
else if (mNextArrowBtn && mNextArrowBtn->getRect().pointInRect(x, y))
{
S32 local_x = x - mNextArrowBtn->getRect().mLeft;
S32 local_y = y - mNextArrowBtn->getRect().mBottom;
local_x = x - mNextArrowBtn->getRect().mLeft;
local_y = y - mNextArrowBtn->getRect().mBottom;
handled = mNextArrowBtn->handleMouseUp(local_x, local_y, mask);
}
}
@ -730,6 +738,10 @@ BOOL LLTabContainer::handleMouseUp( S32 x, S32 y, MASK mask )
}
gFocusMgr.setMouseCapture(NULL);
}
if (handled) {
// Note: may need to capture local coords here
LLViewerEventRecorder::instance().update_xui(getPathname( ));
}
return handled;
}
@ -1160,21 +1172,21 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel)
if (mIsVertical)
{
p.name(std::string("vert tab button"));
p.image_unselected(mMiddleTabParams.tab_left_image_unselected);
p.image_selected(mMiddleTabParams.tab_left_image_selected);
p.follows.flags = p.follows.flags() | FOLLOWS_TOP;
p.name("vtab_"+std::string(child->getName()));
p.image_unselected(mMiddleTabParams.tab_left_image_unselected);
p.image_selected(mMiddleTabParams.tab_left_image_selected);
p.follows.flags = p.follows.flags() | FOLLOWS_TOP;
}
else
{
p.name(std::string(child->getName()) + " tab");
p.visible(false);
p.image_unselected(tab_img);
p.image_selected(tab_selected_img);
p.follows.flags = p.follows.flags() | (getTabPosition() == TOP ? FOLLOWS_TOP : FOLLOWS_BOTTOM);
// Try to squeeze in a bit more text
p.pad_left( mLabelPadLeft );
p.pad_right(2);
{
p.name("htab_"+std::string(child->getName()));
p.visible(false);
p.image_unselected(tab_img);
p.image_selected(tab_selected_img);
p.follows.flags = p.follows.flags() | (getTabPosition() == TOP ? FOLLOWS_TOP : FOLLOWS_BOTTOM);
// Try to squeeze in a bit more text
p.pad_left( mLabelPadLeft );
p.pad_right(2);
}
// <FS:Ansariel> Enable tab flashing

View File

@ -29,7 +29,7 @@
#define LLUICTRL_CPP
#include "lluictrl.h"
#include "llviewereventrecorder.h"
#include "llfocusmgr.h"
#include "llpanel.h"
#include "lluictrlfactory.h"
@ -316,22 +316,40 @@ void LLUICtrl::onMouseLeave(S32 x, S32 y, MASK mask)
//virtual
BOOL LLUICtrl::handleMouseDown(S32 x, S32 y, MASK mask)
{
lldebugs << "LLUICtrl::handleMouseDown calling LLView)'s handleMouseUp (first initialized xui to: " << getPathname() << " )" << llendl;
BOOL handled = LLView::handleMouseDown(x,y,mask);
if (mMouseDownSignal)
{
(*mMouseDownSignal)(this,x,y,mask);
}
lldebugs << "LLUICtrl::handleMousedown - handled is returning as: " << handled << " " << llendl;
if (handled) {
LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-56,-56,getPathname());
}
return handled;
}
//virtual
BOOL LLUICtrl::handleMouseUp(S32 x, S32 y, MASK mask)
{
lldebugs << "LLUICtrl::handleMouseUp calling LLView)'s handleMouseUp (first initialized xui to: " << getPathname() << " )" << llendl;
BOOL handled = LLView::handleMouseUp(x,y,mask);
if (handled) {
LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-56,-56,getPathname());
}
if (mMouseUpSignal)
{
(*mMouseUpSignal)(this,x,y,mask);
}
lldebugs << "LLUICtrl::handleMouseUp - handled for xui " << getPathname() << " - is returning as: " << handled << " " << llendl;
return handled;
}

View File

@ -48,7 +48,9 @@
#include "lluictrlfactory.h"
#include "lltooltip.h"
#include "llsdutil.h"
#include "llsdserialize.h"
#include "llviewereventrecorder.h"
#include "llkeyboard.h"
// for ui edit hack
#include "llbutton.h"
#include "lllineeditor.h"
@ -697,13 +699,27 @@ void LLView::setVisible(BOOL visible)
// virtual
void LLView::handleVisibilityChange ( BOOL new_visibility )
{
BOOL old_visibility;
BOOST_FOREACH(LLView* viewp, mChildList)
{
// only views that are themselves visible will have their overall visibility affected by their ancestors
if (viewp->getVisible())
old_visibility=viewp->getVisible();
if (old_visibility!=new_visibility)
{
LLViewerEventRecorder::instance().logVisibilityChange( viewp->getPathname(), viewp->getName(), new_visibility,"widget");
}
if (old_visibility)
{
viewp->handleVisibilityChange ( new_visibility );
}
// Consider changing returns to confirm success and know which widget grabbed it
// For now assume success and log at highest xui possible
// NOTE we log actual state - which may differ if it somehow failed to set visibility
lldebugs << "LLView::handleVisibilityChange - now: " << getVisible() << " xui: " << viewp->getPathname() << " name: " << viewp->getName() << llendl;
}
}
@ -752,6 +768,7 @@ bool LLView::visibleEnabledAndContains(S32 local_x, S32 local_y)
&& getEnabled();
}
// This is NOT event recording related
void LLView::logMouseEvent()
{
if (sDebugMouseHandling)
@ -798,7 +815,14 @@ LLView* LLView::childrenHandleMouseEvent(const METHOD& method, S32 x, S32 y, XDA
if ((viewp->*method)( local_x, local_y, extra )
|| (allow_mouse_block && viewp->blockMouseEvent( local_x, local_y )))
{
lldebugs << "LLView::childrenHandleMouseEvent calling updatemouseeventinfo - local_x|global x "<< local_x << " " << x << "local/global y " << local_y << " " << y << llendl;
lldebugs << "LLView::childrenHandleMouseEvent getPathname for viewp result: " << viewp->getPathname() << "for this view: " << getPathname() << llendl;
LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname());
// This is NOT event recording related
viewp->logMouseEvent();
return viewp;
}
}
@ -821,6 +845,7 @@ LLView* LLView::childrenHandleToolTip(S32 x, S32 y, MASK mask)
if (viewp->handleToolTip(local_x, local_y, mask)
|| viewp->blockMouseEvent(local_x, local_y))
{
// This is NOT event recording related
viewp->logMouseEvent();
return viewp;
}
@ -879,6 +904,7 @@ LLView* LLView::childrenHandleHover(S32 x, S32 y, MASK mask)
if (viewp->handleHover(local_x, local_y, mask)
|| viewp->blockMouseEvent(local_x, local_y))
{
// This is NOT event recording related
viewp->logMouseEvent();
return viewp;
}
@ -968,10 +994,12 @@ BOOL LLView::handleKey(KEY key, MASK mask, BOOL called_from_parent)
if (!handled)
{
// For event logging we don't care which widget handles it
// So we capture the key at the end of this function once we know if it was handled
handled = handleKeyHere( key, mask );
if (handled && LLView::sDebugKeys)
if (handled)
{
llinfos << "Key handled by " << getName() << llendl;
llwarns << "Key handled by " << getName() << llendl;
}
}
}
@ -1019,6 +1047,11 @@ BOOL LLView::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent)
handled = mParentView->handleUnicodeChar(uni_char, FALSE);
}
if (handled)
{
LLViewerEventRecorder::instance().logKeyUnicodeEvent(uni_char);
}
return handled;
}
@ -1048,12 +1081,16 @@ BOOL LLView::hasMouseCapture()
BOOL LLView::handleMouseUp(S32 x, S32 y, MASK mask)
{
return childrenHandleMouseUp( x, y, mask ) != NULL;
LLView* r = childrenHandleMouseUp( x, y, mask );
return (r!=NULL);
}
BOOL LLView::handleMouseDown(S32 x, S32 y, MASK mask)
{
return childrenHandleMouseDown( x, y, mask ) != NULL;
LLView* r= childrenHandleMouseDown(x, y, mask );
return (r!=NULL);
}
BOOL LLView::handleDoubleClick(S32 x, S32 y, MASK mask)
@ -1126,7 +1163,7 @@ LLView* LLView::childrenHandleDoubleClick(S32 x, S32 y, MASK mask)
LLView* LLView::childrenHandleMouseUp(S32 x, S32 y, MASK mask)
{
return childrenHandleMouseEvent(&LLView::handleMouseUp, x, y, mask);
return childrenHandleMouseEvent(&LLView::handleMouseUp, x, y, mask);
}
LLView* LLView::childrenHandleRightMouseUp(S32 x, S32 y, MASK mask)

View File

@ -0,0 +1,296 @@
/**
* @file llviewereventrecorder.cpp
* @brief Viewer event recording and playback support for mouse and keyboard events
*
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
*
* Copyright (c) 2013, 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 "llviewereventrecorder.h"
#include "llui.h"
#include "llleap.h"
LLViewerEventRecorder::LLViewerEventRecorder() {
clear(UNDEFINED);
// Remove any previous event log file
std::string old_log_ui_events_to_llsd_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife_Events_log.old");
LLFile::remove(old_log_ui_events_to_llsd_file);
mLogFilename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife_Events_log.llsd");
LLFile::rename(mLogFilename, old_log_ui_events_to_llsd_file);
}
bool LLViewerEventRecorder::displayViewerEventRecorderMenuItems() {
return LLUI::sSettingGroups["config"]->getBOOL("ShowEventRecorderMenuItems");
}
void LLViewerEventRecorder::setEventLoggingOn() {
if (! mLog.is_open()) {
mLog.open(mLogFilename, llofstream::out);
}
logEvents=true;
lldebugs << "LLViewerEventRecorder::setEventLoggingOn event logging turned on" << llendl;
}
void LLViewerEventRecorder::setEventLoggingOff() {
logEvents=false;
mLog.flush();
mLog.close();
lldebugs << "LLViewerEventRecorder::setEventLoggingOff event logging turned off" << llendl;
}
LLViewerEventRecorder::~LLViewerEventRecorder() {
if (mLog.is_open()) {
mLog.close();
}
}
void LLViewerEventRecorder::clear_xui() {
xui.clear();
}
void LLViewerEventRecorder::clear(S32 r) {
xui.clear();
local_x=r;
local_y=r;
global_x=r;
global_y=r;
}
void LLViewerEventRecorder::setMouseLocalCoords(S32 x, S32 y) {
local_x=x;
local_y=y;
}
void LLViewerEventRecorder::setMouseGlobalCoords(S32 x, S32 y) {
global_x=x;
global_y=y;
}
void LLViewerEventRecorder::updateMouseEventInfo(S32 local_x, S32 local_y, S32 global_x, S32 global_y, std::string mName) {
LLView * target_view = LLUI::resolvePath(LLUI::getRootView(), xui);
if (! target_view) {
lldebugs << "LLViewerEventRecorder::updateMouseEventInfo - xui path on file at moment is NOT valid - so DO NOT record these local coords" << llendl;
return;
}
lldebugs << "LLViewerEventRecorder::updateMouseEventInfo b4 updatemouseeventinfo - local_x|global x "<< this->local_x << " " << this->global_x << "local/global y " << this->local_y << " " << this->global_y << " mname: " << mName << " xui: " << xui << llendl;
if (this->local_x < 1 && this->local_y<1 && local_x && local_y) {
this->local_x=local_x;
this->local_y=local_y;
}
this->global_x=global_x;
this->global_y=global_y;
// ONLY record deepest xui path for hierarchy searches - or first/only xui for floaters/panels reached via mouse captor - and llmousehandler
if (mName!="" && mName!="/" && xui=="") {
// xui=std::string("/")+mName+xui;
//xui=mName+xui;
xui = mName; // TODO review confirm we never call with partial path - also cAN REMOVE CHECK FOR "" - ON OTHER HAND IT'S PRETTY HARMLESS
}
lldebugs << "LLViewerEventRecorder::updateMouseEventInfo after updatemouseeventinfo - local_x|global x "<< this->local_x << " " << this->global_x << "local/global y " << this->local_y << " " << this->global_y << " mname: " << mName << " xui: " << xui << llendl;
}
void LLViewerEventRecorder::logVisibilityChange(std::string xui, std::string name, BOOL visibility, std::string event_subtype) {
LLSD event=LLSD::emptyMap();
event.insert("event",LLSD(std::string("visibility")));
if (visibility) {
event.insert("visibility",LLSD(true));
} else {
event.insert("visibility",LLSD(false));
}
if (event_subtype!="") {
event.insert("event_subtype", LLSD(event_subtype));
}
if(name!="") {
event.insert("name",LLSD(name));
}
if (xui!="") {
event.insert("path",LLSD(xui));
}
event.insert("timestamp",LLSD(LLDate::now().asString()));
recordEvent(event);
}
std::string LLViewerEventRecorder::get_xui() {
return xui;
}
void LLViewerEventRecorder::update_xui(std::string xui) {
if (xui!="" && this->xui=="" ) {
lldebugs << "LLViewerEventRecorder::update_xui to " << xui << llendl;
this->xui=xui;
} else {
lldebugs << "LLViewerEventRecorder::update_xui called with empty string" << llendl;
}
}
void LLViewerEventRecorder::logKeyEvent(KEY key, MASK mask) {
// NOTE: Event recording only logs keydown events - the viewer itself hides keyup events at a fairly low level in the code and does not appear to care about them anywhere
LLSD event = LLSD::emptyMap();
event.insert("event",LLSD("type"));
// keysym ...or
// keycode...or
// char
event.insert("keysym",LLSD(LLKeyboard::stringFromKey(key)));
// path (optional) - for now we are not recording path for key events during record - should not be needed for full record and playback of recorded steps
// as a vita script - it does become useful if you edit the resulting vita script and wish to remove some steps leading to a key event - that sort of edit might
// break the test script and it would be useful to have more context to make these sorts of edits safer
// TODO replace this with a call which extracts to an array of names of masks (just like vita expects during playback)
// This is looking more and more like an object is a good idea, for this part a handy method call to setMask(mask) would be nice :-)
// call the func - llkeyboard::llsdStringarrayFromMask
LLSD key_mask=LLSD::emptyArray();
if (mask & MASK_CONTROL) { key_mask.append(LLSD("CTL")); } // Mac command key - has code of 0x1 in llcommon/indra_contstants
if (mask & MASK_ALT) { key_mask.append(LLSD("ALT")); }
if (mask & MASK_SHIFT) { key_mask.append(LLSD("SHIFT")); }
if (mask & MASK_MAC_CONTROL) { key_mask.append(LLSD("MAC_CONTROL")); }
event.insert("mask",key_mask);
event.insert("timestamp",LLSD(LLDate::now().asString()));
// Although vita has keyDown and keyUp requests it does not have type as a high-level concept
// (maybe it should) - instead it has a convenience method that generates the keydown and keyup events
// Here we will use "type" as our event type
lldebugs << "LLVIewerEventRecorder::logKeyEvent Serialized LLSD for event " << event.asString() << "\n" << llendl;
//lldebugs << "[VITA] key_name: " << LLKeyboard::stringFromKey(key) << "mask: "<< mask << "handled by " << getName() << llendl;
lldebugs << "LLVIewerEventRecorder::logKeyEvent key_name: " << LLKeyboard::stringFromKey(key) << "mask: "<< mask << llendl;
recordEvent(event);
}
void LLViewerEventRecorder::playbackRecording() {
LLSD LeapCommand;
// ivita sets this on startup, it also sends commands to the viewer to make start, stop, and playback menu items visible in viewer
LeapCommand =LLUI::sSettingGroups["config"]->getLLSD("LeapPlaybackEventsCommand");
lldebugs << "[VITA] launching playback - leap command is: " << LLSDXMLStreamer(LeapCommand) << llendl;
LLLeap::create("", LeapCommand, false); // exception=false
}
void LLViewerEventRecorder::recordEvent(LLSD event) {
lldebugs << "LLViewerEventRecorder::recordEvent event written to log: " << LLSDXMLStreamer(event) << llendl;
mLog << event << std::endl;
}
void LLViewerEventRecorder::logKeyUnicodeEvent(llwchar uni_char) {
if (! logEvents) return;
// Note: keyUp is not captured since the viewer seems to not care about keyUp events
LLSD event=LLSD::emptyMap();
event.insert("timestamp",LLSD(LLDate::now().asString()));
// keysym ...or
// keycode...or
// char
lldebugs << "Wrapped in conversion to wstring " << wstring_to_utf8str(LLWString( 1, uni_char)) << "\n" << llendl;
event.insert("char",
LLSD( wstring_to_utf8str(LLWString( 1,uni_char)) )
);
// path (optional) - for now we are not recording path for key events during record - should not be needed for full record and playback of recorded steps
// as a vita script - it does become useful if you edit the resulting vita script and wish to remove some steps leading to a key event - that sort of edit might
// break the test script and it would be useful to have more context to make these sorts of edits safer
// TODO need to consider mask keys too? Doesn't seem possible - at least not easily at this point
event.insert("event",LLSD("keyDown"));
lldebugs << "[VITA] unicode key: " << uni_char << llendl;
lldebugs << "[VITA] dumpxml " << LLSDXMLStreamer(event) << "\n" << llendl;
recordEvent(event);
}
void LLViewerEventRecorder::logMouseEvent(std::string button_state,std::string button_name)
{
if (! logEvents) return;
LLSD event=LLSD::emptyMap();
event.insert("event",LLSD(std::string("mouse"+ button_state)));
event.insert("button",LLSD(button_name));
if (xui!="") {
event.insert("path",LLSD(xui));
}
if (local_x>0 && local_y>0) {
event.insert("local_x",LLSD(local_x));
event.insert("local_y",LLSD(local_y));
}
if (global_x>0 && global_y>0) {
event.insert("global_x",LLSD(global_x));
event.insert("global_y",LLSD(global_y));
}
event.insert("timestamp",LLSD(LLDate::now().asString()));
recordEvent(event);
clear(UNDEFINED);
}

View File

@ -0,0 +1,103 @@
/**
* @file llviewereventrecorder.h
* @brief Viewer event recording and playback support for mouse and keyboard events
*
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
*
* Copyright (c) 2013, 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_VIEWER_EVENT_RECORDER
#define LL_VIEWER_EVENT_RECORDER
#include "linden_common.h"
#include "lldir.h"
#include "llsd.h"
#include "llfile.h"
#include "llvfile.h"
#include "lldate.h"
#include "llsdserialize.h"
#include "llkeyboard.h"
#include "llstring.h"
#include <sstream>
#include "llsingleton.h" // includes llerror which we need here so we can skip the include here
class LLViewerEventRecorder : public LLSingleton<LLViewerEventRecorder>
{
public:
LLViewerEventRecorder(); // TODO Protect constructor better if we can (not happy in private section) - could add a factory... - we are singleton
~LLViewerEventRecorder();
void updateMouseEventInfo(S32 local_x,S32 local_y, S32 global_x, S32 global_y, std::string mName);
void setMouseLocalCoords(S32 x,S32 y);
void setMouseGlobalCoords(S32 x,S32 y);
void logMouseEvent(std::string button_state, std::string button_name );
void logKeyEvent(KEY key, MASK mask);
void logKeyUnicodeEvent(llwchar uni_char);
void logVisibilityChange(std::string xui, std::string name, BOOL visibility, std::string event_subtype);
void clear_xui();
std::string get_xui();
void update_xui(std::string xui);
bool getLoggingStatus();
void setEventLoggingOn();
void setEventLoggingOff();
void playbackRecording();
bool displayViewerEventRecorderMenuItems();
protected:
// On if we wish to log events at the moment - toggle via Develop/Recorder submenu
bool logEvents;
std::string mLogFilename;
llofstream mLog;
private:
// Mouse event info
S32 global_x;
S32 global_y;
S32 local_x;
S32 local_y;
// XUI path of UI element
std::string xui;
// Actually write the event out to llsd log file
void recordEvent(LLSD event);
void clear(S32 r);
static const S32 UNDEFINED=-1;
};
#endif

View File

@ -1308,6 +1308,8 @@ void LLWindowMacOSX::setupFailure(const std::string& text, const std::string& ca
OSMessageBox(text, caption, type);
}
// Note on event recording - QUIT is a known special case and we are choosing NOT to record it for the record and playback feature
// it is handled at a very low-level
const char* cursorIDToName(int id)
{
BOOL use_legacy_cursors = gSavedSettings.getBOOL("UseLegacyCursors");

View File

@ -477,7 +477,7 @@ LLControlVariable* LLControlGroup::declareControl(const std::string& name, eCont
}
else
{
llwarns << "Control named " << name << " already exists, ignoring new declaration." << llendl;
LL_WARNS("Settings") << "Control named " << name << " already exists, ignoring new declaration." << LL_ENDL;
}
return existing_control;
}
@ -719,14 +719,14 @@ U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, BOOL require
if (!xml_controls.parseFile(filename))
{
llwarns << "Unable to open control file " << filename << llendl;
LL_WARNS("Settings") << "Unable to open control file " << filename << LL_ENDL;
return 0;
}
LLXmlTreeNode* rootp = xml_controls.getRoot();
if (!rootp || !rootp->hasAttribute("version"))
{
llwarns << "No valid settings header found in control file " << filename << llendl;
LL_WARNS("Settings") << "No valid settings header found in control file " << filename << LL_ENDL;
return 0;
}
@ -739,7 +739,7 @@ U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, BOOL require
// Check file version
if (version != CURRENT_VERSION)
{
llinfos << filename << " does not appear to be a version " << CURRENT_VERSION << " controls file" << llendl;
LL_INFOS("Settings") << filename << " does not appear to be a version " << CURRENT_VERSION << " controls file" << LL_ENDL;
return 0;
}
@ -757,7 +757,7 @@ U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, BOOL require
if (!name.empty())
{
//read in to end of line
llwarns << "LLControlGroup::loadFromFile() : Trying to set \"" << name << "\", setting doesn't exist." << llendl;
LL_WARNS("Settings") << "LLControlGroup::loadFromFile() : Trying to set \"" << name << "\", setting doesn't exist." << LL_ENDL;
}
child_nodep = rootp->getNextChild();
continue;
@ -911,7 +911,7 @@ U32 LLControlGroup::saveToFile(const std::string& filename, BOOL nondefault_only
LLControlVariable* control = iter->second;
if (!control)
{
llwarns << "Tried to save invalid control: " << iter->first << llendl;
LL_WARNS("Settings") << "Tried to save invalid control: " << iter->first << LL_ENDL;
}
else if( control->shouldSave(nondefault_only) )
{
@ -928,12 +928,12 @@ U32 LLControlGroup::saveToFile(const std::string& filename, BOOL nondefault_only
{
LLSDSerialize::toPrettyXML(settings, file);
file.close();
llinfos << "Saved to " << filename << llendl;
LL_INFOS("Settings") << "Saved to " << filename << LL_ENDL;
}
else
{
// This is a warning because sometime we want to use settings files which can't be written...
llwarns << "Unable to open settings file: " << filename << llendl;
LL_WARNS("Settings") << "Unable to open settings file: " << filename << LL_ENDL;
return 0;
}
return num_saved;
@ -946,14 +946,14 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v
infile.open(filename);
if(!infile.is_open())
{
llwarns << "Cannot find file " << filename << " to load." << llendl;
LL_WARNS("Settings") << "Cannot find file " << filename << " to load." << LL_ENDL;
return 0;
}
if (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXML(settings, infile))
{
infile.close();
llwarns << "Unable to parse LLSD control file " << filename << ". Trying Legacy Method." << llendl;
LL_WARNS("Settings") << "Unable to parse LLSD control file " << filename << ". Trying Legacy Method." << LL_ENDL;
return loadFromFileLegacy(filename, TRUE, TYPE_STRING);
}
@ -1079,6 +1079,7 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v
++validitems;
}
LL_DEBUGS("Settings") << "Loaded " << validitems << " settings from " << filename << LL_ENDL;
return validitems;
}
@ -1115,7 +1116,7 @@ void main()
BOOL_CONTROL baz;
U32 count = gGlobals.loadFromFile("controls.ini");
llinfos << "Loaded " << count << " controls" << llendl;
LL_INFOS("Settings") << "Loaded " << count << " controls" << LL_ENDL;
// test insertion
foo = new LLControlVariable<F32>("gFoo", 5.f, 1.f, 20.f);
@ -1376,19 +1377,19 @@ LLColor4 convert_from_llsd<LLColor4>(const LLSD& sd, eControlType type, const st
LLColor4 color(sd);
if (color.mV[VRED] < 0.f || color.mV[VRED] > 1.f)
{
llwarns << "Color " << control_name << " red value out of range: " << color << llendl;
LL_WARNS("Settings") << "Color " << control_name << " red value out of range: " << color << LL_ENDL;
}
else if (color.mV[VGREEN] < 0.f || color.mV[VGREEN] > 1.f)
{
llwarns << "Color " << control_name << " green value out of range: " << color << llendl;
LL_WARNS("Settings") << "Color " << control_name << " green value out of range: " << color << LL_ENDL;
}
else if (color.mV[VBLUE] < 0.f || color.mV[VBLUE] > 1.f)
{
llwarns << "Color " << control_name << " blue value out of range: " << color << llendl;
LL_WARNS("Settings") << "Color " << control_name << " blue value out of range: " << color << LL_ENDL;
}
else if (color.mV[VALPHA] < 0.f || color.mV[VALPHA] > 1.f)
{
llwarns << "Color " << control_name << " alpha value out of range: " << color << llendl;
LL_WARNS("Settings") << "Color " << control_name << " alpha value out of range: " << color << LL_ENDL;
}
return LLColor4(sd);

View File

@ -6947,6 +6947,16 @@
<key>Value</key>
<array />
</map>
<key>LeapPlaybackEventsCommand</key>
<map>
<key>Comment</key>
<string>Command line to use leap to launch playback of event recordings</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>LLSD</string>
<key>Value</key>
</map>
<key>LSLFindCaseInsensitivity</key>
<map>
<key>Comment</key>
@ -12998,6 +13008,17 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>ShowEventRecorderMenuItems</key>
<map>
<key>Comment</key>
<string>Whether or not Event Recorder menu choices - Start / Stop event recording should appear in the (currently) Develop menu</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>ShowHoverTips</key>

View File

@ -241,6 +241,10 @@
#include "llmachineid.h"
#include "llmainlooprepeater.h"
#include "llviewereventrecorder.h"
// *FIX: These extern globals should be cleaned up.
// The globals either represent state/config/resource-storage of either
// this app, or another 'component' of the viewer. App globals should be
@ -768,6 +772,7 @@ LLAppViewer::LLAppViewer() :
LLAppViewer::~LLAppViewer()
{
delete mSettingsLocationList;
LLViewerEventRecorder::instance().~LLViewerEventRecorder();
LLLoginInstance::instance().setUpdaterService(0);
@ -2565,13 +2570,13 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
}
// </FS:Ansariel>
llinfos << "Attempting to load settings for the group " << file.name()
<< " - from location " << location_key << llendl;
LL_INFOS("Settings") << "Attempting to load settings for the group " << file.name()
<< " - from location " << location_key << LL_ENDL;
LLControlGroup* settings_group = LLControlGroup::getInstance(file.name);
if(!settings_group)
{
llwarns << "No matching settings group for name " << file.name() << llendl;
LL_WARNS("Settings") << "No matching settings group for name " << file.name() << LL_ENDL;
continue;
}
@ -2600,7 +2605,7 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
if(settings_group->loadFromFile(full_settings_path, set_defaults, file.persistent))
{ // success!
llinfos << "Loaded settings file " << full_settings_path << llendl;
LL_INFOS("Settings") << "Loaded settings file " << full_settings_path << LL_ENDL;
}
else
{ // failed to load
@ -2614,7 +2619,7 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
// only complain if we actually have a filename at this point
if (!full_settings_path.empty())
{
llinfos << "Cannot load " << full_settings_path << " - No settings found." << llendl;
LL_INFOS("Settings") << "Cannot load " << full_settings_path << " - No settings found." << LL_ENDL;
}
}
}
@ -2780,8 +2785,8 @@ bool LLAppViewer::initConfiguration()
LLFile::remove(user_settings_filename);
}
llinfos << "Using command line specified settings filename: "
<< user_settings_filename << llendl;
LL_INFOS("Settings") << "Using command line specified settings filename: "
<< user_settings_filename << LL_ENDL;
}
else
{
@ -2839,8 +2844,8 @@ bool LLAppViewer::initConfiguration()
{
std::string session_settings_filename = clp.getOption("sessionsettings")[0];
gSavedSettings.setString("SessionSettingsFile", session_settings_filename);
llinfos << "Using session settings filename: "
<< session_settings_filename << llendl;
LL_INFOS("Settings") << "Using session settings filename: "
<< session_settings_filename << LL_ENDL;
}
loadSettingsFromDirectory("Session",true); // AO The session file turns into the new defaults
@ -2848,10 +2853,10 @@ bool LLAppViewer::initConfiguration()
{
std::string user_session_settings_filename = clp.getOption("usersessionsettings")[0];
gSavedSettings.setString("UserSessionSettingsFile", user_session_settings_filename);
llinfos << "Using user session settings filename: " << user_session_settings_filename << llendl;
}
LL_INFOS("Settings") << "Using user session settings filename: "
<< user_session_settings_filename << LL_ENDL;
}
loadSettingsFromDirectory("UserSession");
//AO: Re-read user settings again. This is a Firestorm hack to get user settings to override modes
@ -2942,6 +2947,10 @@ bool LLAppViewer::initConfiguration()
}
}
if (clp.hasOption("logevents")) {
LLViewerEventRecorder::instance().setEventLoggingOn();
}
std::string CmdLineChannel(gSavedSettings.getString("CmdLineChannel"));
if(! CmdLineChannel.empty())
{

View File

@ -175,21 +175,20 @@ void ll_nvapi_init(NvDRSSessionHandle hSession)
nvapi_error(status);
return;
}
// (5) Now we apply (or save) our changes to the system
status = NvAPI_DRS_SaveSettings(hSession);
if (status != NVAPI_OK)
{
nvapi_error(status);
return;
}
}
else if (status != NVAPI_OK)
{
nvapi_error(status);
return;
}
// (5) Now we apply (or save) our changes to the system
status = NvAPI_DRS_SaveSettings(hSession);
if (status != NVAPI_OK)
{
nvapi_error(status);
}
}
//#define DEBUGGING_SEH_FILTER 1

View File

@ -73,6 +73,8 @@
#include "llcallingcard.h"
#include "llslurl.h" // IDEVO
#include "llsidepanelinventory.h"
#include "llavatarname.h"
#include "llagentui.h"
// Firestorm includes
#include "fsfloaterim.h"
@ -508,6 +510,72 @@ void LLAvatarActions::pay(const LLUUID& id)
}
}
void LLAvatarActions::teleport_request_callback(const LLSD& notification, const LLSD& response)
{
S32 option;
if (response.isInteger())
{
option = response.asInteger();
}
else
{
option = LLNotificationsUtil::getSelectedOption(notification, response);
}
if (0 == option)
{
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_ImprovedInstantMessage);
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
msg->nextBlockFast(_PREHASH_MessageBlock);
msg->addBOOLFast(_PREHASH_FromGroup, FALSE);
msg->addUUIDFast(_PREHASH_ToAgentID, notification["substitutions"]["uuid"] );
msg->addU8Fast(_PREHASH_Offline, IM_ONLINE);
msg->addU8Fast(_PREHASH_Dialog, IM_TELEPORT_REQUEST);
msg->addUUIDFast(_PREHASH_ID, LLUUID::null);
msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary
std::string name;
LLAgentUI::buildFullname(name);
msg->addStringFast(_PREHASH_FromAgentName, name);
msg->addStringFast(_PREHASH_Message, response["message"]);
msg->addU32Fast(_PREHASH_ParentEstateID, 0);
msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null);
msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent());
gMessageSystem->addBinaryDataFast(
_PREHASH_BinaryBucket,
EMPTY_BINARY_BUCKET,
EMPTY_BINARY_BUCKET_SIZE);
gAgent.sendReliableMessage();
}
}
// static
void LLAvatarActions::teleportRequest(const LLUUID& id)
{
LLSD notification;
notification["uuid"] = id;
LLAvatarName av_name;
if (!LLAvatarNameCache::get(id, &av_name))
{
// unlikely ... they just picked this name from somewhere...
LLAvatarNameCache::get(id, boost::bind(&LLAvatarActions::teleportRequest, id));
return; // reinvoke this when the name resolves
}
notification["NAME"] = av_name.getCompleteName();
LLSD payload;
LLNotificationsUtil::add("TeleportRequestPrompt", notification, payload, teleport_request_callback);
}
// static
void LLAvatarActions::kick(const LLUUID& id)
{

View File

@ -114,6 +114,12 @@ public:
*/
static void pay(const LLUUID& id);
/**
* Request teleport from other avatar
*/
static void teleportRequest(const LLUUID& id);
static void teleport_request_callback(const LLSD& notification, const LLSD& response);
/**
* Share items with the avatar.
*/

View File

@ -341,25 +341,25 @@ void LLNotificationChiclet::setCounter(S32 counter)
bool LLNotificationChiclet::ChicletNotificationChannel::filterNotification( LLNotificationPtr notification )
{
bool display_notification;
bool displayNotification;
if ( (notification->getName() == "ScriptDialog") // special case for scripts
// if there is no toast window for the notification, filter it
|| (!LLNotificationWellWindow::getInstance()->findItemByID(notification->getID()))
)
{
display_notification = false;
displayNotification = false;
}
else if( !(notification->canLogToIM() && notification->hasFormElements())
&& (!notification->getPayload().has("give_inventory_notification")
|| notification->getPayload()["give_inventory_notification"]))
{
display_notification = true;
displayNotification = true;
}
else
{
display_notification = false;
displayNotification = false;
}
return display_notification;
return displayNotification;
}
//////////////////////////////////////////////////////////////////////////

View File

@ -316,6 +316,10 @@ void LLConversationLogList::onCustomAction(const LLSD& userdata)
{
LLAvatarActions::offerTeleport(selected_conversation_participant_id);
}
else if ("request_teleport" == command_name)
{
LLAvatarActions::teleportRequest(selected_conversation_participant_id);
}
else if("add_friend" == command_name)
{
if (!LLAvatarActions::isFriend(selected_conversation_participant_id))

View File

@ -134,6 +134,7 @@ void LLConversationItem::buildParticipantMenuOptions(menuentry_vec_t& items, U32
items.push_back(std::string("view_profile"));
items.push_back(std::string("im"));
items.push_back(std::string("offer_teleport"));
items.push_back(std::string("request_teleport"));
items.push_back(std::string("voice_call"));
items.push_back(std::string("chat_history"));
items.push_back(std::string("separator_chat_history"));

View File

@ -1081,6 +1081,10 @@ void LLFloaterIMContainer::doToParticipants(const std::string& command, uuid_vec
{
LLAvatarActions::offerTeleport(selectedIDS);
}
else if ("request_teleport" == command)
{
LLAvatarActions::teleportRequest(selectedIDS.front());
}
else if ("voice_call" == command)
{
LLAvatarActions::startCall(userID);

View File

@ -2257,7 +2257,6 @@ S32 LLPanelLandOptions::getDirectoryFee()
// virtual
void LLPanelLandOptions::draw()
{
refreshSearch(); // Is this necessary? JC
LLPanel::draw();
}
@ -2271,13 +2270,8 @@ void LLPanelLandOptions::refreshSearch()
mCheckShowDirectory->set(FALSE);
mCheckShowDirectory->setEnabled(FALSE);
// *TODO:Translate
// <FS:Ansariel> FIRE-7773: Parcel categories don't stay selected
//const std::string& none_string = LLParcel::getCategoryUIString(LLParcel::C_NONE);
//mCategoryCombo->setSimple(none_string);
const std::string& none_string = LLParcel::getCategoryString(LLParcel::C_NONE);
mCategoryCombo->setValue(none_string);
// </FS:Ansariel>
mCategoryCombo->setEnabled(FALSE);
return;
}
@ -2304,14 +2298,9 @@ void LLPanelLandOptions::refreshSearch()
mCheckShowDirectory ->set(show_directory);
// Set by string in case the order in UI doesn't match the order by index.
// *TODO:Translate
LLParcel::ECategory cat = parcel->getCategory();
// <FS:Ansariel> FIRE-7773: Parcel categories don't stay selected
//const std::string& category_string = LLParcel::getCategoryUIString(cat);
//mCategoryCombo->setSimple(category_string);
const std::string& category_string = LLParcel::getCategoryString(cat);
mCategoryCombo->setValue(category_string);
// </FS:Ansariel>
std::string tooltip;
bool enable_show_directory = false;

View File

@ -837,6 +837,9 @@ void LLFloaterPreference::cancel()
// hide autoreplace settings floater
LLFloaterReg::hideInstance("prefs_autoreplace");
// hide spellchecker settings folder
LLFloaterReg::hideInstance("prefs_spellchecker");
// <FS:CR> STORM-1888
// hide spellchecker settings floater
LLFloaterReg::hideInstance("prefs_spellchecker");

View File

@ -1912,10 +1912,7 @@ void LLPanelEstateInfo::accessAddCore3(const uuid_vec_t& ids, void* data)
LLSD args;
args["NUM_ADDED"] = llformat("%d",ids.size());
args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
// <FS:Ansariel> Fixed unlocalizable strings
//args["LIST_TYPE"] = "Allowed Residents";
args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeAllowedAgents");
// </FS:Ansariel>
args["NUM_EXCESS"] = llformat("%d",(ids.size()+currentCount)-ESTATE_MAX_ACCESS_IDS);
LLNotificationsUtil::add("MaxAgentOnRegionBatch", args);
delete change_info;
@ -1931,10 +1928,7 @@ void LLPanelEstateInfo::accessAddCore3(const uuid_vec_t& ids, void* data)
LLSD args;
args["NUM_ADDED"] = llformat("%d",ids.size());
args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
// <FS:Ansariel> Fixed unlocalizable strings
//args["LIST_TYPE"] = "Banned Residents";
args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeBannedAgents");
// </FS:Ansariel>
args["NUM_EXCESS"] = llformat("%d",(ids.size()+currentCount)-ESTATE_MAX_ACCESS_IDS);
LLNotificationsUtil::add("MaxAgentOnRegionBatch", args);
delete change_info;
@ -2999,15 +2993,10 @@ bool LLDispatchSetEstateAccess::operator()(
}
// <FS:Ansariel> FIRE-5998: Unlocalizable label
//std::string msg = llformat("Banned residents: (%d, max %d)",
// totalBannedAgents,
// ESTATE_MAX_ACCESS_IDS);
LLStringUtil::format_map_t args;
args["[BANNEDAGENTS]"] = llformat("%d", totalBannedAgents);
args["[MAXBANNED]"] = llformat("%d", ESTATE_MAX_ACCESS_IDS);
std::string msg = LLTrans::getString("RegionInfoBannedResidents", args);
// </FS:Ansariel>
panel->getChild<LLUICtrl>("ban_resident_label")->setValue(LLSD(msg));
if (banned_agent_name_list)
@ -3027,15 +3016,10 @@ bool LLDispatchSetEstateAccess::operator()(
if (access_flags & ESTATE_ACCESS_MANAGERS)
{
// <FS:Ansariel> FIRE-5998: Unlocalizable label
//std::string msg = llformat("Estate Managers: (%d, max %d)",
// num_estate_managers,
// ESTATE_MAX_MANAGERS);
LLStringUtil::format_map_t args;
args["[ESTATEMANAGERS]"] = llformat("%d", num_estate_managers);
args["[MAXMANAGERS]"] = llformat("%d", ESTATE_MAX_MANAGERS);
std::string msg = LLTrans::getString("RegionInfoEstateManagers", args);
// </FS:Ansariel>
panel->getChild<LLUICtrl>("estate_manager_label")->setValue(LLSD(msg));
LLNameListCtrl* estate_manager_name_list =

View File

@ -5062,6 +5062,16 @@ void LLCallingCardBridge::performAction(LLInventoryModel* model, std::string act
LLAvatarActions::offerTeleport(item->getCreatorUUID());
}
}
else if ("request_lure" == action)
{
LLViewerInventoryItem *item = getItem();
if (item && (item->getCreatorUUID() != gAgent.getID()) &&
(!item->getCreatorUUID().isNull()))
{
LLAvatarActions::teleportRequest(item->getCreatorUUID());
}
}
else LLItemBridge::performAction(model, action);
}
@ -5148,6 +5158,7 @@ void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
items.push_back(std::string("Send Instant Message Separator"));
items.push_back(std::string("Send Instant Message"));
items.push_back(std::string("Offer Teleport..."));
items.push_back(std::string("Request Teleport..."));
items.push_back(std::string("Conference Chat"));
if (!good_card)
@ -5157,6 +5168,7 @@ void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
if (!good_card || !user_online)
{
disabled_items.push_back(std::string("Offer Teleport..."));
disabled_items.push_back(std::string("Request Teleport..."));
disabled_items.push_back(std::string("Conference Chat"));
}
}

View File

@ -558,13 +558,11 @@ void LLNetMap::draw()
// Draw avatars
for (U32 i = 0; i < avatar_ids.size(); i++)
{
// <FS:CR> FIRE-11118 - skip our dot, we'll draw one later.
//pos_map = globalPosToView(positions[i]);
LLUUID uuid = avatar_ids[i];
if (uuid == gAgent.getID())
continue;
// Skip self, we'll draw it later
if (uuid == gAgent.getID()) continue;
pos_map = globalPosToView(positions[i]);
// </FS:CR>
// <FS:Ansariel> Check for unknown Z-offset => AVATAR_UNKNOWN_Z_OFFSET
//unknown_relative_z = positions[i].mdV[VZ] == COARSEUPDATE_MAX_Z &&

View File

@ -80,6 +80,7 @@ LLContextMenu* PeopleContextMenu::createMenu()
registrar.add("Avatar.Pay", boost::bind(&LLAvatarActions::pay, id));
registrar.add("Avatar.BlockUnblock", boost::bind(&LLAvatarActions::toggleBlock, id));
registrar.add("Avatar.InviteToGroup", boost::bind(&LLAvatarActions::inviteToGroup, id));
registrar.add("Avatar.TeleportRequest", boost::bind(&PeopleContextMenu::requestTeleport, this));
registrar.add("Avatar.Calllog", boost::bind(&LLAvatarActions::viewChatHistory, id));
// <FS:Ansariel> Firestorm additions
registrar.add("Avatar.GroupInvite", boost::bind(&LLAvatarActions::inviteToGroup, id));
@ -133,6 +134,7 @@ void PeopleContextMenu::buildContextMenu(class LLMenuGL& menu, U32 flags)
items.push_back(std::string("view_profile"));
items.push_back(std::string("im"));
items.push_back(std::string("offer_teleport"));
items.push_back(std::string("request_teleport"));
items.push_back(std::string("voice_call"));
items.push_back(std::string("chat_history"));
items.push_back(std::string("separator_chat_history"));
@ -269,6 +271,13 @@ bool PeopleContextMenu::checkContextMenuItem(const LLSD& userdata)
return false;
}
void PeopleContextMenu::requestTeleport()
{
// boost::bind cannot recognize overloaded method LLAvatarActions::teleportRequest(),
// so we have to use a wrapper.
LLAvatarActions::teleportRequest(mUUIDs.front());
}
void PeopleContextMenu::offerTeleport()
{
// boost::bind cannot recognize overloaded method LLAvatarActions::offerTeleport(),
@ -298,6 +307,7 @@ void NearbyPeopleContextMenu::buildContextMenu(class LLMenuGL& menu, U32 flags)
items.push_back(std::string("view_profile"));
items.push_back(std::string("im"));
items.push_back(std::string("offer_teleport"));
items.push_back(std::string("request_teleport"));
items.push_back(std::string("voice_call"));
items.push_back(std::string("chat_history"));
items.push_back(std::string("separator_chat_history"));

View File

@ -47,6 +47,7 @@ private:
bool enableContextMenuItem(const LLSD& userdata);
bool checkContextMenuItem(const LLSD& userdata);
void offerTeleport();
void requestTeleport();
};
/**

View File

@ -1057,12 +1057,8 @@ void LLBasicCertificateStore::validate(int validation_policy,
throw LLInvalidCertificate((*current_cert));
}
std::string sha1_hash((const char *)cert_x509->sha1_hash, SHA_DIGEST_LENGTH);
// <FS:ND> LLBasicCertificate::getOpenSSLX509 returns a copy made with X509_dup
X509_free( cert_x509 );
cert_x509 = 0;
// </FS:ND>
cert_x509 = NULL;
t_cert_cache::iterator cache_entry = mTrustedCertCache.find(sha1_hash);
if(cache_entry != mTrustedCertCache.end())
{

View File

@ -750,7 +750,10 @@ BOOL LLViewerKeyboard::handleKey(KEY translated_key, MASK translated_mask, BOOL
{
// it is sufficient to set this value once per call to handlekey
// without clearing it, as it is only used in the subsequent call to scanKey
mKeyHandledByUI[translated_key] = gViewerWindow->handleKey(translated_key, translated_mask);
mKeyHandledByUI[translated_key] = gViewerWindow->handleKey(translated_key, translated_mask);
// mKeyHandledByUI is not what you think ... this indicates whether the UI has handled this keypress yet (any keypress)
// NOT whether some UI shortcut wishes to handle the keypress
}
return mKeyHandledByUI[translated_key];
}

View File

@ -40,6 +40,7 @@
#include "llinventorypanel.h"
#include "llnotifications.h"
#include "llnotificationsutil.h"
#include "llviewereventrecorder.h"
// newview includes
#include "llagent.h"
@ -2202,6 +2203,43 @@ class LLAdvancedDropPacket : public view_listener_t
};
////////////////////
// EVENT Recorder //
///////////////////
class LLAdvancedViewerEventRecorder : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
std::string command = userdata.asString();
if ("start playback" == command)
{
llinfos << "Event Playback starting" << llendl;
LLViewerEventRecorder::instance().playbackRecording();
llinfos << "Event Playback completed" << llendl;
}
else if ("stop playback" == command)
{
// Future
}
else if ("start recording" == command)
{
LLViewerEventRecorder::instance().setEventLoggingOn();
llinfos << "Event recording started" << llendl;
}
else if ("stop recording" == command)
{
LLViewerEventRecorder::instance().setEventLoggingOff();
llinfos << "Event recording stopped" << llendl;
}
return true;
}
};
/////////////////
// AGENT PILOT //
@ -10308,6 +10346,8 @@ void initialize_menus()
// Don't prepend MenuName.Foo because these can be used in any menu.
enable.add("IsGodCustomerService", boost::bind(&is_god_customer_service));
enable.add("displayViewerEventRecorderMenuItems",boost::bind(&LLViewerEventRecorder::displayViewerEventRecorderMenuItems,&LLViewerEventRecorder::instance()));
view_listener_t::addEnable(new LLUploadCostCalculator(), "Upload.CalculateCosts");
// <FS:Ansariel> [FS communication UI]
@ -10601,6 +10641,7 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedAgentPilot(), "Advanced.AgentPilot");
view_listener_t::addMenu(new LLAdvancedToggleAgentPilotLoop(), "Advanced.ToggleAgentPilotLoop");
view_listener_t::addMenu(new LLAdvancedCheckAgentPilotLoop(), "Advanced.CheckAgentPilotLoop");
view_listener_t::addMenu(new LLAdvancedViewerEventRecorder(), "Advanced.EventRecorder");
// Advanced > Debugging
view_listener_t::addMenu(new LLAdvancedForceErrorBreakpoint(), "Advanced.ForceErrorBreakpoint");

View File

@ -2545,7 +2545,7 @@ static std::string clean_name_from_im(const std::string& name, EInstantMessage t
case IM_LURE_ACCEPTED:
case IM_LURE_DECLINED:
case IM_GODLIKE_LURE_USER:
case IM_YET_TO_BE_USED:
case IM_TELEPORT_REQUEST:
case IM_GROUP_ELECTION_DEPRECATED:
//IM_GOTO_URL
//IM_FROM_TASK_AS_ALERT
@ -3611,6 +3611,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
break;
case IM_LURE_USER:
case IM_TELEPORT_REQUEST:
{
// [RLVa:KB] - Checked: 2010-12-11 (RLVa-1.2.2c) | Added: RLVa-1.2.2c
// If the lure sender is a specific @accepttp exception they will override muted and busy status
@ -3650,7 +3651,8 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
bool canUserAccessDstRegion = true;
bool doesUserRequireMaturityIncrease = false;
if (parse_lure_bucket(region_info, region_handle, pos, look_at, region_access))
// Do not parse the (empty) lure bucket for TELEPORT_REQUEST
if (IM_TELEPORT_REQUEST != dialog && parse_lure_bucket(region_info, region_handle, pos, look_at, region_access))
{
region_access_str = LLViewerRegion::accessToString(region_access);
region_access_icn = LLViewerRegion::getAccessIcon(region_access);
@ -3744,7 +3746,18 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
}
else
{
LLNotification::Params params("TeleportOffered");
LLNotification::Params params;
if (IM_LURE_USER == dialog)
{
params.name = "TeleportOffered";
params.functor.name = "TeleportOffered";
}
else if (IM_TELEPORT_REQUEST == dialog)
{
params.name = "TeleportRequest";
params.functor.name = "TeleportRequest";
}
params.substitutions = args;
params.payload = payload;
@ -8490,28 +8503,13 @@ void send_group_notice(const LLUUID& group_id,
bin_bucket_size);
}
bool handle_lure_callback(const LLSD& notification, const LLSD& response)
void send_lures(const LLSD& notification, const LLSD& response)
{
static const unsigned OFFER_RECIPIENT_LIMIT = 250;
if(notification["payload"]["ids"].size() > OFFER_RECIPIENT_LIMIT)
{
// More than OFFER_RECIPIENT_LIMIT targets will overload the message
// producing an llerror.
LLSD args;
args["OFFERS"] = notification["payload"]["ids"].size();
args["LIMIT"] = static_cast<int>(OFFER_RECIPIENT_LIMIT);
LLNotificationsUtil::add("TooManyTeleportOffers", args);
return false;
}
std::string text = response["message"].asString();
LLSLURL slurl;
LLAgentUI::buildSLURL(slurl);
text.append("\r\n").append(slurl.getSLURLString());
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if(0 == option)
{
// [RLVa:KB] - Checked: 2010-11-30 (RLVa-1.3.0)
if ( (RlvActions::hasBehaviour(RLV_BHVR_SENDIM)) || (RlvActions::hasBehaviour(RLV_BHVR_SENDIMTO)) )
{
@ -8528,41 +8526,63 @@ bool handle_lure_callback(const LLSD& notification, const LLSD& response)
}
// [/RLVa:KB]
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_StartLure);
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
msg->nextBlockFast(_PREHASH_Info);
msg->addU8Fast(_PREHASH_LureType, (U8)0); // sim will fill this in.
msg->addStringFast(_PREHASH_Message, text);
for(LLSD::array_const_iterator it = notification["payload"]["ids"].beginArray();
it != notification["payload"]["ids"].endArray();
++it)
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_StartLure);
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
msg->nextBlockFast(_PREHASH_Info);
msg->addU8Fast(_PREHASH_LureType, (U8)0); // sim will fill this in.
msg->addStringFast(_PREHASH_Message, text);
for(LLSD::array_const_iterator it = notification["payload"]["ids"].beginArray();
it != notification["payload"]["ids"].endArray();
++it)
{
LLUUID target_id = it->asUUID();
msg->nextBlockFast(_PREHASH_TargetData);
msg->addUUIDFast(_PREHASH_TargetID, target_id);
// Record the offer.
{
LLUUID target_id = it->asUUID();
msg->nextBlockFast(_PREHASH_TargetData);
msg->addUUIDFast(_PREHASH_TargetID, target_id);
// Record the offer.
{
std::string target_name;
gCacheName->getFullName(target_id, target_name); // for im log filenames
LLSD args;
args["TO_NAME"] = LLSLURL("agent", target_id, "displayname").getSLURLString();
std::string target_name;
gCacheName->getFullName(target_id, target_name); // for im log filenames
LLSD args;
args["TO_NAME"] = LLSLURL("agent", target_id, "displayname").getSLURLString();;
LLSD payload;
LLSD payload;
//*TODO please rewrite all keys to the same case, lower or upper
payload["from_id"] = target_id;
LLNotificationsUtil::add("TeleportOfferSent", args, payload);
//*TODO please rewrite all keys to the same case, lower or upper
payload["from_id"] = target_id;
payload["SUPPRESS_TOAST"] = true;
LLNotificationsUtil::add("TeleportOfferSent", args, payload);
// Add the recepient to the recent people list.
LLRecentPeople::instance().add(target_id);
}
// Add the recepient to the recent people list.
LLRecentPeople::instance().add(target_id);
}
gAgent.sendReliableMessage();
}
gAgent.sendReliableMessage();
}
bool handle_lure_callback(const LLSD& notification, const LLSD& response)
{
static const unsigned OFFER_RECIPIENT_LIMIT = 250;
if(notification["payload"]["ids"].size() > OFFER_RECIPIENT_LIMIT)
{
// More than OFFER_RECIPIENT_LIMIT targets will overload the message
// producing an llerror.
LLSD args;
args["OFFERS"] = notification["payload"]["ids"].size();
args["LIMIT"] = static_cast<int>(OFFER_RECIPIENT_LIMIT);
LLNotificationsUtil::add("TooManyTeleportOffers", args);
return false;
}
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if(0 == option)
{
send_lures(notification, response);
}
return false;
@ -8618,6 +8638,58 @@ void handle_lure(const uuid_vec_t& ids)
}
}
bool teleport_request_callback(const LLSD& notification, const LLSD& response)
{
LLUUID from_id = notification["payload"]["from_id"].asUUID();
if(from_id.isNull())
{
llwarns << "from_id is NULL" << llendl;
return false;
}
std::string from_name;
gCacheName->getFullName(from_id, from_name);
if(LLMuteList::getInstance()->isMuted(from_id) && !LLMuteList::getInstance()->isLinden(from_name))
{
return false;
}
S32 option = 0;
if (response.isInteger())
{
option = response.asInteger();
}
else
{
option = LLNotificationsUtil::getSelectedOption(notification, response);
}
switch(option)
{
// Yes
case 0:
{
LLSD dummy_notification;
dummy_notification["payload"]["ids"][0] = from_id;
LLSD dummy_response;
dummy_response["message"] = response["message"];
send_lures(dummy_notification, dummy_response);
}
break;
// No
case 1:
default:
break;
}
return false;
}
static LLNotificationFunctorRegistration teleport_request_callback_reg("TeleportRequest", teleport_request_callback);
void send_improved_im(const LLUUID& to_id,
const std::string& name,

View File

@ -1016,21 +1016,17 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
objectp = *idle_iter;
llassert(objectp->isActive());
objectp->idleUpdate(agent, world, frame_time);
}
}
//update flexible objects
LLVolumeImplFlexible::updateClass();
//update animated textures
// <FS:Ansariel> FIRE-10557 / BUG-2814 / MAINT-2773: Disable texture animation doesn't work
//LLViewerTextureAnim::updateClass();
if (gAnimateTextures)
{
LLViewerTextureAnim::updateClass();
}
// </FS:Ansariel>
}
}

View File

@ -202,6 +202,8 @@
#include "llagentui.h"
#include "llwearablelist.h"
#include "llviewereventrecorder.h"
#include "llnotifications.h"
#include "llnotificationsutil.h"
#include "llnotificationmanager.h"
@ -1010,27 +1012,18 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK
{
llinfos << buttonname << " Mouse " << buttonstatestr << " handled by captor " << mouse_captor->getName() << llendl;
}
return mouse_captor->handleAnyMouseClick(local_x, local_y, mask, clicktype, down);
}
// Topmost view gets a chance before the hierarchy
//LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
//if (top_ctrl)
//{
// S32 local_x, local_y;
// top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
// if (top_ctrl->pointInView(local_x, local_y))
// {
// return top_ctrl->handleAnyMouseClick(local_x, local_y, mask, clicktype, down) ;
// }
// else
// {
// if (down)
// {
// gFocusMgr.setTopCtrl(NULL);
// }
// }
//}
BOOL r = mouse_captor->handleAnyMouseClick(local_x, local_y, mask, clicktype, down);
if (r) {
lldebugs << "LLViewerWindow::handleAnyMouseClick viewer with mousecaptor calling updatemouseeventinfo - local_x|global x "<< local_x << " " << x << "local/global y " << local_y << " " << y << llendl;
LLViewerEventRecorder::instance().setMouseGlobalCoords(x,y);
LLViewerEventRecorder::instance().logMouseEvent(std::string(buttonstatestr),std::string(buttonname));
}
return r;
}
// Mark the click as handled and return if we aren't within the root view to avoid spurious bugs
if( !mRootView->pointInView(x, y) )
@ -1038,27 +1031,44 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK
return TRUE;
}
// Give the UI views a chance to process the click
if( mRootView->handleAnyMouseClick(x, y, mask, clicktype, down) )
BOOL r= mRootView->handleAnyMouseClick(x, y, mask, clicktype, down) ;
if (r)
{
lldebugs << "LLViewerWindow::handleAnyMouseClick calling updatemouseeventinfo - global x "<< " " << x << "global y " << y << "buttonstate: " << buttonstatestr << " buttonname " << buttonname << llendl;
LLViewerEventRecorder::instance().setMouseGlobalCoords(x,y);
// Clear local coords - this was a click on root window so these are not needed
// By not including them, this allows the test skeleton generation tool to be smarter when generating code
// the code generator can be smarter because when local coords are present it can try the xui path with local coords
// and fallback to global coordinates only if needed.
// The drawback to this approach is sometimes a valid xui path will appear to work fine, but NOT interact with the UI element
// (VITA support not implemented yet or not visible to VITA due to widget further up xui path not being visible to VITA)
// For this reason it's best to provide hints where possible here by leaving out local coordinates
LLViewerEventRecorder::instance().setMouseLocalCoords(-1,-1);
LLViewerEventRecorder::instance().logMouseEvent(buttonstatestr,buttonname);
if (LLView::sDebugMouseHandling)
{
llinfos << buttonname << " Mouse " << buttonstatestr << " " << LLView::sMouseHandlerMessage << llendl;
}
llinfos << buttonname << " Mouse " << buttonstatestr << " " << LLViewerEventRecorder::instance().get_xui() << llendl;
}
return TRUE;
}
else if (LLView::sDebugMouseHandling)
{
llinfos << buttonname << " Mouse " << buttonstatestr << " not handled by view" << llendl;
}
} else if (LLView::sDebugMouseHandling)
{
llinfos << buttonname << " Mouse " << buttonstatestr << " not handled by view" << llendl;
}
}
// Do not allow tool manager to handle mouseclicks if we have disconnected
if(!gDisconnected && LLToolMgr::getInstance()->getCurrentTool()->handleAnyMouseClick( x, y, mask, clicktype, down ) )
{
LLViewerEventRecorder::instance().clear_xui();
return TRUE;
}
// If we got this far on a down-click, it wasn't handled.
// Up-clicks, though, are always handled as far as the OS is concerned.
BOOL default_rtn = !down;
@ -1433,7 +1443,8 @@ BOOL LLViewerWindow::handleTranslatedKeyUp(KEY key, MASK mask)
void LLViewerWindow::handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level)
{
LLViewerJoystick::getInstance()->setCameraNeedsUpdate(true);
return gViewerKeyboard.scanKey(key, key_down, key_up, key_level);
gViewerKeyboard.scanKey(key, key_down, key_up, key_level);
return; // Be clear this function returns nothing
}
@ -2743,6 +2754,8 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
||(gLoginMenuBarView && gLoginMenuBarView->handleKey(key, mask, TRUE))
||(gMenuHolder && gMenuHolder->handleKey(key, mask, TRUE)))
{
lldebugs << "LLviewerWindow::handleKey handle nav keys for nav" << llendl;
LLViewerEventRecorder::instance().logKeyEvent(key,mask);
return TRUE;
}
@ -2757,12 +2770,14 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
&& keyboard_focus
&& keyboard_focus->handleKey(key,mask,FALSE))
{
LLViewerEventRecorder::instance().logKeyEvent(key,mask);
return TRUE;
}
if ((gMenuBarView && gMenuBarView->handleAcceleratorKey(key, mask))
||(gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask)))
{
LLViewerEventRecorder::instance().logKeyEvent(key,mask);
return TRUE;
}
}
@ -2772,6 +2787,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
// if nothing has focus, go to first or last UI element as appropriate
if (key == KEY_TAB && (mask & MASK_CONTROL || gFocusMgr.getKeyboardFocus() == NULL))
{
llwarns << "LLviewerWindow::handleKey give floaters first chance at tab key " << llendl;
if (gMenuHolder) gMenuHolder->hideMenus();
// if CTRL-tabbing (and not just TAB with no focus), go into window cycle mode
@ -2786,11 +2802,13 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
{
mRootView->focusNextRoot();
}
LLViewerEventRecorder::instance().logKeyEvent(key,mask);
return TRUE;
}
// hidden edit menu for cut/copy/paste
if (gEditMenu && gEditMenu->handleAcceleratorKey(key, mask))
{
LLViewerEventRecorder::instance().logKeyEvent(key,mask);
return TRUE;
}
@ -2859,18 +2877,27 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
if (keyboard_focus->handleKey(key, mask, FALSE))
{
lldebugs << "LLviewerWindow::handleKey - in 'traverse up' - no loops seen... just called keyboard_focus->handleKey an it returned true" << llendl;
LLViewerEventRecorder::instance().logKeyEvent(key,mask);
return TRUE;
} else {
lldebugs << "LLviewerWindow::handleKey - in 'traverse up' - no loops seen... just called keyboard_focus->handleKey an it returned FALSE" << llendl;
}
}
if( LLToolMgr::getInstance()->getCurrentTool()->handleKey(key, mask) )
{
lldebugs << "LLviewerWindow::handleKey toolbar handling?" << llendl;
LLViewerEventRecorder::instance().logKeyEvent(key,mask);
return TRUE;
}
// Try for a new-format gesture
if (LLGestureMgr::instance().triggerGesture(key, mask))
{
lldebugs << "LLviewerWindow::handleKey new gesture feature" << llendl;
LLViewerEventRecorder::instance().logKeyEvent(key,mask);
return TRUE;
}
@ -2878,6 +2905,8 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
// don't pass it down to the menus.
if (gGestureList.trigger(key, mask))
{
lldebugs << "LLviewerWindow::handleKey check gesture trigger" << llendl;
LLViewerEventRecorder::instance().logKeyEvent(key,mask);
return TRUE;
}
@ -2937,7 +2966,7 @@ BOOL LLViewerWindow::handleUnicodeChar(llwchar uni_char, MASK mask)
// HACK: Numeric keypad <enter> on Mac is Unicode 3
// HACK: Control-M on Windows is Unicode 13
if ((uni_char == 13 && mask != MASK_CONTROL)
|| (uni_char == 3 && mask == MASK_NONE))
|| (uni_char == 3 && mask == MASK_NONE) )
{
if (mask != MASK_ALT)
{
@ -2960,14 +2989,7 @@ BOOL LLViewerWindow::handleUnicodeChar(llwchar uni_char, MASK mask)
return TRUE;
}
//// Topmost view gets a chance before the hierarchy
//LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
//if (top_ctrl && top_ctrl->handleUnicodeChar( uni_char, FALSE ) )
//{
// return TRUE;
//}
return TRUE;
return TRUE;
}
return FALSE;
@ -2976,8 +2998,6 @@ BOOL LLViewerWindow::handleUnicodeChar(llwchar uni_char, MASK mask)
void LLViewerWindow::handleScrollWheel(S32 clicks)
{
LLView::sMouseHandlerMessage.clear();
LLUI::resetMouseIdleTimer();
LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();

View File

@ -265,7 +265,9 @@ void LLWindowListener::getPaths(LLSD const & request)
void LLWindowListener::keyDown(LLSD const & evt)
{
Response response(LLSD(), evt);
KEY key = getKEY(evt);
MASK mask = getMask(evt);
if (evt.has("path"))
{
std::string path(evt["path"]);
@ -280,8 +282,6 @@ void LLWindowListener::keyDown(LLSD const & evt)
response.setResponse(target_view->getInfo());
gFocusMgr.setKeyboardFocus(target_view);
KEY key = getKEY(evt);
MASK mask = getMask(evt);
gViewerKeyboard.handleKey(key, mask, false);
if(key < 0x80) mWindow->handleUnicodeChar(key, mask);
}
@ -294,7 +294,8 @@ void LLWindowListener::keyDown(LLSD const & evt)
}
else
{
mKbGetter()->handleTranslatedKeyDown(getKEY(evt), getMask(evt));
gViewerKeyboard.handleKey(key, mask, false);
if(key < 0x80) mWindow->handleUnicodeChar(key, mask);
}
}

View File

@ -573,6 +573,17 @@ bool LLWorldMap::insertItem(U32 x_world, U32 y_world, std::string& name, LLUUID&
tooltip_fmt.setArg("[AREA]", llformat("%d", extra));
tooltip_fmt.setArg("[PRICE]", llformat("%d", extra2));
// Check for division by zero
if (extra != 0)
{
tooltip_fmt.setArg("[SQMPRICE]", llformat("%.1f", (F32)extra2 / (F32)extra));
}
else
{
tooltip_fmt.setArg("[SQMPRICE]", LLTrans::getString("Unknown"));
}
new_item.setTooltip(tooltip_fmt.getString());
if (type == MAP_ITEM_LAND_FOR_SALE)

View File

@ -52,6 +52,13 @@
<on_click function="Avatar.DoToSelected" parameter="offer_teleport"/>
<on_enable function="Avatar.EnableItem" parameter="can_offer_teleport"/>
</menu_item_call>
<menu_item_call
label="Request teleport"
layout="topleft"
name="request_teleport">
<on_click function="Avatar.DoToSelected" parameter="request_teleport"/>
<on_enable function="Avatar.EnableItem" parameter="can_offer_teleport"/>
</menu_item_call>
<menu_item_call
label="Voice call"
layout="topleft"

View File

@ -67,6 +67,16 @@
function="Calllog.Enable"
parameter="can_offer_teleport"/>
</menu_item_call>
<menu_item_call
label="Request Teleport"
name="request_teleport">
<on_click
function="Calllog.Action"
parameter="request_teleport"/>
<on_enable
function="Calllog.Enable"
parameter="can_offer_teleport"/>
</menu_item_call>
<menu_item_separator />
<menu_item_call
label="Add Friend"

View File

@ -614,6 +614,14 @@
function="Inventory.DoToSelected"
parameter="lure" />
</menu_item_call>
<menu_item_call
label="Request Teleport..."
layout="topleft"
name="Request Teleport...">
<menu_item_call.on_click
function="Inventory.DoToSelected"
parameter="request_lure" />
</menu_item_call>
<menu_item_call
label="Start Conference Chat"
layout="topleft"

View File

@ -28,6 +28,15 @@
function="Avatar.EnableItem"
parameter="can_offer_teleport"/>
</menu_item_call>
<menu_item_call
label="Request Teleport"
name="request_teleport">
<menu_item_call.on_click
function="Avatar.TeleportRequest"/>
<menu_item_call.on_enable
function="Avatar.EnableItem"
parameter="can_offer_teleport"/>
</menu_item_call>
<menu_item_call
label="Voice call"
layout="topleft"
@ -134,5 +143,4 @@
function="Avatar.EnableItem"
parameter="can_block" />
</menu_item_check>
<menu_item_separator />
</context_menu>

View File

@ -3957,6 +3957,34 @@
label="Recorder"
name="Recorder"
tear_off="true">
<menu_item_call visible="false"
label="Start event recording"
name="Start event recording">
<menu_item_call.on_visible
function="displayViewerEventRecorderMenuItems" />
<menu_item_call.on_click
function="Advanced.EventRecorder"
parameter="start recording" />
</menu_item_call>
<menu_item_call visible="false"
label="Stop event recording"
name="Stop event recording">
<menu_item_call.on_visible
function="displayViewerEventRecorderMenuItems" />
<menu_item_call.on_click
function="Advanced.EventRecorder"
parameter="stop recording" />
</menu_item_call>
<menu_item_call visible="false"
label="Playback event recording"
name="Playback event recording">
<menu_item_call.on_visible
function="displayViewerEventRecorderMenuItems" />
<menu_item_call.on_click
function="Advanced.EventRecorder"
parameter="start playback" />
</menu_item_call>
<menu_item_call
label="Start Playback"
name="Start Playback">

View File

@ -4221,6 +4221,27 @@ Join me in [REGION]
</form>
</notification>
<notification
icon="alertmodal.tga"
name="TeleportRequestPrompt"
type="alertmodal">
Request a teleport to [NAME] with the following message
<tag>confirm</tag>
<form name="form">
<input name="message" type="text">
</input>
<button
default="true"
index="0"
name="OK"
text="OK"/>
<button
index="1"
name="Cancel"
text="Cancel"/>
</form>
</notification>
<notification
icon="alertmodal.tga"
name="TooManyTeleportOffers"
@ -7099,7 +7120,7 @@ Joining this group costs a fee and the invitation cannot be accepted because of
sound="UISndTeleportOffer">
[NAME_SLURL] has offered to teleport you to their location:
[MESSAGE]”
"[MESSAGE]”
&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
<tag>confirm</tag>
<form name="form">
@ -7164,6 +7185,27 @@ However, this region contains content accessible to adults only.
Teleport offer sent to [TO_NAME]
</notification>
<notification
icon="notify.tga"
name="TeleportRequest"
log_to_im="true"
type="offer">
[NAME_SLURL] is requesting to be teleported to your location.
[MESSAGE]
Offer a teleport?
<tag>confirm</tag>
<form name="form">
<button
index="0"
name="Yes"
text="Yes"/>
<button
index="1"
name="No"
text="No"/>
</form>
</notification>
<notification
icon="notify.tga"
@ -7213,7 +7255,6 @@ However, this region contains content accessible to adults only.
icon="notify.tga"
name="FriendshipOffered"
log_to_im="true"
show_toast="false"
type="notify">
<tag>friendship</tag>
You have offered friendship to [TO_NAME]
@ -7264,7 +7305,6 @@ However, this region contains content accessible to adults only.
icon="notify.tga"
name="FriendshipAcceptedByMe"
log_to_im="true"
show_toast="false"
type="notify">
<tag>friendship</tag>
Friendship offer accepted.
@ -7274,7 +7314,6 @@ Friendship offer accepted.
icon="notify.tga"
name="FriendshipDeclinedByMe"
log_to_im="true"
show_toast="false"
type="notify">
<tag>friendship</tag>
Friendship offer declined.

View File

@ -216,6 +216,16 @@
width="256" />
<check_box
control_name="FSEnableRightclickMenuInMouselook"
<check_box
control_name="AutomaticFly"
follows="left|top"
height="20"
label="Hold jump or crouch key to start or stop flying"
layout="topleft"
left_delta="0"
name="automatic_fly"
width="237"
top_pad="0"/>
follows="left|top"
enabled_control="EnableMouselook"
height="16"

View File

@ -323,7 +323,6 @@
image_pressed="Pause_Press"
image_pressed_selected="Play_Press"
is_toggle="true"
left_delta="60"
left_pad="2"
top="1"
name="media_toggle_btn"

View File

@ -397,7 +397,7 @@ Please try logging in again in a minute.</string>
<!-- world map -->
<string name="texture_loading">Loading...</string>
<string name="worldmap_offline">Offline</string>
<string name="worldmap_item_tooltip_format">[AREA] m² L$[PRICE]</string>
<string name="worldmap_item_tooltip_format">[AREA] m² L$[PRICE] ([SQMPRICE] L$/m²)</string>
<string name="worldmap_results_none_found">None found.</string>
<string name="worldmap_agent_position">You are here</string>
@ -877,13 +877,11 @@ Drag folders to this area and click "Send to Marketplace" to list them for sale
</string>
<string name="RegionInfoAllowedResidents">Allowed Residents: ([ALLOWEDAGENTS], max [MAXACCESS])</string>
<string name="RegionInfoAllowedGroups">Allowed Groups: ([ALLOWEDGROUPS], max [MAXACCESS])</string>
<!-- FS:Ansariel: Estate managers and banned residents strings -->
<string name="RegionInfoEstateManagers">Estate Managers: ([ESTATEMANAGERS], max [MAXMANAGERS])</string>
<string name="RegionInfoBannedResidents">Banned Residents: ([BANNEDAGENTS], max [MAXBANNED])</string>
<string name="RegionInfoListTypeAllowedAgents">Allowed Residents</string>
<string name="RegionInfoListTypeBannedAgents">Banned Residents</string>
<!-- END FS:Ansariel: Estate managers and banned residents strings -->
<!-- script limits floater -->
<string name="ScriptLimitsParcelScriptMemory">Parcel Script Memory</string>
<string name="ScriptLimitsParcelsOwned">Parcels Listed: [PARCELS]</string>

View File

@ -1320,7 +1320,7 @@ Intenta iniciar sesión de nuevo en unos instantes.
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/
</string>
<string name="MarketplaceURL_CreateStore">
http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4
http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3
</string>
<string name="MarketplaceURL_Dashboard">
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard

View File

@ -1271,7 +1271,7 @@ Veuillez réessayer de vous connecter dans une minute.
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/
</string>
<string name="MarketplaceURL_CreateStore">
http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4
http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3
</string>
<string name="MarketplaceURL_Dashboard">
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard

View File

@ -1262,7 +1262,7 @@ Prova ad accedere nuovamente tra un minuto.
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/
</string>
<string name="MarketplaceURL_CreateStore">
http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4
http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3
</string>
<string name="MarketplaceURL_Dashboard">
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard

View File

@ -1271,7 +1271,7 @@ support@secondlife.com にお問い合わせください。
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/
</string>
<string name="MarketplaceURL_CreateStore">
http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4
http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3
</string>
<string name="MarketplaceURL_Dashboard">
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard

View File

@ -1223,7 +1223,7 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/
</string>
<string name="MarketplaceURL_CreateStore">
http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4
http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3
</string>
<string name="MarketplaceURL_Dashboard">
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard

View File

@ -1271,7 +1271,7 @@ support@secondlife.com.
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/
</string>
<string name="MarketplaceURL_CreateStore">
http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4
http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3
</string>
<string name="MarketplaceURL_Dashboard">
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard

View File

@ -1271,7 +1271,7 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin.
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/
</string>
<string name="MarketplaceURL_CreateStore">
http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4
http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3
</string>
<string name="MarketplaceURL_Dashboard">
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard

View File

@ -1390,7 +1390,7 @@ Only large parcels can be listed in search.
<combo_box.item
label="Any Category"
name="item0"
value="any" />
value="none" />
<combo_box.item
label="Linden Location"
name="item1"

View File

@ -133,26 +133,37 @@ class ViewerManifest(LLManifest):
self.path("beamsColors")
# CHOP-955: If we have "sourceid" in the build process
# environment, generate it into settings_install.xml.
try:
sourceid = os.environ["sourceid"]
except KeyError:
# no sourceid, no settings_install.xml file
pass
else:
if sourceid:
# Single-entry subset of the LLSD content of settings.xml
content = dict(sourceid=dict(Comment='Identify referring agency to Linden web servers',
Persist=1,
Type='String',
Value=sourceid))
# put_in_file(src=) need not be an actual pathname; it
# only needs to be non-empty
settings_install = self.put_in_file(llsd.format_pretty_xml(content),
"settings_install.xml",
src="environment")
print "Put sourceid '%s' in %s" % (sourceid, settings_install)
# CHOP-955: If we have "sourceid" or "viewer_channel" in the
# build process environment, generate it into
# settings_install.xml.
settings_template = dict(
sourceid=dict(Comment='Identify referring agency to Linden web servers',
Persist=1,
Type='String',
Value=''),
CmdLineChannel=dict(Comment='Command line specified channel name',
Persist=0,
Type='String',
Value=''))
settings_install = {}
for key, setting in (("sourceid", "sourceid"),
("channel", "CmdLineChannel")):
if key in self.args:
# only set if value is non-empty
if self.args[key]:
# copy corresponding setting from settings_template
settings_install[setting] = settings_template[setting].copy()
# then fill in Value
settings_install[setting]["Value"] = self.args[key]
print "Put %s '%s' in settings_install.xml" % (setting, self.args[key])
# did we actually copy anything into settings_install dict?
if settings_install:
# put_in_file(src=) need not be an actual pathname; it
# only needs to be non-empty
self.put_in_file(llsd.format_pretty_xml(settings_install),
"settings_install.xml",
src="environment")
self.end_prefix("app_settings")
@ -733,6 +744,9 @@ class WindowsManifest(ViewerManifest):
installer_file = self.args['installer_name']
else:
installer_file = installer_file % substitution_strings
if len(self.args['package_id']) > 0:
installer_file = installer_file.replace(self.args['package_id'], "")
installer_file = installer_file.replace(".exe", self.args['package_id'] + ".exe")
substitution_strings['installer_file'] = installer_file
tempfile = "secondlife_setup_tmp.nsi"
@ -1044,7 +1058,9 @@ class DarwinManifest(ViewerManifest):
#[FS:CR] Understood and disregarded!
volname = (self.app_name() + " " + '.'.join(self.args['version']) + " Installer")
#if self.default_channel():
#if len(self.args['package_id']) > 0:
# imagename = imagename + self.args['package_id']
#elif self.default_channel():
# if not self.default_grid():
# # beta case
# imagename = imagename + '_' + self.args['grid'].upper()
@ -1057,7 +1073,7 @@ class DarwinManifest(ViewerManifest):
# make sure we don't have stale files laying about
self.remove(sparsename, finalname)
self.run_command('hdiutil create %(sparse)r -volname %(vol)r -fs HFS+ -type SPARSE -megabytes 700 -layout SPUD' % {
self.run_command('hdiutil create %(sparse)r -volname %(vol)r -fs HFS+ -type SPARSE -megabytes 1000 -layout SPUD' % {
'sparse':sparsename,
'vol':volname})
@ -1151,6 +1167,7 @@ class DarwinManifest(ViewerManifest):
print "Converting temp disk image to final disk image"
self.run_command('hdiutil convert %(sparse)r -format UDZO -imagekey zlib-level=9 -o %(final)r' % {'sparse':sparsename, 'final':finalname})
self.run_command('hdiutil internet-enable -yes %(final)r' % {'final':finalname})
# get rid of the temp file
self.package_file = finalname
self.remove(sparsename)

View File

@ -79,7 +79,6 @@ void LLUpdateChecker::checkVersion(std::string const & urlBase,
//-----------------------------------------------------------------------------
const char * LLUpdateChecker::Implementation::sLegacyProtocolVersion = "v1.0";
const char * LLUpdateChecker::Implementation::sProtocolVersion = "v1.1";
@ -150,40 +149,11 @@ void LLUpdateChecker::Implementation::completed(U32 status,
server_error += content["error_text"].asString();
}
if (status == 404)
{
if (mProtocol == sProtocolVersion)
{
mProtocol = sLegacyProtocolVersion;
std::string retryUrl = buildUrl(mUrlBase, mChannel, mVersion, mPlatform, mPlatformVersion, mUniqueId, mWillingToTest);
LL_WARNS("UpdaterService")
<< "update response using " << sProtocolVersion
<< " was HTTP 404 (" << server_error
<< "); retry with legacy protocol " << mProtocol
<< "\n at " << retryUrl
<< LL_ENDL;
mHttpClient.get(retryUrl, this);
}
else
{
LL_WARNS("UpdaterService")
<< "update response using " << sLegacyProtocolVersion
<< " was 404 (" << server_error
<< "); request failed"
<< LL_ENDL;
mClient.error(reason);
}
}
else
{
LL_WARNS("UpdaterService") << "response error " << status
<< " " << reason
<< " (" << server_error << ")"
<< LL_ENDL;
mClient.error(reason);
}
LL_WARNS("UpdaterService") << "response error " << status
<< " " << reason
<< " (" << server_error << ")"
<< LL_ENDL;
mClient.error(reason);
}
else
{
@ -213,11 +183,8 @@ std::string LLUpdateChecker::Implementation::buildUrl(std::string const & urlBas
path.append(channel);
path.append(version);
path.append(platform);
if (mProtocol != sLegacyProtocolVersion)
{
path.append(platform_version);
path.append(willing_to_test ? "testok" : "testno");
path.append((char*)uniqueid);
}
path.append(platform_version);
path.append(willing_to_test ? "testok" : "testno");
path.append((char*)uniqueid);
return LLURI::buildHTTP(urlBase, path).asString();
}