Merge branch 'DRTVWR-591-maint-X' of https://github.com/secondlife/viewer

# Conflicts:
#	indra/fix-incredibuild.py
#	indra/newview/app_settings/settings.xml
#	indra/newview/llcontrolavatar.cpp
#	indra/newview/lloutfitslist.cpp
master
Ansariel 2024-04-12 19:36:23 +02:00
commit 9b30bc68c1
23 changed files with 251 additions and 328 deletions

View File

@ -13,7 +13,6 @@ jobs:
matrix:
runner: [windows-large, macos-12-xl]
configuration: [Release, ReleaseOS]
python-version: ["3.11"]
include:
- runner: macos-12-xl
developer_dir: "/Applications/Xcode_14.0.1.app/Contents/Developer"
@ -67,7 +66,7 @@ jobs:
- name: Setup python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
python-version: "3.11"
- name: Checkout build variables
uses: actions/checkout@v4

View File

@ -1,73 +0,0 @@
# BuildParams
#
# Please refer to:
# https://wiki.secondlife.com/wiki/Automated_Build_System
# Variants (NOTE: 'Release' must be last for uploads to work correctly)
variants = "RelWithDebInfo Release"
# Use Public Upload Locations
public_build = true
build_docs = true
# enable Doxygen building on Linux for TeamCity (it can be done manually on any platform)
build_Linux_Doxygen = true
# Need viewer-build-variables as well as other shared repositories
buildscripts_shared_more_NAMEs="build_secrets build_variables git_hooks"
# Python 3 / SL-15742
BUILDSCRIPTS_PY3 = "true"
################################################################
#### Examples of how to set the viewer_channel ####
#
# To build a Release or Release candidate in build bingo:
# bingo.viewer_channel = "Second Life Release"
#
# To build a Beta for the 'Bingo' project in build bingo:
# bingo.viewer_channel = "Second Life Beta Bingo"
#
# To build a Project viewer for the 'Bingo' project in build bingo:
# bingo.viewer_channel = "Second Life Project Bingo"
#
# If left unset, viewer_channel defaults to 'Second Life Test',
# which is appropriate for individual developer builds.
#
# All Linden Lab builds (and only Linden Lab builds)
# should use a viewer_channel that begins with "Second Life"
################################################################
viewer_channel = "Second Life Test"
################################################################
# Special packaging parameters.
# These parameters can be used to create additional packages
# which identify themselves in a distinct way with either
# a sourceid (sent to web services) or a channel name (sent to login)
# the default sourceid should always be a null string:
sourceid = ""
# the additional_packages variable is a blank separated list of package prefixes:
# additional_packages = ""
# to set the special values for a package, create variables using each prefix:
# additional_packages = "Foo Bar"
# Foo_sourceid = "bingo"
# Foo_viewer_channel_suffix = "Foo"
# Bar_sourceid = "bongo"
# Bar_viewer_channel_suffix = "Bar"
# the viewer_channel_suffix is prefixed by a blank and then appended to the viewer_channel
# for the package in a setting that overrides the compiled-in value
################################################################
additional_packages = "EDU"
Linux.additional_packages = ""
# The EDU package allows us to create a separate release channel whose expirations
# are synchronized as much as possible with the academic year
EDU_sourceid = ""
EDU_viewer_channel_suffix = "edu"
# Notifications - to configure email notices use the TeamCity parameter
# setting screen for your project or build configuration to set the
# environment variable 'email' to a space-separated list of email addresses
email=""

View File

@ -6,9 +6,6 @@
# it relies on the environment that sets up, functions it provides, and
# the build result post-processing it does.
#
# The shared buildscript build.sh invokes this because it is named 'build.sh',
# which is the default custom build script name in buildscripts/hg/BuildParams
#
# PLEASE NOTE:
#
# * This script is interpreted on three platforms, including windows and cygwin

View File

