diff options
-rw-r--r-- | OpenSim/Framework/AvatarAppearance.cs | 135 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 32 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | 73 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs | 39 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 7 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 66 | ||||
-rw-r--r-- | bin/assets/TexturesAssetSet/TexturesAssetSet.xml | 6 | ||||
-rw-r--r-- | bin/assets/TexturesAssetSet/default_alpha.jp2 | bin | 0 -> 319 bytes | |||
-rw-r--r-- | bin/inventory/BodyPartsLibrary/BodyPartsLibraryItems.xml | 28 |
9 files changed, 304 insertions, 82 deletions
diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs index e66a1e7..a4bb765 100644 --- a/OpenSim/Framework/AvatarAppearance.cs +++ b/OpenSim/Framework/AvatarAppearance.cs | |||
@@ -35,6 +35,104 @@ using log4net; | |||
35 | 35 | ||
36 | namespace OpenSim.Framework | 36 | namespace OpenSim.Framework |
37 | { | 37 | { |
38 | // A special dictionary for avatar appearance | ||
39 | public struct LayerItem | ||
40 | { | ||
41 | public UUID ItemID; | ||
42 | public UUID AssetID; | ||
43 | |||
44 | public LayerItem(UUID itemID, UUID assetID) | ||
45 | { | ||
46 | ItemID = itemID; | ||
47 | AssetID = assetID; | ||
48 | } | ||
49 | } | ||
50 | |||
51 | public class Layer | ||
52 | { | ||
53 | protected int m_layerType; | ||
54 | protected Dictionary<UUID, UUID> m_items = new Dictionary<UUID, UUID>(); | ||
55 | protected List<UUID> m_ids = new List<UUID>(); | ||
56 | |||
57 | public Layer(int type) | ||
58 | { | ||
59 | m_layerType = type; | ||
60 | } | ||
61 | |||
62 | public int LayerType | ||
63 | { | ||
64 | get { return m_layerType; } | ||
65 | } | ||
66 | |||
67 | public int Count | ||
68 | { | ||
69 | get { return m_ids.Count; } | ||
70 | } | ||
71 | |||
72 | public void Add(UUID itemID, UUID assetID) | ||
73 | { | ||
74 | if (m_items.ContainsKey(itemID)) | ||
75 | return; | ||
76 | if (m_ids.Count >= 5) | ||
77 | return; | ||
78 | |||
79 | m_ids.Add(itemID); | ||
80 | m_items[itemID] = assetID; | ||
81 | } | ||
82 | |||
83 | public void Wear(UUID itemID, UUID assetID) | ||
84 | { | ||
85 | Clear(); | ||
86 | Add(itemID, assetID); | ||
87 | } | ||
88 | |||
89 | public void Clear() | ||
90 | { | ||
91 | m_ids.Clear(); | ||
92 | m_items.Clear(); | ||
93 | } | ||
94 | |||
95 | public void RemoveItem(UUID itemID) | ||
96 | { | ||
97 | if (m_items.ContainsKey(itemID)) | ||
98 | { | ||
99 | m_ids.Remove(itemID); | ||
100 | m_items.Remove(itemID); | ||
101 | } | ||
102 | } | ||
103 | |||
104 | public void RemoveAsset(UUID assetID) | ||
105 | { | ||
106 | UUID itemID = UUID.Zero; | ||
107 | |||
108 | foreach (KeyValuePair<UUID, UUID> kvp in m_items) | ||
109 | { | ||
110 | if (kvp.Value == assetID) | ||
111 | { | ||
112 | itemID = kvp.Key; | ||
113 | break; | ||
114 | } | ||
115 | } | ||
116 | |||
117 | if (itemID != UUID.Zero) | ||
118 | { | ||
119 | m_ids.Remove(itemID); | ||
120 | m_items.Remove(itemID); | ||
121 | } | ||
122 | } | ||
123 | |||
124 | public LayerItem this [int idx] | ||
125 | { | ||
126 | get | ||
127 | { | ||
128 | if (idx >= m_ids.Count || idx < 0) | ||
129 | return new LayerItem(UUID.Zero, UUID.Zero); | ||
130 | |||
131 | return new LayerItem(m_ids[idx], m_items[m_ids[idx]]); | ||
132 | } | ||
133 | } | ||
134 | } | ||
135 | |||
38 | /// <summary> | 136 | /// <summary> |
39 | /// Contains the Avatar's Appearance and methods to manipulate the appearance. | 137 | /// Contains the Avatar's Appearance and methods to manipulate the appearance. |
40 | /// </summary> | 138 | /// </summary> |
@@ -45,6 +143,7 @@ namespace OpenSim.Framework | |||
45 | public readonly static int VISUALPARAM_COUNT = 218; | 143 | public readonly static int VISUALPARAM_COUNT = 218; |
46 | 144 | ||
47 | public readonly static int TEXTURE_COUNT = 21; | 145 | public readonly static int TEXTURE_COUNT = 21; |
146 | public readonly static byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; | ||
48 | 147 | ||
49 | protected UUID m_owner; | 148 | protected UUID m_owner; |
50 | protected int m_serial = 1; | 149 | protected int m_serial = 1; |
@@ -347,14 +446,8 @@ namespace OpenSim.Framework | |||
347 | protected virtual void SetDefaultTexture() | 446 | protected virtual void SetDefaultTexture() |
348 | { | 447 | { |
349 | m_texture = new Primitive.TextureEntry(new UUID("C228D1CF-4B5D-4BA8-84F4-899A0796AA97")); | 448 | m_texture = new Primitive.TextureEntry(new UUID("C228D1CF-4B5D-4BA8-84F4-899A0796AA97")); |
350 | // The initialization of these seems to force a rebake regardless of whether it is needed | 449 | for (uint i = 0; i < TEXTURE_COUNT; i++) |
351 | // m_textures.CreateFace(0).TextureID = new UUID("00000000-0000-1111-9999-000000000012"); | 450 | m_texture.CreateFace(i).TextureID = new UUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE); |
352 | // m_textures.CreateFace(1).TextureID = Util.BLANK_TEXTURE_UUID; | ||
353 | // m_textures.CreateFace(2).TextureID = Util.BLANK_TEXTURE_UUID; | ||
354 | // m_textures.CreateFace(3).TextureID = new UUID("6522E74D-1660-4E7F-B601-6F48C1659A77"); | ||
355 | // m_textures.CreateFace(4).TextureID = new UUID("7CA39B4C-BD19-4699-AFF7-F93FD03D3E7B"); | ||
356 | // m_textures.CreateFace(5).TextureID = new UUID("00000000-0000-1111-9999-000000000010"); | ||
357 | // m_textures.CreateFace(6).TextureID = new UUID("00000000-0000-1111-9999-000000000011"); | ||
358 | } | 451 | } |
359 | 452 | ||
360 | /// <summary> | 453 | /// <summary> |
@@ -371,7 +464,7 @@ namespace OpenSim.Framework | |||
371 | // made. We determine if any of the textures actually | 464 | // made. We determine if any of the textures actually |
372 | // changed to know if the appearance should be saved later | 465 | // changed to know if the appearance should be saved later |
373 | bool changed = false; | 466 | bool changed = false; |
374 | for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++) | 467 | for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++) |
375 | { | 468 | { |
376 | Primitive.TextureEntryFace newface = textureEntry.FaceTextures[i]; | 469 | Primitive.TextureEntryFace newface = textureEntry.FaceTextures[i]; |
377 | Primitive.TextureEntryFace oldface = m_texture.FaceTextures[i]; | 470 | Primitive.TextureEntryFace oldface = m_texture.FaceTextures[i]; |
@@ -385,7 +478,6 @@ namespace OpenSim.Framework | |||
385 | if (oldface != null && oldface.TextureID == newface.TextureID) continue; | 478 | if (oldface != null && oldface.TextureID == newface.TextureID) continue; |
386 | } | 479 | } |
387 | 480 | ||
388 | m_texture.FaceTextures[i] = (newface != null) ? new Primitive.TextureEntryFace(newface) : null; | ||
389 | changed = true; | 481 | changed = true; |
390 | // DEBUG ON | 482 | // DEBUG ON |
391 | if (newface != null) | 483 | if (newface != null) |
@@ -393,6 +485,7 @@ namespace OpenSim.Framework | |||
393 | // DEBUG OFF | 485 | // DEBUG OFF |
394 | } | 486 | } |
395 | 487 | ||
488 | m_texture = textureEntry; | ||
396 | return changed; | 489 | return changed; |
397 | } | 490 | } |
398 | 491 | ||
@@ -415,8 +508,8 @@ namespace OpenSim.Framework | |||
415 | if (visualParams[i] != m_visualparams[i]) | 508 | if (visualParams[i] != m_visualparams[i]) |
416 | { | 509 | { |
417 | // DEBUG ON | 510 | // DEBUG ON |
418 | m_log.WarnFormat("[AVATARAPPEARANCE] vparams changed [{0}] {1} ==> {2}", | 511 | // m_log.WarnFormat("[AVATARAPPEARANCE] vparams changed [{0}] {1} ==> {2}", |
419 | i,m_visualparams[i],visualParams[i]); | 512 | // i,m_visualparams[i],visualParams[i]); |
420 | // DEBUG OFF | 513 | // DEBUG OFF |
421 | m_visualparams[i] = visualParams[i]; | 514 | m_visualparams[i] = visualParams[i]; |
422 | changed = true; | 515 | changed = true; |
@@ -581,6 +674,8 @@ namespace OpenSim.Framework | |||
581 | m_attachments.Clear(); | 674 | m_attachments.Clear(); |
582 | } | 675 | } |
583 | 676 | ||
677 | #region Packing Functions | ||
678 | |||
584 | /// <summary> | 679 | /// <summary> |
585 | /// Create an OSDMap from the appearance data | 680 | /// Create an OSDMap from the appearance data |
586 | /// </summary> | 681 | /// </summary> |
@@ -605,7 +700,7 @@ namespace OpenSim.Framework | |||
605 | if (m_texture.FaceTextures[i] != null) | 700 | if (m_texture.FaceTextures[i] != null) |
606 | textures.Add(OSD.FromUUID(m_texture.FaceTextures[i].TextureID)); | 701 | textures.Add(OSD.FromUUID(m_texture.FaceTextures[i].TextureID)); |
607 | else | 702 | else |
608 | textures.Add(OSD.FromUUID(UUID.Zero)); | 703 | textures.Add(OSD.FromUUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE)); |
609 | } | 704 | } |
610 | data["textures"] = textures; | 705 | data["textures"] = textures; |
611 | 706 | ||
@@ -657,12 +752,10 @@ namespace OpenSim.Framework | |||
657 | OSDArray textures = (OSDArray)(data["textures"]); | 752 | OSDArray textures = (OSDArray)(data["textures"]); |
658 | for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT && i < textures.Count; i++) | 753 | for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT && i < textures.Count; i++) |
659 | { | 754 | { |
755 | UUID textureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE; | ||
660 | if (textures[i] != null) | 756 | if (textures[i] != null) |
661 | { | 757 | textureID = textures[i].AsUUID(); |
662 | UUID textureID = textures[i].AsUUID(); | 758 | m_texture.CreateFace((uint)i).TextureID = new UUID(textureID); |
663 | if (textureID != UUID.Zero) | ||
664 | m_texture.CreateFace((uint)i).TextureID = textureID; | ||
665 | } | ||
666 | } | 759 | } |
667 | } | 760 | } |
668 | else | 761 | else |
@@ -697,6 +790,9 @@ namespace OpenSim.Framework | |||
697 | } | 790 | } |
698 | } | 791 | } |
699 | 792 | ||
793 | #endregion | ||
794 | |||
795 | #region VPElement | ||
700 | 796 | ||
701 | /// <summary> | 797 | /// <summary> |
702 | /// Viewer Params Array Element for AgentSetAppearance | 798 | /// Viewer Params Array Element for AgentSetAppearance |
@@ -1460,5 +1556,6 @@ namespace OpenSim.Framework | |||
1460 | SKIRT_SKIRT_GREEN = 216, | 1556 | SKIRT_SKIRT_GREEN = 216, |
1461 | SKIRT_SKIRT_BLUE = 217 | 1557 | SKIRT_SKIRT_BLUE = 217 |
1462 | } | 1558 | } |
1559 | #endregion | ||
1463 | } | 1560 | } |
1464 | } \ No newline at end of file | 1561 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index ad6b1de..e89368a 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | |||
@@ -123,15 +123,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
123 | m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); | 123 | m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); |
124 | 124 | ||
125 | // Save avatar attachment information | 125 | // Save avatar attachment information |
126 | ScenePresence presence; | 126 | m_log.Info( |
127 | if (m_scene.AvatarService != null && m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) | 127 | "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId |
128 | { | 128 | + ", AttachmentPoint: " + AttachmentPt); |
129 | m_log.Info( | ||
130 | "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId | ||
131 | + ", AttachmentPoint: " + AttachmentPt); | ||
132 | 129 | ||
133 | m_scene.AvatarService.SetAppearance(remoteClient.AgentId, presence.Appearance); | 130 | if (m_scene.AvatarFactory != null) |
134 | } | 131 | m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); |
135 | } | 132 | } |
136 | } | 133 | } |
137 | catch (Exception e) | 134 | catch (Exception e) |
@@ -382,8 +379,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
382 | item = m_scene.InventoryService.GetItem(item); | 379 | item = m_scene.InventoryService.GetItem(item); |
383 | presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /* att.UUID */); | 380 | presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /* att.UUID */); |
384 | 381 | ||
385 | if (m_scene.AvatarService != null) | 382 | if (m_scene.AvatarFactory != null) |
386 | m_scene.AvatarService.SetAppearance(remoteClient.AgentId, presence.Appearance); | 383 | m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); |
387 | } | 384 | } |
388 | } | 385 | } |
389 | 386 | ||
@@ -405,11 +402,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
405 | presence.Appearance.DetachAttachment(itemID); | 402 | presence.Appearance.DetachAttachment(itemID); |
406 | 403 | ||
407 | // Save avatar attachment information | 404 | // Save avatar attachment information |
408 | if (m_scene.AvatarService != null) | 405 | m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID); |
409 | { | 406 | if (m_scene.AvatarFactory != null) |
410 | m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID); | 407 | m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); |
411 | m_scene.AvatarService.SetAppearance(remoteClient.AgentId, presence.Appearance); | ||
412 | } | ||
413 | } | 408 | } |
414 | 409 | ||
415 | DetachSingleAttachmentToInv(itemID, remoteClient); | 410 | DetachSingleAttachmentToInv(itemID, remoteClient); |
@@ -435,10 +430,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
435 | 430 | ||
436 | presence.Appearance.DetachAttachment(itemID); | 431 | presence.Appearance.DetachAttachment(itemID); |
437 | 432 | ||
438 | if (m_scene.AvatarService != null) | 433 | if (m_scene.AvatarFactory != null) |
439 | { | 434 | m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); |
440 | m_scene.AvatarService.SetAppearance(remoteClient.AgentId, presence.Appearance); | 435 | |
441 | } | ||
442 | part.ParentGroup.DetachToGround(); | 436 | part.ParentGroup.DetachToGround(); |
443 | 437 | ||
444 | List<UUID> uuids = new List<UUID>(); | 438 | List<UUID> uuids = new List<UUID>(); |
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 5f8b4f6..bfbbcf8 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | |||
@@ -42,10 +42,9 @@ using OpenSim.Services.Interfaces; | |||
42 | 42 | ||
43 | namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | 43 | namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory |
44 | { | 44 | { |
45 | public class AvatarFactoryModule : IRegionModule | 45 | public class AvatarFactoryModule : IAvatarFactory, IRegionModule |
46 | { | 46 | { |
47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
48 | private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; | ||
49 | private Scene m_scene = null; | 48 | private Scene m_scene = null; |
50 | 49 | ||
51 | private int m_savetime = 5; // seconds to wait before saving changed appearance | 50 | private int m_savetime = 5; // seconds to wait before saving changed appearance |
@@ -60,8 +59,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
60 | 59 | ||
61 | public void Initialise(Scene scene, IConfigSource config) | 60 | public void Initialise(Scene scene, IConfigSource config) |
62 | { | 61 | { |
62 | scene.RegisterModuleInterface<IAvatarFactory>(this); | ||
63 | scene.EventManager.OnNewClient += NewClient; | 63 | scene.EventManager.OnNewClient += NewClient; |
64 | 64 | ||
65 | if (config != null) | 65 | if (config != null) |
66 | { | 66 | { |
67 | IConfig sconfig = config.Configs["Startup"]; | 67 | IConfig sconfig = config.Configs["Startup"]; |
@@ -112,6 +112,34 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
112 | 112 | ||
113 | #endregion | 113 | #endregion |
114 | 114 | ||
115 | public bool ValidateBakedTextureCache(IClientAPI client) | ||
116 | { | ||
117 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); | ||
118 | if (sp == null) | ||
119 | { | ||
120 | m_log.WarnFormat("[AVFACTORY] SetAppearance unable to find presence for {0}",client.AgentId); | ||
121 | return false; | ||
122 | } | ||
123 | |||
124 | bool cached = true; | ||
125 | |||
126 | // Process the texture entry | ||
127 | for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) | ||
128 | { | ||
129 | int idx = AvatarAppearance.BAKE_INDICES[i]; | ||
130 | Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; | ||
131 | if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) | ||
132 | if (! CheckBakedTextureAsset(client,face.TextureID,idx)) | ||
133 | { | ||
134 | sp.Appearance.Texture.FaceTextures[idx] = null; | ||
135 | cached = false; | ||
136 | } | ||
137 | } | ||
138 | |||
139 | return cached; | ||
140 | } | ||
141 | |||
142 | |||
115 | /// <summary> | 143 | /// <summary> |
116 | /// Set appearance data (textureentry and slider settings) received from the client | 144 | /// Set appearance data (textureentry and slider settings) received from the client |
117 | /// </summary> | 145 | /// </summary> |
@@ -137,12 +165,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
137 | { | 165 | { |
138 | changed = sp.Appearance.SetTextureEntries(textureEntry); | 166 | changed = sp.Appearance.SetTextureEntries(textureEntry); |
139 | 167 | ||
140 | for (int i = 0; i < BAKE_INDICES.Length; i++) | 168 | for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) |
141 | { | 169 | { |
142 | int idx = BAKE_INDICES[i]; | 170 | int idx = AvatarAppearance.BAKE_INDICES[i]; |
143 | Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; | 171 | Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; |
144 | if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) | 172 | if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) |
145 | Util.FireAndForget(delegate(object o) { CheckBakedTextureAssets(client,face.TextureID,idx); }); | 173 | Util.FireAndForget(delegate(object o) { |
174 | if (! CheckBakedTextureAsset(client,face.TextureID,idx)) | ||
175 | client.SendRebakeAvatarTextures(face.TextureID); | ||
176 | }); | ||
146 | } | 177 | } |
147 | } | 178 | } |
148 | 179 | ||
@@ -165,9 +196,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
165 | QueueAppearanceSend(client.AgentId); | 196 | QueueAppearanceSend(client.AgentId); |
166 | 197 | ||
167 | // Send the appearance back to the avatar | 198 | // Send the appearance back to the avatar |
168 | AvatarAppearance avp = sp.Appearance; | 199 | // AvatarAppearance avp = sp.Appearance; |
169 | sp.ControllingClient.SendAvatarDataImmediate(sp); | 200 | // sp.ControllingClient.SendAvatarDataImmediate(sp); |
170 | sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes()); | 201 | // sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes()); |
171 | } | 202 | } |
172 | 203 | ||
173 | /// <summary> | 204 | /// <summary> |
@@ -177,14 +208,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
177 | /// <param name="client"></param> | 208 | /// <param name="client"></param> |
178 | /// <param name="textureID"></param> | 209 | /// <param name="textureID"></param> |
179 | /// <param name="idx"></param> | 210 | /// <param name="idx"></param> |
180 | private void CheckBakedTextureAssets(IClientAPI client, UUID textureID, int idx) | 211 | private bool CheckBakedTextureAsset(IClientAPI client, UUID textureID, int idx) |
181 | { | 212 | { |
182 | if (m_scene.AssetService.Get(textureID.ToString()) == null) | 213 | if (m_scene.AssetService.Get(textureID.ToString()) == null) |
183 | { | 214 | { |
184 | m_log.WarnFormat("[AVFACTORY]: Missing baked texture {0} ({1}) for avatar {2}", | 215 | m_log.WarnFormat("[AVFACTORY]: Missing baked texture {0} ({1}) for avatar {2}", |
185 | textureID,idx,client.Name); | 216 | textureID,idx,client.Name); |
186 | client.SendRebakeAvatarTextures(textureID); | 217 | return false; |
187 | } | 218 | } |
219 | return true; | ||
188 | } | 220 | } |
189 | 221 | ||
190 | #region UpdateAppearanceTimer | 222 | #region UpdateAppearanceTimer |
@@ -229,16 +261,16 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
229 | } | 261 | } |
230 | 262 | ||
231 | // DEBUG ON | 263 | // DEBUG ON |
232 | m_log.WarnFormat("[AVFACTORY] Handle appearance send for {0}\n{1}",agentid,sp.Appearance.ToString()); | 264 | m_log.WarnFormat("[AVFACTORY] Handle appearance send for {0}",agentid); |
233 | // DEBUG OFF | 265 | // DEBUG OFF |
234 | 266 | ||
235 | // Send the appearance to everyone in the scene | 267 | // Send the appearance to everyone in the scene |
236 | sp.SendAppearanceToAllOtherAgents(); | 268 | sp.SendAppearanceToAllOtherAgents(); |
269 | sp.ControllingClient.SendAvatarDataImmediate(sp); | ||
237 | 270 | ||
238 | // Send the appearance back to the avatar | 271 | // Send the appearance back to the avatar |
239 | AvatarAppearance avp = sp.Appearance; | 272 | // AvatarAppearance avp = sp.Appearance; |
240 | sp.ControllingClient.SendAvatarDataImmediate(sp); | 273 | // sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes()); |
241 | sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes()); | ||
242 | 274 | ||
243 | /* | 275 | /* |
244 | // this needs to be fixed, the flag should be on scene presence not the region module | 276 | // this needs to be fixed, the flag should be on scene presence not the region module |
@@ -337,14 +369,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
337 | 369 | ||
338 | AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance); | 370 | AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance); |
339 | 371 | ||
340 | //if (!TryGetAvatarAppearance(client.AgentId, out avatAppearance)) | ||
341 | //{ | ||
342 | // m_log.Warn("[AVFACTORY]: We didn't seem to find the appearance, falling back to ScenePresence"); | ||
343 | // avatAppearance = sp.Appearance; | ||
344 | //} | ||
345 | |||
346 | //m_log.DebugFormat("[AVFACTORY]: Received wearables for {0}", client.Name); | ||
347 | |||
348 | foreach (AvatarWearingArgs.Wearable wear in e.NowWearing) | 372 | foreach (AvatarWearingArgs.Wearable wear in e.NowWearing) |
349 | { | 373 | { |
350 | if (wear.Type < AvatarWearable.MAX_WEARABLES) | 374 | if (wear.Type < AvatarWearable.MAX_WEARABLES) |
@@ -354,10 +378,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
354 | } | 378 | } |
355 | } | 379 | } |
356 | 380 | ||
381 | // This could take awhile since it needs to pull inventory | ||
357 | SetAppearanceAssets(sp.UUID, ref avatAppearance); | 382 | SetAppearanceAssets(sp.UUID, ref avatAppearance); |
358 | 383 | ||
359 | m_scene.AvatarService.SetAppearance(client.AgentId, avatAppearance); | ||
360 | sp.Appearance = avatAppearance; | 384 | sp.Appearance = avatAppearance; |
385 | m_scene.AvatarService.SetAppearance(client.AgentId, sp.Appearance); | ||
361 | } | 386 | } |
362 | 387 | ||
363 | private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance) | 388 | private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance) |
diff --git a/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs b/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs new file mode 100644 index 0000000..22795fc --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs | |||
@@ -0,0 +1,39 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using OpenMetaverse; | ||
29 | using OpenSim.Framework; | ||
30 | |||
31 | namespace OpenSim.Region.Framework.Interfaces | ||
32 | { | ||
33 | public interface IAvatarFactory | ||
34 | { | ||
35 | bool ValidateBakedTextureCache(IClientAPI client); | ||
36 | void QueueAppearanceSend(UUID agentid); | ||
37 | void QueueAppearanceSave(UUID agentid); | ||
38 | } | ||
39 | } | ||
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index f77fb2c..3c6bab8 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -119,6 +119,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
119 | 119 | ||
120 | protected IXMLRPC m_xmlrpcModule; | 120 | protected IXMLRPC m_xmlrpcModule; |
121 | protected IWorldComm m_worldCommModule; | 121 | protected IWorldComm m_worldCommModule; |
122 | protected IAvatarFactory m_AvatarFactory; | ||
122 | protected IConfigSource m_config; | 123 | protected IConfigSource m_config; |
123 | protected IRegionSerialiserModule m_serialiser; | 124 | protected IRegionSerialiserModule m_serialiser; |
124 | protected IDialogModule m_dialogModule; | 125 | protected IDialogModule m_dialogModule; |
@@ -398,6 +399,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
398 | 399 | ||
399 | public IAttachmentsModule AttachmentsModule { get; set; } | 400 | public IAttachmentsModule AttachmentsModule { get; set; } |
400 | 401 | ||
402 | public IAvatarFactory AvatarFactory | ||
403 | { | ||
404 | get { return m_AvatarFactory; } | ||
405 | } | ||
406 | |||
401 | public ICapabilitiesModule CapsModule | 407 | public ICapabilitiesModule CapsModule |
402 | { | 408 | { |
403 | get { return m_capsModule; } | 409 | get { return m_capsModule; } |
@@ -1153,6 +1159,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1153 | m_xmlrpcModule = RequestModuleInterface<IXMLRPC>(); | 1159 | m_xmlrpcModule = RequestModuleInterface<IXMLRPC>(); |
1154 | m_worldCommModule = RequestModuleInterface<IWorldComm>(); | 1160 | m_worldCommModule = RequestModuleInterface<IWorldComm>(); |
1155 | XferManager = RequestModuleInterface<IXfer>(); | 1161 | XferManager = RequestModuleInterface<IXfer>(); |
1162 | m_AvatarFactory = RequestModuleInterface<IAvatarFactory>(); | ||
1156 | AttachmentsModule = RequestModuleInterface<IAttachmentsModule>(); | 1163 | AttachmentsModule = RequestModuleInterface<IAttachmentsModule>(); |
1157 | m_serialiser = RequestModuleInterface<IRegionSerialiserModule>(); | 1164 | m_serialiser = RequestModuleInterface<IRegionSerialiserModule>(); |
1158 | m_dialogModule = RequestModuleInterface<IDialogModule>(); | 1165 | m_dialogModule = RequestModuleInterface<IDialogModule>(); |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 1abd134..afafa5b 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -704,20 +704,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
704 | // we created a new ScenePresence (a new child agent) in a fresh region. | 704 | // we created a new ScenePresence (a new child agent) in a fresh region. |
705 | // Request info about all the (root) agents in this region | 705 | // Request info about all the (root) agents in this region |
706 | // Note: This won't send data *to* other clients in that region (children don't send) | 706 | // Note: This won't send data *to* other clients in that region (children don't send) |
707 | |||
708 | // MIC: This gets called again in CompleteMovement | ||
707 | SendInitialFullUpdateToAllClients(); | 709 | SendInitialFullUpdateToAllClients(); |
708 | 710 | ||
709 | RegisterToEvents(); | 711 | RegisterToEvents(); |
710 | SetDirectionVectors(); | 712 | SetDirectionVectors(); |
711 | } | 713 | } |
712 | 714 | ||
713 | /* | ||
714 | public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, byte[] visualParams, | ||
715 | AvatarWearable[] wearables) | ||
716 | : this(client, world, reginfo) | ||
717 | { | ||
718 | m_appearance = new AvatarAppearance(m_uuid, wearables, visualParams); | ||
719 | } | ||
720 | */ | ||
721 | public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance) | 715 | public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance) |
722 | : this(client, world, reginfo) | 716 | : this(client, world, reginfo) |
723 | { | 717 | { |
@@ -1081,7 +1075,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1081 | /// </summary> | 1075 | /// </summary> |
1082 | public void CompleteMovement(IClientAPI client) | 1076 | public void CompleteMovement(IClientAPI client) |
1083 | { | 1077 | { |
1084 | //m_log.Debug("[SCENE PRESENCE]: CompleteMovement"); | 1078 | // DEBUG ON |
1079 | m_log.WarnFormat("[SCENE PRESENCE]: CompleteMovement for {0}",UUID); | ||
1080 | // DEBUG OFF | ||
1085 | 1081 | ||
1086 | Vector3 look = Velocity; | 1082 | Vector3 look = Velocity; |
1087 | if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) | 1083 | if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) |
@@ -2381,12 +2377,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
2381 | // 2 stage check is needed. | 2377 | // 2 stage check is needed. |
2382 | if (remoteAvatar == null) | 2378 | if (remoteAvatar == null) |
2383 | return; | 2379 | return; |
2380 | |||
2384 | IClientAPI cl=remoteAvatar.ControllingClient; | 2381 | IClientAPI cl=remoteAvatar.ControllingClient; |
2385 | if (cl == null) | 2382 | if (cl == null) |
2386 | return; | 2383 | return; |
2384 | |||
2387 | if (m_appearance.Texture == null) | 2385 | if (m_appearance.Texture == null) |
2388 | return; | 2386 | return; |
2389 | 2387 | ||
2388 | if (LocalId == remoteAvatar.LocalId) | ||
2389 | { | ||
2390 | m_log.WarnFormat("[SP] An agent is attempting to send data to itself; {0}",UUID); | ||
2391 | return; | ||
2392 | } | ||
2393 | |||
2390 | if (IsChildAgent) | 2394 | if (IsChildAgent) |
2391 | { | 2395 | { |
2392 | m_log.WarnFormat("[SCENEPRESENCE] A child agent is attempting to send out avatar data"); | 2396 | m_log.WarnFormat("[SCENEPRESENCE] A child agent is attempting to send out avatar data"); |
@@ -2407,20 +2411,23 @@ namespace OpenSim.Region.Framework.Scenes | |||
2407 | m_scene.ForEachScenePresence(delegate(ScenePresence avatar) | 2411 | m_scene.ForEachScenePresence(delegate(ScenePresence avatar) |
2408 | { | 2412 | { |
2409 | ++avUpdates; | 2413 | ++avUpdates; |
2410 | // only send if this is the root (children are only "listening posts" in a foreign region) | 2414 | |
2415 | // Don't update ourselves | ||
2416 | if (avatar.LocalId == LocalId) | ||
2417 | return; | ||
2418 | |||
2419 | // If this is a root agent, then get info about the avatar | ||
2411 | if (!IsChildAgent) | 2420 | if (!IsChildAgent) |
2412 | { | 2421 | { |
2413 | SendFullUpdateToOtherClient(avatar); | 2422 | SendFullUpdateToOtherClient(avatar); |
2414 | } | 2423 | } |
2415 | 2424 | ||
2416 | if (avatar.LocalId != LocalId) | 2425 | // If the other avatar is a root |
2426 | if (!avatar.IsChildAgent) | ||
2417 | { | 2427 | { |
2418 | if (!avatar.IsChildAgent) | 2428 | avatar.SendFullUpdateToOtherClient(this); |
2419 | { | 2429 | avatar.SendAppearanceToOtherAgent(this); |
2420 | avatar.SendFullUpdateToOtherClient(this); | 2430 | avatar.Animator.SendAnimPackToClient(ControllingClient); |
2421 | avatar.SendAppearanceToOtherAgent(this); | ||
2422 | avatar.Animator.SendAnimPackToClient(ControllingClient); | ||
2423 | } | ||
2424 | } | 2431 | } |
2425 | }); | 2432 | }); |
2426 | 2433 | ||
@@ -2465,7 +2472,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
2465 | // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); | 2472 | // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); |
2466 | 2473 | ||
2467 | m_controllingClient.SendAvatarDataImmediate(this); | 2474 | m_controllingClient.SendAvatarDataImmediate(this); |
2468 | m_controllingClient.SendAppearance(m_appearance.Owner,m_appearance.VisualParams,m_appearance.Texture.GetBytes()); | 2475 | if (m_scene.AvatarFactory != null) |
2476 | { | ||
2477 | if (m_scene.AvatarFactory.ValidateBakedTextureCache(m_controllingClient)) | ||
2478 | { | ||
2479 | m_log.WarnFormat("[SP] baked textures are in the ache for {0}",Name); | ||
2480 | m_controllingClient.SendAppearance( | ||
2481 | m_appearance.Owner,m_appearance.VisualParams,m_appearance.Texture.GetBytes()); | ||
2482 | } | ||
2483 | } | ||
2484 | else | ||
2485 | { | ||
2486 | m_log.WarnFormat("[SP] AvatarFactory not set"); | ||
2487 | } | ||
2469 | 2488 | ||
2470 | SendInitialFullUpdateToAllClients(); | 2489 | SendInitialFullUpdateToAllClients(); |
2471 | } | 2490 | } |
@@ -2497,9 +2516,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
2497 | /// <param name="avatar"></param> | 2516 | /// <param name="avatar"></param> |
2498 | public void SendAppearanceToOtherAgent(ScenePresence avatar) | 2517 | public void SendAppearanceToOtherAgent(ScenePresence avatar) |
2499 | { | 2518 | { |
2519 | if (LocalId == avatar.LocalId) | ||
2520 | { | ||
2521 | m_log.WarnFormat("[SP] An agent is attempting to send data to itself; {0}",UUID); | ||
2522 | return; | ||
2523 | } | ||
2524 | |||
2500 | // DEBUG ON | 2525 | // DEBUG ON |
2501 | m_log.WarnFormat("[SP] Send appearance from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId); | 2526 | // m_log.WarnFormat("[SP] Send appearance from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId); |
2502 | // DEBUG OFF | 2527 | // DEBUG OFF |
2528 | |||
2503 | avatar.ControllingClient.SendAppearance( | 2529 | avatar.ControllingClient.SendAppearance( |
2504 | m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes()); | 2530 | m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes()); |
2505 | } | 2531 | } |
@@ -2898,7 +2924,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2898 | public void CopyTo(AgentData cAgent) | 2924 | public void CopyTo(AgentData cAgent) |
2899 | { | 2925 | { |
2900 | cAgent.CallbackURI = m_callbackURI; | 2926 | cAgent.CallbackURI = m_callbackURI; |
2901 | 2927 | ||
2902 | cAgent.AgentID = UUID; | 2928 | cAgent.AgentID = UUID; |
2903 | cAgent.RegionID = Scene.RegionInfo.RegionID; | 2929 | cAgent.RegionID = Scene.RegionInfo.RegionID; |
2904 | 2930 | ||
diff --git a/bin/assets/TexturesAssetSet/TexturesAssetSet.xml b/bin/assets/TexturesAssetSet/TexturesAssetSet.xml index c5cafa7..5484ee2 100644 --- a/bin/assets/TexturesAssetSet/TexturesAssetSet.xml +++ b/bin/assets/TexturesAssetSet/TexturesAssetSet.xml | |||
@@ -1,4 +1,10 @@ | |||
1 | <Nini> | 1 | <Nini> |
2 | <Section Name="Default Alpha"> | ||
3 | <Key Name="assetID" Value="1578a2b1-5179-4b53-b618-fe00ca5a5594" /> | ||
4 | <Key Name="name" Value="alpha" /> | ||
5 | <Key Name="assetType" Value="0" /> | ||
6 | <Key Name="fileName" Value="default_alpha.jp2" /> | ||
7 | </Section> | ||
2 | <Section Name="texture1"> | 8 | <Section Name="texture1"> |
3 | <Key Name="assetID" Value="00000000-0000-2222-3333-000000000099" /> | 9 | <Key Name="assetID" Value="00000000-0000-2222-3333-000000000099" /> |
4 | <Key Name="name" Value="femface" /> | 10 | <Key Name="name" Value="femface" /> |
diff --git a/bin/assets/TexturesAssetSet/default_alpha.jp2 b/bin/assets/TexturesAssetSet/default_alpha.jp2 new file mode 100644 index 0000000..af73c1e --- /dev/null +++ b/bin/assets/TexturesAssetSet/default_alpha.jp2 | |||
Binary files differ | |||
diff --git a/bin/inventory/BodyPartsLibrary/BodyPartsLibraryItems.xml b/bin/inventory/BodyPartsLibrary/BodyPartsLibraryItems.xml index aa8d9d9..5cb71c0 100644 --- a/bin/inventory/BodyPartsLibrary/BodyPartsLibraryItems.xml +++ b/bin/inventory/BodyPartsLibrary/BodyPartsLibraryItems.xml | |||
@@ -16,6 +16,34 @@ | |||
16 | </Section> | 16 | </Section> |
17 | --> | 17 | --> |
18 | <!-- | 18 | <!-- |
19 | <Section Name="Tattoo"> | ||
20 | <Key Name="inventoryID" Value="c47e22bd-3021-4ba4-82aa-2b5cb34d35e1" /> | ||
21 | <Key Name="assetID" Value="00000000-0000-2222-3333-100000001007" /> | ||
22 | <Key Name="folderID" Value="d499e5e0-b9bf-11dc-95ff-0800200c9a66"/> | ||
23 | <Key Name="description" Value="Tattoo" /> | ||
24 | <Key Name="name" Value="Tattoo" /> | ||
25 | <Key Name="assetType" Value="13" /> | ||
26 | <Key Name="inventoryType" Value="18" /> | ||
27 | <Key Name="currentPermissions" Value="2147483647" /> | ||
28 | <Key Name="nextPermissions" Value="2147483647" /> | ||
29 | <Key Name="everyonePermissions" Value="2147483647" /> | ||
30 | <Key Name="basePermissions" Value="2147483647" /> | ||
31 | </Section> | ||
32 | |||
33 | <Section Name="Alpha"> | ||
34 | <Key Name="inventoryID" Value="bfb9923c-4838-4d2d-bf07-608c5b1165c8" /> | ||
35 | <Key Name="assetID" Value="1578a2b1-5179-4b53-b618-fe00ca5a5594" /> | ||
36 | <Key Name="folderID" Value="d499e5e0-b9bf-11dc-95ff-0800200c9a66"/> | ||
37 | <Key Name="description" Value="Hair" /> | ||
38 | <Key Name="name" Value="Hair" /> | ||
39 | <Key Name="assetType" Value="13" /> | ||
40 | <Key Name="inventoryType" Value="18" /> | ||
41 | <Key Name="currentPermissions" Value="2147483647" /> | ||
42 | <Key Name="nextPermissions" Value="2147483647" /> | ||
43 | <Key Name="everyonePermissions" Value="2147483647" /> | ||
44 | <Key Name="basePermissions" Value="2147483647" /> | ||
45 | </Section> | ||
46 | |||
19 | <Section Name="Hair"> | 47 | <Section Name="Hair"> |
20 | <Key Name="inventoryID" Value="d342e6c1-b9d2-11dc-95ff-0800200c9a66" /> | 48 | <Key Name="inventoryID" Value="d342e6c1-b9d2-11dc-95ff-0800200c9a66" /> |
21 | <Key Name="assetID" Value="d342e6c0-b9d2-11dc-95ff-0800200c9a66" /> | 49 | <Key Name="assetID" Value="d342e6c0-b9d2-11dc-95ff-0800200c9a66" /> |