diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs')
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | 463 |
1 files changed, 430 insertions, 33 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index c7ac7c4..bc79944 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | |||
@@ -141,9 +141,24 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
141 | /// <param name="sp"></param> | 141 | /// <param name="sp"></param> |
142 | /// <param name="texture"></param> | 142 | /// <param name="texture"></param> |
143 | /// <param name="visualParam"></param> | 143 | /// <param name="visualParam"></param> |
144 | public void SetAppearance(IScenePresence sp, AvatarAppearance appearance) | 144 | public void SetAppearance(IScenePresence sp, AvatarAppearance appearance, WearableCacheItem[] cacheItems) |
145 | { | 145 | { |
146 | SetAppearance(sp, appearance.Texture, appearance.VisualParams); | 146 | SetAppearance(sp, appearance.Texture, appearance.VisualParams, cacheItems); |
147 | } | ||
148 | |||
149 | |||
150 | public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems) | ||
151 | { | ||
152 | float oldoff = sp.Appearance.AvatarFeetOffset; | ||
153 | Vector3 oldbox = sp.Appearance.AvatarBoxSize; | ||
154 | |||
155 | SetAppearance(sp, textureEntry, visualParams, cacheItems); | ||
156 | sp.Appearance.SetSize(avSize); | ||
157 | |||
158 | float off = sp.Appearance.AvatarFeetOffset; | ||
159 | Vector3 box = sp.Appearance.AvatarBoxSize; | ||
160 | if (oldoff != off || oldbox != box) | ||
161 | ((ScenePresence)sp).SetSize(box, off); | ||
147 | } | 162 | } |
148 | 163 | ||
149 | /// <summary> | 164 | /// <summary> |
@@ -152,7 +167,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
152 | /// <param name="sp"></param> | 167 | /// <param name="sp"></param> |
153 | /// <param name="texture"></param> | 168 | /// <param name="texture"></param> |
154 | /// <param name="visualParam"></param> | 169 | /// <param name="visualParam"></param> |
155 | public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams) | 170 | public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, WearableCacheItem[] cacheItems) |
156 | { | 171 | { |
157 | // m_log.DebugFormat( | 172 | // m_log.DebugFormat( |
158 | // "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}", | 173 | // "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}", |
@@ -175,18 +190,27 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
175 | // m_log.DebugFormat( | 190 | // m_log.DebugFormat( |
176 | // "[AVFACTORY]: Setting visual params for {0} to {1}", | 191 | // "[AVFACTORY]: Setting visual params for {0} to {1}", |
177 | // client.Name, string.Join(", ", visualParamsStrings)); | 192 | // client.Name, string.Join(", ", visualParamsStrings)); |
178 | 193 | /* | |
179 | float oldHeight = sp.Appearance.AvatarHeight; | 194 | float oldHeight = sp.Appearance.AvatarHeight; |
180 | changed = sp.Appearance.SetVisualParams(visualParams); | 195 | changed = sp.Appearance.SetVisualParams(visualParams); |
181 | 196 | ||
182 | if (sp.Appearance.AvatarHeight != oldHeight && sp.Appearance.AvatarHeight > 0) | 197 | if (sp.Appearance.AvatarHeight != oldHeight && sp.Appearance.AvatarHeight > 0) |
183 | ((ScenePresence)sp).SetHeight(sp.Appearance.AvatarHeight); | 198 | ((ScenePresence)sp).SetHeight(sp.Appearance.AvatarHeight); |
184 | } | 199 | */ |
200 | // float oldoff = sp.Appearance.AvatarFeetOffset; | ||
201 | // Vector3 oldbox = sp.Appearance.AvatarBoxSize; | ||
202 | changed = sp.Appearance.SetVisualParams(visualParams); | ||
203 | // float off = sp.Appearance.AvatarFeetOffset; | ||
204 | // Vector3 box = sp.Appearance.AvatarBoxSize; | ||
205 | // if(oldoff != off || oldbox != box) | ||
206 | // ((ScenePresence)sp).SetSize(box,off); | ||
185 | 207 | ||
208 | } | ||
209 | |||
186 | // Process the baked texture array | 210 | // Process the baked texture array |
187 | if (textureEntry != null) | 211 | if (textureEntry != null) |
188 | { | 212 | { |
189 | // m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID); | 213 | m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID); |
190 | 214 | ||
191 | // WriteBakedTexturesReport(sp, m_log.DebugFormat); | 215 | // WriteBakedTexturesReport(sp, m_log.DebugFormat); |
192 | 216 | ||
@@ -255,6 +279,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
255 | return GetBakedTextureFaces(sp); | 279 | return GetBakedTextureFaces(sp); |
256 | } | 280 | } |
257 | 281 | ||
282 | public WearableCacheItem[] GetCachedItems(UUID agentId) | ||
283 | { | ||
284 | ScenePresence sp = m_scene.GetScenePresence(agentId); | ||
285 | WearableCacheItem[] items = sp.Appearance.WearableCacheItems; | ||
286 | //foreach (WearableCacheItem item in items) | ||
287 | //{ | ||
288 | |||
289 | //} | ||
290 | return items; | ||
291 | } | ||
292 | |||
258 | public bool SaveBakedTextures(UUID agentId) | 293 | public bool SaveBakedTextures(UUID agentId) |
259 | { | 294 | { |
260 | ScenePresence sp = m_scene.GetScenePresence(agentId); | 295 | ScenePresence sp = m_scene.GetScenePresence(agentId); |
@@ -341,6 +376,53 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
341 | public bool ValidateBakedTextureCache(IScenePresence sp) | 376 | public bool ValidateBakedTextureCache(IScenePresence sp) |
342 | { | 377 | { |
343 | bool defonly = true; // are we only using default textures | 378 | bool defonly = true; // are we only using default textures |
379 | IImprovedAssetCache cache = m_scene.RequestModuleInterface<IImprovedAssetCache>(); | ||
380 | IBakedTextureModule bakedModule = m_scene.RequestModuleInterface<IBakedTextureModule>(); | ||
381 | WearableCacheItem[] wearableCache = null; | ||
382 | |||
383 | // Cache wearable data for teleport. | ||
384 | // Only makes sense if there's a bake module and a cache module | ||
385 | if (bakedModule != null && cache != null) | ||
386 | { | ||
387 | try | ||
388 | { | ||
389 | wearableCache = bakedModule.Get(sp.UUID); | ||
390 | } | ||
391 | catch (Exception) | ||
392 | { | ||
393 | |||
394 | } | ||
395 | if (wearableCache != null) | ||
396 | { | ||
397 | for (int i = 0; i < wearableCache.Length; i++) | ||
398 | { | ||
399 | cache.Cache(wearableCache[i].TextureAsset); | ||
400 | } | ||
401 | } | ||
402 | } | ||
403 | /* | ||
404 | IBakedTextureModule bakedModule = m_scene.RequestModuleInterface<IBakedTextureModule>(); | ||
405 | if (invService.GetRootFolder(userID) != null) | ||
406 | { | ||
407 | WearableCacheItem[] wearableCache = null; | ||
408 | if (bakedModule != null) | ||
409 | { | ||
410 | try | ||
411 | { | ||
412 | wearableCache = bakedModule.Get(userID); | ||
413 | appearance.WearableCacheItems = wearableCache; | ||
414 | appearance.WearableCacheItemsDirty = false; | ||
415 | foreach (WearableCacheItem item in wearableCache) | ||
416 | { | ||
417 | appearance.Texture.FaceTextures[item.TextureIndex].TextureID = item.TextureID; | ||
418 | } | ||
419 | } | ||
420 | catch (Exception) | ||
421 | { | ||
422 | |||
423 | } | ||
424 | } | ||
425 | */ | ||
344 | 426 | ||
345 | // Process the texture entry | 427 | // Process the texture entry |
346 | for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) | 428 | for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) |
@@ -348,9 +430,32 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
348 | int idx = AvatarAppearance.BAKE_INDICES[i]; | 430 | int idx = AvatarAppearance.BAKE_INDICES[i]; |
349 | Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; | 431 | Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; |
350 | 432 | ||
351 | // if there is no texture entry, skip it | 433 | // No face, so lets check our baked service cache, teleport or login. |
352 | if (face == null) | 434 | if (face == null) |
353 | continue; | 435 | { |
436 | if (wearableCache != null) | ||
437 | { | ||
438 | // If we find the an appearance item, set it as the textureentry and the face | ||
439 | WearableCacheItem searchitem = WearableCacheItem.SearchTextureIndex((uint) idx, wearableCache); | ||
440 | if (searchitem != null) | ||
441 | { | ||
442 | sp.Appearance.Texture.FaceTextures[idx] = sp.Appearance.Texture.CreateFace((uint) idx); | ||
443 | sp.Appearance.Texture.FaceTextures[idx].TextureID = searchitem.TextureID; | ||
444 | face = sp.Appearance.Texture.FaceTextures[idx]; | ||
445 | } | ||
446 | else | ||
447 | { | ||
448 | // if there is no texture entry and no baked cache, skip it | ||
449 | continue; | ||
450 | } | ||
451 | } | ||
452 | else | ||
453 | { | ||
454 | //No texture entry face and no cache. Skip this face. | ||
455 | continue; | ||
456 | } | ||
457 | } | ||
458 | |||
354 | 459 | ||
355 | // m_log.DebugFormat( | 460 | // m_log.DebugFormat( |
356 | // "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}", | 461 | // "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}", |
@@ -365,8 +470,16 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
365 | 470 | ||
366 | defonly = false; // found a non-default texture reference | 471 | defonly = false; // found a non-default texture reference |
367 | 472 | ||
368 | if (m_scene.AssetService.Get(face.TextureID.ToString()) == null) | 473 | if (cache != null) |
369 | return false; | 474 | { |
475 | if (!cache.Check(face.TextureID.ToString())) | ||
476 | return false; | ||
477 | } | ||
478 | else | ||
479 | { | ||
480 | if (m_scene.AssetService.Get(face.TextureID.ToString()) == null) | ||
481 | return false; | ||
482 | } | ||
370 | } | 483 | } |
371 | 484 | ||
372 | // m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID); | 485 | // m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID); |
@@ -378,6 +491,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
378 | public int RequestRebake(IScenePresence sp, bool missingTexturesOnly) | 491 | public int RequestRebake(IScenePresence sp, bool missingTexturesOnly) |
379 | { | 492 | { |
380 | int texturesRebaked = 0; | 493 | int texturesRebaked = 0; |
494 | IImprovedAssetCache cache = m_scene.RequestModuleInterface<IImprovedAssetCache>(); | ||
381 | 495 | ||
382 | for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) | 496 | for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) |
383 | { | 497 | { |
@@ -401,21 +515,36 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
401 | 515 | ||
402 | if (missingTexturesOnly) | 516 | if (missingTexturesOnly) |
403 | { | 517 | { |
404 | if (m_scene.AssetService.Get(face.TextureID.ToString()) != null) | 518 | if (cache != null) |
405 | { | 519 | { |
406 | continue; | 520 | if (cache.Check(face.TextureID.ToString())) |
521 | continue; | ||
522 | else | ||
523 | { | ||
524 | m_log.DebugFormat( | ||
525 | "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.", | ||
526 | face.TextureID, idx, sp.Name); | ||
527 | } | ||
407 | } | 528 | } |
408 | else | 529 | else |
409 | { | 530 | { |
410 | // On inter-simulator teleports, this occurs if baked textures are not being stored by the | 531 | if (m_scene.AssetService.Get(face.TextureID.ToString()) != null) |
411 | // grid asset service (which means that they are not available to the new region and so have | 532 | { |
412 | // to be re-requested from the client). | 533 | continue; |
413 | // | 534 | } |
414 | // The only available core OpenSimulator behaviour right now | 535 | |
415 | // is not to store these textures, temporarily or otherwise. | 536 | else |
416 | m_log.DebugFormat( | 537 | { |
417 | "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.", | 538 | // On inter-simulator teleports, this occurs if baked textures are not being stored by the |
418 | face.TextureID, idx, sp.Name); | 539 | // grid asset service (which means that they are not available to the new region and so have |
540 | // to be re-requested from the client). | ||
541 | // | ||
542 | // The only available core OpenSimulator behaviour right now | ||
543 | // is not to store these textures, temporarily or otherwise. | ||
544 | m_log.DebugFormat( | ||
545 | "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.", | ||
546 | face.TextureID, idx, sp.Name); | ||
547 | } | ||
419 | } | 548 | } |
420 | } | 549 | } |
421 | else | 550 | else |
@@ -557,26 +686,70 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
557 | private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance) | 686 | private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance) |
558 | { | 687 | { |
559 | IInventoryService invService = m_scene.InventoryService; | 688 | IInventoryService invService = m_scene.InventoryService; |
560 | 689 | bool resetwearable = false; | |
561 | if (invService.GetRootFolder(userID) != null) | 690 | if (invService.GetRootFolder(userID) != null) |
562 | { | 691 | { |
563 | for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) | 692 | for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) |
564 | { | 693 | { |
565 | for (int j = 0; j < appearance.Wearables[i].Count; j++) | 694 | for (int j = 0; j < appearance.Wearables[i].Count; j++) |
566 | { | 695 | { |
696 | // Check if the default wearables are not set | ||
567 | if (appearance.Wearables[i][j].ItemID == UUID.Zero) | 697 | if (appearance.Wearables[i][j].ItemID == UUID.Zero) |
698 | { | ||
699 | switch ((WearableType) i) | ||
700 | { | ||
701 | case WearableType.Eyes: | ||
702 | case WearableType.Hair: | ||
703 | case WearableType.Shape: | ||
704 | case WearableType.Skin: | ||
705 | //case WearableType.Underpants: | ||
706 | TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance); | ||
707 | resetwearable = true; | ||
708 | m_log.Warn("[AVFACTORY]: UUID.Zero Wearables, passing fake values."); | ||
709 | resetwearable = true; | ||
710 | break; | ||
711 | |||
712 | } | ||
568 | continue; | 713 | continue; |
714 | } | ||
569 | 715 | ||
570 | // Ignore ruth's assets | 716 | // Ignore ruth's assets except for the body parts! missing body parts fail avatar appearance on V1 |
571 | if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID) | 717 | if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID) |
718 | { | ||
719 | switch ((WearableType)i) | ||
720 | { | ||
721 | case WearableType.Eyes: | ||
722 | case WearableType.Hair: | ||
723 | case WearableType.Shape: | ||
724 | case WearableType.Skin: | ||
725 | //case WearableType.Underpants: | ||
726 | TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance); | ||
727 | |||
728 | m_log.WarnFormat("[AVFACTORY]: {0} Default Wearables, passing existing values.", (WearableType)i); | ||
729 | resetwearable = true; | ||
730 | break; | ||
731 | |||
732 | } | ||
572 | continue; | 733 | continue; |
573 | 734 | } | |
735 | |||
574 | InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID); | 736 | InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID); |
575 | baseItem = invService.GetItem(baseItem); | 737 | baseItem = invService.GetItem(baseItem); |
576 | 738 | ||
577 | if (baseItem != null) | 739 | if (baseItem != null) |
578 | { | 740 | { |
579 | appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID); | 741 | appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID); |
742 | int unmodifiedWearableIndexForClosure = i; | ||
743 | m_scene.AssetService.Get(baseItem.AssetID.ToString(), this, | ||
744 | delegate(string x, object y, AssetBase z) | ||
745 | { | ||
746 | if (z == null) | ||
747 | { | ||
748 | TryAndRepairBrokenWearable( | ||
749 | (WearableType)unmodifiedWearableIndexForClosure, invService, | ||
750 | userID, appearance); | ||
751 | } | ||
752 | }); | ||
580 | } | 753 | } |
581 | else | 754 | else |
582 | { | 755 | { |
@@ -584,17 +757,236 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
584 | "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default", | 757 | "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default", |
585 | appearance.Wearables[i][j].ItemID, (WearableType)i); | 758 | appearance.Wearables[i][j].ItemID, (WearableType)i); |
586 | 759 | ||
587 | appearance.Wearables[i].RemoveItem(appearance.Wearables[i][j].ItemID); | 760 | TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance); |
761 | resetwearable = true; | ||
762 | |||
588 | } | 763 | } |
589 | } | 764 | } |
590 | } | 765 | } |
766 | |||
767 | // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason.... | ||
768 | if (appearance.Wearables[(int) WearableType.Eyes] == null) | ||
769 | { | ||
770 | m_log.WarnFormat("[AVFACTORY]: {0} Eyes are Null, passing existing values.", (WearableType.Eyes)); | ||
771 | |||
772 | TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance); | ||
773 | resetwearable = true; | ||
774 | } | ||
775 | else | ||
776 | { | ||
777 | if (appearance.Wearables[(int) WearableType.Eyes][0].ItemID == UUID.Zero) | ||
778 | { | ||
779 | m_log.WarnFormat("[AVFACTORY]: Eyes are UUID.Zero are broken, {0} {1}", | ||
780 | appearance.Wearables[(int) WearableType.Eyes][0].ItemID, | ||
781 | appearance.Wearables[(int) WearableType.Eyes][0].AssetID); | ||
782 | TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance); | ||
783 | resetwearable = true; | ||
784 | |||
785 | } | ||
786 | |||
787 | } | ||
788 | // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason.... | ||
789 | if (appearance.Wearables[(int)WearableType.Shape] == null) | ||
790 | { | ||
791 | m_log.WarnFormat("[AVFACTORY]: {0} shape is Null, passing existing values.", (WearableType.Shape)); | ||
792 | |||
793 | TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance); | ||
794 | resetwearable = true; | ||
795 | } | ||
796 | else | ||
797 | { | ||
798 | if (appearance.Wearables[(int)WearableType.Shape][0].ItemID == UUID.Zero) | ||
799 | { | ||
800 | m_log.WarnFormat("[AVFACTORY]: Shape is UUID.Zero and broken, {0} {1}", | ||
801 | appearance.Wearables[(int)WearableType.Shape][0].ItemID, | ||
802 | appearance.Wearables[(int)WearableType.Shape][0].AssetID); | ||
803 | TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance); | ||
804 | resetwearable = true; | ||
805 | |||
806 | } | ||
807 | |||
808 | } | ||
809 | // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason.... | ||
810 | if (appearance.Wearables[(int)WearableType.Hair] == null) | ||
811 | { | ||
812 | m_log.WarnFormat("[AVFACTORY]: {0} Hair is Null, passing existing values.", (WearableType.Hair)); | ||
813 | |||
814 | TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance); | ||
815 | resetwearable = true; | ||
816 | } | ||
817 | else | ||
818 | { | ||
819 | if (appearance.Wearables[(int)WearableType.Hair][0].ItemID == UUID.Zero) | ||
820 | { | ||
821 | m_log.WarnFormat("[AVFACTORY]: Hair is UUID.Zero and broken, {0} {1}", | ||
822 | appearance.Wearables[(int)WearableType.Hair][0].ItemID, | ||
823 | appearance.Wearables[(int)WearableType.Hair][0].AssetID); | ||
824 | TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance); | ||
825 | resetwearable = true; | ||
826 | |||
827 | } | ||
828 | |||
829 | } | ||
830 | // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason.... | ||
831 | if (appearance.Wearables[(int)WearableType.Skin] == null) | ||
832 | { | ||
833 | m_log.WarnFormat("[AVFACTORY]: {0} Skin is Null, passing existing values.", (WearableType.Skin)); | ||
834 | |||
835 | TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance); | ||
836 | resetwearable = true; | ||
837 | } | ||
838 | else | ||
839 | { | ||
840 | if (appearance.Wearables[(int)WearableType.Skin][0].ItemID == UUID.Zero) | ||
841 | { | ||
842 | m_log.WarnFormat("[AVFACTORY]: Skin is UUID.Zero and broken, {0} {1}", | ||
843 | appearance.Wearables[(int)WearableType.Skin][0].ItemID, | ||
844 | appearance.Wearables[(int)WearableType.Skin][0].AssetID); | ||
845 | TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance); | ||
846 | resetwearable = true; | ||
847 | |||
848 | } | ||
849 | |||
850 | } | ||
851 | if (resetwearable) | ||
852 | { | ||
853 | ScenePresence presence = null; | ||
854 | if (m_scene.TryGetScenePresence(userID, out presence)) | ||
855 | { | ||
856 | presence.ControllingClient.SendWearables(presence.Appearance.Wearables, | ||
857 | presence.Appearance.Serial++); | ||
858 | } | ||
859 | } | ||
860 | |||
591 | } | 861 | } |
592 | else | 862 | else |
593 | { | 863 | { |
594 | m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID); | 864 | m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID); |
595 | } | 865 | } |
596 | } | 866 | } |
867 | private void TryAndRepairBrokenWearable(WearableType type, IInventoryService invService, UUID userID,AvatarAppearance appearance) | ||
868 | { | ||
869 | UUID defaultwearable = GetDefaultItem(type); | ||
870 | if (defaultwearable != UUID.Zero) | ||
871 | { | ||
872 | UUID newInvItem = UUID.Random(); | ||
873 | InventoryItemBase itembase = new InventoryItemBase(newInvItem, userID) | ||
874 | { | ||
875 | AssetID = | ||
876 | defaultwearable, | ||
877 | AssetType | ||
878 | = | ||
879 | (int) | ||
880 | AssetType | ||
881 | .Bodypart, | ||
882 | CreatorId | ||
883 | = | ||
884 | userID | ||
885 | .ToString | ||
886 | (), | ||
887 | //InvType = (int)InventoryType.Wearable, | ||
888 | |||
889 | Description | ||
890 | = | ||
891 | "Failed Wearable Replacement", | ||
892 | Folder = | ||
893 | invService | ||
894 | .GetFolderForType | ||
895 | (userID, | ||
896 | AssetType | ||
897 | .Bodypart) | ||
898 | .ID, | ||
899 | Flags = (uint) type, | ||
900 | Name = Enum.GetName(typeof (WearableType), type), | ||
901 | BasePermissions = (uint) PermissionMask.Copy, | ||
902 | CurrentPermissions = (uint) PermissionMask.Copy, | ||
903 | EveryOnePermissions = (uint) PermissionMask.Copy, | ||
904 | GroupPermissions = (uint) PermissionMask.Copy, | ||
905 | NextPermissions = (uint) PermissionMask.Copy | ||
906 | }; | ||
907 | invService.AddItem(itembase); | ||
908 | UUID LinkInvItem = UUID.Random(); | ||
909 | itembase = new InventoryItemBase(LinkInvItem, userID) | ||
910 | { | ||
911 | AssetID = | ||
912 | newInvItem, | ||
913 | AssetType | ||
914 | = | ||
915 | (int) | ||
916 | AssetType | ||
917 | .Link, | ||
918 | CreatorId | ||
919 | = | ||
920 | userID | ||
921 | .ToString | ||
922 | (), | ||
923 | InvType = (int) InventoryType.Wearable, | ||
924 | |||
925 | Description | ||
926 | = | ||
927 | "Failed Wearable Replacement", | ||
928 | Folder = | ||
929 | invService | ||
930 | .GetFolderForType | ||
931 | (userID, | ||
932 | AssetType | ||
933 | .CurrentOutfitFolder) | ||
934 | .ID, | ||
935 | Flags = (uint) type, | ||
936 | Name = Enum.GetName(typeof (WearableType), type), | ||
937 | BasePermissions = (uint) PermissionMask.Copy, | ||
938 | CurrentPermissions = (uint) PermissionMask.Copy, | ||
939 | EveryOnePermissions = (uint) PermissionMask.Copy, | ||
940 | GroupPermissions = (uint) PermissionMask.Copy, | ||
941 | NextPermissions = (uint) PermissionMask.Copy | ||
942 | }; | ||
943 | invService.AddItem(itembase); | ||
944 | appearance.Wearables[(int)type] = new AvatarWearable(newInvItem, GetDefaultItem(type)); | ||
945 | ScenePresence presence = null; | ||
946 | if (m_scene.TryGetScenePresence(userID, out presence)) | ||
947 | { | ||
948 | m_scene.SendInventoryUpdate(presence.ControllingClient, | ||
949 | invService.GetFolderForType(userID, | ||
950 | AssetType | ||
951 | .CurrentOutfitFolder), | ||
952 | false, true); | ||
953 | } | ||
954 | } | ||
955 | } | ||
956 | private UUID GetDefaultItem(WearableType wearable) | ||
957 | { | ||
958 | // These are ruth | ||
959 | UUID ret = UUID.Zero; | ||
960 | switch (wearable) | ||
961 | { | ||
962 | case WearableType.Eyes: | ||
963 | ret = new UUID("4bb6fa4d-1cd2-498a-a84c-95c1a0e745a7"); | ||
964 | break; | ||
965 | case WearableType.Hair: | ||
966 | ret = new UUID("d342e6c0-b9d2-11dc-95ff-0800200c9a66"); | ||
967 | break; | ||
968 | case WearableType.Pants: | ||
969 | ret = new UUID("00000000-38f9-1111-024e-222222111120"); | ||
970 | break; | ||
971 | case WearableType.Shape: | ||
972 | ret = new UUID("66c41e39-38f9-f75a-024e-585989bfab73"); | ||
973 | break; | ||
974 | case WearableType.Shirt: | ||
975 | ret = new UUID("00000000-38f9-1111-024e-222222111110"); | ||
976 | break; | ||
977 | case WearableType.Skin: | ||
978 | ret = new UUID("77c41e39-38f9-f75a-024e-585989bbabbb"); | ||
979 | break; | ||
980 | case WearableType.Undershirt: | ||
981 | ret = new UUID("16499ebb-3208-ec27-2def-481881728f47"); | ||
982 | break; | ||
983 | case WearableType.Underpants: | ||
984 | ret = new UUID("4ac2e9c7-3671-d229-316a-67717730841d"); | ||
985 | break; | ||
986 | } | ||
597 | 987 | ||
988 | return ret; | ||
989 | } | ||
598 | #endregion | 990 | #endregion |
599 | 991 | ||
600 | #region Client Event Handlers | 992 | #region Client Event Handlers |
@@ -604,12 +996,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
604 | /// <param name="client"></param> | 996 | /// <param name="client"></param> |
605 | private void Client_OnRequestWearables(IClientAPI client) | 997 | private void Client_OnRequestWearables(IClientAPI client) |
606 | { | 998 | { |
607 | // m_log.DebugFormat("[AVFACTORY]: Client_OnRequestWearables called for {0} ({1})", client.Name, client.AgentId); | 999 | Util.FireAndForget(delegate(object x) |
608 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); | 1000 | { |
609 | if (sp != null) | 1001 | Thread.Sleep(4000); |
610 | client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++); | 1002 | |
611 | else | 1003 | // m_log.DebugFormat("[AVFACTORY]: Client_OnRequestWearables called for {0} ({1})", client.Name, client.AgentId); |
612 | m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId); | 1004 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); |
1005 | if (sp != null) | ||
1006 | client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++); | ||
1007 | else | ||
1008 | m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId); | ||
1009 | }); | ||
613 | } | 1010 | } |
614 | 1011 | ||
615 | /// <summary> | 1012 | /// <summary> |
@@ -618,12 +1015,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
618 | /// <param name="client"></param> | 1015 | /// <param name="client"></param> |
619 | /// <param name="texture"></param> | 1016 | /// <param name="texture"></param> |
620 | /// <param name="visualParam"></param> | 1017 | /// <param name="visualParam"></param> |
621 | private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams) | 1018 | private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems) |
622 | { | 1019 | { |
623 | // m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId); | 1020 | // m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId); |
624 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); | 1021 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); |
625 | if (sp != null) | 1022 | if (sp != null) |
626 | SetAppearance(sp, textureEntry, visualParams); | 1023 | SetAppearance(sp, textureEntry, visualParams,avSize, cacheItems); |
627 | else | 1024 | else |
628 | m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId); | 1025 | m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId); |
629 | } | 1026 | } |