SL-288, SL-10163 - allow joint aliases, but otherwise reject upload of animations containing invalid joint names

# Conflicts:
#	indra/newview/llviewerassetupload.cpp
#	indra/newview/llvoavatar.cpp
master
Brad Payne (Vir Linden) 2018-12-07 21:27:12 +00:00 committed by Andrey Lihatskiy
parent d35f4536cc
commit f7edcab9c3
6 changed files with 71 additions and 9 deletions

View File

@ -927,6 +927,9 @@ BOOL LLAvatarAppearance::loadAvatar()
return FALSE;
}
// initialize mJointAliasMap
getJointAliases();
// avatar_lad.xml : <skeleton>
if( !loadSkeletonNode() )
{
@ -1047,7 +1050,6 @@ BOOL LLAvatarAppearance::loadAvatar()
return FALSE;
}
}
return TRUE;
}

View File

@ -1221,8 +1221,11 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8
//-----------------------------------------------------------------------------
// deserialize()
//
// allow_invalid_joints should be true when handling existing content, to avoid breakage.
// During upload, we should be more restrictive and reject such animations.
//-----------------------------------------------------------------------------
BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id)
BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, bool allow_invalid_joints)
{
BOOL old_version = FALSE;
mJointMotionList = new LLKeyframeMotion::JointMotionList;
@ -1464,7 +1467,10 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id)
{
LL_WARNS() << "invalid joint name: " << joint_name
<< " for animation " << asset_id << LL_ENDL;
//return FALSE;
if (!allow_invalid_joints)
{
return FALSE;
}
}
joint_motion->mJointName = joint_name;

View File

@ -156,7 +156,7 @@ public:
public:
U32 getFileSize();
BOOL serialize(LLDataPacker& dp) const;
BOOL deserialize(LLDataPacker& dp, const LLUUID& asset_id);
BOOL deserialize(LLDataPacker& dp, const LLUUID& asset_id, bool allow_invalid_joints = true);
BOOL isLoaded() { return mJointMotionList != NULL; }
void dumpToFile(const std::string& name);

View File

@ -294,7 +294,7 @@ BOOL LLFloaterBvhPreview::postBuild()
loaderp->serialize(dp);
dp.reset();
LL_INFOS("BVH") << "Deserializing motionp" << LL_ENDL;
BOOL success = motionp && motionp->deserialize(dp, mMotionID);
BOOL success = motionp && motionp->deserialize(dp, mMotionID, false);
LL_INFOS("BVH") << "Done" << LL_ENDL;
delete []buffer;

View File

@ -450,9 +450,54 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile()
errorLabel = "DoNotSupportBulkAnimationUpload";
error = true;
}
else if (assetType == LLAssetType::AT_ANIMATION)
else if (exten == "anim")
{
filename = getFileName();
// Default unless everything succeeds
errorLabel = "ProblemWithFile";
error = true;
// read from getFileName()
LLAPRFile infile;
infile.open(getFileName(),LL_APR_RB);
if (!infile.getFileHandle())
{
LL_WARNS() << "Couldn't open file for reading: " << getFileName() << LL_ENDL;
errorMessage = llformat("Failed to open animation file %s\n", getFileName().c_str());
}
else
{
S32 size = LLAPRFile::size(getFileName());
U8* buffer = new U8[size];
S32 size_read = infile.read(buffer,size);
if (size_read != size)
{
errorMessage = llformat("Failed to read animation file %s: wanted %d bytes, got %d\n", getFileName().c_str(), size, size_read);
}
else
{
LLDataPackerBinaryBuffer dp(buffer, size);
LLKeyframeMotion *motionp = new LLKeyframeMotion(getAssetId());
motionp->setCharacter(gAgentAvatarp);
if (motionp->deserialize(dp, getAssetId(), false))
{
// write to temp file
bool succ = motionp->dumpToFile(filename);
if (succ)
{
assetType = LLAssetType::AT_ANIMATION;
errorLabel = "";
error = false;
}
}
}
}
}
else
{
// Unknown extension
errorMessage = llformat(LLTrans::getString("UnknownFileExtension").c_str(), exten.c_str());
errorLabel = "ErrorMessage";
error = TRUE;;
}
if (error)

View File

@ -6145,8 +6145,17 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name )
LLJoint* jointp = NULL;
if (iter == mJointMap.end() || iter->second == NULL)
{ //search for joint and cache found joint in lookup table
jointp = mRoot->findJoint(name);
joint_alias_map_t::const_iterator alias_iter = mJointAliasMap.find(name);
std::string canonical_name;
if (alias_iter != mJointAliasMap.end())
{
canonical_name = alias_iter->second;
}
else
{
canonical_name = name;
}
jointp = mRoot->findJoint(canonical_name);
mJointMap[name] = jointp;
}
else