aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs289
1 files changed, 282 insertions, 7 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index 7ec2860..bc79944 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -40,6 +40,7 @@ using OpenSim.Region.Framework.Scenes;
40using OpenSim.Services.Interfaces; 40using OpenSim.Services.Interfaces;
41 41
42using Mono.Addins; 42using Mono.Addins;
43using PermissionMask = OpenSim.Framework.PermissionMask;
43 44
44namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory 45namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
45{ 46{
@@ -322,6 +323,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
322 323
323 if (asset != null) 324 if (asset != null)
324 { 325 {
326 // Replace an HG ID with the simple asset ID so that we can persist textures for foreign HG avatars
327 asset.ID = asset.FullID.ToString();
328
325 asset.Temporary = false; 329 asset.Temporary = false;
326 asset.Local = false; 330 asset.Local = false;
327 m_scene.AssetService.Store(asset); 331 m_scene.AssetService.Store(asset);
@@ -358,7 +362,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
358 362
359 public void QueueAppearanceSave(UUID agentid) 363 public void QueueAppearanceSave(UUID agentid)
360 { 364 {
361 // m_log.WarnFormat("[AVFACTORY]: Queue appearance save for {0}", agentid); 365// m_log.DebugFormat("[AVFACTORY]: Queueing appearance save for {0}", agentid);
362 366
363 // 10000 ticks per millisecond, 1000 milliseconds per second 367 // 10000 ticks per millisecond, 1000 milliseconds per second
364 long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000); 368 long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000);
@@ -655,7 +659,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
655 return; 659 return;
656 } 660 }
657 661
658 // m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid); 662// m_log.DebugFormat("[AVFACTORY]: Saving appearance for avatar {0}", agentid);
659 663
660 // This could take awhile since it needs to pull inventory 664 // This could take awhile since it needs to pull inventory
661 // We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape 665 // We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape
@@ -664,6 +668,14 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
664 // multiple save requests. 668 // multiple save requests.
665 SetAppearanceAssets(sp.UUID, sp.Appearance); 669 SetAppearanceAssets(sp.UUID, sp.Appearance);
666 670
671// List<AvatarAttachment> attachments = sp.Appearance.GetAttachments();
672// foreach (AvatarAttachment att in attachments)
673// {
674// m_log.DebugFormat(
675// "[AVFACTORY]: For {0} saving attachment {1} at point {2}",
676// sp.Name, att.ItemID, att.AttachPoint);
677// }
678
667 m_scene.AvatarService.SetAppearance(agentid, sp.Appearance); 679 m_scene.AvatarService.SetAppearance(agentid, sp.Appearance);
668 680
669 // Trigger this here because it's the final step in the set/queue/save process for appearance setting. 681 // Trigger this here because it's the final step in the set/queue/save process for appearance setting.
@@ -674,26 +686,70 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
674 private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance) 686 private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance)
675 { 687 {
676 IInventoryService invService = m_scene.InventoryService; 688 IInventoryService invService = m_scene.InventoryService;
677 689 bool resetwearable = false;
678 if (invService.GetRootFolder(userID) != null) 690 if (invService.GetRootFolder(userID) != null)
679 { 691 {
680 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) 692 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
681 { 693 {
682 for (int j = 0; j < appearance.Wearables[i].Count; j++) 694 for (int j = 0; j < appearance.Wearables[i].Count; j++)
683 { 695 {
696 // Check if the default wearables are not set
684 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 }
685 continue; 713 continue;
714 }
686 715
687 // Ignore ruth's assets 716 // Ignore ruth's assets except for the body parts! missing body parts fail avatar appearance on V1
688 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 }
689 continue; 733 continue;
690 734 }
735
691 InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID); 736 InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID);
692 baseItem = invService.GetItem(baseItem); 737 baseItem = invService.GetItem(baseItem);
693 738
694 if (baseItem != null) 739 if (baseItem != null)
695 { 740 {
696 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 });
697 } 753 }
698 else 754 else
699 { 755 {
@@ -701,17 +757,236 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
701 "[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",
702 appearance.Wearables[i][j].ItemID, (WearableType)i); 758 appearance.Wearables[i][j].ItemID, (WearableType)i);
703 759
704 appearance.Wearables[i].RemoveItem(appearance.Wearables[i][j].ItemID); 760 TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
761 resetwearable = true;
762
705 } 763 }
706 } 764 }
707 } 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
708 } 861 }
709 else 862 else
710 { 863 {
711 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);
712 } 865 }
713 } 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 }
714 987
988 return ret;
989 }
715 #endregion 990 #endregion
716 991
717 #region Client Event Handlers 992 #region Client Event Handlers
@@ -824,7 +1099,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
824 } 1099 }
825 1100
826 bool bakedTextureValid = m_scene.AvatarFactory.ValidateBakedTextureCache(sp); 1101 bool bakedTextureValid = m_scene.AvatarFactory.ValidateBakedTextureCache(sp);
827 outputAction("{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "corrupt"); 1102 outputAction("{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "incomplete");
828 } 1103 }
829 } 1104 }
830} 1105}