@ -1,61 +0,0 @@
#!/usr/bin/env python3
##
## $LicenseInfo:firstyear=2011&license=viewerlgpl$
## Second Life Viewer Source Code
## Copyright (C) 2011, Linden Research, Inc.
##
## This library is free software; you can redistribute it and/or
## modify it under the terms of the GNU Lesser General Public
## License as published by the Free Software Foundation;
## version 2.1 of the License only.
##
## This library is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
## Lesser General Public License for more details.
##
## You should have received a copy of the GNU Lesser General Public
## License along with this library; if not, write to the Free Software
## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
##
## Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
## $/LicenseInfo$
import sys
import os
import glob
def delete_file_types(path, filetypes):
if os.path.exists(path):
print('Cleaning: ' + path)
orig_dir = os.getcwd();
os.chdir(path)
filelist = []
for type in filetypes:
filelist.extend(glob.glob(type))
for file in filelist:
os.remove(file)
os.chdir(orig_dir)
def main():
build_types = ['*.exp','*.exe','*.pdb','*.idb',
'*.ilk','*.lib','*.obj','*.ib_pdb_index']
pch_types = ['*.pch']
delete_file_types("build-vc80/newview/Release", build_types)
delete_file_types("build-vc80/newview/firestorm-bin.dir/Release/",
pch_types)
delete_file_types("build-vc80/newview/RelWithDebInfo", build_types)
delete_file_types("build-vc80/newview/firestorm-bin.dir/RelWithDebInfo/",
pch_types)
delete_file_types("build-vc80/newview/Debug", build_types)
delete_file_types("build-vc80/newview/firestorm-bin.dir/Debug/",
pch_types)
delete_file_types("build-vc80/test/RelWithDebInfo", build_types)
delete_file_types("build-vc80/test/test.dir/RelWithDebInfo/",
pch_types)
if __name__ == "__main__":
main()

View File

@ -1388,6 +1388,10 @@ BOOL gunzip_file(const std::string& srcfile, const std::string& dstfile)
} while(gzeof(src) == 0);
fclose(dst);
dst = NULL;
#if LL_WINDOWS
// Rename in windows needs the dstfile to not exist.
LLFile::remove(dstfile, ENOENT);
#endif
if (LLFile::rename(tmpfile, dstfile) == -1) goto err; /* Flawfinder: ignore */
retval = TRUE;
err:

View File

@ -27,6 +27,7 @@
#include "linden_common.h"
#include "stdtypes.h"
#include "llerror.h"
#include "llexception.h"
#include "llimage.h"
#include "llpngwrapper.h"
@ -51,29 +52,44 @@ bool LLImagePNG::updateData()
{
resetLastError();
// Check to make sure that this instance has been initialized with data
if (!getData() || (0 == getDataSize()))
try
{
setLastError("Uninitialized instance of LLImagePNG");
// Check to make sure that this instance has been initialized with data
if (!getData() || (0 == getDataSize()))
{
setLastError("Uninitialized instance of LLImagePNG");
return false;
}
// Decode the PNG data and extract sizing information
LLPngWrapper pngWrapper;
if (!pngWrapper.isValidPng(getData()))
{
setLastError("LLImagePNG data does not have a valid PNG header!");
return false;
}
LLPngWrapper::ImageInfo infop;
if (!pngWrapper.readPng(getData(), getDataSize(), NULL, &infop))
{
setLastError(pngWrapper.getErrorMessage());
return false;
}
setSize(infop.mWidth, infop.mHeight, infop.mComponents);
}
catch (const LLContinueError& msg)
{
setLastError(msg.what());
LOG_UNHANDLED_EXCEPTION("");
return false;
}
catch (...)
{
setLastError("LLImagePNG");
LOG_UNHANDLED_EXCEPTION("");
return false;
}
// Decode the PNG data and extract sizing information
LLPngWrapper pngWrapper;
if (!pngWrapper.isValidPng(getData()))
{
setLastError("LLImagePNG data does not have a valid PNG header!");
return false;
}
LLPngWrapper::ImageInfo infop;
if (! pngWrapper.readPng(getData(), getDataSize(), NULL, &infop))
{
setLastError(pngWrapper.getErrorMessage());
return false;
}
setSize(infop.mWidth, infop.mHeight, infop.mComponents);
return true;
}

