aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar/AvatarFactory
diff options
context:
space:
mode:
authorMaster ScienceSim2010-11-18 10:01:10 -0800
committerMelanie2010-11-18 19:04:50 +0000
commit8f1a79420be062ea59b3c04aacb439fb57713ac7 (patch)
tree374eca7dccda5d1bfcc3a64f38696f84e3f008a6 /OpenSim/Region/CoreModules/Avatar/AvatarFactory
parentsmall refactor: reuse existing commandLine string rather than calling cmdline... (diff)
downloadopensim-SC_OLD-8f1a79420be062ea59b3c04aacb439fb57713ac7.zip
opensim-SC_OLD-8f1a79420be062ea59b3c04aacb439fb57713ac7.tar.gz
opensim-SC_OLD-8f1a79420be062ea59b3c04aacb439fb57713ac7.tar.bz2
opensim-SC_OLD-8f1a79420be062ea59b3c04aacb439fb57713ac7.tar.xz
Fixed appearance send for avatars with only default textures. This should fix some of the appearance problems on osgrid. Also added a transaction lock on SetAppearance. This won't prevent concurrent access to Appearance but it will at least make sure each update completes.
Signed-off-by: Melanie <melanie@t-data.com>
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/AvatarFactory')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs127
1 files changed, 74 insertions, 53 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index 2dd444d..0df4585 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -55,6 +55,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
55 private Dictionary<UUID,long> m_savequeue = new Dictionary<UUID,long>(); 55 private Dictionary<UUID,long> m_savequeue = new Dictionary<UUID,long>();
56 private Dictionary<UUID,long> m_sendqueue = new Dictionary<UUID,long>(); 56 private Dictionary<UUID,long> m_sendqueue = new Dictionary<UUID,long>();
57 57
58 private object m_setAppearanceLock = new object();
59
58 #region RegionModule Members 60 #region RegionModule Members
59 61
60 public void Initialise(Scene scene, IConfigSource config) 62 public void Initialise(Scene scene, IConfigSource config)
@@ -69,6 +71,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
69 { 71 {
70 m_savetime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime))); 72 m_savetime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime)));
71 m_sendtime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime))); 73 m_sendtime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime)));
74 // m_log.InfoFormat("[AVFACTORY] configured for {0} save and {1} send",m_savetime,m_sendtime);
72 } 75 }
73 } 76 }
74 77
@@ -117,26 +120,28 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
117 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 120 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
118 if (sp == null) 121 if (sp == null)
119 { 122 {
120 m_log.WarnFormat("[AVATAR FACTORY MODULE]: SetAppearance unable to find presence for {0}", client.AgentId); 123 m_log.WarnFormat("[AVFACTORY]: SetAppearance unable to find presence for {0}", client.AgentId);
121 return false; 124 return false;
122 } 125 }
123 126
124 bool cached = true; 127 bool defonly = true; // are we only using default textures
125 128
126 // Process the texture entry 129 // Process the texture entry
127 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) 130 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
128 { 131 {
129 int idx = AvatarAppearance.BAKE_INDICES[i]; 132 int idx = AvatarAppearance.BAKE_INDICES[i];
130 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; 133 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
131 if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) 134 if (face == null || face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
132 if (! CheckBakedTextureAsset(client,face.TextureID,idx)) 135 continue;
133 { 136
134 sp.Appearance.Texture.FaceTextures[idx] = null; 137 defonly = false; // found a non-default texture reference
135 cached = false; 138
136 } 139 if (! CheckBakedTextureAsset(client,face.TextureID,idx))
140 return false;
137 } 141 }
138 142
139 return cached; 143 // If we only found default textures, then the appearance is not cached
144 return (defonly ? false : true);
140 } 145 }
141 146
142 /// <summary> 147 /// <summary>
@@ -146,44 +151,59 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
146 /// <param name="visualParam"></param> 151 /// <param name="visualParam"></param>
147 public void SetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams) 152 public void SetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams)
148 { 153 {
149// m_log.WarnFormat("[AVATAR FACTORY MODULE]: SetAppearance for {0}",client.AgentId);
150
151 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 154 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
152 if (sp == null) 155 if (sp == null)
153 { 156 {
154 m_log.WarnFormat("[AVATAR FACTORY MODULE]: SetAppearance unable to find presence for {0}",client.AgentId); 157 m_log.WarnFormat("[AVFACTORY]: SetAppearance unable to find presence for {0}",client.AgentId);
155 return; 158 return;
156 } 159 }
157 160
161 // m_log.WarnFormat("[AVFACTORY]: Start SetAppearance for {0}",client.AgentId);
162
158 bool changed = false; 163 bool changed = false;
159 164
160 // Process the texture entry 165 // Process the texture entry transactionally, this doesn't guarantee that Appearance is
161 if (textureEntry != null) 166 // going to be handled correctly but it does serialize the updates to the appearance
167 lock (m_setAppearanceLock)
162 { 168 {
163 changed = sp.Appearance.SetTextureEntries(textureEntry); 169 if (textureEntry != null)
164
165 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
166 { 170 {
167 int idx = AvatarAppearance.BAKE_INDICES[i]; 171 changed = sp.Appearance.SetTextureEntries(textureEntry);
168 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; 172
169 if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) 173 // m_log.WarnFormat("[AVFACTORY]: Prepare to check textures for {0}",client.AgentId);
170 Util.FireAndForget(delegate(object o) { 174
171 if (! CheckBakedTextureAsset(client,face.TextureID,idx)) 175 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
172 client.SendRebakeAvatarTextures(face.TextureID); 176 {
173 }); 177 int idx = AvatarAppearance.BAKE_INDICES[i];
178 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
179 if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
180 Util.FireAndForget(delegate(object o) {
181 if (! CheckBakedTextureAsset(client,face.TextureID,idx))
182 client.SendRebakeAvatarTextures(face.TextureID);
183 });
184 }
185
186 // m_log.WarnFormat("[AVFACTORY]: Complete texture check for {0}",client.AgentId);
174 } 187 }
175 }
176 188
177 // Process the visual params, this may change height as well 189 // Process the visual params, this may change height as well
178 if (visualParams != null) 190 if (visualParams != null)
179 {
180 if (sp.Appearance.SetVisualParams(visualParams))
181 { 191 {
182 changed = true; 192 if (sp.Appearance.SetVisualParams(visualParams))
183 if (sp.Appearance.AvatarHeight > 0) 193 {
184 sp.SetHeight(sp.Appearance.AvatarHeight); 194 changed = true;
195 if (sp.Appearance.AvatarHeight > 0)
196 sp.SetHeight(sp.Appearance.AvatarHeight);
197 }
185 } 198 }
199
200 // Send the appearance back to the avatar, not clear that this is needed
201 sp.ControllingClient.SendAvatarDataImmediate(sp);
202 // AvatarAppearance avp = sp.Appearance;
203 // sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes());
204
186 } 205 }
206
187 207
188 // If something changed in the appearance then queue an appearance save 208 // If something changed in the appearance then queue an appearance save
189 if (changed) 209 if (changed)
@@ -192,10 +212,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
192 // And always queue up an appearance update to send out 212 // And always queue up an appearance update to send out
193 QueueAppearanceSend(client.AgentId); 213 QueueAppearanceSend(client.AgentId);
194 214
195 // Send the appearance back to the avatar 215 // m_log.WarnFormat("[AVFACTORY]: Complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString());
196 // AvatarAppearance avp = sp.Appearance;
197 // sp.ControllingClient.SendAvatarDataImmediate(sp);
198 // sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes());
199 } 216 }
200 217
201 /// <summary> 218 /// <summary>
@@ -209,7 +226,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
209 { 226 {
210 if (m_scene.AssetService.Get(textureID.ToString()) == null) 227 if (m_scene.AssetService.Get(textureID.ToString()) == null)
211 { 228 {
212 m_log.WarnFormat("[AVATAR FACTORY MODULE]: Missing baked texture {0} ({1}) for avatar {2}", 229 m_log.WarnFormat("[AVFACTORY]: Missing baked texture {0} ({1}) for avatar {2}",
213 textureID, idx, client.Name); 230 textureID, idx, client.Name);
214 return false; 231 return false;
215 } 232 }
@@ -220,10 +237,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
220 237
221 public void QueueAppearanceSend(UUID agentid) 238 public void QueueAppearanceSend(UUID agentid)
222 { 239 {
223// m_log.WarnFormat("[AVATAR FACTORY MODULE]: Queue appearance send for {0}", agentid); 240 // m_log.WarnFormat("[AVFACTORY]: Queue appearance send for {0}", agentid);
224 241
225 // 100 nanoseconds (ticks) we should wait 242 // 10000 ticks per millisecond, 1000 milliseconds per second
226 long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 10000000); 243 long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 1000 * 10000);
227 lock (m_sendqueue) 244 lock (m_sendqueue)
228 { 245 {
229 m_sendqueue[agentid] = timestamp; 246 m_sendqueue[agentid] = timestamp;
@@ -233,10 +250,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
233 250
234 public void QueueAppearanceSave(UUID agentid) 251 public void QueueAppearanceSave(UUID agentid)
235 { 252 {
236// m_log.WarnFormat("[AVATAR FACTORY MODULE]: Queue appearance save for {0}", agentid); 253 // m_log.WarnFormat("[AVFACTORY]: Queue appearance save for {0}", agentid);
237 254
238 // 100 nanoseconds (ticks) we should wait 255 // 10000 ticks per millisecond, 1000 milliseconds per second
239 long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 10000000); 256 long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000);
240 lock (m_savequeue) 257 lock (m_savequeue)
241 { 258 {
242 m_savequeue[agentid] = timestamp; 259 m_savequeue[agentid] = timestamp;
@@ -249,15 +266,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
249 ScenePresence sp = m_scene.GetScenePresence(agentid); 266 ScenePresence sp = m_scene.GetScenePresence(agentid);
250 if (sp == null) 267 if (sp == null)
251 { 268 {
252 m_log.WarnFormat("[AVATAR FACTORY MODULE]: Agent {0} no longer in the scene", agentid); 269 m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid);
253 return; 270 return;
254 } 271 }
255 272
256// m_log.WarnFormat("[AVATAR FACTORY MODULE]: Handle appearance send for {0}", agentid); 273 // m_log.WarnFormat("[AVFACTORY]: Handle appearance send for {0}", agentid);
257 274
258 // Send the appearance to everyone in the scene 275 // Send the appearance to everyone in the scene
259 sp.SendAppearanceToAllOtherAgents(); 276 sp.SendAppearanceToAllOtherAgents();
260 sp.ControllingClient.SendAvatarDataImmediate(sp); 277 // sp.ControllingClient.SendAvatarDataImmediate(sp);
261 278
262 // Send the appearance back to the avatar 279 // Send the appearance back to the avatar
263 // AvatarAppearance avp = sp.Appearance; 280 // AvatarAppearance avp = sp.Appearance;
@@ -279,10 +296,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
279 ScenePresence sp = m_scene.GetScenePresence(agentid); 296 ScenePresence sp = m_scene.GetScenePresence(agentid);
280 if (sp == null) 297 if (sp == null)
281 { 298 {
282 m_log.WarnFormat("[AVATAR FACTORY MODULE]: Agent {0} no longer in the scene", agentid); 299 m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid);
283 return; 300 return;
284 } 301 }
285 302
303 // m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid);
304
286 m_scene.AvatarService.SetAppearance(agentid, sp.Appearance); 305 m_scene.AvatarService.SetAppearance(agentid, sp.Appearance);
287 } 306 }
288 307
@@ -330,11 +349,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
330 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 349 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
331 if (sp == null) 350 if (sp == null)
332 { 351 {
333 m_log.WarnFormat("[AVATAR FACTORY MODULE]: SendWearables unable to find presence for {0}", client.AgentId); 352 m_log.WarnFormat("[AVFACTORY]: SendWearables unable to find presence for {0}", client.AgentId);
334 return; 353 return;
335 } 354 }
336 355
337// m_log.WarnFormat("[AVATAR FACTORY MODULE]: Received request for wearables of {0}", client.AgentId); 356 // m_log.WarnFormat("[AVFACTORY]: Received request for wearables of {0}", client.AgentId);
338 357
339 client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++); 358 client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++);
340 } 359 }
@@ -349,11 +368,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
349 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 368 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
350 if (sp == null) 369 if (sp == null)
351 { 370 {
352 m_log.WarnFormat("[AVATAR FACTORY MODULE]: AvatarIsWearing unable to find presence for {0}", client.AgentId); 371 m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing unable to find presence for {0}", client.AgentId);
353 return; 372 return;
354 } 373 }
355 374
356// m_log.WarnFormat("[AVATAR FACTORY MODULE]: AvatarIsWearing called for {0}", client.AgentId); 375 // m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing called for {0}", client.AgentId);
357 376
358 AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false); 377 AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false);
359 378
@@ -368,6 +387,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
368 // This could take awhile since it needs to pull inventory 387 // This could take awhile since it needs to pull inventory
369 SetAppearanceAssets(sp.UUID, ref avatAppearance); 388 SetAppearanceAssets(sp.UUID, ref avatAppearance);
370 389
390 // could get fancier with the locks here, but in the spirit of "last write wins"
391 // this should work correctly
371 sp.Appearance = avatAppearance; 392 sp.Appearance = avatAppearance;
372 m_scene.AvatarService.SetAppearance(client.AgentId, sp.Appearance); 393 m_scene.AvatarService.SetAppearance(client.AgentId, sp.Appearance);
373 } 394 }
@@ -398,7 +419,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
398 else 419 else
399 { 420 {
400 m_log.ErrorFormat( 421 m_log.ErrorFormat(
401 "[AVATAR FACTORY MODULE]: Can't find inventory item {0} for {1}, setting to default", 422 "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default",
402 appearance.Wearables[i][j].ItemID, (WearableType)i); 423 appearance.Wearables[i][j].ItemID, (WearableType)i);
403 424
404 appearance.Wearables[i].RemoveItem(appearance.Wearables[i][j].ItemID); 425 appearance.Wearables[i].RemoveItem(appearance.Wearables[i][j].ItemID);
@@ -408,7 +429,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
408 } 429 }
409 else 430 else
410 { 431 {
411 m_log.WarnFormat("[AVATAR FACTORY MODULE]: user {0} has no inventory, appearance isn't going to work", userID); 432 m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID);
412 } 433 }
413 } 434 }
414 } 435 }