Merge viewer-bugsplat
commit
ee34ea1f4b
1
.hgtags
1
.hgtags
|
|
@ -580,3 +580,4 @@ ad0e15543836d64d6399d28b32852510435e344a 5.1.0-release
|
|||
ac3b1332ad4f55b7182a8cbcc1254535a0069f75 5.1.7-release
|
||||
23ea0fe36fadf009a60c080392ce80e4bf8af8d9 5.1.8-release
|
||||
52422540bfe54b71155aa455360bee6e3ef1fd96 5.1.9-release
|
||||
1cfa567caf5088ae299271be08cc2d9f0801ff6a pre-Poseidon
|
||||
|
|
|
|||
202
autobuild.xml
202
autobuild.xml
|
|
@ -448,9 +448,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>7a7bd828233e8a2b0e9c022f6219e6e7</string>
|
||||
<string>c3b5e8c57bd1c92bc9e0956586908b99</string>
|
||||
<key>url</key>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23730/182106/bugsplat-1.0.6.519145-darwin64-519145.tar.bz2</string>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/26330/207568/bugsplat-1.0.7.520791-darwin64-520791.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
|
|
@ -460,9 +460,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>a3938332a11215e6909d67d1b9be5259</string>
|
||||
<string>766dfde65a5b42ea5691d41df79c43e0</string>
|
||||
<key>url</key>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23732/182120/bugsplat-3.6.0.4.519145-windows-519145.tar.bz2</string>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/26332/207582/bugsplat-3.6.0.4.520791-windows-520791.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
|
|
@ -472,46 +472,16 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>453d624d87a80779f59cfb1880613d90</string>
|
||||
<string>afd01285e22f27d473fac6f88fac9a3b</string>
|
||||
<key>url</key>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23731/182115/bugsplat-3.6.0.4.519145-windows64-519145.tar.bz2</string>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/26331/207576/bugsplat-3.6.0.4.520791-windows64-520791.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>1.0.6.519145</string>
|
||||
</map>
|
||||
<key>chardet</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
<string>Contributors to charset (see https://github.com/chardet/chardet)</string>
|
||||
<key>description</key>
|
||||
<string>Python Character Encoding Library</string>
|
||||
<key>license</key>
|
||||
<string>LGPL</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/chardet.txt</string>
|
||||
<key>name</key>
|
||||
<string>chardet</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>darwin64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>0124862b6a1b88455c78a68f8b823d21</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6662/23578/chardet-3.0.4-darwin64-506651.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>3.0.4</string>
|
||||
<string>1.0.7.520791</string>
|
||||
</map>
|
||||
<key>colladadom</key>
|
||||
<map>
|
||||
|
|
@ -1801,36 +1771,6 @@
|
|||
<key>version</key>
|
||||
<string>2012.1-2</string>
|
||||
</map>
|
||||
<key>idna</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
<string>Copyright (c) 2013-2017, Kim Davies. All rights reserved.</string>
|
||||
<key>description</key>
|
||||
<string>Python Internationalized Domain Names in Applications (IDNA) Library</string>
|
||||
<key>license</key>
|
||||
<string>see idna.rst</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/idna.rst</string>
|
||||
<key>name</key>
|
||||
<string>idna</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>darwin64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>7dfe9fc4023d7d4f511dd9fac7258266</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6663/23584/idna-2.5-darwin64-506652.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>2.5</string>
|
||||
</map>
|
||||
<key>jpeglib</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
|
|
@ -2509,46 +2449,6 @@
|
|||
<key>version</key>
|
||||
<string>0.0.1</string>
|
||||
</map>
|
||||
<key>llbase</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
<string>Copyright (c) 2010, Linden Research, Inc.</string>
|
||||
<key>license</key>
|
||||
<string>mit</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/llbase-license.txt</string>
|
||||
<key>name</key>
|
||||
<string>llbase</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>darwin64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>e18eeb0691af053b83bd46b76c6ee86a</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6299/21982/llbase-0.9.3.506286-darwin64-506286.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
</map>
|
||||
<key>windows</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>e6865670f9bca1c82fb8b91db3ea515c</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6301/21994/llbase-0.9.3.506286-windows-506286.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>0.9.3.506286</string>
|
||||
</map>
|
||||
<key>llca</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
|
|
@ -3315,52 +3215,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>version</key>
|
||||
<string>8.35.500898</string>
|
||||
</map>
|
||||
<key>requests</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
<string>Copyright 2016 Kenneth Reitz</string>
|
||||
<key>description</key>
|
||||
<string>Python HTTP Library</string>
|
||||
<key>license</key>
|
||||
<string>Apache</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/requests.txt</string>
|
||||
<key>name</key>
|
||||
<string>requests</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>darwin64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>b8d134a970261b445a3f376ba4e05ff7</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6693/23788/requests-2.18.1-darwin64-506681.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
</map>
|
||||
<key>linux64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>9fe44ba82ee05363fdfa4c1b9f2ec360</string>
|
||||
<key>url</key>
|
||||
<string>http://downloads.phoenixviewer.com/requests-2.18.1-linux64-180841555.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>source</key>
|
||||
<string>https://bitbucket.org/lindenlab/p64_python-requests</string>
|
||||
<key>source_type</key>
|
||||
<string>hg</string>
|
||||
<key>version</key>
|
||||
<string>2.18.1</string>
|
||||
</map>
|
||||
<key>slvoice</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
|
|
@ -3571,36 +3425,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>version</key>
|
||||
<string>0.8.0.1</string>
|
||||
</map>
|
||||
<key>urllib3</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
<string>Copyright 2008-2016 Andrey Petrov and contributors (see CONTRIBUTORS.txt)</string>
|
||||
<key>description</key>
|
||||
<string>Python HTTP Library</string>
|
||||
<key>license</key>
|
||||
<string>MIT</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/urllib3.txt</string>
|
||||
<key>name</key>
|
||||
<string>urllib3</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>darwin64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>22f64c7fbb6704d2e9519fd1cca8e49b</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6659/23560/urllib3-1.21.1-darwin64-506648.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>1.21.1</string>
|
||||
</map>
|
||||
<key>viewer-manager</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
|
|
@ -3608,7 +3432,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>description</key>
|
||||
<string>Linden Lab Viewer Management Process suite.</string>
|
||||
<key>license</key>
|
||||
<string>Proprietary</string>
|
||||
<string>viewerlgpl</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSE</string>
|
||||
<key>name</key>
|
||||
|
|
@ -3620,9 +3444,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>ce95944fb842849108102263a25fc794</string>
|
||||
<string>1d801a03cb87a248b6573f8550603286</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/23237/178332/viewer_manager-1.0.518840-darwin64-518840.tar.bz2</string>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/26264/206909/viewer_manager-2.0.520750-darwin64-520750.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
|
|
@ -3656,9 +3480,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>642f847a9ac45551af65a55826974334</string>
|
||||
<string>65e20bc630033178f3f7e4890c0b85f7</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/23236/178338/viewer_manager-1.0.518840-windows-518840.tar.bz2</string>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/26265/206915/viewer_manager-2.0.520750-windows-520750.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
|
|
@ -3669,7 +3493,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>source_type</key>
|
||||
<string>hg</string>
|
||||
<key>version</key>
|
||||
<string>1.0.518840</string>
|
||||
<string>2.0.520750</string>
|
||||
</map>
|
||||
<key>vlc-bin</key>
|
||||
<map>
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
# -*- cmake -*-
|
||||
include(Prebuilt)
|
||||
|
||||
use_prebuilt_binary(llbase)
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
if (DARWIN)
|
||||
include (Prebuilt)
|
||||
use_prebuilt_binary(requests)
|
||||
use_prebuilt_binary(urllib3)
|
||||
use_prebuilt_binary(chardet)
|
||||
use_prebuilt_binary(idna)
|
||||
endif (DARWIN)
|
||||
|
|
@ -634,6 +634,14 @@ class LLManifest(object):
|
|||
# *TODO is this gonna be useful?
|
||||
print "Cleaning up " + c
|
||||
|
||||
def process_either(self, src, dst):
|
||||
# If it's a real directory, recurse through it --
|
||||
# but not a symlink! Handle those like files.
|
||||
if os.path.isdir(src) and not os.path.islink(src):
|
||||
return self.process_directory(src, dst)
|
||||
else:
|
||||
return self.process_file(src, dst)
|
||||
|
||||
def process_file(self, src, dst):
|
||||
if self.includes(src, dst):
|
||||
for action in self.actions:
|
||||
|
|
@ -660,10 +668,7 @@ class LLManifest(object):
|
|||
for name in names:
|
||||
srcname = os.path.join(src, name)
|
||||
dstname = os.path.join(dst, name)
|
||||
if os.path.isdir(srcname):
|
||||
count += self.process_directory(srcname, dstname)
|
||||
else:
|
||||
count += self.process_file(srcname, dstname)
|
||||
count += self.process_either(srcname, dstname)
|
||||
return count
|
||||
|
||||
def includes(self, src, dst):
|
||||
|
|
@ -835,11 +840,7 @@ class LLManifest(object):
|
|||
# if we're specifying a single path (not a glob),
|
||||
# we should error out if it doesn't exist
|
||||
self.check_file_exists(src)
|
||||
# if it's a directory, recurse through it
|
||||
if os.path.isdir(src):
|
||||
count += self.process_directory(src, dst)
|
||||
else:
|
||||
count += self.process_file(src, dst)
|
||||
count += self.process_either(src, dst)
|
||||
return count
|
||||
|
||||
try_prefixes = [self.get_src_prefix(), self.get_artwork_prefix(), self.get_build_prefix()]
|
||||
|
|
|
|||
|
|
@ -169,6 +169,26 @@ public:
|
|||
static void set_consuming(bool consuming);
|
||||
static bool get_consuming();
|
||||
|
||||
/**
|
||||
* RAII control of the consuming flag
|
||||
*/
|
||||
class OverrideConsuming
|
||||
{
|
||||
public:
|
||||
OverrideConsuming(bool consuming):
|
||||
mPrevConsuming(get_consuming())
|
||||
{
|
||||
set_consuming(consuming);
|
||||
}
|
||||
~OverrideConsuming()
|
||||
{
|
||||
set_consuming(mPrevConsuming);
|
||||
}
|
||||
|
||||
private:
|
||||
bool mPrevConsuming;
|
||||
};
|
||||
|
||||
/**
|
||||
* Please do NOT directly use boost::dcoroutines::future! It is essential
|
||||
* to maintain the "current" coroutine at every context switch. This
|
||||
|
|
|
|||
|
|
@ -119,13 +119,14 @@ namespace {
|
|||
public:
|
||||
RecordToFile(const std::string& filename)
|
||||
{
|
||||
// <FS:Ansariel> Don't screw up log file output
|
||||
this->showMultiline(true);
|
||||
|
||||
mFile.open(filename.c_str(), std::ios_base::out | std::ios_base::app);
|
||||
if (!mFile)
|
||||
{
|
||||
LL_INFOS() << "Error setting log file to " << filename << LL_ENDL;
|
||||
}
|
||||
mWantsTime = true;
|
||||
mWantsTags = true;
|
||||
}
|
||||
|
||||
~RecordToFile()
|
||||
|
|
@ -151,7 +152,7 @@ namespace {
|
|||
public:
|
||||
RecordToStderr(bool timestamp) : mUseANSI(ANSI_PROBE)
|
||||
{
|
||||
mWantsTime = timestamp;
|
||||
this->showMultiline(true);
|
||||
}
|
||||
|
||||
virtual void recordMessage(LLError::ELevel level,
|
||||
|
|
@ -215,7 +216,13 @@ namespace {
|
|||
class RecordToFixedBuffer : public LLError::Recorder
|
||||
{
|
||||
public:
|
||||
RecordToFixedBuffer(LLLineBuffer* buffer) : mBuffer(buffer) { }
|
||||
RecordToFixedBuffer(LLLineBuffer* buffer)
|
||||
: mBuffer(buffer)
|
||||
{
|
||||
this->showMultiline(true);
|
||||
this->showTags(false);
|
||||
this->showLocation(false);
|
||||
}
|
||||
|
||||
virtual void recordMessage(LLError::ELevel level,
|
||||
const std::string& message)
|
||||
|
|
@ -232,7 +239,11 @@ namespace {
|
|||
{
|
||||
public:
|
||||
RecordToWinDebug()
|
||||
{}
|
||||
{
|
||||
this->showMultiline(true);
|
||||
this->showTags(false);
|
||||
this->showLocation(false);
|
||||
}
|
||||
|
||||
virtual void recordMessage(LLError::ELevel level,
|
||||
const std::string& message)
|
||||
|
|
@ -419,8 +430,6 @@ namespace LLError
|
|||
public:
|
||||
virtual ~SettingsConfig();
|
||||
|
||||
bool mPrintLocation;
|
||||
|
||||
LLError::ELevel mDefaultLevel;
|
||||
|
||||
LevelMap mFunctionLevelMap;
|
||||
|
|
@ -461,7 +470,6 @@ namespace LLError
|
|||
|
||||
SettingsConfig::SettingsConfig()
|
||||
: LLRefCount(),
|
||||
mPrintLocation(false),
|
||||
mDefaultLevel(LLError::LEVEL_DEBUG),
|
||||
mFunctionLevelMap(),
|
||||
mClassLevelMap(),
|
||||
|
|
@ -694,12 +702,6 @@ namespace LLError
|
|||
commonInit(user_dir, app_dir, log_to_stderr);
|
||||
}
|
||||
|
||||
void setPrintLocation(bool print)
|
||||
{
|
||||
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
|
||||
s->mPrintLocation = print;
|
||||
}
|
||||
|
||||
void setFatalFunction(const FatalFunction& f)
|
||||
{
|
||||
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
|
||||
|
|
@ -814,7 +816,6 @@ namespace LLError
|
|||
s->mTagLevelMap.clear();
|
||||
s->mUniqueLogMessages.clear();
|
||||
|
||||
setPrintLocation(config["print-location"]);
|
||||
setDefaultLevel(decodeLevel(config["default-level"]));
|
||||
|
||||
LLSD sets = config["settings"];
|
||||
|
|
@ -837,11 +838,12 @@ namespace LLError
|
|||
namespace LLError
|
||||
{
|
||||
Recorder::Recorder()
|
||||
: mWantsTime(false),
|
||||
mWantsTags(false),
|
||||
mWantsLevel(true),
|
||||
mWantsLocation(false),
|
||||
mWantsFunctionName(true)
|
||||
: mWantsTime(true)
|
||||
, mWantsTags(true)
|
||||
, mWantsLevel(true)
|
||||
, mWantsLocation(true)
|
||||
, mWantsFunctionName(true)
|
||||
, mWantsMultiline(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -878,6 +880,42 @@ namespace LLError
|
|||
return mWantsFunctionName;
|
||||
}
|
||||
|
||||
// virtual
|
||||
bool Recorder::wantsMultiline()
|
||||
{
|
||||
return mWantsMultiline;
|
||||
}
|
||||
|
||||
void Recorder::showTime(bool show)
|
||||
{
|
||||
mWantsTime = show;
|
||||
}
|
||||
|
||||
void Recorder::showTags(bool show)
|
||||
{
|
||||
mWantsTags = show;
|
||||
}
|
||||
|
||||
void Recorder::showLevel(bool show)
|
||||
{
|
||||
mWantsLevel = show;
|
||||
}
|
||||
|
||||
void Recorder::showLocation(bool show)
|
||||
{
|
||||
mWantsLocation = show;
|
||||
}
|
||||
|
||||
void Recorder::showFunctionName(bool show)
|
||||
{
|
||||
mWantsFunctionName = show;
|
||||
}
|
||||
|
||||
void Recorder::showMultiline(bool show)
|
||||
{
|
||||
mWantsMultiline = show;
|
||||
}
|
||||
|
||||
void addRecorder(RecorderPtr recorder)
|
||||
{
|
||||
if (!recorder)
|
||||
|
|
@ -910,17 +948,15 @@ namespace LLError
|
|||
s->mFileRecorder.reset();
|
||||
s->mFileRecorderFileName.clear();
|
||||
|
||||
if (file_name.empty())
|
||||
if (!file_name.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RecorderPtr recordToFile(new RecordToFile(file_name));
|
||||
if (boost::dynamic_pointer_cast<RecordToFile>(recordToFile)->okay())
|
||||
{
|
||||
s->mFileRecorderFileName = file_name;
|
||||
s->mFileRecorder = recordToFile;
|
||||
addRecorder(recordToFile);
|
||||
RecorderPtr recordToFile(new RecordToFile(file_name));
|
||||
if (boost::dynamic_pointer_cast<RecordToFile>(recordToFile)->okay())
|
||||
{
|
||||
s->mFileRecorderFileName = file_name;
|
||||
s->mFileRecorder = recordToFile;
|
||||
addRecorder(recordToFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -931,14 +967,12 @@ namespace LLError
|
|||
removeRecorder(s->mFixedBufferRecorder);
|
||||
s->mFixedBufferRecorder.reset();
|
||||
|
||||
if (!fixedBuffer)
|
||||
if (fixedBuffer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RecorderPtr recordToFixedBuffer(new RecordToFixedBuffer(fixedBuffer));
|
||||
s->mFixedBufferRecorder = recordToFixedBuffer;
|
||||
addRecorder(recordToFixedBuffer);
|
||||
RecorderPtr recordToFixedBuffer(new RecordToFixedBuffer(fixedBuffer));
|
||||
s->mFixedBufferRecorder = recordToFixedBuffer;
|
||||
addRecorder(recordToFixedBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
std::string logFileName()
|
||||
|
|
@ -950,9 +984,9 @@ namespace LLError
|
|||
|
||||
namespace
|
||||
{
|
||||
/* <FS:LO> Hide the log sanitize function so gcc doesnt complain.
|
||||
void addEscapedMessage(std::ostream& out, const std::string& message)
|
||||
std::string escapedMessageLines(const std::string& message)
|
||||
{
|
||||
std::ostringstream out;
|
||||
size_t written_out = 0;
|
||||
size_t all_content = message.length();
|
||||
size_t escape_char_index; // always relative to start of message
|
||||
|
|
@ -988,13 +1022,16 @@ namespace
|
|||
// write whatever was left
|
||||
out << message.substr(written_out, std::string::npos);
|
||||
}
|
||||
} </FS:LO> */
|
||||
return out.str();
|
||||
}
|
||||
|
||||
void writeToRecorders(const LLError::CallSite& site, const std::string& escaped_message, bool show_location = true, bool show_time = true, bool show_tags = true, bool show_level = true, bool show_function = true)
|
||||
void writeToRecorders(const LLError::CallSite& site, const std::string& message)
|
||||
{
|
||||
LLError::ELevel level = site.mLevel;
|
||||
LLError::SettingsConfigPtr s = LLError::Settings::getInstance()->getSettingsConfig();
|
||||
|
||||
|
||||
std::string escaped_message;
|
||||
|
||||
for (Recorders::const_iterator i = s->mRecorders.begin();
|
||||
i != s->mRecorders.end();
|
||||
++i)
|
||||
|
|
@ -1009,7 +1046,7 @@ namespace
|
|||
}
|
||||
message_stream << " ";
|
||||
|
||||
if (show_level && r->wantsLevel())
|
||||
if (r->wantsLevel())
|
||||
{
|
||||
message_stream << site.mLevelString;
|
||||
}
|
||||
|
|
@ -1021,19 +1058,30 @@ namespace
|
|||
}
|
||||
message_stream << " ";
|
||||
|
||||
if (r->wantsLocation() || level == LLError::LEVEL_ERROR || s->mPrintLocation)
|
||||
if (r->wantsLocation() || level == LLError::LEVEL_ERROR)
|
||||
{
|
||||
message_stream << site.mLocationString;
|
||||
}
|
||||
message_stream << " ";
|
||||
|
||||
if (show_function && r->wantsFunctionName())
|
||||
if (r->wantsFunctionName())
|
||||
{
|
||||
message_stream << site.mFunctionString;
|
||||
}
|
||||
message_stream << " : ";
|
||||
|
||||
message_stream << escaped_message;
|
||||
if (r->wantsMultiline())
|
||||
{
|
||||
message_stream << message;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (escaped_message.empty())
|
||||
{
|
||||
escaped_message = escapedMessageLines(message);
|
||||
}
|
||||
message_stream << escaped_message;
|
||||
}
|
||||
|
||||
r->recordMessage(level, message_stream.str());
|
||||
}
|
||||
|
|
@ -1235,10 +1283,11 @@ namespace LLError
|
|||
std::ostringstream prefix;
|
||||
if( nd::logging::throttle( site.mFile, site.mLine, &prefix ) )
|
||||
return;
|
||||
std::ostringstream message_stream;
|
||||
|
||||
if (site.mPrintOnce)
|
||||
{
|
||||
std::ostringstream message_stream;
|
||||
|
||||
std::map<std::string, unsigned int>::iterator messageIter = s->mUniqueLogMessages.find(message);
|
||||
if (messageIter != s->mUniqueLogMessages.end())
|
||||
{
|
||||
|
|
@ -1258,22 +1307,18 @@ namespace LLError
|
|||
message_stream << "ONCE: ";
|
||||
s->mUniqueLogMessages[message] = 1;
|
||||
}
|
||||
message_stream << message;
|
||||
message = message_stream.str();
|
||||
}
|
||||
|
||||
// <FS:Ansriel> Fix log output - we don't need an escaped output
|
||||
//addEscapedMessage(message_stream, message);
|
||||
message_stream << message;
|
||||
// </FS:Ansariel>
|
||||
std::string message_line(message_stream.str());
|
||||
|
||||
writeToRecorders(site, message_line);
|
||||
writeToRecorders(site, message);
|
||||
|
||||
if (site.mLevel == LEVEL_ERROR)
|
||||
{
|
||||
g->mFatalMessage = message_line;
|
||||
g->mFatalMessage = message;
|
||||
if (s->mCrashFunction)
|
||||
{
|
||||
s->mCrashFunction(message_line);
|
||||
s->mCrashFunction(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1581,3 +1626,4 @@ bool debugLoggingEnabled(const std::string& tag)
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -148,13 +148,22 @@ namespace LLError
|
|||
bool wantsLevel();
|
||||
bool wantsLocation();
|
||||
bool wantsFunctionName();
|
||||
bool wantsMultiline();
|
||||
|
||||
void showTime(bool show);
|
||||
void showTags(bool show);
|
||||
void showLevel(bool show);
|
||||
void showLocation(bool show);
|
||||
void showFunctionName(bool show);
|
||||
void showMultiline(bool show);
|
||||
|
||||
protected:
|
||||
bool mWantsTime,
|
||||
mWantsTags,
|
||||
mWantsLevel,
|
||||
mWantsLocation,
|
||||
mWantsFunctionName;
|
||||
bool mWantsTime;
|
||||
bool mWantsTags;
|
||||
bool mWantsLevel;
|
||||
bool mWantsLocation;
|
||||
bool mWantsFunctionName;
|
||||
bool mWantsMultiline;
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<Recorder> RecorderPtr;
|
||||
|
|
|
|||
|
|
@ -554,10 +554,8 @@ bool LLEventStream::post(const LLSD& event)
|
|||
*****************************************************************************/
|
||||
bool LLEventMailDrop::post(const LLSD& event)
|
||||
{
|
||||
bool posted = false;
|
||||
|
||||
if (!mSignal->empty())
|
||||
posted = LLEventStream::post(event);
|
||||
// forward the call to our base class
|
||||
bool posted = LLEventStream::post(event);
|
||||
|
||||
if (!posted)
|
||||
{ // if the event was not handled we will save it for later so that it can
|
||||
|
|
@ -573,16 +571,25 @@ LLBoundListener LLEventMailDrop::listen_impl(const std::string& name,
|
|||
const NameList& after,
|
||||
const NameList& before)
|
||||
{
|
||||
if (!mEventHistory.empty())
|
||||
// Before actually connecting this listener for subsequent post() calls,
|
||||
// first feed each of the saved events, in order, to the new listener.
|
||||
// Remove any that this listener consumes -- Effective STL, Item 9.
|
||||
for (auto hi(mEventHistory.begin()), hend(mEventHistory.end()); hi != hend; )
|
||||
{
|
||||
if (listener(mEventHistory.front()))
|
||||
if (listener(*hi))
|
||||
{
|
||||
mEventHistory.pop_front();
|
||||
// new listener consumed this event, erase it
|
||||
hi = mEventHistory.erase(hi);
|
||||
}
|
||||
else
|
||||
{
|
||||
// listener did not consume this event, just move along
|
||||
++hi;
|
||||
}
|
||||
}
|
||||
|
||||
// let base class perform the actual connection
|
||||
return LLEventStream::listen_impl(name, listener, after, before);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -650,15 +650,21 @@ public:
|
|||
* LLEventMailDrop
|
||||
*****************************************************************************/
|
||||
/**
|
||||
* LLEventMailDrop is a specialization of LLEventStream. Events are posted normally,
|
||||
* however if no listeners return that they have handled the event it is placed in
|
||||
* a queue. Subsequent attaching listeners will receive stored events from the queue
|
||||
* until a listener indicates that the event has been handled. In order to receive
|
||||
* multiple events from a mail drop the listener must disconnect and reconnect.
|
||||
* LLEventMailDrop is a specialization of LLEventStream. Events are posted
|
||||
* normally, however if no listener returns that it has handled the event
|
||||
* (returns true), it is placed in a queue. Subsequent attaching listeners
|
||||
* will receive stored events from the queue until some listener indicates
|
||||
* that the event has been handled.
|
||||
*
|
||||
* LLEventMailDrop completely decouples the timing of post() calls from
|
||||
* listen() calls: every event posted to an LLEventMailDrop is eventually seen
|
||||
* by all listeners, until some listener consumes it. The caveat is that each
|
||||
* event *must* eventually reach a listener that will consume it, else the
|
||||
* queue will grow to arbitrary length.
|
||||
*
|
||||
* @NOTE: When using an LLEventMailDrop (or LLEventQueue) with a LLEventTimeout or
|
||||
* LLEventFilter attaching the filter downstream using Timeout's constructor will
|
||||
* cause the MailDrop to discharge any of it's stored events. The timeout should
|
||||
* LLEventFilter attaching the filter downstream, using Timeout's constructor will
|
||||
* cause the MailDrop to discharge any of its stored events. The timeout should
|
||||
* instead be connected upstream using its listen() method.
|
||||
* See llcoro::suspendUntilEventOnWithTimeout() for an example.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -2115,6 +2115,9 @@ namespace LLInitParam
|
|||
typedef typename super_t::iterator iterator;
|
||||
typedef typename super_t::const_iterator const_iterator;
|
||||
|
||||
using super_t::operator();
|
||||
using super_t::operator const container_t&;
|
||||
|
||||
explicit Multiple(const char* name = "")
|
||||
: super_t(DERIVED_BLOCK::getBlockDescriptor(), name, container_t(), &validate, RANGE::minCount, RANGE::maxCount)
|
||||
{}
|
||||
|
|
|
|||
|
|
@ -47,9 +47,9 @@ class LLLeapImpl: public LLLeap
|
|||
LOG_CLASS(LLLeap);
|
||||
public:
|
||||
// Called only by LLLeap::create()
|
||||
LLLeapImpl(const std::string& desc, const std::vector<std::string>& plugin):
|
||||
LLLeapImpl(const LLProcess::Params& cparams):
|
||||
// We might reassign mDesc in the constructor body if it's empty here.
|
||||
mDesc(desc),
|
||||
mDesc(cparams.desc),
|
||||
// We expect multiple LLLeapImpl instances. Definitely tweak
|
||||
// mDonePump's name for uniqueness.
|
||||
mDonePump("LLLeap", true),
|
||||
|
|
@ -67,17 +67,17 @@ public:
|
|||
// this class or method name.
|
||||
mListener(new LLLeapListener(boost::bind(&LLLeapImpl::connect, this, _1, _2)))
|
||||
{
|
||||
// Rule out empty vector
|
||||
if (plugin.empty())
|
||||
// Rule out unpopulated Params block
|
||||
if (! cparams.executable.isProvided())
|
||||
{
|
||||
LLTHROW(Error("no plugin command"));
|
||||
}
|
||||
|
||||
// Don't leave desc empty either, but in this case, if we weren't
|
||||
// given one, we'll fake one.
|
||||
if (desc.empty())
|
||||
if (mDesc.empty())
|
||||
{
|
||||
mDesc = LLProcess::basename(plugin[0]);
|
||||
mDesc = LLProcess::basename(cparams.executable);
|
||||
// how about a toLower() variant that returns the transformed string?!
|
||||
std::string desclower(mDesc);
|
||||
LLStringUtil::toLower(desclower);
|
||||
|
|
@ -87,9 +87,9 @@ public:
|
|||
// notice Python specially: we provide Python LLSD serialization
|
||||
// support, so there's a pretty good reason to implement plugins
|
||||
// in that language.
|
||||
if (plugin.size() >= 2 && (desclower == "python" || desclower == "python.exe"))
|
||||
if (cparams.args.size() && (desclower == "python" || desclower == "python.exe"))
|
||||
{
|
||||
mDesc = LLProcess::basename(plugin[1]);
|
||||
mDesc = LLProcess::basename(cparams.args()[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -97,14 +97,10 @@ public:
|
|||
mDonePump.listen("LLLeap", boost::bind(&LLLeapImpl::bad_launch, this, _1));
|
||||
|
||||
// Okay, launch child.
|
||||
LLProcess::Params params;
|
||||
// Get a modifiable copy of params block to set files and postend.
|
||||
LLProcess::Params params(cparams);
|
||||
// copy our deduced mDesc back into the params block
|
||||
params.desc = mDesc;
|
||||
std::vector<std::string>::const_iterator pi(plugin.begin()), pend(plugin.end());
|
||||
params.executable = *pi++;
|
||||
for ( ; pi != pend; ++pi)
|
||||
{
|
||||
params.args.add(*pi);
|
||||
}
|
||||
params.files.add(LLProcess::FileParam("pipe")); // stdin
|
||||
params.files.add(LLProcess::FileParam("pipe")); // stdout
|
||||
params.files.add(LLProcess::FileParam("pipe")); // stderr
|
||||
|
|
@ -429,17 +425,17 @@ private:
|
|||
boost::scoped_ptr<LLLeapListener> mListener;
|
||||
};
|
||||
|
||||
// This must follow the declaration of LLLeapImpl, so it may as well be last.
|
||||
LLLeap* LLLeap::create(const std::string& desc, const std::vector<std::string>& plugin, bool exc)
|
||||
// These must follow the declaration of LLLeapImpl, so they may as well be last.
|
||||
LLLeap* LLLeap::create(const LLProcess::Params& params, bool exc)
|
||||
{
|
||||
// If caller is willing to permit exceptions, just instantiate.
|
||||
if (exc)
|
||||
return new LLLeapImpl(desc, plugin);
|
||||
return new LLLeapImpl(params);
|
||||
|
||||
// Caller insists on suppressing LLLeap::Error. Very well, catch it.
|
||||
try
|
||||
{
|
||||
return new LLLeapImpl(desc, plugin);
|
||||
return new LLLeapImpl(params);
|
||||
}
|
||||
catch (const LLLeap::Error&)
|
||||
{
|
||||
|
|
@ -447,6 +443,23 @@ LLLeap* LLLeap::create(const std::string& desc, const std::vector<std::string>&
|
|||
}
|
||||
}
|
||||
|
||||
LLLeap* LLLeap::create(const std::string& desc, const std::vector<std::string>& plugin, bool exc)
|
||||
{
|
||||
LLProcess::Params params;
|
||||
params.desc = desc;
|
||||
std::vector<std::string>::const_iterator pi(plugin.begin()), pend(plugin.end());
|
||||
// could validate here, but let's rely on LLLeapImpl's constructor
|
||||
if (pi != pend)
|
||||
{
|
||||
params.executable = *pi++;
|
||||
}
|
||||
for ( ; pi != pend; ++pi)
|
||||
{
|
||||
params.args.add(*pi);
|
||||
}
|
||||
return create(params, exc);
|
||||
}
|
||||
|
||||
LLLeap* LLLeap::create(const std::string& desc, const std::string& plugin, bool exc)
|
||||
{
|
||||
// Use LLStringUtil::getTokens() to parse the command line
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "llinstancetracker.h"
|
||||
#include "llexception.h"
|
||||
#include "llprocess.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
|
@ -61,6 +62,19 @@ public:
|
|||
static LLLeap* create(const std::string& desc, const std::string& plugin,
|
||||
bool exc=true);
|
||||
|
||||
/**
|
||||
* Pass an LLProcess::Params instance to specify desc, executable, args et al.
|
||||
*
|
||||
* Note that files and postend are set implicitly; any values you set in
|
||||
* those fields will be disregarded.
|
||||
*
|
||||
* Pass exc=false to suppress LLLeap::Error exception. Obviously in that
|
||||
* case the caller cannot discover the nature of the error, merely that an
|
||||
* error of some kind occurred (because create() returned NULL). Either
|
||||
* way, the error is logged.
|
||||
*/
|
||||
static LLLeap* create(const LLProcess::Params& params, bool exc=true);
|
||||
|
||||
/**
|
||||
* Exception thrown for invalid create() arguments, e.g. no plugin
|
||||
* program. This is more resiliant than an LL_ERRS failure, because the
|
||||
|
|
|
|||
|
|
@ -78,8 +78,12 @@ namespace tut
|
|||
class TestRecorder : public LLError::Recorder
|
||||
{
|
||||
public:
|
||||
TestRecorder() { mWantsTime = false; mWantsTags = true; }
|
||||
virtual ~TestRecorder() { }
|
||||
TestRecorder()
|
||||
{
|
||||
showTime(false);
|
||||
}
|
||||
virtual ~TestRecorder()
|
||||
{}
|
||||
|
||||
virtual void recordMessage(LLError::ELevel level,
|
||||
const std::string& message)
|
||||
|
|
@ -90,8 +94,6 @@ namespace tut
|
|||
int countMessages() { return (int) mMessages.size(); }
|
||||
void clearMessages() { mMessages.clear(); }
|
||||
|
||||
void setWantsTime(bool t) { mWantsTime = t; }
|
||||
|
||||
std::string message(int n)
|
||||
{
|
||||
std::ostringstream test_name;
|
||||
|
|
@ -139,9 +141,14 @@ namespace tut
|
|||
}
|
||||
|
||||
void setWantsTime(bool t)
|
||||
{
|
||||
boost::dynamic_pointer_cast<TestRecorder>(mRecorder)->setWantsTime(t);
|
||||
}
|
||||
{
|
||||
boost::dynamic_pointer_cast<TestRecorder>(mRecorder)->showTime(t);
|
||||
}
|
||||
|
||||
void setWantsMultiline(bool t)
|
||||
{
|
||||
boost::dynamic_pointer_cast<TestRecorder>(mRecorder)->showMultiline(t);
|
||||
}
|
||||
|
||||
std::string message(int n)
|
||||
{
|
||||
|
|
@ -378,27 +385,6 @@ namespace
|
|||
}
|
||||
}
|
||||
|
||||
namespace tut
|
||||
{
|
||||
template<> template<>
|
||||
void ErrorTestObject::test<5>()
|
||||
// file and line information in log messages
|
||||
{
|
||||
std::string location = writeReturningLocation();
|
||||
// expecting default to not print location information
|
||||
|
||||
LLError::setPrintLocation(true);
|
||||
writeReturningLocation();
|
||||
|
||||
LLError::setPrintLocation(false);
|
||||
writeReturningLocation();
|
||||
|
||||
ensure_message_does_not_contain(0, location);
|
||||
ensure_message_field_equals(1, LOCATION_FIELD, location);
|
||||
ensure_message_does_not_contain(2, location);
|
||||
}
|
||||
}
|
||||
|
||||
/* The following helper functions and class members all log a simple message
|
||||
from some particular function scope. Each function takes a bool argument
|
||||
that indicates if it should log its own name or not (in the manner that
|
||||
|
|
@ -512,6 +498,39 @@ namespace
|
|||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
void writeMsgNeedsEscaping()
|
||||
{
|
||||
LL_DEBUGS("WriteTag") << "backslash\\" << LL_ENDL;
|
||||
LL_INFOS("WriteTag") << "newline\nafternewline" << LL_ENDL;
|
||||
LL_WARNS("WriteTag") << "return\rafterreturn" << LL_ENDL;
|
||||
|
||||
LL_DEBUGS("WriteTag") << "backslash\\backslash\\" << LL_ENDL;
|
||||
LL_INFOS("WriteTag") << "backslash\\newline\nanothernewline\nafternewline" << LL_ENDL;
|
||||
LL_WARNS("WriteTag") << "backslash\\returnnewline\r\n\\afterbackslash" << LL_ENDL;
|
||||
}
|
||||
};
|
||||
|
||||
namespace tut
|
||||
{
|
||||
template<> template<>
|
||||
void ErrorTestObject::test<5>()
|
||||
// backslash, return, and newline are not escaped with backslashes
|
||||
{
|
||||
LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
|
||||
setWantsMultiline(true);
|
||||
writeMsgNeedsEscaping(); // but should not be now
|
||||
ensure_message_field_equals(0, MSG_FIELD, "backslash\\");
|
||||
ensure_message_field_equals(1, MSG_FIELD, "newline\nafternewline");
|
||||
ensure_message_field_equals(2, MSG_FIELD, "return\rafterreturn");
|
||||
ensure_message_field_equals(3, MSG_FIELD, "backslash\\backslash\\");
|
||||
ensure_message_field_equals(4, MSG_FIELD, "backslash\\newline\nanothernewline\nafternewline");
|
||||
ensure_message_field_equals(5, MSG_FIELD, "backslash\\returnnewline\r\n\\afterbackslash");
|
||||
ensure_message_count(6);
|
||||
}
|
||||
}
|
||||
|
||||
namespace tut
|
||||
{
|
||||
template<> template<>
|
||||
|
|
@ -583,7 +602,6 @@ namespace tut
|
|||
// special handling of LL_ERRS() calls
|
||||
void ErrorTestObject::test<8>()
|
||||
{
|
||||
LLError::setPrintLocation(false);
|
||||
std::string location = errorReturningLocation();
|
||||
|
||||
ensure_message_field_equals(0, LOCATION_FIELD, location);
|
||||
|
|
@ -630,15 +648,15 @@ namespace tut
|
|||
// output order
|
||||
void ErrorTestObject::test<10>()
|
||||
{
|
||||
LLError::setPrintLocation(true);
|
||||
LLError::setTimeFunction(roswell);
|
||||
setWantsTime(true);
|
||||
|
||||
std::string location,
|
||||
function;
|
||||
writeReturningLocationAndFunction(location, function);
|
||||
|
||||
ensure_equals("order is time level tags location function message",
|
||||
message(0),
|
||||
message(0),
|
||||
roswell() + " INFO " + "# " /* no tag */ + location + " " + function + " : " + "apple");
|
||||
}
|
||||
|
||||
|
|
@ -658,7 +676,7 @@ namespace tut
|
|||
LLError::setTimeFunction(roswell);
|
||||
|
||||
LLError::RecorderPtr anotherRecorder(new TestRecorder());
|
||||
boost::dynamic_pointer_cast<TestRecorder>(anotherRecorder)->setWantsTime(true);
|
||||
boost::dynamic_pointer_cast<TestRecorder>(anotherRecorder)->showTime(true);
|
||||
LLError::addRecorder(anotherRecorder);
|
||||
|
||||
LL_INFOS() << "baz" << LL_ENDL;
|
||||
|
|
@ -835,20 +853,6 @@ namespace tut
|
|||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
void writeMsgNeedsEscaping()
|
||||
{
|
||||
LL_DEBUGS("WriteTag") << "backslash\\" << LL_ENDL;
|
||||
LL_INFOS("WriteTag") << "newline\nafternewline" << LL_ENDL;
|
||||
LL_WARNS("WriteTag") << "return\rafterreturn" << LL_ENDL;
|
||||
|
||||
LL_DEBUGS("WriteTag") << "backslash\\backslash\\" << LL_ENDL;
|
||||
LL_INFOS("WriteTag") << "backslash\\newline\nanothernewline\nafternewline" << LL_ENDL;
|
||||
LL_WARNS("WriteTag") << "backslash\\returnnewline\r\n\\afterbackslash" << LL_ENDL;
|
||||
}
|
||||
};
|
||||
|
||||
namespace tut
|
||||
{
|
||||
template<> template<>
|
||||
|
|
|
|||
|
|
@ -90,9 +90,12 @@ void LLNotificationsListener::requestAdd(const LLSD& event_data) const
|
|||
{
|
||||
if(event_data.has("reply"))
|
||||
{
|
||||
LLSD payload(event_data["payload"]);
|
||||
// copy reqid, if provided, to link response with request
|
||||
payload["reqid"] = event_data["reqid"];
|
||||
mNotifications.add(event_data["name"],
|
||||
event_data["substitutions"],
|
||||
event_data["payload"],
|
||||
payload,
|
||||
boost::bind(&LLNotificationsListener::NotificationResponder,
|
||||
this,
|
||||
event_data["reply"].asString(),
|
||||
|
|
@ -112,10 +115,12 @@ void LLNotificationsListener::NotificationResponder(const std::string& reply_pum
|
|||
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);
|
||||
LLSD response_event;
|
||||
response_event["notification"] = notification;
|
||||
response_event["response"] = response;
|
||||
// surface reqid at top level of response for request/response protocol
|
||||
response_event["reqid"] = notification["payload"]["reqid"];
|
||||
LLEventPumps::getInstance()->obtain(reply_pump).post(response_event);
|
||||
}
|
||||
|
||||
void LLNotificationsListener::listChannels(const LLSD& params) const
|
||||
|
|
|
|||
|
|
@ -187,9 +187,9 @@ void LLDir_Mac::initAppDirs(const std::string &app_name,
|
|||
if (!app_read_only_data_dir.empty())
|
||||
{
|
||||
mAppRODataDir = app_read_only_data_dir;
|
||||
mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
|
||||
mSkinBaseDir = add(mAppRODataDir, "skins");
|
||||
}
|
||||
mCAFile = getExpandedFilename(LL_PATH_EXECUTABLE, "../Resources", "ca-bundle.crt");
|
||||
mCAFile = add(mAppRODataDir, "ca-bundle.crt");
|
||||
}
|
||||
|
||||
//<FS:TS> Used by LGG's selection beams
|
||||
|
|
|
|||
|
|
@ -1446,12 +1446,10 @@ static CursorRef gCursors[UI_CURSOR_COUNT];
|
|||
static void initPixmapCursor(int cursorid, int hotspotX, int hotspotY)
|
||||
{
|
||||
// cursors are in <Application Bundle>/Contents/Resources/cursors_mac/UI_CURSOR_FOO.tif
|
||||
std::string fullpath = gDirUtilp->getAppRODataDir();
|
||||
fullpath += gDirUtilp->getDirDelimiter();
|
||||
fullpath += "cursors_mac";
|
||||
fullpath += gDirUtilp->getDirDelimiter();
|
||||
fullpath += cursorIDToName(cursorid);
|
||||
fullpath += ".tif";
|
||||
std::string fullpath = gDirUtilp->add(
|
||||
gDirUtilp->getAppRODataDir(),
|
||||
"cursors_mac",
|
||||
cursorIDToName(cursorid) + std::string(".tif"));
|
||||
|
||||
gCursors[cursorid] = createImageCursor(fullpath.c_str(), hotspotX, hotspotY);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ include(GLOD)
|
|||
include(Hunspell)
|
||||
include(JsonCpp)
|
||||
include(LLAppearance)
|
||||
include(LLBase)
|
||||
include(LLAudio)
|
||||
include(LLCA)
|
||||
include(LLCharacter)
|
||||
|
|
@ -51,7 +50,6 @@ include(OPENAL)
|
|||
include(OpenGL)
|
||||
include(OpenSSL)
|
||||
include(PNG)
|
||||
include(Requests)
|
||||
include(TemplateCheck)
|
||||
include(UI)
|
||||
include(UnixInstall)
|
||||
|
|
@ -2536,8 +2534,7 @@ if (DARWIN)
|
|||
# magically known to CMake -- it's that these names are referenced in the
|
||||
# Info-SecondLife.plist file in the configure_file() directive below.
|
||||
set(product "${VIEWER_CHANNEL}")
|
||||
# this is the setting for the Python wrapper, see SL-322 and WRAPPER line in Info-SecondLife.plist
|
||||
set(MACOSX_WRAPPER_EXECUTABLE_NAME "SL_Launcher")
|
||||
set(MACOSX_EXECUTABLE_NAME "${VIEWER_CHANNEL}")
|
||||
set(MACOSX_BUNDLE_INFO_STRING "${VIEWER_CHANNEL}")
|
||||
set(MACOSX_BUNDLE_ICON_FILE "firestorm_icon.icns")
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.phoenixviewer.firestorm.viewer-${ND_VIEWER_FLAVOR}")
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${MACOSX_WRAPPER_EXECUTABLE_NAME}</string>
|
||||
<string>${MACOSX_EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>${MACOSX_BUNDLE_INFO_STRING}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
|
|
|
|||
|
|
@ -6366,6 +6366,17 @@
|
|||
<key>Value</key>
|
||||
<real>96.0</real>
|
||||
</map>
|
||||
<key>ForceAddressSize</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Force Windows update to 32-bit or 64-bit viewer.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>ForceAssetFail</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -17210,19 +17221,6 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Value</key>
|
||||
<real>1.0</real>
|
||||
</map>
|
||||
<key>VerboseLogs</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Display source file and line number for each log item for debugging purposes</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
<key>Backup</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>VertexShaderEnable</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -21080,7 +21078,7 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<string>if true, disables running the GPU benchmark at startup
|
||||
(default to class 1)</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
|
|
|
|||
|
|
@ -341,7 +341,7 @@ SetOutPath "$INSTDIR"
|
|||
CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\$INSTSHORTCUT.lnk" \
|
||||
"$INSTDIR\$VIEWER_EXE" "$SHORTCUT_LANG_PARAM"
|
||||
# <FS:Ansariel> Remove VMP
|
||||
#"$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE"
|
||||
#"$INSTDIR\$VIEWER_EXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE"
|
||||
|
||||
|
||||
WriteINIStr "$SMPROGRAMS\$INSTSHORTCUT\SL Create Account.url" \
|
||||
|
|
@ -365,11 +365,11 @@ SetOutPath "$INSTDIR"
|
|||
CreateShortCut "$DESKTOP\$INSTSHORTCUT.lnk" \
|
||||
"$INSTDIR\$VIEWER_EXE" "$SHORTCUT_LANG_PARAM"
|
||||
# <FS:Ansariel> Remove VMP
|
||||
#"$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE"
|
||||
#"$INSTDIR\$VIEWER_EXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE"
|
||||
CreateShortCut "$INSTDIR\$INSTSHORTCUT.lnk" \
|
||||
"$INSTDIR\$VIEWER_EXE" "$SHORTCUT_LANG_PARAM"
|
||||
# <FS:Ansariel> Remove VMP
|
||||
#"$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE"
|
||||
#"$INSTDIR\$VIEWER_EXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE"
|
||||
CreateShortCut "$INSTDIR\Uninstall $INSTSHORTCUT.lnk" \
|
||||
'"$INSTDIR\uninst.exe"' ''
|
||||
|
||||
|
|
@ -377,7 +377,6 @@ CreateShortCut "$INSTDIR\Uninstall $INSTSHORTCUT.lnk" \
|
|||
WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\The Phoenix Firestorm Project\$INSTPROG" "" "$INSTDIR"
|
||||
WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\The Phoenix Firestorm Project\$INSTPROG" "Version" "${VERSION_LONG}"
|
||||
WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\The Phoenix Firestorm Project\$INSTPROG" "Shortcut" "$INSTSHORTCUT"
|
||||
#WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\The Phoenix Firestorm Project\$INSTPROG" "Exe" "$INSTEXE"
|
||||
WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\The Phoenix Firestorm Project\$INSTPROG" "Exe" "$VIEWER_EXE"
|
||||
WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "Publisher" "The Phoenix Firestorm Project, Inc."
|
||||
WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "URLInfoAbout" "http://www.firestormviewer.org"
|
||||
|
|
@ -395,11 +394,9 @@ ${Else}
|
|||
${EndIf}
|
||||
|
||||
# from FS:Ansariel
|
||||
#WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "DisplayIcon" '"$INSTDIR\$INSTEXE"'
|
||||
WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "DisplayIcon" '"$INSTDIR\$VIEWER_EXE"'
|
||||
|
||||
# BUG-2707 Disable SEHOP for installed viewer.
|
||||
#WriteRegDWORD HKEY_LOCAL_MACHINE "Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\$INSTEXE" "DisableExceptionChainValidation" 1
|
||||
WriteRegDWORD HKEY_LOCAL_MACHINE "Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\$VIEWER_EXE" "DisableExceptionChainValidation" 1
|
||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "NoModify" 1
|
||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "NoRepair" 1
|
||||
|
|
@ -419,11 +416,8 @@ WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info\DefaultIcon" "" '"$INSTDIR\$
|
|||
# URL param must be last item passed to viewer, it ignores subsequent params to avoid parameter injection attacks.
|
||||
WriteRegExpandStr HKEY_CLASSES_ROOT "x-grid-location-info\shell\open\command" "" '"$INSTDIR\$VIEWER_EXE" -url "%1"'
|
||||
|
||||
# Only allow Launcher to be the icon
|
||||
# <FS:Ansariel> Remove VMP
|
||||
#WriteRegStr HKEY_CLASSES_ROOT "Applications\$INSTEXE" "IsHostApp" ""
|
||||
#WriteRegStr HKEY_CLASSES_ROOT "Applications\${VIEWER_EXE}" "NoStartPage" ""
|
||||
# </FS:Ansariel> Remove VMP
|
||||
WriteRegStr HKEY_CLASSES_ROOT "Applications\$VIEWER_EXE" "IsHostApp" ""
|
||||
##WriteRegStr HKEY_CLASSES_ROOT "Applications\${VIEWER_EXE}" "NoStartPage" ""
|
||||
|
||||
# <FS:CR> Register hop:// protocol registry info
|
||||
WriteRegStr HKEY_CLASSES_ROOT "hop" "(default)" "URL:Second Life"
|
||||
|
|
@ -453,7 +447,6 @@ Section Uninstall
|
|||
# Start with some default values.
|
||||
StrCpy $INSTPROG "${INSTNAME}"
|
||||
StrCpy $INSTEXE "${INSTEXE}"
|
||||
StrCpy $VIEWER_EXE "${VIEWER_EXE}" # <FS:Ansariel> Disable VMP
|
||||
StrCpy $INSTSHORTCUT "${SHORTCUT}"
|
||||
|
||||
# Make sure the user can install/uninstall
|
||||
|
|
@ -469,13 +462,9 @@ Call un.CloseSecondLife
|
|||
DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\The Phoenix Firestorm Project\$INSTPROG"
|
||||
DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG"
|
||||
# BUG-2707 Remove entry that disabled SEHOP
|
||||
# <FS:Ansariel> Disable VMP
|
||||
#DeleteRegKey HKEY_LOCAL_MACHINE "Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\$INSTEXE"
|
||||
DeleteRegKey HKEY_LOCAL_MACHINE "Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\$VIEWER_EXE"
|
||||
# <FS:Ansariel> Remove VMP
|
||||
#DeleteRegKey HKEY_CLASSES_ROOT "Applications\$INSTEXE"
|
||||
#DeleteRegKey HKEY_CLASSES_ROOT "Applications\${VIEWER_EXE}"
|
||||
# </FS:Ansariel> Remove VMP
|
||||
DeleteRegKey HKEY_LOCAL_MACHINE "Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\${VIEWER_EXE}"
|
||||
##DeleteRegKey HKEY_CLASSES_ROOT "Applications\$INSTEXE"
|
||||
DeleteRegKey HKEY_CLASSES_ROOT "Applications\${VIEWER_EXE}"
|
||||
|
||||
# Clean up shortcuts
|
||||
Delete "$SMPROGRAMS\$INSTSHORTCUT\*.*"
|
||||
|
|
@ -754,7 +743,7 @@ FunctionEnd
|
|||
;; After install completes, launch app
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
Function .onInstSuccess
|
||||
Call CheckWindowsServPack # Warn if not on the latest SP before asking to launch.
|
||||
Call CheckWindowsServPack # Warn if not on the latest SP before asking to launch.
|
||||
# <FS:Ansariel> Disable VMP
|
||||
#Push $R0
|
||||
#Push $0
|
||||
|
|
@ -797,7 +786,22 @@ label_ask_launch:
|
|||
IDYES label_launch IDNO label_no_launch
|
||||
|
||||
label_launch:
|
||||
# Assumes SetOutPath $INSTDIR
|
||||
# Assumes SetOutPath $INSTDIR
|
||||
# Run INSTEXE (our updater), passing VIEWER_EXE plus the command-line
|
||||
# arguments built into our shortcuts. This gives the updater a chance
|
||||
# to verify that the viewer we just installed is appropriate for the
|
||||
# running system -- or, if not, to download and install a different
|
||||
# viewer. For instance, if a user running 32-bit Windows installs a
|
||||
# 64-bit viewer, it cannot run on this system. But since the updater
|
||||
# is a 32-bit executable even in the 64-bit viewer package, the
|
||||
# updater can detect the problem and adapt accordingly.
|
||||
# Once everything is in order, the updater will run the specified
|
||||
# viewer with the specified params.
|
||||
# Quote the updater executable and the viewer executable because each
|
||||
# must be a distinct command-line token, but DO NOT quote the language
|
||||
# string because it must decompose into separate command-line tokens.
|
||||
# <FS:Ansariel> No updater, thanks!
|
||||
# Exec '"$INSTDIR\$INSTEXE" precheck "$INSTDIR\$VIEWER_EXE" $SHORTCUT_LANG_PARAM'
|
||||
Exec '"$WINDIR\explorer.exe" "$INSTDIR\$INSTSHORTCUT.lnk"'
|
||||
label_no_launch:
|
||||
Pop $R0
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@
|
|||
|
||||
#import "llappdelegate-objc.h"
|
||||
#if defined(LL_BUGSPLAT)
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <vector>
|
||||
@import BugsplatMac;
|
||||
// derived from BugsplatMac's BugsplatTester/AppDelegate.m
|
||||
@interface LLAppDelegate () <BugsplatStartupManagerDelegate>
|
||||
|
|
@ -288,25 +290,59 @@
|
|||
infos("bugsplatStartupManagerWillSendCrashReport");
|
||||
}
|
||||
|
||||
- (BugsplatAttachment *)attachmentForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager {
|
||||
std::string logfile = CrashMetadata_instance().logFilePathname;
|
||||
// Still to do:
|
||||
// userSettingsPathname
|
||||
// staticDebugPathname
|
||||
// but the BugsplatMac version 1.0.5 BugsplatStartupManagerDelegate API
|
||||
// doesn't yet provide a way to attach more than one file.
|
||||
NSString *ns_logfile = [NSString stringWithCString:logfile.c_str()
|
||||
encoding:NSUTF8StringEncoding];
|
||||
NSData *data = [NSData dataWithContentsOfFile:ns_logfile];
|
||||
struct AttachmentInfo
|
||||
{
|
||||
AttachmentInfo(const std::string& path, const std::string& type):
|
||||
pathname(path),
|
||||
basename(boost::filesystem::path(path).filename().string()),
|
||||
mimetype(type)
|
||||
{}
|
||||
|
||||
// Apologies for the hard-coded log-file basename, but I do not know the
|
||||
// incantation for "$(basename "$logfile")" in this language.
|
||||
BugsplatAttachment *attachment =
|
||||
[[BugsplatAttachment alloc] initWithFilename:@"SecondLife.log"
|
||||
attachmentData:data
|
||||
contentType:@"text/plain"];
|
||||
infos("attachmentForBugsplatStartupManager attaching " + logfile);
|
||||
return attachment;
|
||||
std::string pathname, basename, mimetype;
|
||||
};
|
||||
|
||||
- (NSArray<BugsplatAttachment *> *)attachmentsForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager
|
||||
{
|
||||
const CrashMetadata& metadata(CrashMetadata_instance());
|
||||
|
||||
// Since we must do very similar processing for each of several file
|
||||
// pathnames, start by collecting them into a vector so we can iterate
|
||||
// instead of spelling out the logic for each.
|
||||
std::vector<AttachmentInfo> info{
|
||||
AttachmentInfo(metadata.logFilePathname, "text/plain"),
|
||||
AttachmentInfo(metadata.userSettingsPathname, "text/xml"),
|
||||
AttachmentInfo(metadata.staticDebugPathname, "text/xml")
|
||||
};
|
||||
|
||||
// We "happen to know" that info[0].basename is "SecondLife.old" -- due to
|
||||
// the fact that BugsplatMac only notices a crash during the viewer run
|
||||
// following the crash. Replace .old with .log to reduce confusion.
|
||||
info[0].basename =
|
||||
boost::filesystem::path(info[0].pathname).stem().string() + ".log";
|
||||
|
||||
NSMutableArray *attachments = [[NSMutableArray alloc] init];
|
||||
|
||||
// Iterate over each AttachmentInfo in info vector
|
||||
for (const AttachmentInfo& attach : info)
|
||||
{
|
||||
NSString *nspathname = [NSString stringWithCString:attach.pathname.c_str()
|
||||
encoding:NSUTF8StringEncoding];
|
||||
NSString *nsbasename = [NSString stringWithCString:attach.basename.c_str()
|
||||
encoding:NSUTF8StringEncoding];
|
||||
NSString *nsmimetype = [NSString stringWithCString:attach.mimetype.c_str()
|
||||
encoding:NSUTF8StringEncoding];
|
||||
NSData *nsdata = [NSData dataWithContentsOfFile:nspathname];
|
||||
|
||||
BugsplatAttachment *attachment =
|
||||
[[BugsplatAttachment alloc] initWithFilename:nsbasename
|
||||
attachmentData:nsdata
|
||||
contentType:nsmimetype];
|
||||
|
||||
[attachments addObject:attachment];
|
||||
infos("attachmentsForBugsplatStartupManager attaching " + attach.pathname);
|
||||
}
|
||||
|
||||
return attachments;
|
||||
}
|
||||
|
||||
- (void)bugsplatStartupManagerDidFinishSendingCrashReport:(BugsplatStartupManager *)bugsplatStartupManager
|
||||
|
|
|
|||
|
|
@ -1070,11 +1070,6 @@ bool LLAppViewer::init()
|
|||
mNumSessions++;
|
||||
gSavedSettings.setS32("NumSessions", mNumSessions);
|
||||
|
||||
if (gSavedSettings.getBOOL("VerboseLogs"))
|
||||
{
|
||||
LLError::setPrintLocation(true);
|
||||
}
|
||||
|
||||
// LLKeyboard relies on LLUI to know what some accelerator keys are called.
|
||||
LLKeyboard::setStringTranslatorFunc( LLTrans::getKeyboardString );
|
||||
|
||||
|
|
@ -1285,28 +1280,6 @@ bool LLAppViewer::init()
|
|||
}
|
||||
}
|
||||
|
||||
// don't nag developers who need to run the executable directly
|
||||
#if LL_RELEASE_FOR_DOWNLOAD
|
||||
// <FS:Ansariel> Disable VMP
|
||||
// MAINT-8305: If we're processing a SLURL, skip the launcher check.
|
||||
//if (gSavedSettings.getString("CmdLineLoginLocation").empty())
|
||||
//{
|
||||
// const char* PARENT = getenv("PARENT");
|
||||
// if (! (PARENT && std::string(PARENT) == "SL_Launcher"))
|
||||
// {
|
||||
// // Don't directly run this executable. Please run the launcher, which
|
||||
// // will run the viewer itself.
|
||||
// // Naturally we do not consider this bulletproof. The point is to
|
||||
// // gently remind a user who *inadvertently* finds him/herself in this
|
||||
// // situation to do things the Right Way. Anyone who intentionally
|
||||
// // bypasses this mechanism needs no reminder that s/he's shooting
|
||||
// // him/herself in the foot.
|
||||
// LLNotificationsUtil::add("RunLauncher");
|
||||
// }
|
||||
//}
|
||||
// </FS:Ansariel>
|
||||
#endif
|
||||
|
||||
#if LL_WINDOWS
|
||||
if (gGLManager.mGLVersion < LLFeatureManager::getInstance()->getExpectedGLVersion())
|
||||
{
|
||||
|
|
@ -1356,6 +1329,38 @@ bool LLAppViewer::init()
|
|||
|
||||
gGLActive = FALSE;
|
||||
|
||||
// <FS:Ansariel> Disable updater
|
||||
// LLProcess::Params updater;
|
||||
// updater.desc = "updater process";
|
||||
// // Because it's the updater, it MUST persist beyond the lifespan of the
|
||||
// // viewer itself.
|
||||
// updater.autokill = false;
|
||||
//#if LL_WINDOWS
|
||||
// updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "updater.exe");
|
||||
//#elif LL_DARWIN
|
||||
// // explicitly run the system Python interpreter on updater.py
|
||||
// updater.executable = "python";
|
||||
// updater.args.add(gDirUtilp->add(gDirUtilp->getAppRODataDir(), "updater", "updater.py"));
|
||||
//#else
|
||||
// updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "updater");
|
||||
//#endif
|
||||
// // add LEAP mode command-line argument to whichever of these we selected
|
||||
// updater.args.add("leap");
|
||||
// // UpdaterServiceSettings
|
||||
// updater.args.add(stringize(gSavedSettings.getU32("UpdaterServiceSetting")));
|
||||
// // channel
|
||||
// updater.args.add(LLVersionInfo::getChannel());
|
||||
// // testok
|
||||
// updater.args.add(stringize(gSavedSettings.getBOOL("UpdaterWillingToTest")));
|
||||
// // UpdaterServiceURL
|
||||
// updater.args.add(gSavedSettings.getString("UpdaterServiceURL"));
|
||||
// // ForceAddressSize
|
||||
// updater.args.add(stringize(gSavedSettings.getU32("ForceAddressSize")));
|
||||
//
|
||||
// // Run the updater. An exception from launching the updater should bother us.
|
||||
// LLLeap::create(updater, true);
|
||||
// </FS:Ansariel>
|
||||
|
||||
// Iterate over --leap command-line options. But this is a bit tricky: if
|
||||
// there's only one, it won't be an array at all.
|
||||
LLSD LeapCommand(gSavedSettings.getLLSD("LeapCommand"));
|
||||
|
|
@ -1991,7 +1996,7 @@ bool LLAppViewer::cleanup()
|
|||
|
||||
release_start_screen(); // just in case
|
||||
|
||||
LLError::logToFixedBuffer(NULL);
|
||||
LLError::logToFixedBuffer(NULL); // stop the fixed buffer recorder
|
||||
|
||||
LL_INFOS() << "Cleaning Up" << LL_ENDL;
|
||||
|
||||
|
|
@ -4706,14 +4711,6 @@ void LLAppViewer::requestQuit()
|
|||
gAgentAvatarp->updateAvatarRezMetrics(true); // force a last packet to be sent.
|
||||
}
|
||||
|
||||
// Try to send last batch of avatar rez metrics.
|
||||
// <FS:Ansariel> LL merge error
|
||||
//if (!gDisconnected && isAgentAvatarValid())
|
||||
//{
|
||||
// gAgentAvatarp->updateAvatarRezMetrics(true); // force a last packet to be sent.
|
||||
//}
|
||||
// </FS:Ansariel>
|
||||
|
||||
LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);
|
||||
effectp->setPositionGlobal(gAgent.getPositionGlobal());
|
||||
effectp->setColor(LLColor4U(gAgent.getEffectColor()));
|
||||
|
|
|
|||
|
|
@ -268,14 +268,12 @@ bool LLLoginInstance::handleLoginEvent(const LLSD& event)
|
|||
|
||||
mLoginState = event["state"].asString();
|
||||
mResponseData = event["data"];
|
||||
|
||||
|
||||
if(event.has("transfer_rate"))
|
||||
{
|
||||
mTransferRate = event["transfer_rate"].asReal();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Call the method registered in constructor, if any, for more specific
|
||||
// handling
|
||||
mDispatcher.try_call(event);
|
||||
|
|
@ -291,6 +289,14 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
|
|||
// Login has failed.
|
||||
// Figure out why and respond...
|
||||
LLSD response = event["data"];
|
||||
LLSD updater = response["updater"];
|
||||
|
||||
// Always provide a response to the updater, if in fact the updater
|
||||
// contacted us, if in fact the ping contains a 'reply' key. Most code
|
||||
// paths tell it not to proceed with updating.
|
||||
ResponsePtr resp(std::make_shared<LLEventAPI::Response>
|
||||
(LLSDMap("update", false), updater));
|
||||
|
||||
std::string reason_response = response["reason"].asString();
|
||||
std::string message_response = response["message"].asString();
|
||||
LL_DEBUGS("LLLogin") << "reason " << reason_response
|
||||
|
|
@ -342,17 +348,44 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
|
|||
}
|
||||
else if(reason_response == "update")
|
||||
{
|
||||
// This shouldn't happen - the viewer manager should have forced an update;
|
||||
// possibly the user ran the viewer directly and bypassed the update check
|
||||
// This can happen if the user clicked Login quickly, before we heard
|
||||
// back from the Viewer Version Manager, but login failed because
|
||||
// login.cgi is insisting on a required update. We were called with an
|
||||
// event that bundles both the login.cgi 'response' and the
|
||||
// synchronization event from the 'updater'.
|
||||
std::string required_version = response["message_args"]["VERSION"];
|
||||
LL_WARNS("LLLogin") << "Login failed because an update to version " << required_version << " is required." << LL_ENDL;
|
||||
|
||||
if (gViewerWindow)
|
||||
gViewerWindow->setShowProgress(FALSE, FALSE);
|
||||
|
||||
LLSD data(LLSD::emptyMap());
|
||||
data["VERSION"] = required_version;
|
||||
LLNotificationsUtil::add("RequiredUpdate", data, LLSD::emptyMap(), boost::bind(&LLLoginInstance::handleLoginDisallowed, this, _1, _2));
|
||||
LLSD args(LLSDMap("VERSION", required_version));
|
||||
if (updater.isUndefined())
|
||||
{
|
||||
// If the updater failed to shake hands, better advise the user to
|
||||
// download the update him/herself.
|
||||
LLNotificationsUtil::add(
|
||||
"RequiredUpdate",
|
||||
args,
|
||||
updater,
|
||||
boost::bind(&LLLoginInstance::handleLoginDisallowed, this, _1, _2));
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we've heard from the updater that an update is required,
|
||||
// then display the prompt that assures the user we'll take care
|
||||
// of it. This is the one case in which we bind 'resp':
|
||||
// instead of destroying our Response object (and thus sending a
|
||||
// negative reply to the updater) as soon as we exit this
|
||||
// function, bind our shared_ptr so it gets passed into
|
||||
// syncWithUpdater. That ensures that the response is delayed
|
||||
// until the user has responded to the notification.
|
||||
LLNotificationsUtil::add(
|
||||
"PauseForUpdate",
|
||||
args,
|
||||
updater,
|
||||
boost::bind(&LLLoginInstance::syncWithUpdater, this, resp, _1, _2));
|
||||
}
|
||||
}
|
||||
else if( reason_response == "key"
|
||||
|| reason_response == "presence"
|
||||
|
|
@ -375,6 +408,19 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
|
|||
}
|
||||
}
|
||||
|
||||
void LLLoginInstance::syncWithUpdater(ResponsePtr resp, const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
LL_INFOS("LLLogin") << "LLLoginInstance::syncWithUpdater" << LL_ENDL;
|
||||
// 'resp' points to an instance of LLEventAPI::Response that will be
|
||||
// destroyed as soon as we return and the notification response functor is
|
||||
// unregistered. Modify it so that it tells the updater to go ahead and
|
||||
// perform the update. Naturally, if we allowed the user a choice as to
|
||||
// whether to proceed or not, this assignment would reflect the user's
|
||||
// selection.
|
||||
(*resp)["update"] = true;
|
||||
attemptComplete();
|
||||
}
|
||||
|
||||
void LLLoginInstance::handleLoginDisallowed(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
attemptComplete();
|
||||
|
|
@ -434,7 +480,6 @@ bool LLLoginInstance::handleTOSResponse(bool accepted, const std::string& key)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
std::string construct_start_string()
|
||||
{
|
||||
std::string start;
|
||||
|
|
|
|||
|
|
@ -28,8 +28,10 @@
|
|||
#define LL_LLLOGININSTANCE_H
|
||||
|
||||
#include "lleventdispatcher.h"
|
||||
#include "lleventapi.h"
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <memory> // std::shared_ptr
|
||||
#include "llsecapi.h"
|
||||
class LLLogin;
|
||||
class LLEventStream;
|
||||
|
|
@ -71,6 +73,7 @@ public:
|
|||
LLNotificationsInterface& getNotificationsInterface() const { return *mNotifications; }
|
||||
|
||||
private:
|
||||
typedef std::shared_ptr<LLEventAPI::Response> ResponsePtr;
|
||||
void constructAuthParams(LLPointer<LLCredential> user_credentials);
|
||||
void updateApp(bool mandatory, const std::string& message);
|
||||
bool updateDialogCallback(const LLSD& notification, const LLSD& response);
|
||||
|
|
@ -80,7 +83,8 @@ private:
|
|||
void handleLoginSuccess(const LLSD& event);
|
||||
void handleDisconnect(const LLSD& event);
|
||||
void handleIndeterminate(const LLSD& event);
|
||||
void handleLoginDisallowed(const LLSD& notification, const LLSD& response);
|
||||
void handleLoginDisallowed(const LLSD& notification, const LLSD& response);
|
||||
void syncWithUpdater(ResponsePtr resp, const LLSD& notification, const LLSD& response);
|
||||
|
||||
bool handleTOSResponse(bool v, const std::string& key);
|
||||
|
||||
|
|
|
|||
|
|
@ -758,8 +758,7 @@ bool idle_startup()
|
|||
if (!found_template)
|
||||
{
|
||||
message_template_path =
|
||||
gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE,
|
||||
"../Resources/app_settings",
|
||||
gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,
|
||||
"message_template.msg");
|
||||
found_template = LLFile::fopen(message_template_path.c_str(), "r"); /* Flawfinder: ignore */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -332,6 +332,9 @@ private:
|
|||
RecordToChatConsole::RecordToChatConsole():
|
||||
mRecorder(new RecordToChatConsoleRecorder())
|
||||
{
|
||||
mRecorder->showTags(false);
|
||||
mRecorder->showLocation(false);
|
||||
mRecorder->showMultiline(true);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -824,41 +824,41 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
|
|||
{
|
||||
#ifndef VIVOXDAEMON_REMOTEHOST
|
||||
// Launch the voice daemon
|
||||
std::string exe_path = gDirUtilp->getExecutableDir();
|
||||
exe_path += gDirUtilp->getDirDelimiter();
|
||||
std::string exe_path = gDirUtilp->getAppRODataDir();
|
||||
#if LL_WINDOWS
|
||||
// <FS:Ansariel> FIRE-22709: Local voice not working in OpenSim
|
||||
#ifdef OPENSIM
|
||||
if (!LLGridManager::instance().isInSecondLife())
|
||||
{
|
||||
exe_path += "voice_os" + gDirUtilp->getDirDelimiter();
|
||||
gDirUtilp->append(exe_path, "voice_os" + gDirUtilp->getDirDelimiter() + "SLVoice.exe");
|
||||
}
|
||||
else
|
||||
#endif
|
||||
// </FS:Ansariel>
|
||||
exe_path += "SLVoice.exe";
|
||||
gDirUtilp->append(exe_path, "SLVoice.exe");
|
||||
#elif LL_DARWIN
|
||||
// <FS:Ansariel/TS> FIRE-22709: Local voice not working in OpenSim
|
||||
//exe_path += "../Resources/SLVoice";
|
||||
//gDirUtilp->append(exe_path, "SLVoice");
|
||||
#ifdef OPENSIM
|
||||
if (LLGridManager::instance().isInSecondLife())
|
||||
{
|
||||
#endif
|
||||
exe_path += "../Resources/SLVoice";
|
||||
gDirUtilp->append(exe_path, "SLVoice");
|
||||
#ifdef OPENSIM
|
||||
}
|
||||
else
|
||||
{
|
||||
exe_path += "../Resources/voice_os/SLVoice";
|
||||
gDirUtilp->append(exe_path, "voice_os/SLVoice");
|
||||
}
|
||||
#endif
|
||||
// </FS:Ansariel/TS>
|
||||
#else
|
||||
// <FS:ND> On Linux the viewer can run SLVoice.exe through wine (https://www.winehq.org/)
|
||||
// exe_path += "SLVoice";
|
||||
//gDirUtilp->append(exe_path, "SLVoice");
|
||||
if( !viewerUsesWineForVoice() )
|
||||
exe_path += "SLVoice"; // native version
|
||||
gDirUtilp->append(exe_path, "SLVoice"); // native version
|
||||
else
|
||||
exe_path += "win32/SLVoice.exe"; // use bundled win32 version
|
||||
gDirUtilp->append(exe_path, "win32/SLVoice"); // use bundled win32 version
|
||||
// </FS:ND>
|
||||
#endif
|
||||
// See if the vivox executable exists
|
||||
|
|
|
|||
|
|
@ -3950,7 +3950,6 @@ Finished download of raw terrain file to:
|
|||
name="RequiredUpdate"
|
||||
type="alertmodal">
|
||||
Version [VERSION] is required for login.
|
||||
This should have been updated for you but apparently was not.
|
||||
Please download from https://secondlife.com/support/downloads/
|
||||
<tag>confirm</tag>
|
||||
<usetemplate
|
||||
|
|
@ -3958,6 +3957,44 @@ Please download from https://secondlife.com/support/downloads/
|
|||
yestext="OK"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="PauseForUpdate"
|
||||
type="alertmodal">
|
||||
Version [VERSION] is required for login.
|
||||
Click OK to download and install.
|
||||
<tag>confirm</tag>
|
||||
<usetemplate
|
||||
name="okbutton"
|
||||
yestext="OK"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="OptionalUpdateReady"
|
||||
type="alertmodal">
|
||||
Version [VERSION] has been downloaded and is ready to install.
|
||||
Click OK to install.
|
||||
<tag>confirm</tag>
|
||||
<usetemplate
|
||||
name="okbutton"
|
||||
yestext="OK"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="PromptOptionalUpdate"
|
||||
type="alertmodal">
|
||||
Version [VERSION] has been downloaded and is ready to install.
|
||||
Proceed?
|
||||
<tag>confirm</tag>
|
||||
<usetemplate
|
||||
canceltext="Not Now"
|
||||
name="yesnocancelbuttons"
|
||||
notext="Skip"
|
||||
yestext="Install"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="LoginFailedUnknown"
|
||||
|
|
|
|||
|
|
@ -539,7 +539,7 @@ class WindowsManifest(ViewerManifest):
|
|||
pass
|
||||
except NoMatchingAssemblyException as err:
|
||||
pass
|
||||
|
||||
|
||||
self.ccopy(src,dst)
|
||||
else:
|
||||
raise Exception("Directories are not supported by test_CRT_and_copy_action()")
|
||||
|
|
@ -560,7 +560,7 @@ class WindowsManifest(ViewerManifest):
|
|||
# <FS:Ansariel> Remove VMP
|
||||
#with self.prefix(src=os.path.join(pkgdir, "VMP")):
|
||||
# include the compiled launcher scripts so that it gets included in the file_list
|
||||
# self.path('SL_Launcher.exe')
|
||||
# self.path('updater.exe')
|
||||
#IUM is not normally executed directly, just imported. No exe needed.
|
||||
# self.path("InstallerUserMessage.py")
|
||||
|
||||
|
|
@ -572,12 +572,7 @@ class WindowsManifest(ViewerManifest):
|
|||
# self.path("*.png")
|
||||
# self.path("*.gif")
|
||||
|
||||
#before, we only needed llbase at build time. With VMP, we need it at run time.
|
||||
#with self.prefix(src=os.path.join(pkgdir, "lib", "python", "llbase"), dst="llbase"):
|
||||
# self.path("*.py")
|
||||
# self.path("_cllsd.so")
|
||||
# </FS:Ansariel> Remove VMP
|
||||
|
||||
# Plugin host application
|
||||
self.path2basename(os.path.join(os.pardir,
|
||||
'llplugin', 'slplugin', self.args['configuration']),
|
||||
|
|
@ -910,7 +905,7 @@ class WindowsManifest(ViewerManifest):
|
|||
substitution_strings['is64bit'] = (1 if (self.address_size == 64) else 0)
|
||||
|
||||
version_vars = """
|
||||
!define INSTEXE "SL_Launcher.exe"
|
||||
!define INSTEXE "updater.exe"
|
||||
!define VERSION "%(version_short)s"
|
||||
!define VERSION_LONG "%(version)s"
|
||||
!define VERSION_DASHES "%(version_dashes)s"
|
||||
|
|
@ -958,7 +953,8 @@ class WindowsManifest(ViewerManifest):
|
|||
# note that the enclosing setup exe is signed later, after the makensis makes it.
|
||||
# Unlike the viewer binary, the VMP filenames are invariant with respect to version, os, etc.
|
||||
#for exe in (
|
||||
# "SL_Launcher.exe",
|
||||
# self.final_exe(),
|
||||
# "updater.exe",
|
||||
# ):
|
||||
# self.sign(exe)
|
||||
|
||||
|
|
@ -1035,425 +1031,321 @@ class DarwinManifest(ViewerManifest):
|
|||
# return bool(set(["package", "unpacked"]).intersection(self.args['actions']))
|
||||
|
||||
# def construct(self):
|
||||
# # These are the names of the top-level application and the embedded
|
||||
# # applications for the VMP and for the actual viewer, respectively.
|
||||
# # These names, without the .app suffix, determine the flyover text for
|
||||
# # their corresponding Dock icons.
|
||||
# toplevel_app = self.channel()+".app"
|
||||
# toplevel_icon = "secondlife.icns"
|
||||
# launcher_app, launcher_icon = "Second Life Launcher.app", "secondlife.icns"
|
||||
# viewer_app, viewer_icon = "Second Life Viewer.app", "secondlife.icns"
|
||||
|
||||
# # capture the path to the directory containing toplevel_app
|
||||
# parentdir = os.path.join(self.get_dst_prefix(), os.pardir)
|
||||
|
||||
# # copy over the build result (this is a no-op if run within the xcode script)
|
||||
# self.path(os.path.join(self.args['configuration'], toplevel_app), dst="")
|
||||
# self.path(os.path.join(self.args['configuration'], self.channel()+".app"), dst="")
|
||||
|
||||
# pkgdir = os.path.join(self.args['build'], os.pardir, 'packages')
|
||||
# relpkgdir = os.path.join(pkgdir, "lib", "release")
|
||||
# debpkgdir = os.path.join(pkgdir, "lib", "debug")
|
||||
|
||||
# # -------------------- top-level Second Life.app ---------------------
|
||||
# # top-level Second Life application is only a container
|
||||
# with self.prefix(dst="Contents"): # everything goes in Contents
|
||||
# # top-level Info.plist is as generated by CMake
|
||||
# Info_plist = self.dst_path_of("Info.plist")
|
||||
# with self.prefix(src="", dst="Contents"): # everything goes in Contents
|
||||
# bugsplat_db = self.args.get('bugsplat')
|
||||
# if bugsplat_db:
|
||||
# # Inject BugsplatServerURL into Info.plist if provided.
|
||||
# Info_plist = self.dst_path_of("Info.plist")
|
||||
# Info = plistlib.readPlist(Info_plist)
|
||||
# # https://www.bugsplat.com/docs/platforms/os-x#configuration
|
||||
# Info["BugsplatServerURL"] = \
|
||||
# "https://{}.bugsplat.com/".format(bugsplat_db)
|
||||
# self.put_in_file(
|
||||
# plistlib.writePlistToString(Info),
|
||||
# os.path.basename(Info_plist),
|
||||
# "Info.plist")
|
||||
|
||||
# # CEF framework goes inside Contents/Frameworks.
|
||||
# # Remember where we parked this car.
|
||||
# with self.prefix(src="", dst="Frameworks"):
|
||||
# CEF_framework = "Chromium Embedded Framework.framework"
|
||||
# self.path2basename(relpkgdir, CEF_framework)
|
||||
# CEF_framework = self.dst_path_of(CEF_framework)
|
||||
|
||||
# if self.args.get('bugsplat'):
|
||||
# self.path2basename(relpkgdir, "BugsplatMac.framework")
|
||||
|
||||
# toplevel_MacOS = self.dst_path_of("MacOS")
|
||||
# # the one file in top-level MacOS directory is the trampoline to
|
||||
# # our nested launcher_app
|
||||
# with self.prefix(dst="MacOS"):
|
||||
# if not self.is_rearranging():
|
||||
# trampoline = ""
|
||||
# else:
|
||||
# with self.prefix(dst="MacOS"):
|
||||
# trampoline = self.put_in_file("""\
|
||||
# #!/bin/bash
|
||||
# open "%s" --args "$@"
|
||||
# """ %
|
||||
# # up one directory from MacOS to its sibling Resources directory
|
||||
# os.path.join('$(dirname "$0")', os.pardir, 'Resources', launcher_app),
|
||||
# "SL_Launcher", # write this file
|
||||
# "trampoline") # flag to add to list of copied files
|
||||
# # Script must be executable
|
||||
# self.run_command(["chmod", "+x", trampoline])
|
||||
# executable = self.dst_path_of(self.channel())
|
||||
# if self.args.get('bugsplat'):
|
||||
# # According to Apple Technical Note TN2206:
|
||||
# # https://developer.apple.com/library/archive/technotes/tn2206/_index.html#//apple_ref/doc/uid/DTS40007919-CH1-TNTAG207
|
||||
# # "If an app uses @rpath or an absolute path to link to a
|
||||
# # dynamic library outside of the app, the app will be
|
||||
# # rejected by Gatekeeper. ... Neither the codesign nor the
|
||||
# # spctl tool will show the error."
|
||||
# # (Thanks, Apple. Maybe fix spctl to warn?)
|
||||
# # The BugsplatMac framework embeds @rpath, which is
|
||||
# # causing scary Gatekeeper popups at viewer start. Work
|
||||
# # around this by changing the reference baked into our
|
||||
# # viewer. The install_name_tool -change option needs the
|
||||
# # previous value. Instead of guessing -- which might
|
||||
# # silently be defeated by a BugSplat SDK update that
|
||||
# # changes their baked-in @rpath -- ask for the path
|
||||
# # stamped into the framework.
|
||||
# # Let exception, if any, propagate -- if this doesn't
|
||||
# # work, we need the build to noisily fail!
|
||||
# oldpath = subprocess.check_output(
|
||||
# ['objdump', '-macho', '-dylib-id', '-non-verbose',
|
||||
# os.path.join(relpkgdir, "BugsplatMac.framework", "BugsplatMac")]
|
||||
# ).splitlines()[-1] # take the last line of output
|
||||
# self.run_command(
|
||||
# ['install_name_tool', '-change', oldpath,
|
||||
# '@executable_path/../Frameworks/BugsplatMac.framework/BugsplatMac',
|
||||
# executable])
|
||||
|
||||
# # Make a symlink to a nested app Frameworks directory that doesn't
|
||||
# # yet exist. We shouldn't need this; the only things that need
|
||||
# # Frameworks are nested apps under viewer_app, and they should
|
||||
# # simply find its Contents/Frameworks by relative pathnames. But
|
||||
# # empirically, we do: if we omit this symlink, CEF doesn't work --
|
||||
# # the login splash screen doesn't even display. SIIIIGH.
|
||||
# # We're passing a path that's already relative, hence symlinkf()
|
||||
# # rather than relsymlinkf().
|
||||
# self.symlinkf(os.path.join("Resources", viewer_app, "Contents", "Frameworks"))
|
||||
# # NOTE: the -S argument to strip causes it to keep
|
||||
# # enough info for annotated backtraces (i.e. function
|
||||
# # names in the crash log). 'strip' with no arguments
|
||||
# # yields a slightly smaller binary but makes crash
|
||||
# # logs mostly useless. This may be desirable for the
|
||||
# # final release. Or not.
|
||||
# if ("package" in self.args['actions'] or
|
||||
# "unpacked" in self.args['actions']):
|
||||
# self.run_command(
|
||||
# ['strip', '-S', executable])
|
||||
|
||||
# with self.prefix(dst="Resources"):
|
||||
# # top-level Resources directory should be pretty sparse
|
||||
# # need .icns file referenced by top-level Info.plist
|
||||
# with self.prefix(src=self.icon_path()) :
|
||||
# self.path(toplevel_icon)
|
||||
# # defer cross-platform file copies until we're in the
|
||||
# # nested Resources directory
|
||||
# super(DarwinManifest, self).construct()
|
||||
|
||||
# # ------------------- nested launcher_app --------------------
|
||||
# with self.prefix(dst=os.path.join(launcher_app, "Contents")):
|
||||
# # Info.plist is just like top-level one...
|
||||
# Info = plistlib.readPlist(Info_plist)
|
||||
# # except for these replacements:
|
||||
# Info["CFBundleExecutable"] = "SL_Launcher"
|
||||
# Info["CFBundleIconFile"] = launcher_icon
|
||||
# self.put_in_file(
|
||||
# plistlib.writePlistToString(Info),
|
||||
# os.path.basename(Info_plist),
|
||||
# "Info.plist")
|
||||
# # need .icns file referenced by Info.plist
|
||||
# with self.prefix(src=self.icon_path(), dst="") :
|
||||
# self.path("secondlife.icns")
|
||||
|
||||
# # copy VMP libs to MacOS
|
||||
# with self.prefix(dst="MacOS"):
|
||||
# #this copies over the python wrapper script,
|
||||
# #associated utilities and required libraries, see
|
||||
# #SL-321, SL-322, SL-323
|
||||
# with self.prefix(src=os.path.join(pkgdir, "VMP")):
|
||||
# self.path("SL_Launcher")
|
||||
# self.path("*.py")
|
||||
# # certifi will be imported by requests; this is
|
||||
# # our custom version to get our ca-bundle.crt
|
||||
# self.path("certifi")
|
||||
# with self.prefix(src=os.path.join(pkgdir, "lib", "python")):
|
||||
# # llbase provides our llrest service layer and llsd decoding
|
||||
# with self.prefix(src="llbase", dst="llbase"):
|
||||
# # (Why is llbase treated specially here? What
|
||||
# # DON'T we want to copy out of lib/python/llbase?)
|
||||
# self.path("*.py")
|
||||
# self.path("_cllsd.so")
|
||||
# #requests module needed by llbase/llrest.py
|
||||
# #this is only needed on POSIX, because in Windows
|
||||
# #we compile it into the EXE
|
||||
# for pypkg in "chardet", "idna", "requests", "urllib3":
|
||||
# self.path(pypkg)
|
||||
# # Copy in the updater script and helper modules
|
||||
# self.path(src=os.path.join(pkgdir, 'VMP'), dst="updater")
|
||||
|
||||
# # launcher_app/Contents/Resources
|
||||
# with self.prefix(dst="Resources"):
|
||||
# with self.prefix(src=self.icon_path()) :
|
||||
# self.path(launcher_icon)
|
||||
# with self.prefix(dst="vmp_icons"):
|
||||
# self.path("secondlife.ico")
|
||||
# #VMP Tkinter icons
|
||||
# with self.prefix(src_dst="vmp_icons"):
|
||||
# self.path("*.png")
|
||||
# self.path("*.gif")
|
||||
# with self.prefix(src="", dst=os.path.join("updater", "icons")):
|
||||
# self.path2basename(self.icon_path(), "secondlife.ico")
|
||||
# with self.prefix(src="vmp_icons", dst=""):
|
||||
# self.path("*.png")
|
||||
# self.path("*.gif")
|
||||
|
||||
# # -------------------- nested viewer_app ---------------------
|
||||
# with self.prefix(dst=os.path.join(viewer_app, "Contents")):
|
||||
# defer Info.plist until after MacOS
|
||||
# with self.prefix(dst="MacOS"):
|
||||
# # CMake constructs the Second Life executable in the
|
||||
# # MacOS directory belonging to the top-level Second
|
||||
# # Life.app. Move it here.
|
||||
# here = self.get_dst_prefix()
|
||||
# relbase = os.path.realpath(os.path.dirname(Info_plist))
|
||||
# self.cmakedirs(here)
|
||||
# for f in os.listdir(toplevel_MacOS):
|
||||
# if f == os.path.basename(trampoline):
|
||||
# # don't move the trampoline script we just made!
|
||||
# continue
|
||||
# fromwhere = os.path.join(toplevel_MacOS, f)
|
||||
# towhere = self.dst_path_of(f)
|
||||
# fromrel = self.relpath(fromwhere, relbase)
|
||||
# torel = self.relpath(towhere, relbase)
|
||||
# if not self.is_rearranging():
|
||||
# print "Not yet moving {} => {}".format(fromrel, torel)
|
||||
# else:
|
||||
# print "Moving {} => {}".format(fromrel, torel)
|
||||
# # now do it, only without relativizing paths
|
||||
# os.rename(fromwhere, towhere)
|
||||
# with self.prefix(src=relpkgdir, dst=""):
|
||||
# self.path("libndofdev.dylib")
|
||||
# self.path("libhunspell-1.3.0.dylib")
|
||||
|
||||
# # If we haven't yet moved executables, find our viewer
|
||||
# # executable where it was linked, in toplevel_MacOS.
|
||||
# # If we have, find it here.
|
||||
# whichdir = here if self.is_rearranging() else toplevel_MacOS
|
||||
# # Pick the biggest of the executables as the real viewer.
|
||||
# # Make (basename, fullpath) pairs; for each pair,
|
||||
# # expand to (size, basename, fullpath) triples; sort
|
||||
# # by size; pick the last triple; take the basename and
|
||||
# # fullpath from that.
|
||||
# # _, exename, exepath = \
|
||||
# # sorted((os.path.getsize(path), name, path)
|
||||
# # for name, path in
|
||||
# # ((name, os.path.join(whichdir, name))
|
||||
# # for name in os.listdir(whichdir)))[-1]
|
||||
# with self.prefix("cursors_mac"):
|
||||
# self.path("*.tif")
|
||||
|
||||
# if self.is_rearranging():
|
||||
# # NOTE: the -S argument to strip causes it to keep
|
||||
# # enough info for annotated backtraces (i.e. function
|
||||
# # names in the crash log). 'strip' with no arguments
|
||||
# # yields a slightly smaller binary but makes crash
|
||||
# # logs mostly useless. This may be desirable for the
|
||||
# # final release. Or not.
|
||||
# self.run_command(['strip', '-S', exepath])
|
||||
# self.path("licenses-mac.txt", dst="licenses.txt")
|
||||
# self.path("featuretable_mac.txt")
|
||||
# self.path("SecondLife.nib")
|
||||
|
||||
# # Info.plist is just like top-level one...
|
||||
# Info = plistlib.readPlist(Info_plist)
|
||||
# # except for these replacements:
|
||||
# # (CFBundleExecutable may be moot: SL_Launcher directly
|
||||
# # runs the executable, instead of launching the app)
|
||||
# Info["CFBundleExecutable"] = exename
|
||||
# Info["CFBundleIconFile"] = viewer_icon
|
||||
# bugsplat_db = self.args.get('bugsplat')
|
||||
# if bugsplat_db:
|
||||
# # https://www.bugsplat.com/docs/platforms/os-x#configuration
|
||||
# Info["BugsplatServerURL"] = \
|
||||
# "https://{}.bugsplat.com/".format(bugsplat_db)
|
||||
# self.put_in_file(
|
||||
# plistlib.writePlistToString(Info),
|
||||
# os.path.basename(Info_plist),
|
||||
# "Info.plist")
|
||||
# with self.prefix(src=pkgdir,dst=""):
|
||||
# self.path("ca-bundle.crt")
|
||||
|
||||
# with self.prefix(dst="Frameworks"):
|
||||
# # CEF framework goes inside viewer_app/Contents/Frameworks.
|
||||
# CEF_framework = "Chromium Embedded Framework.framework"
|
||||
# self.path2basename(relpkgdir, CEF_framework)
|
||||
# # Remember where we parked this car.
|
||||
# CEF_framework = self.dst_path_of(CEF_framework)
|
||||
# # Translations
|
||||
# self.path("English.lproj/language.txt")
|
||||
# self.replace_in(src="English.lproj/InfoPlist.strings",
|
||||
# dst="English.lproj/InfoPlist.strings",
|
||||
# searchdict={'%%VERSION%%':'.'.join(self.args['version'])}
|
||||
# )
|
||||
# self.path("German.lproj")
|
||||
# self.path("Japanese.lproj")
|
||||
# self.path("Korean.lproj")
|
||||
# self.path("da.lproj")
|
||||
# self.path("es.lproj")
|
||||
# self.path("fr.lproj")
|
||||
# self.path("hu.lproj")
|
||||
# self.path("it.lproj")
|
||||
# self.path("nl.lproj")
|
||||
# self.path("pl.lproj")
|
||||
# self.path("pt.lproj")
|
||||
# self.path("ru.lproj")
|
||||
# self.path("tr.lproj")
|
||||
# self.path("uk.lproj")
|
||||
# self.path("zh-Hans.lproj")
|
||||
|
||||
# if self.args.get('bugsplat'):
|
||||
# self.path2basename(relpkgdir, "BugsplatMac.framework")
|
||||
# def path_optional(src, dst):
|
||||
# """
|
||||
# For a number of our self.path() calls, not only do we want
|
||||
# to deal with the absence of src, we also want to remember
|
||||
# which were present. Return either an empty list (absent)
|
||||
# or a list containing dst (present). Concatenate these
|
||||
# return values to get a list of all libs that are present.
|
||||
# """
|
||||
# # This was simple before we started needing to pass
|
||||
# # wildcards. Fortunately, self.path() ends up appending a
|
||||
# # (source, dest) pair to self.file_list for every expanded
|
||||
# # file processed. Remember its size before the call.
|
||||
# oldlen = len(self.file_list)
|
||||
# self.path(src, dst)
|
||||
# # The dest appended to self.file_list has been prepended
|
||||
# # with self.get_dst_prefix(). Strip it off again.
|
||||
# added = [os.path.relpath(d, self.get_dst_prefix())
|
||||
# for s, d in self.file_list[oldlen:]]
|
||||
# if not added:
|
||||
# print "Skipping %s" % dst
|
||||
# return added
|
||||
|
||||
# with self.prefix(dst="Resources"):
|
||||
# # defer cross-platform file copies until we're in the right
|
||||
# # nested Resources directory
|
||||
# super(DarwinManifest, self).construct()
|
||||
# # dylibs is a list of all the .dylib files we expect to need
|
||||
# # in our bundled sub-apps. For each of these we'll create a
|
||||
# # symlink from sub-app/Contents/Resources to the real .dylib.
|
||||
# # Need to get the llcommon dll from any of the build directories as well.
|
||||
# libfile_parent = self.get_dst_prefix()
|
||||
# libfile = "libllcommon.dylib"
|
||||
# dylibs = path_optional(self.find_existing_file(os.path.join(os.pardir,
|
||||
# "llcommon",
|
||||
# self.args['configuration'],
|
||||
# libfile),
|
||||
# os.path.join(relpkgdir, libfile)),
|
||||
# dst=libfile)
|
||||
|
||||
# with self.prefix(src=self.icon_path()) :
|
||||
# self.path(viewer_icon)
|
||||
# for libfile in (
|
||||
# "libapr-1.0.dylib",
|
||||
# "libaprutil-1.0.dylib",
|
||||
# "libcollada14dom.dylib",
|
||||
# "libexpat.1.dylib",
|
||||
# "libexception_handler.dylib",
|
||||
# "libGLOD.dylib",
|
||||
# # libnghttp2.dylib is a symlink to
|
||||
# # libnghttp2.major.dylib, which is a symlink to
|
||||
# # libnghttp2.version.dylib. Get all of them.
|
||||
# "libnghttp2.*dylib",
|
||||
# ):
|
||||
# dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile)
|
||||
|
||||
# with self.prefix(src=relpkgdir):
|
||||
# self.path("libndofdev.dylib")
|
||||
# self.path("libhunspell-1.3.0.dylib")
|
||||
# # SLVoice and vivox lols, no symlinks needed
|
||||
# for libfile in (
|
||||
# 'libortp.dylib',
|
||||
# 'libsndfile.dylib',
|
||||
# 'libvivoxoal.dylib',
|
||||
# 'libvivoxsdk.dylib',
|
||||
# 'libvivoxplatform.dylib',
|
||||
# 'SLVoice',
|
||||
# ):
|
||||
# self.path2basename(relpkgdir, libfile)
|
||||
|
||||
# with self.prefix("cursors_mac"):
|
||||
# self.path("*.tif")
|
||||
# # dylibs that vary based on configuration
|
||||
# if self.args['configuration'].lower() == 'debug':
|
||||
# for libfile in (
|
||||
# "libfmodexL.dylib",
|
||||
# ):
|
||||
# dylibs += path_optional(os.path.join(debpkgdir, libfile), libfile)
|
||||
# else:
|
||||
# for libfile in (
|
||||
# "libfmodex.dylib",
|
||||
# ):
|
||||
# dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile)
|
||||
|
||||
# self.path("licenses-mac.txt", dst="licenses.txt")
|
||||
# self.path("featuretable_mac.txt")
|
||||
# self.path("SecondLife.nib")
|
||||
# # our apps
|
||||
# executable_path = {}
|
||||
# for app_bld_dir, app in (("mac_crash_logger", "mac-crash-logger.app"),
|
||||
# # plugin launcher
|
||||
# (os.path.join("llplugin", "slplugin"), "SLPlugin.app"),
|
||||
# ):
|
||||
# self.path2basename(os.path.join(os.pardir,
|
||||
# app_bld_dir, self.args['configuration']),
|
||||
# app)
|
||||
# executable_path[app] = \
|
||||
# self.dst_path_of(os.path.join(app, "Contents", "MacOS"))
|
||||
|
||||
# with self.prefix(src=pkgdir,dst=""):
|
||||
# self.path("ca-bundle.crt")
|
||||
# # our apps dependencies on shared libs
|
||||
# # for each app, for each dylib we collected in dylibs,
|
||||
# # create a symlink to the real copy of the dylib.
|
||||
# with self.prefix(dst=os.path.join(app, "Contents", "Resources")):
|
||||
# for libfile in dylibs:
|
||||
# self.relsymlinkf(os.path.join(libfile_parent, libfile))
|
||||
|
||||
# self.path("SecondLife.nib")
|
||||
# # Dullahan helper apps go inside SLPlugin.app
|
||||
# with self.prefix(dst=os.path.join(
|
||||
# "SLPlugin.app", "Contents", "Frameworks")):
|
||||
|
||||
# # Translations
|
||||
# self.path("English.lproj/language.txt")
|
||||
# self.replace_in(src="English.lproj/InfoPlist.strings",
|
||||
# dst="English.lproj/InfoPlist.strings",
|
||||
# searchdict={'%%VERSION%%':'.'.join(self.args['version'])}
|
||||
# )
|
||||
# self.path("German.lproj")
|
||||
# self.path("Japanese.lproj")
|
||||
# self.path("Korean.lproj")
|
||||
# self.path("da.lproj")
|
||||
# self.path("es.lproj")
|
||||
# self.path("fr.lproj")
|
||||
# self.path("hu.lproj")
|
||||
# self.path("it.lproj")
|
||||
# self.path("nl.lproj")
|
||||
# self.path("pl.lproj")
|
||||
# self.path("pt.lproj")
|
||||
# self.path("ru.lproj")
|
||||
# self.path("tr.lproj")
|
||||
# self.path("uk.lproj")
|
||||
# self.path("zh-Hans.lproj")
|
||||
# frameworkname = 'Chromium Embedded Framework'
|
||||
|
||||
# def path_optional(src, dst):
|
||||
# """
|
||||
# For a number of our self.path() calls, not only do we want
|
||||
# to deal with the absence of src, we also want to remember
|
||||
# which were present. Return either an empty list (absent)
|
||||
# or a list containing dst (present). Concatenate these
|
||||
# return values to get a list of all libs that are present.
|
||||
# """
|
||||
# # This was simple before we started needing to pass
|
||||
# # wildcards. Fortunately, self.path() ends up appending a
|
||||
# # (source, dest) pair to self.file_list for every expanded
|
||||
# # file processed. Remember its size before the call.
|
||||
# oldlen = len(self.file_list)
|
||||
# self.path(src, dst)
|
||||
# # The dest appended to self.file_list has been prepended
|
||||
# # with self.get_dst_prefix(). Strip it off again.
|
||||
# added = [os.path.relpath(d, self.get_dst_prefix())
|
||||
# for s, d in self.file_list[oldlen:]]
|
||||
# if not added:
|
||||
# print "Skipping %s" % dst
|
||||
# return added
|
||||
# # This code constructs a relative symlink from the
|
||||
# # target framework folder back to the real CEF framework.
|
||||
# # It needs to be relative so that the symlink still works when
|
||||
# # (as is normal) the user moves the app bundle out of the DMG
|
||||
# # and into the /Applications folder. Note we pass catch=False,
|
||||
# # letting the uncaught exception terminate the process, since
|
||||
# # without this symlink, Second Life web media can't possibly work.
|
||||
|
||||
# # dylibs is a list of all the .dylib files we expect to need
|
||||
# # in our bundled sub-apps. For each of these we'll create a
|
||||
# # symlink from sub-app/Contents/Resources to the real .dylib.
|
||||
# # Need to get the llcommon dll from any of the build directories as well.
|
||||
# libfile_parent = self.get_dst_prefix()
|
||||
# libfile = "libllcommon.dylib"
|
||||
# dylibs = path_optional(self.find_existing_file(os.path.join(os.pardir,
|
||||
# "llcommon",
|
||||
# self.args['configuration'],
|
||||
# libfile),
|
||||
# os.path.join(relpkgdir, libfile)),
|
||||
# dst=libfile)
|
||||
# # It might seem simpler just to symlink Frameworks back to
|
||||
# # the parent of Chromimum Embedded Framework.framework. But
|
||||
# # that would create a symlink cycle, which breaks our
|
||||
# # packaging step. So make a symlink from Chromium Embedded
|
||||
# # Framework.framework to the directory of the same name, which
|
||||
# # is NOT an ancestor of the symlink.
|
||||
|
||||
# for libfile in (
|
||||
# "libapr-1.0.dylib",
|
||||
# "libaprutil-1.0.dylib",
|
||||
# "libcollada14dom.dylib",
|
||||
# "libexpat.1.dylib",
|
||||
# "libexception_handler.dylib",
|
||||
# "libGLOD.dylib",
|
||||
# # libnghttp2.dylib is a symlink to
|
||||
# # libnghttp2.major.dylib, which is a symlink to
|
||||
# # libnghttp2.version.dylib. Get all of them.
|
||||
# "libnghttp2.*dylib",
|
||||
# ):
|
||||
# dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile)
|
||||
# # from SLPlugin.app/Contents/Frameworks/Chromium Embedded
|
||||
# # Framework.framework back to
|
||||
# # $viewer_app/Contents/Frameworks/Chromium Embedded Framework.framework
|
||||
# SLPlugin_framework = self.relsymlinkf(CEF_framework, catch=False)
|
||||
|
||||
# # SLVoice and vivox lols, no symlinks needed
|
||||
# for libfile in (
|
||||
# 'libortp.dylib',
|
||||
# 'libsndfile.dylib',
|
||||
# 'libvivoxoal.dylib',
|
||||
# 'libvivoxsdk.dylib',
|
||||
# 'libvivoxplatform.dylib',
|
||||
# 'SLVoice',
|
||||
# ):
|
||||
# self.path2basename(relpkgdir, libfile)
|
||||
# # copy DullahanHelper.app
|
||||
# self.path2basename(relpkgdir, 'DullahanHelper.app')
|
||||
|
||||
# # dylibs that vary based on configuration
|
||||
# if self.args['configuration'].lower() == 'debug':
|
||||
# for libfile in (
|
||||
# "libfmodexL.dylib",
|
||||
# ):
|
||||
# dylibs += path_optional(os.path.join(debpkgdir, libfile), libfile)
|
||||
# else:
|
||||
# for libfile in (
|
||||
# "libfmodex.dylib",
|
||||
# ):
|
||||
# dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile)
|
||||
# # and fix that up with a Frameworks/CEF symlink too
|
||||
# with self.prefix(dst=os.path.join(
|
||||
# 'DullahanHelper.app', 'Contents', 'Frameworks')):
|
||||
# # from Dullahan Helper.app/Contents/Frameworks/Chromium Embedded
|
||||
# # Framework.framework back to
|
||||
# # SLPlugin.app/Contents/Frameworks/Chromium Embedded Framework.framework
|
||||
# # Since SLPlugin_framework is itself a
|
||||
# # symlink, don't let relsymlinkf() resolve --
|
||||
# # explicitly call relpath(symlink=True) and
|
||||
# # create that symlink here.
|
||||
# DullahanHelper_framework = \
|
||||
# self.symlinkf(self.relpath(SLPlugin_framework, symlink=True),
|
||||
# catch=False)
|
||||
|
||||
# # our apps
|
||||
# executable_path = {}
|
||||
# for app_bld_dir, app in (
|
||||
# ("mac_crash_logger", "mac-crash-logger.app"),
|
||||
# # plugin launcher
|
||||
# (os.path.join("llplugin", "slplugin"), "SLPlugin.app"),
|
||||
# ):
|
||||
# self.path2basename(
|
||||
# os.path.join(os.pardir, app_bld_dir, self.args['configuration']),
|
||||
# app)
|
||||
# executable_path[app] = \
|
||||
# self.dst_path_of(os.path.join(app, "Contents", "MacOS"))
|
||||
# # change_command includes install_name_tool, the
|
||||
# # -change subcommand and the old framework rpath
|
||||
# # stamped into the executable. To use it with
|
||||
# # run_command(), we must still append the new
|
||||
# # framework path and the pathname of the
|
||||
# # executable to change.
|
||||
# change_command = [
|
||||
# 'install_name_tool', '-change',
|
||||
# '@rpath/Frameworks/Chromium Embedded Framework.framework/Chromium Embedded Framework']
|
||||
|
||||
# # our apps dependencies on shared libs
|
||||
# # for each app, for each dylib we collected in dylibs,
|
||||
# # create a symlink to the real copy of the dylib.
|
||||
# with self.prefix(dst=os.path.join(app, "Contents", "Resources")):
|
||||
# for libfile in dylibs:
|
||||
# self.relsymlinkf(os.path.join(libfile_parent, libfile))
|
||||
# with self.prefix(dst=os.path.join(
|
||||
# 'DullahanHelper.app', 'Contents', 'MacOS')):
|
||||
# # Now self.get_dst_prefix() is, at runtime,
|
||||
# # @executable_path. Locate the helper app
|
||||
# # framework (which is a symlink) from here.
|
||||
# newpath = os.path.join(
|
||||
# '@executable_path',
|
||||
# self.relpath(DullahanHelper_framework, symlink=True),
|
||||
# frameworkname)
|
||||
# # and restamp the DullahanHelper executable
|
||||
# self.run_command(
|
||||
# change_command +
|
||||
# [newpath, self.dst_path_of('DullahanHelper')])
|
||||
|
||||
# # Dullahan helper apps go inside SLPlugin.app
|
||||
# with self.prefix(dst=os.path.join(
|
||||
# "SLPlugin.app", "Contents", "Frameworks")):
|
||||
# # SLPlugin plugins
|
||||
# with self.prefix(dst="llplugin"):
|
||||
# dylibexecutable = 'media_plugin_cef.dylib'
|
||||
# self.path2basename("../media_plugins/cef/" + self.args['configuration'],
|
||||
# dylibexecutable)
|
||||
|
||||
# frameworkname = 'Chromium Embedded Framework'
|
||||
# # Do this install_name_tool *after* media plugin is copied over.
|
||||
# # Locate the framework lib executable -- relative to
|
||||
# # SLPlugin.app/Contents/MacOS, which will be our
|
||||
# # @executable_path at runtime!
|
||||
# newpath = os.path.join(
|
||||
# '@executable_path',
|
||||
# self.relpath(SLPlugin_framework, executable_path["SLPlugin.app"],
|
||||
# symlink=True),
|
||||
# frameworkname)
|
||||
# # restamp media_plugin_cef.dylib
|
||||
# self.run_command(
|
||||
# change_command +
|
||||
# [newpath, self.dst_path_of(dylibexecutable)])
|
||||
|
||||
# # This code constructs a relative symlink from the
|
||||
# # target framework folder back to the real CEF framework.
|
||||
# # It needs to be relative so that the symlink still works when
|
||||
# # (as is normal) the user moves the app bundle out of the DMG
|
||||
# # and into the /Applications folder. Note we pass catch=False,
|
||||
# # letting the uncaught exception terminate the process, since
|
||||
# # without this symlink, Second Life web media can't possibly work.
|
||||
# # copy LibVLC plugin itself
|
||||
# self.path2basename("../media_plugins/libvlc/" + self.args['configuration'],
|
||||
# "media_plugin_libvlc.dylib")
|
||||
|
||||
# # It might seem simpler just to symlink Frameworks back to
|
||||
# # the parent of Chromimum Embedded Framework.framework. But
|
||||
# # that would create a symlink cycle, which breaks our
|
||||
# # packaging step. So make a symlink from Chromium Embedded
|
||||
# # Framework.framework to the directory of the same name, which
|
||||
# # is NOT an ancestor of the symlink.
|
||||
# # copy LibVLC dynamic libraries
|
||||
# with self.prefix(src=relpkgdir, dst="lib"):
|
||||
# self.path( "libvlc*.dylib*" )
|
||||
# # copy LibVLC plugins folder
|
||||
# with self.prefix(src='plugins', dst=""):
|
||||
# self.path( "*.dylib" )
|
||||
# self.path( "plugins.dat" )
|
||||
|
||||
# # from SLPlugin.app/Contents/Frameworks/Chromium Embedded
|
||||
# # Framework.framework back to
|
||||
# # $viewer_app/Contents/Frameworks/Chromium Embedded Framework.framework
|
||||
# SLPlugin_framework = self.relsymlinkf(CEF_framework, catch=False)
|
||||
|
||||
# # copy DullahanHelper.app
|
||||
# self.path2basename(relpkgdir, 'DullahanHelper.app')
|
||||
|
||||
# # and fix that up with a Frameworks/CEF symlink too
|
||||
# with self.prefix(dst=os.path.join(
|
||||
# 'DullahanHelper.app', 'Contents', 'Frameworks')):
|
||||
# # from Dullahan Helper.app/Contents/Frameworks/Chromium Embedded
|
||||
# # Framework.framework back to
|
||||
# # SLPlugin.app/Contents/Frameworks/Chromium Embedded Framework.framework
|
||||
# # Since SLPlugin_framework is itself a
|
||||
# # symlink, don't let relsymlinkf() resolve --
|
||||
# # explicitly call relpath(symlink=True) and
|
||||
# # create that symlink here.
|
||||
# DullahanHelper_framework = \
|
||||
# self.symlinkf(self.relpath(SLPlugin_framework, symlink=True),
|
||||
# catch=False)
|
||||
|
||||
# # change_command includes install_name_tool, the
|
||||
# # -change subcommand and the old framework rpath
|
||||
# # stamped into the executable. To use it with
|
||||
# # run_command(), we must still append the new
|
||||
# # framework path and the pathname of the
|
||||
# # executable to change.
|
||||
# change_command = [
|
||||
# 'install_name_tool', '-change',
|
||||
# '@rpath/Frameworks/Chromium Embedded Framework.framework/Chromium Embedded Framework']
|
||||
|
||||
# with self.prefix(dst=os.path.join(
|
||||
# 'DullahanHelper.app', 'Contents', 'MacOS')):
|
||||
# # Now self.get_dst_prefix() is, at runtime,
|
||||
# # @executable_path. Locate the helper app
|
||||
# # framework (which is a symlink) from here.
|
||||
# newpath = os.path.join(
|
||||
# '@executable_path',
|
||||
# self.relpath(DullahanHelper_framework, symlink=True),
|
||||
# frameworkname)
|
||||
# # and restamp the DullahanHelper executable
|
||||
# self.run_command(
|
||||
# change_command +
|
||||
# [newpath, self.dst_path_of('DullahanHelper')])
|
||||
|
||||
# # SLPlugin plugins
|
||||
# with self.prefix(dst="llplugin"):
|
||||
# dylibexecutable = 'media_plugin_cef.dylib'
|
||||
# self.path2basename("../media_plugins/cef/" + self.args['configuration'],
|
||||
# dylibexecutable)
|
||||
|
||||
# # Do this install_name_tool *after* media plugin is copied over.
|
||||
# # Locate the framework lib executable -- relative to
|
||||
# # SLPlugin.app/Contents/MacOS, which will be our
|
||||
# # @executable_path at runtime!
|
||||
# newpath = os.path.join(
|
||||
# '@executable_path',
|
||||
# self.relpath(SLPlugin_framework, executable_path["SLPlugin.app"],
|
||||
# symlink=True),
|
||||
# frameworkname)
|
||||
# # restamp media_plugin_cef.dylib
|
||||
# self.run_command(
|
||||
# change_command +
|
||||
# [newpath, self.dst_path_of(dylibexecutable)])
|
||||
|
||||
# # copy LibVLC plugin itself
|
||||
# self.path2basename("../media_plugins/libvlc/" + self.args['configuration'],
|
||||
# "media_plugin_libvlc.dylib")
|
||||
|
||||
# # copy LibVLC dynamic libraries
|
||||
# with self.prefix(src=relpkgdir, dst="lib"):
|
||||
# self.path( "libvlc*.dylib*" )
|
||||
# # copy LibVLC plugins folder
|
||||
# with self.prefix(src='plugins', dst=""):
|
||||
# self.path( "*.dylib" )
|
||||
# self.path( "plugins.dat" )
|
||||
def construct(self):
|
||||
# copy over the build result (this is a no-op if run within the xcode script)
|
||||
self.path(self.args['configuration'] + "/Firestorm.app", dst="")
|
||||
|
|
@ -1480,14 +1372,14 @@ class DarwinManifest(ViewerManifest):
|
|||
with self.prefix(dst="Resources"):
|
||||
super(DarwinManifest, self).construct()
|
||||
|
||||
with self.prefix(src_dst="cursors_mac"):
|
||||
with self.prefix("cursors_mac"):
|
||||
self.path("*.tif")
|
||||
|
||||
self.path("licenses-mac.txt", dst="licenses.txt")
|
||||
self.path("featuretable_mac.txt")
|
||||
self.path("VivoxAUP.txt")
|
||||
|
||||
with self.prefix(src=pkgdir):
|
||||
with self.prefix(src=pkgdir,dst=""):
|
||||
self.path("ca-bundle.crt")
|
||||
|
||||
icon_path = self.icon_path()
|
||||
|
|
@ -1495,7 +1387,6 @@ class DarwinManifest(ViewerManifest):
|
|||
self.path("firestorm_icon.icns")
|
||||
|
||||
self.path("Firestorm.nib")
|
||||
|
||||
# Translations
|
||||
self.path("English.lproj/language.txt")
|
||||
self.replace_in(src="English.lproj/InfoPlist.strings",
|
||||
|
|
@ -1622,6 +1513,7 @@ class DarwinManifest(ViewerManifest):
|
|||
dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile)
|
||||
|
||||
# our apps
|
||||
executable_path = {}
|
||||
for app_bld_dir, app in (("mac_crash_logger", "mac-crash-logger.app"),
|
||||
# plugin launcher
|
||||
(os.path.join("llplugin", "slplugin"), "SLPlugin.app"),
|
||||
|
|
@ -1629,6 +1521,8 @@ class DarwinManifest(ViewerManifest):
|
|||
self.path2basename(os.path.join(os.pardir,
|
||||
app_bld_dir, self.args['configuration']),
|
||||
app)
|
||||
executable_path[app] = \
|
||||
self.dst_path_of(os.path.join(app, "Contents", "MacOS"))
|
||||
|
||||
# our apps dependencies on shared libs
|
||||
# for each app, for each dylib we collected in dylibs,
|
||||
|
|
@ -1675,8 +1569,9 @@ class DarwinManifest(ViewerManifest):
|
|||
|
||||
# SLPlugin plugins
|
||||
with self.prefix(dst="llplugin"):
|
||||
dylibexecutable = 'media_plugin_cef.dylib'
|
||||
self.path2basename("../media_plugins/cef/" + self.args['configuration'],
|
||||
"media_plugin_cef.dylib")
|
||||
dylibexecutable)
|
||||
|
||||
# copy LibVLC plugin itself
|
||||
self.path2basename("../media_plugins/libvlc/" + self.args['configuration'],
|
||||
|
|
@ -1684,7 +1579,7 @@ class DarwinManifest(ViewerManifest):
|
|||
|
||||
# copy LibVLC dynamic libraries
|
||||
with self.prefix(src=os.path.join(self.args['build'], os.pardir, 'packages', 'lib', 'release' ), dst="lib"):
|
||||
self.path("libvlc*.dylib*")
|
||||
self.path( "libvlc*.dylib*" )
|
||||
|
||||
# copy LibVLC plugins folder
|
||||
with self.prefix(src=os.path.join(self.args['build'], os.pardir, 'packages', 'lib', 'release', 'plugins' ), dst="lib"):
|
||||
|
|
@ -1931,10 +1826,7 @@ class DarwinManifest(ViewerManifest):
|
|||
else:
|
||||
print >> sys.stderr, "Maximum codesign attempts exceeded; giving up"
|
||||
raise
|
||||
self.run_command(['spctl', '-a', '-texec', '-vv', app_in_dmg])
|
||||
|
||||
imagename="SecondLife_" + '_'.join(self.args['version'])
|
||||
|
||||
self.run_command(['spctl', '-a', '-texec', '-vvvv', app_in_dmg])
|
||||
|
||||
finally:
|
||||
# Unmount the image even if exceptions from any of the above
|
||||
|
|
@ -1994,12 +1886,8 @@ class LinuxManifest(ViewerManifest):
|
|||
self.path2basename("../llplugin/slplugin", "SLPlugin")
|
||||
#this copies over the python wrapper script, associated utilities and required libraries, see SL-321, SL-322 and SL-323
|
||||
# <FS:Ansariel> Remove VMP
|
||||
#with self.prefix(src="../viewer_components/manager"):
|
||||
# self.path("SL_Launcher")
|
||||
# self.path("*.py")
|
||||
#with self.prefix(src=os.path.join("lib", "python", "llbase"), dst="llbase"):
|
||||
# self.path("*.py")
|
||||
# self.path("_cllsd.so")
|
||||
# with self.prefix(src="../viewer_components/manager", dst=""):
|
||||
# self.path("*.py")
|
||||
# </FS:Ansariel> Remove VMP
|
||||
|
||||
# recurses, packaged again
|
||||
|
|
@ -2246,7 +2134,7 @@ class LinuxManifest(ViewerManifest):
|
|||
["find"] +
|
||||
[os.path.join(self.get_dst_prefix(), dir) for dir in ('bin', 'lib')] +
|
||||
# <FS:Ansariel> Remove VMP
|
||||
#['-type', 'f', '!', '-name', '*.py', '!', '-name', 'SL_Launcher',
|
||||
# ['-type', 'f', '!', '-name', '*.py',
|
||||
['-type', 'f', "!", "-name", "*.dat", "!", "-name", "*.pak", "!", "-name", "*.bin",
|
||||
# </FS:Ansariel> Remove VMP
|
||||
'!', '-name', 'update_install', '-exec', 'strip', '-S', '{}', ';'])
|
||||
|
|
|
|||
|
|
@ -548,7 +548,6 @@ int main(int argc, char **argv)
|
|||
LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
|
||||
}
|
||||
LLError::setFatalFunction(wouldHaveCrashed);
|
||||
LLError::setPrintLocation(true);
|
||||
std::string test_app_name(argv[0]);
|
||||
std::string test_log = test_app_name + ".log";
|
||||
LLFile::remove(test_log);
|
||||
|
|
|
|||
|
|
@ -128,6 +128,15 @@ void LLLogin::Impl::connect(const std::string& uri, const LLSD& login_params)
|
|||
LL_DEBUGS("LLLogin") << " connected with uri '" << uri << "', login_params " << login_params << LL_ENDL;
|
||||
}
|
||||
|
||||
namespace {
|
||||
// Instantiate this rendezvous point at namespace scope so it's already
|
||||
// present no matter how early the updater might post to it.
|
||||
// Use an LLEventMailDrop, which has future-like semantics: regardless of the
|
||||
// relative order in which post() or listen() are called, it delivers each
|
||||
// post() event to its listener(s) until one of them consumes that event.
|
||||
static LLEventMailDrop sSyncPoint("LoginSync");
|
||||
}
|
||||
|
||||
void LLLogin::Impl::loginCoro(std::string uri, LLSD login_params)
|
||||
{
|
||||
LLSD printable_params = login_params;
|
||||
|
|
@ -219,7 +228,47 @@ void LLLogin::Impl::loginCoro(std::string uri, LLSD login_params)
|
|||
}
|
||||
else
|
||||
{
|
||||
// Synchronize here with the updater. We synchronize here rather
|
||||
// than in the fail.login handler, which actually examines the
|
||||
// response from login.cgi, because here we are definitely in a
|
||||
// coroutine and can definitely use suspendUntilBlah(). Whoever's
|
||||
// listening for fail.login might not be.
|
||||
|
||||
// If the reason for login failure is that we must install a
|
||||
// required update, we definitely want to pass control to the
|
||||
// updater to manage that for us. We'll handle any other login
|
||||
// failure ourselves, as usual. We figure that no matter where you
|
||||
// are in the world, or what kind of network you're on, we can
|
||||
// reasonably expect the Viewer Version Manager to respond more or
|
||||
// less as quickly as login.cgi. This synchronization is only
|
||||
// intended to smooth out minor races between the two services.
|
||||
// But what if the updater crashes? Use a timeout so that
|
||||
// eventually we'll tire of waiting for it and carry on as usual.
|
||||
// Given the above, it can be a fairly short timeout, at least
|
||||
// from a human point of view.
|
||||
|
||||
// Since sSyncPoint is an LLEventMailDrop, we DEFINITELY want to
|
||||
// consume the posted event.
|
||||
// <FS:Ansariel> Disable updater
|
||||
//LLCoros::OverrideConsuming oc(true);
|
||||
//// Timeout should produce the isUndefined() object passed here.
|
||||
//LL_DEBUGS("LLLogin") << "Login failure, waiting for sync from updater" << LL_ENDL;
|
||||
//LLSD updater = llcoro::suspendUntilEventOnWithTimeout(sSyncPoint, 10, LLSD());
|
||||
//if (updater.isUndefined())
|
||||
//{
|
||||
// LL_WARNS("LLLogin") << "Failed to hear from updater, proceeding with fail.login"
|
||||
// << LL_ENDL;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// LL_DEBUGS("LLLogin") << "Got responses from updater and login.cgi" << LL_ENDL;
|
||||
//}
|
||||
//// Let the fail.login handler deal with empty updater response.
|
||||
//LLSD responses(mAuthResponse["responses"]);
|
||||
//responses["updater"] = updater;
|
||||
//sendProgressEvent("offline", "fail.login", responses);
|
||||
sendProgressEvent("offline", "fail.login", mAuthResponse["responses"]);
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
return; // Done!
|
||||
}
|
||||
|
|
@ -249,10 +298,10 @@ void LLLogin::Impl::loginCoro(std::string uri, LLSD login_params)
|
|||
// *NOTE: The response from LLXMLRPCListener's Poller::poll method returns an
|
||||
// llsd with no "responses" node. To make the output from an incomplete login symmetrical
|
||||
// to success, add a data/message and data/reason fields.
|
||||
LLSD error_response;
|
||||
error_response["reason"] = mAuthResponse["status"];
|
||||
error_response["errorcode"] = mAuthResponse["errorcode"];
|
||||
error_response["message"] = mAuthResponse["error"];
|
||||
LLSD error_response(LLSDMap
|
||||
("reason", mAuthResponse["status"])
|
||||
("errorcode", mAuthResponse["errorcode"])
|
||||
("message", mAuthResponse["error"]));
|
||||
if(mAuthResponse.has("certificate"))
|
||||
{
|
||||
error_response["certificate"] = mAuthResponse["certificate"];
|
||||
|
|
|
|||
Loading…
Reference in New Issue