View File

@ -216,6 +216,13 @@ BOOL LLPngWrapper::readPng(U8* src, S32 dataSize, LLImageRaw* rawImage, ImageInf
releaseResources();
return (FALSE);
}
catch (...)
{
mErrorMessage = "LLPngWrapper";
releaseResources();
LOG_UNHANDLED_EXCEPTION("");
return (FALSE);
}
// Clean up and return
releaseResources();

View File

@ -733,7 +733,7 @@ LLSD LLSettingsSky::defaults(const LLSettingsBase::TrackPosition& position)
dfltsetting[SETTING_CLOUD_POS_DENSITY1] = LLColor4(1.0000f, 0.5260f, 1.0000f, 0.0f).getValue();
dfltsetting[SETTING_CLOUD_POS_DENSITY2] = LLColor4(1.0000f, 0.5260f, 1.0000f, 0.0f).getValue();
dfltsetting[SETTING_CLOUD_SCALE] = LLSD::Real(0.4199);
dfltsetting[SETTING_CLOUD_SCROLL_RATE] = llsd::array(0.0f, 0.0f);
dfltsetting[SETTING_CLOUD_SCROLL_RATE] = llsd::array(0.2, 0.01);
dfltsetting[SETTING_CLOUD_SHADOW] = LLSD::Real(0.2699);
dfltsetting[SETTING_CLOUD_VARIANCE] = LLSD::Real(0.0);

View File

@ -1556,6 +1556,11 @@ bool LLNotifications::loadTemplates()
// specific skin.
std::vector<std::string> search_paths =
gDirUtilp->findSkinnedFilenames(LLDir::XUI, "notifications.xml", LLDir::ALL_SKINS);
if (search_paths.empty())
{
LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"));
LL_ERRS() << "Problem finding notifications.xml" << LL_ENDL;
}
std::string base_filename = search_paths.front();
LLXMLNodePtr root;

View File

