From f378dc9d6b8f74d34b4dfd3b65cf564c689bdb95 Mon Sep 17 00:00:00 2001 From: Mike Date: Fri, 23 Oct 2026 09:49:49 -0400 Subject: Add a loopback MCP server for the running viewer (#44) The server is off by default and listens on 127.0.0.1. It can see and act in the logged-in session, including inventory, object contents, script editing, mesh and material upload, and animated mesh. --- indra/newview/llmodelpreview.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'indra/newview/llmodelpreview.cpp') diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index d97525d494..523d55b62f 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -975,6 +975,10 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) if (!mModelLoader) { mLoading = false; + if (mFMP) + { + ((LLFloaterModelPreview*)mFMP)->onHeadlessModelFailed("model loader was not running"); + } return; } if (getLoadState() >= LLModelLoader::ERROR_PARSING) @@ -982,6 +986,10 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) mLoading = false; mModelLoader = NULL; mLodsWithParsingError.push_back(loaded_lod); + if (mFMP) + { + ((LLFloaterModelPreview*)mFMP)->onHeadlessModelFailed("failed to parse the model file"); + } return; } @@ -1277,6 +1285,20 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) mModelLoadedSignal(); mModelLoader = NULL; + + // The next LOD load rejects a live loader. Schedule it after this + // callback returns so the mutex is released and mModelLoader is clear. + if (mFMP) + { + LLFloaterModelPreview* floater = (LLFloaterModelPreview*)mFMP; + doOnIdleOneTime([floater, loaded_lod]() + { + if (LLFloaterModelPreview::sInstance == floater) + { + floater->onHeadlessModelReady(loaded_lod); + } + }); + } } void LLModelPreview::resetPreviewTarget() -- cgit v1.3