diff options
author | UbitUmarov | 2019-09-11 13:51:43 +0100 |
---|---|---|
committer | UbitUmarov | 2019-09-11 13:51:43 +0100 |
commit | 9d6c996570377f137f93d16c388746f949b9a841 (patch) | |
tree | 11076440a1101266dda5651b5160693e25c7b8d0 /OpenSim | |
parent | disable AvatarHoverHeight useless and viewer side broken (without SSA) (diff) | |
download | opensim-SC-9d6c996570377f137f93d16c388746f949b9a841.zip opensim-SC-9d6c996570377f137f93d16c388746f949b9a841.tar.gz opensim-SC-9d6c996570377f137f93d16c388746f949b9a841.tar.bz2 opensim-SC-9d6c996570377f137f93d16c388746f949b9a841.tar.xz |
extent supported number of avatar textures/bakes/wearables, tell viewers about it on lludp RegionHandShake; propagate agenthover; block teleports/crossings based on worn wearables and peer version;
Diffstat (limited to 'OpenSim')
18 files changed, 436 insertions, 407 deletions
diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs index f1713a6..a7bd398 100644 --- a/OpenSim/Framework/AvatarAppearance.cs +++ b/OpenSim/Framework/AvatarAppearance.cs | |||
@@ -51,27 +51,28 @@ namespace OpenSim.Framework | |||
51 | 51 | ||
52 | // this is viewer capabilities and weared things dependent | 52 | // this is viewer capabilities and weared things dependent |
53 | // should be only used as initial default value ( V1 viewers ) | 53 | // should be only used as initial default value ( V1 viewers ) |
54 | public readonly static int VISUALPARAM_COUNT = 218; | 54 | public const int VISUALPARAM_COUNT = 218; |
55 | 55 | ||
56 | // public readonly static int TEXTURE_COUNT = 21 | 56 | // regions and viewer compatibility |
57 | // 21 bad, make it be updated as libovm gets update | 57 | public readonly static int TEXTURE_COUNT = 45; |
58 | // also keeping in sync with it | 58 | public const int TEXTURE_COUNT_PV7 = 26; |
59 | public readonly static int TEXTURE_COUNT = Primitive.TextureEntry.MAX_FACES; | 59 | public const int BAKES_COUNT_PV7 = 6; |
60 | public const int MAXWEARABLE_PV7 = 16; | ||
61 | public const int MAXWEARABLE_LEGACY = 14; | ||
60 | 62 | ||
61 | public readonly static byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; | 63 | public readonly static byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20, 40, 41, 42, 43, 44 }; |
62 | 64 | ||
63 | protected int m_serial = 0; | 65 | protected int m_serial = 0; |
64 | protected byte[] m_visualparams; | 66 | protected byte[] m_visualparams; |
65 | protected Primitive.TextureEntry m_texture; | 67 | protected Primitive.TextureEntry m_texture; |
66 | protected AvatarWearable[] m_wearables; | 68 | protected AvatarWearable[] m_wearables; |
67 | protected Dictionary<int, List<AvatarAttachment>> m_attachments; | 69 | protected Dictionary<int, List<AvatarAttachment>> m_attachments; |
68 | protected float m_avatarHeight = 0; | 70 | protected WearableCacheItem[] m_cacheitems; |
69 | protected Vector3 m_avatarSize = new Vector3(0.45f, 0.6f, 1.9f); // sl Z cloud value | 71 | protected Vector3 m_avatarSize = new Vector3(0.45f, 0.6f, 1.9f); // sl Z cloud value |
70 | protected Vector3 m_avatarBoxSize = new Vector3(0.45f, 0.6f, 1.9f); | 72 | protected Vector3 m_avatarBoxSize = new Vector3(0.45f, 0.6f, 1.9f); |
73 | protected float m_avatarHeight = 0; | ||
71 | protected float m_avatarFeetOffset = 0; | 74 | protected float m_avatarFeetOffset = 0; |
72 | protected float m_avatarAnimOffset = 0; | 75 | protected float m_avatarAnimOffset = 0; |
73 | protected WearableCacheItem[] m_cacheitems; | ||
74 | protected bool m_cacheItemsDirty = true; | ||
75 | 76 | ||
76 | public virtual int Serial | 77 | public virtual int Serial |
77 | { | 78 | { |
@@ -128,11 +129,7 @@ namespace OpenSim.Framework | |||
128 | set { m_cacheitems = value; } | 129 | set { m_cacheitems = value; } |
129 | } | 130 | } |
130 | 131 | ||
131 | public virtual bool WearableCacheItemsDirty | 132 | public virtual float AvatarPreferencesHoverZ { get; set; } |
132 | { | ||
133 | get { return m_cacheItemsDirty; } | ||
134 | set { m_cacheItemsDirty = value; } | ||
135 | } | ||
136 | 133 | ||
137 | public AvatarAppearance() | 134 | public AvatarAppearance() |
138 | { | 135 | { |
@@ -204,12 +201,14 @@ namespace OpenSim.Framework | |||
204 | SetDefaultParams(); | 201 | SetDefaultParams(); |
205 | // SetHeight(); | 202 | // SetHeight(); |
206 | SetSize(new Vector3(0.45f, 0.6f, 1.9f)); | 203 | SetSize(new Vector3(0.45f, 0.6f, 1.9f)); |
204 | AvatarPreferencesHoverZ = 0; | ||
207 | m_attachments = new Dictionary<int, List<AvatarAttachment>>(); | 205 | m_attachments = new Dictionary<int, List<AvatarAttachment>>(); |
208 | 206 | ||
209 | return; | 207 | return; |
210 | } | 208 | } |
211 | 209 | ||
212 | m_serial = appearance.Serial; | 210 | m_serial = appearance.Serial; |
211 | AvatarPreferencesHoverZ = appearance.AvatarPreferencesHoverZ; | ||
213 | 212 | ||
214 | if (copyWearables && (appearance.Wearables != null)) | 213 | if (copyWearables && (appearance.Wearables != null)) |
215 | { | 214 | { |
@@ -228,7 +227,7 @@ namespace OpenSim.Framework | |||
228 | m_texture = null; | 227 | m_texture = null; |
229 | if (appearance.Texture != null) | 228 | if (appearance.Texture != null) |
230 | { | 229 | { |
231 | byte[] tbytes = appearance.Texture.GetBytes(); | 230 | byte[] tbytes = appearance.Texture.GetBakesBytes(); |
232 | m_texture = new Primitive.TextureEntry(tbytes,0,tbytes.Length); | 231 | m_texture = new Primitive.TextureEntry(tbytes,0,tbytes.Length); |
233 | if (copyBaked && appearance.m_cacheitems != null) | 232 | if (copyBaked && appearance.m_cacheitems != null) |
234 | m_cacheitems = (WearableCacheItem[])appearance.m_cacheitems.Clone(); | 233 | m_cacheitems = (WearableCacheItem[])appearance.m_cacheitems.Clone(); |
@@ -295,6 +294,7 @@ namespace OpenSim.Framework | |||
295 | m_serial = 0; | 294 | m_serial = 0; |
296 | 295 | ||
297 | SetDefaultTexture(); | 296 | SetDefaultTexture(); |
297 | AvatarPreferencesHoverZ = 0; | ||
298 | 298 | ||
299 | //for (int i = 0; i < BAKE_INDICES.Length; i++) | 299 | //for (int i = 0; i < BAKE_INDICES.Length; i++) |
300 | // { | 300 | // { |
@@ -330,9 +330,6 @@ namespace OpenSim.Framework | |||
330 | protected virtual void SetDefaultTexture() | 330 | protected virtual void SetDefaultTexture() |
331 | { | 331 | { |
332 | m_texture = new Primitive.TextureEntry(new UUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE)); | 332 | m_texture = new Primitive.TextureEntry(new UUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE)); |
333 | |||
334 | // for (uint i = 0; i < TEXTURE_COUNT; i++) | ||
335 | // m_texture.CreateFace(i).TextureID = new UUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE); | ||
336 | } | 333 | } |
337 | 334 | ||
338 | /// <summary> | 335 | /// <summary> |
@@ -347,31 +344,31 @@ namespace OpenSim.Framework | |||
347 | if (textureEntry == null) | 344 | if (textureEntry == null) |
348 | return false; | 345 | return false; |
349 | 346 | ||
350 | // There are much simpler versions of this copy that could be | ||
351 | // made. We determine if any of the textures actually | ||
352 | // changed to know if the appearance should be saved later | ||
353 | bool changed = false; | 347 | bool changed = false; |
354 | for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++) | 348 | Primitive.TextureEntryFace newface; |
355 | { | 349 | Primitive.TextureEntryFace tmpFace; |
356 | Primitive.TextureEntryFace newface = textureEntry.FaceTextures[i]; | ||
357 | Primitive.TextureEntryFace oldface = m_texture.FaceTextures[i]; | ||
358 | 350 | ||
359 | if (newface == null) | 351 | //make sure textureEntry.DefaultTexture is the unused one(DEFAULT_AVATAR_TEXTURE). |
352 | Primitive.TextureEntry converted = new Primitive.TextureEntry(AppearanceManager.DEFAULT_AVATAR_TEXTURE); | ||
353 | for (uint i = 0; i < TEXTURE_COUNT; ++i) | ||
354 | { | ||
355 | newface = textureEntry.GetFace(i); | ||
356 | if (newface.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) | ||
360 | { | 357 | { |
361 | if (oldface == null) | 358 | tmpFace = converted.GetFace(i); |
362 | continue; | 359 | tmpFace.TextureID = newface.TextureID; // we need a full high level copy, assuming all other parameters are the same. |
360 | if (m_texture.FaceTextures[i] == null || newface.TextureID != m_texture.FaceTextures[i].TextureID) | ||
361 | changed = true; | ||
363 | } | 362 | } |
364 | else | 363 | else |
365 | { | 364 | { if (m_texture.FaceTextures[i] == null) |
366 | if (oldface != null && oldface.TextureID == newface.TextureID) | ||
367 | continue; | 365 | continue; |
366 | if(m_texture.FaceTextures[i].TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) | ||
367 | changed = true; | ||
368 | } | 368 | } |
369 | |||
370 | changed = true; | ||
371 | } | 369 | } |
372 | 370 | if(changed) | |
373 | m_texture = textureEntry; | 371 | m_texture = converted; |
374 | |||
375 | return changed; | 372 | return changed; |
376 | } | 373 | } |
377 | 374 | ||
@@ -736,42 +733,69 @@ namespace OpenSim.Framework | |||
736 | 733 | ||
737 | data["serial"] = OSD.FromInteger(m_serial); | 734 | data["serial"] = OSD.FromInteger(m_serial); |
738 | data["height"] = OSD.FromReal(m_avatarHeight); | 735 | data["height"] = OSD.FromReal(m_avatarHeight); |
736 | data["aphz"] = OSD.FromReal(AvatarPreferencesHoverZ); | ||
737 | |||
738 | if (m_texture == null) | ||
739 | return data; | ||
740 | |||
741 | bool sendPV8 = false; | ||
742 | if(ctx != null) | ||
743 | sendPV8 = ctx.OutboundVersion >= 0.8; | ||
739 | 744 | ||
740 | // Wearables | 745 | // Wearables |
741 | // | 746 | OSDArray wears; |
742 | // This will send as many or as few wearables as we have, unless a count | 747 | int count; |
743 | // is given. Used for legacy (pre 0.4) versions. | 748 | if (ctx == null) |
744 | int count = ctx.WearablesCount; | 749 | count = MAXWEARABLE_LEGACY; |
745 | if (ctx.WearablesCount == -1) | 750 | else |
746 | count = m_wearables.Length; | ||
747 | OSDArray wears = new OSDArray(count); | ||
748 | for (int i = 0; i < count; i++) | ||
749 | { | 751 | { |
750 | AvatarWearable dummyWearable = new AvatarWearable(); | 752 | int wbcount = ctx.WearablesCount; |
753 | if (wbcount == -1) | ||
754 | wbcount = m_wearables.Length; | ||
751 | 755 | ||
752 | if (i < m_wearables.Length) | 756 | count = wbcount; |
753 | wears.Add(m_wearables[i].Pack()); | 757 | if(count > MAXWEARABLE_PV7) |
754 | else | 758 | { |
755 | wears.Add(dummyWearable.Pack()); | 759 | count = MAXWEARABLE_PV7; |
760 | if(sendPV8) | ||
761 | { | ||
762 | wears = new OSDArray(wbcount - MAXWEARABLE_PV7); | ||
763 | for (int i = MAXWEARABLE_PV7; i < wbcount; ++i) | ||
764 | wears.Add(m_wearables[i].Pack()); | ||
765 | |||
766 | data["wrbls8"] = wears; | ||
767 | } | ||
768 | } | ||
756 | } | 769 | } |
770 | |||
771 | wears = new OSDArray(count); | ||
772 | for (int i = 0; i < count; i++) | ||
773 | wears.Add(m_wearables[i].Pack()); | ||
757 | data["wearables"] = wears; | 774 | data["wearables"] = wears; |
758 | 775 | ||
759 | // Avatar Textures | 776 | // Avatar Textures and preferences hover |
760 | OSDArray textures = new OSDArray(AvatarAppearance.TEXTURE_COUNT); | 777 | OSDArray textures; |
761 | for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++) | 778 | if (sendPV8) |
762 | { | 779 | { |
763 | if (m_texture.FaceTextures[i] != null) | 780 | byte[] te = m_texture.GetBakesBytes(); |
764 | textures.Add(OSD.FromUUID(m_texture.FaceTextures[i].TextureID)); | 781 | data["te8"] = OSD.FromBinary(te); |
765 | else | 782 | } |
766 | textures.Add(OSD.FromUUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE)); | 783 | else |
784 | { | ||
785 | textures = new OSDArray(TEXTURE_COUNT_PV7); | ||
786 | for (uint i = 0; i < TEXTURE_COUNT_PV7; i++) | ||
787 | textures.Add(OSD.FromUUID(m_texture.GetFace(i).TextureID)); | ||
788 | data["textures"] = textures; | ||
767 | } | 789 | } |
768 | data["textures"] = textures; | ||
769 | 790 | ||
770 | if (m_cacheitems != null) | 791 | if (m_cacheitems != null) |
771 | { | 792 | { |
772 | OSDArray baked = WearableCacheItem.BakedToOSD(m_cacheitems); | 793 | OSDArray baked = WearableCacheItem.BakedToOSD(m_cacheitems, 0, BAKES_COUNT_PV7); |
773 | if (baked != null) | 794 | if (baked != null && baked.Count > 0) |
774 | data["bakedcache"] = baked; | 795 | data["bakedcache"] = baked; |
796 | baked = WearableCacheItem.BakedToOSD(m_cacheitems, BAKES_COUNT_PV7, -1); | ||
797 | if (baked != null && baked.Count > 0) | ||
798 | data["bc8"] = baked; | ||
775 | } | 799 | } |
776 | 800 | ||
777 | // Visual Parameters | 801 | // Visual Parameters |
@@ -810,48 +834,88 @@ namespace OpenSim.Framework | |||
810 | OSD tmpOSD; | 834 | OSD tmpOSD; |
811 | if (data.TryGetValue("serial", out tmpOSD)) | 835 | if (data.TryGetValue("serial", out tmpOSD)) |
812 | m_serial = tmpOSD.AsInteger(); | 836 | m_serial = tmpOSD.AsInteger(); |
837 | if(data.TryGetValue("aphz", out tmpOSD)) | ||
838 | AvatarPreferencesHoverZ = (float)tmpOSD.AsReal(); | ||
813 | if (data.TryGetValue("height", out tmpOSD)) | 839 | if (data.TryGetValue("height", out tmpOSD)) |
814 | // m_avatarHeight = (float)data["height"].AsReal(); | 840 | SetSize(new Vector3(0.45f, 0.6f, (float)tmpOSD.AsReal())); |
815 | SetSize(new Vector3(0.45f,0.6f, (float)tmpOSD.AsReal())); | ||
816 | 841 | ||
817 | try | 842 | try |
818 | { | 843 | { |
819 | // Wearables | 844 | // Wearables |
845 | OSD tmpOSD8; | ||
846 | OSDArray wears8 = null; | ||
847 | int wears8Count = 0; | ||
848 | |||
849 | if (data.TryGetValue("wrbls8", out tmpOSD8) && (tmpOSD8 is OSDArray)) | ||
850 | { | ||
851 | wears8 = (OSDArray)tmpOSD; | ||
852 | wears8Count = wears8.Count; | ||
853 | } | ||
854 | |||
820 | if (data.TryGetValue("wearables", out tmpOSD) && (tmpOSD is OSDArray)) | 855 | if (data.TryGetValue("wearables", out tmpOSD) && (tmpOSD is OSDArray)) |
821 | { | 856 | { |
822 | OSDArray wears = (OSDArray)tmpOSD; | 857 | OSDArray wears = (OSDArray)tmpOSD; |
823 | m_wearables = new AvatarWearable[wears.Count]; | 858 | m_wearables = new AvatarWearable[wears.Count + wears8Count]; |
824 | 859 | ||
825 | for (int i = 0; i < wears.Count; i++) | 860 | for (int i = 0; i < wears.Count; ++i) |
826 | m_wearables[i] = new AvatarWearable((OSDArray)wears[i]); | 861 | m_wearables[i] = new AvatarWearable((OSDArray)wears[i]); |
862 | if (wears8Count > 0) | ||
863 | { | ||
864 | for (int i = wears.Count; i < wears8Count + wears.Count; ++i) | ||
865 | m_wearables[i] = new AvatarWearable((OSDArray)wears[i]); | ||
866 | } | ||
827 | } | 867 | } |
828 | else | 868 | else |
829 | { | 869 | { |
830 | m_log.Warn("[AVATAR APPEARANCE]: failed to unpack wearables"); | 870 | m_log.Warn("[AVATAR APPEARANCE]: failed to unpack wearables"); |
831 | } | 871 | } |
832 | 872 | ||
833 | // Avatar Textures | ||
834 | if (data.TryGetValue("textures", out tmpOSD) && (tmpOSD is OSDArray)) | 873 | if (data.TryGetValue("textures", out tmpOSD) && (tmpOSD is OSDArray)) |
835 | { | 874 | { |
836 | OSDArray textures = (OSDArray)tmpOSD; | 875 | OSDArray textures = (OSDArray)tmpOSD; |
837 | for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT && i < textures.Count; i++) | 876 | for (int i = 0; i < textures.Count && i < TEXTURE_COUNT_PV7; ++i) |
838 | { | 877 | { |
839 | UUID textureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE; | ||
840 | tmpOSD = textures[i]; | 878 | tmpOSD = textures[i]; |
841 | if (tmpOSD != null) | 879 | if (tmpOSD != null) |
842 | textureID = tmpOSD.AsUUID(); | 880 | m_texture.CreateFace((uint)i).TextureID = tmpOSD.AsUUID(); |
843 | m_texture.CreateFace((uint)i).TextureID = new UUID(textureID); | ||
844 | } | 881 | } |
845 | } | 882 | } |
846 | else | 883 | if (data.TryGetValue("te8", out tmpOSD)) |
847 | { | 884 | { |
848 | m_log.Warn("[AVATAR APPEARANCE]: failed to unpack textures"); | 885 | byte[] teb = tmpOSD.AsBinary(); |
886 | Primitive.TextureEntry te = new Primitive.TextureEntry(teb, 0, teb.Length); | ||
887 | m_texture = te; | ||
849 | } | 888 | } |
850 | 889 | ||
851 | if (data.TryGetValue("bakedcache", out tmpOSD) && (tmpOSD is OSDArray)) | 890 | if (data.TryGetValue("bakedcache", out tmpOSD) && (tmpOSD is OSDArray)) |
852 | { | 891 | { |
853 | OSDArray bakedOSDArray = (OSDArray)tmpOSD; | 892 | OSDArray bakedOSDArray = (OSDArray)tmpOSD; |
854 | m_cacheitems = WearableCacheItem.BakedFromOSD(bakedOSDArray); | 893 | m_cacheitems = WearableCacheItem.GetDefaultCacheItem(); |
894 | |||
895 | bakedOSDArray = (OSDArray)tmpOSD; | ||
896 | foreach (OSDMap item in bakedOSDArray) | ||
897 | { | ||
898 | int idx = item["textureindex"].AsInteger(); | ||
899 | if (idx < 0 || idx >= m_cacheitems.Length) | ||
900 | continue; | ||
901 | m_cacheitems[idx].CacheId = item["cacheid"].AsUUID(); | ||
902 | m_cacheitems[idx].TextureID = item["textureid"].AsUUID(); | ||
903 | m_cacheitems[idx].TextureAsset = null; | ||
904 | } | ||
905 | |||
906 | if (data.TryGetValue("bc8", out tmpOSD) && (tmpOSD is OSDArray)) | ||
907 | { | ||
908 | bakedOSDArray = (OSDArray)tmpOSD; | ||
909 | foreach (OSDMap item in bakedOSDArray) | ||
910 | { | ||
911 | int idx = item["textureindex"].AsInteger(); | ||
912 | if (idx < 0 || idx >= m_cacheitems.Length) | ||
913 | continue; | ||
914 | m_cacheitems[idx].CacheId = item["cacheid"].AsUUID(); | ||
915 | m_cacheitems[idx].TextureID = item["textureid"].AsUUID(); | ||
916 | m_cacheitems[idx].TextureAsset = null; | ||
917 | } | ||
918 | } | ||
855 | } | 919 | } |
856 | 920 | ||
857 | // Visual Parameters | 921 | // Visual Parameters |
@@ -888,6 +952,32 @@ namespace OpenSim.Framework | |||
888 | 952 | ||
889 | #endregion | 953 | #endregion |
890 | 954 | ||
955 | public bool CanTeleport(float version) | ||
956 | { | ||
957 | if (version >= 0.8) | ||
958 | return true; | ||
959 | if (m_wearables.Length <= MAXWEARABLE_PV7) | ||
960 | return true; | ||
961 | for(int i = MAXWEARABLE_PV7; i < m_wearables.Length; ++i) | ||
962 | { | ||
963 | if(m_wearables[i].Count > 0) | ||
964 | return false; | ||
965 | } | ||
966 | |||
967 | // also check baked | ||
968 | for(int i = BAKES_COUNT_PV7; i < BAKE_INDICES.Length; i++) | ||
969 | { | ||
970 | int idx = BAKE_INDICES[i]; | ||
971 | if (m_texture.FaceTextures[idx] == null) | ||
972 | continue; | ||
973 | UUID tid = m_texture.FaceTextures[idx].TextureID; | ||
974 | if(tid == AppearanceManager.DEFAULT_AVATAR_TEXTURE || tid == UUID.Zero) | ||
975 | continue; | ||
976 | return false; | ||
977 | } | ||
978 | return true; | ||
979 | } | ||
980 | |||
891 | #region VPElement | 981 | #region VPElement |
892 | 982 | ||
893 | /// <summary> | 983 | /// <summary> |
diff --git a/OpenSim/Framework/AvatarWearable.cs b/OpenSim/Framework/AvatarWearable.cs index abf5759..1733559 100644 --- a/OpenSim/Framework/AvatarWearable.cs +++ b/OpenSim/Framework/AvatarWearable.cs | |||
@@ -67,10 +67,14 @@ namespace OpenSim.Framework | |||
67 | 67 | ||
68 | public static readonly int ALPHA = 13; | 68 | public static readonly int ALPHA = 13; |
69 | public static readonly int TATTOO = 14; | 69 | public static readonly int TATTOO = 14; |
70 | |||
71 | public static readonly int LEGACY_VERSION_MAX_WEARABLES = 15; | 70 | public static readonly int LEGACY_VERSION_MAX_WEARABLES = 15; |
72 | // public static readonly int PHYSICS = 15; | 71 | |
73 | // public static int MAX_WEARABLES = 16; | 72 | public static readonly int PHYSICS = 15; |
73 | |||
74 | public static int MAX_WEARABLES_PV7 = 16; | ||
75 | |||
76 | public static readonly int UNIVERSAL = 16; | ||
77 | public static int MAX_WEARABLES = 17; | ||
74 | 78 | ||
75 | 79 | ||
76 | public static readonly UUID DEFAULT_BODY_ITEM = new UUID("66c41e39-38f9-f75a-024e-585989bfaba9"); | 80 | public static readonly UUID DEFAULT_BODY_ITEM = new UUID("66c41e39-38f9-f75a-024e-585989bfaba9"); |
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index da964e7..8fcd9a4 100755 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs | |||
@@ -1107,7 +1107,7 @@ namespace OpenSim.Framework | |||
1107 | /// <param name="agentID">The id of the agent associated with the appearance</param> | 1107 | /// <param name="agentID">The id of the agent associated with the appearance</param> |
1108 | /// <param name="visualParams"></param> | 1108 | /// <param name="visualParams"></param> |
1109 | /// <param name="textureEntry"></param> | 1109 | /// <param name="textureEntry"></param> |
1110 | void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry); | 1110 | void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry, float hoverheight); |
1111 | 1111 | ||
1112 | void SendCachedTextureResponse(ISceneEntity avatar, int serial, List<CachedTextureResponseArg> cachedTextures); | 1112 | void SendCachedTextureResponse(ISceneEntity avatar, int serial, List<CachedTextureResponseArg> cachedTextures); |
1113 | 1113 | ||
diff --git a/OpenSim/Framework/Tests/AgentCircuitDataTest.cs b/OpenSim/Framework/Tests/AgentCircuitDataTest.cs index 5ad0030..c8eb57d 100644 --- a/OpenSim/Framework/Tests/AgentCircuitDataTest.cs +++ b/OpenSim/Framework/Tests/AgentCircuitDataTest.cs | |||
@@ -220,12 +220,6 @@ namespace OpenSim.Framework.Tests | |||
220 | 220 | ||
221 | AvAppearance.VisualParams = VisualParams; | 221 | AvAppearance.VisualParams = VisualParams; |
222 | 222 | ||
223 | List<byte> wearbyte = new List<byte>(); | ||
224 | for (int i = 0; i < VisualParams.Length; i++) | ||
225 | { | ||
226 | wearbyte.Add(VisualParams[i]); | ||
227 | } | ||
228 | |||
229 | AvAppearance.SetAppearance(AvAppearance.Texture, (byte[])VisualParams.Clone()); | 223 | AvAppearance.SetAppearance(AvAppearance.Texture, (byte[])VisualParams.Clone()); |
230 | } | 224 | } |
231 | 225 | ||
diff --git a/OpenSim/Framework/VersionInfo.cs b/OpenSim/Framework/VersionInfo.cs index ac1f3a0..a1ba2aa 100644 --- a/OpenSim/Framework/VersionInfo.cs +++ b/OpenSim/Framework/VersionInfo.cs | |||
@@ -85,8 +85,8 @@ namespace OpenSim | |||
85 | /// - this is an older teleport protocol used in OpenSimulator 0.7.5 and before. | 85 | /// - this is an older teleport protocol used in OpenSimulator 0.7.5 and before. |
86 | /// </remarks> | 86 | /// </remarks> |
87 | public readonly static float SimulationServiceVersionAcceptedMin = 0.3f; | 87 | public readonly static float SimulationServiceVersionAcceptedMin = 0.3f; |
88 | public readonly static float SimulationServiceVersionAcceptedMax = 0.7f; | 88 | public readonly static float SimulationServiceVersionAcceptedMax = 0.8f; |
89 | public readonly static float SimulationServiceVersionSupportedMin = 0.3f; | 89 | public readonly static float SimulationServiceVersionSupportedMin = 0.3f; |
90 | public readonly static float SimulationServiceVersionSupportedMax = 0.7f; | 90 | public readonly static float SimulationServiceVersionSupportedMax = 0.8f; |
91 | } | 91 | } |
92 | } | 92 | } |
diff --git a/OpenSim/Framework/WearableCacheItem.cs b/OpenSim/Framework/WearableCacheItem.cs index e060f22..f832ff9 100644 --- a/OpenSim/Framework/WearableCacheItem.cs +++ b/OpenSim/Framework/WearableCacheItem.cs | |||
@@ -128,31 +128,27 @@ namespace OpenSim.Framework | |||
128 | return arr; | 128 | return arr; |
129 | } | 129 | } |
130 | 130 | ||
131 | public static OSDArray BakedToOSD(WearableCacheItem[] pcacheItems) | 131 | public static OSDArray BakedToOSD(WearableCacheItem[] pcacheItems, int start, int end) |
132 | { | 132 | { |
133 | if (pcacheItems.Length < AvatarAppearance.BAKE_INDICES[AvatarAppearance.BAKE_INDICES.Length - 1]) | ||
134 | return null; | ||
135 | |||
136 | OSDArray arr = new OSDArray(); | 133 | OSDArray arr = new OSDArray(); |
134 | if(start < 0) | ||
135 | start = 0; | ||
136 | if (end < 0 || end > AvatarAppearance.BAKE_INDICES.Length) | ||
137 | end = AvatarAppearance.BAKE_INDICES.Length; | ||
138 | if (start > end) | ||
139 | return null; | ||
137 | 140 | ||
138 | for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) | 141 | for (int i = start; i < end; i++) |
139 | { | 142 | { |
140 | int idx = AvatarAppearance.BAKE_INDICES[i]; | 143 | int idx = AvatarAppearance.BAKE_INDICES[i]; |
141 | 144 | if(idx >= pcacheItems.Length) | |
145 | continue; | ||
142 | WearableCacheItem item = pcacheItems[idx]; | 146 | WearableCacheItem item = pcacheItems[idx]; |
143 | 147 | ||
144 | OSDMap itemmap = new OSDMap(); | 148 | OSDMap itemmap = new OSDMap(); |
145 | itemmap.Add("textureindex", OSD.FromUInteger(item.TextureIndex)); | 149 | itemmap.Add("textureindex", OSD.FromUInteger(item.TextureIndex)); |
146 | itemmap.Add("cacheid", OSD.FromUUID(item.CacheId)); | 150 | itemmap.Add("cacheid", OSD.FromUUID(item.CacheId)); |
147 | itemmap.Add("textureid", OSD.FromUUID(item.TextureID)); | 151 | itemmap.Add("textureid", OSD.FromUUID(item.TextureID)); |
148 | /* | ||
149 | if (item.TextureAsset != null) | ||
150 | { | ||
151 | itemmap.Add("assetdata", OSD.FromBinary(item.TextureAsset.Data)); | ||
152 | itemmap.Add("assetcreator", OSD.FromString(item.TextureAsset.CreatorID)); | ||
153 | itemmap.Add("assetname", OSD.FromString(item.TextureAsset.Name)); | ||
154 | } | ||
155 | */ | ||
156 | arr.Add(itemmap); | 152 | arr.Add(itemmap); |
157 | } | 153 | } |
158 | return arr; | 154 | return arr; |
@@ -167,22 +163,11 @@ namespace OpenSim.Framework | |||
167 | foreach (OSDMap item in itemarray) | 163 | foreach (OSDMap item in itemarray) |
168 | { | 164 | { |
169 | int idx = item["textureindex"].AsInteger(); | 165 | int idx = item["textureindex"].AsInteger(); |
170 | if (idx < 0 || idx > pcache.Length) | 166 | if (idx < 0 || idx >= pcache.Length) |
171 | continue; | 167 | continue; |
172 | pcache[idx].CacheId = item["cacheid"].AsUUID(); | 168 | pcache[idx].CacheId = item["cacheid"].AsUUID(); |
173 | pcache[idx].TextureID = item["textureid"].AsUUID(); | 169 | pcache[idx].TextureID = item["textureid"].AsUUID(); |
174 | /* | 170 | pcache[idx].TextureAsset = null; |
175 | if (item.ContainsKey("assetdata")) | ||
176 | { | ||
177 | AssetBase asset = new AssetBase(item["textureid"].AsUUID(), "BakedTexture", (sbyte)AssetType.Texture, UUID.Zero.ToString()); | ||
178 | asset.Temporary = true; | ||
179 | asset.Local = true; | ||
180 | asset.Data = item["assetdata"].AsBinary(); | ||
181 | pcache[idx].TextureAsset = asset; | ||
182 | } | ||
183 | else | ||
184 | */ | ||
185 | pcache[idx].TextureAsset = null; | ||
186 | } | 171 | } |
187 | } | 172 | } |
188 | return pcache; | 173 | return pcache; |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index f8a5636..07d96f0 100755 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | |||
@@ -989,11 +989,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
989 | //RegionInfo4 block | 989 | //RegionInfo4 block |
990 | 990 | ||
991 | //RegionFlagsExtended | 991 | //RegionFlagsExtended |
992 | zc.AddZeros(1); // we dont have this | 992 | //zc.AddZeros(1); // if we dont have this else |
993 | //zc.AddByte(1); | 993 | zc.AddByte(1); |
994 | //zc.AddUInt64(regionFlags); // we have nothing other base flags | 994 | zc.AddUInt64(regionFlags); // we have nothing other base flags |
995 | //RegionProtocols | 995 | //RegionProtocols |
996 | //zc.AddUInt64(0); // bit 0 signals server side texture baking" | 996 | // bit 0 signals server side texture baking |
997 | // bit 63 signals more than 6 baked textures support" | ||
998 | zc.AddUInt64(1UL << 63); | ||
997 | 999 | ||
998 | buf.DataLength = zc.Finish(); | 1000 | buf.DataLength = zc.Finish(); |
999 | m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Unknown); | 1001 | m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Unknown); |
@@ -4434,7 +4436,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4434 | //0xff, 0xff, 0, 1, 158 // ID 158 (low frequency bigendian) zeroencoded | 4436 | //0xff, 0xff, 0, 1, 158 // ID 158 (low frequency bigendian) zeroencoded |
4435 | }; | 4437 | }; |
4436 | 4438 | ||
4437 | public void SendAppearance(UUID targetID, byte[] visualParams, byte[] textureEntry) | 4439 | public void SendAppearance(UUID targetID, byte[] visualParams, byte[] textureEntry, float hover) |
4438 | { | 4440 | { |
4439 | // doing post zero encode, because odds of beeing bad are not that low | 4441 | // doing post zero encode, because odds of beeing bad are not that low |
4440 | UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); | 4442 | UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); |
@@ -4469,7 +4471,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4469 | // no AppearanceData | 4471 | // no AppearanceData |
4470 | data[pos++] = 0; | 4472 | data[pos++] = 0; |
4471 | // no AppearanceHover | 4473 | // no AppearanceHover |
4472 | data[pos++] = 0; | 4474 | data[pos++] = 1; |
4475 | Utils.FloatToBytesSafepos(0, data, pos); pos += 4; | ||
4476 | Utils.FloatToBytesSafepos(0, data, pos); pos += 4; | ||
4477 | Utils.FloatToBytesSafepos(hover, data, pos); pos += 4; | ||
4473 | 4478 | ||
4474 | buf.DataLength = pos; | 4479 | buf.DataLength = pos; |
4475 | m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority, null, false, true); | 4480 | m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority, null, false, true); |
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 777d020..2013938 100755 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Collections.Concurrent; | ||
30 | using System.Reflection; | 31 | using System.Reflection; |
31 | using System.Threading; | 32 | using System.Threading; |
32 | using System.Text; | 33 | using System.Text; |
@@ -35,6 +36,7 @@ using log4net; | |||
35 | using Nini.Config; | 36 | using Nini.Config; |
36 | using OpenMetaverse; | 37 | using OpenMetaverse; |
37 | using OpenSim.Framework; | 38 | using OpenSim.Framework; |
39 | using OpenSim.Framework.Monitoring; | ||
38 | using OpenSim.Region.Framework.Interfaces; | 40 | using OpenSim.Region.Framework.Interfaces; |
39 | using OpenSim.Region.Framework.Scenes; | 41 | using OpenSim.Region.Framework.Scenes; |
40 | using OpenSim.Services.Interfaces; | 42 | using OpenSim.Services.Interfaces; |
@@ -59,8 +61,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
59 | 61 | ||
60 | private int m_checkTime = 500; // milliseconds to wait between checks for appearance updates | 62 | private int m_checkTime = 500; // milliseconds to wait between checks for appearance updates |
61 | private System.Timers.Timer m_updateTimer = new System.Timers.Timer(); | 63 | private System.Timers.Timer m_updateTimer = new System.Timers.Timer(); |
62 | private Dictionary<UUID,long> m_savequeue = new Dictionary<UUID,long>(); | 64 | private ConcurrentDictionary<UUID,long> m_savequeue = new ConcurrentDictionary<UUID,long>(); |
63 | private Dictionary<UUID,long> m_sendqueue = new Dictionary<UUID,long>(); | 65 | private ConcurrentDictionary<UUID,long> m_sendqueue = new ConcurrentDictionary<UUID,long>(); |
66 | private object m_updatesLock = new object(); | ||
67 | private int m_updatesbusy = 0; | ||
64 | 68 | ||
65 | private object m_setAppearanceLock = new object(); | 69 | private object m_setAppearanceLock = new object(); |
66 | 70 | ||
@@ -134,7 +138,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
134 | client.OnRequestWearables += Client_OnRequestWearables; | 138 | client.OnRequestWearables += Client_OnRequestWearables; |
135 | client.OnSetAppearance += Client_OnSetAppearance; | 139 | client.OnSetAppearance += Client_OnSetAppearance; |
136 | client.OnAvatarNowWearing += Client_OnAvatarNowWearing; | 140 | client.OnAvatarNowWearing += Client_OnAvatarNowWearing; |
137 | client.OnCachedTextureRequest += Client_OnCachedTextureRequest; | 141 | //client.OnCachedTextureRequest += Client_OnCachedTextureRequest; |
138 | } | 142 | } |
139 | 143 | ||
140 | #endregion | 144 | #endregion |
@@ -232,20 +236,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
232 | sp.SendAppearanceToAllOtherAgents(); | 236 | sp.SendAppearanceToAllOtherAgents(); |
233 | 237 | ||
234 | // Send animations back to the avatar as well | 238 | // Send animations back to the avatar as well |
235 | sp.Animator.SendAnimPack(); | 239 | if(sp.Animator != null) |
240 | sp.Animator.SendAnimPack(); | ||
236 | } | 241 | } |
237 | 242 | ||
238 | public bool SendAppearance(UUID agentId) | 243 | public bool SendAppearance(UUID agentId) |
239 | { | 244 | { |
240 | // m_log.DebugFormat("[AVFACTORY]: Sending appearance for {0}", agentId); | ||
241 | |||
242 | ScenePresence sp = m_scene.GetScenePresence(agentId); | 245 | ScenePresence sp = m_scene.GetScenePresence(agentId); |
243 | if (sp == null) | 246 | if (sp == null || sp.IsDeleted) |
244 | { | ||
245 | // This is expected if the user has gone away. | ||
246 | // m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId); | ||
247 | return false; | 247 | return false; |
248 | } | ||
249 | 248 | ||
250 | SendAppearance(sp); | 249 | SendAppearance(sp); |
251 | return true; | 250 | return true; |
@@ -338,11 +337,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
338 | 337 | ||
339 | // 10000 ticks per millisecond, 1000 milliseconds per second | 338 | // 10000 ticks per millisecond, 1000 milliseconds per second |
340 | long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 1000 * 10000); | 339 | long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 1000 * 10000); |
341 | lock (m_sendqueue) | 340 | m_sendqueue[agentid] = timestamp; |
342 | { | 341 | m_updateTimer.Start(); |
343 | m_sendqueue[agentid] = timestamp; | ||
344 | m_updateTimer.Start(); | ||
345 | } | ||
346 | } | 342 | } |
347 | 343 | ||
348 | public void QueueAppearanceSave(UUID agentid) | 344 | public void QueueAppearanceSave(UUID agentid) |
@@ -351,11 +347,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
351 | 347 | ||
352 | // 10000 ticks per millisecond, 1000 milliseconds per second | 348 | // 10000 ticks per millisecond, 1000 milliseconds per second |
353 | long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000); | 349 | long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000); |
354 | lock (m_savequeue) | 350 | m_savequeue[agentid] = timestamp; |
355 | { | 351 | m_updateTimer.Start(); |
356 | m_savequeue[agentid] = timestamp; | ||
357 | m_updateTimer.Start(); | ||
358 | } | ||
359 | } | 352 | } |
360 | 353 | ||
361 | // called on textures update | 354 | // called on textures update |
@@ -370,106 +363,90 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
370 | 363 | ||
371 | // uploaded baked textures will be in assets local cache | 364 | // uploaded baked textures will be in assets local cache |
372 | IAssetCache cache = m_scene.RequestModuleInterface<IAssetCache>(); | 365 | IAssetCache cache = m_scene.RequestModuleInterface<IAssetCache>(); |
373 | IBakedTextureModule m_BakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>(); | ||
374 | 366 | ||
375 | int validDirtyBakes = 0; | 367 | int validDirtyBakes = 0; |
376 | int hits = 0; | 368 | int hits = 0; |
377 | 369 | ||
378 | // our main cacheIDs mapper is p.Appearance.WearableCacheItems | 370 | // our main cacheIDs mapper is p.Appearance.WearableCacheItems |
379 | WearableCacheItem[] wearableCache = sp.Appearance.WearableCacheItems; | 371 | bool hadSkirt = false; |
380 | 372 | ||
373 | WearableCacheItem[] wearableCache = sp.Appearance.WearableCacheItems; | ||
381 | if (wearableCache == null) | 374 | if (wearableCache == null) |
382 | { | ||
383 | wearableCache = WearableCacheItem.GetDefaultCacheItem(); | 375 | wearableCache = WearableCacheItem.GetDefaultCacheItem(); |
376 | else | ||
377 | { | ||
378 | hadSkirt = (wearableCache[19].TextureID != UUID.Zero); | ||
384 | } | 379 | } |
385 | 380 | ||
381 | HashSet<uint> updatedFaces = new HashSet<uint>(); | ||
386 | List<UUID> missing = new List<UUID>(); | 382 | List<UUID> missing = new List<UUID>(); |
387 | 383 | ||
388 | bool haveSkirt = (wearableCache[19].TextureID != UUID.Zero); | ||
389 | bool haveNewSkirt = false; | ||
390 | |||
391 | // Process received baked textures | 384 | // Process received baked textures |
392 | for (int i = 0; i < cacheItems.Length; i++) | 385 | for (int i = 0; i < cacheItems.Length; i++) |
393 | { | 386 | { |
394 | int idx = (int)cacheItems[i].TextureIndex; | 387 | uint idx = cacheItems[i].TextureIndex; |
388 | if(idx >= AvatarAppearance.TEXTURE_COUNT) | ||
389 | { | ||
390 | hits++; | ||
391 | continue; | ||
392 | } | ||
393 | |||
394 | updatedFaces.Add(idx); | ||
395 | |||
396 | wearableCache[idx].TextureAsset = null; // just in case | ||
395 | Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; | 397 | Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; |
396 | 398 | ||
397 | // No face | 399 | if (face == null || face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE) |
398 | if (face == null) | ||
399 | { | 400 | { |
400 | // for some reason viewer is cleaning this | ||
401 | if(idx != 19) // skirt is optional | ||
402 | { | ||
403 | sp.Appearance.Texture.FaceTextures[idx] = sp.Appearance.Texture.CreateFace((uint) idx); | ||
404 | sp.Appearance.Texture.FaceTextures[idx].TextureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE; | ||
405 | } | ||
406 | wearableCache[idx].CacheId = UUID.Zero; | 401 | wearableCache[idx].CacheId = UUID.Zero; |
407 | wearableCache[idx].TextureID = UUID.Zero; | 402 | wearableCache[idx].TextureID = UUID.Zero; |
408 | wearableCache[idx].TextureAsset = null; | 403 | if (idx == 19) |
409 | continue; | ||
410 | } | ||
411 | else | ||
412 | { | ||
413 | if (face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE) | ||
414 | { | ||
415 | wearableCache[idx].CacheId = UUID.Zero; | ||
416 | wearableCache[idx].TextureID = UUID.Zero; | ||
417 | wearableCache[idx].TextureAsset = null; | ||
418 | continue; | ||
419 | } | ||
420 | |||
421 | if(idx == 19) | ||
422 | haveNewSkirt = true; | ||
423 | /* | ||
424 | if (face.TextureID == wearableCache[idx].TextureID && m_BakedTextureModule != null) | ||
425 | { | 404 | { |
426 | if (wearableCache[idx].CacheId != cacheItems[i].CacheId) | ||
427 | { | ||
428 | wearableCache[idx].CacheId = cacheItems[i].CacheId; | ||
429 | validDirtyBakes++; | ||
430 | |||
431 | //assuming this can only happen if asset is in cache | ||
432 | } | ||
433 | hits++; | 405 | hits++; |
434 | continue; | 406 | if(hadSkirt) |
435 | } | 407 | validDirtyBakes++; |
436 | */ | ||
437 | wearableCache[idx].TextureAsset = null; | ||
438 | if (cache != null) | ||
439 | { | ||
440 | AssetBase asb = null; | ||
441 | cache.Get(face.TextureID.ToString(), out asb); | ||
442 | wearableCache[idx].TextureAsset = asb; | ||
443 | } | 408 | } |
409 | continue; | ||
410 | } | ||
444 | 411 | ||
445 | if (wearableCache[idx].TextureAsset != null) | 412 | if (cache != null) |
446 | { | 413 | { |
447 | if ( wearableCache[idx].TextureID != face.TextureID || | 414 | AssetBase asb = null; |
448 | wearableCache[idx].CacheId != cacheItems[i].CacheId) | 415 | cache.Get(face.TextureID.ToString(), out asb); |
449 | validDirtyBakes++; | 416 | wearableCache[idx].TextureAsset = asb; |
417 | } | ||
450 | 418 | ||
451 | wearableCache[idx].TextureID = face.TextureID; | 419 | if (wearableCache[idx].TextureAsset != null) |
452 | wearableCache[idx].CacheId = cacheItems[i].CacheId; | 420 | { |
453 | hits++; | 421 | if ( wearableCache[idx].TextureID != face.TextureID || |
454 | } | 422 | wearableCache[idx].CacheId != cacheItems[i].CacheId) |
455 | else | 423 | validDirtyBakes++; |
456 | { | 424 | |
457 | wearableCache[idx].CacheId = UUID.Zero; | 425 | wearableCache[idx].TextureID = face.TextureID; |
458 | wearableCache[idx].TextureID = UUID.Zero; | 426 | wearableCache[idx].CacheId = cacheItems[i].CacheId; |
459 | wearableCache[idx].TextureAsset = null; | 427 | hits++; |
460 | missing.Add(face.TextureID); | 428 | } |
461 | continue; | 429 | else |
462 | } | 430 | { |
431 | wearableCache[idx].CacheId = UUID.Zero; | ||
432 | wearableCache[idx].TextureID = UUID.Zero; | ||
433 | missing.Add(face.TextureID); | ||
434 | continue; | ||
463 | } | 435 | } |
464 | } | 436 | } |
465 | 437 | ||
466 | // handle optional skirt case | 438 | // this may be a current fs bug |
467 | if(!haveNewSkirt && haveSkirt) | 439 | for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) |
468 | { | 440 | { |
469 | wearableCache[19].CacheId = UUID.Zero; | 441 | uint idx = AvatarAppearance.BAKE_INDICES[i]; |
470 | wearableCache[19].TextureID = UUID.Zero; | 442 | if(updatedFaces.Contains(idx)) |
471 | wearableCache[19].TextureAsset = null; | 443 | continue; |
472 | validDirtyBakes++; | 444 | |
445 | sp.Appearance.Texture.FaceTextures[idx] = null; | ||
446 | |||
447 | wearableCache[idx].CacheId = UUID.Zero; | ||
448 | wearableCache[idx].TextureID = UUID.Zero; | ||
449 | wearableCache[idx].TextureAsset = null; | ||
473 | } | 450 | } |
474 | 451 | ||
475 | sp.Appearance.WearableCacheItems = wearableCache; | 452 | sp.Appearance.WearableCacheItems = wearableCache; |
@@ -480,15 +457,18 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
480 | sp.ControllingClient.SendRebakeAvatarTextures(id); | 457 | sp.ControllingClient.SendRebakeAvatarTextures(id); |
481 | } | 458 | } |
482 | 459 | ||
460 | bool changed = false; | ||
483 | if (validDirtyBakes > 0 && hits == cacheItems.Length) | 461 | if (validDirtyBakes > 0 && hits == cacheItems.Length) |
484 | { | 462 | { |
485 | // if we got a full set of baked textures save all in BakedTextureModule | 463 | // if we got a full set of baked textures save all in BakedTextureModule |
464 | IBakedTextureModule m_BakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>(); | ||
486 | if (m_BakedTextureModule != null) | 465 | if (m_BakedTextureModule != null) |
487 | { | 466 | { |
488 | m_log.DebugFormat("[UpdateBakedCache] Uploading to Bakes Server: cache hits: {0} changed entries: {1} rebakes {2}", | 467 | m_log.DebugFormat("[UpdateBakedCache] Uploading to Bakes Server: cache hits: {0} changed entries: {1} rebakes {2}", |
489 | hits.ToString(), validDirtyBakes.ToString(), missing.Count); | 468 | hits.ToString(), validDirtyBakes.ToString(), missing.Count); |
490 | 469 | ||
491 | m_BakedTextureModule.Store(sp.UUID, wearableCache); | 470 | m_BakedTextureModule.Store(sp.UUID, wearableCache); |
471 | changed = true; | ||
492 | } | 472 | } |
493 | } | 473 | } |
494 | else | 474 | else |
@@ -505,26 +485,25 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
505 | // sp.Appearance.WearableCacheItems[j].TextureID); | 485 | // sp.Appearance.WearableCacheItems[j].TextureID); |
506 | } | 486 | } |
507 | 487 | ||
508 | return (hits == cacheItems.Length); | 488 | return changed; |
509 | } | 489 | } |
510 | 490 | ||
511 | // called when we get a new root avatar | 491 | // called when we get a new root avatar |
512 | public bool ValidateBakedTextureCache(IScenePresence sp) | 492 | public bool ValidateBakedTextureCache(IScenePresence sp) |
513 | { | 493 | { |
514 | int hits = 0; | ||
515 | |||
516 | if (((ScenePresence)sp).IsNPC) | 494 | if (((ScenePresence)sp).IsNPC) |
517 | return true; | 495 | return true; |
518 | 496 | ||
519 | lock (m_setAppearanceLock) | 497 | int hits = 0; |
520 | { | ||
521 | IAssetCache cache = m_scene.RequestModuleInterface<IAssetCache>(); | ||
522 | IBakedTextureModule bakedModule = m_scene.RequestModuleInterface<IBakedTextureModule>(); | ||
523 | WearableCacheItem[] bakedModuleCache = null; | ||
524 | 498 | ||
525 | if (cache == null) | 499 | IAssetCache cache = m_scene.RequestModuleInterface<IAssetCache>(); |
526 | return false; | 500 | if (cache == null) |
501 | return false; | ||
527 | 502 | ||
503 | IBakedTextureModule bakedModule = m_scene.RequestModuleInterface<IBakedTextureModule>(); | ||
504 | |||
505 | lock (m_setAppearanceLock) | ||
506 | { | ||
528 | WearableCacheItem[] wearableCache = sp.Appearance.WearableCacheItems; | 507 | WearableCacheItem[] wearableCache = sp.Appearance.WearableCacheItems; |
529 | 508 | ||
530 | // big debug | 509 | // big debug |
@@ -566,70 +545,47 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
566 | } | 545 | } |
567 | else | 546 | else |
568 | { | 547 | { |
569 | // we may have received a full cache | ||
570 | // check same coerence and store | ||
571 | wearableCacheValid = true; | 548 | wearableCacheValid = true; |
549 | Primitive.TextureEntryFace face; | ||
572 | for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) | 550 | for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) |
573 | { | 551 | { |
574 | int idx = AvatarAppearance.BAKE_INDICES[i]; | 552 | int idx = AvatarAppearance.BAKE_INDICES[i]; |
575 | Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; | 553 | face = sp.Appearance.Texture.FaceTextures[idx]; |
576 | if (face != null) | 554 | |
555 | if(face == null || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE) | ||
577 | { | 556 | { |
578 | if (face.TextureID == wearableCache[idx].TextureID && | 557 | wearableCache[idx].CacheId = UUID.Zero; |
579 | face.TextureID != UUID.Zero) | 558 | wearableCache[idx].TextureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE; |
559 | hits++; | ||
560 | continue; | ||
561 | } | ||
562 | |||
563 | if (face.TextureID == wearableCache[idx].TextureID && | ||
564 | face.TextureID != UUID.Zero) | ||
565 | { | ||
566 | if (cache.Check((wearableCache[idx].TextureID).ToString())) | ||
580 | { | 567 | { |
581 | if (wearableCache[idx].TextureAsset != null) | 568 | hits++; |
582 | { | 569 | continue; |
583 | hits++; | ||
584 | wearableCache[idx].TextureAsset.Temporary = true; | ||
585 | wearableCache[idx].TextureAsset.Local = true; | ||
586 | cache.Cache(wearableCache[idx].TextureAsset); | ||
587 | wearableCache[idx].TextureAsset = null; | ||
588 | continue; | ||
589 | } | ||
590 | |||
591 | if (cache.Check((wearableCache[idx].TextureID).ToString())) | ||
592 | { | ||
593 | hits++; | ||
594 | continue; | ||
595 | } | ||
596 | } | 570 | } |
597 | wearableCacheValid = false; | ||
598 | } | 571 | } |
572 | wearableCache[idx].CacheId = UUID.Zero; | ||
573 | wearableCache[idx].TextureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE; | ||
574 | wearableCacheValid = false; | ||
599 | } | 575 | } |
600 | |||
601 | wearableCacheValid = (wearableCacheValid && (hits >= AvatarAppearance.BAKE_INDICES.Length - 1)); | ||
602 | if (wearableCacheValid) | ||
603 | { | ||
604 | // m_log.Debug("[ValidateBakedCache] have valid local cache"); | ||
605 | } | ||
606 | else | ||
607 | wearableCache[19].TextureAsset = null; // clear optional skirt | ||
608 | } | 576 | } |
609 | 577 | ||
610 | bool checkExternal = false; | 578 | bool checkExternal = false; |
611 | |||
612 | if (!wearableCacheValid) | 579 | if (!wearableCacheValid) |
613 | { | 580 | checkExternal = bakedModule != null; |
614 | hits = 0; | ||
615 | // only use external bake module on login condition check | ||
616 | // ScenePresence ssp = null; | ||
617 | // if (sp is ScenePresence) | ||
618 | { | ||
619 | // ssp = (ScenePresence)sp; | ||
620 | // checkExternal = (((uint)ssp.TeleportFlags & (uint)TeleportFlags.ViaLogin) != 0) && | ||
621 | // bakedModule != null; | ||
622 | |||
623 | // or do it anytime we dont have the cache | ||
624 | checkExternal = bakedModule != null; | ||
625 | } | ||
626 | } | ||
627 | 581 | ||
628 | if (checkExternal) | 582 | if (checkExternal) |
629 | { | 583 | { |
584 | WearableCacheItem[] bakedModuleCache = null; | ||
630 | bool gotbacked = false; | 585 | bool gotbacked = false; |
586 | hits = 0; | ||
631 | 587 | ||
632 | // m_log.Debug("[ValidateBakedCache] local cache invalid, checking bakedModule"); | 588 | // m_log.Debug("[ValidateBakedCache] local cache invalid, checking bakedModule"); |
633 | try | 589 | try |
634 | { | 590 | { |
635 | bakedModuleCache = bakedModule.Get(sp.UUID); | 591 | bakedModuleCache = bakedModule.Get(sp.UUID); |
@@ -647,8 +603,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
647 | for (int i = 0; i < bakedModuleCache.Length; i++) | 603 | for (int i = 0; i < bakedModuleCache.Length; i++) |
648 | { | 604 | { |
649 | int j = (int)bakedModuleCache[i].TextureIndex; | 605 | int j = (int)bakedModuleCache[i].TextureIndex; |
650 | 606 | if (j < AvatarAppearance.TEXTURE_COUNT && bakedModuleCache[i].TextureAsset != null) | |
651 | if (bakedModuleCache[i].TextureAsset != null) | ||
652 | { | 607 | { |
653 | wearableCache[j].TextureID = bakedModuleCache[i].TextureID; | 608 | wearableCache[j].TextureID = bakedModuleCache[i].TextureID; |
654 | wearableCache[j].CacheId = bakedModuleCache[i].CacheId; | 609 | wearableCache[j].CacheId = bakedModuleCache[i].CacheId; |
@@ -658,33 +613,27 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
658 | cache.Cache(bakedModuleCache[i].TextureAsset); | 613 | cache.Cache(bakedModuleCache[i].TextureAsset); |
659 | } | 614 | } |
660 | } | 615 | } |
661 | gotbacked = true; | ||
662 | } | ||
663 | 616 | ||
664 | if (gotbacked) | ||
665 | { | ||
666 | // force the ones we got | 617 | // force the ones we got |
667 | for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) | 618 | for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) |
668 | { | 619 | { |
669 | int idx = AvatarAppearance.BAKE_INDICES[i]; | 620 | int idx = AvatarAppearance.BAKE_INDICES[i]; |
670 | if(wearableCache[idx].TextureAsset == null) | 621 | if (wearableCache[idx].TextureAsset == null) |
671 | { | 622 | { |
672 | if(idx == 19) | 623 | if(idx == 19) |
673 | { | 624 | { |
674 | sp.Appearance.Texture.FaceTextures[idx] = null; | 625 | sp.Appearance.Texture.FaceTextures[idx] = null; |
675 | hits++; | 626 | hits++; |
676 | } | 627 | } |
628 | else if(sp.Appearance.Texture.FaceTextures[idx] == null || | ||
629 | sp.Appearance.Texture.FaceTextures[idx].TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE) | ||
630 | hits++; | ||
631 | wearableCache[idx].TextureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE; | ||
632 | wearableCache[idx].CacheId = UUID.Zero; | ||
677 | continue; | 633 | continue; |
678 | } | 634 | } |
679 | 635 | ||
680 | Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; | 636 | Primitive.TextureEntryFace face = sp.Appearance.Texture.GetFace((uint)idx); |
681 | |||
682 | if (face == null) | ||
683 | { | ||
684 | face = sp.Appearance.Texture.CreateFace((uint)idx); | ||
685 | sp.Appearance.Texture.FaceTextures[idx] = face; | ||
686 | } | ||
687 | |||
688 | face.TextureID = wearableCache[idx].TextureID; | 637 | face.TextureID = wearableCache[idx].TextureID; |
689 | hits++; | 638 | hits++; |
690 | wearableCache[idx].TextureAsset = null; | 639 | wearableCache[idx].TextureAsset = null; |
@@ -708,7 +657,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
708 | sp.Appearance.WearableCacheItems[j].TextureID); | 657 | sp.Appearance.WearableCacheItems[j].TextureID); |
709 | } | 658 | } |
710 | */ | 659 | */ |
711 | return (hits >= AvatarAppearance.BAKE_INDICES.Length - 1); // skirt is optional | 660 | return (hits >= AvatarAppearance.BAKE_INDICES.Length); // skirt is optional |
712 | } | 661 | } |
713 | 662 | ||
714 | public int RequestRebake(IScenePresence sp, bool missingTexturesOnly) | 663 | public int RequestRebake(IScenePresence sp, bool missingTexturesOnly) |
@@ -776,13 +725,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
776 | foreach (int i in Enum.GetValues(typeof(BakeType))) | 725 | foreach (int i in Enum.GetValues(typeof(BakeType))) |
777 | { | 726 | { |
778 | BakeType bakeType = (BakeType)i; | 727 | BakeType bakeType = (BakeType)i; |
728 | if (bakeType == BakeType.NumberOfEntries) | ||
729 | break; | ||
779 | 730 | ||
780 | if (bakeType == BakeType.Unknown) | 731 | if (bakeType == BakeType.Unknown) |
781 | continue; | 732 | continue; |
782 | 733 | ||
783 | // m_log.DebugFormat( | 734 | // m_log.DebugFormat( |
784 | // "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}", | 735 | // "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}", |
785 | // acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]); | 736 | // acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]); |
786 | 737 | ||
787 | int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType); | 738 | int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType); |
788 | Primitive.TextureEntryFace texture = faceTextures[ftIndex]; // this will be null if there's no such baked texture | 739 | Primitive.TextureEntryFace texture = faceTextures[ftIndex]; // this will be null if there's no such baked texture |
@@ -794,90 +745,78 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
794 | 745 | ||
795 | private void HandleAppearanceUpdateTimer(object sender, EventArgs ea) | 746 | private void HandleAppearanceUpdateTimer(object sender, EventArgs ea) |
796 | { | 747 | { |
797 | long now = DateTime.Now.Ticks; | 748 | if(Monitor.TryEnter(m_updatesLock)) |
798 | |||
799 | lock (m_sendqueue) | ||
800 | { | 749 | { |
801 | Dictionary<UUID, long> sends = new Dictionary<UUID, long>(m_sendqueue); | 750 | UUID id; |
802 | foreach (KeyValuePair<UUID, long> kvp in sends) | 751 | long now = DateTime.Now.Ticks; |
752 | |||
753 | foreach (KeyValuePair<UUID, long> kvp in m_sendqueue) | ||
803 | { | 754 | { |
804 | // We have to load the key and value into local parameters to avoid a race condition if we loop | ||
805 | // around and load kvp with a different value before FireAndForget has launched its thread. | ||
806 | UUID avatarID = kvp.Key; | ||
807 | long sendTime = kvp.Value; | 755 | long sendTime = kvp.Value; |
756 | if (sendTime > now) | ||
757 | continue; | ||
808 | 758 | ||
809 | // m_log.DebugFormat("[AVFACTORY]: Handling queued appearance updates for {0}, update delta to now is {1}", avatarID, sendTime - now); | 759 | id = kvp.Key; |
810 | 760 | m_sendqueue.TryRemove(id, out sendTime); | |
811 | if (sendTime < now) | 761 | SendAppearance(id); |
812 | { | ||
813 | Util.FireAndForget(o => SendAppearance(avatarID), null, "AvatarFactoryModule.SendAppearance"); | ||
814 | m_sendqueue.Remove(avatarID); | ||
815 | } | ||
816 | } | 762 | } |
817 | } | ||
818 | 763 | ||
819 | lock (m_savequeue) | 764 | if(m_updatesbusy == 0) |
820 | { | ||
821 | Dictionary<UUID, long> saves = new Dictionary<UUID, long>(m_savequeue); | ||
822 | foreach (KeyValuePair<UUID, long> kvp in saves) | ||
823 | { | 765 | { |
824 | // We have to load the key and value into local parameters to avoid a race condition if we loop | 766 | m_updatesbusy = -1; |
825 | // around and load kvp with a different value before FireAndForget has launched its thread. | 767 | List<UUID> saves = new List<UUID>(m_savequeue.Count); |
826 | UUID avatarID = kvp.Key; | 768 | foreach (KeyValuePair<UUID, long> kvp in m_savequeue) |
827 | long sendTime = kvp.Value; | 769 | { |
770 | long sendTime = kvp.Value; | ||
771 | if (sendTime > now) | ||
772 | continue; | ||
773 | |||
774 | id = kvp.Key; | ||
775 | m_savequeue.TryRemove(id, out sendTime); | ||
776 | saves.Add(id); | ||
777 | } | ||
828 | 778 | ||
829 | if (sendTime < now) | 779 | m_updatesbusy = 0; |
780 | if (saves.Count > 0) | ||
830 | { | 781 | { |
831 | Util.FireAndForget(o => SaveAppearance(avatarID), null, "AvatarFactoryModule.SaveAppearance"); | 782 | ++m_updatesbusy; |
832 | m_savequeue.Remove(avatarID); | 783 | WorkManager.RunInThreadPool( |
784 | delegate | ||
785 | { | ||
786 | SaveAppearance(saves); | ||
787 | saves = null; | ||
788 | --m_updatesbusy; | ||
789 | }, null, string.Format("SaveAppearance ({0})", m_scene.Name)); | ||
833 | } | 790 | } |
834 | } | 791 | } |
835 | 792 | ||
836 | // We must lock both queues here so that QueueAppearanceSave() or *Send() don't m_updateTimer.Start() on | 793 | if (m_savequeue.Count == 0 && m_sendqueue.Count == 0) |
837 | // another thread inbetween the first count calls and m_updateTimer.Stop() on this thread. | 794 | m_updateTimer.Stop(); |
838 | lock (m_sendqueue) | 795 | |
839 | if (m_savequeue.Count == 0 && m_sendqueue.Count == 0) | 796 | Monitor.Exit(m_updatesLock); |
840 | m_updateTimer.Stop(); | ||
841 | } | 797 | } |
842 | } | 798 | } |
843 | 799 | ||
844 | private void SaveAppearance(UUID agentid) | 800 | private void SaveAppearance(List<UUID> ids) |
845 | { | 801 | { |
846 | // We must set appearance parameters in the en_US culture in order to avoid issues where values are saved | ||
847 | // in a culture where decimal points are commas and then reloaded in a culture which just treats them as | ||
848 | // number seperators. | ||
849 | Culture.SetCurrentCulture(); | ||
850 | |||
851 | ScenePresence sp = m_scene.GetScenePresence(agentid); | ||
852 | if (sp == null) | ||
853 | { | ||
854 | // This is expected if the user has gone away. | ||
855 | // m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid); | ||
856 | return; | ||
857 | } | ||
858 | |||
859 | // m_log.DebugFormat("[AVFACTORY]: Saving appearance for avatar {0}", agentid); | 802 | // m_log.DebugFormat("[AVFACTORY]: Saving appearance for avatar {0}", agentid); |
860 | 803 | ||
861 | // This could take awhile since it needs to pull inventory | 804 | foreach(UUID id in ids) |
862 | // 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 | 805 | { |
863 | // assets and item asset id changes to complete. | 806 | ScenePresence sp = m_scene.GetScenePresence(id); |
864 | // I don't think we need to worry about doing this within m_setAppearanceLock since the queueing avoids | 807 | if(sp == null) |
865 | // multiple save requests. | 808 | continue; |
866 | SetAppearanceAssets(sp.UUID, sp.Appearance); | 809 | // This could take awhile since it needs to pull inventory |
867 | 810 | // 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 | |
868 | // List<AvatarAttachment> attachments = sp.Appearance.GetAttachments(); | 811 | // assets and item asset id changes to complete. |
869 | // foreach (AvatarAttachment att in attachments) | 812 | // I don't think we need to worry about doing this within m_setAppearanceLock since the queueing avoids |
870 | // { | 813 | // multiple save requests. |
871 | // m_log.DebugFormat( | ||
872 | // "[AVFACTORY]: For {0} saving attachment {1} at point {2}", | ||
873 | // sp.Name, att.ItemID, att.AttachPoint); | ||
874 | // } | ||
875 | 814 | ||
876 | m_scene.AvatarService.SetAppearance(agentid, sp.Appearance); | 815 | SetAppearanceAssets(id, sp.Appearance); |
877 | 816 | ||
878 | // Trigger this here because it's the final step in the set/queue/save process for appearance setting. | 817 | m_scene.AvatarService.SetAppearance(id, sp.Appearance); |
879 | // Everything has been updated and stored. Ensures bakes have been persisted (if option is set to persist bakes). | 818 | //m_scene.EventManager.TriggerAvatarAppearanceChanged(sp); |
880 | m_scene.EventManager.TriggerAvatarAppearanceChanged(sp); | 819 | } |
881 | } | 820 | } |
882 | 821 | ||
883 | /// <summary> | 822 | /// <summary> |
@@ -1231,7 +1170,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
1231 | // m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId); | 1170 | // m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId); |
1232 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); | 1171 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); |
1233 | if (sp != null) | 1172 | if (sp != null) |
1234 | SetAppearance(sp, textureEntry, visualParams,avSize, cacheItems); | 1173 | SetAppearance(sp, textureEntry, visualParams, avSize, cacheItems); |
1235 | else | 1174 | else |
1236 | m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId); | 1175 | m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId); |
1237 | } | 1176 | } |
@@ -1251,9 +1190,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
1251 | return; | 1190 | return; |
1252 | } | 1191 | } |
1253 | 1192 | ||
1254 | // we need to clean out the existing textures | ||
1255 | sp.Appearance.ResetAppearance(); | ||
1256 | |||
1257 | // operate on a copy of the appearance so we don't have to lock anything yet | 1193 | // operate on a copy of the appearance so we don't have to lock anything yet |
1258 | AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false); | 1194 | AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false); |
1259 | 1195 | ||
@@ -1280,15 +1216,13 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
1280 | // often sends AvatarIsWearing and SetAppearance packets at once, and AvatarIsWearing | 1216 | // often sends AvatarIsWearing and SetAppearance packets at once, and AvatarIsWearing |
1281 | // shouldn't overwrite the changes made in SetAppearance. | 1217 | // shouldn't overwrite the changes made in SetAppearance. |
1282 | sp.Appearance.Wearables = avatAppearance.Wearables; | 1218 | sp.Appearance.Wearables = avatAppearance.Wearables; |
1283 | sp.Appearance.Texture = avatAppearance.Texture; | ||
1284 | |||
1285 | // We don't need to send the appearance here since the "iswearing" will trigger a new set | 1219 | // We don't need to send the appearance here since the "iswearing" will trigger a new set |
1286 | // of visual param and baked texture changes. When those complete, the new appearance will be sent | 1220 | // of visual param and baked texture changes. When those complete, the new appearance will be sent |
1287 | |||
1288 | QueueAppearanceSave(client.AgentId); | 1221 | QueueAppearanceSave(client.AgentId); |
1289 | } | 1222 | } |
1290 | } | 1223 | } |
1291 | 1224 | ||
1225 | /* | ||
1292 | /// <summary> | 1226 | /// <summary> |
1293 | /// Respond to the cached textures request from the client | 1227 | /// Respond to the cached textures request from the client |
1294 | /// </summary> | 1228 | /// </summary> |
@@ -1308,23 +1242,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
1308 | 1242 | ||
1309 | if (m_reusetextures) | 1243 | if (m_reusetextures) |
1310 | { | 1244 | { |
1311 | // this is the most insanely dumb way to do this... however it seems to | ||
1312 | // actually work. if the appearance has been reset because wearables have | ||
1313 | // changed then the texture entries are zero'd out until the bakes are | ||
1314 | // uploaded. on login, if the textures exist in the cache (eg if you logged | ||
1315 | // into the simulator recently, then the appearance will pull those and send | ||
1316 | // them back in the packet and you won't have to rebake. if the textures aren't | ||
1317 | // in the cache then the intial makeroot() call in scenepresence will zero | ||
1318 | // them out. | ||
1319 | // | ||
1320 | // a better solution (though how much better is an open question) is to | ||
1321 | // store the hashes in the appearance and compare them. Thats's coming. | ||
1322 | |||
1323 | Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[index]; | 1245 | Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[index]; |
1324 | if (face != null) | 1246 | if (face != null) |
1325 | texture = face.TextureID; | 1247 | texture = face.TextureID; |
1326 | |||
1327 | // m_log.WarnFormat("[AVFACTORY]: reuse texture {0} for index {1}",texture,index); | ||
1328 | } | 1248 | } |
1329 | 1249 | ||
1330 | CachedTextureResponseArg response = new CachedTextureResponseArg(); | 1250 | CachedTextureResponseArg response = new CachedTextureResponseArg(); |
@@ -1334,21 +1254,16 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
1334 | 1254 | ||
1335 | cachedTextureResponse.Add(response); | 1255 | cachedTextureResponse.Add(response); |
1336 | } | 1256 | } |
1337 | |||
1338 | // m_log.WarnFormat("[AVFACTORY]: serial is {0}",serial); | ||
1339 | // The serial number appears to be used to match requests and responses | ||
1340 | // in the texture transaction. We just send back the serial number | ||
1341 | // that was provided in the request. The viewer bumps this for us. | ||
1342 | client.SendCachedTextureResponse(sp, serial, cachedTextureResponse); | 1257 | client.SendCachedTextureResponse(sp, serial, cachedTextureResponse); |
1343 | } | 1258 | } |
1344 | 1259 | */ | |
1345 | 1260 | ||
1346 | #endregion | 1261 | #endregion |
1347 | 1262 | ||
1348 | public void WriteBakedTexturesReport(IScenePresence sp, ReportOutputAction outputAction) | 1263 | public void WriteBakedTexturesReport(IScenePresence sp, ReportOutputAction outputAction) |
1349 | { | 1264 | { |
1350 | outputAction("For {0} in {1}", sp.Name, m_scene.RegionInfo.RegionName); | 1265 | outputAction("For {0} in {1}", null, sp.Name, m_scene.RegionInfo.RegionName); |
1351 | outputAction(BAKED_TEXTURES_REPORT_FORMAT, "Bake Type", "UUID"); | 1266 | outputAction(BAKED_TEXTURES_REPORT_FORMAT, null, "Bake Type", "UUID"); |
1352 | 1267 | ||
1353 | Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = GetBakedTextureFaces(sp.UUID); | 1268 | Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = GetBakedTextureFaces(sp.UUID); |
1354 | 1269 | ||
@@ -1362,19 +1277,38 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
1362 | } | 1277 | } |
1363 | else | 1278 | else |
1364 | { | 1279 | { |
1365 | rawTextureID = bakedTextures[bt].TextureID.ToString(); | 1280 | if(bakedTextures[bt].TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE) |
1366 | 1281 | rawTextureID = "not set"; | |
1367 | if (m_scene.AssetService.Get(rawTextureID) == null) | ||
1368 | rawTextureID += " (not found)"; | ||
1369 | else | 1282 | else |
1370 | rawTextureID += " (uploaded)"; | 1283 | { |
1284 | rawTextureID = bakedTextures[bt].TextureID.ToString(); | ||
1285 | |||
1286 | if (m_scene.AssetService.Get(rawTextureID) == null) | ||
1287 | rawTextureID += " (not found)"; | ||
1288 | else | ||
1289 | rawTextureID += " (uploaded)"; | ||
1290 | } | ||
1371 | } | 1291 | } |
1372 | 1292 | ||
1373 | outputAction(BAKED_TEXTURES_REPORT_FORMAT, null, bt, rawTextureID); | 1293 | outputAction(BAKED_TEXTURES_REPORT_FORMAT, null, bt, rawTextureID); |
1374 | } | 1294 | } |
1375 | 1295 | ||
1376 | bool bakedTextureValid = m_scene.AvatarFactory.ValidateBakedTextureCache(sp); | 1296 | bool bakedTextureValid = m_scene.AvatarFactory.ValidateBakedTextureCache(sp); |
1377 | outputAction("{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "incomplete"); | 1297 | outputAction("{0} baked appearance texture is {1}", null, sp.Name, bakedTextureValid ? "OK" : "incomplete"); |
1298 | } | ||
1299 | |||
1300 | public void SetPreferencesHoverZ(UUID agentId, float val) | ||
1301 | { | ||
1302 | ScenePresence sp = m_scene.GetScenePresence(agentId); | ||
1303 | if (sp == null || sp.IsDeleted || sp.IsNPC || sp.IsInTransit) | ||
1304 | return; | ||
1305 | float last = sp.Appearance.AvatarPreferencesHoverZ; | ||
1306 | if(val != last) | ||
1307 | { | ||
1308 | sp.Appearance.AvatarPreferencesHoverZ = val; | ||
1309 | //sp.SendAppearanceToAgentNF(sp); | ||
1310 | QueueAppearanceSend(agentId); | ||
1311 | } | ||
1378 | } | 1312 | } |
1379 | } | 1313 | } |
1380 | } | 1314 | } |
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 187df31..c55f535 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -53,6 +53,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
53 | { | 53 | { |
54 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 54 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
55 | private static readonly string LogHeader = "[ENTITY TRANSFER MODULE]"; | 55 | private static readonly string LogHeader = "[ENTITY TRANSFER MODULE]"; |
56 | private static readonly string OutfitTPError = "destination region does not support the Outfit you are wearing. Please retry with a simpler one"; | ||
56 | 57 | ||
57 | public const bool WaitForAgentArrivedAtDestinationDefault = true; | 58 | public const bool WaitForAgentArrivedAtDestinationDefault = true; |
58 | 59 | ||
@@ -720,6 +721,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
720 | return; | 721 | return; |
721 | } | 722 | } |
722 | 723 | ||
724 | if (!sp.Appearance.CanTeleport(ctx.OutboundVersion)) | ||
725 | { | ||
726 | sp.ControllingClient.SendTeleportFailed(OutfitTPError); | ||
727 | |||
728 | m_log.DebugFormat( | ||
729 | "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because: {3}", | ||
730 | sp.Name, sp.Scene.Name, finalDestination.RegionName, "incompatible wearable"); | ||
731 | |||
732 | return; | ||
733 | } | ||
734 | |||
723 | // Before this point, teleport 'failure' is due to checkable pre-conditions such as whether the target | 735 | // Before this point, teleport 'failure' is due to checkable pre-conditions such as whether the target |
724 | // simulator can be found and is explicitly prepared to allow access. Therefore, we will not count these | 736 | // simulator can be found and is explicitly prepared to allow access. Therefore, we will not count these |
725 | // as server attempts. | 737 | // as server attempts. |
@@ -1489,6 +1501,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1489 | m_bannedRegionCache.Add(destinyHandle, agentID, 30.0, 30.0); | 1501 | m_bannedRegionCache.Add(destinyHandle, agentID, 30.0, 30.0); |
1490 | return false; | 1502 | return false; |
1491 | } | 1503 | } |
1504 | if (!agent.Appearance.CanTeleport(ctx.OutboundVersion)) | ||
1505 | { | ||
1506 | reason = OutfitTPError; | ||
1507 | m_bannedRegionCache.Add(destinyHandle, agentID, 30.0, 30.0); | ||
1508 | return false; | ||
1509 | } | ||
1510 | |||
1492 | return true; | 1511 | return true; |
1493 | } | 1512 | } |
1494 | 1513 | ||
@@ -1545,7 +1564,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1545 | failureReason = "Access Denied"; | 1564 | failureReason = "Access Denied"; |
1546 | return null; | 1565 | return null; |
1547 | } | 1566 | } |
1548 | |||
1549 | return neighbourRegion; | 1567 | return neighbourRegion; |
1550 | } | 1568 | } |
1551 | 1569 | ||
@@ -1599,9 +1617,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1599 | agent.ControllingClient.SendAlertMessage(failureReason); | 1617 | agent.ControllingClient.SendAlertMessage(failureReason); |
1600 | return agent; | 1618 | return agent; |
1601 | } | 1619 | } |
1620 | if (!agent.Appearance.CanTeleport(ctx.OutboundVersion)) | ||
1621 | { | ||
1622 | if (agent.ControllingClient != null) | ||
1623 | agent.ControllingClient.SendAlertMessage(OutfitTPError); | ||
1624 | return agent; | ||
1625 | } | ||
1602 | 1626 | ||
1603 | // agent.IsInTransit = true; | 1627 | // agent.IsInTransit = true; |
1604 | |||
1605 | CrossAgentToNewRegionAsync(agent, newpos, neighbourRegion, isFlying, ctx); | 1628 | CrossAgentToNewRegionAsync(agent, newpos, neighbourRegion, isFlying, ctx); |
1606 | agent.IsInTransit = false; | 1629 | agent.IsInTransit = false; |
1607 | return agent; | 1630 | return agent; |
@@ -2601,7 +2624,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2601 | string reason = String.Empty; | 2624 | string reason = String.Empty; |
2602 | 2625 | ||
2603 | EntityTransferContext ctx = new EntityTransferContext(); | 2626 | EntityTransferContext ctx = new EntityTransferContext(); |
2604 | bool regionAccepted = scene.SimulationService.CreateAgent(reg, reg, agentCircData, (uint)TeleportFlags.Default, ctx, out reason); | 2627 | bool regionAccepted = scene.SimulationService.CreateAgent(reg, reg, agentCircData, (uint)TeleportFlags.Default, null, out reason); |
2605 | 2628 | ||
2606 | if (regionAccepted) | 2629 | if (regionAccepted) |
2607 | { | 2630 | { |
diff --git a/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs b/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs index 800affe..8faf4a8 100755 --- a/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs | |||
@@ -37,7 +37,7 @@ namespace OpenSim.Region.Framework.Interfaces | |||
37 | { | 37 | { |
38 | void SetAppearance(IScenePresence sp, AvatarAppearance appearance, WearableCacheItem[] cacheItems); | 38 | void SetAppearance(IScenePresence sp, AvatarAppearance appearance, WearableCacheItem[] cacheItems); |
39 | void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, WearableCacheItem[] cacheItems); | 39 | void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, WearableCacheItem[] cacheItems); |
40 | 40 | void SetPreferencesHoverZ(UUID agentId, float val); | |
41 | /// <summary> | 41 | /// <summary> |
42 | /// Send the appearance of an avatar to others in the scene. | 42 | /// Send the appearance of an avatar to others in the scene. |
43 | /// </summary> | 43 | /// </summary> |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index d53c562..9db7633 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -4358,16 +4358,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4358 | 4358 | ||
4359 | public void SendAppearanceToAgentNF(ScenePresence avatar) | 4359 | public void SendAppearanceToAgentNF(ScenePresence avatar) |
4360 | { | 4360 | { |
4361 | if(avatar.UUID == UUID) | 4361 | avatar.ControllingClient.SendAppearance(UUID, Appearance.VisualParams, Appearance.Texture.GetBakesBytes(), Appearance.AvatarPreferencesHoverZ); |
4362 | { | ||
4363 | avatar.ControllingClient.SendAppearance( | ||
4364 | UUID, Appearance.VisualParams, Appearance.Texture.GetBytes()); | ||
4365 | } | ||
4366 | else | ||
4367 | { | ||
4368 | avatar.ControllingClient.SendAppearance( | ||
4369 | UUID, Appearance.VisualParams, Appearance.Texture.GetBakesBytes()); | ||
4370 | } | ||
4371 | } | 4362 | } |
4372 | 4363 | ||
4373 | public void SendAnimPackToAgent(ScenePresence p) | 4364 | public void SendAnimPackToAgent(ScenePresence p) |
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 002bfad..009c72e 100755 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs | |||
@@ -961,7 +961,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
961 | 961 | ||
962 | } | 962 | } |
963 | 963 | ||
964 | public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry) | 964 | public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry, float hoverheight) |
965 | { | 965 | { |
966 | 966 | ||
967 | } | 967 | } |
diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index ded0857..1db9ba7 100755 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs | |||
@@ -413,13 +413,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance | |||
413 | sb.AppendFormat("Wearables checks for {0}\n\n", sp.Name); | 413 | sb.AppendFormat("Wearables checks for {0}\n\n", sp.Name); |
414 | 414 | ||
415 | AvatarWearable[] wearables = sp.Appearance.Wearables; | 415 | AvatarWearable[] wearables = sp.Appearance.Wearables; |
416 | if(wearables.Count() == 0) | 416 | if(wearables.Length == 0) |
417 | { | 417 | { |
418 | MainConsole.Instance.Output("avatar has no wearables"); | 418 | MainConsole.Instance.Output("avatar has no wearables"); |
419 | return; | 419 | return; |
420 | } | 420 | } |
421 | 421 | ||
422 | for (int i = 0; i < wearables.Count(); i++) | 422 | for (int i = 0; i < wearables.Length; i++) |
423 | { | 423 | { |
424 | AvatarWearable aw = wearables[i]; | 424 | AvatarWearable aw = wearables[i]; |
425 | 425 | ||
@@ -477,8 +477,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance | |||
477 | cdt.AddColumn("Type", 10); | 477 | cdt.AddColumn("Type", 10); |
478 | cdt.AddColumn("Item UUID", ConsoleDisplayUtil.UuidSize); | 478 | cdt.AddColumn("Item UUID", ConsoleDisplayUtil.UuidSize); |
479 | cdt.AddColumn("Asset UUID", ConsoleDisplayUtil.UuidSize); | 479 | cdt.AddColumn("Asset UUID", ConsoleDisplayUtil.UuidSize); |
480 | AvatarWearable[] wearables = sp.Appearance.Wearables; | ||
480 | 481 | ||
481 | for (int i = (int)WearableType.Shape; i < (int)WearableType.Physics; i++) | 482 | for (int i = 0; i < wearables.Length; i++) |
482 | { | 483 | { |
483 | AvatarWearable aw = sp.Appearance.Wearables[i]; | 484 | AvatarWearable aw = sp.Appearance.Wearables[i]; |
484 | 485 | ||
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index 798576c..1eb77a7 100755 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs | |||
@@ -664,7 +664,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
664 | { | 664 | { |
665 | } | 665 | } |
666 | 666 | ||
667 | public virtual void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry) | 667 | public virtual void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry, float hover) |
668 | { | 668 | { |
669 | } | 669 | } |
670 | 670 | ||
diff --git a/OpenSim/Server/Handlers/AgentPreferences/AgentPreferencesServerPostHandler.cs b/OpenSim/Server/Handlers/AgentPreferences/AgentPreferencesServerPostHandler.cs index b1b3c6f..2f8f151 100644 --- a/OpenSim/Server/Handlers/AgentPreferences/AgentPreferencesServerPostHandler.cs +++ b/OpenSim/Server/Handlers/AgentPreferences/AgentPreferencesServerPostHandler.cs | |||
@@ -129,7 +129,7 @@ namespace OpenSim.Server.Handlers.AgentPreferences | |||
129 | 129 | ||
130 | AgentPrefs data = new AgentPrefs(userID); | 130 | AgentPrefs data = new AgentPrefs(userID); |
131 | data.AccessPrefs = request["AccessPrefs"].ToString(); | 131 | data.AccessPrefs = request["AccessPrefs"].ToString(); |
132 | data.HoverHeight = double.Parse(request["HoverHeight"].ToString()); | 132 | data.HoverHeight = float.Parse(request["HoverHeight"].ToString()); |
133 | data.Language = request["Language"].ToString(); | 133 | data.Language = request["Language"].ToString(); |
134 | data.LanguageIsPublic = bool.Parse(request["LanguageIsPublic"].ToString()); | 134 | data.LanguageIsPublic = bool.Parse(request["LanguageIsPublic"].ToString()); |
135 | data.PermEveryone = int.Parse(request["PermEveryone"].ToString()); | 135 | data.PermEveryone = int.Parse(request["PermEveryone"].ToString()); |
diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs index f5e7771..18c949e 100644 --- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs | |||
@@ -116,6 +116,8 @@ namespace OpenSim.Services.Connectors.Simulation | |||
116 | try | 116 | try |
117 | { | 117 | { |
118 | OSDMap args = aCircuit.PackAgentCircuitData(ctx); | 118 | OSDMap args = aCircuit.PackAgentCircuitData(ctx); |
119 | if(ctx == null) | ||
120 | ctx = new EntityTransferContext(); | ||
119 | args["context"] = ctx.Pack(); | 121 | args["context"] = ctx.Pack(); |
120 | PackData(args, source, aCircuit, destination, flags); | 122 | PackData(args, source, aCircuit, destination, flags); |
121 | 123 | ||
diff --git a/OpenSim/Services/Interfaces/IAgentPreferencesService.cs b/OpenSim/Services/Interfaces/IAgentPreferencesService.cs index af92326..6d2ce8f 100644 --- a/OpenSim/Services/Interfaces/IAgentPreferencesService.cs +++ b/OpenSim/Services/Interfaces/IAgentPreferencesService.cs | |||
@@ -45,7 +45,7 @@ namespace OpenSim.Services.Interfaces | |||
45 | if (kvp.ContainsKey("AccessPrefs")) | 45 | if (kvp.ContainsKey("AccessPrefs")) |
46 | AccessPrefs = kvp["AccessPrefs"]; | 46 | AccessPrefs = kvp["AccessPrefs"]; |
47 | if (kvp.ContainsKey("HoverHeight")) | 47 | if (kvp.ContainsKey("HoverHeight")) |
48 | HoverHeight = double.Parse(kvp["HoverHeight"]); | 48 | HoverHeight = float.Parse(kvp["HoverHeight"]); |
49 | if (kvp.ContainsKey("Language")) | 49 | if (kvp.ContainsKey("Language")) |
50 | Language = kvp["Language"]; | 50 | Language = kvp["Language"]; |
51 | if (kvp.ContainsKey("LanguageIsPublic")) | 51 | if (kvp.ContainsKey("LanguageIsPublic")) |
@@ -65,7 +65,7 @@ namespace OpenSim.Services.Interfaces | |||
65 | if (kvp.ContainsKey("AccessPrefs")) | 65 | if (kvp.ContainsKey("AccessPrefs")) |
66 | AccessPrefs = kvp["AccessPrefs"].ToString(); | 66 | AccessPrefs = kvp["AccessPrefs"].ToString(); |
67 | if (kvp.ContainsKey("HoverHeight")) | 67 | if (kvp.ContainsKey("HoverHeight")) |
68 | HoverHeight = double.Parse(kvp["HoverHeight"].ToString()); | 68 | HoverHeight = float.Parse(kvp["HoverHeight"].ToString()); |
69 | if (kvp.ContainsKey("Language")) | 69 | if (kvp.ContainsKey("Language")) |
70 | Language = kvp["Language"].ToString(); | 70 | Language = kvp["Language"].ToString(); |
71 | if (kvp.ContainsKey("LanguageIsPublic")) | 71 | if (kvp.ContainsKey("LanguageIsPublic")) |
@@ -95,7 +95,7 @@ namespace OpenSim.Services.Interfaces | |||
95 | public UUID PrincipalID = UUID.Zero; | 95 | public UUID PrincipalID = UUID.Zero; |
96 | public string AccessPrefs = "M"; | 96 | public string AccessPrefs = "M"; |
97 | //public int GodLevel; // *TODO: Implement GodLevel (Unused by the viewer, afaict - 6/11/2015) | 97 | //public int GodLevel; // *TODO: Implement GodLevel (Unused by the viewer, afaict - 6/11/2015) |
98 | public double HoverHeight = 0.0; | 98 | public float HoverHeight = 0.0f; |
99 | public string Language = "en-us"; | 99 | public string Language = "en-us"; |
100 | public bool LanguageIsPublic = true; | 100 | public bool LanguageIsPublic = true; |
101 | // DefaultObjectPermMasks | 101 | // DefaultObjectPermMasks |
diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index 6cea71f..929fa4a 100755 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs | |||
@@ -570,7 +570,7 @@ namespace OpenSim.Tests.Common | |||
570 | { | 570 | { |
571 | } | 571 | } |
572 | 572 | ||
573 | public virtual void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry) | 573 | public virtual void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry, float hover) |
574 | { | 574 | { |
575 | } | 575 | } |
576 | 576 | ||