aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorMic Bowman2013-05-24 13:18:16 -0700
committerMic Bowman2013-05-24 13:18:16 -0700
commit681fbda4b6b9700421b82dc639f954c60871542e (patch)
treedb292ba79bf73f77c9fa9e72262d299a7115c201
parentchange a hull debugging message to Debug instead of Info (diff)
downloadopensim-SC_OLD-681fbda4b6b9700421b82dc639f954c60871542e.zip
opensim-SC_OLD-681fbda4b6b9700421b82dc639f954c60871542e.tar.gz
opensim-SC_OLD-681fbda4b6b9700421b82dc639f954c60871542e.tar.bz2
opensim-SC_OLD-681fbda4b6b9700421b82dc639f954c60871542e.tar.xz
This is an experimental patch that adds support for comparing texture
hashes for the purpose of accurately responding to AgentTextureCached packets. There is a change to IClientAPI to report the wearbles hashes that come in through the SetAppearance packet. Added storage of the texture hashes in the appearance. While these are added to the Pack/Unpack (with support for missing values) routines (which means Simian will store them properly), they are not currently persisted in Robust.
-rw-r--r--OpenSim/Framework/AvatarAppearance.cs98
-rw-r--r--OpenSim/Framework/IClientAPI.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs27
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs102
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs2
5 files changed, 147 insertions, 84 deletions
diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs
index 494ae5e..157feb5 100644
--- a/OpenSim/Framework/AvatarAppearance.cs
+++ b/OpenSim/Framework/AvatarAppearance.cs
@@ -53,6 +53,7 @@ namespace OpenSim.Framework
53 protected AvatarWearable[] m_wearables; 53 protected AvatarWearable[] m_wearables;
54 protected Dictionary<int, List<AvatarAttachment>> m_attachments; 54 protected Dictionary<int, List<AvatarAttachment>> m_attachments;
55 protected float m_avatarHeight = 0; 55 protected float m_avatarHeight = 0;
56 protected UUID[] m_texturehashes;
56 57
57 public virtual int Serial 58 public virtual int Serial
58 { 59 {
@@ -98,6 +99,8 @@ namespace OpenSim.Framework
98 SetDefaultParams(); 99 SetDefaultParams();
99 SetHeight(); 100 SetHeight();
100 m_attachments = new Dictionary<int, List<AvatarAttachment>>(); 101 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
102
103 ResetTextureHashes();
101 } 104 }
102 105
103 public AvatarAppearance(OSDMap map) 106 public AvatarAppearance(OSDMap map)
@@ -108,32 +111,6 @@ namespace OpenSim.Framework
108 SetHeight(); 111 SetHeight();
109 } 112 }
110 113
111 public AvatarAppearance(AvatarWearable[] wearables, Primitive.TextureEntry textureEntry, byte[] visualParams)
112 {
113// m_log.WarnFormat("[AVATAR APPEARANCE] create initialized appearance");
114
115 m_serial = 0;
116
117 if (wearables != null)
118 m_wearables = wearables;
119 else
120 SetDefaultWearables();
121
122 if (textureEntry != null)
123 m_texture = textureEntry;
124 else
125 SetDefaultTexture();
126
127 if (visualParams != null)
128 m_visualparams = visualParams;
129 else
130 SetDefaultParams();
131
132 SetHeight();
133
134 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
135 }
136
137 public AvatarAppearance(AvatarAppearance appearance) : this(appearance, true) 114 public AvatarAppearance(AvatarAppearance appearance) : this(appearance, true)
138 { 115 {
139 } 116 }
@@ -151,6 +128,8 @@ namespace OpenSim.Framework
151 SetHeight(); 128 SetHeight();
152 m_attachments = new Dictionary<int, List<AvatarAttachment>>(); 129 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
153 130
131 ResetTextureHashes();
132
154 return; 133 return;
155 } 134 }
156 135
@@ -166,6 +145,10 @@ namespace OpenSim.Framework
166 SetWearable(i,appearance.Wearables[i]); 145 SetWearable(i,appearance.Wearables[i]);
167 } 146 }
168 147
148 m_texturehashes = new UUID[AvatarAppearance.TEXTURE_COUNT];
149 for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
150 m_texturehashes[i] = new UUID(appearance.m_texturehashes[i]);
151
169 m_texture = null; 152 m_texture = null;
170 if (appearance.Texture != null) 153 if (appearance.Texture != null)
171 { 154 {
@@ -200,6 +183,37 @@ namespace OpenSim.Framework
200 } 183 }
201 } 184 }
202 185
186 public void ResetTextureHashes()
187 {
188 m_texturehashes = new UUID[AvatarAppearance.TEXTURE_COUNT];
189 for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
190 m_texturehashes[i] = UUID.Zero;
191 }
192
193 public UUID GetTextureHash(int textureIndex)
194 {
195 return m_texturehashes[NormalizeBakedTextureIndex(textureIndex)];
196 }
197
198 public void SetTextureHash(int textureIndex, UUID textureHash)
199 {
200 m_texturehashes[NormalizeBakedTextureIndex(textureIndex)] = new UUID(textureHash);
201 }
202
203 /// <summary>
204 /// Normalizes the texture index to the actual bake index, this is done to
205 /// accommodate older viewers that send the BAKE_INDICES index rather than
206 /// the actual texture index
207 /// </summary>
208 private int NormalizeBakedTextureIndex(int textureIndex)
209 {
210 // Earlier viewer send the index into the baked index array, just trying to be careful here
211 if (textureIndex < BAKE_INDICES.Length)
212 return BAKE_INDICES[textureIndex];
213
214 return textureIndex;
215 }
216
203 public void ClearWearables() 217 public void ClearWearables()
204 { 218 {
205 m_wearables = new AvatarWearable[AvatarWearable.MAX_WEARABLES]; 219 m_wearables = new AvatarWearable[AvatarWearable.MAX_WEARABLES];
@@ -223,12 +237,7 @@ namespace OpenSim.Framework
223 m_serial = 0; 237 m_serial = 0;
224 238
225 SetDefaultTexture(); 239 SetDefaultTexture();
226 240 ResetTextureHashes();
227 //for (int i = 0; i < BAKE_INDICES.Length; i++)
228 // {
229 // int idx = BAKE_INDICES[i];
230 // m_texture.FaceTextures[idx].TextureID = UUID.Zero;
231 // }
232 } 241 }
233 242
234 protected virtual void SetDefaultParams() 243 protected virtual void SetDefaultParams()
@@ -598,6 +607,12 @@ namespace OpenSim.Framework
598 data["serial"] = OSD.FromInteger(m_serial); 607 data["serial"] = OSD.FromInteger(m_serial);
599 data["height"] = OSD.FromReal(m_avatarHeight); 608 data["height"] = OSD.FromReal(m_avatarHeight);
600 609
610 // Hashes
611 OSDArray hashes = new OSDArray(AvatarAppearance.TEXTURE_COUNT);
612 for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
613 hashes.Add(OSD.FromUUID(m_texturehashes[i]));
614 data["hashes"] = hashes;
615
601 // Wearables 616 // Wearables
602 OSDArray wears = new OSDArray(AvatarWearable.MAX_WEARABLES); 617 OSDArray wears = new OSDArray(AvatarWearable.MAX_WEARABLES);
603 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) 618 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
@@ -642,6 +657,25 @@ namespace OpenSim.Framework
642 657
643 try 658 try
644 { 659 {
660 // Hashes
661 m_texturehashes = new UUID[AvatarAppearance.TEXTURE_COUNT];
662 if ((data != null) && (data["hashes"] != null) && (data["hashes"]).Type == OSDType.Array)
663 {
664 OSDArray hashes = (OSDArray)(data["hashes"]);
665 for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
666 {
667 UUID hashID = UUID.Zero;
668 if (i < hashes.Count && hashes[i] != null)
669 hashID = hashes[i].AsUUID();
670 m_texturehashes[i] = hashID;
671 }
672 }
673 else
674 {
675 for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
676 m_texturehashes[i] = UUID.Zero;
677 }
678
645 // Wearables 679 // Wearables
646 SetDefaultWearables(); 680 SetDefaultWearables();
647 if ((data != null) && (data["wearables"] != null) && (data["wearables"]).Type == OSDType.Array) 681 if ((data != null) && (data["wearables"] != null) && (data["wearables"]).Type == OSDType.Array)
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index 59ce2c4..1fffeff 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -66,7 +66,7 @@ namespace OpenSim.Framework
66 66
67 public delegate void CachedTextureRequest(IClientAPI remoteClient, int serial, List<CachedTextureRequestArg> cachedTextureRequest); 67 public delegate void CachedTextureRequest(IClientAPI remoteClient, int serial, List<CachedTextureRequestArg> cachedTextureRequest);
68 68
69 public delegate void SetAppearance(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams); 69 public delegate void SetAppearance(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, List<CachedTextureRequestArg> cachedTextureData);
70 70
71 public delegate void StartAnim(IClientAPI remoteClient, UUID animID); 71 public delegate void StartAnim(IClientAPI remoteClient, UUID animID);
72 72
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index e014471..dd8ef9c 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -6214,7 +6214,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6214 if (appear.ObjectData.TextureEntry.Length > 1) 6214 if (appear.ObjectData.TextureEntry.Length > 1)
6215 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length); 6215 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length);
6216 6216
6217 handlerSetAppearance(sender, te, visualparams); 6217 List<CachedTextureRequestArg> hashes = new List<CachedTextureRequestArg>();
6218 for (int i = 0; i < appear.WearableData.Length; i++)
6219 {
6220 CachedTextureRequestArg arg = new CachedTextureRequestArg();
6221 arg.BakedTextureIndex = appear.WearableData[i].TextureIndex;
6222 arg.WearableHashID = appear.WearableData[i].CacheID;
6223 hashes.Add(arg);
6224 }
6225
6226 handlerSetAppearance(sender, te, visualparams, hashes);
6218 } 6227 }
6219 catch (Exception e) 6228 catch (Exception e)
6220 { 6229 {
@@ -11487,12 +11496,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11487 requestArgs.Add(arg); 11496 requestArgs.Add(arg);
11488 } 11497 }
11489 11498
11490 CachedTextureRequest handlerCachedTextureRequest = OnCachedTextureRequest; 11499 try
11491 if (handlerCachedTextureRequest != null) 11500 {
11501 CachedTextureRequest handlerCachedTextureRequest = OnCachedTextureRequest;
11502 if (handlerCachedTextureRequest != null)
11503 {
11504 handlerCachedTextureRequest(simclient,cachedtex.AgentData.SerialNum,requestArgs);
11505 }
11506 }
11507 catch (Exception e)
11492 { 11508 {
11493 handlerCachedTextureRequest(simclient,cachedtex.AgentData.SerialNum,requestArgs); 11509 m_log.ErrorFormat("[CLIENT VIEW]: AgentTextureCached packet handler threw an exception, {0}", e);
11510 return false;
11494 } 11511 }
11495 11512
11496 return true; 11513 return true;
11497 } 11514 }
11498 11515
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index b640b48..482bf6f 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -147,7 +147,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
147 /// <param name="visualParam"></param> 147 /// <param name="visualParam"></param>
148 public void SetAppearance(IScenePresence sp, AvatarAppearance appearance) 148 public void SetAppearance(IScenePresence sp, AvatarAppearance appearance)
149 { 149 {
150 SetAppearance(sp, appearance.Texture, appearance.VisualParams); 150 DoSetAppearance(sp, appearance.Texture, appearance.VisualParams, new List<CachedTextureRequestArg>());
151 } 151 }
152 152
153 /// <summary> 153 /// <summary>
@@ -158,9 +158,20 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
158 /// <param name="visualParam"></param> 158 /// <param name="visualParam"></param>
159 public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams) 159 public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams)
160 { 160 {
161// m_log.DebugFormat( 161 DoSetAppearance(sp, textureEntry, visualParams, new List<CachedTextureRequestArg>());
162// "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}", 162 }
163// sp.Name, textureEntry, visualParams); 163
164 /// <summary>
165 /// Set appearance data (texture asset IDs and slider settings)
166 /// </summary>
167 /// <param name="sp"></param>
168 /// <param name="texture"></param>
169 /// <param name="visualParam"></param>
170 protected void DoSetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, List<CachedTextureRequestArg> hashes)
171 {
172 // m_log.DebugFormat(
173 // "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}",
174 // sp.Name, textureEntry, visualParams);
164 175
165 // TODO: This is probably not necessary any longer, just assume the 176 // TODO: This is probably not necessary any longer, just assume the
166 // textureEntry set implies that the appearance transaction is complete 177 // textureEntry set implies that the appearance transaction is complete
@@ -190,18 +201,22 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
190 // Process the baked texture array 201 // Process the baked texture array
191 if (textureEntry != null) 202 if (textureEntry != null)
192 { 203 {
193// m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID); 204 // m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID);
194 205 // WriteBakedTexturesReport(sp, m_log.DebugFormat);
195// WriteBakedTexturesReport(sp, m_log.DebugFormat);
196 206
197 changed = sp.Appearance.SetTextureEntries(textureEntry) || changed; 207 changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;
198 208
199// WriteBakedTexturesReport(sp, m_log.DebugFormat); 209 // WriteBakedTexturesReport(sp, m_log.DebugFormat);
200 210
201 // If bake textures are missing and this is not an NPC, request a rebake from client 211 // If bake textures are missing and this is not an NPC, request a rebake from client
202 if (!ValidateBakedTextureCache(sp) && (((ScenePresence)sp).PresenceType != PresenceType.Npc)) 212 if (!ValidateBakedTextureCache(sp) && (((ScenePresence)sp).PresenceType != PresenceType.Npc))
203 RequestRebake(sp, true); 213 RequestRebake(sp, true);
204 214
215 // Save the wearble hashes in the appearance
216 sp.Appearance.ResetTextureHashes();
217 foreach (CachedTextureRequestArg arg in hashes)
218 sp.Appearance.SetTextureHash(arg.BakedTextureIndex,arg.WearableHashID);
219
205 // This appears to be set only in the final stage of the appearance 220 // This appears to be set only in the final stage of the appearance
206 // update transaction. In theory, we should be able to do an immediate 221 // update transaction. In theory, we should be able to do an immediate
207 // appearance send and save here. 222 // appearance send and save here.
@@ -235,13 +250,13 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
235 250
236 public bool SendAppearance(UUID agentId) 251 public bool SendAppearance(UUID agentId)
237 { 252 {
238// m_log.DebugFormat("[AVFACTORY]: Sending appearance for {0}", agentId); 253 // m_log.DebugFormat("[AVFACTORY]: Sending appearance for {0}", agentId);
239 254
240 ScenePresence sp = m_scene.GetScenePresence(agentId); 255 ScenePresence sp = m_scene.GetScenePresence(agentId);
241 if (sp == null) 256 if (sp == null)
242 { 257 {
243 // This is expected if the user has gone away. 258 // This is expected if the user has gone away.
244// m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId); 259 // m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId);
245 return false; 260 return false;
246 } 261 }
247 262
@@ -318,7 +333,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
318 /// <param name="agentId"></param> 333 /// <param name="agentId"></param>
319 public void QueueAppearanceSend(UUID agentid) 334 public void QueueAppearanceSend(UUID agentid)
320 { 335 {
321// m_log.DebugFormat("[AVFACTORY]: Queue appearance send for {0}", agentid); 336 // m_log.DebugFormat("[AVFACTORY]: Queue appearance send for {0}", agentid);
322 337
323 // 10000 ticks per millisecond, 1000 milliseconds per second 338 // 10000 ticks per millisecond, 1000 milliseconds per second
324 long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 1000 * 10000); 339 long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 1000 * 10000);
@@ -331,7 +346,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
331 346
332 public void QueueAppearanceSave(UUID agentid) 347 public void QueueAppearanceSave(UUID agentid)
333 { 348 {
334// m_log.DebugFormat("[AVFACTORY]: Queueing appearance save for {0}", agentid); 349 // m_log.DebugFormat("[AVFACTORY]: Queueing appearance save for {0}", agentid);
335 350
336 // 10000 ticks per millisecond, 1000 milliseconds per second 351 // 10000 ticks per millisecond, 1000 milliseconds per second
337 long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000); 352 long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000);
@@ -356,9 +371,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
356 if (face == null) 371 if (face == null)
357 continue; 372 continue;
358 373
359// m_log.DebugFormat( 374 // m_log.DebugFormat(
360// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}", 375 // "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}",
361// face.TextureID, idx, client.Name, client.AgentId); 376 // face.TextureID, idx, client.Name, client.AgentId);
362 377
363 // if the texture is one of the "defaults" then skip it 378 // if the texture is one of the "defaults" then skip it
364 // this should probably be more intelligent (skirt texture doesnt matter 379 // this should probably be more intelligent (skirt texture doesnt matter
@@ -373,7 +388,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
373 return false; 388 return false;
374 } 389 }
375 390
376// m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID); 391 // m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID);
377 392
378 // If we only found default textures, then the appearance is not cached 393 // If we only found default textures, then the appearance is not cached
379 return (defonly ? false : true); 394 return (defonly ? false : true);
@@ -392,9 +407,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
392 if (face == null) 407 if (face == null)
393 continue; 408 continue;
394 409
395// m_log.DebugFormat( 410 // m_log.DebugFormat(
396// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}", 411 // "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}",
397// face.TextureID, idx, client.Name, client.AgentId); 412 // face.TextureID, idx, client.Name, client.AgentId);
398 413
399 // if the texture is one of the "defaults" then skip it 414 // if the texture is one of the "defaults" then skip it
400 // this should probably be more intelligent (skirt texture doesnt matter 415 // this should probably be more intelligent (skirt texture doesnt matter
@@ -458,9 +473,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
458 if (bakeType == BakeType.Unknown) 473 if (bakeType == BakeType.Unknown)
459 continue; 474 continue;
460 475
461// m_log.DebugFormat( 476 // m_log.DebugFormat(
462// "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}", 477 // "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}",
463// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]); 478 // acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]);
464 479
465 int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType); 480 int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType);
466 Primitive.TextureEntryFace texture = faceTextures[ftIndex]; // this will be null if there's no such baked texture 481 Primitive.TextureEntryFace texture = faceTextures[ftIndex]; // this will be null if there's no such baked texture
@@ -484,7 +499,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
484 UUID avatarID = kvp.Key; 499 UUID avatarID = kvp.Key;
485 long sendTime = kvp.Value; 500 long sendTime = kvp.Value;
486 501
487// m_log.DebugFormat("[AVFACTORY]: Handling queued appearance updates for {0}, update delta to now is {1}", avatarID, sendTime - now); 502 // m_log.DebugFormat("[AVFACTORY]: Handling queued appearance updates for {0}, update delta to now is {1}", avatarID, sendTime - now);
488 503
489 if (sendTime < now) 504 if (sendTime < now)
490 { 505 {
@@ -530,11 +545,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
530 if (sp == null) 545 if (sp == null)
531 { 546 {
532 // This is expected if the user has gone away. 547 // This is expected if the user has gone away.
533// m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid); 548 // m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid);
534 return; 549 return;
535 } 550 }
536 551
537// m_log.DebugFormat("[AVFACTORY]: Saving appearance for avatar {0}", agentid); 552 // m_log.DebugFormat("[AVFACTORY]: Saving appearance for avatar {0}", agentid);
538 553
539 // This could take awhile since it needs to pull inventory 554 // This could take awhile since it needs to pull inventory
540 // 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 555 // 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
@@ -622,12 +637,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
622 /// <param name="client"></param> 637 /// <param name="client"></param>
623 /// <param name="texture"></param> 638 /// <param name="texture"></param>
624 /// <param name="visualParam"></param> 639 /// <param name="visualParam"></param>
625 private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams) 640 private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams, List<CachedTextureRequestArg> hashes)
626 { 641 {
627 // m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId); 642 // m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId);
628 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 643 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
629 if (sp != null) 644 if (sp != null)
630 SetAppearance(sp, textureEntry, visualParams); 645 DoSetAppearance(sp, textureEntry, visualParams, hashes);
631 else 646 else
632 m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId); 647 m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId);
633 } 648 }
@@ -684,7 +699,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
684 /// <param name="cachedTextureRequest"></param> 699 /// <param name="cachedTextureRequest"></param>
685 private void Client_OnCachedTextureRequest(IClientAPI client, int serial, List<CachedTextureRequestArg> cachedTextureRequest) 700 private void Client_OnCachedTextureRequest(IClientAPI client, int serial, List<CachedTextureRequestArg> cachedTextureRequest)
686 { 701 {
687 // m_log.WarnFormat("[AVFACTORY]: Client_OnCachedTextureRequest called for {0} ({1})", client.Name, client.AgentId); 702 // m_log.DebugFormat("[AVFACTORY]: Client_OnCachedTextureRequest called for {0} ({1})", client.Name, client.AgentId);
688 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 703 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
689 704
690 List<CachedTextureResponseArg> cachedTextureResponse = new List<CachedTextureResponseArg>(); 705 List<CachedTextureResponseArg> cachedTextureResponse = new List<CachedTextureResponseArg>();
@@ -695,23 +710,20 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
695 710
696 if (m_reusetextures) 711 if (m_reusetextures)
697 { 712 {
698 // this is the most insanely dumb way to do this... however it seems to 713 if (sp.Appearance.GetTextureHash(index) == request.WearableHashID)
699 // actually work. if the appearance has been reset because wearables have 714 {
700 // changed then the texture entries are zero'd out until the bakes are 715 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[index];
701 // uploaded. on login, if the textures exist in the cache (eg if you logged 716 if (face != null)
702 // into the simulator recently, then the appearance will pull those and send 717 texture = face.TextureID;
703 // them back in the packet and you won't have to rebake. if the textures aren't 718 }
704 // in the cache then the intial makeroot() call in scenepresence will zero 719 else
705 // them out. 720 {
706 // 721 // We know that that hash is wrong, null it out
707 // a better solution (though how much better is an open question) is to 722 // and wait for the setappearance call
708 // store the hashes in the appearance and compare them. Thats's coming. 723 sp.Appearance.SetTextureHash(index,UUID.Zero);
709 724 }
710 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[index]; 725
711 if (face != null) 726 // m_log.WarnFormat("[AVFACTORY]: use texture {0} for index {1}; hash={2}",texture,index,request.WearableHashID);
712 texture = face.TextureID;
713
714 // m_log.WarnFormat("[AVFACTORY]: reuse texture {0} for index {1}",texture,index);
715 } 727 }
716 728
717 CachedTextureResponseArg response = new CachedTextureResponseArg(); 729 CachedTextureResponseArg response = new CachedTextureResponseArg();
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index 384eb1f..118635d 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -907,7 +907,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
907 // Mimicking LLClientView which gets always set appearance from client. 907 // Mimicking LLClientView which gets always set appearance from client.
908 AvatarAppearance appearance; 908 AvatarAppearance appearance;
909 m_scene.GetAvatarAppearance(this, out appearance); 909 m_scene.GetAvatarAppearance(this, out appearance);
910 OnSetAppearance(this, appearance.Texture, (byte[])appearance.VisualParams.Clone()); 910 OnSetAppearance(this, appearance.Texture, (byte[])appearance.VisualParams.Clone(), new List<CachedTextureRequestArg>());
911 } 911 }
912 912
913 public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args) 913 public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args)