aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorMic Bowman2013-05-24 13:18:16 -0700
committerMic Bowman2013-05-24 13:18:16 -0700
commit681fbda4b6b9700421b82dc639f954c60871542e (patch)
treedb292ba79bf73f77c9fa9e72262d299a7115c201 /OpenSim/Region
parentchange a hull debugging message to Debug instead of Info (diff)
downloadopensim-SC-681fbda4b6b9700421b82dc639f954c60871542e.zip
opensim-SC-681fbda4b6b9700421b82dc639f954c60871542e.tar.gz
opensim-SC-681fbda4b6b9700421b82dc639f954c60871542e.tar.bz2
opensim-SC-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.
Diffstat (limited to '')
-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
3 files changed, 80 insertions, 51 deletions
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)