@ -187,6 +187,7 @@ LLTextBase::Params::Params()
trusted_content("trusted_content", true),
always_show_icons("always_show_icons", false),
use_ellipses("use_ellipses", false),
use_emoji("use_emoji", true),
use_color("use_color", true),
// <FS:Ansariel> Optional icon position
icon_positioning("icon_positioning", LLTextBaseEnums::RIGHT),
@ -252,6 +253,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
mPlainText ( p.plain_text ),
mWordWrap(p.wrap),
mUseEllipses( p.use_ellipses ),
mUseEmoji(p.use_emoji),
mUseColor(p.use_color),
mParseHTML(p.parse_urls),
mForceUrlsExternal(p.force_urls_external),
@ -1052,6 +1054,7 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s
}
// Insert special segments where necessary (insertSegment takes care of splitting normal text segments around them for us)
if (mUseEmoji)
{
static LLUICachedControl<bool> useBWEmojis("FSUseBWEmojis", false); // <FS:Beq/> Add B&W emoji font support
LLStyleSP emoji_style;

View File

@ -352,6 +352,7 @@ public:
plain_text,
wrap,
use_ellipses,
use_emoji,
use_color,
parse_urls,
force_urls_external,
@ -434,12 +435,15 @@ public:
virtual void onSpellCheckPerformed(){}
// used by LLTextSegment layout code
bool getWordWrap() { return mWordWrap; }
bool getUseEllipses() { return mUseEllipses; }
bool getUseColor() { return mUseColor; }
bool getWordWrap() const { return mWordWrap; }
bool getUseEllipses() const { return mUseEllipses; }
bool getUseEmoji() const { return mUseEmoji; }
void setUseEmoji(bool value) { mUseEmoji = value; }
bool getUseColor() const { return mUseColor; }
void setUseColor(bool value) { mUseColor = value; }
bool truncate(); // returns true of truncation occurred
bool isContentTrusted() {return mTrustedContent;}
bool isContentTrusted() const { return mTrustedContent; }
void setContentTrusted(bool trusted_content) { mTrustedContent = trusted_content; }
// TODO: move into LLTextSegment?
@ -773,6 +777,7 @@ protected:
bool mParseHighlights; // highlight user-defined keywords
bool mWordWrap;
bool mUseEllipses;
bool mUseEmoji;
bool mUseColor;
bool mTrackEnd; // if true, keeps scroll position at end of document during resize
bool mReadOnly;

View File

@ -506,10 +506,12 @@ void LLFloaterEmojiPicker::fillCategoryRecentlyUsed(std::map<std::string, std::v
auto e2d = emoji2descr.find(emoji);
if (e2d != emoji2descr.end() && !e2d->second->ShortCodes.empty())
{
const std::string shortcode(e2d->second->ShortCodes.front());
if (LLEmojiDictionary::searchInShortCode(begin, end, shortcode, mFilterPattern))
for (const std::string& shortcode : e2d->second->ShortCodes)
{
emojis.emplace_back(emoji, shortcode, begin, end);
if (LLEmojiDictionary::searchInShortCode(begin, end, shortcode, mFilterPattern))
{
emojis.emplace_back(emoji, shortcode, begin, end);
}
}
}
}
@ -538,10 +540,12 @@ void LLFloaterEmojiPicker::fillCategoryFrequentlyUsed(std::map<std::string, std:
auto e2d = emoji2descr.find(emoji.first);
if (e2d != emoji2descr.end() && !e2d->second->ShortCodes.empty())
{
const std::string shortcode(e2d->second->ShortCodes.front());
if (LLEmojiDictionary::searchInShortCode(begin, end, shortcode, mFilterPattern))
for (const std::string& shortcode : e2d->second->ShortCodes)
{
emojis.emplace_back(emoji.first, shortcode, begin, end);
if (LLEmojiDictionary::searchInShortCode(begin, end, shortcode, mFilterPattern))
{
emojis.emplace_back(emoji.first, shortcode, begin, end);
}
}
}
}
@ -574,10 +578,12 @@ void LLFloaterEmojiPicker::fillGroupEmojis(std::map<std::string, std::vector<LLE
{
if (!descr->ShortCodes.empty())
{
const std::string shortcode(descr->ShortCodes.front());
if (LLEmojiDictionary::searchInShortCode(begin, end, shortcode, mFilterPattern))
for (const std::string& shortcode : descr->ShortCodes)
{
emojis.emplace_back(descr->Character, shortcode, begin, end);
if (LLEmojiDictionary::searchInShortCode(begin, end, shortcode, mFilterPattern))
{
emojis.emplace_back(descr->Character, shortcode, begin, end);
}
}
}
}

View File

@ -524,54 +524,62 @@ void LLFloaterImagePreview::draw()
//-----------------------------------------------------------------------------
bool LLFloaterImagePreview::loadImage(const std::string& src_filename)
{
std::string exten = gDirUtilp->getExtension(src_filename);
U32 codec = LLImageBase::getCodecFromExtension(exten);
try
{
std::string exten = gDirUtilp->getExtension(src_filename);
U32 codec = LLImageBase::getCodecFromExtension(exten);
LLImageDimensionsInfo image_info;
if (!image_info.load(src_filename,codec))
{
mImageLoadError = image_info.getLastError();
return false;
}
LLImageDimensionsInfo image_info;
if (!image_info.load(src_filename, codec))
{
mImageLoadError = image_info.getLastError();
return false;
}
S32 max_width = gSavedSettings.getS32("max_texture_dimension_X");
S32 max_height = gSavedSettings.getS32("max_texture_dimension_Y");
S32 max_width = gSavedSettings.getS32("max_texture_dimension_X");
S32 max_height = gSavedSettings.getS32("max_texture_dimension_Y");
if ((image_info.getWidth() > max_width) || (image_info.getHeight() > max_height))
{
LLStringUtil::format_map_t args;
args["WIDTH"] = llformat("%d", max_width);
args["HEIGHT"] = llformat("%d", max_height);
if ((image_info.getWidth() > max_width) || (image_info.getHeight() > max_height))
{
LLStringUtil::format_map_t args;
args["WIDTH"] = llformat("%d", max_width);
args["HEIGHT"] = llformat("%d", max_height);
mImageLoadError = LLTrans::getString("texture_load_dimensions_error", args);
return false;
}
// Load the image
LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec);
if (image.isNull())
{
return false;
}
if (!image->load(src_filename))
{
return false;
}
// Decompress or expand it in a raw image structure
LLPointer<LLImageRaw> raw_image = new LLImageRaw;
if (!image->decode(raw_image, 0.0f))
{
return false;
}
// Check the image constraints
if ((image->getComponents() != 3) && (image->getComponents() != 4))
{
image->setLastError("Image files with less than 3 or more than 4 components are not supported.");
return false;
}
raw_image->biasedScaleToPowerOfTwo(1024);
mRawImagep = raw_image;
mImageLoadError = LLTrans::getString("texture_load_dimensions_error", args);
return false;
}
// Load the image
LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec);
if (image.isNull())
{
return false;
}
if (!image->load(src_filename))
{
return false;
}
// Decompress or expand it in a raw image structure
LLPointer<LLImageRaw> raw_image = new LLImageRaw;
if (!image->decode(raw_image, 0.0f))
{
return false;
}
// Check the image constraints
if ((image->getComponents() != 3) && (image->getComponents() != 4))
{
image->setLastError("Image files with less than 3 or more than 4 components are not supported.");
return false;
}
raw_image->biasedScaleToPowerOfTwo(1024);
mRawImagep = raw_image;
}
catch (...)
{
LOG_UNHANDLED_EXCEPTION("");
return false;
}
return true;
}

