diff options
Diffstat (limited to 'linden/indra/newview/primbackup.cpp')
-rw-r--r-- | linden/indra/newview/primbackup.cpp | 1269 |
1 files changed, 710 insertions, 559 deletions
diff --git a/linden/indra/newview/primbackup.cpp b/linden/indra/newview/primbackup.cpp index 613000a..6d9d73f 100644 --- a/linden/indra/newview/primbackup.cpp +++ b/linden/indra/newview/primbackup.cpp | |||
@@ -1,7 +1,6 @@ | |||
1 | 1 | ||
2 | #include "llviewerprecompiledheaders.h" | 2 | #include "llviewerprecompiledheaders.h" |
3 | 3 | ||
4 | |||
5 | // system library includes | 4 | // system library includes |
6 | #include <iostream> | 5 | #include <iostream> |
7 | #include <fstream> | 6 | #include <fstream> |
@@ -60,67 +59,89 @@ | |||
60 | 59 | ||
61 | #include "llviewerobjectlist.h" | 60 | #include "llviewerobjectlist.h" |
62 | 61 | ||
63 | primbackup* primbackup::sInstance = 0; | 62 | PrimBackup* PrimBackup::sInstance = NULL; |
63 | |||
64 | // Note: these default textures are initialized with hard coded values to | ||
65 | // prevent cheating. When not in SL, the user-configurable values are used | ||
66 | // instead (see setDefaultTextures() below). | ||
67 | static LLUUID LL_TEXTURE_PLYWOOD = LLUUID("89556747-24cb-43ed-920b-47caed15465f"); | ||
68 | static LLUUID LL_TEXTURE_BLANK = LLUUID("5748decc-f629-461c-9a36-a35a221fe21f"); | ||
69 | static LLUUID LL_TEXTURE_INVISIBLE = LLUUID("38b86f85-2575-52a9-a531-23108d8da837"); | ||
70 | static LLUUID LL_TEXTURE_TRANSPARENT = LLUUID("8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"); | ||
71 | static LLUUID LL_TEXTURE_MEDIA = LLUUID("8b5fec65-8d8d-9dc5-cda8-8fdf2716e361"); | ||
72 | |||
73 | void setDefaultTextures() | ||
74 | { | ||
75 | if (!gHippoGridManager->getConnectedGrid()->isSecondLife()) | ||
76 | { | ||
77 | // When not in SL (no texture perm check needed), we can get these | ||
78 | // defaults from the user settings... | ||
79 | LL_TEXTURE_PLYWOOD = LLUUID(gSavedSettings.getString("DefaultObjectTexture")); | ||
80 | LL_TEXTURE_BLANK = LLUUID(gSavedSettings.getString("UIImgWhiteUUID")); | ||
81 | if (gSavedSettings.controlExists("UIImgInvisibleUUID")) | ||
82 | { | ||
83 | // This control only exists in the AllowInvisibleTextureInPicker patch | ||
84 | LL_TEXTURE_INVISIBLE = LLUUID(gSavedSettings.getString("UIImgInvisibleUUID")); | ||
85 | } | ||
86 | } | ||
87 | } | ||
64 | 88 | ||
65 | class importResponder: public LLNewAgentInventoryResponder | 89 | class importResponder: public LLNewAgentInventoryResponder |
66 | { | 90 | { |
67 | public: | 91 | public: |
68 | 92 | ||
69 | importResponder(const LLSD& post_data, | 93 | importResponder(const LLSD& post_data, const LLUUID& vfile_id, LLAssetType::EType asset_type) |
70 | const LLUUID& vfile_id, | ||
71 | LLAssetType::EType asset_type) | ||
72 | : LLNewAgentInventoryResponder(post_data, vfile_id, asset_type) | 94 | : LLNewAgentInventoryResponder(post_data, vfile_id, asset_type) |
73 | { | 95 | { |
74 | } | 96 | } |
75 | 97 | ||
76 | 98 | //virtual | |
77 | //virtual | ||
78 | virtual void uploadComplete(const LLSD& content) | 99 | virtual void uploadComplete(const LLSD& content) |
79 | { | 100 | { |
80 | lldebugs << "LLNewAgentInventoryResponder::result from capabilities" << llendl; | 101 | lldebugs << "LLNewAgentInventoryResponder::result from capabilities" << llendl; |
81 | 102 | ||
82 | LLAssetType::EType asset_type = LLAssetType::lookup(mPostData["asset_type"].asString()); | 103 | LLAssetType::EType asset_type = LLAssetType::lookup(mPostData["asset_type"].asString()); |
83 | LLInventoryType::EType inventory_type = LLInventoryType::lookup(mPostData["inventory_type"].asString()); | 104 | LLInventoryType::EType inventory_type = LLInventoryType::lookup(mPostData["inventory_type"].asString()); |
84 | 105 | ||
85 | // Update L$ and ownership credit information | 106 | // Update currency and ownership credit information |
86 | // since it probably changed on the server | 107 | // since it probably changed on the server |
87 | if (asset_type == LLAssetType::AT_TEXTURE || | 108 | if (asset_type == LLAssetType::AT_TEXTURE || |
88 | asset_type == LLAssetType::AT_SOUND || | 109 | asset_type == LLAssetType::AT_SOUND || |
89 | asset_type == LLAssetType::AT_ANIMATION) | 110 | asset_type == LLAssetType::AT_ANIMATION) |
90 | { | ||
91 | gMessageSystem->newMessageFast(_PREHASH_MoneyBalanceRequest); | ||
92 | gMessageSystem->nextBlockFast(_PREHASH_AgentData); | ||
93 | gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); | ||
94 | gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); | ||
95 | gMessageSystem->nextBlockFast(_PREHASH_MoneyData); | ||
96 | gMessageSystem->addUUIDFast(_PREHASH_TransactionID, LLUUID::null ); | ||
97 | gAgent.sendReliableMessage(); | ||
98 | |||
99 | // LLStringUtil::format_map_t args; | ||
100 | // args["[AMOUNT]"] = llformat("%d",LLGlobalEconomy::Singleton::getInstance()->getPriceUpload()); | ||
101 | // LLNotifyBox::showXml("UploadPayment", args); | ||
102 | } | ||
103 | |||
104 | // Actually add the upload to viewer inventory | ||
105 | llinfos << "Adding " << content["new_inventory_item"].asUUID() << " " | ||
106 | << content["new_asset"].asUUID() << " to inventory." << llendl; | ||
107 | if(mPostData["folder_id"].asUUID().notNull()) | ||
108 | { | ||
109 | LLPermissions perm; | ||
110 | U32 next_owner_perm; | ||
111 | perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); | ||
112 | if (mPostData["inventory_type"].asString() == "snapshot") | ||
113 | { | 111 | { |
114 | next_owner_perm = PERM_ALL; | 112 | gMessageSystem->newMessageFast(_PREHASH_MoneyBalanceRequest); |
113 | gMessageSystem->nextBlockFast(_PREHASH_AgentData); | ||
114 | gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); | ||
115 | gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); | ||
116 | gMessageSystem->nextBlockFast(_PREHASH_MoneyData); | ||
117 | gMessageSystem->addUUIDFast(_PREHASH_TransactionID, LLUUID::null ); | ||
118 | gAgent.sendReliableMessage(); | ||
119 | |||
120 | // LLStringUtil::format_map_t args; | ||
121 | // args["[AMOUNT]"] = llformat("%d",LLGlobalEconomy::Singleton::getInstance()->getPriceUpload()); | ||
122 | // LLNotifyBox::showXml("UploadPayment", args); | ||
115 | } | 123 | } |
116 | else | 124 | |
125 | // Actually add the upload to viewer inventory | ||
126 | llinfos << "Adding " << content["new_inventory_item"].asUUID() << " " | ||
127 | << content["new_asset"].asUUID() << " to inventory." << llendl; | ||
128 | if (mPostData["folder_id"].asUUID().notNull()) | ||
117 | { | 129 | { |
118 | next_owner_perm = PERM_MOVE | PERM_TRANSFER; | 130 | LLPermissions perm; |
119 | } | 131 | U32 next_owner_perm; |
120 | perm.initMasks(PERM_ALL, PERM_ALL, PERM_NONE, PERM_NONE, next_owner_perm); | 132 | perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); |
121 | S32 creation_date_now = time_corrected(); | 133 | if (mPostData["inventory_type"].asString() == "snapshot") |
122 | LLPointer<LLViewerInventoryItem> item | 134 | { |
123 | = new LLViewerInventoryItem(content["new_inventory_item"].asUUID(), | 135 | next_owner_perm = PERM_ALL; |
136 | } | ||
137 | else | ||
138 | { | ||
139 | next_owner_perm = PERM_MOVE | PERM_TRANSFER; | ||
140 | } | ||
141 | perm.initMasks(PERM_ALL, PERM_ALL, PERM_NONE, PERM_NONE, next_owner_perm); | ||
142 | S32 creation_date_now = time_corrected(); | ||
143 | LLPointer<LLViewerInventoryItem> item | ||
144 | = new LLViewerInventoryItem(content["new_inventory_item"].asUUID(), | ||
124 | mPostData["folder_id"].asUUID(), | 145 | mPostData["folder_id"].asUUID(), |
125 | perm, | 146 | perm, |
126 | content["new_asset"].asUUID(), | 147 | content["new_asset"].asUUID(), |
@@ -131,95 +152,96 @@ class importResponder: public LLNewAgentInventoryResponder | |||
131 | LLSaleInfo::DEFAULT, | 152 | LLSaleInfo::DEFAULT, |
132 | LLInventoryItem::II_FLAGS_NONE, | 153 | LLInventoryItem::II_FLAGS_NONE, |
133 | creation_date_now); | 154 | creation_date_now); |
134 | gInventory.updateItem(item); | 155 | gInventory.updateItem(item); |
135 | gInventory.notifyObservers(); | 156 | gInventory.notifyObservers(); |
136 | } | 157 | } |
137 | else | 158 | else |
138 | { | 159 | { |
139 | llwarns << "Can't find a folder to put it in" << llendl; | 160 | llwarns << "Can't find a folder to put it into" << llendl; |
140 | } | 161 | } |
141 | 162 | ||
142 | // remove the "Uploading..." message | 163 | // remove the "Uploading..." message |
143 | LLUploadDialog::modalUploadFinished(); | 164 | LLUploadDialog::modalUploadFinished(); |
144 | |||
145 | primbackup::getInstance()->update_map(content["new_asset"].asUUID()); | ||
146 | primbackup::getInstance()->upload_next_asset(); | ||
147 | 165 | ||
166 | PrimBackup::getInstance()->updateMap(content["new_asset"].asUUID()); | ||
167 | PrimBackup::getInstance()->uploadNextAsset(); | ||
148 | } | 168 | } |
149 | |||
150 | }; | 169 | }; |
151 | 170 | ||
152 | |||
153 | |||
154 | class CacheReadResponder : public LLTextureCache::ReadResponder | 171 | class CacheReadResponder : public LLTextureCache::ReadResponder |
172 | { | ||
173 | public: | ||
174 | CacheReadResponder(const LLUUID& id, LLImageFormatted* image) | ||
175 | : mFormattedImage(image), mID(id) | ||
176 | { | ||
177 | setImage(image); | ||
178 | } | ||
179 | void setData(U8* data, S32 datasize, S32 imagesize, S32 imageformat, BOOL imagelocal) | ||
155 | { | 180 | { |
156 | public: | 181 | if (imageformat == IMG_CODEC_TGA && mFormattedImage->getCodec() == IMG_CODEC_J2C) |
157 | CacheReadResponder(const LLUUID& id, LLImageFormatted* image) | ||
158 | : mFormattedImage(image), mID(id) | ||
159 | { | 182 | { |
160 | setImage(image); | 183 | llwarns << "FAILED: texture " << mID << " is formatted as TGA. Not saving." << llendl; |
184 | PrimBackup::getInstance()->mNonExportedTextures |= PrimBackup::TEXTURE_BAD_ENCODING; | ||
185 | mFormattedImage = NULL; | ||
186 | mImageSize = 0; | ||
187 | return; | ||
161 | } | 188 | } |
162 | void setData(U8* data, S32 datasize, S32 imagesize, S32 imageformat, BOOL imagelocal) | 189 | |
190 | if (mFormattedImage.notNull()) | ||
163 | { | 191 | { |
164 | if(imageformat==IMG_CODEC_TGA && mFormattedImage->getCodec()==IMG_CODEC_J2C) | 192 | llassert_always(mFormattedImage->getCodec() == imageformat); |
165 | { | 193 | mFormattedImage->appendData(data, datasize); |
166 | llwarns<<"Bleh its a tga not saving"<<llendl; | 194 | } |
167 | mFormattedImage=NULL; | 195 | else |
168 | mImageSize=0; | 196 | { |
169 | return; | 197 | mFormattedImage = LLImageFormatted::createFromType(imageformat); |
170 | } | 198 | mFormattedImage->setData(data, datasize); |
199 | } | ||
200 | mImageSize = imagesize; | ||
201 | mImageLocal = imagelocal; | ||
202 | } | ||
171 | 203 | ||
172 | if (mFormattedImage.notNull()) | 204 | virtual void completed(bool success) |
173 | { | 205 | { |
174 | llassert_always(mFormattedImage->getCodec() == imageformat); | 206 | if (success && mFormattedImage.notNull() && mImageSize > 0) |
175 | mFormattedImage->appendData(data, datasize); | 207 | { |
176 | } | 208 | llinfos << "SUCCESS getting texture " << mID << llendl; |
177 | else | 209 | std::string name; |
210 | mID.toString(name); | ||
211 | name = PrimBackup::getInstance()->getfolder() + "//" + name; | ||
212 | llinfos << "Saving to " << name << llendl; | ||
213 | if (!mFormattedImage->save(name)) | ||
178 | { | 214 | { |
179 | mFormattedImage = LLImageFormatted::createFromType(imageformat); | 215 | llwarns << "FAILED to save texture " << mID << llendl; |
180 | mFormattedImage->setData(data,datasize); | 216 | PrimBackup::getInstance()->mNonExportedTextures |= PrimBackup::TEXTURE_SAVED_FAILED; |
181 | } | 217 | } |
182 | mImageSize = imagesize; | ||
183 | mImageLocal = imagelocal; | ||
184 | } | 218 | } |
185 | 219 | else | |
186 | virtual void completed(bool success) | ||
187 | { | 220 | { |
188 | if(success && (mFormattedImage.notNull()) && mImageSize>0) | 221 | if (!success) |
189 | { | 222 | { |
190 | 223 | llwarns << "FAILED to get texture " << mID << llendl; | |
191 | llinfos << "SUCCESS getting texture "<<mID<< llendl; | 224 | PrimBackup::getInstance()->mNonExportedTextures |= PrimBackup::TEXTURE_MISSING; |
192 | |||
193 | std::string name; | ||
194 | mID.toString(name); | ||
195 | llinfos << "Saving to "<<(primbackup::getInstance()->getfolder()+"//"+name)<<llendl; | ||
196 | if(!mFormattedImage->save(primbackup::getInstance()->getfolder()+"//"+name)) | ||
197 | { | ||
198 | llinfos << "FAIL saving texture "<<mID<< llendl; | ||
199 | } | ||
200 | |||
201 | } | 225 | } |
202 | else | 226 | if (mFormattedImage.isNull()) |
203 | { | 227 | { |
204 | if(!success) | 228 | llwarns << "FAILED: NULL texture " << mID << llendl; |
205 | llwarns << "FAIL NOT SUCCESSFUL getting texture "<<mID<< llendl; | 229 | PrimBackup::getInstance()->mNonExportedTextures |= PrimBackup::TEXTURE_IS_NULL; |
206 | if(mFormattedImage.isNull()) | 230 | } |
207 | llwarns << "FAIL image is NULL "<<mID<< llendl; | ||
208 | } | ||
209 | |||
210 | primbackup::getInstance()->m_nexttextureready=true; | ||
211 | //JUST SAY NO TO APR DEADLOCKING | ||
212 | //primbackup::getInstance()->export_next_texture(); | ||
213 | } | 231 | } |
214 | private: | ||
215 | LLPointer<LLImageFormatted> mFormattedImage; | ||
216 | LLUUID mID; | ||
217 | }; | ||
218 | 232 | ||
233 | PrimBackup::getInstance()->mNextTextureReady = true; | ||
234 | //JUST SAY NO TO APR DEADLOCKING | ||
235 | //PrimBackup::getInstance()->exportNextTexture(); | ||
236 | } | ||
237 | private: | ||
238 | LLPointer<LLImageFormatted> mFormattedImage; | ||
239 | LLUUID mID; | ||
240 | }; | ||
219 | 241 | ||
220 | 242 | ||
221 | primbackup::primbackup() | 243 | PrimBackup::PrimBackup() |
222 | : LLFloater( std::string("Prim Import Floater") ) | 244 | : LLFloater( std::string("Prim Import Floater"), std::string("FloaterPrimImport"), LLStringUtil::null) |
223 | { | 245 | { |
224 | LLUICtrlFactory::getInstance()->buildFloater( this, "floater_prim_import.xml" ); | 246 | LLUICtrlFactory::getInstance()->buildFloater( this, "floater_prim_import.xml" ); |
225 | 247 | ||
@@ -228,253 +250,354 @@ primbackup::primbackup() | |||
228 | //reshape( rect.getWidth(), rect.getHeight(), FALSE ); | 250 | //reshape( rect.getWidth(), rect.getHeight(), FALSE ); |
229 | //setRect( rect ); | 251 | //setRect( rect ); |
230 | 252 | ||
231 | running=false; | 253 | mRunning = false; |
232 | textures.clear(); | 254 | mTexturesList.clear(); |
233 | assetmap.clear(); | 255 | mAssetMap.clear(); |
234 | current_asset=LLUUID::null; | 256 | mCurrentAsset = LLUUID::null; |
235 | m_retexture=false; | 257 | mRetexture = false; |
236 | close(); | 258 | close(); |
237 | } | 259 | } |
238 | 260 | ||
239 | 261 | ||
240 | //////////////////////////////////////////////////////////////////////////////// | 262 | //////////////////////////////////////////////////////////////////////////////// |
241 | // | 263 | // |
242 | primbackup* primbackup::getInstance() | 264 | PrimBackup* PrimBackup::getInstance() |
243 | { | 265 | { |
244 | if ( ! sInstance ) | 266 | if (!sInstance) |
245 | sInstance = new primbackup(); | 267 | sInstance = new PrimBackup(); |
246 | |||
247 | return sInstance; | 268 | return sInstance; |
248 | } | 269 | } |
249 | 270 | ||
250 | primbackup::~primbackup() | 271 | PrimBackup::~PrimBackup() |
251 | { | 272 | { |
252 | // save position of floater | 273 | // save position of floater |
253 | gSavedSettings.setRect( "FloaterPrimImport", getRect() ); | 274 | gSavedSettings.setRect("FloaterPrimImport", getRect()); |
254 | sInstance = 0; | 275 | sInstance = NULL; |
255 | } | 276 | } |
256 | 277 | ||
257 | void primbackup::draw() | 278 | void PrimBackup::draw() |
258 | { | 279 | { |
259 | LLFloater::draw(); | 280 | LLFloater::draw(); |
260 | } | 281 | } |
261 | 282 | ||
262 | void primbackup::show() | 283 | void PrimBackup::show(bool exporting) |
263 | { | 284 | { |
264 | // set the title | 285 | // set the title |
265 | setTitle( "stuff" ); | 286 | if (exporting) |
266 | m_curobject=1; | 287 | { |
267 | m_curprim=0; | 288 | setTitle("Object export"); |
268 | m_objects=0; | 289 | } |
269 | m_prims=0; | 290 | else |
270 | m_textures=0; | 291 | { |
271 | m_curtexture=0; | 292 | setTitle("Object import"); |
272 | rezcount=0; | 293 | } |
294 | mCurObject = 1; | ||
295 | mCurPrim = 0; | ||
296 | mObjects = 0; | ||
297 | mPrims = 0; | ||
298 | mRezCount = 0; | ||
273 | 299 | ||
274 | // make floater appear | 300 | // make floater appear |
275 | setVisibleAndFrontmost(); | 301 | setVisibleAndFrontmost(); |
276 | } | 302 | } |
277 | 303 | ||
278 | 304 | void PrimBackup::onClose(bool app_quitting) | |
279 | void primbackup::onClose( bool app_quitting ) | ||
280 | { | 305 | { |
281 | setVisible( false ); | 306 | setVisible(false); |
282 | // HACK for fast XML iteration replace with: | 307 | // HACK for fast XML iteration replace with: |
283 | // destroy(); | 308 | // destroy(); |
284 | } | 309 | } |
285 | 310 | ||
286 | void primbackup::updateexportnumbers() | 311 | void PrimBackup::updateExportNumbers() |
287 | { | 312 | { |
313 | std::stringstream sstr; | ||
314 | LLUICtrl* ctrl = getChild<LLUICtrl>("name_label"); | ||
288 | 315 | ||
289 | std::stringstream sstr; | 316 | sstr << "Export Progress \n"; |
290 | LLUICtrl * ctrl=this->getChild<LLUICtrl>("name_label"); | ||
291 | |||
292 | sstr<<"Export Progress \n"; | ||
293 | 317 | ||
294 | sstr << "Remaining Textures "<<textures.size()<<"\n"; | 318 | sstr << "Remaining Textures " << mTexturesList.size() << "\n"; |
295 | ctrl->setValue(LLSD("Text")=sstr.str()); | 319 | ctrl->setValue(LLSD("Text") = sstr.str()); |
296 | |||
297 | } | 320 | } |
298 | 321 | ||
299 | 322 | void PrimBackup::updateImportNumbers() | |
300 | void primbackup::updateimportnumbers() | ||
301 | { | 323 | { |
302 | std::stringstream sstr; | 324 | std::stringstream sstr; |
303 | LLUICtrl * ctrl=this->getChild<LLUICtrl>("name_label"); | 325 | LLUICtrl* ctrl = getChild<LLUICtrl>("name_label"); |
304 | 326 | ||
305 | if(m_retexture) | 327 | if (mRetexture) |
306 | { | 328 | { |
307 | sstr << " Textures uploads remaining : "<<textures.size()<<"\n"; | 329 | sstr << " Textures uploads remaining : " << mTexturesList.size() << "\n"; |
308 | ctrl->setValue(LLSD("Text")=sstr.str()); | 330 | ctrl->setValue(LLSD("Text") = sstr.str()); |
309 | } | 331 | } |
310 | else | 332 | else |
311 | { | 333 | { |
312 | sstr << " Textures uploads N/A \n"; | 334 | sstr << " Textures uploads N/A \n"; |
313 | ctrl->setValue(LLSD("Text")=sstr.str()); | 335 | ctrl->setValue(LLSD("Text") = sstr.str()); |
314 | } | 336 | } |
315 | sstr << " Objects "<<this->m_curobject<<"/"<<this->m_objects<<"\n"; | ||
316 | ctrl->setValue(LLSD("Text")=sstr.str()); | ||
317 | |||
318 | sstr << " Rez "<<this->rezcount<<"/"<<this->m_prims; | ||
319 | ctrl->setValue(LLSD("Text")=sstr.str()); | ||
320 | 337 | ||
321 | sstr << " Build "<<this->m_curprim<<"/"<<this->m_prims; | 338 | sstr << " Objects " << mCurObject << "/" << mObjects << "\n"; |
322 | ctrl->setValue(LLSD("Text")=sstr.str()); | 339 | ctrl->setValue(LLSD("Text") = sstr.str()); |
323 | 340 | ||
341 | sstr << " Rez "<< mRezCount << "/" << mPrims; | ||
342 | ctrl->setValue(LLSD("Text") = sstr.str()); | ||
324 | 343 | ||
344 | sstr << " Build " << mCurPrim << "/" << mPrims; | ||
345 | ctrl->setValue(LLSD("Text") = sstr.str()); | ||
325 | } | 346 | } |
326 | 347 | ||
327 | void primbackup::pre_export_object() | 348 | void PrimBackup::exportObject() |
328 | { | 349 | { |
329 | textures.clear(); | 350 | mTexturesList.clear(); |
330 | llsd.clear(); | 351 | mLLSD.clear(); |
331 | this_group.clear(); | 352 | mThisGroup.clear(); |
353 | |||
354 | setDefaultTextures(); | ||
332 | 355 | ||
333 | // Open the file save dialog | 356 | // Open the file save dialog |
334 | LLFilePicker& file_picker = LLFilePicker::instance(); | 357 | LLFilePicker& file_picker = LLFilePicker::instance(); |
335 | if( !file_picker.getSaveFile( LLFilePicker::FFSAVE_XML ) ) | 358 | if (!file_picker.getSaveFile(LLFilePicker::FFSAVE_XML, LLSelectMgr::getInstance()->getSelection()->getFirstRootNode()->mName)) |
336 | { | 359 | { |
337 | // User canceled save. | 360 | // User canceled save. |
338 | return; | 361 | return; |
339 | } | 362 | } |
340 | |||
341 | file_name = file_picker.getCurFile(); | ||
342 | folder = gDirUtilp->getDirName(file_name); | ||
343 | 363 | ||
344 | export_state=EXPORT_INIT; | 364 | mFileName = file_picker.getCurFile(); |
345 | gIdleCallbacks.addFunction(exportworker, NULL); | 365 | mFolder = gDirUtilp->getDirName(mFileName); |
346 | } | ||
347 | 366 | ||
367 | mNonExportedTextures = TEXTURE_OK; | ||
368 | |||
369 | mExportState = EXPORT_INIT; | ||
370 | gIdleCallbacks.addFunction(exportWorker, NULL); | ||
371 | } | ||
348 | 372 | ||
349 | // static | 373 | // static |
350 | bool primbackup::check_perms( LLSelectNode* node ) | 374 | bool PrimBackup::validatePerms(const LLPermissions *item_permissions) |
351 | { | 375 | { |
352 | LLPermissions *perms = node->mPermissions; | 376 | if(gHippoGridManager->getConnectedGrid()->isSecondLife()) |
353 | return (gAgent.getID() == perms->getOwner() && | 377 | { |
354 | gAgent.getID() == perms->getCreator() && | 378 | // In Second Life, you must be the creator to be permitted to export the asset. |
355 | (PERM_ITEM_UNRESTRICTED & | 379 | return (gAgent.getID() == item_permissions->getOwner() && |
356 | perms->getMaskOwner()) == PERM_ITEM_UNRESTRICTED); | 380 | gAgent.getID() == item_permissions->getCreator() && |
381 | (PERM_ITEM_UNRESTRICTED & item_permissions->getMaskOwner()) == PERM_ITEM_UNRESTRICTED); | ||
382 | } | ||
383 | else | ||
384 | { | ||
385 | // Out of Second Life, simply check that you're the owner and the asset is full perms. | ||
386 | return (gAgent.getID() == item_permissions->getOwner() && | ||
387 | (item_permissions->getMaskOwner() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED); | ||
388 | } | ||
357 | } | 389 | } |
358 | 390 | ||
391 | // So far, only Second Life forces TPVs to verify the creator for textures... | ||
392 | // which sucks, because there is no other way to check for the texture | ||
393 | // permissions or creator than to try and find the asset(s) corresponding to | ||
394 | // the texture in the inventory and check the permissions/creator on the said | ||
395 | // asset(s), meaning that if you created the texture and subsequently deleted | ||
396 | // it from your inventory, you will not be able to export it any more !!! | ||
397 | // The "must be creator" stuff also goes against the usage in Linden Lab's own | ||
398 | // official viewers, since those allow you to save full perm textures (such as | ||
399 | // the textures in the Library), whoever is the actual creator... Go figure ! | ||
400 | LLUUID PrimBackup::validateTextureID(LLUUID asset_id) | ||
401 | { | ||
402 | if (!gHippoGridManager->getConnectedGrid()->isSecondLife()) | ||
403 | { | ||
404 | // If we are not in Second Life, don't bother | ||
405 | return asset_id; | ||
406 | } | ||
359 | 407 | ||
360 | void primbackup::exportworker(void *userdata) | 408 | LLUUID texture = LL_TEXTURE_PLYWOOD; |
361 | { | 409 | if (asset_id == texture || |
362 | primbackup::getInstance()->updateexportnumbers(); | 410 | asset_id == LL_TEXTURE_BLANK || |
411 | asset_id == LL_TEXTURE_INVISIBLE || | ||
412 | asset_id == LL_TEXTURE_TRANSPARENT || | ||
413 | asset_id == LL_TEXTURE_MEDIA) | ||
414 | { | ||
415 | // Allow to export a grid's default textures | ||
416 | return asset_id; | ||
417 | } | ||
418 | LLViewerInventoryCategory::cat_array_t cats; | ||
419 | LLViewerInventoryItem::item_array_t items; | ||
420 | LLAssetIDMatches asset_id_matches(asset_id); | ||
421 | gInventory.collectDescendentsIf(LLUUID::null, | ||
422 | cats, | ||
423 | items, | ||
424 | LLInventoryModel::INCLUDE_TRASH, | ||
425 | asset_id_matches); | ||
426 | |||
427 | if (items.count()) | ||
428 | { | ||
429 | for (S32 i = 0; i < items.count(); i++) | ||
430 | { | ||
431 | const LLPermissions item_permissions = items[i]->getPermissions(); | ||
432 | if (validatePerms(&item_permissions)) | ||
433 | { | ||
434 | texture = asset_id; | ||
435 | } | ||
436 | } | ||
437 | } | ||
363 | 438 | ||
364 | switch(primbackup::getInstance()->export_state) | 439 | if (texture != asset_id) |
365 | { | 440 | { |
366 | case EXPORT_INIT: { | 441 | mNonExportedTextures |= TEXTURE_BAD_PERM; |
367 | primbackup::getInstance()->show(); | 442 | } |
368 | LLSelectMgr::getInstance()->getSelection()->ref(); | 443 | |
444 | return texture; | ||
445 | } | ||
369 | 446 | ||
370 | struct ff : public LLSelectedNodeFunctor | 447 | void PrimBackup::exportWorker(void *userdata) |
448 | { | ||
449 | PrimBackup::getInstance()->updateExportNumbers(); | ||
450 | |||
451 | switch (PrimBackup::getInstance()->mExportState) | ||
452 | { | ||
453 | case EXPORT_INIT: | ||
371 | { | 454 | { |
372 | virtual bool apply(LLSelectNode* node) | 455 | PrimBackup::getInstance()->show(true); |
456 | LLSelectMgr::getInstance()->getSelection()->ref(); | ||
457 | |||
458 | struct ff : public LLSelectedNodeFunctor | ||
373 | { | 459 | { |
374 | return primbackup::check_perms( node ); | 460 | virtual bool apply(LLSelectNode* node) |
375 | } | 461 | { |
376 | } func; | 462 | return PrimBackup::getInstance()->validatePerms(node->mPermissions); |
463 | } | ||
464 | } func; | ||
377 | 465 | ||
378 | if(LLSelectMgr::getInstance()->getSelection()->applyToNodes(&func,false)) | 466 | if (LLSelectMgr::getInstance()->getSelection()->applyToNodes(&func, false)) |
379 | { | ||
380 | if(gHippoGridManager->getConnectedGrid()->isSecondLife()) | ||
381 | { | 467 | { |
382 | LLNotifications::instance().add("NoTextureExportSL"); | 468 | PrimBackup::getInstance()->mExportState = EXPORT_STRUCTURE; |
469 | } | ||
470 | else | ||
471 | { | ||
472 | llwarns << "Incorrect permission to export" << llendl; | ||
473 | PrimBackup::getInstance()->mExportState = EXPORT_FAILED; | ||
474 | LLSelectMgr::getInstance()->getSelection()->unref(); | ||
383 | } | 475 | } |
384 | primbackup::getInstance()->export_state=EXPORT_STRUCTURE; | ||
385 | } | 476 | } |
386 | else | 477 | break; |
478 | |||
479 | case EXPORT_STRUCTURE: | ||
387 | { | 480 | { |
388 | llwarns << "Incorrect permission to export" << llendl; | 481 | struct ff : public LLSelectedObjectFunctor |
389 | primbackup::getInstance()->export_state=EXPORT_DONE; | 482 | { |
390 | primbackup::getInstance()->close(); | 483 | virtual bool apply(LLViewerObject* object) |
391 | gIdleCallbacks.deleteFunction(exportworker); | 484 | { |
485 | bool is_attachment = object->isAttachment(); | ||
486 | object->boostTexturePriority(TRUE); | ||
487 | LLViewerObject::child_list_t children = object->getChildren(); | ||
488 | children.push_front(object); //push root onto list | ||
489 | LLSD prim_llsd = PrimBackup::getInstance()->primsToLLSD(children, is_attachment); | ||
490 | LLSD stuff; | ||
491 | if (is_attachment) | ||
492 | { | ||
493 | stuff["root_position"] = object->getPositionEdit().getValue(); | ||
494 | stuff["root_rotation"] = ll_sd_from_quaternion(object->getRotationEdit()); | ||
495 | } | ||
496 | else | ||
497 | { | ||
498 | stuff["root_position"] = object->getPosition().getValue(); | ||
499 | stuff["root_rotation"] = ll_sd_from_quaternion(object->getRotation()); | ||
500 | } | ||
501 | stuff["group_body"] = prim_llsd; | ||
502 | PrimBackup::getInstance()->mLLSD["data"].append(stuff); | ||
503 | return true; | ||
504 | } | ||
505 | } func; | ||
506 | |||
507 | PrimBackup::getInstance()->mExportState = EXPORT_LLSD; | ||
508 | LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, false); | ||
392 | LLSelectMgr::getInstance()->getSelection()->unref(); | 509 | LLSelectMgr::getInstance()->getSelection()->unref(); |
393 | } | 510 | } |
394 | break; | 511 | break; |
395 | } | ||
396 | 512 | ||
397 | case EXPORT_STRUCTURE: { | 513 | case EXPORT_TEXTURES: |
398 | struct ff : public LLSelectedObjectFunctor | ||
399 | { | 514 | { |
400 | virtual bool apply(LLViewerObject* object) | 515 | // Exporting object textures (or other content) from Second Life |
516 | // without checking creator is a violation of the Second Life | ||
517 | // Policy on Third-Party Viewers and Terms of Service. | ||
518 | if (PrimBackup::getInstance()->mNextTextureReady == false) | ||
519 | return; | ||
520 | |||
521 | // Ok we got work to do | ||
522 | PrimBackup::getInstance()->mNextTextureReady = false; | ||
523 | |||
524 | if (PrimBackup::getInstance()->mTexturesList.empty()) | ||
401 | { | 525 | { |
402 | object->boostTexturePriority(TRUE); | 526 | PrimBackup::getInstance()->mExportState = EXPORT_DONE; |
403 | LLViewerObject::child_list_t children = object->getChildren(); | 527 | return; |
404 | children.push_front(object); //push root onto list | ||
405 | LLSD prim_llsd=primbackup::getInstance()->prims_to_llsd(children); | ||
406 | LLSD stuff; | ||
407 | stuff["root_position"] = object->getPosition().getValue(); | ||
408 | stuff["root_rotation"] = ll_sd_from_quaternion(object->getRotation()); | ||
409 | stuff["group_body"] = prim_llsd; | ||
410 | primbackup::getInstance()->llsd["data"].append(stuff); | ||
411 | return true; | ||
412 | } | 528 | } |
413 | } func; | ||
414 | |||
415 | primbackup::getInstance()->export_state=EXPORT_LLSD; | ||
416 | LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func,false); | ||
417 | LLSelectMgr::getInstance()->getSelection()->unref(); | ||
418 | 529 | ||
530 | PrimBackup::getInstance()->exportNextTexture(); | ||
531 | } | ||
419 | break; | 532 | break; |
420 | } | ||
421 | 533 | ||
422 | case EXPORT_TEXTURES: { | 534 | case EXPORT_LLSD: |
423 | // Exporting object textures (or other content) from Second Life | ||
424 | // without checking creator is a violation of the Second Life | ||
425 | // Policy on Third-Party Viewers and Terms of Service. | ||
426 | if(gHippoGridManager->getConnectedGrid()->isSecondLife()) | ||
427 | { | 535 | { |
428 | primbackup::getInstance()->export_state=EXPORT_DONE; | 536 | // Create a file stream and write to it |
429 | return; | 537 | llofstream export_file(PrimBackup::getInstance()->mFileName); |
538 | LLSDSerialize::toPrettyXML(PrimBackup::getInstance()->mLLSD, export_file); | ||
539 | export_file.close(); | ||
540 | PrimBackup::getInstance()->mNextTextureReady = true; | ||
541 | PrimBackup::getInstance()->mExportState = EXPORT_TEXTURES; | ||
430 | } | 542 | } |
543 | break; | ||
431 | 544 | ||
432 | if(primbackup::getInstance()->m_nexttextureready==false) | 545 | case EXPORT_DONE: |
433 | return; | 546 | gIdleCallbacks.deleteFunction(exportWorker); |
434 | 547 | if (PrimBackup::getInstance()->mNonExportedTextures == PrimBackup::TEXTURE_OK) | |
435 | //Ok we got work to do | ||
436 | primbackup::getInstance()->m_nexttextureready=false; | ||
437 | |||
438 | if(primbackup::getInstance()->textures.empty()) | ||
439 | { | 548 | { |
440 | primbackup::getInstance()->export_state=EXPORT_DONE; | 549 | llinfos << "Export successful and complete." << llendl; |
441 | return; | 550 | LLNotifications::instance().add("ExportSuccessful"); |
442 | } | 551 | } |
443 | 552 | else | |
444 | primbackup::getInstance()->export_next_texture(); | 553 | { |
445 | break; | 554 | llinfos << "Export successful but incomplete: some texture(s) not saved." << llendl; |
446 | } | 555 | std::string reason; |
447 | 556 | if (PrimBackup::getInstance()->mNonExportedTextures & PrimBackup::TEXTURE_BAD_PERM) | |
448 | case EXPORT_LLSD: { | 557 | { |
449 | // Create a file stream and write to it | 558 | reason += "\nBad permissions/creator."; |
450 | llofstream export_file(primbackup::getInstance()->file_name); | 559 | } |
451 | LLSDSerialize::toPrettyXML(primbackup::getInstance()->llsd, export_file); | 560 | if (PrimBackup::getInstance()->mNonExportedTextures & PrimBackup::TEXTURE_MISSING) |
452 | export_file.close(); | 561 | { |
453 | primbackup::getInstance()->m_nexttextureready=true; | 562 | reason += "\nMissing texture."; |
454 | primbackup::getInstance()->export_state=EXPORT_TEXTURES; | 563 | } |
564 | if (PrimBackup::getInstance()->mNonExportedTextures & PrimBackup::TEXTURE_BAD_ENCODING) | ||
565 | { | ||
566 | reason += "\nBad texture encoding."; | ||
567 | } | ||
568 | if (PrimBackup::getInstance()->mNonExportedTextures & PrimBackup::TEXTURE_IS_NULL) | ||
569 | { | ||
570 | reason += "\nNull texture."; | ||
571 | } | ||
572 | if (PrimBackup::getInstance()->mNonExportedTextures & PrimBackup::TEXTURE_SAVED_FAILED) | ||
573 | { | ||
574 | reason += "\nCould not write to disk."; | ||
575 | } | ||
576 | LLSD args; | ||
577 | args["REASON"] = reason; | ||
578 | LLNotifications::instance().add("ExportPartial", args); | ||
579 | } | ||
580 | PrimBackup::getInstance()->close(); | ||
455 | break; | 581 | break; |
456 | } | ||
457 | 582 | ||
458 | case EXPORT_DONE: { | 583 | case EXPORT_FAILED: |
459 | llinfos << "Backup complete" << llendl; | 584 | gIdleCallbacks.deleteFunction(exportWorker); |
460 | gIdleCallbacks.deleteFunction(exportworker); | 585 | llwarns << "Export process aborted." << llendl; |
461 | primbackup::getInstance()->close(); | 586 | LLNotifications::instance().add("ExportFailed"); |
587 | PrimBackup::getInstance()->close(); | ||
462 | break; | 588 | break; |
463 | } | ||
464 | } | 589 | } |
465 | } | 590 | } |
466 | 591 | ||
467 | LLSD primbackup::prims_to_llsd(LLViewerObject::child_list_t child_list) | 592 | LLSD PrimBackup::primsToLLSD(LLViewerObject::child_list_t child_list, bool is_attachment) |
468 | { | 593 | { |
469 | |||
470 | LLViewerObject* object; | 594 | LLViewerObject* object; |
471 | LLSD llsd; | 595 | LLSD llsd; |
472 | |||
473 | char localid[16]; | 596 | char localid[16]; |
474 | 597 | ||
475 | for (LLViewerObject::child_list_t::iterator i = child_list.begin(); i != child_list.end(); ++i) | 598 | for (LLViewerObject::child_list_t::iterator i = child_list.begin(); i != child_list.end(); ++i) |
476 | { | 599 | { |
477 | object=(*i); | 600 | object = (*i); |
478 | LLUUID id = object->getID(); | 601 | LLUUID id = object->getID(); |
479 | 602 | ||
480 | llinfos << "Exporting prim " << object->getID().asString() << llendl; | 603 | llinfos << "Exporting prim " << object->getID().asString() << llendl; |
@@ -485,16 +608,31 @@ LLSD primbackup::prims_to_llsd(LLViewerObject::child_list_t child_list) | |||
485 | 608 | ||
486 | if (!object->isRoot()) | 609 | if (!object->isRoot()) |
487 | { | 610 | { |
488 | |||
489 | // Parent id | 611 | // Parent id |
490 | snprintf(localid, sizeof(localid), "%u", object->getSubParent()->getLocalID()); | 612 | snprintf(localid, sizeof(localid), "%u", object->getSubParent()->getLocalID()); |
491 | prim_llsd["parent"] = localid; | 613 | prim_llsd["parent"] = localid; |
492 | } | 614 | } |
493 | 615 | ||
616 | // Name and description | ||
617 | LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->findNode(object); | ||
618 | if (node) | ||
619 | { | ||
620 | prim_llsd["name"] = node->mName; | ||
621 | prim_llsd["description"] = node->mDescription; | ||
622 | } | ||
623 | |||
494 | // Transforms | 624 | // Transforms |
495 | prim_llsd["position"] = object->getPosition().getValue(); | 625 | if (is_attachment) |
626 | { | ||
627 | prim_llsd["position"] = object->getPositionEdit().getValue(); | ||
628 | prim_llsd["rotation"] = ll_sd_from_quaternion(object->getRotationEdit()); | ||
629 | } | ||
630 | else | ||
631 | { | ||
632 | prim_llsd["position"] = object->getPosition().getValue(); | ||
633 | prim_llsd["rotation"] = ll_sd_from_quaternion(object->getRotation()); | ||
634 | } | ||
496 | prim_llsd["scale"] = object->getScale().getValue(); | 635 | prim_llsd["scale"] = object->getScale().getValue(); |
497 | prim_llsd["rotation"] = ll_sd_from_quaternion(object->getRotation()); | ||
498 | 636 | ||
499 | // Flags | 637 | // Flags |
500 | prim_llsd["shadows"] = object->flagCastShadows(); | 638 | prim_llsd["shadows"] = object->flagCastShadows(); |
@@ -523,37 +661,55 @@ LLSD primbackup::prims_to_llsd(LLViewerObject::child_list_t child_list) | |||
523 | // Sculpt | 661 | // Sculpt |
524 | LLSculptParams* sculpt = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT); | 662 | LLSculptParams* sculpt = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT); |
525 | prim_llsd["sculpt"] = sculpt->asLLSD(); | 663 | prim_llsd["sculpt"] = sculpt->asLLSD(); |
526 | 664 | ||
527 | LLUUID sculpt_texture=sculpt->getSculptTexture(); | 665 | LLUUID sculpt_texture = sculpt->getSculptTexture(); |
528 | bool alreadyseen=false; | 666 | if (sculpt_texture == validateTextureID(sculpt_texture)) |
529 | std::list<LLUUID>::iterator iter; | ||
530 | for(iter = textures.begin(); iter != textures.end() ; iter++) | ||
531 | { | 667 | { |
532 | if( (*iter)==sculpt_texture) | 668 | bool alreadyseen = false; |
533 | alreadyseen=true; | 669 | std::list<LLUUID>::iterator iter; |
670 | for (iter = mTexturesList.begin(); iter != mTexturesList.end(); iter++) | ||
671 | { | ||
672 | if ((*iter) == sculpt_texture) | ||
673 | alreadyseen = true; | ||
674 | } | ||
675 | if (alreadyseen == false) | ||
676 | { | ||
677 | llinfos << "Found a sculpt texture, adding to list " << sculpt_texture << llendl; | ||
678 | mTexturesList.push_back(sculpt_texture); | ||
679 | } | ||
534 | } | 680 | } |
535 | if(alreadyseen==false) | 681 | else |
536 | { | 682 | { |
537 | llinfos << "Found a sculpt texture, adding to list "<<sculpt_texture<<llendl; | 683 | llwarns << "Incorrect permission to export a sculpt texture." << llendl; |
538 | textures.push_back(sculpt_texture); | 684 | PrimBackup::getInstance()->mExportState = EXPORT_FAILED; |
539 | } | 685 | } |
540 | } | 686 | } |
541 | 687 | ||
542 | // Textures | 688 | // Textures |
543 | LLSD te_llsd; | 689 | LLSD te_llsd; |
690 | LLSD this_te_llsd; | ||
691 | LLUUID t_id; | ||
544 | U8 te_count = object->getNumTEs(); | 692 | U8 te_count = object->getNumTEs(); |
545 | for (U8 i = 0; i < te_count; i++) | 693 | for (U8 i = 0; i < te_count; i++) |
546 | { | 694 | { |
547 | bool alreadyseen=false; | 695 | bool alreadyseen = false; |
548 | te_llsd.append(object->getTE(i)->asLLSD()); | 696 | t_id = validateTextureID(object->getTE(i)->getID()); |
549 | std::list<LLUUID>::iterator iter; | 697 | this_te_llsd = object->getTE(i)->asLLSD(); |
550 | for(iter = textures.begin(); iter != textures.end() ; iter++) | 698 | this_te_llsd["imageid"] = t_id; |
699 | te_llsd.append(this_te_llsd); | ||
700 | // We export these default textures -- MC | ||
701 | //if (t_id != LL_TEXTURE_BLANK && t_id != LL_TEXTURE_INVISIBLE) | ||
702 | if (t_id.notNull()) | ||
551 | { | 703 | { |
552 | if( (*iter)==object->getTE(i)->getID()) | 704 | std::list<LLUUID>::iterator iter; |
553 | alreadyseen=true; | 705 | for (iter = mTexturesList.begin(); iter != mTexturesList.end(); iter++) |
706 | { | ||
707 | if ((*iter) == t_id) | ||
708 | alreadyseen = true; | ||
709 | } | ||
710 | if (alreadyseen == false) | ||
711 | mTexturesList.push_back(t_id); | ||
554 | } | 712 | } |
555 | if(alreadyseen==false) | ||
556 | textures.push_back(object->getTE(i)->getID()); | ||
557 | } | 713 | } |
558 | prim_llsd["textures"] = te_llsd; | 714 | prim_llsd["textures"] = te_llsd; |
559 | 715 | ||
@@ -563,43 +719,51 @@ LLSD primbackup::prims_to_llsd(LLViewerObject::child_list_t child_list) | |||
563 | llsd[(const char*)localid] = prim_llsd; | 719 | llsd[(const char*)localid] = prim_llsd; |
564 | } | 720 | } |
565 | 721 | ||
566 | updateexportnumbers(); | 722 | updateExportNumbers(); |
567 | 723 | ||
568 | return llsd; | 724 | return llsd; |
569 | } | 725 | } |
570 | 726 | ||
571 | 727 | void PrimBackup::exportNextTexture() | |
572 | void primbackup::export_next_texture() | ||
573 | { | 728 | { |
574 | if(textures.empty()) | 729 | if (mTexturesList.empty()) |
575 | { | 730 | { |
576 | llinfos << "Finished exporting textures "<<llendl; | 731 | llinfos << "Finished exporting textures" << llendl; |
577 | return; | 732 | return; |
578 | } | 733 | } |
579 | 734 | ||
580 | std::list<LLUUID>::iterator iter; | ||
581 | iter = textures.begin(); | ||
582 | |||
583 | LLUUID id; | 735 | LLUUID id; |
736 | std::list<LLUUID>::iterator iter; | ||
737 | iter = mTexturesList.begin(); | ||
584 | 738 | ||
585 | while(1) | 739 | while (true) |
586 | { | 740 | { |
587 | if(iter==textures.end()) | 741 | if (iter == mTexturesList.end()) |
588 | { | 742 | { |
589 | m_nexttextureready=true; | 743 | mNextTextureReady = true; |
590 | return; | 744 | return; |
591 | } | 745 | } |
592 | 746 | ||
593 | id=(*iter); | 747 | id = (*iter); |
748 | if (id.isNull()) | ||
749 | { | ||
750 | // NULL texture id: just remove and ignore. | ||
751 | mTexturesList.remove(id); | ||
752 | iter = mTexturesList.begin(); | ||
753 | continue; | ||
754 | } | ||
594 | 755 | ||
595 | LLViewerImage * imagep = gImageList.hasImage(id); | 756 | LLViewerImage* imagep = gImageList.hasImage(id); |
596 | if(imagep!=NULL) | 757 | if (imagep != NULL) |
597 | { | 758 | { |
598 | S32 cur_discard = imagep->getDiscardLevel(); | 759 | S32 cur_discard = imagep->getDiscardLevel(); |
599 | if(cur_discard>0) | 760 | if (cur_discard > 0) |
600 | { | 761 | { |
601 | if(imagep->getBoostLevel()!=LLViewerImageBoostLevel::BOOST_PREVIEW) | 762 | if (imagep->getBoostLevel() != LLViewerImageBoostLevel::BOOST_PREVIEW) |
602 | imagep->setBoostLevel(LLViewerImageBoostLevel::BOOST_PREVIEW); //we want to force discard 0 this one does this. | 763 | { |
764 | // we want to force discard 0: this one does this. | ||
765 | imagep->setBoostLevel(LLViewerImageBoostLevel::BOOST_PREVIEW); | ||
766 | } | ||
603 | } | 767 | } |
604 | else | 768 | else |
605 | { | 769 | { |
@@ -608,427 +772,428 @@ void primbackup::export_next_texture() | |||
608 | } | 772 | } |
609 | else | 773 | else |
610 | { | 774 | { |
611 | llwarns<<" We *DONT* have the texture "<<llendl; | 775 | llwarns << "We *DON'T* have the texture " << id.asString() << llendl; |
776 | mNonExportedTextures |= TEXTURE_MISSING; | ||
777 | mTexturesList.remove(id); | ||
778 | return; | ||
612 | } | 779 | } |
613 | iter++; | 780 | iter++; |
614 | } | 781 | } |
615 | 782 | ||
616 | textures.remove(id); | 783 | mTexturesList.remove(id); |
617 | 784 | ||
618 | llinfos<<"Requesting texture "<<id<<llendl; | 785 | llinfos << "Requesting texture " << id << llendl; |
619 | LLImageJ2C * mFormattedImage = new LLImageJ2C; | 786 | LLImageJ2C* mFormattedImage = new LLImageJ2C; |
620 | CacheReadResponder* responder = new CacheReadResponder(id, mFormattedImage); | 787 | CacheReadResponder* responder = new CacheReadResponder(id, mFormattedImage); |
621 | LLAppViewer::getTextureCache()->readFromCache(id,LLWorkerThread::PRIORITY_HIGH,0,999999,responder); | 788 | LLAppViewer::getTextureCache()->readFromCache(id, LLWorkerThread::PRIORITY_HIGH, 0, 999999, responder); |
622 | } | 789 | } |
623 | 790 | ||
624 | 791 | void PrimBackup::importObject(bool upload) | |
625 | |||
626 | void primbackup::import_object(bool upload) | ||
627 | { | 792 | { |
793 | mTexturesList.clear(); | ||
794 | mAssetMap.clear(); | ||
795 | mCurrentAsset = LLUUID::null; | ||
628 | 796 | ||
797 | setDefaultTextures(); | ||
629 | 798 | ||
630 | textures.clear(); | 799 | mRetexture = upload; |
631 | assetmap.clear(); | ||
632 | current_asset=LLUUID::null; | ||
633 | |||
634 | this->m_retexture=upload; | ||
635 | 800 | ||
636 | // Open the file open dialog | 801 | // Open the file open dialog |
637 | LLFilePicker& file_picker = LLFilePicker::instance(); | 802 | LLFilePicker& file_picker = LLFilePicker::instance(); |
638 | if( !file_picker.getOpenFile( LLFilePicker::FFLOAD_XML ) ) | 803 | if (!file_picker.getOpenFile(LLFilePicker::FFLOAD_XML)) |
639 | { | 804 | { |
640 | // User canceled save. | 805 | // User canceled save. |
641 | return; | 806 | return; |
642 | } | 807 | } |
643 | std::string file_name = file_picker.getFirstFile().c_str(); | 808 | std::string file_name = file_picker.getFirstFile().c_str(); |
644 | folder = gDirUtilp->getDirName(file_name); | 809 | mFolder = gDirUtilp->getDirName(file_name); |
645 | 810 | ||
646 | { | 811 | LLSD import_llsd; |
647 | LLSD import_llsd; | 812 | llifstream import_file(file_name); |
648 | llifstream import_file(file_name); | 813 | S32 status; |
649 | S32 status; | 814 | status = LLSDSerialize::fromXML(import_llsd, import_file); |
650 | status = LLSDSerialize::fromXML(import_llsd, import_file); | 815 | import_file.close(); |
651 | import_file.close(); | ||
652 | |||
653 | if (LLSDParser::PARSE_FAILURE == status) | ||
654 | { | ||
655 | llwarns << "invalid xml file." << llendl; | ||
656 | return; | ||
657 | } | ||
658 | 816 | ||
659 | llsd = import_llsd; | 817 | if (LLSDParser::PARSE_FAILURE == status) |
818 | { | ||
819 | llwarns << "invalid xml file." << llendl; | ||
820 | return; | ||
660 | } | 821 | } |
661 | 822 | ||
662 | show(); | 823 | mLLSD = import_llsd; |
824 | |||
825 | show(false); | ||
826 | |||
827 | mAgentPos = gAgent.getPositionAgent(); | ||
828 | mAgentRot = LLQuaternion(gAgent.getAtAxis(), gAgent.getLeftAxis(), gAgent.getUpAxis()); | ||
829 | |||
830 | // Get the texture map | ||
663 | 831 | ||
664 | //Get the texture map | ||
665 | |||
666 | LLSD::map_const_iterator prim_it; | 832 | LLSD::map_const_iterator prim_it; |
667 | LLSD::array_const_iterator prim_arr_it; | 833 | LLSD::array_const_iterator prim_arr_it; |
668 | |||
669 | this->m_curobject=1; | ||
670 | this->m_curprim=1; | ||
671 | this->m_objects=llsd["data"].size(); | ||
672 | this->m_prims=0; | ||
673 | rezcount=0; | ||
674 | 834 | ||
675 | updateimportnumbers(); | 835 | mCurObject = 1; |
836 | mCurPrim = 1; | ||
837 | mObjects = mLLSD["data"].size(); | ||
838 | mPrims = 0; | ||
839 | mRezCount = 0; | ||
840 | updateImportNumbers(); | ||
676 | 841 | ||
677 | for( prim_arr_it = llsd["data"].beginArray(); prim_arr_it != llsd["data"].endArray(); prim_arr_it++) | 842 | for (prim_arr_it = mLLSD["data"].beginArray(); prim_arr_it != mLLSD["data"].endArray(); prim_arr_it++) |
678 | { | 843 | { |
679 | |||
680 | LLSD llsd2; | 844 | LLSD llsd2; |
681 | llsd2=(*prim_arr_it)["group_body"]; | 845 | llsd2 = (*prim_arr_it)["group_body"]; |
682 | 846 | ||
683 | for( prim_it = llsd2.beginMap(); prim_it != llsd2.endMap(); prim_it++) | 847 | for (prim_it = llsd2.beginMap(); prim_it != llsd2.endMap(); prim_it++) |
684 | { | 848 | { |
685 | LLSD prim_llsd; | 849 | LLSD prim_llsd; |
686 | prim_llsd=llsd2[prim_it->first]; | 850 | prim_llsd = llsd2[prim_it->first]; |
687 | LLSD::array_iterator text_it; | 851 | LLSD::array_iterator text_it; |
688 | std::list<LLUUID>::iterator iter; | 852 | std::list<LLUUID>::iterator iter; |
689 | 853 | ||
690 | if(prim_llsd.has("sculpt")) | 854 | if (prim_llsd.has("sculpt")) |
691 | { | 855 | { |
692 | LLSculptParams* sculpt=new LLSculptParams(); | 856 | LLSculptParams* sculpt = new LLSculptParams(); |
693 | sculpt->fromLLSD(prim_llsd["sculpt"]); | 857 | sculpt->fromLLSD(prim_llsd["sculpt"]); |
694 | LLUUID orig=sculpt->getSculptTexture(); | 858 | LLUUID orig = sculpt->getSculptTexture(); |
695 | bool alreadyseen=false; | 859 | bool alreadyseen = false; |
696 | for(iter = textures.begin(); iter != textures.end() ; iter++) | 860 | for (iter = mTexturesList.begin(); iter != mTexturesList.end(); iter++) |
697 | { | 861 | { |
698 | if( (*iter)==orig) | 862 | if ((*iter) == orig) |
699 | alreadyseen=true; | 863 | alreadyseen = true; |
700 | } | 864 | } |
701 | if(alreadyseen==false) | 865 | if (alreadyseen == false) |
702 | { | 866 | { |
703 | llinfos << "Found a new SCULPT texture to upload "<<orig<<llendl; | 867 | llinfos << "Found a new SCULPT texture to upload " << orig << llendl; |
704 | textures.push_back(orig); | 868 | mTexturesList.push_back(orig); |
705 | } | 869 | } |
706 | } | 870 | } |
707 | 871 | ||
708 | |||
709 | LLSD te_llsd; | 872 | LLSD te_llsd; |
710 | te_llsd=prim_llsd["textures"]; | 873 | te_llsd = prim_llsd["textures"]; |
711 | 874 | ||
712 | 875 | for (text_it = te_llsd.beginArray(); text_it != te_llsd.endArray(); text_it++) | |
713 | for(text_it=te_llsd.beginArray(); text_it !=te_llsd.endArray(); text_it++) | ||
714 | { | 876 | { |
715 | LLSD the_te; | 877 | LLSD the_te; |
716 | the_te=(*text_it); | 878 | the_te = (*text_it); |
717 | LLTextureEntry te; | 879 | LLTextureEntry te; |
718 | te.fromLLSD(the_te); | 880 | te.fromLLSD(the_te); |
719 | 881 | ||
720 | te.getID(); | 882 | LLUUID id = te.getID(); |
721 | bool alreadyseen=false; | 883 | // We upload the default textures in case we're on a grid with different ones and they're part of the build -- MC |
722 | 884 | //if (id != LL_TEXTURE_PLYWOOD && id != LL_TEXTURE_BLANK && id != LL_TEXTURE_INVISIBLE) | |
723 | for(iter = textures.begin(); iter != textures.end() ; iter++) | 885 | if (id.notNull()) |
724 | { | 886 | { |
725 | if( (*iter)==te.getID()) | 887 | bool alreadyseen = false; |
726 | alreadyseen=true; | 888 | |
889 | for (iter = mTexturesList.begin(); iter != mTexturesList.end(); iter++) | ||
890 | { | ||
891 | if ((*iter) == te.getID()) | ||
892 | alreadyseen = true; | ||
893 | } | ||
894 | if (alreadyseen == false) | ||
895 | { | ||
896 | llinfos << "Found a new texture to upload "<< te.getID() << llendl; | ||
897 | mTexturesList.push_back(te.getID()); | ||
898 | } | ||
727 | } | 899 | } |
728 | if(alreadyseen==false) | ||
729 | { | ||
730 | llinfos << "Found a new texture to upload "<<te.getID()<<llendl; | ||
731 | textures.push_back(te.getID()); | ||
732 | } | ||
733 | } | 900 | } |
734 | |||
735 | } | 901 | } |
736 | } | 902 | } |
737 | 903 | ||
738 | if(m_retexture==TRUE) | 904 | if (mRetexture == TRUE) |
739 | upload_next_asset(); | 905 | uploadNextAsset(); |
740 | else | 906 | else |
741 | import_object1a(); | 907 | importFirstObject(); |
742 | } | 908 | } |
743 | 909 | ||
744 | LLVector3 primbackup::offset_agent(LLVector3 offset) | 910 | LLVector3 PrimBackup::offsetAgent(LLVector3 offset) |
745 | { | 911 | { |
746 | LLVector3 pos= gAgent.getPositionAgent(); | 912 | return offset * mAgentRot + mAgentPos; |
747 | LLQuaternion agent_rot=LLQuaternion(gAgent.getAtAxis(),gAgent.getLeftAxis(),gAgent.getUpAxis()); | ||
748 | pos=(offset*agent_rot+pos); | ||
749 | return pos; | ||
750 | } | 913 | } |
751 | 914 | ||
752 | void primbackup::rez_agent_offset(LLVector3 offset) | 915 | void PrimBackup::rezAgentOffset(LLVector3 offset) |
753 | { | 916 | { |
754 | // This will break for a sitting agent | 917 | // This will break for a sitting agent |
755 | LLToolPlacer* mPlacer = new LLToolPlacer(); | 918 | LLToolPlacer* mPlacer = new LLToolPlacer(); |
756 | mPlacer->setObjectType(LL_PCODE_CUBE); | 919 | mPlacer->setObjectType(LL_PCODE_CUBE); |
757 | //LLVector3 pos=offset_agent(offset); | 920 | //LLVector3 pos = offsetAgent(offset); |
758 | mPlacer->placeObject((S32)(offset.mV[0]), (S32)(offset.mV[1]), 0); | 921 | mPlacer->placeObject((S32)offset.mV[0], (S32)offset.mV[1], MASK_NONE); |
759 | } | 922 | } |
760 | 923 | ||
761 | void primbackup::import_object1a() | 924 | void PrimBackup::importFirstObject() |
762 | { | 925 | { |
763 | running=true; | 926 | mRunning = true; |
927 | show(false); | ||
928 | mGroupPrimImportIter = mLLSD["data"].beginArray(); | ||
929 | mRootRootPos = (*mGroupPrimImportIter)["root_position"]; | ||
930 | mObjects = mLLSD["data"].size(); | ||
931 | mCurObject = 1; | ||
932 | importNextObject(); | ||
933 | } | ||
764 | 934 | ||
765 | show(); | 935 | void PrimBackup::importNextObject() |
936 | { | ||
937 | mToSelect.clear(); | ||
938 | mRezCount = 0; | ||
766 | 939 | ||
767 | group_prim_import_iter=llsd["data"].beginArray(); | 940 | mThisGroup = (*mGroupPrimImportIter)["group_body"]; |
768 | root_root_pos=(*group_prim_import_iter)["root_position"]; | 941 | mPrimImportIter = mThisGroup.beginMap(); |
769 | 942 | ||
770 | this->m_objects=llsd["data"].size(); | 943 | mCurPrim = 0; |
771 | this->m_curobject=1; | 944 | mPrims = mThisGroup.size(); |
772 | import_next_object(); | 945 | updateImportNumbers(); |
773 | } | ||
774 | 946 | ||
775 | void primbackup::import_next_object() | 947 | LLVector3 lgpos = (*mGroupPrimImportIter)["root_position"]; |
776 | { | 948 | mGroupOffset = lgpos - mRootRootPos; |
777 | toselect.clear(); | 949 | mRootPos = offsetAgent(LLVector3(2.0, 0.0, 0.0)); |
778 | rezcount=0; | 950 | mRootRot = ll_quaternion_from_sd((*mGroupPrimImportIter)["root_rotation"]); |
779 | 951 | ||
780 | this_group=(*group_prim_import_iter)["group_body"]; | 952 | rezAgentOffset(LLVector3(0.0, 2.0, 0.0)); |
781 | prim_import_iter=this_group.beginMap(); | ||
782 | |||
783 | m_curprim=0; | ||
784 | m_prims=this_group.size(); | ||
785 | updateimportnumbers(); | ||
786 | LLVector3 lgpos=(*group_prim_import_iter)["root_position"]; | ||
787 | |||
788 | group_offset=lgpos-root_root_pos; | ||
789 | root_pos=offset_agent(LLVector3(2.0,0,0)); | ||
790 | root_rot=ll_quaternion_from_sd((*group_prim_import_iter)["root_rotation"]); | ||
791 | |||
792 | rez_agent_offset(LLVector3(0.0,2.0,0.0)); | ||
793 | // Now we must wait for the callback when ViewerObjectList gets the new objects and we have the correct number selected | 953 | // Now we must wait for the callback when ViewerObjectList gets the new objects and we have the correct number selected |
794 | } | 954 | } |
795 | 955 | ||
796 | // This function takes a pointer to a viewerobject and applys the prim definition that prim_llsd has | 956 | // This function takes a pointer to a viewerobject and applies the prim definition that prim_llsd has |
797 | void primbackup::xmltoprim(LLSD prim_llsd,LLViewerObject * object) | 957 | void PrimBackup::xmlToPrim(LLSD prim_llsd, LLViewerObject* object) |
798 | { | 958 | { |
799 | LLUUID id = object->getID(); | 959 | LLUUID id = object->getID(); |
800 | expecting_update = object->getID(); | 960 | mExpectingUpdate = object->getID(); |
801 | LLSelectMgr::getInstance()->selectObjectAndFamily(object); | 961 | LLSelectMgr::getInstance()->selectObjectAndFamily(object); |
802 | 962 | ||
803 | if(prim_llsd.has("parent")) | 963 | if (prim_llsd.has("name")) |
964 | { | ||
965 | LLSelectMgr::getInstance()->selectionSetObjectName(prim_llsd["name"]); | ||
966 | } | ||
967 | |||
968 | if (prim_llsd.has("description")) | ||
969 | { | ||
970 | LLSelectMgr::getInstance()->selectionSetObjectDescription(prim_llsd["description"]); | ||
971 | } | ||
972 | |||
973 | if (prim_llsd.has("parent")) | ||
804 | { | 974 | { |
805 | //we are not the root node. | 975 | //we are not the root node. |
806 | LLVector3 pos=prim_llsd["position"]; | 976 | LLVector3 pos = prim_llsd["position"]; |
807 | LLQuaternion rot=ll_quaternion_from_sd(prim_llsd["rotation"]); | 977 | LLQuaternion rot = ll_quaternion_from_sd(prim_llsd["rotation"]); |
808 | object->setPositionRegion((pos*root_rot)+(root_pos+group_offset)); | 978 | object->setPositionRegion(pos * mRootRot + mRootPos + mGroupOffset); |
809 | object->setRotation(rot*root_rot); | 979 | object->setRotation(rot * mRootRot); |
810 | } | 980 | } |
811 | else | 981 | else |
812 | { | 982 | { |
813 | object->setPositionRegion(root_pos+group_offset); | 983 | object->setPositionRegion(mRootPos + mGroupOffset); |
814 | LLQuaternion rot=ll_quaternion_from_sd(prim_llsd["rotation"]); | 984 | LLQuaternion rot=ll_quaternion_from_sd(prim_llsd["rotation"]); |
815 | object->setRotation(rot); | 985 | object->setRotation(rot); |
816 | } | 986 | } |
817 | 987 | ||
818 | object->setScale(prim_llsd["scale"]); | 988 | object->setScale(prim_llsd["scale"]); |
819 | 989 | ||
820 | if(prim_llsd.has("shadows")) | 990 | if (prim_llsd.has("shadows")) |
821 | if(prim_llsd["shadows"].asInteger()==1) | 991 | if (prim_llsd["shadows"].asInteger() == 1) |
822 | object->setFlags(FLAGS_CAST_SHADOWS,true); | 992 | object->setFlags(FLAGS_CAST_SHADOWS, true); |
823 | 993 | ||
824 | if(prim_llsd.has("phantom")) | 994 | if (prim_llsd.has("phantom")) |
825 | if(prim_llsd["phantom"].asInteger()==1) | 995 | if (prim_llsd["phantom"].asInteger() == 1) |
826 | object->setFlags(FLAGS_PHANTOM,true); | 996 | object->setFlags(FLAGS_PHANTOM, true); |
827 | 997 | ||
828 | if(prim_llsd.has("physical")) | 998 | if (prim_llsd.has("physical")) |
829 | if(prim_llsd["physical"].asInteger()==1) | 999 | if (prim_llsd["physical"].asInteger() == 1) |
830 | object->setFlags(FLAGS_USE_PHYSICS,true); | 1000 | object->setFlags(FLAGS_USE_PHYSICS, true); |
831 | 1001 | ||
832 | // Volume params | 1002 | // Volume params |
833 | LLVolumeParams volume_params = object->getVolume()->getParams(); | 1003 | LLVolumeParams volume_params = object->getVolume()->getParams(); |
834 | volume_params.fromLLSD(prim_llsd["volume"]) ; | 1004 | volume_params.fromLLSD(prim_llsd["volume"]); |
835 | object->updateVolume(volume_params); | 1005 | object->updateVolume(volume_params); |
836 | 1006 | ||
837 | if(prim_llsd.has("sculpt")) | 1007 | if (prim_llsd.has("sculpt")) |
838 | { | 1008 | { |
839 | LLSculptParams* sculpt=new LLSculptParams(); | 1009 | LLSculptParams* sculpt = new LLSculptParams(); |
840 | sculpt->fromLLSD(prim_llsd["sculpt"]); | 1010 | sculpt->fromLLSD(prim_llsd["sculpt"]); |
841 | |||
842 | //TODO check if map is valid and only set texture is map is valid and changes | ||
843 | 1011 | ||
844 | if(assetmap[sculpt->getSculptTexture()].notNull()) | 1012 | // TODO: check if map is valid and only set texture if map is valid and changes |
1013 | |||
1014 | if (mAssetMap[sculpt->getSculptTexture()].notNull()) | ||
845 | { | 1015 | { |
846 | LLUUID replacment=assetmap[sculpt->getSculptTexture()]; | 1016 | LLUUID replacment = mAssetMap[sculpt->getSculptTexture()]; |
847 | sculpt->setSculptTexture(replacment); | 1017 | sculpt->setSculptTexture(replacment); |
848 | } | 1018 | } |
849 | 1019 | ||
850 | object->setParameterEntry(LLNetworkData::PARAMS_SCULPT,(LLNetworkData&)(*sculpt),true); | 1020 | object->setParameterEntry(LLNetworkData::PARAMS_SCULPT,(LLNetworkData&)(*sculpt),true); |
851 | } | 1021 | } |
852 | 1022 | ||
853 | if(prim_llsd.has("light")) | 1023 | if (prim_llsd.has("light")) |
854 | { | 1024 | { |
855 | LLLightParams * light=new LLLightParams(); | 1025 | LLLightParams* light = new LLLightParams(); |
856 | light->fromLLSD(prim_llsd["light"]); | 1026 | light->fromLLSD(prim_llsd["light"]); |
857 | object->setParameterEntry(LLNetworkData::PARAMS_LIGHT,(LLNetworkData&)(*light),true); | 1027 | object->setParameterEntry(LLNetworkData::PARAMS_LIGHT,(LLNetworkData&)(*light), true); |
858 | } | 1028 | } |
859 | 1029 | ||
860 | if(prim_llsd.has("flexible")) | 1030 | if (prim_llsd.has("flexible")) |
861 | { | 1031 | { |
862 | LLFlexibleObjectData* flex=new LLFlexibleObjectData(); | 1032 | LLFlexibleObjectData* flex = new LLFlexibleObjectData(); |
863 | flex->fromLLSD(prim_llsd["flexible"]); | 1033 | flex->fromLLSD(prim_llsd["flexible"]); |
864 | object->setParameterEntry(LLNetworkData::PARAMS_FLEXIBLE,(LLNetworkData&)(*flex),true); | 1034 | object->setParameterEntry(LLNetworkData::PARAMS_FLEXIBLE,(LLNetworkData&)(*flex), true); |
865 | } | 1035 | } |
866 | 1036 | ||
867 | |||
868 | // Textures | 1037 | // Textures |
869 | LLSD te_llsd; | ||
870 | llinfos << "Processing textures for prim" << llendl; | 1038 | llinfos << "Processing textures for prim" << llendl; |
871 | 1039 | LLSD te_llsd; | |
872 | te_llsd=prim_llsd["textures"]; | 1040 | te_llsd = prim_llsd["textures"]; |
873 | 1041 | ||
874 | LLSD::array_iterator text_it; | 1042 | LLSD::array_iterator text_it; |
875 | U8 i=0; | 1043 | U8 i = 0; |
876 | i=0; | ||
877 | 1044 | ||
878 | for(text_it=te_llsd.beginArray(); text_it !=te_llsd.endArray(); text_it++) | 1045 | for (text_it = te_llsd.beginArray(); text_it != te_llsd.endArray(); text_it++) |
879 | { | 1046 | { |
880 | LLSD the_te; | 1047 | LLSD the_te; |
881 | the_te=(*text_it); | 1048 | the_te = (*text_it); |
882 | LLTextureEntry te; | 1049 | LLTextureEntry te; |
883 | te.fromLLSD(the_te); | 1050 | te.fromLLSD(the_te); |
884 | 1051 | ||
885 | if(assetmap[te.getID()].notNull()) | 1052 | if (mAssetMap[te.getID()].notNull()) |
886 | { | 1053 | { |
887 | LLUUID replacment=assetmap[te.getID()]; | 1054 | LLUUID replacment = mAssetMap[te.getID()]; |
888 | te.setID(replacment); | 1055 | te.setID(replacment); |
889 | } | 1056 | } |
890 | 1057 | ||
891 | object->setTE(i,te); // | 1058 | object->setTE(i, te); |
892 | i++; | 1059 | i++; |
893 | } | 1060 | } |
894 | 1061 | ||
895 | llinfos << "Textures done!" << llendl; | 1062 | llinfos << "Textures done!" << llendl; |
896 | 1063 | ||
897 | //bump the iterator now so the callbacks hook together nicely | 1064 | //bump the iterator now so the callbacks hook together nicely |
898 | //if(prim_import_iter!=this_group.endMap()) | 1065 | //if (mPrimImportIter != mThisGroup.endMap()) |
899 | // prim_import_iter++; | 1066 | // mPrimImportIter++; |
900 | 1067 | ||
901 | object->sendRotationUpdate(); | 1068 | object->sendRotationUpdate(); |
902 | object->sendTEUpdate(); | 1069 | object->sendTEUpdate(); |
903 | object->sendShapeUpdate(); | 1070 | object->sendShapeUpdate(); |
904 | LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_SCALE |UPD_POSITION); | 1071 | LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_SCALE | UPD_POSITION); |
905 | 1072 | ||
906 | LLSelectMgr::getInstance()->deselectAll(); | 1073 | LLSelectMgr::getInstance()->deselectAll(); |
907 | } | 1074 | } |
908 | 1075 | ||
909 | //This is fired when the update packet is processed so we know the prim settings have stuck | 1076 | // This is fired when the update packet is processed so we know the prim settings have stuck |
910 | void primbackup::prim_update(LLViewerObject* object) | 1077 | void PrimBackup::primUpdate(LLViewerObject* object) |
911 | { | 1078 | { |
912 | if(!running) | 1079 | if (!mRunning) |
913 | return; | 1080 | return; |
914 | 1081 | ||
915 | if(object!=NULL) | 1082 | if (object != NULL) |
916 | if(object->mID!=expecting_update) | 1083 | if (object->mID != mExpectingUpdate) |
917 | return; | 1084 | return; |
918 | 1085 | ||
919 | m_curprim++; | 1086 | mCurPrim++; |
920 | updateimportnumbers(); | 1087 | updateImportNumbers(); |
921 | 1088 | mPrimImportIter++; | |
922 | prim_import_iter++; | ||
923 | 1089 | ||
924 | LLUUID x; | 1090 | LLUUID x; |
925 | expecting_update=x.null; | 1091 | mExpectingUpdate = x.null; |
926 | 1092 | ||
927 | if(prim_import_iter==this_group.endMap()) | 1093 | if (mPrimImportIter == mThisGroup.endMap()) |
928 | { | 1094 | { |
929 | llinfos<<"Trying to link"<<llendl; | 1095 | llinfos << "Trying to link" << llendl; |
930 | 1096 | ||
931 | if(toselect.size()>1) | 1097 | if (mToSelect.size() > 1) |
932 | { | 1098 | { |
933 | std::reverse(toselect.begin(),toselect.end()); | 1099 | std::reverse(mToSelect.begin(), mToSelect.end()); |
934 | //Now link | 1100 | // Now link |
935 | LLSelectMgr::getInstance()->deselectAll(); | 1101 | LLSelectMgr::getInstance()->deselectAll(); |
936 | LLSelectMgr::getInstance()->selectObjectAndFamily(toselect,true); | 1102 | LLSelectMgr::getInstance()->selectObjectAndFamily(mToSelect, true); |
937 | LLSelectMgr::getInstance()->sendLink(); | 1103 | LLSelectMgr::getInstance()->sendLink(); |
938 | LLViewerObject * root=toselect.back(); | 1104 | LLViewerObject* root = mToSelect.back(); |
939 | root->setRotation(root_rot); | 1105 | root->setRotation(mRootRot); |
940 | } | 1106 | } |
941 | 1107 | ||
942 | this->m_curobject++; | 1108 | mCurObject++; |
943 | group_prim_import_iter++; | 1109 | mGroupPrimImportIter++; |
944 | if(group_prim_import_iter!=llsd["data"].endArray()) | 1110 | if (mGroupPrimImportIter != mLLSD["data"].endArray()) |
945 | { | 1111 | { |
946 | import_next_object(); | 1112 | importNextObject(); |
947 | return; | 1113 | return; |
948 | } | 1114 | } |
949 | 1115 | ||
950 | running=false; | 1116 | mRunning = false; |
951 | this->close(); | 1117 | close(); |
952 | return; | 1118 | return; |
953 | } | 1119 | } |
954 | 1120 | ||
955 | LLSD prim_llsd; | 1121 | LLSD prim_llsd; |
956 | prim_llsd=this_group[prim_import_iter->first]; | 1122 | prim_llsd = mThisGroup[mPrimImportIter->first]; |
957 | 1123 | ||
958 | if(toselect.empty()) | 1124 | if (mToSelect.empty()) |
959 | { | 1125 | { |
960 | llwarns << "error: ran out of objects to mod" << llendl; | 1126 | llwarns << "error: ran out of objects to mod" << llendl; |
961 | return; | 1127 | return; |
962 | } | 1128 | } |
963 | 1129 | ||
964 | if(prim_import_iter!=this_group.endMap()) | 1130 | if (mPrimImportIter != mThisGroup.endMap()) |
965 | { | 1131 | { |
966 | //rez_agent_offset(LLVector3(1.0,0,0)); | 1132 | //rezAgentOffset(LLVector3(1.0, 0.0, 0.0)); |
967 | LLSD prim_llsd=this_group[prim_import_iter->first]; | 1133 | LLSD prim_llsd = mThisGroup[mPrimImportIter->first]; |
968 | process_iter++; | 1134 | mProcessIter++; |
969 | xmltoprim(prim_llsd,(*process_iter)); | 1135 | xmlToPrim(prim_llsd, *mProcessIter); |
970 | } | 1136 | } |
971 | } | 1137 | } |
972 | 1138 | ||
973 | // Callback when we rez a new object when the importer is running. | 1139 | // Callback when we rez a new object when the importer is running. |
974 | bool primbackup::newprim(LLViewerObject * pobject) | 1140 | bool PrimBackup::newPrim(LLViewerObject* pobject) |
975 | { | 1141 | { |
976 | if(running) | 1142 | if (mRunning) |
977 | { | 1143 | { |
978 | rezcount++; | 1144 | mRezCount++; |
979 | toselect.push_back(pobject); | 1145 | mToSelect.push_back(pobject); |
980 | updateimportnumbers(); | 1146 | updateImportNumbers(); |
981 | prim_import_iter++; | 1147 | mPrimImportIter++; |
982 | 1148 | ||
983 | if(prim_import_iter!=this_group.endMap()) | 1149 | if (mPrimImportIter != mThisGroup.endMap()) |
984 | { | 1150 | { |
985 | 1151 | pobject->setPosition(offsetAgent(LLVector3(0.0, 1.0, 0.0))); | |
986 | pobject->setPosition(this->offset_agent(LLVector3(0,1.0,0))); | ||
987 | LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_POSITION); | 1152 | LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_POSITION); |
988 | 1153 | ||
989 | rez_agent_offset(LLVector3(1.0,0,0)); | 1154 | rezAgentOffset(LLVector3(1.0, 0.0 ,0.0)); |
990 | } | 1155 | } |
991 | else | 1156 | else |
992 | { | 1157 | { |
993 | llinfos << "All prims rezed, moving to build stage" <<llendl; | 1158 | llinfos << "All prims rezzed, moving to build stage" << llendl; |
994 | prim_import_iter=this_group.beginMap(); | 1159 | // Deselecting is required to ensure that the first child prim |
995 | LLSD prim_llsd=this_group[prim_import_iter->first]; | 1160 | // in the link set (which is also the last rezzed prim and thus |
996 | process_iter=toselect.begin(); | 1161 | // currently selected) will be properly renamed and desced. |
997 | xmltoprim(prim_llsd,(*process_iter)); | 1162 | LLSelectMgr::getInstance()->deselectAll(); |
1163 | mPrimImportIter = mThisGroup.beginMap(); | ||
1164 | LLSD prim_llsd = mThisGroup[mPrimImportIter->first]; | ||
1165 | mProcessIter = mToSelect.begin(); | ||
1166 | xmlToPrim(prim_llsd, *mProcessIter); | ||
998 | } | 1167 | } |
999 | } | 1168 | } |
1000 | |||
1001 | return true; | 1169 | return true; |
1002 | } | 1170 | } |
1003 | 1171 | ||
1004 | void primbackup::update_map(LLUUID uploaded_asset) | 1172 | void PrimBackup::updateMap(LLUUID uploaded_asset) |
1005 | { | 1173 | { |
1006 | if(current_asset.isNull()) | 1174 | if (mCurrentAsset.isNull()) |
1007 | return; | 1175 | return; |
1008 | 1176 | ||
1009 | assetmap.insert(std::pair<LLUUID,LLUUID>(current_asset,uploaded_asset)); | 1177 | llinfos << "Mapping " << mCurrentAsset << " to " << uploaded_asset << llendl; |
1010 | llinfos << "Mapping "<<current_asset<<" to "<<uploaded_asset<<llendl; | 1178 | mAssetMap.insert(std::pair<LLUUID, LLUUID>(mCurrentAsset, uploaded_asset)); |
1011 | |||
1012 | } | 1179 | } |
1013 | 1180 | ||
1014 | 1181 | ||
1015 | void myupload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_type, | 1182 | void myupload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_type, |
1016 | std::string name, | 1183 | std::string name, std::string desc, S32 compression_info, |
1017 | std::string desc, S32 compression_info, | ||
1018 | LLAssetType::EType destination_folder_type, | 1184 | LLAssetType::EType destination_folder_type, |
1019 | LLInventoryType::EType inv_type, | 1185 | LLInventoryType::EType inv_type, U32 next_owner_perm, |
1020 | U32 next_owner_perm, | ||
1021 | const std::string& display_name, | 1186 | const std::string& display_name, |
1022 | LLAssetStorage::LLStoreAssetCallback callback, | 1187 | LLAssetStorage::LLStoreAssetCallback callback, |
1023 | void *userdata) | 1188 | void *userdata) |
1024 | { | 1189 | { |
1025 | if(gDisconnected) | 1190 | if (gDisconnected) |
1026 | { | 1191 | { |
1027 | return ; | 1192 | return; |
1028 | } | 1193 | } |
1029 | 1194 | ||
1030 | LLAssetID uuid = tid.makeAssetID(gAgent.getSecureSessionID()); | 1195 | LLAssetID uuid = tid.makeAssetID(gAgent.getSecureSessionID()); |
1031 | 1196 | ||
1032 | // At this point, we're ready for the upload. | 1197 | // At this point, we're ready for the upload. |
1033 | std::string upload_message = "Uploading...\n\n"; | 1198 | std::string upload_message = "Uploading...\n\n"; |
1034 | upload_message.append(display_name); | 1199 | upload_message.append(display_name); |
@@ -1043,66 +1208,61 @@ void myupload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ | |||
1043 | body["inventory_type"] = LLInventoryType::lookup(inv_type); | 1208 | body["inventory_type"] = LLInventoryType::lookup(inv_type); |
1044 | body["name"] = name; | 1209 | body["name"] = name; |
1045 | body["description"] = desc; | 1210 | body["description"] = desc; |
1046 | 1211 | ||
1047 | std::ostringstream llsdxml; | 1212 | std::ostringstream llsdxml; |
1048 | LLSDSerialize::toXML(body, llsdxml); | 1213 | LLSDSerialize::toXML(body, llsdxml); |
1049 | lldebugs << "posting body to capability: " << llsdxml.str() << llendl; | 1214 | lldebugs << "posting body to capability: " << llsdxml.str() << llendl; |
1050 | //LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, uuid, asset_type)); | 1215 | //LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, uuid, asset_type)); |
1051 | LLHTTPClient::post(url, body, new importResponder(body, uuid, asset_type)); | 1216 | LLHTTPClient::post(url, body, new importResponder(body, uuid, asset_type)); |
1052 | |||
1053 | } | 1217 | } |
1054 | else | 1218 | else |
1055 | { | 1219 | { |
1056 | llinfos << "NewAgentInventory capability not found, FUCK!" << llendl; | 1220 | llinfos << "NewAgentInventory capability not found. Can't upload !" << llendl; |
1057 | } | 1221 | } |
1058 | } | 1222 | } |
1059 | 1223 | ||
1060 | 1224 | void PrimBackup::uploadNextAsset() | |
1061 | |||
1062 | void primbackup::upload_next_asset() | ||
1063 | { | 1225 | { |
1064 | if(textures.empty()) | 1226 | if (mTexturesList.empty()) |
1065 | { | 1227 | { |
1066 | llinfos<<" Texture list is empty, moving to rez statge"<< llendl; | 1228 | llinfos << "Texture list is empty, moving to rez stage." << llendl; |
1067 | current_asset=LLUUID::null; | 1229 | mCurrentAsset = LLUUID::null; |
1068 | import_object1a(); | 1230 | importFirstObject(); |
1069 | return; | 1231 | return; |
1070 | } | 1232 | } |
1071 | 1233 | ||
1072 | this->updateimportnumbers(); | 1234 | updateImportNumbers(); |
1073 | 1235 | ||
1074 | std::list<LLUUID>::iterator iter; | 1236 | std::list<LLUUID>::iterator iter; |
1075 | iter=textures.begin(); | 1237 | iter = mTexturesList.begin(); |
1076 | LLUUID id=(*iter); | 1238 | LLUUID id = *iter; |
1077 | textures.pop_front(); | 1239 | mTexturesList.pop_front(); |
1078 | 1240 | ||
1079 | llinfos<<"Got texture ID "<<id<< "trying to upload"<<llendl; | 1241 | llinfos << "Got texture ID " << id << ": trying to upload" << llendl; |
1080 | 1242 | ||
1081 | current_asset=id; | 1243 | mCurrentAsset = id; |
1082 | std::string struid; | 1244 | std::string struid; |
1083 | id.toString(struid); | 1245 | id.toString(struid); |
1084 | std::string filename=folder+"//"+struid; | 1246 | std::string filename = mFolder + "//" + struid; |
1085 | |||
1086 | |||
1087 | LLAssetID uuid; | 1247 | LLAssetID uuid; |
1088 | LLTransactionID tid; | 1248 | LLTransactionID tid; |
1089 | 1249 | ||
1090 | // gen a new transaction ID for this asset | 1250 | // generate a new transaction ID for this asset |
1091 | tid.generate(); | 1251 | tid.generate(); |
1092 | uuid = tid.makeAssetID(gAgent.getSecureSessionID()); | 1252 | uuid = tid.makeAssetID(gAgent.getSecureSessionID()); |
1093 | 1253 | ||
1094 | S32 file_size; | 1254 | S32 file_size; |
1095 | apr_file_t* fp; | 1255 | apr_file_t* fp; |
1096 | LLAPRFile aFile; | 1256 | LLAPRFile aFile; |
1097 | aFile.open(filename, LL_APR_RB, LLAPRFile::global, &file_size); | 1257 | aFile.open(filename, LL_APR_RB, LLAPRFile::global, &file_size); |
1098 | fp = aFile.getFileHandle(); | 1258 | fp = aFile.getFileHandle(); |
1099 | if (fp) | 1259 | if (fp) |
1100 | { | 1260 | { |
1101 | const S32 buf_size = 65536; | 1261 | const S32 buf_size = 65536; |
1102 | U8 copy_buf[buf_size]; | 1262 | U8 copy_buf[buf_size]; |
1103 | LLVFile file(gVFS, uuid, LLAssetType::AT_TEXTURE, LLVFile::WRITE); | 1263 | LLVFile file(gVFS, uuid, LLAssetType::AT_TEXTURE, LLVFile::WRITE); |
1104 | file.setMaxSize(file_size); | 1264 | file.setMaxSize(file_size); |
1105 | 1265 | ||
1106 | while ((file_size =aFile.read(copy_buf, buf_size))) | 1266 | while ((file_size =aFile.read(copy_buf, buf_size))) |
1107 | { | 1267 | { |
1108 | file.write(copy_buf, file_size); | 1268 | file.write(copy_buf, file_size); |
@@ -1111,21 +1271,12 @@ void primbackup::upload_next_asset() | |||
1111 | } | 1271 | } |
1112 | else | 1272 | else |
1113 | { | 1273 | { |
1114 | llwarns<<"Unable to access output file "<<filename<<llendl; | 1274 | llwarns << "Unable to access output file " << filename << llendl; |
1115 | upload_next_asset(); | 1275 | uploadNextAsset(); |
1116 | return; | 1276 | return; |
1117 | } | 1277 | } |
1118 | 1278 | ||
1119 | myupload_new_resource( | 1279 | myupload_new_resource(tid, LLAssetType::AT_TEXTURE, struid, struid, 0, |
1120 | tid, LLAssetType::AT_TEXTURE, struid, | 1280 | LLAssetType::AT_TEXTURE, LLInventoryType::defaultForAssetType(LLAssetType::AT_TEXTURE), |
1121 | struid, 0, | 1281 | 0x0, "Uploaded texture", NULL, NULL); |
1122 | LLAssetType::AT_TEXTURE, | ||
1123 | LLInventoryType::defaultForAssetType(LLAssetType::AT_TEXTURE), | ||
1124 | 0x0, | ||
1125 | "Uploaded texture", | ||
1126 | NULL, | ||
1127 | NULL); | ||
1128 | |||
1129 | |||
1130 | } | 1282 | } |
1131 | |||