aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules')
-rw-r--r--OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs6
-rw-r--r--OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs4
-rw-r--r--OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs169
-rw-r--r--OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs5
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs556
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs8
-rw-r--r--OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs71
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs738
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsIn/UserProfiles/LocalUserProfilesServiceConnector.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandObject.cs13
-rw-r--r--OpenSim/Region/CoreModules/World/Wind/WindModule.cs38
11 files changed, 959 insertions, 651 deletions
diff --git a/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs b/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs
index e40caec..f43305f 100644
--- a/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs
@@ -194,6 +194,12 @@ namespace OpenSim.Region.CoreModules.Asset
194 194
195 #region IImprovedAssetCache Members 195 #region IImprovedAssetCache Members
196 196
197
198 public bool Check(string id)
199 {
200 return false;
201 }
202
197 /// <summary> 203 /// <summary>
198 /// Cache asset. 204 /// Cache asset.
199 /// </summary> 205 /// </summary>
diff --git a/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs b/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs
index 9742a5c..58ce61a 100644
--- a/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs
@@ -112,6 +112,10 @@ namespace OpenSim.Region.CoreModules.Asset
112 //////////////////////////////////////////////////////////// 112 ////////////////////////////////////////////////////////////
113 // IImprovedAssetCache 113 // IImprovedAssetCache
114 // 114 //
115 public bool Check(string id)
116 {
117 return false;
118 }
115 119
116 public void Cache(AssetBase asset) 120 public void Cache(AssetBase asset)
117 { 121 {
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index 08d4fc0..f1fee63 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -248,57 +248,70 @@ namespace OpenSim.Region.CoreModules.Asset
248 248
249 private void UpdateFileCache(string key, AssetBase asset) 249 private void UpdateFileCache(string key, AssetBase asset)
250 { 250 {
251 string filename = GetFileName(asset.ID); 251 // TODO: Spawn this off to some seperate thread to do the actual writing
252 252 if (asset != null)
253 try
254 { 253 {
255 // If the file is already cached just update access time. 254 string filename = GetFileName(key);
256 if (File.Exists(filename)) 255
257 { 256 try
258 lock (m_CurrentlyWriting)
259 {
260 if (!m_CurrentlyWriting.Contains(filename))
261 File.SetLastAccessTime(filename, DateTime.Now);
262 }
263 }
264 else
265 { 257 {
266 // Once we start writing, make sure we flag that we're writing 258 // If the file is already cached, don't cache it, just touch it so access time is updated
267 // that object to the cache so that we don't try to write the 259 if (File.Exists(filename))
268 // same file multiple times.
269 lock (m_CurrentlyWriting)
270 { 260 {
271#if WAIT_ON_INPROGRESS_REQUESTS 261 // We don't really want to know about sharing
272 if (m_CurrentlyWriting.ContainsKey(filename)) 262 // violations here. If the file is locked, then
263 // the other thread has updated the time for us.
264 try
273 { 265 {
274 return; 266 lock (m_CurrentlyWriting)
267 {
268 if (!m_CurrentlyWriting.Contains(filename))
269 File.SetLastAccessTime(filename, DateTime.Now);
270 }
275 } 271 }
276 else 272 catch
277 {
278 m_CurrentlyWriting.Add(filename, new ManualResetEvent(false));
279 }
280
281#else
282 if (m_CurrentlyWriting.Contains(filename))
283 { 273 {
284 return;
285 } 274 }
286 else 275 } else {
276
277 // Once we start writing, make sure we flag that we're writing
278 // that object to the cache so that we don't try to write the
279 // same file multiple times.
280 lock (m_CurrentlyWriting)
287 { 281 {
288 m_CurrentlyWriting.Add(filename); 282#if WAIT_ON_INPROGRESS_REQUESTS
289 } 283 if (m_CurrentlyWriting.ContainsKey(filename))
284 {
285 return;
286 }
287 else
288 {
289 m_CurrentlyWriting.Add(filename, new ManualResetEvent(false));
290 }
291
292#else
293 if (m_CurrentlyWriting.Contains(filename))
294 {
295 return;
296 }
297 else
298 {
299 m_CurrentlyWriting.Add(filename);
300 }
290#endif 301#endif
291 }
292 302
293 Util.FireAndForget( 303 }
294 delegate { WriteFileCache(filename, asset); }); 304
305 Util.FireAndForget(
306 delegate { WriteFileCache(filename, asset); });
307 }
308 }
309 catch (Exception e)
310 {
311 m_log.ErrorFormat(
312 "[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}",
313 asset.ID, e.Message, e.StackTrace);
295 } 314 }
296 }
297 catch (Exception e)
298 {
299 m_log.WarnFormat(
300 "[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}",
301 asset.ID, e.Message, e.StackTrace);
302 } 315 }
303 } 316 }
304 317
@@ -332,6 +345,17 @@ namespace OpenSim.Region.CoreModules.Asset
332 return asset; 345 return asset;
333 } 346 }
334 347
348 private bool CheckFromMemoryCache(string id)
349 {
350 AssetBase asset = null;
351
352 if (m_MemoryCache.TryGetValue(id, out asset))
353 return true;
354
355 return false;
356 }
357
358
335 /// <summary> 359 /// <summary>
336 /// Try to get an asset from the file cache. 360 /// Try to get an asset from the file cache.
337 /// </summary> 361 /// </summary>
@@ -396,6 +420,7 @@ namespace OpenSim.Region.CoreModules.Asset
396 m_log.WarnFormat( 420 m_log.WarnFormat(
397 "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}", 421 "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}",
398 filename, id, e.Message, e.StackTrace); 422 filename, id, e.Message, e.StackTrace);
423
399 } 424 }
400 finally 425 finally
401 { 426 {
@@ -407,6 +432,50 @@ namespace OpenSim.Region.CoreModules.Asset
407 return asset; 432 return asset;
408 } 433 }
409 434
435 private bool CheckFromFileCache(string id)
436 {
437 bool found = false;
438
439 string filename = GetFileName(id);
440 if (File.Exists(filename))
441 {
442 // actually check if we can open it, and so update expire
443 FileStream stream = null;
444 try
445 {
446 stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
447 if (stream != null)
448 {
449 found = true;
450 stream.Close();
451 }
452
453 }
454 catch (System.Runtime.Serialization.SerializationException e)
455 {
456 found = false;
457 m_log.ErrorFormat(
458 "[FLOTSAM ASSET CACHE]: Failed to check file {0} for asset {1}. Exception {2} {3}",
459 filename, id, e.Message, e.StackTrace);
460
461 // If there was a problem deserializing the asset, the asset may
462 // either be corrupted OR was serialized under an old format
463 // {different version of AssetBase} -- we should attempt to
464 // delete it and re-cache
465 File.Delete(filename);
466 }
467 catch (Exception e)
468 {
469 found = false;
470 m_log.ErrorFormat(
471 "[FLOTSAM ASSET CACHE]: Failed to check file {0} for asset {1}. Exception {2} {3}",
472 filename, id, e.Message, e.StackTrace);
473 }
474 }
475
476 return found;
477 }
478
410 public AssetBase Get(string id) 479 public AssetBase Get(string id)
411 { 480 {
412 m_Requests++; 481 m_Requests++;
@@ -434,11 +503,26 @@ namespace OpenSim.Region.CoreModules.Asset
434 return asset; 503 return asset;
435 } 504 }
436 505
506 public bool Check(string id)
507 {
508 if (m_MemoryCacheEnabled && CheckFromMemoryCache(id))
509 return true;
510
511 if (m_FileCacheEnabled && CheckFromFileCache(id))
512 return true;
513 return false;
514 }
515
437 public AssetBase GetCached(string id) 516 public AssetBase GetCached(string id)
438 { 517 {
439 return Get(id); 518 return Get(id);
440 } 519 }
441 520
521 public AssetBase CheckCached(string id)
522 {
523 return Get(id);
524 }
525
442 public void Expire(string id) 526 public void Expire(string id)
443 { 527 {
444 if (m_LogLevel >= 2) 528 if (m_LogLevel >= 2)
@@ -983,6 +1067,11 @@ namespace OpenSim.Region.CoreModules.Asset
983 return asset.Data; 1067 return asset.Data;
984 } 1068 }
985 1069
1070 public bool CheckData(string id)
1071 {
1072 return Check(id); ;
1073 }
1074
986 public bool Get(string id, object sender, AssetRetrieved handler) 1075 public bool Get(string id, object sender, AssetRetrieved handler)
987 { 1076 {
988 AssetBase asset = Get(id); 1077 AssetBase asset = Get(id);
diff --git a/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs b/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs
index 9592ca0..ce9b546 100644
--- a/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs
@@ -115,6 +115,11 @@ namespace OpenSim.Region.CoreModules.Asset
115 // IImprovedAssetCache 115 // IImprovedAssetCache
116 // 116 //
117 117
118 public bool Check(string id)
119 {
120 return false;
121 }
122
118 public void Cache(AssetBase asset) 123 public void Cache(AssetBase asset)
119 { 124 {
120 if (asset != null) 125 if (asset != null)
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index aea768e..09cc998 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -145,33 +145,37 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
145 /// <param name="sp"></param> 145 /// <param name="sp"></param>
146 /// <param name="texture"></param> 146 /// <param name="texture"></param>
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, WearableCacheItem[] cacheItems)
149 { 149 {
150 DoSetAppearance(sp, appearance.Texture, appearance.VisualParams, new List<CachedTextureRequestArg>()); 150 SetAppearance(sp, appearance.Texture, appearance.VisualParams, cacheItems);
151 } 151 }
152 152
153 /// <summary> 153
154 /// Set appearance data (texture asset IDs and slider settings) 154 public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems)
155 /// </summary>
156 /// <param name="sp"></param>
157 /// <param name="texture"></param>
158 /// <param name="visualParam"></param>
159 public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams)
160 { 155 {
161 DoSetAppearance(sp, textureEntry, visualParams, new List<CachedTextureRequestArg>()); 156 float oldoff = sp.Appearance.AvatarFeetOffset;
157 Vector3 oldbox = sp.Appearance.AvatarBoxSize;
158
159 SetAppearance(sp, textureEntry, visualParams, cacheItems);
160 sp.Appearance.SetSize(avSize);
161
162 float off = sp.Appearance.AvatarFeetOffset;
163 Vector3 box = sp.Appearance.AvatarBoxSize;
164 if (oldoff != off || oldbox != box)
165 ((ScenePresence)sp).SetSize(box, off);
162 } 166 }
163 167
164 /// <summary> 168 /// <summary>
165 /// Set appearance data (texture asset IDs and slider settings) 169 /// Set appearance data (texture asset IDs and slider settings)
166 /// </summary> 170 /// </summary>
167 /// <param name="sp"></param> 171 /// <param name="sp"></param>
168 /// <param name="texture"></param> 172 /// <param name="texture"></param>
169 /// <param name="visualParam"></param> 173 /// <param name="visualParam"></param>
170 protected void DoSetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, List<CachedTextureRequestArg> hashes) 174 public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, WearableCacheItem[] cacheItems)
171 { 175 {
172 // m_log.DebugFormat( 176// m_log.DebugFormat(
173 // "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}", 177// "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}",
174 // sp.Name, textureEntry, visualParams); 178// sp.Name, textureEntry, visualParams);
175 179
176 // TODO: This is probably not necessary any longer, just assume the 180 // TODO: This is probably not necessary any longer, just assume the
177 // textureEntry set implies that the appearance transaction is complete 181 // textureEntry set implies that the appearance transaction is complete
@@ -190,36 +194,38 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
190 // m_log.DebugFormat( 194 // m_log.DebugFormat(
191 // "[AVFACTORY]: Setting visual params for {0} to {1}", 195 // "[AVFACTORY]: Setting visual params for {0} to {1}",
192 // client.Name, string.Join(", ", visualParamsStrings)); 196 // client.Name, string.Join(", ", visualParamsStrings));
193 197/*
194 float oldHeight = sp.Appearance.AvatarHeight; 198 float oldHeight = sp.Appearance.AvatarHeight;
195 changed = sp.Appearance.SetVisualParams(visualParams); 199 changed = sp.Appearance.SetVisualParams(visualParams);
196 200
197 if (sp.Appearance.AvatarHeight != oldHeight && sp.Appearance.AvatarHeight > 0) 201 if (sp.Appearance.AvatarHeight != oldHeight && sp.Appearance.AvatarHeight > 0)
198 ((ScenePresence)sp).SetHeight(sp.Appearance.AvatarHeight); 202 ((ScenePresence)sp).SetHeight(sp.Appearance.AvatarHeight);
199 } 203 */
204// float oldoff = sp.Appearance.AvatarFeetOffset;
205// Vector3 oldbox = sp.Appearance.AvatarBoxSize;
206 changed = sp.Appearance.SetVisualParams(visualParams);
207// float off = sp.Appearance.AvatarFeetOffset;
208// Vector3 box = sp.Appearance.AvatarBoxSize;
209// if(oldoff != off || oldbox != box)
210// ((ScenePresence)sp).SetSize(box,off);
200 211
212 }
213
201 // Process the baked texture array 214 // Process the baked texture array
202 if (textureEntry != null) 215 if (textureEntry != null)
203 { 216 {
204 // m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID); 217 m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID);
205 // WriteBakedTexturesReport(sp, m_log.DebugFormat); 218
219// WriteBakedTexturesReport(sp, m_log.DebugFormat);
206 220
207 changed = sp.Appearance.SetTextureEntries(textureEntry) || changed; 221 changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;
208 222
209 // WriteBakedTexturesReport(sp, m_log.DebugFormat); 223// WriteBakedTexturesReport(sp, m_log.DebugFormat);
210 224
211 // If bake textures are missing and this is not an NPC, request a rebake from client 225 // If bake textures are missing and this is not an NPC, request a rebake from client
212 if (!ValidateBakedTextureCache(sp) && (((ScenePresence)sp).PresenceType != PresenceType.Npc)) 226 if (!ValidateBakedTextureCache(sp) && (((ScenePresence)sp).PresenceType != PresenceType.Npc))
213 RequestRebake(sp, true); 227 RequestRebake(sp, true);
214 228
215 // Save the wearble hashes in the appearance
216 sp.Appearance.ResetTextureHashes();
217 if (m_reusetextures)
218 {
219 foreach (CachedTextureRequestArg arg in hashes)
220 sp.Appearance.SetTextureHash(arg.BakedTextureIndex,arg.WearableHashID);
221 }
222
223 // This appears to be set only in the final stage of the appearance 229 // This appears to be set only in the final stage of the appearance
224 // update transaction. In theory, we should be able to do an immediate 230 // update transaction. In theory, we should be able to do an immediate
225 // appearance send and save here. 231 // appearance send and save here.
@@ -253,13 +259,13 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
253 259
254 public bool SendAppearance(UUID agentId) 260 public bool SendAppearance(UUID agentId)
255 { 261 {
256 // m_log.DebugFormat("[AVFACTORY]: Sending appearance for {0}", agentId); 262// m_log.DebugFormat("[AVFACTORY]: Sending appearance for {0}", agentId);
257 263
258 ScenePresence sp = m_scene.GetScenePresence(agentId); 264 ScenePresence sp = m_scene.GetScenePresence(agentId);
259 if (sp == null) 265 if (sp == null)
260 { 266 {
261 // This is expected if the user has gone away. 267 // This is expected if the user has gone away.
262 // m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId); 268// m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId);
263 return false; 269 return false;
264 } 270 }
265 271
@@ -277,6 +283,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
277 return GetBakedTextureFaces(sp); 283 return GetBakedTextureFaces(sp);
278 } 284 }
279 285
286 public WearableCacheItem[] GetCachedItems(UUID agentId)
287 {
288 ScenePresence sp = m_scene.GetScenePresence(agentId);
289 WearableCacheItem[] items = sp.Appearance.WearableCacheItems;
290 //foreach (WearableCacheItem item in items)
291 //{
292
293 //}
294 return items;
295 }
296
280 public bool SaveBakedTextures(UUID agentId) 297 public bool SaveBakedTextures(UUID agentId)
281 { 298 {
282 ScenePresence sp = m_scene.GetScenePresence(agentId); 299 ScenePresence sp = m_scene.GetScenePresence(agentId);
@@ -336,7 +353,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
336 /// <param name="agentId"></param> 353 /// <param name="agentId"></param>
337 public void QueueAppearanceSend(UUID agentid) 354 public void QueueAppearanceSend(UUID agentid)
338 { 355 {
339 // m_log.DebugFormat("[AVFACTORY]: Queue appearance send for {0}", agentid); 356// m_log.DebugFormat("[AVFACTORY]: Queue appearance send for {0}", agentid);
340 357
341 // 10000 ticks per millisecond, 1000 milliseconds per second 358 // 10000 ticks per millisecond, 1000 milliseconds per second
342 long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 1000 * 10000); 359 long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 1000 * 10000);
@@ -349,7 +366,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
349 366
350 public void QueueAppearanceSave(UUID agentid) 367 public void QueueAppearanceSave(UUID agentid)
351 { 368 {
352 // m_log.DebugFormat("[AVFACTORY]: Queueing appearance save for {0}", agentid); 369// m_log.DebugFormat("[AVFACTORY]: Queueing appearance save for {0}", agentid);
353 370
354 // 10000 ticks per millisecond, 1000 milliseconds per second 371 // 10000 ticks per millisecond, 1000 milliseconds per second
355 long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000); 372 long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000);
@@ -363,6 +380,53 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
363 public bool ValidateBakedTextureCache(IScenePresence sp) 380 public bool ValidateBakedTextureCache(IScenePresence sp)
364 { 381 {
365 bool defonly = true; // are we only using default textures 382 bool defonly = true; // are we only using default textures
383 IImprovedAssetCache cache = m_scene.RequestModuleInterface<IImprovedAssetCache>();
384 IBakedTextureModule bakedModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
385 WearableCacheItem[] wearableCache = null;
386
387 // Cache wearable data for teleport.
388 // Only makes sense if there's a bake module and a cache module
389 if (bakedModule != null && cache != null)
390 {
391 try
392 {
393 wearableCache = bakedModule.Get(sp.UUID);
394 }
395 catch (Exception)
396 {
397
398 }
399 if (wearableCache != null)
400 {
401 for (int i = 0; i < wearableCache.Length; i++)
402 {
403 cache.Cache(wearableCache[i].TextureAsset);
404 }
405 }
406 }
407 /*
408 IBakedTextureModule bakedModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
409 if (invService.GetRootFolder(userID) != null)
410 {
411 WearableCacheItem[] wearableCache = null;
412 if (bakedModule != null)
413 {
414 try
415 {
416 wearableCache = bakedModule.Get(userID);
417 appearance.WearableCacheItems = wearableCache;
418 appearance.WearableCacheItemsDirty = false;
419 foreach (WearableCacheItem item in wearableCache)
420 {
421 appearance.Texture.FaceTextures[item.TextureIndex].TextureID = item.TextureID;
422 }
423 }
424 catch (Exception)
425 {
426
427 }
428 }
429 */
366 430
367 // Process the texture entry 431 // Process the texture entry
368 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) 432 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
@@ -370,13 +434,36 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
370 int idx = AvatarAppearance.BAKE_INDICES[i]; 434 int idx = AvatarAppearance.BAKE_INDICES[i];
371 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; 435 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
372 436
373 // if there is no texture entry, skip it 437 // No face, so lets check our baked service cache, teleport or login.
374 if (face == null) 438 if (face == null)
375 continue; 439 {
440 if (wearableCache != null)
441 {
442 // If we find the an appearance item, set it as the textureentry and the face
443 WearableCacheItem searchitem = WearableCacheItem.SearchTextureIndex((uint) idx, wearableCache);
444 if (searchitem != null)
445 {
446 sp.Appearance.Texture.FaceTextures[idx] = sp.Appearance.Texture.CreateFace((uint) idx);
447 sp.Appearance.Texture.FaceTextures[idx].TextureID = searchitem.TextureID;
448 face = sp.Appearance.Texture.FaceTextures[idx];
449 }
450 else
451 {
452 // if there is no texture entry and no baked cache, skip it
453 continue;
454 }
455 }
456 else
457 {
458 //No texture entry face and no cache. Skip this face.
459 continue;
460 }
461 }
462
376 463
377 // m_log.DebugFormat( 464// m_log.DebugFormat(
378 // "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}", 465// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}",
379 // face.TextureID, idx, client.Name, client.AgentId); 466// face.TextureID, idx, client.Name, client.AgentId);
380 467
381 // if the texture is one of the "defaults" then skip it 468 // if the texture is one of the "defaults" then skip it
382 // this should probably be more intelligent (skirt texture doesnt matter 469 // this should probably be more intelligent (skirt texture doesnt matter
@@ -387,11 +474,19 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
387 474
388 defonly = false; // found a non-default texture reference 475 defonly = false; // found a non-default texture reference
389 476
390 if (m_scene.AssetService.Get(face.TextureID.ToString()) == null) 477 if (cache != null)
391 return false; 478 {
479 if (!cache.Check(face.TextureID.ToString()))
480 return false;
481 }
482 else
483 {
484 if (m_scene.AssetService.Get(face.TextureID.ToString()) == null)
485 return false;
486 }
392 } 487 }
393 488
394 // m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID); 489// m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID);
395 490
396 // If we only found default textures, then the appearance is not cached 491 // If we only found default textures, then the appearance is not cached
397 return (defonly ? false : true); 492 return (defonly ? false : true);
@@ -400,6 +495,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
400 public int RequestRebake(IScenePresence sp, bool missingTexturesOnly) 495 public int RequestRebake(IScenePresence sp, bool missingTexturesOnly)
401 { 496 {
402 int texturesRebaked = 0; 497 int texturesRebaked = 0;
498 IImprovedAssetCache cache = m_scene.RequestModuleInterface<IImprovedAssetCache>();
403 499
404 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) 500 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
405 { 501 {
@@ -410,9 +506,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
410 if (face == null) 506 if (face == null)
411 continue; 507 continue;
412 508
413 // m_log.DebugFormat( 509// m_log.DebugFormat(
414 // "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}", 510// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}",
415 // face.TextureID, idx, client.Name, client.AgentId); 511// face.TextureID, idx, client.Name, client.AgentId);
416 512
417 // if the texture is one of the "defaults" then skip it 513 // if the texture is one of the "defaults" then skip it
418 // this should probably be more intelligent (skirt texture doesnt matter 514 // this should probably be more intelligent (skirt texture doesnt matter
@@ -423,21 +519,36 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
423 519
424 if (missingTexturesOnly) 520 if (missingTexturesOnly)
425 { 521 {
426 if (m_scene.AssetService.Get(face.TextureID.ToString()) != null) 522 if (cache != null)
427 { 523 {
428 continue; 524 if (cache.Check(face.TextureID.ToString()))
525 continue;
526 else
527 {
528 m_log.DebugFormat(
529 "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.",
530 face.TextureID, idx, sp.Name);
531 }
429 } 532 }
430 else 533 else
431 { 534 {
432 // On inter-simulator teleports, this occurs if baked textures are not being stored by the 535 if (m_scene.AssetService.Get(face.TextureID.ToString()) != null)
433 // grid asset service (which means that they are not available to the new region and so have 536 {
434 // to be re-requested from the client). 537 continue;
435 // 538 }
436 // The only available core OpenSimulator behaviour right now 539
437 // is not to store these textures, temporarily or otherwise. 540 else
438 m_log.DebugFormat( 541 {
439 "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.", 542 // On inter-simulator teleports, this occurs if baked textures are not being stored by the
440 face.TextureID, idx, sp.Name); 543 // grid asset service (which means that they are not available to the new region and so have
544 // to be re-requested from the client).
545 //
546 // The only available core OpenSimulator behaviour right now
547 // is not to store these textures, temporarily or otherwise.
548 m_log.DebugFormat(
549 "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.",
550 face.TextureID, idx, sp.Name);
551 }
441 } 552 }
442 } 553 }
443 else 554 else
@@ -476,9 +587,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
476 if (bakeType == BakeType.Unknown) 587 if (bakeType == BakeType.Unknown)
477 continue; 588 continue;
478 589
479 // m_log.DebugFormat( 590// m_log.DebugFormat(
480 // "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}", 591// "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}",
481 // acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]); 592// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]);
482 593
483 int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType); 594 int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType);
484 Primitive.TextureEntryFace texture = faceTextures[ftIndex]; // this will be null if there's no such baked texture 595 Primitive.TextureEntryFace texture = faceTextures[ftIndex]; // this will be null if there's no such baked texture
@@ -502,7 +613,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
502 UUID avatarID = kvp.Key; 613 UUID avatarID = kvp.Key;
503 long sendTime = kvp.Value; 614 long sendTime = kvp.Value;
504 615
505 // m_log.DebugFormat("[AVFACTORY]: Handling queued appearance updates for {0}, update delta to now is {1}", avatarID, sendTime - now); 616// m_log.DebugFormat("[AVFACTORY]: Handling queued appearance updates for {0}, update delta to now is {1}", avatarID, sendTime - now);
506 617
507 if (sendTime < now) 618 if (sendTime < now)
508 { 619 {
@@ -548,11 +659,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
548 if (sp == null) 659 if (sp == null)
549 { 660 {
550 // This is expected if the user has gone away. 661 // This is expected if the user has gone away.
551 // m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid); 662// m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid);
552 return; 663 return;
553 } 664 }
554 665
555 // m_log.DebugFormat("[AVFACTORY]: Saving appearance for avatar {0}", agentid); 666// m_log.DebugFormat("[AVFACTORY]: Saving appearance for avatar {0}", agentid);
556 667
557 // This could take awhile since it needs to pull inventory 668 // This could take awhile since it needs to pull inventory
558 // 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 669 // 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
@@ -579,26 +690,70 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
579 private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance) 690 private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance)
580 { 691 {
581 IInventoryService invService = m_scene.InventoryService; 692 IInventoryService invService = m_scene.InventoryService;
582 693 bool resetwearable = false;
583 if (invService.GetRootFolder(userID) != null) 694 if (invService.GetRootFolder(userID) != null)
584 { 695 {
585 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) 696 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
586 { 697 {
587 for (int j = 0; j < appearance.Wearables[i].Count; j++) 698 for (int j = 0; j < appearance.Wearables[i].Count; j++)
588 { 699 {
700 // Check if the default wearables are not set
589 if (appearance.Wearables[i][j].ItemID == UUID.Zero) 701 if (appearance.Wearables[i][j].ItemID == UUID.Zero)
702 {
703 switch ((WearableType) i)
704 {
705 case WearableType.Eyes:
706 case WearableType.Hair:
707 case WearableType.Shape:
708 case WearableType.Skin:
709 //case WearableType.Underpants:
710 TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
711 resetwearable = true;
712 m_log.Warn("[AVFACTORY]: UUID.Zero Wearables, passing fake values.");
713 resetwearable = true;
714 break;
715
716 }
590 continue; 717 continue;
718 }
591 719
592 // Ignore ruth's assets 720 // Ignore ruth's assets except for the body parts! missing body parts fail avatar appearance on V1
593 if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID) 721 if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID)
722 {
723 switch ((WearableType)i)
724 {
725 case WearableType.Eyes:
726 case WearableType.Hair:
727 case WearableType.Shape:
728 case WearableType.Skin:
729 //case WearableType.Underpants:
730 TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
731
732 m_log.WarnFormat("[AVFACTORY]: {0} Default Wearables, passing existing values.", (WearableType)i);
733 resetwearable = true;
734 break;
735
736 }
594 continue; 737 continue;
595 738 }
739
596 InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID); 740 InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID);
597 baseItem = invService.GetItem(baseItem); 741 baseItem = invService.GetItem(baseItem);
598 742
599 if (baseItem != null) 743 if (baseItem != null)
600 { 744 {
601 appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID); 745 appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID);
746 int unmodifiedWearableIndexForClosure = i;
747 m_scene.AssetService.Get(baseItem.AssetID.ToString(), this,
748 delegate(string x, object y, AssetBase z)
749 {
750 if (z == null)
751 {
752 TryAndRepairBrokenWearable(
753 (WearableType)unmodifiedWearableIndexForClosure, invService,
754 userID, appearance);
755 }
756 });
602 } 757 }
603 else 758 else
604 { 759 {
@@ -606,17 +761,236 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
606 "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default", 761 "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default",
607 appearance.Wearables[i][j].ItemID, (WearableType)i); 762 appearance.Wearables[i][j].ItemID, (WearableType)i);
608 763
609 appearance.Wearables[i].RemoveItem(appearance.Wearables[i][j].ItemID); 764 TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
765 resetwearable = true;
766
610 } 767 }
611 } 768 }
612 } 769 }
770
771 // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
772 if (appearance.Wearables[(int) WearableType.Eyes] == null)
773 {
774 m_log.WarnFormat("[AVFACTORY]: {0} Eyes are Null, passing existing values.", (WearableType.Eyes));
775
776 TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance);
777 resetwearable = true;
778 }
779 else
780 {
781 if (appearance.Wearables[(int) WearableType.Eyes][0].ItemID == UUID.Zero)
782 {
783 m_log.WarnFormat("[AVFACTORY]: Eyes are UUID.Zero are broken, {0} {1}",
784 appearance.Wearables[(int) WearableType.Eyes][0].ItemID,
785 appearance.Wearables[(int) WearableType.Eyes][0].AssetID);
786 TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance);
787 resetwearable = true;
788
789 }
790
791 }
792 // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
793 if (appearance.Wearables[(int)WearableType.Shape] == null)
794 {
795 m_log.WarnFormat("[AVFACTORY]: {0} shape is Null, passing existing values.", (WearableType.Shape));
796
797 TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance);
798 resetwearable = true;
799 }
800 else
801 {
802 if (appearance.Wearables[(int)WearableType.Shape][0].ItemID == UUID.Zero)
803 {
804 m_log.WarnFormat("[AVFACTORY]: Shape is UUID.Zero and broken, {0} {1}",
805 appearance.Wearables[(int)WearableType.Shape][0].ItemID,
806 appearance.Wearables[(int)WearableType.Shape][0].AssetID);
807 TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance);
808 resetwearable = true;
809
810 }
811
812 }
813 // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
814 if (appearance.Wearables[(int)WearableType.Hair] == null)
815 {
816 m_log.WarnFormat("[AVFACTORY]: {0} Hair is Null, passing existing values.", (WearableType.Hair));
817
818 TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance);
819 resetwearable = true;
820 }
821 else
822 {
823 if (appearance.Wearables[(int)WearableType.Hair][0].ItemID == UUID.Zero)
824 {
825 m_log.WarnFormat("[AVFACTORY]: Hair is UUID.Zero and broken, {0} {1}",
826 appearance.Wearables[(int)WearableType.Hair][0].ItemID,
827 appearance.Wearables[(int)WearableType.Hair][0].AssetID);
828 TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance);
829 resetwearable = true;
830
831 }
832
833 }
834 // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
835 if (appearance.Wearables[(int)WearableType.Skin] == null)
836 {
837 m_log.WarnFormat("[AVFACTORY]: {0} Skin is Null, passing existing values.", (WearableType.Skin));
838
839 TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance);
840 resetwearable = true;
841 }
842 else
843 {
844 if (appearance.Wearables[(int)WearableType.Skin][0].ItemID == UUID.Zero)
845 {
846 m_log.WarnFormat("[AVFACTORY]: Skin is UUID.Zero and broken, {0} {1}",
847 appearance.Wearables[(int)WearableType.Skin][0].ItemID,
848 appearance.Wearables[(int)WearableType.Skin][0].AssetID);
849 TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance);
850 resetwearable = true;
851
852 }
853
854 }
855 if (resetwearable)
856 {
857 ScenePresence presence = null;
858 if (m_scene.TryGetScenePresence(userID, out presence))
859 {
860 presence.ControllingClient.SendWearables(presence.Appearance.Wearables,
861 presence.Appearance.Serial++);
862 }
863 }
864
613 } 865 }
614 else 866 else
615 { 867 {
616 m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID); 868 m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID);
617 } 869 }
618 } 870 }
871 private void TryAndRepairBrokenWearable(WearableType type, IInventoryService invService, UUID userID,AvatarAppearance appearance)
872 {
873 UUID defaultwearable = GetDefaultItem(type);
874 if (defaultwearable != UUID.Zero)
875 {
876 UUID newInvItem = UUID.Random();
877 InventoryItemBase itembase = new InventoryItemBase(newInvItem, userID)
878 {
879 AssetID =
880 defaultwearable,
881 AssetType
882 =
883 (int)
884 AssetType
885 .Bodypart,
886 CreatorId
887 =
888 userID
889 .ToString
890 (),
891 //InvType = (int)InventoryType.Wearable,
892
893 Description
894 =
895 "Failed Wearable Replacement",
896 Folder =
897 invService
898 .GetFolderForType
899 (userID,
900 AssetType
901 .Bodypart)
902 .ID,
903 Flags = (uint) type,
904 Name = Enum.GetName(typeof (WearableType), type),
905 BasePermissions = (uint) PermissionMask.Copy,
906 CurrentPermissions = (uint) PermissionMask.Copy,
907 EveryOnePermissions = (uint) PermissionMask.Copy,
908 GroupPermissions = (uint) PermissionMask.Copy,
909 NextPermissions = (uint) PermissionMask.Copy
910 };
911 invService.AddItem(itembase);
912 UUID LinkInvItem = UUID.Random();
913 itembase = new InventoryItemBase(LinkInvItem, userID)
914 {
915 AssetID =
916 newInvItem,
917 AssetType
918 =
919 (int)
920 AssetType
921 .Link,
922 CreatorId
923 =
924 userID
925 .ToString
926 (),
927 InvType = (int) InventoryType.Wearable,
928
929 Description
930 =
931 "Failed Wearable Replacement",
932 Folder =
933 invService
934 .GetFolderForType
935 (userID,
936 AssetType
937 .CurrentOutfitFolder)
938 .ID,
939 Flags = (uint) type,
940 Name = Enum.GetName(typeof (WearableType), type),
941 BasePermissions = (uint) PermissionMask.Copy,
942 CurrentPermissions = (uint) PermissionMask.Copy,
943 EveryOnePermissions = (uint) PermissionMask.Copy,
944 GroupPermissions = (uint) PermissionMask.Copy,
945 NextPermissions = (uint) PermissionMask.Copy
946 };
947 invService.AddItem(itembase);
948 appearance.Wearables[(int)type] = new AvatarWearable(newInvItem, GetDefaultItem(type));
949 ScenePresence presence = null;
950 if (m_scene.TryGetScenePresence(userID, out presence))
951 {
952 m_scene.SendInventoryUpdate(presence.ControllingClient,
953 invService.GetFolderForType(userID,
954 AssetType
955 .CurrentOutfitFolder),
956 false, true);
957 }
958 }
959 }
960 private UUID GetDefaultItem(WearableType wearable)
961 {
962 // These are ruth
963 UUID ret = UUID.Zero;
964 switch (wearable)
965 {
966 case WearableType.Eyes:
967 ret = new UUID("4bb6fa4d-1cd2-498a-a84c-95c1a0e745a7");
968 break;
969 case WearableType.Hair:
970 ret = new UUID("d342e6c0-b9d2-11dc-95ff-0800200c9a66");
971 break;
972 case WearableType.Pants:
973 ret = new UUID("00000000-38f9-1111-024e-222222111120");
974 break;
975 case WearableType.Shape:
976 ret = new UUID("66c41e39-38f9-f75a-024e-585989bfab73");
977 break;
978 case WearableType.Shirt:
979 ret = new UUID("00000000-38f9-1111-024e-222222111110");
980 break;
981 case WearableType.Skin:
982 ret = new UUID("77c41e39-38f9-f75a-024e-585989bbabbb");
983 break;
984 case WearableType.Undershirt:
985 ret = new UUID("16499ebb-3208-ec27-2def-481881728f47");
986 break;
987 case WearableType.Underpants:
988 ret = new UUID("4ac2e9c7-3671-d229-316a-67717730841d");
989 break;
990 }
619 991
992 return ret;
993 }
620 #endregion 994 #endregion
621 995
622 #region Client Event Handlers 996 #region Client Event Handlers
@@ -626,12 +1000,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
626 /// <param name="client"></param> 1000 /// <param name="client"></param>
627 private void Client_OnRequestWearables(IClientAPI client) 1001 private void Client_OnRequestWearables(IClientAPI client)
628 { 1002 {
629 // m_log.DebugFormat("[AVFACTORY]: Client_OnRequestWearables called for {0} ({1})", client.Name, client.AgentId); 1003 Util.FireAndForget(delegate(object x)
630 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 1004 {
631 if (sp != null) 1005 Thread.Sleep(4000);
632 client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++); 1006
633 else 1007 // m_log.DebugFormat("[AVFACTORY]: Client_OnRequestWearables called for {0} ({1})", client.Name, client.AgentId);
634 m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId); 1008 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
1009 if (sp != null)
1010 client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++);
1011 else
1012 m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId);
1013 });
635 } 1014 }
636 1015
637 /// <summary> 1016 /// <summary>
@@ -640,12 +1019,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
640 /// <param name="client"></param> 1019 /// <param name="client"></param>
641 /// <param name="texture"></param> 1020 /// <param name="texture"></param>
642 /// <param name="visualParam"></param> 1021 /// <param name="visualParam"></param>
643 private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams, List<CachedTextureRequestArg> hashes) 1022 private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems)
644 { 1023 {
645 // m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId); 1024 // m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId);
646 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 1025 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
647 if (sp != null) 1026 if (sp != null)
648 DoSetAppearance(sp, textureEntry, visualParams, hashes); 1027 SetAppearance(sp, textureEntry, visualParams,avSize, cacheItems);
649 else 1028 else
650 m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId); 1029 m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId);
651 } 1030 }
@@ -702,7 +1081,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
702 /// <param name="cachedTextureRequest"></param> 1081 /// <param name="cachedTextureRequest"></param>
703 private void Client_OnCachedTextureRequest(IClientAPI client, int serial, List<CachedTextureRequestArg> cachedTextureRequest) 1082 private void Client_OnCachedTextureRequest(IClientAPI client, int serial, List<CachedTextureRequestArg> cachedTextureRequest)
704 { 1083 {
705 // m_log.DebugFormat("[AVFACTORY]: Client_OnCachedTextureRequest called for {0} ({1})", client.Name, client.AgentId); 1084 // m_log.WarnFormat("[AVFACTORY]: Client_OnCachedTextureRequest called for {0} ({1})", client.Name, client.AgentId);
706 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 1085 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
707 1086
708 List<CachedTextureResponseArg> cachedTextureResponse = new List<CachedTextureResponseArg>(); 1087 List<CachedTextureResponseArg> cachedTextureResponse = new List<CachedTextureResponseArg>();
@@ -713,20 +1092,23 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
713 1092
714 if (m_reusetextures) 1093 if (m_reusetextures)
715 { 1094 {
716 if (sp.Appearance.GetTextureHash(index) == request.WearableHashID) 1095 // this is the most insanely dumb way to do this... however it seems to
717 { 1096 // actually work. if the appearance has been reset because wearables have
718 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[index]; 1097 // changed then the texture entries are zero'd out until the bakes are
719 if (face != null) 1098 // uploaded. on login, if the textures exist in the cache (eg if you logged
720 texture = face.TextureID; 1099 // into the simulator recently, then the appearance will pull those and send
721 } 1100 // them back in the packet and you won't have to rebake. if the textures aren't
722 else 1101 // in the cache then the intial makeroot() call in scenepresence will zero
723 { 1102 // them out.
724 // We know that that hash is wrong, null it out 1103 //
725 // and wait for the setappearance call 1104 // a better solution (though how much better is an open question) is to
726 sp.Appearance.SetTextureHash(index,UUID.Zero); 1105 // store the hashes in the appearance and compare them. Thats's coming.
727 } 1106
728 1107 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[index];
729 // m_log.WarnFormat("[AVFACTORY]: use texture {0} for index {1}; hash={2}",texture,index,request.WearableHashID); 1108 if (face != null)
1109 texture = face.TextureID;
1110
1111 // m_log.WarnFormat("[AVFACTORY]: reuse texture {0} for index {1}",texture,index);
730 } 1112 }
731 1113
732 CachedTextureResponseArg response = new CachedTextureResponseArg(); 1114 CachedTextureResponseArg response = new CachedTextureResponseArg();
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs
index 1830d41..ff4c6c9 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs
@@ -61,10 +61,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
61 for (byte i = 0; i < visualParams.Length; i++) 61 for (byte i = 0; i < visualParams.Length; i++)
62 visualParams[i] = i; 62 visualParams[i] = i;
63 63
64 afm.SetAppearance(sp, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams); 64// afm.SetAppearance(sp, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams);
65 65
66 // TODO: Check baked texture 66 // TODO: Check baked texture
67 Assert.AreEqual(visualParams, sp.Appearance.VisualParams); 67// Assert.AreEqual(visualParams, sp.Appearance.VisualParams);
68 } 68 }
69 69
70 [Test] 70 [Test]
@@ -102,6 +102,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
102 Primitive.TextureEntryFace eyesFace = bakedTextureEntry.CreateFace(eyesFaceIndex); 102 Primitive.TextureEntryFace eyesFace = bakedTextureEntry.CreateFace(eyesFaceIndex);
103 eyesFace.TextureID = eyesTextureId; 103 eyesFace.TextureID = eyesTextureId;
104 104
105/*
105 afm.SetAppearance(sp, bakedTextureEntry, visualParams); 106 afm.SetAppearance(sp, bakedTextureEntry, visualParams);
106 afm.SaveBakedTextures(userId); 107 afm.SaveBakedTextures(userId);
107// Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = afm.GetBakedTextureFaces(userId); 108// Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = afm.GetBakedTextureFaces(userId);
@@ -113,6 +114,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
113 Assert.That(eyesBake, Is.Not.Null); 114 Assert.That(eyesBake, Is.Not.Null);
114 Assert.That(eyesBake.Temporary, Is.False); 115 Assert.That(eyesBake.Temporary, Is.False);
115 Assert.That(eyesBake.Local, Is.False); 116 Assert.That(eyesBake.Local, Is.False);
117*/
116 } 118 }
117 } 119 }
118} \ No newline at end of file 120}
diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs
index 80dfa04..7e50cc6 100644
--- a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs
@@ -270,6 +270,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
270 // Notes 270 // Notes
271 client.AddGenericPacketHandler("avatarnotesrequest", NotesRequest); 271 client.AddGenericPacketHandler("avatarnotesrequest", NotesRequest);
272 client.OnAvatarNotesUpdate += NotesUpdate; 272 client.OnAvatarNotesUpdate += NotesUpdate;
273
274 // Preferences
275 client.OnUserInfoRequest += UserPreferencesRequest;
276 client.OnUpdateUserInfo += UpdateUserPreferences;
273 } 277 }
274 #endregion Region Event Handlers 278 #endregion Region Event Handlers
275 279
@@ -754,8 +758,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
754 IClientAPI remoteClient = (IClientAPI)sender; 758 IClientAPI remoteClient = (IClientAPI)sender;
755 string serverURI = string.Empty; 759 string serverURI = string.Empty;
756 GetUserProfileServerURI(remoteClient.AgentId, out serverURI); 760 GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
757 note.TargetId = remoteClient.AgentId; 761 note.UserId = remoteClient.AgentId;
758 UUID.TryParse(args[0], out note.UserId); 762 UUID.TryParse(args[0], out note.TargetId);
759 763
760 object Note = (object)note; 764 object Note = (object)note;
761 if(!JsonRpcRequest(ref Note, "avatarnotesrequest", serverURI, UUID.Random().ToString())) 765 if(!JsonRpcRequest(ref Note, "avatarnotesrequest", serverURI, UUID.Random().ToString()))
@@ -799,6 +803,69 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
799 } 803 }
800 #endregion Notes 804 #endregion Notes
801 805
806 #region User Preferences
807 /// <summary>
808 /// Updates the user preferences.
809 /// </summary>
810 /// <param name='imViaEmail'>
811 /// Im via email.
812 /// </param>
813 /// <param name='visible'>
814 /// Visible.
815 /// </param>
816 /// <param name='remoteClient'>
817 /// Remote client.
818 /// </param>
819 public void UpdateUserPreferences(bool imViaEmail, bool visible, IClientAPI remoteClient)
820 {
821 UserPreferences pref = new UserPreferences();
822
823 pref.UserId = remoteClient.AgentId;
824 pref.IMViaEmail = imViaEmail;
825 pref.Visible = visible;
826
827 string serverURI = string.Empty;
828 bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
829
830 object Pref = pref;
831 if(!JsonRpcRequest(ref Pref, "user_preferences_update", serverURI, UUID.Random().ToString()))
832 {
833 m_log.InfoFormat("[PROFILES]: UserPreferences update error");
834 remoteClient.SendAgentAlertMessage("Error updating preferences", false);
835 return;
836 }
837 }
838
839 /// <summary>
840 /// Users the preferences request.
841 /// </summary>
842 /// <param name='remoteClient'>
843 /// Remote client.
844 /// </param>
845 public void UserPreferencesRequest(IClientAPI remoteClient)
846 {
847 UserPreferences pref = new UserPreferences();
848
849 pref.UserId = remoteClient.AgentId;
850
851 string serverURI = string.Empty;
852 bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
853
854
855 object Pref = (object)pref;
856 if(!JsonRpcRequest(ref Pref, "user_preferences_request", serverURI, UUID.Random().ToString()))
857 {
858 m_log.InfoFormat("[PROFILES]: UserPreferences request error");
859 remoteClient.SendAgentAlertMessage("Error requesting preferences", false);
860 return;
861 }
862 pref = (UserPreferences) Pref;
863
864 remoteClient.SendUserInfoReply(pref.IMViaEmail, pref.Visible, pref.EMail);
865
866 }
867 #endregion User Preferences
868
802 #region Avatar Properties 869 #region Avatar Properties
803 /// <summary> 870 /// <summary>
804 /// Update the avatars interests . 871 /// Update the avatars interests .
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 1bb3e3b..4954cd9 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -410,7 +410,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
410 /// <param name="sp"></param> 410 /// <param name="sp"></param>
411 /// <param name="position"></param> 411 /// <param name="position"></param>
412 /// <param name="lookAt"></param> 412 /// <param name="lookAt"></param>
413 /// <param name="teleportFlags"></param 413 /// <param name="teleportFlags"></param>
414 private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags) 414 private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags)
415 { 415 {
416 m_log.DebugFormat( 416 m_log.DebugFormat(
@@ -442,11 +442,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
442 position.Z = newPosZ; 442 position.Z = newPosZ;
443 } 443 }
444 444
445 if (sp.Flying)
446 teleportFlags |= (uint)TeleportFlags.IsFlying;
447
445 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); 448 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
446 449
447 sp.ControllingClient.SendTeleportStart(teleportFlags); 450 sp.ControllingClient.SendTeleportStart(teleportFlags);
448 451
449 sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); 452 sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags);
453 sp.TeleportFlags = (Constants.TeleportFlags)teleportFlags;
450 sp.Velocity = Vector3.Zero; 454 sp.Velocity = Vector3.Zero;
451 sp.Teleport(position); 455 sp.Teleport(position);
452 456
@@ -649,8 +653,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
649 // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, 653 // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field,
650 // it's actually doing a lot of work. 654 // it's actually doing a lot of work.
651 IPEndPoint endPoint = finalDestination.ExternalEndPoint; 655 IPEndPoint endPoint = finalDestination.ExternalEndPoint;
652 656 if (endPoint == null || endPoint.Address == null)
653 if (endPoint.Address == null)
654 { 657 {
655 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); 658 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down");
656 659
@@ -689,6 +692,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
689 // both regions 692 // both regions
690 if (sp.ParentID != (uint)0) 693 if (sp.ParentID != (uint)0)
691 sp.StandUp(); 694 sp.StandUp();
695 else if (sp.Flying)
696 teleportFlags |= (uint)TeleportFlags.IsFlying;
692 697
693 if (DisableInterRegionTeleportCancellation) 698 if (DisableInterRegionTeleportCancellation)
694 teleportFlags |= (uint)TeleportFlags.DisableCancel; 699 teleportFlags |= (uint)TeleportFlags.DisableCancel;
@@ -1316,11 +1321,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1316 1321
1317 #region Teleport Home 1322 #region Teleport Home
1318 1323
1319 public virtual void TriggerTeleportHome(UUID id, IClientAPI client) 1324 public virtual void TriggerTeleportHome(UUID id, IClientAPI client)
1320 { 1325 {
1321 TeleportHome(id, client); 1326 TeleportHome(id, client);
1322 } 1327 }
1323 1328
1324 public virtual bool TeleportHome(UUID id, IClientAPI client) 1329 public virtual bool TeleportHome(UUID id, IClientAPI client)
1325 { 1330 {
1326 m_log.DebugFormat( 1331 m_log.DebugFormat(
@@ -1331,6 +1336,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1331 1336
1332 if (uinfo != null) 1337 if (uinfo != null)
1333 { 1338 {
1339 if (uinfo.HomeRegionID == UUID.Zero)
1340 {
1341 // can't find the Home region: Tell viewer and abort
1342 m_log.ErrorFormat("{0} No grid user info found for {1} {2}. Cannot send home.",
1343 LogHeader, client.Name, client.AgentId);
1344 client.SendTeleportFailed("You don't have a home position set.");
1345 return false;
1346 }
1334 GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); 1347 GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID);
1335 if (regionInfo == null) 1348 if (regionInfo == null)
1336 { 1349 {
@@ -1350,9 +1363,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1350 } 1363 }
1351 else 1364 else
1352 { 1365 {
1353 m_log.ErrorFormat( 1366 // can't find the Home region: Tell viewer and abort
1354 "[ENTITY TRANSFER MODULE]: No grid user information found for {0} {1}. Cannot send home.", 1367 client.SendTeleportFailed("Your home region could not be found.");
1355 client.Name, client.AgentId);
1356 } 1368 }
1357 return false; 1369 return false;
1358 } 1370 }
@@ -1362,177 +1374,21 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1362 1374
1363 #region Agent Crossings 1375 #region Agent Crossings
1364 1376
1365 public bool Cross(ScenePresence agent, bool isFlying) 1377 // Given a position relative to the current region (which has previously been tested to
1378 // see that it is actually outside the current region), find the new region that the
1379 // point is actually in.
1380 // Returns the coordinates and information of the new region or 'null' of it doesn't exist.
1381 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out string version, out Vector3 newpos)
1366 { 1382 {
1367 Scene scene = agent.Scene; 1383 version = String.Empty;
1368 Vector3 pos = agent.AbsolutePosition; 1384 newpos = new Vector3(pos.X, pos.Y, pos.Z);
1369 1385
1370// m_log.DebugFormat( 1386// m_log.DebugFormat(
1371// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); 1387// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name);
1372 /*
1373
1374 Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z);
1375 uint neighbourx = scene.RegionInfo.LegacyRegionLocX;
1376 uint neighboury = scene.RegionInfo.LegacyRegionLocY;
1377 const float boundaryDistance = 1.7f;
1378 Vector3 northCross = new Vector3(0, boundaryDistance, 0);
1379 Vector3 southCross = new Vector3(0, -1 * boundaryDistance, 0);
1380 Vector3 eastCross = new Vector3(boundaryDistance, 0, 0);
1381 Vector3 westCross = new Vector3(-1 * boundaryDistance, 0, 0);
1382
1383 // distance into new region to place avatar
1384 const float enterDistance = 0.5f;
1385
1386 if (scene.TestBorderCross(pos + westCross, Cardinals.W))
1387 {
1388 if (scene.TestBorderCross(pos + northCross, Cardinals.N))
1389 {
1390 Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N);
1391 neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize);
1392 }
1393 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1394 {
1395 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S);
1396 if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0)
1397 {
1398 neighboury--;
1399 newpos.Y = Constants.RegionSize - enterDistance;
1400 }
1401 else
1402 {
1403 agent.IsInTransit = true;
1404
1405 neighboury = b.TriggerRegionY;
1406 neighbourx = b.TriggerRegionX;
1407
1408 Vector3 newposition = pos;
1409 newposition.X += (scene.RegionInfo.LegacyRegionLocX - neighbourx) * Constants.RegionSize;
1410 newposition.Y += (scene.RegionInfo.LegacyRegionLocY - neighboury) * Constants.RegionSize;
1411 agent.ControllingClient.SendAgentAlertMessage(
1412 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1413 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
1414 return true;
1415 }
1416 }
1417
1418 Border ba = scene.GetCrossedBorder(pos + westCross, Cardinals.W);
1419 if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0)
1420 {
1421 neighbourx--;
1422 newpos.X = Constants.RegionSize - enterDistance;
1423 }
1424 else
1425 {
1426 agent.IsInTransit = true;
1427
1428 neighboury = ba.TriggerRegionY;
1429 neighbourx = ba.TriggerRegionX;
1430
1431 Vector3 newposition = pos;
1432 newposition.X += (scene.RegionInfo.LegacyRegionLocX - neighbourx) * Constants.RegionSize;
1433 newposition.Y += (scene.RegionInfo.LegacyRegionLocY - neighboury) * Constants.RegionSize;
1434 agent.ControllingClient.SendAgentAlertMessage(
1435 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1436 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
1437
1438 return true;
1439 }
1440
1441 }
1442 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E))
1443 {
1444 Border b = scene.GetCrossedBorder(pos + eastCross, Cardinals.E);
1445 neighbourx += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize);
1446 newpos.X = enterDistance;
1447
1448 if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1449 {
1450 Border ba = scene.GetCrossedBorder(pos + southCross, Cardinals.S);
1451 if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0)
1452 {
1453 neighboury--;
1454 newpos.Y = Constants.RegionSize - enterDistance;
1455 }
1456 else
1457 {
1458 agent.IsInTransit = true;
1459
1460 neighboury = ba.TriggerRegionY;
1461 neighbourx = ba.TriggerRegionX;
1462 Vector3 newposition = pos;
1463 newposition.X += (scene.RegionInfo.LegacyRegionLocX - neighbourx) * Constants.RegionSize;
1464 newposition.Y += (scene.RegionInfo.LegacyRegionLocY - neighboury) * Constants.RegionSize;
1465 agent.ControllingClient.SendAgentAlertMessage(
1466 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1467 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
1468 return true;
1469 }
1470 }
1471 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
1472 {
1473 Border c = scene.GetCrossedBorder(pos + northCross, Cardinals.N);
1474 neighboury += (uint)(int)(c.BorderLine.Z / (int)Constants.RegionSize);
1475 newpos.Y = enterDistance;
1476 }
1477 }
1478 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1479 {
1480 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S);
1481 if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0)
1482 {
1483 neighboury--;
1484 newpos.Y = Constants.RegionSize - enterDistance;
1485 }
1486 else
1487 {
1488 agent.IsInTransit = true;
1489
1490 neighboury = b.TriggerRegionY;
1491 neighbourx = b.TriggerRegionX;
1492 Vector3 newposition = pos;
1493 newposition.X += (scene.RegionInfo.LegacyRegionLocX - neighbourx) * Constants.RegionSize;
1494 newposition.Y += (scene.RegionInfo.LegacyRegionLocY - neighboury) * Constants.RegionSize;
1495 agent.ControllingClient.SendAgentAlertMessage(
1496 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1497 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
1498 return true;
1499 }
1500 }
1501 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
1502 {
1503 Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N);
1504 neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize);
1505 newpos.Y = enterDistance;
1506 }
1507 */
1508
1509 /*
1510
1511 if (pos.X < boundaryDistance) //West
1512 {
1513 neighbourx--;
1514 newpos.X = Constants.RegionSize - enterDistance;
1515 }
1516 else if (pos.X > Constants.RegionSize - boundaryDistance) // East
1517 {
1518 neighbourx++;
1519 newpos.X = enterDistance;
1520 }
1521
1522 if (pos.Y < boundaryDistance) // South
1523 {
1524 neighboury--;
1525 newpos.Y = Constants.RegionSize - enterDistance;
1526 }
1527 else if (pos.Y > Constants.RegionSize - boundaryDistance) // North
1528 {
1529 neighboury++;
1530 newpos.Y = enterDistance;
1531 }
1532 */
1533 1388
1534 double presenceWorldX = (double)scene.RegionInfo.RegionLocX + pos.X; 1389 // Compute world location of the object's position
1535 double presenceWorldY = (double)scene.RegionInfo.RegionLocY + pos.Y; 1390 double presenceWorldX = (double)scene.RegionInfo.WorldLocX + pos.X;
1391 double presenceWorldY = (double)scene.RegionInfo.WorldLocY + pos.Y;
1536 1392
1537 // Call the grid service to lookup the region containing the new position. 1393 // Call the grid service to lookup the region containing the new position.
1538 GridRegion neighbourRegion = GetRegionContainingWorldLocation(scene.GridService, scene.RegionInfo.ScopeID, 1394 GridRegion neighbourRegion = GetRegionContainingWorldLocation(scene.GridService, scene.RegionInfo.ScopeID,
@@ -1540,63 +1396,73 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1540 1396
1541 if (neighbourRegion != null) 1397 if (neighbourRegion != null)
1542 { 1398 {
1543 Vector3 newRegionRelativeObjectPosition = new Vector3( 1399 // Compute the entity's position relative to the new region
1544 (float)(presenceWorldX - (double)neighbourRegion.RegionLocX), 1400 newpos = new Vector3( (float)(presenceWorldX - (double)neighbourRegion.RegionLocX),
1545 (float)(presenceWorldY - (double)neighbourRegion.RegionLocY), 1401 (float)(presenceWorldY - (double)neighbourRegion.RegionLocY),
1546 pos.Z); 1402 pos.Z);
1547 agent.ControllingClient.SendAgentAlertMessage( 1403
1548 String.Format("Moving you to region {0},{1}", neighbourRegion.RegionCoordX, neighbourRegion.RegionCoordY), false); 1404 // Check if banned from destination region.
1549 InformClientToInitiateTeleportToLocation(agent, (uint)neighbourRegion.RegionCoordX, (uint)neighbourRegion.RegionCoordY,
1550 newRegionRelativeObjectPosition, scene);
1551
1552 ExpiringCache<ulong, DateTime> r; 1405 ExpiringCache<ulong, DateTime> r;
1553 DateTime banUntil; 1406 DateTime banUntil;
1554 1407 if (m_bannedRegions.TryGetValue(agentID, out r))
1555 if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r)) 1408 {
1556 { 1409 if (r.TryGetValue(neighbourRegion.RegionHandle, out banUntil))
1557 if (r.TryGetValue(neighbourRegion.RegionHandle, out banUntil)) 1410 {
1558 { 1411 if (DateTime.Now < banUntil)
1559 if (DateTime.Now < banUntil) 1412 {
1560 return false; 1413 // If we're banned from the destination, we just can't go there.
1561 r.Remove(neighbourRegion.RegionHandle); 1414 neighbourRegion = null;
1562 } 1415 }
1563 } 1416 r.Remove(neighbourRegion.RegionHandle);
1564 else 1417 }
1565 { 1418 }
1566 r = null; 1419 else
1420 {
1421 r = null;
1567 } 1422 }
1568 1423
1424 // Check to see if we have access to the target region.
1569 string reason; 1425 string reason;
1570 string version; 1426 if (neighbourRegion != null
1571 if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newRegionRelativeObjectPosition, out version, out reason)) 1427 && !scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason))
1572 { 1428 {
1573 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
1574 if (r == null) 1429 if (r == null)
1575 { 1430 {
1576 r = new ExpiringCache<ulong, DateTime>(); 1431 r = new ExpiringCache<ulong, DateTime>();
1577 r.Add(neighbourRegion.RegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 1432 r.Add(neighbourRegion.RegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1578 1433
1579 m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45)); 1434 m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(45));
1580 } 1435 }
1581 else 1436 else
1582 { 1437 {
1583 r.Add(neighbourRegion.RegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 1438 r.Add(neighbourRegion.RegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1584 } 1439 }
1585 return false; 1440 neighbourRegion = null;
1586 } 1441 }
1442 }
1587 1443
1588 agent.IsInTransit = true; 1444 return neighbourRegion;
1445 }
1589 1446
1590 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; 1447 public bool Cross(ScenePresence agent, bool isFlying)
1591 d.BeginInvoke(agent, newRegionRelativeObjectPosition, 1448 {
1592 (uint)neighbourRegion.RegionLocX, (uint)neighbourRegion.RegionLocY, 1449 uint x;
1593 neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); 1450 uint y;
1594 } 1451 Vector3 newpos;
1595 else 1452 string version;
1453
1454 GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out version, out newpos);
1455 if (neighbourRegion == null)
1596 { 1456 {
1597 m_log.ErrorFormat("{0} Cross(sp). Did not find target region. SP.AbsolutePosition={1}", LogHeader, pos); 1457 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
1458 return false;
1598 } 1459 }
1599 1460
1461 agent.IsInTransit = true;
1462
1463 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
1464 d.BeginInvoke(agent, newpos, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);
1465
1600 return true; 1466 return true;
1601 } 1467 }
1602 1468
@@ -1677,52 +1543,49 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1677 icon.EndInvoke(iar); 1543 icon.EndInvoke(iar);
1678 } 1544 }
1679 1545
1680 public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version); 1546 public bool CrossAgentToNewRegionPrep(ScenePresence agent, GridRegion neighbourRegion)
1547 {
1548 if (neighbourRegion == null)
1549 return false;
1550
1551 m_entityTransferStateMachine.SetInTransit(agent.UUID);
1552
1553 agent.RemoveFromPhysicalScene();
1554
1555 return true;
1556 }
1681 1557
1682 /// <summary> 1558 /// <summary>
1683 /// This Closes child agents on neighbouring regions 1559 /// This Closes child agents on neighbouring regions
1684 /// Calls an asynchronous method to do so.. so it doesn't lag the sim. 1560 /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
1685 /// </summary> 1561 /// </summary>
1686 protected ScenePresence CrossAgentToNewRegionAsync( 1562 public ScenePresence CrossAgentToNewRegionAsync(
1687 ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, 1563 ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
1688 bool isFlying, string version) 1564 bool isFlying, string version)
1689 { 1565 {
1690 if (neighbourRegion == null) 1566 if (!CrossAgentToNewRegionPrep(agent, neighbourRegion))
1567 {
1568 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1691 return agent; 1569 return agent;
1570 }
1692 1571
1693 if (!m_entityTransferStateMachine.SetInTransit(agent.UUID)) 1572 if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying))
1694 { 1573 {
1695 m_log.ErrorFormat( 1574 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1696 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2} - agent is already in transit",
1697 agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName);
1698 return agent; 1575 return agent;
1699 } 1576 }
1700 1577
1701 bool transitWasReset = false; 1578 CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, version);
1579 return agent;
1580 }
1702 1581
1582 public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying)
1583 {
1703 try 1584 try
1704 { 1585 {
1705 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); 1586 AgentData cAgent = new AgentData();
1706
1707 m_log.DebugFormat(
1708 "[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}",
1709 agent.Firstname, agent.Lastname, neighbourx, neighboury, version);
1710
1711 Scene m_scene = agent.Scene;
1712
1713 if (!agent.ValidateAttachments())
1714 m_log.DebugFormat(
1715 "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.",
1716 agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName);
1717
1718 pos = pos + agent.Velocity;
1719 Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
1720
1721 agent.RemoveFromPhysicalScene();
1722
1723 AgentData cAgent = new AgentData();
1724 agent.CopyTo(cAgent); 1587 agent.CopyTo(cAgent);
1725 cAgent.Position = pos; 1588 cAgent.Position = pos + agent.Velocity;
1726 if (isFlying) 1589 if (isFlying)
1727 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; 1590 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
1728 1591
@@ -1732,7 +1595,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1732 // Beyond this point, extra cleanup is needed beyond removing transit state 1595 // Beyond this point, extra cleanup is needed beyond removing transit state
1733 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); 1596 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring);
1734 1597
1735 if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) 1598 if (!agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent))
1736 { 1599 {
1737 // region doesn't take it 1600 // region doesn't take it
1738 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); 1601 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
@@ -1744,88 +1607,108 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1744 ReInstantiateScripts(agent); 1607 ReInstantiateScripts(agent);
1745 agent.AddToPhysicalScene(isFlying); 1608 agent.AddToPhysicalScene(isFlying);
1746 1609
1747 return agent; 1610 return false;
1748 } 1611 }
1749 1612
1750 //m_log.Debug("BEFORE CROSS"); 1613 }
1751 //Scene.DumpChildrenSeeds(UUID); 1614 catch (Exception e)
1752 //DumpKnownRegions(); 1615 {
1753 string agentcaps; 1616 m_log.ErrorFormat(
1754 if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) 1617 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}",
1755 { 1618 agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace);
1756 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.", 1619
1757 neighbourRegion.RegionHandle); 1620 // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc.
1758 return agent; 1621 return false;
1759 } 1622 }
1623
1624 return true;
1625 }
1760 1626
1761 // No turning back 1627 public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
1762 agent.IsChildAgent = true; 1628 bool isFlying, string version)
1629 {
1630 agent.ControllingClient.RequestClientInfo();
1763 1631
1764 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); 1632 string agentcaps;
1633 if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps))
1634 {
1635 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.",
1636 neighbourRegion.RegionHandle);
1637 return;
1638 }
1765 1639
1766 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); 1640 // No turning back
1641 agent.IsChildAgent = true;
1767 1642
1768 if (m_eqModule != null) 1643 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps);
1769 {
1770 m_eqModule.CrossRegion(
1771 neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint,
1772 capsPath, agent.UUID, agent.ControllingClient.SessionId);
1773 }
1774 else
1775 {
1776 agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint,
1777 capsPath);
1778 }
1779 1644
1780 // SUCCESS! 1645 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID);
1781 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination);
1782 1646
1783 // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. 1647 Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
1784 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1785 1648
1786 agent.MakeChildAgent(); 1649 if (m_eqModule != null)
1650 {
1651 m_eqModule.CrossRegion(
1652 neighbourRegion.RegionHandle, pos + agent.Velocity, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint,
1653 capsPath, agent.UUID, agent.ControllingClient.SessionId);
1654 }
1655 else
1656 {
1657 agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, neighbourRegion.ExternalEndPoint,
1658 capsPath);
1659 }
1787 1660
1788 // FIXME: Possibly this should occur lower down after other commands to close other agents, 1661 // SUCCESS!
1789 // but not sure yet what the side effects would be. 1662 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination);
1790 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1791 transitWasReset = true;
1792 1663
1793 // now we have a child agent in this region. Request all interesting data about other (root) agents 1664 // Unlike a teleport, here we do not wait for the destination region to confirm the receipt.
1794 agent.SendOtherAgentsAvatarDataToMe(); 1665 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1795 agent.SendOtherAgentsAppearanceToMe();
1796 1666
1797 // Backwards compatibility. Best effort 1667 agent.MakeChildAgent();
1798 if (version == "Unknown" || version == string.Empty)
1799 {
1800 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one...");
1801 Thread.Sleep(3000); // wait a little now that we're not waiting for the callback
1802 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
1803 }
1804 1668
1805 // Next, let's close the child agent connections that are too far away. 1669 // FIXME: Possibly this should occur lower down after other commands to close other agents,
1806 agent.CloseChildAgents(neighbourx, neighboury); 1670 // but not sure yet what the side effects would be.
1671 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1807 1672
1808 AgentHasMovedAway(agent, false); 1673 // now we have a child agent in this region. Request all interesting data about other (root) agents
1809 1674 agent.SendOtherAgentsAvatarDataToMe();
1810 //m_log.Debug("AFTER CROSS"); 1675 agent.SendOtherAgentsAppearanceToMe();
1811 //Scene.DumpChildrenSeeds(UUID);
1812 //DumpKnownRegions();
1813 }
1814 catch (Exception e)
1815 {
1816 m_log.ErrorFormat(
1817 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}",
1818 agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace);
1819 1676
1820 // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. 1677 // Backwards compatibility. Best effort
1821 } 1678 if (version == "Unknown" || version == string.Empty)
1822 finally
1823 { 1679 {
1824 if (!transitWasReset) 1680 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one...");
1825 m_entityTransferStateMachine.ResetFromTransit(agent.UUID); 1681 Thread.Sleep(3000); // wait a little now that we're not waiting for the callback
1682 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
1826 } 1683 }
1827 1684
1828 return agent; 1685 // Next, let's close the child agent connections that are too far away.
1686 uint neighbourx;
1687 uint neighboury;
1688
1689 Utils.LongToUInts(neighbourRegion.RegionHandle, out neighbourx, out neighboury);
1690
1691 neighbourx /= Constants.RegionSize;
1692 neighboury /= Constants.RegionSize;
1693
1694 agent.CloseChildAgents(neighbourx, neighboury);
1695
1696 AgentHasMovedAway(agent, false);
1697
1698 // the user may change their profile information in other region,
1699 // so the userinfo in UserProfileCache is not reliable any more, delete it
1700 // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
1701// if (agent.Scene.NeedSceneCacheClear(agent.UUID))
1702// {
1703// m_log.DebugFormat(
1704// "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID);
1705// }
1706
1707 //m_log.Debug("AFTER CROSS");
1708 //Scene.DumpChildrenSeeds(UUID);
1709 //DumpKnownRegions();
1710
1711 return;
1829 } 1712 }
1830 1713
1831 private void CrossAgentToNewRegionCompleted(IAsyncResult iar) 1714 private void CrossAgentToNewRegionCompleted(IAsyncResult iar)
@@ -1896,10 +1779,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1896 agent.Id0 = currentAgentCircuit.Id0; 1779 agent.Id0 = currentAgentCircuit.Id0;
1897 } 1780 }
1898 1781
1899 InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; 1782 IPEndPoint external = region.ExternalEndPoint;
1900 d.BeginInvoke(sp, agent, region, region.ExternalEndPoint, true, 1783 if (external != null)
1784 {
1785 InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync;
1786 d.BeginInvoke(sp, agent, region, external, true,
1901 InformClientOfNeighbourCompleted, 1787 InformClientOfNeighbourCompleted,
1902 d); 1788 d);
1789 }
1903 } 1790 }
1904 #endregion 1791 #endregion
1905 1792
@@ -2116,7 +2003,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2116 if (ret == null) 2003 if (ret == null)
2117 { 2004 {
2118 // If the simple lookup failed, search the larger area for a region that contains this point 2005 // If the simple lookup failed, search the larger area for a region that contains this point
2119 double range = (double)Constants.RegionSize + 2; 2006 double range = (double)Constants.RegionSize * 2 + 2;
2120 while (ret == null && range <= (Constants.MaximumRegionSize + Constants.RegionSize)) 2007 while (ret == null && range <= (Constants.MaximumRegionSize + Constants.RegionSize))
2121 { 2008 {
2122 // Get from the grid service a list of regions that might contain this point 2009 // Get from the grid service a list of regions that might contain this point
@@ -2387,175 +2274,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2387 return; 2274 return;
2388 } 2275 }
2389 2276
2390 /*
2391 int thisx = (int)scene.RegionInfo.LegacyRegionLocX;
2392 int thisy = (int)scene.RegionInfo.LegacyRegionLocY;
2393 Vector3 EastCross = new Vector3(0.1f, 0, 0);
2394 Vector3 WestCross = new Vector3(-0.1f, 0, 0);
2395 Vector3 NorthCross = new Vector3(0, 0.1f, 0);
2396 Vector3 SouthCross = new Vector3(0, -0.1f, 0);
2397
2398
2399 // use this default if no borders were crossed (handle of the current region)
2400 ulong newRegionHandle = Util.RegionWorldLocToHandle(scene.RegionInfo.RegionWorldLocX, scene.RegionInfo.RegionWorldLocY);
2401
2402 Vector3 pos = attemptedPosition;
2403
2404 int changeX = 1;
2405 int changeY = 1;
2406
2407 if (scene.TestBorderCross(attemptedPosition + WestCross, Cardinals.W))
2408 {
2409 if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
2410 {
2411
2412 Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);
2413
2414 if (crossedBorderx.BorderLine.Z > 0)
2415 {
2416 pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
2417 changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize);
2418 }
2419 else
2420 pos.X = ((pos.X + Constants.RegionSize));
2421
2422 Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
2423 //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)
2424
2425 if (crossedBordery.BorderLine.Z > 0)
2426 {
2427 pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
2428 changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
2429 }
2430 else
2431 pos.Y = ((pos.Y + Constants.RegionSize));
2432
2433
2434
2435 newRegionHandle
2436 = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize),
2437 (uint)((thisy - changeY) * Constants.RegionSize));
2438 // x - 1
2439 // y - 1
2440 }
2441 else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
2442 {
2443 Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);
2444
2445 if (crossedBorderx.BorderLine.Z > 0)
2446 {
2447 pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
2448 changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize);
2449 }
2450 else
2451 pos.X = ((pos.X + Constants.RegionSize));
2452
2453
2454 Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
2455 //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)
2456
2457 if (crossedBordery.BorderLine.Z > 0)
2458 {
2459 pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
2460 changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
2461 }
2462 else
2463 pos.Y = ((pos.Y + Constants.RegionSize));
2464
2465 newRegionHandle
2466 = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize),
2467 (uint)((thisy + changeY) * Constants.RegionSize));
2468 // x - 1
2469 // y + 1
2470 }
2471 else
2472 {
2473 Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);
2474
2475 if (crossedBorderx.BorderLine.Z > 0)
2476 {
2477 pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
2478 changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize);
2479 }
2480 else
2481 pos.X = ((pos.X + Constants.RegionSize));
2482
2483 newRegionHandle
2484 = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize),
2485 (uint)(thisy * Constants.RegionSize));
2486 // x - 1
2487 }
2488 }
2489 else if (scene.TestBorderCross(attemptedPosition + EastCross, Cardinals.E))
2490 {
2491 if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
2492 {
2493
2494 pos.X = ((pos.X - Constants.RegionSize));
2495 Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
2496 //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)
2497
2498 if (crossedBordery.BorderLine.Z > 0)
2499 {
2500 pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
2501 changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
2502 }
2503 else
2504 pos.Y = ((pos.Y + Constants.RegionSize));
2505
2506
2507 newRegionHandle
2508 = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
2509 (uint)((thisy - changeY) * Constants.RegionSize));
2510 // x + 1
2511 // y - 1
2512 }
2513 else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
2514 {
2515 pos.X = ((pos.X - Constants.RegionSize));
2516 pos.Y = ((pos.Y - Constants.RegionSize));
2517 newRegionHandle
2518 = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
2519 (uint)((thisy + changeY) * Constants.RegionSize));
2520 // x + 1
2521 // y + 1
2522 }
2523 else
2524 {
2525 pos.X = ((pos.X - Constants.RegionSize));
2526 newRegionHandle
2527 = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
2528 (uint)(thisy * Constants.RegionSize));
2529 // x + 1
2530 }
2531 }
2532 else if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
2533 {
2534 Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
2535 //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)
2536
2537 if (crossedBordery.BorderLine.Z > 0)
2538 {
2539 pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
2540 changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
2541 }
2542 else
2543 pos.Y = ((pos.Y + Constants.RegionSize));
2544
2545 newRegionHandle
2546 = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy - changeY) * Constants.RegionSize));
2547 // y - 1
2548 }
2549 else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
2550 {
2551
2552 pos.Y = ((pos.Y - Constants.RegionSize));
2553 newRegionHandle
2554 = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy + changeY) * Constants.RegionSize));
2555 // y + 1
2556 }
2557 */
2558
2559 // Remember the old group position in case the region lookup fails so position can be restored. 2277 // Remember the old group position in case the region lookup fails so position can be restored.
2560 Vector3 oldGroupPosition = grp.RootPart.GroupPosition; 2278 Vector3 oldGroupPosition = grp.RootPart.GroupPosition;
2561 2279
@@ -2576,30 +2294,31 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2576 attemptedPosition.Z); 2294 attemptedPosition.Z);
2577 } 2295 }
2578 2296
2579 if (destination == null || !CrossPrimGroupIntoNewRegion(destination, pos, grp, silent)) 2297 if (destination != null)
2580 { 2298 {
2581 m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}", grp.UUID); 2299 if (!CrossPrimGroupIntoNewRegion(destination, pos, grp, silent))
2582 2300 {
2583 // We are going to move the object back to the old position so long as the old position 2301 m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}", grp.UUID);
2584 // is in the region 2302
2585 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 1.0f, (float)(scene.RegionInfo.RegionSizeX - 1)); 2303 // We are going to move the object back to the old position so long as the old position
2586 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 1.0f, (float)(scene.RegionInfo.RegionSizeY - 1)); 2304 // is in the region
2587 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 1.0f, Constants.RegionHeight); 2305 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 1.0f, (float)(scene.RegionInfo.RegionSizeX - 1));
2588 2306 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 1.0f, (float)(scene.RegionInfo.RegionSizeY - 1));
2589 grp.RootPart.GroupPosition = oldGroupPosition; 2307 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 1.0f, Constants.RegionHeight);
2590 2308
2591 // Need to turn off the physics flags, otherwise the object will continue to attempt to 2309 grp.AbsolutePosition = oldGroupPosition;
2592 // move out of the region creating an infinite loop of failed attempts to cross 2310 grp.Velocity = Vector3.Zero;
2593 grp.UpdatePrimFlags(grp.RootPart.LocalId, false, grp.IsTemporary, grp.IsPhantom, false); 2311 if (grp.RootPart.PhysActor != null)
2594 2312 grp.RootPart.PhysActor.CrossingFailure();
2595 if (grp.RootPart.KeyframeMotion != null) 2313
2596 grp.RootPart.KeyframeMotion.CrossingFailure(); 2314 if (grp.RootPart.KeyframeMotion != null)
2597 2315 grp.RootPart.KeyframeMotion.CrossingFailure();
2598 grp.ScheduleGroupForFullUpdate(); 2316
2317 grp.ScheduleGroupForFullUpdate();
2318 }
2599 } 2319 }
2600 } 2320 }
2601 2321
2602
2603 /// <summary> 2322 /// <summary>
2604 /// Move the given scene object into a new region 2323 /// Move the given scene object into a new region
2605 /// </summary> 2324 /// </summary>
@@ -2650,17 +2369,30 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2650 grp, e); 2369 grp, e);
2651 } 2370 }
2652 } 2371 }
2372/*
2373 * done on caller ( not in attachments crossing for now)
2653 else 2374 else
2654 { 2375 {
2376
2655 if (!grp.IsDeleted) 2377 if (!grp.IsDeleted)
2656 { 2378 {
2657 PhysicsActor pa = grp.RootPart.PhysActor; 2379 PhysicsActor pa = grp.RootPart.PhysActor;
2658 if (pa != null) 2380 if (pa != null)
2381 {
2659 pa.CrossingFailure(); 2382 pa.CrossingFailure();
2383 if (grp.RootPart.KeyframeMotion != null)
2384 {
2385 // moved to KeyframeMotion.CrossingFailure
2386// grp.RootPart.Velocity = Vector3.Zero;
2387 grp.RootPart.KeyframeMotion.CrossingFailure();
2388// grp.SendGroupRootTerseUpdate();
2389 }
2390 }
2660 } 2391 }
2661 2392
2662 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp); 2393 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp);
2663 } 2394 }
2395 */
2664 } 2396 }
2665 else 2397 else
2666 { 2398 {
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/UserProfiles/LocalUserProfilesServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/UserProfiles/LocalUserProfilesServiceConnector.cs
index 323535a..4701ee6 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/UserProfiles/LocalUserProfilesServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/UserProfiles/LocalUserProfilesServiceConnector.cs
@@ -153,6 +153,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Profile
153 Server.AddJsonRPCHandler("avatar_properties_request", handler.AvatarPropertiesRequest); 153 Server.AddJsonRPCHandler("avatar_properties_request", handler.AvatarPropertiesRequest);
154 Server.AddJsonRPCHandler("avatar_properties_update", handler.AvatarPropertiesUpdate); 154 Server.AddJsonRPCHandler("avatar_properties_update", handler.AvatarPropertiesUpdate);
155 Server.AddJsonRPCHandler("avatar_interests_update", handler.AvatarInterestsUpdate); 155 Server.AddJsonRPCHandler("avatar_interests_update", handler.AvatarInterestsUpdate);
156 Server.AddJsonRPCHandler("user_preferences_update", handler.UserPreferenecesUpdate);
157 Server.AddJsonRPCHandler("user_preferences_request", handler.UserPreferencesRequest);
156 Server.AddJsonRPCHandler("image_assets_request", handler.AvatarImageAssetsRequest); 158 Server.AddJsonRPCHandler("image_assets_request", handler.AvatarImageAssetsRequest);
157 Server.AddJsonRPCHandler("user_data_request", handler.RequestUserAppData); 159 Server.AddJsonRPCHandler("user_data_request", handler.RequestUserAppData);
158 Server.AddJsonRPCHandler("user_data_update", handler.UpdateUserAppData); 160 Server.AddJsonRPCHandler("user_data_update", handler.UpdateUserAppData);
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
index 2a4d8d8..f8f4986 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
@@ -425,6 +425,19 @@ namespace OpenSim.Region.CoreModules.World.Land
425 return false; 425 return false;
426 } 426 }
427 427
428 public bool CanBeOnThisLand(UUID avatar, float posHeight)
429 {
430 if (posHeight < LandChannel.BAN_LINE_SAFETY_HIEGHT && IsBannedFromLand(avatar))
431 {
432 return false;
433 }
434 else if (IsRestrictedFromLand(avatar))
435 {
436 return false;
437 }
438 return true;
439 }
440
428 public bool HasGroupAccess(UUID avatar) 441 public bool HasGroupAccess(UUID avatar)
429 { 442 {
430 if (LandData.GroupID != UUID.Zero && (LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup) 443 if (LandData.GroupID != UUID.Zero && (LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup)
diff --git a/OpenSim/Region/CoreModules/World/Wind/WindModule.cs b/OpenSim/Region/CoreModules/World/Wind/WindModule.cs
index 9de588c..35014f5 100644
--- a/OpenSim/Region/CoreModules/World/Wind/WindModule.cs
+++ b/OpenSim/Region/CoreModules/World/Wind/WindModule.cs
@@ -216,13 +216,13 @@ namespace OpenSim.Region.CoreModules
216 // FIXME: If console region is root then this will be printed by every module. Currently, there is no 216 // FIXME: If console region is root then this will be printed by every module. Currently, there is no
217 // way to prevent this, short of making the entire module shared (which is complete overkill). 217 // way to prevent this, short of making the entire module shared (which is complete overkill).
218 // One possibility is to return a bool to signal whether the module has completely handled the command 218 // One possibility is to return a bool to signal whether the module has completely handled the command
219 m_log.InfoFormat("[WIND]: Please change to a specific region in order to set Sun parameters."); 219 MainConsole.Instance.Output("Please change to a specific region in order to set Sun parameters.");
220 return; 220 return;
221 } 221 }
222 222
223 if (m_scene.ConsoleScene() != m_scene) 223 if (m_scene.ConsoleScene() != m_scene)
224 { 224 {
225 m_log.InfoFormat("[WIND]: Console Scene is not my scene."); 225 MainConsole.Instance.Output("Console Scene is not my scene.");
226 return; 226 return;
227 } 227 }
228 } 228 }
@@ -233,7 +233,9 @@ namespace OpenSim.Region.CoreModules
233 private void HandleConsoleCommand(string module, string[] cmdparams) 233 private void HandleConsoleCommand(string module, string[] cmdparams)
234 { 234 {
235 ValidateConsole(); 235 ValidateConsole();
236 m_log.Info("[WIND] The wind command can be used to change the currently active wind model plugin and update the parameters for wind plugins."); 236
237 MainConsole.Instance.Output(
238 "The wind command can be used to change the currently active wind model plugin and update the parameters for wind plugins.");
237 } 239 }
238 240
239 /// <summary> 241 /// <summary>
@@ -246,7 +248,9 @@ namespace OpenSim.Region.CoreModules
246 if ((cmdparams.Length != 4) 248 if ((cmdparams.Length != 4)
247 || !cmdparams[1].Equals("base")) 249 || !cmdparams[1].Equals("base"))
248 { 250 {
249 m_log.Info("[WIND] Invalid parameters to change parameters for Wind module base, usage: wind base <parameter> <value>"); 251 MainConsole.Instance.Output(
252 "Invalid parameters to change parameters for Wind module base, usage: wind base <parameter> <value>");
253
250 return; 254 return;
251 } 255 }
252 256
@@ -261,7 +265,9 @@ namespace OpenSim.Region.CoreModules
261 } 265 }
262 else 266 else
263 { 267 {
264 m_log.InfoFormat("[WIND] Invalid value {0} specified for {1}", cmdparams[3], cmdparams[2]); 268 MainConsole.Instance.OutputFormat(
269 "Invalid value {0} specified for {1}", cmdparams[3], cmdparams[2]);
270
265 return; 271 return;
266 } 272 }
267 273
@@ -271,22 +277,23 @@ namespace OpenSim.Region.CoreModules
271 277
272 if (desiredPlugin.Equals(m_activeWindPlugin.Name)) 278 if (desiredPlugin.Equals(m_activeWindPlugin.Name))
273 { 279 {
274 m_log.InfoFormat("[WIND] Wind model plugin {0} is already active", cmdparams[3]); 280 MainConsole.Instance.OutputFormat("Wind model plugin {0} is already active", cmdparams[3]);
281
275 return; 282 return;
276 } 283 }
277 284
278 if (m_availableWindPlugins.ContainsKey(desiredPlugin)) 285 if (m_availableWindPlugins.ContainsKey(desiredPlugin))
279 { 286 {
280 m_activeWindPlugin = m_availableWindPlugins[cmdparams[3]]; 287 m_activeWindPlugin = m_availableWindPlugins[cmdparams[3]];
281 m_log.InfoFormat("[WIND] {0} wind model plugin now active", m_activeWindPlugin.Name); 288
289 MainConsole.Instance.OutputFormat("{0} wind model plugin now active", m_activeWindPlugin.Name);
282 } 290 }
283 else 291 else
284 { 292 {
285 m_log.InfoFormat("[WIND] Could not find wind model plugin {0}", desiredPlugin); 293 MainConsole.Instance.OutputFormat("Could not find wind model plugin {0}", desiredPlugin);
286 } 294 }
287 break; 295 break;
288 } 296 }
289
290 } 297 }
291 298
292 /// <summary> 299 /// <summary>
@@ -300,7 +307,7 @@ namespace OpenSim.Region.CoreModules
300 if ((cmdparams.Length != 4) 307 if ((cmdparams.Length != 4)
301 && (cmdparams.Length != 3)) 308 && (cmdparams.Length != 3))
302 { 309 {
303 m_log.Info("[WIND] Usage: wind <plugin> <param> [value]"); 310 MainConsole.Instance.Output("Usage: wind <plugin> <param> [value]");
304 return; 311 return;
305 } 312 }
306 313
@@ -311,16 +318,17 @@ namespace OpenSim.Region.CoreModules
311 { 318 {
312 if (!float.TryParse(cmdparams[3], out value)) 319 if (!float.TryParse(cmdparams[3], out value))
313 { 320 {
314 m_log.InfoFormat("[WIND] Invalid value {0}", cmdparams[3]); 321 MainConsole.Instance.OutputFormat("Invalid value {0}", cmdparams[3]);
315 } 322 }
316 323
317 try 324 try
318 { 325 {
319 WindParamSet(plugin, param, value); 326 WindParamSet(plugin, param, value);
327 MainConsole.Instance.OutputFormat("{0} set to {1}", param, value);
320 } 328 }
321 catch (Exception e) 329 catch (Exception e)
322 { 330 {
323 m_log.InfoFormat("[WIND] {0}", e.Message); 331 MainConsole.Instance.OutputFormat("{0}", e.Message);
324 } 332 }
325 } 333 }
326 else 334 else
@@ -328,11 +336,11 @@ namespace OpenSim.Region.CoreModules
328 try 336 try
329 { 337 {
330 value = WindParamGet(plugin, param); 338 value = WindParamGet(plugin, param);
331 m_log.InfoFormat("[WIND] {0} : {1}", param, value); 339 MainConsole.Instance.OutputFormat("{0} : {1}", param, value);
332 } 340 }
333 catch (Exception e) 341 catch (Exception e)
334 { 342 {
335 m_log.InfoFormat("[WIND] {0}", e.Message); 343 MainConsole.Instance.OutputFormat("{0}", e.Message);
336 } 344 }
337 } 345 }
338 346
@@ -366,13 +374,11 @@ namespace OpenSim.Region.CoreModules
366 { 374 {
367 IWindModelPlugin windPlugin = m_availableWindPlugins[plugin]; 375 IWindModelPlugin windPlugin = m_availableWindPlugins[plugin];
368 windPlugin.WindParamSet(param, value); 376 windPlugin.WindParamSet(param, value);
369 m_log.InfoFormat("[WIND] {0} set to {1}", param, value);
370 } 377 }
371 else 378 else
372 { 379 {
373 throw new Exception(String.Format("Could not find plugin {0}", plugin)); 380 throw new Exception(String.Format("Could not find plugin {0}", plugin));
374 } 381 }
375
376 } 382 }
377 383
378 public float WindParamGet(string plugin, string param) 384 public float WindParamGet(string plugin, string param)