View File

@ -73,8 +73,6 @@ void LLProfileImageCtrl::releaseTexture()
}
mImage = NULL;
}
LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList);
}
void LLProfileImageCtrl::setValue(const LLSD& value)

View File

@ -2940,6 +2940,17 @@ bool LLInventoryModel::loadSkeleton(
gzip_filename.append(".gz");
LLFILE* fp = LLFile::fopen(gzip_filename, "rb");
bool remove_inventory_file = false;
if (LLAppViewer::instance()->isSecondInstance())
{
// Safeguard viewer against trying to unpack file twice
// ex: user logs into two accounts simultaneously, so two
// viewers are trying to unpack library into same file
//
// Would be better to do it in gunzip_file, but it doesn't
// have access to llfilesystem
inventory_filename = gDirUtilp->getTempFilename();
remove_inventory_file = true;
}
if(fp)
{
fclose(fp);
@ -3148,7 +3159,7 @@ bool LLInventoryModel::loadSkeleton(
// clean up the gunzipped file.
LLFile::remove(inventory_filename);
}
if(is_cache_obsolete)
if(is_cache_obsolete && !LLAppViewer::instance()->isSecondInstance())
{
// If out of date, remove the gzipped file too.
LL_WARNS(LOG_INV) << "Inv cache out of date, removing" << LL_ENDL;

View File

@ -3907,7 +3907,9 @@ std::string LLStartUp::startupStateToString(EStartupState state)
RTNENUM( STATE_AGENT_SEND );
RTNENUM( STATE_AGENT_WAIT );
RTNENUM( STATE_INVENTORY_SEND );
RTNENUM(STATE_INVENTORY_CALLBACKS );
RTNENUM( STATE_INVENTORY_CALLBACKS );
RTNENUM( STATE_INVENTORY_SKEL );
RTNENUM( STATE_INVENTORY_SEND2 );
RTNENUM( STATE_MISC );
RTNENUM( STATE_PRECACHE );
RTNENUM( STATE_WEARABLES_WAIT );

View File

@ -54,8 +54,8 @@ S32 BUTTON_WIDTH = 90;
//static
const LLFontGL* LLToastNotifyPanel::sFont = NULL;
const LLFontGL* LLToastNotifyPanel::sFontSmall = NULL;
const std::string LLToastNotifyPanel::sFontDefault("Emoji");
const std::string LLToastNotifyPanel::sFontScript("SansSerif");
LLToastNotifyPanel::button_click_signal_t LLToastNotifyPanel::sButtonClickSignal;
@ -89,11 +89,15 @@ LLButton* LLToastNotifyPanel::createButton(const LLSD& form_element, BOOL is_opt
mBtnCallbackData.push_back(userdata);
LLButton::Params p;
bool make_small_btn = form_element["index"].asInteger() == -1 || form_element["index"].asInteger() == -2;
const LLFontGL* font = make_small_btn ? sFontSmall: sFont; // for block and ignore buttons in script dialog
p.name = form_element["name"].asString();
p.label = form_element["text"].asString();
p.tool_tip = form_element["text"].asString();
S32 index = form_element["index"].asInteger();
std::string name = form_element["name"].asString();
std::string text = form_element["text"].asString();
bool make_small_btn = index == -1 || index == -2; // for block and ignore buttons in script dialog
const LLFontGL* font = LLFontGL::getFont(LLFontDescriptor(
mIsScriptDialog ? sFontScript : sFontDefault, make_small_btn ? "Small" : "Medium", 0));
p.name = name;
p.label = text;
p.tool_tip = text;
p.font = font;
p.rect.height = BTN_HEIGHT;
p.click_callback.function(boost::bind(&LLToastNotifyPanel::onClickButton, userdata));
@ -263,19 +267,12 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
{
deleteAllChildren();
mTextBox = NULL;
mInfoPanel = NULL;
mControlPanel = NULL;
mNumOptions = 0;
mNumButtons = 0;
mAddedDefaultBtn = false;
LLRect current_rect = getRect();
setXMLFilename("");
buildFromFile("panel_notification.xml");
if(rect != LLRect::null)
if (rect != LLRect::null)
{
this->setShape(rect);
}
@ -302,12 +299,6 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
// setup parameters
// get a notification message
mMessage = mNotification->getMessage();
// init font variables
if (!sFont)
{
sFont = LLFontGL::getFontSansSerif();
sFontSmall = LLFontGL::getFontSansSerifSmall();
}
// initialize
setFocusRoot(!mIsTip);
// get a form for the notification
@ -325,15 +316,18 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
if (mIsCaution && !mIsTip)
{
mTextBox = getChild<LLTextBox>("caution_text_box");
mTextBox->setFont(LLFontGL::getFont(LLFontDescriptor(mIsScriptDialog ? sFontScript : sFontDefault, "Medium", LLFontGL::BOLD)));
}
else
{
mTextBox = getChild<LLTextEditor>("text_editor_box");
mTextBox->setFont(LLFontGL::getFont(LLFontDescriptor(mIsScriptDialog ? sFontScript : sFontDefault, "Medium", 0)));
}
mTextBox->setMaxTextLength(LLToastPanel::MAX_TEXT_LENGTH);
mTextBox->setVisible(TRUE);
mTextBox->setPlainText(!show_images);
mTextBox->setUseEmoji(!mIsScriptDialog);
mTextBox->setContentTrusted(is_content_trusted);
mTextBox->setValue(mNotification->getMessage());
mTextBox->setIsFriendCallback(LLAvatarActions::isFriend);

View File

@ -102,9 +102,9 @@ protected:
//std::vector<index_button_pair_t> mButtons;
// panel elements
LLTextBase* mTextBox;
LLPanel* mInfoPanel; // a panel, that contains an information
LLPanel* mControlPanel; // a panel, that contains buttons (if present)
LLTextBase* mTextBox { nullptr };
LLPanel* mInfoPanel { nullptr }; // panel for text information
LLPanel* mControlPanel { nullptr }; // panel for buttons (if present)
// internal handler for button being clicked
static void onClickButton(void* data);
@ -124,17 +124,17 @@ protected:
*/
//void disableRespondedOptions(const LLNotificationPtr& notification);
bool mIsTip;
bool mAddedDefaultBtn;
bool mIsScriptDialog;
bool mIsCaution;
bool mIsTip { false };
bool mAddedDefaultBtn { false };
bool mIsScriptDialog { false };
bool mIsCaution { false };
std::string mMessage;
S32 mNumOptions;
S32 mNumButtons;
S32 mNumOptions { 0 };
S32 mNumButtons { 0 };
static const LLFontGL* sFont;
static const LLFontGL* sFontSmall;
static const std::string sFontDefault;
static const std::string sFontScript;
};
class LLIMToastNotifyPanel : public LLToastNotifyPanel

View File

@ -5302,6 +5302,12 @@ void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data)
LLVOAvatar::AnimSourceIterator anim_it = avatarp->mAnimationSources.find(object_id);
for (;anim_it != avatarp->mAnimationSources.end(); ++anim_it)
{
if (anim_it->first != object_id)
{
// elements with the same key are always contiguous, bail if we went past the
// end of this object's animations
break;
}
if (anim_it->second == animation_id)
{
anim_found = TRUE;

View File

@ -1313,7 +1313,7 @@ bool LLViewerTextureList::createUploadFile(LLPointer<LLImageRaw> raw_image,
return true;
}
BOOL LLViewerTextureList::createUploadFile(const std::string& filename,
bool LLViewerTextureList::createUploadFile(const std::string& filename,
const std::string& out_filename,
const U8 codec,
const S32 max_image_dimentions,
@ -1321,64 +1321,72 @@ BOOL LLViewerTextureList::createUploadFile(const std::string& filename,
bool force_square)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
// Load the image
LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec);
if (image.isNull())
{
LL_WARNS() << "Couldn't open the image to be uploaded." << LL_ENDL;
return FALSE;
}
if (!image->load(filename))
{
image->setLastError("Couldn't load the image to be uploaded.");
return FALSE;
}
// Decompress or expand it in a raw image structure
LLPointer<LLImageRaw> raw_image = new LLImageRaw;
if (!image->decode(raw_image, 0.0f))
{
image->setLastError("Couldn't decode the image to be uploaded.");
return FALSE;
}
// Check the image constraints
if ((image->getComponents() != 3) && (image->getComponents() != 4))
{
image->setLastError("Image files with less than 3 or more than 4 components are not supported.");
return FALSE;
}
if (image->getWidth() < min_image_dimentions || image->getHeight() < min_image_dimentions)
try
{
std::string reason = llformat("Images below %d x %d pixels are not allowed. Actual size: %d x %dpx",
min_image_dimentions,
min_image_dimentions,
image->getWidth(),
image->getHeight());
image->setLastError(reason);
return FALSE;
// Load the image
LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec);
if (image.isNull())
{
LL_WARNS() << "Couldn't open the image to be uploaded." << LL_ENDL;
return false;
}
if (!image->load(filename))
{
image->setLastError("Couldn't load the image to be uploaded.");
return false;
}
// Decompress or expand it in a raw image structure
LLPointer<LLImageRaw> raw_image = new LLImageRaw;
if (!image->decode(raw_image, 0.0f))
{
image->setLastError("Couldn't decode the image to be uploaded.");
return false;
}
// Check the image constraints
if ((image->getComponents() != 3) && (image->getComponents() != 4))
{
image->setLastError("Image files with less than 3 or more than 4 components are not supported.");
return false;
}
if (image->getWidth() < min_image_dimentions || image->getHeight() < min_image_dimentions)
{
std::string reason = llformat("Images below %d x %d pixels are not allowed. Actual size: %d x %dpx",
min_image_dimentions,
min_image_dimentions,
image->getWidth(),
image->getHeight());
image->setLastError(reason);
return false;
}
// Convert to j2c (JPEG2000) and save the file locally
LLPointer<LLImageJ2C> compressedImage = convertToUploadFile(raw_image, max_image_dimentions, force_square);
if (compressedImage.isNull())
{
image->setLastError("Couldn't convert the image to jpeg2000.");
LL_INFOS() << "Couldn't convert to j2c, file : " << filename << LL_ENDL;
return false;
}
if (!compressedImage->save(out_filename))
{
image->setLastError("Couldn't create the jpeg2000 image for upload.");
LL_INFOS() << "Couldn't create output file : " << out_filename << LL_ENDL;
return false;
}
// Test to see if the encode and save worked
LLPointer<LLImageJ2C> integrity_test = new LLImageJ2C;
if (!integrity_test->loadAndValidate(out_filename))
{
image->setLastError("The created jpeg2000 image is corrupt.");
LL_INFOS() << "Image file : " << out_filename << " is corrupt" << LL_ENDL;
return false;
}
}
// Convert to j2c (JPEG2000) and save the file locally
LLPointer<LLImageJ2C> compressedImage = convertToUploadFile(raw_image, max_image_dimentions, force_square);
if (compressedImage.isNull())
{
image->setLastError("Couldn't convert the image to jpeg2000.");
LL_INFOS() << "Couldn't convert to j2c, file : " << filename << LL_ENDL;
return FALSE;
}
if (!compressedImage->save(out_filename))
{
image->setLastError("Couldn't create the jpeg2000 image for upload.");
LL_INFOS() << "Couldn't create output file : " << out_filename << LL_ENDL;
return FALSE;
}
// Test to see if the encode and save worked
LLPointer<LLImageJ2C> integrity_test = new LLImageJ2C;
if (!integrity_test->loadAndValidate( out_filename ))
{
image->setLastError("The created jpeg2000 image is corrupt.");
LL_INFOS() << "Image file : " << out_filename << " is corrupt" << LL_ENDL;
return FALSE;
}
return TRUE;
catch (...)
{
LOG_UNHANDLED_EXCEPTION("");
return false;
}
return true;
}
// note: modifies the argument raw_image!!!!

View File

@ -96,7 +96,7 @@ public:
const std::string& out_filename,
const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT,
const S32 min_image_dimentions = 0);
static BOOL createUploadFile(const std::string& filename,
static bool createUploadFile(const std::string& filename,
const std::string& out_filename,
const U8 codec,
const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT,

View File

@ -1195,7 +1195,11 @@ void LLVOAvatarSelf::stopMotionFromSource(const LLUUID& source_id)
for (AnimSourceIterator motion_it = mAnimationSources.find(source_id); motion_it != mAnimationSources.end(); )
{
gAgent.sendAnimationRequest(motion_it->second, ANIM_REQUEST_STOP);
mAnimationSources.erase(motion_it++);
mAnimationSources.erase(motion_it);
// Must find() after each erase() to deal with potential iterator invalidation
// This also ensures that we don't go past the end of this source's animations
// into those of another source.
motion_it = mAnimationSources.find(source_id);
}

View File

@ -32,21 +32,6 @@
<text
border_visible="false"
follows="left|right|top|bottom"
font="SansSerif"
height="85"
layout="topleft"
left="10"
name="text_box"
read_only="true"
text_color="White"
top="10"
visible="false"
width="285"
wrap="true"/>
<text
border_visible="false"
follows="left|right|top|bottom"
font="SansSerifBold"
height="85"
layout="topleft"
left="10"
@ -64,7 +49,6 @@
embedded_items="false"
enabled="false"
follows="left|right|top|bottom"
font="SansSerif"
height="85"
layout="topleft"
left="10"