Merge branch 'master' of https://vcs.firestormviewer.org/phoenix-firestorm
commit
508eb80872
|
|
@ -14,8 +14,6 @@ env:
|
|||
EXTRA_ARGS: -DUSE_FMODSTUDIO=ON -DUSE_KDU=ON --crashreporting
|
||||
build_secrets_checkout: ${{github.workspace}}/signing
|
||||
XZ_DEFAULTS: -T0
|
||||
|
||||
|
||||
jobs:
|
||||
build_matrix:
|
||||
strategy:
|
||||
|
|
@ -25,21 +23,28 @@ jobs:
|
|||
addrsize: [64]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Install Bash 4 and GNU sed on Mac
|
||||
if: runner.os == 'macOS'
|
||||
run: |
|
||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
brew update
|
||||
brew install bash
|
||||
brew install gnu-sed
|
||||
|
||||
echo "/usr/local/bin" >> $GITHUB_PATH
|
||||
echo "$(brew --prefix)/opt/gnu-sed/libexec/gnubin" >> $GITHUB_PATH
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v4
|
||||
id: py311
|
||||
id: py312
|
||||
with:
|
||||
python-version: '3.11'
|
||||
python-version: '3.11.6'
|
||||
cache: 'pip'
|
||||
|
||||
- if: runner.os == 'Windows'
|
||||
run: |
|
||||
python3 -m pip install -r requirements.txt --user
|
||||
echo "$HOME/.local/bin" >> $GITHUB_PATH
|
||||
|
||||
- if: runner.os != 'Windows'
|
||||
- name: Install python requirements
|
||||
run: |
|
||||
python3 -m pip install -r requirements.txt
|
||||
python -m pip install -r requirements.txt
|
||||
|
||||
- name: Check python version
|
||||
run: python -V
|
||||
|
|
@ -54,6 +59,14 @@ jobs:
|
|||
EOF
|
||||
shell: bash
|
||||
|
||||
- name: Test python3 llsd
|
||||
run: |
|
||||
python3 - <<EOF
|
||||
import llsd
|
||||
print("Hello from inline Python script!")
|
||||
EOF
|
||||
shell: bash
|
||||
|
||||
- name: Free Disk Space (Ubuntu)
|
||||
if: runner.os == 'Linux'
|
||||
uses: jlumbroso/free-disk-space@main
|
||||
|
|
@ -66,17 +79,6 @@ jobs:
|
|||
echo "CC=gcc-10" >> $GITHUB_ENV
|
||||
echo "CXX=g++-10" >> $GITHUB_ENV
|
||||
|
||||
- name: Install Bash 4 and GNU sed on Mac
|
||||
if: runner.os == 'macOS'
|
||||
run: |
|
||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
brew update
|
||||
|
||||
brew install bash
|
||||
brew install gnu-sed
|
||||
|
||||
echo "/usr/local/bin" >> $GITHUB_PATH
|
||||
echo "$(brew --prefix)/opt/gnu-sed/libexec/gnubin" >> $GITHUB_PATH
|
||||
|
||||
- name: Setup rclone and download the folder
|
||||
uses: beqjanus/setup-rclone@main
|
||||
|
|
|
|||
|
|
@ -1479,9 +1479,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>3142fccbcc0e2c5a019e3177ef364290</string>
|
||||
<string>47af788cc447a64e311e3a65b74a9cf9</string>
|
||||
<key>url</key>
|
||||
<string>file:///opt/firestorm/kdu-8.3-darwin64-232392239.tar.bz2</string>
|
||||
<string>file:///opt/firestorm/kdu-8.4.1-darwin64-233220201.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
|
|
@ -1491,9 +1491,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>e13d6fe708613bb3a5d630c4cdd97a3b</string>
|
||||
<string>b464a547d5bedcc72e9173d860f40656</string>
|
||||
<key>url</key>
|
||||
<string>file:///opt/firestorm/kdu-8.3-linux64-232392238.tar.bz2</string>
|
||||
<string>file:///opt/firestorm/kdu-8.4.1-linux64-233220158.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -1503,9 +1503,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>4aa7df19125708580055b42190d2511e</string>
|
||||
<string>526965ad83ad9ee355b6596f489d82d9</string>
|
||||
<key>url</key>
|
||||
<string>file:///c:/cygwin/opt/firestorm/kdu-8.3-windows-232392239.tar.bz2</string>
|
||||
<string>file:///c:/cygwin/opt/firestorm/kdu-8.4.1-windows-233220159.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
|
|
|
|||
|
|
@ -2144,9 +2144,9 @@ if (WINDOWS)
|
|||
set_target_properties(${VIEWER_BINARY_NAME}
|
||||
PROPERTIES
|
||||
# *TODO -reenable this once we get server usage sorted out
|
||||
LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /LARGEADDRESSAWARE /LTCG"
|
||||
LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO /LARGEADDRESSAWARE /LTCG"
|
||||
LINK_FLAGS_RELEASE "/FORCE:MULTIPLE /MAP\"secondlife-bin.MAP\" /OPT:REF /LARGEADDRESSAWARE /LTCG"
|
||||
LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /LARGEADDRESSAWARE /LTCG /NOEXP /NOIMPLIB"
|
||||
LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO /LARGEADDRESSAWARE /LTCG /NOEXP /NOIMPLIB"
|
||||
LINK_FLAGS_RELEASE "/FORCE:MULTIPLE /MAP\"secondlife-bin.MAP\" /OPT:REF /LARGEADDRESSAWARE /LTCG /NOEXP /NOIMPLIB"
|
||||
)
|
||||
|
||||
if(USE_PRECOMPILED_HEADERS)
|
||||
|
|
|
|||
|
|
@ -534,7 +534,7 @@ bool FloaterAO::newSetCallback(const LLSD& notification, const LLSD& response)
|
|||
|
||||
if (option == 0)
|
||||
{
|
||||
return AOEngine::instance().addSet(newSetName, [this](const LLUUID& new_cat_id)
|
||||
AOEngine::instance().addSet(newSetName, [this](const LLUUID& new_cat_id)
|
||||
{
|
||||
reloading(true);
|
||||
});
|
||||
|
|
@ -891,14 +891,12 @@ BOOL FloaterAO::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDr
|
|||
*accept = ACCEPT_YES_MULTI;
|
||||
if (item && drop)
|
||||
{
|
||||
if (AOEngine::instance().addAnimation(mSelectedSet, mSelectedState, item))
|
||||
{
|
||||
addAnimation(item->getName());
|
||||
AOEngine::instance().addAnimation(mSelectedSet, mSelectedState, item);
|
||||
addAnimation(item->getName());
|
||||
|
||||
// TODO: this would be the right thing to do, but it blocks multi drop
|
||||
// before final release this must be resolved
|
||||
reloading(true);
|
||||
}
|
||||
// TODO: this would be the right thing to do, but it blocks multi drop
|
||||
// before final release this must be resolved
|
||||
reloading(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -55,7 +55,6 @@ AOEngine::AOEngine() :
|
|||
mInMouselook(false),
|
||||
mUnderWater(false),
|
||||
mImportSet(nullptr),
|
||||
mImportCategory(LLUUID::null),
|
||||
mAOFolder(LLUUID::null),
|
||||
mLastMotion(ANIM_AGENT_STAND),
|
||||
mLastOverriddenMotion(ANIM_AGENT_STAND)
|
||||
|
|
@ -976,61 +975,35 @@ void AOEngine::updateSortOrder(AOSet::AOState* state)
|
|||
}
|
||||
}
|
||||
|
||||
bool AOEngine::addSet(const std::string& name, inventory_func_type callback, bool reload)
|
||||
void AOEngine::addSet(const std::string& name, inventory_func_type callback, bool reload)
|
||||
{
|
||||
if (mAOFolder.isNull())
|
||||
{
|
||||
LL_WARNS("AOEngine") << ROOT_AO_FOLDER << " folder not there yet. Requesting recreation." << LL_ENDL;
|
||||
tick();
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
BOOL wasProtected = gSavedPerAccountSettings.getBOOL("LockAOFolders");
|
||||
gSavedPerAccountSettings.setBOOL("LockAOFolders", FALSE);
|
||||
LL_DEBUGS("AOEngine") << "adding set folder " << name << LL_ENDL;
|
||||
gInventory.createNewCategory(mAOFolder, LLFolderType::FT_NONE, name, [callback, wasProtected, reload, this](const LLUUID &new_cat_id)
|
||||
gInventory.createNewCategory(mAOFolder, LLFolderType::FT_NONE, name, [callback, wasProtected](const LLUUID &new_cat_id)
|
||||
{
|
||||
gSavedPerAccountSettings.setBOOL("LockAOFolders", wasProtected);
|
||||
|
||||
if (reload)
|
||||
{
|
||||
mTimerCollection.enableReloadTimer(true);
|
||||
}
|
||||
|
||||
callback(new_cat_id);
|
||||
});
|
||||
return true;
|
||||
|
||||
if (reload)
|
||||
{
|
||||
mTimerCollection.enableReloadTimer(true);
|
||||
}
|
||||
}
|
||||
|
||||
bool AOEngine::createAnimationLink(const AOSet* set, AOSet::AOState* state, const LLInventoryItem* item)
|
||||
bool AOEngine::createAnimationLink(AOSet::AOState* state, const LLInventoryItem* item)
|
||||
{
|
||||
LL_DEBUGS("AOEngine") << "Asset ID " << item->getAssetUUID() << " inventory id " << item->getUUID() << " category id " << state->mInventoryUUID << LL_ENDL;
|
||||
if (state->mInventoryUUID.isNull())
|
||||
{
|
||||
LL_DEBUGS("AOEngine") << "no " << state->mName << " folder yet. Creating ..." << LL_ENDL;
|
||||
gInventory.createNewCategory(set->getInventoryUUID(), LLFolderType::FT_NONE, state->mName);
|
||||
|
||||
LL_DEBUGS("AOEngine") << "looking for folder to get UUID ..." << LL_ENDL;
|
||||
LLUUID newStateFolderUUID;
|
||||
|
||||
LLInventoryModel::item_array_t* items;
|
||||
LLInventoryModel::cat_array_t* cats;
|
||||
gInventory.getDirectDescendentsOf(set->getInventoryUUID(), cats, items);
|
||||
|
||||
if (cats)
|
||||
{
|
||||
for (const auto& cat : *cats)
|
||||
{
|
||||
if (cat->getName().compare(state->mName) == 0)
|
||||
{
|
||||
LL_DEBUGS("AOEngine") << "UUID found!" << LL_ENDL;
|
||||
newStateFolderUUID = cat->getUUID();
|
||||
state->mInventoryUUID = newStateFolderUUID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
LL_DEBUGS("AOEngine") << "state " << state->mName << " item " << item->getName() << LL_ENDL;
|
||||
|
||||
if (state->mInventoryUUID.isNull())
|
||||
{
|
||||
|
|
@ -1046,7 +1019,7 @@ bool AOEngine::createAnimationLink(const AOSet* set, AOSet::AOState* state, cons
|
|||
return true;
|
||||
}
|
||||
|
||||
bool AOEngine::addAnimation(const AOSet* set, AOSet::AOState* state, const LLInventoryItem* item, bool reload)
|
||||
void AOEngine::addAnimation(const AOSet* set, AOSet::AOState* state, const LLInventoryItem* item, bool reload)
|
||||
{
|
||||
AOSet::AOAnimation anim;
|
||||
anim.mAssetUUID = item->getAssetUUID();
|
||||
|
|
@ -1057,14 +1030,47 @@ bool AOEngine::addAnimation(const AOSet* set, AOSet::AOState* state, const LLInv
|
|||
|
||||
BOOL wasProtected = gSavedPerAccountSettings.getBOOL("LockAOFolders");
|
||||
gSavedPerAccountSettings.setBOOL("LockAOFolders", FALSE);
|
||||
createAnimationLink(set, state, item);
|
||||
bool success = createAnimationLink(state, item);
|
||||
gSavedPerAccountSettings.setBOOL("LockAOFolders", wasProtected);
|
||||
|
||||
if (reload)
|
||||
if(success)
|
||||
{
|
||||
mTimerCollection.enableReloadTimer(true);
|
||||
if (reload)
|
||||
{
|
||||
mTimerCollection.enableReloadTimer(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// creating the animation link failed, so we need to create a new folder for this state -
|
||||
// add the animation asset to the queue of animations to insert into the state - this takes
|
||||
// care of multi animation drag & drop that come in faster than the viewer can create a new
|
||||
// inventory folder
|
||||
state->mAddQueue.push_back(item);
|
||||
|
||||
// if this is the first queued animation for this state, create the folder asyncronously
|
||||
if(state->mAddQueue.size() == 1)
|
||||
{
|
||||
gInventory.createNewCategory(set->getInventoryUUID(), LLFolderType::FT_NONE, state->mName, [this, state, reload, wasProtected](const LLUUID &new_cat_id)
|
||||
{
|
||||
state->mInventoryUUID = new_cat_id;
|
||||
gSavedPerAccountSettings.setBOOL("LockAOFolders", FALSE);
|
||||
|
||||
// add all queued animations to this state's folder and then clear the queue
|
||||
for (const auto item : state->mAddQueue)
|
||||
{
|
||||
createAnimationLink(state, item);
|
||||
}
|
||||
state->mAddQueue.clear();
|
||||
|
||||
gSavedPerAccountSettings.setBOOL("LockAOFolders", wasProtected);
|
||||
|
||||
if (reload)
|
||||
{
|
||||
mTimerCollection.enableReloadTimer(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AOEngine::findForeignItems(const LLUUID& uuid) const
|
||||
|
|
@ -1965,6 +1971,8 @@ bool AOEngine::importNotecard(const LLInventoryItem* item)
|
|||
|
||||
if (item->getAssetUUID().notNull())
|
||||
{
|
||||
// create the new set with the folder UUID where the notecard is in, so we can reference it
|
||||
// in the notecard reader, this will later be cleared to make room for the real #AO subfolder
|
||||
mImportSet = new AOSet(item->getParentUUID());
|
||||
mImportSet->setName(item->getName());
|
||||
|
||||
|
|
@ -2033,7 +2041,7 @@ void AOEngine::parseNotecard(const char* buffer)
|
|||
LL_WARNS("AOEngine") << "buffer==NULL - aborting import" << LL_ENDL;
|
||||
// NOTE: cleanup is always the same, needs streamlining
|
||||
delete mImportSet;
|
||||
mImportSet = 0;
|
||||
mImportSet = nullptr;
|
||||
mUpdatedSignal();
|
||||
return;
|
||||
}
|
||||
|
|
@ -2044,31 +2052,29 @@ void AOEngine::parseNotecard(const char* buffer)
|
|||
std::vector<std::string> lines;
|
||||
LLStringUtil::getTokens(text, lines, "\n");
|
||||
|
||||
bool found{ false };
|
||||
for (const auto& line : lines)
|
||||
{
|
||||
if (line.find("Text length ") == 0)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
auto it = std::find_if(lines.begin(), lines.end(), [](const std::string& line) {
|
||||
return line.find("Text length ") == 0;
|
||||
});
|
||||
|
||||
if (!found)
|
||||
{
|
||||
if (it == lines.end()) {
|
||||
// Line not found
|
||||
LLNotificationsUtil::add("AOImportNoText", LLSD());
|
||||
delete mImportSet;
|
||||
mImportSet = 0;
|
||||
mImportSet = nullptr;
|
||||
mUpdatedSignal();
|
||||
return;
|
||||
}
|
||||
|
||||
// Line found, 'it' points to the found element
|
||||
std::size_t found = std::distance(lines.begin(), it) + 1;
|
||||
|
||||
// mImportSet->getInventoryUUID() right now contains the folder UUID where the notecard is in
|
||||
LLViewerInventoryCategory* importCategory = gInventory.getCategory(mImportSet->getInventoryUUID());
|
||||
if (!importCategory)
|
||||
{
|
||||
LLNotificationsUtil::add("AOImportNoFolder", LLSD());
|
||||
delete mImportSet;
|
||||
mImportSet = 0;
|
||||
mImportSet = nullptr;
|
||||
mUpdatedSignal();
|
||||
return;
|
||||
}
|
||||
|
|
@ -2077,16 +2083,15 @@ void AOEngine::parseNotecard(const char* buffer)
|
|||
LLInventoryModel::cat_array_t* dummy;
|
||||
LLInventoryModel::item_array_t* items;
|
||||
|
||||
gInventory.getDirectDescendentsOf(mImportSet->getInventoryUUID(), dummy, items);
|
||||
for (auto index = 0; index < items->size(); ++index)
|
||||
{
|
||||
animationMap[items->at(index)->getName()] = items->at(index)->getUUID();
|
||||
LL_DEBUGS("AOEngine") << "animation " << items->at(index)->getName() <<
|
||||
" has inventory UUID " << animationMap[items->at(index)->getName()] << LL_ENDL;
|
||||
}
|
||||
gInventory.getDirectDescendentsOf(mImportSet->getInventoryUUID(), dummy, items);
|
||||
for (auto& item : *items)
|
||||
{
|
||||
animationMap[item->getName()] = item->getUUID();
|
||||
LL_DEBUGS("AOEngine") << "animation " << item->getName() << " has inventory UUID " << animationMap[item->getName()] << LL_ENDL;
|
||||
}
|
||||
|
||||
// [ State ]Anim1|Anim2|Anim3
|
||||
for (auto index = found + 1; index < lines.size(); ++index)
|
||||
for (auto index = found; index < lines.size(); ++index)
|
||||
{
|
||||
std::string line = lines[index];
|
||||
|
||||
|
|
@ -2169,6 +2174,8 @@ void AOEngine::parseNotecard(const char* buffer)
|
|||
return;
|
||||
}
|
||||
|
||||
// clear out set UUID so processImport() knows we need to create a new folder for it
|
||||
mImportSet->setInventoryUUID(LLUUID::null);
|
||||
mTimerCollection.enableImportTimer(true);
|
||||
mImportRetryCount = 0;
|
||||
processImport(false);
|
||||
|
|
@ -2176,74 +2183,87 @@ void AOEngine::parseNotecard(const char* buffer)
|
|||
|
||||
void AOEngine::processImport(bool from_timer)
|
||||
{
|
||||
if (mImportCategory.isNull())
|
||||
if (mImportSet->getInventoryUUID().isNull())
|
||||
{
|
||||
bool success = addSet(mImportSet->getName(), [this, from_timer](const LLUUID& new_cat_id)
|
||||
// create new inventory folder for this AO set, the next timer tick should pick it up
|
||||
addSet(mImportSet->getName(), [this](const LLUUID& new_cat_id)
|
||||
{
|
||||
mImportCategory = new_cat_id;
|
||||
mImportSet->setInventoryUUID(mImportCategory);
|
||||
|
||||
bool allComplete = true;
|
||||
for (S32 index = 0; index < AOSet::AOSTATES_MAX; ++index)
|
||||
{
|
||||
AOSet::AOState* state = mImportSet->getState(index);
|
||||
if (!state->mAnimations.empty())
|
||||
{
|
||||
allComplete = false;
|
||||
LL_DEBUGS("AOEngine") << "state " << state->mName << " still has animations to link." << LL_ENDL;
|
||||
|
||||
for (auto animationIndex = state->mAnimations.size() - 1; animationIndex >= 0; --animationIndex)
|
||||
{
|
||||
LL_DEBUGS("AOEngine") << "linking animation " << state->mAnimations[animationIndex].mName << LL_ENDL;
|
||||
if (createAnimationLink(mImportSet, state, gInventory.getItem(state->mAnimations[animationIndex].mInventoryUUID)))
|
||||
{
|
||||
LL_DEBUGS("AOEngine") << "link success, size " << state->mAnimations.size() << ", removing animation "
|
||||
<< (*(state->mAnimations.begin() + animationIndex)).mName << " from import state" << LL_ENDL;
|
||||
state->mAnimations.erase(state->mAnimations.begin() + animationIndex);
|
||||
LL_DEBUGS("AOEngine") << "deleted, size now: " << state->mAnimations.size() << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
LLSD args;
|
||||
args["NAME"] = state->mAnimations[animationIndex].mName;
|
||||
LLNotificationsUtil::add("AOImportLinkFailed", args);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (allComplete)
|
||||
{
|
||||
mTimerCollection.enableImportTimer(false);
|
||||
mOldImportSets.push_back(mImportSet); //<ND/> FIRE-3801; Cannot delete here, or LLInstanceTracker gets upset. Just remember and delete mOldImportSets once we can.
|
||||
mImportSet = nullptr;
|
||||
mImportCategory.setNull();
|
||||
reload(from_timer);
|
||||
}
|
||||
mImportSet->setInventoryUUID(new_cat_id);
|
||||
}, false);
|
||||
|
||||
if (!success)
|
||||
mImportRetryCount++;
|
||||
|
||||
// if it takes this long to create a new inventoey category, there might be something wrong,
|
||||
// so give some user feedback at first
|
||||
if (mImportRetryCount == 2)
|
||||
{
|
||||
mImportRetryCount++;
|
||||
if (mImportRetryCount == 5)
|
||||
{
|
||||
// NOTE: cleanup is the same as at the end of this function. Needs streamlining.
|
||||
mTimerCollection.enableImportTimer(false);
|
||||
delete mImportSet;
|
||||
mImportSet = nullptr;
|
||||
mImportCategory.setNull();
|
||||
mUpdatedSignal();
|
||||
LLSD args;
|
||||
args["NAME"] = mImportSet->getName();
|
||||
LLNotificationsUtil::add("AOImportAbortCreateSet", args);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLSD args;
|
||||
args["NAME"] = mImportSet->getName();
|
||||
LLNotificationsUtil::add("AOImportRetryCreateSet", args);
|
||||
}
|
||||
LLSD args;
|
||||
args["NAME"] = mImportSet->getName();
|
||||
LLNotificationsUtil::add("AOImportRetryCreateSet", args);
|
||||
return;
|
||||
}
|
||||
// by now there clearly is something wrong, so stop trying
|
||||
else if (mImportRetryCount == 5)
|
||||
{
|
||||
// NOTE: cleanup is the same as at the end of this function. Needs streamlining.
|
||||
mTimerCollection.enableImportTimer(false);
|
||||
delete mImportSet;
|
||||
mImportSet = nullptr;
|
||||
mUpdatedSignal();
|
||||
LLSD args;
|
||||
args["NAME"] = mImportSet->getName();
|
||||
LLNotificationsUtil::add("AOImportAbortCreateSet", args);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool allComplete = true;
|
||||
for (S32 index = 0; index < AOSet::AOSTATES_MAX; ++index)
|
||||
{
|
||||
AOSet::AOState* state = mImportSet->getState(index);
|
||||
if (!state->mAnimations.empty())
|
||||
{
|
||||
allComplete = false;
|
||||
LL_DEBUGS("AOEngine") << "state " << state->mName << " still has animations to link." << LL_ENDL;
|
||||
|
||||
gInventory.createNewCategory(mImportSet->getInventoryUUID(), LLFolderType::FT_NONE, state->mName, [this, state](const LLUUID& new_cat_id)
|
||||
{
|
||||
LL_DEBUGS("AOEngine") << "new_cat_id: " << new_cat_id << LL_ENDL;
|
||||
state->mInventoryUUID = new_cat_id;
|
||||
|
||||
S32 animationIndex = state->mAnimations.size() - 1;
|
||||
while (!state->mAnimations.empty())
|
||||
{
|
||||
LL_DEBUGS("AOEngine") << "linking animation " << state->mAnimations[animationIndex].mName << LL_ENDL;
|
||||
if (createAnimationLink(state, gInventory.getItem(state->mAnimations[animationIndex].mInventoryUUID)))
|
||||
{
|
||||
LL_DEBUGS("AOEngine") << "link success, size " << state->mAnimations.size() << ", removing animation "
|
||||
<< state->mAnimations[animationIndex].mName << " from import state" << LL_ENDL;
|
||||
state->mAnimations.pop_back();
|
||||
LL_DEBUGS("AOEngine") << "deleted, size now: " << state->mAnimations.size() << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
LLSD args;
|
||||
args["NAME"] = state->mAnimations[animationIndex].mName;
|
||||
LLNotificationsUtil::add("AOImportLinkFailed", args);
|
||||
}
|
||||
animationIndex--;
|
||||
}
|
||||
|
||||
LL_DEBUGS("AOEngine") << "exiting lambda" << LL_ENDL;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (allComplete)
|
||||
{
|
||||
mTimerCollection.enableImportTimer(false);
|
||||
mOldImportSets.push_back(mImportSet); //<ND/> FIRE-3801; Cannot delete here, or LLInstanceTracker gets upset. Just remember and delete mOldImportSets once we can.
|
||||
mImportSet = nullptr;
|
||||
reload(from_timer);
|
||||
LLNotificationsUtil::add("AOImportComplete");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -106,10 +106,10 @@ class AOEngine
|
|||
|
||||
const LLUUID& getAOFolder() const;
|
||||
|
||||
bool addSet(const std::string& name, inventory_func_type callback, bool reload = true);
|
||||
void addSet(const std::string& name, inventory_func_type callback, bool reload = true);
|
||||
bool removeSet(AOSet* set);
|
||||
|
||||
bool addAnimation(const AOSet* set, AOSet::AOState* state, const LLInventoryItem* item, bool reload = true);
|
||||
void addAnimation(const AOSet* set, AOSet::AOState* state, const LLInventoryItem* item, bool reload = true);
|
||||
bool removeAnimation(const AOSet* set, AOSet::AOState* state, S32 index);
|
||||
void checkSitCancel();
|
||||
void checkBelowWater(bool check_underwater);
|
||||
|
|
@ -176,7 +176,7 @@ class AOEngine
|
|||
void saveSet(const AOSet* set);
|
||||
void saveState(const AOSet::AOState* state);
|
||||
|
||||
bool createAnimationLink(const AOSet* set, AOSet::AOState* state, const LLInventoryItem* item);
|
||||
bool createAnimationLink(AOSet::AOState* state, const LLInventoryItem* item);
|
||||
bool findForeignItems(const LLUUID& uuid) const;
|
||||
void purgeFolder(const LLUUID& uuid) const;
|
||||
|
||||
|
|
@ -217,7 +217,6 @@ class AOEngine
|
|||
|
||||
AOSet* mImportSet;
|
||||
std::vector<AOSet*> mOldImportSets;
|
||||
LLUUID mImportCategory;
|
||||
S32 mImportRetryCount;
|
||||
|
||||
boost::signals2::connection mRegionChangeConnection;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
|
||||
#include "lleventtimer.h"
|
||||
|
||||
class LLInventoryItem;
|
||||
|
||||
class AOSet
|
||||
: public LLEventTimer
|
||||
{
|
||||
|
|
@ -78,6 +80,7 @@ class AOSet
|
|||
{
|
||||
std::string mName;
|
||||
std::vector<std::string> mAlternateNames;
|
||||
std::vector<const LLInventoryItem*> mAddQueue;
|
||||
LLUUID mRemapID;
|
||||
bool mCycle;
|
||||
bool mRandom;
|
||||
|
|
|
|||
|
|
@ -110,9 +110,13 @@
|
|||
#include "llavatarname.h"
|
||||
#include "llavatarnamecache.h"
|
||||
#include "llcorehttputil.h"
|
||||
#include "llfloater.h"
|
||||
#include "llformat.h"
|
||||
#include "llmatrix4a.h"
|
||||
#include "llpanel.h"
|
||||
#include "lluictrl.h"
|
||||
#include "llvector4a.h"
|
||||
#include "llview.h"
|
||||
#include <boost/array.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
|
@ -131,6 +135,6 @@
|
|||
#include <boost/function/function1.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <boost/unordered_set.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -10674,6 +10674,13 @@ Remove AO set "[AO_SET_NAME]" from the list?
|
|||
The animation overrider found at least one item that did not belong in the configuration. Please check your "Lost and Found" folder for items that were moved out of the animation overrider configuration.
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="notifytip.tga"
|
||||
name="AOImportComplete"
|
||||
type="notifytip">
|
||||
Animation Overrider notecard import complete!
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="notifytip.tga"
|
||||
name="AOImportSetAlreadyExists"
|
||||
|
|
|
|||
|
|
@ -4176,6 +4176,9 @@ Le nom ne peut contenir que des caractères ASCII, sauf ":" et "|".
|
|||
<notification name="AOForeignItemsFound">
|
||||
L'AO a trouvé au moins un élément qui n'avait pas sa place dans la configuration. Veuillez vérifier dans votre dossier "Objets trouvés" les éléments qui ont été déplacés hors de la configuration de l'AO.
|
||||
</notification>
|
||||
<notification name="AOImportComplete">
|
||||
L'importation de la notice d'AO est terminée !
|
||||
</notification>
|
||||
<notification name="AOImportSetAlreadyExists">
|
||||
Un ensemble d'animations portant ce nom existe déjà.
|
||||
</notification>
|
||||
|
|
|
|||
|
|
@ -3967,6 +3967,9 @@ Nazwa może zawierać tylko znaki ASCII, za wyjątkiem ":" oraz "|".
|
|||
Usunąć zestaw AO "[AO_SET_NAME]" z listy?
|
||||
<usetemplate name="okcancelbuttons" notext="Anuluj" yestext="Usuń"/>
|
||||
</notification>
|
||||
<notification name="AOImportComplete">
|
||||
Importowanie notki dla Animatora zakończone!
|
||||
</notification>
|
||||
<notification name="AOImportSetAlreadyExists">
|
||||
Zestaw animacji o tej nazwie już istnieje.
|
||||
</notification>
|
||||
|
|
|
|||
|
|
@ -53,8 +53,13 @@ viewer_dir = os.path.dirname(__file__)
|
|||
# indra.util.llmanifest under their system Python!
|
||||
sys.path.insert(0, os.path.join(viewer_dir, os.pardir, "lib", "python"))
|
||||
from indra.util.llmanifest import LLManifest, main, path_ancestors, CHANNEL_VENDOR_BASE, RELEASE_CHANNEL, ManifestError, MissingError
|
||||
import llsd
|
||||
|
||||
# <FS:Beq> try to work around weird Mac build issue that seems to find the wrong python
|
||||
#import llsd
|
||||
try:
|
||||
import llsd
|
||||
except ImportError:
|
||||
from llbase import llsd
|
||||
# </FS:Beq>
|
||||
class ViewerManifest(LLManifest,FSViewerManifest):
|
||||
def is_packaging_viewer(self):
|
||||
# Some commands, files will only be included
|
||||
|
|
|
|||
Loading…
Reference in New Issue